From d4add184fd09ac1c8cf1d0e5d7378ae80f65ae99 Mon Sep 17 00:00:00 2001 From: Jess Lowe Date: Sun, 11 Jan 2026 21:09:03 +0000 Subject: [PATCH 1/5] Add flag to reject on failure --- vulnfeeds/cmd/cve-bulk-converter/main.go | 19 ++++++++++++++----- vulnfeeds/cmd/cve-single-converter/main.go | 4 ++-- vulnfeeds/cvelist2osv/common.go | 21 +++++++++++++++++++++ vulnfeeds/cvelist2osv/converter.go | 10 +++++----- vulnfeeds/cvelist2osv/converter_test.go | 2 +- 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/vulnfeeds/cmd/cve-bulk-converter/main.go b/vulnfeeds/cmd/cve-bulk-converter/main.go index 065d098c4b4..0a8029bbffe 100644 --- a/vulnfeeds/cmd/cve-bulk-converter/main.go +++ b/vulnfeeds/cmd/cve-bulk-converter/main.go @@ -23,6 +23,7 @@ var ( years = flag.String("years", "2022,2023,2024,2025", "A comma-separated list of years to process.") workers = flag.Int("workers", 30, "The number of concurrent workers to use for processing CVEs.") cnaAllowList = flag.String("cnas-allowlist", "", "A comma-separated list of CNAs to process. If not provided, defaults to cna_allowlist.txt.") + rejectFailed = flag.Bool("reject-failed", false, "If set, OSV records with a failed conversion outcome will not be generated.") ) //go:embed cna_allowlist.txt @@ -32,7 +33,7 @@ func main() { flag.Parse() logger.InitGlobalLogger() - logger.Info("Commencing Linux CVE to OSV conversion run") + logger.Info("Commencing CVE to OSV conversion run") if err := os.MkdirAll(*localOutputDir, 0755); err != nil { logger.Fatal("Failed to create local output directory", slog.Any("err", err)) } @@ -54,7 +55,7 @@ func main() { // Start the worker pool. for range *workers { wg.Add(1) - go worker(&wg, jobs, *localOutputDir, cnaList) + go worker(&wg, jobs, *localOutputDir, cnaList, *rejectFailed) } // Discover files and send them to the workers. @@ -71,6 +72,7 @@ func main() { logger.Info("Processing CVEs for year", slog.String("year", year)) err := filepath.Walk(yearDir, func(path string, info os.FileInfo, err error) error { if err != nil { + logger.Info("Error walking directory for year", slog.String("year", year), slog.Any("err", err)) return err } if !info.IsDir() && strings.HasSuffix(info.Name(), ".json") { @@ -90,7 +92,7 @@ func main() { } // worker is a function that processes CVE files from the jobs channel. -func worker(wg *sync.WaitGroup, jobs <-chan string, outDir string, cnas []string) { +func worker(wg *sync.WaitGroup, jobs <-chan string, outDir string, cnas []string, rejectFailed bool) { defer wg.Done() for path := range jobs { data, err := os.ReadFile(path) @@ -126,10 +128,17 @@ func worker(wg *sync.WaitGroup, jobs <-chan string, outDir string, cnas []string } // Perform the conversion and export the results. - if err = cvelist2osv.ConvertAndExportCVEToOSV(cve, osvFile, metricsFile, sourceLink); err != nil { + metrics, err := cvelist2osv.ConvertAndExportCVEToOSV(cve, osvFile, metricsFile, sourceLink) + if err != nil { logger.Warn("Failed to generate an OSV record", slog.String("cve", string(cveID)), slog.Any("err", err)) } else { - logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName)) + if rejectFailed && metrics.Outcome != cvelist2osv.Successful { + logger.Info("Rejecting failed OSV record", slog.String("cve", string(cveID)), slog.String("outcome", metrics.Outcome.String())) + osvFile.Close() + os.Remove(osvFile.Name()) + } else { + logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName)) + } } metricsFile.Close() diff --git a/vulnfeeds/cmd/cve-single-converter/main.go b/vulnfeeds/cmd/cve-single-converter/main.go index 471e95fc161..03b98d281b1 100644 --- a/vulnfeeds/cmd/cve-single-converter/main.go +++ b/vulnfeeds/cmd/cve-single-converter/main.go @@ -51,10 +51,10 @@ func main() { } // Perform the conversion and export the results. - if err = cvelist2osv.ConvertAndExportCVEToOSV(cve, osvFile, metricsFile, ""); err != nil { + if metrics, err := cvelist2osv.ConvertAndExportCVEToOSV(cve, osvFile, metricsFile, ""); err != nil { logger.Warn("Failed to generate an OSV record", slog.String("cve", string(cveID)), slog.Any("err", err)) } else { - logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName)) + logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName), slog.String("metrics", metrics.Outcome.String())) } metricsFile.Close() diff --git a/vulnfeeds/cvelist2osv/common.go b/vulnfeeds/cvelist2osv/common.go index da185c331c5..c853091e176 100644 --- a/vulnfeeds/cvelist2osv/common.go +++ b/vulnfeeds/cvelist2osv/common.go @@ -53,6 +53,27 @@ const ( FixUnresolvable // Partial resolution of versions, resulting in a false positive. ) +func (c ConversionOutcome) String() string { + switch c { + case Successful: + return "Successful" + case Rejected: + return "Rejected" + case NoSoftware: + return "NoSoftware" + case NoRepos: + return "NoRepos" + case NoCommitRanges: + return "NoCommitRanges" + case NoRanges: + return "NoRanges" + case FixUnresolvable: + return "FixUnresolvable" + default: + return "Unknown" + } +} + // String returns the string representation of a VersionRangeType. func (vrt VersionRangeType) String() string { switch vrt { diff --git a/vulnfeeds/cvelist2osv/converter.go b/vulnfeeds/cvelist2osv/converter.go index 3f643659d8c..c525e57a41e 100644 --- a/vulnfeeds/cvelist2osv/converter.go +++ b/vulnfeeds/cvelist2osv/converter.go @@ -229,7 +229,7 @@ func determineOutcome(metrics *ConversionMetrics) { // ConvertAndExportCVEToOSV is the main function for this file. It takes a CVE, // converts it into an OSV record, collects metrics, and writes both to disk. -func ConvertAndExportCVEToOSV(cve cves.CVE5, vulnSink io.Writer, metricsSink io.Writer, sourceLink string) error { +func ConvertAndExportCVEToOSV(cve cves.CVE5, vulnSink io.Writer, metricsSink io.Writer, sourceLink string) (*ConversionMetrics, error) { cveID := cve.Metadata.CVEID cnaAssigner := cve.Metadata.AssignerShortName references := identifyPossibleURLs(cve) @@ -261,21 +261,21 @@ func ConvertAndExportCVEToOSV(cve cves.CVE5, vulnSink io.Writer, metricsSink io. err := v.ToJSON(vulnSink) if err != nil { logger.Info("Failed to write", slog.Any("err", err)) - return err + return &metrics, err } marshalledMetrics, err := json.MarshalIndent(&metrics, "", " ") if err != nil { logger.Info("Failed to marshal", slog.Any("err", err)) - return err + return &metrics, err } _, err = metricsSink.Write(marshalledMetrics) if err != nil { logger.Info("Failed to write", slog.Any("err", err)) - return err + return &metrics, err } - return nil + return &metrics, nil } // identifyPossibleURLs extracts all URLs from a CVE object. diff --git a/vulnfeeds/cvelist2osv/converter_test.go b/vulnfeeds/cvelist2osv/converter_test.go index 7ce0523525b..5d73721851d 100644 --- a/vulnfeeds/cvelist2osv/converter_test.go +++ b/vulnfeeds/cvelist2osv/converter_test.go @@ -583,7 +583,7 @@ func TestConvertAndExportCVEToOSV(t *testing.T) { t.Run(tc.name, func(t *testing.T) { vWriter := bytes.NewBuffer(nil) mWriter := bytes.NewBuffer(nil) - err := ConvertAndExportCVEToOSV(tc.cve, vWriter, mWriter, "") + _, err := ConvertAndExportCVEToOSV(tc.cve, vWriter, mWriter, "") if err != nil { t.Errorf("Unexpected error from ConvertAndExportCVEToOSV: %v", err) } From f6e470c93b4ecbcd9ba09cb3c4be508d7fbbded4 Mon Sep 17 00:00:00 2001 From: Jess Lowe <86962800+jess-lowe@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:05:45 +1300 Subject: [PATCH 2/5] Apply suggestion from @jess-lowe --- vulnfeeds/cmd/cve-single-converter/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vulnfeeds/cmd/cve-single-converter/main.go b/vulnfeeds/cmd/cve-single-converter/main.go index 03b98d281b1..a2af6573492 100644 --- a/vulnfeeds/cmd/cve-single-converter/main.go +++ b/vulnfeeds/cmd/cve-single-converter/main.go @@ -54,7 +54,7 @@ func main() { if metrics, err := cvelist2osv.ConvertAndExportCVEToOSV(cve, osvFile, metricsFile, ""); err != nil { logger.Warn("Failed to generate an OSV record", slog.String("cve", string(cveID)), slog.Any("err", err)) } else { - logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName), slog.String("metrics", metrics.Outcome.String())) + logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName), slog.String("outcome", metrics.Outcome.String())) } metricsFile.Close() From 257e23830934b72aacb3664168d05f9a6417efc5 Mon Sep 17 00:00:00 2001 From: Jess Lowe <86962800+jess-lowe@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:07:09 +1300 Subject: [PATCH 3/5] add more logging --- vulnfeeds/cmd/cve-bulk-converter/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vulnfeeds/cmd/cve-bulk-converter/main.go b/vulnfeeds/cmd/cve-bulk-converter/main.go index 0a8029bbffe..9f34f7c4cf7 100644 --- a/vulnfeeds/cmd/cve-bulk-converter/main.go +++ b/vulnfeeds/cmd/cve-bulk-converter/main.go @@ -137,7 +137,7 @@ func worker(wg *sync.WaitGroup, jobs <-chan string, outDir string, cnas []string osvFile.Close() os.Remove(osvFile.Name()) } else { - logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName)) + logger.Info("Generated OSV record for "+string(cveID), slog.String("cve", string(cveID)), slog.String("cna", cve.Metadata.AssignerShortName), slog.String("outcome", metrics.Outcome.String())) } } From fcc5926ebac930b102a7979bdc96db2f15a8c830 Mon Sep 17 00:00:00 2001 From: Jess Lowe Date: Wed, 28 Jan 2026 05:28:45 +0000 Subject: [PATCH 4/5] Merge main --- .github/workflows/codeql-analysis.yml | 8 +- .github/workflows/links.yml | 2 +- .github/workflows/lint.yaml | 8 +- .github/workflows/pr-check.yml | 2 +- .github/workflows/publish-to-pypi.yaml | 4 +- .github/workflows/renovate-validator.yml | 4 +- .github/workflows/scorecards.yml | 6 +- .github/workflows/snapshots.yml | 6 +- .github/workflows/staleness.yml | 2 +- .gitignore | 1 + CONTRIBUTING.md | 11 + Makefile | 8 +- bindings/go/go.mod | 18 +- bindings/go/go.sum | 32 +- bindings/go/osvdev/osvdev_test.go | 2 +- cloudbuild.yaml | 3 +- deployment/build-and-stage.yaml | 37 +- .../clouddeploy/gke-workers/base/gitter.yaml | 6 +- .../gke-workers/base/importer.yaml | 6 +- .../environments/oss-vdb/kustomization.yaml | 2 - .../oss-fuzz-workers/clouddeploy.yaml | 23 + .../oss-fuzz-workers/importer.yaml | 54 + .../make-bugs-public.yaml | 0 .../process-results.yaml | 0 .../clouddeploy/oss-fuzz-workers/scaler.yaml | 47 + .../oss-fuzz-workers/skaffold.yaml | 16 + .../clouddeploy/oss-fuzz-workers/workers.yaml | 54 + deployment/deploy-prod.yaml | 9 + deployment/deploy.sh | 2 +- .../oss-vdb-test/.terraform.lock.hcl | 46 +- .../environments/oss-vdb-test/main.tf | 2 +- .../environments/oss-vdb/.terraform.lock.hcl | 46 +- .../terraform/environments/oss-vdb/main.tf | 10 +- .../environments/oss-vdb/unmanaged.md | 1 + deployment/terraform/modules/oss_fuzz/main.tf | 102 + .../terraform/modules/oss_fuzz/outputs.tf | 11 + .../terraform/modules/oss_fuzz/variables.tf | 30 + deployment/terraform/modules/osv/outputs.tf | 14 + .../terraform/modules/osv/workers_gke.tf | 2 +- docker/deployment/Dockerfile | 2 +- docker/poetry/requirements-py3.12.txt | 20 +- docker/poetry/requirements.txt | 60 +- docker/terraform/Dockerfile | 4 +- docker/worker-base/Dockerfile | 2 +- docs/data.md | 3 + gcp/api/cloudbuild.yaml | 14 +- gcp/api/googleapis | 2 +- gcp/api/poetry.lock | 320 +- gcp/api/run_apitester.py | 72 + gcp/api/run_tests.sh | 5 +- gcp/api/run_tests_e2e.sh | 31 + gcp/api/server.py | 80 +- gcp/datastore/index.yaml | 8 + gcp/functions/pypi/poetry.lock | 221 +- gcp/indexer/Dockerfile | 4 +- gcp/indexer/go.mod | 30 +- gcp/indexer/go.sum | 60 +- gcp/website/Dockerfile | 2 +- .../content/posts/2025-in-review/index.md | 114 + .../2025-in-review/star-history-202616.png | Bin 0 -> 482764 bytes gcp/website/cloudbuild.yaml | 3 + gcp/website/frontend3/package-lock.json | 1474 +++-- gcp/website/frontend3/package.json | 26 +- gcp/website/frontend3/src/styles.scss | 17 + gcp/website/poetry.lock | 182 +- gcp/website/pyproject.toml | 2 +- gcp/website/run_tests.sh | 5 +- gcp/workers/alias/run_tests.sh | 5 +- gcp/workers/cloudbuild.yaml | 2 + gcp/workers/importer/importer.py | 250 +- gcp/workers/importer/importer_test.py | 296 - gcp/workers/importer/run_tests.sh | 5 +- gcp/workers/linter/Dockerfile | 4 +- gcp/workers/mock_test/rest_test.json | 254 - gcp/workers/oss_fuzz_importer/Dockerfile | 19 + gcp/workers/oss_fuzz_importer/importer.py | 1362 +++++ .../oss_fuzz_importer/importer_test.py | 1091 ++++ gcp/workers/oss_fuzz_importer/run_tests.sh | 19 + gcp/workers/oss_fuzz_importer/testdata | 1 + gcp/workers/oss_fuzz_worker/Dockerfile | 34 + gcp/workers/oss_fuzz_worker/oss_fuzz.py | 551 ++ gcp/workers/oss_fuzz_worker/osv-test | 1 + gcp/workers/oss_fuzz_worker/poetry.lock | 2088 +++++++ gcp/workers/oss_fuzz_worker/pyproject.toml | 32 + gcp/workers/oss_fuzz_worker/run_tests.sh | 19 + .../testdata/CVE-2022-27449.json | 138 + .../oss_fuzz_worker/testdata/DSA-3029-1.json | 37 + .../testdata/GHSA-838r-hvwh-24h8.json | 61 + .../oss_fuzz_worker/testdata/GSD-123.yaml | 19 + .../testdata/ImpactTest_basic.txt | 64 + .../ImpactTest_fixed_range_too_long.txt | 62 + .../testdata/ImpactTest_not_fixed.txt | 62 + .../testdata/ImpactTest_range.txt | 62 + .../testdata/ImpactTest_simplify_range.txt | 64 + .../ImpactTest_zero_regression_range.txt | 60 + .../testdata/LINUX-123.yaml | 0 .../oss_fuzz_worker/testdata/OSV-123.yaml | 30 + .../oss_fuzz_worker/testdata/OSV-124.yaml | 20 + .../oss_fuzz_worker/testdata/OSV-125.yaml | 28 + .../oss_fuzz_worker/testdata/OSV-126.yaml | 21 + .../oss_fuzz_worker/testdata/OSV-127.yaml | 21 + .../oss_fuzz_worker/testdata/OSV-128.yaml | 25 + .../oss_fuzz_worker/testdata/OSV-129.yaml | 21 + .../oss_fuzz_worker/testdata/OSV-130.yaml | 35 + .../oss_fuzz_worker/testdata/OSV-131.yaml | 21 + .../testdata/OSV-TEST-last-affected-01.yaml | 16 + .../oss_fuzz_worker/testdata/PYSEC-123.yaml | 23 + .../oss_fuzz_worker/testdata/PYSEC-124.yaml | 18 + .../oss_fuzz_worker/testdata/PYSEC-456.yaml | 23 + .../RESTUpdateTest_update_no_introduced.txt | 427 ++ .../testdata/UBUNTU-CVE-2025-38094.json | 262 + .../UpdateTest_analysis_crash_handling.txt | 170 + .../testdata/UpdateTest_diff_alpine.txt | 616 ++ .../testdata/UpdateTest_diff_debian.txt | 64 + .../UpdateTest_diff_last_affected.txt | 78 + .../UpdateTest_diff_last_affected_git.txt | 35 + .../testdata/UpdateTest_diff_maven.txt | 110 + .../UpdateTest_diff_normalized_pypi.txt | 29 + .../testdata/UpdateTest_diff_pypi.txt | 85 + .../testdata/UpdateTest_diff_update.txt | 61 + .../UpdateTest_diff_update_add_fix.txt | 43 + .../testdata/UpdateTest_diff_update_limit.txt | 55 + .../UpdateTest_diff_update_no_introduced.txt | 45 + ...eTest_dont_index_too_many_git_versions.txt | 5067 +++++++++++++++++ .../testdata/UpdateTest_last_affected_git.txt | 66 + .../testdata/UpdateTest_normalized_pypi.txt | 63 + ...pdateTest_normalized_pypi_pubsub_calls.txt | 1 + .../testdata/UpdateTest_pypi_pubsub_calls.txt | 1 + .../UpdateTest_ubuntu_severity_type.txt | 437 ++ .../testdata/UpdateTest_update.txt | 70 + .../testdata/UpdateTest_update_add_fix.txt | 67 + .../testdata/UpdateTest_update_alpine.txt | 689 +++ .../UpdateTest_update_bad_ecosystem_new.txt | 7 + .../testdata/UpdateTest_update_bucket_0.txt | 104 + .../testdata/UpdateTest_update_bucket_1.txt | 50 + .../testdata/UpdateTest_update_bucket_2.txt | 63 + .../testdata/UpdateTest_update_bucket_cve.txt | 152 + .../testdata/UpdateTest_update_debian.txt | 95 + .../UpdateTest_update_last_affected.txt | 129 + .../testdata/UpdateTest_update_limit.txt | 79 + .../testdata/UpdateTest_update_linux.txt | 52 + .../testdata/UpdateTest_update_maven.txt | 100 + .../testdata/UpdateTest_update_new.txt | 67 + .../UpdateTest_update_no_introduced.txt | 67 + ...est_update_partly_bad_ecosystem_delete.txt | 7 + ...teTest_update_partly_bad_ecosystem_new.txt | 65 + .../testdata/UpdateTest_update_pypi.txt | 143 + gcp/workers/oss_fuzz_worker/worker.py | 851 +++ gcp/workers/oss_fuzz_worker/worker_test.py | 1783 ++++++ gcp/workers/recoverer/recoverer.py | 46 +- gcp/workers/recoverer/recoverer_test.py | 26 +- gcp/workers/recoverer/run_tests.sh | 5 +- gcp/workers/worker/poetry.lock | 235 +- gcp/workers/worker/pyproject.toml | 4 +- gcp/workers/worker/run_tests.sh | 5 +- gcp/workers/worker/testdata/GSD-123.yaml | 19 + .../RESTUpdateTest_update_no_introduced.txt | 592 +- .../testdata/UpdateTest_last_affected_git.txt | 76 +- .../testdata/UpdateTest_normalized_pypi.txt | 78 +- ...pdateTest_normalized_pypi_pubsub_calls.txt | 2 +- .../testdata/UpdateTest_pypi_pubsub_calls.txt | 2 +- .../UpdateTest_ubuntu_severity_type.txt | 640 +-- .../worker/testdata/UpdateTest_update.txt | 89 +- .../testdata/UpdateTest_update_alpine.txt | 1195 ++-- .../UpdateTest_update_bad_ecosystem_new.txt | 7 + .../testdata/UpdateTest_update_bucket_0.txt | 131 +- .../testdata/UpdateTest_update_bucket_2.txt | 76 +- .../testdata/UpdateTest_update_bucket_cve.txt | 242 +- .../testdata/UpdateTest_update_debian.txt | 83 +- .../UpdateTest_update_last_affected.txt | 182 +- .../testdata/UpdateTest_update_limit.txt | 103 +- .../testdata/UpdateTest_update_linux.txt | 62 +- .../testdata/UpdateTest_update_maven.txt | 114 +- .../worker/testdata/UpdateTest_update_new.txt | 84 +- .../UpdateTest_update_no_introduced.txt | 84 +- ...est_update_partly_bad_ecosystem_delete.txt | 7 + ...teTest_update_partly_bad_ecosystem_new.txt | 81 +- .../testdata/UpdateTest_update_pypi.txt | 199 +- gcp/workers/worker/worker.py | 350 +- gcp/workers/worker/worker_test.py | 1104 +--- go/cmd/custommetrics/Dockerfile | 4 +- go/cmd/exporter/Dockerfile | 4 +- go/cmd/generatesitemap/Dockerfile | 4 +- go/cmd/gitter/Dockerfile | 2 +- go/cmd/gitter/gitter.go | 107 +- go/cmd/recordchecker/Dockerfile | 4 +- go/cmd/relations/Dockerfile | 4 +- go/go.mod | 54 +- go/go.sum | 120 +- .../models/internal/validate/run_validate.sh | 6 +- osv/cloudbuild.yaml | 2 + osv/ecosystems/_ecosystems.py | 3 + osv/ecosystems/alpine.py | 36 +- osv/ecosystems/alpine_test.py | 18 + .../coarse_version_monotonicity_test.py | 168 + osv/ecosystems/cran.py | 23 +- osv/ecosystems/cran_test.py | 8 + osv/ecosystems/debian.py | 58 +- osv/ecosystems/debian_test.py | 40 + osv/ecosystems/ecosystems_base.py | 173 +- osv/ecosystems/haskell.py | 21 +- osv/ecosystems/haskell_test.py | 10 + osv/ecosystems/maven.py | 31 +- osv/ecosystems/maven_test.py | 14 + osv/ecosystems/nuget.py | 30 +- osv/ecosystems/nuget_test.py | 17 + osv/ecosystems/opam.py | 43 + osv/ecosystems/packagist.py | 50 +- osv/ecosystems/packagist_test.py | 18 + osv/ecosystems/pub.py | 33 +- osv/ecosystems/pub_test.py | 16 + osv/ecosystems/pypi.py | 34 +- osv/ecosystems/pypi_test.py | 14 + osv/ecosystems/redhat.py | 45 +- osv/ecosystems/redhat_test.py | 12 + osv/ecosystems/root.py | 112 +- osv/ecosystems/root_test.py | 170 + osv/ecosystems/rubygems.py | 26 +- osv/ecosystems/rubygems_test.py | 8 + osv/ecosystems/semver_ecosystem_helper.py | 28 +- .../semver_ecosystem_helper_test.py | 25 + osv/ecosystems/ubuntu.py | 16 +- osv/ecosystems/ubuntu_test.py | 47 - osv/models.py | 296 +- osv/models_test.py | 44 +- osv/osv-schema | 2 +- osv/purl_helpers.py | 15 +- osv/purl_helpers_test.py | 40 +- osv/repos.py | 39 +- osv/semver_index.py | 4 +- osv/sources.py | 41 +- osv/third_party/univers/alpine.py | 27 +- osv/third_party/univers/debian.py | 4 +- osv/third_party/univers/gem.py | 4 +- osv/third_party/univers/gentoo.py | 3 + poetry.lock | 272 +- pyproject.toml | 3 +- renovate.json | 79 +- run_tests.sh | 5 +- source.yaml | 2 +- source_test.yaml | 17 +- tools/apitester/README.md | 3 +- .../__snapshots__/cassette_TestCommand.snap | 472 +- .../cassette_TestCommand_CallAnalysis.snap | 6 +- ...cassette_TestCommand_JavareachArchive.snap | 16 +- .../cassette_TestCommand_MoreLockfiles.snap | 6 +- .../cassette_TestCommand_Transitive.snap | 70 +- .../__snapshots__/cassette_single_query.snap | 652 ++- tools/apitester/go.mod | 2 +- tools/apitester/internal/vcr/interactions.go | 4 +- tools/datafix/list_ids_for_source.py | 24 +- tools/datafix/old/README.md | 5 + tools/datafix/{ => old}/delete_bugs.py | 0 tools/datafix/{ => old}/delete_invalid.py | 0 tools/datafix/{ => old}/reput_all.py | 0 tools/datafix/{ => old}/reput_bugs.py | 0 tools/datafix/{ => old}/reput_helper.py | 0 tools/datafix/{ => old}/withdraw_invalid.py | 0 tools/datafix/poetry.lock | 220 +- tools/datafix/pyproject.toml | 2 +- tools/datafix/reimport_gcs_record.py | 60 +- tools/datafix/request_worker_update_record.py | 38 +- tools/datastore-remover/go.mod | 25 +- tools/datastore-remover/go.sum | 50 +- tools/indexer-api-caller/go.mod | 2 +- tools/sourcerepo-sync/run_tests.sh | 5 +- vulnfeeds/build_and_deploy.sh | 8 +- vulnfeeds/cmd/combine-to-osv/Dockerfile | 6 +- vulnfeeds/cmd/combine-to-osv/README.md | 4 +- vulnfeeds/cmd/combine-to-osv/main.go | 14 +- vulnfeeds/cmd/combine-to-osv/main_test.go | 4 +- .../cmd/{ => converters}/alpine/Dockerfile | 8 +- .../{ => converters}/alpine/alpine_secdb.go | 0 .../alpine/fixtures/invalid_versions.txt | 0 .../alpine/fixtures/valid_versions.txt | 0 vulnfeeds/cmd/{ => converters}/alpine/main.go | 5 +- .../alpine/run_alpine_convert.sh | 0 .../cmd/{ => converters}/alpine/verify.go | 0 .../{ => converters}/alpine/verify_test.go | 0 .../cve/cve5/bulk-converter}/Dockerfile | 8 +- .../cve5/bulk-converter}/cna_allowlist.txt | 0 .../cve/cve5/bulk-converter}/main.go | 21 +- .../bulk-converter}/run-cvelist-converter.sh | 2 +- .../cve/cve5/single-converter}/main.go | 9 +- .../cve}/nvd-cve-osv/Dockerfile | 8 +- .../cve}/nvd-cve-osv/README.md | 0 .../{ => converters/cve}/nvd-cve-osv/build.sh | 2 +- .../cmd/converters/cve/nvd-cve-osv/main.go | 136 + .../nvd-cve-osv/run_cve_to_osv_generation.sh | 0 .../cmd/{ => converters}/debian/Dockerfile | 8 +- .../debian/debian_security_tracker.go | 0 vulnfeeds/cmd/{ => converters}/debian/main.go | 5 +- .../cmd/{ => converters}/debian/main_test.go | 14 +- .../debian/run_debian_convert.sh | 0 .../cmd/{ => mirrors}/cpe-repo-gen/Dockerfile | 8 +- .../cmd/{ => mirrors}/cpe-repo-gen/README.md | 0 .../cmd/{ => mirrors}/cpe-repo-gen/build.sh | 0 .../cpe-repo-gen/cpe-repo-gen_map.sh | 0 .../cmd/{ => mirrors}/cpe-repo-gen/main.go | 0 .../debian-copyright-mirror/Dockerfile | 2 +- .../debian-copyright-mirror/build.sh | 0 .../debian-copyright-mirror.py | 0 .../debian-copyright-mirror.sh | 0 .../{ => mirrors}/download-cves/Dockerfile | 8 +- .../cmd/{ => mirrors}/download-cves/main.go | 8 +- .../{ => mirrors}/download-cves/mirror_nvd.sh | 0 vulnfeeds/cmd/nvd-cve-osv/main.go | 486 -- vulnfeeds/cmd/pypi/main.go | 15 +- vulnfeeds/conversion/common.go | 113 + .../{cvelist2osv => conversion}/grouping.go | 6 +- .../grouping_test.go | 4 +- vulnfeeds/conversion/nvd/converter.go | 349 ++ vulnfeeds/cvelist2osv/common.go | 94 +- vulnfeeds/cvelist2osv/common_test.go | 6 +- vulnfeeds/cvelist2osv/converter.go | 144 +- vulnfeeds/cvelist2osv/converter_test.go | 145 +- vulnfeeds/cvelist2osv/default_extractor.go | 27 +- vulnfeeds/cvelist2osv/extraction.go | 6 +- vulnfeeds/cvelist2osv/linux_extractor.go | 18 +- vulnfeeds/cvelist2osv/strategies.go | 16 +- .../cvelist2osv/version_extraction_test.go | 59 +- ...eVPRepoCache_Test_with_an_empty_cache.yaml | 54 - ...with_an_empty_cache_adding_two_values.yaml | 105 - ...RepoCache_Test_with_an_existing_cache.yaml | 54 - ...eUpdateVPRepoCache_Test_with_no_cache.yaml | 3 - ..._MaybeUpdate_Test_with_an_empty_cache.yaml | 54 + ...with_an_empty_cache_adding_two_values.yaml | 105 + ..._an_empty_cache_and_an_unusable_repo.yaml} | 6 +- ...ybeUpdate_Test_with_an_existing_cache.yaml | 54 + vulnfeeds/cves/versions.go | 167 +- vulnfeeds/cves/versions_test.go | 219 +- vulnfeeds/git/repository.go | 41 +- vulnfeeds/git/repository_test.go | 17 +- vulnfeeds/git/versions_test.go | 4 +- vulnfeeds/go.mod | 36 +- vulnfeeds/go.sum | 72 +- vulnfeeds/{cves => models}/cve.go | 4 +- vulnfeeds/models/metrics.go | 93 + vulnfeeds/{cves => models}/nvd2.go | 12 +- vulnfeeds/models/types.go | 2 +- vulnfeeds/pypi/pypi.go | 10 +- vulnfeeds/tools/debian/Dockerfile | 2 +- .../tools/debian/debian_converter/poetry.lock | 168 +- vulnfeeds/vulns/vulns.go | 43 +- vulnfeeds/vulns/vulns_test.go | 25 +- 345 files changed, 27622 insertions(+), 8363 deletions(-) create mode 100644 deployment/clouddeploy/oss-fuzz-workers/clouddeploy.yaml create mode 100644 deployment/clouddeploy/oss-fuzz-workers/importer.yaml rename deployment/clouddeploy/{gke-workers/environments/oss-vdb => oss-fuzz-workers}/make-bugs-public.yaml (100%) rename deployment/clouddeploy/{gke-workers/environments/oss-vdb => oss-fuzz-workers}/process-results.yaml (100%) create mode 100644 deployment/clouddeploy/oss-fuzz-workers/scaler.yaml create mode 100644 deployment/clouddeploy/oss-fuzz-workers/skaffold.yaml create mode 100644 deployment/clouddeploy/oss-fuzz-workers/workers.yaml create mode 100644 deployment/terraform/modules/oss_fuzz/main.tf create mode 100644 deployment/terraform/modules/oss_fuzz/outputs.tf create mode 100644 deployment/terraform/modules/oss_fuzz/variables.tf create mode 100644 gcp/api/run_apitester.py create mode 100755 gcp/api/run_tests_e2e.sh create mode 100644 gcp/website/blog/content/posts/2025-in-review/index.md create mode 100644 gcp/website/blog/content/posts/2025-in-review/star-history-202616.png create mode 100644 gcp/workers/oss_fuzz_importer/Dockerfile create mode 100755 gcp/workers/oss_fuzz_importer/importer.py create mode 100644 gcp/workers/oss_fuzz_importer/importer_test.py create mode 100755 gcp/workers/oss_fuzz_importer/run_tests.sh create mode 120000 gcp/workers/oss_fuzz_importer/testdata create mode 100644 gcp/workers/oss_fuzz_worker/Dockerfile create mode 100644 gcp/workers/oss_fuzz_worker/oss_fuzz.py create mode 120000 gcp/workers/oss_fuzz_worker/osv-test create mode 100644 gcp/workers/oss_fuzz_worker/poetry.lock create mode 100644 gcp/workers/oss_fuzz_worker/pyproject.toml create mode 100755 gcp/workers/oss_fuzz_worker/run_tests.sh create mode 100644 gcp/workers/oss_fuzz_worker/testdata/CVE-2022-27449.json create mode 100644 gcp/workers/oss_fuzz_worker/testdata/DSA-3029-1.json create mode 100644 gcp/workers/oss_fuzz_worker/testdata/GHSA-838r-hvwh-24h8.json create mode 100644 gcp/workers/oss_fuzz_worker/testdata/GSD-123.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/ImpactTest_basic.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/ImpactTest_fixed_range_too_long.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/ImpactTest_not_fixed.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/ImpactTest_range.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/ImpactTest_simplify_range.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/ImpactTest_zero_regression_range.txt rename gcp/workers/{worker => oss_fuzz_worker}/testdata/LINUX-123.yaml (100%) create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-123.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-124.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-125.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-126.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-127.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-128.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-129.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-130.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-131.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/OSV-TEST-last-affected-01.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/PYSEC-123.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/PYSEC-124.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/PYSEC-456.yaml create mode 100644 gcp/workers/oss_fuzz_worker/testdata/RESTUpdateTest_update_no_introduced.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UBUNTU-CVE-2025-38094.json create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_analysis_crash_handling.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_alpine.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_debian.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected_git.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_maven.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_normalized_pypi.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_pypi.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_add_fix.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_limit.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_no_introduced.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_dont_index_too_many_git_versions.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_last_affected_git.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_pypi_pubsub_calls.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_ubuntu_severity_type.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_add_fix.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_alpine.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bad_ecosystem_new.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_0.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_1.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_2.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_cve.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_debian.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_last_affected.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_limit.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_linux.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_maven.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_new.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_no_introduced.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt create mode 100644 gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_pypi.txt create mode 100644 gcp/workers/oss_fuzz_worker/worker.py create mode 100644 gcp/workers/oss_fuzz_worker/worker_test.py create mode 100644 gcp/workers/worker/testdata/GSD-123.yaml create mode 100644 gcp/workers/worker/testdata/UpdateTest_update_bad_ecosystem_new.txt create mode 100644 gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt create mode 100644 osv/ecosystems/coarse_version_monotonicity_test.py create mode 100644 osv/ecosystems/opam.py create mode 100644 osv/ecosystems/root_test.py delete mode 100644 osv/ecosystems/ubuntu_test.py create mode 100644 tools/datafix/old/README.md rename tools/datafix/{ => old}/delete_bugs.py (100%) rename tools/datafix/{ => old}/delete_invalid.py (100%) rename tools/datafix/{ => old}/reput_all.py (100%) rename tools/datafix/{ => old}/reput_bugs.py (100%) rename tools/datafix/{ => old}/reput_helper.py (100%) rename tools/datafix/{ => old}/withdraw_invalid.py (100%) rename vulnfeeds/cmd/{ => converters}/alpine/Dockerfile (75%) rename vulnfeeds/cmd/{ => converters}/alpine/alpine_secdb.go (100%) rename vulnfeeds/cmd/{ => converters}/alpine/fixtures/invalid_versions.txt (100%) rename vulnfeeds/cmd/{ => converters}/alpine/fixtures/valid_versions.txt (100%) rename vulnfeeds/cmd/{ => converters}/alpine/main.go (97%) rename vulnfeeds/cmd/{ => converters}/alpine/run_alpine_convert.sh (100%) rename vulnfeeds/cmd/{ => converters}/alpine/verify.go (100%) rename vulnfeeds/cmd/{ => converters}/alpine/verify_test.go (100%) rename vulnfeeds/cmd/{cve-bulk-converter => converters/cve/cve5/bulk-converter}/Dockerfile (73%) rename vulnfeeds/cmd/{cve-bulk-converter => converters/cve/cve5/bulk-converter}/cna_allowlist.txt (100%) rename vulnfeeds/cmd/{cve-bulk-converter => converters/cve/cve5/bulk-converter}/main.go (88%) rename vulnfeeds/cmd/{cve-bulk-converter => converters/cve/cve5/bulk-converter}/run-cvelist-converter.sh (98%) rename vulnfeeds/cmd/{cve-single-converter => converters/cve/cve5/single-converter}/main.go (86%) rename vulnfeeds/cmd/{ => converters/cve}/nvd-cve-osv/Dockerfile (68%) rename vulnfeeds/cmd/{ => converters/cve}/nvd-cve-osv/README.md (100%) rename vulnfeeds/cmd/{ => converters/cve}/nvd-cve-osv/build.sh (93%) create mode 100644 vulnfeeds/cmd/converters/cve/nvd-cve-osv/main.go rename vulnfeeds/cmd/{ => converters/cve}/nvd-cve-osv/run_cve_to_osv_generation.sh (100%) rename vulnfeeds/cmd/{ => converters}/debian/Dockerfile (76%) rename vulnfeeds/cmd/{ => converters}/debian/debian_security_tracker.go (100%) rename vulnfeeds/cmd/{ => converters}/debian/main.go (97%) rename vulnfeeds/cmd/{ => converters}/debian/main_test.go (95%) rename vulnfeeds/cmd/{ => converters}/debian/run_debian_convert.sh (100%) rename vulnfeeds/cmd/{ => mirrors}/cpe-repo-gen/Dockerfile (74%) rename vulnfeeds/cmd/{ => mirrors}/cpe-repo-gen/README.md (100%) rename vulnfeeds/cmd/{ => mirrors}/cpe-repo-gen/build.sh (100%) rename vulnfeeds/cmd/{ => mirrors}/cpe-repo-gen/cpe-repo-gen_map.sh (100%) rename vulnfeeds/cmd/{ => mirrors}/cpe-repo-gen/main.go (100%) rename vulnfeeds/cmd/{ => mirrors}/debian-copyright-mirror/Dockerfile (91%) rename vulnfeeds/cmd/{ => mirrors}/debian-copyright-mirror/build.sh (100%) rename vulnfeeds/cmd/{ => mirrors}/debian-copyright-mirror/debian-copyright-mirror.py (100%) rename vulnfeeds/cmd/{ => mirrors}/debian-copyright-mirror/debian-copyright-mirror.sh (100%) rename vulnfeeds/cmd/{ => mirrors}/download-cves/Dockerfile (75%) rename vulnfeeds/cmd/{ => mirrors}/download-cves/main.go (97%) rename vulnfeeds/cmd/{ => mirrors}/download-cves/mirror_nvd.sh (100%) delete mode 100644 vulnfeeds/cmd/nvd-cve-osv/main.go create mode 100644 vulnfeeds/conversion/common.go rename vulnfeeds/{cvelist2osv => conversion}/grouping.go (97%) rename vulnfeeds/{cvelist2osv => conversion}/grouping_test.go (99%) create mode 100644 vulnfeeds/conversion/nvd/converter.go delete mode 100644 vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache.yaml delete mode 100644 vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_adding_two_values.yaml delete mode 100644 vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_existing_cache.yaml delete mode 100644 vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_no_cache.yaml create mode 100644 vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache.yaml create mode 100644 vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache_adding_two_values.yaml rename vulnfeeds/cves/testdata/{Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_and_an_unusable_repo.yaml => Test_MaybeUpdate_Test_with_an_empty_cache_and_an_unusable_repo.yaml} (90%) create mode 100644 vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_existing_cache.yaml rename vulnfeeds/{cves => models}/cve.go (98%) create mode 100644 vulnfeeds/models/metrics.go rename vulnfeeds/{cves => models}/nvd2.go (99%) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 03c5e405d02..13770309c7b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,11 +39,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@45c373516f557556c15d420e3f5e0aa3d64366bc # v3.31.9 + uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -54,7 +54,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@45c373516f557556c15d420e3f5e0aa3d64366bc # v3.31.9 + uses: github/codeql-action/autobuild@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -68,4 +68,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@45c373516f557556c15d420e3f5e0aa3d64366bc # v3.31.9 + uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml index 713a2b1aebc..21ae3b26e5c 100644 --- a/.github/workflows/links.yml +++ b/.github/workflows/links.yml @@ -20,7 +20,7 @@ jobs: contents: read # to fetch code (actions/checkout) runs-on: ubuntu-latest steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: tcort/github-action-markdown-link-check@e7c7a18363c842693fadde5d41a3bd3573a7a225 # v1.1.2 with: use-quiet-mode: "yes" diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index c8afb147baa..4dfb5f0f5e2 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -28,7 +28,7 @@ jobs: filenames: runs-on: ubuntu-latest steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - run: | @@ -40,9 +40,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.13' - name: Install poetry @@ -50,7 +50,7 @@ jobs: - name: Set up poetry run: poetry install - name: Set up Go - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version: '>=1.23.6' - name: Set up terraform diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 4e01978bf93..2d53d54811f 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -30,6 +30,6 @@ jobs: name: Validate PR title runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3 + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish-to-pypi.yaml b/.github/workflows/publish-to-pypi.yaml index c10f08075ea..aec8c261883 100644 --- a/.github/workflows/publish-to-pypi.yaml +++ b/.github/workflows/publish-to-pypi.yaml @@ -24,12 +24,12 @@ jobs: name: Publish runs-on: ubuntu-latest steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 submodules: recursive - name: Set up Python 3 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.13 - name: Install pypa/build diff --git a/.github/workflows/renovate-validator.yml b/.github/workflows/renovate-validator.yml index 22edf2e377e..7430f171d3a 100644 --- a/.github/workflows/renovate-validator.yml +++ b/.github/workflows/renovate-validator.yml @@ -17,10 +17,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Nodes.js - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: '^24' diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8efd42c2294..3b1c7912d97 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -22,7 +22,7 @@ jobs: id-token: write steps: - name: "Checkout code" - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -42,7 +42,7 @@ jobs: # Upload the results as artifacts (optional). - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: SARIF file path: results.sarif @@ -50,6 +50,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@45c373516f557556c15d420e3f5e0aa3d64366bc # v3.31.9 + uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: sarif_file: results.sarif diff --git a/.github/workflows/snapshots.yml b/.github/workflows/snapshots.yml index 66a0dd746ea..e78078ef0d9 100644 --- a/.github/workflows/snapshots.yml +++ b/.github/workflows/snapshots.yml @@ -21,10 +21,10 @@ jobs: pull-requests: write # Create pull requests runs-on: ubuntu-latest steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version: stable check-latest: true @@ -33,7 +33,7 @@ jobs: env: OSV_API_BASE_URL: api.test.osv.dev UPDATE_SNAPS: always - - uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 + - uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: token: ${{ secrets.PR_TOKEN_BOT }} title: "test: update apitester snapshots" diff --git a/.github/workflows/staleness.yml b/.github/workflows/staleness.yml index fc7b25bd2c2..347adf7164f 100644 --- a/.github/workflows/staleness.yml +++ b/.github/workflows/staleness.yml @@ -13,7 +13,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 + - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 with: days-before-stale: 60 days-before-close: 14 diff --git a/.gitignore b/.gitignore index 1b44107bde5..2d896a85840 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ hurl-scripts/ temp/* **/tmp/** gcp/api/v1/osv/** +.hypothesis \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14da6bd5ef1..e6efd4f909f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -142,6 +142,17 @@ gcloud auth login --update-adc make run-api-server ``` +#### API E2E Snapshots + +If you have made any changes to the API, please update the API query snapshots with + +```shell +gcloud auth login --update-adc +make update-api-snapshots +``` + +and check the git diff to see if the API result changes are expected. + ### Making commits Please follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification for commit messages. This helps us to automate processes like changelog generation and ensures a clear and consistent commit history. diff --git a/Makefile b/Makefile index bfd4e43a4c6..d54021b227a 100644 --- a/Makefile +++ b/Makefile @@ -47,9 +47,15 @@ api-server-tests: test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth login --update-adc'"; exit 1) cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest . cd gcp/api && ./run_tests.sh $(HOME)/.config/gcloud/application_default_credentials.json + cd gcp/api && ./run_tests_e2e.sh $(HOME)/.config/gcloud/application_default_credentials.json + +update-api-snapshots: + test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth login --update-adc'"; exit 1) + cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest . + cd gcp/api && UPDATE_SNAPS=true ./run_tests_e2e.sh $(HOME)/.config/gcloud/application_default_credentials.json lint: - GOTOOLCHAIN=go1.25.5 $(run-cmd) tools/lint_and_format.sh + GOTOOLCHAIN=go1.25.6 $(run-cmd) tools/lint_and_format.sh build-osv-protos: cd osv && $(run-cmd) python -m grpc_tools.protoc --python_out=. --mypy_out=. --proto_path=. --proto_path=osv-schema/proto vulnerability.proto importfinding.proto diff --git a/bindings/go/go.mod b/bindings/go/go.mod index 8896c48ba6a..6b0d87ee9e3 100644 --- a/bindings/go/go.mod +++ b/bindings/go/go.mod @@ -1,19 +1,19 @@ module osv.dev/bindings/go -go 1.25.5 +go 1.25.6 require ( github.com/google/go-cmp v0.7.0 - github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae - golang.org/x/sync v0.18.0 - google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b - google.golang.org/grpc v1.77.0 + github.com/ossf/osv-schema/bindings/go v0.0.0-20260128001339-9d03e8f4632b + golang.org/x/sync v0.19.0 + google.golang.org/genproto/googleapis/api v0.0.0-20260128004102-de31872fb2ec + google.golang.org/grpc v1.78.0 ) require ( - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.30.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d // indirect google.golang.org/protobuf v1.36.11 ) diff --git a/bindings/go/go.sum b/bindings/go/go.sum index 6271936e47c..54678b3ee7c 100644 --- a/bindings/go/go.sum +++ b/bindings/go/go.sum @@ -8,8 +8,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae h1:nvfTerE/hSYc/TQ3JUZYeL7DuVhjPkBeOGxicPzoJmc= -github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae/go.mod h1:Eo7R19vlnflsCRdHW1ynyNUyoRwxdaTmTWD9MtKnJTc= +github.com/ossf/osv-schema/bindings/go v0.0.0-20260128001339-9d03e8f4632b h1:xoaQGKeEQccRHVY7wJz1NJR1S7ViBM1nKeN5Ck0t4r8= +github.com/ossf/osv-schema/bindings/go v0.0.0-20260128001339-9d03e8f4632b/go.mod h1:Eo7R19vlnflsCRdHW1ynyNUyoRwxdaTmTWD9MtKnJTc= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= @@ -22,21 +22,21 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6 go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E= -google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/genproto/googleapis/api v0.0.0-20260128004102-de31872fb2ec h1:enb0nUQ3SSTFHfDh583KVk3pNunrbyfmtw9JSYY4LTA= +google.golang.org/genproto/googleapis/api v0.0.0-20260128004102-de31872fb2ec/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d h1:xXzuihhT3gL/ntduUZwHECzAn57E8dA6l8SOtYWdD8Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/bindings/go/osvdev/osvdev_test.go b/bindings/go/osvdev/osvdev_test.go index feb4d45ac82..88a38ca2b76 100644 --- a/bindings/go/osvdev/osvdev_test.go +++ b/bindings/go/osvdev/osvdev_test.go @@ -220,7 +220,7 @@ func TestOSVClient_QueryBatchDeadline(t *testing.T) { c := osvdev.DefaultClient() c.Config.UserAgent = "osv-scanner-api-test" - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*1)) + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Millisecond*100)) got, err := c.QueryBatch(ctx, tt.queries) cancel() diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 2b5efa3ab3d..79a2e53670f 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -34,7 +34,8 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:slim' id: 'api-tests' - args: ['gcloud', 'builds', 'submit', '--region=${LOCATION}', '--config=gcp/api/cloudbuild.yaml', '.'] + # Need custom service account for api tests access to oss-vdb-test datastore + args: ['gcloud', 'builds', 'submit', '--region=${LOCATION}', '--config=gcp/api/cloudbuild.yaml', '--service-account=projects/oss-vdb/serviceAccounts/api-e2e-tester@oss-vdb.iam.gserviceaccount.com', '.'] waitFor: ['init'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:slim' diff --git a/deployment/build-and-stage.yaml b/deployment/build-and-stage.yaml index 35f03e9fa14..9a686a9de4b 100644 --- a/deployment/build-and-stage.yaml +++ b/deployment/build-and-stage.yaml @@ -89,6 +89,23 @@ steps: args: ['push', '--all-tags', 'gcr.io/oss-vdb/recoverer'] waitFor: ['build-recoverer', 'cloud-build-queue'] +- name: gcr.io/cloud-builders/docker + args: ['build', '-t', 'gcr.io/oss-vdb/oss-fuzz-worker:latest', '-t', 'gcr.io/oss-vdb/oss-fuzz-worker:$COMMIT_SHA', '-f', 'gcp/workers/oss_fuzz_worker/Dockerfile', '.'] + id: 'build-oss-fuzz-worker' + waitFor: ['build-worker-base'] +- name: gcr.io/cloud-builders/docker + args: ['push', '--all-tags', 'gcr.io/oss-vdb/oss-fuzz-worker'] + waitFor: ['build-oss-fuzz-worker', 'cloud-build-queue'] + +- name: gcr.io/cloud-builders/docker + args: ['build', '-t', 'gcr.io/oss-vdb/oss-fuzz-importer:latest', '-t', 'gcr.io/oss-vdb/oss-fuzz-importer:$COMMIT_SHA', '.'] + dir: 'gcp/workers/oss_fuzz_importer' + id: 'build-oss-fuzz-importer' + waitFor: ['build-oss-fuzz-worker'] +- name: gcr.io/cloud-builders/docker + args: ['push', '--all-tags', 'gcr.io/oss-vdb/oss-fuzz-importer'] + waitFor: ['build-oss-fuzz-importer', 'cloud-build-queue'] + # Build/push go images - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' @@ -211,7 +228,7 @@ steps: id: 'pull-alpine-cve-convert' waitFor: ['setup'] - name: gcr.io/cloud-builders/docker - args: ['build', '-t', 'gcr.io/oss-vdb/alpine-cve-convert:latest', '-t', 'gcr.io/oss-vdb/alpine-cve-convert:$COMMIT_SHA', '-f', 'cmd/alpine/Dockerfile', '--cache-from', 'gcr.io/oss-vdb/alpine-cve-convert:latest', '--pull', '.'] + args: ['build', '-t', 'gcr.io/oss-vdb/alpine-cve-convert:latest', '-t', 'gcr.io/oss-vdb/alpine-cve-convert:$COMMIT_SHA', '-f', 'cmd/converters/alpine/Dockerfile', '--cache-from', 'gcr.io/oss-vdb/alpine-cve-convert:latest', '--pull', '.'] dir: 'vulnfeeds' id: 'build-alpine-cve-convert' waitFor: ['pull-alpine-cve-convert'] @@ -225,7 +242,7 @@ steps: id: 'pull-debian-cve-convert' waitFor: ['setup'] - name: gcr.io/cloud-builders/docker - args: ['build', '-t', 'gcr.io/oss-vdb/debian-cve-convert:latest', '-t', 'gcr.io/oss-vdb/debian-cve-convert:$COMMIT_SHA', '-f', 'cmd/debian/Dockerfile', '--cache-from', 'gcr.io/oss-vdb/debian-cve-convert:latest', '--pull', '.'] + args: ['build', '-t', 'gcr.io/oss-vdb/debian-cve-convert:latest', '-t', 'gcr.io/oss-vdb/debian-cve-convert:$COMMIT_SHA', '-f', 'cmd/converters/debian/Dockerfile', '--cache-from', 'gcr.io/oss-vdb/debian-cve-convert:latest', '--pull', '.'] dir: 'vulnfeeds' id: 'build-debian-cve-convert' waitFor: ['pull-debian-cve-convert'] @@ -253,7 +270,7 @@ steps: id: 'pull-cve5-to-osv' waitFor: ['setup'] - name: gcr.io/cloud-builders/docker - args: ['build', '-t', 'gcr.io/oss-vdb/cve5-to-osv:latest', '-t', 'gcr.io/oss-vdb/cve5-to-osv:$COMMIT_SHA', '-f', 'cmd/cve-bulk-converter/Dockerfile', '--cache-from', 'gcr.io/oss-vdb/cve5-to-osv:latest', '--pull', '.'] + args: ['build', '-t', 'gcr.io/oss-vdb/cve5-to-osv:latest', '-t', 'gcr.io/oss-vdb/cve5-to-osv:$COMMIT_SHA', '-f', 'cmd/converters/cve/cve5/bulk-converter/Dockerfile', '--cache-from', 'gcr.io/oss-vdb/cve5-to-osv:latest', '--pull', '.'] dir: 'vulnfeeds' id: 'build-cve5-to-osv' waitFor: ['pull-cve5-to-osv'] @@ -297,7 +314,7 @@ steps: # Build/push Debian copyright mirror image - name: gcr.io/cloud-builders/docker args: ['build', '-t', 'gcr.io/oss-vdb/debian-copyright-mirror:latest', '-t', 'gcr.io/oss-vdb/debian-copyright-mirror:$COMMIT_SHA', '.'] - dir: 'vulnfeeds/cmd/debian-copyright-mirror' + dir: 'vulnfeeds/cmd/mirrors/debian-copyright-mirror' id: 'build-debian-copyright-mirror' waitFor: ['setup'] - name: gcr.io/cloud-builders/docker @@ -306,7 +323,7 @@ steps: # Build/push CPE repo map generating image - name: gcr.io/cloud-builders/docker - args: ['build', '-t', 'gcr.io/oss-vdb/cpe-repo-gen:latest', '-t', 'gcr.io/oss-vdb/cpe-repo-gen:$COMMIT_SHA', '-f', 'cmd/cpe-repo-gen/Dockerfile','.'] + args: ['build', '-t', 'gcr.io/oss-vdb/cpe-repo-gen:latest', '-t', 'gcr.io/oss-vdb/cpe-repo-gen:$COMMIT_SHA', '-f', 'cmd/mirrors/cpe-repo-gen/Dockerfile','.'] dir: 'vulnfeeds' id: 'build-cpe-repo-gen' waitFor: ['setup'] @@ -316,7 +333,7 @@ steps: # Build/push NVD CVE to OSV conversion image - name: gcr.io/cloud-builders/docker - args: ['build', '-t', 'gcr.io/oss-vdb/nvd-cve-osv:latest', '-t', 'gcr.io/oss-vdb/nvd-cve-osv:$COMMIT_SHA', '-f', 'cmd/nvd-cve-osv/Dockerfile','.'] + args: ['build', '-t', 'gcr.io/oss-vdb/nvd-cve-osv:latest', '-t', 'gcr.io/oss-vdb/nvd-cve-osv:$COMMIT_SHA', '-f', 'cmd/converters/cve/nvd-cve-osv/Dockerfile','.'] dir: 'vulnfeeds' id: 'build-nvd-cve-osv' waitFor: ['setup'] @@ -344,7 +361,7 @@ steps: # Build/push NVD mirror image - name: gcr.io/cloud-builders/docker - args: ['build', '-t', 'gcr.io/oss-vdb/nvd-mirror:latest', '-t', 'gcr.io/oss-vdb/nvd-mirror:$COMMIT_SHA', '-f', 'cmd/download-cves/Dockerfile','.'] + args: ['build', '-t', 'gcr.io/oss-vdb/nvd-mirror:latest', '-t', 'gcr.io/oss-vdb/nvd-mirror:$COMMIT_SHA', '-f', 'cmd/mirrors/download-cves/Dockerfile','.'] dir: 'vulnfeeds' id: 'build-nvd-mirror' waitFor: ['setup'] @@ -372,7 +389,6 @@ steps: exporter=gcr.io/oss-vdb/exporter:$COMMIT_SHA,\ staging-api-test=gcr.io/oss-vdb-test/staging-api-test:$COMMIT_SHA,\ osv-linter=gcr.io/oss-vdb-test/osv-linter:$COMMIT_SHA,\ - cron=gcr.io/oss-vdb/cron:$COMMIT_SHA,\ debian-convert=gcr.io/oss-vdb/debian-convert:$COMMIT_SHA,\ combine-to-osv=gcr.io/oss-vdb/combine-to-osv:$COMMIT_SHA,\ alpine-cve-convert=gcr.io/oss-vdb/alpine-cve-convert:$COMMIT_SHA,\ @@ -387,7 +403,8 @@ steps: custommetrics=gcr.io/oss-vdb/custommetrics:$COMMIT_SHA,\ relations=gcr.io/oss-vdb/relations:$COMMIT_SHA,\ generatesitemap=gcr.io/oss-vdb/generatesitemap:$COMMIT_SHA,\ - gitter=gcr.io/oss-vdb/gitter:$COMMIT_SHA" + gitter=gcr.io/oss-vdb/gitter:$COMMIT_SHA,\ + cron=gcr.io/oss-vdb/cron:$COMMIT_SHA" ] dir: deployment/clouddeploy/gke-workers @@ -447,5 +464,7 @@ images: - 'gcr.io/oss-vdb/record-checker:$COMMIT_SHA' - 'gcr.io/oss-vdb/custommetrics:$COMMIT_SHA' - 'gcr.io/oss-vdb/relations:$COMMIT_SHA' +- 'gcr.io/oss-vdb/oss-fuzz-worker:$COMMIT_SHA' +- 'gcr.io/oss-vdb/oss-fuzz-importer:$COMMIT_SHA' - 'gcr.io/oss-vdb/generatesitemap:$COMMIT_SHA' - 'gcr.io/oss-vdb/gitter:$COMMIT_SHA' diff --git a/deployment/clouddeploy/gke-workers/base/gitter.yaml b/deployment/clouddeploy/gke-workers/base/gitter.yaml index 8f8b2ff809d..b89b5077649 100644 --- a/deployment/clouddeploy/gke-workers/base/gitter.yaml +++ b/deployment/clouddeploy/gke-workers/base/gitter.yaml @@ -5,10 +5,7 @@ metadata: spec: replicas: 1 strategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 1 - maxSurge: 1 + type: Recreate selector: matchLabels: name: gitter @@ -17,6 +14,7 @@ spec: labels: name: gitter spec: + terminationGracePeriodSeconds: 60 tolerations: - key: workloadType operator: Equal diff --git a/deployment/clouddeploy/gke-workers/base/importer.yaml b/deployment/clouddeploy/gke-workers/base/importer.yaml index 6973271bc3c..d073fc0fa07 100644 --- a/deployment/clouddeploy/gke-workers/base/importer.yaml +++ b/deployment/clouddeploy/gke-workers/base/importer.yaml @@ -30,10 +30,10 @@ spec: resources: requests: cpu: "1" - memory: "8G" + memory: "24G" limits: - cpu: "1" - memory: "16G" + cpu: "2" + memory: "32G" nodeSelector: cloud.google.com/gke-nodepool: importer-pool restartPolicy: Never diff --git a/deployment/clouddeploy/gke-workers/environments/oss-vdb/kustomization.yaml b/deployment/clouddeploy/gke-workers/environments/oss-vdb/kustomization.yaml index 701f5e6b8fa..fb1adb7c072 100644 --- a/deployment/clouddeploy/gke-workers/environments/oss-vdb/kustomization.yaml +++ b/deployment/clouddeploy/gke-workers/environments/oss-vdb/kustomization.yaml @@ -1,7 +1,5 @@ resources: - ../../base -- make-bugs-public.yaml -- process-results.yaml patches: - path: workers.yaml - path: importer.yaml diff --git a/deployment/clouddeploy/oss-fuzz-workers/clouddeploy.yaml b/deployment/clouddeploy/oss-fuzz-workers/clouddeploy.yaml new file mode 100644 index 00000000000..6c65554dba0 --- /dev/null +++ b/deployment/clouddeploy/oss-fuzz-workers/clouddeploy.yaml @@ -0,0 +1,23 @@ +apiVersion: deploy.cloud.google.com/v1 +kind: DeliveryPipeline +metadata: + name: oss-fuzz-workers +description: oss-fuzz worker and importer pipeline +serialPipeline: + stages: + - targetId: production-oss-fuzz-workers + profiles: [ prod ] +--- + +apiVersion: deploy.cloud.google.com/v1 +kind: Target +metadata: + name: production-oss-fuzz-workers +description: oss-vdb oss-fuzz worker cluster +gke: + cluster: projects/oss-vdb/locations/us-central1-f/clusters/oss-fuzz-workers +executionConfigs: +- usages: + - RENDER + - DEPLOY + serviceAccount: deployment@oss-vdb.iam.gserviceaccount.com diff --git a/deployment/clouddeploy/oss-fuzz-workers/importer.yaml b/deployment/clouddeploy/oss-fuzz-workers/importer.yaml new file mode 100644 index 00000000000..84d5118e4e8 --- /dev/null +++ b/deployment/clouddeploy/oss-fuzz-workers/importer.yaml @@ -0,0 +1,54 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: importer + labels: + cronLastSuccessfulTimeMins: "90" +spec: + schedule: "*/15 * * * *" + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + spec: + containers: + - name: importer + image: importer + imagePullPolicy: Always + env: + - name: GOOGLE_CLOUD_PROJECT + value: oss-vdb + - name: OSV_VULNERABILITIES_BUCKET + value: osv-vulnerabilities + args: + - "--ssh_key_public=/secrets/ssh.pub" + - "--ssh_key_private=/secrets/ssh" + - "--public_log_bucket=osv-public-import-logs" + volumeMounts: + - mountPath: "/work" + name: "ssd" + - mountPath: "/secrets" + name: "secrets" + securityContext: + privileged: true + resources: + requests: + cpu: "1" + memory: "8G" + limits: + cpu: "1" + memory: "16G" + restartPolicy: Never + volumes: + - name: "ssd" + hostPath: + path: "/mnt/disks/ssd0" + - name: secrets + secret: + items: + - key: ssh + mode: 384 + path: ssh + - key: ssh.pub + path: ssh.pub + secretName: secrets diff --git a/deployment/clouddeploy/gke-workers/environments/oss-vdb/make-bugs-public.yaml b/deployment/clouddeploy/oss-fuzz-workers/make-bugs-public.yaml similarity index 100% rename from deployment/clouddeploy/gke-workers/environments/oss-vdb/make-bugs-public.yaml rename to deployment/clouddeploy/oss-fuzz-workers/make-bugs-public.yaml diff --git a/deployment/clouddeploy/gke-workers/environments/oss-vdb/process-results.yaml b/deployment/clouddeploy/oss-fuzz-workers/process-results.yaml similarity index 100% rename from deployment/clouddeploy/gke-workers/environments/oss-vdb/process-results.yaml rename to deployment/clouddeploy/oss-fuzz-workers/process-results.yaml diff --git a/deployment/clouddeploy/oss-fuzz-workers/scaler.yaml b/deployment/clouddeploy/oss-fuzz-workers/scaler.yaml new file mode 100644 index 00000000000..b81c1d13689 --- /dev/null +++ b/deployment/clouddeploy/oss-fuzz-workers/scaler.yaml @@ -0,0 +1,47 @@ +# Copyright 2026 Google LLC +# +# 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. + +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: pubsub +spec: + minReplicas: 1 + maxReplicas: 400 + metrics: + - external: + metric: + name: pubsub.googleapis.com|subscription|num_undelivered_messages + selector: + matchLabels: + resource.labels.subscription_id: oss-fuzz-tasks + target: + type: AverageValue + averageValue: 1 + type: External + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: workers + behavior: + scaleUp: + stabilizationWindowSeconds: 0 + policies: + - type: Percent + value: 10 + periodSeconds: 300 + - type: Pods + value: 20 + periodSeconds: 300 + selectPolicy: Max diff --git a/deployment/clouddeploy/oss-fuzz-workers/skaffold.yaml b/deployment/clouddeploy/oss-fuzz-workers/skaffold.yaml new file mode 100644 index 00000000000..11dd51be8db --- /dev/null +++ b/deployment/clouddeploy/oss-fuzz-workers/skaffold.yaml @@ -0,0 +1,16 @@ +apiVersion: skaffold/v3 +kind: Config +metadata: + name: oss-fuzz-workers +profiles: +- name: prod + manifests: + rawYaml: + - importer.yaml + - workers.yaml + - make-bugs-public.yaml + - process-results.yaml + - scaler.yaml + +deploy: + kubectl: {} diff --git a/deployment/clouddeploy/oss-fuzz-workers/workers.yaml b/deployment/clouddeploy/oss-fuzz-workers/workers.yaml new file mode 100644 index 00000000000..25e4961e52f --- /dev/null +++ b/deployment/clouddeploy/oss-fuzz-workers/workers.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: workers +spec: + replicas: 1 + selector: + matchLabels: + name: worker-private + template: + metadata: + labels: + name: worker-private + spec: + containers: + - name: worker-private + image: worker + imagePullPolicy: Always + env: + - name: GOOGLE_CLOUD_PROJECT + value: oss-vdb + - name: OSV_VULNERABILITIES_BUCKET + value: osv-vulnerabilities + args: + - "--ssh_key_public=/secrets/ssh.pub" + - "--ssh_key_private=/secrets/ssh" + - "--redis_host=10.102.25.213" + volumeMounts: + - mountPath: "/work" + name: "ssd" + - mountPath: "/secrets" + name: "secrets" + securityContext: + privileged: true + resources: + requests: + cpu: 1 + memory: "10G" + limits: + cpu: 2 + memory: "13G" + volumes: + - name: "ssd" + hostPath: + path: "/mnt/disks/ssd0" + - name: secrets + secret: + secretName: secrets + items: + - key: ssh + path: ssh + mode: 0600 + - key: ssh.pub + path: ssh.pub diff --git a/deployment/deploy-prod.yaml b/deployment/deploy-prod.yaml index c48cc7bbd0f..b67c8ac2660 100644 --- a/deployment/deploy-prod.yaml +++ b/deployment/deploy-prod.yaml @@ -23,13 +23,22 @@ steps: - name: gcr.io/cloud-builders/gcloud args: ['deploy', 'releases', 'promote', '--quiet', '--release=osv-$SHORT_SHA', '--region=us-central1', '--delivery-pipeline=osv-website', '--to-target=production-website', '--annotations=tag=$TAG_NAME'] +# Deploy OSS-Fuzz workers +- name: gcr.io/cloud-builders/gcloud + args: ['deploy', 'releases', 'create', 'osv-$SHORT_SHA', '--project=oss-vdb', '--region=us-central1', '--delivery-pipeline=oss-fuzz-workers', '--images', 'worker=gcr.io/oss-vdb/oss-fuzz-worker:$COMMIT_SHA,importer=gcr.io/oss-vdb/oss-fuzz-importer:$COMMIT_SHA,cron=gcr.io/oss-vdb/cron:$COMMIT_SHA', '--annotations=tag=$TAG_NAME'] + dir: 'oss-fuzz-workers' + # Tag the deployed images with the git tag - name: gcr.io/cloud-builders/gcloud args: ['container', 'images', 'add-tag', '--quiet', 'gcr.io/oss-vdb/worker-base:$COMMIT_SHA', 'gcr.io/oss-vdb/worker-base:$TAG_NAME'] - name: gcr.io/cloud-builders/gcloud args: ['container', 'images', 'add-tag', '--quiet', 'gcr.io/oss-vdb/worker:$COMMIT_SHA', 'gcr.io/oss-vdb/worker:$TAG_NAME'] +- name: gcr.io/cloud-builders/gcloud + args: ['container', 'images', 'add-tag', '--quiet', 'gcr.io/oss-vdb/oss-fuzz-worker:$COMMIT_SHA', 'gcr.io/oss-vdb/oss-fuzz-worker:$TAG_NAME'] - name: gcr.io/cloud-builders/gcloud args: ['container', 'images', 'add-tag', '--quiet', 'gcr.io/oss-vdb/importer:$COMMIT_SHA', 'gcr.io/oss-vdb/importer:$TAG_NAME'] +- name: gcr.io/cloud-builders/gcloud + args: ['container', 'images', 'add-tag', '--quiet', 'gcr.io/oss-vdb/oss-fuzz-importer:$COMMIT_SHA', 'gcr.io/oss-vdb/oss-fuzz-importer:$TAG_NAME'] - name: gcr.io/cloud-builders/gcloud args: ['container', 'images', 'add-tag', '--quiet', 'gcr.io/oss-vdb/exporter:$COMMIT_SHA', 'gcr.io/oss-vdb/exporter:$TAG_NAME'] - name: gcr.io/cloud-builders/gcloud diff --git a/deployment/deploy.sh b/deployment/deploy.sh index 85fdd1f6b1e..86b8bd4182b 100755 --- a/deployment/deploy.sh +++ b/deployment/deploy.sh @@ -38,4 +38,4 @@ if [[ -z "$commit_sha" || -z "$short_sha" ]]; then exit 1 fi -gcloud beta builds submit --config=deploy-prod.yaml --project=oss-vdb --no-source --substitutions="COMMIT_SHA=${commit_sha},SHORT_SHA=${short_sha},TAG_NAME=${tag_name}" +gcloud beta builds submit ./clouddeploy --config=deploy-prod.yaml --project=oss-vdb --substitutions="COMMIT_SHA=${commit_sha},SHORT_SHA=${short_sha},TAG_NAME=${tag_name}" diff --git a/deployment/terraform/environments/oss-vdb-test/.terraform.lock.hcl b/deployment/terraform/environments/oss-vdb-test/.terraform.lock.hcl index 4a96cbc9400..142754dc2a7 100644 --- a/deployment/terraform/environments/oss-vdb-test/.terraform.lock.hcl +++ b/deployment/terraform/environments/oss-vdb-test/.terraform.lock.hcl @@ -122,31 +122,31 @@ provider "registry.terraform.io/hashicorp/null" { } provider "registry.terraform.io/hashicorp/random" { - version = "3.7.2" + version = "3.8.1" constraints = ">= 2.1.0" hashes = [ - "h1:0hcNr59VEJbhZYwuDE/ysmyTS0evkfcLarlni+zATPM=", - "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", - "h1:Def/iHM4HihJCIxQ8AYoxtoVL5lVlYx0V7bX91pxwgM=", - "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", - "h1:Lmv2TxyKKm9Vt4uxcPZHw1uf0Ax/yYizJlilbLSZN8E=", - "h1:hkKSY5xI4R1H4Yrg10HHbtOoxZif2dXa9HFPSbaVg5o=", - "h1:khu3pu9zeUMd6Ev+yH6cQ1S4+xpzx8wqwwFwADYGeRI=", - "h1:l35vnL76rzaOjhhJQiaWviW0noK2YzHeHN0/vIXJnHk=", - "h1:nWZjMYzp+nsqD3xslcihzq1Enxv33a7iC8/I8CTBcHA=", - "h1:pSMn/cwmyHB6V67lToGmCHfJFfzA711vV+E1cGP0LBg=", - "h1:w+NoF7vNMFS+qrU2XUEm0/wnuIZxPC733qOOfLVOdfk=", - "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", - "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", - "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", - "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", - "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", - "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "h1:Eexl06+6J+s75uD46+WnZtpJZYRVUMB0AiuPBifK6Jc=", + "h1:fPaZ+S6As5cOPbsB/cfBFKnUKlX/Qe/HwdFfZYO8Iao=", + "h1:fdfOl1HabDT42XLH8qjmfTbVZpgQZ5lyOyOa+GQhm0w=", + "h1:m2y2fw9SBQ6+e7pNhi3+qsh8bYNmqkL89BulzH7uK3U=", + "h1:nvy3PZJeuG7g0ltqrJB7LNugxPWhTLs1SZ+J0YDZ3h4=", + "h1:osH3aBqEARwOz3VBJKdpFKJJCNIdgRC6k8vPojkLmlY=", + "h1:shNrbtcKsavnQPkDwxosDSeyh+D9cPEs3FbQ5mq71Hk=", + "h1:sootvBMql2BEt2EGWrwKXSD8I2aXXAD5wuVZ9JcVEYw=", + "h1:u6B/wWlCTCsVWuDk/V7YFwPW9dcEoLU93kmnJdQdx/k=", + "h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=", + "h1:upGnsdxcWL8c2KI95w4lZvn9S/6HTJI26zOoy6wNb6k=", + "zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4", + "zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae", + "zh:229665ddf060aa0ed315597908483eee5b818a17d09b6417a0f52fd9405c4f57", + "zh:2469d2e48f28076254a2a3fc327f184914566d9e40c5780b8d96ebf7205f8bc0", + "zh:37d7eb334d9561f335e748280f5535a384a88675af9a9eac439d4cfd663bcb66", + "zh:741101426a2f2c52dee37122f0f4a2f2d6af6d852cb1db634480a86398fa3511", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", - "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", - "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", - "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", - "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + "zh:a902473f08ef8df62cfe6116bd6c157070a93f66622384300de235a533e9d4a9", + "zh:b85c511a23e57a2147355932b3b6dce2a11e856b941165793a0c3d7578d94d05", + "zh:c5172226d18eaac95b1daac80172287b69d4ce32750c82ad77fa0768be4ea4b8", + "zh:dab4434dba34aad569b0bc243c2d3f3ff86dd7740def373f2a49816bd2ff819b", + "zh:f49fd62aa8c5525a5c17abd51e27ca5e213881d58882fd42fec4a545b53c9699", ] } diff --git a/deployment/terraform/environments/oss-vdb-test/main.tf b/deployment/terraform/environments/oss-vdb-test/main.tf index 1fc47bd52bf..cf979d201ff 100644 --- a/deployment/terraform/environments/oss-vdb-test/main.tf +++ b/deployment/terraform/environments/oss-vdb-test/main.tf @@ -45,7 +45,7 @@ module "osv_test" { website_domain = "test.osv.dev" api_url = "api.test.osv.dev" - esp_version = "2.53.0" + esp_version = "2.54.0" } module "k8s_cron_alert" { diff --git a/deployment/terraform/environments/oss-vdb/.terraform.lock.hcl b/deployment/terraform/environments/oss-vdb/.terraform.lock.hcl index 4a96cbc9400..142754dc2a7 100644 --- a/deployment/terraform/environments/oss-vdb/.terraform.lock.hcl +++ b/deployment/terraform/environments/oss-vdb/.terraform.lock.hcl @@ -122,31 +122,31 @@ provider "registry.terraform.io/hashicorp/null" { } provider "registry.terraform.io/hashicorp/random" { - version = "3.7.2" + version = "3.8.1" constraints = ">= 2.1.0" hashes = [ - "h1:0hcNr59VEJbhZYwuDE/ysmyTS0evkfcLarlni+zATPM=", - "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", - "h1:Def/iHM4HihJCIxQ8AYoxtoVL5lVlYx0V7bX91pxwgM=", - "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", - "h1:Lmv2TxyKKm9Vt4uxcPZHw1uf0Ax/yYizJlilbLSZN8E=", - "h1:hkKSY5xI4R1H4Yrg10HHbtOoxZif2dXa9HFPSbaVg5o=", - "h1:khu3pu9zeUMd6Ev+yH6cQ1S4+xpzx8wqwwFwADYGeRI=", - "h1:l35vnL76rzaOjhhJQiaWviW0noK2YzHeHN0/vIXJnHk=", - "h1:nWZjMYzp+nsqD3xslcihzq1Enxv33a7iC8/I8CTBcHA=", - "h1:pSMn/cwmyHB6V67lToGmCHfJFfzA711vV+E1cGP0LBg=", - "h1:w+NoF7vNMFS+qrU2XUEm0/wnuIZxPC733qOOfLVOdfk=", - "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", - "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", - "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", - "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", - "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", - "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "h1:Eexl06+6J+s75uD46+WnZtpJZYRVUMB0AiuPBifK6Jc=", + "h1:fPaZ+S6As5cOPbsB/cfBFKnUKlX/Qe/HwdFfZYO8Iao=", + "h1:fdfOl1HabDT42XLH8qjmfTbVZpgQZ5lyOyOa+GQhm0w=", + "h1:m2y2fw9SBQ6+e7pNhi3+qsh8bYNmqkL89BulzH7uK3U=", + "h1:nvy3PZJeuG7g0ltqrJB7LNugxPWhTLs1SZ+J0YDZ3h4=", + "h1:osH3aBqEARwOz3VBJKdpFKJJCNIdgRC6k8vPojkLmlY=", + "h1:shNrbtcKsavnQPkDwxosDSeyh+D9cPEs3FbQ5mq71Hk=", + "h1:sootvBMql2BEt2EGWrwKXSD8I2aXXAD5wuVZ9JcVEYw=", + "h1:u6B/wWlCTCsVWuDk/V7YFwPW9dcEoLU93kmnJdQdx/k=", + "h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=", + "h1:upGnsdxcWL8c2KI95w4lZvn9S/6HTJI26zOoy6wNb6k=", + "zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4", + "zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae", + "zh:229665ddf060aa0ed315597908483eee5b818a17d09b6417a0f52fd9405c4f57", + "zh:2469d2e48f28076254a2a3fc327f184914566d9e40c5780b8d96ebf7205f8bc0", + "zh:37d7eb334d9561f335e748280f5535a384a88675af9a9eac439d4cfd663bcb66", + "zh:741101426a2f2c52dee37122f0f4a2f2d6af6d852cb1db634480a86398fa3511", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", - "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", - "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", - "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", - "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + "zh:a902473f08ef8df62cfe6116bd6c157070a93f66622384300de235a533e9d4a9", + "zh:b85c511a23e57a2147355932b3b6dce2a11e856b941165793a0c3d7578d94d05", + "zh:c5172226d18eaac95b1daac80172287b69d4ce32750c82ad77fa0768be4ea4b8", + "zh:dab4434dba34aad569b0bc243c2d3f3ff86dd7740def373f2a49816bd2ff819b", + "zh:f49fd62aa8c5525a5c17abd51e27ca5e213881d58882fd42fec4a545b53c9699", ] } diff --git a/deployment/terraform/environments/oss-vdb/main.tf b/deployment/terraform/environments/oss-vdb/main.tf index 0e0d478160b..2d5f9600697 100644 --- a/deployment/terraform/environments/oss-vdb/main.tf +++ b/deployment/terraform/environments/oss-vdb/main.tf @@ -45,7 +45,15 @@ module "osv" { website_domain = "osv.dev" api_url = "api.osv.dev" - esp_version = "2.53.0" + esp_version = "2.54.0" +} + +module "oss_fuzz" { + source = "../../modules/oss_fuzz" + project_id = "oss-vdb" + tasks_topic_id = module.osv.tasks_topic_id + failed_tasks_topic_id = module.osv.failed_tasks_topic_id + pubsub_service_account_email = module.osv.pubsub_service_account_email } module "k8s_cron_alert" { diff --git a/deployment/terraform/environments/oss-vdb/unmanaged.md b/deployment/terraform/environments/oss-vdb/unmanaged.md index cc37c133e3e..94a86781c71 100644 --- a/deployment/terraform/environments/oss-vdb/unmanaged.md +++ b/deployment/terraform/environments/oss-vdb/unmanaged.md @@ -42,6 +42,7 @@ Not everything here needs to be managed by Terraform, this is just for reference - `esp-test` - `osv-user` (unused?) - `terraform-plan` + - `api-e2e-tester` - `worker` (unused?) - A number of IAM permissions - `osv-vulnerabilities GCS bucket health` Monitoring Alert Policy diff --git a/deployment/terraform/modules/oss_fuzz/main.tf b/deployment/terraform/modules/oss_fuzz/main.tf new file mode 100644 index 00000000000..750b0576107 --- /dev/null +++ b/deployment/terraform/modules/oss_fuzz/main.tf @@ -0,0 +1,102 @@ +resource "google_compute_subnetwork" "oss_fuzz_subnet" { + project = var.project_id + name = "oss-fuzz-subnet" + network = var.network + ip_cidr_range = "10.45.36.0/22" + private_ip_google_access = true + region = var.region +} + +resource "google_container_cluster" "workers" { + project = var.project_id + name = "oss-fuzz-workers" + location = "${var.region}-f" + subnetwork = google_compute_subnetwork.oss_fuzz_subnet.self_link + + private_cluster_config { + enable_private_endpoint = false + enable_private_nodes = true + master_ipv4_cidr_block = "172.16.0.48/28" + } + + ip_allocation_policy {} + + addons_config { + gce_persistent_disk_csi_driver_config { + enabled = true + } + } + + remove_default_node_pool = true + initial_node_count = 1 + lifecycle { + ignore_changes = [ + initial_node_count, + ] + prevent_destroy = true + } + + monitoring_config { + managed_prometheus { + enabled = true + } + } +} + +resource "google_container_node_pool" "workers_pool" { + project = var.project_id + name = "workers-pool" + cluster = google_container_cluster.workers.name + location = google_container_cluster.workers.location + + lifecycle { + replace_triggered_by = [ + google_container_cluster.workers.id, + ] + } + + autoscaling { + min_node_count = 1 + max_node_count = 100 + location_policy = "BALANCED" + } + + node_config { + machine_type = "n2-highmem-2" + disk_type = "pd-ssd" + disk_size_gb = 64 + local_ssd_count = 1 + + oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"] + } +} + +resource "google_pubsub_subscription" "oss_fuzz_tasks" { + project = var.project_id + name = "oss-fuzz-tasks" + topic = var.tasks_topic_id + message_retention_duration = "604800s" + ack_deadline_seconds = 600 + + dead_letter_policy { + dead_letter_topic = var.failed_tasks_topic_id + max_delivery_attempts = 5 + } + + expiration_policy { + ttl = "" # never expires + } + + labels = { + goog-dm = "pubsub" + } + + filter = "attributes.type = \"regressed\" OR attributes.type = \"fixed\" OR attributes.type = \"impact\" OR attributes.type = \"invalid\" OR attributes.type = \"update-oss-fuzz\"" +} + +resource "google_pubsub_subscription_iam_member" "oss_fuzz_tasks_service_subscriber" { + project = var.project_id + subscription = google_pubsub_subscription.oss_fuzz_tasks.name + role = "roles/pubsub.subscriber" + member = "serviceAccount:${var.pubsub_service_account_email}" +} diff --git a/deployment/terraform/modules/oss_fuzz/outputs.tf b/deployment/terraform/modules/oss_fuzz/outputs.tf new file mode 100644 index 00000000000..b7ae582e9d8 --- /dev/null +++ b/deployment/terraform/modules/oss_fuzz/outputs.tf @@ -0,0 +1,11 @@ +output "cluster_name" { + value = google_container_cluster.workers.name +} + +output "cluster_endpoint" { + value = google_container_cluster.workers.endpoint +} + +output "cluster_location" { + value = google_container_cluster.workers.location +} diff --git a/deployment/terraform/modules/oss_fuzz/variables.tf b/deployment/terraform/modules/oss_fuzz/variables.tf new file mode 100644 index 00000000000..933cc8f759e --- /dev/null +++ b/deployment/terraform/modules/oss_fuzz/variables.tf @@ -0,0 +1,30 @@ +variable "project_id" { + type = string + description = "GCP Project ID." +} + +variable "region" { + type = string + description = "GCP Region." + default = "us-central1" +} + +variable "network" { + type = string + description = "VPC Network name." + default = "default" +} +variable "tasks_topic_id" { + type = string + description = "The ID of the tasks Pub/Sub topic." +} + +variable "failed_tasks_topic_id" { + type = string + description = "The ID of the failed-tasks Pub/Sub topic." +} + +variable "pubsub_service_account_email" { + type = string + description = "The email of the Pub/Sub service account." +} diff --git a/deployment/terraform/modules/osv/outputs.tf b/deployment/terraform/modules/osv/outputs.tf index f7ef960ebdc..5e144f3f819 100644 --- a/deployment/terraform/modules/osv/outputs.tf +++ b/deployment/terraform/modules/osv/outputs.tf @@ -2,3 +2,17 @@ output "project_id" { value = var.project_id # Assuming you are using a variable for project_id within the module description = "The Google Cloud Project ID" } +output "tasks_topic_id" { + value = google_pubsub_topic.tasks.id + description = "The ID of the tasks Pub/Sub topic" +} + +output "failed_tasks_topic_id" { + value = google_pubsub_topic.failed_tasks.id + description = "The ID of the failed-tasks Pub/Sub topic" +} + +output "pubsub_service_account_email" { + value = google_project_service_identity.pubsub.email + description = "The email of the Pub/Sub service account" +} diff --git a/deployment/terraform/modules/osv/workers_gke.tf b/deployment/terraform/modules/osv/workers_gke.tf index e706bf04130..b4e39fa37d2 100644 --- a/deployment/terraform/modules/osv/workers_gke.tf +++ b/deployment/terraform/modules/osv/workers_gke.tf @@ -140,7 +140,7 @@ resource "google_container_node_pool" "importer_pool" { } node_config { - machine_type = "n2-highmem-2" + machine_type = "n2-highmem-4" disk_type = "pd-ssd" disk_size_gb = 64 local_ssd_count = 1 diff --git a/docker/deployment/Dockerfile b/docker/deployment/Dockerfile index 5c5a0d67293..271c12d35b9 100644 --- a/docker/deployment/Dockerfile +++ b/docker/deployment/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04@sha256:104ae83764a5119017b8e8d6218fa0832b09df65aae7d5a6de29a85d813da2fb +FROM ubuntu:24.04@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b RUN apt-get update && \ apt-get install -y curl jq diff --git a/docker/poetry/requirements-py3.12.txt b/docker/poetry/requirements-py3.12.txt index 821a495f7db..6b3649b8afc 100644 --- a/docker/poetry/requirements-py3.12.txt +++ b/docker/poetry/requirements-py3.12.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --generate-hashes requirements.in +# pip-compile --generate-hashes --output-file=requirements-py3.12.txt requirements.in # anyio==4.11.0 \ --hash=sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc \ @@ -293,9 +293,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via poetry -filelock==3.20.1 \ - --hash=sha256:15d9e9a67306188a44baa72f569d2bfd803076269365fdea0934385da4dc361a \ - --hash=sha256:b8360948b351b80f420878d8516519a2204b07aefcdcfd24912a5d33127f188c +filelock==3.20.3 \ + --hash=sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1 \ + --hash=sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1 # via # cachecontrol # virtualenv @@ -330,9 +330,9 @@ jaraco-classes==3.4.0 \ --hash=sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd \ --hash=sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790 # via keyring -jaraco-context==6.0.1 \ - --hash=sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3 \ - --hash=sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4 +jaraco-context==6.1.0 \ + --hash=sha256:129a341b0a85a7db7879e22acd66902fda67882db771754574338898b2d5d86f \ + --hash=sha256:a43b5ed85815223d0d3cfdb6d7ca0d2bc8946f28f30b6f3216bda070f68badda # via keyring jaraco-functools==4.3.0 \ --hash=sha256:227ff8ed6f7b8f62c56deff101545fa7543cf2c8e7b82a7c2116e672f29c26e8 \ @@ -590,9 +590,9 @@ urllib3==2.6.3 \ # via # dulwich # requests -virtualenv==20.34.0 \ - --hash=sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026 \ - --hash=sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a +virtualenv==20.36.1 \ + --hash=sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f \ + --hash=sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba # via poetry zstandard==0.25.0 \ --hash=sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64 \ diff --git a/docker/poetry/requirements.txt b/docker/poetry/requirements.txt index 2ad04cb2f1f..c3a265479e1 100644 --- a/docker/poetry/requirements.txt +++ b/docker/poetry/requirements.txt @@ -4,21 +4,21 @@ # # pip-compile --generate-hashes requirements.in # -anyio==4.12.0 \ - --hash=sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0 \ - --hash=sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb +anyio==4.12.1 \ + --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ + --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c # via httpx -build==1.3.0 \ - --hash=sha256:698edd0ea270bde950f53aed21f3a0135672206f3911e0176261a31e0e07b397 \ - --hash=sha256:7145f0b5061ba90a1500d60bd1b13ca0a8a4cebdd0cc16ed8adf1c0e739f43b4 +build==1.4.0 \ + --hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \ + --hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936 # via poetry cachecontrol[filecache]==0.14.4 \ --hash=sha256:b7ac014ff72ee199b5f8af1de29d60239954f223e948196fa3d84adaffc71d2b \ --hash=sha256:e6220afafa4c22a47dd0badb319f84475d79108100d04e26e8542ef7d3ab05a1 # via poetry -certifi==2025.11.12 \ - --hash=sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b \ - --hash=sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316 +certifi==2026.1.4 \ + --hash=sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c \ + --hash=sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120 # via # httpcore # httpx @@ -329,9 +329,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via poetry -filelock==3.20.1 \ - --hash=sha256:15d9e9a67306188a44baa72f569d2bfd803076269365fdea0934385da4dc361a \ - --hash=sha256:b8360948b351b80f420878d8516519a2204b07aefcdcfd24912a5d33127f188c +filelock==3.20.3 \ + --hash=sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1 \ + --hash=sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1 # via # cachecontrol # virtualenv @@ -366,13 +366,13 @@ jaraco-classes==3.4.0 \ --hash=sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd \ --hash=sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790 # via keyring -jaraco-context==6.0.1 \ - --hash=sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3 \ - --hash=sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4 +jaraco-context==6.1.0 \ + --hash=sha256:129a341b0a85a7db7879e22acd66902fda67882db771754574338898b2d5d86f \ + --hash=sha256:a43b5ed85815223d0d3cfdb6d7ca0d2bc8946f28f30b6f3216bda070f68badda # via keyring -jaraco-functools==4.3.0 \ - --hash=sha256:227ff8ed6f7b8f62c56deff101545fa7543cf2c8e7b82a7c2116e672f29c26e8 \ - --hash=sha256:cfd13ad0dd2c47a3600b439ef72d8615d482cedcff1632930d6f28924d92f294 +jaraco-functools==4.4.0 \ + --hash=sha256:9eec1e36f45c818d9bf307c8948eb03b2b56cd44087b3cdc989abca1f20b9176 \ + --hash=sha256:da21933b0417b89515562656547a77b4931f98176eb173644c0d35032a33d6bb # via keyring jeepney==0.9.0 \ --hash=sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683 \ @@ -598,23 +598,23 @@ shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de # via poetry -tomlkit==0.13.3 \ - --hash=sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1 \ - --hash=sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0 +tomlkit==0.14.0 \ + --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ + --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 # via poetry -trove-classifiers==2025.12.1.14 \ - --hash=sha256:a74f0400524fc83620a9be74a07074b5cbe7594fd4d97fd4c2bfde625fdc1633 \ - --hash=sha256:a8206978ede95937b9959c3aff3eb258bbf7b07dff391ddd4ea7e61f316635ab +trove-classifiers==2026.1.12.15 \ + --hash=sha256:832a7e89ccc43b64b89f8f9d9150c069ebcd17d2dc68279bc00bb53f2a9ae112 \ + --hash=sha256:8832dfbc226fc4df986666b9cb3a018818b1498aeb79f5f66a31a918b47a98f1 # via poetry -urllib3==2.6.2 \ - --hash=sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797 \ - --hash=sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd +urllib3==2.6.3 \ + --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ + --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 # via # dulwich # requests -virtualenv==20.35.4 \ - --hash=sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c \ - --hash=sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b +virtualenv==20.36.1 \ + --hash=sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f \ + --hash=sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba # via poetry zstandard==0.25.0 \ --hash=sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64 \ diff --git a/docker/terraform/Dockerfile b/docker/terraform/Dockerfile index 8ea338fde6f..ef28358b880 100644 --- a/docker/terraform/Dockerfile +++ b/docker/terraform/Dockerfile @@ -1,12 +1,12 @@ # Taken and modified from https://github.com/GoogleCloudPlatform/cloud-builders-community/tree/master/terraform -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD ARG TERRAFORM_VERSION WORKDIR /build/ RUN GOBIN=$(pwd) go install github.com/hashicorp/terraform@v${TERRAFORM_VERSION} -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed COPY --from=GO_BUILD /build/terraform /usr/bin/terraform COPY entrypoint.bash /builder/entrypoint.bash diff --git a/docker/worker-base/Dockerfile b/docker/worker-base/Dockerfile index 0691c612fa0..612ebfe4812 100644 --- a/docker/worker-base/Dockerfile +++ b/docker/worker-base/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM ubuntu:24.04@sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54 +FROM ubuntu:24.04@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && apt-get upgrade -y && \ diff --git a/docs/data.md b/docs/data.md index e74d810cee9..06c4eca585c 100644 --- a/docs/data.md +++ b/docs/data.md @@ -58,6 +58,8 @@ The following ecosystems have vulnerabilities encoded in this format: ([CC0 1.0](https://github.com/haskell/security-advisories/blob/main/LICENSE.txt)) - [Ubuntu](https://github.com/canonical/ubuntu-security-notices) ([CC-BY-SA 4.0](https://github.com/canonical/ubuntu-security-notices/blob/main/LICENSE)) +- [opam (OCaml package manager)](https://github.com/ocaml/security-advisories) + ([CC0 1.0](https://github.com/ocaml/security-advisories/blob/main/LICENSE.txt)) ## Converted data @@ -91,6 +93,7 @@ Between the data served in OSV and the data converted to OSV the following ecosy - Maven - npm - NuGet +- opam (OCaml package manager) - OSS-Fuzz - Packagist - Pub diff --git a/gcp/api/cloudbuild.yaml b/gcp/api/cloudbuild.yaml index 7190530a129..d7cad579243 100644 --- a/gcp/api/cloudbuild.yaml +++ b/gcp/api/cloudbuild.yaml @@ -39,8 +39,18 @@ steps: dir: gcp/api #TODO: Update test scripts to support not supplying a credential. args: ['bash', '-ex', 'run_tests.sh', '/workspace/dummy.json'] - env: - - CLOUDBUILD=1 waitFor: ['init', 'sync'] +- name: 'gcr.io/oss-vdb/ci' + id: 'api-snapshot-tests' + dir: gcp/api + args: ['bash', '-ex', 'run_tests_e2e.sh', '/workspace/dummy.json'] + # Don't run at the same time as api-tests + waitFor: ['init', 'sync', 'api-tests'] + timeout: 7200s +serviceAccount: 'projects/oss-vdb/serviceAccounts/api-e2e-tester@oss-vdb.iam.gserviceaccount.com' +options: + logging: CLOUD_LOGGING_ONLY + env: + - CLOUDBUILD=1 diff --git a/gcp/api/googleapis b/gcp/api/googleapis index d4a34bf03d6..cfe62b3c5ce 160000 --- a/gcp/api/googleapis +++ b/gcp/api/googleapis @@ -1 +1 @@ -Subproject commit d4a34bf03d617723146fe3ae15192c4d93981a27 +Subproject commit cfe62b3c5ceb9f81879c61480f26707980534462 diff --git a/gcp/api/poetry.lock b/gcp/api/poetry.lock index 40e1db2fbb4..8fd50219c3b 100644 --- a/gcp/api/poetry.lock +++ b/gcp/api/poetry.lock @@ -2,14 +2,14 @@ [[package]] name = "astroid" -version = "4.0.2" +version = "4.0.3" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.10.0" groups = ["dev"] files = [ - {file = "astroid-4.0.2-py3-none-any.whl", hash = "sha256:d7546c00a12efc32650b19a2bb66a153883185d3179ab0d4868086f807338b9b"}, - {file = "astroid-4.0.2.tar.gz", hash = "sha256:ac8fb7ca1c08eb9afec91ccc23edbd8ac73bb22cbdd7da1d488d9fb8d6579070"}, + {file = "astroid-4.0.3-py3-none-any.whl", hash = "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14"}, + {file = "astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3"}, ] [[package]] @@ -24,28 +24,16 @@ files = [ {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] -[[package]] -name = "cachetools" -version = "6.2.4" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "cachetools-6.2.4-py3-none-any.whl", hash = "sha256:69a7a52634fed8b8bf6e24a050fb60bff1c9bd8f6d24572b99c32d4e71e62a51"}, - {file = "cachetools-6.2.4.tar.gz", hash = "sha256:82c5c05585e70b6ba2d3ae09ea60b79548872185d2f24ae1f2709d37299fd607"}, -] - [[package]] name = "certifi" -version = "2025.11.12" +version = "2026.1.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, - {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, + {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, ] [[package]] @@ -281,16 +269,93 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "cryptography" +version = "46.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, + {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, + {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, + {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, + {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, + {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, + {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, + {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, + {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, + {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, + {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, +] + +[package.dependencies] +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" description = "serialize all of Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, - {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, ] [package.extras] @@ -327,15 +392,15 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] [[package]] name = "google-api-core" -version = "2.28.1" +version = "2.29.0" description = "Google API client core library" optional = false python-versions = ">=3.7" groups = ["main"] markers = "python_version == \"3.13\"" files = [ - {file = "google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c"}, - {file = "google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8"}, + {file = "google_api_core-2.29.0-py3-none-any.whl", hash = "sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9"}, + {file = "google_api_core-2.29.0.tar.gz", hash = "sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7"}, ] [package.dependencies] @@ -355,30 +420,30 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] [[package]] name = "google-auth" -version = "2.45.0" +version = "2.48.0" description = "Google Authentication Library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "google_auth-2.45.0-py2.py3-none-any.whl", hash = "sha256:82344e86dc00410ef5382d99be677c6043d72e502b625aa4f4afa0bdacca0f36"}, - {file = "google_auth-2.45.0.tar.gz", hash = "sha256:90d3f41b6b72ea72dd9811e765699ee491ab24139f34ebf1ca2b9cc0c38708f3"}, + {file = "google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f"}, + {file = "google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce"}, ] [package.dependencies] -cachetools = ">=2.0.0,<7.0" +cryptography = ">=38.0.3" pyasn1-modules = ">=0.2.1" rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] -cryptography = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)"] -enterprise-cert = ["cryptography", "pyopenssl"] -pyjwt = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyjwt (>=2.0)"] -pyopenssl = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +cryptography = ["cryptography (>=38.0.3)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0)"] -testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "mock", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] urllib3 = ["packaging", "urllib3"] [[package]] @@ -402,15 +467,15 @@ protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4 [[package]] name = "google-cloud-appengine-logging" -version = "1.7.0" +version = "1.8.0" description = "Google Cloud Appengine Logging API client library" optional = false python-versions = ">=3.7" groups = ["main"] markers = "python_version == \"3.13\"" files = [ - {file = "google_cloud_appengine_logging-1.7.0-py3-none-any.whl", hash = "sha256:cfd28bc61a030008381a646d112ebe2734bf72abc8c12afc47d035a2c9b041fe"}, - {file = "google_cloud_appengine_logging-1.7.0.tar.gz", hash = "sha256:ea9ce73430cfc99f8957fd7df97733f9a759d4caab65e19d63a7474f012ffd94"}, + {file = "google_cloud_appengine_logging-1.8.0-py3-none-any.whl", hash = "sha256:a4ce9ce94a9fd8c89ed07fa0b06fcf9ea3642f9532a1be1a8c7b5f82c0a70ec6"}, + {file = "google_cloud_appengine_logging-1.8.0.tar.gz", hash = "sha256:84b705a69e4109fc2f68dfe36ce3df6a34d5c3d989eee6d0ac1b024dda0ba6f5"}, ] [package.dependencies] @@ -626,15 +691,15 @@ tracing = ["opentelemetry-api (>=1.1.0,<2.0.0)"] [[package]] name = "google-cloud-storage" -version = "3.7.0" +version = "3.8.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" groups = ["main"] markers = "python_version == \"3.13\"" files = [ - {file = "google_cloud_storage-3.7.0-py3-none-any.whl", hash = "sha256:469bc9540936e02f8a4bfd1619e9dca1e42dec48f95e4204d783b36476a15093"}, - {file = "google_cloud_storage-3.7.0.tar.gz", hash = "sha256:9ce59c65f4d6e372effcecc0456680a8d73cef4f2dc9212a0704799cb3d69237"}, + {file = "google_cloud_storage-3.8.0-py3-none-any.whl", hash = "sha256:78cfeae7cac2ca9441d0d0271c2eb4ebfa21aa4c6944dd0ccac0389e81d955a7"}, + {file = "google_cloud_storage-3.8.0.tar.gz", hash = "sha256:cc67952dce84ebc9d44970e24647a58260630b7b64d72360cedaf422d6727f28"}, ] [package.dependencies] @@ -987,21 +1052,21 @@ plugins = ["setuptools"] [[package]] name = "jsonschema" -version = "4.25.1" +version = "4.26.0" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, - {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, ] [package.dependencies] attrs = ">=22.2.0" jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" -rpds-py = ">=0.7.1" +rpds-py = ">=0.25.0" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1210,34 +1275,34 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "6.33.2" +version = "6.33.4" description = "" optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d"}, - {file = "protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4"}, - {file = "protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f"}, - {file = "protobuf-6.33.2-cp39-cp39-win32.whl", hash = "sha256:7109dcc38a680d033ffb8bf896727423528db9163be1b6a02d6a49606dcadbfe"}, - {file = "protobuf-6.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:2981c58f582f44b6b13173e12bb8656711189c2a70250845f264b877f00b1913"}, - {file = "protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c"}, - {file = "protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4"}, + {file = "protobuf-6.33.4-cp310-abi3-win32.whl", hash = "sha256:918966612c8232fc6c24c78e1cd89784307f5814ad7506c308ee3cf86662850d"}, + {file = "protobuf-6.33.4-cp310-abi3-win_amd64.whl", hash = "sha256:8f11ffae31ec67fc2554c2ef891dcb561dae9a2a3ed941f9e134c2db06657dbc"}, + {file = "protobuf-6.33.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2fe67f6c014c84f655ee06f6f66213f9254b3a8b6bda6cda0ccd4232c73c06f0"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:757c978f82e74d75cba88eddec479df9b99a42b31193313b75e492c06a51764e"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c7c64f259c618f0bef7bee042075e390debbf9682334be2b67408ec7c1c09ee6"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:3df850c2f8db9934de4cf8f9152f8dc2558f49f298f37f90c517e8e5c84c30e9"}, + {file = "protobuf-6.33.4-cp39-cp39-win32.whl", hash = "sha256:955478a89559fa4568f5a81dce77260eabc5c686f9e8366219ebd30debf06aa6"}, + {file = "protobuf-6.33.4-cp39-cp39-win_amd64.whl", hash = "sha256:0f12ddbf96912690c3582f9dffb55530ef32015ad8e678cd494312bd78314c4f"}, + {file = "protobuf-6.33.4-py3-none-any.whl", hash = "sha256:1fe3730068fcf2e595816a6c34fe66eeedd37d51d0400b72fabc848811fdc1bc"}, + {file = "protobuf-6.33.4.tar.gz", hash = "sha256:dc2e61bca3b10470c1912d166fe0af67bfc20eb55971dcef8dfa48ce14f0ed91"}, ] [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, - {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, + {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"}, + {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"}, ] [[package]] @@ -1257,74 +1322,81 @@ pyasn1 = ">=0.6.1,<0.7.0" [[package]] name = "pycparser" -version = "2.23" +version = "3.0" description = "C parser in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] markers = "implementation_name != \"PyPy\"" files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, ] [[package]] name = "pygit2" -version = "1.19.0" +version = "1.19.1" description = "Python bindings for libgit2." optional = false python-versions = ">=3.11" groups = ["main"] files = [ - {file = "pygit2-1.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:12ee8dc6d14573811ba52a18b37d4f6f42e66e0fcef7ed7d4b5e799bc66455f5"}, - {file = "pygit2-1.19.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae8fe208d11bbfb2dd2716ac8871764c847d1db29f40a1bb20b469df652ca0e3"}, - {file = "pygit2-1.19.0-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18c13b8c49402d007b58744379c455d56526eae16bb9059b2a578d43dd8dfc40"}, - {file = "pygit2-1.19.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f23387f555f6a7224657c7cec618b374c7b01fc617b38ca551859bb69548ed53"}, - {file = "pygit2-1.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a29bd5db67631ac526dbab327f6e254e33e44aa14169055621da6c94636e7e2c"}, - {file = "pygit2-1.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6d7a90a3cfa55b828c912c1817a1c8c4d5a0988df0958371c122774e997a6c3e"}, - {file = "pygit2-1.19.0-cp311-cp311-win32.whl", hash = "sha256:30266cf1e679a24f689d753931d465bedc7e1270a8aa10abe9065a78439a5558"}, - {file = "pygit2-1.19.0-cp311-cp311-win_amd64.whl", hash = "sha256:c6f519790957936dcc54849b901af0cc1cec7aef3be1eb336184b1790a41ebf2"}, - {file = "pygit2-1.19.0-cp311-cp311-win_arm64.whl", hash = "sha256:8a7e7ef28a457643bc6a4d17ca4b437db5f5e400926efda4d269a597a6350e4e"}, - {file = "pygit2-1.19.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:770e1d506ceb08cc65ac0de4e8a9911a169603361c23c3386556a8aab7ee1f7e"}, - {file = "pygit2-1.19.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db2a75f4a2e896a8b09bcfdeb1d52c0fc72b403e0e9910c03307d5e577e3fb40"}, - {file = "pygit2-1.19.0-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2600ed9acc3b6f52e49a65c2200e5eadd70ef6d022fd8e029adbfa6e6d9cbf50"}, - {file = "pygit2-1.19.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:795dce83170f4b82fa275a6233ee3f70673a06a3e22a1c57221e16b9a140ef98"}, - {file = "pygit2-1.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b26875600a8720196d0cdaacdb485761ac07334512a44da79d7b2398672549f7"}, - {file = "pygit2-1.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b5dd263e0d3820892e0751b344eab30f5fb068f20a456e2b2fc2082160d263fe"}, - {file = "pygit2-1.19.0-cp312-cp312-win32.whl", hash = "sha256:1314c81d3608201be032ff1631392f92c767b65d3c81f7efb4e83a551b65290d"}, - {file = "pygit2-1.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:f7efa3fe6d818b48561bc5b72bd991eb57c0baaafc864b64b27f9d064761e557"}, - {file = "pygit2-1.19.0-cp312-cp312-win_arm64.whl", hash = "sha256:c433b9d448912ba7237cb26149b43252b6187acebfa205edf53cfde9e0e441bb"}, - {file = "pygit2-1.19.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e84d4a1c8bcd462524bf9d0c5778c2219042c8aeeea82735e8f415d8f8519797"}, - {file = "pygit2-1.19.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5998943514b89fd4bf8ab11320872bc4c0b6d3517b27beaf79ff9591d3142f1c"}, - {file = "pygit2-1.19.0-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:38ea299bd02584df017f44a0673157bb7b28a2ae69826cfbb456f7429e781d58"}, - {file = "pygit2-1.19.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:46f5f287f19053eb1ba36d72a7458712bc5dcdb1b667ecf162a6cae7e643afe2"}, - {file = "pygit2-1.19.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41d9effdc1e54e7bcd14013ea5a86c9dbf9bbc16b7c932d6e0ed96773e0baa68"}, - {file = "pygit2-1.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e74312467a45de208dc157d1053b851b4181c2fabcacc5d9c578a8ef1b367e13"}, - {file = "pygit2-1.19.0-cp313-cp313-win32.whl", hash = "sha256:eb55020bf0bd36e9a4c167c88139a9e20e787b2c66b5c2f60a8a12f3e0334a82"}, - {file = "pygit2-1.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:37ba33c59b8b941f7a2fa1014c11bc847c315ebbaeb92341f7f39efeab75edb2"}, - {file = "pygit2-1.19.0-cp313-cp313-win_arm64.whl", hash = "sha256:f59b39b7f9583fd0e5dbd63b6f156b735293b3b4a1688534a5eb2c695975eb39"}, - {file = "pygit2-1.19.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:db136a24a9b46327f334a960604f5ed5ca138cab57cf54906c82bae147b2f600"}, - {file = "pygit2-1.19.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1487023a52d25d169fd3d5c146475dec0f39dd54586bd55aac810ae0d7809154"}, - {file = "pygit2-1.19.0-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:14bd00877c5b2571d1e8e2e203df35291198a3a9a90602121a8419b540174b8a"}, - {file = "pygit2-1.19.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cb47afb011ef6133e1b938018afa7d6435040d1ae1e84242bf0699dc6960a4cf"}, - {file = "pygit2-1.19.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4d81f578aef1c04cd5169b96aa38f864c0ed1a37249e13bff69b49f12f6ae761"}, - {file = "pygit2-1.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8c97c281d4e24d45b1d93ea844b52ea157a7c1c408e31e53bbb7b969c3168a96"}, - {file = "pygit2-1.19.0-cp314-cp314-win32.whl", hash = "sha256:e69576401664911633351ebbe2a896861a8c1ff531d0375796e61483db39ebd7"}, - {file = "pygit2-1.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:e56a14fcbfb8e07e30d18f21cfb790a74506957fa3ce03c54c02745b5d0152e2"}, - {file = "pygit2-1.19.0-cp314-cp314-win_arm64.whl", hash = "sha256:2e84ab99802d8de643c6f8aa5b689b033ee5d5dee70ae04432005299dec33ee4"}, - {file = "pygit2-1.19.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:12c8f8672fb319ee4276fc028019de4d3e6b9cd94bffc74a1aaa81ffc6445dc7"}, - {file = "pygit2-1.19.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ccddde0826101035ca31f9df42c6a57704285e2387ab15cd314afa18f0521d95"}, - {file = "pygit2-1.19.0-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de1fe1a2dfd10a58d17e88c14b363aa809a480c181b56c47cbc4fa83b0b68918"}, - {file = "pygit2-1.19.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b775d93b7ea9b8ff676002a857eabbe07fbc838802fd76b9b1e17109f571557"}, - {file = "pygit2-1.19.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:21a9bf74720360fcb21a0e6ad750013ba3e0625cd484f1bb7ddfefdcd207c0f5"}, - {file = "pygit2-1.19.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba17b947b2166000aeb9b19135160bb32aec38a7da9892d9fb476cdb3f518aba"}, - {file = "pygit2-1.19.0-cp314-cp314t-win32.whl", hash = "sha256:772bf01936eb306c6dfb3cc3b955e2f8d3271d0eef2c23e24203352519421b20"}, - {file = "pygit2-1.19.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4516e87d35df9b2867b5f859a0d09cd86857f1e3ef4215d6c87850ce4869a793"}, - {file = "pygit2-1.19.0-cp314-cp314t-win_arm64.whl", hash = "sha256:fceba6e279ab2be9ec762f2b3ff1b315cd922de879800d1f57a25eba4a90bc60"}, - {file = "pygit2-1.19.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6163a94e60ccd574c76018fdd19316c3c0671858a83000ea7978c28f55c78fc"}, - {file = "pygit2-1.19.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9ebbd394ce40024499d0e5905d1d26cd2bbc4429a30c2ac13a98f990e84ab88"}, - {file = "pygit2-1.19.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:33a509b4df90e23e87b4118020cabecd1910ede436d90a43c31eec27e33f52ce"}, - {file = "pygit2-1.19.0.tar.gz", hash = "sha256:ca5db6f395a74166a019d777895f96bcb211ee60ce0be4132b139603e0066d83"}, + {file = "pygit2-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b54f3a94648ac8e287f5e4333710d9fe05f9e09de3da232d50df753bb01b643"}, + {file = "pygit2-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e46618a912fc984b8a9f4d8322704620f1315264359c7fa61c899128e23e226"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2eb386b3e98f7056d76bc7e805e8fce3cd0a773cbbb30b0f7e144c0ac37270f2"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f41a9b866676922ac9b0ec60f0dc9735a5d1ba6bb34146a6212dc0012d7959f"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2cdc81ecffd990d8c6dce44a16b1dc4494b5dd5381d6e1f508e459c4bca09e0"}, + {file = "pygit2-1.19.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a1c8645287556aa9b670886dbc0d5daa1d49040511940822fd43dbda13cfe4e8"}, + {file = "pygit2-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e388d1eb0c44d92d8ff01b25eb9a969fc28748966843c2e26e9e084e42567f7d"}, + {file = "pygit2-1.19.1-cp311-cp311-win32.whl", hash = "sha256:815c0b12845253929f2275759d623b3b4093e67e6536d2463177e6ff1d9ff0df"}, + {file = "pygit2-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:93f4986b35984aaaa5e7613ceb1ba4c184d890589df60b0d8d74e7dccec1d8cb"}, + {file = "pygit2-1.19.1-cp311-cp311-win_arm64.whl", hash = "sha256:fef27b206955e66e3a63664e2ec93821e00ce2d917f8b4eae87c738163c00e14"}, + {file = "pygit2-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8e6a4f4a711750c286a13cea0007b40f7466c4d741c3d9b223ffbc3bbfbafe7"}, + {file = "pygit2-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3f2340a668eb3e2d8927dcbeb1a043d3a65d2dd39a913995b34fc437da5e73af"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe41f09b1e334c43def6636b1133d2f4c91a20d9a6691bb4e7558e42a31bcb4e"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:527e57133d30ff6ea96634da6bf428f7d551958207fa73f9e9a18582b885e192"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a9340cb85b7be40080186a9d4dbf712a6be8a842556acbbfb305baebfb854f3"}, + {file = "pygit2-1.19.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:66ecfa69f2287f50ec95dfc04821219c2f664c4cd292c7b33c10ed9afe975132"}, + {file = "pygit2-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:14c76ec968ae20a6689c7b6fa833ef546c7bc176127d71e7b67cb2345a9813fb"}, + {file = "pygit2-1.19.1-cp312-cp312-win32.whl", hash = "sha256:ffe94118d39f6969fda594224b2b6df1ae79306adaf090ede65bcaf1a41b3a81"}, + {file = "pygit2-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:c2ee3f2e91b0a5674ab7cb373234c23cf5f1cf6d84e56e6d12ff3db21414cf47"}, + {file = "pygit2-1.19.1-cp312-cp312-win_arm64.whl", hash = "sha256:c8747d968d8d6b9d390263907f014d38a0f67bd26d8243e5bc3384cb252ec3d3"}, + {file = "pygit2-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:39af62f3e18dfdfb15c347c12b51231fdb3db3c9d5105d9046847ead14b42fce"}, + {file = "pygit2-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed39106f1d9560709191093ed5251471dfb6b9e4aa35299dde45f4b91f7c984e"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb4da746c92e23281890e865887d83f24e662fc3e1c481420e4993c5a13203fe"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:93ccfab2340d38374f91ecf6cae6658bebc73883c376eb81eeb293781f6aef94"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef18f1208422d3cac1c109417a5fc6143704cfff8e5de4e1665fa4a89ffe3902"}, + {file = "pygit2-1.19.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:344f4c1e84eaa2434fbb43d96a1dd79796ab9559587a8533331fef92eab0ec7d"}, + {file = "pygit2-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1ae2f408206c67d395e8dc77425f8ab457cad59faaa58c700164398a62823e82"}, + {file = "pygit2-1.19.1-cp313-cp313-win32.whl", hash = "sha256:9d6cf97c2da5c589b65371a8115be920cf417c46a80a2b12edb26e54a5238190"}, + {file = "pygit2-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:6d73aedffad280f6b655394e303533fcff15545d4d8f322011179c9474bb1b13"}, + {file = "pygit2-1.19.1-cp313-cp313-win_arm64.whl", hash = "sha256:8b067241c03a29440507e78637e233998fe1a11d2082169bd8177694ec4ee747"}, + {file = "pygit2-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d10a46285b9ae39b9de2d9f44ac7f933993aecfab189c2932320b3df596311c8"}, + {file = "pygit2-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d0f3924d8d0d54a7fe186761c76dc1b6e5fcf41794a6daba1630db3bc216b9ba"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4fcc301cfe9c29f3e29f0f80d81ae65c0bee368672b23566467dc91b5edae4b"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3c6eacf82f15e001121dc0f60057f462627045447d8bd8587b33b13159ae5155"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:074b0b14c6f3c7e2c6ea0b01a90832407a71520c920918aa07f509c91f1691f9"}, + {file = "pygit2-1.19.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ada5d3e813e21918e004a33c66aba4a2b829cd5c0c0e85b92dd70f84cf95ac56"}, + {file = "pygit2-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:19ebe25fd8e95ed8a0be0a9dd4cecc1233db4f2a44a2a73984620909e98e907f"}, + {file = "pygit2-1.19.1-cp314-cp314-win32.whl", hash = "sha256:5bc0738a49cceb76f0fba7cdb24532857a980e4a36b9a0da025c359dfe3676b4"}, + {file = "pygit2-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:527d40925bb85b86da0e96ecc90e9ca74d0a0273ab645bac0787b95923d93160"}, + {file = "pygit2-1.19.1-cp314-cp314-win_arm64.whl", hash = "sha256:21c7c8b5aa2f48cefdb8521185f0cd3c110a340e2d9f62a46a94db01a907db73"}, + {file = "pygit2-1.19.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9c5e4eb975b664b6821fe6a05b03bbc51052d1fb22f20652e1d4349ae24ed7ac"}, + {file = "pygit2-1.19.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8752eae5780ee51edae326cac394868917704624b63d03a5217c5e94a532a0e3"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:457f5a2e6d8527b5ad7a8bd16586c72ad2ce0aa218a37380f16d07520569ceaf"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3c8a9d53c84724c97d7e298f6628655c19f9911a90b88c362cb7d5daa645464f"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d8442ad863be83be86baff006a6e11de3cddf17c7ee77eac2d389765987b554"}, + {file = "pygit2-1.19.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ae9c775be518c7f20bf340091d329d3b9203cbd4273bf1b5505dc82dccf08147"}, + {file = "pygit2-1.19.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d5a45d466a4bc5d9eb0619ffc26b17e4018285e35ba9e2fe39576f13480b63bc"}, + {file = "pygit2-1.19.1-cp314-cp314t-win32.whl", hash = "sha256:6621acaaf2670e8fd0727c15271e5209a99769b127300ef7fc56b49babc8b1c1"}, + {file = "pygit2-1.19.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4418dea6936fe3c1a9375d7cd31a69e72997e645e588ed31c40d785c71adde35"}, + {file = "pygit2-1.19.1-cp314-cp314t-win_arm64.whl", hash = "sha256:3cbb8ab952224c0b305aa56f8759bcad5d9a9de885b00fe0ff8bed9ac365472e"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3c56ef9ac89e020ca005a39db4e045792b1ce98c2450a53f79815e9d831c006a"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a6d89079f3af32f25abb8680eabea31143a4f02f3d1da6644c296ba89b6a2fc"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bfd44dc6f1d5b1165cc2097c39000c4a5cc05443d27a3a5f2791ad338f52b07"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0aca00ff7e3420f9c06d9386b0bfc76c18fd8a2c5234412db0e200a6cc47ed03"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f89f047667a218b71ebc96c398aca1e5109f149045a8d59ca9fd4a557d1e932e"}, + {file = "pygit2-1.19.1.tar.gz", hash = "sha256:3165f784aae56a309a27d8eeae7923d53da2e8f6094308c7f5b428deec925cf9"}, ] [package.dependencies] @@ -1671,14 +1743,14 @@ files = [ [[package]] name = "setuptools" -version = "80.9.0" +version = "80.10.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, - {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, + {file = "setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173"}, + {file = "setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70"}, ] [package.extras] @@ -1692,14 +1764,14 @@ type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.deve [[package]] name = "tomlkit" -version = "0.13.3" +version = "0.14.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, ] [[package]] @@ -1728,14 +1800,14 @@ files = [ [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] diff --git a/gcp/api/run_apitester.py b/gcp/api/run_apitester.py new file mode 100644 index 00000000000..281063a320b --- /dev/null +++ b/gcp/api/run_apitester.py @@ -0,0 +1,72 @@ +# Copyright 2025 Google LLC +# +# 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. +"""Run E2E golang cassette API tests.""" + +import os +import sys +import subprocess +import time +import test_server + +_PORT = 8080 + + +def main(): + if len(sys.argv) < 2: + print(f'Usage: {sys.argv[0]} path/to/credential.json') + sys.exit(1) + + credential_path = sys.argv[1] + + # Ensure Docker image is pulled + subprocess.run( + ['docker', 'pull', 'gcr.io/endpoints-release/endpoints-runtime:2'], + check=True) + + print("Starting test server...") + server = test_server.start(credential_path, port=_PORT) + + # Wait for server to start up + time.sleep(10) + + try: + # Determine API URL + if os.getenv('CLOUDBUILD'): + host = test_server.get_cloudbuild_esp_host() + else: + host = 'localhost' + + api_base_url = f"{host}:{_PORT}" + print(f"Running Go tests against {api_base_url}") + + env = os.environ.copy() + env['OSV_API_BASE_URL'] = api_base_url + + # Go tests path + # Assuming this script is in gcp/api/ + go_test_dir = os.path.abspath( + os.path.join(os.path.dirname(__file__), '../../tools/apitester')) + + cmd = ['go', 'test', './...'] + print(f"Executing: {' '.join(cmd)} in {go_test_dir}") + + subprocess.run(cmd, cwd=go_test_dir, env=env, check=True) + + finally: + print("Stopping test server...") + server.stop() + + +if __name__ == '__main__': + main() diff --git a/gcp/api/run_tests.sh b/gcp/api/run_tests.sh index 697dfdbd372..bada310ec4e 100755 --- a/gcp/api/run_tests.sh +++ b/gcp/api/run_tests.sh @@ -24,6 +24,9 @@ service docker start # Set -e later as service docker start should be able to successfully fail set -e -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python server_test.py poetry run python integration_tests.py "$1" diff --git a/gcp/api/run_tests_e2e.sh b/gcp/api/run_tests_e2e.sh new file mode 100755 index 00000000000..aebf45a5e02 --- /dev/null +++ b/gcp/api/run_tests_e2e.sh @@ -0,0 +1,31 @@ +#!/bin/bash -x +# Copyright 2025 Google LLC +# +# 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. + +if [ $# -lt 1 ]; then + echo "Usage: $0 /path/to/credential.json" + exit 1 +fi + +export GOOGLE_CLOUD_PROJECT=oss-vdb-test OSV_VULNERABILITIES_BUCKET=osv-test-vulnerabilities + +# Try to start docker if not running (mostly for CI) +service docker start || true + +set -e + +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi +poetry run python run_apitester.py "$1" diff --git a/gcp/api/server.py b/gcp/api/server.py index 47d1fbbf695..1f25d0c9f59 100644 --- a/gcp/api/server.py +++ b/gcp/api/server.py @@ -25,7 +25,6 @@ import threading import time import concurrent.futures -from typing import Callable from collections import defaultdict @@ -100,11 +99,6 @@ _TEST_INSTANCE = 'oss-vdb-test' -# ---- -# Type Aliases: - -ToResponseCallable = Callable[[osv.Bug], ndb.Future] - # ---- _ndb_client = ndb.Client() @@ -392,9 +386,9 @@ def Check(self, request, context: grpc.ServicerContext): del request # Unused. del context # Unused. - # Read up to a single Bug entity from the DB. This should not cause an - # exception or time out. - osv.Bug.query().fetch(1) + # Read up to a single Vulnerability entity from the DB. + # This should not cause an exception or time out. + osv.Vulnerability.query().fetch(1) return health_pb2.HealthCheckResponse( status=health_pb2.HealthCheckResponse.ServingStatus.SERVING) @@ -965,12 +959,6 @@ def query_package(context: QueryContext, if not package_name: return [] - if (package_name.startswith('linux') and ecosystem.startswith('Ubuntu') and - version): - result = yield query_ubuntu_linux(context, package_name, ecosystem, version, - include_details) - return result - # Ideally, we'd check both unnormalized and normalized named at once, if there # is no provided ecosystem (even though that is not explicitly supported), but # Datastore cannot give cursors for 'OR' queries, so just only normalize if @@ -981,6 +969,18 @@ def query_package(context: QueryContext, query = osv.AffectedVersions.query(osv.AffectedVersions.name == package_name) if ecosystem: query = query.filter(osv.AffectedVersions.ecosystem == ecosystem) + if version: + helper = ecosystems.get(ecosystem) + if helper is not None: + try: + coarse = helper.coarse_version(version) + query = query.filter(osv.AffectedVersions.coarse_min <= coarse) + query = query.filter(osv.AffectedVersions.coarse_max >= coarse) + except (ValueError, NotImplementedError): + # We want to avoid logging user requests. + pass + # TODO(michaelkedar): I think a ValueError would mean the version + # would not match any affected versions, so we may be able to return. query = query.order(osv.AffectedVersions.vuln_id) bugs = [] @@ -1147,56 +1147,6 @@ def cleanup(_: ndb.Future): return future -@ndb.tasklet -def query_ubuntu_linux(context: QueryContext, - package_name: str, - ecosystem: str, - version: str, - include_details: bool = True) -> list[ndb.Future]: - """Workaround query for linux kernel vulns in Ubuntu, because there's heaps of - them and it takes a while to check all the version ranges. - - The logic here is copied from the original implementation of server.py, - using the Bug entity to perform matching on only the version strings, and not - doing range-based matching. - """ - - query = osv.Bug.query( - osv.Bug.status == osv.BugStatus.PROCESSED, - osv.Bug.project == package_name, - # pylint: disable=singleton-comparison - osv.Bug.public == True, - osv.Bug.ecosystem == ecosystem, - osv.Bug.affected_fuzzy == version) - - bugs = [] - it: ndb.QueryIterator = query.iter(start_cursor=context.cursor_at_current()) - while (yield it.has_next_async()): - if context.should_break_page(len(bugs)): - context.save_cursor_at_page_break(it) - break - - bug: osv.Bug = it.next() - for affected in bug.affected_packages: - eco = affected.package.ecosystem - if ecosystem not in (eco, ecosystems.normalize(eco), - ecosystems.remove_variants(eco)): - continue - if package_name != affected.package.name: - continue - if version not in affected.versions: - continue - # Found a match: retrieve the proto from the bucket / Vulnerability entity - if include_details: - bugs.append(get_vuln_async(bug.db_id)) - else: - bugs.append(get_minimal_async(bug.db_id)) - context.total_responses.add(1) - break - - return bugs - - def serve(port: int, local: bool): """Configures and runs the OSV API server.""" server = grpc.server(concurrent.futures.ThreadPoolExecutor(max_workers=5)) diff --git a/gcp/datastore/index.yaml b/gcp/datastore/index.yaml index a1504ca13ca..9211b025c94 100644 --- a/gcp/datastore/index.yaml +++ b/gcp/datastore/index.yaml @@ -123,6 +123,14 @@ indexes: properties: - name: name - name: vuln_id + + - kind: AffectedVersions + properties: + - name: ecosystem + - name: name + - name: vuln_id + - name: coarse_min + - name: coarse_max # Indexes for website /list search - kind: ListedVulnerability diff --git a/gcp/functions/pypi/poetry.lock b/gcp/functions/pypi/poetry.lock index 18edf6c46d4..f376860d8c9 100644 --- a/gcp/functions/pypi/poetry.lock +++ b/gcp/functions/pypi/poetry.lock @@ -12,28 +12,16 @@ files = [ {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] -[[package]] -name = "cachetools" -version = "6.2.4" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "cachetools-6.2.4-py3-none-any.whl", hash = "sha256:69a7a52634fed8b8bf6e24a050fb60bff1c9bd8f6d24572b99c32d4e71e62a51"}, - {file = "cachetools-6.2.4.tar.gz", hash = "sha256:82c5c05585e70b6ba2d3ae09ea60b79548872185d2f24ae1f2709d37299fd607"}, -] - [[package]] name = "certifi" -version = "2025.11.12" +version = "2026.1.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, - {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, + {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, ] [[package]] @@ -318,14 +306,14 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "google-api-core" -version = "2.28.1" +version = "2.29.0" description = "Google API client core library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c"}, - {file = "google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8"}, + {file = "google_api_core-2.29.0-py3-none-any.whl", hash = "sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9"}, + {file = "google_api_core-2.29.0.tar.gz", hash = "sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7"}, ] [package.dependencies] @@ -351,42 +339,42 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] [[package]] name = "google-auth" -version = "2.45.0" +version = "2.48.0" description = "Google Authentication Library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "google_auth-2.45.0-py2.py3-none-any.whl", hash = "sha256:82344e86dc00410ef5382d99be677c6043d72e502b625aa4f4afa0bdacca0f36"}, - {file = "google_auth-2.45.0.tar.gz", hash = "sha256:90d3f41b6b72ea72dd9811e765699ee491ab24139f34ebf1ca2b9cc0c38708f3"}, + {file = "google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f"}, + {file = "google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce"}, ] [package.dependencies] -cachetools = ">=2.0.0,<7.0" +cryptography = ">=38.0.3" pyasn1-modules = ">=0.2.1" rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] -cryptography = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)"] -enterprise-cert = ["cryptography", "pyopenssl"] -pyjwt = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyjwt (>=2.0)"] -pyopenssl = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +cryptography = ["cryptography (>=38.0.3)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0)"] -testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "mock", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] urllib3 = ["packaging", "urllib3"] [[package]] name = "google-cloud-appengine-logging" -version = "1.7.0" +version = "1.8.0" description = "Google Cloud Appengine Logging API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_appengine_logging-1.7.0-py3-none-any.whl", hash = "sha256:cfd28bc61a030008381a646d112ebe2734bf72abc8c12afc47d035a2c9b041fe"}, - {file = "google_cloud_appengine_logging-1.7.0.tar.gz", hash = "sha256:ea9ce73430cfc99f8957fd7df97733f9a759d4caab65e19d63a7474f012ffd94"}, + {file = "google_cloud_appengine_logging-1.8.0-py3-none-any.whl", hash = "sha256:a4ce9ce94a9fd8c89ed07fa0b06fcf9ea3642f9532a1be1a8c7b5f82c0a70ec6"}, + {file = "google_cloud_appengine_logging-1.8.0.tar.gz", hash = "sha256:84b705a69e4109fc2f68dfe36ce3df6a34d5c3d989eee6d0ac1b024dda0ba6f5"}, ] [package.dependencies] @@ -557,14 +545,14 @@ protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4 [[package]] name = "google-cloud-storage" -version = "3.7.0" +version = "3.8.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_storage-3.7.0-py3-none-any.whl", hash = "sha256:469bc9540936e02f8a4bfd1619e9dca1e42dec48f95e4204d783b36476a15093"}, - {file = "google_cloud_storage-3.7.0.tar.gz", hash = "sha256:9ce59c65f4d6e372effcecc0456680a8d73cef4f2dc9212a0704799cb3d69237"}, + {file = "google_cloud_storage-3.8.0-py3-none-any.whl", hash = "sha256:78cfeae7cac2ca9441d0d0271c2eb4ebfa21aa4c6944dd0ccac0389e81d955a7"}, + {file = "google_cloud_storage-3.8.0.tar.gz", hash = "sha256:cc67952dce84ebc9d44970e24647a58260630b7b64d72360cedaf422d6727f28"}, ] [package.dependencies] @@ -813,21 +801,21 @@ type = ["mypy (<1.19) ; platform_python_implementation == \"PyPy\"", "pytest-myp [[package]] name = "jsonschema" -version = "4.25.1" +version = "4.26.0" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, - {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, ] [package.dependencies] attrs = ">=22.2.0" jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" -rpds-py = ">=0.7.1" +rpds-py = ">=0.25.0" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -944,14 +932,14 @@ test = ["pytest"] [[package]] name = "packaging" -version = "25.0" +version = "26.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, ] [[package]] @@ -989,34 +977,34 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "6.33.2" +version = "6.33.4" description = "" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d"}, - {file = "protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4"}, - {file = "protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f"}, - {file = "protobuf-6.33.2-cp39-cp39-win32.whl", hash = "sha256:7109dcc38a680d033ffb8bf896727423528db9163be1b6a02d6a49606dcadbfe"}, - {file = "protobuf-6.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:2981c58f582f44b6b13173e12bb8656711189c2a70250845f264b877f00b1913"}, - {file = "protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c"}, - {file = "protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4"}, + {file = "protobuf-6.33.4-cp310-abi3-win32.whl", hash = "sha256:918966612c8232fc6c24c78e1cd89784307f5814ad7506c308ee3cf86662850d"}, + {file = "protobuf-6.33.4-cp310-abi3-win_amd64.whl", hash = "sha256:8f11ffae31ec67fc2554c2ef891dcb561dae9a2a3ed941f9e134c2db06657dbc"}, + {file = "protobuf-6.33.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2fe67f6c014c84f655ee06f6f66213f9254b3a8b6bda6cda0ccd4232c73c06f0"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:757c978f82e74d75cba88eddec479df9b99a42b31193313b75e492c06a51764e"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c7c64f259c618f0bef7bee042075e390debbf9682334be2b67408ec7c1c09ee6"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:3df850c2f8db9934de4cf8f9152f8dc2558f49f298f37f90c517e8e5c84c30e9"}, + {file = "protobuf-6.33.4-cp39-cp39-win32.whl", hash = "sha256:955478a89559fa4568f5a81dce77260eabc5c686f9e8366219ebd30debf06aa6"}, + {file = "protobuf-6.33.4-cp39-cp39-win_amd64.whl", hash = "sha256:0f12ddbf96912690c3582f9dffb55530ef32015ad8e678cd494312bd78314c4f"}, + {file = "protobuf-6.33.4-py3-none-any.whl", hash = "sha256:1fe3730068fcf2e595816a6c34fe66eeedd37d51d0400b72fabc848811fdc1bc"}, + {file = "protobuf-6.33.4.tar.gz", hash = "sha256:dc2e61bca3b10470c1912d166fe0af67bfc20eb55971dcef8dfa48ce14f0ed91"}, ] [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, - {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, + {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"}, + {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"}, ] [[package]] @@ -1036,74 +1024,81 @@ pyasn1 = ">=0.6.1,<0.7.0" [[package]] name = "pycparser" -version = "2.23" +version = "3.0" description = "C parser in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] markers = "implementation_name != \"PyPy\"" files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, ] [[package]] name = "pygit2" -version = "1.19.0" +version = "1.19.1" description = "Python bindings for libgit2." optional = false python-versions = ">=3.11" groups = ["main"] files = [ - {file = "pygit2-1.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:12ee8dc6d14573811ba52a18b37d4f6f42e66e0fcef7ed7d4b5e799bc66455f5"}, - {file = "pygit2-1.19.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae8fe208d11bbfb2dd2716ac8871764c847d1db29f40a1bb20b469df652ca0e3"}, - {file = "pygit2-1.19.0-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18c13b8c49402d007b58744379c455d56526eae16bb9059b2a578d43dd8dfc40"}, - {file = "pygit2-1.19.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f23387f555f6a7224657c7cec618b374c7b01fc617b38ca551859bb69548ed53"}, - {file = "pygit2-1.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a29bd5db67631ac526dbab327f6e254e33e44aa14169055621da6c94636e7e2c"}, - {file = "pygit2-1.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6d7a90a3cfa55b828c912c1817a1c8c4d5a0988df0958371c122774e997a6c3e"}, - {file = "pygit2-1.19.0-cp311-cp311-win32.whl", hash = "sha256:30266cf1e679a24f689d753931d465bedc7e1270a8aa10abe9065a78439a5558"}, - {file = "pygit2-1.19.0-cp311-cp311-win_amd64.whl", hash = "sha256:c6f519790957936dcc54849b901af0cc1cec7aef3be1eb336184b1790a41ebf2"}, - {file = "pygit2-1.19.0-cp311-cp311-win_arm64.whl", hash = "sha256:8a7e7ef28a457643bc6a4d17ca4b437db5f5e400926efda4d269a597a6350e4e"}, - {file = "pygit2-1.19.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:770e1d506ceb08cc65ac0de4e8a9911a169603361c23c3386556a8aab7ee1f7e"}, - {file = "pygit2-1.19.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db2a75f4a2e896a8b09bcfdeb1d52c0fc72b403e0e9910c03307d5e577e3fb40"}, - {file = "pygit2-1.19.0-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2600ed9acc3b6f52e49a65c2200e5eadd70ef6d022fd8e029adbfa6e6d9cbf50"}, - {file = "pygit2-1.19.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:795dce83170f4b82fa275a6233ee3f70673a06a3e22a1c57221e16b9a140ef98"}, - {file = "pygit2-1.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b26875600a8720196d0cdaacdb485761ac07334512a44da79d7b2398672549f7"}, - {file = "pygit2-1.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b5dd263e0d3820892e0751b344eab30f5fb068f20a456e2b2fc2082160d263fe"}, - {file = "pygit2-1.19.0-cp312-cp312-win32.whl", hash = "sha256:1314c81d3608201be032ff1631392f92c767b65d3c81f7efb4e83a551b65290d"}, - {file = "pygit2-1.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:f7efa3fe6d818b48561bc5b72bd991eb57c0baaafc864b64b27f9d064761e557"}, - {file = "pygit2-1.19.0-cp312-cp312-win_arm64.whl", hash = "sha256:c433b9d448912ba7237cb26149b43252b6187acebfa205edf53cfde9e0e441bb"}, - {file = "pygit2-1.19.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e84d4a1c8bcd462524bf9d0c5778c2219042c8aeeea82735e8f415d8f8519797"}, - {file = "pygit2-1.19.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5998943514b89fd4bf8ab11320872bc4c0b6d3517b27beaf79ff9591d3142f1c"}, - {file = "pygit2-1.19.0-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:38ea299bd02584df017f44a0673157bb7b28a2ae69826cfbb456f7429e781d58"}, - {file = "pygit2-1.19.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:46f5f287f19053eb1ba36d72a7458712bc5dcdb1b667ecf162a6cae7e643afe2"}, - {file = "pygit2-1.19.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41d9effdc1e54e7bcd14013ea5a86c9dbf9bbc16b7c932d6e0ed96773e0baa68"}, - {file = "pygit2-1.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e74312467a45de208dc157d1053b851b4181c2fabcacc5d9c578a8ef1b367e13"}, - {file = "pygit2-1.19.0-cp313-cp313-win32.whl", hash = "sha256:eb55020bf0bd36e9a4c167c88139a9e20e787b2c66b5c2f60a8a12f3e0334a82"}, - {file = "pygit2-1.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:37ba33c59b8b941f7a2fa1014c11bc847c315ebbaeb92341f7f39efeab75edb2"}, - {file = "pygit2-1.19.0-cp313-cp313-win_arm64.whl", hash = "sha256:f59b39b7f9583fd0e5dbd63b6f156b735293b3b4a1688534a5eb2c695975eb39"}, - {file = "pygit2-1.19.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:db136a24a9b46327f334a960604f5ed5ca138cab57cf54906c82bae147b2f600"}, - {file = "pygit2-1.19.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1487023a52d25d169fd3d5c146475dec0f39dd54586bd55aac810ae0d7809154"}, - {file = "pygit2-1.19.0-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:14bd00877c5b2571d1e8e2e203df35291198a3a9a90602121a8419b540174b8a"}, - {file = "pygit2-1.19.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cb47afb011ef6133e1b938018afa7d6435040d1ae1e84242bf0699dc6960a4cf"}, - {file = "pygit2-1.19.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4d81f578aef1c04cd5169b96aa38f864c0ed1a37249e13bff69b49f12f6ae761"}, - {file = "pygit2-1.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8c97c281d4e24d45b1d93ea844b52ea157a7c1c408e31e53bbb7b969c3168a96"}, - {file = "pygit2-1.19.0-cp314-cp314-win32.whl", hash = "sha256:e69576401664911633351ebbe2a896861a8c1ff531d0375796e61483db39ebd7"}, - {file = "pygit2-1.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:e56a14fcbfb8e07e30d18f21cfb790a74506957fa3ce03c54c02745b5d0152e2"}, - {file = "pygit2-1.19.0-cp314-cp314-win_arm64.whl", hash = "sha256:2e84ab99802d8de643c6f8aa5b689b033ee5d5dee70ae04432005299dec33ee4"}, - {file = "pygit2-1.19.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:12c8f8672fb319ee4276fc028019de4d3e6b9cd94bffc74a1aaa81ffc6445dc7"}, - {file = "pygit2-1.19.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ccddde0826101035ca31f9df42c6a57704285e2387ab15cd314afa18f0521d95"}, - {file = "pygit2-1.19.0-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de1fe1a2dfd10a58d17e88c14b363aa809a480c181b56c47cbc4fa83b0b68918"}, - {file = "pygit2-1.19.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b775d93b7ea9b8ff676002a857eabbe07fbc838802fd76b9b1e17109f571557"}, - {file = "pygit2-1.19.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:21a9bf74720360fcb21a0e6ad750013ba3e0625cd484f1bb7ddfefdcd207c0f5"}, - {file = "pygit2-1.19.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba17b947b2166000aeb9b19135160bb32aec38a7da9892d9fb476cdb3f518aba"}, - {file = "pygit2-1.19.0-cp314-cp314t-win32.whl", hash = "sha256:772bf01936eb306c6dfb3cc3b955e2f8d3271d0eef2c23e24203352519421b20"}, - {file = "pygit2-1.19.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4516e87d35df9b2867b5f859a0d09cd86857f1e3ef4215d6c87850ce4869a793"}, - {file = "pygit2-1.19.0-cp314-cp314t-win_arm64.whl", hash = "sha256:fceba6e279ab2be9ec762f2b3ff1b315cd922de879800d1f57a25eba4a90bc60"}, - {file = "pygit2-1.19.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6163a94e60ccd574c76018fdd19316c3c0671858a83000ea7978c28f55c78fc"}, - {file = "pygit2-1.19.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9ebbd394ce40024499d0e5905d1d26cd2bbc4429a30c2ac13a98f990e84ab88"}, - {file = "pygit2-1.19.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:33a509b4df90e23e87b4118020cabecd1910ede436d90a43c31eec27e33f52ce"}, - {file = "pygit2-1.19.0.tar.gz", hash = "sha256:ca5db6f395a74166a019d777895f96bcb211ee60ce0be4132b139603e0066d83"}, + {file = "pygit2-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b54f3a94648ac8e287f5e4333710d9fe05f9e09de3da232d50df753bb01b643"}, + {file = "pygit2-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e46618a912fc984b8a9f4d8322704620f1315264359c7fa61c899128e23e226"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2eb386b3e98f7056d76bc7e805e8fce3cd0a773cbbb30b0f7e144c0ac37270f2"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f41a9b866676922ac9b0ec60f0dc9735a5d1ba6bb34146a6212dc0012d7959f"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2cdc81ecffd990d8c6dce44a16b1dc4494b5dd5381d6e1f508e459c4bca09e0"}, + {file = "pygit2-1.19.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a1c8645287556aa9b670886dbc0d5daa1d49040511940822fd43dbda13cfe4e8"}, + {file = "pygit2-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e388d1eb0c44d92d8ff01b25eb9a969fc28748966843c2e26e9e084e42567f7d"}, + {file = "pygit2-1.19.1-cp311-cp311-win32.whl", hash = "sha256:815c0b12845253929f2275759d623b3b4093e67e6536d2463177e6ff1d9ff0df"}, + {file = "pygit2-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:93f4986b35984aaaa5e7613ceb1ba4c184d890589df60b0d8d74e7dccec1d8cb"}, + {file = "pygit2-1.19.1-cp311-cp311-win_arm64.whl", hash = "sha256:fef27b206955e66e3a63664e2ec93821e00ce2d917f8b4eae87c738163c00e14"}, + {file = "pygit2-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8e6a4f4a711750c286a13cea0007b40f7466c4d741c3d9b223ffbc3bbfbafe7"}, + {file = "pygit2-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3f2340a668eb3e2d8927dcbeb1a043d3a65d2dd39a913995b34fc437da5e73af"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe41f09b1e334c43def6636b1133d2f4c91a20d9a6691bb4e7558e42a31bcb4e"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:527e57133d30ff6ea96634da6bf428f7d551958207fa73f9e9a18582b885e192"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a9340cb85b7be40080186a9d4dbf712a6be8a842556acbbfb305baebfb854f3"}, + {file = "pygit2-1.19.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:66ecfa69f2287f50ec95dfc04821219c2f664c4cd292c7b33c10ed9afe975132"}, + {file = "pygit2-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:14c76ec968ae20a6689c7b6fa833ef546c7bc176127d71e7b67cb2345a9813fb"}, + {file = "pygit2-1.19.1-cp312-cp312-win32.whl", hash = "sha256:ffe94118d39f6969fda594224b2b6df1ae79306adaf090ede65bcaf1a41b3a81"}, + {file = "pygit2-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:c2ee3f2e91b0a5674ab7cb373234c23cf5f1cf6d84e56e6d12ff3db21414cf47"}, + {file = "pygit2-1.19.1-cp312-cp312-win_arm64.whl", hash = "sha256:c8747d968d8d6b9d390263907f014d38a0f67bd26d8243e5bc3384cb252ec3d3"}, + {file = "pygit2-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:39af62f3e18dfdfb15c347c12b51231fdb3db3c9d5105d9046847ead14b42fce"}, + {file = "pygit2-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed39106f1d9560709191093ed5251471dfb6b9e4aa35299dde45f4b91f7c984e"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb4da746c92e23281890e865887d83f24e662fc3e1c481420e4993c5a13203fe"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:93ccfab2340d38374f91ecf6cae6658bebc73883c376eb81eeb293781f6aef94"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef18f1208422d3cac1c109417a5fc6143704cfff8e5de4e1665fa4a89ffe3902"}, + {file = "pygit2-1.19.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:344f4c1e84eaa2434fbb43d96a1dd79796ab9559587a8533331fef92eab0ec7d"}, + {file = "pygit2-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1ae2f408206c67d395e8dc77425f8ab457cad59faaa58c700164398a62823e82"}, + {file = "pygit2-1.19.1-cp313-cp313-win32.whl", hash = "sha256:9d6cf97c2da5c589b65371a8115be920cf417c46a80a2b12edb26e54a5238190"}, + {file = "pygit2-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:6d73aedffad280f6b655394e303533fcff15545d4d8f322011179c9474bb1b13"}, + {file = "pygit2-1.19.1-cp313-cp313-win_arm64.whl", hash = "sha256:8b067241c03a29440507e78637e233998fe1a11d2082169bd8177694ec4ee747"}, + {file = "pygit2-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d10a46285b9ae39b9de2d9f44ac7f933993aecfab189c2932320b3df596311c8"}, + {file = "pygit2-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d0f3924d8d0d54a7fe186761c76dc1b6e5fcf41794a6daba1630db3bc216b9ba"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4fcc301cfe9c29f3e29f0f80d81ae65c0bee368672b23566467dc91b5edae4b"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3c6eacf82f15e001121dc0f60057f462627045447d8bd8587b33b13159ae5155"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:074b0b14c6f3c7e2c6ea0b01a90832407a71520c920918aa07f509c91f1691f9"}, + {file = "pygit2-1.19.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ada5d3e813e21918e004a33c66aba4a2b829cd5c0c0e85b92dd70f84cf95ac56"}, + {file = "pygit2-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:19ebe25fd8e95ed8a0be0a9dd4cecc1233db4f2a44a2a73984620909e98e907f"}, + {file = "pygit2-1.19.1-cp314-cp314-win32.whl", hash = "sha256:5bc0738a49cceb76f0fba7cdb24532857a980e4a36b9a0da025c359dfe3676b4"}, + {file = "pygit2-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:527d40925bb85b86da0e96ecc90e9ca74d0a0273ab645bac0787b95923d93160"}, + {file = "pygit2-1.19.1-cp314-cp314-win_arm64.whl", hash = "sha256:21c7c8b5aa2f48cefdb8521185f0cd3c110a340e2d9f62a46a94db01a907db73"}, + {file = "pygit2-1.19.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9c5e4eb975b664b6821fe6a05b03bbc51052d1fb22f20652e1d4349ae24ed7ac"}, + {file = "pygit2-1.19.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8752eae5780ee51edae326cac394868917704624b63d03a5217c5e94a532a0e3"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:457f5a2e6d8527b5ad7a8bd16586c72ad2ce0aa218a37380f16d07520569ceaf"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3c8a9d53c84724c97d7e298f6628655c19f9911a90b88c362cb7d5daa645464f"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d8442ad863be83be86baff006a6e11de3cddf17c7ee77eac2d389765987b554"}, + {file = "pygit2-1.19.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ae9c775be518c7f20bf340091d329d3b9203cbd4273bf1b5505dc82dccf08147"}, + {file = "pygit2-1.19.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d5a45d466a4bc5d9eb0619ffc26b17e4018285e35ba9e2fe39576f13480b63bc"}, + {file = "pygit2-1.19.1-cp314-cp314t-win32.whl", hash = "sha256:6621acaaf2670e8fd0727c15271e5209a99769b127300ef7fc56b49babc8b1c1"}, + {file = "pygit2-1.19.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4418dea6936fe3c1a9375d7cd31a69e72997e645e588ed31c40d785c71adde35"}, + {file = "pygit2-1.19.1-cp314-cp314t-win_arm64.whl", hash = "sha256:3cbb8ab952224c0b305aa56f8759bcad5d9a9de885b00fe0ff8bed9ac365472e"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3c56ef9ac89e020ca005a39db4e045792b1ce98c2450a53f79815e9d831c006a"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a6d89079f3af32f25abb8680eabea31143a4f02f3d1da6644c296ba89b6a2fc"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bfd44dc6f1d5b1165cc2097c39000c4a5cc05443d27a3a5f2791ad338f52b07"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0aca00ff7e3420f9c06d9386b0bfc76c18fd8a2c5234412db0e200a6cc47ed03"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f89f047667a218b71ebc96c398aca1e5109f149045a8d59ca9fd4a557d1e932e"}, + {file = "pygit2-1.19.1.tar.gz", hash = "sha256:3165f784aae56a309a27d8eeae7923d53da2e8f6094308c7f5b428deec925cf9"}, ] [package.dependencies] @@ -1437,14 +1432,14 @@ files = [ [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] diff --git a/gcp/indexer/Dockerfile b/gcp/indexer/Dockerfile index 127903f85eb..fe9f533433b 100644 --- a/gcp/indexer/Dockerfile +++ b/gcp/indexer/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD WORKDIR /build # Cache dependencies in these steps @@ -24,7 +24,7 @@ RUN go mod download COPY ./ /build RUN CGO_ENABLED=0 ./build.sh -FROM gcr.io/distroless/base-debian12@sha256:f5a3067027c2b322cd71b844f3d84ad3deada45ceb8a30f301260a602455070e +FROM gcr.io/distroless/base-debian12@sha256:0c70ab46409b94a96f4e98e32e7333050581e75f7038de2877a4bfc146dfc7ce COPY --from=GO_BUILD build/indexer /indexer ENTRYPOINT ["/indexer"] CMD ["--help"] diff --git a/gcp/indexer/go.mod b/gcp/indexer/go.mod index 5fbe8619918..ef54ad3e1ae 100644 --- a/gcp/indexer/go.mod +++ b/gcp/indexer/go.mod @@ -1,23 +1,23 @@ module github.com/google/osv.dev/gcp/indexer -go 1.25.5 +go 1.25.6 require ( cloud.google.com/go/datastore v1.21.0 cloud.google.com/go/pubsub v1.50.1 - cloud.google.com/go/storage v1.58.0 + cloud.google.com/go/storage v1.59.1 github.com/go-git/go-git/v5 v5.16.4 github.com/golang/glog v1.2.5 github.com/google/go-cmp v0.7.0 golang.org/x/sync v0.19.0 - google.golang.org/api v0.259.0 + google.golang.org/api v0.263.0 gopkg.in/yaml.v3 v3.0.1 ) require ( cel.dev/expr v0.24.0 // indirect cloud.google.com/go v0.123.0 // indirect - cloud.google.com/go/auth v0.18.0 // indirect + cloud.google.com/go/auth v0.18.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.5.3 // indirect @@ -45,7 +45,7 @@ require ( github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect github.com/googleapis/gax-go/v2 v2.16.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect @@ -60,20 +60,20 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect - golang.org/x/crypto v0.46.0 // indirect - golang.org/x/net v0.48.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/net v0.49.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d // indirect google.golang.org/grpc v1.78.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/gcp/indexer/go.sum b/gcp/indexer/go.sum index e78065df13e..0744a87c8b7 100644 --- a/gcp/indexer/go.sum +++ b/gcp/indexer/go.sum @@ -3,8 +3,8 @@ cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= -cloud.google.com/go/auth v0.18.0 h1:wnqy5hrv7p3k7cShwAU/Br3nzod7fxoqG+k0VZ+/Pk0= -cloud.google.com/go/auth v0.18.0/go.mod h1:wwkPM1AgE1f2u6dG443MiWoD8C3BtOywNsUMcUTVDRo= +cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= +cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= @@ -25,8 +25,8 @@ cloud.google.com/go/pubsub v1.50.1 h1:fzbXpPyJnSGvWXF1jabhQeXyxdbCIkXTpjXHy7xviB cloud.google.com/go/pubsub v1.50.1/go.mod h1:6YVJv3MzWJUVdvQXG081sFvS0dWQOdnV+oTo++q/xFk= cloud.google.com/go/pubsub/v2 v2.0.0 h1:0qS6mRJ41gD1lNmM/vdm6bR7DQu6coQcVwD+VPf0Bz0= cloud.google.com/go/pubsub/v2 v2.0.0/go.mod h1:0aztFxNzVQIRSZ8vUr79uH2bS3jwLebwK6q1sgEub+E= -cloud.google.com/go/storage v1.58.0 h1:PflFXlmFJjG/nBeR9B7pKddLQWaFaRWx4uUi/LyNxxo= -cloud.google.com/go/storage v1.58.0/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI= +cloud.google.com/go/storage v1.59.1 h1:DXAZLcTimtiXdGqDSnebROVPd9QvRsFVVlptz02Wk58= +cloud.google.com/go/storage v1.59.1/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI= cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U= cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= @@ -132,8 +132,8 @@ github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= +github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y= github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -192,23 +192,23 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= @@ -222,8 +222,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= @@ -242,16 +242,16 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= -golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -262,8 +262,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.259.0 h1:90TaGVIxScrh1Vn/XI2426kRpBqHwWIzVBzJsVZ5XrQ= -google.golang.org/api v0.259.0/go.mod h1:LC2ISWGWbRoyQVpxGntWwLWN/vLNxxKBK9KuJRI8Te4= +google.golang.org/api v0.263.0 h1:UFs7qn8gInIdtk1ZA6eXRXp5JDAnS4x9VRsRVCeKdbk= +google.golang.org/api v0.263.0/go.mod h1:fAU1xtNNisHgOF5JooAs8rRaTkl2rT3uaoNGo9NS3R8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -273,8 +273,8 @@ google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d h1:xXzuihhT3gL/ntduUZwHECzAn57E8dA6l8SOtYWdD8Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/gcp/website/Dockerfile b/gcp/website/Dockerfile index 411cb855545..2c56395977e 100644 --- a/gcp/website/Dockerfile +++ b/gcp/website/Dockerfile @@ -1,5 +1,5 @@ # Build the Javascript frontend -FROM node:20.19@sha256:4b4e58e59c5e042928790c6fccd8ad16da6296bcc2e9924c56fba84a8e5ff662 AS FRONTEND3_BUILD +FROM node:24.13@sha256:b2b2184ba9b78c022e1d6a7924ec6fba577adf28f15c9d9c457730cc4ad3807a AS FRONTEND3_BUILD WORKDIR /build/frontend3 # Install dependencies first for better caching diff --git a/gcp/website/blog/content/posts/2025-in-review/index.md b/gcp/website/blog/content/posts/2025-in-review/index.md new file mode 100644 index 00000000000..48d68ed2504 --- /dev/null +++ b/gcp/website/blog/content/posts/2025-in-review/index.md @@ -0,0 +1,114 @@ +--- +title: "The Year in Review" +date: 2026-01-13T00:00:00Z +draft: false +author: The OSV Team +--- + +2025 has been an eventful year for OSV, marked by significant expansion, infrastructure improvements, and continued community growth across all our projects. + + + +## OSV Data Adoption and Improvements + +We welcomed 11 new data providers, and 11 new ecosystems. Every new data provider helps us improve vulnerability coverage and matching for the open source community. + +**Data Providers:** +- [BELL] BellSoft +- [CLEANSTART] CleanStart (Coming Soon) +- [DRUPAL] Drupal +- [DHI] Docker Hardened Images (Coming Soon) +- [ECHO] Echo +- [EEF] Erlang Ecosystem Foundation +- [FreeBSD] FreeBSD (Coming Soon) +- [JLSEC] Julia +- [MINI] Minimus +- [OESA] openEuler +- [V8] V8 + +**Ecosystems:** +- Alpaquita +- BellSoft Hardened Containers +- CleanStart +- Docker Hardened Images +- Echo +- FreeBSD +- Julia +- Kubernetes +- MinimOS +- openEuler +- VSCode + +### CVE Data Ingestion + +We’ve also begun to diversify our CVE matching data by ingesting directly from the CVE Program’s CVEList as well as the NVD, allowing for more accurate vulnerable ranges. Look out for an upcoming blog post going deeper into this project. + +### Decoupling Alpine and Debian Data + +Following the introduction of the `upstream` field last year, we have separated the Debian and Alpine vulnerability data, which were previously merged with the main NVD CVE record-into distinct records, each with its own prefix. This ensures records only apply to the environments they exist in, significantly reducing false positives–such as preventing Debian vulnerability alerts from appearing on Alpine systems. + +## Infrastructure and Data Quality + +Behind the scenes, we've focused on ensuring OSV.dev remains fast and reliable. + +### API Improvements +Early last year, we [announced the significant improvements on the performance and reliability of the OSV.dev API](https://osv.dev/blog/posts/api-latency-improvements-and-revised-slos/). By implementing a new database indexing strategy, we made API queries up to 5 times faster. This is a substantial improvement, with the 95th percentile latency for batch queries dropping from ~10 seconds to ~3 seconds. This speed increase unlocks new possibilities for real-time CI/CD integration, allowing developers to scan against the API without hitting timeout thresholds. Following these enhancements, we have revised our API SLOs to reflect this new, higher standard of performance. + +### Vanir Signature Integration + +[Vanir](https://github.com/google/vanir) signatures are now available through OSV.dev. To enhance Vanir's coverage of open-source libraries, the OSV.dev worker is now responsible for generating and processing Vanir signatures for all vulnerabilities with GIT affected ranges. In addition, a new public data dump is now available, which provides a JSON file listing all GIT vulnerabilities that have Vanir signatures. This file is designed to simplify the use of Vanir's offline directory scanner. + +### OSV linter + +On the data quality front, we launched an [experimental OSV linter](https://test.osv.dev/linter) to help maintain high consistency across all incoming vulnerability data. This tool checks for consistency beyond schema validation, ensuring high-quality, usable vulnerability data. It allows OSV record creators to integrate these essential quality checks into their workflows, leading to more accurate and immediately useful information. + +### Standardizing core data structure + +We significantly reorganized our core data structures last year to improve consistency and simplify development: + - Migrating `vulnerability.proto` to **OSV-Schema**, establishing it as the authoritative source of truth alongside `schema.json`. + - Transitioning away from manually maintained language bindings in favor of reliable, automatically generated protobuf code. + +This standardization allowed us to successfully deprecate manual bindings across the entire OSV ecosystem. For the open-source community, this eliminates the risk of inconsistencies between protocol definitions and language bindings, while removing the need for tedious manual data conversion. + +## Community + +![Image shows the GitHub star history for all OSV-related GitHub repositories taken at Jan 6, 2026.](star-history-202616.png "GitHub star history for all OSV repos, as of 2026/1/6") + +Last year saw sustained interest and external contributions across all our major repositories: + - **OSV Schema**: 32 contributors + - **OSV.dev**: 28 total contributors + - **OSV-Scanner**: 33 total contributors + - **OSV-Scalibr**: 52 total contributors + +Notably, the **OSV-Scanner GitHub Action** has been adopted by **over 1600 GitHub repositories**, demonstrating its value to the developer community. + +### Conferences + +We also engaged with the community at several key events, with OSV-related presentations at: + - **VulnCon (Raleigh):** Presented [“Let’s Talk About Fitness for Purpose: Comparing and Contrasting the CVE List with OSV.dev”](https://youtu.be/qHcpKW2nOqI?si=IXJ_B7qfdlU0DnOs) + - **RSAC Conference (San Francisco)** + - **Open Source Summit (Denver):** Presented [“Navigating the Sea of CVEs: Securing Your Linux Distribution”](https://youtu.be/Vsp-RuwJM8c?si=YBc-vQS9ZSuSArh4) + - **OpenSSF Community Day (Denver):** Presented [“Myths Developers Believe About Open Source Security”](https://youtu.be/bjEyIPSpLRw?si=P9mwNM5TtK8e9Z9N) + - **Diana Initiative (Las Vegas):** Presented [“Insecurity in Security: Maintainer Support”](https://youtu.be/l5VJtpuqYTM?si=n2VxkFRZl7MOXPJo) + - **Google Developer Groups DevFest (Sydney and Auckland)** + +## Tooling + +Our tooling (OSV-Scanner and OSV-Scalibr) continues to evolve with a focus on developer experience and accuracy. Key updates last year include: + - **Scalibr feature unification** to streamline the tooling experience. + - Launch of an **experimental MCP server**, allowing AI agents (like Claude or ChatGPT) to query the OSV database directly for live vulnerability intelligence. + - Enhanced Python vulnerability management including **transitive dependency scanning for `requirements.txt`** and **Guided Remediation for Python**. + - Improvements to **Reachability Analysis for Java**. + +## More to Come in 2026 + +We're already looking forward to the year ahead with ambitious goals to continue improving OSV. + +**Data Precision and Trust:** + - Delivering higher quality CVE records + - Achieving full filesystem accountability + - Introducing a public metrics dashboard + +**AI and Automation:** + - Expanding VEX support and reachability features + - Integrating LLM agents to further assist developers diff --git a/gcp/website/blog/content/posts/2025-in-review/star-history-202616.png b/gcp/website/blog/content/posts/2025-in-review/star-history-202616.png new file mode 100644 index 0000000000000000000000000000000000000000..611715082f7696e09a25941d99e9d94d108ff996 GIT binary patch literal 482764 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�*}uwvC^G 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

1Ul3(e^3+{!I*hb> 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 literal 0 HcmV?d00001 diff --git a/gcp/website/cloudbuild.yaml b/gcp/website/cloudbuild.yaml index 95ec59eb424..4fd73299be1 100644 --- a/gcp/website/cloudbuild.yaml +++ b/gcp/website/cloudbuild.yaml @@ -44,3 +44,6 @@ steps: waitFor: ['init', 'sync'] timeout: 7200s +options: + env: + - CLOUDBUILD=1 diff --git a/gcp/website/frontend3/package-lock.json b/gcp/website/frontend3/package-lock.json index baef09f9934..334794f89e4 100644 --- a/gcp/website/frontend3/package-lock.json +++ b/gcp/website/frontend3/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "@github/clipboard-copy-element": "1.3.0", - "@hotwired/turbo": "7.3.0", + "@hotwired/turbo": "8.0.21", "@material/data-table": "13.0.0", "@material/layout-grid": "13.0.0", "@material/theme": "13.0.0", @@ -18,18 +18,18 @@ "spicy-sections": "git+https://github.com/tabvengers/spicy-sections.git#c3aae99dbf1e627cdf03a35c913d7f6e970de22b" }, "devDependencies": { - "copy-webpack-plugin": "10.2.4", - "css-loader": "6.11.0", - "html-webpack-plugin": "5.6.5", - "mini-css-extract-plugin": "2.9.4", - "raw-loader": "4.0.2", - "sass": "1.97.2", - "sass-loader": "12.6.0", - "style-loader": "3.3.4", - "webpack": "5.104.1", - "webpack-bundle-analyzer": "4.10.2", - "webpack-cli": "4.10.0", - "webpack-dev-server": "5.2.2" + "copy-webpack-plugin": "^13.0.0", + "css-loader": "^7.1.3", + "html-webpack-plugin": "^5.6.6", + "mini-css-extract-plugin": "^2.10.0", + "raw-loader": "^4.0.2", + "sass": "^1.97.3", + "sass-loader": "^16.0.0", + "style-loader": "^4.0.0", + "webpack": "^5.104.1", + "webpack-bundle-analyzer": "^5.0.0", + "webpack-cli": "^6.0.0", + "webpack-dev-server": "^5.2.3" } }, "node_modules/@discoveryjs/json-ext": { @@ -49,12 +49,12 @@ "license": "MIT" }, "node_modules/@hotwired/turbo": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@hotwired/turbo/-/turbo-7.3.0.tgz", - "integrity": "sha512-Dcu+NaSvHLT7EjrDrkEmH4qET2ZJZ5IcCWmNXxNQTBwlnE5tBZfN6WxZ842n5cHV52DH/AKNirbPBtcEXDLW4g==", + "version": "8.0.21", + "resolved": "https://registry.npmjs.org/@hotwired/turbo/-/turbo-8.0.21.tgz", + "integrity": "sha512-fJTv3JnzFHeDxBb23esZSOhT4r142xf5o3lKMFMvzPC6AllkqbBKk5Yb31UZhtIsKQCwmO/pUQrtTUlYl5CHAQ==", "license": "MIT", "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@jridgewell/gen-mapping": { @@ -125,9 +125,9 @@ } }, "node_modules/@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.65.0.tgz", + "integrity": "sha512-eBrIXd0/Ld3p9lpDDlMaMn6IEfWqtHMD+z61u0JrIiPzsV1r7m6xDZFRxJyvIFTEO+SWdYF9EiQbXZGd8BzPfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -158,6 +158,282 @@ "tslib": "2" } }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.56.10.tgz", + "integrity": "sha512-PyAEA/3cnHhsGcdY+AmIU+ZPqTuZkDhCXQ2wkXypdLitSpd6d5Ivxhnq4wa2ETRWFVJGabYynBWxIijOswSmOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.56.10", + "@jsonjoy.com/fs-node-utils": "4.56.10", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.10.tgz", + "integrity": "sha512-/FVK63ysNzTPOnCCcPoPHt77TOmachdMS422txM4KhxddLdbW1fIbFMYH0AM0ow/YchCyS5gqEjKLNyv71j/5Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.10", + "@jsonjoy.com/fs-node-builtins": "4.56.10", + "@jsonjoy.com/fs-node-utils": "4.56.10", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.56.10.tgz", + "integrity": "sha512-7R4Gv3tkUdW3dXfXiOkqxkElxKNVdd8BDOWC0/dbERd0pXpPY+s2s1Mino+aTvkGrFPiY+mmVxA7zhskm4Ue4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.10", + "@jsonjoy.com/fs-node-builtins": "4.56.10", + "@jsonjoy.com/fs-node-utils": "4.56.10", + "@jsonjoy.com/fs-print": "4.56.10", + "@jsonjoy.com/fs-snapshot": "4.56.10", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.10.tgz", + "integrity": "sha512-uUnKz8R0YJyKq5jXpZtkGV9U0pJDt8hmYcLRrPjROheIfjMXsz82kXMgAA/qNg0wrZ1Kv+hrg7azqEZx6XZCVw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.10.tgz", + "integrity": "sha512-oH+O6Y4lhn9NyG6aEoFwIBNKZeYy66toP5LJcDOMBgL99BKQMUf/zWJspdRhMdn/3hbzQsZ8EHHsuekbFLGUWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.56.10", + "@jsonjoy.com/fs-node-builtins": "4.56.10", + "@jsonjoy.com/fs-node-utils": "4.56.10" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.10.tgz", + "integrity": "sha512-8EuPBgVI2aDPwFdaNQeNpHsyqPi3rr+85tMNG/lHvQLiVjzoZsvxA//Xd8aB567LUhy4QS03ptT+unkD/DIsNg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.56.10" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.56.10.tgz", + "integrity": "sha512-JW4fp5mAYepzFsSGrQ48ep8FXxpg4niFWHdF78wDrFGof7F3tKDJln72QFDEn/27M1yHd4v7sKHHVPh78aWcEw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.56.10", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.10.tgz", + "integrity": "sha512-DkR6l5fj7+qj0+fVKm/OOXMGfDFCGXLfyHkORH3DF8hxkpDgIHbhf/DwncBMs2igu/ST7OEkexn1gIqoU6Y+9g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.56.10", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.65.0.tgz", + "integrity": "sha512-Xrh7Fm/M0QAYpekSgmskdZYnFdSGnsxJ/tHaolA4bNwWdG9i65S8m83Meh7FOxyJyQAdo4d4J97NOomBLEfkDQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.65.0.tgz", + "integrity": "sha512-7MXcRYe7n3BG+fo3jicvjB0+6ypl2Y/bQp79Sp7KeSiiCgLqw4Oled6chVv07/xLVTdo3qa1CD0VCCnPaw+RGA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.65.0.tgz", + "integrity": "sha512-e0SG/6qUCnVhHa0rjDJHgnXnbsacooHVqQHxspjvlYQSkHm+66wkHw6Gql+3u/WxI/b1VsOdUi0M+fOtkgKGdQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.65.0", + "@jsonjoy.com/buffers": "17.65.0", + "@jsonjoy.com/codegen": "17.65.0", + "@jsonjoy.com/json-pointer": "17.65.0", + "@jsonjoy.com/util": "17.65.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.65.0.tgz", + "integrity": "sha512-uhTe+XhlIZpWOxgPcnO+iSCDgKKBpwkDVTyYiXX9VayGV8HSFVJM67M6pUE71zdnXF1W0Da21AvnhlmdwYPpow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.65.0.tgz", + "integrity": "sha512-cWiEHZccQORf96q2y6zU3wDeIVPeidmGqd9cNKJRYoVHTV0S1eHPy5JTbHpMnGfDvtvujQwQozOqgO9ABu6h0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.65.0", + "@jsonjoy.com/codegen": "17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@jsonjoy.com/json-pack": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", @@ -185,6 +461,23 @@ "tslib": "2" } }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@jsonjoy.com/json-pointer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", @@ -227,6 +520,23 @@ "tslib": "2" } }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", @@ -235,9 +545,9 @@ "license": "MIT" }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.0.tgz", - "integrity": "sha512-HLomZXMmrCFHSRKESF5vklAKsDY7/fsT/ZhqCu3V0UoW/Qbv8wxmO4W9bx4KnCCF2Zak4yuk+AGraK/bPmI4kA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.1.tgz", + "integrity": "sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA==", "license": "BSD-3-Clause" }, "node_modules/@lit/reactive-element": { @@ -606,57 +916,32 @@ "tslib": "^2.4.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "node": ">= 16" }, - "engines": { - "node": ">= 8" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.3", "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">= 10.0.0" @@ -666,25 +951,25 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" } }, "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", "cpu": [ "arm64" ], @@ -703,9 +988,9 @@ } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", "cpu": [ "arm64" ], @@ -724,9 +1009,9 @@ } }, "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", "cpu": [ "x64" ], @@ -745,9 +1030,9 @@ } }, "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", "cpu": [ "x64" ], @@ -766,9 +1051,9 @@ } }, "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", "cpu": [ "arm" ], @@ -787,9 +1072,9 @@ } }, "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", "cpu": [ "arm" ], @@ -808,9 +1093,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", "cpu": [ "arm64" ], @@ -829,9 +1114,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", "cpu": [ "arm64" ], @@ -850,9 +1135,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", "cpu": [ "x64" ], @@ -871,9 +1156,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", "cpu": [ "x64" ], @@ -892,9 +1177,9 @@ } }, "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", "cpu": [ "arm64" ], @@ -913,9 +1198,9 @@ } }, "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", "cpu": [ "ia32" ], @@ -934,9 +1219,9 @@ } }, "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", "cpu": [ "x64" ], @@ -954,6 +1239,165 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.0.tgz", + "integrity": "sha512-2uZqP+ggSncESeUF/9Su8rWqGclEfEiz1SyU02WX5fUONFfkjzS2Z/F1Li0ofSmf4JqYXIOdCAZqIXAIBAT1OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "@peculiar/asn1-x509-attr": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.0.tgz", + "integrity": "sha512-BeWIu5VpTIhfRysfEp73SGbwjjoLL/JWXhJ/9mo4vXnz3tRGm+NGm3KNcRzQ9VMVqwYS2RHlolz21svzRXIHPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.0.tgz", + "integrity": "sha512-FF3LMGq6SfAOwUG2sKpPXblibn6XnEIKa+SryvUl5Pik+WR9rmRA3OCiwz8R3lVXnYnyRkSZsSLdml8H3UiOcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.0.tgz", + "integrity": "sha512-rtUvtf+tyKGgokHHmZzeUojRZJYPxoD/jaN1+VAB4kKR7tXrnDCA/RAWXAIhMJJC+7W27IIRGe9djvxKgsldCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-pkcs8": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.0.tgz", + "integrity": "sha512-KyQ4D8G/NrS7Fw3XCJrngxmjwO/3htnA0lL9gDICvEQ+GJ+EPFqldcJQTwPIdvx98Tua+WjkdKHSC0/Km7T+lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.0.tgz", + "integrity": "sha512-b78OQ6OciW0aqZxdzliXGYHASeCvvw5caqidbpQRYW2mBtXIX2WhofNXTEe7NyxTb0P6J62kAAWLwn0HuMF1Fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-pfx": "^2.6.0", + "@peculiar/asn1-pkcs8": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "@peculiar/asn1-x509-attr": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.0.tgz", + "integrity": "sha512-Nu4C19tsrTsCp9fDrH+sdcOKoVfdfoQQ7S3VqjJU6vedR7tY3RLkQ5oguOIB3zFW33USDUuYZnPEQYySlgha4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", + "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.0.tgz", + "integrity": "sha512-uzYbPEpoQiBoTq0/+jZtpM6Gq6zADBx+JNFP3yqRgziWBxQ/Dt/HcuvRfm9zJTPdRcBqPNdaRHTVwpyiq6iNMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.0.tgz", + "integrity": "sha512-MuIAXFX3/dc8gmoZBkwJWxUWOSvG4MMDntXhrOZpJVMkYX+MYc/rUAU2uJOved9iJEoiUx7//3D8oG83a78UJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", @@ -1046,9 +1490,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", "dev": true, "license": "MIT", "dependencies": { @@ -1097,25 +1541,15 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", - "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~7.16.0" } }, - "node_modules/@types/node-forge": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", - "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", @@ -1368,37 +1802,45 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", + "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", "dev": true, "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", + "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", "dev": true, "license": "MIT", - "dependencies": { - "envinfo": "^7.7.3" + "engines": { + "node": ">=18.12.0" }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", + "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -1570,6 +2012,19 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -1577,23 +2032,25 @@ "dev": true, "license": "MIT" }, - "node_modules/array-union": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", - "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "node_modules/asn1js": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", + "integrity": "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=12.0.0" } }, "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "version": "2.9.18", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz", + "integrity": "sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1754,6 +2211,16 @@ "node": ">= 0.8" } }, + "node_modules/bytestreamjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz", + "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1797,9 +2264,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001762", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", - "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", "dev": true, "funding": [ { @@ -1971,21 +2438,20 @@ "license": "MIT" }, "node_modules/copy-webpack-plugin": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz", - "integrity": "sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz", + "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==", "dev": true, "license": "MIT", "dependencies": { - "fast-glob": "^3.2.7", "glob-parent": "^6.0.1", - "globby": "^12.0.2", "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" }, "engines": { - "node": ">= 12.20.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", @@ -2018,23 +2484,23 @@ } }, "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.3.tgz", + "integrity": "sha512-frbERmjT0UC5lMheWpJmMilnt9GEhbZJN/heUb7/zaJYeIzj5St9HvDcfshzzOqbsS+rYpMk++2SD3vGETDSyA==", "dev": true, "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.33", + "postcss": "^8.4.40", "postcss-modules-extract-imports": "^3.1.0", "postcss-modules-local-by-default": "^4.0.5", "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" + "semver": "^7.6.3" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", @@ -2042,7 +2508,7 @@ }, "peerDependencies": { "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" + "webpack": "^5.27.0" }, "peerDependenciesMeta": { "@rspack/core": { @@ -2178,17 +2644,14 @@ } }, "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "optional": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, "engines": { - "node": ">=0.10" + "node": ">=8" } }, "node_modules/detect-node": { @@ -2198,19 +2661,6 @@ "dev": true, "license": "MIT" }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", @@ -2319,13 +2769,6 @@ "node": ">= 0.4" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true, - "license": "MIT" - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2334,9 +2777,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.279", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.279.tgz", + "integrity": "sha512-0bblUU5UNdOt5G7XqGiJtpZMONma6WAfq9vsFmtn9x1+joAObr6x1chfqyxFSDCAFwFhCQDrqeAr6MYdpwJ9Hg==", "dev": true, "license": "ISC" }, @@ -2595,36 +3038,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2659,16 +3072,6 @@ "node": ">= 4.9.1" } }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -2682,6 +3085,24 @@ "node": ">=0.8.0" } }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2880,27 +3301,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/globby": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", - "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^3.0.1", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.7", - "ignore": "^5.1.9", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -2916,26 +3316,10 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" }, "node_modules/handle-thing": { "version": "2.0.1", @@ -3066,9 +3450,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.6.5", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.5.tgz", - "integrity": "sha512-4xynFbKNNk+WlzXeQQ+6YYsH2g7mpfPszQZUi3ovKlj+pDmngQ7vRXjrrmGROabmKwyQkcgcX5hqfOwHbFmK5g==", + "version": "5.6.6", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.6.tgz", + "integrity": "sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==", "dev": true, "license": "MIT", "dependencies": { @@ -3229,16 +3613,6 @@ "postcss": "^8.1.0" } }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/immutable": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", @@ -3274,13 +3648,13 @@ "license": "ISC" }, "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=10.13.0" } }, "node_modules/ipaddr.js": { @@ -3521,16 +3895,6 @@ "node": ">=0.10.0" } }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/launch-editor": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz", @@ -3616,9 +3980,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, @@ -3653,12 +4017,20 @@ } }, "node_modules/memfs": { - "version": "4.51.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.51.1.tgz", - "integrity": "sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ==", + "version": "4.56.10", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.56.10.tgz", + "integrity": "sha512-eLvzyrwqLHnLYalJP7YZ3wBe79MXktMdfQbvMrVD80K+NhrIukCVBvgP30zTJYEEDh9hZ/ep9z0KOdD7FSHo7w==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@jsonjoy.com/fs-core": "4.56.10", + "@jsonjoy.com/fs-fsa": "4.56.10", + "@jsonjoy.com/fs-node": "4.56.10", + "@jsonjoy.com/fs-node-builtins": "4.56.10", + "@jsonjoy.com/fs-node-to-fsa": "4.56.10", + "@jsonjoy.com/fs-node-utils": "4.56.10", + "@jsonjoy.com/fs-print": "4.56.10", + "@jsonjoy.com/fs-snapshot": "4.56.10", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", @@ -3669,6 +4041,9 @@ "funding": { "type": "github", "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, "node_modules/merge-descriptors": { @@ -3688,16 +4063,6 @@ "dev": true, "license": "MIT" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -3722,6 +4087,19 @@ "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -3759,9 +4137,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", - "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.0.tgz", + "integrity": "sha512-540P2c5dYnJlyJxTaSloliZexv8rji6rY8FhQN+WF/82iHQfA23j/xtJx97L+mXOML27EqksSek/g4eK7jaL3g==", "dev": true, "license": "MIT", "dependencies": { @@ -3872,16 +4250,6 @@ "license": "MIT", "optional": true }, - "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", - "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/node-releases": { "version": "2.0.27", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", @@ -4107,16 +4475,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -4125,13 +4483,14 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -4150,6 +4509,24 @@ "node": ">=8" } }, + "node_modules/pkijs": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.3.3.tgz", + "integrity": "sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@noble/hashes": "1.4.0", + "asn1js": "^3.0.6", + "bytestreamjs": "^2.0.1", + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -4316,6 +4693,26 @@ "node": ">=6" } }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", + "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/qs": { "version": "6.14.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", @@ -4332,27 +4729,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -4494,18 +4870,25 @@ } }, "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "license": "MIT", "dependencies": { - "resolve": "^1.9.0" + "resolve": "^1.20.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 10.13.0" } }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -4601,17 +4984,6 @@ "node": ">= 4" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", @@ -4625,30 +4997,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4678,9 +5026,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.97.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.2.tgz", - "integrity": "sha512-y5LWb0IlbO4e97Zr7c3mlpabcbBtS+ieiZ9iwDooShpFKWXf62zz5pEPdwrLYm+Bxn1fnbwFGzHuCLSA9tBmrw==", + "version": "1.97.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", + "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "dev": true, "license": "MIT", "peer": true, @@ -4700,31 +5048,30 @@ } }, "node_modules/sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "version": "16.0.6", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.6.tgz", + "integrity": "sha512-sglGzId5gmlfxNs4gK2U3h7HlVRfx278YK6Ono5lwzuvi1jxig80YiuHkaDBVsYIKFhx8wN7XSCI0M2IDS/3qA==", "dev": true, "license": "MIT", "dependencies": { - "klona": "^2.0.4", "neo-async": "^2.6.2" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", "sass": "^1.3.0", "sass-embedded": "*", "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "fibers": { + "@rspack/core": { "optional": true }, "node-sass": { @@ -4735,6 +5082,9 @@ }, "sass-embedded": { "optional": true + }, + "webpack": { + "optional": true } } }, @@ -4766,17 +5116,17 @@ "license": "MIT" }, "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz", + "integrity": "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==", "dev": true, "license": "MIT", "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" + "@peculiar/x509": "^1.14.2", + "pkijs": "^3.3.3" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/semver": { @@ -4835,22 +5185,26 @@ } }, "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz", + "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==", "dev": true, "license": "MIT", "dependencies": { - "accepts": "~1.3.4", + "accepts": "~1.3.8", "batch": "0.6.1", "debug": "2.6.9", "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" + "http-errors": "~1.8.0", + "mime-types": "~2.1.35", + "parseurl": "~1.3.3" }, "engines": { "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/serve-index/node_modules/depd": { @@ -4864,35 +5218,22 @@ } }, "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "license": "MIT", "dependencies": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.6" } }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true, - "license": "ISC" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true, - "license": "ISC" - }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -5052,9 +5393,9 @@ } }, "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", "dependencies": { @@ -5063,20 +5404,7 @@ "totalist": "^3.0.0" }, "engines": { - "node": ">= 10" - } - }, - "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, "node_modules/sockjs": { @@ -5244,20 +5572,20 @@ } }, "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "webpack": "^5.27.0" } }, "node_modules/supports-color": { @@ -5304,9 +5632,9 @@ } }, "node_modules/terser": { - "version": "5.44.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", - "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5388,6 +5716,23 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5445,6 +5790,26 @@ "license": "0BSD", "peer": true }, + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -5562,9 +5927,9 @@ } }, "node_modules/watchpack": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz", - "integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, "license": "MIT", "dependencies": { @@ -5636,9 +6001,9 @@ } }, "node_modules/webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.2.0.tgz", + "integrity": "sha512-Etrauj1wYO/xjiz/Vfd6bW1lG9fEhrJpNmu10tv0X9kv+gyY3qiE09uYepqg1Xd0PxOvllRXwWYWjtQYoO/glQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5648,18 +6013,17 @@ "commander": "^7.2.0", "debounce": "^1.2.1", "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", "html-escaper": "^2.0.2", "opener": "^1.5.2", "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" + "sirv": "^3.0.2", + "ws": "^8.19.0" }, "bin": { "webpack-bundle-analyzer": "lib/bin/analyzer.js" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 20.9.0" } }, "node_modules/webpack-bundle-analyzer/node_modules/commander": { @@ -5673,45 +6037,40 @@ } }, "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", + "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", "dev": true, "license": "MIT", "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", + "@discoveryjs/json-ext": "^0.6.1", + "@webpack-cli/configtest": "^3.0.1", + "@webpack-cli/info": "^3.0.1", + "@webpack-cli/serve": "^3.0.1", "colorette": "^2.0.14", - "commander": "^7.0.0", + "commander": "^12.1.0", "cross-spawn": "^7.0.3", + "envinfo": "^7.14.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^6.0.1" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=10.13.0" + "node": ">=18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "webpack": "^5.82.0" }, "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "@webpack-cli/migrate": { - "optional": true - }, "webpack-bundle-analyzer": { "optional": true }, @@ -5720,14 +6079,24 @@ } } }, + "node_modules/webpack-cli/node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=18" } }, "node_modules/webpack-dev-middleware": { @@ -5788,15 +6157,15 @@ } }, "node_modules/webpack-dev-server": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", - "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz", + "integrity": "sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==", "dev": true, "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^4.17.21", + "@types/express": "^4.17.25", "@types/express-serve-static-core": "^4.17.21", "@types/serve-index": "^1.9.4", "@types/serve-static": "^1.15.5", @@ -5806,9 +6175,9 @@ "bonjour-service": "^1.2.1", "chokidar": "^3.6.0", "colorette": "^2.0.10", - "compression": "^1.7.4", + "compression": "^1.8.1", "connect-history-api-fallback": "^2.0.0", - "express": "^4.21.2", + "express": "^4.22.1", "graceful-fs": "^4.2.6", "http-proxy-middleware": "^2.0.9", "ipaddr.js": "^2.1.0", @@ -5816,7 +6185,7 @@ "open": "^10.0.3", "p-retry": "^6.2.0", "schema-utils": "^4.2.0", - "selfsigned": "^2.4.1", + "selfsigned": "^5.5.0", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", @@ -5883,6 +6252,19 @@ "node": ">= 6" } }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/webpack-dev-server/node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -5896,41 +6278,19 @@ "node": ">=8.10.0" } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", - "wildcard": "^2.0.0" + "wildcard": "^2.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, "node_modules/webpack-sources": { @@ -5992,17 +6352,17 @@ "license": "MIT" }, "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { diff --git a/gcp/website/frontend3/package.json b/gcp/website/frontend3/package.json index 7c821474ca9..da15c599493 100644 --- a/gcp/website/frontend3/package.json +++ b/gcp/website/frontend3/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@github/clipboard-copy-element": "1.3.0", - "@hotwired/turbo": "7.3.0", + "@hotwired/turbo": "8.0.21", "@material/data-table": "13.0.0", "@material/layout-grid": "13.0.0", "@material/theme": "13.0.0", @@ -19,17 +19,17 @@ "spicy-sections": "git+https://github.com/tabvengers/spicy-sections.git#c3aae99dbf1e627cdf03a35c913d7f6e970de22b" }, "devDependencies": { - "copy-webpack-plugin": "10.2.4", - "css-loader": "6.11.0", - "html-webpack-plugin": "5.6.5", - "mini-css-extract-plugin": "2.9.4", - "raw-loader": "4.0.2", - "sass": "1.97.2", - "sass-loader": "12.6.0", - "style-loader": "3.3.4", - "webpack": "5.104.1", - "webpack-bundle-analyzer": "4.10.2", - "webpack-cli": "4.10.0", - "webpack-dev-server": "5.2.2" + "copy-webpack-plugin": "^13.0.0", + "css-loader": "^7.1.3", + "html-webpack-plugin": "^5.6.6", + "mini-css-extract-plugin": "^2.10.0", + "raw-loader": "^4.0.2", + "sass": "^1.97.3", + "sass-loader": "^16.0.0", + "style-loader": "^4.0.0", + "webpack": "^5.104.1", + "webpack-bundle-analyzer": "^5.0.0", + "webpack-cli": "^6.0.0", + "webpack-dev-server": "^5.2.3" } } diff --git a/gcp/website/frontend3/src/styles.scss b/gcp/website/frontend3/src/styles.scss index da501ef6109..10740b59234 100644 --- a/gcp/website/frontend3/src/styles.scss +++ b/gcp/website/frontend3/src/styles.scss @@ -20,6 +20,7 @@ $osv-heading-line-height: 70px; $osv-heading-line-height-mobile: 50px; $osv-mobile-breakpoint: 500px; $osv-border-radius-small: 4px; +$osv-border-color: #555; @use '@material/theme' with ($surface: $osv-background, ); @@ -1800,6 +1801,22 @@ div.highlight { max-width: 800px; width: 100%; margin: 0 auto; + + table { + margin: 1em auto; + + th, + td { + padding: 0.75em 1em; + text-align: left; + border: 1px solid $osv-border-color; + } + + th { + font-weight: 600; + background: $osv-grey-800; + } + } } .author { diff --git a/gcp/website/poetry.lock b/gcp/website/poetry.lock index 8c2ad3d6c4a..df3814176c2 100644 --- a/gcp/website/poetry.lock +++ b/gcp/website/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "astroid" @@ -569,6 +569,83 @@ files = [ ] markers = {main = "platform_system == \"Windows\"", dev = "sys_platform == \"win32\""} +[[package]] +name = "cryptography" +version = "46.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, + {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, + {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, + {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, + {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, + {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, + {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, + {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, + {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, + {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, + {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, +] + +[package.dependencies] +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "cvss" version = "3.6" @@ -583,14 +660,14 @@ files = [ [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" description = "serialize all of Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, - {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, ] [package.extras] @@ -656,14 +733,14 @@ flask = "*" [[package]] name = "google-api-core" -version = "2.28.1" +version = "2.29.0" description = "Google API client core library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c"}, - {file = "google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8"}, + {file = "google_api_core-2.29.0-py3-none-any.whl", hash = "sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9"}, + {file = "google_api_core-2.29.0.tar.gz", hash = "sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7"}, ] [package.dependencies] @@ -689,41 +766,42 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] [[package]] name = "google-auth" -version = "2.47.0" +version = "2.48.0" description = "Google Authentication Library" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "google_auth-2.47.0-py3-none-any.whl", hash = "sha256:c516d68336bfde7cf0da26aab674a36fedcf04b37ac4edd59c597178760c3498"}, - {file = "google_auth-2.47.0.tar.gz", hash = "sha256:833229070a9dfee1a353ae9877dcd2dec069a8281a4e72e72f77d4a70ff945da"}, + {file = "google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f"}, + {file = "google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce"}, ] [package.dependencies] +cryptography = ">=38.0.3" pyasn1-modules = ">=0.2.1" rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] cryptography = ["cryptography (>=38.0.3)"] -enterprise-cert = ["cryptography", "pyopenssl"] -pyjwt = ["cryptography (>=38.0.3)", "pyjwt (>=2.0)"] -pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0)"] -testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (>=38.0.3)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] urllib3 = ["packaging", "urllib3"] [[package]] name = "google-cloud-appengine-logging" -version = "1.7.0" +version = "1.8.0" description = "Google Cloud Appengine Logging API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_appengine_logging-1.7.0-py3-none-any.whl", hash = "sha256:cfd28bc61a030008381a646d112ebe2734bf72abc8c12afc47d035a2c9b041fe"}, - {file = "google_cloud_appengine_logging-1.7.0.tar.gz", hash = "sha256:ea9ce73430cfc99f8957fd7df97733f9a759d4caab65e19d63a7474f012ffd94"}, + {file = "google_cloud_appengine_logging-1.8.0-py3-none-any.whl", hash = "sha256:a4ce9ce94a9fd8c89ed07fa0b06fcf9ea3642f9532a1be1a8c7b5f82c0a70ec6"}, + {file = "google_cloud_appengine_logging-1.8.0.tar.gz", hash = "sha256:84b705a69e4109fc2f68dfe36ce3df6a34d5c3d989eee6d0ac1b024dda0ba6f5"}, ] [package.dependencies] @@ -1194,21 +1272,21 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.25.1" +version = "4.26.0" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, - {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, ] [package.dependencies] attrs = ">=22.2.0" jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" -rpds-py = ">=0.7.1" +rpds-py = ">=0.25.0" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1427,14 +1505,14 @@ test = ["pytest"] [[package]] name = "packaging" -version = "25.0" +version = "26.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, ] [[package]] @@ -1489,34 +1567,34 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "6.33.2" +version = "6.33.4" description = "" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d"}, - {file = "protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4"}, - {file = "protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f"}, - {file = "protobuf-6.33.2-cp39-cp39-win32.whl", hash = "sha256:7109dcc38a680d033ffb8bf896727423528db9163be1b6a02d6a49606dcadbfe"}, - {file = "protobuf-6.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:2981c58f582f44b6b13173e12bb8656711189c2a70250845f264b877f00b1913"}, - {file = "protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c"}, - {file = "protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4"}, + {file = "protobuf-6.33.4-cp310-abi3-win32.whl", hash = "sha256:918966612c8232fc6c24c78e1cd89784307f5814ad7506c308ee3cf86662850d"}, + {file = "protobuf-6.33.4-cp310-abi3-win_amd64.whl", hash = "sha256:8f11ffae31ec67fc2554c2ef891dcb561dae9a2a3ed941f9e134c2db06657dbc"}, + {file = "protobuf-6.33.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2fe67f6c014c84f655ee06f6f66213f9254b3a8b6bda6cda0ccd4232c73c06f0"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:757c978f82e74d75cba88eddec479df9b99a42b31193313b75e492c06a51764e"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c7c64f259c618f0bef7bee042075e390debbf9682334be2b67408ec7c1c09ee6"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:3df850c2f8db9934de4cf8f9152f8dc2558f49f298f37f90c517e8e5c84c30e9"}, + {file = "protobuf-6.33.4-cp39-cp39-win32.whl", hash = "sha256:955478a89559fa4568f5a81dce77260eabc5c686f9e8366219ebd30debf06aa6"}, + {file = "protobuf-6.33.4-cp39-cp39-win_amd64.whl", hash = "sha256:0f12ddbf96912690c3582f9dffb55530ef32015ad8e678cd494312bd78314c4f"}, + {file = "protobuf-6.33.4-py3-none-any.whl", hash = "sha256:1fe3730068fcf2e595816a6c34fe66eeedd37d51d0400b72fabc848811fdc1bc"}, + {file = "protobuf-6.33.4.tar.gz", hash = "sha256:dc2e61bca3b10470c1912d166fe0af67bfc20eb55971dcef8dfa48ce14f0ed91"}, ] [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, - {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, + {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"}, + {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"}, ] [[package]] @@ -1536,15 +1614,15 @@ pyasn1 = ">=0.6.1,<0.7.0" [[package]] name = "pycparser" -version = "2.23" +version = "3.0" description = "C parser in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] markers = "implementation_name != \"PyPy\"" files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, ] [[package]] @@ -1956,14 +2034,14 @@ files = [ [[package]] name = "tomlkit" -version = "0.13.3" +version = "0.14.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, ] [[package]] @@ -1980,14 +2058,14 @@ files = [ [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] @@ -2067,4 +2145,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.13,<4.0" -content-hash = "16edff8e2601cc5dad22cff598f01b1e0005039bd970c7b1cb6b1c122346e441" +content-hash = "c2bdf1a07e9a43487dabb9f2207d454990d4d7dff8b58306819f5a983f588fe3" diff --git a/gcp/website/pyproject.toml b/gcp/website/pyproject.toml index cf9105edacb..0e6a24da2f2 100644 --- a/gcp/website/pyproject.toml +++ b/gcp/website/pyproject.toml @@ -6,7 +6,7 @@ dependencies = [ "Flask-Caching==2.3.1", "Flask-Compress==1.23", "werkzeug==3.1.5", - "google-auth==2.47.0", + "google-auth==2.48.0", "google-cloud-ndb==2.4.0", "google-cloud-logging==3.13.0", "google-cloud-storage==2.19.0", diff --git a/gcp/website/run_tests.sh b/gcp/website/run_tests.sh index 16b8ac94842..466375c80d3 100755 --- a/gcp/website/run_tests.sh +++ b/gcp/website/run_tests.sh @@ -2,5 +2,8 @@ export GOOGLE_CLOUD_PROJECT=fake-project123 -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python frontend_handlers_test.py diff --git a/gcp/workers/alias/run_tests.sh b/gcp/workers/alias/run_tests.sh index 99ec9363e1e..c453dc477da 100755 --- a/gcp/workers/alias/run_tests.sh +++ b/gcp/workers/alias/run_tests.sh @@ -15,6 +15,9 @@ cd ../worker -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python ../alias/alias_computation_test.py poetry run python ../alias/upstream_computation_test.py diff --git a/gcp/workers/cloudbuild.yaml b/gcp/workers/cloudbuild.yaml index 3dd03038892..d8b3d9ff9fe 100644 --- a/gcp/workers/cloudbuild.yaml +++ b/gcp/workers/cloudbuild.yaml @@ -73,3 +73,5 @@ steps: timeout: 7200s options: machineType: E2_HIGHCPU_8 + env: + - CLOUDBUILD=1 diff --git a/gcp/workers/importer/importer.py b/gcp/workers/importer/importer.py index e738dd09d65..55824172287 100755 --- a/gcp/workers/importer/importer.py +++ b/gcp/workers/importer/importer.py @@ -176,22 +176,6 @@ def _git_callbacks(self, source_repo): self._ssh_key_public_path, self._ssh_key_private_path) - def _request_analysis(self, bug, source_repo, repo): - """Request analysis.""" - if bug.source_of_truth == osv.SourceOfTruth.SOURCE_REPO: - path = osv.source_path(source_repo, bug) - file_path = os.path.join(osv.repo_path(repo), path) - if not os.path.exists(file_path): - logging.info( - 'Skipping analysis for %s as the source file no longer exists.', - path) - return - - original_sha256 = osv.sha256(file_path) - self._request_analysis_external(source_repo, original_sha256, path) - else: - self._request_internal_analysis(bug) - def _request_analysis_external(self, source_repo, original_sha256, @@ -229,7 +213,7 @@ def _request_internal_analysis(self, bug): req_timestamp=str(int(time.time()))) def _infer_id_from_invalid_data(self, name: str, content: bytes) -> str: - """Best effort infer the bug ID for data that failed to parse. + """Best effort infer the vulnerability ID for data that failed to parse. First try and extract something that looks like an "id" field, and failing that, try to infer from the filename. @@ -296,9 +280,9 @@ def _record_quality_finding( def run(self): """Run importer.""" for source_repo in osv.SourceRepository.query(): + if source_repo.name == 'oss-fuzz': + continue try: - if not self._delete and source_repo.name == 'oss-fuzz': - self.process_oss_fuzz(source_repo) self.validate_source_repo(source_repo) if not self._delete: self.process_updates(source_repo) @@ -315,84 +299,6 @@ def checkout(self, source_repo): git_callbacks=self._git_callbacks(source_repo), branch=source_repo.repo_branch) - def import_new_oss_fuzz_entries(self, repo, oss_fuzz_source): - """Import new entries.""" - exported = [] - for bug in osv.Bug.query( - osv.Bug.source_of_truth == osv.SourceOfTruth.INTERNAL): - if bug.status != osv.BugStatus.PROCESSED: - continue - - if not bug.public: - continue - - # We don't index this as INTERNAL generally implies OSS-Fuzz anyway (at - # time of writing). - source_name, _ = osv.parse_source_id(bug.source_id) - if source_name != oss_fuzz_source.name: - continue - - vulnerability_path = os.path.join( - osv.repo_path(repo), osv.source_path(oss_fuzz_source, bug)) - os.makedirs(os.path.dirname(vulnerability_path), exist_ok=True) - if os.path.exists(vulnerability_path): - continue - - logging.info('Writing %s', bug.key.id()) - osv.write_vulnerability(bug.to_vulnerability(), vulnerability_path) - # The source of truth is now this yaml file. - bug.source_of_truth = osv.SourceOfTruth.SOURCE_REPO - exported.append(bug) - - # Commit Vulnerability changes back to the oss-fuzz source repository. - repo.index.add_all() - diff = repo.index.diff_to_tree(repo.head.peel().tree) - if not diff: - logging.info('No new entries, skipping committing.') - return - - logging.info('Committing and pushing new entries') - if osv.push_source_changes(repo, 'Import from OSS-Fuzz', - self._git_callbacks(oss_fuzz_source)): - ndb.put_multi(exported) - - def schedule_regular_updates(self, repo, source_repo: osv.SourceRepository): - """Schedule regular updates.""" - aest_time_now = aestnow() - - if (source_repo.last_update_date and - # OSV devs are mostly located in australia, - # so only schedule update near midnight sydney time - source_repo.last_update_date.date() >= aest_time_now.date()): - return - - for bug in osv.Bug.query( - osv.Bug.status == osv.BugStatus.PROCESSED, - osv.Bug.is_fixed == False, # pylint: disable=singleton-comparison - osv.Bug.source == source_repo.name): - self._request_analysis(bug, source_repo, repo) - - # yapf: disable - # Perform a re-analysis on existing oss-fuzz bugs for a period of time, - # more vulnerable releases might be made even though fixes have - # already been merged into master/main - cutoff_time = aest_time_now - datetime.timedelta(days=_BUG_REDO_DAYS) - query = osv.Bug.query(osv.Bug.status == osv.BugStatus.PROCESSED, - osv.Bug.source == source_repo.name, - osv.Bug.timestamp >= cutoff_time) - # yapf: enable - - for bug in query: - logging.info('Re-requesting impact for %s.', bug.key.id()) - if not bug.is_fixed: - # Previous query already requested impact tasks for unfixed bugs. - continue - - self._request_analysis(bug, source_repo, repo) - - source_repo.last_update_date = aest_time_now - source_repo.put() - def _vuln_ids_from_gcs_blob(self, client: storage.Client, source_repo: osv.SourceRepository, blob: storage.Blob) -> Optional[Tuple[str]]: @@ -524,10 +430,10 @@ def _convert_blob_to_vuln( # This is the typical execution path (when reimporting not triggered) with ndb_ctx: for vuln in vulns: - bug = osv.Bug.get_by_id(vuln.id) - # The bug already exists and has been modified since last import - if (bug is None or - bug.import_last_modified != vuln.modified.ToDatetime(datetime.UTC)): + v = osv.Vulnerability.get_by_id(vuln.id) + # The vuln already exists and has been modified since last import + if (v is None or + v.modified_raw != vuln.modified.ToDatetime(datetime.UTC)): return blob_hash, blob.name, blob.updated, vulns return None @@ -633,9 +539,9 @@ def _process_updates_git(self, source_repo: osv.SourceRepository): logging.error('Failed to parse %s: %s', changed_entry, str(e)) with open(path, "rb") as f: content = f.read() - bug_id = self._infer_id_from_invalid_data( + vuln_id = self._infer_id_from_invalid_data( os.path.basename(path), content) - self._record_quality_finding(source_repo.name, bug_id) + self._record_quality_finding(source_repo.name, vuln_id) # Don't include error stack trace as that might leak sensitive info import_failure_logs.append('Failed to parse vulnerability "' + path + '"') @@ -728,9 +634,9 @@ def _process_updates_bucket(self, source_repo: osv.SourceRepository): logging.error('Failed to parse vulnerability %s: %s', blob.name, e) # TODO(apollock): log finding here # This feels gross to redownload it again. - bug_id = self._infer_id_from_invalid_data(blob.name, - blob.download_as_bytes()) - self._record_quality_finding(source_repo.name, bug_id) + vuln_id = self._infer_id_from_invalid_data(blob.name, + blob.download_as_bytes()) + self._record_quality_finding(source_repo.name, vuln_id) import_failure_logs.append( 'Failed to parse vulnerability (when considering for import) "' + blob.name + '"') @@ -763,10 +669,10 @@ def _process_deletions_bucket(self, threshold: float = 10.0): """Process deletions from a GCS bucket source. - This validates the continued existence of every Bug in Datastore (for the - given source) against every bug currently in that source's GCS bucket, - calculating the delta. The bugs determined to have been - deleted from GCS are then flagged for treatment by the worker. + This validates the continued existence of every Vulnerability in Datastore + (for the given source) against every vulnerability currently in that + source's GCS bucket, calculating the delta. The vulnerabilities determined + to have been deleted from GCS are then flagged for treatment by the worker. If the delta is too large, something undesirable has been assumed to have happened and further processing is aborted. @@ -778,30 +684,29 @@ def _process_deletions_bucket(self, logging.info('Begin processing bucket for deletions: %s', source_repo.name) - # Get all the existing non-withdrawn Bug IDs for + # Get all the existing non-withdrawn Vulnerability IDs for # source_repo.name in Datastore - query = osv.Bug.query() - query = query.filter(osv.Bug.source == source_repo.name) + query = osv.Vulnerability.query() + # everything with source_id starting with 'name:' + query = query.filter(osv.Vulnerability.source_id > source_repo.name + ':', + osv.Vulnerability.source_id < source_repo.name + ';') result = list(query.fetch(keys_only=False)) - result.sort(key=lambda r: r.id()) + result.sort(key=lambda r: r.key.id()) VulnAndSource = namedtuple('VulnAndSource', ['id', 'path']) logging.info('Retrieved %s results from query', len(result)) vuln_ids_for_source = [ - VulnAndSource(id=r.id(), path=r.source_id.partition(':')[2]) + VulnAndSource(id=r.key.id(), path=r.source_id.partition(':')[2]) for r in result - if not r.withdrawn + if not r.is_withdrawn ] logging.info( - 'Counted %d Bugs for %s in Datastore', + 'Counted %d Vulnerabilities for %s in Datastore', len(vuln_ids_for_source), source_repo.name, - extra={ - 'json_fields': { - 'vuln_ids_for_source': vuln_ids_for_source, - 'source_repo': source_repo.name, - } - }) + extra={'json_fields': { + 'source_repo': source_repo.name, + }}) storage_client = storage.Client() # Get all of the existing records in the GCS bucket @@ -854,11 +759,13 @@ def _process_deletions_bucket(self, v for v in vuln_ids_for_source if v.id not in vuln_ids_in_gcs ] - logging.info('%d Bugs in Datastore considered deleted from GCS for %s', - len(vulns_to_delete), source_repo.name) + logging.info( + '%d Vulnerabilities in Datastore considered deleted from GCS for %s', + len(vulns_to_delete), source_repo.name) if len(vulns_to_delete) == 0: - logging.info('No bugs to delete from GCS for %s', source_repo.name) + logging.info('No vulnerabilities to delete from GCS for %s', + source_repo.name) replace_importer_log(storage_client, source_repo.name, self._public_log_bucket, import_failure_logs) return @@ -985,10 +892,10 @@ def _process_updates_rest(self, source_repo: osv.SourceRepository): except Exception as e: logging.error('Failed to parse %s: %s', str(single_vuln.content), str(e)) - bug_id = self._infer_id_from_invalid_data( + vuln_id = self._infer_id_from_invalid_data( source_repo.link + vuln.id + source_repo.extension, single_vuln.content) - self._record_quality_finding(source_repo.name, bug_id) + self._record_quality_finding(source_repo.name, vuln_id) continue ts = None if ignore_last_import else vuln_modified @@ -1025,10 +932,11 @@ def _process_deletions_rest(self, threshold: float = 10.0): """Process deletions from a REST bucket source. - This validates the continued existence of every Bug in Datastore (for the - given source) against every bug currently in that source's REST API, - calculating the delta. The bugs determined to have been - deleted from the REST API are then flagged for treatment by the worker. + This validates the continued existence of every Vulnerability in Datastore + (for the given source) against every vulnerability currently in that + source's REST API, calculating the delta. The vulnerabilities determined + to have been deleted from the REST API are then flagged for treatment by + the worker. If the number of deletions exceeds the safety threshold (default 10%), the operation is aborted unless ignore_deletion_threshold is set on the @@ -1036,30 +944,29 @@ def _process_deletions_rest(self, """ logging.info('Begin processing REST for deletions: %s', source_repo.name) - # Get all the existing non-withdrawn Bug IDs for + # Get all the existing non-withdrawn Vulnerability IDs for # source_repo.name in Datastore - query = osv.Bug.query() - query = query.filter(osv.Bug.source == source_repo.name) + query = osv.Vulnerability.query() + # everything with source_id starting with 'name:' + query = query.filter(osv.Vulnerability.source_id > source_repo.name + ':', + osv.Vulnerability.source_id < source_repo.name + ';') result = list(query.fetch(keys_only=False)) - result.sort(key=lambda r: r.id()) + result.sort(key=lambda r: r.key.id()) VulnAndSource = namedtuple('VulnAndSource', ['id', 'path']) logging.info('Retrieved %s results from query', len(result)) vuln_ids_for_source = [ - VulnAndSource(id=r.id(), path=r.source_id.partition(':')[2]) + VulnAndSource(id=r.key.id(), path=r.source_id.partition(':')[2]) for r in result - if not r.withdrawn + if not r.is_withdrawn ] logging.info( - 'Counted %d Bugs for %s in Datastore', + 'Counted %d Vulnerabilities for %s in Datastore', len(vuln_ids_for_source), source_repo.name, - extra={ - 'json_fields': { - 'vuln_ids_for_source': vuln_ids_for_source, - 'source_repo': source_repo.name, - } - }) + extra={'json_fields': { + 'source_repo': source_repo.name, + }}) s = requests.Session() adapter = HTTPAdapter( @@ -1097,11 +1004,13 @@ def _process_deletions_rest(self, v for v in vuln_ids_for_source if v.id not in vuln_ids_in_rest ] - logging.info('%d Bugs in Datastore considered deleted from REST for %s', - len(vulns_to_delete), source_repo.name) + logging.info( + '%d Vulnerabilities in Datastore considered deleted from REST for %s', + len(vulns_to_delete), source_repo.name) if len(vulns_to_delete) == 0: - logging.info('No bugs to delete from REST for %s', source_repo.name) + logging.info('No vulnerabilities to delete from REST for %s', + source_repo.name) return # sanity check: deleting a lot/all of the records for source in Datastore is @@ -1168,50 +1077,6 @@ def process_deletions(self, source_repo: osv.SourceRepository): logging.error('Invalid repo type: %s - %d', source_repo.name, source_repo.type) - def process_oss_fuzz(self, oss_fuzz_source): - """Process OSS-Fuzz source data.""" - # Export OSS-Fuzz Vulnerability data into source repository. - # OSS-Fuzz data is first imported via a special Pub/Sub pipeline into OSV. - # This data needs to be dumped into a publicly accessible/editable place for - # manual/human editing if required. - # - # This then becomes the source of truth where any edits are imported back - # into OSV. - repo = self.checkout(oss_fuzz_source) - self.schedule_regular_updates(repo, oss_fuzz_source) - self.import_new_oss_fuzz_entries(repo, oss_fuzz_source) - self.export_oss_fuzz_to_bucket() - - def export_oss_fuzz_to_bucket(self): - """Export OSS-Fuzz vulns to bucket.""" - storage_client = storage.Client() - bucket = storage_client.get_bucket(self._oss_fuzz_export_bucket) - - def export_oss_fuzz(vulnerability, testcase_id, issue_id): - """Export a single vulnerability.""" - try: - blob = bucket.blob(f'testcase/{testcase_id}.json') - data = json.dumps(osv.vulnerability_to_dict(vulnerability)) - blob.upload_from_string(data, retry=retry.DEFAULT_RETRY) - - if not issue_id: - return - - blob = bucket.blob(f'issue/{issue_id}.json') - blob.upload_from_string(data, retry=retry.DEFAULT_RETRY) - except Exception as e: - logging.error('Failed to export: %s', e) - - with concurrent.futures.ThreadPoolExecutor( - max_workers=_EXPORT_WORKERS) as executor: - for bug in osv.Bug.query(osv.Bug.ecosystem == 'OSS-Fuzz'): - if not bug.public: - continue - - _, source_id = osv.parse_source_id(bug.source_id) - executor.submit(export_oss_fuzz, bug.to_vulnerability(), source_id, - bug.issue_id) - def preprocess_vuln(vuln: vulnerability_pb2.Vulnerability): """Do preprocessing steps on vulnerability that the worker does.""" @@ -1360,6 +1225,7 @@ def put_if_newer_batch( """ # TODO(michaelkedar): Putting so many records is causing slowdowns on the # importer, need to reconsider the approach. + # TODO(michaelkedar): This code is still using old Bug entities. return # pylint: disable=unreachable if not vulns_and_paths: diff --git a/gcp/workers/importer/importer_test.py b/gcp/workers/importer/importer_test.py index c2003a2424e..ca50cee6c76 100644 --- a/gcp/workers/importer/importer_test.py +++ b/gcp/workers/importer/importer_test.py @@ -29,7 +29,6 @@ from google.cloud import ndb from google.cloud import storage -from google.cloud.storage import retry import pygit2 from gcp.workers.mock_test.mock_test_handler import MockDataHandler import importer @@ -101,172 +100,6 @@ def setUp(self): def tearDown(self): shutil.rmtree(self.tmp_dir, ignore_errors=True) - @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') - @mock.patch('time.time', return_value=12345.0) - def test_basic(self, unused_mock_time: mock.MagicMock, - mock_publish: mock.MagicMock): - """Test basic run.""" - osv.Bug( - db_id='OSV-2017-134', - affected_packages=[{ - 'versions': ['FILE5_29', 'FILE5_30'], - 'ranges': [{ - 'type': - 'GIT', - 'repo_url': - 'https://github.com/file/file.git', - 'events': [ - { - 'type': 'introduced', - 'value': '17ee4cf670c363de8d2ea4a4897d7a699837873f' - }, - { - 'type': 'fixed', - 'value': '19ccebafb7663c422c714e0c67fa4775abf91c43' - }, - ], - }], - 'package': { - 'ecosystem': 'OSS-Fuzz', - 'name': 'file', - 'purl': 'pkg:generic/file', - }, - 'ecosystem_specific': { - 'severity': 'MEDIUM', - }, - 'database_specific': { - 'database_specific': 1337, - }, - }], - affected_fuzzy=['5-29', '5-30'], - credits=[{ - 'name': 'Foo bar', - 'contact': [], - }, { - 'name': 'Bar foo', - 'contact': ['mailto:bar@foo.com'], - }], - severities=[{ - 'type': 'CVSS_V3', - 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L', - }], - details=( - 'OSS-Fuzz report: ' - 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064\n\n' - 'Crash type: Heap-buffer-overflow READ 1\n' - 'Crash state:\ncdf_file_property_info\ncdf_file_summary_info\n' - 'cdf_check_summary_info\n'), - fixed='19ccebafb7663c422c714e0c67fa4775abf91c43', - has_affected=True, - issue_id='1064', - public=True, - reference_url_types={ - 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064': - 'REPORT' - }, - regressed='17ee4cf670c363de8d2ea4a4897d7a699837873f', - search_indices=['file', '2017-134', '2017', '134'], - source_id='oss-fuzz:5417710252982272', - source_of_truth=osv.SourceOfTruth.INTERNAL, - status=1, - summary='Heap-buffer-overflow in cdf_file_property_info', - timestamp=datetime.datetime( - 2021, 1, 15, 0, 0, 24, 559102, tzinfo=datetime.UTC), - database_specific={ - 'database_specific': 1337 - }, - ).put() - - self.mock_repo.add_file('2021-111.yaml', _MIN_VALID_VULNERABILITY) - self.mock_repo.commit('User', 'user@email') - - imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, - importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', - True, False) - imp.run() - - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Import from OSS-Fuzz', commit.message) - diff = repo.diff(commit.parents[0], commit) - self.expect_equal('diff_basic', diff.patch) - - mock_publish.assert_has_calls([ - mock.call( - self.tasks_topic, - data=b'', - deleted='false', - original_sha256=('874535768a62eb9dc4f3ea7acd9a4601' - '19a3cd03fc15360bf16187f54df92a75'), - path='2021-111.yaml', - source='oss-fuzz', - type='update-oss-fuzz', - req_timestamp='12345', - src_timestamp='') - ]) - bug = osv.Bug.get_by_id('OSV-2017-134') - self.assertEqual(osv.SourceOfTruth.SOURCE_REPO, bug.source_of_truth) - - source_repo = osv.SourceRepository.get_by_id('oss-fuzz') - self.assertEqual(str(commit.id), source_repo.last_synced_hash) - - self.mock_storage_client().get_bucket.assert_called_with('bucket') - bucket = self.mock_storage_client().get_bucket('bucket') - - expected_json = bucket.blob().upload_from_string.call_args[0][0] - self.expect_equal('expected.json', expected_json) - - bucket.blob.assert_has_calls([ - mock.call('testcase/5417710252982272.json'), - mock.call().upload_from_string( - expected_json, retry=retry.DEFAULT_RETRY), - mock.call('issue/1064.json'), - mock.call().upload_from_string( - expected_json, retry=retry.DEFAULT_RETRY), - ]) - - @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') - def test_invalid(self, mock_publish: mock.MagicMock): - """Test invalid entries behaves correctly.""" - self.mock_repo.add_file('2021-111.yaml', _MIN_INVALID_VULNERABILITY) - self.mock_repo.commit('User', 'user@email') - - imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, - importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', - True, False) - with self.assertLogs(level='WARNING') as logs: - imp.run() - - self.assertIn( - osv.ImportFinding( - bug_id='OSV-2017-145', - source='oss-fuzz', - findings=[osv.ImportFindings.INVALID_JSON], - first_seen=importer.utcnow(), - last_attempt=importer.utcnow()).to_dict(), - [r.to_dict() for r in osv.ImportFinding.query()]) - - self.assertEqual( - 5, - len(logs.output), - msg='Expected number of WARNING level (or higher) logs not found') - self.assertEqual( - "WARNING:root:Failed to validate loaded OSV entry: 'modified' is a required property", # pylint: disable=line-too-long - logs.output[0]) - self.assertIn('WARNING:root:Invalid data:', logs.output[1]) - self.assertIn( - "ERROR:root:Failed to parse 2021-111.yaml: 'modified' is a required property", # pylint: disable=line-too-long - logs.output[2]) - - mock_publish.assert_not_called() - bucket = self.mock_storage_client().bucket( - importer.DEFAULT_PUBLIC_LOGGING_BUCKET) - expected_log = bucket.blob().upload_from_string.call_args[0][0] - self.assertIn('Failed to parse vulnerability', expected_log) - @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') def test_nop(self, mock_publish: mock.MagicMock): """Test deletion.""" @@ -286,135 +119,6 @@ def test_nop(self, mock_publish: mock.MagicMock): mock_publish.assert_not_called() - @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') - @mock.patch('time.time', return_value=12345.0) - def test_scheduled_updates(self, unused_mock_time: mock.MagicMock, - mock_publish: mock.MagicMock): - """Test scheduled updates.""" - self.mock_repo.add_file('proj/OSV-2021-1337.yaml', _MIN_VALID_VULNERABILITY) - self.mock_repo.add_file('proj/OSV-2021-1339.yaml', _MIN_VALID_VULNERABILITY) - self.mock_repo.add_file('OSV-2021-1338.yaml', _MIN_VALID_VULNERABILITY) - self.mock_repo.commit('OSV', 'infra@osv.dev') - - osv.SourceRepository( - type=osv.SourceRepositoryType.GIT, - id='source', - name='source', - repo_url='file://' + self.remote_source_repo_path, - repo_username='', - strict_validation=True).put() - osv.Bug( - db_id='OSV-2021-1337', - affected_packages=[ - osv.AffectedPackage( - package=osv.Package(ecosystem='OSS-Fuzz', name='proj')) - ], - status=1, - source_id='oss-fuzz:123', - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - timestamp=datetime.datetime( - 2020, 1, 1, 0, 0, 0, 0, tzinfo=datetime.UTC)).put() - osv.Bug( - db_id='OSV-2021-1338', - affected_packages=[ - osv.AffectedPackage( - package=osv.Package(ecosystem='ecosystem', name='proj'), - ranges=[ - osv.AffectedRange2( - type='GIT', - repo_url='https://example.com/some/repo', - events=[ - osv.AffectedEvent(type='introduced', value='0'), - osv.AffectedEvent(type='fixed', value='fix'), - ]) - ]) - ], - source_id='source:OSV-2021-1338.yaml', - status=1, - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - timestamp=importer.utcnow()).put() - osv.Bug( - db_id='OSV-2021-1339', - affected_packages=[ - osv.AffectedPackage( - package=osv.Package(ecosystem='OSS-Fuzz', name='proj')) - ], - status=1, - source_id='oss-fuzz:124', - source_of_truth=osv.SourceOfTruth.INTERNAL, - timestamp=datetime.datetime( - 2020, 1, 1, 0, 0, 0, 0, tzinfo=datetime.UTC)).put() - - imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, - importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', - True, False) - imp.run() - - mock_publish.assert_has_calls([ - mock.call( - self.tasks_topic, - data=b'', - deleted='false', - original_sha256=('874535768a62eb9dc4f3ea7acd9a4601' - '19a3cd03fc15360bf16187f54df92a75'), - path='proj/OSV-2021-1337.yaml', - source='oss-fuzz', - type='update-oss-fuzz', - req_timestamp='12345', - src_timestamp=''), - mock.call( - self.tasks_topic, - allocated_id='OSV-2021-1339', - data=b'', - source_id='oss-fuzz:124', - type='impact', - req_timestamp='12345'), - ]) - - source_repo = osv.SourceRepository.get_by_id('oss-fuzz') - self.assertEqual( - datetime.datetime(2021, 1, 1, 10, 0, tzinfo=datetime.UTC), - source_repo.last_update_date) - - @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') - def test_scheduled_updates_already_done(self, mock_publish): # pylint: disable=unused-argument - """Scheduled updates already done.""" - # TODO(michaelkedar): This test doesn't check anything - self.skipTest("Not Implemented") - source_repo = osv.SourceRepository.get_by_id('oss-fuzz') - source_repo.last_update_date = importer.utcnow() - source_repo.put() - - self.mock_repo.add_file('proj/OSV-2021-1337.yaml', _MIN_VALID_VULNERABILITY) - self.mock_repo.commit('OSV', 'infra@osv.dev') - osv.Bug( - db_id='OSV-2021-1337', - project=['proj'], - fixed='', - status=1, - source_id='oss-fuzz:123', - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - timestamp=datetime.datetime( - 2020, 1, 1, 0, 0, 0, 0, tzinfo=datetime.UTC)).put() - - imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, - importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', - True, False) - imp.run() - - @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') - def test_no_updates(self, mock_publish): # pylint: disable=unused-argument - """Test no update marker.""" - # TODO(michaelkedar): This test doesn't check anything - self.skipTest("Not Implemented") - self.mock_repo.add_file('2021-111.yaml', _MIN_VALID_VULNERABILITY) - self.mock_repo.commit('User', 'user@email', 'message. OSV-NO-UPDATE') - - imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, - importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', - True, False) - imp.run() - @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') def test_ignore(self, mock_publish): # pylint: disable=unused-argument """Test ignoring.""" diff --git a/gcp/workers/importer/run_tests.sh b/gcp/workers/importer/run_tests.sh index 114f531923a..ce1c489b1b9 100755 --- a/gcp/workers/importer/run_tests.sh +++ b/gcp/workers/importer/run_tests.sh @@ -15,5 +15,8 @@ cd ../worker -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python ../importer/importer_test.py diff --git a/gcp/workers/linter/Dockerfile b/gcp/workers/linter/Dockerfile index 98eecf34023..eb6b3f54791 100644 --- a/gcp/workers/linter/Dockerfile +++ b/gcp/workers/linter/Dockerfile @@ -14,13 +14,13 @@ # Stage 1: Build the Go linter binary -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS go_builder +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS go_builder RUN apk add --no-cache git WORKDIR /src # Using osv-schema v1.7.3+ -RUN git clone https://github.com/ossf/osv-schema.git osv-schema && cd osv-schema && git checkout 88c48750ddae8c47a59fc8412c72ebb885d0bdc3 +RUN git clone https://github.com/ossf/osv-schema.git osv-schema && cd osv-schema && git checkout fe5c3a64c8f43962c7821a38a9d57770a0a0ddb1 WORKDIR /src/osv-schema/tools/osv-linter diff --git a/gcp/workers/mock_test/rest_test.json b/gcp/workers/mock_test/rest_test.json index ed751f8290e..a01a19febbd 100644 --- a/gcp/workers/mock_test/rest_test.json +++ b/gcp/workers/mock_test/rest_test.json @@ -3384,259 +3384,5 @@ } ], "details": "When doing HTTP(S) transfers, libcurl might erroneously use the read callback\n(`CURLOPT_READFUNCTION`) to ask for data to send, even when the\n`CURLOPT_POSTFIELDS` option has been set, if the same handle previously was\nused to issue a `PUT` request which used that callback.\n\nThis flaw may surprise the application and cause it to misbehave and either\nsend off the wrong data or use memory after free or similar in the subsequent\n`POST` request.\n\nThe problem exists in the logic for a reused handle when it is changed from a\nPUT to a POST." - }, -{ - "schema_version": "1.6.7", - "id": "RHSA-2018:3140", - "related": [ - "CVE-2015-9381", - "CVE-2015-9382", - "CVE-2017-2862", - "CVE-2017-18267", - "CVE-2018-4121", - "CVE-2018-4200", - "CVE-2018-4204", - "CVE-2018-10733", - "CVE-2018-10767", - "CVE-2018-10768", - "CVE-2018-11712", - "CVE-2018-11713", - "CVE-2018-12910", - "CVE-2018-13988", - "CVE-2018-14036" - ], - "published": "2024-09-16T01:35:05Z", - "modified": "2024-09-16T01:35:05Z", - "summary": "Red Hat Security Advisory: GNOME security, bug fix, and enhancement update", - "severity": [ - { - "type": "CVSS_V3", - "score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N" - } - ], - "affected": [ - { - "package": { - "name": "PackageKit", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-command-not-found", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-command-not-found" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-cron", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-cron" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-debuginfo", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-debuginfo" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-glib", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-glib" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-glib-devel", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-glib-devel" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-gstreamer-plugin", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-gstreamer-plugin" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-gtk3-module", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-gtk3-module" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-yum", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-yum" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - }, - { - "package": { - "name": "PackageKit-yum-plugin", - "ecosystem": "Red Hat:enterprise_linux:7::client", - "purl": "pkg:rpm/redhat/PackageKit-yum-plugin" - }, - "ranges": [ - { - "events": [ - { - "introduced": "0" - }, - { - "fixed": "0:1.1.10-1.el7" - } - ], - "type": "ECOSYSTEM" - } - ] - } - ], - "references": [ - { - "type": "ADVISORY", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-13988" - }, - { - "type": "REPORT", - "url": "https://access.redhat.com/security/cve/CVE-2018-14036" - }, - { - "type": "REPORT", - "url": "https://bugzilla.redhat.com/show_bug.cgi?id=1601019" - }, - { - "type": "ADVISORY", - "url": "https://www.cve.org/CVERecord?id=CVE-2018-14036" - }, - { - "type": "ADVISORY", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-14036" } - ] -} ] diff --git a/gcp/workers/oss_fuzz_importer/Dockerfile b/gcp/workers/oss_fuzz_importer/Dockerfile new file mode 100644 index 00000000000..cb271e42b91 --- /dev/null +++ b/gcp/workers/oss_fuzz_importer/Dockerfile @@ -0,0 +1,19 @@ +# Copyright 2021 Google LLC +# +# 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. + +FROM gcr.io/oss-vdb/oss-fuzz-worker + +COPY importer.py /usr/local/bin +RUN chmod 755 /usr/local/bin/importer.py +ENTRYPOINT ["importer.py"] diff --git a/gcp/workers/oss_fuzz_importer/importer.py b/gcp/workers/oss_fuzz_importer/importer.py new file mode 100755 index 00000000000..2b8c9e09e32 --- /dev/null +++ b/gcp/workers/oss_fuzz_importer/importer.py @@ -0,0 +1,1362 @@ +#!/usr/bin/env python3 +# Copyright 2021 Google LLC +# +# 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. +"""OSV Importer.""" + +# TODO: Refactor per +# https://github.com/google/osv.dev/pull/2030#discussion_r1513861856 + +import argparse +import concurrent.futures +from collections import namedtuple +import datetime +import json +import logging +import os +import requests +from google.protobuf import json_format +from requests.adapters import HTTPAdapter +import shutil +import threading +import time +from urllib3.util import Retry +import atexit +from typing import List, Tuple, Optional + +from google.cloud import ndb +from google.cloud import pubsub_v1 +from google.cloud import storage +from google.cloud.storage import retry +from google.cloud.exceptions import NotFound +import pygit2.enums + +import osv +import osv.logs +from osv import vulnerability_pb2 + +DEFAULT_WORK_DIR = '/work' +DEFAULT_PUBLIC_LOGGING_BUCKET = 'osv-public-import-logs' + +_BUG_REDO_DAYS = 14 +_TASKS_TOPIC = 'tasks' +_OSS_FUZZ_EXPORT_BUCKET = 'oss-fuzz-osv-vulns' +_EXPORT_WORKERS = 32 +_NO_UPDATE_MARKER = 'OSV-NO-UPDATE' +_BUCKET_THREAD_COUNT = 20 +_HTTP_LAST_MODIFIED_FORMAT = '%a, %d %b %Y %H:%M:%S %Z' +_TIMEOUT_SECONDS = 60 +_NDB_PUT_BATCH_SIZE = 500 + +_client_store = threading.local() + + +def modify_storage_client_adapters(storage_client: storage.Client, + pool_connections: int = 128, + max_retries: int = 3, + pool_block: bool = True) -> storage.Client: + """Returns a modified google.cloud.storage.Client object. + + Due to many concurrent GCS connections, the default connection pool can become + overwhelmed, introducing delays. + + Solution described in https://github.com/googleapis/python-storage/issues/253 + + These affect the urllib3.HTTPConnectionPool underpinning the storage.Client's + HTTP requests. + + Args: + storage_client: an existing google.cloud.storage.Client object + pool_connections: number of pool_connections desired + max_retries: maximum retries + pool_block: blocking behaviour when pool is exhausted + + Returns: + the google.cloud.storage.Client appropriately modified. + + """ + adapter = HTTPAdapter( + pool_connections=pool_connections, + max_retries=max_retries, + pool_block=pool_block) + # pylint: disable=protected-access + storage_client._http.mount('https://', adapter) + storage_client._http._auth_request.session.mount('https://', adapter) + return storage_client + + +def _is_vulnerability_file(source_repo, file_path): + """Return whether or not the file is a Vulnerability entry.""" + if (source_repo.directory_path and + not file_path.startswith(source_repo.directory_path.rstrip('/') + '/')): + return False + + if source_repo.ignore_file(file_path): + return False + + return file_path.endswith(source_repo.extension) + + +def aestnow() -> datetime.datetime: + """Get the current AEST time""" + # To retain the original timezone-unaware behaviour of this function, + # returns the current AEST time with a UTC timezone. + # i.e. returns (utcnow() + 10 hours) UTC + return utcnow().astimezone(datetime.timezone( + datetime.timedelta(hours=10))).replace(tzinfo=datetime.UTC) + + +def utcnow() -> datetime.datetime: + """utcnow() for mocking.""" + return datetime.datetime.now(datetime.UTC) + + +def replace_importer_log(client: storage.Client, source_name: str, + bucket_name: str, import_failure_logs: List[str]): + """Replace the public importer logs with the new one.""" + bucket: storage.Bucket = client.bucket(bucket_name) + upload_string = f'--- {datetime.datetime.now(datetime.UTC).isoformat()} ---\n' + upload_string += '\n'.join(import_failure_logs) + bucket.blob(source_name).upload_from_string( + upload_string, retry=retry.DEFAULT_RETRY) + + +def log_run_duration(start: float): + """Log the elapsed wallclock duration at the end of the program. + + This enables a log-based metric to be created. + + Args: + start: the time the program started. + """ + elapsed = time.time() - start + logging.info('Importer run duration: %d', elapsed) + + +class Importer: + """Importer.""" + + def __init__(self, + ssh_key_public_path, + ssh_key_private_path, + work_dir, + public_log_bucket, + oss_fuzz_export_bucket, + strict_validation: bool, + delete: bool, + deletion_safety_threshold_pct: float = 10.0): + self._ssh_key_public_path = ssh_key_public_path + self._ssh_key_private_path = ssh_key_private_path + self._work_dir = work_dir + self._publisher = pubsub_v1.PublisherClient() + project = os.environ['GOOGLE_CLOUD_PROJECT'] + self._tasks_topic = self._publisher.topic_path(project, _TASKS_TOPIC) + self._public_log_bucket = public_log_bucket + self._oss_fuzz_export_bucket = oss_fuzz_export_bucket + + self._sources_dir = os.path.join(self._work_dir, 'sources') + self._strict_validation = strict_validation + self._delete = delete + self._deletion_safety_threshold_pct = deletion_safety_threshold_pct + os.makedirs(self._sources_dir, exist_ok=True) + + def _git_callbacks(self, source_repo): + """Get git auth callbacks.""" + return osv.GitRemoteCallback(source_repo.repo_username, + self._ssh_key_public_path, + self._ssh_key_private_path) + + def _request_analysis(self, bug, source_repo, repo): + """Request analysis.""" + if bug.source_of_truth == osv.SourceOfTruth.SOURCE_REPO: + path = osv.source_path(source_repo, bug) + file_path = os.path.join(osv.repo_path(repo), path) + if not os.path.exists(file_path): + logging.info( + 'Skipping analysis for %s as the source file no longer exists.', + path) + return + + original_sha256 = osv.sha256(file_path) + self._request_analysis_external(source_repo, original_sha256, path) + else: + self._request_internal_analysis(bug) + + def _request_analysis_external(self, + source_repo, + original_sha256, + path, + deleted=False, + source_timestamp=None): + """Request analysis.""" + # TODO(michaelkedar): Making a distinction for oss-fuzz updates so we can + # track the logic flow for our eventual decoupling of the special logic. + src_ts = '' + if source_timestamp is not None: + src_ts = str(int(source_timestamp.timestamp())) + task_type = 'update' + if source_repo.name == 'oss-fuzz': + task_type = 'update-oss-fuzz' + self._publisher.publish( + self._tasks_topic, + data=b'', + type=task_type, + source=source_repo.name, + path=path, + original_sha256=original_sha256, + deleted=str(deleted).lower(), + req_timestamp=str(int(time.time())), + src_timestamp=src_ts) + + def _request_internal_analysis(self, bug): + """Request internal analysis.""" + self._publisher.publish( + self._tasks_topic, + data=b'', + type='impact', + source_id=bug.source_id, + allocated_id=bug.key.id(), + req_timestamp=str(int(time.time()))) + + def _infer_id_from_invalid_data(self, name: str, content: bytes) -> str: + """Best effort infer the bug ID for data that failed to parse. + + First try and extract something that looks like an "id" field, and failing + that, try to infer from the filename. + + Args: + name: the name associated with the data + content: the data itself + + Returns: + str: the inferred identifer + """ + + # First try without strict validation + extension = os.path.splitext(name)[1] + try: + vulns = osv.parse_vulnerabilities_from_data( + content, extension, strict=False) + if vulns: + return vulns[0].id + except RuntimeError: + # Happens if filename extension is unsupported. + pass + except Exception: + # This function is called from an Exception handler. + # Do not cause further exceptions. + pass + + # TODO(apollock): Then try by poking around at the data. + + # Then use the filename + return os.path.splitext(os.path.basename(name))[0] + + def _record_quality_finding( + self, + source: osv.SourceRepository.name, + bug_id: str, + maybe_new_finding: osv.ImportFindings = osv.ImportFindings.INVALID_JSON): + """Record the quality finding about a record in Datastore. + + Args: + source: the name of the source of the vulnerability record + bug_id: the ID of the vulnerability + maybe_new_finding: the finding to record + + Sets the finding's last_attempt to now, and adds the finding to the list of + findings for the record (if any already exist) + """ + + # Get any current findings for this record. + findingtimenow = utcnow() + if existing_finding := osv.ImportFinding.get_by_id(bug_id): + if maybe_new_finding not in existing_finding.findings: + existing_finding.findings.append(maybe_new_finding) + existing_finding.last_attempt: findingtimenow + existing_finding.put() + else: + osv.ImportFinding( + bug_id=bug_id, + source=source, + findings=[maybe_new_finding], + first_seen=findingtimenow, + last_attempt=findingtimenow).put() + + def run(self): + """Run importer.""" + source_repo = osv.SourceRepository.get_by_id('oss-fuzz') + if not source_repo: + logging.error('OSS-Fuzz source repo not found') + return + + try: + if not self._delete: + self.process_oss_fuzz(source_repo) + self.validate_source_repo(source_repo) + if not self._delete: + self.process_updates(source_repo) + if self._delete: + self.process_deletions(source_repo) + except Exception as e: + logging.exception(e) + + def checkout(self, source_repo): + """Check out a source repo.""" + return osv.ensure_updated_checkout( + source_repo.repo_url, + os.path.join(self._sources_dir, source_repo.name), + git_callbacks=self._git_callbacks(source_repo), + branch=source_repo.repo_branch) + + def import_new_oss_fuzz_entries(self, repo, oss_fuzz_source): + """Import new entries.""" + exported = [] + for bug in osv.Bug.query( + osv.Bug.source_of_truth == osv.SourceOfTruth.INTERNAL): + if bug.status != osv.BugStatus.PROCESSED: + continue + + if not bug.public: + continue + + # We don't index this as INTERNAL generally implies OSS-Fuzz anyway (at + # time of writing). + source_name, _ = osv.parse_source_id(bug.source_id) + if source_name != oss_fuzz_source.name: + continue + + vulnerability_path = os.path.join( + osv.repo_path(repo), osv.source_path(oss_fuzz_source, bug)) + os.makedirs(os.path.dirname(vulnerability_path), exist_ok=True) + if os.path.exists(vulnerability_path): + continue + + logging.info('Writing %s', bug.key.id()) + osv.write_vulnerability(bug.to_vulnerability(), vulnerability_path) + # The source of truth is now this yaml file. + bug.source_of_truth = osv.SourceOfTruth.SOURCE_REPO + exported.append(bug) + + # Commit Vulnerability changes back to the oss-fuzz source repository. + repo.index.add_all() + diff = repo.index.diff_to_tree(repo.head.peel().tree) + if not diff: + logging.info('No new entries, skipping committing.') + return + + logging.info('Committing and pushing new entries') + if osv.push_source_changes(repo, 'Import from OSS-Fuzz', + self._git_callbacks(oss_fuzz_source)): + ndb.put_multi(exported) + + def schedule_regular_updates(self, repo, source_repo: osv.SourceRepository): + """Schedule regular updates.""" + aest_time_now = aestnow() + + if (source_repo.last_update_date and + # OSV devs are mostly located in australia, + # so only schedule update near midnight sydney time + source_repo.last_update_date.date() >= aest_time_now.date()): + return + + for bug in osv.Bug.query( + osv.Bug.status == osv.BugStatus.PROCESSED, + osv.Bug.is_fixed == False, # pylint: disable=singleton-comparison + osv.Bug.source == source_repo.name): + self._request_analysis(bug, source_repo, repo) + + # yapf: disable + # Perform a re-analysis on existing oss-fuzz bugs for a period of time, + # more vulnerable releases might be made even though fixes have + # already been merged into master/main + cutoff_time = aest_time_now - datetime.timedelta(days=_BUG_REDO_DAYS) + query = osv.Bug.query(osv.Bug.status == osv.BugStatus.PROCESSED, + osv.Bug.source == source_repo.name, + osv.Bug.timestamp >= cutoff_time) + # yapf: enable + + for bug in query: + logging.info('Re-requesting impact for %s.', bug.key.id()) + if not bug.is_fixed: + # Previous query already requested impact tasks for unfixed bugs. + continue + + self._request_analysis(bug, source_repo, repo) + + source_repo.last_update_date = aest_time_now + source_repo.put() + + def _vuln_ids_from_gcs_blob(self, client: storage.Client, + source_repo: osv.SourceRepository, + blob: storage.Blob) -> Optional[Tuple[str]]: + """Returns a list of the vulnerability IDs from a parsable OSV file in GCS. + + Usually an OSV file has a single vulnerability in it, but it is permissible + to have more than one, hence it returns a list. + + This is runnable in parallel using concurrent.futures.ThreadPoolExecutor + + Args: + client: a storage.Client() to use for retrieval of the blob + source_repo: the osv.SourceRepository the blob relates to + blob: the storage.Blob object to operate on + + Raises: + jsonschema.exceptions.ValidationError when self._strict_validation is True + input fails OSV JSON Schema validation + + Returns: + a list of one or more vulnerability IDs (from the Vulnerability proto) or + None when the blob has an unexpected name or fails to retrieve + """ + if not _is_vulnerability_file(source_repo, blob.name): + return None + + # Download in a blob generation agnostic way to cope with the blob + # changing between when it was listed and now (if the generation doesn't + # match, retrieval fails otherwise). + try: + blob_bytes = storage.Blob( + blob.name, blob.bucket, generation=None).download_as_bytes(client) + except NotFound: + # The file can disappear between bucket listing and blob retrieval. + return None + + vuln_ids = [] + # When self._strict_validation is True, + # this *may* raise a jsonschema.exceptions.ValidationError + vulns = osv.parse_vulnerabilities_from_data( + blob_bytes, + os.path.splitext(blob.name)[1], + strict=source_repo.strict_validation and self._strict_validation) + for vuln in vulns: + vuln_ids.append(vuln.id) + return vuln_ids + + def _convert_blob_to_vuln( + self, storage_client: storage.Client, ndb_client: ndb.Client, + source_repo: osv.SourceRepository, blob: storage.Blob, + ignore_last_import_time: bool + ) -> None | Tuple[str, str, None | datetime.datetime, + List[vulnerability_pb2.Vulnerability]]: + """Parse a GCS blob into a tuple of hash, path, updated, and Vulnerability + list. + + Criteria for returning a tuple: + - any record in the blob is new (i.e. a new ID) or modified since last run, + and the hash for the blob has changed + - the importer is reimporting the entire source + - ignore_last_import_time is True + - the record passes OSV JSON Schema validation + + Usually an OSV file has a single vulnerability in it, but it is permissible + to have more than one, hence it returns a list of tuples. + + This is runnable in parallel using concurrent.futures.ThreadPoolExecutor + + Args: + storage_client: a storage.Client() to use for retrieval of the blob + ndb_client: an ndb.Client() to use for Data Store access + source_repo: the osv.SourceRepository the blob relates to + blob: the storage.Blob object to operate on + + Raises: + jsonschema.exceptions.ValidationError when self._strict_validation is True + input fails OSV JSON Schema validation + + Returns: + a tuple of (hash, path, updated, vulnerability_list) or None when the blob + has an unexpected name or doesn't meet the import criteria. + """ + if not _is_vulnerability_file(source_repo, blob.name): + return None + + utc_last_update_date = source_repo.last_update_date + + if (not ignore_last_import_time and blob.updated and + blob.updated <= utc_last_update_date): + return None + + # The record in GCS appears to be new/changed, examine further. + logging.info('Bucket entry triggered for %s/%s', source_repo.bucket, + blob.name) + + # Download in a blob generation agnostic way to cope with the blob + # changing between when it was listed and now (if the generation doesn't + # match, retrieval fails otherwise). + blob_bytes = storage.Blob( + blob.name, blob.bucket, + generation=None).download_as_bytes(storage_client) + + blob_hash = osv.sha256_bytes(blob_bytes) + + # When self._strict_validation is True, + # this *may* raise a jsonschema.exceptions.ValidationError + vulns = osv.parse_vulnerabilities_from_data( + blob_bytes, + os.path.splitext(blob.name)[1], + strict=self._strict_validation) + + # TODO(andrewpollock): integrate with linter here. + + # This is the atypical execution path (when reimporting is triggered) + if ignore_last_import_time: + # do not log updated date for reimports + return blob_hash, blob.name, None, vulns + + # If being run under test, reuse existing NDB client. + ndb_ctx = ndb.context.get_context(False) + if ndb_ctx is None: + # Production. Use the NDB client passed in. + ndb_ctx = ndb_client.context(cache_policy=False) + else: + # Unit testing. Reuse the unit test's existing NDB client to avoid + # "RuntimeError: Context is already created for this thread." + ndb_ctx = ndb_ctx.use() + + # This is the typical execution path (when reimporting not triggered) + with ndb_ctx: + for vuln in vulns: + bug = osv.Bug.get_by_id(vuln.id) + # The bug already exists and has been modified since last import + if (bug is None or + bug.import_last_modified != vuln.modified.ToDatetime(datetime.UTC)): + return blob_hash, blob.name, blob.updated, vulns + + return None + + def _sync_from_previous_commit(self, source_repo, repo): + """Sync the repository from the previous commit. + + This was refactored out of _process_updates_git() due to excessive + indentation. + + Args: + source_repo: the Git source repository. + repo: the checked out Git source repository. + + Returns: + changed_entries: the dict of {path: timestamp} that have changed. + deleted_entries: the dict of {path: timestamp} that have been deleted. + """ + changed_entries = {} + deleted_entries = {} + + walker = repo.walk(repo.head.target, pygit2.enums.SortMode.TOPOLOGICAL) + walker.hide(source_repo.last_synced_hash) + + for commit in walker: + if commit.author.email == osv.AUTHOR_EMAIL: + continue + + if _NO_UPDATE_MARKER in commit.message: + logging.info('Skipping commit %s as no update marker found.', commit.id) + continue + + logging.info('Processing commit %s from %s', commit.id, + commit.author.email) + + for parent in commit.parents: + diff = repo.diff(parent, commit) + for delta in diff.deltas: + if delta.old_file and _is_vulnerability_file(source_repo, + delta.old_file.path): + if delta.status == pygit2.enums.DeltaStatus.DELETED: + deleted_entries[ + delta.old_file.path] = datetime.datetime.fromtimestamp( + commit.commit_time, datetime.UTC) + continue + + changed_entries[ + delta.old_file.path] = datetime.datetime.fromtimestamp( + commit.commit_time, datetime.UTC) + + if delta.new_file and _is_vulnerability_file(source_repo, + delta.new_file.path): + changed_entries[ + delta.new_file.path] = datetime.datetime.fromtimestamp( + commit.commit_time, datetime.UTC) + + return changed_entries, deleted_entries + + def _process_updates_git(self, source_repo: osv.SourceRepository): + """Process updates for a git source_repo.""" + logging.info("Begin processing git: %s", source_repo.name) + + repo = self.checkout(source_repo) + + # Get list of changed files since last sync. + changed_entries = {} + + if source_repo.last_synced_hash: + # Syncing from a previous commit. + changed_entries, _ = self._sync_from_previous_commit(source_repo, repo) + + else: + # First sync from scratch. + logging.info('Syncing repo from scratch') + for root, _, filenames in os.walk(osv.repo_path(repo)): + for filename in filenames: + path = os.path.join(root, filename) + rel_path = os.path.relpath(path, osv.repo_path(repo)) + if _is_vulnerability_file(source_repo, rel_path): + # set the timestamp to None when syncing from scratch + changed_entries[rel_path] = None + + import_failure_logs = [] + changed_entries_to_process = [] + # Create tasks for changed files. + for changed_entry, ts in changed_entries.items(): + path = os.path.join(osv.repo_path(repo), changed_entry) + if not os.path.exists(path): + # Path no longer exists. It must have been deleted in another commit. + continue + + try: + vuln = osv.parse_vulnerability( + path, + key_path=source_repo.key_path, + strict=source_repo.strict_validation and self._strict_validation) + except osv.sources.KeyPathError: + # Key path doesn't exist in the vulnerability. + # No need to log a full error, as this is expected result. + logging.info('Entry does not have an OSV entry: %s', changed_entry) + continue + except Exception as e: + logging.error('Failed to parse %s: %s', changed_entry, str(e)) + with open(path, "rb") as f: + content = f.read() + bug_id = self._infer_id_from_invalid_data( + os.path.basename(path), content) + self._record_quality_finding(source_repo.name, bug_id) + # Don't include error stack trace as that might leak sensitive info + import_failure_logs.append('Failed to parse vulnerability "' + path + + '"') + continue + + logging.info('Re-analysis triggered for %s', changed_entry) + original_sha256 = osv.sha256(path) + # Collect for batch processing + changed_entries_to_process.append( + (vuln, path, ts, original_sha256, changed_entry)) + + if changed_entries_to_process: + put_if_newer_batch( + [(v, p) for v, p, _, _, _ in changed_entries_to_process], + source_repo.name) + for vuln, path, ts, orig_sha256, entry in changed_entries_to_process: + self._request_analysis_external( + source_repo, orig_sha256, entry, source_timestamp=ts) + + replace_importer_log(storage.Client(), source_repo.name, + self._public_log_bucket, import_failure_logs) + source_repo.last_synced_hash = str(repo.head.target) + source_repo.put() + + logging.info('Finished processing git: %s', source_repo.name) + + def _process_updates_bucket(self, source_repo: osv.SourceRepository): + """Process updates from bucket.""" + # TODO(ochang): Use Pub/Sub change notifications for more efficient + # processing. + logging.info("Begin processing bucket for updates: %s", source_repo.name) + + # Record import time at the start to avoid race conditions + # where a new record is added to the bucket while we are processing. + import_time_now = utcnow() + + if not source_repo.last_update_date: + source_repo.last_update_date = datetime.datetime.min.replace( + tzinfo=datetime.UTC) + + ignore_last_import_time = source_repo.ignore_last_import_time + if ignore_last_import_time: + source_repo.ignore_last_import_time = False + source_repo.put() + + storage_client = modify_storage_client_adapters(storage.Client()) + + # Get all of the existing records in the GCS bucket + logging.info( + 'Listing blobs in gs://%s', + os.path.join(source_repo.bucket, + ('' if source_repo.directory_path is None else + source_repo.directory_path))) + # Convert to list to retrieve all information into memory + # This makes its concurrent use later faster + listed_blobs = list( + storage_client.list_blobs( + source_repo.bucket, + prefix=source_repo.directory_path, + retry=retry.DEFAULT_RETRY)) + + import_failure_logs = [] + + # Get the hash and the parsed vulnerability from every GCS object that + # parses as an OSV record. Do this in parallel for a degree of expedience. + with concurrent.futures.ThreadPoolExecutor( + max_workers=_BUCKET_THREAD_COUNT) as executor: + + logging.info('Parallel-parsing %d blobs in %s', len(listed_blobs), + source_repo.name) + datastore_client = ndb.Client() + future_to_blob = { + executor.submit(self._convert_blob_to_vuln, storage_client, + datastore_client, source_repo, blob, + ignore_last_import_time): + blob for blob in listed_blobs + } + + converted_vulns = [] + logging.info('Processing %d parallel-parsed blobs in %s', + len(future_to_blob), source_repo.name) + + for future in concurrent.futures.as_completed(future_to_blob): + blob = future_to_blob[future] + try: + if result := future.result(): + converted_vulns.append(result) + except Exception as e: + # Don't include error stack trace as that might leak sensitive info + logging.error('Failed to parse vulnerability %s: %s', blob.name, e) + # TODO(apollock): log finding here + # This feels gross to redownload it again. + bug_id = self._infer_id_from_invalid_data(blob.name, + blob.download_as_bytes()) + self._record_quality_finding(source_repo.name, bug_id) + import_failure_logs.append( + 'Failed to parse vulnerability (when considering for import) "' + + blob.name + '"') + + for cv_result in converted_vulns: + if not cv_result: + continue + blob_hash, blob_name, source_timestamp, vulns = cv_result + logging.info('Requesting analysis of bucket entry: %s/%s', + source_repo.bucket, blob_name) + + put_if_newer_batch([(v, blob_name) for v in vulns], source_repo.name) + + self._request_analysis_external( + source_repo, + blob_hash, + blob_name, + source_timestamp=source_timestamp) + + replace_importer_log(storage_client, source_repo.name, + self._public_log_bucket, import_failure_logs) + + source_repo.last_update_date = import_time_now + source_repo.put() + + logging.info('Finished processing bucket: %s', source_repo.name) + + def _process_deletions_bucket(self, + source_repo: osv.SourceRepository, + threshold: float = 10.0): + """Process deletions from a GCS bucket source. + + This validates the continued existence of every Bug in Datastore (for the + given source) against every bug currently in that source's GCS bucket, + calculating the delta. The bugs determined to have been + deleted from GCS are then flagged for treatment by the worker. + + If the delta is too large, something undesirable has been assumed to have + happened and further processing is aborted. + + Args: + source_repo: the osv.SourceRepository being operated on + threshold: the percentage delta considered safe to delete + """ + + logging.info('Begin processing bucket for deletions: %s', source_repo.name) + + # Get all the existing non-withdrawn Bug IDs for + # source_repo.name in Datastore + query = osv.Bug.query() + query = query.filter(osv.Bug.source == source_repo.name) + result = list(query.fetch(keys_only=False)) + result.sort(key=lambda r: r.id()) + VulnAndSource = namedtuple('VulnAndSource', ['id', 'path']) + logging.info('Retrieved %s results from query', len(result)) + + vuln_ids_for_source = [ + VulnAndSource(id=r.id(), path=r.source_id.partition(':')[2]) + for r in result + if not r.withdrawn + ] + logging.info( + 'Counted %d Bugs for %s in Datastore', + len(vuln_ids_for_source), + source_repo.name, + extra={ + 'json_fields': { + 'vuln_ids_for_source': vuln_ids_for_source, + 'source_repo': source_repo.name, + } + }) + + storage_client = storage.Client() + # Get all of the existing records in the GCS bucket + # (to get their IDs for checking against Datastore) + logging.info( + 'Listing blobs in gs://%s', + os.path.join(source_repo.bucket, + ('' if source_repo.directory_path is None else + source_repo.directory_path))) + listed_blobs = list( + storage_client.list_blobs( + source_repo.bucket, + prefix=source_repo.directory_path, + retry=retry.DEFAULT_RETRY)) + + import_failure_logs = [] + + # Get the vulnerability ID from every GCS object that parses as an OSV + # record. Do this in parallel for a degree of expedience. + with concurrent.futures.ThreadPoolExecutor( + max_workers=_BUCKET_THREAD_COUNT) as executor: + logging.info('Parallel-parsing %d blobs in %s', len(listed_blobs), + source_repo.name) + future_to_blob = { + executor.submit(self._vuln_ids_from_gcs_blob, storage_client, + source_repo, blob): + blob for blob in listed_blobs + } + vuln_ids_in_gcs = [] + logging.info('Processing %d parallel-parsed blobs in %s', + len(future_to_blob), source_repo.name) + for future in concurrent.futures.as_completed(future_to_blob): + blob = future_to_blob[future] + try: + if future.result(): + vuln_ids_in_gcs.extend( + [vuln_id for vuln_id in future.result() if vuln_id]) + except Exception as e: + # Don't include error stack trace as that might leak sensitive info + logging.error('Failed to parse vulnerability %s: %s', blob.name, e) + # List.append() is atomic and threadsafe. + import_failure_logs.append( + 'Failed to parse vulnerability (when considering for deletion)"' + + blob.name + '"') + logging.info('Counted %d parsed vulnerabilities (from %d blobs) for %s', + len(vuln_ids_in_gcs), len(listed_blobs), source_repo.name) + + # diff what's in Datastore with what was seen in GCS. + vulns_to_delete = [ + v for v in vuln_ids_for_source if v.id not in vuln_ids_in_gcs + ] + + logging.info('%d Bugs in Datastore considered deleted from GCS for %s', + len(vulns_to_delete), source_repo.name) + + if len(vulns_to_delete) == 0: + logging.info('No bugs to delete from GCS for %s', source_repo.name) + replace_importer_log(storage_client, source_repo.name, + self._public_log_bucket, import_failure_logs) + return + + # sanity check: deleting a lot/all of the records for source in Datastore is + # probably worth flagging for review. + if (len(vulns_to_delete) / len(vuln_ids_for_source) * 100) >= threshold: + logging.error( + 'Cowardly refusing to delete %d missing records from ' + 'GCS for: %s', + len(vulns_to_delete), + source_repo.name, + extra={}) + vulns = [v.id for v in vulns_to_delete] + logging.info('Vulnerabilities to delete: %s', vulns) + return + + # Request deletion. + for v in vulns_to_delete: + logging.info('Requesting deletion of bucket entry: %s/%s for %s', + source_repo.bucket, v.path, v.id) + self._request_analysis_external( + source_repo, original_sha256='', path=v.path, deleted=True) + + replace_importer_log(storage_client, source_repo.name, + self._public_log_bucket, import_failure_logs) + + def _process_updates_rest(self, source_repo: osv.SourceRepository): + """Process updates from REST API. + + To find new updates, first makes a HEAD request to check the 'Last-Modified' + header, and skips processing if it's before the source's last_modified_date + (and ignore_last_import_time isn't set). + + Otherwise, GETs the list of vulnerabilities and requests updates for + vulnerabilities modified after last_modified_date. + + last_modified_date is updated to the HEAD's 'Last-Modified' time, or the + latest vulnerability's modified date if 'Last-Modified' was missing/invalid. + """ + logging.info('Begin processing REST: %s', source_repo.name) + + last_update_date = ( + source_repo.last_update_date or + datetime.datetime.min.replace(tzinfo=datetime.UTC)) + ignore_last_import = source_repo.ignore_last_import_time + if ignore_last_import: + last_update_date = datetime.datetime.min.replace(tzinfo=datetime.UTC) + source_repo.ignore_last_import_time = False + source_repo.put() + + s = requests.Session() + adapter = HTTPAdapter( + max_retries=Retry( + total=3, status_forcelist=[502, 503, 504], backoff_factor=1)) + s.mount('http://', adapter) + s.mount('https://', adapter) + + try: + request = s.head(source_repo.rest_api_url, timeout=_TIMEOUT_SECONDS) + except Exception: + logging.exception('Exception querying REST API:') + return + if request.status_code != 200: + logging.error('Failed to fetch REST API: %s', request.status_code) + return + + request_last_modified = None + if last_modified := request.headers.get('Last-Modified'): + try: + # strptime discards timezone information - assume UTC + request_last_modified = datetime.datetime.strptime( + last_modified, + _HTTP_LAST_MODIFIED_FORMAT).replace(tzinfo=datetime.UTC) + # Check whether endpoint has been modified since last update + if request_last_modified <= last_update_date: + logging.info('No changes since last update.') + return + except ValueError: + logging.error('Invalid Last-Modified header: "%s"', last_modified) + + try: + request = s.get(source_repo.rest_api_url, timeout=_TIMEOUT_SECONDS) + except Exception: + logging.exception('Exception querying REST API:') + return + + data = json.loads(request.text) + vulns = [] + for datum in data: + vulnerability = vulnerability_pb2.Vulnerability() + json_format.ParseDict(datum, vulnerability, ignore_unknown_fields=True) + if not vulnerability.id: + raise ValueError('Missing id field. Invalid vulnerability.') + if not vulnerability.modified: + raise ValueError('Missing modified field. Invalid vulnerability.') + vulns.append(vulnerability) + + vulns_last_modified = last_update_date + logging.info('%d records to consider', len(vulns)) + # Create tasks for changed files. + vulns_to_process = [] + for vuln in vulns: + import_failure_logs = [] + vuln_modified = vuln.modified.ToDatetime(datetime.UTC) + if request_last_modified and vuln_modified > request_last_modified: + logging.warning('%s was modified (%s) after Last-Modified header (%s)', + vuln.id, vuln_modified, request_last_modified) + vulns_last_modified = max(vulns_last_modified, vuln_modified) + if vuln_modified <= last_update_date: + continue + try: + # TODO(jesslowe): Use a ThreadPoolExecutor to parallelize this + single_vuln = s.get( + source_repo.link + vuln.id + source_repo.extension, + timeout=_TIMEOUT_SECONDS) + # Validate the individual request and parse the vulnerability. + try: + v = osv.parse_vulnerability_from_dict( + single_vuln.json(), + source_repo.key_path, + strict=source_repo.strict_validation and self._strict_validation) + except Exception as e: + logging.error('Failed to parse %s: %s', str(single_vuln.content), + str(e)) + bug_id = self._infer_id_from_invalid_data( + source_repo.link + vuln.id + source_repo.extension, + single_vuln.content) + self._record_quality_finding(source_repo.name, bug_id) + continue + + ts = None if ignore_last_import else vuln_modified + vulns_to_process.append((v, vuln.id + source_repo.extension, ts, + osv.sha256_bytes(single_vuln.text.encode()))) + except osv.sources.KeyPathError: + # Key path doesn't exist in the vulnerability. + # No need to log a full error, as this is expected result. + logging.info('Entry does not have an OSV entry: %s', vuln.id) + continue + except Exception as e: + logging.exception('Failed to parse %s: error type: %s, details: %s', + vuln.id, e.__class__.__name__, e) + import_failure_logs.append(f'Failed to parse vulnerability "{vuln.id}"') + continue + + if vulns_to_process: + put_if_newer_batch([(v, p) for v, p, _, _ in vulns_to_process], + source_repo.name) + for v, path, ts, sha256 in vulns_to_process: + self._request_analysis_external( + source_repo, sha256, path, source_timestamp=ts) + + replace_importer_log(storage.Client(), source_repo.name, + self._public_log_bucket, import_failure_logs) + + source_repo.last_update_date = request_last_modified or vulns_last_modified + source_repo.put() + + logging.info('Finished processing REST: %s', source_repo.name) + + def _process_deletions_rest(self, source_repo: osv.SourceRepository): + """Process deletions from a REST bucket source.""" + raise NotImplementedError + + def validate_source_repo(self, source_repo: osv.SourceRepository): + """Validate the source_repo for correctness.""" + if source_repo.link and source_repo.link[-1] != '/': + raise ValueError('Source repository link must end with /') + + def process_updates(self, source_repo: osv.SourceRepository): + """Process source record changes and updates.""" + if source_repo.type == osv.SourceRepositoryType.GIT: + self._process_updates_git(source_repo) + return + + if source_repo.type == osv.SourceRepositoryType.BUCKET: + self._process_updates_bucket(source_repo) + return + + if source_repo.type == osv.SourceRepositoryType.REST_ENDPOINT: + self._process_updates_rest(source_repo) + return + + logging.error('Invalid repo type: %s - %d', source_repo.name, + source_repo.type) + + def process_deletions(self, source_repo: osv.SourceRepository): + """Process source record deletions by withdrawing them.""" + if source_repo.type == osv.SourceRepositoryType.GIT: + # TODO: To be implemented. + # NOTE: this may require reintroducing special node GKE node treatment + # see discussion on https://github.com/google/osv.dev/pull/2133 + return + + if source_repo.type == osv.SourceRepositoryType.BUCKET: + self._process_deletions_bucket(source_repo, + self._deletion_safety_threshold_pct) + return + + if source_repo.type == osv.SourceRepositoryType.REST_ENDPOINT: + # TODO: To be implemented. + return + + logging.error('Invalid repo type: %s - %d', source_repo.name, + source_repo.type) + + def process_oss_fuzz(self, oss_fuzz_source): + """Process OSS-Fuzz source data.""" + # Export OSS-Fuzz Vulnerability data into source repository. + # OSS-Fuzz data is first imported via a special Pub/Sub pipeline into OSV. + # This data needs to be dumped into a publicly accessible/editable place for + # manual/human editing if required. + # + # This then becomes the source of truth where any edits are imported back + # into OSV. + repo = self.checkout(oss_fuzz_source) + self.schedule_regular_updates(repo, oss_fuzz_source) + self.import_new_oss_fuzz_entries(repo, oss_fuzz_source) + self.export_oss_fuzz_to_bucket() + + def export_oss_fuzz_to_bucket(self): + """Export OSS-Fuzz vulns to bucket.""" + storage_client = storage.Client() + bucket = storage_client.get_bucket(self._oss_fuzz_export_bucket) + + def export_oss_fuzz(vulnerability, testcase_id, issue_id): + """Export a single vulnerability.""" + try: + blob = bucket.blob(f'testcase/{testcase_id}.json') + data = json.dumps(osv.vulnerability_to_dict(vulnerability)) + blob.upload_from_string(data, retry=retry.DEFAULT_RETRY) + + if not issue_id: + return + + blob = bucket.blob(f'issue/{issue_id}.json') + blob.upload_from_string(data, retry=retry.DEFAULT_RETRY) + except Exception as e: + logging.error('Failed to export: %s', e) + + with concurrent.futures.ThreadPoolExecutor( + max_workers=_EXPORT_WORKERS) as executor: + for bug in osv.Bug.query(osv.Bug.ecosystem == 'OSS-Fuzz'): + if not bug.public: + continue + + _, source_id = osv.parse_source_id(bug.source_id) + executor.submit(export_oss_fuzz, bug.to_vulnerability(), source_id, + bug.issue_id) + + +def preprocess_vuln(vuln: vulnerability_pb2.Vulnerability): + """Do preprocessing steps on vulnerability that the worker does.""" + # Duplicating parts of _do_update() in worker.py + # maybe_normalize_package_names: + for affected in vuln.affected: + if not affected.package.ecosystem: + continue + affected.package.name = osv.ecosystems.maybe_normalize_package_names( + affected.package.name, affected.package.ecosystem) + # skipping fix_invalid_ghsa because I don't think it's a problem anymore. + # filter_unknown_ecoystems: + filtered = [] + for affected in vuln.affected: + if not affected.HasField('package'): + filtered.append(affected) + elif osv.ecosystems.is_known(affected.package.ecosystem): + filtered.append(affected) + else: + logging.error('%s contains unknown ecosystem "%s"', vuln.id, + affected.package.ecosystem) + del vuln.affected[:] + vuln.affected.extend(filtered) + + +def new_bug_from_vuln(vuln: vulnerability_pb2.Vulnerability, source: str, + path: str) -> osv.Bug: + """Create a new Bug entity from a vulnerability, following similar logic to + worker._do_update()""" + orig_modified = vuln.modified.ToDatetime(datetime.UTC) + bug = osv.Bug( + db_id=vuln.id, + timestamp=osv.utcnow(), + status=osv.BugStatus.PROCESSED, + source_of_truth=osv.SourceOfTruth.SOURCE_REPO) + bug.update_from_vulnerability(vuln) + bug.public = True + bug.import_last_modified = orig_modified + if source != 'oss-fuzz' or not bug.source_id: + bug.source_id = f'{source}:{path}' + if bug.withdrawn: + bug.status = osv.BugStatus.INVALID + else: + bug.status = osv.BugStatus.PROCESSED + + if not vuln.affected: + logging.info('%s does not affect any packages. Marking as invalid.', + vuln.id) + bug.status = osv.BugStatus.INVALID + + bug.affected_checksum = compute_raw_affected_checksum(vuln) + + return bug + + +def update_bug_from_vuln(bug: osv.Bug, vuln: vulnerability_pb2.Vulnerability, + source: str, path: str): + """Updates a Bug entity from a vulnerability, following similar logic to + worker._do_update(), with special handling to check if the raw affected + packages has changed.""" + import_modified = vuln.modified.ToDatetime(datetime.UTC) + prev_modified = bug.last_modified + prev_affected = bug.affected_packages + bug.update_from_vulnerability(vuln) + bug.public = True + bug.import_last_modified = import_modified + if source != 'oss-fuzz' or not bug.source_id: + bug.source_id = f'{source}:{path}' + if bug.withdrawn: + bug.status = osv.BugStatus.INVALID + else: + bug.status = osv.BugStatus.PROCESSED + + if not vuln.affected: + logging.info('%s does not affect any packages. Marking as invalid.', + vuln.id) + bug.status = osv.BugStatus.INVALID + + if bug.last_modified < prev_modified: + # Prevent the modified date going backwards, + # e.g. if source updated the bug again before the worker finished + bug.last_modified = osv.utcnow() + + new_checksum = compute_raw_affected_checksum(vuln) + if bug.affected_checksum == new_checksum: + # The checksum of the raw affected packages is unchanged (so no change has + # been made to the affected packages). Restore the previously enriched, + # affected_packages from the workers. + bug.affected_packages = prev_affected + bug.affected_checksum = new_checksum + + +def compute_raw_affected_checksum(vuln: vulnerability_pb2.Vulnerability): + """Computes a checksum of the affected array from a vulnerability.""" + # Grab the minimum information out of afftected and sort. + #TODO(michaelkedar): This should be in models.py + aff = [] + # (ecocystem, package, [ + # (type, repo, [(introduced, fixed, last_affected, limit)]) + # ], [versions]) + for affected in vuln.affected: + ecosystem = affected.package.ecosystem + package = affected.package.name + versions = sorted(affected.versions) + ranges = [] + for r in affected.ranges: + t = r.type + repo = r.repo + events = sorted( + (e.introduced, e.fixed, e.last_affected, e.limit) for e in r.events) + ranges.append((t, repo, events)) + ranges.sort() + aff.append((ecosystem, package, ranges, versions)) + aff.sort() + b = json.dumps(aff).encode() + return osv.sha256_bytes(b) + + +def log_update_latency(bug: osv.Bug): + now = int(time.time()) + source_time = int(bug.import_last_modified.timestamp()) + logging.info( + 'Importer put Bug', + extra={ + 'json_fields': { + 'vuln_id': bug.db_id, + 'latency': str(now - source_time), + } + }) + + +def put_if_newer(vuln: vulnerability_pb2.Vulnerability, source: str, path: str): + """Try to write vulnerability to datastore, keeping enumerated versions if + unchanged. Does not write if vuln's modified date is older than what's already + in datastore. + """ + put_if_newer_batch([(vuln, path)], source) + + +def put_if_newer_batch( + vulns_and_paths: list[tuple[vulnerability_pb2.Vulnerability, + str]], source: str): + """Try to write vulnerabilities to datastore in batch, keeping enumerated + versions if unchanged. Does not write if vuln's modified date is older than + what's already in datastore. + """ + # TODO(michaelkedar): Putting so many records is causing slowdowns on the + # importer, need to reconsider the approach. + return + # pylint: disable=unreachable + if not vulns_and_paths: + return + + # Deduplicate by vuln.id, keeping the last one. + unique_vulns_and_paths = {} + for vuln, path in vulns_and_paths: + unique_vulns_and_paths[vuln.id] = (vuln, path) + vulns_and_paths = list(unique_vulns_and_paths.values()) + + for vuln, _ in vulns_and_paths: + preprocess_vuln(vuln) + + keys = [ndb.Key(osv.Bug, v.id) for v, _ in vulns_and_paths] + existing_bugs = [] + for i in range(0, len(keys), _NDB_PUT_BATCH_SIZE): + batch_keys = keys[i:i + _NDB_PUT_BATCH_SIZE] + existing_bugs.extend(ndb.get_multi(batch_keys)) + + bugs_to_put = [] + for i, (vuln, path) in enumerate(vulns_and_paths): + bug = existing_bugs[i] + if bug is None: + bug = new_bug_from_vuln(vuln, source, path) + bugs_to_put.append(bug) + continue + + # Only update if the incoming vulnerability is newer. + orig_modified = vuln.modified.ToDatetime(datetime.UTC) + if bug.import_last_modified and orig_modified <= bug.import_last_modified: + logging.info( + 'Skipping update for %s because incoming modification time' + ' (%s) is not newer than existing record (%s)', vuln.id, + orig_modified, bug.import_last_modified) + continue + update_bug_from_vuln(bug, vuln, source, path) + bugs_to_put.append(bug) + + if bugs_to_put: + for i in range(0, len(bugs_to_put), _NDB_PUT_BATCH_SIZE): + batch = bugs_to_put[i:i + _NDB_PUT_BATCH_SIZE] + ndb.put_multi(batch) + for bug in batch: + log_update_latency(bug) + + +def main(): + parser = argparse.ArgumentParser(description='Importer') + parser.add_argument( + '--work_dir', help='Working directory', default=DEFAULT_WORK_DIR) + parser.add_argument( + '--public_log_bucket', + help="Public logging bucket", + default=DEFAULT_PUBLIC_LOGGING_BUCKET) + parser.add_argument('--ssh_key_public', help='Public SSH key path') + parser.add_argument('--ssh_key_private', help='Private SSH key path') + parser.add_argument( + '--strict_validation', + action='store_true', + help='Fail to import entries that does not pass validation', + default=False) + parser.add_argument( + '--delete', + action='store_true', + help=('Bypass importing and propagate record deletions from source to ' + 'Datastore'), + default=False) + parser.add_argument( + '--delete_threshold_pct', + type=float, + help='More than this percent of records for a given source ' + 'being deleted triggers an error', + default=10) + args = parser.parse_args() + + tmp_dir = os.path.join(args.work_dir, 'tmp') + # Temp files are on the persistent local SSD, + # and they do not get removed when GKE sends a SIGTERM to stop the pod. + # Manually clear the tmp_dir folder of any leftover files + # TODO(michaelkedar): use an ephemeral disk for temp storage. + if os.path.exists(tmp_dir): + shutil.rmtree(tmp_dir) + os.makedirs(tmp_dir, exist_ok=True) + os.environ['TMPDIR'] = tmp_dir + + importer = Importer(args.ssh_key_public, args.ssh_key_private, args.work_dir, + args.public_log_bucket, _OSS_FUZZ_EXPORT_BUCKET, + args.strict_validation, args.delete, + args.delete_threshold_pct) + importer.run() + + +if __name__ == '__main__': + atexit.register(log_run_duration, time.time()) + osv.logs.setup_gcp_logging('importer') + _ndb_client = ndb.Client() + with _ndb_client.context(cache_policy=False): + main() diff --git a/gcp/workers/oss_fuzz_importer/importer_test.py b/gcp/workers/oss_fuzz_importer/importer_test.py new file mode 100644 index 00000000000..afa29f43756 --- /dev/null +++ b/gcp/workers/oss_fuzz_importer/importer_test.py @@ -0,0 +1,1091 @@ +# Copyright 2021 Google LLC +# +# 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. +"""Importer tests.""" +import contextlib +import datetime +import os +import shutil +import tempfile +import unittest +import http.server +import logging +import threading + +from unittest import mock +from urllib3.exceptions import SystemTimeWarning +import warnings + +from google.cloud import ndb +from google.cloud import storage +from google.cloud.storage import retry +import pygit2 +from gcp.workers.mock_test.mock_test_handler import MockDataHandler +import importer +import osv +from osv import tests + +TEST_DATA_DIR = os.path.join( + os.path.dirname(os.path.abspath(__file__)), 'testdata') +TEST_BUCKET = 'test-osv-source-bucket' + +_MIN_VALID_VULNERABILITY = '''{ + "id":"OSV-2017-134", + "modified":"2021-01-01T00:00:00Z", + "schema_version":"1.3.0", +}''' + +_MIN_INVALID_VULNERABILITY = '''{ + "id":"OSV-2017-145", + "schema_version":"1.3.0", +}''' +PORT = 8888 +SERVER_ADDRESS = ('localhost', PORT) +MOCK_ADDRESS_FORMAT = f"http://{SERVER_ADDRESS[0]}:{SERVER_ADDRESS[1]}/" + + +@mock.patch('importer.utcnow', + lambda: datetime.datetime(2021, 1, 1, tzinfo=datetime.UTC)) +class ImporterTest(unittest.TestCase, tests.ExpectationTest(TEST_DATA_DIR)): + """Importer tests.""" + + def _load_test_data(self, name): + """Load test data.""" + with open(os.path.join(TEST_DATA_DIR, name)) as f: + return f.read() + + @classmethod + def setUpClass(cls): + # Start the emulator BEFORE creating the ndb client + cls.emulator = cls.enterClassContext(tests.datastore_emulator()) + cls.enterClassContext(ndb.Client().context(cache_policy=False)) + + def setUp(self): + self.emulator.reset() + self.maxDiff = None # pylint: disable=invalid-name + self.tmp_dir = tempfile.mkdtemp() + + tests.mock_datetime(self) + warnings.filterwarnings('ignore', category=SystemTimeWarning) + self.mock_repo = tests.mock_repository(self) + + storage_patcher = mock.patch('google.cloud.storage.Client') + self.addCleanup(storage_patcher.stop) + self.mock_storage_client = storage_patcher.start() + + self.remote_source_repo_path = self.mock_repo.path + self.source_repo = osv.SourceRepository( + type=osv.SourceRepositoryType.GIT, + id='oss-fuzz', + name='oss-fuzz', + db_prefix=['OSV-'], + repo_url='file://' + self.remote_source_repo_path, + repo_username='', + ignore_patterns=['.*IGNORE.*'], + strict_validation=True) + self.source_repo.put() + + self.tasks_topic = f'projects/{tests.TEST_PROJECT_ID}/topics/tasks' + + def tearDown(self): + shutil.rmtree(self.tmp_dir, ignore_errors=True) + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + @mock.patch('time.time', return_value=12345.0) + def test_basic(self, unused_mock_time: mock.MagicMock, + mock_publish: mock.MagicMock): + """Test basic run.""" + osv.Bug( + db_id='OSV-2017-134', + affected_packages=[{ + 'versions': ['FILE5_29', 'FILE5_30'], + 'ranges': [{ + 'type': + 'GIT', + 'repo_url': + 'https://github.com/file/file.git', + 'events': [ + { + 'type': 'introduced', + 'value': '17ee4cf670c363de8d2ea4a4897d7a699837873f' + }, + { + 'type': 'fixed', + 'value': '19ccebafb7663c422c714e0c67fa4775abf91c43' + }, + ], + }], + 'package': { + 'ecosystem': 'OSS-Fuzz', + 'name': 'file', + 'purl': 'pkg:generic/file', + }, + 'ecosystem_specific': { + 'severity': 'MEDIUM', + }, + 'database_specific': { + 'database_specific': 1337, + }, + }], + affected_fuzzy=['5-29', '5-30'], + credits=[{ + 'name': 'Foo bar', + 'contact': [], + }, { + 'name': 'Bar foo', + 'contact': ['mailto:bar@foo.com'], + }], + severities=[{ + 'type': 'CVSS_V3', + 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L', + }], + details=( + 'OSS-Fuzz report: ' + 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064\n\n' + 'Crash type: Heap-buffer-overflow READ 1\n' + 'Crash state:\ncdf_file_property_info\ncdf_file_summary_info\n' + 'cdf_check_summary_info\n'), + fixed='19ccebafb7663c422c714e0c67fa4775abf91c43', + has_affected=True, + issue_id='1064', + public=True, + reference_url_types={ + 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064': + 'REPORT' + }, + regressed='17ee4cf670c363de8d2ea4a4897d7a699837873f', + search_indices=['file', '2017-134', '2017', '134'], + source_id='oss-fuzz:5417710252982272', + source_of_truth=osv.SourceOfTruth.INTERNAL, + status=1, + summary='Heap-buffer-overflow in cdf_file_property_info', + timestamp=datetime.datetime( + 2021, 1, 15, 0, 0, 24, 559102, tzinfo=datetime.UTC), + database_specific={ + 'database_specific': 1337 + }, + ).put() + + self.mock_repo.add_file('2021-111.yaml', _MIN_VALID_VULNERABILITY) + self.mock_repo.commit('User', 'user@email') + + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + imp.run() + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Import from OSS-Fuzz', commit.message) + diff = repo.diff(commit.parents[0], commit) + self.expect_equal('diff_basic', diff.patch) + + mock_publish.assert_has_calls([ + mock.call( + self.tasks_topic, + data=b'', + deleted='false', + original_sha256=('874535768a62eb9dc4f3ea7acd9a4601' + '19a3cd03fc15360bf16187f54df92a75'), + path='2021-111.yaml', + source='oss-fuzz', + type='update-oss-fuzz', + req_timestamp='12345', + src_timestamp='') + ]) + bug = osv.Bug.get_by_id('OSV-2017-134') + self.assertEqual(osv.SourceOfTruth.SOURCE_REPO, bug.source_of_truth) + + source_repo = osv.SourceRepository.get_by_id('oss-fuzz') + self.assertEqual(str(commit.id), source_repo.last_synced_hash) + + self.mock_storage_client().get_bucket.assert_called_with('bucket') + bucket = self.mock_storage_client().get_bucket('bucket') + + expected_json = bucket.blob().upload_from_string.call_args[0][0] + self.expect_equal('expected.json', expected_json) + + bucket.blob.assert_has_calls([ + mock.call('testcase/5417710252982272.json'), + mock.call().upload_from_string( + expected_json, retry=retry.DEFAULT_RETRY), + mock.call('issue/1064.json'), + mock.call().upload_from_string( + expected_json, retry=retry.DEFAULT_RETRY), + ]) + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + def test_invalid(self, mock_publish: mock.MagicMock): + """Test invalid entries behaves correctly.""" + self.mock_repo.add_file('2021-111.yaml', _MIN_INVALID_VULNERABILITY) + self.mock_repo.commit('User', 'user@email') + + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + with self.assertLogs(level='WARNING') as logs: + imp.run() + + self.assertIn( + osv.ImportFinding( + bug_id='OSV-2017-145', + source='oss-fuzz', + findings=[osv.ImportFindings.INVALID_JSON], + first_seen=importer.utcnow(), + last_attempt=importer.utcnow()).to_dict(), + [r.to_dict() for r in osv.ImportFinding.query()]) + + self.assertEqual( + 5, + len(logs.output), + msg='Expected number of WARNING level (or higher) logs not found') + self.assertEqual( + "WARNING:root:Failed to validate loaded OSV entry: 'modified' is a required property", # pylint: disable=line-too-long + logs.output[0]) + self.assertIn('WARNING:root:Invalid data:', logs.output[1]) + self.assertIn( + "ERROR:root:Failed to parse 2021-111.yaml: 'modified' is a required property", # pylint: disable=line-too-long + logs.output[2]) + + mock_publish.assert_not_called() + bucket = self.mock_storage_client().bucket( + importer.DEFAULT_PUBLIC_LOGGING_BUCKET) + expected_log = bucket.blob().upload_from_string.call_args[0][0] + self.assertIn('Failed to parse vulnerability', expected_log) + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + def test_nop(self, mock_publish: mock.MagicMock): + """Test deletion.""" + self.mock_repo.add_file('2021-111.yaml', _MIN_VALID_VULNERABILITY) + self.mock_repo.commit('User', 'user@email') + + repo = pygit2.Repository(self.remote_source_repo_path) + synced_commit = repo.head.peel() + + self.source_repo.last_synced_hash = str(synced_commit.id) + self.source_repo.put() + + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + imp.run() + + mock_publish.assert_not_called() + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + @mock.patch('time.time', return_value=12345.0) + def test_scheduled_updates(self, unused_mock_time: mock.MagicMock, + mock_publish: mock.MagicMock): + """Test scheduled updates.""" + self.mock_repo.add_file('proj/OSV-2021-1337.yaml', _MIN_VALID_VULNERABILITY) + self.mock_repo.add_file('proj/OSV-2021-1339.yaml', _MIN_VALID_VULNERABILITY) + self.mock_repo.add_file('OSV-2021-1338.yaml', _MIN_VALID_VULNERABILITY) + self.mock_repo.commit('OSV', 'infra@osv.dev') + + osv.SourceRepository( + type=osv.SourceRepositoryType.GIT, + id='source', + name='source', + repo_url='file://' + self.remote_source_repo_path, + repo_username='', + strict_validation=True).put() + osv.Bug( + db_id='OSV-2021-1337', + affected_packages=[ + osv.AffectedPackage( + package=osv.Package(ecosystem='OSS-Fuzz', name='proj')) + ], + status=1, + source_id='oss-fuzz:123', + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + timestamp=datetime.datetime( + 2020, 1, 1, 0, 0, 0, 0, tzinfo=datetime.UTC)).put() + osv.Bug( + db_id='OSV-2021-1338', + affected_packages=[ + osv.AffectedPackage( + package=osv.Package(ecosystem='ecosystem', name='proj'), + ranges=[ + osv.AffectedRange2( + type='GIT', + repo_url='https://example.com/some/repo', + events=[ + osv.AffectedEvent(type='introduced', value='0'), + osv.AffectedEvent(type='fixed', value='fix'), + ]) + ]) + ], + source_id='source:OSV-2021-1338.yaml', + status=1, + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + timestamp=importer.utcnow()).put() + osv.Bug( + db_id='OSV-2021-1339', + affected_packages=[ + osv.AffectedPackage( + package=osv.Package(ecosystem='OSS-Fuzz', name='proj')) + ], + status=1, + source_id='oss-fuzz:124', + source_of_truth=osv.SourceOfTruth.INTERNAL, + timestamp=datetime.datetime( + 2020, 1, 1, 0, 0, 0, 0, tzinfo=datetime.UTC)).put() + + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + imp.run() + + mock_publish.assert_has_calls([ + mock.call( + self.tasks_topic, + data=b'', + deleted='false', + original_sha256=('874535768a62eb9dc4f3ea7acd9a4601' + '19a3cd03fc15360bf16187f54df92a75'), + path='proj/OSV-2021-1337.yaml', + source='oss-fuzz', + type='update-oss-fuzz', + req_timestamp='12345', + src_timestamp=''), + mock.call( + self.tasks_topic, + allocated_id='OSV-2021-1339', + data=b'', + source_id='oss-fuzz:124', + type='impact', + req_timestamp='12345'), + ]) + + source_repo = osv.SourceRepository.get_by_id('oss-fuzz') + self.assertEqual( + datetime.datetime(2021, 1, 1, 10, 0, tzinfo=datetime.UTC), + source_repo.last_update_date) + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + def test_scheduled_updates_already_done(self, mock_publish): # pylint: disable=unused-argument + """Scheduled updates already done.""" + # TODO(michaelkedar): This test doesn't check anything + self.skipTest("Not Implemented") + source_repo = osv.SourceRepository.get_by_id('oss-fuzz') + source_repo.last_update_date = importer.utcnow() + source_repo.put() + + self.mock_repo.add_file('proj/OSV-2021-1337.yaml', _MIN_VALID_VULNERABILITY) + self.mock_repo.commit('OSV', 'infra@osv.dev') + osv.Bug( + db_id='OSV-2021-1337', + project=['proj'], + fixed='', + status=1, + source_id='oss-fuzz:123', + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + timestamp=datetime.datetime( + 2020, 1, 1, 0, 0, 0, 0, tzinfo=datetime.UTC)).put() + + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + imp.run() + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + def test_no_updates(self, mock_publish): # pylint: disable=unused-argument + """Test no update marker.""" + # TODO(michaelkedar): This test doesn't check anything + self.skipTest("Not Implemented") + self.mock_repo.add_file('2021-111.yaml', _MIN_VALID_VULNERABILITY) + self.mock_repo.commit('User', 'user@email', 'message. OSV-NO-UPDATE') + + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + imp.run() + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + def test_ignore(self, mock_publish): # pylint: disable=unused-argument + """Test ignoring.""" + self.assertTrue(self.source_repo.ignore_file('/tmp/foo/recoredIGNOREme')) + source_repo_ignore_negative = osv.SourceRepository( + ignore_patterns=['(^(?!USN-).*$)']) + self.assertTrue( + source_repo_ignore_negative.ignore_file('/tmp/foo/CVE-2024-1234.json')) + source_repo_ignore_multiple = osv.SourceRepository( + ignore_patterns=['^(?!MAL-).*$', 'MAL-0000.*']) + self.assertTrue( + source_repo_ignore_multiple.ignore_file('/tmp/foo/CVE-2024-1234.json')) + self.assertTrue( + source_repo_ignore_multiple.ignore_file('/tmp/foo/MAL-0000-0001.json')) + + @mock.patch('osv.repos.FETCH_CACHE_SECONDS', 0) + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + def test_importer_bug_creation_and_update_git(self, mock_publish): + """Test importer bug creation and updates via Git.""" + self.skipTest('disabled') + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + + # 1. Start with bug not in db. + test_id = 'OSV-TEST-GIT-1' + self.assertIsNone(osv.Bug.get_by_id(test_id)) + + # 2. Run importer for one Git record. + vuln_v1 = f''' +id: {test_id} +modified: '2023-01-01T00:00:00Z' +schema_version: '1.3.0' +summary: Summary v1 +affected: +- package: + name: package-a + ecosystem: PyPI + versions: + - 1.0.0 +''' + self.mock_repo.add_file(f'{test_id}.yaml', vuln_v1) + self.mock_repo.commit('User', 'user@email') + imp.run() + + # 3. Check that record is now in db. + mock_publish.assert_called_once() + bug_v1 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v1) + self.assertEqual('Summary v1', bug_v1.summary) + self.assertEqual(1, len(bug_v1.affected_packages)) + self.assertEqual('package-a', bug_v1.affected_packages[0].package.name) + self.assertIsNotNone(bug_v1.affected_checksum) + v1_checksum = bug_v1.affected_checksum + + mock_publish.reset_mock() + + # 4. Rerun import for record w/ modified affected[]. + vuln_v2 = f''' +id: {test_id} +modified: '2023-01-02T00:00:00Z' +schema_version: '1.3.0' +summary: Summary v1 +affected: +- package: + name: package-b + ecosystem: PyPI + versions: + - 2.0.0 +''' + self.mock_repo.add_file(f'{test_id}.yaml', vuln_v2) + self.mock_repo.commit('User', 'user@email') + imp.run() + + # 5. Check that modified affected now in datastore. + mock_publish.assert_called_once() + bug_v2 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v2) + self.assertEqual('Summary v1', bug_v2.summary) + self.assertEqual(1, len(bug_v2.affected_packages)) + self.assertEqual('package-b', bug_v2.affected_packages[0].package.name) + self.assertNotEqual(v1_checksum, bug_v2.affected_checksum) + v2_checksum = bug_v2.affected_checksum + + mock_publish.reset_mock() + + # 6. Manually modify the Bug.affected (to pretend it's been enriched). + enriched_package = osv.AffectedPackage( + package=osv.Package(name='package-b', ecosystem='PyPI'), + ecosystem_specific={'extra_data': 'enriched'}) + bug_v2.affected_packages = [enriched_package] + bug_v2.put() + + # 7. Rerun import for record w/ modified summary (but affected the same). + vuln_v3 = f''' +id: {test_id} +modified: '2023-01-03T00:00:00Z' +schema_version: '1.3.0' +summary: Summary v3 +affected: +- package: + name: package-b + ecosystem: PyPI + versions: + - 2.0.0 +''' + self.mock_repo.add_file(f'{test_id}.yaml', vuln_v3) + self.mock_repo.commit('User', 'user@email') + imp.run() + + # 8. Check that summary has been updated, but not affected. + mock_publish.assert_called_once() + bug_v3 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v3) + self.assertEqual('Summary v3', bug_v3.summary) + self.assertEqual(1, len(bug_v3.affected_packages)) + self.assertEqual('package-b', bug_v3.affected_packages[0].package.name) + # This is the key check: the enriched data should still be there. + self.assertEqual({'extra_data': 'enriched'}, + bug_v3.affected_packages[0].ecosystem_specific) + # The checksum should be the same as before enrichment, as it's based on + # the raw vuln. + self.assertEqual(v2_checksum, bug_v3.affected_checksum) + + +@mock.patch('importer.utcnow', + lambda: datetime.datetime(2021, 1, 1, tzinfo=datetime.UTC)) +class BucketImporterTest(unittest.TestCase): + """GCS bucket importer tests.""" + + @classmethod + def setUpClass(cls): + # Start the emulator BEFORE creating the ndb client + cls.emulator = cls.enterClassContext(tests.datastore_emulator()) + cls.ndb_context = cls.enterClassContext( + ndb.Client().context(cache_policy=False)) + + def setUp(self): + self.emulator.reset() + self.maxDiff = None # pylint: disable=invalid-name + self.tmp_dir = tempfile.mkdtemp() + + tests.mock_datetime(self) + warnings.filterwarnings('ignore', category=SystemTimeWarning) + + self.source_repo = osv.SourceRepository( + type=osv.SourceRepositoryType.BUCKET, + id='test', + name='test', + bucket=TEST_BUCKET, + directory_path='a/b', + extension='.json', + strict_validation=True) + self.source_repo.put() + + # Preexisting Bug that exists in GCS. + osv.Bug( + id='DSA-3029-1', + db_id='DSA-3029-1', + status=1, + source='test', + source_id='test:a/b/DSA-3029-1.json', + public=True, + affected_packages=[{ + 'package': { + 'ecosystem': 'Debian:7', + 'name': 'test', + }, + }], + # Same timestamp as the gs://TEST_BUCKET/a/b/DSA-3029-1.json modified + # file + import_last_modified=datetime.datetime( + 2014, 9, 20, 8, 18, 7, 0, tzinfo=datetime.UTC), + ).put() + + # Preexisting Bug that does not exist in GCS. + osv.Bug( + id='CVE-2018-1000030', + db_id='CVE-2018-1000030', + status=1, + source='test', + source_id='test:a/b/CVE-2018-1000030.json', + public=True, + affected_packages=[{ + 'package': { + 'ecosystem': '', + 'name': '', + 'purl': None, + }, + 'ranges': [{ + 'events': [{ + 'value': '0', + 'type': 'introduced' + }, { + 'value': '84471935ed2f62b8c5758fd544c7d37076fe0fa5', + 'type': 'last_affected', + }], + "type": "GIT", + "repo_url": "https://github.com/python/cpython" + }] + }], + import_last_modified=datetime.datetime( + 2018, 2, 9, 3, 29, 0, 0, tzinfo=datetime.UTC), + ).put() + + # Preexisting Bug (with a colon in the ID) that does not exist in GCS. + osv.Bug( + id='RXSA-2023:0101', + db_id='RXSA-2023:0101', + status=1, + source='test', + source_id='test:RXSA-2023:0101.json', + public=True, + affected_packages=[{ + 'package': { + 'ecosystem': + 'Rocky Linux:8', + 'name': + 'kernel', + 'purl': ('pkg:rpm/rocky-linux/kernel' + '?distro=rocky-linux-8-sig-cloud&epoch=0'), + }, + 'ranges': [{ + 'events': [{ + 'value': '0', + 'type': 'introduced' + }, { + 'value': '0:4.18.0-425.10.1.el8_7.cloud', + 'type': 'fixed' + }], + 'type': 'ECOSYSTEM', + }], + }], + import_last_modified=datetime.datetime( + 2018, 2, 9, 3, 29, 0, 0, tzinfo=datetime.UTC), + ).put() + + self.tasks_topic = f'projects/{tests.TEST_PROJECT_ID}/topics/tasks' + + def tearDown(self): + shutil.rmtree(self.tmp_dir, ignore_errors=True) + + @mock.patch('google.cloud.storage.Blob.download_as_bytes') + @mock.patch('google.cloud.storage.Client.list_blobs') + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + @mock.patch('time.time', return_value=12345.0) + def test_importer_bug_creation_and_update(self, mock_time, mock_publish, + mock_list_blobs, mock_download): + """Test importer bug creation and updates.""" + self.skipTest('disabled') + del mock_time # Unused. + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + True, False) + + # 1. Start with bug not in db. + test_id = 'OSV-TEST-1' + self.assertIsNone(osv.Bug.get_by_id(test_id)) + + # 2. Run importer for one GCS record. + vuln_v1 = f'''{{ + "id": "{test_id}", + "modified": "2023-01-01T00:00:00Z", + "schema_version": "1.3.0", + "summary": "Summary v1", + "affected": [ + {{ + "package": {{ "name": "package-a", "ecosystem": "PyPI" }}, + "versions": [ "1.0.0" ] + }} + ] + }}''' + + mock_blob_v1 = mock.MagicMock(spec=storage.Blob) + mock_blob_v1.name = f'a/b/{test_id}.json' + mock_blob_v1.updated = datetime.datetime( + 2023, 1, 1, 0, 0, 1, tzinfo=datetime.UTC) + + mock_list_blobs.return_value = [mock_blob_v1] + mock_download.return_value = vuln_v1.encode() + + imp.run() + + # 3. Check that record is now in db. + mock_publish.assert_called_once() + bug_v1 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v1) + self.assertEqual('Summary v1', bug_v1.summary) + self.assertEqual(1, len(bug_v1.affected_packages)) + self.assertEqual('package-a', bug_v1.affected_packages[0].package.name) + self.assertIsNotNone(bug_v1.affected_checksum) + v1_checksum = bug_v1.affected_checksum + + mock_publish.reset_mock() + mock_list_blobs.reset_mock() + mock_download.reset_mock() + + # 4. Rerun import for record w/ modified affected[]. + vuln_v2 = f'''{{ + "id": "{test_id}", + "modified": "2023-01-02T00:00:00Z", + "schema_version": "1.3.0", + "summary": "Summary v1", + "affected": [ + {{ + "package": {{ "name": "package-b", "ecosystem": "PyPI" }}, + "versions": [ "2.0.0" ] + }} + ] + }}''' + mock_blob_v2 = mock.MagicMock(spec=storage.Blob) + mock_blob_v2.name = f'a/b/{test_id}.json' + mock_blob_v2.updated = datetime.datetime( + 2023, 1, 2, 0, 0, 1, tzinfo=datetime.UTC) + mock_list_blobs.return_value = [mock_blob_v2] + mock_download.return_value = vuln_v2.encode() + + imp.run() + + # 5. Check that modified affected now in datastore. + mock_publish.assert_called_once() + bug_v2 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v2) + self.assertEqual('Summary v1', bug_v2.summary) + self.assertEqual(1, len(bug_v2.affected_packages)) + self.assertEqual('package-b', bug_v2.affected_packages[0].package.name) + self.assertNotEqual(v1_checksum, bug_v2.affected_checksum) + v2_checksum = bug_v2.affected_checksum + + mock_publish.reset_mock() + mock_list_blobs.reset_mock() + mock_download.reset_mock() + + # 6. Manually modify the Bug.affected (to pretend it's been enriched). + enriched_package = osv.AffectedPackage( + package=osv.Package(name='package-b', ecosystem='PyPI'), + ecosystem_specific={'extra_data': 'enriched'}) + bug_v2.affected_packages = [enriched_package] + bug_v2.put() + + # 7. Rerun import for record w/ modified summary (but affected the same). + vuln_v3 = f'''{{ + "id": "{test_id}", + "modified": "2023-01-03T00:00:00Z", + "schema_version": "1.3.0", + "summary": "Summary v3", + "affected": [ + {{ + "package": {{ "name": "package-b", "ecosystem": "PyPI" }}, + "versions": [ "2.0.0" ] + }} + ] + }}''' + mock_blob_v3 = mock.MagicMock(spec=storage.Blob) + mock_blob_v3.name = f'a/b/{test_id}.json' + mock_blob_v3.updated = datetime.datetime( + 2023, 1, 3, 0, 0, 1, tzinfo=datetime.UTC) + mock_list_blobs.return_value = [mock_blob_v3] + mock_download.return_value = vuln_v3.encode() + + imp.run() + + # 8. Check that summary has been updated, but not affected. + mock_publish.assert_called_once() + bug_v3 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v3) + self.assertEqual('Summary v3', bug_v3.summary) + self.assertEqual(1, len(bug_v3.affected_packages)) + self.assertEqual('package-b', bug_v3.affected_packages[0].package.name) + # This is the key check: the enriched data should still be there. + self.assertEqual({'extra_data': 'enriched'}, + bug_v3.affected_packages[0].ecosystem_specific) + # The checksum should be the same as before enrichment, as it's based on + # the raw vuln. + self.assertEqual(v2_checksum, bug_v3.affected_checksum) + + +class BucketImporterMassDeletionTest(unittest.TestCase): + """Rigorous deletion testing against production data (in staging).""" + + def setUp(self): + if not (os.environ.get('CLOUD_BUILD') != 1 and + 'RUN_SLOW_TESTS' in os.environ): + self.skipTest('Skipping slow test') + # Note: This runs (non-destructively) against the real live (non-emulated) + # staging datastore and GCS bucket. + self.old_gcp = os.environ.get('GOOGLE_CLOUD_PROJECT') + os.environ['GOOGLE_CLOUD_PROJECT'] = 'oss-vdb-test' + self.enterContext(ndb.Client(project='oss-vdb-test').context()) + + self.maxDiff = None # pylint: disable=invalid-name + self.tmp_dir = tempfile.mkdtemp() + + self.tasks_topic = f'projects/{tests.TEST_PROJECT_ID}/topics/tasks' + + # The live bucket in staging. + self.source_repo = osv.SourceRepository( + type=osv.SourceRepositoryType.BUCKET, + id='cve-osv', + name='cve-osv', + bucket='osv-test-cve-osv-conversion', + directory_path='osv-output', + extension='.json', + db_prefix=['CVE-']) + + tests.mock_datetime(self) + + self.logger = logging.getLogger() + self.logger.level = logging.INFO + + def tearDown(self): + if self.old_gcp is None: + os.environ.pop('GOOGLE_CLOUD_PROJECT') + else: + os.environ['GOOGLE_CLOUD_PROJECT'] = self.old_gcp + shutil.rmtree(self.tmp_dir, ignore_errors=True) + + @mock.patch('google.cloud.storage.Blob.upload_from_string') + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + def test_deletions_in_staging(self, mock_publish: mock.MagicMock, + unused_upload_from_str: mock.MagicMock): + """Load test against staging bucket and (non-emulated) staging Datastore.""" + imp = importer.Importer( + 'fake_public_key', + 'fake_private_key', + self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, + 'bucket', + True, + False, + deletion_safety_threshold_pct=100) + + imp.process_deletions(self.source_repo) + # This will start to fail once relevant records are actually deleted out of + # Datastore in staging. + mock_publish.assert_has_calls([ + mock.call( + self.tasks_topic, + data=b'', + type='update', + source='cve-osv', + path=mock.ANY, + original_sha256=mock.ANY, + deleted='true', + req_timestamp=mock.ANY) + ]) + + +@mock.patch('importer.utcnow', + lambda: datetime.datetime(2024, 1, 1, tzinfo=datetime.UTC)) +class RESTImporterTest(unittest.TestCase): + """REST importer tests.""" + httpd = None + + @classmethod + def setUpClass(cls): + # Start the emulator BEFORE creating the ndb client + cls.emulator = cls.enterClassContext(tests.datastore_emulator()) + cls.enterClassContext(ndb.Client().context(cache_policy=False)) + + def setUp(self): + self.emulator.reset() + self.tmp_dir = tempfile.mkdtemp() + + tests.mock_datetime(self) + warnings.filterwarnings('ignore', category=SystemTimeWarning) + + storage_patcher = mock.patch('google.cloud.storage.Client') + self.addCleanup(storage_patcher.stop) + self.mock_storage_client = storage_patcher.start() + + self.source_repo = osv.SourceRepository( + type=osv.SourceRepositoryType.REST_ENDPOINT, + id='curl', + name='curl', + link=MOCK_ADDRESS_FORMAT, + rest_api_url=MOCK_ADDRESS_FORMAT, + db_prefix=['CURL-', 'RHSA-', 'OSV-'], + extension='.json', + editable=False, + strict_validation=True) + self.source_repo.put() + self.tasks_topic = f'projects/{tests.TEST_PROJECT_ID}/topics/tasks' + + def tearDown(self): + shutil.rmtree(self.tmp_dir, ignore_errors=True) + + @contextlib.contextmanager + def server(self, handler_class): + """REST mock server context manager.""" + httpd = http.server.HTTPServer(SERVER_ADDRESS, handler_class) + thread = threading.Thread(target=httpd.serve_forever) + thread.start() + try: + yield httpd + finally: + httpd.shutdown() + httpd.server_close() + thread.join() + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + @mock.patch('time.time', return_value=12345.0) + def test_invalid(self, unused_mock_time: mock.MagicMock, + mock_publish: mock.MagicMock): + """Test invalid records are treated correctly.""" + # TODO(apollock): implement + + @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + @mock.patch('time.time', return_value=12345.0) + def test_importer_bug_creation_and_update_rest(self, unused_mock_time, + mock_publish): + """Test importer bug creation and updates via REST.""" + self.skipTest('disabled') + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + False, False) + + # 1. Start with bug not in db. + test_id = 'OSV-TEST-REST-1' + self.assertIsNone(osv.Bug.get_by_id(test_id)) + + # 2. Run importer for one REST record. + vuln_v1 = f'''[{{ + "id": "{test_id}", + "modified": "2023-01-01T00:00:00Z", + "schema_version": "1.3.0", + "summary": "Summary v1", + "affected": [ + {{ + "package": {{ "name": "package-a", "ecosystem": "PyPI" }}, + "versions": [ "1.0.0" ] + }} + ] + }}]''' + data_handler = MockDataHandler + data_handler.last_modified = 'Mon, 01 Jan 2023 00:00:00 GMT' + data_handler.load_data(data_handler, vuln_v1) + + with self.server(data_handler): + imp.run() + + # 3. Check that record is now in db. + mock_publish.assert_called_once() + bug_v1 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v1) + self.assertEqual('Summary v1', bug_v1.summary) + self.assertEqual(1, len(bug_v1.affected_packages)) + self.assertEqual('package-a', bug_v1.affected_packages[0].package.name) + self.assertIsNotNone(bug_v1.affected_checksum) + v1_checksum = bug_v1.affected_checksum + + mock_publish.reset_mock() + + # 4. Rerun import for record w/ modified affected[]. + vuln_v2 = f'''[{{ + "id": "{test_id}", + "modified": "2023-01-02T00:00:00Z", + "schema_version": "1.3.0", + "summary": "Summary v1", + "affected": [ + {{ + "package": {{ "name": "package-b", "ecosystem": "PyPI" }}, + "versions": [ "2.0.0" ] + }} + ] + }}]''' + data_handler.last_modified = 'Mon, 02 Jan 2023 00:00:00 GMT' + data_handler.load_data(data_handler, vuln_v2) + + with self.server(data_handler): + imp.run() + + # 5. Check that modified affected now in datastore. + mock_publish.assert_called_once() + bug_v2 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v2) + self.assertEqual('Summary v1', bug_v2.summary) + self.assertEqual(1, len(bug_v2.affected_packages)) + self.assertEqual('package-b', bug_v2.affected_packages[0].package.name) + self.assertNotEqual(v1_checksum, bug_v2.affected_checksum) + v2_checksum = bug_v2.affected_checksum + + mock_publish.reset_mock() + + # 6. Manually modify the Bug.affected (to pretend it's been enriched). + enriched_package = osv.AffectedPackage( + package=osv.Package(name='package-b', ecosystem='PyPI'), + ecosystem_specific={'extra_data': 'enriched'}) + bug_v2.affected_packages = [enriched_package] + bug_v2.put() + + # 7. Rerun import for record w/ modified summary (but affected the same). + vuln_v3 = f'''[{{ + "id": "{test_id}", + "modified": "2023-01-03T00:00:00Z", + "schema_version": "1.3.0", + "summary": "Summary v3", + "affected": [ + {{ + "package": {{ "name": "package-b", "ecosystem": "PyPI" }}, + "versions": [ "2.0.0" ] + }} + ] + }}]''' + data_handler.last_modified = 'Mon, 03 Jan 2023 00:00:00 GMT' + data_handler.load_data(data_handler, vuln_v3) + + with self.server(data_handler): + imp.run() + + # 8. Check that summary has been updated, but not affected. + mock_publish.assert_called_once() + bug_v3 = osv.Bug.get_by_id(test_id) + self.assertIsNotNone(bug_v3) + self.assertEqual('Summary v3', bug_v3.summary) + self.assertEqual(1, len(bug_v3.affected_packages)) + self.assertEqual('package-b', bug_v3.affected_packages[0].package.name) + # This is the key check: the enriched data should still be there. + self.assertEqual({'extra_data': 'enriched'}, + bug_v3.affected_packages[0].ecosystem_specific) + # The checksum should be the same as before enrichment, as it's based on + # the raw vuln. + self.assertEqual(v2_checksum, bug_v3.affected_checksum) + + +@mock.patch('importer.utcnow', + lambda: datetime.datetime(2024, 1, 1, tzinfo=datetime.UTC)) +class ImportFindingsTest(unittest.TestCase): + """Import Finding tests.""" + + @classmethod + def setUpClass(cls): + # Start the emulator BEFORE creating the ndb client + cls.emulator = cls.enterClassContext(tests.datastore_emulator()) + cls.enterClassContext(ndb.Client().context(cache_policy=False)) + + def setUp(self): + self.emulator.reset() + self.tmp_dir = tempfile.mkdtemp() + + tests.mock_datetime(self) + warnings.filterwarnings('ignore', category=SystemTimeWarning) + + def test_add_finding(self): + """Test that creating an import finding works.""" + expected = osv.ImportFinding( + bug_id='CVE-2024-1234', + source='cve-osv', + findings=[ + osv.ImportFindings.INVALID_VERSION, + ], + first_seen=importer.utcnow(), + last_attempt=importer.utcnow(), + ).to_dict() + + imp = importer.Importer('fake_public_key', 'fake_private_key', self.tmp_dir, + importer.DEFAULT_PUBLIC_LOGGING_BUCKET, 'bucket', + False, False) + # pylint: disable-next=protected-access + imp._record_quality_finding('cve-osv', 'CVE-2024-1234', + osv.ImportFindings.INVALID_VERSION) + + actual = osv.ImportFinding.get_by_id(expected['bug_id']).to_dict() + self.assertEqual(expected, actual) + + +def setUpModule(): + """Set up the test module.""" + logging.getLogger().setLevel(logging.ERROR) + logging.getLogger("UpstreamTest.test_compute_upstream").setLevel( + logging.DEBUG) + + +if __name__ == '__main__': + unittest.main() diff --git a/gcp/workers/oss_fuzz_importer/run_tests.sh b/gcp/workers/oss_fuzz_importer/run_tests.sh new file mode 100755 index 00000000000..97749d070a7 --- /dev/null +++ b/gcp/workers/oss_fuzz_importer/run_tests.sh @@ -0,0 +1,19 @@ +#!/bin/bash -ex +# Copyright 2021 Google LLC +# +# 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. + +cd ../oss_fuzz_worker + +poetry install +poetry run python ../oss_fuzz_importer/importer_test.py diff --git a/gcp/workers/oss_fuzz_importer/testdata b/gcp/workers/oss_fuzz_importer/testdata new file mode 120000 index 00000000000..ccb04084adb --- /dev/null +++ b/gcp/workers/oss_fuzz_importer/testdata @@ -0,0 +1 @@ +../importer/testdata/ \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/Dockerfile b/gcp/workers/oss_fuzz_worker/Dockerfile new file mode 100644 index 00000000000..abe11176650 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/Dockerfile @@ -0,0 +1,34 @@ +# Copyright 2021 Google LLC +# +# 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. + +FROM gcr.io/oss-vdb/worker-base + +RUN apt-get update && apt-get upgrade -y + +RUN mkdir /work && mkdir -p /env/gcp/workers/worker +VOLUME /var/lib/docker + +# Replicate project structure to make relative editable poetry dependency work. +# TODO(ochang): Just copy the entire project (needs a clean checkout). +COPY gcp/workers/oss_fuzz_worker/poetry.lock gcp/workers/oss_fuzz_worker/pyproject.toml /env/gcp/workers/worker/ +COPY poetry.lock pyproject.toml README.md /env/ +COPY osv /env/osv + +# Set virtualenv creation to false to install globally +RUN cd /env/gcp/workers/worker && POETRY_VIRTUALENVS_CREATE=false poetry install + +COPY gcp/workers/oss_fuzz_worker/oss_fuzz.py gcp/workers/oss_fuzz_worker/worker.py /usr/local/bin/ +RUN chmod 755 /usr/local/bin/worker.py + +ENTRYPOINT ["worker.py"] diff --git a/gcp/workers/oss_fuzz_worker/oss_fuzz.py b/gcp/workers/oss_fuzz_worker/oss_fuzz.py new file mode 100644 index 00000000000..c0e91ad07d8 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/oss_fuzz.py @@ -0,0 +1,551 @@ +# Copyright 2021 Google LLC +# +# 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. +"""OSS-Fuzz integration.""" +import datetime +import logging +import os +import re +import sys +import traceback +import tempfile +import yaml + +from google.cloud import ndb +import pygit2.enums + +sys.path.append(os.path.dirname(os.path.realpath(__file__))) +import osv + +OSS_FUZZ_ISSUE_URL = 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=' +SOURCE_PREFIX = 'oss-fuzz:' + +COMMIT_RANGE_LIMIT = 4 + +# Used in cases where an earlier commit in a regression range cannot be +# determined. +UNKNOWN_COMMIT = 'unknown' + +# Projects that are excluded from OSV analysis. +# TODO(ochang): Don't hardcode this. +PROJECT_DENYLIST = { + 'avahi', # https://github.com/google/osv.dev/issues/2178 + 'boringssl', # https://github.com/google/osv.dev/issues/2178 + 'dbus-broker', # https://github.com/google/osv.dev/issues/2178 + 'elfutils', # https://github.com/google/osv.dev/issues/2178 + 'ffmpeg', + 'imagemagick', + 'libbpf', # https://github.com/google/osv.dev/issues/2178 + 'libreoffice', + 'systemd', # https://github.com/google/osv.dev/issues/2178 + 'xpdf', # https://github.com/google/oss-fuzz/issues/13248 +} + +REPO_DENYLIST = { + 'https://github.com/google/AFL.git', +} + + +def format_commit_range(old_commit, new_commit): + """Format a commit range.""" + if old_commit == new_commit: + return old_commit + + return (old_commit or UNKNOWN_COMMIT) + ':' + new_commit + + +def find_oss_fuzz_fix_via_commit(repo, start_commit, end_commit, source_id, + issue_id): + """Find fix commit by checking commit messages.""" + if not source_id.startswith(SOURCE_PREFIX): + return None + + # Walk through start_commit..end_commit + try: + walker = repo.walk(end_commit, pygit2.enums.SortMode.TOPOLOGICAL) + except KeyError: + logging.warning('Failed to walk repo with invalid commit: %s', end_commit) + return None + + walker.hide(start_commit) + + testcase_id = source_id.split(':')[1] + oss_fuzz_pattern = re.compile(r'oss-?fuzz', re.IGNORECASE) + has_oss_fuzz_in_message = [] + has_testcase_id_in_message = [] + has_issue_id_in_message = [] + + # Look for commits with (in order of decreasing priority): + # - "oss-?fuzz" and the issue ID in the message. + # - ClusterFuzz testcase ID in the message. + # - "oss-?fuzz" in the message. + + for commit in walker: + commit_message = commit.message.lower() + has_oss_fuzz = False + + if oss_fuzz_pattern.search(commit_message): + has_oss_fuzz = True + has_oss_fuzz_in_message.append(commit) + + if testcase_id in commit_message: + has_testcase_id_in_message.append(commit) + + if issue_id and issue_id in commit_message and has_oss_fuzz: + has_issue_id_in_message.append(commit) + + if has_issue_id_in_message: + return str(has_issue_id_in_message[0].id) + + if has_testcase_id_in_message: + return str(has_testcase_id_in_message[0].id) + + if len(has_oss_fuzz_in_message) == 1: + # Only pick the commit if there is a single one that mentions oss-fuzz. + return str(has_oss_fuzz_in_message[0].id) + + return None + + +def do_bisect(bisect_type, source_id, project_name, engine, sanitizer, + architecture, fuzz_target, old_commit, new_commit, testcase): + """Do the actual bisect.""" + import bisector + import build_specified_commit + + with tempfile.NamedTemporaryFile() as f: + f.write(testcase) + f.flush() + + build_data = build_specified_commit.BuildData( + project_name=project_name, + engine=engine, + sanitizer=sanitizer, + architecture=architecture) + try: + result = bisector.bisect(bisect_type, old_commit, new_commit, f.name, + fuzz_target, build_data) + except bisector.BisectError as e: + logging.warning('Bisect failed with exception:\n%s', + traceback.format_exc()) + return bisector.Result(e.repo_url, None) + except Exception: + logging.error('Bisect failed with unexpected exception:\n%s', + traceback.format_exc()) + return None + + if result.commit == old_commit: + logging.warning('Bisect failed for testcase %s, bisected to old_commit', + source_id) + result = None + + return result + + +def process_bisect_task(oss_fuzz_dir, bisect_type, source_id, message): + """Process a bisect task.""" + bisect_type = message.attributes['type'] + project_name = message.attributes['project_name'] + engine = 'libfuzzer' + architecture = message.attributes['architecture'] or 'x86_64' + sanitizer = message.attributes['sanitizer'] + fuzz_target = message.attributes['fuzz_target'] + old_commit = message.attributes['old_commit'] + + new_commit = message.attributes['new_commit'] + testcase = message.data + logging.info( + 'Performing %s bisect on source_id=%s, project=%s, engine=%s, ' + 'architecture=%s, sanitizer=%s, fuzz_target=%s, old_commit=%s, ' + 'new_commit=%s', bisect_type, source_id, project_name, engine, + architecture, sanitizer, fuzz_target, old_commit, new_commit) + + result = None + if project_name in PROJECT_DENYLIST: + logging.info('Skipping bisect for denylisted project %s', project_name) + elif not old_commit: + logging.info('Skipping bisect since there is no old_commit.') + else: + result = do_bisect(bisect_type, source_id, project_name, engine, sanitizer, + architecture, fuzz_target, old_commit, new_commit, + testcase) + + if result and result.repo_url in REPO_DENYLIST: + logging.info('Skipping because of denylisted repo %s.', result.repo_url) + return + + if bisect_type == 'fixed': + entity = osv.FixResult(id=source_id) + else: + assert bisect_type == 'regressed' + entity = osv.RegressResult(id=source_id) + + _set_result_attributes(oss_fuzz_dir, message, entity) + + if result and result.commit: + logging.info('Bisected to %s', result.commit) + entity.commit = result.commit + entity.repo_url = result.repo_url + else: + logging.info( + 'Bisect not successfully performed. Setting commit range from request.') + entity.commit = format_commit_range(old_commit, new_commit) + entity.repo_url = result.repo_url if result else None + entity.error = 'Bisect error' + + entity.put() + + +def set_bug_attributes(bug, regress_result, fix_result): + """Set bug attributes from bisection results.""" + issue_id = fix_result.issue_id or regress_result.issue_id + project = fix_result.project or regress_result.project + ecosystem = fix_result.ecosystem or regress_result.ecosystem + summary = fix_result.summary or regress_result.summary + details = fix_result.details or regress_result.details + severity = fix_result.severity or regress_result.severity + reference_urls = fix_result.reference_urls or regress_result.reference_urls + + bug.affected_packages = [ + osv.AffectedPackage( + package=osv.Package(name=project, ecosystem=ecosystem), + ecosystem_specific={ + 'severity': severity, + }) + ] + + bug.issue_id = issue_id + bug.summary = summary + bug.details = details + bug.severity = severity + bug.reference_url_types = {} + + for reference_url in reference_urls: + if OSS_FUZZ_ISSUE_URL in reference_url: + link_type = 'REPORT' + else: + link_type = 'WEB' + bug.reference_url_types[reference_url] = link_type + + bug.regressed = regress_result.commit or '' + bug.fixed = fix_result.commit or '' + + +def _get_commit_range(repo, commit_or_range): + """Get a commit range.""" + if not commit_or_range: + return [] + + if ':' not in commit_or_range: + return [commit_or_range] + + start_commit, end_commit = commit_or_range.split(':') + if start_commit == UNKNOWN_COMMIT: + # Special case: No information about earlier builds. Assume the end_commit + # is the regressing commit as that's the best we can do. + return [end_commit] + + commits, _ = osv.get_commit_and_tag_list(repo, start_commit, end_commit) + return commits + + +def _get_commits(repo, regress_commit_or_range, fix_commit_or_range): + """Get commits for analysis.""" + regress_commits = _get_commit_range(repo, regress_commit_or_range) + if len(regress_commits) > COMMIT_RANGE_LIMIT: + raise osv.ImpactError('Too many commits in regression range.') + + fix_commits = _get_commit_range(repo, fix_commit_or_range) + if len(fix_commits) > COMMIT_RANGE_LIMIT: + logging.warning('Too many commits in fix range.') + # Rather than bail out here and potentially leaving a Bug as "unfixed" + # indefinitely, we continue. + + return regress_commits, fix_commits + + +def process_impact_task(source_id, message): + """Process an impact task.""" + logging.info('Processing impact task for %s', source_id) + + regress_result = ndb.Key(osv.RegressResult, source_id).get() + if not regress_result: + logging.error('Missing RegressResult for %s', source_id) + return + + fix_result = ndb.Key(osv.FixResult, source_id).get() + if not fix_result: + logging.warning('Missing FixResult for %s', source_id) + fix_result = osv.FixResult() + + # Check if there is an existing Bug for the same source, but with a different + # allocated ID. This shouldn't happen. + allocated_bug_id = message.attributes['allocated_id'] + + existing_bug = osv.Bug.query(osv.Bug.source_id == source_id).get() + if existing_bug and existing_bug.key.id() != allocated_bug_id: + logging.error('Bug entry already exists for %s with a different ID %s', + source_id, existing_bug.key.id()) + return + + if existing_bug and existing_bug.status == osv.BugStatus.INVALID: + logging.warning('Bug %s already marked as invalid.', existing_bug.key.id()) + return + + if existing_bug: + public = existing_bug.public + else: + raise osv.ImpactError('Task requested without Bug allocated.') + + repo_url = regress_result.repo_url or fix_result.repo_url + if not repo_url: + raise osv.ImpactError('No repo_url set') + + # Always populate Bug attributes, even if the remainder of the analysis fails. + # This does not mark the Bug as being valid. + set_bug_attributes(existing_bug, regress_result, fix_result) + existing_bug.put() + + issue_id = fix_result.issue_id or regress_result.issue_id + fix_commit = fix_result.commit + + with tempfile.TemporaryDirectory() as tmp_dir: + repo = osv.clone_with_retries(repo_url, tmp_dir) + + # If not a precise fix commit, try to find the exact one by going through + # commit messages (oss-fuzz only). + if source_id.startswith(SOURCE_PREFIX) and ':' in fix_commit: + start_commit, end_commit = fix_commit.split(':') + commit = find_oss_fuzz_fix_via_commit(repo, start_commit, end_commit, + source_id, issue_id) + if commit: + logging.info('Found exact fix commit %s via commit message (oss-fuzz)', + commit) + fix_commit = commit + + # Actually compute the affected commits/tags. + repo_analyzer = osv.RepoAnalyzer() + regress_commits, fix_commits = _get_commits(repo, regress_result.commit, + fix_commit) + + # If multiple, assume the first commit in the regression range cause the + # regression. + if regress_commits: + regress_commit_to_analyze = regress_commits[0] + else: + regress_commit_to_analyze = None + + # If multiple, assume the last commit is necessary for fixing the + # regression. + if fix_commits: + fix_commit_to_analyze = fix_commits[-1] + else: + fix_commit_to_analyze = None + + result = repo_analyzer.get_affected(repo, [regress_commit_to_analyze], + [fix_commit_to_analyze]) + affected_tags = sorted(list(result.tags)) + logging.info('Found affected %s', ', '.join(affected_tags)) + + if len(regress_commits) > 1 or len(fix_commits) > 1: + # Don't return ranges if input regressed and fixed commits are not single + # commits. + result.affected_ranges.clear() + + # If the range resolved to a single commit, simplify it. + if len(fix_commits) == 1: + fix_commit = fix_commits[0] + elif not fix_commits: + # Not fixed. + fix_commit = '' + + if (len(regress_commits) == 1 and + UNKNOWN_COMMIT not in regress_result.commit): + regress_commit = regress_commits[0] + else: + regress_commit = regress_result.commit + + project = fix_result.project or regress_result.project + ecosystem = fix_result.ecosystem or regress_result.ecosystem + osv.update_affected_commits(allocated_bug_id, result.commits, public) + + affected_tags = sorted(list(result.tags)) + existing_bug.fixed = fix_commit + existing_bug.regressed = regress_commit + existing_bug.status = osv.BugStatus.PROCESSED + + if existing_bug.affected_packages: + affected_package = existing_bug.affected_packages[0] + else: + affected_package = osv.AffectedPackage( + package=osv.Package(name=project, ecosystem=ecosystem)) + existing_bug.affected_packages = [affected_package] + + affected_package.versions = affected_tags + + # For the AffectedRange, use the first commit in the regress commit range, and + # the last commit in the fix commit range. + introduced = regress_commits[0] if regress_commits else '' + fixed = fix_commits[-1] if fix_commits else '' + events = [ + osv.AffectedEvent(type='introduced', value=introduced), + ] + if fixed: + events.append(osv.AffectedEvent(type='fixed', value=fixed)) + + git_range = osv.AffectedRange2(type='GIT', repo_url=repo_url, events=events) + affected_package.ranges = [git_range] + + # Expose range data in `database_specific`. + database_specific = {} + if ':' in existing_bug.regressed: + database_specific['introduced_range'] = existing_bug.regressed + if ':' in existing_bug.fixed: + database_specific['fixed_range'] = existing_bug.fixed + + if database_specific: + affected_package.database_specific = database_specific + + # Don't display additional ranges for imprecise commits, as they can be + # confusing. + if ':' in existing_bug.fixed or ':' in existing_bug.regressed: + existing_bug.put() + return + + def _sort_key(value): + # Allow sorting of None values. + return (value[0] or '', value[1] or '', value[2] or '') + + for introduced_in, fixed_in, last_affected_in in sorted( + result.affected_ranges, key=_sort_key): + if not fixed_in: + fixed_in = '' # convert NoneType to str for next comparison + + if (introduced_in == existing_bug.regressed and + fixed_in == existing_bug.fixed): + # Don't repeat the main range. + continue + + introduced = osv.AffectedEvent(type='introduced', value=introduced_in) + if introduced not in git_range.events: + git_range.events.append(introduced) + + if last_affected_in: + last_affected = osv.AffectedEvent( + type='last_affected', value=last_affected_in) + if last_affected not in git_range.events: + git_range.events.append(last_affected) + + if fixed_in: + fixed = osv.AffectedEvent(type='fixed', value=fixed_in) + if fixed not in git_range.events: + git_range.events.append(fixed) + + existing_bug.put() + + +def get_ecosystem(oss_fuzz_dir, project_name): + """Get ecosystem.""" + project_yaml_path = os.path.join(oss_fuzz_dir, 'projects', project_name, + 'project.yaml') + + with open(project_yaml_path) as f: + project_yaml = yaml.safe_load(f) + + language = project_yaml.get('language', '') + + ecosystems = { + 'python': 'PyPI', + 'go': 'Go', + } + + # C/C++ projects from OSS-Fuzz don't belong to any package ecosystem, so we + # set "OSS-Fuzz". + return ecosystems.get(language, 'OSS-Fuzz') + + +def _set_result_attributes(oss_fuzz_dir, message, entity): + """Set necessary fields from bisection message.""" + project_name = message.attributes['project_name'] + issue_id = message.attributes['issue_id'] or None + crash_type = message.attributes['crash_type'] + crash_state = message.attributes['crash_state'] + severity = message.attributes['severity'].upper() + + timestamp = message.attributes['timestamp'] + if timestamp: + timestamp = datetime.datetime.fromisoformat(timestamp) + + entity.project = project_name + entity.ecosystem = get_ecosystem(oss_fuzz_dir, project_name) + entity.issue_id = issue_id + if issue_id: + entity.reference_urls.append(OSS_FUZZ_ISSUE_URL + issue_id) + + entity.summary = get_oss_fuzz_summary(crash_type, crash_state) + entity.details = get_oss_fuzz_details(issue_id, crash_type, crash_state) + + if severity: + entity.severity = severity + + if timestamp: + entity.timestamp = timestamp + + +def handle_timeout(task_type, source_id, oss_fuzz_dir, message): + """Handle a timeout.""" + old_commit = message.attributes['old_commit'] + new_commit = message.attributes['new_commit'] + + if task_type == 'fixed': + entity = osv.FixResult(id=source_id) + else: + assert task_type == 'regressed' + entity = osv.RegressResult(id=source_id) + + _set_result_attributes(oss_fuzz_dir, message, entity) + + entity.commit = format_commit_range(old_commit, new_commit) + entity.error = 'Timeout' + entity.put() + + +def get_oss_fuzz_summary(crash_type, crash_state): + """Generate a summary from OSS-Fuzz crash type and crash state.""" + crash_type = crash_type.splitlines()[0] + state_lines = crash_state.splitlines() + if crash_type in ('ASSERT', 'CHECK failure', 'Security CHECK failure', + 'Security DCHECK failure'): + return crash_type + ': ' + state_lines[0] + + if crash_type == 'Bad-cast': + return state_lines[0] + + if not crash_state or crash_state == 'NULL': + return crash_type + + return crash_type + ' in ' + state_lines[0] + + +def get_oss_fuzz_details(issue_id, crash_type, crash_state): + """Generate details from OSS-Fuzz crash type and crash state.""" + details = '' + if issue_id: + oss_fuzz_link = OSS_FUZZ_ISSUE_URL + issue_id + details = f'OSS-Fuzz report: {oss_fuzz_link}\n\n' + + crash_type = crash_type.replace('\n', ' ') + return details + ('```\n' + f'Crash type: {crash_type}\n' + f'Crash state:\n{crash_state}' + '```\n') diff --git a/gcp/workers/oss_fuzz_worker/osv-test b/gcp/workers/oss_fuzz_worker/osv-test new file mode 120000 index 00000000000..38cf9f1af28 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/osv-test @@ -0,0 +1 @@ +../worker/osv-test/ \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/poetry.lock b/gcp/workers/oss_fuzz_worker/poetry.lock new file mode 100644 index 00000000000..eedac8c11bb --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/poetry.lock @@ -0,0 +1,2088 @@ +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. + +[[package]] +name = "absl-py" +version = "2.3.1" +description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "absl_py-2.3.1-py3-none-any.whl", hash = "sha256:eeecf07f0c2a93ace0772c92e596ace6d3d3996c042b2128459aaae2a76de11d"}, + {file = "absl_py-2.3.1.tar.gz", hash = "sha256:a97820526f7fbfd2ec1bce83f3f25e3a14840dac0d8e02a0b71cd75db3f77fc9"}, +] + +[[package]] +name = "astroid" +version = "4.0.3" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.10.0" +groups = ["dev"] +files = [ + {file = "astroid-4.0.3-py3-none-any.whl", hash = "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14"}, + {file = "astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3"}, +] + +[[package]] +name = "attrs" +version = "25.4.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"}, + {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, +] + +[[package]] +name = "cffi" +version = "2.0.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"}, + {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"}, + {file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"}, + {file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}, + {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}, + {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}, + {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}, + {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}, + {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}, + {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"}, + {file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"}, + {file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"}, + {file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"}, + {file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"}, + {file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"}, + {file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"}, + {file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"}, + {file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"}, + {file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"}, + {file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"}, + {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"}, + {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, +] + +[package.dependencies] +pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, + {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, + {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +markers = "sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "cryptography" +version = "46.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, + {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, + {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, + {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, + {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, + {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, + {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, + {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, + {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, + {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, + {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, +] + +[package.dependencies] +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "dill" +version = "0.4.1" +description = "serialize all of Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + +[[package]] +name = "google-api-core" +version = "2.29.0" +description = "Google API client core library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_api_core-2.29.0-py3-none-any.whl", hash = "sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9"}, + {file = "google_api_core-2.29.0.tar.gz", hash = "sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7"}, +] + +[package.dependencies] +google-auth = ">=2.14.1,<3.0.0" +googleapis-common-protos = ">=1.56.2,<2.0.0" +grpcio = {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} +grpcio-status = {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} +proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" +requests = ">=2.18.0,<3.0.0" + +[package.extras] +async-rest = ["google-auth[aiohttp] (>=2.35.0,<3.0.0)"] +grpc = ["grpcio (>=1.33.2,<2.0.0)", "grpcio (>=1.49.1,<2.0.0) ; python_version >= \"3.11\"", "grpcio (>=1.75.1,<2.0.0) ; python_version >= \"3.14\"", "grpcio-status (>=1.33.2,<2.0.0)", "grpcio-status (>=1.49.1,<2.0.0) ; python_version >= \"3.11\"", "grpcio-status (>=1.75.1,<2.0.0) ; python_version >= \"3.14\""] +grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] +grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] + +[[package]] +name = "google-api-python-client" +version = "2.188.0" +description = "Google API Client Library for Python" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_api_python_client-2.188.0-py3-none-any.whl", hash = "sha256:3cad1b68f9d48b82b93d77927e8370a6f43f33d97848242601f14a93a1c70ef5"}, + {file = "google_api_python_client-2.188.0.tar.gz", hash = "sha256:5c469db6614f071009e3e5bb8b6aeeccae3beb3647fa9c6cd97f0d551edde0b6"}, +] + +[package.dependencies] +google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0" +google-auth = ">=1.32.0,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" +google-auth-httplib2 = ">=0.2.0,<1.0.0" +httplib2 = ">=0.19.0,<1.0.0" +uritemplate = ">=3.0.1,<5" + +[[package]] +name = "google-auth" +version = "2.48.0" +description = "Google Authentication Library" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f"}, + {file = "google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce"}, +] + +[package.dependencies] +cryptography = ">=38.0.3" +pyasn1-modules = ">=0.2.1" +rsa = ">=3.1.4,<5" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] +cryptography = ["cryptography (>=38.0.3)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] +reauth = ["pyu2f (>=0.1.5)"] +requests = ["requests (>=2.20.0,<3.0.0)"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +urllib3 = ["packaging", "urllib3"] + +[[package]] +name = "google-auth-httplib2" +version = "0.3.0" +description = "Google Authentication Library: httplib2 transport" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_auth_httplib2-0.3.0-py3-none-any.whl", hash = "sha256:426167e5df066e3f5a0fc7ea18768c08e7296046594ce4c8c409c2457dd1f776"}, + {file = "google_auth_httplib2-0.3.0.tar.gz", hash = "sha256:177898a0175252480d5ed916aeea183c2df87c1f9c26705d74ae6b951c268b0b"}, +] + +[package.dependencies] +google-auth = ">=1.32.0,<3.0.0" +httplib2 = ">=0.19.0,<1.0.0" + +[[package]] +name = "google-cloud-appengine-logging" +version = "1.8.0" +description = "Google Cloud Appengine Logging API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_appengine_logging-1.8.0-py3-none-any.whl", hash = "sha256:a4ce9ce94a9fd8c89ed07fa0b06fcf9ea3642f9532a1be1a8c7b5f82c0a70ec6"}, + {file = "google_cloud_appengine_logging-1.8.0.tar.gz", hash = "sha256:84b705a69e4109fc2f68dfe36ce3df6a34d5c3d989eee6d0ac1b024dda0ba6f5"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} +google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" +grpcio = ">=1.33.2,<2.0.0" +proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} +protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[[package]] +name = "google-cloud-audit-log" +version = "0.4.0" +description = "Google Cloud Audit Protos" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_audit_log-0.4.0-py3-none-any.whl", hash = "sha256:6b88e2349df45f8f4cc0993b687109b1388da1571c502dc1417efa4b66ec55e0"}, + {file = "google_cloud_audit_log-0.4.0.tar.gz", hash = "sha256:8467d4dcca9f3e6160520c24d71592e49e874838f174762272ec10e7950b6feb"}, +] + +[package.dependencies] +googleapis-common-protos = ">=1.56.2,<2.0.0" +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[[package]] +name = "google-cloud-core" +version = "2.5.0" +description = "Google Cloud API client core library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_core-2.5.0-py3-none-any.whl", hash = "sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc"}, + {file = "google_cloud_core-2.5.0.tar.gz", hash = "sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963"}, +] + +[package.dependencies] +google-api-core = ">=1.31.6,<2.0.dev0 || >2.3.0,<3.0.0" +google-auth = ">=1.25.0,<3.0.0" + +[package.extras] +grpc = ["grpcio (>=1.38.0,<2.0.0) ; python_version < \"3.14\"", "grpcio (>=1.75.1,<2.0.0) ; python_version >= \"3.14\"", "grpcio-status (>=1.38.0,<2.0.0)"] + +[[package]] +name = "google-cloud-datastore" +version = "2.23.0" +description = "Google Cloud Datastore API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_datastore-2.23.0-py3-none-any.whl", hash = "sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f"}, + {file = "google_cloud_datastore-2.23.0.tar.gz", hash = "sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} +google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" +google-cloud-core = ">=1.4.0,<3.0.0" +grpcio = ">=1.38.0,<2.0.0" +proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} +protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[package.extras] +libcst = ["libcst (>=0.2.5)"] + +[[package]] +name = "google-cloud-iam" +version = "2.21.0" +description = "Google Cloud Iam API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_iam-2.21.0-py3-none-any.whl", hash = "sha256:1b4a21302b186a31f3a516ccff303779638308b7c801fb61a2406b6a0c6293c4"}, + {file = "google_cloud_iam-2.21.0.tar.gz", hash = "sha256:fc560527e22b97c6cbfba0797d867cf956c727ba687b586b9aa44d78e92281a3"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} +google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" +grpc-google-iam-v1 = ">=0.12.4,<1.0.0" +grpcio = ">=1.33.2,<2.0.0" +proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} +protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[[package]] +name = "google-cloud-logging" +version = "3.13.0" +description = "Stackdriver Logging API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_logging-3.13.0-py3-none-any.whl", hash = "sha256:f215e1c76ee29239c6cacf02443dffa985663c74bf47c9818854694805c6019f"}, + {file = "google_cloud_logging-3.13.0.tar.gz", hash = "sha256:3aae0573b1a1a4f59ecdf4571f4e7881b5823bd129fe469561c1c49a7fa8a4c1"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} +google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" +google-cloud-appengine-logging = ">=0.1.3,<2.0.0" +google-cloud-audit-log = ">=0.3.1,<1.0.0" +google-cloud-core = ">=2.0.0,<3.0.0" +grpc-google-iam-v1 = ">=0.12.4,<1.0.0" +opentelemetry-api = ">=1.9.0" +proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} +protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[[package]] +name = "google-cloud-ndb" +version = "2.4.0" +description = "NDB library for Google Cloud Datastore" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_ndb-2.4.0-py3-none-any.whl", hash = "sha256:adbb34d14f6657b48d8b3d460fcf2dcb274acf2d574d5efc33d13e903504fe85"}, + {file = "google_cloud_ndb-2.4.0.tar.gz", hash = "sha256:3a2ab97b4402f1e18cca0ef31ea40695a07483421dd1a59d4aa36c59916d10d0"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} +google-cloud-datastore = ">=2.16.0,<2.20.2 || >2.20.2,<3.0.0" +protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" +pymemcache = ">=2.1.0,<5.0.0" +pytz = ">=2018.3" +redis = ">=3.0.0,<7.0.0" + +[[package]] +name = "google-cloud-pubsub" +version = "2.34.0" +description = "Google Cloud Pub/Sub API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_pubsub-2.34.0-py3-none-any.whl", hash = "sha256:aa11b2471c6d509058b42a103ed1b3643f01048311a34fd38501a16663267206"}, + {file = "google_cloud_pubsub-2.34.0.tar.gz", hash = "sha256:25f98c3ba16a69871f9ebbad7aece3fe63c8afe7ba392aad2094be730d545976"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} +google-auth = ">=2.14.1,<3.0.0" +grpc-google-iam-v1 = ">=0.12.4,<1.0.0" +grpcio = {version = ">=1.51.3,<2.0.0", markers = "python_version < \"3.14\""} +grpcio-status = ">=1.33.2" +opentelemetry-api = {version = ">=1.27.0", markers = "python_version >= \"3.8\""} +opentelemetry-sdk = {version = ">=1.27.0", markers = "python_version >= \"3.8\""} +proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} +protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[package.extras] +libcst = ["libcst (>=0.3.10)"] + +[[package]] +name = "google-cloud-storage" +version = "2.19.0" +description = "Google Cloud Storage API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_cloud_storage-2.19.0-py2.py3-none-any.whl", hash = "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba"}, + {file = "google_cloud_storage-2.19.0.tar.gz", hash = "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2"}, +] + +[package.dependencies] +google-api-core = ">=2.15.0,<3.0.0dev" +google-auth = ">=2.26.1,<3.0dev" +google-cloud-core = ">=2.3.0,<3.0dev" +google-crc32c = ">=1.0,<2.0dev" +google-resumable-media = ">=2.7.2" +requests = ">=2.18.0,<3.0.0dev" + +[package.extras] +protobuf = ["protobuf (<6.0.0dev)"] +tracing = ["opentelemetry-api (>=1.1.0)"] + +[[package]] +name = "google-crc32c" +version = "1.8.0" +description = "A python wrapper of the C library 'Google CRC32C'" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "google_crc32c-1.8.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:0470b8c3d73b5f4e3300165498e4cf25221c7eb37f1159e221d1825b6df8a7ff"}, + {file = "google_crc32c-1.8.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:119fcd90c57c89f30040b47c211acee231b25a45d225e3225294386f5d258288"}, + {file = "google_crc32c-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6f35aaffc8ccd81ba3162443fabb920e65b1f20ab1952a31b13173a67811467d"}, + {file = "google_crc32c-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:864abafe7d6e2c4c66395c1eb0fe12dc891879769b52a3d56499612ca93b6092"}, + {file = "google_crc32c-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:db3fe8eaf0612fc8b20fa21a5f25bd785bc3cd5be69f8f3412b0ac2ffd49e733"}, + {file = "google_crc32c-1.8.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:014a7e68d623e9a4222d663931febc3033c5c7c9730785727de2a81f87d5bab8"}, + {file = "google_crc32c-1.8.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:86cfc00fe45a0ac7359e5214a1704e51a99e757d0272554874f419f79838c5f7"}, + {file = "google_crc32c-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:19b40d637a54cb71e0829179f6cb41835f0fbd9e8eb60552152a8b52c36cbe15"}, + {file = "google_crc32c-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:17446feb05abddc187e5441a45971b8394ea4c1b6efd88ab0af393fd9e0a156a"}, + {file = "google_crc32c-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:71734788a88f551fbd6a97be9668a0020698e07b2bf5b3aa26a36c10cdfb27b2"}, + {file = "google_crc32c-1.8.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:4b8286b659c1335172e39563ab0a768b8015e88e08329fa5321f774275fc3113"}, + {file = "google_crc32c-1.8.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:2a3dc3318507de089c5384cc74d54318401410f82aa65b2d9cdde9d297aca7cb"}, + {file = "google_crc32c-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14f87e04d613dfa218d6135e81b78272c3b904e2a7053b841481b38a7d901411"}, + {file = "google_crc32c-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb5c869c2923d56cb0c8e6bcdd73c009c36ae39b652dbe46a05eb4ef0ad01454"}, + {file = "google_crc32c-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:3cc0c8912038065eafa603b238abf252e204accab2a704c63b9e14837a854962"}, + {file = "google_crc32c-1.8.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:3ebb04528e83b2634857f43f9bb8ef5b2bbe7f10f140daeb01b58f972d04736b"}, + {file = "google_crc32c-1.8.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:450dc98429d3e33ed2926fc99ee81001928d63460f8538f21a5d6060912a8e27"}, + {file = "google_crc32c-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3b9776774b24ba76831609ffbabce8cdf6fa2bd5e9df37b594221c7e333a81fa"}, + {file = "google_crc32c-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:89c17d53d75562edfff86679244830599ee0a48efc216200691de8b02ab6b2b8"}, + {file = "google_crc32c-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:57a50a9035b75643996fbf224d6661e386c7162d1dfdab9bc4ca790947d1007f"}, + {file = "google_crc32c-1.8.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:e6584b12cb06796d285d09e33f63309a09368b9d806a551d8036a4207ea43697"}, + {file = "google_crc32c-1.8.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:f4b51844ef67d6cf2e9425983274da75f18b1597bb2c998e1c0a0e8d46f8f651"}, + {file = "google_crc32c-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b0d1a7afc6e8e4635564ba8aa5c0548e3173e41b6384d7711a9123165f582de2"}, + {file = "google_crc32c-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3f68782f3cbd1bce027e48768293072813469af6a61a86f6bb4977a4380f21"}, + {file = "google_crc32c-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:d511b3153e7011a27ab6ee6bb3a5404a55b994dc1a7322c0b87b29606d9790e2"}, + {file = "google_crc32c-1.8.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ba6aba18daf4d36ad4412feede6221414692f44d17e5428bdd81ad3fc1eee5dc"}, + {file = "google_crc32c-1.8.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:87b0072c4ecc9505cfa16ee734b00cd7721d20a0f595be4d40d3d21b41f65ae2"}, + {file = "google_crc32c-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d488e98b18809f5e322978d4506373599c0c13e6c5ad13e53bb44758e18d215"}, + {file = "google_crc32c-1.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01f126a5cfddc378290de52095e2c7052be2ba7656a9f0caf4bcd1bfb1833f8a"}, + {file = "google_crc32c-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:61f58b28e0b21fcb249a8247ad0db2e64114e201e2e9b4200af020f3b6242c9f"}, + {file = "google_crc32c-1.8.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:87fa445064e7db928226b2e6f0d5304ab4cd0339e664a4e9a25029f384d9bb93"}, + {file = "google_crc32c-1.8.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f639065ea2042d5c034bf258a9f085eaa7af0cd250667c0635a3118e8f92c69c"}, + {file = "google_crc32c-1.8.0.tar.gz", hash = "sha256:a428e25fb7691024de47fecfbff7ff957214da51eddded0da0ae0e0f03a2cf79"}, +] + +[[package]] +name = "google-resumable-media" +version = "2.8.0" +description = "Utilities for Google Media Downloads and Resumable Uploads" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "google_resumable_media-2.8.0-py3-none-any.whl", hash = "sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582"}, + {file = "google_resumable_media-2.8.0.tar.gz", hash = "sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae"}, +] + +[package.dependencies] +google-crc32c = ">=1.0.0,<2.0.0" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "google-auth (>=1.22.0,<2.0.0)"] +requests = ["requests (>=2.18.0,<3.0.0)"] + +[[package]] +name = "googleapis-common-protos" +version = "1.72.0" +description = "Common protobufs used in Google APIs" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038"}, + {file = "googleapis_common_protos-1.72.0.tar.gz", hash = "sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5"}, +] + +[package.dependencies] +grpcio = {version = ">=1.44.0,<2.0.0", optional = true, markers = "extra == \"grpc\""} +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[package.extras] +grpc = ["grpcio (>=1.44.0,<2.0.0)"] + +[[package]] +name = "grpc-google-iam-v1" +version = "0.14.3" +description = "IAM API client library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "grpc_google_iam_v1-0.14.3-py3-none-any.whl", hash = "sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6"}, + {file = "grpc_google_iam_v1-0.14.3.tar.gz", hash = "sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389"}, +] + +[package.dependencies] +googleapis-common-protos = {version = ">=1.56.0,<2.0.0", extras = ["grpc"]} +grpcio = ">=1.44.0,<2.0.0" +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[[package]] +name = "grpcio" +version = "1.76.0" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "grpcio-1.76.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:65a20de41e85648e00305c1bb09a3598f840422e522277641145a32d42dcefcc"}, + {file = "grpcio-1.76.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:40ad3afe81676fd9ec6d9d406eda00933f218038433980aa19d401490e46ecde"}, + {file = "grpcio-1.76.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:035d90bc79eaa4bed83f524331d55e35820725c9fbb00ffa1904d5550ed7ede3"}, + {file = "grpcio-1.76.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4215d3a102bd95e2e11b5395c78562967959824156af11fa93d18fdd18050990"}, + {file = "grpcio-1.76.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:49ce47231818806067aea3324d4bf13825b658ad662d3b25fada0bdad9b8a6af"}, + {file = "grpcio-1.76.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8cc3309d8e08fd79089e13ed4819d0af72aa935dd8f435a195fd152796752ff2"}, + {file = "grpcio-1.76.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:971fd5a1d6e62e00d945423a567e42eb1fa678ba89072832185ca836a94daaa6"}, + {file = "grpcio-1.76.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d9adda641db7207e800a7f089068f6f645959f2df27e870ee81d44701dd9db3"}, + {file = "grpcio-1.76.0-cp310-cp310-win32.whl", hash = "sha256:063065249d9e7e0782d03d2bca50787f53bd0fb89a67de9a7b521c4a01f1989b"}, + {file = "grpcio-1.76.0-cp310-cp310-win_amd64.whl", hash = "sha256:a6ae758eb08088d36812dd5d9af7a9859c05b1e0f714470ea243694b49278e7b"}, + {file = "grpcio-1.76.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2e1743fbd7f5fa713a1b0a8ac8ebabf0ec980b5d8809ec358d488e273b9cf02a"}, + {file = "grpcio-1.76.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:a8c2cf1209497cf659a667d7dea88985e834c24b7c3b605e6254cbb5076d985c"}, + {file = "grpcio-1.76.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:08caea849a9d3c71a542827d6df9d5a69067b0a1efbea8a855633ff5d9571465"}, + {file = "grpcio-1.76.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f0e34c2079d47ae9f6188211db9e777c619a21d4faba6977774e8fa43b085e48"}, + {file = "grpcio-1.76.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8843114c0cfce61b40ad48df65abcfc00d4dba82eae8718fab5352390848c5da"}, + {file = "grpcio-1.76.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8eddfb4d203a237da6f3cc8a540dad0517d274b5a1e9e636fd8d2c79b5c1d397"}, + {file = "grpcio-1.76.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:32483fe2aab2c3794101c2a159070584e5db11d0aa091b2c0ea9c4fc43d0d749"}, + {file = "grpcio-1.76.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dcfe41187da8992c5f40aa8c5ec086fa3672834d2be57a32384c08d5a05b4c00"}, + {file = "grpcio-1.76.0-cp311-cp311-win32.whl", hash = "sha256:2107b0c024d1b35f4083f11245c0e23846ae64d02f40b2b226684840260ed054"}, + {file = "grpcio-1.76.0-cp311-cp311-win_amd64.whl", hash = "sha256:522175aba7af9113c48ec10cc471b9b9bd4f6ceb36aeb4544a8e2c80ed9d252d"}, + {file = "grpcio-1.76.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:81fd9652b37b36f16138611c7e884eb82e0cec137c40d3ef7c3f9b3ed00f6ed8"}, + {file = "grpcio-1.76.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:04bbe1bfe3a68bbfd4e52402ab7d4eb59d72d02647ae2042204326cf4bbad280"}, + {file = "grpcio-1.76.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d388087771c837cdb6515539f43b9d4bf0b0f23593a24054ac16f7a960be16f4"}, + {file = "grpcio-1.76.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9f8f757bebaaea112c00dba718fc0d3260052ce714e25804a03f93f5d1c6cc11"}, + {file = "grpcio-1.76.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:980a846182ce88c4f2f7e2c22c56aefd515daeb36149d1c897f83cf57999e0b6"}, + {file = "grpcio-1.76.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f92f88e6c033db65a5ae3d97905c8fea9c725b63e28d5a75cb73b49bda5024d8"}, + {file = "grpcio-1.76.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4baf3cbe2f0be3289eb68ac8ae771156971848bb8aaff60bad42005539431980"}, + {file = "grpcio-1.76.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:615ba64c208aaceb5ec83bfdce7728b80bfeb8be97562944836a7a0a9647d882"}, + {file = "grpcio-1.76.0-cp312-cp312-win32.whl", hash = "sha256:45d59a649a82df5718fd9527ce775fd66d1af35e6d31abdcdc906a49c6822958"}, + {file = "grpcio-1.76.0-cp312-cp312-win_amd64.whl", hash = "sha256:c088e7a90b6017307f423efbb9d1ba97a22aa2170876223f9709e9d1de0b5347"}, + {file = "grpcio-1.76.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:26ef06c73eb53267c2b319f43e6634c7556ea37672029241a056629af27c10e2"}, + {file = "grpcio-1.76.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:45e0111e73f43f735d70786557dc38141185072d7ff8dc1829d6a77ac1471468"}, + {file = "grpcio-1.76.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:83d57312a58dcfe2a3a0f9d1389b299438909a02db60e2f2ea2ae2d8034909d3"}, + {file = "grpcio-1.76.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:3e2a27c89eb9ac3d81ec8835e12414d73536c6e620355d65102503064a4ed6eb"}, + {file = "grpcio-1.76.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61f69297cba3950a524f61c7c8ee12e55c486cb5f7db47ff9dcee33da6f0d3ae"}, + {file = "grpcio-1.76.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6a15c17af8839b6801d554263c546c69c4d7718ad4321e3166175b37eaacca77"}, + {file = "grpcio-1.76.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:25a18e9810fbc7e7f03ec2516addc116a957f8cbb8cbc95ccc80faa072743d03"}, + {file = "grpcio-1.76.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:931091142fd8cc14edccc0845a79248bc155425eee9a98b2db2ea4f00a235a42"}, + {file = "grpcio-1.76.0-cp313-cp313-win32.whl", hash = "sha256:5e8571632780e08526f118f74170ad8d50fb0a48c23a746bef2a6ebade3abd6f"}, + {file = "grpcio-1.76.0-cp313-cp313-win_amd64.whl", hash = "sha256:f9f7bd5faab55f47231ad8dba7787866b69f5e93bc306e3915606779bbfb4ba8"}, + {file = "grpcio-1.76.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:ff8a59ea85a1f2191a0ffcc61298c571bc566332f82e5f5be1b83c9d8e668a62"}, + {file = "grpcio-1.76.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:06c3d6b076e7b593905d04fdba6a0525711b3466f43b3400266f04ff735de0cd"}, + {file = "grpcio-1.76.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd5ef5932f6475c436c4a55e4336ebbe47bd3272be04964a03d316bbf4afbcbc"}, + {file = "grpcio-1.76.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b331680e46239e090f5b3cead313cc772f6caa7d0fc8de349337563125361a4a"}, + {file = "grpcio-1.76.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2229ae655ec4e8999599469559e97630185fdd53ae1e8997d147b7c9b2b72cba"}, + {file = "grpcio-1.76.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:490fa6d203992c47c7b9e4a9d39003a0c2bcc1c9aa3c058730884bbbb0ee9f09"}, + {file = "grpcio-1.76.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:479496325ce554792dba6548fae3df31a72cef7bad71ca2e12b0e58f9b336bfc"}, + {file = "grpcio-1.76.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c9b93f79f48b03ada57ea24725d83a30284a012ec27eab2cf7e50a550cbbbcc"}, + {file = "grpcio-1.76.0-cp314-cp314-win32.whl", hash = "sha256:747fa73efa9b8b1488a95d0ba1039c8e2dca0f741612d80415b1e1c560febf4e"}, + {file = "grpcio-1.76.0-cp314-cp314-win_amd64.whl", hash = "sha256:922fa70ba549fce362d2e2871ab542082d66e2aaf0c19480ea453905b01f384e"}, + {file = "grpcio-1.76.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:8ebe63ee5f8fa4296b1b8cfc743f870d10e902ca18afc65c68cf46fd39bb0783"}, + {file = "grpcio-1.76.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:3bf0f392c0b806905ed174dcd8bdd5e418a40d5567a05615a030a5aeddea692d"}, + {file = "grpcio-1.76.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b7604868b38c1bfd5cf72d768aedd7db41d78cb6a4a18585e33fb0f9f2363fd"}, + {file = "grpcio-1.76.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e6d1db20594d9daba22f90da738b1a0441a7427552cc6e2e3d1297aeddc00378"}, + {file = "grpcio-1.76.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d099566accf23d21037f18a2a63d323075bebace807742e4b0ac210971d4dd70"}, + {file = "grpcio-1.76.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ebea5cc3aa8ea72e04df9913492f9a96d9348db876f9dda3ad729cfedf7ac416"}, + {file = "grpcio-1.76.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0c37db8606c258e2ee0c56b78c62fc9dee0e901b5dbdcf816c2dd4ad652b8b0c"}, + {file = "grpcio-1.76.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ebebf83299b0cb1721a8859ea98f3a77811e35dce7609c5c963b9ad90728f886"}, + {file = "grpcio-1.76.0-cp39-cp39-win32.whl", hash = "sha256:0aaa82d0813fd4c8e589fac9b65d7dd88702555f702fb10417f96e2a2a6d4c0f"}, + {file = "grpcio-1.76.0-cp39-cp39-win_amd64.whl", hash = "sha256:acab0277c40eff7143c2323190ea57b9ee5fd353d8190ee9652369fae735668a"}, + {file = "grpcio-1.76.0.tar.gz", hash = "sha256:7be78388d6da1a25c0d5ec506523db58b18be22d9c37d8d3a32c08be4987bd73"}, +] + +[package.dependencies] +typing-extensions = ">=4.12,<5.0" + +[package.extras] +protobuf = ["grpcio-tools (>=1.76.0)"] + +[[package]] +name = "grpcio-status" +version = "1.76.0" +description = "Status proto mapping for gRPC" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "grpcio_status-1.76.0-py3-none-any.whl", hash = "sha256:380568794055a8efbbd8871162df92012e0228a5f6dffaf57f2a00c534103b18"}, + {file = "grpcio_status-1.76.0.tar.gz", hash = "sha256:25fcbfec74c15d1a1cb5da3fab8ee9672852dc16a5a9eeb5baf7d7a9952943cd"}, +] + +[package.dependencies] +googleapis-common-protos = ">=1.5.5" +grpcio = ">=1.76.0" +protobuf = ">=6.31.1,<7.0.0" + +[[package]] +name = "httplib2" +version = "0.31.2" +description = "A comprehensive HTTP client library." +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "httplib2-0.31.2-py3-none-any.whl", hash = "sha256:dbf0c2fa3862acf3c55c078ea9c0bc4481d7dc5117cae71be9514912cf9f8349"}, + {file = "httplib2-0.31.2.tar.gz", hash = "sha256:385e0869d7397484f4eab426197a4c020b606edd43372492337c0b4010ae5d24"}, +] + +[package.dependencies] +pyparsing = ">=3.1,<4" + +[[package]] +name = "idna" +version = "3.11" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "importlib-metadata" +version = "8.7.1" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151"}, + {file = "importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=3.4)"] +perf = ["ipython"] +test = ["flufl.flake8", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["mypy (<1.19) ; platform_python_implementation == \"PyPy\"", "pytest-mypy (>=1.0.1)"] + +[[package]] +name = "isort" +version = "7.0.0" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.10.0" +groups = ["dev"] +files = [ + {file = "isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1"}, + {file = "isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187"}, +] + +[package.extras] +colors = ["colorama"] +plugins = ["setuptools"] + +[[package]] +name = "jinja2" +version = "3.1.6" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jsonpath-ng" +version = "1.7.0" +description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"}, + {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"}, + {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"}, +] + +[package.dependencies] +ply = "*" + +[[package]] +name = "jsonschema" +version = "4.26.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.25.0" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "rfc3987-syntax (>=1.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe"}, + {file = "jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "markupsafe" +version = "3.0.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, + {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"}, + {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}, + {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}, + {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, + {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}, + {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"}, + {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"}, + {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "mmh3" +version = "5.2.0" +description = "Python extension for MurmurHash (MurmurHash3), a set of fast and robust hash functions." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "mmh3-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:81c504ad11c588c8629536b032940f2a359dda3b6cbfd4ad8f74cb24dcd1b0bc"}, + {file = "mmh3-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b898cecff57442724a0f52bf42c2de42de63083a91008fb452887e372f9c328"}, + {file = "mmh3-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be1374df449465c9f2500e62eee73a39db62152a8bdfbe12ec5b5c1cd451344d"}, + {file = "mmh3-5.2.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0d753ad566c721faa33db7e2e0eddd74b224cdd3eaf8481d76c926603c7a00e"}, + {file = "mmh3-5.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dfbead5575f6470c17e955b94f92d62a03dfc3d07f2e6f817d9b93dc211a1515"}, + {file = "mmh3-5.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7434a27754049144539d2099a6d2da5d88b8bdeedf935180bf42ad59b3607aa3"}, + {file = "mmh3-5.2.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cadc16e8ea64b5d9a47363013e2bea469e121e6e7cb416a7593aeb24f2ad122e"}, + {file = "mmh3-5.2.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d765058da196f68dc721116cab335e696e87e76720e6ef8ee5a24801af65e63d"}, + {file = "mmh3-5.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8b0c53fe0994beade1ad7c0f13bd6fec980a0664bfbe5a6a7d64500b9ab76772"}, + {file = "mmh3-5.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:49037d417419863b222ae47ee562b2de9c3416add0a45c8d7f4e864be8dc4f89"}, + {file = "mmh3-5.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6ecb4e750d712abde046858ee6992b65c93f1f71b397fce7975c3860c07365d2"}, + {file = "mmh3-5.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:382a6bb3f8c6532ea084e7acc5be6ae0c6effa529240836d59352398f002e3fc"}, + {file = "mmh3-5.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7733ec52296fc1ba22e9b90a245c821adbb943e98c91d8a330a2254612726106"}, + {file = "mmh3-5.2.0-cp310-cp310-win32.whl", hash = "sha256:127c95336f2a98c51e7682341ab7cb0be3adb9df0819ab8505a726ed1801876d"}, + {file = "mmh3-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:419005f84ba1cab47a77465a2a843562dadadd6671b8758bf179d82a15ca63eb"}, + {file = "mmh3-5.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:d22c9dcafed659fadc605538946c041722b6d1104fe619dbf5cc73b3c8a0ded8"}, + {file = "mmh3-5.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7901c893e704ee3c65f92d39b951f8f34ccf8e8566768c58103fb10e55afb8c1"}, + {file = "mmh3-5.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5f5536b1cbfa72318ab3bfc8a8188b949260baed186b75f0abc75b95d8c051"}, + {file = "mmh3-5.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cedac4f4054b8f7859e5aed41aaa31ad03fce6851901a7fdc2af0275ac533c10"}, + {file = "mmh3-5.2.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:eb756caf8975882630ce4e9fbbeb9d3401242a72528230422c9ab3a0d278e60c"}, + {file = "mmh3-5.2.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:097e13c8b8a66c5753c6968b7640faefe85d8e38992703c1f666eda6ef4c3762"}, + {file = "mmh3-5.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7c0c7845566b9686480e6a7e9044db4afb60038d5fabd19227443f0104eeee4"}, + {file = "mmh3-5.2.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:61ac226af521a572700f863d6ecddc6ece97220ce7174e311948ff8c8919a363"}, + {file = "mmh3-5.2.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:582f9dbeefe15c32a5fa528b79b088b599a1dfe290a4436351c6090f90ddebb8"}, + {file = "mmh3-5.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2ebfc46b39168ab1cd44670a32ea5489bcbc74a25795c61b6d888c5c2cf654ed"}, + {file = "mmh3-5.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1556e31e4bd0ac0c17eaf220be17a09c171d7396919c3794274cb3415a9d3646"}, + {file = "mmh3-5.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:81df0dae22cd0da87f1c978602750f33d17fb3d21fb0f326c89dc89834fea79b"}, + {file = "mmh3-5.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:eba01ec3bd4a49b9ac5ca2bc6a73ff5f3af53374b8556fcc2966dd2af9eb7779"}, + {file = "mmh3-5.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e9a011469b47b752e7d20de296bb34591cdfcbe76c99c2e863ceaa2aa61113d2"}, + {file = "mmh3-5.2.0-cp311-cp311-win32.whl", hash = "sha256:bc44fc2b886243d7c0d8daeb37864e16f232e5b56aaec27cc781d848264cfd28"}, + {file = "mmh3-5.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:8ebf241072cf2777a492d0e09252f8cc2b3edd07dfdb9404b9757bffeb4f2cee"}, + {file = "mmh3-5.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:b5f317a727bba0e633a12e71228bc6a4acb4f471a98b1c003163b917311ea9a9"}, + {file = "mmh3-5.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:384eda9361a7bf83a85e09447e1feafe081034af9dd428893701b959230d84be"}, + {file = "mmh3-5.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2c9da0d568569cc87315cb063486d761e38458b8ad513fedd3dc9263e1b81bcd"}, + {file = "mmh3-5.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86d1be5d63232e6eb93c50881aea55ff06eb86d8e08f9b5417c8c9b10db9db96"}, + {file = "mmh3-5.2.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bf7bee43e17e81671c447e9c83499f53d99bf440bc6d9dc26a841e21acfbe094"}, + {file = "mmh3-5.2.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7aa18cdb58983ee660c9c400b46272e14fa253c675ed963d3812487f8ca42037"}, + {file = "mmh3-5.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9d032488fcec32d22be6542d1a836f00247f40f320844dbb361393b5b22773"}, + {file = "mmh3-5.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1861fb6b1d0453ed7293200139c0a9011eeb1376632e048e3766945b13313c5"}, + {file = "mmh3-5.2.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:99bb6a4d809aa4e528ddfe2c85dd5239b78b9dd14be62cca0329db78505e7b50"}, + {file = "mmh3-5.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1f8d8b627799f4e2fcc7c034fed8f5f24dc7724ff52f69838a3d6d15f1ad4765"}, + {file = "mmh3-5.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b5995088dd7023d2d9f310a0c67de5a2b2e06a570ecfd00f9ff4ab94a67cde43"}, + {file = "mmh3-5.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1a5f4d2e59d6bba8ef01b013c472741835ad961e7c28f50c82b27c57748744a4"}, + {file = "mmh3-5.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fd6e6c3d90660d085f7e73710eab6f5545d4854b81b0135a3526e797009dbda3"}, + {file = "mmh3-5.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c4a2f3d83879e3de2eb8cbf562e71563a8ed15ee9b9c2e77ca5d9f73072ac15c"}, + {file = "mmh3-5.2.0-cp312-cp312-win32.whl", hash = "sha256:2421b9d665a0b1ad724ec7332fb5a98d075f50bc51a6ff854f3a1882bd650d49"}, + {file = "mmh3-5.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:72d80005b7634a3a2220f81fbeb94775ebd12794623bb2e1451701ea732b4aa3"}, + {file = "mmh3-5.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:3d6bfd9662a20c054bc216f861fa330c2dac7c81e7fb8307b5e32ab5b9b4d2e0"}, + {file = "mmh3-5.2.0-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:e79c00eba78f7258e5b354eccd4d7907d60317ced924ea4a5f2e9d83f5453065"}, + {file = "mmh3-5.2.0-cp313-cp313-android_21_x86_64.whl", hash = "sha256:956127e663d05edbeec54df38885d943dfa27406594c411139690485128525de"}, + {file = "mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c3dca4cb5b946ee91b3d6bb700d137b1cd85c20827f89fdf9c16258253489044"}, + {file = "mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e651e17bfde5840e9e4174b01e9e080ce49277b70d424308b36a7969d0d1af73"}, + {file = "mmh3-5.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:9f64bf06f4bf623325fda3a6d02d36cd69199b9ace99b04bb2d7fd9f89688504"}, + {file = "mmh3-5.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ddc63328889bcaee77b743309e5c7d2d52cee0d7d577837c91b6e7cc9e755e0b"}, + {file = "mmh3-5.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bb0fdc451fb6d86d81ab8f23d881b8d6e37fc373a2deae1c02d27002d2ad7a05"}, + {file = "mmh3-5.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b29044e1ffdb84fe164d0a7ea05c7316afea93c00f8ed9449cf357c36fc4f814"}, + {file = "mmh3-5.2.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:58981d6ea9646dbbf9e59a30890cbf9f610df0e4a57dbfe09215116fd90b0093"}, + {file = "mmh3-5.2.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e5634565367b6d98dc4aa2983703526ef556b3688ba3065edb4b9b90ede1c54"}, + {file = "mmh3-5.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0271ac12415afd3171ab9a3c7cbfc71dee2c68760a7dc9d05bf8ed6ddfa3a7a"}, + {file = "mmh3-5.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:45b590e31bc552c6f8e2150ff1ad0c28dd151e9f87589e7eaf508fbdd8e8e908"}, + {file = "mmh3-5.2.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bdde97310d59604f2a9119322f61b31546748499a21b44f6715e8ced9308a6c5"}, + {file = "mmh3-5.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc9c5f280438cf1c1a8f9abb87dc8ce9630a964120cfb5dd50d1e7ce79690c7a"}, + {file = "mmh3-5.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c903e71fd8debb35ad2a4184c1316b3cb22f64ce517b4e6747f25b0a34e41266"}, + {file = "mmh3-5.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:eed4bba7ff8a0d37106ba931ab03bdd3915fbb025bcf4e1f0aa02bc8114960c5"}, + {file = "mmh3-5.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1fdb36b940e9261aff0b5177c5b74a36936b902f473180f6c15bde26143681a9"}, + {file = "mmh3-5.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7303aab41e97adcf010a09efd8f1403e719e59b7705d5e3cfed3dd7571589290"}, + {file = "mmh3-5.2.0-cp313-cp313-win32.whl", hash = "sha256:03e08c6ebaf666ec1e3d6ea657a2d363bb01effd1a9acfe41f9197decaef0051"}, + {file = "mmh3-5.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:7fddccd4113e7b736706e17a239a696332360cbaddf25ae75b57ba1acce65081"}, + {file = "mmh3-5.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa0c966ee727aad5406d516375593c5f058c766b21236ab8985693934bb5085b"}, + {file = "mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e5015f0bb6eb50008bed2d4b1ce0f2a294698a926111e4bb202c0987b4f89078"}, + {file = "mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e0f3ed828d709f5b82d8bfe14f8856120718ec4bd44a5b26102c3030a1e12501"}, + {file = "mmh3-5.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:f35727c5118aba95f0397e18a1a5b8405425581bfe53e821f0fb444cbdc2bc9b"}, + {file = "mmh3-5.2.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bc244802ccab5220008cb712ca1508cb6a12f0eb64ad62997156410579a1770"}, + {file = "mmh3-5.2.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ff3d50dc3fe8a98059f99b445dfb62792b5d006c5e0b8f03c6de2813b8376110"}, + {file = "mmh3-5.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:37a358cc881fe796e099c1db6ce07ff757f088827b4e8467ac52b7a7ffdca647"}, + {file = "mmh3-5.2.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b9a87025121d1c448f24f27ff53a5fe7b6ef980574b4a4f11acaabe702420d63"}, + {file = "mmh3-5.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ba55d6ca32eeef8b2625e1e4bfc3b3db52bc63014bd7e5df8cc11bf2b036b12"}, + {file = "mmh3-5.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9ff37ba9f15637e424c2ab57a1a590c52897c845b768e4e0a4958084ec87f22"}, + {file = "mmh3-5.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a094319ec0db52a04af9fdc391b4d39a1bc72bc8424b47c4411afb05413a44b5"}, + {file = "mmh3-5.2.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c5584061fd3da584659b13587f26c6cad25a096246a481636d64375d0c1f6c07"}, + {file = "mmh3-5.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecbfc0437ddfdced5e7822d1ce4855c9c64f46819d0fdc4482c53f56c707b935"}, + {file = "mmh3-5.2.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:7b986d506a8e8ea345791897ba5d8ba0d9d8820cd4fc3e52dbe6de19388de2e7"}, + {file = "mmh3-5.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:38d899a156549da8ef6a9f1d6f7ef231228d29f8f69bce2ee12f5fba6d6fd7c5"}, + {file = "mmh3-5.2.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d86651fa45799530885ba4dab3d21144486ed15285e8784181a0ab37a4552384"}, + {file = "mmh3-5.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c463d7c1c4cfc9d751efeaadd936bbba07b5b0ed81a012b3a9f5a12f0872bd6e"}, + {file = "mmh3-5.2.0-cp314-cp314-win32.whl", hash = "sha256:bb4fe46bdc6104fbc28db7a6bacb115ee6368ff993366bbd8a2a7f0076e6f0c0"}, + {file = "mmh3-5.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:7c7f0b342fd06044bedd0b6e72177ddc0076f54fd89ee239447f8b271d919d9b"}, + {file = "mmh3-5.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:3193752fc05ea72366c2b63ff24b9a190f422e32d75fdeae71087c08fff26115"}, + {file = "mmh3-5.2.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:69fc339d7202bea69ef9bd7c39bfdf9fdabc8e6822a01eba62fb43233c1b3932"}, + {file = "mmh3-5.2.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:12da42c0a55c9d86ab566395324213c319c73ecb0c239fad4726324212b9441c"}, + {file = "mmh3-5.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f7f9034c7cf05ddfaac8d7a2e63a3c97a840d4615d0a0e65ba8bdf6f8576e3be"}, + {file = "mmh3-5.2.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:11730eeb16dfcf9674fdea9bb6b8e6dd9b40813b7eb839bc35113649eef38aeb"}, + {file = "mmh3-5.2.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:932a6eec1d2e2c3c9e630d10f7128d80e70e2d47fe6b8c7ea5e1afbd98733e65"}, + {file = "mmh3-5.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ca975c51c5028947bbcfc24966517aac06a01d6c921e30f7c5383c195f87991"}, + {file = "mmh3-5.2.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5b0b58215befe0f0e120b828f7645e97719bbba9f23b69e268ed0ac7adde8645"}, + {file = "mmh3-5.2.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29c2b9ce61886809d0492a274a5a53047742dea0f703f9c4d5d223c3ea6377d3"}, + {file = "mmh3-5.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a367d4741ac0103f8198c82f429bccb9359f543ca542b06a51f4f0332e8de279"}, + {file = "mmh3-5.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5a5dba98e514fb26241868f6eb90a7f7ca0e039aed779342965ce24ea32ba513"}, + {file = "mmh3-5.2.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:941603bfd75a46023807511c1ac2f1b0f39cccc393c15039969806063b27e6db"}, + {file = "mmh3-5.2.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:132dd943451a7c7546978863d2f5a64977928410782e1a87d583cb60eb89e667"}, + {file = "mmh3-5.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f698733a8a494466432d611a8f0d1e026f5286dee051beea4b3c3146817e35d5"}, + {file = "mmh3-5.2.0-cp314-cp314t-win32.whl", hash = "sha256:6d541038b3fc360ec538fc116de87462627944765a6750308118f8b509a8eec7"}, + {file = "mmh3-5.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e912b19cf2378f2967d0c08e86ff4c6c360129887f678e27e4dde970d21b3f4d"}, + {file = "mmh3-5.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e7884931fe5e788163e7b3c511614130c2c59feffdc21112290a194487efb2e9"}, + {file = "mmh3-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3c6041fd9d5fb5fcac57d5c80f521a36b74aea06b8566431c63e4ffc49aced51"}, + {file = "mmh3-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:58477cf9ef16664d1ce2b038f87d2dc96d70fe50733a34a7f07da6c9a5e3538c"}, + {file = "mmh3-5.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:be7d3dca9358e01dab1bad881fb2b4e8730cec58d36dd44482bc068bfcd3bc65"}, + {file = "mmh3-5.2.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:931d47e08c9c8a67bf75d82f0ada8399eac18b03388818b62bfa42882d571d72"}, + {file = "mmh3-5.2.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dd966df3489ec13848d6c6303429bbace94a153f43d1ae2a55115fd36fd5ca5d"}, + {file = "mmh3-5.2.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c677d78887244bf3095020b73c42b505b700f801c690f8eaa90ad12d3179612f"}, + {file = "mmh3-5.2.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:63830f846797187c5d3e2dae50f0848fdc86032f5bfdc58ae352f02f857e9025"}, + {file = "mmh3-5.2.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c3f563e8901960e2eaa64c8e8821895818acabeb41c96f2efbb936f65dbe486c"}, + {file = "mmh3-5.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:96f1e1ac44cbb42bcc406e509f70c9af42c594e72ccc7b1257f97554204445f0"}, + {file = "mmh3-5.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:7bbb0df897944b5ec830f3ad883e32c5a7375370a521565f5fe24443bfb2c4f7"}, + {file = "mmh3-5.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:1fae471339ae1b9c641f19cf46dfe6ffd7f64b1fba7c4333b99fa3dd7f21ae0a"}, + {file = "mmh3-5.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:aa6e5d31fdc5ed9e3e95f9873508615a778fe9b523d52c17fc770a3eb39ab6e4"}, + {file = "mmh3-5.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:746a5ee71c6d1103d9b560fa147881b5e68fd35da56e54e03d5acefad0e7c055"}, + {file = "mmh3-5.2.0-cp39-cp39-win32.whl", hash = "sha256:10983c10f5c77683bd845751905ba535ec47409874acc759d5ce3ff7ef34398a"}, + {file = "mmh3-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:fdfd3fb739f4e22746e13ad7ba0c6eedf5f454b18d11249724a388868e308ee4"}, + {file = "mmh3-5.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:33576136c06b46a7046b6d83a3d75fbca7d25f84cec743f1ae156362608dc6d2"}, + {file = "mmh3-5.2.0.tar.gz", hash = "sha256:1efc8fec8478e9243a78bb993422cf79f8ff85cb4cf6b79647480a31e0d950a8"}, +] + +[package.extras] +benchmark = ["pymmh3 (==0.0.5)", "pyperf (==2.9.0)", "xxhash (==3.5.0)"] +docs = ["myst-parser (==4.0.1)", "shibuya (==2025.7.24)", "sphinx (==8.2.3)", "sphinx-copybutton (==0.5.2)"] +lint = ["black (==25.1.0)", "clang-format (==20.1.8)", "isort (==6.0.1)", "pylint (==3.3.7)"] +plot = ["matplotlib (==3.10.3)", "pandas (==2.3.1)"] +test = ["pytest (==8.4.1)", "pytest-sugar (==1.0.0)"] +type = ["mypy (==1.17.0)"] + +[[package]] +name = "opentelemetry-api" +version = "1.39.1" +description = "OpenTelemetry Python API" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_api-1.39.1-py3-none-any.whl", hash = "sha256:2edd8463432a7f8443edce90972169b195e7d6a05500cd29e6d13898187c9950"}, + {file = "opentelemetry_api-1.39.1.tar.gz", hash = "sha256:fbde8c80e1b937a2c61f20347e91c0c18a1940cecf012d62e65a7caf08967c9c"}, +] + +[package.dependencies] +importlib-metadata = ">=6.0,<8.8.0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-sdk" +version = "1.39.1" +description = "OpenTelemetry Python SDK" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_sdk-1.39.1-py3-none-any.whl", hash = "sha256:4d5482c478513ecb0a5d938dcc61394e647066e0cc2676bee9f3af3f3f45f01c"}, + {file = "opentelemetry_sdk-1.39.1.tar.gz", hash = "sha256:cf4d4563caf7bff906c9f7967e2be22d0d6b349b908be0d90fb21c8e9c995cc6"}, +] + +[package.dependencies] +opentelemetry-api = "1.39.1" +opentelemetry-semantic-conventions = "0.60b1" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.60b1" +description = "OpenTelemetry Semantic Conventions" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_semantic_conventions-0.60b1-py3-none-any.whl", hash = "sha256:9fa8c8b0c110da289809292b0591220d3a7b53c1526a23021e977d68597893fb"}, + {file = "opentelemetry_semantic_conventions-0.60b1.tar.gz", hash = "sha256:87c228b5a0669b748c76d76df6c364c369c28f1c465e50f661e39737e84bc953"}, +] + +[package.dependencies] +opentelemetry-api = "1.39.1" +typing-extensions = ">=4.5.0" + +[[package]] +name = "osv" +version = "0.1.2" +description = "Open Source Vulnerabilities library" +optional = false +python-versions = ">=3.13,<4.0" +groups = ["main"] +files = [] +develop = true + +[package.dependencies] +attrs = ">=23.2" +google-cloud-logging = ">=3.10" +google-cloud-ndb = ">=2.3" +google-cloud-pubsub = ">=2.31.1" +google-cloud-storage = ">=2.17" +grpcio = ">=1.0" +jsonschema = ">=4.0" +packageurl-python = ">=0.17.0" +packaging-legacy = ">=23.0.post0" +pygit2 = ">=1.14.0" +pyyaml = ">=6.0" +requests = ">=2.32" +semver = ">=3.0" + +[package.source] +type = "directory" +url = "../../.." + +[[package]] +name = "packageurl-python" +version = "0.17.6" +description = "A purl aka. Package URL parser and builder" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "packageurl_python-0.17.6-py3-none-any.whl", hash = "sha256:31a85c2717bc41dd818f3c62908685ff9eebcb68588213745b14a6ee9e7df7c9"}, + {file = "packageurl_python-0.17.6.tar.gz", hash = "sha256:1252ce3a102372ca6f86eb968e16f9014c4ba511c5c37d95a7f023e2ca6e5c25"}, +] + +[package.extras] +build = ["setuptools", "wheel"] +lint = ["black", "isort", "mypy"] +sqlalchemy = ["sqlalchemy (>=2.0.0)"] +test = ["pytest"] + +[[package]] +name = "packaging" +version = "26.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, +] + +[[package]] +name = "packaging-legacy" +version = "23.0.post0" +description = "Core utilities for legacy Python packages" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "packaging_legacy-23.0.post0-py3-none-any.whl", hash = "sha256:6cd21cd283c09409349bccc10bb55bfd837b4aab86a7b0f87bfcb8dd9831a8a3"}, + {file = "packaging_legacy-23.0.post0.tar.gz", hash = "sha256:c974a42291a77112313f0198b87ad96e07a3c357295d572560a4b9c368f7d9db"}, +] + +[package.dependencies] +packaging = ">=23.0" + +[[package]] +name = "platformdirs" +version = "4.5.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31"}, + {file = "platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda"}, +] + +[package.extras] +docs = ["furo (>=2025.9.25)", "proselint (>=0.14)", "sphinx (>=8.2.3)", "sphinx-autodoc-typehints (>=3.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.4.2)", "pytest-cov (>=7)", "pytest-mock (>=3.15.1)"] +type = ["mypy (>=1.18.2)"] + +[[package]] +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, +] + +[[package]] +name = "proto-plus" +version = "1.27.0" +description = "Beautiful, Pythonic protocol buffers" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "proto_plus-1.27.0-py3-none-any.whl", hash = "sha256:1baa7f81cf0f8acb8bc1f6d085008ba4171eaf669629d1b6d1673b21ed1c0a82"}, + {file = "proto_plus-1.27.0.tar.gz", hash = "sha256:873af56dd0d7e91836aee871e5799e1c6f1bda86ac9a983e0bb9f0c266a568c4"}, +] + +[package.dependencies] +protobuf = ">=3.19.0,<7.0.0" + +[package.extras] +testing = ["google-api-core (>=1.31.5)"] + +[[package]] +name = "protobuf" +version = "6.33.4" +description = "" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "protobuf-6.33.4-cp310-abi3-win32.whl", hash = "sha256:918966612c8232fc6c24c78e1cd89784307f5814ad7506c308ee3cf86662850d"}, + {file = "protobuf-6.33.4-cp310-abi3-win_amd64.whl", hash = "sha256:8f11ffae31ec67fc2554c2ef891dcb561dae9a2a3ed941f9e134c2db06657dbc"}, + {file = "protobuf-6.33.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2fe67f6c014c84f655ee06f6f66213f9254b3a8b6bda6cda0ccd4232c73c06f0"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:757c978f82e74d75cba88eddec479df9b99a42b31193313b75e492c06a51764e"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c7c64f259c618f0bef7bee042075e390debbf9682334be2b67408ec7c1c09ee6"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:3df850c2f8db9934de4cf8f9152f8dc2558f49f298f37f90c517e8e5c84c30e9"}, + {file = "protobuf-6.33.4-cp39-cp39-win32.whl", hash = "sha256:955478a89559fa4568f5a81dce77260eabc5c686f9e8366219ebd30debf06aa6"}, + {file = "protobuf-6.33.4-cp39-cp39-win_amd64.whl", hash = "sha256:0f12ddbf96912690c3582f9dffb55530ef32015ad8e678cd494312bd78314c4f"}, + {file = "protobuf-6.33.4-py3-none-any.whl", hash = "sha256:1fe3730068fcf2e595816a6c34fe66eeedd37d51d0400b72fabc848811fdc1bc"}, + {file = "protobuf-6.33.4.tar.gz", hash = "sha256:dc2e61bca3b10470c1912d166fe0af67bfc20eb55971dcef8dfa48ce14f0ed91"}, +] + +[[package]] +name = "pyasn1" +version = "0.6.2" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"}, + {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +description = "A collection of ASN.1-based protocols modules" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a"}, + {file = "pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6"}, +] + +[package.dependencies] +pyasn1 = ">=0.6.1,<0.7.0" + +[[package]] +name = "pycparser" +version = "3.0" +description = "C parser in Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "implementation_name != \"PyPy\"" +files = [ + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, +] + +[[package]] +name = "pygit2" +version = "1.19.1" +description = "Python bindings for libgit2." +optional = false +python-versions = ">=3.11" +groups = ["main"] +files = [ + {file = "pygit2-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b54f3a94648ac8e287f5e4333710d9fe05f9e09de3da232d50df753bb01b643"}, + {file = "pygit2-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e46618a912fc984b8a9f4d8322704620f1315264359c7fa61c899128e23e226"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2eb386b3e98f7056d76bc7e805e8fce3cd0a773cbbb30b0f7e144c0ac37270f2"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f41a9b866676922ac9b0ec60f0dc9735a5d1ba6bb34146a6212dc0012d7959f"}, + {file = "pygit2-1.19.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2cdc81ecffd990d8c6dce44a16b1dc4494b5dd5381d6e1f508e459c4bca09e0"}, + {file = "pygit2-1.19.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a1c8645287556aa9b670886dbc0d5daa1d49040511940822fd43dbda13cfe4e8"}, + {file = "pygit2-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e388d1eb0c44d92d8ff01b25eb9a969fc28748966843c2e26e9e084e42567f7d"}, + {file = "pygit2-1.19.1-cp311-cp311-win32.whl", hash = "sha256:815c0b12845253929f2275759d623b3b4093e67e6536d2463177e6ff1d9ff0df"}, + {file = "pygit2-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:93f4986b35984aaaa5e7613ceb1ba4c184d890589df60b0d8d74e7dccec1d8cb"}, + {file = "pygit2-1.19.1-cp311-cp311-win_arm64.whl", hash = "sha256:fef27b206955e66e3a63664e2ec93821e00ce2d917f8b4eae87c738163c00e14"}, + {file = "pygit2-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8e6a4f4a711750c286a13cea0007b40f7466c4d741c3d9b223ffbc3bbfbafe7"}, + {file = "pygit2-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3f2340a668eb3e2d8927dcbeb1a043d3a65d2dd39a913995b34fc437da5e73af"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe41f09b1e334c43def6636b1133d2f4c91a20d9a6691bb4e7558e42a31bcb4e"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:527e57133d30ff6ea96634da6bf428f7d551958207fa73f9e9a18582b885e192"}, + {file = "pygit2-1.19.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a9340cb85b7be40080186a9d4dbf712a6be8a842556acbbfb305baebfb854f3"}, + {file = "pygit2-1.19.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:66ecfa69f2287f50ec95dfc04821219c2f664c4cd292c7b33c10ed9afe975132"}, + {file = "pygit2-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:14c76ec968ae20a6689c7b6fa833ef546c7bc176127d71e7b67cb2345a9813fb"}, + {file = "pygit2-1.19.1-cp312-cp312-win32.whl", hash = "sha256:ffe94118d39f6969fda594224b2b6df1ae79306adaf090ede65bcaf1a41b3a81"}, + {file = "pygit2-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:c2ee3f2e91b0a5674ab7cb373234c23cf5f1cf6d84e56e6d12ff3db21414cf47"}, + {file = "pygit2-1.19.1-cp312-cp312-win_arm64.whl", hash = "sha256:c8747d968d8d6b9d390263907f014d38a0f67bd26d8243e5bc3384cb252ec3d3"}, + {file = "pygit2-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:39af62f3e18dfdfb15c347c12b51231fdb3db3c9d5105d9046847ead14b42fce"}, + {file = "pygit2-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed39106f1d9560709191093ed5251471dfb6b9e4aa35299dde45f4b91f7c984e"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb4da746c92e23281890e865887d83f24e662fc3e1c481420e4993c5a13203fe"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:93ccfab2340d38374f91ecf6cae6658bebc73883c376eb81eeb293781f6aef94"}, + {file = "pygit2-1.19.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef18f1208422d3cac1c109417a5fc6143704cfff8e5de4e1665fa4a89ffe3902"}, + {file = "pygit2-1.19.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:344f4c1e84eaa2434fbb43d96a1dd79796ab9559587a8533331fef92eab0ec7d"}, + {file = "pygit2-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1ae2f408206c67d395e8dc77425f8ab457cad59faaa58c700164398a62823e82"}, + {file = "pygit2-1.19.1-cp313-cp313-win32.whl", hash = "sha256:9d6cf97c2da5c589b65371a8115be920cf417c46a80a2b12edb26e54a5238190"}, + {file = "pygit2-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:6d73aedffad280f6b655394e303533fcff15545d4d8f322011179c9474bb1b13"}, + {file = "pygit2-1.19.1-cp313-cp313-win_arm64.whl", hash = "sha256:8b067241c03a29440507e78637e233998fe1a11d2082169bd8177694ec4ee747"}, + {file = "pygit2-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d10a46285b9ae39b9de2d9f44ac7f933993aecfab189c2932320b3df596311c8"}, + {file = "pygit2-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d0f3924d8d0d54a7fe186761c76dc1b6e5fcf41794a6daba1630db3bc216b9ba"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4fcc301cfe9c29f3e29f0f80d81ae65c0bee368672b23566467dc91b5edae4b"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3c6eacf82f15e001121dc0f60057f462627045447d8bd8587b33b13159ae5155"}, + {file = "pygit2-1.19.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:074b0b14c6f3c7e2c6ea0b01a90832407a71520c920918aa07f509c91f1691f9"}, + {file = "pygit2-1.19.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ada5d3e813e21918e004a33c66aba4a2b829cd5c0c0e85b92dd70f84cf95ac56"}, + {file = "pygit2-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:19ebe25fd8e95ed8a0be0a9dd4cecc1233db4f2a44a2a73984620909e98e907f"}, + {file = "pygit2-1.19.1-cp314-cp314-win32.whl", hash = "sha256:5bc0738a49cceb76f0fba7cdb24532857a980e4a36b9a0da025c359dfe3676b4"}, + {file = "pygit2-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:527d40925bb85b86da0e96ecc90e9ca74d0a0273ab645bac0787b95923d93160"}, + {file = "pygit2-1.19.1-cp314-cp314-win_arm64.whl", hash = "sha256:21c7c8b5aa2f48cefdb8521185f0cd3c110a340e2d9f62a46a94db01a907db73"}, + {file = "pygit2-1.19.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9c5e4eb975b664b6821fe6a05b03bbc51052d1fb22f20652e1d4349ae24ed7ac"}, + {file = "pygit2-1.19.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8752eae5780ee51edae326cac394868917704624b63d03a5217c5e94a532a0e3"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:457f5a2e6d8527b5ad7a8bd16586c72ad2ce0aa218a37380f16d07520569ceaf"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3c8a9d53c84724c97d7e298f6628655c19f9911a90b88c362cb7d5daa645464f"}, + {file = "pygit2-1.19.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d8442ad863be83be86baff006a6e11de3cddf17c7ee77eac2d389765987b554"}, + {file = "pygit2-1.19.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ae9c775be518c7f20bf340091d329d3b9203cbd4273bf1b5505dc82dccf08147"}, + {file = "pygit2-1.19.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d5a45d466a4bc5d9eb0619ffc26b17e4018285e35ba9e2fe39576f13480b63bc"}, + {file = "pygit2-1.19.1-cp314-cp314t-win32.whl", hash = "sha256:6621acaaf2670e8fd0727c15271e5209a99769b127300ef7fc56b49babc8b1c1"}, + {file = "pygit2-1.19.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4418dea6936fe3c1a9375d7cd31a69e72997e645e588ed31c40d785c71adde35"}, + {file = "pygit2-1.19.1-cp314-cp314t-win_arm64.whl", hash = "sha256:3cbb8ab952224c0b305aa56f8759bcad5d9a9de885b00fe0ff8bed9ac365472e"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3c56ef9ac89e020ca005a39db4e045792b1ce98c2450a53f79815e9d831c006a"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a6d89079f3af32f25abb8680eabea31143a4f02f3d1da6644c296ba89b6a2fc"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bfd44dc6f1d5b1165cc2097c39000c4a5cc05443d27a3a5f2791ad338f52b07"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0aca00ff7e3420f9c06d9386b0bfc76c18fd8a2c5234412db0e200a6cc47ed03"}, + {file = "pygit2-1.19.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f89f047667a218b71ebc96c398aca1e5109f149045a8d59ca9fd4a557d1e932e"}, + {file = "pygit2-1.19.1.tar.gz", hash = "sha256:3165f784aae56a309a27d8eeae7923d53da2e8f6094308c7f5b428deec925cf9"}, +] + +[package.dependencies] +cffi = ">=2.0" + +[[package]] +name = "pyjwt" +version = "2.10.1" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pylint" +version = "4.0.4" +description = "python code static checker" +optional = false +python-versions = ">=3.10.0" +groups = ["dev"] +files = [ + {file = "pylint-4.0.4-py3-none-any.whl", hash = "sha256:63e06a37d5922555ee2c20963eb42559918c20bd2b21244e4ef426e7c43b92e0"}, + {file = "pylint-4.0.4.tar.gz", hash = "sha256:d9b71674e19b1c36d79265b5887bf8e55278cbe236c9e95d22dc82cf044fdbd2"}, +] + +[package.dependencies] +astroid = ">=4.0.2,<=4.1.dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = {version = ">=0.3.7", markers = "python_version >= \"3.12\""} +isort = ">=5,<5.13 || >5.13,<8" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2" +tomlkit = ">=0.10.1" + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + +[[package]] +name = "pymemcache" +version = "4.0.0" +description = "A comprehensive, fast, pure Python memcached client" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "pymemcache-4.0.0-py2.py3-none-any.whl", hash = "sha256:f507bc20e0dc8d562f8df9d872107a278df049fa496805c1431b926f3ddd0eab"}, + {file = "pymemcache-4.0.0.tar.gz", hash = "sha256:27bf9bd1bbc1e20f83633208620d56de50f14185055e49504f4f5e94e94aff94"}, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +description = "pyparsing - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d"}, + {file = "pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2025.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, + {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"}, + {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"}, + {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"}, + {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"}, + {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"}, + {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"}, + {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"}, + {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"}, + {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"}, + {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"}, + {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}, + {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}, + {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}, + {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}, + {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}, + {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}, + {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, + {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}, + {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}, + {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}, + {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, + {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, + {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, + {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, + {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}, + {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}, + {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}, + {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}, + {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}, + {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}, + {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}, + {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}, + {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}, + {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}, + {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}, + {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}, + {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"}, + {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"}, + {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"}, + {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"}, + {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"}, + {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"}, + {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, +] + +[[package]] +name = "redis" +version = "5.3.1" +description = "Python client for Redis database and key-value store" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "redis-5.3.1-py3-none-any.whl", hash = "sha256:dc1909bd24669cc31b5f67a039700b16ec30571096c5f1f0d9d2324bff31af97"}, + {file = "redis-5.3.1.tar.gz", hash = "sha256:ca49577a531ea64039b5a36db3d6cd1a0c7a60c34124d46924a45b956e8cf14c"}, +] + +[package.dependencies] +PyJWT = ">=2.9.0" + +[package.extras] +hiredis = ["hiredis (>=3.0.0)"] +ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==23.2.1)", "requests (>=2.31.0)"] + +[[package]] +name = "referencing" +version = "0.37.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231"}, + {file = "referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "requests" +version = "2.32.5" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, + {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rpds-py" +version = "0.30.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288"}, + {file = "rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7"}, + {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff"}, + {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7"}, + {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139"}, + {file = "rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464"}, + {file = "rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169"}, + {file = "rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425"}, + {file = "rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038"}, + {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7"}, + {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed"}, + {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85"}, + {file = "rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c"}, + {file = "rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825"}, + {file = "rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229"}, + {file = "rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad"}, + {file = "rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51"}, + {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5"}, + {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e"}, + {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394"}, + {file = "rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf"}, + {file = "rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b"}, + {file = "rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e"}, + {file = "rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2"}, + {file = "rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d"}, + {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7"}, + {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31"}, + {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95"}, + {file = "rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d"}, + {file = "rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15"}, + {file = "rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1"}, + {file = "rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a"}, + {file = "rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0"}, + {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94"}, + {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08"}, + {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27"}, + {file = "rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6"}, + {file = "rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d"}, + {file = "rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0"}, + {file = "rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f"}, + {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65"}, + {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f"}, + {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53"}, + {file = "rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed"}, + {file = "rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950"}, + {file = "rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6"}, + {file = "rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb"}, + {file = "rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5"}, + {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404"}, + {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856"}, + {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40"}, + {file = "rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0"}, + {file = "rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e"}, + {file = "rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84"}, +] + +[[package]] +name = "rsa" +version = "4.9.1" +description = "Pure-Python RSA implementation" +optional = false +python-versions = "<4,>=3.6" +groups = ["main"] +files = [ + {file = "rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762"}, + {file = "rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75"}, +] + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "semver" +version = "3.0.4" +description = "Python helper for Semantic Versioning (https://semver.org)" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "semver-3.0.4-py3-none-any.whl", hash = "sha256:9c824d87ba7f7ab4a1890799cec8596f15c1241cb473404ea1cb0c55e4b04746"}, + {file = "semver-3.0.4.tar.gz", hash = "sha256:afc7d8c584a5ed0a11033af086e8af226a9c0b206f313e0301f8dd7b6b589602"}, +] + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "tenacity" +version = "9.1.2" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"}, + {file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + +[[package]] +name = "tomlkit" +version = "0.14.0" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, + {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, +] + +[[package]] +name = "unidiff" +version = "0.7.5" +description = "Unified diff parsing/metadata extraction library." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "unidiff-0.7.5-py2.py3-none-any.whl", hash = "sha256:c93bf2265cc1ba2a520e415ab05da587370bc2a3ae9e0414329f54f0c2fc09e8"}, + {file = "unidiff-0.7.5.tar.gz", hash = "sha256:2e5f0162052248946b9f0970a40e9e124236bf86c82b70821143a6fc1dea2574"}, +] + +[[package]] +name = "uritemplate" +version = "4.2.0" +description = "Implementation of RFC 6570 URI Templates" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686"}, + {file = "uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e"}, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, +] + +[package.extras] +brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] + +[[package]] +name = "vanir" +version = "1.0.2" +description = "Vanir is a source code-based static analysis tool that automatically identifies the list of missing security patches in the target system. " +optional = false +python-versions = "<3.14,>=3.9" +groups = ["main"] +files = [ + {file = "vanir-1.0.2-py3-none-any.whl", hash = "sha256:d924328f5f52f0315bc4489ede33869592a2c44f4faa703d596a85923e3cea40"}, +] + +[package.dependencies] +absl-py = ">=2.3.1,<3" +google-api-core = {version = ">=2.25.1,<3", extras = ["grpc"]} +google-auth = ">=2.40.3,<3" +google-cloud-iam = ">=2.19.1,<3" +google-cloud-storage = ">=2.19.0,<4" +jinja2 = ">=3.1.6,<4" +jsonpath_ng = ">=1.7.0,<2" +mmh3 = ">=5.2.0,<6" +osv = {version = ">=0.1.2,<1", markers = "python_version >= \"3.13\""} +protobuf = {version = ">=6.32.1,<7", markers = "python_version >= \"3.10\""} +python-dateutil = ">=2.9.0.post0,<3" +requests = ">=2.32.5,<3" +tenacity = ">=9.1.2,<10" +typing-extensions = ">=4.15.0,<5" +unidiff = ">=0.7.5,<1" + +[[package]] +name = "yapf" +version = "0.43.0" +description = "A formatter for Python code" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "yapf-0.43.0-py3-none-any.whl", hash = "sha256:224faffbc39c428cb095818cf6ef5511fdab6f7430a10783fdfb292ccf2852ca"}, + {file = "yapf-0.43.0.tar.gz", hash = "sha256:00d3aa24bfedff9420b2e0d5d9f5ab6d9d4268e72afbf59bb3fa542781d5218e"}, +] + +[package.dependencies] +platformdirs = ">=3.5.1" + +[[package]] +name = "zipp" +version = "3.23.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, + {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + +[metadata] +lock-version = "2.1" +python-versions = ">=3.13,<3.14" +content-hash = "63b5812d3a1cfdbaa311d604861ce414e94d416ae0e6f97658161faac0525073" diff --git a/gcp/workers/oss_fuzz_worker/pyproject.toml b/gcp/workers/oss_fuzz_worker/pyproject.toml new file mode 100644 index 00000000000..f252a08bc89 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/pyproject.toml @@ -0,0 +1,32 @@ +[project] +name = "worker" +requires-python = ">=3.13,<3.14" +dependencies = [ + "google-auth-httplib2==0.3.0", + "google-api-python-client==2.188.0", + "google-cloud-pubsub==2.34.0", + "google-cloud-ndb==2.4.0", + "google-cloud-storage==2.19.0", + "pyyaml==6.0.3", + "redis==5.3.1", + "packageurl-python==0.17.6", + "pygit2==1.19.1", + "requests==2.32.5", + "jsonschema==4.26.0", + "vanir==1.0.2", + "osv", +] + +[tool.poetry] +package-mode = false + +[tool.poetry.dependencies] +osv = { path = "../../../", develop = true } + +[tool.poetry.group.dev.dependencies] +yapf = "*" +pylint = "*" + +[build-system] +requires = ["poetry-core>=2.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/gcp/workers/oss_fuzz_worker/run_tests.sh b/gcp/workers/oss_fuzz_worker/run_tests.sh new file mode 100755 index 00000000000..23ef251dbb3 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/run_tests.sh @@ -0,0 +1,19 @@ +#!/bin/bash -xe +# Copyright 2021 Google LLC +# +# 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. + +export GOOGLE_CLOUD_PROJECT=fake-project123 + +poetry install +poetry run python worker_test.py diff --git a/gcp/workers/oss_fuzz_worker/testdata/CVE-2022-27449.json b/gcp/workers/oss_fuzz_worker/testdata/CVE-2022-27449.json new file mode 100644 index 00000000000..3fc80cd9564 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/CVE-2022-27449.json @@ -0,0 +1,138 @@ +{ + "id": "CVE-2022-27449", + "details": "MariaDB Server v10.9 and below was discovered to contain a segmentation fault via the component sql/item_func.cc:148.", + "affected": [ + { + "package": { + "name": "mariadb", + "ecosystem": "Alpine:v3.12", + "purl": "pkg:alpine/mariadb" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "10.4.25-r0" + } + ] + } + ] + }, + { + "package": { + "name": "mariadb", + "ecosystem": "Alpine:v3.13", + "purl": "pkg:alpine/mariadb" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "10.5.16-r0" + } + ] + } + ] + }, + { + "package": { + "name": "mariadb", + "ecosystem": "Alpine:v3.14", + "purl": "pkg:alpine/mariadb" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "10.5.16-r0" + } + ] + } + ] + }, + { + "package": { + "name": "mariadb", + "ecosystem": "Alpine:v3.15", + "purl": "pkg:alpine/mariadb" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "10.6.8-r0" + } + ] + } + ] + }, + { + "package": { + "name": "mariadb", + "ecosystem": "Alpine:v3.16", + "purl": "pkg:alpine/mariadb" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "10.6.8-r0" + } + ] + } + ] + } + ], + "references": [ + { + "type": "EVIDENCE", + "url": "https://jira.mariadb.org/browse/MDEV-28089" + }, + { + "type": "REPORT", + "url": "https://jira.mariadb.org/browse/MDEV-28089" + }, + { + "type": "FIX", + "url": "https://jira.mariadb.org/browse/MDEV-28089" + }, + { + "type": "WEB", + "url": "https://jira.mariadb.org/browse/MDEV-28089" + }, + { + "type": "ADVISORY", + "url": "https://security.netapp.com/advisory/ntap-20220526-0006/" + }, + { + "type": "ARTICLE", + "url": "https://lists.debian.org/debian-lts-announce/2022/09/msg00023.html" + }, + { + "type": "WEB", + "url": "https://lists.debian.org/debian-lts-announce/2022/09/msg00023.html" + } + ], + "modified": "2022-10-07T18:59:00Z", + "published": "2022-04-14T13:15:00Z" +} diff --git a/gcp/workers/oss_fuzz_worker/testdata/DSA-3029-1.json b/gcp/workers/oss_fuzz_worker/testdata/DSA-3029-1.json new file mode 100644 index 00000000000..1b732107b57 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/DSA-3029-1.json @@ -0,0 +1,37 @@ +{ + "id": "DSA-3029-1", + "summary": "nginx - security update", + "affected": [ + { + "package": { + "ecosystem": "Debian:7", + "name": "nginx" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "1.2.1-2.2+wheezy3" + } + ] + } + ] + } + ], + "aliases": [ + "CVE-2014-3616" + ], + "published": "2014-09-20T00:00:00Z", + "modified": "2014-09-20T08:18:07Z", + "details": "\nAntoine Delignat-Lavaud and Karthikeyan Bhargavan discovered that it was\npossible to reuse cached SSL sessions in unrelated contexts, allowing\nvirtual host confusion attacks in some configurations by an attacker in\na privileged network position.\n\n\nFor the stable distribution (wheezy), this problem has been fixed in\nversion 1.2.1-2.2+wheezy3.\n\n\nFor the testing distribution (jessie), this problem has been fixed in\nversion 1.6.2-1.\n\n\nFor the unstable distribution (sid), this problem has been fixed in\nversion 1.6.2-1.\n\n\nWe recommend that you upgrade your nginx packages.\n\n\n", + "references": [ + { + "type": "ADVISORY", + "url": "https://www.debian.org/security/2014/dsa-3029" + } + ] +} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/GHSA-838r-hvwh-24h8.json b/gcp/workers/oss_fuzz_worker/testdata/GHSA-838r-hvwh-24h8.json new file mode 100644 index 00000000000..13e8570e573 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/GHSA-838r-hvwh-24h8.json @@ -0,0 +1,61 @@ +{ + "schema_version": "1.4.0", + "id": "GHSA-838r-hvwh-24h8", + "modified": "2021-09-24T13:10:05Z", + "published": "2021-09-13T20:06:31Z", + "aliases": [ + "CVE-2021-38555" + ], + "summary": "XML Injection in Any23", + "details": "An XML external entity (XXE) injection vulnerability was discovered in the Any23 StreamUtils.java file and is known to affect Any23 versions < 2.5. XML external entity injection (also known as XXE) is a web security vulnerability that allows an attacker to interfere with an application's processing of XML data. It often allows an attacker to view files on the application server filesystem, and to interact with any back-end or external systems that the application itself can access.", + "severity": [ + { + "type": "CVSS_V3", + "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N" + } + ], + "affected": [ + { + "package": { + "ecosystem": "Maven", + "name": "org.apache.any23:apache-any23" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "2.5" + } + ] + } + ] + } + ], + "references": [ + { + "type": "ADVISORY", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-38555" + }, + { + "type": "PACKAGE", + "url": "https://github.com/apache/any23" + }, + { + "type": "WEB", + "url": "https://lists.apache.org/thread.html/r589d1a9f94dbeee7a0f5dbe8513a0e300dfe669bd964ba2fbfe28e07%40%3Cannounce.apache.org%3E" + } + ], + "database_specific": { + "cwe_ids": [ + "CWE-611" + ], + "severity": "CRITICAL", + "github_reviewed": true, + "github_reviewed_at": "2021-09-13T19:31:01Z", + "nvd_published_at": "2021-09-11T11:15:00Z" + } +} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/GSD-123.yaml b/gcp/workers/oss_fuzz_worker/testdata/GSD-123.yaml new file mode 100644 index 00000000000..ae7ed14ddec --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/GSD-123.yaml @@ -0,0 +1,19 @@ +id: GSD-123 +summary: A vulnerability +details: | + Blah blah blah + Blah +modified: 2022-10-07T18:59:00Z +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: Kernel + ecosystem: Linux + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 diff --git a/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_basic.txt b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_basic.txt new file mode 100644 index 00000000000..709e2d6633b --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_basic.txt @@ -0,0 +1,64 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': {'severity': 'MEDIUM'}, + 'package': { 'ecosystem': 'ecosystem', + 'name': 'project', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}, + { 'type': 'introduced', + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}], + 'repo_url': 'https://repo.com/repo', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-2020-1337', + 'details': 'DETAILS', + 'ecosystem': ['GIT', 'ecosystem'], + 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + 'has_affected': True, + 'import_last_modified': None, + 'is_fixed': True, + 'issue_id': '9001', + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['project'], + 'public': False, + 'purl': [], + 'reference_url_types': {'https://url/': 'WEB'}, + 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + 'related': [], + 'search_indices': [ '1337', + '2020', + '2020-1337', + 'ecosystem', + 'git', + 'https://repo.com/repo', + 'osv', + 'osv-2020', + 'osv-2020-1337', + 'project', + 'repo', + 'repo.com/repo'], + 'search_tags': ['osv-2020-1337', 'project'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'oss-fuzz', + 'source_id': 'oss-fuzz:123', + 'source_of_truth': 1, + 'status': 1, + 'summary': 'Heap-buffer-overflow in Foo', + 'timestamp': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_fixed_range_too_long.txt b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_fixed_range_too_long.txt new file mode 100644 index 00000000000..c6d4f3f9a6b --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_fixed_range_too_long.txt @@ -0,0 +1,62 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '0-2', '1'], + 'affected_packages': [ { 'database_specific': { 'fixed_range': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:b587c21c36a84e16cfc6b39eb68578d43b5281ad'}, + 'ecosystem_specific': {'severity': 'MEDIUM'}, + 'package': { 'ecosystem': 'ecosystem', + 'name': 'project', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': 'b587c21c36a84e16cfc6b39eb68578d43b5281ad'}], + 'repo_url': 'https://repo.com/repo', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch-v0.1.1-with-fix', + 'branch_1_cherrypick_regress', + 'v0.1.1', + 'v0.2']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-2020-1337', + 'details': 'DETAILS', + 'ecosystem': ['GIT', 'ecosystem'], + 'fixed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:b587c21c36a84e16cfc6b39eb68578d43b5281ad', + 'has_affected': True, + 'import_last_modified': None, + 'is_fixed': True, + 'issue_id': '9001', + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['project'], + 'public': False, + 'purl': [], + 'reference_url_types': {'https://url/': 'WEB'}, + 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + 'related': [], + 'search_indices': [ '1337', + '2020', + '2020-1337', + 'ecosystem', + 'git', + 'https://repo.com/repo', + 'osv', + 'osv-2020', + 'osv-2020-1337', + 'project', + 'repo', + 'repo.com/repo'], + 'search_tags': ['osv-2020-1337', 'project'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'oss-fuzz', + 'source_id': 'oss-fuzz:123', + 'source_of_truth': 1, + 'status': 1, + 'summary': 'Heap-buffer-overflow in Foo', + 'timestamp': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_not_fixed.txt b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_not_fixed.txt new file mode 100644 index 00000000000..e40014229ae --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_not_fixed.txt @@ -0,0 +1,62 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '0-2', '1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': {'severity': 'MEDIUM'}, + 'package': { 'ecosystem': 'ecosystem', + 'name': 'project', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'introduced', + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}], + 'repo_url': 'https://repo.com/repo', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch-v0.1.1-with-fix', + 'branch_1_cherrypick_regress', + 'v0.1.1', + 'v0.2']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-2020-1337', + 'details': 'DETAILS', + 'ecosystem': ['GIT', 'ecosystem'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': None, + 'is_fixed': False, + 'issue_id': '9001', + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['project'], + 'public': False, + 'purl': [], + 'reference_url_types': {'https://url/': 'WEB'}, + 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + 'related': [], + 'search_indices': [ '1337', + '2020', + '2020-1337', + 'ecosystem', + 'git', + 'https://repo.com/repo', + 'osv', + 'osv-2020', + 'osv-2020-1337', + 'project', + 'repo', + 'repo.com/repo'], + 'search_tags': ['osv-2020-1337', 'project'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'oss-fuzz', + 'source_id': 'oss-fuzz:123', + 'source_of_truth': 1, + 'status': 1, + 'summary': 'Heap-buffer-overflow in Foo', + 'timestamp': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_range.txt b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_range.txt new file mode 100644 index 00000000000..301b29f89b8 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_range.txt @@ -0,0 +1,62 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '0-2', '1'], + 'affected_packages': [ { 'database_specific': { 'fixed_range': 'b1c95a196f22d06fcf80df8c6691cd113d8fefff:36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2'}, + 'ecosystem_specific': {'severity': 'MEDIUM'}, + 'package': { 'ecosystem': 'ecosystem', + 'name': 'project', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2'}], + 'repo_url': 'https://repo.com/repo', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch-v0.1.1-with-fix', + 'branch_1_cherrypick_regress', + 'v0.1.1', + 'v0.2']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-2020-1337', + 'details': 'DETAILS', + 'ecosystem': ['GIT', 'ecosystem'], + 'fixed': 'b1c95a196f22d06fcf80df8c6691cd113d8fefff:36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', + 'has_affected': True, + 'import_last_modified': None, + 'is_fixed': True, + 'issue_id': '9001', + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['project'], + 'public': False, + 'purl': [], + 'reference_url_types': {'https://url/': 'WEB'}, + 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + 'related': [], + 'search_indices': [ '1337', + '2020', + '2020-1337', + 'ecosystem', + 'git', + 'https://repo.com/repo', + 'osv', + 'osv-2020', + 'osv-2020-1337', + 'project', + 'repo', + 'repo.com/repo'], + 'search_tags': ['osv-2020-1337', 'project'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'oss-fuzz', + 'source_id': 'oss-fuzz:123', + 'source_of_truth': 1, + 'status': 1, + 'summary': 'Heap-buffer-overflow in Foo', + 'timestamp': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_simplify_range.txt b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_simplify_range.txt new file mode 100644 index 00000000000..709e2d6633b --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_simplify_range.txt @@ -0,0 +1,64 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': {'severity': 'MEDIUM'}, + 'package': { 'ecosystem': 'ecosystem', + 'name': 'project', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}, + { 'type': 'introduced', + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}], + 'repo_url': 'https://repo.com/repo', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-2020-1337', + 'details': 'DETAILS', + 'ecosystem': ['GIT', 'ecosystem'], + 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + 'has_affected': True, + 'import_last_modified': None, + 'is_fixed': True, + 'issue_id': '9001', + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['project'], + 'public': False, + 'purl': [], + 'reference_url_types': {'https://url/': 'WEB'}, + 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + 'related': [], + 'search_indices': [ '1337', + '2020', + '2020-1337', + 'ecosystem', + 'git', + 'https://repo.com/repo', + 'osv', + 'osv-2020', + 'osv-2020-1337', + 'project', + 'repo', + 'repo.com/repo'], + 'search_tags': ['osv-2020-1337', 'project'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'oss-fuzz', + 'source_id': 'oss-fuzz:123', + 'source_of_truth': 1, + 'status': 1, + 'summary': 'Heap-buffer-overflow in Foo', + 'timestamp': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_zero_regression_range.txt b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_zero_regression_range.txt new file mode 100644 index 00000000000..a81cf737422 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/ImpactTest_zero_regression_range.txt @@ -0,0 +1,60 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '1'], + 'affected_packages': [ { 'database_specific': { 'introduced_range': 'unknown:eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + 'ecosystem_specific': {'severity': 'MEDIUM'}, + 'package': { 'ecosystem': 'ecosystem', + 'name': 'project', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo_url': 'https://repo.com/repo', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-2020-1337', + 'details': 'DETAILS', + 'ecosystem': ['GIT', 'ecosystem'], + 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + 'has_affected': True, + 'import_last_modified': None, + 'is_fixed': True, + 'issue_id': '9001', + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['project'], + 'public': False, + 'purl': [], + 'reference_url_types': {'https://url/': 'WEB'}, + 'regressed': 'unknown:eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + 'related': [], + 'search_indices': [ '1337', + '2020', + '2020-1337', + 'ecosystem', + 'git', + 'https://repo.com/repo', + 'osv', + 'osv-2020', + 'osv-2020-1337', + 'project', + 'repo', + 'repo.com/repo'], + 'search_tags': ['osv-2020-1337', 'project'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'oss-fuzz', + 'source_id': 'oss-fuzz:123', + 'source_of_truth': 1, + 'status': 1, + 'summary': 'Heap-buffer-overflow in Foo', + 'timestamp': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/LINUX-123.yaml b/gcp/workers/oss_fuzz_worker/testdata/LINUX-123.yaml similarity index 100% rename from gcp/workers/worker/testdata/LINUX-123.yaml rename to gcp/workers/oss_fuzz_worker/testdata/LINUX-123.yaml diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-123.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-123.yaml new file mode 100644 index 00000000000..0d93ff864ce --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-123.yaml @@ -0,0 +1,30 @@ +id: OSV-123 +summary: A vulnerability +details: | + Blah blah blah + Blah +severity: +- type: CVSS_V3 + score: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L +credits: +- name: Foo bar + contact: + - mailto:foo@bar.com +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: blah.com/package + ecosystem: Go + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + versions: + - branch-v0.1.1 +database_specific: + specific: 1337 +modified: '2020-01-01T00:00:00Z' \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-124.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-124.yaml new file mode 100644 index 00000000000..4d2eedef66a --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-124.yaml @@ -0,0 +1,20 @@ +id: OSV-124 +summary: A vulnerability +details: | + Blah blah blah + Blah +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: blah.com/package + ecosystem: Go + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + versions: + - branch-v0.1.1 +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-125.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-125.yaml new file mode 100644 index 00000000000..1d10d5409df --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-125.yaml @@ -0,0 +1,28 @@ +id: OSV-125 +summary: A vulnerability +details: | + Blah blah blah + Blah +severity: +- type: CVSS_V3 + score: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L +affected: +- package: + name: blah.com/package + ecosystem: Go + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + - fixed: b9b3fd4732695b83c3068b7b6a14bb372ec31f98 + - introduced: febfac1940086bc1f6d3dc33fda0a1d1ba336209 + versions: + - branch-v0.1.1 + - branch_1_cherrypick_regress + - v0.1.1 +references: +- type: WEB + url: https://ref.com/ref +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-126.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-126.yaml new file mode 100644 index 00000000000..a8ae7ed1e32 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-126.yaml @@ -0,0 +1,21 @@ +id: OSV-126 +summary: A vulnerability +details: | + Blah blah blah + Blah +affected: +- package: + name: blah.com/package + ecosystem: Go + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + versions: + - branch-v0.1.1 +references: +- type: WEB + url: https://ref.com/ref +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-127.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-127.yaml new file mode 100644 index 00000000000..a1a76f16f4f --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-127.yaml @@ -0,0 +1,21 @@ +id: OSV-127 +summary: A vulnerability +details: | + Blah blah blah + Blah +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: blah.com/package + ecosystem: Go + versions: + - branch-v0.1.1 + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: '0' + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-128.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-128.yaml new file mode 100644 index 00000000000..9b928c1f457 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-128.yaml @@ -0,0 +1,25 @@ +id: OSV-128 +summary: A vulnerability +details: | + Blah blah blah + Blah +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: grpcio + ecosystem: PyPI + versions: + - branch-v0.1.1 + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: '0' + - limit: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + - type: ECOSYSTEM + events: + - introduced: 1.13.0 + - limit: 1.14.2 +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-129.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-129.yaml new file mode 100644 index 00000000000..d9eb33d1c97 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-129.yaml @@ -0,0 +1,21 @@ +id: OSV-129 +summary: A vulnerability +details: | + Blah blah blah + Blah +affected: +- package: + name: blah.com/package + ecosystem: not a supported ecosystem + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + versions: + - branch-v0.1.1 +references: +- type: WEB + url: https://ref.com/ref +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-130.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-130.yaml new file mode 100644 index 00000000000..d2d319bf552 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-130.yaml @@ -0,0 +1,35 @@ +id: OSV-130 +summary: A vulnerability +details: | + Blah blah blah + Blah +affected: +- package: + name: blah.com/package + ecosystem: ecosystem + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + versions: + - branch-v0.1.1 +- package: + name: blah.com/package + ecosystem: not a supported ecosystem + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + versions: + - branch-v0.1.1 +references: +- type: WEB + url: https://ref.com/ref +references: +- type: WEB + url: https://ref.com/ref +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-131.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-131.yaml new file mode 100644 index 00000000000..d62b1b10840 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-131.yaml @@ -0,0 +1,21 @@ +id: OSV-131 +summary: A vulnerability +details: | + Blah blah blah + Blah +affected: +- package: + name: blah.com/package + ecosystem: not a supported ecosystem + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + versions: + - branch-v0.1.1 +references: +- type: WEB + url: https://ref.com/ref +modified: '2020-01-01T00:00:00Z' diff --git a/gcp/workers/oss_fuzz_worker/testdata/OSV-TEST-last-affected-01.yaml b/gcp/workers/oss_fuzz_worker/testdata/OSV-TEST-last-affected-01.yaml new file mode 100644 index 00000000000..86e69d4f5d0 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/OSV-TEST-last-affected-01.yaml @@ -0,0 +1,16 @@ +id: OSV-TEST-last-affected-01 +summary: A vulnerability +details: | + Blah blah blah + Blah +modified: 2022-10-07T18:59:00Z +references: +- type: WEB + url: https://ref.com/ref +affected: +- ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - last_affected: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 diff --git a/gcp/workers/oss_fuzz_worker/testdata/PYSEC-123.yaml b/gcp/workers/oss_fuzz_worker/testdata/PYSEC-123.yaml new file mode 100644 index 00000000000..40653cf838c --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/PYSEC-123.yaml @@ -0,0 +1,23 @@ +id: PYSEC-123 +summary: A vulnerability +details: | + Blah blah blah + Blah +modified: 2022-10-07T18:59:00Z +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: grpcio + ecosystem: PyPI + ranges: + - type: ECOSYSTEM + events: + - introduced: 1.14.2 + - fixed: 1.31.0 + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 diff --git a/gcp/workers/oss_fuzz_worker/testdata/PYSEC-124.yaml b/gcp/workers/oss_fuzz_worker/testdata/PYSEC-124.yaml new file mode 100644 index 00000000000..5fc3c832257 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/PYSEC-124.yaml @@ -0,0 +1,18 @@ +id: PYSEC-124 +summary: A vulnerability +details: | + Blah blah blah + Blah +modified: 2022-10-07T18:59:00Z +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: grpcio + ecosystem: PyPI + ranges: + - type: ECOSYSTEM + events: + - introduced: 1.14.2 + - last_affected: 1.31.0 diff --git a/gcp/workers/oss_fuzz_worker/testdata/PYSEC-456.yaml b/gcp/workers/oss_fuzz_worker/testdata/PYSEC-456.yaml new file mode 100644 index 00000000000..008c694bf41 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/PYSEC-456.yaml @@ -0,0 +1,23 @@ +id: PYSEC-456 +summary: A vulnerability in an unnormalized package +details: | + Blah blah blah + Blah +modified: 2022-10-07T18:59:00Z +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: Scrapy + ecosystem: PyPI + ranges: + - type: ECOSYSTEM + events: + - introduced: 1.14.2 + - fixed: 1.31.0 + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 diff --git a/gcp/workers/oss_fuzz_worker/testdata/RESTUpdateTest_update_no_introduced.txt b/gcp/workers/oss_fuzz_worker/testdata/RESTUpdateTest_update_no_introduced.txt new file mode 100644 index 00000000000..2c52b812385 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/RESTUpdateTest_update_no_introduced.txt @@ -0,0 +1,427 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '7-10', + '7-10-1', + '7-10-2', + '7-10-3', + '7-10-4', + '7-10-5', + '7-10-6', + '7-10-7', + '7-10-8', + '7-11-0', + '7-11-1', + '7-11-2', + '7-12-0', + '7-12-1', + '7-12-2', + '7-12-3', + '7-13-0', + '7-13-1', + '7-13-2', + '7-14-0', + '7-14-1', + '7-15-0', + '7-15-1', + '7-15-2', + '7-15-3', + '7-15-4', + '7-15-5', + '7-16-0', + '7-16-1', + '7-16-2', + '7-16-3', + '7-16-4', + '7-17-0', + '7-17-1', + '7-18-0', + '7-18-1', + '7-18-2', + '7-19-0', + '7-19-1', + '7-19-2', + '7-19-3', + '7-19-4', + '7-19-5', + '7-19-6', + '7-19-7', + '7-20-0', + '7-20-1', + '7-21-0', + '7-21-1', + '7-21-2', + '7-21-3', + '7-21-4', + '7-21-5', + '7-21-6', + '7-21-7', + '7-22-0', + '7-23-0', + '7-23-1', + '7-24-0', + '7-25-0', + '7-26-0', + '7-27-0', + '7-28-0', + '7-28-1', + '7-29-0', + '7-30-0', + '7-31-0', + '7-32-0', + '7-33-0', + '7-34-0', + '7-35-0', + '7-36-0', + '7-37-0', + '7-37-1', + '7-38-0', + '7-39-0', + '7-40-0', + '7-41-0', + '7-42-0', + '7-42-1', + '7-43-0', + '7-44-0', + '7-45-0', + '7-46-0', + '7-47-0', + '7-47-1', + '7-48-0', + '7-49-0', + '7-49-1', + '7-50-0', + '7-50-1', + '7-50-2', + '7-50-3', + '7-51-0', + '7-52-0', + '7-52-1', + '7-53-0', + '7-53-1', + '7-54-0', + '7-54-1', + '7-55-0', + '7-55-1', + '7-56-0', + '7-56-1', + '7-57-0', + '7-58-0', + '7-59-0', + '7-60-0', + '7-61-0', + '7-61-1', + '7-62-0', + '7-63-0', + '7-64-0', + '7-64-1', + '7-65-0', + '7-65-1', + '7-65-2', + '7-65-3', + '7-66-0', + '7-67-0', + '7-68-0', + '7-69-0', + '7-69-1', + '7-7', + '7-7-1', + '7-7-2', + '7-7-3', + '7-70-0', + '7-71-0', + '7-71-1', + '7-72-0', + '7-73-0', + '7-74-0', + '7-75-0', + '7-76-0', + '7-76-1', + '7-77-0', + '7-78-0', + '7-79-0', + '7-79-1', + '7-8', + '7-8-1', + '7-80-0', + '7-81-0', + '7-82-0', + '7-83-0', + '7-83-1', + '7-84-0', + '7-85-0', + '7-9', + '7-9-1', + '7-9-2', + '7-9-3', + '7-9-4', + '7-9-5', + '7-9-6', + '7-9-7', + '7-9-8'], + 'affected_packages': [ { 'database_specific': { 'vanir_signatures': [ { 'deprecated': False, + 'digest': { 'function_hash': '22968065415160735040135778472335782425', + 'length': 58084.0}, + 'id': 'CURL-CVE-2022-32221-9751f04c', + 'signature_type': 'Function', + 'signature_version': 'v1', + 'source': 'https://github.com/curl/curl.git/commit/a64e3e59938abd7d667e4470a18072a24d7e9de9', + 'target': { 'file': 'lib/setopt.c', + 'function': 'Curl_vsetopt'}}, + { 'deprecated': False, + 'digest': { 'line_hashes': [ '73596727404438881622769716353410783065', + '150108665408450698810391826671290668314', + '264542534956227828232279400943172691231', + '248438938282829223471764231064667949049'], + 'threshold': 0.9}, + 'id': 'CURL-CVE-2022-32221-b7951194', + 'signature_type': 'Line', + 'signature_version': 'v1', + 'source': 'https://github.com/curl/curl.git/commit/a64e3e59938abd7d667e4470a18072a24d7e9de9', + 'target': { 'file': 'lib/setopt.c'}}]}, + 'ecosystem_specific': None, + 'package': { 'ecosystem': '', + 'name': '', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '7.7'}, + { 'type': 'fixed', + 'value': '7.86.0'}], + 'repo_url': '', + 'type': 'SEMVER'}, + { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '546572da0457f37c698c02d0a08d90fdfcbeedec'}, + { 'type': 'fixed', + 'value': 'a64e3e59938abd7d667e4470a18072a24d7e9de9'}], + 'repo_url': 'https://github.com/curl/curl.git', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ '7.85.0', + '7.84.0', + '7.83.1', + '7.83.0', + '7.82.0', + '7.81.0', + '7.80.0', + '7.79.1', + '7.79.0', + '7.78.0', + '7.77.0', + '7.76.1', + '7.76.0', + '7.75.0', + '7.74.0', + '7.73.0', + '7.72.0', + '7.71.1', + '7.71.0', + '7.70.0', + '7.69.1', + '7.69.0', + '7.68.0', + '7.67.0', + '7.66.0', + '7.65.3', + '7.65.2', + '7.65.1', + '7.65.0', + '7.64.1', + '7.64.0', + '7.63.0', + '7.62.0', + '7.61.1', + '7.61.0', + '7.60.0', + '7.59.0', + '7.58.0', + '7.57.0', + '7.56.1', + '7.56.0', + '7.55.1', + '7.55.0', + '7.54.1', + '7.54.0', + '7.53.1', + '7.53.0', + '7.52.1', + '7.52.0', + '7.51.0', + '7.50.3', + '7.50.2', + '7.50.1', + '7.50.0', + '7.49.1', + '7.49.0', + '7.48.0', + '7.47.1', + '7.47.0', + '7.46.0', + '7.45.0', + '7.44.0', + '7.43.0', + '7.42.1', + '7.42.0', + '7.41.0', + '7.40.0', + '7.39.0', + '7.38.0', + '7.37.1', + '7.37.0', + '7.36.0', + '7.35.0', + '7.34.0', + '7.33.0', + '7.32.0', + '7.31.0', + '7.30.0', + '7.29.0', + '7.28.1', + '7.28.0', + '7.27.0', + '7.26.0', + '7.25.0', + '7.24.0', + '7.23.1', + '7.23.0', + '7.22.0', + '7.21.7', + '7.21.6', + '7.21.5', + '7.21.4', + '7.21.3', + '7.21.2', + '7.21.1', + '7.21.0', + '7.20.1', + '7.20.0', + '7.19.7', + '7.19.6', + '7.19.5', + '7.19.4', + '7.19.3', + '7.19.2', + '7.19.1', + '7.19.0', + '7.18.2', + '7.18.1', + '7.18.0', + '7.17.1', + '7.17.0', + '7.16.4', + '7.16.3', + '7.16.2', + '7.16.1', + '7.16.0', + '7.15.5', + '7.15.4', + '7.15.3', + '7.15.2', + '7.15.1', + '7.15.0', + '7.14.1', + '7.14.0', + '7.13.2', + '7.13.1', + '7.13.0', + '7.12.3', + '7.12.2', + '7.12.1', + '7.12.0', + '7.11.2', + '7.11.1', + '7.11.0', + '7.10.8', + '7.10.7', + '7.10.6', + '7.10.5', + '7.10.4', + '7.10.3', + '7.10.2', + '7.10.1', + '7.10', + '7.9.8', + '7.9.7', + '7.9.6', + '7.9.5', + '7.9.4', + '7.9.3', + '7.9.2', + '7.9.1', + '7.9', + '7.8.1', + '7.8', + '7.7.3', + '7.7.2', + '7.7.1', + '7.7']}], + 'aliases': ['CVE-2022-32221'], + 'credits': [ {'contact': [], 'name': 'Robby Simpson', 'type': 'FINDER'}, + { 'contact': [], + 'name': 'Daniel Stenberg', + 'type': 'REMEDIATION_DEVELOPER'}], + 'database_specific': { 'CWE': { 'desc': 'Expected Behavior Violation', + 'id': 'CWE-440'}, + 'URL': 'https://curl.se/docs/CVE-2022-32221.json', + 'award': {'amount': '2400', 'currency': 'USD'}, + 'issue': 'https://hackerone.com/reports/1704017', + 'last_affected': '7.85.0', + 'package': 'curl', + 'severity': 'Medium', + 'www': 'https://curl.se/docs/CVE-2022-32221.html'}, + 'db_id': 'CURL-CVE-2022-32221', + 'details': 'When doing HTTP(S) transfers, libcurl might erroneously use ' + 'the read callback\n' + '(`CURLOPT_READFUNCTION`) to ask for data to send, even when ' + 'the\n' + '`CURLOPT_POSTFIELDS` option has been set, if the same handle ' + 'previously was\n' + 'used to issue a `PUT` request which used that callback.\n' + '\n' + 'This flaw may surprise the application and cause it to ' + 'misbehave and either\n' + 'send off the wrong data or use memory after free or similar in ' + 'the subsequent\n' + '`POST` request.\n' + '\n' + 'The problem exists in the logic for a reused handle when it is ' + 'changed from a\n' + 'PUT to a POST.', + 'ecosystem': ['GIT'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2023, 5, 10, 0, 37, 6, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': [], + 'public': True, + 'purl': [], + 'reference_url_types': {}, + 'regressed': '', + 'related': [], + 'search_indices': [ '2022', + '2022-32221', + '32221', + 'curl', + 'curl-cve', + 'curl-cve-2022', + 'curl-cve-2022-32221', + 'curl.git', + 'cve', + 'cve-2022', + 'cve-2022-32221', + 'git', + 'github.com/curl/curl.git', + 'https://github.com/curl/curl.git'], + 'search_tags': ['curl-cve-2022-32221'], + 'semver_fixed_indexes': ['00000007.00000086.00000000-zzzzzzzzzzzzzzzz'], + 'severities': [], + 'source': 'source', + 'source_id': 'source:CURL-CVE-2022-32221.json', + 'source_of_truth': 1, + 'status': 1, + 'summary': 'POST following PUT confusion', + 'timestamp': DatetimeWithNanoseconds(2022, 10, 26, 8, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UBUNTU-CVE-2025-38094.json b/gcp/workers/oss_fuzz_worker/testdata/UBUNTU-CVE-2025-38094.json new file mode 100644 index 00000000000..58150ba4c32 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UBUNTU-CVE-2025-38094.json @@ -0,0 +1,262 @@ +{ + "schema_version": "1.7.3", + "id": "UBUNTU-CVE-2025-38094", + "details": "In the Linux kernel, the following vulnerability has been resolved: net: cadence: macb: Fix a possible deadlock in macb_halt_tx. There is a situation where after THALT is set high, TGO stays high as well. Because jiffies are never updated, as we are in a context with interrupts disabled, we never exit that loop and have a deadlock. That deadlock was noticed on a sama5d4 device that stayed locked for days. Use retries instead of jiffies so that the timeout really works and we do not have a deadlock anymore.", + "aliases": [], + "upstream": [ + "CVE-2025-38094" + ], + "related": [], + "severity": [ + { + "type": "Ubuntu", + "score": "medium" + } + ], + "published": "2025-07-04T00:00:00Z", + "modified": "2025-07-04T00:00:00Z", + "affected": [ + { + "package": { + "ecosystem": "Ubuntu:Pro:14.04:LTS", + "name": "linux", + "purl": "pkg:deb/ubuntu/linux@3.13.0-206.257?arch=source&distro=esm-infra-legacy/trusty" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + } + ] + } + ], + "versions": [ + "3.11.0-12.19", + "3.12.0-1.3", + "3.12.0-2.5", + "3.12.0-2.7", + "3.12.0-3.8", + "3.12.0-3.9", + "3.12.0-4.10", + "3.12.0-4.12", + "3.12.0-5.13", + "3.12.0-7.15", + "3.13.0-1.16", + "3.13.0-2.17", + "3.13.0-3.18", + "3.13.0-4.19", + "3.13.0-5.20", + "3.13.0-6.23", + "3.13.0-7.25", + "3.13.0-7.26", + "3.13.0-8.27", + "3.13.0-8.28", + "3.13.0-10.30", + "3.13.0-11.31", + "3.13.0-12.32", + "3.13.0-13.33", + "3.13.0-14.34", + "3.13.0-15.35", + "3.13.0-16.36", + "3.13.0-17.37", + "3.13.0-18.38", + "3.13.0-19.39", + "3.13.0-19.40", + "3.13.0-20.42", + "3.13.0-21.43", + "3.13.0-22.44", + "3.13.0-23.45", + "3.13.0-24.46", + "3.13.0-24.47", + "3.13.0-27.50", + "3.13.0-29.53", + "3.13.0-30.54", + "3.13.0-30.55", + "3.13.0-32.57", + "3.13.0-33.58", + "3.13.0-34.60", + "3.13.0-35.62", + "3.13.0-36.63", + "3.13.0-37.64", + "3.13.0-39.66", + "3.13.0-40.69", + "3.13.0-41.70", + "3.13.0-43.72", + "3.13.0-44.73", + "3.13.0-45.74", + "3.13.0-46.75", + "3.13.0-46.76", + "3.13.0-46.77", + "3.13.0-46.79", + "3.13.0-48.80", + "3.13.0-49.81", + "3.13.0-49.83", + "3.13.0-51.84", + "3.13.0-52.85", + "3.13.0-52.86", + "3.13.0-53.88", + "3.13.0-53.89", + "3.13.0-54.91", + "3.13.0-55.92", + "3.13.0-55.94", + "3.13.0-57.95", + "3.13.0-58.97", + "3.13.0-59.98", + "3.13.0-61.100", + "3.13.0-62.102", + "3.13.0-63.103", + "3.13.0-65.105", + "3.13.0-65.106", + "3.13.0-66.108", + "3.13.0-67.110", + "3.13.0-68.111", + "3.13.0-70.113", + "3.13.0-71.114", + "3.13.0-73.116", + "3.13.0-74.118", + "3.13.0-76.120", + "3.13.0-77.121", + "3.13.0-79.123", + "3.13.0-83.127", + "3.13.0-85.129", + "3.13.0-86.130", + "3.13.0-86.131", + "3.13.0-87.133", + "3.13.0-88.135", + "3.13.0-91.138", + "3.13.0-92.139", + "3.13.0-93.140", + "3.13.0-95.142", + "3.13.0-96.143", + "3.13.0-98.145", + "3.13.0-100.147", + "3.13.0-101.148", + "3.13.0-103.150", + "3.13.0-105.152", + "3.13.0-106.153", + "3.13.0-107.154", + "3.13.0-108.155", + "3.13.0-109.156", + "3.13.0-110.157", + "3.13.0-111.158", + "3.13.0-112.159", + "3.13.0-113.160", + "3.13.0-115.162", + "3.13.0-116.163", + "3.13.0-117.164", + "3.13.0-119.166", + "3.13.0-121.170", + "3.13.0-123.172", + "3.13.0-125.174", + "3.13.0-126.175", + "3.13.0-128.177", + "3.13.0-129.178", + "3.13.0-132.181", + "3.13.0-133.182", + "3.13.0-135.184", + "3.13.0-137.186", + "3.13.0-139.188", + "3.13.0-141.190", + "3.13.0-142.191", + "3.13.0-143.192", + "3.13.0-144.193", + "3.13.0-145.194", + "3.13.0-147.196", + "3.13.0-149.199", + "3.13.0-151.201", + "3.13.0-153.203", + "3.13.0-155.205", + "3.13.0-156.206", + "3.13.0-157.207", + "3.13.0-158.208", + "3.13.0-160.210", + "3.13.0-161.211", + "3.13.0-162.212", + "3.13.0-163.213", + "3.13.0-164.214", + "3.13.0-165.215", + "3.13.0-166.216", + "3.13.0-167.217", + "3.13.0-168.218", + "3.13.0-169.219", + "3.13.0-170.220", + "3.13.0-173.224", + "3.13.0-174.225", + "3.13.0-175.226", + "3.13.0-176.227", + "3.13.0-180.231", + "3.13.0-181.232", + "3.13.0-182.233", + "3.13.0-183.234", + "3.13.0-184.235", + "3.13.0-185.236", + "3.13.0-186.237", + "3.13.0-187.238", + "3.13.0-188.239", + "3.13.0-189.240", + "3.13.0-190.241", + "3.13.0-191.242", + "3.13.0-192.243", + "3.13.0-193.244", + "3.13.0-194.245", + "3.13.0-195.246", + "3.13.0-196.247", + "3.13.0-197.248", + "3.13.0-198.249", + "3.13.0-199.250", + "3.13.0-200.251", + "3.13.0-201.252", + "3.13.0-202.253", + "3.13.0-203.254", + "3.13.0-204.255", + "3.13.0-205.256", + "3.13.0-206.257" + ], + "ecosystem_specific": {} + } + ], + "references": [ + { + "type": "REPORT", + "url": "https://ubuntu.com/security/CVE-2025-38094" + }, + { + "type": "REPORT", + "url": "https://www.cve.org/CVERecord?id=CVE-2025-38094" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/linus/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/stable/c/0772a608d799ac0d127c0a36047a2725777aba9d" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/stable/c/1d60c0781c1bbeaa1196b0d8aad5c435f06cb7c4" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/stable/c/3e64d35475aa21d13dab71da51de51923c1a3a48" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/stable/c/64675a9c00443b2e8af42af08c38fc1b78b68ba2" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/stable/c/84f98955a9de0e0f591df85aa1a44f3ebcf1cb37" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/stable/c/aace6b63892ce8307e502a60fe2f5a4bc6e1cfe7" + }, + { + "type": "REPORT", + "url": "https://git.kernel.org/stable/c/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f" + } + ] +} diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_analysis_crash_handling.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_analysis_crash_handling.txt new file mode 100644 index 00000000000..6968470d21e --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_analysis_crash_handling.txt @@ -0,0 +1,170 @@ +{ 'affected': [], + 'affected_fuzzy': [ '6-9-4-0', + '6-9-4-1', + '6-9-4-10', + '6-9-4-2', + '6-9-4-3', + '6-9-4-4', + '6-9-4-5', + '6-9-4-6', + '6-9-4-7', + '6-9-4-8', + '6-9-4-9', + '6-9-5-0', + '6-9-5-1', + '6-9-5-2', + '6-9-5-3', + '6-9-5-4'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': { 'urgency': 'not yet ' + 'assigned'}, + 'package': { 'ecosystem': 'Debian:11', + 'name': 'imagemagick', + 'purl': 'pkg:deb/debian/imagemagick?arch=source'}, + 'ranges': [ { 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '8:6.9.6.2+dfsg-2'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': []}, + { 'database_specific': None, + 'ecosystem_specific': { 'urgency': 'not yet ' + 'assigned'}, + 'package': { 'ecosystem': 'Debian:12', + 'name': 'imagemagick', + 'purl': 'pkg:deb/debian/imagemagick?arch=source'}, + 'ranges': [ { 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '8:6.9.6.2+dfsg-2'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': []}, + { 'database_specific': None, + 'ecosystem_specific': { 'urgency': 'not yet ' + 'assigned'}, + 'package': { 'ecosystem': 'Debian:13', + 'name': 'imagemagick', + 'purl': 'pkg:deb/debian/imagemagick?arch=source'}, + 'ranges': [ { 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '8:6.9.6.2+dfsg-2'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': []}, + { 'database_specific': { 'vanir_signatures': [ { 'deprecated': False, + 'digest': { 'function_hash': '105821297934886641033004172548266479551', + 'length': 34630.0}, + 'id': 'CVE-2016-10046-90cf14aa', + 'signature_type': 'Function', + 'signature_version': 'v1', + 'source': 'https://github.com/imagemagick/imagemagick/commit/989f9f88ea6db09b99d25586e912c921c0da8d3f', + 'target': { 'file': 'magick/draw.c', + 'function': 'DrawImage'}}, + { 'deprecated': False, + 'digest': { 'line_hashes': [ '111474618106123245942052817755198756272', + '301954155546171996711090723027809067481', + '279975694698735176382484669604413338546', + '183001078492337674961672731704068361015'], + 'threshold': 0.9}, + 'id': 'CVE-2016-10046-b43115ee', + 'signature_type': 'Line', + 'signature_version': 'v1', + 'source': 'https://github.com/imagemagick/imagemagick/commit/989f9f88ea6db09b99d25586e912c921c0da8d3f', + 'target': { 'file': 'magick/draw.c'}}]}, + 'ecosystem_specific': None, + 'package': { 'ecosystem': '', + 'name': '', + 'purl': None}, + 'ranges': [ { 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '989f9f88ea6db09b99d25586e912c921c0da8d3f'}], + 'repo_url': 'https://github.com/imagemagick/imagemagick', + 'type': 'GIT'}, + { 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'last_affected', + 'value': '969a96ed7eea9603bea46492e9116c2ba28da60f'}], + 'repo_url': 'https://github.com/imagemagick/imagemagick6', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ '6.9.4-0', + '6.9.4-1', + '6.9.4-10', + '6.9.4-2', + '6.9.4-3', + '6.9.4-4', + '6.9.4-5', + '6.9.4-6', + '6.9.4-7', + '6.9.4-8', + '6.9.4-9', + '6.9.5-0', + '6.9.5-1', + '6.9.5-2', + '6.9.5-3', + '6.9.5-4']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'CVE-2016-10046', + 'details': 'Heap-based buffer overflow in the DrawImage function in ' + 'magick/draw.c in ImageMagick before 6.9.5-5 allows remote ' + 'attackers to cause a denial of service (application crash) via ' + 'a crafted image file.', + 'ecosystem': ['Debian', 'Debian:11', 'Debian:12', 'Debian:13', 'GIT'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2024, 9, 18, 1, 0, 20, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['imagemagick'], + 'public': True, + 'purl': [ 'pkg:deb/debian/imagemagick', + 'pkg:deb/debian/imagemagick?arch=source'], + 'reference_url_types': { 'http://www.openwall.com/lists/oss-security/2016/12/26/9': 'WEB', + 'http://www.securityfocus.com/bid/95183': 'WEB', + 'https://bugzilla.redhat.com/show_bug.cgi?id=1410448': 'REPORT', + 'https://github.com/ImageMagick/ImageMagick/commit/989f9f88ea6db09b99d25586e912c921c0da8d3f': 'REPORT', + 'https://security-tracker.debian.org/tracker/CVE-2016-10046': 'ADVISORY'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '10046', + '11', + '12', + '13', + '2016', + '2016-10046', + 'cve', + 'cve-2016', + 'cve-2016-10046', + 'debian', + 'debian:11', + 'debian:12', + 'debian:13', + 'git', + 'github.com/imagemagick/imagemagick', + 'github.com/imagemagick/imagemagick6', + 'https://github.com/imagemagick/imagemagick', + 'https://github.com/imagemagick/imagemagick6', + 'imagemagick', + 'imagemagick6'], + 'search_tags': ['cve-2016-10046', 'imagemagick'], + 'semver_fixed_indexes': [], + 'severities': [ { 'score': 'CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H', + 'type': 'CVSS_V3'}], + 'source': 'source', + 'source_id': 'source:CVE-2016-10046.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': '', + 'timestamp': DatetimeWithNanoseconds(2017, 3, 23, 17, 59, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_alpine.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_alpine.txt new file mode 100644 index 00000000000..cb4c04fa467 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_alpine.txt @@ -0,0 +1,616 @@ +('diff --git a/CVE-2022-27449.json b/CVE-2022-27449.json\n' + 'index 3fc80cd..e6cf371 100644\n' + '--- a/CVE-2022-27449.json\n' + '+++ b/CVE-2022-27449.json\n' + '@@ -1,16 +1,13 @@\n' + ' {\n' + '- "id": "CVE-2022-27449",\n' + '- "details": "MariaDB Server v10.9 and below was discovered to contain a ' + 'segmentation fault via the component sql/item_func.cc:148.",\n' + ' "affected": [\n' + ' {\n' + ' "package": {\n' + '- "name": "mariadb",\n' + ' "ecosystem": "Alpine:v3.12",\n' + '+ "name": "mariadb",\n' + ' "purl": "pkg:alpine/mariadb"\n' + ' },\n' + ' "ranges": [\n' + ' {\n' + '- "type": "ECOSYSTEM",\n' + ' "events": [\n' + ' {\n' + ' "introduced": "0"\n' + '@@ -18,19 +15,110 @@\n' + ' {\n' + ' "fixed": "10.4.25-r0"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "type": "ECOSYSTEM"\n' + ' }\n' + '+ ],\n' + '+ "versions": [\n' + '+ "10.0.21-r0",\n' + '+ "10.0.21-r1",\n' + '+ "10.0.21-r2",\n' + '+ "10.1.11-r0",\n' + '+ "10.1.11-r1",\n' + '+ "10.1.12-r0",\n' + '+ "10.1.12-r1",\n' + '+ "10.1.13-r0",\n' + '+ "10.1.13-r1",\n' + '+ "10.1.14-r0",\n' + '+ "10.1.14-r1",\n' + '+ "10.1.14-r2",\n' + '+ "10.1.14-r3",\n' + '+ "10.1.16-r0",\n' + '+ "10.1.17-r0",\n' + '+ "10.1.17-r1",\n' + '+ "10.1.18-r0",\n' + '+ "10.1.18-r1",\n' + '+ "10.1.19-r0",\n' + '+ "10.1.20-r0",\n' + '+ "10.1.21-r0",\n' + '+ "10.1.22-r0",\n' + '+ "10.1.22-r1",\n' + '+ "10.1.22-r2",\n' + '+ "10.1.24-r0",\n' + '+ "10.1.26-r0",\n' + '+ "10.1.28-r0",\n' + '+ "10.1.28-r1",\n' + '+ "10.1.28-r2",\n' + '+ "10.1.31-r0",\n' + '+ "10.1.8-r0",\n' + '+ "10.1.8-r1",\n' + '+ "10.1.9-r0",\n' + '+ "10.1.9-r1",\n' + '+ "10.1.9-r2",\n' + '+ "10.1.9-r3",\n' + '+ "10.2.13-r0",\n' + '+ "10.2.13-r1",\n' + '+ "10.2.14-r0",\n' + '+ "10.2.14-r1",\n' + '+ "10.2.14-r2",\n' + '+ "10.2.15-r0",\n' + '+ "10.3.10-r0",\n' + '+ "10.3.10-r1",\n' + '+ "10.3.11-r0",\n' + '+ "10.3.12-r0",\n' + '+ "10.3.12-r1",\n' + '+ "10.3.12-r2",\n' + '+ "10.3.13-r0",\n' + '+ "10.3.13-r1",\n' + '+ "10.3.13-r2",\n' + '+ "10.3.13-r3",\n' + '+ "10.3.13-r4",\n' + '+ "10.3.15-r0",\n' + '+ "10.3.16-r0",\n' + '+ "10.3.9-r0",\n' + '+ "10.3.9-r1",\n' + '+ "10.3.9-r2",\n' + '+ "10.4.10-r0",\n' + '+ "10.4.10-r1",\n' + '+ "10.4.11-r0",\n' + '+ "10.4.12-r0",\n' + '+ "10.4.13-r0",\n' + '+ "10.4.15-r0",\n' + '+ "10.4.17-r0",\n' + '+ "10.4.17-r1",\n' + '+ "10.4.18-r0",\n' + '+ "10.4.19-r0",\n' + '+ "10.4.21-r0",\n' + '+ "10.4.22-r0",\n' + '+ "10.4.24-r0",\n' + '+ "10.4.6-r0",\n' + '+ "10.4.6-r1",\n' + '+ "10.4.7-r0",\n' + '+ "10.4.8-r0",\n' + '+ "5.5.41-r0",\n' + '+ "5.5.41-r1",\n' + '+ "5.5.41-r2",\n' + '+ "5.5.42-r0",\n' + '+ "5.5.42-r1",\n' + '+ "5.5.42-r2",\n' + '+ "5.5.42-r3",\n' + '+ "5.5.42-r4",\n' + '+ "5.5.43-r0",\n' + '+ "5.5.43-r1",\n' + '+ "5.5.43-r2",\n' + '+ "5.5.43-r3",\n' + '+ "5.5.43-r4",\n' + '+ "5.5.43-r5"\n' + ' ]\n' + ' },\n' + ' {\n' + ' "package": {\n' + '- "name": "mariadb",\n' + ' "ecosystem": "Alpine:v3.13",\n' + '+ "name": "mariadb",\n' + ' "purl": "pkg:alpine/mariadb"\n' + ' },\n' + ' "ranges": [\n' + ' {\n' + '- "type": "ECOSYSTEM",\n' + ' "events": [\n' + ' {\n' + ' "introduced": "0"\n' + '@@ -38,19 +126,113 @@\n' + ' {\n' + ' "fixed": "10.5.16-r0"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "type": "ECOSYSTEM"\n' + ' }\n' + '+ ],\n' + '+ "versions": [\n' + '+ "10.0.21-r0",\n' + '+ "10.0.21-r1",\n' + '+ "10.0.21-r2",\n' + '+ "10.1.11-r0",\n' + '+ "10.1.11-r1",\n' + '+ "10.1.12-r0",\n' + '+ "10.1.12-r1",\n' + '+ "10.1.13-r0",\n' + '+ "10.1.13-r1",\n' + '+ "10.1.14-r0",\n' + '+ "10.1.14-r1",\n' + '+ "10.1.14-r2",\n' + '+ "10.1.14-r3",\n' + '+ "10.1.16-r0",\n' + '+ "10.1.17-r0",\n' + '+ "10.1.17-r1",\n' + '+ "10.1.18-r0",\n' + '+ "10.1.18-r1",\n' + '+ "10.1.19-r0",\n' + '+ "10.1.20-r0",\n' + '+ "10.1.21-r0",\n' + '+ "10.1.22-r0",\n' + '+ "10.1.22-r1",\n' + '+ "10.1.22-r2",\n' + '+ "10.1.24-r0",\n' + '+ "10.1.26-r0",\n' + '+ "10.1.28-r0",\n' + '+ "10.1.28-r1",\n' + '+ "10.1.28-r2",\n' + '+ "10.1.31-r0",\n' + '+ "10.1.8-r0",\n' + '+ "10.1.8-r1",\n' + '+ "10.1.9-r0",\n' + '+ "10.1.9-r1",\n' + '+ "10.1.9-r2",\n' + '+ "10.1.9-r3",\n' + '+ "10.2.13-r0",\n' + '+ "10.2.13-r1",\n' + '+ "10.2.14-r0",\n' + '+ "10.2.14-r1",\n' + '+ "10.2.14-r2",\n' + '+ "10.2.15-r0",\n' + '+ "10.3.10-r0",\n' + '+ "10.3.10-r1",\n' + '+ "10.3.11-r0",\n' + '+ "10.3.12-r0",\n' + '+ "10.3.12-r1",\n' + '+ "10.3.12-r2",\n' + '+ "10.3.13-r0",\n' + '+ "10.3.13-r1",\n' + '+ "10.3.13-r2",\n' + '+ "10.3.13-r3",\n' + '+ "10.3.13-r4",\n' + '+ "10.3.15-r0",\n' + '+ "10.3.16-r0",\n' + '+ "10.3.9-r0",\n' + '+ "10.3.9-r1",\n' + '+ "10.3.9-r2",\n' + '+ "10.4.10-r0",\n' + '+ "10.4.10-r1",\n' + '+ "10.4.11-r0",\n' + '+ "10.4.12-r0",\n' + '+ "10.4.13-r0",\n' + '+ "10.4.13-r1",\n' + '+ "10.4.14-r0",\n' + '+ "10.4.6-r0",\n' + '+ "10.4.6-r1",\n' + '+ "10.4.7-r0",\n' + '+ "10.4.8-r0",\n' + '+ "10.5.10-r0",\n' + '+ "10.5.11-r0",\n' + '+ "10.5.12-r0",\n' + '+ "10.5.13-r0",\n' + '+ "10.5.15-r0",\n' + '+ "10.5.5-r0",\n' + '+ "10.5.6-r0",\n' + '+ "10.5.8-r0",\n' + '+ "10.5.9-r0",\n' + '+ "5.5.41-r0",\n' + '+ "5.5.41-r1",\n' + '+ "5.5.41-r2",\n' + '+ "5.5.42-r0",\n' + '+ "5.5.42-r1",\n' + '+ "5.5.42-r2",\n' + '+ "5.5.42-r3",\n' + '+ "5.5.42-r4",\n' + '+ "5.5.43-r0",\n' + '+ "5.5.43-r1",\n' + '+ "5.5.43-r2",\n' + '+ "5.5.43-r3",\n' + '+ "5.5.43-r4",\n' + '+ "5.5.43-r5"\n' + ' ]\n' + ' },\n' + ' {\n' + ' "package": {\n' + '- "name": "mariadb",\n' + ' "ecosystem": "Alpine:v3.14",\n' + '+ "name": "mariadb",\n' + ' "purl": "pkg:alpine/mariadb"\n' + ' },\n' + ' "ranges": [\n' + ' {\n' + '- "type": "ECOSYSTEM",\n' + ' "events": [\n' + ' {\n' + ' "introduced": "0"\n' + '@@ -58,19 +240,112 @@\n' + ' {\n' + ' "fixed": "10.5.16-r0"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "type": "ECOSYSTEM"\n' + ' }\n' + '+ ],\n' + '+ "versions": [\n' + '+ "10.0.21-r0",\n' + '+ "10.0.21-r1",\n' + '+ "10.0.21-r2",\n' + '+ "10.1.11-r0",\n' + '+ "10.1.11-r1",\n' + '+ "10.1.12-r0",\n' + '+ "10.1.12-r1",\n' + '+ "10.1.13-r0",\n' + '+ "10.1.13-r1",\n' + '+ "10.1.14-r0",\n' + '+ "10.1.14-r1",\n' + '+ "10.1.14-r2",\n' + '+ "10.1.14-r3",\n' + '+ "10.1.16-r0",\n' + '+ "10.1.17-r0",\n' + '+ "10.1.17-r1",\n' + '+ "10.1.18-r0",\n' + '+ "10.1.18-r1",\n' + '+ "10.1.19-r0",\n' + '+ "10.1.20-r0",\n' + '+ "10.1.21-r0",\n' + '+ "10.1.22-r0",\n' + '+ "10.1.22-r1",\n' + '+ "10.1.22-r2",\n' + '+ "10.1.24-r0",\n' + '+ "10.1.26-r0",\n' + '+ "10.1.28-r0",\n' + '+ "10.1.28-r1",\n' + '+ "10.1.28-r2",\n' + '+ "10.1.31-r0",\n' + '+ "10.1.8-r0",\n' + '+ "10.1.8-r1",\n' + '+ "10.1.9-r0",\n' + '+ "10.1.9-r1",\n' + '+ "10.1.9-r2",\n' + '+ "10.1.9-r3",\n' + '+ "10.2.13-r0",\n' + '+ "10.2.13-r1",\n' + '+ "10.2.14-r0",\n' + '+ "10.2.14-r1",\n' + '+ "10.2.14-r2",\n' + '+ "10.2.15-r0",\n' + '+ "10.3.10-r0",\n' + '+ "10.3.10-r1",\n' + '+ "10.3.11-r0",\n' + '+ "10.3.12-r0",\n' + '+ "10.3.12-r1",\n' + '+ "10.3.12-r2",\n' + '+ "10.3.13-r0",\n' + '+ "10.3.13-r1",\n' + '+ "10.3.13-r2",\n' + '+ "10.3.13-r3",\n' + '+ "10.3.13-r4",\n' + '+ "10.3.15-r0",\n' + '+ "10.3.16-r0",\n' + '+ "10.3.9-r0",\n' + '+ "10.3.9-r1",\n' + '+ "10.3.9-r2",\n' + '+ "10.4.10-r0",\n' + '+ "10.4.10-r1",\n' + '+ "10.4.11-r0",\n' + '+ "10.4.12-r0",\n' + '+ "10.4.13-r0",\n' + '+ "10.4.13-r1",\n' + '+ "10.4.14-r0",\n' + '+ "10.4.6-r0",\n' + '+ "10.4.6-r1",\n' + '+ "10.4.7-r0",\n' + '+ "10.4.8-r0",\n' + '+ "10.5.11-r0",\n' + '+ "10.5.12-r0",\n' + '+ "10.5.13-r0",\n' + '+ "10.5.15-r0",\n' + '+ "10.5.5-r0",\n' + '+ "10.5.6-r0",\n' + '+ "10.5.8-r0",\n' + '+ "10.5.9-r0",\n' + '+ "5.5.41-r0",\n' + '+ "5.5.41-r1",\n' + '+ "5.5.41-r2",\n' + '+ "5.5.42-r0",\n' + '+ "5.5.42-r1",\n' + '+ "5.5.42-r2",\n' + '+ "5.5.42-r3",\n' + '+ "5.5.42-r4",\n' + '+ "5.5.43-r0",\n' + '+ "5.5.43-r1",\n' + '+ "5.5.43-r2",\n' + '+ "5.5.43-r3",\n' + '+ "5.5.43-r4",\n' + '+ "5.5.43-r5"\n' + ' ]\n' + ' },\n' + ' {\n' + ' "package": {\n' + '- "name": "mariadb",\n' + ' "ecosystem": "Alpine:v3.15",\n' + '+ "name": "mariadb",\n' + ' "purl": "pkg:alpine/mariadb"\n' + ' },\n' + ' "ranges": [\n' + ' {\n' + '- "type": "ECOSYSTEM",\n' + ' "events": [\n' + ' {\n' + ' "introduced": "0"\n' + '@@ -78,19 +353,115 @@\n' + ' {\n' + ' "fixed": "10.6.8-r0"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "type": "ECOSYSTEM"\n' + ' }\n' + '+ ],\n' + '+ "versions": [\n' + '+ "10.0.21-r0",\n' + '+ "10.0.21-r1",\n' + '+ "10.0.21-r2",\n' + '+ "10.1.11-r0",\n' + '+ "10.1.11-r1",\n' + '+ "10.1.12-r0",\n' + '+ "10.1.12-r1",\n' + '+ "10.1.13-r0",\n' + '+ "10.1.13-r1",\n' + '+ "10.1.14-r0",\n' + '+ "10.1.14-r1",\n' + '+ "10.1.14-r2",\n' + '+ "10.1.14-r3",\n' + '+ "10.1.16-r0",\n' + '+ "10.1.17-r0",\n' + '+ "10.1.17-r1",\n' + '+ "10.1.18-r0",\n' + '+ "10.1.18-r1",\n' + '+ "10.1.19-r0",\n' + '+ "10.1.20-r0",\n' + '+ "10.1.21-r0",\n' + '+ "10.1.22-r0",\n' + '+ "10.1.22-r1",\n' + '+ "10.1.22-r2",\n' + '+ "10.1.24-r0",\n' + '+ "10.1.26-r0",\n' + '+ "10.1.28-r0",\n' + '+ "10.1.28-r1",\n' + '+ "10.1.28-r2",\n' + '+ "10.1.31-r0",\n' + '+ "10.1.8-r0",\n' + '+ "10.1.8-r1",\n' + '+ "10.1.9-r0",\n' + '+ "10.1.9-r1",\n' + '+ "10.1.9-r2",\n' + '+ "10.1.9-r3",\n' + '+ "10.2.13-r0",\n' + '+ "10.2.13-r1",\n' + '+ "10.2.14-r0",\n' + '+ "10.2.14-r1",\n' + '+ "10.2.14-r2",\n' + '+ "10.2.15-r0",\n' + '+ "10.3.10-r0",\n' + '+ "10.3.10-r1",\n' + '+ "10.3.11-r0",\n' + '+ "10.3.12-r0",\n' + '+ "10.3.12-r1",\n' + '+ "10.3.12-r2",\n' + '+ "10.3.13-r0",\n' + '+ "10.3.13-r1",\n' + '+ "10.3.13-r2",\n' + '+ "10.3.13-r3",\n' + '+ "10.3.13-r4",\n' + '+ "10.3.15-r0",\n' + '+ "10.3.16-r0",\n' + '+ "10.3.9-r0",\n' + '+ "10.3.9-r1",\n' + '+ "10.3.9-r2",\n' + '+ "10.4.10-r0",\n' + '+ "10.4.10-r1",\n' + '+ "10.4.11-r0",\n' + '+ "10.4.12-r0",\n' + '+ "10.4.13-r0",\n' + '+ "10.4.13-r1",\n' + '+ "10.4.14-r0",\n' + '+ "10.4.6-r0",\n' + '+ "10.4.6-r1",\n' + '+ "10.4.7-r0",\n' + '+ "10.4.8-r0",\n' + '+ "10.5.11-r0",\n' + '+ "10.5.11-r1",\n' + '+ "10.5.5-r0",\n' + '+ "10.5.6-r0",\n' + '+ "10.5.8-r0",\n' + '+ "10.5.9-r0",\n' + '+ "10.6.3-r0",\n' + '+ "10.6.4-r0",\n' + '+ "10.6.4-r1",\n' + '+ "10.6.4-r2",\n' + '+ "10.6.7-r0",\n' + '+ "5.5.41-r0",\n' + '+ "5.5.41-r1",\n' + '+ "5.5.41-r2",\n' + '+ "5.5.42-r0",\n' + '+ "5.5.42-r1",\n' + '+ "5.5.42-r2",\n' + '+ "5.5.42-r3",\n' + '+ "5.5.42-r4",\n' + '+ "5.5.43-r0",\n' + '+ "5.5.43-r1",\n' + '+ "5.5.43-r2",\n' + '+ "5.5.43-r3",\n' + '+ "5.5.43-r4",\n' + '+ "5.5.43-r5"\n' + ' ]\n' + ' },\n' + ' {\n' + ' "package": {\n' + '- "name": "mariadb",\n' + ' "ecosystem": "Alpine:v3.16",\n' + '+ "name": "mariadb",\n' + ' "purl": "pkg:alpine/mariadb"\n' + ' },\n' + ' "ranges": [\n' + ' {\n' + '- "type": "ECOSYSTEM",\n' + ' "events": [\n' + ' {\n' + ' "introduced": "0"\n' + '@@ -98,11 +469,112 @@\n' + ' {\n' + ' "fixed": "10.6.8-r0"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "type": "ECOSYSTEM"\n' + ' }\n' + '+ ],\n' + '+ "versions": [\n' + '+ "10.0.21-r0",\n' + '+ "10.0.21-r1",\n' + '+ "10.0.21-r2",\n' + '+ "10.1.11-r0",\n' + '+ "10.1.11-r1",\n' + '+ "10.1.12-r0",\n' + '+ "10.1.12-r1",\n' + '+ "10.1.13-r0",\n' + '+ "10.1.13-r1",\n' + '+ "10.1.14-r0",\n' + '+ "10.1.14-r1",\n' + '+ "10.1.14-r2",\n' + '+ "10.1.14-r3",\n' + '+ "10.1.16-r0",\n' + '+ "10.1.17-r0",\n' + '+ "10.1.17-r1",\n' + '+ "10.1.18-r0",\n' + '+ "10.1.18-r1",\n' + '+ "10.1.19-r0",\n' + '+ "10.1.20-r0",\n' + '+ "10.1.21-r0",\n' + '+ "10.1.22-r0",\n' + '+ "10.1.22-r1",\n' + '+ "10.1.22-r2",\n' + '+ "10.1.24-r0",\n' + '+ "10.1.26-r0",\n' + '+ "10.1.28-r0",\n' + '+ "10.1.28-r1",\n' + '+ "10.1.28-r2",\n' + '+ "10.1.31-r0",\n' + '+ "10.1.8-r0",\n' + '+ "10.1.8-r1",\n' + '+ "10.1.9-r0",\n' + '+ "10.1.9-r1",\n' + '+ "10.1.9-r2",\n' + '+ "10.1.9-r3",\n' + '+ "10.2.13-r0",\n' + '+ "10.2.13-r1",\n' + '+ "10.2.14-r0",\n' + '+ "10.2.14-r1",\n' + '+ "10.2.14-r2",\n' + '+ "10.2.15-r0",\n' + '+ "10.3.10-r0",\n' + '+ "10.3.10-r1",\n' + '+ "10.3.11-r0",\n' + '+ "10.3.12-r0",\n' + '+ "10.3.12-r1",\n' + '+ "10.3.12-r2",\n' + '+ "10.3.13-r0",\n' + '+ "10.3.13-r1",\n' + '+ "10.3.13-r2",\n' + '+ "10.3.13-r3",\n' + '+ "10.3.13-r4",\n' + '+ "10.3.15-r0",\n' + '+ "10.3.16-r0",\n' + '+ "10.3.9-r0",\n' + '+ "10.3.9-r1",\n' + '+ "10.3.9-r2",\n' + '+ "10.4.10-r0",\n' + '+ "10.4.10-r1",\n' + '+ "10.4.11-r0",\n' + '+ "10.4.12-r0",\n' + '+ "10.4.13-r0",\n' + '+ "10.4.13-r1",\n' + '+ "10.4.14-r0",\n' + '+ "10.4.6-r0",\n' + '+ "10.4.6-r1",\n' + '+ "10.4.7-r0",\n' + '+ "10.4.8-r0",\n' + '+ "10.5.11-r0",\n' + '+ "10.5.11-r1",\n' + '+ "10.5.5-r0",\n' + '+ "10.5.6-r0",\n' + '+ "10.5.8-r0",\n' + '+ "10.5.9-r0",\n' + '+ "10.6.3-r0",\n' + '+ "10.6.4-r0",\n' + '+ "10.6.4-r1",\n' + '+ "10.6.4-r2",\n' + '+ "10.6.7-r0",\n' + '+ "5.5.41-r0",\n' + '+ "5.5.41-r1",\n' + '+ "5.5.41-r2",\n' + '+ "5.5.42-r0",\n' + '+ "5.5.42-r1",\n' + '+ "5.5.42-r2",\n' + '+ "5.5.42-r3",\n' + '+ "5.5.42-r4",\n' + '+ "5.5.43-r0",\n' + '+ "5.5.43-r1",\n' + '+ "5.5.43-r2",\n' + '+ "5.5.43-r3",\n' + '+ "5.5.43-r4",\n' + '+ "5.5.43-r5"\n' + ' ]\n' + ' }\n' + ' ],\n' + '+ "details": "MariaDB Server v10.9 and below was discovered to contain a ' + 'segmentation fault via the component sql/item_func.cc:148.",\n' + '+ "id": "CVE-2022-27449",\n' + '+ "modified": "3000-01-01T00:00:00Z",\n' + '+ "published": "2022-04-14T13:15:00Z",\n' + ' "references": [\n' + ' {\n' + ' "type": "EVIDENCE",\n' + '@@ -132,7 +604,5 @@\n' + ' "type": "WEB",\n' + ' "url": ' + '"https://lists.debian.org/debian-lts-announce/2022/09/msg00023.html"\n' + ' }\n' + '- ],\n' + '- "modified": "2022-10-07T18:59:00Z",\n' + '- "published": "2022-04-14T13:15:00Z"\n' + '-}\n' + '+ ]\n' + '+}\n' + '\\ No newline at end of file\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_debian.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_debian.txt new file mode 100644 index 00000000000..0433f0bc3ff --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_debian.txt @@ -0,0 +1,64 @@ +('diff --git a/DSA-3029-1.json b/DSA-3029-1.json\n' + 'index 1b73210..c114001 100644\n' + '--- a/DSA-3029-1.json\n' + '+++ b/DSA-3029-1.json\n' + '@@ -1,6 +1,4 @@\n' + ' {\n' + '- "id": "DSA-3029-1",\n' + '- "summary": "nginx - security update",\n' + ' "affected": [\n' + ' {\n' + ' "package": {\n' + '@@ -9,7 +7,6 @@\n' + ' },\n' + ' "ranges": [\n' + ' {\n' + '- "type": "ECOSYSTEM",\n' + ' "events": [\n' + ' {\n' + ' "introduced": "0"\n' + '@@ -17,21 +14,30 @@\n' + ' {\n' + ' "fixed": "1.2.1-2.2+wheezy3"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "type": "ECOSYSTEM"\n' + ' }\n' + '+ ],\n' + '+ "versions": [\n' + '+ "1.2.1-2.2",\n' + '+ "1.2.1-2.2+wheezy1",\n' + '+ "1.2.1-2.2+wheezy2",\n' + '+ "1.2.1-2.2+wheezy3~bpo60+1"\n' + ' ]\n' + ' }\n' + ' ],\n' + ' "aliases": [\n' + ' "CVE-2014-3616"\n' + ' ],\n' + '- "published": "2014-09-20T00:00:00Z",\n' + '- "modified": "2014-09-20T08:18:07Z",\n' + ' "details": "\\nAntoine Delignat-Lavaud and Karthikeyan Bhargavan ' + 'discovered that it was\\npossible to reuse cached SSL sessions in unrelated ' + 'contexts, allowing\\nvirtual host confusion attacks in some configurations ' + 'by an attacker in\\na privileged network position.\\n\\n\\nFor the stable ' + 'distribution (wheezy), this problem has been fixed in\\nversion ' + '1.2.1-2.2+wheezy3.\\n\\n\\nFor the testing distribution (jessie), this ' + 'problem has been fixed in\\nversion 1.6.2-1.\\n\\n\\nFor the unstable ' + 'distribution (sid), this problem has been fixed in\\nversion ' + '1.6.2-1.\\n\\n\\nWe recommend that you upgrade your nginx ' + 'packages.\\n\\n\\n",\n' + '+ "id": "DSA-3029-1",\n' + '+ "modified": "3000-01-01T00:00:00Z",\n' + '+ "published": "2014-09-20T00:00:00Z",\n' + ' "references": [\n' + ' {\n' + ' "type": "ADVISORY",\n' + ' "url": "https://www.debian.org/security/2014/dsa-3029"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "summary": "nginx - security update"\n' + ' }\n' + '\\ No newline at end of file\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected.txt new file mode 100644 index 00000000000..1cc3591ae79 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected.txt @@ -0,0 +1,78 @@ +('diff --git a/PYSEC-124.yaml b/PYSEC-124.yaml\n' + 'index 5fc3c83..bc7539c 100644\n' + '--- a/PYSEC-124.yaml\n' + '+++ b/PYSEC-124.yaml\n' + '@@ -1,18 +1,61 @@\n' + '-id: PYSEC-124\n' + '-summary: A vulnerability\n' + '-details: |\n' + '- Blah blah blah\n' + '- Blah\n' + '-modified: 2022-10-07T18:59:00Z\n' + '-references:\n' + '-- type: WEB\n' + '- url: https://ref.com/ref\n' + ' affected:\n' + ' - package:\n' + '- name: grpcio\n' + ' ecosystem: PyPI\n' + '+ name: grpcio\n' + ' ranges:\n' + '- - type: ECOSYSTEM\n' + '- events:\n' + '+ - events:\n' + ' - introduced: 1.14.2\n' + ' - last_affected: 1.31.0\n' + '+ type: ECOSYSTEM\n' + '+ versions:\n' + '+ - 1.14.2\n' + '+ - 1.15.0\n' + '+ - 1.15.0rc1\n' + '+ - 1.16.0\n' + '+ - 1.16.0rc1\n' + '+ - 1.16.1\n' + '+ - 1.17.0\n' + '+ - 1.17.1\n' + '+ - 1.18.0\n' + '+ - 1.19.0\n' + '+ - 1.20.0\n' + '+ - 1.20.0rc1\n' + '+ - 1.20.0rc2\n' + '+ - 1.20.0rc3\n' + '+ - 1.20.1\n' + '+ - 1.21.0rc1\n' + '+ - 1.21.1\n' + '+ - 1.21.1rc1\n' + '+ - 1.22.0\n' + '+ - 1.22.0rc1\n' + '+ - 1.22.1\n' + '+ - 1.23.0\n' + '+ - 1.23.0rc1\n' + '+ - 1.23.1\n' + '+ - 1.24.0\n' + '+ - 1.24.0rc1\n' + '+ - 1.24.1\n' + '+ - 1.24.3\n' + '+ - 1.25.0\n' + '+ - 1.25.0rc1\n' + '+ - 1.26.0\n' + '+ - 1.26.0rc1\n' + '+ - 1.27.0rc1\n' + '+ - 1.27.0rc2\n' + '+ - 1.27.1\n' + '+ - 1.27.2\n' + '+ - 1.28.0rc1\n' + '+ - 1.28.0rc2\n' + '+ - 1.28.1\n' + '+ - 1.29.0\n' + '+ - 1.30.0\n' + '+ - 1.31.0\n' + '+details: |\n' + '+ Blah blah blah\n' + '+ Blah\n' + '+id: PYSEC-124\n' + "+modified: '3000-01-01T00:00:00Z'\n" + '+references:\n' + '+- type: WEB\n' + '+ url: https://ref.com/ref\n' + '+summary: A vulnerability\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected_git.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected_git.txt new file mode 100644 index 00000000000..990ff79da6e --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_last_affected_git.txt @@ -0,0 +1,35 @@ +('diff --git a/OSV-TEST-last-affected-01.yaml ' + 'b/OSV-TEST-last-affected-01.yaml\n' + 'index 86e69d4..db61731 100644\n' + '--- a/OSV-TEST-last-affected-01.yaml\n' + '+++ b/OSV-TEST-last-affected-01.yaml\n' + '@@ -1,16 +1,19 @@\n' + '-id: OSV-TEST-last-affected-01\n' + '-summary: A vulnerability\n' + '+affected:\n' + '+- ranges:\n' + '+ - events:\n' + '+ - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd\n' + '+ - last_affected: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' + '+ repo: https://osv-test/repo/url\n' + '+ type: GIT\n' + '+ versions:\n' + '+ - v0.1.1\n' + '+ - v0.2\n' + ' details: |\n' + ' Blah blah blah\n' + ' Blah\n' + '-modified: 2022-10-07T18:59:00Z\n' + '+id: OSV-TEST-last-affected-01\n' + "+modified: '3000-01-01T00:00:00Z'\n" + ' references:\n' + ' - type: WEB\n' + ' url: https://ref.com/ref\n' + '-affected:\n' + '-- ranges:\n' + '- - type: GIT\n' + '- repo: https://osv-test/repo/url\n' + '- events:\n' + '- - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd\n' + '- - last_affected: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' + '+summary: A vulnerability\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_maven.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_maven.txt new file mode 100644 index 00000000000..600a0536a0d --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_maven.txt @@ -0,0 +1,110 @@ +('diff --git a/GHSA-838r-hvwh-24h8.json b/GHSA-838r-hvwh-24h8.json\n' + 'index 13e8570..55b233a 100644\n' + '--- a/GHSA-838r-hvwh-24h8.json\n' + '+++ b/GHSA-838r-hvwh-24h8.json\n' + '@@ -1,19 +1,4 @@\n' + ' {\n' + '- "schema_version": "1.4.0",\n' + '- "id": "GHSA-838r-hvwh-24h8",\n' + '- "modified": "2021-09-24T13:10:05Z",\n' + '- "published": "2021-09-13T20:06:31Z",\n' + '- "aliases": [\n' + '- "CVE-2021-38555"\n' + '- ],\n' + '- "summary": "XML Injection in Any23",\n' + '- "details": "An XML external entity (XXE) injection vulnerability was ' + 'discovered in the Any23 StreamUtils.java file and is known to affect Any23 ' + 'versions < 2.5. XML external entity injection (also known as XXE) is a web ' + 'security vulnerability that allows an attacker to interfere with an ' + "application's processing of XML data. It often allows an attacker to view " + 'files on the application server filesystem, and to interact with any ' + 'back-end or external systems that the application itself can access.",\n' + '- "severity": [\n' + '- {\n' + '- "type": "CVSS_V3",\n' + '- "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N"\n' + '- }\n' + '- ],\n' + ' "affected": [\n' + ' {\n' + ' "package": {\n' + '@@ -22,7 +7,6 @@\n' + ' },\n' + ' "ranges": [\n' + ' {\n' + '- "type": "ECOSYSTEM",\n' + ' "events": [\n' + ' {\n' + ' "introduced": "0"\n' + '@@ -30,11 +14,40 @@\n' + ' {\n' + ' "fixed": "2.5"\n' + ' }\n' + '- ]\n' + '+ ],\n' + '+ "type": "ECOSYSTEM"\n' + ' }\n' + '+ ],\n' + '+ "versions": [\n' + '+ "0.7.0-incubating",\n' + '+ "0.8.0",\n' + '+ "0.9.0",\n' + '+ "1.0",\n' + '+ "1.1",\n' + '+ "2.0",\n' + '+ "2.1",\n' + '+ "2.2",\n' + '+ "2.3",\n' + '+ "2.4"\n' + ' ]\n' + ' }\n' + ' ],\n' + '+ "aliases": [\n' + '+ "CVE-2021-38555"\n' + '+ ],\n' + '+ "database_specific": {\n' + '+ "cwe_ids": [\n' + '+ "CWE-611"\n' + '+ ],\n' + '+ "github_reviewed": true,\n' + '+ "github_reviewed_at": "2021-09-13T19:31:01Z",\n' + '+ "nvd_published_at": "2021-09-11T11:15:00Z",\n' + '+ "severity": "CRITICAL"\n' + '+ },\n' + '+ "details": "An XML external entity (XXE) injection vulnerability was ' + 'discovered in the Any23 StreamUtils.java file and is known to affect Any23 ' + 'versions < 2.5. XML external entity injection (also known as XXE) is a web ' + 'security vulnerability that allows an attacker to interfere with an ' + "application's processing of XML data. It often allows an attacker to view " + 'files on the application server filesystem, and to interact with any ' + 'back-end or external systems that the application itself can access.",\n' + '+ "id": "GHSA-838r-hvwh-24h8",\n' + '+ "modified": "3000-01-01T00:00:00Z",\n' + '+ "published": "2021-09-13T20:06:31Z",\n' + ' "references": [\n' + ' {\n' + ' "type": "ADVISORY",\n' + '@@ -49,13 +62,12 @@\n' + ' "url": ' + '"https://lists.apache.org/thread.html/r589d1a9f94dbeee7a0f5dbe8513a0e300dfe669bd964ba2fbfe28e07%40%3Cannounce.apache.org%3E"\n' + ' }\n' + ' ],\n' + '- "database_specific": {\n' + '- "cwe_ids": [\n' + '- "CWE-611"\n' + '- ],\n' + '- "severity": "CRITICAL",\n' + '- "github_reviewed": true,\n' + '- "github_reviewed_at": "2021-09-13T19:31:01Z",\n' + '- "nvd_published_at": "2021-09-11T11:15:00Z"\n' + '- }\n' + '+ "schema_version": "1.4.0",\n' + '+ "severity": [\n' + '+ {\n' + '+ "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",\n' + '+ "type": "CVSS_V3"\n' + '+ }\n' + '+ ],\n' + '+ "summary": "XML Injection in Any23"\n' + ' }\n' + '\\ No newline at end of file\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_normalized_pypi.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_normalized_pypi.txt new file mode 100644 index 00000000000..9c7aacfe8a2 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_normalized_pypi.txt @@ -0,0 +1,29 @@ +('diff --git a/PYSEC-456.yaml b/PYSEC-456.yaml\n' + 'new file mode 100644\n' + 'index 0000000..008c694\n' + '--- /dev/null\n' + '+++ b/PYSEC-456.yaml\n' + '@@ -0,0 +1,23 @@\n' + '+id: PYSEC-456\n' + '+summary: A vulnerability in an unnormalized package\n' + '+details: |\n' + '+ Blah blah blah\n' + '+ Blah\n' + '+modified: 2022-10-07T18:59:00Z\n' + '+references:\n' + '+- type: WEB\n' + '+ url: https://ref.com/ref\n' + '+affected:\n' + '+- package:\n' + '+ name: Scrapy\n' + '+ ecosystem: PyPI\n' + '+ ranges:\n' + '+ - type: ECOSYSTEM\n' + '+ events:\n' + '+ - introduced: 1.14.2\n' + '+ - fixed: 1.31.0\n' + '+ - type: GIT\n' + '+ repo: https://osv-test/repo/url\n' + '+ events:\n' + '+ - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd\n' + '+ - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_pypi.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_pypi.txt new file mode 100644 index 00000000000..9bdb664f6e3 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_pypi.txt @@ -0,0 +1,85 @@ +('diff --git a/PYSEC-123.yaml b/PYSEC-123.yaml\n' + 'index 40653cf..8e2c331 100644\n' + '--- a/PYSEC-123.yaml\n' + '+++ b/PYSEC-123.yaml\n' + '@@ -1,23 +1,65 @@\n' + '-id: PYSEC-123\n' + '-summary: A vulnerability\n' + '-details: |\n' + '- Blah blah blah\n' + '- Blah\n' + '-modified: 2022-10-07T18:59:00Z\n' + '-references:\n' + '-- type: WEB\n' + '- url: https://ref.com/ref\n' + ' affected:\n' + ' - package:\n' + '- name: grpcio\n' + ' ecosystem: PyPI\n' + '+ name: grpcio\n' + ' ranges:\n' + '- - type: ECOSYSTEM\n' + '- events:\n' + '+ - events:\n' + ' - introduced: 1.14.2\n' + ' - fixed: 1.31.0\n' + '- - type: GIT\n' + '- repo: https://osv-test/repo/url\n' + '- events:\n' + '+ type: ECOSYSTEM\n' + '+ - events:\n' + ' - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd\n' + ' - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' + '+ repo: https://osv-test/repo/url\n' + '+ type: GIT\n' + '+ versions:\n' + '+ - 1.14.2\n' + '+ - 1.15.0\n' + '+ - 1.15.0rc1\n' + '+ - 1.16.0\n' + '+ - 1.16.0rc1\n' + '+ - 1.16.1\n' + '+ - 1.17.0\n' + '+ - 1.17.1\n' + '+ - 1.18.0\n' + '+ - 1.19.0\n' + '+ - 1.20.0\n' + '+ - 1.20.0rc1\n' + '+ - 1.20.0rc2\n' + '+ - 1.20.0rc3\n' + '+ - 1.20.1\n' + '+ - 1.21.0rc1\n' + '+ - 1.21.1\n' + '+ - 1.21.1rc1\n' + '+ - 1.22.0\n' + '+ - 1.22.0rc1\n' + '+ - 1.22.1\n' + '+ - 1.23.0\n' + '+ - 1.23.0rc1\n' + '+ - 1.23.1\n' + '+ - 1.24.0\n' + '+ - 1.24.0rc1\n' + '+ - 1.24.1\n' + '+ - 1.24.3\n' + '+ - 1.25.0\n' + '+ - 1.25.0rc1\n' + '+ - 1.26.0\n' + '+ - 1.26.0rc1\n' + '+ - 1.27.0rc1\n' + '+ - 1.27.0rc2\n' + '+ - 1.27.1\n' + '+ - 1.27.2\n' + '+ - 1.28.0rc1\n' + '+ - 1.28.0rc2\n' + '+ - 1.28.1\n' + '+ - 1.29.0\n' + '+ - 1.30.0\n' + '+details: |\n' + '+ Blah blah blah\n' + '+ Blah\n' + '+id: PYSEC-123\n' + "+modified: '3000-01-01T00:00:00Z'\n" + '+references:\n' + '+- type: WEB\n' + '+ url: https://ref.com/ref\n' + '+summary: A vulnerability\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update.txt new file mode 100644 index 00000000000..6c3164251ff --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update.txt @@ -0,0 +1,61 @@ +('diff --git a/OSV-123.yaml b/OSV-123.yaml\n' + 'index 0d93ff8..e765523 100644\n' + '--- a/OSV-123.yaml\n' + '+++ b/OSV-123.yaml\n' + '@@ -1,30 +1,34 @@\n' + '-id: OSV-123\n' + '-summary: A vulnerability\n' + '-details: |\n' + '- Blah blah blah\n' + '- Blah\n' + '-severity:\n' + '-- type: CVSS_V3\n' + '- score: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L\n' + '-credits:\n' + '-- name: Foo bar\n' + '- contact:\n' + '- - mailto:foo@bar.com\n' + '-references:\n' + '-- type: WEB\n' + '- url: https://ref.com/ref\n' + ' affected:\n' + ' - package:\n' + '- name: blah.com/package\n' + ' ecosystem: Go\n' + '+ name: blah.com/package\n' + ' ranges:\n' + '- - type: GIT\n' + '- repo: https://osv-test/repo/url\n' + '- events:\n' + '+ - events:\n' + ' - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd\n' + ' - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' + '+ - introduced: febfac1940086bc1f6d3dc33fda0a1d1ba336209\n' + '+ - fixed: b9b3fd4732695b83c3068b7b6a14bb372ec31f98\n' + '+ repo: https://osv-test/repo/url\n' + '+ type: GIT\n' + ' versions:\n' + ' - branch-v0.1.1\n' + '+ - branch_1_cherrypick_regress\n' + '+ - v0.1.1\n' + '+credits:\n' + '+- contact:\n' + '+ - mailto:foo@bar.com\n' + '+ name: Foo bar\n' + ' database_specific:\n' + '- specific: 1337\n' + "-modified: '2020-01-01T00:00:00Z'\n" + '\\ No newline at end of file\n' + '+ specific: 1337.0\n' + '+details: |\n' + '+ Blah blah blah\n' + '+ Blah\n' + '+id: OSV-123\n' + "+modified: '3000-01-01T00:00:00Z'\n" + '+references:\n' + '+- type: WEB\n' + '+ url: https://ref.com/ref\n' + '+severity:\n' + '+- score: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L\n' + '+ type: CVSS_V3\n' + '+summary: A vulnerability\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_add_fix.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_add_fix.txt new file mode 100644 index 00000000000..64d431543b5 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_add_fix.txt @@ -0,0 +1,43 @@ +('diff --git a/OSV-124.yaml b/OSV-124.yaml\n' + 'index 4d2eede..8b6df18 100644\n' + '--- a/OSV-124.yaml\n' + '+++ b/OSV-124.yaml\n' + '@@ -1,20 +1,25 @@\n' + '-id: OSV-124\n' + '-summary: A vulnerability\n' + '-details: |\n' + '- Blah blah blah\n' + '- Blah\n' + '-references:\n' + '-- type: WEB\n' + '- url: https://ref.com/ref\n' + ' affected:\n' + ' - package:\n' + '- name: blah.com/package\n' + ' ecosystem: Go\n' + '+ name: blah.com/package\n' + ' ranges:\n' + '- - type: GIT\n' + '- repo: https://osv-test/repo/url\n' + '- events:\n' + '+ - events:\n' + ' - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd\n' + '+ - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' + '+ - introduced: febfac1940086bc1f6d3dc33fda0a1d1ba336209\n' + '+ - fixed: b9b3fd4732695b83c3068b7b6a14bb372ec31f98\n' + '+ repo: https://osv-test/repo/url\n' + '+ type: GIT\n' + ' versions:\n' + ' - branch-v0.1.1\n' + "-modified: '2020-01-01T00:00:00Z'\n" + '+ - branch_1_cherrypick_regress\n' + '+ - v0.1.1\n' + '+details: |\n' + '+ Blah blah blah\n' + '+ Blah\n' + '+id: OSV-124\n' + "+modified: '3000-01-01T00:00:00Z'\n" + '+references:\n' + '+- type: WEB\n' + '+ url: https://ref.com/ref\n' + '+summary: A vulnerability\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_limit.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_limit.txt new file mode 100644 index 00000000000..8765ed63433 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_limit.txt @@ -0,0 +1,55 @@ +('diff --git a/OSV-128.yaml b/OSV-128.yaml\n' + 'index 9b928c1..e4b6aad 100644\n' + '--- a/OSV-128.yaml\n' + '+++ b/OSV-128.yaml\n' + '@@ -1,25 +1,33 @@\n' + '-id: OSV-128\n' + '-summary: A vulnerability\n' + '-details: |\n' + '- Blah blah blah\n' + '- Blah\n' + '-references:\n' + '-- type: WEB\n' + '- url: https://ref.com/ref\n' + ' affected:\n' + ' - package:\n' + '- name: grpcio\n' + ' ecosystem: PyPI\n' + '- versions:\n' + '- - branch-v0.1.1\n' + '+ name: grpcio\n' + ' ranges:\n' + '- - type: GIT\n' + '- repo: https://osv-test/repo/url\n' + '- events:\n' + '+ - events:\n' + " - introduced: '0'\n" + ' - limit: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' + '- - type: ECOSYSTEM\n' + '- events:\n' + '+ repo: https://osv-test/repo/url\n' + '+ type: GIT\n' + '+ - events:\n' + ' - introduced: 1.13.0\n' + ' - limit: 1.14.2\n' + "-modified: '2020-01-01T00:00:00Z'\n" + '+ type: ECOSYSTEM\n' + '+ versions:\n' + '+ - branch-v0.1.1\n' + '+ - 1.13.0\n' + '+ - 1.14.0\n' + '+ - 1.14.0rc1\n' + '+ - 1.14.0rc2\n' + '+ - 1.14.1\n' + '+ - 1.14.2rc1\n' + '+ - v0.1\n' + '+ - v0.1.1\n' + '+details: |\n' + '+ Blah blah blah\n' + '+ Blah\n' + '+id: OSV-128\n' + "+modified: '3000-01-01T00:00:00Z'\n" + '+references:\n' + '+- type: WEB\n' + '+ url: https://ref.com/ref\n' + '+summary: A vulnerability\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_no_introduced.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_no_introduced.txt new file mode 100644 index 00000000000..4c56c356353 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_diff_update_no_introduced.txt @@ -0,0 +1,45 @@ +('diff --git a/OSV-127.yaml b/OSV-127.yaml\n' + 'index a1a76f1..163c78a 100644\n' + '--- a/OSV-127.yaml\n' + '+++ b/OSV-127.yaml\n' + '@@ -1,21 +1,25 @@\n' + '-id: OSV-127\n' + '-summary: A vulnerability\n' + '-details: |\n' + '- Blah blah blah\n' + '- Blah\n' + '-references:\n' + '-- type: WEB\n' + '- url: https://ref.com/ref\n' + ' affected:\n' + ' - package:\n' + '- name: blah.com/package\n' + ' ecosystem: Go\n' + '- versions:\n' + '- - branch-v0.1.1\n' + '+ name: blah.com/package\n' + ' ranges:\n' + '- - type: GIT\n' + '- repo: https://osv-test/repo/url\n' + '- events:\n' + '+ - events:\n' + " - introduced: '0'\n" + ' - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' + "-modified: '2020-01-01T00:00:00Z'\n" + '+ - fixed: b9b3fd4732695b83c3068b7b6a14bb372ec31f98\n' + '+ repo: https://osv-test/repo/url\n' + '+ type: GIT\n' + '+ versions:\n' + '+ - branch-v0.1.1\n' + '+ - branch_1_cherrypick_regress\n' + '+ - v0.1\n' + '+ - v0.1.1\n' + '+details: |\n' + '+ Blah blah blah\n' + '+ Blah\n' + '+id: OSV-127\n' + "+modified: '3000-01-01T00:00:00Z'\n" + '+references:\n' + '+- type: WEB\n' + '+ url: https://ref.com/ref\n' + '+summary: A vulnerability\n') \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_dont_index_too_many_git_versions.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_dont_index_too_many_git_versions.txt new file mode 100644 index 00000000000..a277e3adbe1 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_dont_index_too_many_git_versions.txt @@ -0,0 +1,5067 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': '', + 'name': '', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'last_affected', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ '00000', + '00001', + '00002', + '00003', + '00004', + '00005', + '00006', + '00007', + '00008', + '00009', + '00010', + '00011', + '00012', + '00013', + '00014', + '00015', + '00016', + '00017', + '00018', + '00019', + '00020', + '00021', + '00022', + '00023', + '00024', + '00025', + '00026', + '00027', + '00028', + '00029', + '00030', + '00031', + '00032', + '00033', + '00034', + '00035', + '00036', + '00037', + '00038', + '00039', + '00040', + '00041', + '00042', + '00043', + '00044', + '00045', + '00046', + '00047', + '00048', + '00049', + '00050', + '00051', + '00052', + '00053', + '00054', + '00055', + '00056', + '00057', + '00058', + '00059', + '00060', + '00061', + '00062', + '00063', + '00064', + '00065', + '00066', + '00067', + '00068', + '00069', + '00070', + '00071', + '00072', + '00073', + '00074', + '00075', + '00076', + '00077', + '00078', + '00079', + '00080', + '00081', + '00082', + '00083', + '00084', + '00085', + '00086', + '00087', + '00088', + '00089', + '00090', + '00091', + '00092', + '00093', + '00094', + '00095', + '00096', + '00097', + '00098', + '00099', + '00100', + '00101', + '00102', + '00103', + '00104', + '00105', + '00106', + '00107', + '00108', + '00109', + '00110', + '00111', + '00112', + '00113', + '00114', + '00115', + '00116', + '00117', + '00118', + '00119', + '00120', + '00121', + '00122', + '00123', + '00124', + '00125', + '00126', + '00127', + '00128', + '00129', + '00130', + '00131', + '00132', + '00133', + '00134', + '00135', + '00136', + '00137', + '00138', + '00139', + '00140', + '00141', + '00142', + '00143', + '00144', + '00145', + '00146', + '00147', + '00148', + '00149', + '00150', + '00151', + '00152', + '00153', + '00154', + '00155', + '00156', + '00157', + '00158', + '00159', + '00160', + '00161', + '00162', + '00163', + '00164', + '00165', + '00166', + '00167', + '00168', + '00169', + '00170', + '00171', + '00172', + '00173', + '00174', + '00175', + '00176', + '00177', + '00178', + '00179', + '00180', + '00181', + '00182', + '00183', + '00184', + '00185', + '00186', + '00187', + '00188', + '00189', + '00190', + '00191', + '00192', + '00193', + '00194', + '00195', + '00196', + '00197', + '00198', + '00199', + '00200', + '00201', + '00202', + '00203', + '00204', + '00205', + '00206', + '00207', + '00208', + '00209', + '00210', + '00211', + '00212', + '00213', + '00214', + '00215', + '00216', + '00217', + '00218', + '00219', + '00220', + '00221', + '00222', + '00223', + '00224', + '00225', + '00226', + '00227', + '00228', + '00229', + '00230', + '00231', + '00232', + '00233', + '00234', + '00235', + '00236', + '00237', + '00238', + '00239', + '00240', + '00241', + '00242', + '00243', + '00244', + '00245', + '00246', + '00247', + '00248', + '00249', + '00250', + '00251', + '00252', + '00253', + '00254', + '00255', + '00256', + '00257', + '00258', + '00259', + '00260', + '00261', + '00262', + '00263', + '00264', + '00265', + '00266', + '00267', + '00268', + '00269', + '00270', + '00271', + '00272', + '00273', + '00274', + '00275', + '00276', + '00277', + '00278', + '00279', + '00280', + '00281', + '00282', + '00283', + '00284', + '00285', + '00286', + '00287', + '00288', + '00289', + '00290', + '00291', + '00292', + '00293', + '00294', + '00295', + '00296', + '00297', + '00298', + '00299', + '00300', + '00301', + '00302', + '00303', + '00304', + '00305', + '00306', + '00307', + '00308', + '00309', + '00310', + '00311', + '00312', + '00313', + '00314', + '00315', + '00316', + '00317', + '00318', + '00319', + '00320', + '00321', + '00322', + '00323', + '00324', + '00325', + '00326', + '00327', + '00328', + '00329', + '00330', + '00331', + '00332', + '00333', + '00334', + '00335', + '00336', + '00337', + '00338', + '00339', + '00340', + '00341', + '00342', + '00343', + '00344', + '00345', + '00346', + '00347', + '00348', + '00349', + '00350', + '00351', + '00352', + '00353', + '00354', + '00355', + '00356', + '00357', + '00358', + '00359', + '00360', + '00361', + '00362', + '00363', + '00364', + '00365', + '00366', + '00367', + '00368', + '00369', + '00370', + '00371', + '00372', + '00373', + '00374', + '00375', + '00376', + '00377', + '00378', + '00379', + '00380', + '00381', + '00382', + '00383', + '00384', + '00385', + '00386', + '00387', + '00388', + '00389', + '00390', + '00391', + '00392', + '00393', + '00394', + '00395', + '00396', + '00397', + '00398', + '00399', + '00400', + '00401', + '00402', + '00403', + '00404', + '00405', + '00406', + '00407', + '00408', + '00409', + '00410', + '00411', + '00412', + '00413', + '00414', + '00415', + '00416', + '00417', + '00418', + '00419', + '00420', + '00421', + '00422', + '00423', + '00424', + '00425', + '00426', + '00427', + '00428', + '00429', + '00430', + '00431', + '00432', + '00433', + '00434', + '00435', + '00436', + '00437', + '00438', + '00439', + '00440', + '00441', + '00442', + '00443', + '00444', + '00445', + '00446', + '00447', + '00448', + '00449', + '00450', + '00451', + '00452', + '00453', + '00454', + '00455', + '00456', + '00457', + '00458', + '00459', + '00460', + '00461', + '00462', + '00463', + '00464', + '00465', + '00466', + '00467', + '00468', + '00469', + '00470', + '00471', + '00472', + '00473', + '00474', + '00475', + '00476', + '00477', + '00478', + '00479', + '00480', + '00481', + '00482', + '00483', + '00484', + '00485', + '00486', + '00487', + '00488', + '00489', + '00490', + '00491', + '00492', + '00493', + '00494', + '00495', + '00496', + '00497', + '00498', + '00499', + '00500', + '00501', + '00502', + '00503', + '00504', + '00505', + '00506', + '00507', + '00508', + '00509', + '00510', + '00511', + '00512', + '00513', + '00514', + '00515', + '00516', + '00517', + '00518', + '00519', + '00520', + '00521', + '00522', + '00523', + '00524', + '00525', + '00526', + '00527', + '00528', + '00529', + '00530', + '00531', + '00532', + '00533', + '00534', + '00535', + '00536', + '00537', + '00538', + '00539', + '00540', + '00541', + '00542', + '00543', + '00544', + '00545', + '00546', + '00547', + '00548', + '00549', + '00550', + '00551', + '00552', + '00553', + '00554', + '00555', + '00556', + '00557', + '00558', + '00559', + '00560', + '00561', + '00562', + '00563', + '00564', + '00565', + '00566', + '00567', + '00568', + '00569', + '00570', + '00571', + '00572', + '00573', + '00574', + '00575', + '00576', + '00577', + '00578', + '00579', + '00580', + '00581', + '00582', + '00583', + '00584', + '00585', + '00586', + '00587', + '00588', + '00589', + '00590', + '00591', + '00592', + '00593', + '00594', + '00595', + '00596', + '00597', + '00598', + '00599', + '00600', + '00601', + '00602', + '00603', + '00604', + '00605', + '00606', + '00607', + '00608', + '00609', + '00610', + '00611', + '00612', + '00613', + '00614', + '00615', + '00616', + '00617', + '00618', + '00619', + '00620', + '00621', + '00622', + '00623', + '00624', + '00625', + '00626', + '00627', + '00628', + '00629', + '00630', + '00631', + '00632', + '00633', + '00634', + '00635', + '00636', + '00637', + '00638', + '00639', + '00640', + '00641', + '00642', + '00643', + '00644', + '00645', + '00646', + '00647', + '00648', + '00649', + '00650', + '00651', + '00652', + '00653', + '00654', + '00655', + '00656', + '00657', + '00658', + '00659', + '00660', + '00661', + '00662', + '00663', + '00664', + '00665', + '00666', + '00667', + '00668', + '00669', + '00670', + '00671', + '00672', + '00673', + '00674', + '00675', + '00676', + '00677', + '00678', + '00679', + '00680', + '00681', + '00682', + '00683', + '00684', + '00685', + '00686', + '00687', + '00688', + '00689', + '00690', + '00691', + '00692', + '00693', + '00694', + '00695', + '00696', + '00697', + '00698', + '00699', + '00700', + '00701', + '00702', + '00703', + '00704', + '00705', + '00706', + '00707', + '00708', + '00709', + '00710', + '00711', + '00712', + '00713', + '00714', + '00715', + '00716', + '00717', + '00718', + '00719', + '00720', + '00721', + '00722', + '00723', + '00724', + '00725', + '00726', + '00727', + '00728', + '00729', + '00730', + '00731', + '00732', + '00733', + '00734', + '00735', + '00736', + '00737', + '00738', + '00739', + '00740', + '00741', + '00742', + '00743', + '00744', + '00745', + '00746', + '00747', + '00748', + '00749', + '00750', + '00751', + '00752', + '00753', + '00754', + '00755', + '00756', + '00757', + '00758', + '00759', + '00760', + '00761', + '00762', + '00763', + '00764', + '00765', + '00766', + '00767', + '00768', + '00769', + '00770', + '00771', + '00772', + '00773', + '00774', + '00775', + '00776', + '00777', + '00778', + '00779', + '00780', + '00781', + '00782', + '00783', + '00784', + '00785', + '00786', + '00787', + '00788', + '00789', + '00790', + '00791', + '00792', + '00793', + '00794', + '00795', + '00796', + '00797', + '00798', + '00799', + '00800', + '00801', + '00802', + '00803', + '00804', + '00805', + '00806', + '00807', + '00808', + '00809', + '00810', + '00811', + '00812', + '00813', + '00814', + '00815', + '00816', + '00817', + '00818', + '00819', + '00820', + '00821', + '00822', + '00823', + '00824', + '00825', + '00826', + '00827', + '00828', + '00829', + '00830', + '00831', + '00832', + '00833', + '00834', + '00835', + '00836', + '00837', + '00838', + '00839', + '00840', + '00841', + '00842', + '00843', + '00844', + '00845', + '00846', + '00847', + '00848', + '00849', + '00850', + '00851', + '00852', + '00853', + '00854', + '00855', + '00856', + '00857', + '00858', + '00859', + '00860', + '00861', + '00862', + '00863', + '00864', + '00865', + '00866', + '00867', + '00868', + '00869', + '00870', + '00871', + '00872', + '00873', + '00874', + '00875', + '00876', + '00877', + '00878', + '00879', + '00880', + '00881', + '00882', + '00883', + '00884', + '00885', + '00886', + '00887', + '00888', + '00889', + '00890', + '00891', + '00892', + '00893', + '00894', + '00895', + '00896', + '00897', + '00898', + '00899', + '00900', + '00901', + '00902', + '00903', + '00904', + '00905', + '00906', + '00907', + '00908', + '00909', + '00910', + '00911', + '00912', + '00913', + '00914', + '00915', + '00916', + '00917', + '00918', + '00919', + '00920', + '00921', + '00922', + '00923', + '00924', + '00925', + '00926', + '00927', + '00928', + '00929', + '00930', + '00931', + '00932', + '00933', + '00934', + '00935', + '00936', + '00937', + '00938', + '00939', + '00940', + '00941', + '00942', + '00943', + '00944', + '00945', + '00946', + '00947', + '00948', + '00949', + '00950', + '00951', + '00952', + '00953', + '00954', + '00955', + '00956', + '00957', + '00958', + '00959', + '00960', + '00961', + '00962', + '00963', + '00964', + '00965', + '00966', + '00967', + '00968', + '00969', + '00970', + '00971', + '00972', + '00973', + '00974', + '00975', + '00976', + '00977', + '00978', + '00979', + '00980', + '00981', + '00982', + '00983', + '00984', + '00985', + '00986', + '00987', + '00988', + '00989', + '00990', + '00991', + '00992', + '00993', + '00994', + '00995', + '00996', + '00997', + '00998', + '00999', + '01000', + '01001', + '01002', + '01003', + '01004', + '01005', + '01006', + '01007', + '01008', + '01009', + '01010', + '01011', + '01012', + '01013', + '01014', + '01015', + '01016', + '01017', + '01018', + '01019', + '01020', + '01021', + '01022', + '01023', + '01024', + '01025', + '01026', + '01027', + '01028', + '01029', + '01030', + '01031', + '01032', + '01033', + '01034', + '01035', + '01036', + '01037', + '01038', + '01039', + '01040', + '01041', + '01042', + '01043', + '01044', + '01045', + '01046', + '01047', + '01048', + '01049', + '01050', + '01051', + '01052', + '01053', + '01054', + '01055', + '01056', + '01057', + '01058', + '01059', + '01060', + '01061', + '01062', + '01063', + '01064', + '01065', + '01066', + '01067', + '01068', + '01069', + '01070', + '01071', + '01072', + '01073', + '01074', + '01075', + '01076', + '01077', + '01078', + '01079', + '01080', + '01081', + '01082', + '01083', + '01084', + '01085', + '01086', + '01087', + '01088', + '01089', + '01090', + '01091', + '01092', + '01093', + '01094', + '01095', + '01096', + '01097', + '01098', + '01099', + '01100', + '01101', + '01102', + '01103', + '01104', + '01105', + '01106', + '01107', + '01108', + '01109', + '01110', + '01111', + '01112', + '01113', + '01114', + '01115', + '01116', + '01117', + '01118', + '01119', + '01120', + '01121', + '01122', + '01123', + '01124', + '01125', + '01126', + '01127', + '01128', + '01129', + '01130', + '01131', + '01132', + '01133', + '01134', + '01135', + '01136', + '01137', + '01138', + '01139', + '01140', + '01141', + '01142', + '01143', + '01144', + '01145', + '01146', + '01147', + '01148', + '01149', + '01150', + '01151', + '01152', + '01153', + '01154', + '01155', + '01156', + '01157', + '01158', + '01159', + '01160', + '01161', + '01162', + '01163', + '01164', + '01165', + '01166', + '01167', + '01168', + '01169', + '01170', + '01171', + '01172', + '01173', + '01174', + '01175', + '01176', + '01177', + '01178', + '01179', + '01180', + '01181', + '01182', + '01183', + '01184', + '01185', + '01186', + '01187', + '01188', + '01189', + '01190', + '01191', + '01192', + '01193', + '01194', + '01195', + '01196', + '01197', + '01198', + '01199', + '01200', + '01201', + '01202', + '01203', + '01204', + '01205', + '01206', + '01207', + '01208', + '01209', + '01210', + '01211', + '01212', + '01213', + '01214', + '01215', + '01216', + '01217', + '01218', + '01219', + '01220', + '01221', + '01222', + '01223', + '01224', + '01225', + '01226', + '01227', + '01228', + '01229', + '01230', + '01231', + '01232', + '01233', + '01234', + '01235', + '01236', + '01237', + '01238', + '01239', + '01240', + '01241', + '01242', + '01243', + '01244', + '01245', + '01246', + '01247', + '01248', + '01249', + '01250', + '01251', + '01252', + '01253', + '01254', + '01255', + '01256', + '01257', + '01258', + '01259', + '01260', + '01261', + '01262', + '01263', + '01264', + '01265', + '01266', + '01267', + '01268', + '01269', + '01270', + '01271', + '01272', + '01273', + '01274', + '01275', + '01276', + '01277', + '01278', + '01279', + '01280', + '01281', + '01282', + '01283', + '01284', + '01285', + '01286', + '01287', + '01288', + '01289', + '01290', + '01291', + '01292', + '01293', + '01294', + '01295', + '01296', + '01297', + '01298', + '01299', + '01300', + '01301', + '01302', + '01303', + '01304', + '01305', + '01306', + '01307', + '01308', + '01309', + '01310', + '01311', + '01312', + '01313', + '01314', + '01315', + '01316', + '01317', + '01318', + '01319', + '01320', + '01321', + '01322', + '01323', + '01324', + '01325', + '01326', + '01327', + '01328', + '01329', + '01330', + '01331', + '01332', + '01333', + '01334', + '01335', + '01336', + '01337', + '01338', + '01339', + '01340', + '01341', + '01342', + '01343', + '01344', + '01345', + '01346', + '01347', + '01348', + '01349', + '01350', + '01351', + '01352', + '01353', + '01354', + '01355', + '01356', + '01357', + '01358', + '01359', + '01360', + '01361', + '01362', + '01363', + '01364', + '01365', + '01366', + '01367', + '01368', + '01369', + '01370', + '01371', + '01372', + '01373', + '01374', + '01375', + '01376', + '01377', + '01378', + '01379', + '01380', + '01381', + '01382', + '01383', + '01384', + '01385', + '01386', + '01387', + '01388', + '01389', + '01390', + '01391', + '01392', + '01393', + '01394', + '01395', + '01396', + '01397', + '01398', + '01399', + '01400', + '01401', + '01402', + '01403', + '01404', + '01405', + '01406', + '01407', + '01408', + '01409', + '01410', + '01411', + '01412', + '01413', + '01414', + '01415', + '01416', + '01417', + '01418', + '01419', + '01420', + '01421', + '01422', + '01423', + '01424', + '01425', + '01426', + '01427', + '01428', + '01429', + '01430', + '01431', + '01432', + '01433', + '01434', + '01435', + '01436', + '01437', + '01438', + '01439', + '01440', + '01441', + '01442', + '01443', + '01444', + '01445', + '01446', + '01447', + '01448', + '01449', + '01450', + '01451', + '01452', + '01453', + '01454', + '01455', + '01456', + '01457', + '01458', + '01459', + '01460', + '01461', + '01462', + '01463', + '01464', + '01465', + '01466', + '01467', + '01468', + '01469', + '01470', + '01471', + '01472', + '01473', + '01474', + '01475', + '01476', + '01477', + '01478', + '01479', + '01480', + '01481', + '01482', + '01483', + '01484', + '01485', + '01486', + '01487', + '01488', + '01489', + '01490', + '01491', + '01492', + '01493', + '01494', + '01495', + '01496', + '01497', + '01498', + '01499', + '01500', + '01501', + '01502', + '01503', + '01504', + '01505', + '01506', + '01507', + '01508', + '01509', + '01510', + '01511', + '01512', + '01513', + '01514', + '01515', + '01516', + '01517', + '01518', + '01519', + '01520', + '01521', + '01522', + '01523', + '01524', + '01525', + '01526', + '01527', + '01528', + '01529', + '01530', + '01531', + '01532', + '01533', + '01534', + '01535', + '01536', + '01537', + '01538', + '01539', + '01540', + '01541', + '01542', + '01543', + '01544', + '01545', + '01546', + '01547', + '01548', + '01549', + '01550', + '01551', + '01552', + '01553', + '01554', + '01555', + '01556', + '01557', + '01558', + '01559', + '01560', + '01561', + '01562', + '01563', + '01564', + '01565', + '01566', + '01567', + '01568', + '01569', + '01570', + '01571', + '01572', + '01573', + '01574', + '01575', + '01576', + '01577', + '01578', + '01579', + '01580', + '01581', + '01582', + '01583', + '01584', + '01585', + '01586', + '01587', + '01588', + '01589', + '01590', + '01591', + '01592', + '01593', + '01594', + '01595', + '01596', + '01597', + '01598', + '01599', + '01600', + '01601', + '01602', + '01603', + '01604', + '01605', + '01606', + '01607', + '01608', + '01609', + '01610', + '01611', + '01612', + '01613', + '01614', + '01615', + '01616', + '01617', + '01618', + '01619', + '01620', + '01621', + '01622', + '01623', + '01624', + '01625', + '01626', + '01627', + '01628', + '01629', + '01630', + '01631', + '01632', + '01633', + '01634', + '01635', + '01636', + '01637', + '01638', + '01639', + '01640', + '01641', + '01642', + '01643', + '01644', + '01645', + '01646', + '01647', + '01648', + '01649', + '01650', + '01651', + '01652', + '01653', + '01654', + '01655', + '01656', + '01657', + '01658', + '01659', + '01660', + '01661', + '01662', + '01663', + '01664', + '01665', + '01666', + '01667', + '01668', + '01669', + '01670', + '01671', + '01672', + '01673', + '01674', + '01675', + '01676', + '01677', + '01678', + '01679', + '01680', + '01681', + '01682', + '01683', + '01684', + '01685', + '01686', + '01687', + '01688', + '01689', + '01690', + '01691', + '01692', + '01693', + '01694', + '01695', + '01696', + '01697', + '01698', + '01699', + '01700', + '01701', + '01702', + '01703', + '01704', + '01705', + '01706', + '01707', + '01708', + '01709', + '01710', + '01711', + '01712', + '01713', + '01714', + '01715', + '01716', + '01717', + '01718', + '01719', + '01720', + '01721', + '01722', + '01723', + '01724', + '01725', + '01726', + '01727', + '01728', + '01729', + '01730', + '01731', + '01732', + '01733', + '01734', + '01735', + '01736', + '01737', + '01738', + '01739', + '01740', + '01741', + '01742', + '01743', + '01744', + '01745', + '01746', + '01747', + '01748', + '01749', + '01750', + '01751', + '01752', + '01753', + '01754', + '01755', + '01756', + '01757', + '01758', + '01759', + '01760', + '01761', + '01762', + '01763', + '01764', + '01765', + '01766', + '01767', + '01768', + '01769', + '01770', + '01771', + '01772', + '01773', + '01774', + '01775', + '01776', + '01777', + '01778', + '01779', + '01780', + '01781', + '01782', + '01783', + '01784', + '01785', + '01786', + '01787', + '01788', + '01789', + '01790', + '01791', + '01792', + '01793', + '01794', + '01795', + '01796', + '01797', + '01798', + '01799', + '01800', + '01801', + '01802', + '01803', + '01804', + '01805', + '01806', + '01807', + '01808', + '01809', + '01810', + '01811', + '01812', + '01813', + '01814', + '01815', + '01816', + '01817', + '01818', + '01819', + '01820', + '01821', + '01822', + '01823', + '01824', + '01825', + '01826', + '01827', + '01828', + '01829', + '01830', + '01831', + '01832', + '01833', + '01834', + '01835', + '01836', + '01837', + '01838', + '01839', + '01840', + '01841', + '01842', + '01843', + '01844', + '01845', + '01846', + '01847', + '01848', + '01849', + '01850', + '01851', + '01852', + '01853', + '01854', + '01855', + '01856', + '01857', + '01858', + '01859', + '01860', + '01861', + '01862', + '01863', + '01864', + '01865', + '01866', + '01867', + '01868', + '01869', + '01870', + '01871', + '01872', + '01873', + '01874', + '01875', + '01876', + '01877', + '01878', + '01879', + '01880', + '01881', + '01882', + '01883', + '01884', + '01885', + '01886', + '01887', + '01888', + '01889', + '01890', + '01891', + '01892', + '01893', + '01894', + '01895', + '01896', + '01897', + '01898', + '01899', + '01900', + '01901', + '01902', + '01903', + '01904', + '01905', + '01906', + '01907', + '01908', + '01909', + '01910', + '01911', + '01912', + '01913', + '01914', + '01915', + '01916', + '01917', + '01918', + '01919', + '01920', + '01921', + '01922', + '01923', + '01924', + '01925', + '01926', + '01927', + '01928', + '01929', + '01930', + '01931', + '01932', + '01933', + '01934', + '01935', + '01936', + '01937', + '01938', + '01939', + '01940', + '01941', + '01942', + '01943', + '01944', + '01945', + '01946', + '01947', + '01948', + '01949', + '01950', + '01951', + '01952', + '01953', + '01954', + '01955', + '01956', + '01957', + '01958', + '01959', + '01960', + '01961', + '01962', + '01963', + '01964', + '01965', + '01966', + '01967', + '01968', + '01969', + '01970', + '01971', + '01972', + '01973', + '01974', + '01975', + '01976', + '01977', + '01978', + '01979', + '01980', + '01981', + '01982', + '01983', + '01984', + '01985', + '01986', + '01987', + '01988', + '01989', + '01990', + '01991', + '01992', + '01993', + '01994', + '01995', + '01996', + '01997', + '01998', + '01999', + '02000', + '02001', + '02002', + '02003', + '02004', + '02005', + '02006', + '02007', + '02008', + '02009', + '02010', + '02011', + '02012', + '02013', + '02014', + '02015', + '02016', + '02017', + '02018', + '02019', + '02020', + '02021', + '02022', + '02023', + '02024', + '02025', + '02026', + '02027', + '02028', + '02029', + '02030', + '02031', + '02032', + '02033', + '02034', + '02035', + '02036', + '02037', + '02038', + '02039', + '02040', + '02041', + '02042', + '02043', + '02044', + '02045', + '02046', + '02047', + '02048', + '02049', + '02050', + '02051', + '02052', + '02053', + '02054', + '02055', + '02056', + '02057', + '02058', + '02059', + '02060', + '02061', + '02062', + '02063', + '02064', + '02065', + '02066', + '02067', + '02068', + '02069', + '02070', + '02071', + '02072', + '02073', + '02074', + '02075', + '02076', + '02077', + '02078', + '02079', + '02080', + '02081', + '02082', + '02083', + '02084', + '02085', + '02086', + '02087', + '02088', + '02089', + '02090', + '02091', + '02092', + '02093', + '02094', + '02095', + '02096', + '02097', + '02098', + '02099', + '02100', + '02101', + '02102', + '02103', + '02104', + '02105', + '02106', + '02107', + '02108', + '02109', + '02110', + '02111', + '02112', + '02113', + '02114', + '02115', + '02116', + '02117', + '02118', + '02119', + '02120', + '02121', + '02122', + '02123', + '02124', + '02125', + '02126', + '02127', + '02128', + '02129', + '02130', + '02131', + '02132', + '02133', + '02134', + '02135', + '02136', + '02137', + '02138', + '02139', + '02140', + '02141', + '02142', + '02143', + '02144', + '02145', + '02146', + '02147', + '02148', + '02149', + '02150', + '02151', + '02152', + '02153', + '02154', + '02155', + '02156', + '02157', + '02158', + '02159', + '02160', + '02161', + '02162', + '02163', + '02164', + '02165', + '02166', + '02167', + '02168', + '02169', + '02170', + '02171', + '02172', + '02173', + '02174', + '02175', + '02176', + '02177', + '02178', + '02179', + '02180', + '02181', + '02182', + '02183', + '02184', + '02185', + '02186', + '02187', + '02188', + '02189', + '02190', + '02191', + '02192', + '02193', + '02194', + '02195', + '02196', + '02197', + '02198', + '02199', + '02200', + '02201', + '02202', + '02203', + '02204', + '02205', + '02206', + '02207', + '02208', + '02209', + '02210', + '02211', + '02212', + '02213', + '02214', + '02215', + '02216', + '02217', + '02218', + '02219', + '02220', + '02221', + '02222', + '02223', + '02224', + '02225', + '02226', + '02227', + '02228', + '02229', + '02230', + '02231', + '02232', + '02233', + '02234', + '02235', + '02236', + '02237', + '02238', + '02239', + '02240', + '02241', + '02242', + '02243', + '02244', + '02245', + '02246', + '02247', + '02248', + '02249', + '02250', + '02251', + '02252', + '02253', + '02254', + '02255', + '02256', + '02257', + '02258', + '02259', + '02260', + '02261', + '02262', + '02263', + '02264', + '02265', + '02266', + '02267', + '02268', + '02269', + '02270', + '02271', + '02272', + '02273', + '02274', + '02275', + '02276', + '02277', + '02278', + '02279', + '02280', + '02281', + '02282', + '02283', + '02284', + '02285', + '02286', + '02287', + '02288', + '02289', + '02290', + '02291', + '02292', + '02293', + '02294', + '02295', + '02296', + '02297', + '02298', + '02299', + '02300', + '02301', + '02302', + '02303', + '02304', + '02305', + '02306', + '02307', + '02308', + '02309', + '02310', + '02311', + '02312', + '02313', + '02314', + '02315', + '02316', + '02317', + '02318', + '02319', + '02320', + '02321', + '02322', + '02323', + '02324', + '02325', + '02326', + '02327', + '02328', + '02329', + '02330', + '02331', + '02332', + '02333', + '02334', + '02335', + '02336', + '02337', + '02338', + '02339', + '02340', + '02341', + '02342', + '02343', + '02344', + '02345', + '02346', + '02347', + '02348', + '02349', + '02350', + '02351', + '02352', + '02353', + '02354', + '02355', + '02356', + '02357', + '02358', + '02359', + '02360', + '02361', + '02362', + '02363', + '02364', + '02365', + '02366', + '02367', + '02368', + '02369', + '02370', + '02371', + '02372', + '02373', + '02374', + '02375', + '02376', + '02377', + '02378', + '02379', + '02380', + '02381', + '02382', + '02383', + '02384', + '02385', + '02386', + '02387', + '02388', + '02389', + '02390', + '02391', + '02392', + '02393', + '02394', + '02395', + '02396', + '02397', + '02398', + '02399', + '02400', + '02401', + '02402', + '02403', + '02404', + '02405', + '02406', + '02407', + '02408', + '02409', + '02410', + '02411', + '02412', + '02413', + '02414', + '02415', + '02416', + '02417', + '02418', + '02419', + '02420', + '02421', + '02422', + '02423', + '02424', + '02425', + '02426', + '02427', + '02428', + '02429', + '02430', + '02431', + '02432', + '02433', + '02434', + '02435', + '02436', + '02437', + '02438', + '02439', + '02440', + '02441', + '02442', + '02443', + '02444', + '02445', + '02446', + '02447', + '02448', + '02449', + '02450', + '02451', + '02452', + '02453', + '02454', + '02455', + '02456', + '02457', + '02458', + '02459', + '02460', + '02461', + '02462', + '02463', + '02464', + '02465', + '02466', + '02467', + '02468', + '02469', + '02470', + '02471', + '02472', + '02473', + '02474', + '02475', + '02476', + '02477', + '02478', + '02479', + '02480', + '02481', + '02482', + '02483', + '02484', + '02485', + '02486', + '02487', + '02488', + '02489', + '02490', + '02491', + '02492', + '02493', + '02494', + '02495', + '02496', + '02497', + '02498', + '02499', + '02500', + '02501', + '02502', + '02503', + '02504', + '02505', + '02506', + '02507', + '02508', + '02509', + '02510', + '02511', + '02512', + '02513', + '02514', + '02515', + '02516', + '02517', + '02518', + '02519', + '02520', + '02521', + '02522', + '02523', + '02524', + '02525', + '02526', + '02527', + '02528', + '02529', + '02530', + '02531', + '02532', + '02533', + '02534', + '02535', + '02536', + '02537', + '02538', + '02539', + '02540', + '02541', + '02542', + '02543', + '02544', + '02545', + '02546', + '02547', + '02548', + '02549', + '02550', + '02551', + '02552', + '02553', + '02554', + '02555', + '02556', + '02557', + '02558', + '02559', + '02560', + '02561', + '02562', + '02563', + '02564', + '02565', + '02566', + '02567', + '02568', + '02569', + '02570', + '02571', + '02572', + '02573', + '02574', + '02575', + '02576', + '02577', + '02578', + '02579', + '02580', + '02581', + '02582', + '02583', + '02584', + '02585', + '02586', + '02587', + '02588', + '02589', + '02590', + '02591', + '02592', + '02593', + '02594', + '02595', + '02596', + '02597', + '02598', + '02599', + '02600', + '02601', + '02602', + '02603', + '02604', + '02605', + '02606', + '02607', + '02608', + '02609', + '02610', + '02611', + '02612', + '02613', + '02614', + '02615', + '02616', + '02617', + '02618', + '02619', + '02620', + '02621', + '02622', + '02623', + '02624', + '02625', + '02626', + '02627', + '02628', + '02629', + '02630', + '02631', + '02632', + '02633', + '02634', + '02635', + '02636', + '02637', + '02638', + '02639', + '02640', + '02641', + '02642', + '02643', + '02644', + '02645', + '02646', + '02647', + '02648', + '02649', + '02650', + '02651', + '02652', + '02653', + '02654', + '02655', + '02656', + '02657', + '02658', + '02659', + '02660', + '02661', + '02662', + '02663', + '02664', + '02665', + '02666', + '02667', + '02668', + '02669', + '02670', + '02671', + '02672', + '02673', + '02674', + '02675', + '02676', + '02677', + '02678', + '02679', + '02680', + '02681', + '02682', + '02683', + '02684', + '02685', + '02686', + '02687', + '02688', + '02689', + '02690', + '02691', + '02692', + '02693', + '02694', + '02695', + '02696', + '02697', + '02698', + '02699', + '02700', + '02701', + '02702', + '02703', + '02704', + '02705', + '02706', + '02707', + '02708', + '02709', + '02710', + '02711', + '02712', + '02713', + '02714', + '02715', + '02716', + '02717', + '02718', + '02719', + '02720', + '02721', + '02722', + '02723', + '02724', + '02725', + '02726', + '02727', + '02728', + '02729', + '02730', + '02731', + '02732', + '02733', + '02734', + '02735', + '02736', + '02737', + '02738', + '02739', + '02740', + '02741', + '02742', + '02743', + '02744', + '02745', + '02746', + '02747', + '02748', + '02749', + '02750', + '02751', + '02752', + '02753', + '02754', + '02755', + '02756', + '02757', + '02758', + '02759', + '02760', + '02761', + '02762', + '02763', + '02764', + '02765', + '02766', + '02767', + '02768', + '02769', + '02770', + '02771', + '02772', + '02773', + '02774', + '02775', + '02776', + '02777', + '02778', + '02779', + '02780', + '02781', + '02782', + '02783', + '02784', + '02785', + '02786', + '02787', + '02788', + '02789', + '02790', + '02791', + '02792', + '02793', + '02794', + '02795', + '02796', + '02797', + '02798', + '02799', + '02800', + '02801', + '02802', + '02803', + '02804', + '02805', + '02806', + '02807', + '02808', + '02809', + '02810', + '02811', + '02812', + '02813', + '02814', + '02815', + '02816', + '02817', + '02818', + '02819', + '02820', + '02821', + '02822', + '02823', + '02824', + '02825', + '02826', + '02827', + '02828', + '02829', + '02830', + '02831', + '02832', + '02833', + '02834', + '02835', + '02836', + '02837', + '02838', + '02839', + '02840', + '02841', + '02842', + '02843', + '02844', + '02845', + '02846', + '02847', + '02848', + '02849', + '02850', + '02851', + '02852', + '02853', + '02854', + '02855', + '02856', + '02857', + '02858', + '02859', + '02860', + '02861', + '02862', + '02863', + '02864', + '02865', + '02866', + '02867', + '02868', + '02869', + '02870', + '02871', + '02872', + '02873', + '02874', + '02875', + '02876', + '02877', + '02878', + '02879', + '02880', + '02881', + '02882', + '02883', + '02884', + '02885', + '02886', + '02887', + '02888', + '02889', + '02890', + '02891', + '02892', + '02893', + '02894', + '02895', + '02896', + '02897', + '02898', + '02899', + '02900', + '02901', + '02902', + '02903', + '02904', + '02905', + '02906', + '02907', + '02908', + '02909', + '02910', + '02911', + '02912', + '02913', + '02914', + '02915', + '02916', + '02917', + '02918', + '02919', + '02920', + '02921', + '02922', + '02923', + '02924', + '02925', + '02926', + '02927', + '02928', + '02929', + '02930', + '02931', + '02932', + '02933', + '02934', + '02935', + '02936', + '02937', + '02938', + '02939', + '02940', + '02941', + '02942', + '02943', + '02944', + '02945', + '02946', + '02947', + '02948', + '02949', + '02950', + '02951', + '02952', + '02953', + '02954', + '02955', + '02956', + '02957', + '02958', + '02959', + '02960', + '02961', + '02962', + '02963', + '02964', + '02965', + '02966', + '02967', + '02968', + '02969', + '02970', + '02971', + '02972', + '02973', + '02974', + '02975', + '02976', + '02977', + '02978', + '02979', + '02980', + '02981', + '02982', + '02983', + '02984', + '02985', + '02986', + '02987', + '02988', + '02989', + '02990', + '02991', + '02992', + '02993', + '02994', + '02995', + '02996', + '02997', + '02998', + '02999', + '03000', + '03001', + '03002', + '03003', + '03004', + '03005', + '03006', + '03007', + '03008', + '03009', + '03010', + '03011', + '03012', + '03013', + '03014', + '03015', + '03016', + '03017', + '03018', + '03019', + '03020', + '03021', + '03022', + '03023', + '03024', + '03025', + '03026', + '03027', + '03028', + '03029', + '03030', + '03031', + '03032', + '03033', + '03034', + '03035', + '03036', + '03037', + '03038', + '03039', + '03040', + '03041', + '03042', + '03043', + '03044', + '03045', + '03046', + '03047', + '03048', + '03049', + '03050', + '03051', + '03052', + '03053', + '03054', + '03055', + '03056', + '03057', + '03058', + '03059', + '03060', + '03061', + '03062', + '03063', + '03064', + '03065', + '03066', + '03067', + '03068', + '03069', + '03070', + '03071', + '03072', + '03073', + '03074', + '03075', + '03076', + '03077', + '03078', + '03079', + '03080', + '03081', + '03082', + '03083', + '03084', + '03085', + '03086', + '03087', + '03088', + '03089', + '03090', + '03091', + '03092', + '03093', + '03094', + '03095', + '03096', + '03097', + '03098', + '03099', + '03100', + '03101', + '03102', + '03103', + '03104', + '03105', + '03106', + '03107', + '03108', + '03109', + '03110', + '03111', + '03112', + '03113', + '03114', + '03115', + '03116', + '03117', + '03118', + '03119', + '03120', + '03121', + '03122', + '03123', + '03124', + '03125', + '03126', + '03127', + '03128', + '03129', + '03130', + '03131', + '03132', + '03133', + '03134', + '03135', + '03136', + '03137', + '03138', + '03139', + '03140', + '03141', + '03142', + '03143', + '03144', + '03145', + '03146', + '03147', + '03148', + '03149', + '03150', + '03151', + '03152', + '03153', + '03154', + '03155', + '03156', + '03157', + '03158', + '03159', + '03160', + '03161', + '03162', + '03163', + '03164', + '03165', + '03166', + '03167', + '03168', + '03169', + '03170', + '03171', + '03172', + '03173', + '03174', + '03175', + '03176', + '03177', + '03178', + '03179', + '03180', + '03181', + '03182', + '03183', + '03184', + '03185', + '03186', + '03187', + '03188', + '03189', + '03190', + '03191', + '03192', + '03193', + '03194', + '03195', + '03196', + '03197', + '03198', + '03199', + '03200', + '03201', + '03202', + '03203', + '03204', + '03205', + '03206', + '03207', + '03208', + '03209', + '03210', + '03211', + '03212', + '03213', + '03214', + '03215', + '03216', + '03217', + '03218', + '03219', + '03220', + '03221', + '03222', + '03223', + '03224', + '03225', + '03226', + '03227', + '03228', + '03229', + '03230', + '03231', + '03232', + '03233', + '03234', + '03235', + '03236', + '03237', + '03238', + '03239', + '03240', + '03241', + '03242', + '03243', + '03244', + '03245', + '03246', + '03247', + '03248', + '03249', + '03250', + '03251', + '03252', + '03253', + '03254', + '03255', + '03256', + '03257', + '03258', + '03259', + '03260', + '03261', + '03262', + '03263', + '03264', + '03265', + '03266', + '03267', + '03268', + '03269', + '03270', + '03271', + '03272', + '03273', + '03274', + '03275', + '03276', + '03277', + '03278', + '03279', + '03280', + '03281', + '03282', + '03283', + '03284', + '03285', + '03286', + '03287', + '03288', + '03289', + '03290', + '03291', + '03292', + '03293', + '03294', + '03295', + '03296', + '03297', + '03298', + '03299', + '03300', + '03301', + '03302', + '03303', + '03304', + '03305', + '03306', + '03307', + '03308', + '03309', + '03310', + '03311', + '03312', + '03313', + '03314', + '03315', + '03316', + '03317', + '03318', + '03319', + '03320', + '03321', + '03322', + '03323', + '03324', + '03325', + '03326', + '03327', + '03328', + '03329', + '03330', + '03331', + '03332', + '03333', + '03334', + '03335', + '03336', + '03337', + '03338', + '03339', + '03340', + '03341', + '03342', + '03343', + '03344', + '03345', + '03346', + '03347', + '03348', + '03349', + '03350', + '03351', + '03352', + '03353', + '03354', + '03355', + '03356', + '03357', + '03358', + '03359', + '03360', + '03361', + '03362', + '03363', + '03364', + '03365', + '03366', + '03367', + '03368', + '03369', + '03370', + '03371', + '03372', + '03373', + '03374', + '03375', + '03376', + '03377', + '03378', + '03379', + '03380', + '03381', + '03382', + '03383', + '03384', + '03385', + '03386', + '03387', + '03388', + '03389', + '03390', + '03391', + '03392', + '03393', + '03394', + '03395', + '03396', + '03397', + '03398', + '03399', + '03400', + '03401', + '03402', + '03403', + '03404', + '03405', + '03406', + '03407', + '03408', + '03409', + '03410', + '03411', + '03412', + '03413', + '03414', + '03415', + '03416', + '03417', + '03418', + '03419', + '03420', + '03421', + '03422', + '03423', + '03424', + '03425', + '03426', + '03427', + '03428', + '03429', + '03430', + '03431', + '03432', + '03433', + '03434', + '03435', + '03436', + '03437', + '03438', + '03439', + '03440', + '03441', + '03442', + '03443', + '03444', + '03445', + '03446', + '03447', + '03448', + '03449', + '03450', + '03451', + '03452', + '03453', + '03454', + '03455', + '03456', + '03457', + '03458', + '03459', + '03460', + '03461', + '03462', + '03463', + '03464', + '03465', + '03466', + '03467', + '03468', + '03469', + '03470', + '03471', + '03472', + '03473', + '03474', + '03475', + '03476', + '03477', + '03478', + '03479', + '03480', + '03481', + '03482', + '03483', + '03484', + '03485', + '03486', + '03487', + '03488', + '03489', + '03490', + '03491', + '03492', + '03493', + '03494', + '03495', + '03496', + '03497', + '03498', + '03499', + '03500', + '03501', + '03502', + '03503', + '03504', + '03505', + '03506', + '03507', + '03508', + '03509', + '03510', + '03511', + '03512', + '03513', + '03514', + '03515', + '03516', + '03517', + '03518', + '03519', + '03520', + '03521', + '03522', + '03523', + '03524', + '03525', + '03526', + '03527', + '03528', + '03529', + '03530', + '03531', + '03532', + '03533', + '03534', + '03535', + '03536', + '03537', + '03538', + '03539', + '03540', + '03541', + '03542', + '03543', + '03544', + '03545', + '03546', + '03547', + '03548', + '03549', + '03550', + '03551', + '03552', + '03553', + '03554', + '03555', + '03556', + '03557', + '03558', + '03559', + '03560', + '03561', + '03562', + '03563', + '03564', + '03565', + '03566', + '03567', + '03568', + '03569', + '03570', + '03571', + '03572', + '03573', + '03574', + '03575', + '03576', + '03577', + '03578', + '03579', + '03580', + '03581', + '03582', + '03583', + '03584', + '03585', + '03586', + '03587', + '03588', + '03589', + '03590', + '03591', + '03592', + '03593', + '03594', + '03595', + '03596', + '03597', + '03598', + '03599', + '03600', + '03601', + '03602', + '03603', + '03604', + '03605', + '03606', + '03607', + '03608', + '03609', + '03610', + '03611', + '03612', + '03613', + '03614', + '03615', + '03616', + '03617', + '03618', + '03619', + '03620', + '03621', + '03622', + '03623', + '03624', + '03625', + '03626', + '03627', + '03628', + '03629', + '03630', + '03631', + '03632', + '03633', + '03634', + '03635', + '03636', + '03637', + '03638', + '03639', + '03640', + '03641', + '03642', + '03643', + '03644', + '03645', + '03646', + '03647', + '03648', + '03649', + '03650', + '03651', + '03652', + '03653', + '03654', + '03655', + '03656', + '03657', + '03658', + '03659', + '03660', + '03661', + '03662', + '03663', + '03664', + '03665', + '03666', + '03667', + '03668', + '03669', + '03670', + '03671', + '03672', + '03673', + '03674', + '03675', + '03676', + '03677', + '03678', + '03679', + '03680', + '03681', + '03682', + '03683', + '03684', + '03685', + '03686', + '03687', + '03688', + '03689', + '03690', + '03691', + '03692', + '03693', + '03694', + '03695', + '03696', + '03697', + '03698', + '03699', + '03700', + '03701', + '03702', + '03703', + '03704', + '03705', + '03706', + '03707', + '03708', + '03709', + '03710', + '03711', + '03712', + '03713', + '03714', + '03715', + '03716', + '03717', + '03718', + '03719', + '03720', + '03721', + '03722', + '03723', + '03724', + '03725', + '03726', + '03727', + '03728', + '03729', + '03730', + '03731', + '03732', + '03733', + '03734', + '03735', + '03736', + '03737', + '03738', + '03739', + '03740', + '03741', + '03742', + '03743', + '03744', + '03745', + '03746', + '03747', + '03748', + '03749', + '03750', + '03751', + '03752', + '03753', + '03754', + '03755', + '03756', + '03757', + '03758', + '03759', + '03760', + '03761', + '03762', + '03763', + '03764', + '03765', + '03766', + '03767', + '03768', + '03769', + '03770', + '03771', + '03772', + '03773', + '03774', + '03775', + '03776', + '03777', + '03778', + '03779', + '03780', + '03781', + '03782', + '03783', + '03784', + '03785', + '03786', + '03787', + '03788', + '03789', + '03790', + '03791', + '03792', + '03793', + '03794', + '03795', + '03796', + '03797', + '03798', + '03799', + '03800', + '03801', + '03802', + '03803', + '03804', + '03805', + '03806', + '03807', + '03808', + '03809', + '03810', + '03811', + '03812', + '03813', + '03814', + '03815', + '03816', + '03817', + '03818', + '03819', + '03820', + '03821', + '03822', + '03823', + '03824', + '03825', + '03826', + '03827', + '03828', + '03829', + '03830', + '03831', + '03832', + '03833', + '03834', + '03835', + '03836', + '03837', + '03838', + '03839', + '03840', + '03841', + '03842', + '03843', + '03844', + '03845', + '03846', + '03847', + '03848', + '03849', + '03850', + '03851', + '03852', + '03853', + '03854', + '03855', + '03856', + '03857', + '03858', + '03859', + '03860', + '03861', + '03862', + '03863', + '03864', + '03865', + '03866', + '03867', + '03868', + '03869', + '03870', + '03871', + '03872', + '03873', + '03874', + '03875', + '03876', + '03877', + '03878', + '03879', + '03880', + '03881', + '03882', + '03883', + '03884', + '03885', + '03886', + '03887', + '03888', + '03889', + '03890', + '03891', + '03892', + '03893', + '03894', + '03895', + '03896', + '03897', + '03898', + '03899', + '03900', + '03901', + '03902', + '03903', + '03904', + '03905', + '03906', + '03907', + '03908', + '03909', + '03910', + '03911', + '03912', + '03913', + '03914', + '03915', + '03916', + '03917', + '03918', + '03919', + '03920', + '03921', + '03922', + '03923', + '03924', + '03925', + '03926', + '03927', + '03928', + '03929', + '03930', + '03931', + '03932', + '03933', + '03934', + '03935', + '03936', + '03937', + '03938', + '03939', + '03940', + '03941', + '03942', + '03943', + '03944', + '03945', + '03946', + '03947', + '03948', + '03949', + '03950', + '03951', + '03952', + '03953', + '03954', + '03955', + '03956', + '03957', + '03958', + '03959', + '03960', + '03961', + '03962', + '03963', + '03964', + '03965', + '03966', + '03967', + '03968', + '03969', + '03970', + '03971', + '03972', + '03973', + '03974', + '03975', + '03976', + '03977', + '03978', + '03979', + '03980', + '03981', + '03982', + '03983', + '03984', + '03985', + '03986', + '03987', + '03988', + '03989', + '03990', + '03991', + '03992', + '03993', + '03994', + '03995', + '03996', + '03997', + '03998', + '03999', + '04000', + '04001', + '04002', + '04003', + '04004', + '04005', + '04006', + '04007', + '04008', + '04009', + '04010', + '04011', + '04012', + '04013', + '04014', + '04015', + '04016', + '04017', + '04018', + '04019', + '04020', + '04021', + '04022', + '04023', + '04024', + '04025', + '04026', + '04027', + '04028', + '04029', + '04030', + '04031', + '04032', + '04033', + '04034', + '04035', + '04036', + '04037', + '04038', + '04039', + '04040', + '04041', + '04042', + '04043', + '04044', + '04045', + '04046', + '04047', + '04048', + '04049', + '04050', + '04051', + '04052', + '04053', + '04054', + '04055', + '04056', + '04057', + '04058', + '04059', + '04060', + '04061', + '04062', + '04063', + '04064', + '04065', + '04066', + '04067', + '04068', + '04069', + '04070', + '04071', + '04072', + '04073', + '04074', + '04075', + '04076', + '04077', + '04078', + '04079', + '04080', + '04081', + '04082', + '04083', + '04084', + '04085', + '04086', + '04087', + '04088', + '04089', + '04090', + '04091', + '04092', + '04093', + '04094', + '04095', + '04096', + '04097', + '04098', + '04099', + '04100', + '04101', + '04102', + '04103', + '04104', + '04105', + '04106', + '04107', + '04108', + '04109', + '04110', + '04111', + '04112', + '04113', + '04114', + '04115', + '04116', + '04117', + '04118', + '04119', + '04120', + '04121', + '04122', + '04123', + '04124', + '04125', + '04126', + '04127', + '04128', + '04129', + '04130', + '04131', + '04132', + '04133', + '04134', + '04135', + '04136', + '04137', + '04138', + '04139', + '04140', + '04141', + '04142', + '04143', + '04144', + '04145', + '04146', + '04147', + '04148', + '04149', + '04150', + '04151', + '04152', + '04153', + '04154', + '04155', + '04156', + '04157', + '04158', + '04159', + '04160', + '04161', + '04162', + '04163', + '04164', + '04165', + '04166', + '04167', + '04168', + '04169', + '04170', + '04171', + '04172', + '04173', + '04174', + '04175', + '04176', + '04177', + '04178', + '04179', + '04180', + '04181', + '04182', + '04183', + '04184', + '04185', + '04186', + '04187', + '04188', + '04189', + '04190', + '04191', + '04192', + '04193', + '04194', + '04195', + '04196', + '04197', + '04198', + '04199', + '04200', + '04201', + '04202', + '04203', + '04204', + '04205', + '04206', + '04207', + '04208', + '04209', + '04210', + '04211', + '04212', + '04213', + '04214', + '04215', + '04216', + '04217', + '04218', + '04219', + '04220', + '04221', + '04222', + '04223', + '04224', + '04225', + '04226', + '04227', + '04228', + '04229', + '04230', + '04231', + '04232', + '04233', + '04234', + '04235', + '04236', + '04237', + '04238', + '04239', + '04240', + '04241', + '04242', + '04243', + '04244', + '04245', + '04246', + '04247', + '04248', + '04249', + '04250', + '04251', + '04252', + '04253', + '04254', + '04255', + '04256', + '04257', + '04258', + '04259', + '04260', + '04261', + '04262', + '04263', + '04264', + '04265', + '04266', + '04267', + '04268', + '04269', + '04270', + '04271', + '04272', + '04273', + '04274', + '04275', + '04276', + '04277', + '04278', + '04279', + '04280', + '04281', + '04282', + '04283', + '04284', + '04285', + '04286', + '04287', + '04288', + '04289', + '04290', + '04291', + '04292', + '04293', + '04294', + '04295', + '04296', + '04297', + '04298', + '04299', + '04300', + '04301', + '04302', + '04303', + '04304', + '04305', + '04306', + '04307', + '04308', + '04309', + '04310', + '04311', + '04312', + '04313', + '04314', + '04315', + '04316', + '04317', + '04318', + '04319', + '04320', + '04321', + '04322', + '04323', + '04324', + '04325', + '04326', + '04327', + '04328', + '04329', + '04330', + '04331', + '04332', + '04333', + '04334', + '04335', + '04336', + '04337', + '04338', + '04339', + '04340', + '04341', + '04342', + '04343', + '04344', + '04345', + '04346', + '04347', + '04348', + '04349', + '04350', + '04351', + '04352', + '04353', + '04354', + '04355', + '04356', + '04357', + '04358', + '04359', + '04360', + '04361', + '04362', + '04363', + '04364', + '04365', + '04366', + '04367', + '04368', + '04369', + '04370', + '04371', + '04372', + '04373', + '04374', + '04375', + '04376', + '04377', + '04378', + '04379', + '04380', + '04381', + '04382', + '04383', + '04384', + '04385', + '04386', + '04387', + '04388', + '04389', + '04390', + '04391', + '04392', + '04393', + '04394', + '04395', + '04396', + '04397', + '04398', + '04399', + '04400', + '04401', + '04402', + '04403', + '04404', + '04405', + '04406', + '04407', + '04408', + '04409', + '04410', + '04411', + '04412', + '04413', + '04414', + '04415', + '04416', + '04417', + '04418', + '04419', + '04420', + '04421', + '04422', + '04423', + '04424', + '04425', + '04426', + '04427', + '04428', + '04429', + '04430', + '04431', + '04432', + '04433', + '04434', + '04435', + '04436', + '04437', + '04438', + '04439', + '04440', + '04441', + '04442', + '04443', + '04444', + '04445', + '04446', + '04447', + '04448', + '04449', + '04450', + '04451', + '04452', + '04453', + '04454', + '04455', + '04456', + '04457', + '04458', + '04459', + '04460', + '04461', + '04462', + '04463', + '04464', + '04465', + '04466', + '04467', + '04468', + '04469', + '04470', + '04471', + '04472', + '04473', + '04474', + '04475', + '04476', + '04477', + '04478', + '04479', + '04480', + '04481', + '04482', + '04483', + '04484', + '04485', + '04486', + '04487', + '04488', + '04489', + '04490', + '04491', + '04492', + '04493', + '04494', + '04495', + '04496', + '04497', + '04498', + '04499', + '04500', + '04501', + '04502', + '04503', + '04504', + '04505', + '04506', + '04507', + '04508', + '04509', + '04510', + '04511', + '04512', + '04513', + '04514', + '04515', + '04516', + '04517', + '04518', + '04519', + '04520', + '04521', + '04522', + '04523', + '04524', + '04525', + '04526', + '04527', + '04528', + '04529', + '04530', + '04531', + '04532', + '04533', + '04534', + '04535', + '04536', + '04537', + '04538', + '04539', + '04540', + '04541', + '04542', + '04543', + '04544', + '04545', + '04546', + '04547', + '04548', + '04549', + '04550', + '04551', + '04552', + '04553', + '04554', + '04555', + '04556', + '04557', + '04558', + '04559', + '04560', + '04561', + '04562', + '04563', + '04564', + '04565', + '04566', + '04567', + '04568', + '04569', + '04570', + '04571', + '04572', + '04573', + '04574', + '04575', + '04576', + '04577', + '04578', + '04579', + '04580', + '04581', + '04582', + '04583', + '04584', + '04585', + '04586', + '04587', + '04588', + '04589', + '04590', + '04591', + '04592', + '04593', + '04594', + '04595', + '04596', + '04597', + '04598', + '04599', + '04600', + '04601', + '04602', + '04603', + '04604', + '04605', + '04606', + '04607', + '04608', + '04609', + '04610', + '04611', + '04612', + '04613', + '04614', + '04615', + '04616', + '04617', + '04618', + '04619', + '04620', + '04621', + '04622', + '04623', + '04624', + '04625', + '04626', + '04627', + '04628', + '04629', + '04630', + '04631', + '04632', + '04633', + '04634', + '04635', + '04636', + '04637', + '04638', + '04639', + '04640', + '04641', + '04642', + '04643', + '04644', + '04645', + '04646', + '04647', + '04648', + '04649', + '04650', + '04651', + '04652', + '04653', + '04654', + '04655', + '04656', + '04657', + '04658', + '04659', + '04660', + '04661', + '04662', + '04663', + '04664', + '04665', + '04666', + '04667', + '04668', + '04669', + '04670', + '04671', + '04672', + '04673', + '04674', + '04675', + '04676', + '04677', + '04678', + '04679', + '04680', + '04681', + '04682', + '04683', + '04684', + '04685', + '04686', + '04687', + '04688', + '04689', + '04690', + '04691', + '04692', + '04693', + '04694', + '04695', + '04696', + '04697', + '04698', + '04699', + '04700', + '04701', + '04702', + '04703', + '04704', + '04705', + '04706', + '04707', + '04708', + '04709', + '04710', + '04711', + '04712', + '04713', + '04714', + '04715', + '04716', + '04717', + '04718', + '04719', + '04720', + '04721', + '04722', + '04723', + '04724', + '04725', + '04726', + '04727', + '04728', + '04729', + '04730', + '04731', + '04732', + '04733', + '04734', + '04735', + '04736', + '04737', + '04738', + '04739', + '04740', + '04741', + '04742', + '04743', + '04744', + '04745', + '04746', + '04747', + '04748', + '04749', + '04750', + '04751', + '04752', + '04753', + '04754', + '04755', + '04756', + '04757', + '04758', + '04759', + '04760', + '04761', + '04762', + '04763', + '04764', + '04765', + '04766', + '04767', + '04768', + '04769', + '04770', + '04771', + '04772', + '04773', + '04774', + '04775', + '04776', + '04777', + '04778', + '04779', + '04780', + '04781', + '04782', + '04783', + '04784', + '04785', + '04786', + '04787', + '04788', + '04789', + '04790', + '04791', + '04792', + '04793', + '04794', + '04795', + '04796', + '04797', + '04798', + '04799', + '04800', + '04801', + '04802', + '04803', + '04804', + '04805', + '04806', + '04807', + '04808', + '04809', + '04810', + '04811', + '04812', + '04813', + '04814', + '04815', + '04816', + '04817', + '04818', + '04819', + '04820', + '04821', + '04822', + '04823', + '04824', + '04825', + '04826', + '04827', + '04828', + '04829', + '04830', + '04831', + '04832', + '04833', + '04834', + '04835', + '04836', + '04837', + '04838', + '04839', + '04840', + '04841', + '04842', + '04843', + '04844', + '04845', + '04846', + '04847', + '04848', + '04849', + '04850', + '04851', + '04852', + '04853', + '04854', + '04855', + '04856', + '04857', + '04858', + '04859', + '04860', + '04861', + '04862', + '04863', + '04864', + '04865', + '04866', + '04867', + '04868', + '04869', + '04870', + '04871', + '04872', + '04873', + '04874', + '04875', + '04876', + '04877', + '04878', + '04879', + '04880', + '04881', + '04882', + '04883', + '04884', + '04885', + '04886', + '04887', + '04888', + '04889', + '04890', + '04891', + '04892', + '04893', + '04894', + '04895', + '04896', + '04897', + '04898', + '04899', + '04900', + '04901', + '04902', + '04903', + '04904', + '04905', + '04906', + '04907', + '04908', + '04909', + '04910', + '04911', + '04912', + '04913', + '04914', + '04915', + '04916', + '04917', + '04918', + '04919', + '04920', + '04921', + '04922', + '04923', + '04924', + '04925', + '04926', + '04927', + '04928', + '04929', + '04930', + '04931', + '04932', + '04933', + '04934', + '04935', + '04936', + '04937', + '04938', + '04939', + '04940', + '04941', + '04942', + '04943', + '04944', + '04945', + '04946', + '04947', + '04948', + '04949', + '04950', + '04951', + '04952', + '04953', + '04954', + '04955', + '04956', + '04957', + '04958', + '04959', + '04960', + '04961', + '04962', + '04963', + '04964', + '04965', + '04966', + '04967', + '04968', + '04969', + '04970', + '04971', + '04972', + '04973', + '04974', + '04975', + '04976', + '04977', + '04978', + '04979', + '04980', + '04981', + '04982', + '04983', + '04984', + '04985', + '04986', + '04987', + '04988', + '04989', + '04990', + '04991', + '04992', + '04993', + '04994', + '04995', + '04996', + '04997', + '04998', + '04999', + '05000']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-TEST-last-affected-01', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'is_fixed': False, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['https://osv-test/repo/url'], + 'public': True, + 'purl': [], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '01', + 'affected', + 'affected-01', + 'git', + 'https', + 'https://osv-test/repo/url', + 'last', + 'last-affected', + 'last-affected-01', + 'osv', + 'osv-test', + 'osv-test-last', + 'osv-test-last-affected', + 'osv-test-last-affected-01', + 'osv-test/repo/url', + 'repo', + 'test', + 'test-last', + 'test-last-affected', + 'test-last-affected-01', + 'url'], + 'search_tags': ['https://osv-test/repo/url', 'osv-test-last-affected-01'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:OSV-TEST-last-affected-01.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_last_affected_git.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_last_affected_git.txt new file mode 100644 index 00000000000..f3b59017be9 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_last_affected_git.txt @@ -0,0 +1,66 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '0-2'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': '', + 'name': '', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'last_affected', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': ['v0.1.1', 'v0.2']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-TEST-last-affected-01', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'is_fixed': False, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': [], + 'public': True, + 'purl': [], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '01', + 'affected', + 'affected-01', + 'git', + 'https://osv-test/repo/url', + 'last', + 'last-affected', + 'last-affected-01', + 'osv', + 'osv-test', + 'osv-test-last', + 'osv-test-last-affected', + 'osv-test-last-affected-01', + 'osv-test/repo/url', + 'repo', + 'test', + 'test-last', + 'test-last-affected', + 'test-last-affected-01', + 'url'], + 'search_tags': ['osv-test-last-affected-01'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:OSV-TEST-last-affected-01.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi.txt new file mode 100644 index 00000000000..db898e1515c --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi.txt @@ -0,0 +1,63 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'PyPI', + 'name': 'scrapy', + 'purl': 'pkg:pypi/scrapy'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '1.14.2'}, + { 'type': 'fixed', + 'value': '1.31.0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}, + { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': []}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'PYSEC-456', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'PyPI'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['scrapy'], + 'public': True, + 'purl': ['pkg:pypi/scrapy'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '456', + 'git', + 'https://osv-test/repo/url', + 'osv-test/repo/url', + 'pypi', + 'pysec', + 'pysec-456', + 'repo', + 'scrapy', + 'url'], + 'search_tags': ['pysec-456', 'scrapy'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:PYSEC-456.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability in an unnormalized package', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt new file mode 100644 index 00000000000..d97673f2dc1 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt @@ -0,0 +1 @@ +[call('projects/test-osv/topics/pypi-bridge', data=b'{"id": "PYSEC-456", "summary": "A vulnerability in an unnormalized package", "details": "Blah blah blah\\nBlah\\n", "modified": "2022-10-07T18:59:00Z", "references": [{"type": "WEB", "url": "https://ref.com/ref"}], "affected": [{"package": {"name": "scrapy", "ecosystem": "PyPI"}, "ranges": [{"type": "ECOSYSTEM", "events": [{"introduced": "1.14.2"}, {"fixed": "1.31.0"}]}, {"type": "GIT", "repo": "https://osv-test/repo/url", "events": [{"introduced": "eefe8ec3f1f90d0e684890e810f3f21e8500a4cd"}, {"fixed": "8d8242f545e9cec3e6d0d2e3f5bde8be1c659735"}]}], "versions": []}]}')] \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_pypi_pubsub_calls.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_pypi_pubsub_calls.txt new file mode 100644 index 00000000000..1180b274143 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_pypi_pubsub_calls.txt @@ -0,0 +1 @@ +[call('projects/test-osv/topics/pypi-bridge', data=b'{"id": "PYSEC-123", "summary": "A vulnerability", "details": "Blah blah blah\\nBlah\\n", "modified": "3000-01-01T00:00:00Z", "references": [{"type": "WEB", "url": "https://ref.com/ref"}], "affected": [{"package": {"name": "grpcio", "ecosystem": "PyPI"}, "ranges": [{"type": "ECOSYSTEM", "events": [{"introduced": "1.14.2"}, {"fixed": "1.31.0"}]}, {"type": "GIT", "repo": "https://osv-test/repo/url", "events": [{"introduced": "eefe8ec3f1f90d0e684890e810f3f21e8500a4cd"}, {"fixed": "8d8242f545e9cec3e6d0d2e3f5bde8be1c659735"}]}], "versions": ["1.14.2", "1.15.0", "1.15.0rc1", "1.16.0", "1.16.0rc1", "1.16.1", "1.17.0", "1.17.1", "1.18.0", "1.19.0", "1.20.0", "1.20.0rc1", "1.20.0rc2", "1.20.0rc3", "1.20.1", "1.21.0rc1", "1.21.1", "1.21.1rc1", "1.22.0", "1.22.0rc1", "1.22.1", "1.23.0", "1.23.0rc1", "1.23.1", "1.24.0", "1.24.0rc1", "1.24.1", "1.24.3", "1.25.0", "1.25.0rc1", "1.26.0", "1.26.0rc1", "1.27.0rc1", "1.27.0rc2", "1.27.1", "1.27.2", "1.28.0rc1", "1.28.0rc2", "1.28.1", "1.29.0", "1.30.0"]}]}')] \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_ubuntu_severity_type.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_ubuntu_severity_type.txt new file mode 100644 index 00000000000..07664040628 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_ubuntu_severity_type.txt @@ -0,0 +1,437 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '3.11.0-12.19', + '3.12.0-1.3', + '3.12.0-2.5', + '3.12.0-2.7', + '3.12.0-3.8', + '3.12.0-3.9', + '3.12.0-4.10', + '3.12.0-4.12', + '3.12.0-5.13', + '3.12.0-7.15', + '3.13.0-1.16', + '3.13.0-10.30', + '3.13.0-100.147', + '3.13.0-101.148', + '3.13.0-103.150', + '3.13.0-105.152', + '3.13.0-106.153', + '3.13.0-107.154', + '3.13.0-108.155', + '3.13.0-109.156', + '3.13.0-11.31', + '3.13.0-110.157', + '3.13.0-111.158', + '3.13.0-112.159', + '3.13.0-113.160', + '3.13.0-115.162', + '3.13.0-116.163', + '3.13.0-117.164', + '3.13.0-119.166', + '3.13.0-12.32', + '3.13.0-121.170', + '3.13.0-123.172', + '3.13.0-125.174', + '3.13.0-126.175', + '3.13.0-128.177', + '3.13.0-129.178', + '3.13.0-13.33', + '3.13.0-132.181', + '3.13.0-133.182', + '3.13.0-135.184', + '3.13.0-137.186', + '3.13.0-139.188', + '3.13.0-14.34', + '3.13.0-141.190', + '3.13.0-142.191', + '3.13.0-143.192', + '3.13.0-144.193', + '3.13.0-145.194', + '3.13.0-147.196', + '3.13.0-149.199', + '3.13.0-15.35', + '3.13.0-151.201', + '3.13.0-153.203', + '3.13.0-155.205', + '3.13.0-156.206', + '3.13.0-157.207', + '3.13.0-158.208', + '3.13.0-16.36', + '3.13.0-160.210', + '3.13.0-161.211', + '3.13.0-162.212', + '3.13.0-163.213', + '3.13.0-164.214', + '3.13.0-165.215', + '3.13.0-166.216', + '3.13.0-167.217', + '3.13.0-168.218', + '3.13.0-169.219', + '3.13.0-17.37', + '3.13.0-170.220', + '3.13.0-173.224', + '3.13.0-174.225', + '3.13.0-175.226', + '3.13.0-176.227', + '3.13.0-18.38', + '3.13.0-180.231', + '3.13.0-181.232', + '3.13.0-182.233', + '3.13.0-183.234', + '3.13.0-184.235', + '3.13.0-185.236', + '3.13.0-186.237', + '3.13.0-187.238', + '3.13.0-188.239', + '3.13.0-189.240', + '3.13.0-19.39', + '3.13.0-19.40', + '3.13.0-190.241', + '3.13.0-191.242', + '3.13.0-192.243', + '3.13.0-193.244', + '3.13.0-194.245', + '3.13.0-195.246', + '3.13.0-196.247', + '3.13.0-197.248', + '3.13.0-198.249', + '3.13.0-199.250', + '3.13.0-2.17', + '3.13.0-20.42', + '3.13.0-200.251', + '3.13.0-201.252', + '3.13.0-202.253', + '3.13.0-203.254', + '3.13.0-204.255', + '3.13.0-205.256', + '3.13.0-206.257', + '3.13.0-21.43', + '3.13.0-22.44', + '3.13.0-23.45', + '3.13.0-24.46', + '3.13.0-24.47', + '3.13.0-27.50', + '3.13.0-29.53', + '3.13.0-3.18', + '3.13.0-30.54', + '3.13.0-30.55', + '3.13.0-32.57', + '3.13.0-33.58', + '3.13.0-34.60', + '3.13.0-35.62', + '3.13.0-36.63', + '3.13.0-37.64', + '3.13.0-39.66', + '3.13.0-4.19', + '3.13.0-40.69', + '3.13.0-41.70', + '3.13.0-43.72', + '3.13.0-44.73', + '3.13.0-45.74', + '3.13.0-46.75', + '3.13.0-46.76', + '3.13.0-46.77', + '3.13.0-46.79', + '3.13.0-48.80', + '3.13.0-49.81', + '3.13.0-49.83', + '3.13.0-5.20', + '3.13.0-51.84', + '3.13.0-52.85', + '3.13.0-52.86', + '3.13.0-53.88', + '3.13.0-53.89', + '3.13.0-54.91', + '3.13.0-55.92', + '3.13.0-55.94', + '3.13.0-57.95', + '3.13.0-58.97', + '3.13.0-59.98', + '3.13.0-6.23', + '3.13.0-61.100', + '3.13.0-62.102', + '3.13.0-63.103', + '3.13.0-65.105', + '3.13.0-65.106', + '3.13.0-66.108', + '3.13.0-67.110', + '3.13.0-68.111', + '3.13.0-7.25', + '3.13.0-7.26', + '3.13.0-70.113', + '3.13.0-71.114', + '3.13.0-73.116', + '3.13.0-74.118', + '3.13.0-76.120', + '3.13.0-77.121', + '3.13.0-79.123', + '3.13.0-8.27', + '3.13.0-8.28', + '3.13.0-83.127', + '3.13.0-85.129', + '3.13.0-86.130', + '3.13.0-86.131', + '3.13.0-87.133', + '3.13.0-88.135', + '3.13.0-91.138', + '3.13.0-92.139', + '3.13.0-93.140', + '3.13.0-95.142', + '3.13.0-96.143', + '3.13.0-98.145'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Ubuntu:Pro:14.04:LTS', + 'name': 'linux', + 'purl': 'pkg:deb/ubuntu/linux@3.13.0-206.257?arch=source&distro=esm-infra-legacy/trusty'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '3.11.0-12.19', + '3.12.0-1.3', + '3.12.0-2.5', + '3.12.0-2.7', + '3.12.0-3.8', + '3.12.0-3.9', + '3.12.0-4.10', + '3.12.0-4.12', + '3.12.0-5.13', + '3.12.0-7.15', + '3.13.0-1.16', + '3.13.0-2.17', + '3.13.0-3.18', + '3.13.0-4.19', + '3.13.0-5.20', + '3.13.0-6.23', + '3.13.0-7.25', + '3.13.0-7.26', + '3.13.0-8.27', + '3.13.0-8.28', + '3.13.0-10.30', + '3.13.0-11.31', + '3.13.0-12.32', + '3.13.0-13.33', + '3.13.0-14.34', + '3.13.0-15.35', + '3.13.0-16.36', + '3.13.0-17.37', + '3.13.0-18.38', + '3.13.0-19.39', + '3.13.0-19.40', + '3.13.0-20.42', + '3.13.0-21.43', + '3.13.0-22.44', + '3.13.0-23.45', + '3.13.0-24.46', + '3.13.0-24.47', + '3.13.0-27.50', + '3.13.0-29.53', + '3.13.0-30.54', + '3.13.0-30.55', + '3.13.0-32.57', + '3.13.0-33.58', + '3.13.0-34.60', + '3.13.0-35.62', + '3.13.0-36.63', + '3.13.0-37.64', + '3.13.0-39.66', + '3.13.0-40.69', + '3.13.0-41.70', + '3.13.0-43.72', + '3.13.0-44.73', + '3.13.0-45.74', + '3.13.0-46.75', + '3.13.0-46.76', + '3.13.0-46.77', + '3.13.0-46.79', + '3.13.0-48.80', + '3.13.0-49.81', + '3.13.0-49.83', + '3.13.0-51.84', + '3.13.0-52.85', + '3.13.0-52.86', + '3.13.0-53.88', + '3.13.0-53.89', + '3.13.0-54.91', + '3.13.0-55.92', + '3.13.0-55.94', + '3.13.0-57.95', + '3.13.0-58.97', + '3.13.0-59.98', + '3.13.0-61.100', + '3.13.0-62.102', + '3.13.0-63.103', + '3.13.0-65.105', + '3.13.0-65.106', + '3.13.0-66.108', + '3.13.0-67.110', + '3.13.0-68.111', + '3.13.0-70.113', + '3.13.0-71.114', + '3.13.0-73.116', + '3.13.0-74.118', + '3.13.0-76.120', + '3.13.0-77.121', + '3.13.0-79.123', + '3.13.0-83.127', + '3.13.0-85.129', + '3.13.0-86.130', + '3.13.0-86.131', + '3.13.0-87.133', + '3.13.0-88.135', + '3.13.0-91.138', + '3.13.0-92.139', + '3.13.0-93.140', + '3.13.0-95.142', + '3.13.0-96.143', + '3.13.0-98.145', + '3.13.0-100.147', + '3.13.0-101.148', + '3.13.0-103.150', + '3.13.0-105.152', + '3.13.0-106.153', + '3.13.0-107.154', + '3.13.0-108.155', + '3.13.0-109.156', + '3.13.0-110.157', + '3.13.0-111.158', + '3.13.0-112.159', + '3.13.0-113.160', + '3.13.0-115.162', + '3.13.0-116.163', + '3.13.0-117.164', + '3.13.0-119.166', + '3.13.0-121.170', + '3.13.0-123.172', + '3.13.0-125.174', + '3.13.0-126.175', + '3.13.0-128.177', + '3.13.0-129.178', + '3.13.0-132.181', + '3.13.0-133.182', + '3.13.0-135.184', + '3.13.0-137.186', + '3.13.0-139.188', + '3.13.0-141.190', + '3.13.0-142.191', + '3.13.0-143.192', + '3.13.0-144.193', + '3.13.0-145.194', + '3.13.0-147.196', + '3.13.0-149.199', + '3.13.0-151.201', + '3.13.0-153.203', + '3.13.0-155.205', + '3.13.0-156.206', + '3.13.0-157.207', + '3.13.0-158.208', + '3.13.0-160.210', + '3.13.0-161.211', + '3.13.0-162.212', + '3.13.0-163.213', + '3.13.0-164.214', + '3.13.0-165.215', + '3.13.0-166.216', + '3.13.0-167.217', + '3.13.0-168.218', + '3.13.0-169.219', + '3.13.0-170.220', + '3.13.0-173.224', + '3.13.0-174.225', + '3.13.0-175.226', + '3.13.0-176.227', + '3.13.0-180.231', + '3.13.0-181.232', + '3.13.0-182.233', + '3.13.0-183.234', + '3.13.0-184.235', + '3.13.0-185.236', + '3.13.0-186.237', + '3.13.0-187.238', + '3.13.0-188.239', + '3.13.0-189.240', + '3.13.0-190.241', + '3.13.0-191.242', + '3.13.0-192.243', + '3.13.0-193.244', + '3.13.0-194.245', + '3.13.0-195.246', + '3.13.0-196.247', + '3.13.0-197.248', + '3.13.0-198.249', + '3.13.0-199.250', + '3.13.0-200.251', + '3.13.0-201.252', + '3.13.0-202.253', + '3.13.0-203.254', + '3.13.0-204.255', + '3.13.0-205.256', + '3.13.0-206.257']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'UBUNTU-CVE-2025-38094', + 'details': 'In the Linux kernel, the following vulnerability has been ' + 'resolved: net: cadence: macb: Fix a possible deadlock in ' + 'macb_halt_tx. There is a situation where after THALT is set ' + 'high, TGO stays high as well. Because jiffies are never ' + 'updated, as we are in a context with interrupts disabled, we ' + 'never exit that loop and have a deadlock. That deadlock was ' + 'noticed on a sama5d4 device that stayed locked for days. Use ' + 'retries instead of jiffies so that the timeout really works ' + 'and we do not have a deadlock anymore.', + 'ecosystem': ['Ubuntu', 'Ubuntu:14.04', 'Ubuntu:Pro:14.04:LTS'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2025, 7, 4, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': False, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['linux'], + 'public': True, + 'purl': [ 'pkg:deb/ubuntu/linux@3.13.0-206.257', + 'pkg:deb/ubuntu/linux@3.13.0-206.257?arch=source&distro=esm-infra-legacy/trusty'], + 'reference_url_types': { 'https://git.kernel.org/linus/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f': 'REPORT', + 'https://git.kernel.org/stable/c/0772a608d799ac0d127c0a36047a2725777aba9d': 'REPORT', + 'https://git.kernel.org/stable/c/1d60c0781c1bbeaa1196b0d8aad5c435f06cb7c4': 'REPORT', + 'https://git.kernel.org/stable/c/3e64d35475aa21d13dab71da51de51923c1a3a48': 'REPORT', + 'https://git.kernel.org/stable/c/64675a9c00443b2e8af42af08c38fc1b78b68ba2': 'REPORT', + 'https://git.kernel.org/stable/c/84f98955a9de0e0f591df85aa1a44f3ebcf1cb37': 'REPORT', + 'https://git.kernel.org/stable/c/aace6b63892ce8307e502a60fe2f5a4bc6e1cfe7': 'REPORT', + 'https://git.kernel.org/stable/c/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f': 'REPORT', + 'https://ubuntu.com/security/CVE-2025-38094': 'REPORT', + 'https://www.cve.org/CVERecord?id=CVE-2025-38094': 'REPORT'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '04', + '14', + '2025', + '2025-38094', + '38094', + 'cve', + 'cve-2025', + 'cve-2025-38094', + 'linux', + 'lts', + 'pro', + 'ubuntu', + 'ubuntu-cve', + 'ubuntu-cve-2025', + 'ubuntu-cve-2025-38094', + 'ubuntu:14.04', + 'ubuntu:pro:14.04:lts'], + 'search_tags': ['linux', 'ubuntu-cve-2025-38094'], + 'semver_fixed_indexes': [], + 'severities': [{'score': 'medium', 'type': 'Ubuntu'}], + 'source': 'source', + 'source_id': 'source:UBUNTU-CVE-2025-38094.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': '', + 'timestamp': DatetimeWithNanoseconds(2025, 7, 4, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': ['CVE-2025-38094'], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update.txt new file mode 100644 index 00000000000..654da618d93 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update.txt @@ -0,0 +1,70 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Go', + 'name': 'blah.com/package', + 'purl': 'pkg:golang/blah.com/package'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'type': 'introduced', + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'aliases': [], + 'credits': [ { 'contact': ['mailto:foo@bar.com'], + 'name': 'Foo bar', + 'type': None}], + 'database_specific': {'specific': 1337.0}, + 'db_id': 'OSV-123', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'Go'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['blah.com/package'], + 'public': True, + 'purl': ['pkg:golang/blah.com/package'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '123', + 'blah', + 'blah.com/package', + 'com', + 'git', + 'go', + 'https://osv-test/repo/url', + 'osv', + 'osv-123', + 'osv-test/repo/url', + 'package', + 'repo', + 'url'], + 'search_tags': ['blah.com/package', 'osv-123'], + 'semver_fixed_indexes': [], + 'severities': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L', + 'type': 'CVSS_V3'}], + 'source': 'source', + 'source_id': 'source:OSV-123.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': None, + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_add_fix.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_add_fix.txt new file mode 100644 index 00000000000..a5ae0a7faa7 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_add_fix.txt @@ -0,0 +1,67 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Go', + 'name': 'blah.com/package', + 'purl': 'pkg:golang/blah.com/package'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'type': 'introduced', + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-124', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'Go'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['blah.com/package'], + 'public': True, + 'purl': ['pkg:golang/blah.com/package'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + 'related': [], + 'search_indices': [ '124', + 'blah', + 'blah.com/package', + 'com', + 'git', + 'go', + 'https://osv-test/repo/url', + 'osv', + 'osv-124', + 'osv-test/repo/url', + 'package', + 'repo', + 'url'], + 'search_tags': ['blah.com/package', 'osv-124'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:OSV-124.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': None, + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_alpine.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_alpine.txt new file mode 100644 index 00000000000..f1001d855f0 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_alpine.txt @@ -0,0 +1,689 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.15-r0', + '10.4.17-r0', + '10.4.17-r1', + '10.4.18-r0', + '10.4.19-r0', + '10.4.21-r0', + '10.4.22-r0', + '10.4.24-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.10-r0', + '10.5.11-r0', + '10.5.11-r1', + '10.5.12-r0', + '10.5.13-r0', + '10.5.15-r0', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '10.6.3-r0', + '10.6.4-r0', + '10.6.4-r1', + '10.6.4-r2', + '10.6.7-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Alpine:v3.12', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '10.4.25-r0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.15-r0', + '10.4.17-r0', + '10.4.17-r1', + '10.4.18-r0', + '10.4.19-r0', + '10.4.21-r0', + '10.4.22-r0', + '10.4.24-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Alpine:v3.13', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '10.5.16-r0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.10-r0', + '10.5.11-r0', + '10.5.12-r0', + '10.5.13-r0', + '10.5.15-r0', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Alpine:v3.14', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '10.5.16-r0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.11-r0', + '10.5.12-r0', + '10.5.13-r0', + '10.5.15-r0', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Alpine:v3.15', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '10.6.8-r0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.11-r0', + '10.5.11-r1', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '10.6.3-r0', + '10.6.4-r0', + '10.6.4-r1', + '10.6.4-r2', + '10.6.7-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Alpine:v3.16', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '10.6.8-r0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.11-r0', + '10.5.11-r1', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '10.6.3-r0', + '10.6.4-r0', + '10.6.4-r1', + '10.6.4-r2', + '10.6.7-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'CVE-2022-27449', + 'details': 'MariaDB Server v10.9 and below was discovered to contain a ' + 'segmentation fault via the component sql/item_func.cc:148.', + 'ecosystem': [ 'Alpine', + 'Alpine:v3.12', + 'Alpine:v3.13', + 'Alpine:v3.14', + 'Alpine:v3.15', + 'Alpine:v3.16'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['mariadb'], + 'public': True, + 'purl': ['pkg:alpine/mariadb'], + 'reference_url_types': { 'https://jira.mariadb.org/browse/MDEV-28089': 'WEB', + 'https://lists.debian.org/debian-lts-announce/2022/09/msg00023.html': 'WEB', + 'https://security.netapp.com/advisory/ntap-20220526-0006/': 'ADVISORY'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '12', + '13', + '14', + '15', + '16', + '2022', + '2022-27449', + '27449', + 'alpine', + 'alpine:v3.12', + 'alpine:v3.13', + 'alpine:v3.14', + 'alpine:v3.15', + 'alpine:v3.16', + 'cve', + 'cve-2022', + 'cve-2022-27449', + 'mariadb', + 'v3'], + 'search_tags': ['cve-2022-27449', 'mariadb'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:CVE-2022-27449.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': '', + 'timestamp': DatetimeWithNanoseconds(2022, 4, 14, 13, 15, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bad_ecosystem_new.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bad_ecosystem_new.txt new file mode 100644 index 00000000000..d5828e36cba --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bad_ecosystem_new.txt @@ -0,0 +1,7 @@ +{ 'details': 'Blah blah blah\nBlah\n', + 'id': 'OSV-129', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_0.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_0.txt new file mode 100644 index 00000000000..184148e93f4 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_0.txt @@ -0,0 +1,104 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': { 'imports': [ { 'path': 'github.com/opencontainers/runc/libcontainer/apparmor', + 'symbols': [ 'ApplyProfile']}, + { 'path': 'github.com/opencontainers/runc/libcontainer/utils', + 'symbols': [ 'CloseExecFrom']}]}, + 'package': { 'ecosystem': 'Go', + 'name': 'github.com/opencontainers/runc', + 'purl': 'pkg:golang/github.com/opencontainers/runc'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '1.0.0-rc8.0.20190930145003-cad42f6e0932'}], + 'repo_url': '', + 'type': 'SEMVER'}], + 'severities': [], + 'versions': []}, + { 'database_specific': None, + 'ecosystem_specific': { 'imports': [ { 'path': 'github.com/opencontainers/selinux/go-selinux', + 'symbols': [ 'readCon', + 'writeCon']}]}, + 'package': { 'ecosystem': 'Go', + 'name': 'github.com/opencontainers/selinux', + 'purl': 'pkg:golang/github.com/opencontainers/selinux'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '1.3.1-0.20190929122143-5215b1806f52'}], + 'repo_url': '', + 'type': 'SEMVER'}], + 'severities': [], + 'versions': []}], + 'aliases': ['CVE-2019-16884', 'GHSA-fgv8-vj5c-2ppq'], + 'credits': [{'contact': [], 'name': 'Leopold Schabel', 'type': None}], + 'database_specific': {'url': 'https://pkg.go.dev/vuln/GO-2021-0085'}, + 'db_id': 'GO-2021-0085', + 'details': 'AppArmor restrictions may be bypassed due to improper ' + 'validation of mount targets, allowing a malicious image to ' + 'mount volumes over e.g. /proc.', + 'ecosystem': ['Go'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2023, 4, 3, 15, 57, 51, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': [ 'github.com/opencontainers/runc', + 'github.com/opencontainers/selinux'], + 'public': True, + 'purl': [ 'pkg:golang/github.com/opencontainers/runc', + 'pkg:golang/github.com/opencontainers/selinux'], + 'reference_url_types': { 'https://github.com/opencontainers/runc/commit/cad42f6e0932db0ce08c3a3d9e89e6063ec283e4': 'FIX', + 'https://github.com/opencontainers/runc/issues/2128': 'WEB', + 'https://github.com/opencontainers/runc/pull/2130': 'FIX', + 'https://github.com/opencontainers/selinux/commit/03b517dc4fd57245b1cf506e8ba7b817b6d309da': 'FIX'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '0085', + '16884', + '2019', + '2019-16884', + '2021', + '2021-0085', + '2ppq', + 'com', + 'cve', + 'cve-2019', + 'cve-2019-16884', + 'fgv8', + 'fgv8-vj5c', + 'fgv8-vj5c-2ppq', + 'ghsa', + 'ghsa-fgv8', + 'ghsa-fgv8-vj5c', + 'ghsa-fgv8-vj5c-2ppq', + 'github', + 'github.com/opencontainers/runc', + 'github.com/opencontainers/selinux', + 'go', + 'go-2021', + 'go-2021-0085', + 'opencontainers', + 'runc', + 'selinux', + 'vj5c', + 'vj5c-2ppq'], + 'search_tags': [ 'github.com/opencontainers/runc', + 'github.com/opencontainers/selinux', + 'go-2021-0085'], + 'semver_fixed_indexes': [ '00000001.00000000.00000000-1rc8.00000000.120190930145003-cad42f6e0932', + '00000001.00000003.00000001-00000000.120190929122143-5215b1806f52'], + 'severities': [], + 'source': 'source', + 'source_id': 'source:a/b/test.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': '', + 'timestamp': DatetimeWithNanoseconds(2021, 4, 14, 20, 4, 52, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_1.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_1.txt new file mode 100644 index 00000000000..73a984afc15 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_1.txt @@ -0,0 +1,50 @@ +{ 'affected': [], + 'affected_fuzzy': [], + 'affected_packages': [], + 'aliases': ['CVE-2019-19921'], + 'credits': [], + 'database_specific': None, + 'db_id': 'GO-2021-0087', + 'details': 'A race while mounting volumes allows a possible ' + 'symlink-exchange\n' + 'attack, allowing a user whom can start multiple containers ' + 'with\n' + 'custom volume mount configurations to escape the container.\n' + '\n', + 'ecosystem': [], + 'fixed': '', + 'has_affected': False, + 'import_last_modified': datetime.datetime(2021, 4, 14, 12, 0), + 'is_fixed': False, + 'issue_id': None, + 'last_modified': datetime.datetime(2021, 4, 14, 12, 0), + 'project': [], + 'public': True, + 'purl': [], + 'reference_url_types': { 'https://github.com/opencontainers/runc/commit/2fc03cc11c775b7a8b2e48d7ee447cb9bef32ad0': 'FIX', + 'https://github.com/opencontainers/runc/issues/2197': 'WEB', + 'https://github.com/opencontainers/runc/pull/2207': 'FIX'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '0087', + '19921', + '2019', + '2019-19921', + '2021', + '2021-0087', + 'cve', + 'cve-2019', + 'cve-2019-19921', + 'go', + 'go-2021', + 'go-2021-0087'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:a/b/test.json', + 'source_of_truth': 2, + 'status': 2, + 'summary': '', + 'timestamp': datetime.datetime(2021, 4, 14, 12, 0), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_2.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_2.txt new file mode 100644 index 00000000000..9b228142cd0 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_2.txt @@ -0,0 +1,63 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['10', '11'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': { 'severity': 'High', + 'spl': '2021-10-01', + 'type': 'EoP'}, + 'package': { 'ecosystem': 'Android', + 'name': 'Media Framework', + 'purl': None}, + 'ranges': [], + 'severities': [], + 'versions': ['10', '11']}], + 'aliases': ['CVE-2021-0483'], + 'credits': [], + 'database_specific': None, + 'db_id': 'ASB-A-153358911', + 'details': '', + 'ecosystem': ['Android'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2021, 10, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': False, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['Media Framework'], + 'public': True, + 'purl': [], + 'reference_url_types': { 'https://android.googlesource.com/platform/frameworks/av/+/084077feb6b8c961adcbe77b2bd76601ca54e534': 'FIX', + 'https://android.googlesource.com/platform/frameworks/av/+/cc2165840d524bb9553f9d73d1904633d20100a2': 'FIX', + 'https://source.android.com/security/bulletin/2021-10-01#2021-10-01-security-patch-level-vulnerability-details': 'ADVISORY'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '0483', + '153358911', + '2021', + '2021-0483', + 'a', + 'a-153358911', + 'android', + 'asb', + 'asb-a', + 'asb-a-153358911', + 'cve', + 'cve-2021', + 'cve-2021-0483', + 'framework', + 'media', + 'media framework'], + 'search_tags': ['asb-a-153358911', 'media framework'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:a/b/android-test.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'In multiple methods of AAudioService, there is a possible ' + 'use-after-free due to a race condition. This could lead to ' + 'local escalation of privilege with User execution privileges ' + 'needed. User interaction is not needed for exploitation.', + 'timestamp': DatetimeWithNanoseconds(2021, 10, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_cve.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_cve.txt new file mode 100644 index 00000000000..32722079b69 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_bucket_cve.txt @@ -0,0 +1,152 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '1-2-1', + '1-2-2', + '1-2-3', + '1-2-4', + '1-2-5', + '1-2-6', + '1-3-0', + '1-3-1'], + 'affected_packages': [ { 'database_specific': { 'vanir_signatures': [ { 'deprecated': False, + 'digest': { 'line_hashes': [ '18066036635502801806677364178756254862', + '88369412895184753394283011451803187548', + '50848458948504730426650075084385046530', + '91284993680127737564993618090545145416', + '30779278950355321333621475605602830830', + '122421578121241373365155348152646941523', + '267652210589392654099845994262755826062', + '334808111126213430220547654602188383660', + '234389204524678077984531197469034242690', + '152880517379272209571165325006789878786', + '299871312446227378724863519270618301341', + '157634544376100154879962283397081738110', + '103663099829328578689797223848801574827', + '158563421165358858389893196995983570762', + '315965584007238676040631750953088200664'], + 'threshold': 0.9}, + 'id': 'CVE-2016-15011-929806e0', + 'signature_type': 'Line', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/metadata/DigitalSignatureServiceMetadata.java'}}, + { 'deprecated': False, + 'digest': { 'line_hashes': [ '6674387965125354881111149989428882853', + '100741820504985357262218153349452233434', + '253366101641995550384755812786879052342', + '245037096886845520996519599411616661529', + '158852189579109359359946013476030639584', + '298614597347537877121532413760030558894', + '180181956682520524395173299138562004562', + '146502839243717526526406585366671557144', + '244996413515733361838850122849344525825', + '166554563875570093109470347687697544350', + '9427977046515615106319032886256396870', + '279044285883194738631442483325879094037', + '295198785562376785392477306514392217432', + '44714085523243422643465698936438435501', + '267608316591780380179772018605253867646', + '182074437577114148436758739432546664545', + '87621961972550109442760282702331746920', + '64897152403082006856773989396486955494', + '184138636401118235309885205539354874180', + '62633257528035095954429323509732904426'], + 'threshold': 0.9}, + 'id': 'CVE-2016-15011-bd561b7b', + 'signature_type': 'Line', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/SignResponseVerifier.java'}}, + { 'deprecated': False, + 'digest': { 'function_hash': '259495117689681377355427521574538727644', + 'length': 1591.0}, + 'id': 'CVE-2016-15011-d557e328', + 'signature_type': 'Function', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/metadata/DigitalSignatureServiceMetadata.java', + 'function': 'DigitalSignatureServiceMetadata'}}, + { 'deprecated': False, + 'digest': { 'function_hash': '249451297539985081987952306682300702892', + 'length': 4302.0}, + 'id': 'CVE-2016-15011-fcf07dd1', + 'signature_type': 'Function', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/SignResponseVerifier.java', + 'function': 'checkSignResponse'}}]}, + 'ecosystem_specific': None, + 'package': { 'ecosystem': '', + 'name': '', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '001ef99b0c8194468de960d007e2d82dcebc3bca'}, + { 'type': 'fixed', + 'value': 'ec4238349691ec66dd30b416ec6eaab02d722302'}], + 'repo_url': 'https://github.com/e-contract/dssp', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'dssp-1.2.1', + 'dssp-1.2.2', + 'dssp-1.2.3', + 'dssp-1.2.4', + 'dssp-1.2.5', + 'dssp-1.2.6', + 'dssp-1.3.0', + 'dssp-1.3.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'CVE-2016-15011', + 'details': 'A vulnerability classified as problematic was found in ' + 'e-Contract dssp up to 1.3.1. Affected by this vulnerability is ' + 'the function checkSignResponse of the file ' + 'dssp-client/src/main/java/be/e_contract/dssp/client/SignResponseVerifier.java. ' + 'The manipulation leads to xml external entity reference. ' + 'Upgrading to version 1.3.2 is able to address this issue. The ' + 'identifier of the patch is ' + 'ec4238349691ec66dd30b416ec6eaab02d722302. It is recommended to ' + 'upgrade the affected component. The identifier VDB-217549 was ' + 'assigned to this vulnerability.', + 'ecosystem': ['GIT'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2025, 7, 1, 21, 44, 41, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': [], + 'public': True, + 'purl': [], + 'reference_url_types': { 'https://github.com/e-Contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302': 'FIX', + 'https://github.com/e-Contract/dssp/releases/tag/dssp-1.3.2': 'ADVISORY', + 'https://vuldb.com/?ctiid.217549': 'REPORT', + 'https://vuldb.com/?id.217549': 'REPORT'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '15011', + '2016', + '2016-15011', + 'cve', + 'cve-2016', + 'cve-2016-15011', + 'dssp', + 'e-contract', + 'git', + 'github.com/e-contract/dssp', + 'https://github.com/e-contract/dssp'], + 'search_tags': ['cve-2016-15011'], + 'semver_fixed_indexes': [], + 'severities': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H', + 'type': 'CVSS_V3'}], + 'source': 'source', + 'source_id': 'source:a/b/CVE-2016-15011.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': '', + 'timestamp': DatetimeWithNanoseconds(2023, 1, 6, 10, 15, 9, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_debian.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_debian.txt new file mode 100644 index 00000000000..5aebf710c03 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_debian.txt @@ -0,0 +1,95 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '1.2.1-2.2', + '1.2.1-2.2+wheezy1', + '1.2.1-2.2+wheezy2', + '1.2.1-2.2+wheezy3~bpo60+1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Debian:7', + 'name': 'nginx', + 'purl': 'pkg:deb/debian/nginx?arch=source'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '1.2.1-2.2+wheezy3'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '1.2.1-2.2', + '1.2.1-2.2+wheezy1', + '1.2.1-2.2+wheezy2', + '1.2.1-2.2+wheezy3~bpo60+1']}], + 'aliases': ['CVE-2014-3616'], + 'credits': [], + 'database_specific': None, + 'db_id': 'DSA-3029-1', + 'details': '\n' + 'Antoine Delignat-Lavaud and Karthikeyan Bhargavan discovered ' + 'that it was\n' + 'possible to reuse cached SSL sessions in unrelated contexts, ' + 'allowing\n' + 'virtual host confusion attacks in some configurations by an ' + 'attacker in\n' + 'a privileged network position.\n' + '\n' + '\n' + 'For the stable distribution (wheezy), this problem has been ' + 'fixed in\n' + 'version 1.2.1-2.2+wheezy3.\n' + '\n' + '\n' + 'For the testing distribution (jessie), this problem has been ' + 'fixed in\n' + 'version 1.6.2-1.\n' + '\n' + '\n' + 'For the unstable distribution (sid), this problem has been ' + 'fixed in\n' + 'version 1.6.2-1.\n' + '\n' + '\n' + 'We recommend that you upgrade your nginx packages.\n' + '\n' + '\n', + 'ecosystem': ['Debian', 'Debian:7'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2014, 9, 20, 8, 18, 7, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['nginx'], + 'public': True, + 'purl': ['pkg:deb/debian/nginx', 'pkg:deb/debian/nginx?arch=source'], + 'reference_url_types': { 'https://www.debian.org/security/2014/dsa-3029': 'ADVISORY'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '1', + '2014', + '2014-3616', + '3029', + '3029-1', + '3616', + '7', + 'cve', + 'cve-2014', + 'cve-2014-3616', + 'debian', + 'debian:7', + 'dsa', + 'dsa-3029', + 'dsa-3029-1', + 'nginx'], + 'search_tags': ['dsa-3029-1', 'nginx'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:DSA-3029-1.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'nginx - security update', + 'timestamp': DatetimeWithNanoseconds(2014, 9, 20, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_last_affected.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_last_affected.txt new file mode 100644 index 00000000000..eb8631f7074 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_last_affected.txt @@ -0,0 +1,129 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '1.14.2', + '1.15.0', + '1.15.0rc1', + '1.16.0', + '1.16.0rc1', + '1.16.1', + '1.17.0', + '1.17.1', + '1.18.0', + '1.19.0', + '1.20.0', + '1.20.0rc1', + '1.20.0rc2', + '1.20.0rc3', + '1.20.1', + '1.21.0rc1', + '1.21.1', + '1.21.1rc1', + '1.22.0', + '1.22.0rc1', + '1.22.1', + '1.23.0', + '1.23.0rc1', + '1.23.1', + '1.24.0', + '1.24.0rc1', + '1.24.1', + '1.24.3', + '1.25.0', + '1.25.0rc1', + '1.26.0', + '1.26.0rc1', + '1.27.0rc1', + '1.27.0rc2', + '1.27.1', + '1.27.2', + '1.28.0rc1', + '1.28.0rc2', + '1.28.1', + '1.29.0', + '1.30.0', + '1.31.0'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'PyPI', + 'name': 'grpcio', + 'purl': 'pkg:pypi/grpcio'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '1.14.2'}, + { 'type': 'last_affected', + 'value': '1.31.0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '1.14.2', + '1.15.0', + '1.15.0rc1', + '1.16.0', + '1.16.0rc1', + '1.16.1', + '1.17.0', + '1.17.1', + '1.18.0', + '1.19.0', + '1.20.0', + '1.20.0rc1', + '1.20.0rc2', + '1.20.0rc3', + '1.20.1', + '1.21.0rc1', + '1.21.1', + '1.21.1rc1', + '1.22.0', + '1.22.0rc1', + '1.22.1', + '1.23.0', + '1.23.0rc1', + '1.23.1', + '1.24.0', + '1.24.0rc1', + '1.24.1', + '1.24.3', + '1.25.0', + '1.25.0rc1', + '1.26.0', + '1.26.0rc1', + '1.27.0rc1', + '1.27.0rc2', + '1.27.1', + '1.27.2', + '1.28.0rc1', + '1.28.0rc2', + '1.28.1', + '1.29.0', + '1.30.0', + '1.31.0']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'PYSEC-124', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['PyPI'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'is_fixed': False, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['grpcio'], + 'public': True, + 'purl': ['pkg:pypi/grpcio'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': ['124', 'grpcio', 'pypi', 'pysec', 'pysec-124'], + 'search_tags': ['grpcio', 'pysec-124'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:PYSEC-124.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_limit.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_limit.txt new file mode 100644 index 00000000000..dc9a0912254 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_limit.txt @@ -0,0 +1,79 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '1.13.0', + '1.14.0', + '1.14.0rc1', + '1.14.0rc2', + '1.14.1', + '1.14.2rc1', + 'branch-v0.1.1', + 'v0.1', + 'v0.1.1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'PyPI', + 'name': 'grpcio', + 'purl': 'pkg:pypi/grpcio'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'limit', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}, + { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '1.13.0'}, + { 'type': 'limit', + 'value': '1.14.2'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + '1.13.0', + '1.14.0', + '1.14.0rc1', + '1.14.0rc2', + '1.14.1', + '1.14.2rc1', + 'v0.1', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-128', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'PyPI'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['grpcio'], + 'public': True, + 'purl': ['pkg:pypi/grpcio'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '128', + 'git', + 'grpcio', + 'https://osv-test/repo/url', + 'osv', + 'osv-128', + 'osv-test/repo/url', + 'pypi', + 'repo', + 'url'], + 'search_tags': ['grpcio', 'osv-128'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:OSV-128.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_linux.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_linux.txt new file mode 100644 index 00000000000..18dff8e75c6 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_linux.txt @@ -0,0 +1,52 @@ +{ 'affected': [], + 'affected_fuzzy': [], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Linux', + 'name': 'Kernel', + 'purl': None}, + 'ranges': [ { 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': []}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'LINUX-123', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT','Linux'], + 'fixed': '', + 'has_affected': False, + 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'project': ['Kernel'], + 'public': True, + 'purl': [], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '123', + 'git', + 'https://osv-test/repo/url', + 'kernel', + 'linux', + 'linux-123', + 'osv-test/repo/url', + 'repo', + 'url'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:LINUX-123.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_maven.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_maven.txt new file mode 100644 index 00000000000..38df7620556 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_maven.txt @@ -0,0 +1,100 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '0.7.0-incubating', + '0.8.0', + '0.9.0', + '1.0', + '1.1', + '2.0', + '2.1', + '2.2', + '2.3', + '2.4'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Maven', + 'name': 'org.apache.any23:apache-any23', + 'purl': 'pkg:maven/org.apache.any23/apache-any23'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '2.5'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}], + 'severities': [], + 'versions': [ '0.7.0-incubating', + '0.8.0', + '0.9.0', + '1.0', + '1.1', + '2.0', + '2.1', + '2.2', + '2.3', + '2.4']}], + 'aliases': ['CVE-2021-38555'], + 'credits': [], + 'database_specific': { 'cwe_ids': ['CWE-611'], + 'github_reviewed': True, + 'github_reviewed_at': '2021-09-13T19:31:01Z', + 'nvd_published_at': '2021-09-11T11:15:00Z', + 'severity': 'CRITICAL'}, + 'db_id': 'GHSA-838r-hvwh-24h8', + 'details': 'An XML external entity (XXE) injection vulnerability was ' + 'discovered in the Any23 StreamUtils.java file and is known to ' + 'affect Any23 versions < 2.5. XML external entity injection ' + '(also known as XXE) is a web security vulnerability that ' + "allows an attacker to interfere with an application's " + 'processing of XML data. It often allows an attacker to view ' + 'files on the application server filesystem, and to interact ' + 'with any back-end or external systems that the application ' + 'itself can access.', + 'ecosystem': ['Maven'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2021, 9, 24, 13, 10, 5, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['org.apache.any23:apache-any23'], + 'public': True, + 'purl': ['pkg:maven/org.apache.any23/apache-any23'], + 'reference_url_types': { 'https://github.com/apache/any23': 'PACKAGE', + 'https://lists.apache.org/thread.html/r589d1a9f94dbeee7a0f5dbe8513a0e300dfe669bd964ba2fbfe28e07%40%3Cannounce.apache.org%3E': 'WEB', + 'https://nvd.nist.gov/vuln/detail/CVE-2021-38555': 'ADVISORY'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '2021', + '2021-38555', + '24h8', + '38555', + '838r', + '838r-hvwh', + '838r-hvwh-24h8', + 'any23', + 'apache', + 'cve', + 'cve-2021', + 'cve-2021-38555', + 'ghsa', + 'ghsa-838r', + 'ghsa-838r-hvwh', + 'ghsa-838r-hvwh-24h8', + 'hvwh', + 'hvwh-24h8', + 'maven', + 'org', + 'org.apache.any23:apache-any23'], + 'search_tags': ['ghsa-838r-hvwh-24h8', 'org.apache.any23:apache-any23'], + 'semver_fixed_indexes': [], + 'severities': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N', + 'type': 'CVSS_V3'}], + 'source': 'source', + 'source_id': 'source:GHSA-838r-hvwh-24h8.json', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'XML Injection in Any23', + 'timestamp': DatetimeWithNanoseconds(2021, 9, 13, 20, 6, 31, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_new.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_new.txt new file mode 100644 index 00000000000..7c36f197aad --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_new.txt @@ -0,0 +1,67 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Go', + 'name': 'blah.com/package', + 'purl': 'pkg:golang/blah.com/package'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'type': 'introduced', + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-126', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'Go'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['blah.com/package'], + 'public': True, + 'purl': ['pkg:golang/blah.com/package'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '126', + 'blah', + 'blah.com/package', + 'com', + 'git', + 'go', + 'https://osv-test/repo/url', + 'osv', + 'osv-126', + 'osv-test/repo/url', + 'package', + 'repo', + 'url'], + 'search_tags': ['blah.com/package', 'osv-126'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:OSV-126.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_no_introduced.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_no_introduced.txt new file mode 100644 index 00000000000..821fb369530 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_no_introduced.txt @@ -0,0 +1,67 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1', + 'v0.1.1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'Go', + 'name': 'blah.com/package', + 'purl': 'pkg:golang/blah.com/package'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '0'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-127', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'Go'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['blah.com/package'], + 'public': True, + 'purl': ['pkg:golang/blah.com/package'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '127', + 'blah', + 'blah.com/package', + 'com', + 'git', + 'go', + 'https://osv-test/repo/url', + 'osv', + 'osv-127', + 'osv-test/repo/url', + 'package', + 'repo', + 'url'], + 'search_tags': ['blah.com/package', 'osv-127'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:OSV-127.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': None, + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt new file mode 100644 index 00000000000..39b24a9dd51 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt @@ -0,0 +1,7 @@ +{ 'details': 'Blah blah blah\nBlah\n', + 'id': 'OSV-131', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2021-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt new file mode 100644 index 00000000000..3c2c9cfd004 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt @@ -0,0 +1,65 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': ['0-1-1', '1'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'ecosystem', + 'name': 'blah.com/package', + 'purl': None}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'type': 'introduced', + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'OSV-130', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'ecosystem'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['blah.com/package'], + 'public': True, + 'purl': [], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '130', + 'blah', + 'blah.com/package', + 'com', + 'ecosystem', + 'git', + 'https://osv-test/repo/url', + 'osv', + 'osv-130', + 'osv-test/repo/url', + 'package', + 'repo', + 'url'], + 'search_tags': ['blah.com/package', 'osv-130'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:OSV-130.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_pypi.txt b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_pypi.txt new file mode 100644 index 00000000000..17d13fe02f8 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/testdata/UpdateTest_update_pypi.txt @@ -0,0 +1,143 @@ +{ 'affected': [], + 'affected_checksum': None, + 'affected_fuzzy': [ '1.14.2', + '1.15.0', + '1.15.0rc1', + '1.16.0', + '1.16.0rc1', + '1.16.1', + '1.17.0', + '1.17.1', + '1.18.0', + '1.19.0', + '1.20.0', + '1.20.0rc1', + '1.20.0rc2', + '1.20.0rc3', + '1.20.1', + '1.21.0rc1', + '1.21.1', + '1.21.1rc1', + '1.22.0', + '1.22.0rc1', + '1.22.1', + '1.23.0', + '1.23.0rc1', + '1.23.1', + '1.24.0', + '1.24.0rc1', + '1.24.1', + '1.24.3', + '1.25.0', + '1.25.0rc1', + '1.26.0', + '1.26.0rc1', + '1.27.0rc1', + '1.27.0rc2', + '1.27.1', + '1.27.2', + '1.28.0rc1', + '1.28.0rc2', + '1.28.1', + '1.29.0', + '1.30.0'], + 'affected_packages': [ { 'database_specific': None, + 'ecosystem_specific': None, + 'package': { 'ecosystem': 'PyPI', + 'name': 'grpcio', + 'purl': 'pkg:pypi/grpcio'}, + 'ranges': [ { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': '1.14.2'}, + { 'type': 'fixed', + 'value': '1.31.0'}], + 'repo_url': '', + 'type': 'ECOSYSTEM'}, + { 'database_specific': None, + 'events': [ { 'type': 'introduced', + 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'type': 'fixed', + 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo_url': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'severities': [], + 'versions': [ '1.14.2', + '1.15.0', + '1.15.0rc1', + '1.16.0', + '1.16.0rc1', + '1.16.1', + '1.17.0', + '1.17.1', + '1.18.0', + '1.19.0', + '1.20.0', + '1.20.0rc1', + '1.20.0rc2', + '1.20.0rc3', + '1.20.1', + '1.21.0rc1', + '1.21.1', + '1.21.1rc1', + '1.22.0', + '1.22.0rc1', + '1.22.1', + '1.23.0', + '1.23.0rc1', + '1.23.1', + '1.24.0', + '1.24.0rc1', + '1.24.1', + '1.24.3', + '1.25.0', + '1.25.0rc1', + '1.26.0', + '1.26.0rc1', + '1.27.0rc1', + '1.27.0rc2', + '1.27.1', + '1.27.2', + '1.28.0rc1', + '1.28.0rc2', + '1.28.1', + '1.29.0', + '1.30.0']}], + 'aliases': [], + 'credits': [], + 'database_specific': None, + 'db_id': 'PYSEC-123', + 'details': 'Blah blah blah\nBlah\n', + 'ecosystem': ['GIT', 'PyPI'], + 'fixed': '', + 'has_affected': True, + 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), + 'is_fixed': True, + 'issue_id': None, + 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'project': ['grpcio'], + 'public': True, + 'purl': ['pkg:pypi/grpcio'], + 'reference_url_types': {'https://ref.com/ref': 'WEB'}, + 'regressed': '', + 'related': [], + 'search_indices': [ '123', + 'git', + 'grpcio', + 'https://osv-test/repo/url', + 'osv-test/repo/url', + 'pypi', + 'pysec', + 'pysec-123', + 'repo', + 'url'], + 'search_tags': ['grpcio', 'pysec-123'], + 'semver_fixed_indexes': [], + 'severities': [], + 'source': 'source', + 'source_id': 'source:PYSEC-123.yaml', + 'source_of_truth': 2, + 'status': 1, + 'summary': 'A vulnerability', + 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + 'upstream_raw': [], + 'withdrawn': None} \ No newline at end of file diff --git a/gcp/workers/oss_fuzz_worker/worker.py b/gcp/workers/oss_fuzz_worker/worker.py new file mode 100644 index 00000000000..9187b6b6c51 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/worker.py @@ -0,0 +1,851 @@ +#!/usr/bin/env python3 +# Copyright 2021 Google LLC +# +# 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. +"""OSV Worker.""" +import argparse +import datetime +import json +import logging +import os +import redis +import requests +import resource +import shutil +import subprocess +import sys +import threading +import time + +import google.cloud.exceptions +from google.cloud import ndb +from google.cloud import pubsub_v1 +from google.cloud import storage +from google.cloud.storage import retry +from google.protobuf import json_format + +sys.path.append(os.path.dirname(os.path.realpath(__file__))) +import osv +import osv.ecosystems +import osv.cache +import osv.logs +from osv import vulnerability_pb2 +import oss_fuzz + +from vanir import vulnerability_manager + +DEFAULT_WORK_DIR = '/work' +OSS_FUZZ_GIT_URL = 'https://github.com/google/oss-fuzz.git' +TASK_SUBSCRIPTION = 'oss-fuzz-tasks' +MAX_LEASE_DURATION = 6 * 60 * 60 # 4 hours. +_TIMEOUT_SECONDS = 60 + +_ECOSYSTEM_PUSH_TOPICS = { + 'PyPI': 'pypi-bridge', +} + +_state = threading.local() +_state.source_id = None +_state.bug_id = None + + +class RedisCache(osv.cache.Cache): + """Redis cache implementation.""" + + redis_instance: redis.client.Redis + + def __init__(self, host, port): + self.redis_instance = redis.Redis(host, port) + + def get(self, key): + try: + return json.loads(self.redis_instance.get(json.dumps(key))) + except Exception: + # TODO(ochang): Remove this after old cache entries are flushed. + return None + + def set(self, key, value, ttl): + return self.redis_instance.set(json.dumps(key), json.dumps(value), ex=ttl) + + +class UpdateConflictError(Exception): + """Update conflict exception.""" + + +class _ContextFilter(logging.Filter): + """Context filter to add extra GCP logging information.""" + + def filter(self, record): + """Add extra fields to the log record.""" + json_fields = getattr(record, 'json_fields', {}) + + if getattr(_state, 'source_id', None): + json_fields['source_id'] = _state.source_id + + if getattr(_state, 'bug_id', None): + json_fields['bug_id'] = _state.bug_id + + json_fields['thread'] = record.thread + record.json_fields = json_fields + return True + + +def _setup_logging_extra_info(): + """Set up extra GCP logging information.""" + logging.getLogger().addFilter(_ContextFilter()) + + +class _PubSubLeaserThread(threading.Thread): + """Thread that continuously renews the lease for a message.""" + + EXTENSION_TIME_SECONDS = 10 * 60 # 10 minutes. + + def __init__(self, subscriber_client, subscription, ack_id, done_event, + max_lease_seconds): + super().__init__() + self.daemon = True + self._subscriber = subscriber_client + self._subscription = subscription + self._ack_id = ack_id + self._done_event = done_event + self._max_lease_seconds = max_lease_seconds + + def run(self): + """Run the leaser thread.""" + latest_end_time = time.time() + self._max_lease_seconds + + while True: + try: + time_left = latest_end_time - time.time() + if time_left <= 0: + logging.warning( + 'Lease reached maximum lease time of %d seconds, ' + 'stopping renewal.', self._max_lease_seconds) + break + + extension_seconds = int(min(self.EXTENSION_TIME_SECONDS, time_left)) + + logging.info('Renewing lease for task by %d seconds.', + extension_seconds) + self._subscriber.modify_ack_deadline( + subscription=self._subscription, + ack_ids=[self._ack_id], + ack_deadline_seconds=extension_seconds) + + # Schedule renewals earlier than the extension to avoid race conditions + # and performing the next extension too late. + wait_seconds = min(time_left, self.EXTENSION_TIME_SECONDS // 2) + + # Wait until the next scheduled renewal, or if the task is complete. + if self._done_event.wait(wait_seconds): + logging.info('Task complete, stopping renewal.') + break + except Exception: + logging.exception('Leaser thread failed: ') + + +def clean_artifacts(oss_fuzz_dir): + """Clean build artifact from previous runs.""" + build_dir = os.path.join(oss_fuzz_dir, 'build') + if os.path.exists(build_dir): + shutil.rmtree(build_dir, ignore_errors=True) + + +def mark_bug_invalid(message): + """Mark a bug as invalid.""" + source_id = get_source_id(message) + for bug in osv.Bug.query(osv.Bug.source_id == source_id): + bug.withdrawn = datetime.datetime.now(datetime.UTC) + bug.status = osv.BugStatus.INVALID + bug.put() + + osv.delete_affected_commits(bug.key.id()) + + +def get_source_id(message): + """Get message ID.""" + source_id = message.attributes['source_id'] + if source_id: + return source_id + + testcase_id = message.attributes['testcase_id'] + if testcase_id: + return oss_fuzz.SOURCE_PREFIX + testcase_id + + return None + + +def add_fix_information(vulnerability, fix_result): + """Add fix information to a vulnerability.""" + database_specific = {} + fix_commit = fix_result.commit + if ':' in fix_result.commit: + database_specific['fixed_range'] = fix_result.commit + fix_commit = fix_result.commit.split(':')[1] + + has_changes = False + + for affected_package in vulnerability.affected: + added_fix = False + + # Count unique repo URLs. + repos = set() + for affected_range in affected_package.ranges: + if affected_range.type == vulnerability_pb2.Range.GIT: + repos.add(affected_range.repo) + + for affected_range in affected_package.ranges: + if affected_range.type != vulnerability_pb2.Range.GIT: + continue + + # If this range does not include the fixed commit, add it. + # Do this if: + # - There is only one repo URL in the entire vulnerability, or + # - The repo URL matches the FixResult repo URL. + if ((fix_result.repo_url == affected_range.repo or len(repos) == 1) and + not any(event.fixed == fix_commit + for event in affected_range.events)): + added_fix = True + has_changes = True + affected_range.events.add(fixed=fix_commit) + # Clear existing versions to re-compute them from scratch. + del affected_package.versions[:] + + if added_fix: + affected_package.database_specific.update(database_specific) + + return has_changes + + +# TODO(ochang): Remove this function once GHSA's encoding is fixed. +def fix_invalid_ghsa(vulnerability): + """Attempt to fix an invalid GHSA entry. + + Args: + vulnerability: a vulnerability object. + + Returns: + whether the GHSA entry is valid. + """ + packages = {} + for affected in vulnerability.affected: + details = packages.setdefault( + (affected.package.ecosystem, affected.package.name), { + 'has_single_introduced': False, + 'has_fixed': False + }) + + has_bad_equals_encoding = False + for affected_range in affected.ranges: + if len( + affected_range.events) == 1 and affected_range.events[0].introduced: + details['has_single_introduced'] = True + if (affected.versions and + affected.versions[0] == affected_range.events[0].introduced): + # https://github.com/github/advisory-database/issues/59. + has_bad_equals_encoding = True + + for event in affected_range.events: + if event.fixed: + details['has_fixed'] = True + + if has_bad_equals_encoding: + if len(affected.ranges) == 1: + # Try to fix this by removing the range. + del affected.ranges[:] + logging.info('Removing bad range from %s', vulnerability.id) + else: + # Unable to fix this if there are multiple ranges. + return False + + for details in packages.values(): + # Another case of a bad encoding: Having ranges with a single "introduced" + # event, when there are actually "fix" events encoded in another range for + # the same package. + if details['has_single_introduced'] and details['has_fixed']: + return False + + return True + + +def maybe_normalize_package_names(vulnerability): + """Normalize package names as necessary.""" + for affected in vulnerability.affected: + if not affected.package.ecosystem: + continue + affected.package.name = osv.ecosystems.maybe_normalize_package_names( + affected.package.name, affected.package.ecosystem) + + return vulnerability + + +def filter_unknown_ecosystems(vulnerability): + """Remove unknown ecosystems from vulnerability.""" + filtered = [] + for affected in vulnerability.affected: + # CVE-converted OSV records have no package information. + if not affected.HasField('package'): + filtered.append(affected) + elif osv.ecosystems.is_known(affected.package.ecosystem): + filtered.append(affected) + else: + logging.error('%s contains unknown ecosystem "%s"', vulnerability.id, + affected.package.ecosystem) + del vulnerability.affected[:] + vulnerability.affected.extend(filtered) + + +class TaskRunner: + """Task runner.""" + + def __init__(self, ndb_client, oss_fuzz_dir, work_dir, ssh_key_public_path, + ssh_key_private_path): + self._ndb_client = ndb_client + self._oss_fuzz_dir = oss_fuzz_dir + self._work_dir = work_dir + self._sources_dir = os.path.join(self._work_dir, 'sources') + self._ssh_key_public_path = ssh_key_public_path + self._ssh_key_private_path = ssh_key_private_path + os.makedirs(self._sources_dir, exist_ok=True) + logging.info('Created task runner') + + def _git_callbacks(self, source_repo): + """Get git auth callbacks.""" + return osv.GitRemoteCallback(source_repo.repo_username, + self._ssh_key_public_path, + self._ssh_key_private_path) + + def _source_update(self, message): + """Source update.""" + source = message.attributes['source'] + path = message.attributes['path'] + original_sha256 = message.attributes['original_sha256'] + deleted = message.attributes['deleted'] == 'true' + + source_repo = osv.get_source_repository(source) + if source_repo is None: + raise ValueError('Failed to get source repository %s' % source) + + if source_repo.type == osv.SourceRepositoryType.GIT: + repo = osv.ensure_updated_checkout( + source_repo.repo_url, + os.path.join(self._sources_dir, source), + git_callbacks=self._git_callbacks(source_repo), + branch=source_repo.repo_branch) + + vuln_path = os.path.join(osv.repo_path(repo), path) + if not os.path.exists(vuln_path): + logging.info('%s was deleted.', vuln_path) + if deleted: + self._handle_deleted(source_repo, path) + + return + + if deleted: + logging.info('Deletion request but source still exists, aborting.') + return + + try: + vulnerabilities = osv.parse_vulnerabilities( + vuln_path, key_path=source_repo.key_path) + except Exception: + logging.exception('Failed to parse vulnerability %s:', vuln_path) + return + + current_sha256 = osv.sha256(vuln_path) + elif source_repo.type == osv.SourceRepositoryType.BUCKET: + if deleted: + self._handle_deleted(source_repo, path) + return + storage_client = storage.Client() + bucket = storage_client.bucket(source_repo.bucket) + try: + blob = bucket.blob(path).download_as_bytes(retry=retry.DEFAULT_RETRY) + except google.cloud.exceptions.NotFound: + logging.exception('Bucket path %s does not exist.', path) + return + + current_sha256 = osv.sha256_bytes(blob) + try: + vulnerabilities = osv.parse_vulnerabilities_from_data( + blob, + extension=os.path.splitext(path)[1], + key_path=source_repo.key_path) + except Exception: + logging.exception('Failed to parse vulnerability %s', path) + return + + repo = None + elif source_repo.type == osv.SourceRepositoryType.REST_ENDPOINT: + vulnerabilities = [] + request = requests.get(source_repo.link + path, timeout=_TIMEOUT_SECONDS) + if request.status_code != 200: + logging.error('Failed to fetch REST API: %s', request.status_code) + return + vuln = request.json() + try: + vulnerabilities.append(osv.parse_vulnerability_from_dict(vuln)) + except Exception as e: + logging.exception('Failed to parse %s:%s', vuln['id'], e) + current_sha256 = osv.sha256_bytes(request.text.encode()) + repo = None + + else: + raise RuntimeError('Unsupported SourceRepository type.') + + if current_sha256 != original_sha256: + logging.warning( + 'sha256sum of %s no longer matches (expected=%s vs current=%s).', + path, original_sha256, current_sha256) + return + + if len(vulnerabilities) > 1: + # While the code allows for having multiple vulnerabilities in a file, + # it's not really documented anywhere, and no one seems to be doing this. + # I (michaelkedar) think we should stop supporting this, so adding this + # log here to verify if it's okay to remove. + logging.error( + 'file has multiple vulnerabilities', + extra={'json_fields': { + 'source': source, + 'path': path, + }}) + + for vulnerability in vulnerabilities: + self._do_update(source_repo, repo, vulnerability, path, original_sha256) + + def _handle_deleted(self, source_repo, vuln_path): + """Handle existing bugs that have been subsequently deleted at their source. + + Args: + source_repo: Source repository. + vuln_path: Path to vulnerability. + + This marks the Bug as INVALID and as withdrawn. + """ + vuln_id = os.path.splitext(os.path.basename(vuln_path))[0] + bug = osv.Bug.get_by_id(vuln_id) + if not bug: + logging.error('Failed to find Bug with ID %s', vuln_id) + return + + bug_source_path = osv.source_path(source_repo, bug) + if bug_source_path != vuln_path: + logging.error('Request path %s does not match %s, aborting.', vuln_path, + bug_source_path) + return + + logging.info('Marking %s as invalid and withdrawn.', vuln_id) + bug.status = osv.BugStatus.INVALID + bug.withdrawn = datetime.datetime.now(datetime.UTC) + bug.put() + + def _push_new_ranges_and_versions(self, source_repo, repo, vulnerability, + output_path, original_sha256): + """Pushes new ranges and versions.""" + osv.write_vulnerability( + vulnerability, output_path, key_path=source_repo.key_path) + repo.index.add_all() + return osv.push_source_changes( + repo, + f'Update {vulnerability.id}', + self._git_callbacks(source_repo), + expected_hashes={ + output_path: original_sha256, + }) + + def _analyze_vulnerability(self, source_repo, repo, vulnerability, path, + original_sha256): + """Analyze vulnerability and push new changes.""" + # Add OSS-Fuzz + added_fix_info = False + bug = osv.Bug.get_by_id(vulnerability.id) + if bug: + fix_result = osv.FixResult.get_by_id(bug.source_id) + if fix_result: + added_fix_info = add_fix_information(vulnerability, fix_result) + + result = osv.analyze( + vulnerability, + analyze_git=not source_repo.ignore_git, + detect_cherrypicks=source_repo.detect_cherrypicks, + versions_from_repo=source_repo.versions_from_repo, + consider_all_branches=source_repo.consider_all_branches) + + if not result.has_changes and not added_fix_info: + return result + + if not source_repo.editable: + return result + + output_path = os.path.join(osv.repo_path(repo), path) + if self._push_new_ranges_and_versions(source_repo, repo, vulnerability, + output_path, original_sha256): + logging.info('Updated range/versions for vulnerability %s.', + vulnerability.id) + return result + + logging.warning('Discarding changes for %s due to conflicts.', + vulnerability.id) + raise UpdateConflictError + + def _generate_vanir_signatures(self, vulnerability): + """Generates Vanir signatures for a vulnerability.""" + if not any(r.type == vulnerability_pb2.Range.GIT + for affected in vulnerability.affected + for r in affected.ranges): + logging.info( + 'Skipping Vanir signature generation for %s as it has no ' + 'GIT affected ranges.', vulnerability.id) + return vulnerability + if any(affected.package.name == "Kernel" and + affected.package.ecosystem == "Linux" + for affected in vulnerability.affected): + logging.info( + 'Skipping Vanir signature generation for %s as it is a ' + 'Kernel vulnerability.', vulnerability.id) + return vulnerability + + logging.info('Generating Vanir signatures for %s', vulnerability.id) + try: + vuln_manager = vulnerability_manager.generate_from_json_string( + content=json.dumps([ + json_format.MessageToDict( + vulnerability, preserving_proto_field_name=True) + ]),) + vuln_manager.generate_signatures() + + if not vuln_manager.vulnerabilities: + logging.warning('Vanir signature generation resulted in no ' + 'vulnerabilities.') + return vulnerability + + return vuln_manager.vulnerabilities[0].to_proto() + except Exception: + logging.exception('Failed to generate Vanir signatures for %s', + vulnerability.id) + return vulnerability + + def _do_update(self, source_repo, repo, vulnerability, relative_path, + original_sha256): + """Process updates on a vulnerability.""" + _state.bug_id = vulnerability.id + logging.info('Processing update for vulnerability %s', vulnerability.id) + vulnerability = maybe_normalize_package_names(vulnerability) + if source_repo.name == 'ghsa' and not fix_invalid_ghsa(vulnerability): + logging.warning('%s has an encoding error, skipping.', vulnerability.id) + return + + filter_unknown_ecosystems(vulnerability) + + # Keep a copy of the original modified date from the source file. + orig_modified_date = vulnerability.modified.ToDatetime(datetime.UTC) + + # Fully enrich the vulnerability object in memory. + vulnerability = self._generate_vanir_signatures(vulnerability) + try: + result = self._analyze_vulnerability(source_repo, repo, vulnerability, + relative_path, original_sha256) + except UpdateConflictError: + # Discard changes due to conflict. + return + + # Fetch the current state from Datastore. + bug = osv.Bug.get_by_id(vulnerability.id) + is_new_bug = bug is None + + has_changed = False + if is_new_bug: + has_changed = True + if source_repo.name == 'oss-fuzz': + logging.warning('%s not found for OSS-Fuzz source.', vulnerability.id) + return + + bug = osv.Bug( + db_id=vulnerability.id, + timestamp=osv.utcnow(), + status=osv.BugStatus.PROCESSED, + source_of_truth=osv.SourceOfTruth.SOURCE_REPO) + else: + # Compare the newly enriched vulnerability with the stored one. + # Create a 'pure' vulnerability object from the existing bug for + # comparison, excluding external data that would cause false positives. + old_vulnerability = bug.to_vulnerability( + include_source=False, include_alias=False, include_upstream=False) + + # Clear modified timestamps for a clean comparison. + old_vulnerability.modified.Clear() + vulnerability.modified.Clear() + + if old_vulnerability != vulnerability: + has_changed = True + + # Update the bug entity based on the comparison. + if has_changed: + bug.update_from_vulnerability(vulnerability) + bug.last_modified = osv.utcnow() + else: + # If no meaningful change, ensure last_modified reflects the source file's + # modified date, as only metadata might have changed. + bug.last_modified = orig_modified_date + + bug.public = True + bug.import_last_modified = orig_modified_date + # OSS-Fuzz sourced bugs use a different format for source_id. + if source_repo.name != 'oss-fuzz' or not bug.source_id: + bug.source_id = f'{source_repo.name}:{relative_path}' + + if bug.withdrawn: + bug.status = osv.BugStatus.INVALID + else: + bug.status = osv.BugStatus.PROCESSED + + if not vulnerability.affected: + logging.info('%s does not affect any packages. Marking as invalid.', + vulnerability.id) + bug.status = osv.BugStatus.INVALID + try: + bug.put() + except (google.api_core.exceptions.Cancelled, ndb.exceptions.Error) as e: + e.add_note(f'Happened processing {vulnerability.id}') + logging.exception('Unexpected exception while writing %s to Datastore', + vulnerability.id) + + osv.update_affected_commits(bug.key.id(), result.commits, bug.public) + self._notify_ecosystem_bridge(vulnerability) + self._maybe_remove_import_findings(bug) + + def _notify_ecosystem_bridge(self, vulnerability): + """Notify ecosystem bridges.""" + ecosystems = set() + for affected in vulnerability.affected: + if affected.package.ecosystem in ecosystems: + continue + + ecosystems.add(affected.package.ecosystem) + ecosystem_push_topic = _ECOSYSTEM_PUSH_TOPICS.get( + affected.package.ecosystem) + if ecosystem_push_topic: + publisher = pubsub_v1.PublisherClient() + cloud_project = os.environ['GOOGLE_CLOUD_PROJECT'] + push_topic = publisher.topic_path(cloud_project, ecosystem_push_topic) + publisher.publish( + push_topic, + data=json.dumps(osv.vulnerability_to_dict(vulnerability)).encode()) + + def _maybe_remove_import_findings(self, vulnerability: osv.Bug): + """Remove any stale import findings for a successfully processed Bug,""" + + finding = osv.ImportFinding.get_by_id(vulnerability.id()) + if finding: + logging.info('Removing stale import finding for %s', vulnerability.id()) + finding.key.delete() + + def _do_process_task(self, subscriber, subscription, ack_id, message, + done_event): + """Process task with timeout.""" + try: + with self._ndb_client.context(): + source_id = get_source_id(message) or message.attributes.get( + 'source', None) + _state.source_id = source_id + _state.bug_id = message.attributes.get('allocated_bug_id', None) + + task_type = message.attributes['type'] + + # Validating that oss-fuzz-related tasks are only sent by oss-fuzz and + # the non-oss-fuzz task is not used by oss-fuzz. + if not source_id: + logging.error('got message without source_id: %s', message) + return + + if not source_id.startswith('oss-fuzz'): + logging.error('got non-oss-fuzz task for source %s', source_id) + return + + if task_type not in ('regressed', 'fixed', 'impact', 'invalid', + 'update-oss-fuzz'): + logging.error('got unexpected \'%s\' task for oss-fuzz source %s', + task_type, source_id) + + if task_type in ('regressed', 'fixed'): + oss_fuzz.process_bisect_task(self._oss_fuzz_dir, task_type, source_id, + message) + elif task_type == 'impact': + try: + oss_fuzz.process_impact_task(source_id, message) + except osv.ImpactError: + logging.exception('Failed to process impact: ') + elif task_type == 'invalid': + mark_bug_invalid(message) + elif task_type == 'update-oss-fuzz': + # TODO(michaelkedar): create separate _source_update for oss-fuzz. + self._source_update(message) + + _state.source_id = None + subscriber.acknowledge(subscription=subscription, ack_ids=[ack_id]) + except Exception: + logging.exception('Unexpected exception while processing task: ',) + subscriber.modify_ack_deadline( + subscription=subscription, ack_ids=[ack_id], ack_deadline_seconds=0) + finally: + logging.info('Ending task') + done_event.set() + + def handle_timeout(self, subscriber, subscription, ack_id, message): + """Handle a timeout.""" + subscriber.acknowledge(subscription=subscription, ack_ids=[ack_id]) + task_type = message.attributes['type'] + source_id = get_source_id(message) or message.attributes.get('source', None) + + logging.warning('Task %s timed out (source_id=%s)', task_type, source_id) + if task_type in ('fixed', 'regressed'): + oss_fuzz.handle_timeout(task_type, source_id, self._oss_fuzz_dir, message) + + def _log_task_latency(self, message): + """Determine how long ago the task was requested. + + Log how long it took to be serviced.""" + request_time = message.attributes.get('req_timestamp') + if request_time: + now = int(time.time()) + request_time = int(request_time) + latency = now - request_time + + json_fields = { + 'source': message.attributes.get('source'), + 'path': message.attributes.get('path'), + 'latency': latency, + } + if source_time := message.attributes.get('src_timestamp'): + source_time = int(source_time) + src_latency = now - source_time + json_fields['src_latency'] = src_latency + + task_type = message.attributes['type'] + source_id = get_source_id(message) or message.attributes.get( + 'source', None) + + logging.info( + 'Task %s (source_id=%s) latency %d', + task_type, + source_id, + latency, + extra={'json_fields': json_fields}) + + def loop(self): + """Task loop.""" + subscriber = pubsub_v1.SubscriberClient() + + cloud_project = os.environ['GOOGLE_CLOUD_PROJECT'] + subscription = subscriber.subscription_path(cloud_project, + TASK_SUBSCRIPTION) + + def process_task(ack_id, message): + """Process a task.""" + osv.ensure_updated_checkout(OSS_FUZZ_GIT_URL, self._oss_fuzz_dir) + clean_artifacts(self._oss_fuzz_dir) + + # Enforce timeout by doing the work in another thread. + done_event = threading.Event() + thread = threading.Thread( + target=self._do_process_task, + args=(subscriber, subscription, ack_id, message, done_event), + daemon=True) + logging.info('Creating task thread for %s', message) + thread.start() + + done = done_event.wait(timeout=MAX_LEASE_DURATION) + logging.info('Returned from task thread') + if done: + self._log_task_latency(message) + else: + self.handle_timeout(subscriber, subscription, ack_id, message) + logging.warning('Timed out processing task') + + while True: + response = subscriber.pull(subscription=subscription, max_messages=1) + if not response.received_messages: + continue + + message = response.received_messages[0].message + ack_id = response.received_messages[0].ack_id + + leaser_done = threading.Event() + leaser = _PubSubLeaserThread(subscriber, subscription, ack_id, + leaser_done, MAX_LEASE_DURATION) + leaser.start() + + try: + process_task(ack_id, message) + finally: + leaser_done.set() + leaser.join() + + +def main(): + parser = argparse.ArgumentParser(description='Worker') + parser.add_argument( + '--work_dir', help='Working directory', default=DEFAULT_WORK_DIR) + parser.add_argument('--ssh_key_public', help='Public SSH key path') + parser.add_argument('--ssh_key_private', help='Private SSH key path') + parser.add_argument( + '--redis_host', help='URL to redis instance, enables redis cache') + parser.add_argument( + '--redis_port', default=6379, help='Port of redis instance') + args = parser.parse_args() + + if args.redis_host: + osv.ecosystems.config.set_cache( + RedisCache(args.redis_host, args.redis_port)) + + osv.ecosystems.config.work_dir = args.work_dir + + # Work around kernel bug: https://gvisor.dev/issue/1765 + resource.setrlimit(resource.RLIMIT_MEMLOCK, + (resource.RLIM_INFINITY, resource.RLIM_INFINITY)) + + subprocess.call(('service', 'docker', 'start')) + + oss_fuzz_dir = os.path.join(args.work_dir, 'oss-fuzz') + + tmp_dir = os.path.join(args.work_dir, 'tmp') + # Temp files are on the persistent local SSD, + # and they do not get removed when GKE sends a SIGTERM to stop the pod. + # Manually clear the tmp_dir folder of any leftover files + # TODO(michaelkedar): use an ephemeral disk for temp storage. + if os.path.exists(tmp_dir): + shutil.rmtree(tmp_dir) + os.makedirs(tmp_dir, exist_ok=True) + os.environ['TMPDIR'] = tmp_dir + + # Add oss-fuzz/infra to the import path so we can import from it. + sys.path.append(os.path.join(oss_fuzz_dir, 'infra')) + + # Suppress OSS-Fuzz build error logs. These are expected as part of + # bisection. + logging.getLogger('helper').setLevel(logging.CRITICAL) + + osv.ensure_updated_checkout(OSS_FUZZ_GIT_URL, oss_fuzz_dir) + + ndb_client = ndb.Client() + with ndb_client.context(): + task_runner = TaskRunner(ndb_client, oss_fuzz_dir, args.work_dir, + args.ssh_key_public, args.ssh_key_private) + task_runner.loop() + + +if __name__ == '__main__': + osv.logs.setup_gcp_logging('worker') + _setup_logging_extra_info() + main() diff --git a/gcp/workers/oss_fuzz_worker/worker_test.py b/gcp/workers/oss_fuzz_worker/worker_test.py new file mode 100644 index 00000000000..adeab470cd5 --- /dev/null +++ b/gcp/workers/oss_fuzz_worker/worker_test.py @@ -0,0 +1,1783 @@ +# Copyright 2021 Google LLC +# +# 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. +"""Worker tests.""" +# pylint: disable=line-too-long +import codecs +import datetime +import hashlib +from gcp.workers.mock_test.mock_test_handler import MockDataHandler +import http.server +import os +import shutil +import tempfile +import threading +import warnings +import unittest +from unittest import mock + +from google.cloud import ndb +import pygit2 + +import osv +from osv import tests +import oss_fuzz +import worker + +TEST_BUCKET = 'test-osv-source-bucket' +TEST_DATA_DIR = os.path.join( + os.path.dirname(os.path.abspath(__file__)), 'testdata') + +ndb_client = None +ds_emulator = None +context_manager = None + +PORT = 8000 +SERVER_ADDRESS = ('localhost', PORT) +MOCK_ADDRESS_FORMAT = f'http://{SERVER_ADDRESS[0]}:{SERVER_ADDRESS[1]}/' +# pylint: disable=protected-access,invalid-name + + +def _sha256(test_name): + """Get sha256 sum.""" + hasher = hashlib.sha256() + + with open(os.path.join(TEST_DATA_DIR, test_name), 'rb') as f: + hasher.update(f.read()) + + return hasher.hexdigest() + + +class OssFuzzDetailsTest(unittest.TestCase): + """Details generation tests.""" + + def test_basic(self): + """Basic tests.""" + crash_type = 'Heap-buffer-overflow' + crash_state = 'Foo\nBar\nBlah\n' + + summary = oss_fuzz.get_oss_fuzz_summary(crash_type, crash_state) + self.assertEqual('Heap-buffer-overflow in Foo', summary) + + details = oss_fuzz.get_oss_fuzz_details('1337', crash_type, crash_state) + self.assertEqual( + 'OSS-Fuzz report: ' + 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1337\n\n' + '```\n' + 'Crash type: Heap-buffer-overflow\n' + 'Crash state:\n' + 'Foo\n' + 'Bar\n' + 'Blah\n```\n', + details, + ) + + def test_no_issue(self): + """Test generating details without an issue ID.""" + crash_type = 'Heap-buffer-overflow' + crash_state = 'Foo\nBar\nBlah\n' + + details = oss_fuzz.get_oss_fuzz_details('', crash_type, crash_state) + self.assertEqual( + '```\n' + 'Crash type: Heap-buffer-overflow\n' + 'Crash state:\n' + 'Foo\n' + 'Bar\n' + 'Blah\n```\n', + details, + ) + + def test_assert(self): + """Basic assertion failures.""" + crash_type = 'ASSERT' + crash_state = 'idx < length\nFoo\nBar\n' + + summary = oss_fuzz.get_oss_fuzz_summary(crash_type, crash_state) + self.assertEqual('ASSERT: idx < length', summary) + + details = oss_fuzz.get_oss_fuzz_details('1337', crash_type, crash_state) + self.assertEqual( + 'OSS-Fuzz report: ' + 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1337\n\n' + '```\n' + 'Crash type: ASSERT\n' + 'Crash state:\n' + 'idx < length\n' + 'Foo\n' + 'Bar\n```\n', + details, + ) + + def test_bad_cast(self): + """Basic bad casts.""" + crash_type = 'Bad-cast' + crash_state = 'Bad-cast to A from B\nFoo\nBar\n' + + summary = oss_fuzz.get_oss_fuzz_summary(crash_type, crash_state) + self.assertEqual('Bad-cast to A from B', summary) + + details = oss_fuzz.get_oss_fuzz_details('1337', crash_type, crash_state) + self.assertEqual( + 'OSS-Fuzz report: ' + 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1337\n\n' + '```\n' + 'Crash type: Bad-cast\n' + 'Crash state:\n' + 'Bad-cast to A from B\n' + 'Foo\n' + 'Bar\n```\n', + details, + ) + + +class ImpactTest(unittest.TestCase, tests.ExpectationTest(TEST_DATA_DIR)): + """Impact task tests.""" + + def setUp(self): + ds_emulator.reset() + self.maxDiff = None + + tests.mock_clone(self, return_value=pygit2.Repository('osv-test')) + tests.mock_datetime(self) + + osv.SourceRepository( + id='oss-fuzz', name='oss-fuzz', db_prefix=['OSV-']).put() + + allocated_bug = osv.Bug( + db_id='OSV-2020-1337', + timestamp=datetime.datetime(2020, 1, 1, tzinfo=datetime.UTC), + source_id='oss-fuzz:123', + status=osv.BugStatus.UNPROCESSED, + public=False, + ) + allocated_bug.put() + + # This should be deleted and overwritten with the actual computed commits. + osv.AffectedCommits( + id='OSV-2020-1337-3', bug_id='OSV-2020-1337', page=3).put() + + def test_basic(self): + """Basic test.""" + message = mock.Mock() + message.attributes = { + 'source_id': 'oss-fuzz:123', + 'allocated_id': 'OSV-2020-1337', + } + + regress_result = osv.RegressResult( + id='oss-fuzz:123', + commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + repo_url='https://repo.com/repo', + issue_id='9001', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + regress_result.put() + + fix_result = osv.FixResult( + id='oss-fuzz:123', + commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + repo_url='https://repo.com/repo', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + details='DETAILS', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + fix_result.put() + + oss_fuzz.process_impact_task('oss-fuzz:123', message) + self.expect_dict_equal('basic', + ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'4c155795426727ea05575bd5904321def23c03f4', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_range(self): + """Test commit range.""" + message = mock.Mock() + message.attributes = { + 'source_id': 'oss-fuzz:123', + 'allocated_id': 'OSV-2020-1337', + } + + regress_result = osv.RegressResult( + id='oss-fuzz:123', + commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + repo_url='https://repo.com/repo', + issue_id='9001', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + regress_result.put() + + fix_result = osv.FixResult( + id='oss-fuzz:123', + commit=('b1c95a196f22d06fcf80df8c6691cd113d8fefff:' + '36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2'), + repo_url='https://repo.com/repo', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + details='DETAILS', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + fix_result.put() + + oss_fuzz.process_impact_task('oss-fuzz:123', message) + self.expect_dict_equal('range', + ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'4c155795426727ea05575bd5904321def23c03f4', + b'8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_fixed_range_too_long(self): + """Test fixed range that's too long.""" + message = mock.Mock() + message.attributes = { + 'source_id': 'oss-fuzz:123', + 'allocated_id': 'OSV-2020-1337', + } + + regress_result = osv.RegressResult( + id='oss-fuzz:123', + commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + repo_url='https://repo.com/repo', + issue_id='9001', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + regress_result.put() + + fix_result = osv.FixResult( + id='oss-fuzz:123', + commit=('eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:' + 'b587c21c36a84e16cfc6b39eb68578d43b5281ad'), + repo_url='https://repo.com/repo', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + details='DETAILS', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + fix_result.put() + + with self.assertLogs(level='WARNING') as logs: + oss_fuzz.process_impact_task('oss-fuzz:123', message) + self.assertEqual(logs.output, + ['WARNING:root:Too many commits in fix range.']) + + self.expect_dict_equal( + 'fixed_range_too_long', + ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict(), + ) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', + b'3ea6feea9bb853596c727abab309476cc07d1505', + b'4c155795426727ea05575bd5904321def23c03f4', + b'8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_zero_regression_range(self): + """Test regression range with '0:X'.""" + message = mock.Mock() + message.attributes = { + 'source_id': 'oss-fuzz:123', + 'allocated_id': 'OSV-2020-1337', + } + + regress_result = osv.RegressResult( + id='oss-fuzz:123', + commit='unknown:eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + repo_url='https://repo.com/repo', + issue_id='9001', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + regress_result.put() + + fix_result = osv.FixResult( + id='oss-fuzz:123', + commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + repo_url='https://repo.com/repo', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + details='DETAILS', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + fix_result.put() + + oss_fuzz.process_impact_task('oss-fuzz:123', message) + self.expect_dict_equal( + 'zero_regression_range', + ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict(), + ) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'4c155795426727ea05575bd5904321def23c03f4', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_simplify_range(self): + """Test simplifying commit range.""" + message = mock.Mock() + message.attributes = { + 'source_id': 'oss-fuzz:123', + 'allocated_id': 'OSV-2020-1337', + } + + regress_result = osv.RegressResult( + id='oss-fuzz:123', + commit=('a2ba949290915d445d34d0e8e9de2e7ce38198fc:' + 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'), + repo_url='https://repo.com/repo', + issue_id='9001', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + regress_result.put() + + fix_result = osv.FixResult( + id='oss-fuzz:123', + commit=('b1c95a196f22d06fcf80df8c6691cd113d8fefff:' + '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'), + repo_url='https://repo.com/repo', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + details='DETAILS', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + fix_result.put() + + oss_fuzz.process_impact_task('oss-fuzz:123', message) + self.expect_dict_equal('simplify_range', + ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) + + def test_not_fixed(self): + """Test not fixed bug.""" + message = mock.Mock() + message.attributes = { + 'source_id': 'oss-fuzz:123', + 'allocated_id': 'OSV-2020-1337', + } + + regress_result = osv.RegressResult( + id='oss-fuzz:123', + commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + repo_url='https://repo.com/repo', + issue_id='9001', + project='project', + ecosystem='ecosystem', + summary='Heap-buffer-overflow in Foo', + details='DETAILS', + severity='MEDIUM', + reference_urls=['https://url/'], + ) + regress_result.put() + + with self.assertLogs(level='WARNING') as logs: + oss_fuzz.process_impact_task('oss-fuzz:123', message) + self.assertEqual(logs.output, + ['WARNING:root:Missing FixResult for oss-fuzz:123']) + + self.expect_dict_equal('not_fixed', + ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', + b'3ea6feea9bb853596c727abab309476cc07d1505', + b'4c155795426727ea05575bd5904321def23c03f4', + b'88e5ae3c40c85b702ba89a34c29f233048abb12b', + b'8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'b587c21c36a84e16cfc6b39eb68578d43b5281ad', + b'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + +class EcosystemTest(unittest.TestCase): + """Test getting ecosystem.""" + + def setUp(self): + self.tmp_dir = tempfile.mkdtemp() + self.oss_fuzz_checkout = os.path.join(self.tmp_dir, 'oss-fuzz') + osv.ensure_updated_checkout(worker.OSS_FUZZ_GIT_URL, self.oss_fuzz_checkout) + + def tearDown(self): + shutil.rmtree(self.tmp_dir, ignore_errors=True) + + def test_get_ecosystem(self): + """Test getting ecosystems.""" + self.assertEqual('PyPI', + oss_fuzz.get_ecosystem(self.oss_fuzz_checkout, 'pillow')) + self.assertEqual( + 'Go', + oss_fuzz.get_ecosystem(self.oss_fuzz_checkout, 'golang-protobuf'), + ) + self.assertEqual( + 'OSS-Fuzz', + oss_fuzz.get_ecosystem(self.oss_fuzz_checkout, 'openssl'), + ) + + +class MarkBugInvalidTest(unittest.TestCase): + """Test mark_bug_invalid.""" + + def setUp(self): + ds_emulator.reset() + + def test_mark_bug_invalid(self): + """Test mark_bug_invalid.""" + osv.SourceRepository( + id='oss-fuzz', name='oss-fuzz', db_prefix=['OSV-']).put() + osv.Bug(db_id='OSV-2021-1', source_id='oss-fuzz:1337').put() + osv.AffectedCommits(bug_id='OSV-2021-1').put() + osv.AffectedCommits(bug_id='OSV-2021-1').put() + + message = mock.Mock() + message.attributes = { + 'type': 'invalid', + 'testcase_id': '1337', + 'source_id': '', + } + + worker.mark_bug_invalid(message) + bug = ndb.Key(osv.Bug, 'OSV-2021-1').get() + self.assertEqual(osv.BugStatus.INVALID, bug.status) + + commits = list(osv.AffectedCommits.query()) + self.assertEqual(0, len(commits)) + + +class FindOssFuzzFixViaCommitTest(unittest.TestCase): + """Test finding OSS-Fuzz fixes via commits.""" + + def setUp(self): + self.repo = pygit2.Repository('osv-test') + + def test_has_issue_id(self): + """Test identifying the commit that has the issue ID.""" + commit = oss_fuzz.find_oss_fuzz_fix_via_commit( + self.repo, + 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', + '949f182716f037e25394bbb98d39b3295d230a29', + 'oss-fuzz:133713371337', + '12345', + ) + self.assertEqual('57e58a5d7c2bb3ce0f04f17ec0648b92ee82531f', commit) + + commit = oss_fuzz.find_oss_fuzz_fix_via_commit( + self.repo, + 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', + '25147a74d8aeb27b43665530ee121a2a1b19dc58', + 'oss-fuzz:133713371337', + '12345', + ) + self.assertEqual('25147a74d8aeb27b43665530ee121a2a1b19dc58', commit) + + def test_has_testcase_id(self): + """Test identifying the commit that has the testcase ID.""" + commit = oss_fuzz.find_oss_fuzz_fix_via_commit( + self.repo, + 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', + '00514d6f244f696e750a37083163992c6a50cfd3', + 'oss-fuzz:133713371337', + '12345', + ) + + self.assertEqual('90aa4127295b2c37b5f7fcf6a9772b12c99a5212', commit) + + def test_has_oss_fuzz_reference(self): + """Test identifying the commit that has the testcase ID.""" + commit = oss_fuzz.find_oss_fuzz_fix_via_commit( + self.repo, + 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', + 'b1fa81a5d59e9b4d6e276d82fc17058f3cf139d9', + 'oss-fuzz:133713371337', + '12345', + ) + + self.assertEqual('3c5dcf6a5bec14baab3b247d369a7270232e1b83', commit) + + def test_has_multiple_oss_fuzz_reference(self): + commit = oss_fuzz.find_oss_fuzz_fix_via_commit( + self.repo, + 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', + '949f182716f037e25394bbb98d39b3295d230a29', + 'oss-fuzz:7331', + '54321', + ) + self.assertIsNone(commit) + + +class RESTUpdateTest(unittest.TestCase, tests.ExpectationTest(TEST_DATA_DIR)): + """Vulnerability update tests.""" + + def setUp(self): + self.maxDiff = None + ds_emulator.reset() + tests.mock_datetime(self) + + # Initialise fake source_repo. + self.tmp_dir = tempfile.TemporaryDirectory() + + self.source_repo = osv.SourceRepository( + type=osv.SourceRepositoryType.REST_ENDPOINT, + id='source', + name='source', + rest_api_url=MOCK_ADDRESS_FORMAT, + link=MOCK_ADDRESS_FORMAT, + editable=False, + repo_username='', + extension='.json', + ignore_git=True, + ) + self.source_repo.put() + osv.ecosystems.config.work_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), 'testdata/tmp/') + + mock_publish = mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + self.mock_publish = mock_publish.start() + self.addCleanup(mock_publish.stop) + warnings.filterwarnings('ignore', 'unclosed', ResourceWarning) + self.httpd = http.server.HTTPServer(SERVER_ADDRESS, MockDataHandler) + thread = threading.Thread(target=self.httpd.serve_forever) + thread.start() + + def tearDown(self): + self.httpd.shutdown() + self.tmp_dir.cleanup() + + def test_update(self): + """Test updating rest.""" + solo_endpoint = 'CURL-CVE-2022-32221' + '.json' + sha = '6138604b5537caab2afc0ee3e2b11f1574fdd5d8f3c6173f64048341cf55aee4' + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': solo_endpoint, + 'original_sha256': sha, + 'deleted': 'false', + } + task_runner._source_update(message) + self.mock_publish.assert_not_called() + + def test_git_ranges(self): + """Test updating rest.""" + solo_endpoint = 'CURL-CVE-2022-32221' + '.json' + sha = '6138604b5537caab2afc0ee3e2b11f1574fdd5d8f3c6173f64048341cf55aee4' + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + osv.Bug( + db_id='CURL-CVE-2022-32221', + ecosystem=[''], + source_id='source:CURL-CVE-2022-32221.json', + import_last_modified=datetime.datetime( + 2020, 1, 1, 0, 0, tzinfo=datetime.UTC), + ).put() + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': solo_endpoint, + 'original_sha256': sha, + 'deleted': 'false', + } + task_runner._source_update(message) + + self.expect_dict_equal('update_no_introduced', + osv.Bug.get_by_id('CURL-CVE-2022-32221')._to_dict()) + + @unittest.skip('Takes too long. ' + 'Also, firestore emulator cannot handle records of this size.') + def test_update_redhat_toobig(self): + """Test failure handling of a too-large Red Hat record.""" + solo_endpoint = 'RHSA-2018:3140' + '.json' + sha = 'a5cc068278ddad5f4c63d9b4f27baf59f296076306a24e850c5edde1b0232b0c' + + self.source_repo.db_prefix.append('RHSA-') + self.source_repo.put() + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': solo_endpoint, + 'original_sha256': sha, + 'deleted': 'false', + } + with self.assertLogs(level='ERROR') as logs: + task_runner._source_update(message) + + self.assertIn( + 'ERROR:root:Not writing new entities for RHSA-2018:3140 since Bug.put() failed', + logs.output[0]) + self.assertIn( + 'ERROR:root:Unexpected exception while writing RHSA-2018:3140 to Datastore', + logs.output[1]) + + self.mock_publish.assert_not_called() + + +class UpdateTest(unittest.TestCase, tests.ExpectationTest(TEST_DATA_DIR)): + """Vulnerability update tests.""" + + def mock_clone(self, repo_url, *args, **kwargs): + if 'osv-test' in repo_url: + return pygit2.Repository('osv-test') + + return self.original_clone(repo_url, *args, **kwargs) + + def _load_test_data(self, name): + """Load test data.""" + with open(os.path.join(TEST_DATA_DIR, name)) as f: + return f.read() + + def setUp(self): + self.maxDiff = None + ds_emulator.reset() + + self.original_clone = osv.clone + tests.mock_clone(self, func=self.mock_clone) + + tests.mock_datetime(self) + + # Initialise fake source_repo. + self.tmp_dir = tempfile.TemporaryDirectory() + + self.mock_repo = tests.mock_repository(self) + self.remote_source_repo_path = self.mock_repo.path + self.mock_repo.add_file( + 'OSV-123.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-123.yaml')), + ) + self.mock_repo.add_file( + 'OSV-124.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-124.yaml')), + ) + self.mock_repo.add_file( + 'OSV-125.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-125.yaml')), + ) + self.mock_repo.add_file( + 'OSV-127.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-127.yaml')), + ) + self.mock_repo.add_file( + 'OSV-128.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-128.yaml')), + ) + self.mock_repo.add_file( + 'OSV-131.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-131.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + + self.source_repo = osv.SourceRepository( + type=osv.SourceRepositoryType.GIT, + id='source', + name='source', + db_prefix=['OSV-'], + repo_url='file://' + self.remote_source_repo_path, + editable=True, + repo_username='', + ) + self.source_repo.put() + + osv.Bug( + db_id='OSV-123', + project=['blah.com/package'], + ecosystem=['Go'], + source_id='source:OSV-123.yaml', + import_last_modified=datetime.datetime( + 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + ).put() + osv.Bug( + db_id='OSV-124', + regressed='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + project=['blah.com/package'], + ecosystem=['Go'], + source_id='source:OSV-124.yaml', + import_last_modified=datetime.datetime( + 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + ).put() + osv.Bug( + db_id='OSV-125', + regressed='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + fixed='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + project=['blah.com/package'], + ecosystem=['Go'], + source_id='source:OSV-125.yaml', + import_last_modified=datetime.datetime( + 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + ).put() + osv.Bug( + db_id='OSV-127', + project=['blah.com/package'], + ecosystem=['Go'], + source_id='source:OSV-127.yaml', + import_last_modified=datetime.datetime( + 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + ).put() + osv.Bug( + db_id='OSV-131', + project=['blah.com/package'], + ecosystem=['ecosystem'], + source_id='source:OSV-131.yaml', + import_last_modified=datetime.datetime( + 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + ).put() + + mock_publish = mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') + self.mock_publish = mock_publish.start() + self.addCleanup(mock_publish.stop) + + osv.ecosystems.config.work_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), 'testdata/tmp/') + + # Add fake ecosystems used in tests to supported ecosystems. + osv.ecosystems._ecosystems._ecosystems.update({ + 'ecosystem': None, + }) + + def tearDown(self): + self.tmp_dir.cleanup() + + def test_update(self): + """Test basic update.""" + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-123.yaml', + 'original_sha256': _sha256('OSV-123.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update OSV-123', commit.message) + diff = repo.diff(commit.parents[0], commit) + + self.expect_equal('diff_update', diff.patch) + self.expect_dict_equal('update', osv.Bug.get_by_id('OSV-123')._to_dict()) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'4c155795426727ea05575bd5904321def23c03f4', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + self.mock_publish.assert_not_called() + + def test_update_limit(self): + """Test basic update with limit events.""" + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-128.yaml', + 'original_sha256': _sha256('OSV-128.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update OSV-128', commit.message) + diff = repo.diff(commit.parents[0], commit) + + self.expect_equal('diff_update_limit', diff.patch) + self.expect_dict_equal('update_limit', + osv.Bug.get_by_id('OSV-128')._to_dict()) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'a2ba949290915d445d34d0e8e9de2e7ce38198fc', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'e1b045257bc5ca2a11d0476474f45ef77a0366c7', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_update_add_fix(self): + """Test basic update adding a fix.""" + fix_result = osv.FixResult( + id='source:OSV-124.yaml', + repo_url='https://osv-test/repo/url', + commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + ) + fix_result.put() + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-124.yaml', + 'original_sha256': _sha256('OSV-124.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update OSV-124', commit.message) + diff = repo.diff(commit.parents[0], commit) + + self.expect_equal('diff_update_add_fix', diff.patch) + self.expect_dict_equal('update_add_fix', + osv.Bug.get_by_id('OSV-124')._to_dict()) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'4c155795426727ea05575bd5904321def23c03f4', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_update_no_introduced(self): + """Test update vulnerability with no introduced commit.""" + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-127.yaml', + 'original_sha256': _sha256('OSV-127.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update OSV-127', commit.message) + diff = repo.diff(commit.parents[0], commit) + + self.expect_dict_equal('update_no_introduced', + osv.Bug.get_by_id('OSV-127')._to_dict()) + self.expect_equal('diff_update_no_introduced', diff.patch) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'00514d6f244f696e750a37083163992c6a50cfd3', + b'25147a74d8aeb27b43665530ee121a2a1b19dc58', + b'3c5dcf6a5bec14baab3b247d369a7270232e1b83', + b'4c155795426727ea05575bd5904321def23c03f4', + b'57e58a5d7c2bb3ce0f04f17ec0648b92ee82531f', + b'90aa4127295b2c37b5f7fcf6a9772b12c99a5212', + b'949f182716f037e25394bbb98d39b3295d230a29', + b'a2ba949290915d445d34d0e8e9de2e7ce38198fc', + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'b1fa81a5d59e9b4d6e276d82fc17058f3cf139d9', + b'e1b045257bc5ca2a11d0476474f45ef77a0366c7', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'f0cc40d8c3dabb27c2cfe26f1764305abc91a0b9', + b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', + b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_update_new(self): + """Test update with new vulnerability added.""" + self.mock_repo.add_file( + 'OSV-126.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-126.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-126.yaml', + 'original_sha256': _sha256('OSV-126.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update OSV-126', commit.message) + + self.expect_dict_equal('update_new', + osv.Bug.get_by_id('OSV-126')._to_dict()) + + def test_update_delete(self): + """Test deletion.""" + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + self.mock_repo.delete_file('OSV-123.yaml') + self.mock_repo.commit('User', 'user@email') + + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-123.yaml', + 'original_sha256': _sha256('OSV-123.yaml'), + 'deleted': 'true', + } + task_runner._source_update(message) + bug = osv.Bug.get_by_id('OSV-123') + self.assertEqual(osv.BugStatus.INVALID, bug.status) + + def test_update_no_changes(self): + """Test basic update (with no changes).""" + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-125.yaml', + 'original_sha256': _sha256('OSV-125.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('user@email', commit.author.email) + self.assertEqual('User', commit.author.name) + + def test_update_conflict(self): + """Test basic update with a conflict.""" + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-123.yaml', + 'original_sha256': 'invalid', + 'deleted': 'false', + } + + with self.assertLogs(level='WARNING') as logs: + task_runner._source_update(message) + self.assertEqual( + logs.output, + [ + f'WARNING:root:sha256sum of OSV-123.yaml no longer matches (expected=invalid vs current={_sha256("OSV-123.yaml")}).' + ], + ) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + # Latest commit is still the user commit. + self.assertEqual('user@email', commit.author.email) + self.assertEqual('User', commit.author.name) + + def test_update_conflict_while_pushing(self): + """Test basic update with a conflict while pushing.""" + original_push_source_changes = osv.push_source_changes + + def mock_push_source_changes(*args, **kwargs): + self.mock_repo.add_file('OSV-123.yaml', 'changed') + self.mock_repo.commit('Another user', 'user@email') + + original_push_source_changes(*args, **kwargs) + + patcher = mock.patch('osv.push_source_changes') + self.addCleanup(patcher.stop) + patcher.start().side_effect = mock_push_source_changes + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-123.yaml', + 'original_sha256': _sha256('OSV-123.yaml'), + 'deleted': 'false', + } + + with self.assertLogs(level='WARNING') as logs: + task_runner._source_update(message) + + self.assertEqual(len(logs.output), 4) + self.assertEqual( + logs.output[0], + 'ERROR:absl:Code extraction failed for OSV-123 (Unsupported ecosystem: Go). Skipping affected[0]', + ) + self.assertEqual( + logs.output[1], + 'WARNING:root:Failed to push: cannot push because a reference that you are trying to update on the remote contains commits that are not present locally.', + ) + self.assertRegex( + logs.output[2], + r'WARNING:root:Upstream hash for .*/OSV-123.yaml changed \(expected=.* vs current=.*\)', + ) + self.assertEqual( + logs.output[3], + 'WARNING:root:Discarding changes for OSV-123 due to conflicts.', + ) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + # Latest commit is still the user commit. + self.assertEqual('user@email', commit.author.email) + self.assertEqual('Another user', commit.author.name) + + def test_update_pypi(self): + """Test a PyPI entry.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('PYSEC-') + self.source_repo.put() + + self.mock_repo.add_file( + 'PYSEC-123.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'PYSEC-123.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'PYSEC-123.yaml', + 'original_sha256': _sha256('PYSEC-123.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update PYSEC-123', commit.message) + diff = repo.diff(commit.parents[0], commit) + self.expect_equal('diff_pypi', diff.patch) + + self.expect_dict_equal('update_pypi', + ndb.Key(osv.Bug, 'PYSEC-123').get()._to_dict()) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + self.expect_equal('pypi_pubsub_calls', self.mock_publish.mock_calls) + + def test_normalize_pypi(self): + """Test a PyPI entry normalizes as expected.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('PYSEC-') + self.source_repo.put() + + self.mock_repo.add_file( + 'PYSEC-456.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'PYSEC-456.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'PYSEC-456.yaml', + 'original_sha256': _sha256('PYSEC-456.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + diff = repo.diff(commit.parents[0], commit) + + self.expect_equal('diff_normalized_pypi', diff.patch) + + self.expect_dict_equal( + 'normalized_pypi', + ndb.Key(osv.Bug, 'PYSEC-456').get()._to_dict(), + ) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + self.expect_equal('normalized_pypi_pubsub_calls', + self.mock_publish.mock_calls) + + def test_update_last_affected(self): + """Test a PyPI entry.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('PYSEC-') + self.source_repo.put() + + self.mock_repo.add_file( + 'PYSEC-124.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'PYSEC-124.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'PYSEC-124.yaml', + 'original_sha256': _sha256('PYSEC-124.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update PYSEC-124', commit.message) + diff = repo.diff(commit.parents[0], commit) + self.expect_equal('diff_last_affected', diff.patch) + + self.expect_dict_equal( + 'update_last_affected', + ndb.Key(osv.Bug, 'PYSEC-124').get()._to_dict(), + ) + + def test_update_maven(self): + """Test updating maven.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('GHSA-') + self.source_repo.put() + + self.mock_repo.add_file( + 'GHSA-838r-hvwh-24h8.json', + self._load_test_data( + os.path.join(TEST_DATA_DIR, 'GHSA-838r-hvwh-24h8.json')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'GHSA-838r-hvwh-24h8.json', + 'original_sha256': _sha256('GHSA-838r-hvwh-24h8.json'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update GHSA-838r-hvwh-24h8', commit.message) + diff = repo.diff(commit.parents[0], commit) + self.expect_equal('diff_maven', diff.patch) + + self.expect_dict_equal( + 'update_maven', + ndb.Key(osv.Bug, 'GHSA-838r-hvwh-24h8').get()._to_dict(), + ) + + self.mock_publish.assert_not_called() + + def test_update_linux(self): + """Test a Linux entry.""" + self.skipTest("Prefix not supported by schema") + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('LINUX-') + self.source_repo.put() + + self.mock_repo.add_file( + 'LINUX-123.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'LINUX-123.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'LINUX-123.yaml', + 'original_sha256': _sha256('LINUX-123.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + self.expect_dict_equal( + 'update_linux', + ndb.Key(osv.Bug, 'LINUX-123').get()._to_dict(), + ) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_update_bucket(self): + """Test bucket entries.""" + self.source_repo.type = osv.SourceRepositoryType.BUCKET + self.source_repo.bucket = TEST_BUCKET + self.source_repo.editable = False + self.source_repo.db_prefix.append('GO-') + self.source_repo.put() + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'a/b/test.json', + 'original_sha256': ('62966a80f6f9f54161803211069216177' + '37340a47f43356ee4a1cabe8f089869'), + 'deleted': 'false', + } + task_runner._source_update(message) + + self.expect_dict_equal('update_bucket_0', + osv.Bug.get_by_id('GO-2021-0085')._to_dict()) + + def test_update_debian(self): + """Test updating debian.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('DSA-') + self.source_repo.put() + + self.mock_repo.add_file( + 'DSA-3029-1.json', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'DSA-3029-1.json')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'DSA-3029-1.json', + 'original_sha256': _sha256('DSA-3029-1.json'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update DSA-3029-1', commit.message) + diff = repo.diff(commit.parents[0], commit) + + self.expect_equal('diff_debian', diff.patch) + + self.expect_dict_equal( + 'update_debian', + ndb.Key(osv.Bug, 'DSA-3029-1').get()._to_dict(), + ) + + self.mock_publish.assert_not_called() + + def test_update_alpine(self): + """Test updating alpine.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('CVE-') + self.source_repo.put() + + self.mock_repo.add_file( + 'CVE-2022-27449.json', + self._load_test_data( + os.path.join(TEST_DATA_DIR, 'CVE-2022-27449.json')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'CVE-2022-27449.json', + 'original_sha256': _sha256('CVE-2022-27449.json'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update CVE-2022-27449', commit.message) + diff = repo.diff(commit.parents[0], commit) + + self.expect_equal('diff_alpine', diff.patch) + + self.expect_dict_equal( + 'update_alpine', + ndb.Key(osv.Bug, 'CVE-2022-27449').get()._to_dict(), + ) + + self.mock_publish.assert_not_called() + + def test_update_android(self): + """Test updating Android through bucket entries.""" + self.source_repo.type = osv.SourceRepositoryType.BUCKET + self.source_repo.bucket = TEST_BUCKET + self.source_repo.editable = False + self.source_repo.db_prefix.append('ASB-A-') + self.source_repo.put() + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'a/b/android-test.json', + 'original_sha256': ('12453f85cd87bc1d465e0d013db572c0' + '1f7fb7de3b3a33de94ebcc7bd0f23a14'), + 'deleted': 'false', + } + + task_runner._source_update(message) + self.expect_dict_equal('update_bucket_2', + osv.Bug.get_by_id('ASB-A-153358911')._to_dict()) + + def test_update_bad_ecosystem_new(self): + """Test adding from an unsupported ecosystem.""" + self.mock_repo.add_file( + 'OSV-129.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-129.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-129.yaml', + 'original_sha256': _sha256('OSV-129.yaml'), + 'deleted': 'false', + } + + with self.assertLogs(level='WARNING'): + task_runner._source_update(message) + + bug = osv.Bug.get_by_id('OSV-129') + self.assertEqual(osv.BugStatus.INVALID, bug.status) + + def test_update_partly_bad_ecosystem_new(self): + """Test adding vuln with both supported and unsupported ecosystem.""" + self.mock_repo.add_file( + 'OSV-130.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'OSV-130.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-130.yaml', + 'original_sha256': _sha256('OSV-130.yaml'), + 'deleted': 'false', + } + + with self.assertLogs(level='WARNING'): + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + + self.assertEqual('infra@osv.dev', commit.author.email) + self.assertEqual('OSV', commit.author.name) + self.assertEqual('Update OSV-130', commit.message) + + self.expect_dict_equal( + 'update_partly_bad_ecosystem_new', + osv.Bug.get_by_id('OSV-130')._to_dict(), + ) + + def test_update_partly_bad_ecosystem_delete(self): + """Test removal of only supported ecosystem in vulnerability with + unsupported and supported ecosystems. + """ + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-131.yaml', + 'original_sha256': _sha256('OSV-131.yaml'), + 'deleted': 'false', + } + + with self.assertLogs(level='WARNING'): + task_runner._source_update(message) + + bug = osv.Bug.get_by_id('OSV-131') + self.assertEqual(osv.BugStatus.INVALID, bug.status) + + def test_update_bucket_cve(self): + """Test a bucket entry that is a converted CVE and doesn't have an ecosystem.""" + self.source_repo.type = osv.SourceRepositoryType.BUCKET + self.source_repo.bucket = TEST_BUCKET + self.source_repo.editable = False + self.source_repo.db_prefix.append('CVE-') + self.source_repo.put() + + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'a/b/CVE-2016-15011.json', + 'original_sha256': + ('88696731b137858e82177bdd9fe938eaa4e75507a2c9228fd21d98f91963ae90' + ), + 'deleted': 'false', + } + task_runner._source_update(message) + + processed_result = osv.Bug.get_by_id('CVE-2016-15011') + + self.expect_dict_equal('update_bucket_cve', processed_result._to_dict()) + + def test_last_affected_git(self): + """Basic last_affected GIT enumeration.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = True + # detect_cherrypicks should not cause result in cherrypick detection for + # `last_affected`, since equivalent `last_affected` across different + # branches likely no have relation to the actual vulnerable range. + self.source_repo.detect_cherrypicks = True + self.source_repo.put() + + self.mock_repo.add_file( + 'OSV-TEST-last-affected-01.yaml', + self._load_test_data( + os.path.join(TEST_DATA_DIR, 'OSV-TEST-last-affected-01.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-TEST-last-affected-01.yaml', + 'original_sha256': _sha256('OSV-TEST-last-affected-01.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + repo = pygit2.Repository(self.remote_source_repo_path) + commit = repo.head.peel() + diff = repo.diff(commit.parents[0], commit) + + self.expect_equal('diff_last_affected_git', diff.patch) + + self.expect_dict_equal( + 'last_affected_git', + ndb.Key(osv.Bug, 'OSV-TEST-last-affected-01').get()._to_dict(), + ) + + affected_commits = list(osv.AffectedCommits.query()) + self.assertEqual(1, len(affected_commits)) + affected_commits = affected_commits[0] + + self.assertCountEqual( + [ + b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', + b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', + b'8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', + ], + [codecs.encode(commit, 'hex') for commit in affected_commits.commits], + ) + + def test_invalid_prefix(self): + """Test attempting to create a bug with a invalid db_prefix.""" + with self.assertRaises(ValueError): + # Default db_prefix is `OSV-` + osv.Bug( + db_id='BLAH-131', + project=['blah.com/package'], + ecosystem=['ecosystem'], + source_id='source:OSV-131.yaml', + import_last_modified=datetime.datetime( + 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), + source_of_truth=osv.SourceOfTruth.SOURCE_REPO, + ).put() + + def test_dont_index_too_many_git_versions(self): + """Test that we don't index too many versions from Git.""" + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = True + self.source_repo.detect_cherrypicks = True + self.source_repo.put() + + # Use any valid OSV input test file here. + self.mock_repo.add_file( + 'OSV-TEST-last-affected-01.yaml', + self._load_test_data( + os.path.join(TEST_DATA_DIR, 'OSV-TEST-last-affected-01.yaml')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-TEST-last-affected-01.yaml', + 'original_sha256': _sha256('OSV-TEST-last-affected-01.yaml'), + 'deleted': 'false', + } + task_runner._source_update(message) + + bug = ndb.Key(osv.Bug, 'OSV-TEST-last-affected-01').get() + + # Manually append versions over the expected version limit. + bug.affected_packages[0].versions = ['%05d' % i for i in range(5001)] + bug.put() + self.expect_dict_equal('dont_index_too_many_git_versions', bug._to_dict()) + + def test_update_clears_stale_import_finding(self): + """A subsequent successful update removes the now stale import finding.""" + + # Add a pre-existing record import finding. + + osv.ImportFinding( + bug_id='OSV-123', + source='source', + findings=[osv.ImportFindings.INVALID_JSON], + first_seen=osv.utcnow(), + last_attempt=osv.utcnow()).put() + + # Simulate a successful record update. + + self.test_update() + + # Check the pre-existing finding is no longer present. + + self.assertIsNone( + osv.ImportFinding.get_by_id('OSV-123'), + 'Stale import finding still present after successful record processing') + + def test_ubuntu_severity(self): + """Test whether Ubuntu severity is parsed as expected.""" + + self.source_repo.ignore_git = False + self.source_repo.versions_from_repo = False + self.source_repo.detect_cherrypicks = False + self.source_repo.db_prefix.append('UBUNTU-CVE') + self.source_repo.put() + + self.mock_repo.add_file( + 'UBUNTU-CVE-2025-38094.json', + self._load_test_data( + os.path.join(TEST_DATA_DIR, 'UBUNTU-CVE-2025-38094.json')), + ) + self.mock_repo.commit('User', 'user@email') + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'UBUNTU-CVE-2025-38094.json', + 'original_sha256': _sha256('UBUNTU-CVE-2025-38094.json'), + 'deleted': 'false', + } + task_runner._source_update(message) + + bug = ndb.Key(osv.Bug, 'UBUNTU-CVE-2025-38094').get() + self.expect_dict_equal('ubuntu_severity_type', bug._to_dict()) + + +def setUpModule(): + """Set up the test module.""" + print("Starting Datastore Emulator for the test suite...") + global ds_emulator, ndb_client + # Start the emulator BEFORE creating the ndb client + ds_emulator = unittest.enterModuleContext(tests.datastore_emulator()) + ndb_client = ndb.Client() + unittest.enterModuleContext(ndb_client.context(cache_policy=False)) + + +if __name__ == '__main__': + unittest.main() diff --git a/gcp/workers/recoverer/recoverer.py b/gcp/workers/recoverer/recoverer.py index 36bba14454c..3ceee794f5d 100644 --- a/gcp/workers/recoverer/recoverer.py +++ b/gcp/workers/recoverer/recoverer.py @@ -19,14 +19,18 @@ import logging import os import sys +import time from google.cloud import ndb from google.cloud import pubsub_v1 import osv +import osv.models +import osv.sources from osv.logs import setup_gcp_logging _FAILED_TASKS_SUBSCRIPTION = 'recovery' +_TASKS_TOPIC = 'tasks' _ndb_client = None @@ -54,6 +58,7 @@ def handle_gcs_retry(message: pubsub_v1.types.PubsubMessage) -> bool: } }) return True + logging.info('gcs_retry: vulnerability: %s', vuln.id) modified = vuln.modified.ToDatetime(datetime.UTC) bucket = osv.gcs.get_osv_bucket() path = os.path.join(osv.gcs.VULN_PB_PATH, vuln.id + '.pb') @@ -80,24 +85,42 @@ def handle_gcs_retry(message: pubsub_v1.types.PubsubMessage) -> bool: def handle_gcs_missing(message: pubsub_v1.types.PubsubMessage) -> bool: """Handle a failed GCS read.""" vuln_id = message.attributes.get('id') + logging.info('gcs_missing: vulnerability: %s', vuln_id) if not vuln_id: logging.error('gcs_missing: message missing id attribute: %s', message) return True - # Re-put the Bug to regenerate the GCS & Datastore entities + with ndb_client().context(): - bug = osv.Bug.get_by_id(vuln_id) - if not bug: - logging.error('gcs_missing: Bug entity not found for %s', vuln_id) - # TODO(michaelkedar): What can we do in this case? + vuln = osv.Vulnerability.get_by_id(vuln_id) + if not vuln: + logging.error('gcs_missing: Vulnerability entity not found for %s', + vuln_id) return True + try: - bug.put() + source, path = osv.sources.parse_source_id(vuln.source_id) + except ValueError: + logging.error('gcs_missing: invalid source_id for %s: %s', vuln_id, + vuln.source_id) return True - except Exception: - logging.exception('gcs_missing: failed to put Bug entity for %s', vuln_id) - return False - # TODO(michaelkedar): We will want to stop using the Bug entity eventually. - # This will need to trigger a reimport of the record from the datasource. + + logging.info('gcs_missing: triggering re-import for %s (%s)', vuln_id, + vuln.source_id) + publisher = pubsub_v1.PublisherClient() + project = os.environ['GOOGLE_CLOUD_PROJECT'] + topic_path = publisher.topic_path(project, _TASKS_TOPIC) + publisher.publish( + topic_path, + data=b'', + type='update', + source=source, + path=path, + original_sha256='', + deleted='false', + skip_hash_check='true', + req_timestamp=str(int(time.time()))) + + return True def handle_gcs_gen_mismatch(message: pubsub_v1.types.PubsubMessage) -> bool: @@ -106,6 +129,7 @@ def handle_gcs_gen_mismatch(message: pubsub_v1.types.PubsubMessage) -> bool: """ vuln_id = message.attributes.get('id') field = message.attributes.get('field') + logging.info('gcs_gen_mismatch: vulnerability: %s, field: %s', vuln_id, field) if not vuln_id or not field: logging.error('gcs_gen_mismatch: message missing id or field attribute: %s', message) diff --git a/gcp/workers/recoverer/recoverer_test.py b/gcp/workers/recoverer/recoverer_test.py index c0c5d5cfa07..fb392bd0dd9 100644 --- a/gcp/workers/recoverer/recoverer_test.py +++ b/gcp/workers/recoverer/recoverer_test.py @@ -15,6 +15,7 @@ import datetime import os import unittest +import unittest.mock from google.cloud import ndb from google.cloud import pubsub_v1 @@ -53,6 +54,11 @@ def setUp(self): import_last_modified=datetime.datetime( 2025, 1, 1, tzinfo=datetime.UTC), ).put() + osv.Vulnerability( + id='TEST-123', + source_id='test:TEST-123.yaml', + modified=datetime.datetime(2025, 1, 1, tzinfo=datetime.UTC), + ).put() return super().setUp() def test_handle_gcs_retry(self): @@ -100,19 +106,19 @@ def test_handle_gcs_retry_invalid_data(self): self.assertEqual(1, len(cm.output)) self.assertIn('failed to decode protobuf', cm.output[0]) - def test_handle_gcs_missing(self): + @unittest.mock.patch('google.cloud.pubsub_v1.PublisherClient') + def test_handle_gcs_missing(self, mock_publisher): """Test standard handle_gcs_missing""" - # Going to pretend this is missing, we'll check the contents don't change. - original_result = osv.gcs.get_by_id_with_generation('TEST-123') - self.assertIsNotNone(original_result) - original_data, original_generation = original_result message = pubsub_v1.types.PubsubMessage(attributes={'id': 'TEST-123'}) self.assertTrue(recoverer.handle_gcs_missing(message)) - new_result = osv.gcs.get_by_id_with_generation('TEST-123') - self.assertIsNotNone(new_result) - new_data, new_generation = new_result - self.assertEqual(original_data, new_data) - self.assertNotEqual(original_generation, new_generation) + + # Check that the update message was published + mock_publisher.return_value.publish.assert_called_once() + call_args = mock_publisher.return_value.publish.call_args + self.assertEqual(call_args.kwargs['type'], 'update') + self.assertEqual(call_args.kwargs['source'], 'test') + self.assertEqual(call_args.kwargs['path'], 'TEST-123.yaml') + self.assertEqual(call_args.kwargs['skip_hash_check'], 'true') def test_handle_gcs_gen_mismatch_aliases(self): """Test handle_gcs_gen_mismatch for aliases.""" diff --git a/gcp/workers/recoverer/run_tests.sh b/gcp/workers/recoverer/run_tests.sh index 799c5f26e88..a4fe3d75a56 100755 --- a/gcp/workers/recoverer/run_tests.sh +++ b/gcp/workers/recoverer/run_tests.sh @@ -15,5 +15,8 @@ cd ../worker -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python ../recoverer/recoverer_test.py diff --git a/gcp/workers/worker/poetry.lock b/gcp/workers/worker/poetry.lock index 4e46f044ca9..eedac8c11bb 100644 --- a/gcp/workers/worker/poetry.lock +++ b/gcp/workers/worker/poetry.lock @@ -14,14 +14,14 @@ files = [ [[package]] name = "astroid" -version = "4.0.2" +version = "4.0.3" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.10.0" groups = ["dev"] files = [ - {file = "astroid-4.0.2-py3-none-any.whl", hash = "sha256:d7546c00a12efc32650b19a2bb66a153883185d3179ab0d4868086f807338b9b"}, - {file = "astroid-4.0.2.tar.gz", hash = "sha256:ac8fb7ca1c08eb9afec91ccc23edbd8ac73bb22cbdd7da1d488d9fb8d6579070"}, + {file = "astroid-4.0.3-py3-none-any.whl", hash = "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14"}, + {file = "astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3"}, ] [[package]] @@ -36,28 +36,16 @@ files = [ {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] -[[package]] -name = "cachetools" -version = "6.2.4" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "cachetools-6.2.4-py3-none-any.whl", hash = "sha256:69a7a52634fed8b8bf6e24a050fb60bff1c9bd8f6d24572b99c32d4e71e62a51"}, - {file = "cachetools-6.2.4.tar.gz", hash = "sha256:82c5c05585e70b6ba2d3ae09ea60b79548872185d2f24ae1f2709d37299fd607"}, -] - [[package]] name = "certifi" -version = "2025.11.12" +version = "2026.1.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, - {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, + {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, ] [[package]] @@ -293,16 +281,93 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "cryptography" +version = "46.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, + {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, + {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, + {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, + {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, + {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, + {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, + {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, + {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, + {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, + {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, +] + +[package.dependencies] +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" description = "serialize all of Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, - {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, ] [package.extras] @@ -311,14 +376,14 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "google-api-core" -version = "2.28.1" +version = "2.29.0" description = "Google API client core library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c"}, - {file = "google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8"}, + {file = "google_api_core-2.29.0-py3-none-any.whl", hash = "sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9"}, + {file = "google_api_core-2.29.0.tar.gz", hash = "sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7"}, ] [package.dependencies] @@ -338,14 +403,14 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] [[package]] name = "google-api-python-client" -version = "2.187.0" +version = "2.188.0" description = "Google API Client Library for Python" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_api_python_client-2.187.0-py3-none-any.whl", hash = "sha256:d8d0f6d85d7d1d10bdab32e642312ed572bdc98919f72f831b44b9a9cebba32f"}, - {file = "google_api_python_client-2.187.0.tar.gz", hash = "sha256:e98e8e8f49e1b5048c2f8276473d6485febc76c9c47892a8b4d1afa2c9ec8278"}, + {file = "google_api_python_client-2.188.0-py3-none-any.whl", hash = "sha256:3cad1b68f9d48b82b93d77927e8370a6f43f33d97848242601f14a93a1c70ef5"}, + {file = "google_api_python_client-2.188.0.tar.gz", hash = "sha256:5c469db6614f071009e3e5bb8b6aeeccae3beb3647fa9c6cd97f0d551edde0b6"}, ] [package.dependencies] @@ -357,30 +422,30 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.45.0" +version = "2.48.0" description = "Google Authentication Library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "google_auth-2.45.0-py2.py3-none-any.whl", hash = "sha256:82344e86dc00410ef5382d99be677c6043d72e502b625aa4f4afa0bdacca0f36"}, - {file = "google_auth-2.45.0.tar.gz", hash = "sha256:90d3f41b6b72ea72dd9811e765699ee491ab24139f34ebf1ca2b9cc0c38708f3"}, + {file = "google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f"}, + {file = "google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce"}, ] [package.dependencies] -cachetools = ">=2.0.0,<7.0" +cryptography = ">=38.0.3" pyasn1-modules = ">=0.2.1" rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] -cryptography = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)"] -enterprise-cert = ["cryptography", "pyopenssl"] -pyjwt = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyjwt (>=2.0)"] -pyopenssl = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +cryptography = ["cryptography (>=38.0.3)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0)"] -testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "mock", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] urllib3 = ["packaging", "urllib3"] [[package]] @@ -401,14 +466,14 @@ httplib2 = ">=0.19.0,<1.0.0" [[package]] name = "google-cloud-appengine-logging" -version = "1.7.0" +version = "1.8.0" description = "Google Cloud Appengine Logging API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_appengine_logging-1.7.0-py3-none-any.whl", hash = "sha256:cfd28bc61a030008381a646d112ebe2734bf72abc8c12afc47d035a2c9b041fe"}, - {file = "google_cloud_appengine_logging-1.7.0.tar.gz", hash = "sha256:ea9ce73430cfc99f8957fd7df97733f9a759d4caab65e19d63a7474f012ffd94"}, + {file = "google_cloud_appengine_logging-1.8.0-py3-none-any.whl", hash = "sha256:a4ce9ce94a9fd8c89ed07fa0b06fcf9ea3642f9532a1be1a8c7b5f82c0a70ec6"}, + {file = "google_cloud_appengine_logging-1.8.0.tar.gz", hash = "sha256:84b705a69e4109fc2f68dfe36ce3df6a34d5c3d989eee6d0ac1b024dda0ba6f5"}, ] [package.dependencies] @@ -478,14 +543,14 @@ libcst = ["libcst (>=0.2.5)"] [[package]] name = "google-cloud-iam" -version = "2.20.0" +version = "2.21.0" description = "Google Cloud Iam API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_iam-2.20.0-py3-none-any.whl", hash = "sha256:643fcf6db3100772f222c7173bc1af15541a05ec1c43785191e835146ed150b8"}, - {file = "google_cloud_iam-2.20.0.tar.gz", hash = "sha256:06568ed8313f59fac46d21a5aae4c54eb1dda9f6bcecf2736c58ab1065dc9173"}, + {file = "google_cloud_iam-2.21.0-py3-none-any.whl", hash = "sha256:1b4a21302b186a31f3a516ccff303779638308b7c801fb61a2406b6a0c6293c4"}, + {file = "google_cloud_iam-2.21.0.tar.gz", hash = "sha256:fc560527e22b97c6cbfba0797d867cf956c727ba687b586b9aa44d78e92281a3"}, ] [package.dependencies] @@ -783,18 +848,18 @@ protobuf = ">=6.31.1,<7.0.0" [[package]] name = "httplib2" -version = "0.31.0" +version = "0.31.2" description = "A comprehensive HTTP client library." optional = false python-versions = ">=3.6" groups = ["main"] files = [ - {file = "httplib2-0.31.0-py3-none-any.whl", hash = "sha256:b9cd78abea9b4e43a7714c6e0f8b6b8561a6fc1e95d5dbd367f5bf0ef35f5d24"}, - {file = "httplib2-0.31.0.tar.gz", hash = "sha256:ac7ab497c50975147d4f7b1ade44becc7df2f8954d42b38b3d69c515f531135c"}, + {file = "httplib2-0.31.2-py3-none-any.whl", hash = "sha256:dbf0c2fa3862acf3c55c078ea9c0bc4481d7dc5117cae71be9514912cf9f8349"}, + {file = "httplib2-0.31.2.tar.gz", hash = "sha256:385e0869d7397484f4eab426197a4c020b606edd43372492337c0b4010ae5d24"}, ] [package.dependencies] -pyparsing = ">=3.0.4,<4" +pyparsing = ">=3.1,<4" [[package]] name = "idna" @@ -887,21 +952,21 @@ ply = "*" [[package]] name = "jsonschema" -version = "4.25.1" +version = "4.26.0" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, - {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, ] [package.dependencies] attrs = ">=22.2.0" jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" -rpds-py = ">=0.7.1" +rpds-py = ">=0.25.0" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1270,14 +1335,14 @@ test = ["pytest"] [[package]] name = "packaging" -version = "25.0" +version = "26.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, ] [[package]] @@ -1344,34 +1409,34 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "6.33.2" +version = "6.33.4" description = "" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d"}, - {file = "protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4"}, - {file = "protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f"}, - {file = "protobuf-6.33.2-cp39-cp39-win32.whl", hash = "sha256:7109dcc38a680d033ffb8bf896727423528db9163be1b6a02d6a49606dcadbfe"}, - {file = "protobuf-6.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:2981c58f582f44b6b13173e12bb8656711189c2a70250845f264b877f00b1913"}, - {file = "protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c"}, - {file = "protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4"}, + {file = "protobuf-6.33.4-cp310-abi3-win32.whl", hash = "sha256:918966612c8232fc6c24c78e1cd89784307f5814ad7506c308ee3cf86662850d"}, + {file = "protobuf-6.33.4-cp310-abi3-win_amd64.whl", hash = "sha256:8f11ffae31ec67fc2554c2ef891dcb561dae9a2a3ed941f9e134c2db06657dbc"}, + {file = "protobuf-6.33.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2fe67f6c014c84f655ee06f6f66213f9254b3a8b6bda6cda0ccd4232c73c06f0"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:757c978f82e74d75cba88eddec479df9b99a42b31193313b75e492c06a51764e"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c7c64f259c618f0bef7bee042075e390debbf9682334be2b67408ec7c1c09ee6"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:3df850c2f8db9934de4cf8f9152f8dc2558f49f298f37f90c517e8e5c84c30e9"}, + {file = "protobuf-6.33.4-cp39-cp39-win32.whl", hash = "sha256:955478a89559fa4568f5a81dce77260eabc5c686f9e8366219ebd30debf06aa6"}, + {file = "protobuf-6.33.4-cp39-cp39-win_amd64.whl", hash = "sha256:0f12ddbf96912690c3582f9dffb55530ef32015ad8e678cd494312bd78314c4f"}, + {file = "protobuf-6.33.4-py3-none-any.whl", hash = "sha256:1fe3730068fcf2e595816a6c34fe66eeedd37d51d0400b72fabc848811fdc1bc"}, + {file = "protobuf-6.33.4.tar.gz", hash = "sha256:dc2e61bca3b10470c1912d166fe0af67bfc20eb55971dcef8dfa48ce14f0ed91"}, ] [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, - {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, + {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"}, + {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"}, ] [[package]] @@ -1391,15 +1456,15 @@ pyasn1 = ">=0.6.1,<0.7.0" [[package]] name = "pycparser" -version = "2.23" +version = "3.0" description = "C parser in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] markers = "implementation_name != \"PyPy\"" files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, ] [[package]] @@ -1528,14 +1593,14 @@ files = [ [[package]] name = "pyparsing" -version = "3.3.1" +version = "3.3.2" description = "pyparsing - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "pyparsing-3.3.1-py3-none-any.whl", hash = "sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82"}, - {file = "pyparsing-3.3.1.tar.gz", hash = "sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c"}, + {file = "pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d"}, + {file = "pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc"}, ] [package.extras] @@ -1890,14 +1955,14 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomlkit" -version = "0.13.3" +version = "0.14.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, ] [[package]] @@ -1938,14 +2003,14 @@ files = [ [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] @@ -2020,4 +2085,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.13,<3.14" -content-hash = "e70601c806d065f3c09c9b2a2204743e2f330f294d68d5b30e9b392dce900524" +content-hash = "63b5812d3a1cfdbaa311d604861ce414e94d416ae0e6f97658161faac0525073" diff --git a/gcp/workers/worker/pyproject.toml b/gcp/workers/worker/pyproject.toml index 6e88a79a3d4..f252a08bc89 100644 --- a/gcp/workers/worker/pyproject.toml +++ b/gcp/workers/worker/pyproject.toml @@ -3,7 +3,7 @@ name = "worker" requires-python = ">=3.13,<3.14" dependencies = [ "google-auth-httplib2==0.3.0", - "google-api-python-client==2.187.0", + "google-api-python-client==2.188.0", "google-cloud-pubsub==2.34.0", "google-cloud-ndb==2.4.0", "google-cloud-storage==2.19.0", @@ -12,7 +12,7 @@ dependencies = [ "packageurl-python==0.17.6", "pygit2==1.19.1", "requests==2.32.5", - "jsonschema==4.25.1", + "jsonschema==4.26.0", "vanir==1.0.2", "osv", ] diff --git a/gcp/workers/worker/run_tests.sh b/gcp/workers/worker/run_tests.sh index 23ef251dbb3..39d14578035 100755 --- a/gcp/workers/worker/run_tests.sh +++ b/gcp/workers/worker/run_tests.sh @@ -15,5 +15,8 @@ export GOOGLE_CLOUD_PROJECT=fake-project123 -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python worker_test.py diff --git a/gcp/workers/worker/testdata/GSD-123.yaml b/gcp/workers/worker/testdata/GSD-123.yaml new file mode 100644 index 00000000000..ae7ed14ddec --- /dev/null +++ b/gcp/workers/worker/testdata/GSD-123.yaml @@ -0,0 +1,19 @@ +id: GSD-123 +summary: A vulnerability +details: | + Blah blah blah + Blah +modified: 2022-10-07T18:59:00Z +references: +- type: WEB + url: https://ref.com/ref +affected: +- package: + name: Kernel + ecosystem: Linux + ranges: + - type: GIT + repo: https://osv-test/repo/url + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 diff --git a/gcp/workers/worker/testdata/RESTUpdateTest_update_no_introduced.txt b/gcp/workers/worker/testdata/RESTUpdateTest_update_no_introduced.txt index 2c52b812385..15e5b16f2bb 100644 --- a/gcp/workers/worker/testdata/RESTUpdateTest_update_no_introduced.txt +++ b/gcp/workers/worker/testdata/RESTUpdateTest_update_no_introduced.txt @@ -1,364 +1,192 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '7-10', - '7-10-1', - '7-10-2', - '7-10-3', - '7-10-4', - '7-10-5', - '7-10-6', - '7-10-7', - '7-10-8', - '7-11-0', - '7-11-1', - '7-11-2', - '7-12-0', - '7-12-1', - '7-12-2', - '7-12-3', - '7-13-0', - '7-13-1', - '7-13-2', - '7-14-0', - '7-14-1', - '7-15-0', - '7-15-1', - '7-15-2', - '7-15-3', - '7-15-4', - '7-15-5', - '7-16-0', - '7-16-1', - '7-16-2', - '7-16-3', - '7-16-4', - '7-17-0', - '7-17-1', - '7-18-0', - '7-18-1', - '7-18-2', - '7-19-0', - '7-19-1', - '7-19-2', - '7-19-3', - '7-19-4', - '7-19-5', - '7-19-6', - '7-19-7', - '7-20-0', - '7-20-1', - '7-21-0', - '7-21-1', - '7-21-2', - '7-21-3', - '7-21-4', - '7-21-5', - '7-21-6', - '7-21-7', - '7-22-0', - '7-23-0', - '7-23-1', - '7-24-0', - '7-25-0', - '7-26-0', - '7-27-0', - '7-28-0', - '7-28-1', - '7-29-0', - '7-30-0', - '7-31-0', - '7-32-0', - '7-33-0', - '7-34-0', - '7-35-0', - '7-36-0', - '7-37-0', - '7-37-1', - '7-38-0', - '7-39-0', - '7-40-0', - '7-41-0', - '7-42-0', - '7-42-1', - '7-43-0', - '7-44-0', - '7-45-0', - '7-46-0', - '7-47-0', - '7-47-1', - '7-48-0', - '7-49-0', - '7-49-1', - '7-50-0', - '7-50-1', - '7-50-2', - '7-50-3', - '7-51-0', - '7-52-0', - '7-52-1', - '7-53-0', - '7-53-1', - '7-54-0', - '7-54-1', - '7-55-0', - '7-55-1', - '7-56-0', - '7-56-1', - '7-57-0', - '7-58-0', - '7-59-0', - '7-60-0', - '7-61-0', - '7-61-1', - '7-62-0', - '7-63-0', - '7-64-0', - '7-64-1', - '7-65-0', - '7-65-1', - '7-65-2', - '7-65-3', - '7-66-0', - '7-67-0', - '7-68-0', - '7-69-0', - '7-69-1', - '7-7', - '7-7-1', - '7-7-2', - '7-7-3', - '7-70-0', - '7-71-0', - '7-71-1', - '7-72-0', - '7-73-0', - '7-74-0', - '7-75-0', - '7-76-0', - '7-76-1', - '7-77-0', - '7-78-0', - '7-79-0', - '7-79-1', - '7-8', - '7-8-1', - '7-80-0', - '7-81-0', - '7-82-0', - '7-83-0', - '7-83-1', - '7-84-0', - '7-85-0', - '7-9', - '7-9-1', - '7-9-2', - '7-9-3', - '7-9-4', - '7-9-5', - '7-9-6', - '7-9-7', - '7-9-8'], - 'affected_packages': [ { 'database_specific': { 'vanir_signatures': [ { 'deprecated': False, - 'digest': { 'function_hash': '22968065415160735040135778472335782425', - 'length': 58084.0}, - 'id': 'CURL-CVE-2022-32221-9751f04c', - 'signature_type': 'Function', - 'signature_version': 'v1', - 'source': 'https://github.com/curl/curl.git/commit/a64e3e59938abd7d667e4470a18072a24d7e9de9', - 'target': { 'file': 'lib/setopt.c', - 'function': 'Curl_vsetopt'}}, - { 'deprecated': False, - 'digest': { 'line_hashes': [ '73596727404438881622769716353410783065', - '150108665408450698810391826671290668314', - '264542534956227828232279400943172691231', - '248438938282829223471764231064667949049'], - 'threshold': 0.9}, - 'id': 'CURL-CVE-2022-32221-b7951194', - 'signature_type': 'Line', - 'signature_version': 'v1', - 'source': 'https://github.com/curl/curl.git/commit/a64e3e59938abd7d667e4470a18072a24d7e9de9', - 'target': { 'file': 'lib/setopt.c'}}]}, - 'ecosystem_specific': None, - 'package': { 'ecosystem': '', - 'name': '', - 'purl': None}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '7.7'}, - { 'type': 'fixed', - 'value': '7.86.0'}], - 'repo_url': '', - 'type': 'SEMVER'}, - { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '546572da0457f37c698c02d0a08d90fdfcbeedec'}, - { 'type': 'fixed', - 'value': 'a64e3e59938abd7d667e4470a18072a24d7e9de9'}], - 'repo_url': 'https://github.com/curl/curl.git', - 'type': 'GIT'}], - 'severities': [], - 'versions': [ '7.85.0', - '7.84.0', - '7.83.1', - '7.83.0', - '7.82.0', - '7.81.0', - '7.80.0', - '7.79.1', - '7.79.0', - '7.78.0', - '7.77.0', - '7.76.1', - '7.76.0', - '7.75.0', - '7.74.0', - '7.73.0', - '7.72.0', - '7.71.1', - '7.71.0', - '7.70.0', - '7.69.1', - '7.69.0', - '7.68.0', - '7.67.0', - '7.66.0', - '7.65.3', - '7.65.2', - '7.65.1', - '7.65.0', - '7.64.1', - '7.64.0', - '7.63.0', - '7.62.0', - '7.61.1', - '7.61.0', - '7.60.0', - '7.59.0', - '7.58.0', - '7.57.0', - '7.56.1', - '7.56.0', - '7.55.1', - '7.55.0', - '7.54.1', - '7.54.0', - '7.53.1', - '7.53.0', - '7.52.1', - '7.52.0', - '7.51.0', - '7.50.3', - '7.50.2', - '7.50.1', - '7.50.0', - '7.49.1', - '7.49.0', - '7.48.0', - '7.47.1', - '7.47.0', - '7.46.0', - '7.45.0', - '7.44.0', - '7.43.0', - '7.42.1', - '7.42.0', - '7.41.0', - '7.40.0', - '7.39.0', - '7.38.0', - '7.37.1', - '7.37.0', - '7.36.0', - '7.35.0', - '7.34.0', - '7.33.0', - '7.32.0', - '7.31.0', - '7.30.0', - '7.29.0', - '7.28.1', - '7.28.0', - '7.27.0', - '7.26.0', - '7.25.0', - '7.24.0', - '7.23.1', - '7.23.0', - '7.22.0', - '7.21.7', - '7.21.6', - '7.21.5', - '7.21.4', - '7.21.3', - '7.21.2', - '7.21.1', - '7.21.0', - '7.20.1', - '7.20.0', - '7.19.7', - '7.19.6', - '7.19.5', - '7.19.4', - '7.19.3', - '7.19.2', - '7.19.1', - '7.19.0', - '7.18.2', - '7.18.1', - '7.18.0', - '7.17.1', - '7.17.0', - '7.16.4', - '7.16.3', - '7.16.2', - '7.16.1', - '7.16.0', - '7.15.5', - '7.15.4', - '7.15.3', - '7.15.2', - '7.15.1', - '7.15.0', - '7.14.1', - '7.14.0', - '7.13.2', - '7.13.1', - '7.13.0', - '7.12.3', - '7.12.2', - '7.12.1', - '7.12.0', - '7.11.2', - '7.11.1', - '7.11.0', - '7.10.8', - '7.10.7', - '7.10.6', - '7.10.5', - '7.10.4', - '7.10.3', - '7.10.2', - '7.10.1', - '7.10', - '7.9.8', - '7.9.7', - '7.9.6', - '7.9.5', - '7.9.4', - '7.9.3', - '7.9.2', - '7.9.1', - '7.9', - '7.8.1', - '7.8', - '7.7.3', - '7.7.2', - '7.7.1', - '7.7']}], +{ 'affected': [ { 'database_specific': { 'source': 'http://localhost:8000/CURL-CVE-2022-32221.json', + 'vanir_signatures': [ { 'deprecated': False, + 'digest': { 'function_hash': '22968065415160735040135778472335782425', + 'length': 58084.0}, + 'id': 'CURL-CVE-2022-32221-9751f04c', + 'signature_type': 'Function', + 'signature_version': 'v1', + 'source': 'https://github.com/curl/curl.git/commit/a64e3e59938abd7d667e4470a18072a24d7e9de9', + 'target': { 'file': 'lib/setopt.c', + 'function': 'Curl_vsetopt'}}, + { 'deprecated': False, + 'digest': { 'line_hashes': [ '73596727404438881622769716353410783065', + '150108665408450698810391826671290668314', + '264542534956227828232279400943172691231', + '248438938282829223471764231064667949049'], + 'threshold': 0.9}, + 'id': 'CURL-CVE-2022-32221-b7951194', + 'signature_type': 'Line', + 'signature_version': 'v1', + 'source': 'https://github.com/curl/curl.git/commit/a64e3e59938abd7d667e4470a18072a24d7e9de9', + 'target': { 'file': 'lib/setopt.c'}}]}, + 'ranges': [ { 'events': [ {'introduced': '7.7'}, + {'fixed': '7.86.0'}], + 'type': 'SEMVER'}, + { 'events': [ { 'introduced': '546572da0457f37c698c02d0a08d90fdfcbeedec'}, + { 'fixed': 'a64e3e59938abd7d667e4470a18072a24d7e9de9'}], + 'repo': 'https://github.com/curl/curl.git', + 'type': 'GIT'}], + 'versions': [ '7.85.0', + '7.84.0', + '7.83.1', + '7.83.0', + '7.82.0', + '7.81.0', + '7.80.0', + '7.79.1', + '7.79.0', + '7.78.0', + '7.77.0', + '7.76.1', + '7.76.0', + '7.75.0', + '7.74.0', + '7.73.0', + '7.72.0', + '7.71.1', + '7.71.0', + '7.70.0', + '7.69.1', + '7.69.0', + '7.68.0', + '7.67.0', + '7.66.0', + '7.65.3', + '7.65.2', + '7.65.1', + '7.65.0', + '7.64.1', + '7.64.0', + '7.63.0', + '7.62.0', + '7.61.1', + '7.61.0', + '7.60.0', + '7.59.0', + '7.58.0', + '7.57.0', + '7.56.1', + '7.56.0', + '7.55.1', + '7.55.0', + '7.54.1', + '7.54.0', + '7.53.1', + '7.53.0', + '7.52.1', + '7.52.0', + '7.51.0', + '7.50.3', + '7.50.2', + '7.50.1', + '7.50.0', + '7.49.1', + '7.49.0', + '7.48.0', + '7.47.1', + '7.47.0', + '7.46.0', + '7.45.0', + '7.44.0', + '7.43.0', + '7.42.1', + '7.42.0', + '7.41.0', + '7.40.0', + '7.39.0', + '7.38.0', + '7.37.1', + '7.37.0', + '7.36.0', + '7.35.0', + '7.34.0', + '7.33.0', + '7.32.0', + '7.31.0', + '7.30.0', + '7.29.0', + '7.28.1', + '7.28.0', + '7.27.0', + '7.26.0', + '7.25.0', + '7.24.0', + '7.23.1', + '7.23.0', + '7.22.0', + '7.21.7', + '7.21.6', + '7.21.5', + '7.21.4', + '7.21.3', + '7.21.2', + '7.21.1', + '7.21.0', + '7.20.1', + '7.20.0', + '7.19.7', + '7.19.6', + '7.19.5', + '7.19.4', + '7.19.3', + '7.19.2', + '7.19.1', + '7.19.0', + '7.18.2', + '7.18.1', + '7.18.0', + '7.17.1', + '7.17.0', + '7.16.4', + '7.16.3', + '7.16.2', + '7.16.1', + '7.16.0', + '7.15.5', + '7.15.4', + '7.15.3', + '7.15.2', + '7.15.1', + '7.15.0', + '7.14.1', + '7.14.0', + '7.13.2', + '7.13.1', + '7.13.0', + '7.12.3', + '7.12.2', + '7.12.1', + '7.12.0', + '7.11.2', + '7.11.1', + '7.11.0', + '7.10.8', + '7.10.7', + '7.10.6', + '7.10.5', + '7.10.4', + '7.10.3', + '7.10.2', + '7.10.1', + '7.10', + '7.9.8', + '7.9.7', + '7.9.6', + '7.9.5', + '7.9.4', + '7.9.3', + '7.9.2', + '7.9.1', + '7.9', + '7.8.1', + '7.8', + '7.7.3', + '7.7.2', + '7.7.1', + '7.7']}], 'aliases': ['CVE-2022-32221'], - 'credits': [ {'contact': [], 'name': 'Robby Simpson', 'type': 'FINDER'}, - { 'contact': [], - 'name': 'Daniel Stenberg', + 'credits': [ {'name': 'Robby Simpson', 'type': 'FINDER'}, + { 'name': 'Daniel Stenberg', 'type': 'REMEDIATION_DEVELOPER'}], 'database_specific': { 'CWE': { 'desc': 'Expected Behavior Violation', 'id': 'CWE-440'}, @@ -369,7 +197,6 @@ 'package': 'curl', 'severity': 'Medium', 'www': 'https://curl.se/docs/CVE-2022-32221.html'}, - 'db_id': 'CURL-CVE-2022-32221', 'details': 'When doing HTTP(S) transfers, libcurl might erroneously use ' 'the read callback\n' '(`CURLOPT_READFUNCTION`) to ask for data to send, even when ' @@ -387,41 +214,8 @@ 'The problem exists in the logic for a reused handle when it is ' 'changed from a\n' 'PUT to a POST.', - 'ecosystem': ['GIT'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2023, 5, 10, 0, 37, 6, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': [], - 'public': True, - 'purl': [], - 'reference_url_types': {}, - 'regressed': '', - 'related': [], - 'search_indices': [ '2022', - '2022-32221', - '32221', - 'curl', - 'curl-cve', - 'curl-cve-2022', - 'curl-cve-2022-32221', - 'curl.git', - 'cve', - 'cve-2022', - 'cve-2022-32221', - 'git', - 'github.com/curl/curl.git', - 'https://github.com/curl/curl.git'], - 'search_tags': ['curl-cve-2022-32221'], - 'semver_fixed_indexes': ['00000007.00000086.00000000-zzzzzzzzzzzzzzzz'], - 'severities': [], - 'source': 'source', - 'source_id': 'source:CURL-CVE-2022-32221.json', - 'source_of_truth': 1, - 'status': 1, - 'summary': 'POST following PUT confusion', - 'timestamp': DatetimeWithNanoseconds(2022, 10, 26, 8, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'CURL-CVE-2022-32221', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2022-10-26T08:00:00Z', + 'schema_version': '1.7.3', + 'summary': 'POST following PUT confusion'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_last_affected_git.txt b/gcp/workers/worker/testdata/UpdateTest_last_affected_git.txt index f3b59017be9..f528ee84c41 100644 --- a/gcp/workers/worker/testdata/UpdateTest_last_affected_git.txt +++ b/gcp/workers/worker/testdata/UpdateTest_last_affected_git.txt @@ -1,66 +1,12 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': ['0-1-1', '0-2'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': '', - 'name': '', - 'purl': None}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, - { 'type': 'last_affected', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': ['v0.1.1', 'v0.2']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'OSV-TEST-last-affected-01', +{ 'affected': [ { 'ranges': [ { 'events': [ { 'introduced': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'last_affected': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'versions': ['v0.1.1', 'v0.2']}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), - 'is_fixed': False, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': [], - 'public': True, - 'purl': [], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '01', - 'affected', - 'affected-01', - 'git', - 'https://osv-test/repo/url', - 'last', - 'last-affected', - 'last-affected-01', - 'osv', - 'osv-test', - 'osv-test-last', - 'osv-test-last-affected', - 'osv-test-last-affected-01', - 'osv-test/repo/url', - 'repo', - 'test', - 'test-last', - 'test-last-affected', - 'test-last-affected-01', - 'url'], - 'search_tags': ['osv-test-last-affected-01'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:OSV-TEST-last-affected-01.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'OSV-TEST-last-affected-01', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_normalized_pypi.txt b/gcp/workers/worker/testdata/UpdateTest_normalized_pypi.txt index db898e1515c..f0dd9538315 100644 --- a/gcp/workers/worker/testdata/UpdateTest_normalized_pypi.txt +++ b/gcp/workers/worker/testdata/UpdateTest_normalized_pypi.txt @@ -1,63 +1,17 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'PyPI', - 'name': 'scrapy', - 'purl': 'pkg:pypi/scrapy'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '1.14.2'}, - { 'type': 'fixed', - 'value': '1.31.0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}, - { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, - { 'type': 'fixed', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': []}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'PYSEC-456', +{ 'affected': [ { 'package': { 'ecosystem': 'PyPI', + 'name': 'scrapy', + 'purl': 'pkg:pypi/scrapy'}, + 'ranges': [ { 'events': [ { 'introduced': '1.14.2'}, + {'fixed': '1.31.0'}], + 'type': 'ECOSYSTEM'}, + { 'events': [ { 'introduced': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}]}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT', 'PyPI'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['scrapy'], - 'public': True, - 'purl': ['pkg:pypi/scrapy'], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '456', - 'git', - 'https://osv-test/repo/url', - 'osv-test/repo/url', - 'pypi', - 'pysec', - 'pysec-456', - 'repo', - 'scrapy', - 'url'], - 'search_tags': ['pysec-456', 'scrapy'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:PYSEC-456.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability in an unnormalized package', - 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'PYSEC-456', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability in an unnormalized package'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt b/gcp/workers/worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt index d97673f2dc1..dee3a939577 100644 --- a/gcp/workers/worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt +++ b/gcp/workers/worker/testdata/UpdateTest_normalized_pypi_pubsub_calls.txt @@ -1 +1 @@ -[call('projects/test-osv/topics/pypi-bridge', data=b'{"id": "PYSEC-456", "summary": "A vulnerability in an unnormalized package", "details": "Blah blah blah\\nBlah\\n", "modified": "2022-10-07T18:59:00Z", "references": [{"type": "WEB", "url": "https://ref.com/ref"}], "affected": [{"package": {"name": "scrapy", "ecosystem": "PyPI"}, "ranges": [{"type": "ECOSYSTEM", "events": [{"introduced": "1.14.2"}, {"fixed": "1.31.0"}]}, {"type": "GIT", "repo": "https://osv-test/repo/url", "events": [{"introduced": "eefe8ec3f1f90d0e684890e810f3f21e8500a4cd"}, {"fixed": "8d8242f545e9cec3e6d0d2e3f5bde8be1c659735"}]}], "versions": []}]}')] \ No newline at end of file +[call('projects/test-osv/topics/pypi-bridge', data=b'{"id": "PYSEC-456", "summary": "A vulnerability in an unnormalized package", "details": "Blah blah blah\\nBlah\\n", "modified": "3000-01-01T00:00:00Z", "published": "3000-01-01T00:00:00Z", "references": [{"type": "WEB", "url": "https://ref.com/ref"}], "affected": [{"package": {"name": "scrapy", "ecosystem": "PyPI", "purl": "pkg:pypi/scrapy"}, "ranges": [{"type": "ECOSYSTEM", "events": [{"introduced": "1.14.2"}, {"fixed": "1.31.0"}]}, {"type": "GIT", "repo": "https://osv-test/repo/url", "events": [{"introduced": "eefe8ec3f1f90d0e684890e810f3f21e8500a4cd"}, {"fixed": "8d8242f545e9cec3e6d0d2e3f5bde8be1c659735"}]}], "versions": []}], "schema_version": "1.7.3"}')] \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_pypi_pubsub_calls.txt b/gcp/workers/worker/testdata/UpdateTest_pypi_pubsub_calls.txt index 1180b274143..32a1b96792f 100644 --- a/gcp/workers/worker/testdata/UpdateTest_pypi_pubsub_calls.txt +++ b/gcp/workers/worker/testdata/UpdateTest_pypi_pubsub_calls.txt @@ -1 +1 @@ -[call('projects/test-osv/topics/pypi-bridge', data=b'{"id": "PYSEC-123", "summary": "A vulnerability", "details": "Blah blah blah\\nBlah\\n", "modified": "3000-01-01T00:00:00Z", "references": [{"type": "WEB", "url": "https://ref.com/ref"}], "affected": [{"package": {"name": "grpcio", "ecosystem": "PyPI"}, "ranges": [{"type": "ECOSYSTEM", "events": [{"introduced": "1.14.2"}, {"fixed": "1.31.0"}]}, {"type": "GIT", "repo": "https://osv-test/repo/url", "events": [{"introduced": "eefe8ec3f1f90d0e684890e810f3f21e8500a4cd"}, {"fixed": "8d8242f545e9cec3e6d0d2e3f5bde8be1c659735"}]}], "versions": ["1.14.2", "1.15.0", "1.15.0rc1", "1.16.0", "1.16.0rc1", "1.16.1", "1.17.0", "1.17.1", "1.18.0", "1.19.0", "1.20.0", "1.20.0rc1", "1.20.0rc2", "1.20.0rc3", "1.20.1", "1.21.0rc1", "1.21.1", "1.21.1rc1", "1.22.0", "1.22.0rc1", "1.22.1", "1.23.0", "1.23.0rc1", "1.23.1", "1.24.0", "1.24.0rc1", "1.24.1", "1.24.3", "1.25.0", "1.25.0rc1", "1.26.0", "1.26.0rc1", "1.27.0rc1", "1.27.0rc2", "1.27.1", "1.27.2", "1.28.0rc1", "1.28.0rc2", "1.28.1", "1.29.0", "1.30.0"]}]}')] \ No newline at end of file +[call('projects/test-osv/topics/pypi-bridge', data=b'{"id": "PYSEC-123", "summary": "A vulnerability", "details": "Blah blah blah\\nBlah\\n", "modified": "3000-01-01T00:00:00Z", "published": "3000-01-01T00:00:00Z", "references": [{"type": "WEB", "url": "https://ref.com/ref"}], "affected": [{"package": {"name": "grpcio", "ecosystem": "PyPI", "purl": "pkg:pypi/grpcio"}, "ranges": [{"type": "ECOSYSTEM", "events": [{"introduced": "1.14.2"}, {"fixed": "1.31.0"}]}, {"type": "GIT", "repo": "https://osv-test/repo/url", "events": [{"introduced": "eefe8ec3f1f90d0e684890e810f3f21e8500a4cd"}, {"fixed": "8d8242f545e9cec3e6d0d2e3f5bde8be1c659735"}]}], "versions": ["1.14.2", "1.15.0", "1.15.0rc1", "1.16.0", "1.16.0rc1", "1.16.1", "1.17.0", "1.17.1", "1.18.0", "1.19.0", "1.20.0", "1.20.0rc1", "1.20.0rc2", "1.20.0rc3", "1.20.1", "1.21.0rc1", "1.21.1", "1.21.1rc1", "1.22.0", "1.22.0rc1", "1.22.1", "1.23.0", "1.23.0rc1", "1.23.1", "1.24.0", "1.24.0rc1", "1.24.1", "1.24.3", "1.25.0", "1.25.0rc1", "1.26.0", "1.26.0rc1", "1.27.0rc1", "1.27.0rc2", "1.27.1", "1.27.2", "1.28.0rc1", "1.28.0rc2", "1.28.1", "1.29.0", "1.30.0"]}], "schema_version": "1.7.3"}')] \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_ubuntu_severity_type.txt b/gcp/workers/worker/testdata/UpdateTest_ubuntu_severity_type.txt index 07664040628..a79a031c48b 100644 --- a/gcp/workers/worker/testdata/UpdateTest_ubuntu_severity_type.txt +++ b/gcp/workers/worker/testdata/UpdateTest_ubuntu_severity_type.txt @@ -1,380 +1,189 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '3.11.0-12.19', - '3.12.0-1.3', - '3.12.0-2.5', - '3.12.0-2.7', - '3.12.0-3.8', - '3.12.0-3.9', - '3.12.0-4.10', - '3.12.0-4.12', - '3.12.0-5.13', - '3.12.0-7.15', - '3.13.0-1.16', - '3.13.0-10.30', - '3.13.0-100.147', - '3.13.0-101.148', - '3.13.0-103.150', - '3.13.0-105.152', - '3.13.0-106.153', - '3.13.0-107.154', - '3.13.0-108.155', - '3.13.0-109.156', - '3.13.0-11.31', - '3.13.0-110.157', - '3.13.0-111.158', - '3.13.0-112.159', - '3.13.0-113.160', - '3.13.0-115.162', - '3.13.0-116.163', - '3.13.0-117.164', - '3.13.0-119.166', - '3.13.0-12.32', - '3.13.0-121.170', - '3.13.0-123.172', - '3.13.0-125.174', - '3.13.0-126.175', - '3.13.0-128.177', - '3.13.0-129.178', - '3.13.0-13.33', - '3.13.0-132.181', - '3.13.0-133.182', - '3.13.0-135.184', - '3.13.0-137.186', - '3.13.0-139.188', - '3.13.0-14.34', - '3.13.0-141.190', - '3.13.0-142.191', - '3.13.0-143.192', - '3.13.0-144.193', - '3.13.0-145.194', - '3.13.0-147.196', - '3.13.0-149.199', - '3.13.0-15.35', - '3.13.0-151.201', - '3.13.0-153.203', - '3.13.0-155.205', - '3.13.0-156.206', - '3.13.0-157.207', - '3.13.0-158.208', - '3.13.0-16.36', - '3.13.0-160.210', - '3.13.0-161.211', - '3.13.0-162.212', - '3.13.0-163.213', - '3.13.0-164.214', - '3.13.0-165.215', - '3.13.0-166.216', - '3.13.0-167.217', - '3.13.0-168.218', - '3.13.0-169.219', - '3.13.0-17.37', - '3.13.0-170.220', - '3.13.0-173.224', - '3.13.0-174.225', - '3.13.0-175.226', - '3.13.0-176.227', - '3.13.0-18.38', - '3.13.0-180.231', - '3.13.0-181.232', - '3.13.0-182.233', - '3.13.0-183.234', - '3.13.0-184.235', - '3.13.0-185.236', - '3.13.0-186.237', - '3.13.0-187.238', - '3.13.0-188.239', - '3.13.0-189.240', - '3.13.0-19.39', - '3.13.0-19.40', - '3.13.0-190.241', - '3.13.0-191.242', - '3.13.0-192.243', - '3.13.0-193.244', - '3.13.0-194.245', - '3.13.0-195.246', - '3.13.0-196.247', - '3.13.0-197.248', - '3.13.0-198.249', - '3.13.0-199.250', - '3.13.0-2.17', - '3.13.0-20.42', - '3.13.0-200.251', - '3.13.0-201.252', - '3.13.0-202.253', - '3.13.0-203.254', - '3.13.0-204.255', - '3.13.0-205.256', - '3.13.0-206.257', - '3.13.0-21.43', - '3.13.0-22.44', - '3.13.0-23.45', - '3.13.0-24.46', - '3.13.0-24.47', - '3.13.0-27.50', - '3.13.0-29.53', - '3.13.0-3.18', - '3.13.0-30.54', - '3.13.0-30.55', - '3.13.0-32.57', - '3.13.0-33.58', - '3.13.0-34.60', - '3.13.0-35.62', - '3.13.0-36.63', - '3.13.0-37.64', - '3.13.0-39.66', - '3.13.0-4.19', - '3.13.0-40.69', - '3.13.0-41.70', - '3.13.0-43.72', - '3.13.0-44.73', - '3.13.0-45.74', - '3.13.0-46.75', - '3.13.0-46.76', - '3.13.0-46.77', - '3.13.0-46.79', - '3.13.0-48.80', - '3.13.0-49.81', - '3.13.0-49.83', - '3.13.0-5.20', - '3.13.0-51.84', - '3.13.0-52.85', - '3.13.0-52.86', - '3.13.0-53.88', - '3.13.0-53.89', - '3.13.0-54.91', - '3.13.0-55.92', - '3.13.0-55.94', - '3.13.0-57.95', - '3.13.0-58.97', - '3.13.0-59.98', - '3.13.0-6.23', - '3.13.0-61.100', - '3.13.0-62.102', - '3.13.0-63.103', - '3.13.0-65.105', - '3.13.0-65.106', - '3.13.0-66.108', - '3.13.0-67.110', - '3.13.0-68.111', - '3.13.0-7.25', - '3.13.0-7.26', - '3.13.0-70.113', - '3.13.0-71.114', - '3.13.0-73.116', - '3.13.0-74.118', - '3.13.0-76.120', - '3.13.0-77.121', - '3.13.0-79.123', - '3.13.0-8.27', - '3.13.0-8.28', - '3.13.0-83.127', - '3.13.0-85.129', - '3.13.0-86.130', - '3.13.0-86.131', - '3.13.0-87.133', - '3.13.0-88.135', - '3.13.0-91.138', - '3.13.0-92.139', - '3.13.0-93.140', - '3.13.0-95.142', - '3.13.0-96.143', - '3.13.0-98.145'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Ubuntu:Pro:14.04:LTS', - 'name': 'linux', - 'purl': 'pkg:deb/ubuntu/linux@3.13.0-206.257?arch=source&distro=esm-infra-legacy/trusty'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '3.11.0-12.19', - '3.12.0-1.3', - '3.12.0-2.5', - '3.12.0-2.7', - '3.12.0-3.8', - '3.12.0-3.9', - '3.12.0-4.10', - '3.12.0-4.12', - '3.12.0-5.13', - '3.12.0-7.15', - '3.13.0-1.16', - '3.13.0-2.17', - '3.13.0-3.18', - '3.13.0-4.19', - '3.13.0-5.20', - '3.13.0-6.23', - '3.13.0-7.25', - '3.13.0-7.26', - '3.13.0-8.27', - '3.13.0-8.28', - '3.13.0-10.30', - '3.13.0-11.31', - '3.13.0-12.32', - '3.13.0-13.33', - '3.13.0-14.34', - '3.13.0-15.35', - '3.13.0-16.36', - '3.13.0-17.37', - '3.13.0-18.38', - '3.13.0-19.39', - '3.13.0-19.40', - '3.13.0-20.42', - '3.13.0-21.43', - '3.13.0-22.44', - '3.13.0-23.45', - '3.13.0-24.46', - '3.13.0-24.47', - '3.13.0-27.50', - '3.13.0-29.53', - '3.13.0-30.54', - '3.13.0-30.55', - '3.13.0-32.57', - '3.13.0-33.58', - '3.13.0-34.60', - '3.13.0-35.62', - '3.13.0-36.63', - '3.13.0-37.64', - '3.13.0-39.66', - '3.13.0-40.69', - '3.13.0-41.70', - '3.13.0-43.72', - '3.13.0-44.73', - '3.13.0-45.74', - '3.13.0-46.75', - '3.13.0-46.76', - '3.13.0-46.77', - '3.13.0-46.79', - '3.13.0-48.80', - '3.13.0-49.81', - '3.13.0-49.83', - '3.13.0-51.84', - '3.13.0-52.85', - '3.13.0-52.86', - '3.13.0-53.88', - '3.13.0-53.89', - '3.13.0-54.91', - '3.13.0-55.92', - '3.13.0-55.94', - '3.13.0-57.95', - '3.13.0-58.97', - '3.13.0-59.98', - '3.13.0-61.100', - '3.13.0-62.102', - '3.13.0-63.103', - '3.13.0-65.105', - '3.13.0-65.106', - '3.13.0-66.108', - '3.13.0-67.110', - '3.13.0-68.111', - '3.13.0-70.113', - '3.13.0-71.114', - '3.13.0-73.116', - '3.13.0-74.118', - '3.13.0-76.120', - '3.13.0-77.121', - '3.13.0-79.123', - '3.13.0-83.127', - '3.13.0-85.129', - '3.13.0-86.130', - '3.13.0-86.131', - '3.13.0-87.133', - '3.13.0-88.135', - '3.13.0-91.138', - '3.13.0-92.139', - '3.13.0-93.140', - '3.13.0-95.142', - '3.13.0-96.143', - '3.13.0-98.145', - '3.13.0-100.147', - '3.13.0-101.148', - '3.13.0-103.150', - '3.13.0-105.152', - '3.13.0-106.153', - '3.13.0-107.154', - '3.13.0-108.155', - '3.13.0-109.156', - '3.13.0-110.157', - '3.13.0-111.158', - '3.13.0-112.159', - '3.13.0-113.160', - '3.13.0-115.162', - '3.13.0-116.163', - '3.13.0-117.164', - '3.13.0-119.166', - '3.13.0-121.170', - '3.13.0-123.172', - '3.13.0-125.174', - '3.13.0-126.175', - '3.13.0-128.177', - '3.13.0-129.178', - '3.13.0-132.181', - '3.13.0-133.182', - '3.13.0-135.184', - '3.13.0-137.186', - '3.13.0-139.188', - '3.13.0-141.190', - '3.13.0-142.191', - '3.13.0-143.192', - '3.13.0-144.193', - '3.13.0-145.194', - '3.13.0-147.196', - '3.13.0-149.199', - '3.13.0-151.201', - '3.13.0-153.203', - '3.13.0-155.205', - '3.13.0-156.206', - '3.13.0-157.207', - '3.13.0-158.208', - '3.13.0-160.210', - '3.13.0-161.211', - '3.13.0-162.212', - '3.13.0-163.213', - '3.13.0-164.214', - '3.13.0-165.215', - '3.13.0-166.216', - '3.13.0-167.217', - '3.13.0-168.218', - '3.13.0-169.219', - '3.13.0-170.220', - '3.13.0-173.224', - '3.13.0-174.225', - '3.13.0-175.226', - '3.13.0-176.227', - '3.13.0-180.231', - '3.13.0-181.232', - '3.13.0-182.233', - '3.13.0-183.234', - '3.13.0-184.235', - '3.13.0-185.236', - '3.13.0-186.237', - '3.13.0-187.238', - '3.13.0-188.239', - '3.13.0-189.240', - '3.13.0-190.241', - '3.13.0-191.242', - '3.13.0-192.243', - '3.13.0-193.244', - '3.13.0-194.245', - '3.13.0-195.246', - '3.13.0-196.247', - '3.13.0-197.248', - '3.13.0-198.249', - '3.13.0-199.250', - '3.13.0-200.251', - '3.13.0-201.252', - '3.13.0-202.253', - '3.13.0-203.254', - '3.13.0-204.255', - '3.13.0-205.256', - '3.13.0-206.257']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'UBUNTU-CVE-2025-38094', +{ 'affected': [ { 'ecosystem_specific': {}, + 'package': { 'ecosystem': 'Ubuntu:Pro:14.04:LTS', + 'name': 'linux', + 'purl': 'pkg:deb/ubuntu/linux@3.13.0-206.257?arch=source&distro=esm-infra-legacy/trusty'}, + 'ranges': [ { 'events': [{'introduced': '0'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '3.11.0-12.19', + '3.12.0-1.3', + '3.12.0-2.5', + '3.12.0-2.7', + '3.12.0-3.8', + '3.12.0-3.9', + '3.12.0-4.10', + '3.12.0-4.12', + '3.12.0-5.13', + '3.12.0-7.15', + '3.13.0-1.16', + '3.13.0-2.17', + '3.13.0-3.18', + '3.13.0-4.19', + '3.13.0-5.20', + '3.13.0-6.23', + '3.13.0-7.25', + '3.13.0-7.26', + '3.13.0-8.27', + '3.13.0-8.28', + '3.13.0-10.30', + '3.13.0-11.31', + '3.13.0-12.32', + '3.13.0-13.33', + '3.13.0-14.34', + '3.13.0-15.35', + '3.13.0-16.36', + '3.13.0-17.37', + '3.13.0-18.38', + '3.13.0-19.39', + '3.13.0-19.40', + '3.13.0-20.42', + '3.13.0-21.43', + '3.13.0-22.44', + '3.13.0-23.45', + '3.13.0-24.46', + '3.13.0-24.47', + '3.13.0-27.50', + '3.13.0-29.53', + '3.13.0-30.54', + '3.13.0-30.55', + '3.13.0-32.57', + '3.13.0-33.58', + '3.13.0-34.60', + '3.13.0-35.62', + '3.13.0-36.63', + '3.13.0-37.64', + '3.13.0-39.66', + '3.13.0-40.69', + '3.13.0-41.70', + '3.13.0-43.72', + '3.13.0-44.73', + '3.13.0-45.74', + '3.13.0-46.75', + '3.13.0-46.76', + '3.13.0-46.77', + '3.13.0-46.79', + '3.13.0-48.80', + '3.13.0-49.81', + '3.13.0-49.83', + '3.13.0-51.84', + '3.13.0-52.85', + '3.13.0-52.86', + '3.13.0-53.88', + '3.13.0-53.89', + '3.13.0-54.91', + '3.13.0-55.92', + '3.13.0-55.94', + '3.13.0-57.95', + '3.13.0-58.97', + '3.13.0-59.98', + '3.13.0-61.100', + '3.13.0-62.102', + '3.13.0-63.103', + '3.13.0-65.105', + '3.13.0-65.106', + '3.13.0-66.108', + '3.13.0-67.110', + '3.13.0-68.111', + '3.13.0-70.113', + '3.13.0-71.114', + '3.13.0-73.116', + '3.13.0-74.118', + '3.13.0-76.120', + '3.13.0-77.121', + '3.13.0-79.123', + '3.13.0-83.127', + '3.13.0-85.129', + '3.13.0-86.130', + '3.13.0-86.131', + '3.13.0-87.133', + '3.13.0-88.135', + '3.13.0-91.138', + '3.13.0-92.139', + '3.13.0-93.140', + '3.13.0-95.142', + '3.13.0-96.143', + '3.13.0-98.145', + '3.13.0-100.147', + '3.13.0-101.148', + '3.13.0-103.150', + '3.13.0-105.152', + '3.13.0-106.153', + '3.13.0-107.154', + '3.13.0-108.155', + '3.13.0-109.156', + '3.13.0-110.157', + '3.13.0-111.158', + '3.13.0-112.159', + '3.13.0-113.160', + '3.13.0-115.162', + '3.13.0-116.163', + '3.13.0-117.164', + '3.13.0-119.166', + '3.13.0-121.170', + '3.13.0-123.172', + '3.13.0-125.174', + '3.13.0-126.175', + '3.13.0-128.177', + '3.13.0-129.178', + '3.13.0-132.181', + '3.13.0-133.182', + '3.13.0-135.184', + '3.13.0-137.186', + '3.13.0-139.188', + '3.13.0-141.190', + '3.13.0-142.191', + '3.13.0-143.192', + '3.13.0-144.193', + '3.13.0-145.194', + '3.13.0-147.196', + '3.13.0-149.199', + '3.13.0-151.201', + '3.13.0-153.203', + '3.13.0-155.205', + '3.13.0-156.206', + '3.13.0-157.207', + '3.13.0-158.208', + '3.13.0-160.210', + '3.13.0-161.211', + '3.13.0-162.212', + '3.13.0-163.213', + '3.13.0-164.214', + '3.13.0-165.215', + '3.13.0-166.216', + '3.13.0-167.217', + '3.13.0-168.218', + '3.13.0-169.219', + '3.13.0-170.220', + '3.13.0-173.224', + '3.13.0-174.225', + '3.13.0-175.226', + '3.13.0-176.227', + '3.13.0-180.231', + '3.13.0-181.232', + '3.13.0-182.233', + '3.13.0-183.234', + '3.13.0-184.235', + '3.13.0-185.236', + '3.13.0-186.237', + '3.13.0-187.238', + '3.13.0-188.239', + '3.13.0-189.240', + '3.13.0-190.241', + '3.13.0-191.242', + '3.13.0-192.243', + '3.13.0-193.244', + '3.13.0-194.245', + '3.13.0-195.246', + '3.13.0-196.247', + '3.13.0-197.248', + '3.13.0-198.249', + '3.13.0-199.250', + '3.13.0-200.251', + '3.13.0-201.252', + '3.13.0-202.253', + '3.13.0-203.254', + '3.13.0-204.255', + '3.13.0-205.256', + '3.13.0-206.257']}], 'details': 'In the Linux kernel, the following vulnerability has been ' 'resolved: net: cadence: macb: Fix a possible deadlock in ' 'macb_halt_tx. There is a situation where after THALT is set ' @@ -384,54 +193,29 @@ 'noticed on a sama5d4 device that stayed locked for days. Use ' 'retries instead of jiffies so that the timeout really works ' 'and we do not have a deadlock anymore.', - 'ecosystem': ['Ubuntu', 'Ubuntu:14.04', 'Ubuntu:Pro:14.04:LTS'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2025, 7, 4, 0, 0, tzinfo=datetime.timezone.utc), - 'is_fixed': False, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['linux'], - 'public': True, - 'purl': [ 'pkg:deb/ubuntu/linux@3.13.0-206.257', - 'pkg:deb/ubuntu/linux@3.13.0-206.257?arch=source&distro=esm-infra-legacy/trusty'], - 'reference_url_types': { 'https://git.kernel.org/linus/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f': 'REPORT', - 'https://git.kernel.org/stable/c/0772a608d799ac0d127c0a36047a2725777aba9d': 'REPORT', - 'https://git.kernel.org/stable/c/1d60c0781c1bbeaa1196b0d8aad5c435f06cb7c4': 'REPORT', - 'https://git.kernel.org/stable/c/3e64d35475aa21d13dab71da51de51923c1a3a48': 'REPORT', - 'https://git.kernel.org/stable/c/64675a9c00443b2e8af42af08c38fc1b78b68ba2': 'REPORT', - 'https://git.kernel.org/stable/c/84f98955a9de0e0f591df85aa1a44f3ebcf1cb37': 'REPORT', - 'https://git.kernel.org/stable/c/aace6b63892ce8307e502a60fe2f5a4bc6e1cfe7': 'REPORT', - 'https://git.kernel.org/stable/c/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f': 'REPORT', - 'https://ubuntu.com/security/CVE-2025-38094': 'REPORT', - 'https://www.cve.org/CVERecord?id=CVE-2025-38094': 'REPORT'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '04', - '14', - '2025', - '2025-38094', - '38094', - 'cve', - 'cve-2025', - 'cve-2025-38094', - 'linux', - 'lts', - 'pro', - 'ubuntu', - 'ubuntu-cve', - 'ubuntu-cve-2025', - 'ubuntu-cve-2025-38094', - 'ubuntu:14.04', - 'ubuntu:pro:14.04:lts'], - 'search_tags': ['linux', 'ubuntu-cve-2025-38094'], - 'semver_fixed_indexes': [], - 'severities': [{'score': 'medium', 'type': 'Ubuntu'}], - 'source': 'source', - 'source_id': 'source:UBUNTU-CVE-2025-38094.json', - 'source_of_truth': 2, - 'status': 1, - 'summary': '', - 'timestamp': DatetimeWithNanoseconds(2025, 7, 4, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': ['CVE-2025-38094'], - 'withdrawn': None} \ No newline at end of file + 'id': 'UBUNTU-CVE-2025-38094', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2025-07-04T00:00:00Z', + 'references': [ { 'type': 'REPORT', + 'url': 'https://ubuntu.com/security/CVE-2025-38094'}, + { 'type': 'REPORT', + 'url': 'https://www.cve.org/CVERecord?id=CVE-2025-38094'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/linus/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/stable/c/0772a608d799ac0d127c0a36047a2725777aba9d'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/stable/c/1d60c0781c1bbeaa1196b0d8aad5c435f06cb7c4'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/stable/c/3e64d35475aa21d13dab71da51de51923c1a3a48'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/stable/c/64675a9c00443b2e8af42af08c38fc1b78b68ba2'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/stable/c/84f98955a9de0e0f591df85aa1a44f3ebcf1cb37'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/stable/c/aace6b63892ce8307e502a60fe2f5a4bc6e1cfe7'}, + { 'type': 'REPORT', + 'url': 'https://git.kernel.org/stable/c/c92d6089d8ad7d4d815ebcedee3f3907b539ff1f'}], + 'schema_version': '1.7.3', + 'severity': [{'score': 'medium', 'type': 'Ubuntu'}], + 'upstream': ['CVE-2025-38094']} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update.txt b/gcp/workers/worker/testdata/UpdateTest_update.txt index 654da618d93..11f21ecb72f 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update.txt @@ -1,70 +1,23 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ 'branch-v0.1.1', - 'branch_1_cherrypick_regress', - 'v0.1.1'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Go', - 'name': 'blah.com/package', - 'purl': 'pkg:golang/blah.com/package'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, - { 'type': 'fixed', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, - { 'type': 'introduced', - 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, - { 'type': 'fixed', - 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': [ 'branch-v0.1.1', - 'branch_1_cherrypick_regress', - 'v0.1.1']}], - 'aliases': [], - 'credits': [ { 'contact': ['mailto:foo@bar.com'], - 'name': 'Foo bar', - 'type': None}], +{ 'affected': [ { 'package': { 'ecosystem': 'Go', + 'name': 'blah.com/package', + 'purl': 'pkg:golang/blah.com/package'}, + 'ranges': [ { 'events': [ { 'introduced': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'introduced': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'fixed': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], + 'credits': [{'contact': ['mailto:foo@bar.com'], 'name': 'Foo bar'}], 'database_specific': {'specific': 1337.0}, - 'db_id': 'OSV-123', 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT', 'Go'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['blah.com/package'], - 'public': True, - 'purl': ['pkg:golang/blah.com/package'], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '123', - 'blah', - 'blah.com/package', - 'com', - 'git', - 'go', - 'https://osv-test/repo/url', - 'osv', - 'osv-123', - 'osv-test/repo/url', - 'package', - 'repo', - 'url'], - 'search_tags': ['blah.com/package', 'osv-123'], - 'semver_fixed_indexes': [], - 'severities': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L', - 'type': 'CVSS_V3'}], - 'source': 'source', - 'source_id': 'source:OSV-123.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': None, - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'OSV-123', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2021-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'severity': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L', + 'type': 'CVSS_V3'}], + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_alpine.txt b/gcp/workers/worker/testdata/UpdateTest_update_alpine.txt index f1001d855f0..bc29cb45861 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_alpine.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_alpine.txt @@ -1,689 +1,510 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '10.0.21-r0', - '10.0.21-r1', - '10.0.21-r2', - '10.1.11-r0', - '10.1.11-r1', - '10.1.12-r0', - '10.1.12-r1', - '10.1.13-r0', - '10.1.13-r1', - '10.1.14-r0', - '10.1.14-r1', - '10.1.14-r2', - '10.1.14-r3', - '10.1.16-r0', - '10.1.17-r0', - '10.1.17-r1', - '10.1.18-r0', - '10.1.18-r1', - '10.1.19-r0', - '10.1.20-r0', - '10.1.21-r0', - '10.1.22-r0', - '10.1.22-r1', - '10.1.22-r2', - '10.1.24-r0', - '10.1.26-r0', - '10.1.28-r0', - '10.1.28-r1', - '10.1.28-r2', - '10.1.31-r0', - '10.1.8-r0', - '10.1.8-r1', - '10.1.9-r0', - '10.1.9-r1', - '10.1.9-r2', - '10.1.9-r3', - '10.2.13-r0', - '10.2.13-r1', - '10.2.14-r0', - '10.2.14-r1', - '10.2.14-r2', - '10.2.15-r0', - '10.3.10-r0', - '10.3.10-r1', - '10.3.11-r0', - '10.3.12-r0', - '10.3.12-r1', - '10.3.12-r2', - '10.3.13-r0', - '10.3.13-r1', - '10.3.13-r2', - '10.3.13-r3', - '10.3.13-r4', - '10.3.15-r0', - '10.3.16-r0', - '10.3.9-r0', - '10.3.9-r1', - '10.3.9-r2', - '10.4.10-r0', - '10.4.10-r1', - '10.4.11-r0', - '10.4.12-r0', - '10.4.13-r0', - '10.4.13-r1', - '10.4.14-r0', - '10.4.15-r0', - '10.4.17-r0', - '10.4.17-r1', - '10.4.18-r0', - '10.4.19-r0', - '10.4.21-r0', - '10.4.22-r0', - '10.4.24-r0', - '10.4.6-r0', - '10.4.6-r1', - '10.4.7-r0', - '10.4.8-r0', - '10.5.10-r0', - '10.5.11-r0', - '10.5.11-r1', - '10.5.12-r0', - '10.5.13-r0', - '10.5.15-r0', - '10.5.5-r0', - '10.5.6-r0', - '10.5.8-r0', - '10.5.9-r0', - '10.6.3-r0', - '10.6.4-r0', - '10.6.4-r1', - '10.6.4-r2', - '10.6.7-r0', - '5.5.41-r0', - '5.5.41-r1', - '5.5.41-r2', - '5.5.42-r0', - '5.5.42-r1', - '5.5.42-r2', - '5.5.42-r3', - '5.5.42-r4', - '5.5.43-r0', - '5.5.43-r1', - '5.5.43-r2', - '5.5.43-r3', - '5.5.43-r4', - '5.5.43-r5'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Alpine:v3.12', - 'name': 'mariadb', - 'purl': 'pkg:alpine/mariadb'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '10.4.25-r0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '10.0.21-r0', - '10.0.21-r1', - '10.0.21-r2', - '10.1.11-r0', - '10.1.11-r1', - '10.1.12-r0', - '10.1.12-r1', - '10.1.13-r0', - '10.1.13-r1', - '10.1.14-r0', - '10.1.14-r1', - '10.1.14-r2', - '10.1.14-r3', - '10.1.16-r0', - '10.1.17-r0', - '10.1.17-r1', - '10.1.18-r0', - '10.1.18-r1', - '10.1.19-r0', - '10.1.20-r0', - '10.1.21-r0', - '10.1.22-r0', - '10.1.22-r1', - '10.1.22-r2', - '10.1.24-r0', - '10.1.26-r0', - '10.1.28-r0', - '10.1.28-r1', - '10.1.28-r2', - '10.1.31-r0', - '10.1.8-r0', - '10.1.8-r1', - '10.1.9-r0', - '10.1.9-r1', - '10.1.9-r2', - '10.1.9-r3', - '10.2.13-r0', - '10.2.13-r1', - '10.2.14-r0', - '10.2.14-r1', - '10.2.14-r2', - '10.2.15-r0', - '10.3.10-r0', - '10.3.10-r1', - '10.3.11-r0', - '10.3.12-r0', - '10.3.12-r1', - '10.3.12-r2', - '10.3.13-r0', - '10.3.13-r1', - '10.3.13-r2', - '10.3.13-r3', - '10.3.13-r4', - '10.3.15-r0', - '10.3.16-r0', - '10.3.9-r0', - '10.3.9-r1', - '10.3.9-r2', - '10.4.10-r0', - '10.4.10-r1', - '10.4.11-r0', - '10.4.12-r0', - '10.4.13-r0', - '10.4.15-r0', - '10.4.17-r0', - '10.4.17-r1', - '10.4.18-r0', - '10.4.19-r0', - '10.4.21-r0', - '10.4.22-r0', - '10.4.24-r0', - '10.4.6-r0', - '10.4.6-r1', - '10.4.7-r0', - '10.4.8-r0', - '5.5.41-r0', - '5.5.41-r1', - '5.5.41-r2', - '5.5.42-r0', - '5.5.42-r1', - '5.5.42-r2', - '5.5.42-r3', - '5.5.42-r4', - '5.5.43-r0', - '5.5.43-r1', - '5.5.43-r2', - '5.5.43-r3', - '5.5.43-r4', - '5.5.43-r5']}, - { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Alpine:v3.13', - 'name': 'mariadb', - 'purl': 'pkg:alpine/mariadb'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '10.5.16-r0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '10.0.21-r0', - '10.0.21-r1', - '10.0.21-r2', - '10.1.11-r0', - '10.1.11-r1', - '10.1.12-r0', - '10.1.12-r1', - '10.1.13-r0', - '10.1.13-r1', - '10.1.14-r0', - '10.1.14-r1', - '10.1.14-r2', - '10.1.14-r3', - '10.1.16-r0', - '10.1.17-r0', - '10.1.17-r1', - '10.1.18-r0', - '10.1.18-r1', - '10.1.19-r0', - '10.1.20-r0', - '10.1.21-r0', - '10.1.22-r0', - '10.1.22-r1', - '10.1.22-r2', - '10.1.24-r0', - '10.1.26-r0', - '10.1.28-r0', - '10.1.28-r1', - '10.1.28-r2', - '10.1.31-r0', - '10.1.8-r0', - '10.1.8-r1', - '10.1.9-r0', - '10.1.9-r1', - '10.1.9-r2', - '10.1.9-r3', - '10.2.13-r0', - '10.2.13-r1', - '10.2.14-r0', - '10.2.14-r1', - '10.2.14-r2', - '10.2.15-r0', - '10.3.10-r0', - '10.3.10-r1', - '10.3.11-r0', - '10.3.12-r0', - '10.3.12-r1', - '10.3.12-r2', - '10.3.13-r0', - '10.3.13-r1', - '10.3.13-r2', - '10.3.13-r3', - '10.3.13-r4', - '10.3.15-r0', - '10.3.16-r0', - '10.3.9-r0', - '10.3.9-r1', - '10.3.9-r2', - '10.4.10-r0', - '10.4.10-r1', - '10.4.11-r0', - '10.4.12-r0', - '10.4.13-r0', - '10.4.13-r1', - '10.4.14-r0', - '10.4.6-r0', - '10.4.6-r1', - '10.4.7-r0', - '10.4.8-r0', - '10.5.10-r0', - '10.5.11-r0', - '10.5.12-r0', - '10.5.13-r0', - '10.5.15-r0', - '10.5.5-r0', - '10.5.6-r0', - '10.5.8-r0', - '10.5.9-r0', - '5.5.41-r0', - '5.5.41-r1', - '5.5.41-r2', - '5.5.42-r0', - '5.5.42-r1', - '5.5.42-r2', - '5.5.42-r3', - '5.5.42-r4', - '5.5.43-r0', - '5.5.43-r1', - '5.5.43-r2', - '5.5.43-r3', - '5.5.43-r4', - '5.5.43-r5']}, - { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Alpine:v3.14', - 'name': 'mariadb', - 'purl': 'pkg:alpine/mariadb'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '10.5.16-r0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '10.0.21-r0', - '10.0.21-r1', - '10.0.21-r2', - '10.1.11-r0', - '10.1.11-r1', - '10.1.12-r0', - '10.1.12-r1', - '10.1.13-r0', - '10.1.13-r1', - '10.1.14-r0', - '10.1.14-r1', - '10.1.14-r2', - '10.1.14-r3', - '10.1.16-r0', - '10.1.17-r0', - '10.1.17-r1', - '10.1.18-r0', - '10.1.18-r1', - '10.1.19-r0', - '10.1.20-r0', - '10.1.21-r0', - '10.1.22-r0', - '10.1.22-r1', - '10.1.22-r2', - '10.1.24-r0', - '10.1.26-r0', - '10.1.28-r0', - '10.1.28-r1', - '10.1.28-r2', - '10.1.31-r0', - '10.1.8-r0', - '10.1.8-r1', - '10.1.9-r0', - '10.1.9-r1', - '10.1.9-r2', - '10.1.9-r3', - '10.2.13-r0', - '10.2.13-r1', - '10.2.14-r0', - '10.2.14-r1', - '10.2.14-r2', - '10.2.15-r0', - '10.3.10-r0', - '10.3.10-r1', - '10.3.11-r0', - '10.3.12-r0', - '10.3.12-r1', - '10.3.12-r2', - '10.3.13-r0', - '10.3.13-r1', - '10.3.13-r2', - '10.3.13-r3', - '10.3.13-r4', - '10.3.15-r0', - '10.3.16-r0', - '10.3.9-r0', - '10.3.9-r1', - '10.3.9-r2', - '10.4.10-r0', - '10.4.10-r1', - '10.4.11-r0', - '10.4.12-r0', - '10.4.13-r0', - '10.4.13-r1', - '10.4.14-r0', - '10.4.6-r0', - '10.4.6-r1', - '10.4.7-r0', - '10.4.8-r0', - '10.5.11-r0', - '10.5.12-r0', - '10.5.13-r0', - '10.5.15-r0', - '10.5.5-r0', - '10.5.6-r0', - '10.5.8-r0', - '10.5.9-r0', - '5.5.41-r0', - '5.5.41-r1', - '5.5.41-r2', - '5.5.42-r0', - '5.5.42-r1', - '5.5.42-r2', - '5.5.42-r3', - '5.5.42-r4', - '5.5.43-r0', - '5.5.43-r1', - '5.5.43-r2', - '5.5.43-r3', - '5.5.43-r4', - '5.5.43-r5']}, - { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Alpine:v3.15', - 'name': 'mariadb', - 'purl': 'pkg:alpine/mariadb'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '10.6.8-r0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '10.0.21-r0', - '10.0.21-r1', - '10.0.21-r2', - '10.1.11-r0', - '10.1.11-r1', - '10.1.12-r0', - '10.1.12-r1', - '10.1.13-r0', - '10.1.13-r1', - '10.1.14-r0', - '10.1.14-r1', - '10.1.14-r2', - '10.1.14-r3', - '10.1.16-r0', - '10.1.17-r0', - '10.1.17-r1', - '10.1.18-r0', - '10.1.18-r1', - '10.1.19-r0', - '10.1.20-r0', - '10.1.21-r0', - '10.1.22-r0', - '10.1.22-r1', - '10.1.22-r2', - '10.1.24-r0', - '10.1.26-r0', - '10.1.28-r0', - '10.1.28-r1', - '10.1.28-r2', - '10.1.31-r0', - '10.1.8-r0', - '10.1.8-r1', - '10.1.9-r0', - '10.1.9-r1', - '10.1.9-r2', - '10.1.9-r3', - '10.2.13-r0', - '10.2.13-r1', - '10.2.14-r0', - '10.2.14-r1', - '10.2.14-r2', - '10.2.15-r0', - '10.3.10-r0', - '10.3.10-r1', - '10.3.11-r0', - '10.3.12-r0', - '10.3.12-r1', - '10.3.12-r2', - '10.3.13-r0', - '10.3.13-r1', - '10.3.13-r2', - '10.3.13-r3', - '10.3.13-r4', - '10.3.15-r0', - '10.3.16-r0', - '10.3.9-r0', - '10.3.9-r1', - '10.3.9-r2', - '10.4.10-r0', - '10.4.10-r1', - '10.4.11-r0', - '10.4.12-r0', - '10.4.13-r0', - '10.4.13-r1', - '10.4.14-r0', - '10.4.6-r0', - '10.4.6-r1', - '10.4.7-r0', - '10.4.8-r0', - '10.5.11-r0', - '10.5.11-r1', - '10.5.5-r0', - '10.5.6-r0', - '10.5.8-r0', - '10.5.9-r0', - '10.6.3-r0', - '10.6.4-r0', - '10.6.4-r1', - '10.6.4-r2', - '10.6.7-r0', - '5.5.41-r0', - '5.5.41-r1', - '5.5.41-r2', - '5.5.42-r0', - '5.5.42-r1', - '5.5.42-r2', - '5.5.42-r3', - '5.5.42-r4', - '5.5.43-r0', - '5.5.43-r1', - '5.5.43-r2', - '5.5.43-r3', - '5.5.43-r4', - '5.5.43-r5']}, - { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Alpine:v3.16', - 'name': 'mariadb', - 'purl': 'pkg:alpine/mariadb'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '10.6.8-r0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '10.0.21-r0', - '10.0.21-r1', - '10.0.21-r2', - '10.1.11-r0', - '10.1.11-r1', - '10.1.12-r0', - '10.1.12-r1', - '10.1.13-r0', - '10.1.13-r1', - '10.1.14-r0', - '10.1.14-r1', - '10.1.14-r2', - '10.1.14-r3', - '10.1.16-r0', - '10.1.17-r0', - '10.1.17-r1', - '10.1.18-r0', - '10.1.18-r1', - '10.1.19-r0', - '10.1.20-r0', - '10.1.21-r0', - '10.1.22-r0', - '10.1.22-r1', - '10.1.22-r2', - '10.1.24-r0', - '10.1.26-r0', - '10.1.28-r0', - '10.1.28-r1', - '10.1.28-r2', - '10.1.31-r0', - '10.1.8-r0', - '10.1.8-r1', - '10.1.9-r0', - '10.1.9-r1', - '10.1.9-r2', - '10.1.9-r3', - '10.2.13-r0', - '10.2.13-r1', - '10.2.14-r0', - '10.2.14-r1', - '10.2.14-r2', - '10.2.15-r0', - '10.3.10-r0', - '10.3.10-r1', - '10.3.11-r0', - '10.3.12-r0', - '10.3.12-r1', - '10.3.12-r2', - '10.3.13-r0', - '10.3.13-r1', - '10.3.13-r2', - '10.3.13-r3', - '10.3.13-r4', - '10.3.15-r0', - '10.3.16-r0', - '10.3.9-r0', - '10.3.9-r1', - '10.3.9-r2', - '10.4.10-r0', - '10.4.10-r1', - '10.4.11-r0', - '10.4.12-r0', - '10.4.13-r0', - '10.4.13-r1', - '10.4.14-r0', - '10.4.6-r0', - '10.4.6-r1', - '10.4.7-r0', - '10.4.8-r0', - '10.5.11-r0', - '10.5.11-r1', - '10.5.5-r0', - '10.5.6-r0', - '10.5.8-r0', - '10.5.9-r0', - '10.6.3-r0', - '10.6.4-r0', - '10.6.4-r1', - '10.6.4-r2', - '10.6.7-r0', - '5.5.41-r0', - '5.5.41-r1', - '5.5.41-r2', - '5.5.42-r0', - '5.5.42-r1', - '5.5.42-r2', - '5.5.42-r3', - '5.5.42-r4', - '5.5.43-r0', - '5.5.43-r1', - '5.5.43-r2', - '5.5.43-r3', - '5.5.43-r4', - '5.5.43-r5']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'CVE-2022-27449', +{ 'affected': [ { 'package': { 'ecosystem': 'Alpine:v3.12', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '10.4.25-r0'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.15-r0', + '10.4.17-r0', + '10.4.17-r1', + '10.4.18-r0', + '10.4.19-r0', + '10.4.21-r0', + '10.4.22-r0', + '10.4.24-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'package': { 'ecosystem': 'Alpine:v3.13', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '10.5.16-r0'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.10-r0', + '10.5.11-r0', + '10.5.12-r0', + '10.5.13-r0', + '10.5.15-r0', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'package': { 'ecosystem': 'Alpine:v3.14', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '10.5.16-r0'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.11-r0', + '10.5.12-r0', + '10.5.13-r0', + '10.5.15-r0', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'package': { 'ecosystem': 'Alpine:v3.15', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + {'fixed': '10.6.8-r0'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.11-r0', + '10.5.11-r1', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '10.6.3-r0', + '10.6.4-r0', + '10.6.4-r1', + '10.6.4-r2', + '10.6.7-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}, + { 'package': { 'ecosystem': 'Alpine:v3.16', + 'name': 'mariadb', + 'purl': 'pkg:alpine/mariadb'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + {'fixed': '10.6.8-r0'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '10.0.21-r0', + '10.0.21-r1', + '10.0.21-r2', + '10.1.11-r0', + '10.1.11-r1', + '10.1.12-r0', + '10.1.12-r1', + '10.1.13-r0', + '10.1.13-r1', + '10.1.14-r0', + '10.1.14-r1', + '10.1.14-r2', + '10.1.14-r3', + '10.1.16-r0', + '10.1.17-r0', + '10.1.17-r1', + '10.1.18-r0', + '10.1.18-r1', + '10.1.19-r0', + '10.1.20-r0', + '10.1.21-r0', + '10.1.22-r0', + '10.1.22-r1', + '10.1.22-r2', + '10.1.24-r0', + '10.1.26-r0', + '10.1.28-r0', + '10.1.28-r1', + '10.1.28-r2', + '10.1.31-r0', + '10.1.8-r0', + '10.1.8-r1', + '10.1.9-r0', + '10.1.9-r1', + '10.1.9-r2', + '10.1.9-r3', + '10.2.13-r0', + '10.2.13-r1', + '10.2.14-r0', + '10.2.14-r1', + '10.2.14-r2', + '10.2.15-r0', + '10.3.10-r0', + '10.3.10-r1', + '10.3.11-r0', + '10.3.12-r0', + '10.3.12-r1', + '10.3.12-r2', + '10.3.13-r0', + '10.3.13-r1', + '10.3.13-r2', + '10.3.13-r3', + '10.3.13-r4', + '10.3.15-r0', + '10.3.16-r0', + '10.3.9-r0', + '10.3.9-r1', + '10.3.9-r2', + '10.4.10-r0', + '10.4.10-r1', + '10.4.11-r0', + '10.4.12-r0', + '10.4.13-r0', + '10.4.13-r1', + '10.4.14-r0', + '10.4.6-r0', + '10.4.6-r1', + '10.4.7-r0', + '10.4.8-r0', + '10.5.11-r0', + '10.5.11-r1', + '10.5.5-r0', + '10.5.6-r0', + '10.5.8-r0', + '10.5.9-r0', + '10.6.3-r0', + '10.6.4-r0', + '10.6.4-r1', + '10.6.4-r2', + '10.6.7-r0', + '5.5.41-r0', + '5.5.41-r1', + '5.5.41-r2', + '5.5.42-r0', + '5.5.42-r1', + '5.5.42-r2', + '5.5.42-r3', + '5.5.42-r4', + '5.5.43-r0', + '5.5.43-r1', + '5.5.43-r2', + '5.5.43-r3', + '5.5.43-r4', + '5.5.43-r5']}], 'details': 'MariaDB Server v10.9 and below was discovered to contain a ' 'segmentation fault via the component sql/item_func.cc:148.', - 'ecosystem': [ 'Alpine', - 'Alpine:v3.12', - 'Alpine:v3.13', - 'Alpine:v3.14', - 'Alpine:v3.15', - 'Alpine:v3.16'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['mariadb'], - 'public': True, - 'purl': ['pkg:alpine/mariadb'], - 'reference_url_types': { 'https://jira.mariadb.org/browse/MDEV-28089': 'WEB', - 'https://lists.debian.org/debian-lts-announce/2022/09/msg00023.html': 'WEB', - 'https://security.netapp.com/advisory/ntap-20220526-0006/': 'ADVISORY'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '12', - '13', - '14', - '15', - '16', - '2022', - '2022-27449', - '27449', - 'alpine', - 'alpine:v3.12', - 'alpine:v3.13', - 'alpine:v3.14', - 'alpine:v3.15', - 'alpine:v3.16', - 'cve', - 'cve-2022', - 'cve-2022-27449', - 'mariadb', - 'v3'], - 'search_tags': ['cve-2022-27449', 'mariadb'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:CVE-2022-27449.json', - 'source_of_truth': 2, - 'status': 1, - 'summary': '', - 'timestamp': DatetimeWithNanoseconds(2022, 4, 14, 13, 15, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'CVE-2022-27449', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2022-04-14T13:15:00Z', + 'references': [ { 'type': 'EVIDENCE', + 'url': 'https://jira.mariadb.org/browse/MDEV-28089'}, + { 'type': 'REPORT', + 'url': 'https://jira.mariadb.org/browse/MDEV-28089'}, + { 'type': 'FIX', + 'url': 'https://jira.mariadb.org/browse/MDEV-28089'}, + { 'type': 'WEB', + 'url': 'https://jira.mariadb.org/browse/MDEV-28089'}, + { 'type': 'ADVISORY', + 'url': 'https://security.netapp.com/advisory/ntap-20220526-0006/'}, + { 'type': 'ARTICLE', + 'url': 'https://lists.debian.org/debian-lts-announce/2022/09/msg00023.html'}, + { 'type': 'WEB', + 'url': 'https://lists.debian.org/debian-lts-announce/2022/09/msg00023.html'}], + 'schema_version': '1.7.3'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_bad_ecosystem_new.txt b/gcp/workers/worker/testdata/UpdateTest_update_bad_ecosystem_new.txt new file mode 100644 index 00000000000..d5828e36cba --- /dev/null +++ b/gcp/workers/worker/testdata/UpdateTest_update_bad_ecosystem_new.txt @@ -0,0 +1,7 @@ +{ 'details': 'Blah blah blah\nBlah\n', + 'id': 'OSV-129', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_bucket_0.txt b/gcp/workers/worker/testdata/UpdateTest_update_bucket_0.txt index 184148e93f4..17143e52ecd 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_bucket_0.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_bucket_0.txt @@ -1,104 +1,37 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': { 'imports': [ { 'path': 'github.com/opencontainers/runc/libcontainer/apparmor', - 'symbols': [ 'ApplyProfile']}, - { 'path': 'github.com/opencontainers/runc/libcontainer/utils', - 'symbols': [ 'CloseExecFrom']}]}, - 'package': { 'ecosystem': 'Go', - 'name': 'github.com/opencontainers/runc', - 'purl': 'pkg:golang/github.com/opencontainers/runc'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '1.0.0-rc8.0.20190930145003-cad42f6e0932'}], - 'repo_url': '', - 'type': 'SEMVER'}], - 'severities': [], - 'versions': []}, - { 'database_specific': None, - 'ecosystem_specific': { 'imports': [ { 'path': 'github.com/opencontainers/selinux/go-selinux', - 'symbols': [ 'readCon', - 'writeCon']}]}, - 'package': { 'ecosystem': 'Go', - 'name': 'github.com/opencontainers/selinux', - 'purl': 'pkg:golang/github.com/opencontainers/selinux'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '1.3.1-0.20190929122143-5215b1806f52'}], - 'repo_url': '', - 'type': 'SEMVER'}], - 'severities': [], - 'versions': []}], +{ 'affected': [ { 'ecosystem_specific': { 'imports': [ { 'path': 'github.com/opencontainers/runc/libcontainer/apparmor', + 'symbols': [ 'ApplyProfile']}, + { 'path': 'github.com/opencontainers/runc/libcontainer/utils', + 'symbols': [ 'CloseExecFrom']}]}, + 'package': { 'ecosystem': 'Go', + 'name': 'github.com/opencontainers/runc', + 'purl': 'pkg:golang/github.com/opencontainers/runc'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '1.0.0-rc8.0.20190930145003-cad42f6e0932'}], + 'type': 'SEMVER'}]}, + { 'ecosystem_specific': { 'imports': [ { 'path': 'github.com/opencontainers/selinux/go-selinux', + 'symbols': [ 'readCon', + 'writeCon']}]}, + 'package': { 'ecosystem': 'Go', + 'name': 'github.com/opencontainers/selinux', + 'purl': 'pkg:golang/github.com/opencontainers/selinux'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '1.3.1-0.20190929122143-5215b1806f52'}], + 'type': 'SEMVER'}]}], 'aliases': ['CVE-2019-16884', 'GHSA-fgv8-vj5c-2ppq'], - 'credits': [{'contact': [], 'name': 'Leopold Schabel', 'type': None}], + 'credits': [{'name': 'Leopold Schabel'}], 'database_specific': {'url': 'https://pkg.go.dev/vuln/GO-2021-0085'}, - 'db_id': 'GO-2021-0085', 'details': 'AppArmor restrictions may be bypassed due to improper ' 'validation of mount targets, allowing a malicious image to ' 'mount volumes over e.g. /proc.', - 'ecosystem': ['Go'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2023, 4, 3, 15, 57, 51, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': [ 'github.com/opencontainers/runc', - 'github.com/opencontainers/selinux'], - 'public': True, - 'purl': [ 'pkg:golang/github.com/opencontainers/runc', - 'pkg:golang/github.com/opencontainers/selinux'], - 'reference_url_types': { 'https://github.com/opencontainers/runc/commit/cad42f6e0932db0ce08c3a3d9e89e6063ec283e4': 'FIX', - 'https://github.com/opencontainers/runc/issues/2128': 'WEB', - 'https://github.com/opencontainers/runc/pull/2130': 'FIX', - 'https://github.com/opencontainers/selinux/commit/03b517dc4fd57245b1cf506e8ba7b817b6d309da': 'FIX'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '0085', - '16884', - '2019', - '2019-16884', - '2021', - '2021-0085', - '2ppq', - 'com', - 'cve', - 'cve-2019', - 'cve-2019-16884', - 'fgv8', - 'fgv8-vj5c', - 'fgv8-vj5c-2ppq', - 'ghsa', - 'ghsa-fgv8', - 'ghsa-fgv8-vj5c', - 'ghsa-fgv8-vj5c-2ppq', - 'github', - 'github.com/opencontainers/runc', - 'github.com/opencontainers/selinux', - 'go', - 'go-2021', - 'go-2021-0085', - 'opencontainers', - 'runc', - 'selinux', - 'vj5c', - 'vj5c-2ppq'], - 'search_tags': [ 'github.com/opencontainers/runc', - 'github.com/opencontainers/selinux', - 'go-2021-0085'], - 'semver_fixed_indexes': [ '00000001.00000000.00000000-1rc8.00000000.120190930145003-cad42f6e0932', - '00000001.00000003.00000001-00000000.120190929122143-5215b1806f52'], - 'severities': [], - 'source': 'source', - 'source_id': 'source:a/b/test.json', - 'source_of_truth': 2, - 'status': 1, - 'summary': '', - 'timestamp': DatetimeWithNanoseconds(2021, 4, 14, 20, 4, 52, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'GO-2021-0085', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2021-04-14T20:04:52Z', + 'references': [ { 'type': 'FIX', + 'url': 'https://github.com/opencontainers/runc/pull/2130'}, + { 'type': 'FIX', + 'url': 'https://github.com/opencontainers/runc/commit/cad42f6e0932db0ce08c3a3d9e89e6063ec283e4'}, + { 'type': 'FIX', + 'url': 'https://github.com/opencontainers/selinux/commit/03b517dc4fd57245b1cf506e8ba7b817b6d309da'}, + { 'type': 'WEB', + 'url': 'https://github.com/opencontainers/runc/issues/2128'}], + 'schema_version': '1.7.3'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_bucket_2.txt b/gcp/workers/worker/testdata/UpdateTest_update_bucket_2.txt index 9b228142cd0..053d0e49367 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_bucket_2.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_bucket_2.txt @@ -1,63 +1,21 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': ['10', '11'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': { 'severity': 'High', - 'spl': '2021-10-01', - 'type': 'EoP'}, - 'package': { 'ecosystem': 'Android', - 'name': 'Media Framework', - 'purl': None}, - 'ranges': [], - 'severities': [], - 'versions': ['10', '11']}], +{ 'affected': [ { 'ecosystem_specific': { 'severity': 'High', + 'spl': '2021-10-01', + 'type': 'EoP'}, + 'package': { 'ecosystem': 'Android', + 'name': 'Media Framework'}, + 'versions': ['10', '11']}], 'aliases': ['CVE-2021-0483'], - 'credits': [], - 'database_specific': None, - 'db_id': 'ASB-A-153358911', - 'details': '', - 'ecosystem': ['Android'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2021, 10, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'is_fixed': False, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['Media Framework'], - 'public': True, - 'purl': [], - 'reference_url_types': { 'https://android.googlesource.com/platform/frameworks/av/+/084077feb6b8c961adcbe77b2bd76601ca54e534': 'FIX', - 'https://android.googlesource.com/platform/frameworks/av/+/cc2165840d524bb9553f9d73d1904633d20100a2': 'FIX', - 'https://source.android.com/security/bulletin/2021-10-01#2021-10-01-security-patch-level-vulnerability-details': 'ADVISORY'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '0483', - '153358911', - '2021', - '2021-0483', - 'a', - 'a-153358911', - 'android', - 'asb', - 'asb-a', - 'asb-a-153358911', - 'cve', - 'cve-2021', - 'cve-2021-0483', - 'framework', - 'media', - 'media framework'], - 'search_tags': ['asb-a-153358911', 'media framework'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:a/b/android-test.json', - 'source_of_truth': 2, - 'status': 1, + 'id': 'ASB-A-153358911', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2021-10-01T00:00:00Z', + 'references': [ { 'type': 'ADVISORY', + 'url': 'https://source.android.com/security/bulletin/2021-10-01#2021-10-01-security-patch-level-vulnerability-details'}, + { 'type': 'FIX', + 'url': 'https://android.googlesource.com/platform/frameworks/av/+/084077feb6b8c961adcbe77b2bd76601ca54e534'}, + { 'type': 'FIX', + 'url': 'https://android.googlesource.com/platform/frameworks/av/+/cc2165840d524bb9553f9d73d1904633d20100a2'}], + 'schema_version': '1.7.3', 'summary': 'In multiple methods of AAudioService, there is a possible ' 'use-after-free due to a race condition. This could lead to ' 'local escalation of privilege with User execution privileges ' - 'needed. User interaction is not needed for exploitation.', - 'timestamp': DatetimeWithNanoseconds(2021, 10, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'needed. User interaction is not needed for exploitation.'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_bucket_cve.txt b/gcp/workers/worker/testdata/UpdateTest_update_bucket_cve.txt index 32722079b69..49fafa64d5c 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_bucket_cve.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_bucket_cve.txt @@ -1,106 +1,83 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '1-2-1', - '1-2-2', - '1-2-3', - '1-2-4', - '1-2-5', - '1-2-6', - '1-3-0', - '1-3-1'], - 'affected_packages': [ { 'database_specific': { 'vanir_signatures': [ { 'deprecated': False, - 'digest': { 'line_hashes': [ '18066036635502801806677364178756254862', - '88369412895184753394283011451803187548', - '50848458948504730426650075084385046530', - '91284993680127737564993618090545145416', - '30779278950355321333621475605602830830', - '122421578121241373365155348152646941523', - '267652210589392654099845994262755826062', - '334808111126213430220547654602188383660', - '234389204524678077984531197469034242690', - '152880517379272209571165325006789878786', - '299871312446227378724863519270618301341', - '157634544376100154879962283397081738110', - '103663099829328578689797223848801574827', - '158563421165358858389893196995983570762', - '315965584007238676040631750953088200664'], - 'threshold': 0.9}, - 'id': 'CVE-2016-15011-929806e0', - 'signature_type': 'Line', - 'signature_version': 'v1', - 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', - 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/metadata/DigitalSignatureServiceMetadata.java'}}, - { 'deprecated': False, - 'digest': { 'line_hashes': [ '6674387965125354881111149989428882853', - '100741820504985357262218153349452233434', - '253366101641995550384755812786879052342', - '245037096886845520996519599411616661529', - '158852189579109359359946013476030639584', - '298614597347537877121532413760030558894', - '180181956682520524395173299138562004562', - '146502839243717526526406585366671557144', - '244996413515733361838850122849344525825', - '166554563875570093109470347687697544350', - '9427977046515615106319032886256396870', - '279044285883194738631442483325879094037', - '295198785562376785392477306514392217432', - '44714085523243422643465698936438435501', - '267608316591780380179772018605253867646', - '182074437577114148436758739432546664545', - '87621961972550109442760282702331746920', - '64897152403082006856773989396486955494', - '184138636401118235309885205539354874180', - '62633257528035095954429323509732904426'], - 'threshold': 0.9}, - 'id': 'CVE-2016-15011-bd561b7b', - 'signature_type': 'Line', - 'signature_version': 'v1', - 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', - 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/SignResponseVerifier.java'}}, - { 'deprecated': False, - 'digest': { 'function_hash': '259495117689681377355427521574538727644', - 'length': 1591.0}, - 'id': 'CVE-2016-15011-d557e328', - 'signature_type': 'Function', - 'signature_version': 'v1', - 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', - 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/metadata/DigitalSignatureServiceMetadata.java', - 'function': 'DigitalSignatureServiceMetadata'}}, - { 'deprecated': False, - 'digest': { 'function_hash': '249451297539985081987952306682300702892', - 'length': 4302.0}, - 'id': 'CVE-2016-15011-fcf07dd1', - 'signature_type': 'Function', - 'signature_version': 'v1', - 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', - 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/SignResponseVerifier.java', - 'function': 'checkSignResponse'}}]}, - 'ecosystem_specific': None, - 'package': { 'ecosystem': '', - 'name': '', - 'purl': None}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '001ef99b0c8194468de960d007e2d82dcebc3bca'}, - { 'type': 'fixed', - 'value': 'ec4238349691ec66dd30b416ec6eaab02d722302'}], - 'repo_url': 'https://github.com/e-contract/dssp', - 'type': 'GIT'}], - 'severities': [], - 'versions': [ 'dssp-1.2.1', - 'dssp-1.2.2', - 'dssp-1.2.3', - 'dssp-1.2.4', - 'dssp-1.2.5', - 'dssp-1.2.6', - 'dssp-1.3.0', - 'dssp-1.3.1']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'CVE-2016-15011', +{ 'affected': [ { 'database_specific': { 'vanir_signatures': [ { 'deprecated': False, + 'digest': { 'line_hashes': [ '18066036635502801806677364178756254862', + '88369412895184753394283011451803187548', + '50848458948504730426650075084385046530', + '91284993680127737564993618090545145416', + '30779278950355321333621475605602830830', + '122421578121241373365155348152646941523', + '267652210589392654099845994262755826062', + '334808111126213430220547654602188383660', + '234389204524678077984531197469034242690', + '152880517379272209571165325006789878786', + '299871312446227378724863519270618301341', + '157634544376100154879962283397081738110', + '103663099829328578689797223848801574827', + '158563421165358858389893196995983570762', + '315965584007238676040631750953088200664'], + 'threshold': 0.9}, + 'id': 'CVE-2016-15011-929806e0', + 'signature_type': 'Line', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/metadata/DigitalSignatureServiceMetadata.java'}}, + { 'deprecated': False, + 'digest': { 'line_hashes': [ '6674387965125354881111149989428882853', + '100741820504985357262218153349452233434', + '253366101641995550384755812786879052342', + '245037096886845520996519599411616661529', + '158852189579109359359946013476030639584', + '298614597347537877121532413760030558894', + '180181956682520524395173299138562004562', + '146502839243717526526406585366671557144', + '244996413515733361838850122849344525825', + '166554563875570093109470347687697544350', + '9427977046515615106319032886256396870', + '279044285883194738631442483325879094037', + '295198785562376785392477306514392217432', + '44714085523243422643465698936438435501', + '267608316591780380179772018605253867646', + '182074437577114148436758739432546664545', + '87621961972550109442760282702331746920', + '64897152403082006856773989396486955494', + '184138636401118235309885205539354874180', + '62633257528035095954429323509732904426'], + 'threshold': 0.9}, + 'id': 'CVE-2016-15011-bd561b7b', + 'signature_type': 'Line', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/SignResponseVerifier.java'}}, + { 'deprecated': False, + 'digest': { 'function_hash': '259495117689681377355427521574538727644', + 'length': 1591.0}, + 'id': 'CVE-2016-15011-d557e328', + 'signature_type': 'Function', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/metadata/DigitalSignatureServiceMetadata.java', + 'function': 'DigitalSignatureServiceMetadata'}}, + { 'deprecated': False, + 'digest': { 'function_hash': '249451297539985081987952306682300702892', + 'length': 4302.0}, + 'id': 'CVE-2016-15011-fcf07dd1', + 'signature_type': 'Function', + 'signature_version': 'v1', + 'source': 'https://github.com/e-contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302', + 'target': { 'file': 'dssp-client/src/main/java/be/e_contract/dssp/client/SignResponseVerifier.java', + 'function': 'checkSignResponse'}}]}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '001ef99b0c8194468de960d007e2d82dcebc3bca'}, + { 'fixed': 'ec4238349691ec66dd30b416ec6eaab02d722302'}], + 'repo': 'https://github.com/e-contract/dssp', + 'type': 'GIT'}], + 'versions': [ 'dssp-1.2.1', + 'dssp-1.2.2', + 'dssp-1.2.3', + 'dssp-1.2.4', + 'dssp-1.2.5', + 'dssp-1.2.6', + 'dssp-1.3.0', + 'dssp-1.3.1']}], 'details': 'A vulnerability classified as problematic was found in ' 'e-Contract dssp up to 1.3.1. Affected by this vulnerability is ' 'the function checkSignResponse of the file ' @@ -111,42 +88,23 @@ 'ec4238349691ec66dd30b416ec6eaab02d722302. It is recommended to ' 'upgrade the affected component. The identifier VDB-217549 was ' 'assigned to this vulnerability.', - 'ecosystem': ['GIT'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2025, 7, 1, 21, 44, 41, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': [], - 'public': True, - 'purl': [], - 'reference_url_types': { 'https://github.com/e-Contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302': 'FIX', - 'https://github.com/e-Contract/dssp/releases/tag/dssp-1.3.2': 'ADVISORY', - 'https://vuldb.com/?ctiid.217549': 'REPORT', - 'https://vuldb.com/?id.217549': 'REPORT'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '15011', - '2016', - '2016-15011', - 'cve', - 'cve-2016', - 'cve-2016-15011', - 'dssp', - 'e-contract', - 'git', - 'github.com/e-contract/dssp', - 'https://github.com/e-contract/dssp'], - 'search_tags': ['cve-2016-15011'], - 'semver_fixed_indexes': [], - 'severities': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H', - 'type': 'CVSS_V3'}], - 'source': 'source', - 'source_id': 'source:a/b/CVE-2016-15011.json', - 'source_of_truth': 2, - 'status': 1, - 'summary': '', - 'timestamp': DatetimeWithNanoseconds(2023, 1, 6, 10, 15, 9, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'CVE-2016-15011', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2023-01-06T10:15:09Z', + 'references': [ { 'type': 'ADVISORY', + 'url': 'https://github.com/e-Contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302'}, + { 'type': 'ADVISORY', + 'url': 'https://github.com/e-Contract/dssp/releases/tag/dssp-1.3.2'}, + { 'type': 'ADVISORY', + 'url': 'https://vuldb.com/?ctiid.217549'}, + { 'type': 'ADVISORY', + 'url': 'https://vuldb.com/?id.217549'}, + { 'type': 'FIX', + 'url': 'https://github.com/e-Contract/dssp/commit/ec4238349691ec66dd30b416ec6eaab02d722302'}, + { 'type': 'REPORT', + 'url': 'https://vuldb.com/?ctiid.217549'}, + { 'type': 'REPORT', + 'url': 'https://vuldb.com/?id.217549'}], + 'schema_version': '1.7.3', + 'severity': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H', + 'type': 'CVSS_V3'}]} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_debian.txt b/gcp/workers/worker/testdata/UpdateTest_update_debian.txt index 5aebf710c03..b42b09b1107 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_debian.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_debian.txt @@ -1,30 +1,14 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '1.2.1-2.2', - '1.2.1-2.2+wheezy1', - '1.2.1-2.2+wheezy2', - '1.2.1-2.2+wheezy3~bpo60+1'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Debian:7', - 'name': 'nginx', - 'purl': 'pkg:deb/debian/nginx?arch=source'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '1.2.1-2.2+wheezy3'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '1.2.1-2.2', - '1.2.1-2.2+wheezy1', - '1.2.1-2.2+wheezy2', - '1.2.1-2.2+wheezy3~bpo60+1']}], +{ 'affected': [ { 'package': { 'ecosystem': 'Debian:7', + 'name': 'nginx', + 'purl': 'pkg:deb/debian/nginx?arch=source'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '1.2.1-2.2+wheezy3'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '1.2.1-2.2', + '1.2.1-2.2+wheezy1', + '1.2.1-2.2+wheezy2', + '1.2.1-2.2+wheezy3~bpo60+1']}], 'aliases': ['CVE-2014-3616'], - 'credits': [], - 'database_specific': None, - 'db_id': 'DSA-3029-1', 'details': '\n' 'Antoine Delignat-Lavaud and Karthikeyan Bhargavan discovered ' 'that it was\n' @@ -53,43 +37,10 @@ 'We recommend that you upgrade your nginx packages.\n' '\n' '\n', - 'ecosystem': ['Debian', 'Debian:7'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2014, 9, 20, 8, 18, 7, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['nginx'], - 'public': True, - 'purl': ['pkg:deb/debian/nginx', 'pkg:deb/debian/nginx?arch=source'], - 'reference_url_types': { 'https://www.debian.org/security/2014/dsa-3029': 'ADVISORY'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '1', - '2014', - '2014-3616', - '3029', - '3029-1', - '3616', - '7', - 'cve', - 'cve-2014', - 'cve-2014-3616', - 'debian', - 'debian:7', - 'dsa', - 'dsa-3029', - 'dsa-3029-1', - 'nginx'], - 'search_tags': ['dsa-3029-1', 'nginx'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:DSA-3029-1.json', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'nginx - security update', - 'timestamp': DatetimeWithNanoseconds(2014, 9, 20, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'DSA-3029-1', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2014-09-20T00:00:00Z', + 'references': [ { 'type': 'ADVISORY', + 'url': 'https://www.debian.org/security/2014/dsa-3029'}], + 'schema_version': '1.7.3', + 'summary': 'nginx - security update'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_last_affected.txt b/gcp/workers/worker/testdata/UpdateTest_update_last_affected.txt index eb8631f7074..545e9381ef5 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_last_affected.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_last_affected.txt @@ -1,129 +1,55 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '1.14.2', - '1.15.0', - '1.15.0rc1', - '1.16.0', - '1.16.0rc1', - '1.16.1', - '1.17.0', - '1.17.1', - '1.18.0', - '1.19.0', - '1.20.0', - '1.20.0rc1', - '1.20.0rc2', - '1.20.0rc3', - '1.20.1', - '1.21.0rc1', - '1.21.1', - '1.21.1rc1', - '1.22.0', - '1.22.0rc1', - '1.22.1', - '1.23.0', - '1.23.0rc1', - '1.23.1', - '1.24.0', - '1.24.0rc1', - '1.24.1', - '1.24.3', - '1.25.0', - '1.25.0rc1', - '1.26.0', - '1.26.0rc1', - '1.27.0rc1', - '1.27.0rc2', - '1.27.1', - '1.27.2', - '1.28.0rc1', - '1.28.0rc2', - '1.28.1', - '1.29.0', - '1.30.0', - '1.31.0'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'PyPI', - 'name': 'grpcio', - 'purl': 'pkg:pypi/grpcio'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '1.14.2'}, - { 'type': 'last_affected', - 'value': '1.31.0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '1.14.2', - '1.15.0', - '1.15.0rc1', - '1.16.0', - '1.16.0rc1', - '1.16.1', - '1.17.0', - '1.17.1', - '1.18.0', - '1.19.0', - '1.20.0', - '1.20.0rc1', - '1.20.0rc2', - '1.20.0rc3', - '1.20.1', - '1.21.0rc1', - '1.21.1', - '1.21.1rc1', - '1.22.0', - '1.22.0rc1', - '1.22.1', - '1.23.0', - '1.23.0rc1', - '1.23.1', - '1.24.0', - '1.24.0rc1', - '1.24.1', - '1.24.3', - '1.25.0', - '1.25.0rc1', - '1.26.0', - '1.26.0rc1', - '1.27.0rc1', - '1.27.0rc2', - '1.27.1', - '1.27.2', - '1.28.0rc1', - '1.28.0rc2', - '1.28.1', - '1.29.0', - '1.30.0', - '1.31.0']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'PYSEC-124', +{ 'affected': [ { 'package': { 'ecosystem': 'PyPI', + 'name': 'grpcio', + 'purl': 'pkg:pypi/grpcio'}, + 'ranges': [ { 'events': [ { 'introduced': '1.14.2'}, + { 'last_affected': '1.31.0'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '1.14.2', + '1.15.0', + '1.15.0rc1', + '1.16.0', + '1.16.0rc1', + '1.16.1', + '1.17.0', + '1.17.1', + '1.18.0', + '1.19.0', + '1.20.0', + '1.20.0rc1', + '1.20.0rc2', + '1.20.0rc3', + '1.20.1', + '1.21.0rc1', + '1.21.1', + '1.21.1rc1', + '1.22.0', + '1.22.0rc1', + '1.22.1', + '1.23.0', + '1.23.0rc1', + '1.23.1', + '1.24.0', + '1.24.0rc1', + '1.24.1', + '1.24.3', + '1.25.0', + '1.25.0rc1', + '1.26.0', + '1.26.0rc1', + '1.27.0rc1', + '1.27.0rc2', + '1.27.1', + '1.27.2', + '1.28.0rc1', + '1.28.0rc2', + '1.28.1', + '1.29.0', + '1.30.0', + '1.31.0']}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['PyPI'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), - 'is_fixed': False, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['grpcio'], - 'public': True, - 'purl': ['pkg:pypi/grpcio'], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': ['124', 'grpcio', 'pypi', 'pysec', 'pysec-124'], - 'search_tags': ['grpcio', 'pysec-124'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:PYSEC-124.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'PYSEC-124', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_limit.txt b/gcp/workers/worker/testdata/UpdateTest_update_limit.txt index dc9a0912254..ded5ae60b02 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_limit.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_limit.txt @@ -1,79 +1,26 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '1.13.0', - '1.14.0', - '1.14.0rc1', - '1.14.0rc2', - '1.14.1', - '1.14.2rc1', - 'branch-v0.1.1', - 'v0.1', - 'v0.1.1'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'PyPI', - 'name': 'grpcio', - 'purl': 'pkg:pypi/grpcio'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'limit', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}, - { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '1.13.0'}, - { 'type': 'limit', - 'value': '1.14.2'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ 'branch-v0.1.1', - '1.13.0', - '1.14.0', - '1.14.0rc1', - '1.14.0rc2', - '1.14.1', - '1.14.2rc1', - 'v0.1', - 'v0.1.1']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'OSV-128', +{ 'affected': [ { 'package': { 'ecosystem': 'PyPI', + 'name': 'grpcio', + 'purl': 'pkg:pypi/grpcio'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'limit': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}, + { 'events': [ { 'introduced': '1.13.0'}, + {'limit': '1.14.2'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ 'branch-v0.1.1', + '1.13.0', + '1.14.0', + '1.14.0rc1', + '1.14.0rc2', + '1.14.1', + '1.14.2rc1', + 'v0.1', + 'v0.1.1']}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT', 'PyPI'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['grpcio'], - 'public': True, - 'purl': ['pkg:pypi/grpcio'], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '128', - 'git', - 'grpcio', - 'https://osv-test/repo/url', - 'osv', - 'osv-128', - 'osv-test/repo/url', - 'pypi', - 'repo', - 'url'], - 'search_tags': ['grpcio', 'osv-128'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:OSV-128.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'OSV-128', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_linux.txt b/gcp/workers/worker/testdata/UpdateTest_update_linux.txt index 18dff8e75c6..8abe827660b 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_linux.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_linux.txt @@ -1,52 +1,12 @@ -{ 'affected': [], - 'affected_fuzzy': [], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Linux', - 'name': 'Kernel', - 'purl': None}, - 'ranges': [ { 'events': [ { 'type': 'introduced', - 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, - { 'type': 'fixed', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': []}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'LINUX-123', +{ 'affected': [ { 'package': {'ecosystem': 'Linux', 'name': 'Kernel'}, + 'ranges': [ { 'events': [ { 'introduced': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}]}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT','Linux'], - 'fixed': '', - 'has_affected': False, - 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), - 'project': ['Kernel'], - 'public': True, - 'purl': [], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '123', - 'git', - 'https://osv-test/repo/url', - 'kernel', - 'linux', - 'linux-123', - 'osv-test/repo/url', - 'repo', - 'url'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:LINUX-123.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': DatetimeWithNanoseconds(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'GSD-123', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_maven.txt b/gcp/workers/worker/testdata/UpdateTest_update_maven.txt index 38df7620556..b8f92df1d2f 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_maven.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_maven.txt @@ -1,46 +1,25 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '0.7.0-incubating', - '0.8.0', - '0.9.0', - '1.0', - '1.1', - '2.0', - '2.1', - '2.2', - '2.3', - '2.4'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Maven', - 'name': 'org.apache.any23:apache-any23', - 'purl': 'pkg:maven/org.apache.any23/apache-any23'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '2.5'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}], - 'severities': [], - 'versions': [ '0.7.0-incubating', - '0.8.0', - '0.9.0', - '1.0', - '1.1', - '2.0', - '2.1', - '2.2', - '2.3', - '2.4']}], +{ 'affected': [ { 'package': { 'ecosystem': 'Maven', + 'name': 'org.apache.any23:apache-any23', + 'purl': 'pkg:maven/org.apache.any23/apache-any23'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + {'fixed': '2.5'}], + 'type': 'ECOSYSTEM'}], + 'versions': [ '0.7.0-incubating', + '0.8.0', + '0.9.0', + '1.0', + '1.1', + '2.0', + '2.1', + '2.2', + '2.3', + '2.4']}], 'aliases': ['CVE-2021-38555'], - 'credits': [], 'database_specific': { 'cwe_ids': ['CWE-611'], 'github_reviewed': True, 'github_reviewed_at': '2021-09-13T19:31:01Z', 'nvd_published_at': '2021-09-11T11:15:00Z', 'severity': 'CRITICAL'}, - 'db_id': 'GHSA-838r-hvwh-24h8', 'details': 'An XML external entity (XXE) injection vulnerability was ' 'discovered in the Any23 StreamUtils.java file and is known to ' 'affect Any23 versions < 2.5. XML external entity injection ' @@ -50,51 +29,16 @@ 'files on the application server filesystem, and to interact ' 'with any back-end or external systems that the application ' 'itself can access.', - 'ecosystem': ['Maven'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2021, 9, 24, 13, 10, 5, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['org.apache.any23:apache-any23'], - 'public': True, - 'purl': ['pkg:maven/org.apache.any23/apache-any23'], - 'reference_url_types': { 'https://github.com/apache/any23': 'PACKAGE', - 'https://lists.apache.org/thread.html/r589d1a9f94dbeee7a0f5dbe8513a0e300dfe669bd964ba2fbfe28e07%40%3Cannounce.apache.org%3E': 'WEB', - 'https://nvd.nist.gov/vuln/detail/CVE-2021-38555': 'ADVISORY'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '2021', - '2021-38555', - '24h8', - '38555', - '838r', - '838r-hvwh', - '838r-hvwh-24h8', - 'any23', - 'apache', - 'cve', - 'cve-2021', - 'cve-2021-38555', - 'ghsa', - 'ghsa-838r', - 'ghsa-838r-hvwh', - 'ghsa-838r-hvwh-24h8', - 'hvwh', - 'hvwh-24h8', - 'maven', - 'org', - 'org.apache.any23:apache-any23'], - 'search_tags': ['ghsa-838r-hvwh-24h8', 'org.apache.any23:apache-any23'], - 'semver_fixed_indexes': [], - 'severities': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N', - 'type': 'CVSS_V3'}], - 'source': 'source', - 'source_id': 'source:GHSA-838r-hvwh-24h8.json', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'XML Injection in Any23', - 'timestamp': DatetimeWithNanoseconds(2021, 9, 13, 20, 6, 31, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'GHSA-838r-hvwh-24h8', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2021-09-13T20:06:31Z', + 'references': [ { 'type': 'ADVISORY', + 'url': 'https://nvd.nist.gov/vuln/detail/CVE-2021-38555'}, + { 'type': 'PACKAGE', + 'url': 'https://github.com/apache/any23'}, + { 'type': 'WEB', + 'url': 'https://lists.apache.org/thread.html/r589d1a9f94dbeee7a0f5dbe8513a0e300dfe669bd964ba2fbfe28e07%40%3Cannounce.apache.org%3E'}], + 'schema_version': '1.7.3', + 'severity': [ { 'score': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N', + 'type': 'CVSS_V3'}], + 'summary': 'XML Injection in Any23'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_new.txt b/gcp/workers/worker/testdata/UpdateTest_update_new.txt index 7c36f197aad..1b333bd0a52 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_new.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_new.txt @@ -1,67 +1,19 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ 'branch-v0.1.1', - 'branch_1_cherrypick_regress', - 'v0.1.1'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Go', - 'name': 'blah.com/package', - 'purl': 'pkg:golang/blah.com/package'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, - { 'type': 'fixed', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, - { 'type': 'introduced', - 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, - { 'type': 'fixed', - 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': [ 'branch-v0.1.1', - 'branch_1_cherrypick_regress', - 'v0.1.1']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'OSV-126', +{ 'affected': [ { 'package': { 'ecosystem': 'Go', + 'name': 'blah.com/package', + 'purl': 'pkg:golang/blah.com/package'}, + 'ranges': [ { 'events': [ { 'introduced': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'introduced': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'fixed': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT', 'Go'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['blah.com/package'], - 'public': True, - 'purl': ['pkg:golang/blah.com/package'], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '126', - 'blah', - 'blah.com/package', - 'com', - 'git', - 'go', - 'https://osv-test/repo/url', - 'osv', - 'osv-126', - 'osv-test/repo/url', - 'package', - 'repo', - 'url'], - 'search_tags': ['blah.com/package', 'osv-126'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:OSV-126.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'OSV-126', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_no_introduced.txt b/gcp/workers/worker/testdata/UpdateTest_update_no_introduced.txt index 821fb369530..9a6219d1cc8 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_no_introduced.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_no_introduced.txt @@ -1,67 +1,19 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ 'branch-v0.1.1', - 'branch_1_cherrypick_regress', - 'v0.1', - 'v0.1.1'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'Go', - 'name': 'blah.com/package', - 'purl': 'pkg:golang/blah.com/package'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, - { 'type': 'fixed', - 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': [ 'branch-v0.1.1', - 'branch_1_cherrypick_regress', - 'v0.1', - 'v0.1.1']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'OSV-127', +{ 'affected': [ { 'package': { 'ecosystem': 'Go', + 'name': 'blah.com/package', + 'purl': 'pkg:golang/blah.com/package'}, + 'ranges': [ { 'events': [ {'introduced': '0'}, + { 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'fixed': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1', + 'v0.1.1']}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT', 'Go'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['blah.com/package'], - 'public': True, - 'purl': ['pkg:golang/blah.com/package'], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '127', - 'blah', - 'blah.com/package', - 'com', - 'git', - 'go', - 'https://osv-test/repo/url', - 'osv', - 'osv-127', - 'osv-test/repo/url', - 'package', - 'repo', - 'url'], - 'search_tags': ['blah.com/package', 'osv-127'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:OSV-127.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': None, - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'OSV-127', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2021-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt b/gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt new file mode 100644 index 00000000000..39b24a9dd51 --- /dev/null +++ b/gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_delete.txt @@ -0,0 +1,7 @@ +{ 'details': 'Blah blah blah\nBlah\n', + 'id': 'OSV-131', + 'modified': '3000-01-01T00:00:00Z', + 'published': '2021-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt b/gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt index 3c2c9cfd004..5e0f3a2b915 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_partly_bad_ecosystem_new.txt @@ -1,65 +1,18 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': ['0-1-1', '1'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'ecosystem', - 'name': 'blah.com/package', - 'purl': None}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, - { 'type': 'fixed', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, - { 'type': 'introduced', - 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, - { 'type': 'fixed', - 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': [ 'branch-v0.1.1', - 'branch_1_cherrypick_regress', - 'v0.1.1']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'OSV-130', +{ 'affected': [ { 'package': { 'ecosystem': 'ecosystem', + 'name': 'blah.com/package'}, + 'ranges': [ { 'events': [ { 'introduced': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, + { 'introduced': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'fixed': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'versions': [ 'branch-v0.1.1', + 'branch_1_cherrypick_regress', + 'v0.1.1']}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT', 'ecosystem'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['blah.com/package'], - 'public': True, - 'purl': [], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '130', - 'blah', - 'blah.com/package', - 'com', - 'ecosystem', - 'git', - 'https://osv-test/repo/url', - 'osv', - 'osv-130', - 'osv-test/repo/url', - 'package', - 'repo', - 'url'], - 'search_tags': ['blah.com/package', 'osv-130'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:OSV-130.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'OSV-130', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/testdata/UpdateTest_update_pypi.txt b/gcp/workers/worker/testdata/UpdateTest_update_pypi.txt index 17d13fe02f8..26c2f56db26 100644 --- a/gcp/workers/worker/testdata/UpdateTest_update_pypi.txt +++ b/gcp/workers/worker/testdata/UpdateTest_update_pypi.txt @@ -1,143 +1,58 @@ -{ 'affected': [], - 'affected_checksum': None, - 'affected_fuzzy': [ '1.14.2', - '1.15.0', - '1.15.0rc1', - '1.16.0', - '1.16.0rc1', - '1.16.1', - '1.17.0', - '1.17.1', - '1.18.0', - '1.19.0', - '1.20.0', - '1.20.0rc1', - '1.20.0rc2', - '1.20.0rc3', - '1.20.1', - '1.21.0rc1', - '1.21.1', - '1.21.1rc1', - '1.22.0', - '1.22.0rc1', - '1.22.1', - '1.23.0', - '1.23.0rc1', - '1.23.1', - '1.24.0', - '1.24.0rc1', - '1.24.1', - '1.24.3', - '1.25.0', - '1.25.0rc1', - '1.26.0', - '1.26.0rc1', - '1.27.0rc1', - '1.27.0rc2', - '1.27.1', - '1.27.2', - '1.28.0rc1', - '1.28.0rc2', - '1.28.1', - '1.29.0', - '1.30.0'], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': None, - 'package': { 'ecosystem': 'PyPI', - 'name': 'grpcio', - 'purl': 'pkg:pypi/grpcio'}, - 'ranges': [ { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': '1.14.2'}, - { 'type': 'fixed', - 'value': '1.31.0'}], - 'repo_url': '', - 'type': 'ECOSYSTEM'}, - { 'database_specific': None, - 'events': [ { 'type': 'introduced', - 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, - { 'type': 'fixed', - 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], - 'repo_url': 'https://osv-test/repo/url', - 'type': 'GIT'}], - 'severities': [], - 'versions': [ '1.14.2', - '1.15.0', - '1.15.0rc1', - '1.16.0', - '1.16.0rc1', - '1.16.1', - '1.17.0', - '1.17.1', - '1.18.0', - '1.19.0', - '1.20.0', - '1.20.0rc1', - '1.20.0rc2', - '1.20.0rc3', - '1.20.1', - '1.21.0rc1', - '1.21.1', - '1.21.1rc1', - '1.22.0', - '1.22.0rc1', - '1.22.1', - '1.23.0', - '1.23.0rc1', - '1.23.1', - '1.24.0', - '1.24.0rc1', - '1.24.1', - '1.24.3', - '1.25.0', - '1.25.0rc1', - '1.26.0', - '1.26.0rc1', - '1.27.0rc1', - '1.27.0rc2', - '1.27.1', - '1.27.2', - '1.28.0rc1', - '1.28.0rc2', - '1.28.1', - '1.29.0', - '1.30.0']}], - 'aliases': [], - 'credits': [], - 'database_specific': None, - 'db_id': 'PYSEC-123', +{ 'affected': [ { 'package': { 'ecosystem': 'PyPI', + 'name': 'grpcio', + 'purl': 'pkg:pypi/grpcio'}, + 'ranges': [ { 'events': [ { 'introduced': '1.14.2'}, + {'fixed': '1.31.0'}], + 'type': 'ECOSYSTEM'}, + { 'events': [ { 'introduced': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, + { 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}], + 'repo': 'https://osv-test/repo/url', + 'type': 'GIT'}], + 'versions': [ '1.14.2', + '1.15.0', + '1.15.0rc1', + '1.16.0', + '1.16.0rc1', + '1.16.1', + '1.17.0', + '1.17.1', + '1.18.0', + '1.19.0', + '1.20.0', + '1.20.0rc1', + '1.20.0rc2', + '1.20.0rc3', + '1.20.1', + '1.21.0rc1', + '1.21.1', + '1.21.1rc1', + '1.22.0', + '1.22.0rc1', + '1.22.1', + '1.23.0', + '1.23.0rc1', + '1.23.1', + '1.24.0', + '1.24.0rc1', + '1.24.1', + '1.24.3', + '1.25.0', + '1.25.0rc1', + '1.26.0', + '1.26.0rc1', + '1.27.0rc1', + '1.27.0rc2', + '1.27.1', + '1.27.2', + '1.28.0rc1', + '1.28.0rc2', + '1.28.1', + '1.29.0', + '1.30.0']}], 'details': 'Blah blah blah\nBlah\n', - 'ecosystem': ['GIT', 'PyPI'], - 'fixed': '', - 'has_affected': True, - 'import_last_modified': DatetimeWithNanoseconds(2022, 10, 7, 18, 59, tzinfo=datetime.timezone.utc), - 'is_fixed': True, - 'issue_id': None, - 'last_modified': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'project': ['grpcio'], - 'public': True, - 'purl': ['pkg:pypi/grpcio'], - 'reference_url_types': {'https://ref.com/ref': 'WEB'}, - 'regressed': '', - 'related': [], - 'search_indices': [ '123', - 'git', - 'grpcio', - 'https://osv-test/repo/url', - 'osv-test/repo/url', - 'pypi', - 'pysec', - 'pysec-123', - 'repo', - 'url'], - 'search_tags': ['grpcio', 'pysec-123'], - 'semver_fixed_indexes': [], - 'severities': [], - 'source': 'source', - 'source_id': 'source:PYSEC-123.yaml', - 'source_of_truth': 2, - 'status': 1, - 'summary': 'A vulnerability', - 'timestamp': DatetimeWithNanoseconds(3000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - 'upstream_raw': [], - 'withdrawn': None} \ No newline at end of file + 'id': 'PYSEC-123', + 'modified': '3000-01-01T00:00:00Z', + 'published': '3000-01-01T00:00:00Z', + 'references': [{'type': 'WEB', 'url': 'https://ref.com/ref'}], + 'schema_version': '1.7.3', + 'summary': 'A vulnerability'} \ No newline at end of file diff --git a/gcp/workers/worker/worker.py b/gcp/workers/worker/worker.py index cf61a5694bc..5ab8e058541 100644 --- a/gcp/workers/worker/worker.py +++ b/gcp/workers/worker/worker.py @@ -18,6 +18,7 @@ import json import logging import os +import pygit2 import redis import requests import resource @@ -32,14 +33,15 @@ from google.cloud import pubsub_v1 from google.cloud import storage from google.cloud.storage import retry -from google.protobuf import json_format +from google.protobuf import json_format, timestamp_pb2 sys.path.append(os.path.dirname(os.path.realpath(__file__))) import osv -import osv.ecosystems import osv.cache +import osv.ecosystems +import osv.gcs import osv.logs -from osv import vulnerability_pb2 +from osv import vulnerability_pb2, purl_helpers import oss_fuzz from vanir import vulnerability_manager @@ -161,17 +163,6 @@ def clean_artifacts(oss_fuzz_dir): shutil.rmtree(build_dir, ignore_errors=True) -def mark_bug_invalid(message): - """Mark a bug as invalid.""" - source_id = get_source_id(message) - for bug in osv.Bug.query(osv.Bug.source_id == source_id): - bug.withdrawn = datetime.datetime.now(datetime.UTC) - bug.status = osv.BugStatus.INVALID - bug.put() - - osv.delete_affected_commits(bug.key.id()) - - def get_source_id(message): """Get message ID.""" source_id = message.attributes['source_id'] @@ -278,7 +269,9 @@ def fix_invalid_ghsa(vulnerability): return True -def maybe_normalize_package_names(vulnerability): +def maybe_normalize_package_names( + vulnerability: vulnerability_pb2.Vulnerability +) -> vulnerability_pb2.Vulnerability: """Normalize package names as necessary.""" for affected in vulnerability.affected: if not affected.package.ecosystem: @@ -331,6 +324,7 @@ def _source_update(self, message): path = message.attributes['path'] original_sha256 = message.attributes['original_sha256'] deleted = message.attributes['deleted'] == 'true' + skip_hash_check = message.attributes.get('skip_hash_check') == 'true' source_repo = osv.get_source_repository(source) if source_repo is None: @@ -346,8 +340,8 @@ def _source_update(self, message): vuln_path = os.path.join(osv.repo_path(repo), path) if not os.path.exists(vuln_path): logging.info('%s was deleted.', vuln_path) - if deleted: - self._handle_deleted(source_repo, path) + if deleted or skip_hash_check: + self._handle_deleted(path) return @@ -365,7 +359,7 @@ def _source_update(self, message): current_sha256 = osv.sha256(vuln_path) elif source_repo.type == osv.SourceRepositoryType.BUCKET: if deleted: - self._handle_deleted(source_repo, path) + self._handle_deleted(path) return storage_client = storage.Client() bucket = storage_client.bucket(source_repo.bucket) @@ -373,6 +367,8 @@ def _source_update(self, message): blob = bucket.blob(path).download_as_bytes(retry=retry.DEFAULT_RETRY) except google.cloud.exceptions.NotFound: logging.exception('Bucket path %s does not exist.', path) + if skip_hash_check: + self._handle_deleted(path) return current_sha256 = osv.sha256_bytes(blob) @@ -387,10 +383,15 @@ def _source_update(self, message): repo = None elif source_repo.type == osv.SourceRepositoryType.REST_ENDPOINT: + if deleted: + self._handle_deleted(path) + return vulnerabilities = [] request = requests.get(source_repo.link + path, timeout=_TIMEOUT_SECONDS) if request.status_code != 200: logging.error('Failed to fetch REST API: %s', request.status_code) + if request.status_code == 404 and skip_hash_check: + self._handle_deleted(path) return vuln = request.json() try: @@ -403,7 +404,7 @@ def _source_update(self, message): else: raise RuntimeError('Unsupported SourceRepository type.') - if current_sha256 != original_sha256: + if not skip_hash_check and current_sha256 != original_sha256: logging.warning( 'sha256sum of %s no longer matches (expected=%s vs current=%s).', path, original_sha256, current_sha256) @@ -424,31 +425,71 @@ def _source_update(self, message): for vulnerability in vulnerabilities: self._do_update(source_repo, repo, vulnerability, path, original_sha256) - def _handle_deleted(self, source_repo, vuln_path): - """Handle existing bugs that have been subsequently deleted at their source. + def _handle_deleted(self, vuln_path: str): + """Handle existing vulns that have been subsequently deleted at their + source. Args: - source_repo: Source repository. vuln_path: Path to vulnerability. - This marks the Bug as INVALID and as withdrawn. + This marks the Vulnerability as withdrawn. """ vuln_id = os.path.splitext(os.path.basename(vuln_path))[0] - bug = osv.Bug.get_by_id(vuln_id) - if not bug: - logging.error('Failed to find Bug with ID %s', vuln_id) - return + vuln_and_gen = osv.gcs.get_by_id_with_generation(vuln_id) + gcs_gen = None + proto_vuln = None + + def xact(): + nonlocal gcs_gen + nonlocal proto_vuln + ds_vuln: osv.Vulnerability = osv.Vulnerability.get_by_id(vuln_id) + if not ds_vuln: + logging.error('Failed to find Vulnerability with ID %s', vuln_id) + return - bug_source_path = osv.source_path(source_repo, bug) - if bug_source_path != vuln_path: - logging.error('Request path %s does not match %s, aborting.', vuln_path, - bug_source_path) - return + _, _, ds_path = ds_vuln.source_id.partition(':') - logging.info('Marking %s as invalid and withdrawn.', vuln_id) - bug.status = osv.BugStatus.INVALID - bug.withdrawn = datetime.datetime.now(datetime.UTC) - bug.put() + if ds_path != vuln_path: + logging.error('Request path %s does not match %s, aborting.', vuln_path, + ds_path) + return + + logging.info('Marking %s as withdrawn.', vuln_id) + if not vuln_and_gen: + logging.error('Failed to find Vulnerability with ID %s in GCS', vuln_id) + # contruct an empty withdrawn vuln + proto_vuln = vulnerability_pb2.Vulnerability(id=vuln_id) + else: + proto_vuln, gcs_gen = vuln_and_gen + + if not proto_vuln.HasField('withdrawn'): + # in case this was already withdrawn for some reason + proto_vuln.withdrawn.FromDatetime(datetime.datetime.now(datetime.UTC)) + if (not proto_vuln.HasField('modified') or + proto_vuln.withdrawn.ToDatetime( + datetime.UTC) > proto_vuln.modified.ToDatetime(datetime.UTC)): + proto_vuln.modified.CopyFrom(proto_vuln.withdrawn) + ds_vuln.is_withdrawn = True + ds_vuln.modified = proto_vuln.modified.ToDatetime(datetime.UTC) + osv.models.put_entities(ds_vuln, proto_vuln) + + try: + ndb.transaction(xact) + except (google.api_core.exceptions.Cancelled, ndb.exceptions.Error) as e: + e.add_note(f'Happened processing {vuln_id}') + logging.exception('Unexpected exception while writing %s to Datastore', + vuln_id) + raise + if not proto_vuln: + return + try: + osv.gcs.upload_vulnerability(proto_vuln, gcs_gen) + except Exception: + # Writing to bucket failed for some reason. + # Send a pub/sub message to retry. + logging.error('Writing to bucket failed for %s', vuln_id) + data = proto_vuln.SerializeToString(deterministic=True) + osv.pubsub.publish_failure(data, type='gcs_retry') def _push_new_ranges_and_versions(self, source_repo, repo, vulnerability, output_path, original_sha256): @@ -464,17 +505,12 @@ def _push_new_ranges_and_versions(self, source_repo, repo, vulnerability, output_path: original_sha256, }) - def _analyze_vulnerability(self, source_repo, repo, vulnerability, path, - original_sha256): + def _analyze_vulnerability(self, source_repo: osv.SourceRepository, + repo: pygit2.Repository | None, + vulnerability: vulnerability_pb2.Vulnerability, + path: str, + original_sha256: str) -> osv.AnalyzeResult: """Analyze vulnerability and push new changes.""" - # Add OSS-Fuzz - added_fix_info = False - bug = osv.Bug.get_by_id(vulnerability.id) - if bug: - fix_result = osv.FixResult.get_by_id(bug.source_id) - if fix_result: - added_fix_info = add_fix_information(vulnerability, fix_result) - result = osv.analyze( vulnerability, checkout_path=os.path.join(self._work_dir, 'checkout'), @@ -483,12 +519,14 @@ def _analyze_vulnerability(self, source_repo, repo, vulnerability, path, versions_from_repo=source_repo.versions_from_repo, consider_all_branches=source_repo.consider_all_branches) - if not result.has_changes and not added_fix_info: + if not result.has_changes: return result if not source_repo.editable: return result - + # NB: Only OSS-Fuzz is editable - all other sources are read-only. + # This should not be reachable by this worker. + logging.error('Source %s flagged as editable', source_repo.name) output_path = os.path.join(osv.repo_path(repo), path) if self._push_new_ranges_and_versions(source_repo, repo, vulnerability, output_path, original_sha256): @@ -500,7 +538,9 @@ def _analyze_vulnerability(self, source_repo, repo, vulnerability, path, vulnerability.id) raise UpdateConflictError - def _generate_vanir_signatures(self, vulnerability): + def _generate_vanir_signatures( + self, vulnerability: vulnerability_pb2.Vulnerability + ) -> vulnerability_pb2.Vulnerability: """Generates Vanir signatures for a vulnerability.""" if not any(r.type == vulnerability_pb2.Range.GIT for affected in vulnerability.affected @@ -537,8 +577,10 @@ def _generate_vanir_signatures(self, vulnerability): vulnerability.id) return vulnerability - def _do_update(self, source_repo, repo, vulnerability, relative_path, - original_sha256): + def _do_update(self, source_repo: osv.SourceRepository, + repo: pygit2.Repository | None, + vulnerability: vulnerability_pb2.Vulnerability, + relative_path: str, original_sha256: str): """Process updates on a vulnerability.""" _state.bug_id = vulnerability.id logging.info('Processing update for vulnerability %s', vulnerability.id) @@ -561,70 +603,139 @@ def _do_update(self, source_repo, repo, vulnerability, relative_path, # Discard changes due to conflict. return - # Fetch the current state from Datastore. - bug = osv.Bug.get_by_id(vulnerability.id) - is_new_bug = bug is None - - has_changed = False - if is_new_bug: - has_changed = True - if source_repo.name == 'oss-fuzz': - logging.warning('%s not found for OSS-Fuzz source.', vulnerability.id) - return - - bug = osv.Bug( - db_id=vulnerability.id, - timestamp=osv.utcnow(), - status=osv.BugStatus.PROCESSED, - source_of_truth=osv.SourceOfTruth.SOURCE_REPO) - else: - # Compare the newly enriched vulnerability with the stored one. - # Create a 'pure' vulnerability object from the existing bug for - # comparison, excluding external data that would cause false positives. - old_vulnerability = bug.to_vulnerability( - include_source=False, include_alias=False, include_upstream=False) - - # Clear modified timestamps for a clean comparison. - old_vulnerability.modified.Clear() - vulnerability.modified.Clear() - - if old_vulnerability != vulnerability: + vuln_and_gen = osv.gcs.get_by_id_with_generation(vulnerability.id) + gcs_gen = None + + def xact(): + # Fetch the current state from Datastore. + nonlocal gcs_gen + ds_vuln = osv.Vulnerability.get_by_id(vulnerability.id) + is_new_bug = ds_vuln is None + + # Compute the related fields here first. + # TODO(michaelkedar): Make a related computation in relations cron + related_raw = vulnerability.related + q = osv.Vulnerability.query( + osv.Vulnerability.related_raw == vulnerability.id) + related = set(vulnerability.related).union(set(r.key.id() for r in q)) + vulnerability.related[:] = sorted(related) + + old_published = None + + # Update the schema version + # TODO(michaelkedar): osv.SCHEMA_VERSION is not kept up to date with + # the osv-schema submodule + vulnerability.schema_version = osv.SCHEMA_VERSION + # Add PURLs and source if they are missing. + source_link = None + if source_repo and source_repo.link: + source_link = source_repo.link + relative_path + for affected in vulnerability.affected: + if not affected.package.purl: + if purl := purl_helpers.package_to_purl( + osv.ecosystems.normalize(affected.package.ecosystem), + affected.package.name): + affected.package.purl = purl + if source_link: + affected.database_specific.update({'source': source_link}) + + has_changed = False + if is_new_bug: has_changed = True + ds_vuln = osv.Vulnerability( + id=vulnerability.id, + source_id=f'{source_repo.name}:{relative_path}', + ) + else: + # Compare the newly enriched vulnerability with the stored one. + # Create a 'pure' vulnerability object from the existing vuln for + # comparison, excluding external data that would cause false positives. + if vuln_and_gen is None: + logging.warning('Vulnerability %s found in Datastore but not in GCS.', + vulnerability.id) + # We need to write the vuln in this case + has_changed = True + else: + old_vulnerability, gcs_gen = vuln_and_gen + if old_vulnerability.HasField('published'): + old_published = timestamp_pb2.Timestamp() + old_published.CopyFrom(old_vulnerability.published) + new_vulnerability = vulnerability_pb2.Vulnerability() + new_vulnerability.CopyFrom(vulnerability) + + # Clear modified/published timestamps for a clean comparison. + old_vulnerability.modified.Clear() + new_vulnerability.modified.Clear() + old_vulnerability.published.Clear() + new_vulnerability.published.Clear() + # Clear aliases and upstream, as they are computed separately. + old_vulnerability.aliases.clear() + new_vulnerability.aliases.clear() + old_vulnerability.upstream.clear() + new_vulnerability.upstream.clear() + + has_changed = old_vulnerability != new_vulnerability + + ds_vuln.is_withdrawn = vulnerability.HasField('withdrawn') + ds_vuln.modified_raw = orig_modified_date + ds_vuln.alias_raw = list(vulnerability.aliases) + ds_vuln.related_raw = list(related_raw) + ds_vuln.upstream_raw = list(vulnerability.upstream) + # Update the bug entity based on the comparison. + if has_changed: + ds_vuln.modified = osv.utcnow() + else: + # If no meaningful change, ensure last_modified reflects the source + # file's modified date, as only metadata might have changed. + ds_vuln.modified = orig_modified_date + + # Overwrite aliases / upstream from computation + alias_group = osv.AliasGroup.query( + osv.AliasGroup.bug_ids == vulnerability.id).get() + if alias_group: + aliases = sorted(set(alias_group.bug_ids) - {vulnerability.id}) + vulnerability.aliases[:] = aliases + ds_vuln.modified = max(alias_group.last_modified, ds_vuln.modified) + upstream_group = osv.UpstreamGroup.query( + osv.UpstreamGroup.db_id == vulnerability.id).get() + if upstream_group: + vulnerability.upstream[:] = sorted(upstream_group.upstream_ids) + ds_vuln.modified = max(upstream_group.last_modified, ds_vuln.modified) + # Make sure modified date is >= withdrawn date + if ds_vuln.is_withdrawn and vulnerability.withdrawn.ToDatetime( + datetime.UTC) > ds_vuln.modified: + ds_vuln.modified = vulnerability.withdrawn.ToDatetime(datetime.UTC) + + vulnerability.modified.FromDatetime(ds_vuln.modified) + + # Make sure vuln has a published date + if not vulnerability.HasField('published'): + if old_published: + vulnerability.published.CopyFrom(old_published) + else: + vulnerability.published.CopyFrom(vulnerability.modified) + + osv.models.put_entities(ds_vuln, vulnerability) + osv.update_affected_commits(vulnerability.id, result.commits, True) - # Update the bug entity based on the comparison. - if has_changed: - bug.update_from_vulnerability(vulnerability) - bug.last_modified = osv.utcnow() - else: - # If no meaningful change, ensure last_modified reflects the source file's - # modified date, as only metadata might have changed. - bug.last_modified = orig_modified_date - - bug.public = True - bug.import_last_modified = orig_modified_date - # OSS-Fuzz sourced bugs use a different format for source_id. - if source_repo.name != 'oss-fuzz' or not bug.source_id: - bug.source_id = f'{source_repo.name}:{relative_path}' - - if bug.withdrawn: - bug.status = osv.BugStatus.INVALID - else: - bug.status = osv.BugStatus.PROCESSED - - if not vulnerability.affected: - logging.info('%s does not affect any packages. Marking as invalid.', - vulnerability.id) - bug.status = osv.BugStatus.INVALID try: - bug.put() + ndb.transaction(xact) except (google.api_core.exceptions.Cancelled, ndb.exceptions.Error) as e: e.add_note(f'Happened processing {vulnerability.id}') logging.exception('Unexpected exception while writing %s to Datastore', vulnerability.id) + raise + try: + osv.gcs.upload_vulnerability(vulnerability, gcs_gen) + except Exception: + # Writing to bucket failed for some reason. + # Send a pub/sub message to retry. + logging.error('Writing to bucket failed for %s', vulnerability.id) + data = vulnerability.SerializeToString(deterministic=True) + osv.pubsub.publish_failure(data, type='gcs_retry') - osv.update_affected_commits(bug.key.id(), result.commits, bug.public) self._notify_ecosystem_bridge(vulnerability) - self._maybe_remove_import_findings(bug) + self._maybe_remove_import_findings(vulnerability.id) def _notify_ecosystem_bridge(self, vulnerability): """Notify ecosystem bridges.""" @@ -644,12 +755,12 @@ def _notify_ecosystem_bridge(self, vulnerability): push_topic, data=json.dumps(osv.vulnerability_to_dict(vulnerability)).encode()) - def _maybe_remove_import_findings(self, vulnerability: osv.Bug): - """Remove any stale import findings for a successfully processed Bug,""" + def _maybe_remove_import_findings(self, vuln_id: str): + """Remove any stale import findings for a successfully processed Vuln,""" - finding = osv.ImportFinding.get_by_id(vulnerability.id()) + finding = osv.ImportFinding.get_by_id(vuln_id) if finding: - logging.info('Removing stale import finding for %s', vulnerability.id()) + logging.info('Removing stale import finding for %s', vuln_id) finding.key.delete() def _do_process_task(self, subscriber, subscription, ack_id, message, @@ -677,19 +788,12 @@ def _do_process_task(self, subscriber, subscription, ack_id, message, logging.error('got unexpected \'%s\' task for non-oss-fuzz source %s', task_type, source_id) - if task_type in ('regressed', 'fixed'): - oss_fuzz.process_bisect_task(self._oss_fuzz_dir, task_type, source_id, - message) - elif task_type == 'impact': - try: - oss_fuzz.process_impact_task(source_id, message) - except osv.ImpactError: - logging.exception('Failed to process impact: ') - elif task_type == 'invalid': - mark_bug_invalid(message) - elif task_type == 'update-oss-fuzz': - # TODO(michaelkedar): create separate _source_update for oss-fuzz. - self._source_update(message) + if task_type in ('regressed', 'fixed', 'impact', 'invalid', + 'update-oss-fuzz'): + # TODO(michaelkedar): Remove this once the cutover is complete and the + # subscription filter is updated. + logging.info('Ignoring OSS-Fuzz task %s for source %s', task_type, + source_id) elif task_type == 'update': self._source_update(message) diff --git a/gcp/workers/worker/worker_test.py b/gcp/workers/worker/worker_test.py index 2e4fc8dc540..15997c87142 100644 --- a/gcp/workers/worker/worker_test.py +++ b/gcp/workers/worker/worker_test.py @@ -18,8 +18,8 @@ import hashlib from gcp.workers.mock_test.mock_test_handler import MockDataHandler import http.server +import logging import os -import shutil import tempfile import threading import warnings @@ -27,11 +27,12 @@ from unittest import mock from google.cloud import ndb +from google.protobuf.json_format import MessageToDict import pygit2 import osv from osv import tests -import oss_fuzz +from osv import vulnerability_pb2 import worker TEST_BUCKET = 'test-osv-source-bucket' @@ -58,550 +59,6 @@ def _sha256(test_name): return hasher.hexdigest() -class OssFuzzDetailsTest(unittest.TestCase): - """Details generation tests.""" - - def test_basic(self): - """Basic tests.""" - crash_type = 'Heap-buffer-overflow' - crash_state = 'Foo\nBar\nBlah\n' - - summary = oss_fuzz.get_oss_fuzz_summary(crash_type, crash_state) - self.assertEqual('Heap-buffer-overflow in Foo', summary) - - details = oss_fuzz.get_oss_fuzz_details('1337', crash_type, crash_state) - self.assertEqual( - 'OSS-Fuzz report: ' - 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1337\n\n' - '```\n' - 'Crash type: Heap-buffer-overflow\n' - 'Crash state:\n' - 'Foo\n' - 'Bar\n' - 'Blah\n```\n', - details, - ) - - def test_no_issue(self): - """Test generating details without an issue ID.""" - crash_type = 'Heap-buffer-overflow' - crash_state = 'Foo\nBar\nBlah\n' - - details = oss_fuzz.get_oss_fuzz_details('', crash_type, crash_state) - self.assertEqual( - '```\n' - 'Crash type: Heap-buffer-overflow\n' - 'Crash state:\n' - 'Foo\n' - 'Bar\n' - 'Blah\n```\n', - details, - ) - - def test_assert(self): - """Basic assertion failures.""" - crash_type = 'ASSERT' - crash_state = 'idx < length\nFoo\nBar\n' - - summary = oss_fuzz.get_oss_fuzz_summary(crash_type, crash_state) - self.assertEqual('ASSERT: idx < length', summary) - - details = oss_fuzz.get_oss_fuzz_details('1337', crash_type, crash_state) - self.assertEqual( - 'OSS-Fuzz report: ' - 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1337\n\n' - '```\n' - 'Crash type: ASSERT\n' - 'Crash state:\n' - 'idx < length\n' - 'Foo\n' - 'Bar\n```\n', - details, - ) - - def test_bad_cast(self): - """Basic bad casts.""" - crash_type = 'Bad-cast' - crash_state = 'Bad-cast to A from B\nFoo\nBar\n' - - summary = oss_fuzz.get_oss_fuzz_summary(crash_type, crash_state) - self.assertEqual('Bad-cast to A from B', summary) - - details = oss_fuzz.get_oss_fuzz_details('1337', crash_type, crash_state) - self.assertEqual( - 'OSS-Fuzz report: ' - 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1337\n\n' - '```\n' - 'Crash type: Bad-cast\n' - 'Crash state:\n' - 'Bad-cast to A from B\n' - 'Foo\n' - 'Bar\n```\n', - details, - ) - - -class ImpactTest(unittest.TestCase, tests.ExpectationTest(TEST_DATA_DIR)): - """Impact task tests.""" - - def setUp(self): - ds_emulator.reset() - self.maxDiff = None - - tests.mock_clone(self, return_value=pygit2.Repository('osv-test')) - tests.mock_datetime(self) - - osv.SourceRepository( - id='oss-fuzz', name='oss-fuzz', db_prefix=['OSV-']).put() - - allocated_bug = osv.Bug( - db_id='OSV-2020-1337', - timestamp=datetime.datetime(2020, 1, 1, tzinfo=datetime.UTC), - source_id='oss-fuzz:123', - status=osv.BugStatus.UNPROCESSED, - public=False, - ) - allocated_bug.put() - - # This should be deleted and overwritten with the actual computed commits. - osv.AffectedCommits( - id='OSV-2020-1337-3', bug_id='OSV-2020-1337', page=3).put() - - def test_basic(self): - """Basic test.""" - message = mock.Mock() - message.attributes = { - 'source_id': 'oss-fuzz:123', - 'allocated_id': 'OSV-2020-1337', - } - - regress_result = osv.RegressResult( - id='oss-fuzz:123', - commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - repo_url='https://repo.com/repo', - issue_id='9001', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - regress_result.put() - - fix_result = osv.FixResult( - id='oss-fuzz:123', - commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', - repo_url='https://repo.com/repo', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - details='DETAILS', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - fix_result.put() - - oss_fuzz.process_impact_task('oss-fuzz:123', message) - self.expect_dict_equal('basic', - ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) - - affected_commits = list(osv.AffectedCommits.query()) - self.assertEqual(1, len(affected_commits)) - affected_commits = affected_commits[0] - - self.assertCountEqual( - [ - b'4c155795426727ea05575bd5904321def23c03f4', - b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', - b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', - b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', - ], - [codecs.encode(commit, 'hex') for commit in affected_commits.commits], - ) - - def test_range(self): - """Test commit range.""" - message = mock.Mock() - message.attributes = { - 'source_id': 'oss-fuzz:123', - 'allocated_id': 'OSV-2020-1337', - } - - regress_result = osv.RegressResult( - id='oss-fuzz:123', - commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - repo_url='https://repo.com/repo', - issue_id='9001', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - regress_result.put() - - fix_result = osv.FixResult( - id='oss-fuzz:123', - commit=('b1c95a196f22d06fcf80df8c6691cd113d8fefff:' - '36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2'), - repo_url='https://repo.com/repo', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - details='DETAILS', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - fix_result.put() - - oss_fuzz.process_impact_task('oss-fuzz:123', message) - self.expect_dict_equal('range', - ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) - - affected_commits = list(osv.AffectedCommits.query()) - self.assertEqual(1, len(affected_commits)) - affected_commits = affected_commits[0] - - self.assertCountEqual( - [ - b'4c155795426727ea05575bd5904321def23c03f4', - b'8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', - b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', - b'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', - b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', - b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', - ], - [codecs.encode(commit, 'hex') for commit in affected_commits.commits], - ) - - def test_fixed_range_too_long(self): - """Test fixed range that's too long.""" - message = mock.Mock() - message.attributes = { - 'source_id': 'oss-fuzz:123', - 'allocated_id': 'OSV-2020-1337', - } - - regress_result = osv.RegressResult( - id='oss-fuzz:123', - commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - repo_url='https://repo.com/repo', - issue_id='9001', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - regress_result.put() - - fix_result = osv.FixResult( - id='oss-fuzz:123', - commit=('eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:' - 'b587c21c36a84e16cfc6b39eb68578d43b5281ad'), - repo_url='https://repo.com/repo', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - details='DETAILS', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - fix_result.put() - - with self.assertLogs(level='WARNING') as logs: - oss_fuzz.process_impact_task('oss-fuzz:123', message) - self.assertEqual(logs.output, - ['WARNING:root:Too many commits in fix range.']) - - self.expect_dict_equal( - 'fixed_range_too_long', - ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict(), - ) - - affected_commits = list(osv.AffectedCommits.query()) - self.assertEqual(1, len(affected_commits)) - affected_commits = affected_commits[0] - - self.assertCountEqual( - [ - b'36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', - b'3ea6feea9bb853596c727abab309476cc07d1505', - b'4c155795426727ea05575bd5904321def23c03f4', - b'8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', - b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', - b'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', - b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', - b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', - ], - [codecs.encode(commit, 'hex') for commit in affected_commits.commits], - ) - - def test_zero_regression_range(self): - """Test regression range with '0:X'.""" - message = mock.Mock() - message.attributes = { - 'source_id': 'oss-fuzz:123', - 'allocated_id': 'OSV-2020-1337', - } - - regress_result = osv.RegressResult( - id='oss-fuzz:123', - commit='unknown:eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - repo_url='https://repo.com/repo', - issue_id='9001', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - regress_result.put() - - fix_result = osv.FixResult( - id='oss-fuzz:123', - commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', - repo_url='https://repo.com/repo', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - details='DETAILS', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - fix_result.put() - - oss_fuzz.process_impact_task('oss-fuzz:123', message) - self.expect_dict_equal( - 'zero_regression_range', - ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict(), - ) - - affected_commits = list(osv.AffectedCommits.query()) - self.assertEqual(1, len(affected_commits)) - affected_commits = affected_commits[0] - - self.assertCountEqual( - [ - b'4c155795426727ea05575bd5904321def23c03f4', - b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', - b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', - b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', - ], - [codecs.encode(commit, 'hex') for commit in affected_commits.commits], - ) - - def test_simplify_range(self): - """Test simplifying commit range.""" - message = mock.Mock() - message.attributes = { - 'source_id': 'oss-fuzz:123', - 'allocated_id': 'OSV-2020-1337', - } - - regress_result = osv.RegressResult( - id='oss-fuzz:123', - commit=('a2ba949290915d445d34d0e8e9de2e7ce38198fc:' - 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'), - repo_url='https://repo.com/repo', - issue_id='9001', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - regress_result.put() - - fix_result = osv.FixResult( - id='oss-fuzz:123', - commit=('b1c95a196f22d06fcf80df8c6691cd113d8fefff:' - '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'), - repo_url='https://repo.com/repo', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - details='DETAILS', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - fix_result.put() - - oss_fuzz.process_impact_task('oss-fuzz:123', message) - self.expect_dict_equal('simplify_range', - ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) - - def test_not_fixed(self): - """Test not fixed bug.""" - message = mock.Mock() - message.attributes = { - 'source_id': 'oss-fuzz:123', - 'allocated_id': 'OSV-2020-1337', - } - - regress_result = osv.RegressResult( - id='oss-fuzz:123', - commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - repo_url='https://repo.com/repo', - issue_id='9001', - project='project', - ecosystem='ecosystem', - summary='Heap-buffer-overflow in Foo', - details='DETAILS', - severity='MEDIUM', - reference_urls=['https://url/'], - ) - regress_result.put() - - with self.assertLogs(level='WARNING') as logs: - oss_fuzz.process_impact_task('oss-fuzz:123', message) - self.assertEqual(logs.output, - ['WARNING:root:Missing FixResult for oss-fuzz:123']) - - self.expect_dict_equal('not_fixed', - ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) - - affected_commits = list(osv.AffectedCommits.query()) - self.assertEqual(1, len(affected_commits)) - affected_commits = affected_commits[0] - - self.assertCountEqual( - [ - b'36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', - b'3ea6feea9bb853596c727abab309476cc07d1505', - b'4c155795426727ea05575bd5904321def23c03f4', - b'88e5ae3c40c85b702ba89a34c29f233048abb12b', - b'8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', - b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', - b'b587c21c36a84e16cfc6b39eb68578d43b5281ad', - b'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', - b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', - b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', - ], - [codecs.encode(commit, 'hex') for commit in affected_commits.commits], - ) - - -class EcosystemTest(unittest.TestCase): - """Test getting ecosystem.""" - - def setUp(self): - self.tmp_dir = tempfile.mkdtemp() - self.oss_fuzz_checkout = os.path.join(self.tmp_dir, 'oss-fuzz') - osv.ensure_updated_checkout(worker.OSS_FUZZ_GIT_URL, self.oss_fuzz_checkout) - - def tearDown(self): - shutil.rmtree(self.tmp_dir, ignore_errors=True) - - def test_get_ecosystem(self): - """Test getting ecosystems.""" - self.assertEqual('PyPI', - oss_fuzz.get_ecosystem(self.oss_fuzz_checkout, 'pillow')) - self.assertEqual( - 'Go', - oss_fuzz.get_ecosystem(self.oss_fuzz_checkout, 'golang-protobuf'), - ) - self.assertEqual( - 'OSS-Fuzz', - oss_fuzz.get_ecosystem(self.oss_fuzz_checkout, 'openssl'), - ) - - -class MarkBugInvalidTest(unittest.TestCase): - """Test mark_bug_invalid.""" - - def setUp(self): - ds_emulator.reset() - - def test_mark_bug_invalid(self): - """Test mark_bug_invalid.""" - osv.SourceRepository( - id='oss-fuzz', name='oss-fuzz', db_prefix=['OSV-']).put() - osv.Bug(db_id='OSV-2021-1', source_id='oss-fuzz:1337').put() - osv.AffectedCommits(bug_id='OSV-2021-1').put() - osv.AffectedCommits(bug_id='OSV-2021-1').put() - - message = mock.Mock() - message.attributes = { - 'type': 'invalid', - 'testcase_id': '1337', - 'source_id': '', - } - - worker.mark_bug_invalid(message) - bug = ndb.Key(osv.Bug, 'OSV-2021-1').get() - self.assertEqual(osv.BugStatus.INVALID, bug.status) - - commits = list(osv.AffectedCommits.query()) - self.assertEqual(0, len(commits)) - - -class FindOssFuzzFixViaCommitTest(unittest.TestCase): - """Test finding OSS-Fuzz fixes via commits.""" - - def setUp(self): - self.repo = pygit2.Repository('osv-test') - - def test_has_issue_id(self): - """Test identifying the commit that has the issue ID.""" - commit = oss_fuzz.find_oss_fuzz_fix_via_commit( - self.repo, - 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', - '949f182716f037e25394bbb98d39b3295d230a29', - 'oss-fuzz:133713371337', - '12345', - ) - self.assertEqual('57e58a5d7c2bb3ce0f04f17ec0648b92ee82531f', commit) - - commit = oss_fuzz.find_oss_fuzz_fix_via_commit( - self.repo, - 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', - '25147a74d8aeb27b43665530ee121a2a1b19dc58', - 'oss-fuzz:133713371337', - '12345', - ) - self.assertEqual('25147a74d8aeb27b43665530ee121a2a1b19dc58', commit) - - def test_has_testcase_id(self): - """Test identifying the commit that has the testcase ID.""" - commit = oss_fuzz.find_oss_fuzz_fix_via_commit( - self.repo, - 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', - '00514d6f244f696e750a37083163992c6a50cfd3', - 'oss-fuzz:133713371337', - '12345', - ) - - self.assertEqual('90aa4127295b2c37b5f7fcf6a9772b12c99a5212', commit) - - def test_has_oss_fuzz_reference(self): - """Test identifying the commit that has the testcase ID.""" - commit = oss_fuzz.find_oss_fuzz_fix_via_commit( - self.repo, - 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', - 'b1fa81a5d59e9b4d6e276d82fc17058f3cf139d9', - 'oss-fuzz:133713371337', - '12345', - ) - - self.assertEqual('3c5dcf6a5bec14baab3b247d369a7270232e1b83', commit) - - def test_has_multiple_oss_fuzz_reference(self): - commit = oss_fuzz.find_oss_fuzz_fix_via_commit( - self.repo, - 'e1b045257bc5ca2a11d0476474f45ef77a0366c7', - '949f182716f037e25394bbb98d39b3295d230a29', - 'oss-fuzz:7331', - '54321', - ) - self.assertIsNone(commit) - - class RESTUpdateTest(unittest.TestCase, tests.ExpectationTest(TEST_DATA_DIR)): """Vulnerability update tests.""" @@ -612,6 +69,7 @@ def setUp(self): # Initialise fake source_repo. self.tmp_dir = tempfile.TemporaryDirectory() + self.addCleanup(self.tmp_dir.cleanup) self.source_repo = osv.SourceRepository( type=osv.SourceRepositoryType.REST_ENDPOINT, @@ -638,7 +96,6 @@ def setUp(self): def tearDown(self): self.httpd.shutdown() - self.tmp_dir.cleanup() def test_update(self): """Test updating rest.""" @@ -662,13 +119,17 @@ def test_git_ranges(self): sha = '6138604b5537caab2afc0ee3e2b11f1574fdd5d8f3c6173f64048341cf55aee4' task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, None) - osv.Bug( - db_id='CURL-CVE-2022-32221', - ecosystem=[''], + vuln_pb = vulnerability_pb2.Vulnerability(id='CURL-CVE-2022-32221') + vuln_pb.modified.FromDatetime( + datetime.datetime(2020, 1, 1, 0, 0, tzinfo=datetime.UTC)) + vuln_ds = osv.Vulnerability( + id='CURL-CVE-2022-32221', + modified=datetime.datetime(2020, 1, 1, 0, 0, tzinfo=datetime.UTC), source_id='source:CURL-CVE-2022-32221.json', - import_last_modified=datetime.datetime( - 2020, 1, 1, 0, 0, tzinfo=datetime.UTC), - ).put() + modified_raw=datetime.datetime(2020, 1, 1, 0, 0, tzinfo=datetime.UTC), + ) + osv.put_entities(vuln_ds, vuln_pb) + osv.gcs.upload_vulnerability(vuln_pb) message = mock.Mock() message.attributes = { 'source': 'source', @@ -678,39 +139,9 @@ def test_git_ranges(self): } task_runner._source_update(message) - self.expect_dict_equal('update_no_introduced', - osv.Bug.get_by_id('CURL-CVE-2022-32221')._to_dict()) - - @unittest.skip('Takes too long. ' - 'Also, firestore emulator cannot handle records of this size.') - def test_update_redhat_toobig(self): - """Test failure handling of a too-large Red Hat record.""" - solo_endpoint = 'RHSA-2018:3140' + '.json' - sha = 'a5cc068278ddad5f4c63d9b4f27baf59f296076306a24e850c5edde1b0232b0c' - - self.source_repo.db_prefix.append('RHSA-') - self.source_repo.put() - - task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, - None) - message = mock.Mock() - message.attributes = { - 'source': 'source', - 'path': solo_endpoint, - 'original_sha256': sha, - 'deleted': 'false', - } - with self.assertLogs(level='ERROR') as logs: - task_runner._source_update(message) - - self.assertIn( - 'ERROR:root:Not writing new entities for RHSA-2018:3140 since Bug.put() failed', - logs.output[0]) - self.assertIn( - 'ERROR:root:Unexpected exception while writing RHSA-2018:3140 to Datastore', - logs.output[1]) - - self.mock_publish.assert_not_called() + self.expect_dict_equal( + 'update_no_introduced', + MessageToDict(osv.gcs.get_by_id('CURL-CVE-2022-32221'))) class UpdateTest(unittest.TestCase, tests.ExpectationTest(TEST_DATA_DIR)): @@ -727,6 +158,21 @@ def _load_test_data(self, name): with open(os.path.join(TEST_DATA_DIR, name)) as f: return f.read() + def _put_vuln(self, vuln: vulnerability_pb2.Vulnerability, source_id: str): + """Put vulnerability into Datastore and GCS (emulators).""" + ds_vuln = osv.Vulnerability( + id=vuln.id, + source_id=source_id, + modified=vuln.modified.ToDatetime(datetime.UTC), + is_withdrawn=vuln.HasField('withdrawn'), + modified_raw=vuln.modified.ToDatetime(datetime.UTC), + alias_raw=list(vuln.aliases), + related_raw=list(vuln.related), + upstream_raw=list(vuln.upstream), + ) + osv.put_entities(ds_vuln, vuln) + osv.gcs.upload_vulnerability(vuln) + def setUp(self): self.maxDiff = None ds_emulator.reset() @@ -738,6 +184,7 @@ def setUp(self): # Initialise fake source_repo. self.tmp_dir = tempfile.TemporaryDirectory() + self.addCleanup(self.tmp_dir.cleanup) self.mock_repo = tests.mock_repository(self) self.remote_source_repo_path = self.mock_repo.path @@ -773,59 +220,36 @@ def setUp(self): name='source', db_prefix=['OSV-'], repo_url='file://' + self.remote_source_repo_path, - editable=True, + editable=False, repo_username='', ) self.source_repo.put() - osv.Bug( - db_id='OSV-123', - project=['blah.com/package'], - ecosystem=['Go'], - source_id='source:OSV-123.yaml', - import_last_modified=datetime.datetime( - 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - ).put() - osv.Bug( - db_id='OSV-124', - regressed='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - project=['blah.com/package'], - ecosystem=['Go'], - source_id='source:OSV-124.yaml', - import_last_modified=datetime.datetime( - 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - ).put() - osv.Bug( - db_id='OSV-125', - regressed='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - fixed='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', - project=['blah.com/package'], - ecosystem=['Go'], - source_id='source:OSV-125.yaml', - import_last_modified=datetime.datetime( - 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - ).put() - osv.Bug( - db_id='OSV-127', - project=['blah.com/package'], - ecosystem=['Go'], - source_id='source:OSV-127.yaml', - import_last_modified=datetime.datetime( - 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - ).put() - osv.Bug( - db_id='OSV-131', - project=['blah.com/package'], - ecosystem=['ecosystem'], - source_id='source:OSV-131.yaml', - import_last_modified=datetime.datetime( - 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - ).put() + vuln = vulnerability_pb2.Vulnerability(id='OSV-123') + vuln.modified.FromDatetime( + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.UTC)) + vuln.published.CopyFrom(vuln.modified) + self._put_vuln(vuln, 'source:OSV-123.yaml') + vuln = vulnerability_pb2.Vulnerability(id='OSV-124') + vuln.modified.FromDatetime( + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.UTC)) + vuln.published.CopyFrom(vuln.modified) + self._put_vuln(vuln, 'source:OSV-124.yaml') + vuln = vulnerability_pb2.Vulnerability(id='OSV-125') + vuln.modified.FromDatetime( + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.UTC)) + vuln.published.CopyFrom(vuln.modified) + self._put_vuln(vuln, 'source:OSV-125.yaml') + vuln = vulnerability_pb2.Vulnerability(id='OSV-127') + vuln.modified.FromDatetime( + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.UTC)) + vuln.published.CopyFrom(vuln.modified) + self._put_vuln(vuln, 'source:OSV-127.yaml') + vuln = vulnerability_pb2.Vulnerability(id='OSV-131') + vuln.modified.FromDatetime( + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.UTC)) + vuln.published.CopyFrom(vuln.modified) + self._put_vuln(vuln, 'source:OSV-131.yaml') mock_publish = mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') self.mock_publish = mock_publish.start() @@ -839,9 +263,6 @@ def setUp(self): 'ecosystem': None, }) - def tearDown(self): - self.tmp_dir.cleanup() - def test_update(self): """Test basic update.""" task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, @@ -855,16 +276,8 @@ def test_update(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update OSV-123', commit.message) - diff = repo.diff(commit.parents[0], commit) - - self.expect_equal('diff_update', diff.patch) - self.expect_dict_equal('update', osv.Bug.get_by_id('OSV-123')._to_dict()) + self.expect_dict_equal('update', + MessageToDict(osv.gcs.get_by_id('OSV-123'))) affected_commits = list(osv.AffectedCommits.query()) self.assertEqual(1, len(affected_commits)) @@ -896,17 +309,8 @@ def test_update_limit(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update OSV-128', commit.message) - diff = repo.diff(commit.parents[0], commit) - - self.expect_equal('diff_update_limit', diff.patch) self.expect_dict_equal('update_limit', - osv.Bug.get_by_id('OSV-128')._to_dict()) + MessageToDict(osv.gcs.get_by_id('OSV-128'))) affected_commits = list(osv.AffectedCommits.query()) self.assertEqual(1, len(affected_commits)) @@ -922,52 +326,6 @@ def test_update_limit(self): [codecs.encode(commit, 'hex') for commit in affected_commits.commits], ) - def test_update_add_fix(self): - """Test basic update adding a fix.""" - fix_result = osv.FixResult( - id='source:OSV-124.yaml', - repo_url='https://osv-test/repo/url', - commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', - ) - fix_result.put() - task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, - None) - message = mock.Mock() - message.attributes = { - 'source': 'source', - 'path': 'OSV-124.yaml', - 'original_sha256': _sha256('OSV-124.yaml'), - 'deleted': 'false', - } - task_runner._source_update(message) - - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update OSV-124', commit.message) - diff = repo.diff(commit.parents[0], commit) - - self.expect_equal('diff_update_add_fix', diff.patch) - self.expect_dict_equal('update_add_fix', - osv.Bug.get_by_id('OSV-124')._to_dict()) - - affected_commits = list(osv.AffectedCommits.query()) - self.assertEqual(1, len(affected_commits)) - affected_commits = affected_commits[0] - - self.assertCountEqual( - [ - b'4c155795426727ea05575bd5904321def23c03f4', - b'b1c95a196f22d06fcf80df8c6691cd113d8fefff', - b'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', - b'febfac1940086bc1f6d3dc33fda0a1d1ba336209', - b'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', - ], - [codecs.encode(commit, 'hex') for commit in affected_commits.commits], - ) - def test_update_no_introduced(self): """Test update vulnerability with no introduced commit.""" task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, @@ -982,17 +340,8 @@ def test_update_no_introduced(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update OSV-127', commit.message) - diff = repo.diff(commit.parents[0], commit) - self.expect_dict_equal('update_no_introduced', - osv.Bug.get_by_id('OSV-127')._to_dict()) - self.expect_equal('diff_update_no_introduced', diff.patch) + MessageToDict(osv.gcs.get_by_id('OSV-127'))) affected_commits = list(osv.AffectedCommits.query()) self.assertEqual(1, len(affected_commits)) @@ -1038,52 +387,36 @@ def test_update_new(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update OSV-126', commit.message) - self.expect_dict_equal('update_new', - osv.Bug.get_by_id('OSV-126')._to_dict()) + MessageToDict(osv.gcs.get_by_id('OSV-126'))) def test_update_delete(self): """Test deletion.""" task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, None) - self.mock_repo.delete_file('OSV-123.yaml') - self.mock_repo.commit('User', 'user@email') - message = mock.Mock() message.attributes = { 'source': 'source', 'path': 'OSV-123.yaml', 'original_sha256': _sha256('OSV-123.yaml'), - 'deleted': 'true', + 'deleted': 'false', } task_runner._source_update(message) - bug = osv.Bug.get_by_id('OSV-123') - self.assertEqual(osv.BugStatus.INVALID, bug.status) + self.mock_repo.delete_file('OSV-123.yaml') + self.mock_repo.commit('User', 'user@email') - def test_update_no_changes(self): - """Test basic update (with no changes).""" - task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, - None) message = mock.Mock() message.attributes = { 'source': 'source', - 'path': 'OSV-125.yaml', - 'original_sha256': _sha256('OSV-125.yaml'), - 'deleted': 'false', + 'path': 'OSV-123.yaml', + 'original_sha256': _sha256('OSV-123.yaml'), + 'deleted': 'true', } task_runner._source_update(message) - - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('user@email', commit.author.email) - self.assertEqual('User', commit.author.name) + vuln = osv.Vulnerability.get_by_id('OSV-123') + self.assertTrue(vuln.is_withdrawn) + vuln_pb = osv.gcs.get_by_id('OSV-123') + self.assertTrue(vuln_pb.HasField('withdrawn')) def test_update_conflict(self): """Test basic update with a conflict.""" @@ -1106,65 +439,6 @@ def test_update_conflict(self): ], ) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - # Latest commit is still the user commit. - self.assertEqual('user@email', commit.author.email) - self.assertEqual('User', commit.author.name) - - def test_update_conflict_while_pushing(self): - """Test basic update with a conflict while pushing.""" - original_push_source_changes = osv.push_source_changes - - def mock_push_source_changes(*args, **kwargs): - self.mock_repo.add_file('OSV-123.yaml', 'changed') - self.mock_repo.commit('Another user', 'user@email') - - original_push_source_changes(*args, **kwargs) - - patcher = mock.patch('osv.push_source_changes') - self.addCleanup(patcher.stop) - patcher.start().side_effect = mock_push_source_changes - - task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, - None) - message = mock.Mock() - message.attributes = { - 'source': 'source', - 'path': 'OSV-123.yaml', - 'original_sha256': _sha256('OSV-123.yaml'), - 'deleted': 'false', - } - - with self.assertLogs(level='WARNING') as logs: - task_runner._source_update(message) - - self.assertEqual(len(logs.output), 4) - self.assertEqual( - logs.output[0], - 'ERROR:absl:Code extraction failed for OSV-123 (Unsupported ecosystem: Go). Skipping affected[0]', - ) - self.assertEqual( - logs.output[1], - 'WARNING:root:Failed to push: cannot push because a reference that you are trying to update on the remote contains commits that are not present locally.', - ) - self.assertRegex( - logs.output[2], - r'WARNING:root:Upstream hash for .*/OSV-123.yaml changed \(expected=.* vs current=.*\)', - ) - self.assertEqual( - logs.output[3], - 'WARNING:root:Discarding changes for OSV-123 due to conflicts.', - ) - - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - # Latest commit is still the user commit. - self.assertEqual('user@email', commit.author.email) - self.assertEqual('Another user', commit.author.name) - def test_update_pypi(self): """Test a PyPI entry.""" self.source_repo.ignore_git = False @@ -1189,17 +463,8 @@ def test_update_pypi(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update PYSEC-123', commit.message) - diff = repo.diff(commit.parents[0], commit) - self.expect_equal('diff_pypi', diff.patch) - self.expect_dict_equal('update_pypi', - ndb.Key(osv.Bug, 'PYSEC-123').get()._to_dict()) + MessageToDict(osv.gcs.get_by_id('PYSEC-123'))) affected_commits = list(osv.AffectedCommits.query()) self.assertEqual(1, len(affected_commits)) @@ -1239,16 +504,8 @@ def test_normalize_pypi(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - diff = repo.diff(commit.parents[0], commit) - - self.expect_equal('diff_normalized_pypi', diff.patch) - - self.expect_dict_equal( - 'normalized_pypi', - ndb.Key(osv.Bug, 'PYSEC-456').get()._to_dict(), - ) + self.expect_dict_equal('normalized_pypi', + MessageToDict(osv.gcs.get_by_id('PYSEC-456'))) affected_commits = list(osv.AffectedCommits.query()) self.assertEqual(1, len(affected_commits)) @@ -1289,19 +546,8 @@ def test_update_last_affected(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update PYSEC-124', commit.message) - diff = repo.diff(commit.parents[0], commit) - self.expect_equal('diff_last_affected', diff.patch) - - self.expect_dict_equal( - 'update_last_affected', - ndb.Key(osv.Bug, 'PYSEC-124').get()._to_dict(), - ) + self.expect_dict_equal('update_last_affected', + MessageToDict(osv.gcs.get_by_id('PYSEC-124'))) def test_update_maven(self): """Test updating maven.""" @@ -1328,34 +574,22 @@ def test_update_maven(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update GHSA-838r-hvwh-24h8', commit.message) - diff = repo.diff(commit.parents[0], commit) - self.expect_equal('diff_maven', diff.patch) - self.expect_dict_equal( - 'update_maven', - ndb.Key(osv.Bug, 'GHSA-838r-hvwh-24h8').get()._to_dict(), - ) + 'update_maven', MessageToDict(osv.gcs.get_by_id('GHSA-838r-hvwh-24h8'))) self.mock_publish.assert_not_called() def test_update_linux(self): """Test a Linux entry.""" - self.skipTest("Prefix not supported by schema") self.source_repo.ignore_git = False self.source_repo.versions_from_repo = False self.source_repo.detect_cherrypicks = False - self.source_repo.db_prefix.append('LINUX-') + self.source_repo.db_prefix.append('GSD-') self.source_repo.put() self.mock_repo.add_file( - 'LINUX-123.yaml', - self._load_test_data(os.path.join(TEST_DATA_DIR, 'LINUX-123.yaml')), + 'GSD-123.yaml', + self._load_test_data(os.path.join(TEST_DATA_DIR, 'GSD-123.yaml')), ) self.mock_repo.commit('User', 'user@email') task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, @@ -1363,16 +597,14 @@ def test_update_linux(self): message = mock.Mock() message.attributes = { 'source': 'source', - 'path': 'LINUX-123.yaml', - 'original_sha256': _sha256('LINUX-123.yaml'), + 'path': 'GSD-123.yaml', + 'original_sha256': _sha256('GSD-123.yaml'), 'deleted': 'false', } task_runner._source_update(message) - self.expect_dict_equal( - 'update_linux', - ndb.Key(osv.Bug, 'LINUX-123').get()._to_dict(), - ) + self.expect_dict_equal('update_linux', + MessageToDict(osv.gcs.get_by_id('GSD-123'))) affected_commits = list(osv.AffectedCommits.query()) self.assertEqual(1, len(affected_commits)) @@ -1408,7 +640,7 @@ def test_update_bucket(self): task_runner._source_update(message) self.expect_dict_equal('update_bucket_0', - osv.Bug.get_by_id('GO-2021-0085')._to_dict()) + MessageToDict(osv.gcs.get_by_id('GO-2021-0085'))) def test_update_debian(self): """Test updating debian.""" @@ -1434,20 +666,8 @@ def test_update_debian(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update DSA-3029-1', commit.message) - diff = repo.diff(commit.parents[0], commit) - - self.expect_equal('diff_debian', diff.patch) - - self.expect_dict_equal( - 'update_debian', - ndb.Key(osv.Bug, 'DSA-3029-1').get()._to_dict(), - ) + self.expect_dict_equal('update_debian', + MessageToDict(osv.gcs.get_by_id('DSA-3029-1'))) self.mock_publish.assert_not_called() @@ -1476,22 +696,8 @@ def test_update_alpine(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update CVE-2022-27449', commit.message) - diff = repo.diff(commit.parents[0], commit) - - self.expect_equal('diff_alpine', diff.patch) - - self.expect_dict_equal( - 'update_alpine', - ndb.Key(osv.Bug, 'CVE-2022-27449').get()._to_dict(), - ) - - self.mock_publish.assert_not_called() + self.expect_dict_equal('update_alpine', + MessageToDict(osv.gcs.get_by_id('CVE-2022-27449'))) def test_update_android(self): """Test updating Android through bucket entries.""" @@ -1515,7 +721,7 @@ def test_update_android(self): task_runner._source_update(message) self.expect_dict_equal('update_bucket_2', - osv.Bug.get_by_id('ASB-A-153358911')._to_dict()) + MessageToDict(osv.gcs.get_by_id('ASB-A-153358911'))) def test_update_bad_ecosystem_new(self): """Test adding from an unsupported ecosystem.""" @@ -1538,8 +744,8 @@ def test_update_bad_ecosystem_new(self): with self.assertLogs(level='WARNING'): task_runner._source_update(message) - bug = osv.Bug.get_by_id('OSV-129') - self.assertEqual(osv.BugStatus.INVALID, bug.status) + self.expect_dict_equal('update_bad_ecosystem_new', + MessageToDict(osv.gcs.get_by_id('OSV-129'))) def test_update_partly_bad_ecosystem_new(self): """Test adding vuln with both supported and unsupported ecosystem.""" @@ -1562,17 +768,8 @@ def test_update_partly_bad_ecosystem_new(self): with self.assertLogs(level='WARNING'): task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - - self.assertEqual('infra@osv.dev', commit.author.email) - self.assertEqual('OSV', commit.author.name) - self.assertEqual('Update OSV-130', commit.message) - - self.expect_dict_equal( - 'update_partly_bad_ecosystem_new', - osv.Bug.get_by_id('OSV-130')._to_dict(), - ) + self.expect_dict_equal('update_partly_bad_ecosystem_new', + MessageToDict(osv.gcs.get_by_id('OSV-130'))) def test_update_partly_bad_ecosystem_delete(self): """Test removal of only supported ecosystem in vulnerability with @@ -1591,8 +788,8 @@ def test_update_partly_bad_ecosystem_delete(self): with self.assertLogs(level='WARNING'): task_runner._source_update(message) - bug = osv.Bug.get_by_id('OSV-131') - self.assertEqual(osv.BugStatus.INVALID, bug.status) + self.expect_dict_equal('update_partly_bad_ecosystem_delete', + MessageToDict(osv.gcs.get_by_id('OSV-131'))) def test_update_bucket_cve(self): """Test a bucket entry that is a converted CVE and doesn't have an ecosystem.""" @@ -1616,9 +813,8 @@ def test_update_bucket_cve(self): } task_runner._source_update(message) - processed_result = osv.Bug.get_by_id('CVE-2016-15011') - - self.expect_dict_equal('update_bucket_cve', processed_result._to_dict()) + self.expect_dict_equal('update_bucket_cve', + MessageToDict(osv.gcs.get_by_id('CVE-2016-15011'))) def test_last_affected_git(self): """Basic last_affected GIT enumeration.""" @@ -1647,16 +843,9 @@ def test_last_affected_git(self): } task_runner._source_update(message) - repo = pygit2.Repository(self.remote_source_repo_path) - commit = repo.head.peel() - diff = repo.diff(commit.parents[0], commit) - - self.expect_equal('diff_last_affected_git', diff.patch) - self.expect_dict_equal( 'last_affected_git', - ndb.Key(osv.Bug, 'OSV-TEST-last-affected-01').get()._to_dict(), - ) + MessageToDict(osv.gcs.get_by_id('OSV-TEST-last-affected-01'))) affected_commits = list(osv.AffectedCommits.query()) self.assertEqual(1, len(affected_commits)) @@ -1671,52 +860,6 @@ def test_last_affected_git(self): [codecs.encode(commit, 'hex') for commit in affected_commits.commits], ) - def test_invalid_prefix(self): - """Test attempting to create a bug with a invalid db_prefix.""" - with self.assertRaises(ValueError): - # Default db_prefix is `OSV-` - osv.Bug( - db_id='BLAH-131', - project=['blah.com/package'], - ecosystem=['ecosystem'], - source_id='source:OSV-131.yaml', - import_last_modified=datetime.datetime( - 2021, 1, 1, 0, 0, tzinfo=datetime.UTC), - source_of_truth=osv.SourceOfTruth.SOURCE_REPO, - ).put() - - def test_dont_index_too_many_git_versions(self): - """Test that we don't index too many versions from Git.""" - self.source_repo.ignore_git = False - self.source_repo.versions_from_repo = True - self.source_repo.detect_cherrypicks = True - self.source_repo.put() - - # Use any valid OSV input test file here. - self.mock_repo.add_file( - 'OSV-TEST-last-affected-01.yaml', - self._load_test_data( - os.path.join(TEST_DATA_DIR, 'OSV-TEST-last-affected-01.yaml')), - ) - self.mock_repo.commit('User', 'user@email') - task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, - None) - message = mock.Mock() - message.attributes = { - 'source': 'source', - 'path': 'OSV-TEST-last-affected-01.yaml', - 'original_sha256': _sha256('OSV-TEST-last-affected-01.yaml'), - 'deleted': 'false', - } - task_runner._source_update(message) - - bug = ndb.Key(osv.Bug, 'OSV-TEST-last-affected-01').get() - - # Manually append versions over the expected version limit. - bug.affected_packages[0].versions = ['%05d' % i for i in range(5001)] - bug.put() - self.expect_dict_equal('dont_index_too_many_git_versions', bug._to_dict()) - def test_update_clears_stale_import_finding(self): """A subsequent successful update removes the now stale import finding.""" @@ -1765,13 +908,52 @@ def test_ubuntu_severity(self): } task_runner._source_update(message) - bug = ndb.Key(osv.Bug, 'UBUNTU-CVE-2025-38094').get() - self.expect_dict_equal('ubuntu_severity_type', bug._to_dict()) + self.expect_dict_equal( + 'ubuntu_severity_type', + MessageToDict(osv.gcs.get_by_id('UBUNTU-CVE-2025-38094'))) + + def test_update_skip_hash_check(self): + """Test update with skip_hash_check=true.""" + task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, + None) + # Case 1: File exists, hash mismatch but skipped + message = mock.Mock() + message.attributes = { + 'source': 'source', + 'path': 'OSV-123.yaml', + 'original_sha256': 'mismatch', + 'deleted': 'false', + 'skip_hash_check': 'true', + } + + # Should not log warning about hash mismatch + with self.assertLogs(level='INFO'): # capture info to ensure no warning + task_runner._source_update(message) + + # Verify it updated (we can check GCS or just that it didn't return early) + self.expect_dict_equal('update', + MessageToDict(osv.gcs.get_by_id('OSV-123'))) + + # Case 2: File missing, skip_hash_check=true -> should delete + self.mock_repo.delete_file('OSV-123.yaml') + self.mock_repo.commit('User', 'user@email') + + message.attributes['original_sha256'] = '' # irrelevant + + task_runner._source_update(message) + + vuln = osv.Vulnerability.get_by_id('OSV-123') + self.assertTrue(vuln.is_withdrawn) + vuln_pb = osv.gcs.get_by_id('OSV-123') + self.assertTrue(vuln_pb.HasField('withdrawn')) def setUpModule(): """Set up the test module.""" print("Starting Datastore Emulator for the test suite...") + # Silence logs coming from Vanir + absl_logger = logging.getLogger('absl') + absl_logger.setLevel(logging.CRITICAL) global ds_emulator, ndb_client # Start the emulator BEFORE creating the ndb client ds_emulator = unittest.enterModuleContext(tests.datastore_emulator()) diff --git a/go/cmd/custommetrics/Dockerfile b/go/cmd/custommetrics/Dockerfile index 8604d8080a2..66282c76559 100644 --- a/go/cmd/custommetrics/Dockerfile +++ b/go/cmd/custommetrics/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS build +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS build WORKDIR /src @@ -24,7 +24,7 @@ RUN go mod download && go mod verify COPY ./ /src/ RUN CGO_ENABLED=0 go build -o custommetrics ./cmd/custommetrics -FROM gcr.io/distroless/static-debian12@sha256:4b2a093ef4649bccd586625090a3c668b254cfe180dee54f4c94f3e9bd7e381e +FROM gcr.io/distroless/static-debian12@sha256:cd64bec9cec257044ce3a8dd3620cf83b387920100332f2b041f19c4d2febf93 COPY --from=build /src/custommetrics / diff --git a/go/cmd/exporter/Dockerfile b/go/cmd/exporter/Dockerfile index 120101241cd..48ce9322d0f 100644 --- a/go/cmd/exporter/Dockerfile +++ b/go/cmd/exporter/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS build +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS build WORKDIR /src @@ -24,7 +24,7 @@ RUN go mod download && go mod verify COPY ./ /src/ RUN CGO_ENABLED=0 go build -o exporter ./cmd/exporter -FROM gcr.io/distroless/static-debian12@sha256:4b2a093ef4649bccd586625090a3c668b254cfe180dee54f4c94f3e9bd7e381e +FROM gcr.io/distroless/static-debian12@sha256:cd64bec9cec257044ce3a8dd3620cf83b387920100332f2b041f19c4d2febf93 COPY --from=build /src/exporter / diff --git a/go/cmd/generatesitemap/Dockerfile b/go/cmd/generatesitemap/Dockerfile index 68cade689b0..d652ef1bda6 100644 --- a/go/cmd/generatesitemap/Dockerfile +++ b/go/cmd/generatesitemap/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS build +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS build WORKDIR /src @@ -24,7 +24,7 @@ RUN go mod download && go mod verify COPY ./ /src/ RUN CGO_ENABLED=0 go build -o generatesitemap ./cmd/generatesitemap -FROM gcr.io/distroless/static-debian12@sha256:87bce11be0af225e4ca761c40babb06d6d559f5767fbf7dc3c47f0f1a466b92c +FROM gcr.io/distroless/static-debian12@sha256:cd64bec9cec257044ce3a8dd3620cf83b387920100332f2b041f19c4d2febf93 COPY --from=build /src/generatesitemap / diff --git a/go/cmd/gitter/Dockerfile b/go/cmd/gitter/Dockerfile index 86b9496eda4..c872d05e5e4 100644 --- a/go/cmd/gitter/Dockerfile +++ b/go/cmd/gitter/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS build +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS build WORKDIR /src diff --git a/go/cmd/gitter/gitter.go b/go/cmd/gitter/gitter.go index 8e5796deaa2..a0ba1121743 100644 --- a/go/cmd/gitter/gitter.go +++ b/go/cmd/gitter/gitter.go @@ -15,9 +15,11 @@ import ( "net/http" "os" "os/exec" + "os/signal" "path" "regexp" "strings" + "syscall" "time" "github.com/google/osv.dev/go/logger" @@ -36,6 +38,39 @@ var ( fetchTimeout time.Duration ) +const shutdownTimeout = 10 * time.Second + +// runCmd executes a command with context cancellation handled by sending SIGINT. +// It logs cancellation errors separately as requested. +func runCmd(ctx context.Context, dir string, env []string, name string, args ...string) error { + cmd := exec.CommandContext(ctx, name, args...) + if dir != "" { + cmd.Dir = dir + } + if len(env) > 0 { + cmd.Env = append(os.Environ(), env...) + } + // Use SIGINT instead of SIGKILL for graceful shutdown of subprocesses + cmd.Cancel = func() error { + return cmd.Process.Signal(syscall.SIGINT) + } + // Ensure it eventually dies if it ignores SIGINT + cmd.WaitDelay = shutdownTimeout / 2 + + out, err := cmd.CombinedOutput() + if err != nil { + if ctx.Err() != nil { + // Log separately if cancelled + logger.Warn("Command cancelled", slog.String("cmd", name), slog.Any("err", ctx.Err())) + return fmt.Errorf("command %s cancelled: %w", name, ctx.Err()) + } + + return fmt.Errorf("command %s failed: %w, output: %s", name, err, out) + } + + return nil +} + func isLocalRequest(r *http.Request) bool { host, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { @@ -82,22 +117,21 @@ func fetchBlob(ctx context.Context, url string) ([]byte, error) { logger.Info("Fetching git blob", slog.String("url", url), slog.Duration("sinceAccessTime", time.Since(accessTime))) if _, err := os.Stat(path.Join(repoPath, ".git")); os.IsNotExist(err) { // Clone - cmd := exec.Command("git", "clone", "--", url, repoPath) - cmd.Env = append(cmd.Env, "GIT_TERMINAL_PROMPT=0") - if out, err := cmd.CombinedOutput(); err != nil { - return nil, fmt.Errorf("git clone failed: %w, output: %s", err, out) + err := runCmd(ctx, "", []string{"GIT_TERMINAL_PROMPT=0"}, "git", "clone", "--", url, repoPath) + if err != nil { + return nil, fmt.Errorf("git clone failed: %w", err) } } else { // Fetch/Pull - implementing simple git pull for now, might need reset --hard if we want exact mirrors // For a generic "get latest", pull is usually sufficient if we treat it as read-only. // Ideally safely: git fetch origin && git reset --hard origin/HEAD - cmd := exec.Command("git", "-C", repoPath, "fetch", "origin") - if out, err := cmd.CombinedOutput(); err != nil { - return nil, fmt.Errorf("git fetch failed: %w, output: %s", err, out) + err := runCmd(ctx, repoPath, nil, "git", "fetch", "origin") + if err != nil { + return nil, fmt.Errorf("git fetch failed: %w", err) } - cmd = exec.Command("git", "-C", repoPath, "reset", "--hard", "origin/HEAD") - if out, err := cmd.CombinedOutput(); err != nil { - return nil, fmt.Errorf("git reset failed: %w, output: %s", err, out) + err = runCmd(ctx, repoPath, nil, "git", "reset", "--hard", "origin/HEAD") + if err != nil { + return nil, fmt.Errorf("git reset failed: %w", err) } } @@ -105,9 +139,9 @@ func fetchBlob(ctx context.Context, url string) ([]byte, error) { // Archive // tar --zstd -cf -C "/" . // using -C to archive the relative path so it unzips nicely - cmd := exec.Command("tar", "--zstd", "-cf", archivePath, "-C", path.Join(gitStorePath, repoDirName), ".") - if out, err := cmd.CombinedOutput(); err != nil { - return nil, fmt.Errorf("tar zstd failed: %w, output: %s", err, out) + err := runCmd(ctx, "", nil, "tar", "--zstd", "-cf", archivePath, "-C", path.Join(gitStorePath, repoDirName), ".") + if err != nil { + return nil, fmt.Errorf("tar zstd failed: %w", err) } updateLastFetch(url) @@ -147,18 +181,57 @@ func main() { loadMap() + // Create a context that listens for the interrupt signal from the OS. + ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer stop() + http.HandleFunc(getGitEndpoint, gitHandler) logger.Info("Gitter starting and listening", slog.Int("port", *port)) + // --- Server Shutdown Protocol --- + // This is what happens when a kubernetes send a SIGTERM signal: + // 1. Kubernetes sends SIGTERM to the process + // 2. The process receives the signal and prints "Shutting down gracefully..." + // 3. The process calls server.Shutdown(ctx) to close incoming connections, and wait for timeout. + // 4. The context within each request will be automatically cancelled (does not wait for timeout). + // 5. Any subprocesses will be sent SIGINT, with a timeout / 2 duration before SIGKILL. + // 6. The server waits for the timeout to finish processing all requests. + // 7. We save the lastFetch map to disk. + // 8. The process exits + server := &http.Server{ Addr: fmt.Sprintf(":%d", *port), ReadHeaderTimeout: 3 * time.Second, + BaseContext: func(_ net.Listener) context.Context { + // Return the context tied to the termination signal. + return ctx + }, } - if err := server.ListenAndServe(); err != nil { - logger.Error("Gitter failed to start", slog.Int("port", *port), slog.Any("error", err)) - os.Exit(1) + + go func() { + if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + logger.Error("Gitter failed to start", slog.Int("port", *port), slog.Any("error", err)) + } + }() + + // Listen for the interrupt signal. + <-ctx.Done() + + // Restore default behavior on the interrupt signal and notify user of shutdown. + stop() + logger.Info("Shutting down gracefully, press Ctrl+C again to force") + + // The context is used to inform the server it has 5 seconds to finish + // the request it is currently handling + ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) + defer cancel() + if err := server.Shutdown(ctx); err != nil { + logger.Error("Server forced to shutdown", slog.Any("error", err)) } + + saveMap() + logger.Info("Server exiting") } func gitHandler(w http.ResponseWriter, r *http.Request) { @@ -203,4 +276,6 @@ func gitHandler(w http.ResponseWriter, r *http.Request) { return } + + logger.Info("Request completed successfully", slog.String("url", url)) } diff --git a/go/cmd/recordchecker/Dockerfile b/go/cmd/recordchecker/Dockerfile index 1a47c87519c..a6da2085771 100644 --- a/go/cmd/recordchecker/Dockerfile +++ b/go/cmd/recordchecker/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS build +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS build WORKDIR /src @@ -24,7 +24,7 @@ RUN go mod download && go mod verify COPY ./ /src/ RUN CGO_ENABLED=0 go build -o recordchecker ./cmd/recordchecker/ -FROM gcr.io/distroless/static-debian12@sha256:4b2a093ef4649bccd586625090a3c668b254cfe180dee54f4c94f3e9bd7e381e +FROM gcr.io/distroless/static-debian12@sha256:cd64bec9cec257044ce3a8dd3620cf83b387920100332f2b041f19c4d2febf93 COPY --from=build /src/recordchecker / diff --git a/go/cmd/relations/Dockerfile b/go/cmd/relations/Dockerfile index 66b0ed09273..ae09d09ccfa 100644 --- a/go/cmd/relations/Dockerfile +++ b/go/cmd/relations/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS build +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS build WORKDIR /src @@ -24,7 +24,7 @@ RUN go mod download && go mod verify COPY ./ /src/ RUN CGO_ENABLED=0 go build -o relations ./cmd/relations -FROM gcr.io/distroless/static-debian12@sha256:4b2a093ef4649bccd586625090a3c668b254cfe180dee54f4c94f3e9bd7e381e +FROM gcr.io/distroless/static-debian12@sha256:cd64bec9cec257044ce3a8dd3620cf83b387920100332f2b041f19c4d2febf93 COPY --from=build /src/relations / diff --git a/go/go.mod b/go/go.mod index eed854d9452..ef3d97efcae 100644 --- a/go/go.mod +++ b/go/go.mod @@ -1,30 +1,30 @@ module github.com/google/osv.dev/go -go 1.25.5 +go 1.25.6 require ( cloud.google.com/go/datastore v1.21.0 cloud.google.com/go/monitoring v1.24.3 cloud.google.com/go/pubsub/v2 v2.3.0 - cloud.google.com/go/storage v1.57.2 + cloud.google.com/go/storage v1.59.1 github.com/charmbracelet/lipgloss v1.1.0 - github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae - golang.org/x/sync v0.18.0 - google.golang.org/api v0.257.0 - google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b + github.com/ossf/osv-schema/bindings/go v0.0.0-20260128001339-9d03e8f4632b + golang.org/x/sync v0.19.0 + google.golang.org/api v0.263.0 + google.golang.org/genproto/googleapis/api v0.0.0-20260128004102-de31872fb2ec google.golang.org/protobuf v1.36.11 ) require ( cel.dev/expr v0.24.0 // indirect - cloud.google.com/go v0.121.6 // indirect - cloud.google.com/go/auth v0.17.0 // indirect + cloud.google.com/go v0.123.0 // indirect + cloud.google.com/go/auth v0.18.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect - cloud.google.com/go/iam v1.5.2 // indirect + cloud.google.com/go/iam v1.5.3 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect @@ -41,8 +41,8 @@ require ( github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect - github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect + github.com/googleapis/gax-go/v2 v2.16.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -54,21 +54,21 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect - golang.org/x/crypto v0.45.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + golang.org/x/crypto v0.47.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect - google.golang.org/grpc v1.77.0 // indirect + google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d // indirect + google.golang.org/grpc v1.78.0 // indirect ) diff --git a/go/go.sum b/go/go.sum index dcb39fbdd4e..96295f83ad1 100644 --- a/go/go.sum +++ b/go/go.sum @@ -1,39 +1,39 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c= -cloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI= -cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4= -cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ= +cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= +cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= +cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/datastore v1.21.0 h1:dUrYq47ysCA4nM7u8kRT0WnbfXc6TzX49cP3TCwIiA0= cloud.google.com/go/datastore v1.21.0/go.mod h1:9l+KyAHO+YVVcdBbNQZJu8svF17Nw5sMKuFR0LYf1nY= -cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= -cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= -cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= -cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= +cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= +cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= +cloud.google.com/go/logging v1.13.1 h1:O7LvmO0kGLaHY/gq8cV7T0dyp6zJhYAOtZPX4TF3QtY= +cloud.google.com/go/logging v1.13.1/go.mod h1:XAQkfkMBxQRjQek96WLPNze7vsOmay9H5PqfsNYDqvw= cloud.google.com/go/longrunning v0.7.0 h1:FV0+SYF1RIj59gyoWDRi45GiYUMM3K1qO51qoboQT1E= cloud.google.com/go/longrunning v0.7.0/go.mod h1:ySn2yXmjbK9Ba0zsQqunhDkYi0+9rlXIwnoAf+h+TPY= cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE= cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI= cloud.google.com/go/pubsub/v2 v2.3.0 h1:DgAN907x+sP0nScYfBzneRiIhWoXcpCD8ZAut8WX9vs= cloud.google.com/go/pubsub/v2 v2.3.0/go.mod h1:O5f0KHG9zDheZAd3z5rlCRhxt2JQtB+t/IYLKK3Bpvw= -cloud.google.com/go/storage v1.57.2 h1:sVlym3cHGYhrp6XZKkKb+92I1V42ks2qKKpB0CF5Mb4= -cloud.google.com/go/storage v1.57.2/go.mod h1:n5ijg4yiRXXpCu0sJTD6k+eMf7GRrJmPyr9YxLXGHOk= -cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= -cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= +cloud.google.com/go/storage v1.59.1 h1:DXAZLcTimtiXdGqDSnebROVPd9QvRsFVVlptz02Wk58= +cloud.google.com/go/storage v1.59.1/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI= +cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U= +cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0 h1:4LP6hvB4I5ouTbGgWtixJhgED6xdf67twf9PoY96Tbg= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0/go.mod h1:jUZ5LYlw40WMd07qxcQJD5M40aUxrfwqQX1g7zxYnrQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.54.0 h1:xfK3bbi6F2RDtaZFtUdKO3osOBIhNb+xTs8lFW6yx9o= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.54.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -109,10 +109,10 @@ github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= -github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= -github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= +github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= +github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y= +github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -121,8 +121,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= -github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae h1:nvfTerE/hSYc/TQ3JUZYeL7DuVhjPkBeOGxicPzoJmc= -github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae/go.mod h1:Eo7R19vlnflsCRdHW1ynyNUyoRwxdaTmTWD9MtKnJTc= +github.com/ossf/osv-schema/bindings/go v0.0.0-20260128001339-9d03e8f4632b h1:xoaQGKeEQccRHVY7wJz1NJR1S7ViBM1nKeN5Ck0t4r8= +github.com/ossf/osv-schema/bindings/go v0.0.0-20260128001339-9d03e8f4632b/go.mod h1:Eo7R19vlnflsCRdHW1ynyNUyoRwxdaTmTWD9MtKnJTc= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -152,26 +152,26 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs= go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0= golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= @@ -184,27 +184,27 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -215,26 +215,26 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.257.0 h1:8Y0lzvHlZps53PEaw+G29SsQIkuKrumGWs9puiexNAA= -google.golang.org/api v0.257.0/go.mod h1:4eJrr+vbVaZSqs7vovFd1Jb/A6ml6iw2e6FBYf3GAO4= +google.golang.org/api v0.263.0 h1:UFs7qn8gInIdtk1ZA6eXRXp5JDAnS4x9VRsRVCeKdbk= +google.golang.org/api v0.263.0/go.mod h1:fAU1xtNNisHgOF5JooAs8rRaTkl2rT3uaoNGo9NS3R8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E= -google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934= +google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0= +google.golang.org/genproto/googleapis/api v0.0.0-20260128004102-de31872fb2ec h1:enb0nUQ3SSTFHfDh583KVk3pNunrbyfmtw9JSYY4LTA= +google.golang.org/genproto/googleapis/api v0.0.0-20260128004102-de31872fb2ec/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d h1:xXzuihhT3gL/ntduUZwHECzAn57E8dA6l8SOtYWdD8Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/go/osv/models/internal/validate/run_validate.sh b/go/osv/models/internal/validate/run_validate.sh index d224302a2f8..473aa415032 100755 --- a/go/osv/models/internal/validate/run_validate.sh +++ b/go/osv/models/internal/validate/run_validate.sh @@ -1,2 +1,6 @@ #!/bin/bash -poetry sync && poetry run python validate.py \ No newline at end of file +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi +poetry run python validate.py \ No newline at end of file diff --git a/osv/cloudbuild.yaml b/osv/cloudbuild.yaml index 55ed50ac241..ad442386dac 100644 --- a/osv/cloudbuild.yaml +++ b/osv/cloudbuild.yaml @@ -53,3 +53,5 @@ steps: timeout: 7200s options: machineType: E2_HIGHCPU_8 + env: + - CLOUDBUILD=1 diff --git a/osv/ecosystems/_ecosystems.py b/osv/ecosystems/_ecosystems.py index f7cd436eca4..91a2bc1ed64 100644 --- a/osv/ecosystems/_ecosystems.py +++ b/osv/ecosystems/_ecosystems.py @@ -24,6 +24,7 @@ from .hex import Hex from .maven import Maven from .nuget import NuGet +from .opam import Opam from .packagist import Packagist from .pub import Pub from .pypi import PyPI @@ -44,6 +45,7 @@ 'CRAN': CRAN, 'crates.io': SemverEcosystem, 'Debian': Debian, + 'Docker Hardened Images': SemverEcosystem, 'Echo': DPKG, 'GHC': GHC, 'Go': SemverEcosystem, @@ -55,6 +57,7 @@ 'MinimOS': APK, 'npm': SemverEcosystem, 'NuGet': NuGet, + 'opam': Opam, 'openEuler': RPM, 'openSUSE': RPM, 'Packagist': Packagist, diff --git a/osv/ecosystems/alpine.py b/osv/ecosystems/alpine.py index 3862b344e05..12b9d4640b3 100644 --- a/osv/ecosystems/alpine.py +++ b/osv/ecosystems/alpine.py @@ -22,8 +22,12 @@ from ..third_party.univers.alpine import AlpineLinuxVersion from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError -from .ecosystems_base import OrderedEcosystem +from .ecosystems_base import ( + coarse_version_generic, + EnumerableEcosystem, + EnumerateError, + OrderedEcosystem, +) from .. import repos from ..cache import cached @@ -33,11 +37,31 @@ class APK(OrderedEcosystem): def _sort_key(self, version): if not AlpineLinuxVersion.is_valid(version): - # If version is not valid, it is most likely an invalid input - # version then sort it to the last/largest element - return AlpineLinuxVersion('9999999999') + raise ValueError(f'Invalid version: {version}') return AlpineLinuxVersion(version) + def coarse_version(self, version): + """Coarse version. + + Treats version as dot-separated integers. + Trims suffixes (_rc, _p, -r) to ensure monotonicity (e.g. 1.2_rc1 < 1.2). + """ + if not AlpineLinuxVersion.is_valid(version): + raise ValueError(f'Invalid version: {version}') + # is_valid uses a $ regex anchor (which can match a newline), + # so we need to remove the newline if one exists. + if version[-1] == '\n': + version = version[:-1] + return coarse_version_generic( + version, + separators_regex=r'[.]', + # in APK, 1.0.2 < 1.02.1 < 1.1.1 + # We must treat everything after .0x as 0 + # Also split off the _rc, _p, or -r suffixes + truncate_regex=r'(?:\.0|[_-])', + implicit_split=False, + empty_as='') + class Alpine(APK, EnumerableEcosystem): """ @@ -99,7 +123,7 @@ def clean_versions(ver: str) -> str: current_ver = clean_versions(current_ver) current_rel = clean_versions(current_rel) # Ignore occasional version that is still not valid. - if AlpineLinuxVersion.is_valid(current_ver) and current_rel.isdigit(): + if AlpineLinuxVersion.is_valid(current_ver) and current_rel.isdecimal(): all_versions.add(current_ver + '-r' + current_rel) else: logging.warning('Alpine version "%s" - "%s" is not valid', diff --git a/osv/ecosystems/alpine_test.py b/osv/ecosystems/alpine_test.py index 9d24382f9c2..9a5711c1d86 100644 --- a/osv/ecosystems/alpine_test.py +++ b/osv/ecosystems/alpine_test.py @@ -85,6 +85,24 @@ def test_apk(self): self.assertLessEqual( ecosystem.sort_key('1.2.0-r0'), ecosystem.sort_key('1.10.0-r0')) + def test_coarse_version(self): + """Test coarse version.""" + ecosystem = alpine.APK() + self.assertEqual('00:00000010.00000002.00000033', + ecosystem.coarse_version('10.2.33')) + self.assertEqual('00:00000004.00000005.00000000', + ecosystem.coarse_version('4.5_alpha')) + self.assertEqual('00:20200712.00000000.00000000', + ecosystem.coarse_version('20200712-r0')) + self.assertEqual('00:00000011.00000003.00000020', + ecosystem.coarse_version('11.3.20.1_p1-r0')) + self.assertEqual('00:00000002.00000003.00000000', + ecosystem.coarse_version('02.3')) + self.assertEqual('00:00000005.00000000.00000000', + ecosystem.coarse_version('5.06.7')) + self.assertEqual('00:00000005.00000000.00000000', + ecosystem.coarse_version('5.0.9')) + def test_apk_ecosystems(self): """Test apk-based ecosystems return an APK ecosystem.""" ecos = [ diff --git a/osv/ecosystems/coarse_version_monotonicity_test.py b/osv/ecosystems/coarse_version_monotonicity_test.py new file mode 100644 index 00000000000..000ac91f6b3 --- /dev/null +++ b/osv/ecosystems/coarse_version_monotonicity_test.py @@ -0,0 +1,168 @@ +# Copyright 2026 Google LLC +# +# 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. +"""Coarse version monotonicity tests.""" + +import re +import unittest +from hypothesis import given, example, strategies as st +import packaging.version + +from .. import ecosystems +from ..third_party.univers.gem import GemVersion + +from . import alpine +from . import cran +from . import debian +from . import haskell +from . import maven +from . import nuget +from . import packagist +from . import pub +from . import pypi +from . import redhat +from . import rubygems +from . import semver_ecosystem_helper + +# Strategies + +# Matches standard SemVer: major.minor.patch, optional 'v', prerelease/build. +# Note: OSV's SemVer implementation coerces partial versions +# (e.g. '1.0' -> '1.0.0'). +semver_strategy = st.from_regex( + r'^v?[0-9]+(\.[0-9]+){0,2}(-[0-9a-zA-z.-]*)?\+?[0-9a-zA-z.-]*$') + +# Matches standard Alpine versions like 1.2.3, optionally with suffixes +# like _rc1, _p2, and revision -r3. +apk_version_strategy = st.from_regex( + r'^[0-9]+(\.[0-9]+)*(_rc[0-9]*|_p[0-9]*)*(-r[0-9]+)?$') + +# Matches R versions: sequence of numbers separated by dots or dashes +# (e.g. 1.2-3). +cran_version_strategy = st.from_regex(r'^[0-9]+([.-][0-9]+)+$') + +# Matches Debian versions: optional epoch, upstream version +# (alphanumerics/separators), optional debian revision. +dpkg_version_strategy = st.from_regex( + r'^(\d+:)?\d([A-Za-z0-9\.\+\~\-]+|[A-Za-z0-9\.\+\~]+-[A-Za-z0-9\+\.\~]+)?$') + +# Matches Haskell versions: dot-separated integers (e.g. 1.2.3). +hackage_version_strategy = st.from_regex(r'^[0-9]+(\.[0-9]+)*$') + +# Matches Maven versions: flexible sequence of numbers or identifiers +# separated by dots or dashes. +maven_version_strategy = st.from_regex(r'^(([0-9]*|[A-Za-z+]*)[.-]?)*$') + +# Matches NuGet versions: SemVer-like, optional 'v' prefix, 4th component, +# prerelease/build metadata. +nuget_version_strategy = st.from_regex( + r'^v?[0-9]+(\.[0-9]+){0,3}(-[0-9a-zA-z.-]*)?\+?[0-9a-zA-z.-]*$') + +# Matches Packagist versions: 'v' prefix, flexible components separated by +# ., +, _, -. +packagist_version_strategy = st.from_regex(r'^v?(([0-9]*|[A-Za-z+]*)[.+_-]?)*$') + +# Pub versions are the same format as SemVer. +pub_version_strategy = semver_strategy + +# Uses standard packaging.version pattern. +pypi_strategy = st.one_of( + st.text(), # legacy version can be any string + st.from_regex( + re.compile(r'^' + packaging.version.VERSION_PATTERN + r'$', + re.IGNORECASE | re.VERBOSE | re.ASCII))) + +# Matches RPM versions: optional epoch, alternating alphanumeric segments. +rpm_version_strategy = st.from_regex( + re.compile(r'^([0-9]+:)?(([0-9]+|[A-Za-z]+)((?![0-9A-Za-z])[ -~])*)+$', + re.ASCII)) + +# Uses standard GemVersion pattern. +rubygems_version_strategy = st.from_regex(r'^' + GemVersion.VERSION_PATTERN + + r'$') + + +def check_coarse_version_monotonic(test_case: unittest.TestCase, + ecosystem: ecosystems.OrderedEcosystem, + v1_str: str, v2_str: str): + """Test coarse_version monotonicity.""" + v1 = ecosystem.sort_key(v1_str) + v2 = ecosystem.sort_key(v2_str) + if v2 < v1: + v1, v2 = v2, v1 + v1_str, v2_str = v2_str, v1_str + + if v1.is_invalid: + test_case.assertRaises(ValueError, ecosystem.coarse_version, v1_str) + if v2.is_invalid: + test_case.assertRaises(ValueError, ecosystem.coarse_version, v2_str) + + if not v1.is_invalid and not v2.is_invalid: + v1_coarse = ecosystem.coarse_version(v1_str) + v2_coarse = ecosystem.coarse_version(v2_str) + test_case.assertLessEqual(v1_coarse, v2_coarse) + + +class CoarseVersionMonotonicityTest(unittest.TestCase): + """Coarse version monotonicity tests.""" + + @given(apk_version_strategy, apk_version_strategy) + @example('1.02', '1.1') + @example('5.0.9', '5.06.7') + def test_apk(self, v1_str, v2_str): + check_coarse_version_monotonic(self, alpine.APK(), v1_str, v2_str) + + @given(cran_version_strategy, cran_version_strategy) + def test_cran(self, v1_str, v2_str): + check_coarse_version_monotonic(self, cran.CRAN(), v1_str, v2_str) + + @given(dpkg_version_strategy, dpkg_version_strategy) + def test_dpkg(self, v1_str, v2_str): + check_coarse_version_monotonic(self, debian.DPKG(), v1_str, v2_str) + + @given(hackage_version_strategy, hackage_version_strategy) + def test_hackage(self, v1_str, v2_str): + check_coarse_version_monotonic(self, haskell.Hackage(), v1_str, v2_str) + + @given(maven_version_strategy, maven_version_strategy) + def test_maven(self, v1_str, v2_str): + check_coarse_version_monotonic(self, maven.Maven(), v1_str, v2_str) + + @given(nuget_version_strategy, nuget_version_strategy) + def test_nuget(self, v1_str, v2_str): + check_coarse_version_monotonic(self, nuget.NuGet(), v1_str, v2_str) + + @given(packagist_version_strategy, packagist_version_strategy) + def test_packagist(self, v1_str, v2_str): + check_coarse_version_monotonic(self, packagist.Packagist(), v1_str, v2_str) + + @given(pub_version_strategy, pub_version_strategy) + def test_pub(self, v1_str, v2_str): + check_coarse_version_monotonic(self, pub.Pub(), v1_str, v2_str) + + @given(pypi_strategy, pypi_strategy) + def test_pypi(self, v1_str, v2_str): + check_coarse_version_monotonic(self, pypi.PyPI(), v1_str, v2_str) + + @given(rpm_version_strategy, rpm_version_strategy) + def test_rpm(self, v1_str, v2_str): + check_coarse_version_monotonic(self, redhat.RPM(), v1_str, v2_str) + + @given(rubygems_version_strategy, rubygems_version_strategy) + def test_rubygems(self, v1_str, v2_str): + check_coarse_version_monotonic(self, rubygems.RubyGems(), v1_str, v2_str) + + @given(semver_strategy, semver_strategy) + def test_semver(self, v1_str, v2_str): + check_coarse_version_monotonic(self, semver_ecosystem_helper.SemverLike(), + v1_str, v2_str) diff --git a/osv/ecosystems/cran.py b/osv/ecosystems/cran.py index c5991283800..6dd1b6ed24b 100644 --- a/osv/ecosystems/cran.py +++ b/osv/ecosystems/cran.py @@ -14,10 +14,13 @@ """CRAN helpers.""" import requests -import packaging_legacy.version from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_from_ints, + EnumerableEcosystem, + EnumerateError, +) class CRAN(EnumerableEcosystem): @@ -34,11 +37,19 @@ def _sort_key(self, version): # Some documentation on CRAN versioning and the R numeric_version method: # https://cran.r-project.org/doc/manuals/R-exts.html#The-DESCRIPTION-file # https://stat.ethz.ch/R-manual/R-devel/library/base/html/numeric_version.html - # The packaging.version appears to work for the typical X.Y.Z and - # X.Y-Z cases version = version.replace("-", ".") - # version.parse() handles invalid versions by returning LegacyVersion() - return packaging_legacy.version.parse(version) + try: + return tuple(int(part) for part in version.split('.')) + except ValueError as exc: + raise ValueError(f'Invalid version: {version}') from exc + + def coarse_version(self, version): + """Coarse version. + + Treats version as integers separated by dots or dashes. + """ + # Use _sort_key to validate or raise ValueError + return coarse_version_from_ints(self._sort_key(version)) def _enumerate_versions(self, url, diff --git a/osv/ecosystems/cran_test.py b/osv/ecosystems/cran_test.py index c61f04e6ce7..efd67594acb 100644 --- a/osv/ecosystems/cran_test.py +++ b/osv/ecosystems/cran_test.py @@ -58,3 +58,11 @@ def test_sort_key(self): ecosystem.sort_key('1.10-0'), ecosystem.sort_key('1.2-0')) self.assertLessEqual( ecosystem.sort_key('1.2-0'), ecosystem.sort_key('1.10-0')) + + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = ecosystems.get('CRAN') + self.assertEqual('00:00009001.00000010.00000033', + ecosystem.coarse_version('9001.10-33.4')) + self.assertEqual('00:00000000.00000001.00000000', + ecosystem.coarse_version('0-1')) diff --git a/osv/ecosystems/debian.py b/osv/ecosystems/debian.py index de1fad8bd69..bb75aaffd42 100644 --- a/osv/ecosystems/debian.py +++ b/osv/ecosystems/debian.py @@ -13,14 +13,21 @@ # limitations under the License. """Debian ecosystem helper.""" +from itertools import batched import json import logging +import re import requests from ..third_party.univers.debian import Version as DebianVersion from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_from_ints, + EnumerableEcosystem, + EnumerateError, + MAX_COARSE_PART, +) from .ecosystems_base import OrderedEcosystem from .. import cache from ..request_helper import RequestError, RequestHelper @@ -31,11 +38,54 @@ class DPKG(OrderedEcosystem): def _sort_key(self, version): if not DebianVersion.is_valid(version): - # If debian version is not valid, it is most likely an invalid fixed - # version then sort it to the last/largest element - return DebianVersion(9999999999, '9999999999') + raise ValueError(f'Invalid version: {version}') return DebianVersion.from_string(version) + def coarse_version(self, version: str) -> str: + """Coarse version. + + Treats version as alternating digit/non-digit strings. + Truncates at non-dot separators (like ~) to ensure monotonicity + (e.g. 1.0~rc1 < 1.0). + Epochs are preserved. + """ + if not DebianVersion.is_valid(version): + raise ValueError(f'Invalid version: {version}') + + # Try extract epoch. + e, p, v = version.partition(':') + if not p: + v = e + e = '0' + try: + epoch = int(e) + except ValueError as e: + raise ValueError(f'Invalid version: {version}') from e + + # Versions are treated as alternating digit/non-digit strings + # We treat the exact string '.' as a digit separator. + # Any strings starting with '.' (that are not exactly '.') + # are greater than any number. + # Any strings starting with anything else are less than any number. + parts = re.findall(r'^$|\d+|\D+', v) + int_parts = [] + for couple in batched(parts, 2): + if not couple[0].isdecimal(): + # This is probably handled by is_valid + break + int_parts.append(int(couple[0])) + if len(couple) == 1: + break + sep = couple[1] + if sep == '.': + continue + if sep[0] == '.': + # Bigger than the max int, so we overflow + int_parts.append(MAX_COARSE_PART + 1) + break + + return coarse_version_from_ints(int_parts, epoch=epoch) + # TODO(another-rex): Update this to use dynamically # change depending on the project diff --git a/osv/ecosystems/debian_test.py b/osv/ecosystems/debian_test.py index 9656529e461..9a797fbb40f 100644 --- a/osv/ecosystems/debian_test.py +++ b/osv/ecosystems/debian_test.py @@ -14,6 +14,7 @@ """dpkg / Debian ecosystem helper tests.""" import requests + import vcr.unittest import unittest from unittest import mock @@ -81,16 +82,55 @@ def test_dpkg(self): self.assertLessEqual( ecosystem.sort_key('1.2.0-1'), ecosystem.sort_key('1.10.0-1')) + def test_ubuntu(self): + """Test sort_key from Ubuntu""" + ecosystem = debian.DPKG() + self.assertGreater( + ecosystem.sort_key('2.42.8+dfsg-1ubuntu0.3'), + ecosystem.sort_key('2.40.0+dfsg-3ubuntu0.5')) + self.assertGreater( + ecosystem.sort_key('2.42.8+dfsg-1ubuntu0.3'), + ecosystem.sort_key('2.42.8+dfsg-1ubuntu0.2')) + self.assertGreater(ecosystem.sort_key('5.4.13-1'), ecosystem.sort_key('0')) + + # Check the 0 sentinel value. + self.assertLess(ecosystem.sort_key('0'), ecosystem.sort_key('0:0~0-0')) + + self.assertGreater( + ecosystem.sort_key('5.4.13-1'), ecosystem.sort_key('3.2.30-1')) + self.assertGreater( + ecosystem.sort_key('invalid'), ecosystem.sort_key('3.2.30-1')) + # Check >= / <= methods + self.assertGreaterEqual( + ecosystem.sort_key('2.10.8+dfsg-1ubuntu0.3'), + ecosystem.sort_key('2.2.8+dfsg-1ubuntu0.3')) + self.assertLessEqual( + ecosystem.sort_key('2.2.8+dfsg-1ubuntu0.3'), + ecosystem.sort_key('2.10.8+dfsg-1ubuntu0.3')) + def test_dpkg_ecosystems(self): """Test dpkg-based ecosystems return a DPKG ecosystem.""" ecos = [ 'Debian', 'Echo', + 'Ubuntu', ] for ecosystem_name in ecos: ecosystem = ecosystems.get(ecosystem_name) self.assertIsInstance(ecosystem, debian.DPKG) + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = debian.DPKG() + self.assertEqual('00:00000001.00000002.00000000', + ecosystem.coarse_version('1.2+1')) + self.assertEqual('01:20230101.00000000.00000000', + ecosystem.coarse_version('1:20230101~dfsg-1.1~deb12u1')) + self.assertEqual('00:00000010.00000020.00000030', + ecosystem.coarse_version('10.20.30')) + self.assertEqual('00:00000010.00000020.99999999', + ecosystem.coarse_version('10.20.a30')) + class DebianEcosystemTest(vcr.unittest.VCRTestCase): """Debian ecosystem helper tests.""" diff --git a/osv/ecosystems/ecosystems_base.py b/osv/ecosystems/ecosystems_base.py index 7366351148b..653fe030254 100644 --- a/osv/ecosystems/ecosystems_base.py +++ b/osv/ecosystems/ecosystems_base.py @@ -13,10 +13,11 @@ # limitations under the License. """Ecosystems base classes.""" from abc import ABC, abstractmethod -from typing import Any +from typing import Any, Iterable from warnings import deprecated import bisect import functools +import re import requests from urllib.parse import quote @@ -29,15 +30,34 @@ class VersionKey: _key: Any _is_zero: bool - - def __init__(self, key: Any = None, is_zero: bool = False): + _is_invalid: bool + _error: Exception | None + + def __init__(self, + key: Any = None, + is_zero: bool = False, + is_invalid: bool = False, + error: Exception | None = None): self._key = key self._is_zero = is_zero + self._is_invalid = is_invalid + self._error = error + + @property + def is_invalid(self): + return self._is_invalid def __lt__(self, other): if not isinstance(other, VersionKey): return NotImplemented + # Invalid versions are greater than everything else + if self._is_invalid: + # If both are invalid, they are equal (not less than) + return False + if other._is_invalid: + return True + if self._is_zero: return not other._is_zero @@ -50,6 +70,12 @@ def __eq__(self, other): if not isinstance(other, VersionKey): return NotImplemented + if self._is_invalid: + return other._is_invalid + + if other._is_invalid: + return False + if self._is_zero: return other._is_zero @@ -59,13 +85,15 @@ def __eq__(self, other): return self._key == other._key def __repr__(self): + if self._is_invalid: + return 'VersionKey(is_invalid=True)' if self._is_zero: return 'VersionKey(is_zero=True)' - - return f'VersionKey(key={self._key!r})' + return f'VersionKey({self._key})' _VERSION_ZERO = VersionKey(is_zero=True) +_VERSION_INVALID = VersionKey(is_invalid=True) class OrderedEcosystem(ABC): @@ -83,7 +111,7 @@ def __init__(self, suffix: str | None = None): def _sort_key(self, version: str) -> Any: """Comparable key for a version. - If the version string is invalid, return a very large version. + If the version string is invalid, raise a ValueError. """ def sort_key(self, version: str) -> VersionKey: @@ -91,12 +119,41 @@ def sort_key(self, version: str) -> VersionKey: if version == '0': return _VERSION_ZERO - return VersionKey(self._sort_key(version)) + try: + return VersionKey(self._sort_key(version)) + except ValueError as e: + # Store the exception for potential logging/debugging. + return VersionKey(is_invalid=True, error=e) def sort_versions(self, versions: list[str]): """Sort versions.""" versions.sort(key=self.sort_key) + def coarse_version(self, version: str) -> str: + """Convert a version string for this ecosystem to a lexicographically + sortable string in the form: + + EE:XXXXXXXX.YYYYYYYY.ZZZZZZZZ + where: + EE is the 0-padded 2-digit epoch number (or equivalent), + XXXXXXXX is the 0-padded 8-digit major version (or equivalent), + YYYYYYYY is the 0-padded 8-digit minor version (or equivalent), + ZZZZZZZZ is the 0-padded 8-digit patch version (or equivalent). + + The returned string is used for database range queries + (e.g. coarse_min <= v <= coarse_max). + It does not need to be a perfect representation of the version, but it + MUST be monotonically non-decreasing with respect to the ecosystem's sort + order. + i.e. if v1 < v2, then coarse_version(v1) <= coarse_version(v2). + + Version string '0' should map to 00:0000000.00000000.00000000 + + Should raise a ValueError if the version string is invalid. + """ + raise NotImplementedError( + f'coarse_version not implemented for {self.__class__.__name__}') + class EnumerateError(Exception): """Non-retryable version enumeration error.""" @@ -210,3 +267,105 @@ def _deps_dev_enumerate(self, self.sort_versions(versions) return self._get_affected_versions(versions, introduced, fixed, last_affected, limits) + + +MAX_COARSE_EPOCH = 99 +MAX_COARSE_PART = 99999999 + + +def coarse_version_generic(version: str, + separators_regex=r'[.]', + truncate_regex=r'[-+]', + implicit_split=False, + empty_as: str | None = None, + epoch: int = 0) -> str: + """ + Convert a version string into a coarse, lexicographically comparable string. + + Format: 00:00000000.00000000.00000000 + (Epoch:Major.Minor.Patch) + + Only the first 3 integer components (Major, Minor, Patch) are used. + + Args: + version: The version string to convert. + separators_regex: Regex for separators (default: r'[.]'). + truncate_regex: Regex for characters to truncate after (default: r'[-+]'). + If None, no truncation is performed. + implicit_split: If True, splits on transitions between digits and non-digits + (in addition to separators_regex). + empty_as: If not None, treats empty parts as the given string instead of + removing them. + epoch: The epoch to use. + + Returns: + A string in the format 00:00000000.00000000.00000000 + """ + if version == '0': + return coarse_version_from_ints((0, 0, 0), epoch=epoch) + + main = version + if truncate_regex: + # Truncate off trailing components (e.g. prerelease/build) + main = re.split(truncate_regex, version, maxsplit=1)[0] + parts = re.split(separators_regex, main) + if implicit_split: + # Also split on transitions between digits and non-digits + parts = [p for part in parts for p in re.findall(r'^$|\d+|\D+', part)] + + # Filter empty parts or treat as zero + if empty_as is not None: + parts = [p if p else empty_as for p in parts] + else: + parts = [p for p in parts if p] + + # Extract up to 3 integer components + components = [] + for p in parts[:3]: + if not p.isdecimal(): + break + components.append(int(p)) + + return coarse_version_from_ints(components, epoch=epoch) + + +def coarse_version_from_ints(parts: Iterable[int], epoch: int = 0) -> str: + """ + Convert a list of integers into a coarse version string. + + Format: 00:00000000.00000000.00000000 + (Epoch:Major.Minor.Patch) + + Only the first 3 integer components (Major, Minor, Patch) are used. + + Args: + parts: The list of integers to convert. + epoch: The epoch to use. + """ + if epoch < 0: + # A negative epoch doesn't really make sense + return '00:00000000.00000000.00000000' + if epoch > MAX_COARSE_EPOCH: + return '99:99999999.99999999.99999999' + ints = [] + overflow = False + for p in parts: + if p < 0: + # A negative part doesn't really make sense + # but let's just treat it and all following parts as 0 + ints.append(0) + break + if p > MAX_COARSE_PART: + p = MAX_COARSE_PART + overflow = True + ints.append(p) + if overflow or len(ints) == 3: + break + + # Pad with zeros to ensure 3 components + # If we overflowed, we should pad with MAX instead of 0 + pad_value = MAX_COARSE_PART if overflow else 0 + while len(ints) < 3: + ints.append(pad_value) + + return f'{epoch:02d}:{ints[0]:08d}.{ints[1]:08d}.{ints[2]:08d}' diff --git a/osv/ecosystems/haskell.py b/osv/ecosystems/haskell.py index 3895472390e..a72cdb9a8a7 100644 --- a/osv/ecosystems/haskell.py +++ b/osv/ecosystems/haskell.py @@ -23,7 +23,11 @@ import requests from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_from_ints, + EnumerableEcosystem, + EnumerateError, +) from .semver_ecosystem_helper import SemverLike @@ -39,12 +43,17 @@ def _sort_key(self, version): https://hackage.haskell.org/package/Cabal-syntax/docs/Distribution-Types-Version.html """ - # If version is not valid, it is most likely an invalid input version - # then sort it to the last/largest element try: return [int(x) for x in version.split('.')] - except ValueError: - return [999999] + except ValueError as exc: + raise ValueError(f'Invalid version: {version}') from exc + + def coarse_version(self, version): + """Coarse version. + + Hackage versions are treated as dot-separated integers. + """ + return coarse_version_from_ints(self._sort_key(version)) def enumerate_versions(self, package, @@ -123,7 +132,7 @@ def tag_to_version(cls, tag: str) -> str | None: def is_major_minor_patch(s: str) -> bool: """Check that string matches ``..``.""" parts = s.split('.') - return len(parts) == 3 and all(x.isdigit() for x in parts) + return len(parts) == 3 and all(x.isdecimal() for x in parts) def enumerate_versions(self, package, diff --git a/osv/ecosystems/haskell_test.py b/osv/ecosystems/haskell_test.py index 6d9b20868f5..b7b5e15a5c7 100644 --- a/osv/ecosystems/haskell_test.py +++ b/osv/ecosystems/haskell_test.py @@ -51,6 +51,16 @@ def test_sort_key(self): self.assertLessEqual( ecosystem.sort_key('1.20.0'), ecosystem.sort_key('1-20-0')) + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = ecosystems.get('Hackage') + self.assertEqual('00:00009001.00000010.00000033', + ecosystem.coarse_version('9001.10.33.4')) + self.assertEqual('00:00000000.00000001.00000000', + ecosystem.coarse_version('0.1')) + self.assertEqual('00:00000067.00000000.00000000', + ecosystem.coarse_version('67')) + class GHCEcosystemTest(vcr.unittest.VCRTestCase): """GHC ecosystem helper tests.""" diff --git a/osv/ecosystems/maven.py b/osv/ecosystems/maven.py index f2dc4851682..e14de1398a0 100644 --- a/osv/ecosystems/maven.py +++ b/osv/ecosystems/maven.py @@ -17,7 +17,11 @@ import functools import re -from .ecosystems_base import EnumerableEcosystem, DepsDevMixin +from .ecosystems_base import ( + coarse_version_generic, + EnumerableEcosystem, + DepsDevMixin, +) # pylint: disable=line-too-long @@ -31,7 +35,7 @@ def qualifier_order(token): """Returns an integer representing a token's order.""" # ".qualifier" < "-qualifier" < "-number" < ".number" - if token.value.isdigit(): + if token.value.isdecimal(): if token.prefix == '-': return 2 @@ -58,16 +62,16 @@ def __eq__(self, other): def __lt__(self, other): if self.prefix == other.prefix: # if the prefix is the same, then compare the token: - if self.value.isdigit() and other.value.isdigit(): + if self.value.isdecimal() and other.value.isdecimal(): # Numeric tokens have the natural order. return int(self.value) < int(other.value) # The spec is unclear, but according to Maven's implementation, numerics # sort after non-numerics, **unless it's a null value**. # https://github.com/apache/maven/blob/965aaa53da5c2d814e94a41d37142d0d6830375d/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java#L443 - if self.value.isdigit() and not self.is_null: + if self.value.isdecimal() and not self.is_null: return False - if other.value.isdigit() and not other.is_null: + if other.value.isdecimal() and not other.is_null: return True # Non-numeric tokens ("qualifiers") have the alphabetical order, except @@ -208,7 +212,7 @@ def from_string(cls, str_version): if current == 'm': current = 'milestone' - if current.isdigit(): + if current.isdecimal(): # Remove any leading zeros. current = str(int(current)) @@ -244,6 +248,21 @@ def _sort_key(self, version): """Sort key.""" return Version.from_string(version) + def coarse_version(self, version): + """Coarse version. + + Treats version as dot-separated integers. + Trims at hyphens to ensure monotonicity for qualifiers (1.2-beta < 1.2) + and numeric suffixes (1.2-3 < 1.2.1). + """ + return coarse_version_generic( + version, + separators_regex=r'[.]', + truncate_regex=r'-', + implicit_split=True, + empty_as='0', + ) + def enumerate_versions(self, package, introduced, diff --git a/osv/ecosystems/maven_test.py b/osv/ecosystems/maven_test.py index e4a06dbe541..292ac121b1e 100644 --- a/osv/ecosystems/maven_test.py +++ b/osv/ecosystems/maven_test.py @@ -16,6 +16,7 @@ # Many tests are ported from # https://github.com/apache/maven/blob/c3cf29438e3d65d6ee5c5726f8611af99d9a649a/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java. """Maven ecosystem helper tests.""" + import unittest import vcr.unittest import warnings @@ -259,6 +260,19 @@ def test_version_ge_le(self): self.assertLessEqual( self.ecosystem.sort_key('1.2.0'), self.ecosystem.sort_key('1.10.0')) + def test_coarse_version(self): + """Test coarse_version.""" + self.assertEqual('00:00000001.00000002.00000003', + self.ecosystem.coarse_version('1.2.3')) + self.assertEqual('00:00000002.00000003.00000000', + self.ecosystem.coarse_version('2.3-5.4')) + self.assertEqual('00:00000000.00000000.00000000', + self.ecosystem.coarse_version('alpha-alpha')) + self.assertEqual('00:00000005.00000010.00000000', + self.ecosystem.coarse_version('5.10.foo-6')) + self.assertEqual('00:00000001.00000000.00000009', + self.ecosystem.coarse_version('1..9foo')) + class MavenEcosystemTest(vcr.unittest.VCRTestCase): """Maven ecosystem helper tests.""" diff --git a/osv/ecosystems/nuget.py b/osv/ecosystems/nuget.py index 5da2aee3634..4a92473eced 100644 --- a/osv/ecosystems/nuget.py +++ b/osv/ecosystems/nuget.py @@ -18,7 +18,11 @@ import requests from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_generic, + EnumerableEcosystem, + EnumerateError, +) from .. import semver_index # This relies on a strict SemVer implementation. @@ -74,10 +78,8 @@ def from_string(cls, str_version): str_version, revision = _extract_revision(str_version) try: return Version(semver_index.parse(str_version), revision) - except ValueError: - # If a user gives us an unparsable semver version, - # treat it as a very large version so as to not match anything. - return Version(semver_index.parse('999999'), 999999) + except ValueError as exc: + raise ValueError(f'Invalid version: {str_version}') from exc class NuGet(EnumerableEcosystem): @@ -90,6 +92,24 @@ def _sort_key(self, version): """Sort key.""" return Version.from_string(version) + def coarse_version(self, version): + """Coarse version. + + Treats version as dot-separated integers. + Trims prerelease/build suffixes to ensure monotonicity + (e.g. 1.0.0-beta < 1.0.0). + """ + # Call _sort_key to force a ValueError if the version is invalid. + self._sort_key(version) + if version[0] == 'v': + version = version[1:] + return coarse_version_generic( + version, + separators_regex=r'[.]', + truncate_regex=r'[-+]', + implicit_split=True, + empty_as=None) + def enumerate_versions(self, package, introduced, diff --git a/osv/ecosystems/nuget_test.py b/osv/ecosystems/nuget_test.py index 9052004f2a5..1a7732f1a12 100644 --- a/osv/ecosystems/nuget_test.py +++ b/osv/ecosystems/nuget_test.py @@ -18,6 +18,7 @@ """NuGet ecosystem helper tests.""" import unittest + import vcr.unittest import warnings @@ -92,6 +93,22 @@ def test_ge_le(self): self.check_order(self.assertGreaterEqual, '1.10.0', '1.2.0') self.check_order(self.assertLessEqual, '1.2.0', '1.10.0') + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = nuget.NuGet() + self.assertEqual('00:00000000.00000000.00000000', + ecosystem.coarse_version('0')) + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1.2.3.5')) + self.assertEqual('00:00000010.00000020.00000030', + ecosystem.coarse_version('10.20.30-alpha.1')) + self.assertEqual('00:00000000.00000002.00000000', + ecosystem.coarse_version('0.2.0.1+a')) + self.assertEqual('00:00000000.00000000.00000099', + ecosystem.coarse_version('0.0.99.10-pre+b')) + self.assertEqual('00:00000002.99999999.99999999', + ecosystem.coarse_version('2.100000000.1.1')) + class NuGetEcosystemTest(vcr.unittest.VCRTestCase): """NuGet ecosystem helper tests.""" diff --git a/osv/ecosystems/opam.py b/osv/ecosystems/opam.py new file mode 100644 index 00000000000..e120869da81 --- /dev/null +++ b/osv/ecosystems/opam.py @@ -0,0 +1,43 @@ +"""opam ecosystem helper.""" +import requests + +from . import config +from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .debian import DPKG + + +class Opam(EnumerableEcosystem, DPKG): + """opam packages ecosystem""" + + _BASE = 'https://api.github.com/repos/ocaml/' + _REPO = _BASE + 'opam-repository/contents/packages/' + _REPO_ARCHIVE = _BASE + 'opam-repository-archive/contents/packages/' + + def enumerate_versions(self, + package, + introduced, + fixed=None, + last_affected=None, + limits=None): + """Enumerate versions.""" + response = requests.get(self._REPO + package, timeout=config.timeout) + archive_response = requests.get( + self._REPO_ARCHIVE + package, timeout=config.timeout) + if response.status_code == 404 and archive_response.status_code == 404: + raise EnumerateError(f'Package {package} not found') + if response.status_code != 200 and archive_response.status_code != 200: + raise RuntimeError( + f'Failed to get opam versions for {package} with: {response.text}') + + responses = {} + + if response.status_code == 200: + responses.extend(response.json()) + if archive_response.status_code == 200: + responses.extend(archive_response.json()) + + versions = [x["name"].removeprefix(package + '.') for x in responses] + + self.sort_versions(versions) + return self._get_affected_versions(versions, introduced, fixed, + last_affected, limits) diff --git a/osv/ecosystems/packagist.py b/osv/ecosystems/packagist.py index 83f36550d84..cc14170d02c 100644 --- a/osv/ecosystems/packagist.py +++ b/osv/ecosystems/packagist.py @@ -18,7 +18,12 @@ from typing import List from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_from_ints, + EnumerableEcosystem, + EnumerateError, + MAX_COARSE_PART, +) from ..request_helper import RequestError, RequestHelper @@ -92,11 +97,11 @@ def php_slices_compare(a_split: List[str], b_split: List[str]): Compare php versions after being split by '.' """ for a, b in zip(a_split, b_split): - if a.isdigit() and b.isdigit(): + if a.isdecimal() and b.isdecimal(): compare = int(a) - int(b) - elif not a.isdigit() and not b.isdigit(): + elif not a.isdecimal() and not b.isdecimal(): compare = PackagistVersion.compare_special_versions(a, b) - elif a.isdigit(): + elif a.isdecimal(): compare = PackagistVersion.compare_special_versions('#', b) else: compare = PackagistVersion.compare_special_versions(a, '#') @@ -108,13 +113,13 @@ def php_slices_compare(a_split: List[str], b_split: List[str]): if len(a_split) > len(b_split): next_char = a_split[len(b_split)] - if next_char.isdigit(): + if next_char.isdecimal(): return 1 return PackagistVersion.php_slices_compare(a_split[len(b_split):], ['#']) if len(a_split) < len(b_split): next_char = b_split[len(a_split)] - if next_char.isdigit(): + if next_char.isdecimal(): return -1 return PackagistVersion.php_slices_compare(['#'], b_split[len(a_split):]) @@ -202,6 +207,39 @@ class Packagist(EnumerableEcosystem): def _sort_key(self, version): return PackagistVersion(version) + def coarse_version(self, version): + """Coarse version. + + Treats version as integers separated by ., -, _, or +. + Treats 'p'/'pl' suffixes as MAX_INT to ensure they sort after base versions + (e.g. 1.0 < 1.0-p1). + """ + if version.startswith('v'): + version = version[1:] + # Cannot use coarse_version_generic because 'p' and 'pl' are considered + # greater than numbers + # 0 > .1 (but 0.1 == 0..1) + if not version or version[0] in '-_+.': + return coarse_version_from_ints([0]) + # Split on separators. + parts = re.split(r'[-_+.]', version) + # Split on transitions between digits and non-digits + parts = [p for part in parts for p in re.findall(r'^$|\d+|\D+', part)] + # Filter empty parts + parts = [p for p in parts if p] + # Extract up to 3 integer components + components = [] + for p in parts[:3]: + if p in ('p', 'pl'): + val = MAX_COARSE_PART + 1 # trigger overflow + elif not p.isdecimal(): + break + else: + val = int(p) + components.append(val) + + return coarse_version_from_ints(components) + def enumerate_versions(self, package, introduced, diff --git a/osv/ecosystems/packagist_test.py b/osv/ecosystems/packagist_test.py index 52c6cc7a7c9..d7f1d3c467f 100644 --- a/osv/ecosystems/packagist_test.py +++ b/osv/ecosystems/packagist_test.py @@ -24,6 +24,24 @@ class PackagistEcosystemTest(vcr.unittest.VCRTestCase): _TEST_DATA_DIR = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'testdata') + def test_coarse_version(self): + """Test coarse_version.""" + ecosystem = ecosystems.get('Packagist') + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1.2.3')) + self.assertEqual('00:00000001.00000000.00000000', + ecosystem.coarse_version('1.0.0-alpha')) + self.assertEqual('00:00000001.00000000.00000000', + ecosystem.coarse_version('1.0.0-p1')) + self.assertEqual('00:00000004.00000003.00000002', + ecosystem.coarse_version('4.3-2RC1')) + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1+.+2-_-3')) + self.assertEqual('00:00000008.99999999.99999999', + ecosystem.coarse_version('8.p2')) + self.assertEqual('00:99999999.99999999.99999999', + ecosystem.coarse_version('pl')) + def test_packagist(self): """Test Packagist.""" ecosystem = ecosystems.get('Packagist') diff --git a/osv/ecosystems/pub.py b/osv/ecosystems/pub.py index b7657bbbcba..61b2fb4eacb 100644 --- a/osv/ecosystems/pub.py +++ b/osv/ecosystems/pub.py @@ -17,7 +17,11 @@ import json from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_generic, + EnumerableEcosystem, + EnumerateError, +) from .. import semver_index from ..request_helper import RequestError, RequestHelper @@ -58,12 +62,10 @@ def __eq__(self, other): @classmethod def from_string(cls, str_version): - # If version is not valid, it is most likely an invalid input - # version then sort it to the last/largest element try: return Version(semver_index.parse(str_version)) - except ValueError: - return Version(semver_index.parse('999999')) + except ValueError as exc: + raise ValueError(f'Invalid version: {str_version}') from exc class Pub(EnumerableEcosystem): @@ -75,6 +77,27 @@ def _sort_key(self, version): """Sort key.""" return Version.from_string(version) + def coarse_version(self, version): + """Coarse version. + + Treats version as dot-separated integers. + Trims prerelease/build suffixes to ensure monotonicity + (e.g. 1.0.0-beta < 1.0.0). + """ + # Make sure the version is valid before trying to make it coarse. + try: + semver_index.parse(version) + except ValueError as e: + raise ValueError(f'Invalid version: {version}') from e + if version[0] == 'v': + version = version[1:] + return coarse_version_generic( + version, + separators_regex=r'[.]', + truncate_regex=r'[-+]', + implicit_split=True, + empty_as=None) + def enumerate_versions(self, package, introduced, diff --git a/osv/ecosystems/pub_test.py b/osv/ecosystems/pub_test.py index d7cd7a782c4..a21951926e2 100644 --- a/osv/ecosystems/pub_test.py +++ b/osv/ecosystems/pub_test.py @@ -113,6 +113,22 @@ def test_empty_identifier(self): # The implementation incorrectly assumes "1.0.0-a..b" == "1.0.0-a.-.b" # I have decided that this extreme edge case is not worth fixing. + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = pub.Pub() + self.assertEqual('00:00000000.00000000.00000000', + ecosystem.coarse_version('0')) + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1.2.3')) + self.assertEqual('00:00000010.00000020.00000030', + ecosystem.coarse_version('10.20.30-alpha.1')) + self.assertEqual('00:00000000.00000002.00000000', + ecosystem.coarse_version('0.2.0+a')) + self.assertEqual('00:00000000.00000000.00000099', + ecosystem.coarse_version('0.0.99-pre+b')) + self.assertEqual('00:00000002.99999999.99999999', + ecosystem.coarse_version('2.100000000.1')) + class PubEcosystemTest(vcr.unittest.VCRTestCase): """Pub ecosystem helper tests.""" diff --git a/osv/ecosystems/pypi.py b/osv/ecosystems/pypi.py index 23add43e138..56f2866e0e4 100644 --- a/osv/ecosystems/pypi.py +++ b/osv/ecosystems/pypi.py @@ -17,7 +17,12 @@ import requests from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_generic, + coarse_version_from_ints, + EnumerableEcosystem, + EnumerateError, +) class PyPI(EnumerableEcosystem): @@ -30,6 +35,33 @@ def _sort_key(self, version): # version.parse() handles invalid versions by returning LegacyVersion() return packaging_legacy.version.parse(version) + def coarse_version(self, version: str): + """Coarse version. + + Treats version as dot-separated integers. + Maps legacy versions to 0 (sort before valid versions). + Epochs are preserved. + """ + # legacy versions are less than non-legacy versions, thus mapped to 0 + ver = packaging_legacy.version.parse(version) + if isinstance(ver, packaging_legacy.version.LegacyVersion): + return coarse_version_from_ints([0]) + + epoch = ver.epoch + + # parse the epoch-less string + if version[0].lower() == 'v': + version = version[1:] + epochless = version.split('!', 1)[-1] + + return coarse_version_generic( + epochless, + separators_regex=r'[.]', + truncate_regex=r'[+_-]', + implicit_split=True, + empty_as=None, + epoch=epoch) + def enumerate_versions(self, package, introduced, diff --git a/osv/ecosystems/pypi_test.py b/osv/ecosystems/pypi_test.py index 8b61f2fce94..f8f7eb23cb9 100644 --- a/osv/ecosystems/pypi_test.py +++ b/osv/ecosystems/pypi_test.py @@ -48,3 +48,17 @@ def test_sort_key(self): ecosystem.sort_key('1.10.0'), ecosystem.sort_key('1.2.0')) self.assertLessEqual( ecosystem.sort_key('1.2.0'), ecosystem.sort_key('1.10.0')) + + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = ecosystems.get('PyPI') + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1.2.3')) + self.assertEqual('00:00002020.00000000.00000000', + ecosystem.coarse_version('0!2020.post1')) + self.assertEqual('02:00000001.00000002.00000003', + ecosystem.coarse_version('2!1.2.3')) + self.assertEqual('99:99999999.99999999.99999999', + ecosystem.coarse_version('100!1.0.0')) + self.assertEqual('00:00000000.00000000.00000000', + ecosystem.coarse_version('1.foobar')) diff --git a/osv/ecosystems/redhat.py b/osv/ecosystems/redhat.py index 03679669d84..490464c931e 100644 --- a/osv/ecosystems/redhat.py +++ b/osv/ecosystems/redhat.py @@ -14,11 +14,52 @@ """Red Hat Linux ecosystem helper.""" from ..third_party.univers.rpm import RpmVersion -from .ecosystems_base import OrderedEcosystem +from .ecosystems_base import coarse_version_generic, OrderedEcosystem + +# A real, valid Rpm Version to check against +_rpm_test_version = RpmVersion.from_string('0') class RPM(OrderedEcosystem): """Red Hat Package Manager ecosystem helper.""" def _sort_key(self, version): - return RpmVersion.from_string(version) + ver = RpmVersion.from_string(version) + # Invalid RPM versions only reveal themselves when doing a comparison. + try: + _rpm_test_version < ver + except Exception as e: + raise ValueError(f'Invalid version: {version}') from e + return ver + + def coarse_version(self, version: str) -> str: + """Coarse version. + + Treats version as alternating digit/non-digit strings. + Treats ~, ^, - as separators that sort before regular separators + (e.g. 1.0~rc1 < 1.0). + Epochs are preserved. + """ + # Call sort key to validate the version + self._sort_key(version) + # Extract epoch, if it exists + e, p, v = version.partition(':') + if not p: + v = e + e = '0' + try: + epoch = int(e) + except ValueError as e: + raise ValueError(f'Invalid version: {version}') from e + + return coarse_version_generic( + v, + # any non-alphanumeric character is considered a separator + separators_regex=r'[^0-9A-Za-z~^-]', + # ~, ^, - separators are special and treated as less than a regular + # separator + truncate_regex=r'[~^-]', + implicit_split=True, + empty_as=None, + epoch=epoch, + ) diff --git a/osv/ecosystems/redhat_test.py b/osv/ecosystems/redhat_test.py index b440edf7a1d..0f785d27b11 100644 --- a/osv/ecosystems/redhat_test.py +++ b/osv/ecosystems/redhat_test.py @@ -135,3 +135,15 @@ def test_rpm_ecosystems(self): for ecosystem_name in ecos: ecosystem = ecosystems.get(ecosystem_name) self.assertIsInstance(ecosystem, redhat.RPM) + + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = redhat.RPM() + self.assertEqual('00:00000003.00000004.00000001', + ecosystem.coarse_version('0:3.4.1-6.el8_10')) + self.assertEqual('02:00000001.00000035.00000000', + ecosystem.coarse_version('2:1.35-9.el10_1')) + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1+2__3')) + self.assertEqual('00:00000010.00000020.00000000', + ecosystem.coarse_version('10.20^2')) diff --git a/osv/ecosystems/root.py b/osv/ecosystems/root.py index 653d08be08d..83857328e64 100644 --- a/osv/ecosystems/root.py +++ b/osv/ecosystems/root.py @@ -14,7 +14,11 @@ """Root ecosystem helper.""" import re +import packaging_legacy.version from .ecosystems_base import OrderedEcosystem +from .maven import Version as MavenVersion +from ..third_party.univers.alpine import AlpineLinuxVersion +from ..third_party.univers.debian import Version as DebianVersion class Root(OrderedEcosystem): @@ -37,79 +41,91 @@ class Root(OrderedEcosystem): def _sort_key(self, version: str): """Generate sort key for Root version strings. - Handles multiple version formats: - - Alpine: 1.0.0-r10071 - - Python: 1.0.0+root.io.1 - - Others: 1.0.0.root.io.1 + Delegates to the appropriate ecosystem version parser based on the + ecosystem suffix (e.g., :Alpine:3.18, :Debian:12, :npm). Args: version: Version string to parse Returns: - Tuple suitable for sorting + Tuple with (version_object, root_patch) for sorting """ - # Try Alpine format: -r - alpine_match = re.match(r'^(.+?)-r(\d+)$', version) - if alpine_match: - upstream = alpine_match.group(1) - root_patch = int(alpine_match.group(2)) - return self._parse_upstream_version(upstream) + (root_patch,) + upstream_version = version + root_patch = 0 - # Try Python format: +root.io. + # Extract Root-specific suffixes + # Python format: +root.io. python_match = re.match(r'^(.+?)\+root\.io\.(\d+)$', version) if python_match: - upstream = python_match.group(1) + upstream_version = python_match.group(1) root_patch = int(python_match.group(2)) - return self._parse_upstream_version(upstream) + (root_patch,) - # Try other format: .root.io. + # Generic format: .root.io. other_match = re.match(r'^(.+?)\.root\.io\.(\d+)$', version) if other_match: - upstream = other_match.group(1) + upstream_version = other_match.group(1) root_patch = int(other_match.group(2)) - return self._parse_upstream_version(upstream) + (root_patch,) - # Fallback: treat as generic version - return self._parse_upstream_version(version) + # Alpine format with Root suffix: -r + # Note: Alpine naturally uses -r + alpine_match = re.match(r'^(.+?)-r(\d+)$', upstream_version) + if alpine_match: + root_patch = int(alpine_match.group(2)) - def _parse_upstream_version(self, version: str): - """Parse upstream version component. + # Determine the sub-ecosystem from the suffix + sub_ecosystem = self._get_sub_ecosystem() - Attempts to extract numeric and string components for sorting. + # Parse the upstream version using the appropriate version class + return self._parse_upstream_version(upstream_version, + sub_ecosystem) + (root_patch,) - Args: - version: Upstream version string + def _get_sub_ecosystem(self) -> str: + """Extract the sub-ecosystem from the suffix. Returns: - Tuple of parsed components + Sub-ecosystem name (e.g., 'Alpine', 'Debian', 'npm', 'PyPI') """ - parts = [] - - # Split on common delimiters - components = re.split(r'[.-]', version) - - for component in components: - # Try to parse as integer - try: - parts.append(int(component)) - except ValueError: - # If not numeric, use string comparison - # Convert to tuple of character codes for consistent sorting - parts.append(component) + if not self.suffix: + return 'unknown' - return tuple(parts) + # Parse suffix like ":Alpine:3.18" -> "Alpine" + # or ":npm" -> "npm" + parts = self.suffix.strip(':').split(':') + if parts: + return parts[0] + return 'unknown' - def sort_key(self, version: str): - """Public sort key method. + def _parse_upstream_version(self, version: str, sub_ecosystem: str): + """Parse upstream version using ecosystem-specific parser. Args: - version: Version string + version: Upstream version string + sub_ecosystem: Sub-ecosystem name (e.g., 'Alpine', 'Debian', 'npm') Returns: - Tuple for sorting + Tuple with version object for comparison + + Raises: + ValueError: If the version cannot be parsed by the appropriate parser """ - try: - return self._sort_key(version) - except Exception: - # Fallback to string comparison if parsing fails - return (version,) + match sub_ecosystem.lower(): + case 'alpine': + if not AlpineLinuxVersion.is_valid(version): + raise ValueError(f'Invalid Alpine version: {version}') + return (AlpineLinuxVersion(version),) + + case 'debian' | 'ubuntu': + if not DebianVersion.is_valid(version): + raise ValueError(f'Invalid Debian/Ubuntu version: {version}') + return (DebianVersion.from_string(version),) + + case 'pypi' | 'python': + # packaging_legacy.version.parse handles invalid versions gracefully + # by returning LegacyVersion, so we don't need explicit validation + return (packaging_legacy.version.parse(version),) + + case 'maven': + return (MavenVersion.from_string(version),) + + case _: + return (packaging_legacy.version.parse(version),) diff --git a/osv/ecosystems/root_test.py b/osv/ecosystems/root_test.py new file mode 100644 index 00000000000..840eb1809ed --- /dev/null +++ b/osv/ecosystems/root_test.py @@ -0,0 +1,170 @@ +# Copyright 2025 Google LLC +# +# 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. +"""Root ecosystem helper tests.""" + +import unittest + +from . import root + + +class RootEcosystemTest(unittest.TestCase): + """Root ecosystem helper tests.""" + + def test_alpine_versions(self): + """Test Root:Alpine version comparison.""" + ecosystem = root.Root(suffix=':Alpine:3.18') + + # Basic Alpine version ordering + self.assertGreater( + ecosystem.sort_key('1.51.0-r20072'), + ecosystem.sort_key('1.51.0-r20071')) + self.assertGreater( + ecosystem.sort_key('1.0.0-r2'), ecosystem.sort_key('1.0.0-r1')) + + # Check the 0 sentinel value + self.assertLess(ecosystem.sort_key('0'), ecosystem.sort_key('1.0.0-r1')) + + # Check equality + self.assertEqual( + ecosystem.sort_key('1.51.0-r20071'), + ecosystem.sort_key('1.51.0-r20071')) + + def test_debian_versions(self): + """Test Root:Debian version comparison.""" + ecosystem = root.Root(suffix=':Debian:12') + + # Basic Debian version ordering with Root suffix + self.assertGreater( + ecosystem.sort_key('22.12.0-2+deb12u1.root.io.5'), + ecosystem.sort_key('22.12.0-2.root.io.1')) + + self.assertGreater( + ecosystem.sort_key('1.18.0-6+deb11u3-r20072'), + ecosystem.sort_key('1.18.0-6+deb11u3-r20071')) + + # Check equality + self.assertEqual( + ecosystem.sort_key('1.18.0-6+deb11u3-r20071'), + ecosystem.sort_key('1.18.0-6+deb11u3-r20071')) + + def test_ubuntu_versions(self): + """Test Root:Ubuntu version comparison.""" + ecosystem = root.Root(suffix=':Ubuntu:22.04') + + # Ubuntu version ordering + self.assertGreater( + ecosystem.sort_key('1.2.3-4ubuntu2'), + ecosystem.sort_key('1.2.3-4ubuntu1')) + + def test_pypi_versions(self): + """Test Root:PyPI version comparison.""" + ecosystem = root.Root(suffix=':PyPI') + + # Python version ordering with Root suffix + self.assertGreater( + ecosystem.sort_key('1.0.0+root.io.5'), + ecosystem.sort_key('1.0.0+root.io.1')) + + # PEP440 version ordering + self.assertGreater(ecosystem.sort_key('2.0.0'), ecosystem.sort_key('1.9.9')) + self.assertGreater( + ecosystem.sort_key('1.0.0'), ecosystem.sort_key('1.0.0rc1')) + + def test_npm_versions(self): + """Test Root:npm version comparison.""" + ecosystem = root.Root(suffix=':npm') + + # npm semver ordering with Root suffix + self.assertGreater( + ecosystem.sort_key('1.0.0.root.io.5'), + ecosystem.sort_key('1.0.0.root.io.1')) + + # Basic semver ordering + self.assertGreater(ecosystem.sort_key('2.0.0'), ecosystem.sort_key('1.9.9')) + self.assertGreater(ecosystem.sort_key('1.0.1'), ecosystem.sort_key('1.0.0')) + + def test_maven_versions(self): + """Test Root:Maven version comparison.""" + ecosystem = root.Root(suffix=':Maven') + + # Maven version ordering + self.assertGreater(ecosystem.sort_key('2.0'), ecosystem.sort_key('1.0')) + self.assertGreater( + ecosystem.sort_key('1.0'), ecosystem.sort_key('1.0-SNAPSHOT')) + + def test_unknown_ecosystem_fallback(self): + """Test fallback behavior for unknown ecosystems.""" + ecosystem = root.Root(suffix=None) + + # Should still work with Alpine-like versions + self.assertGreater( + ecosystem.sort_key('1.0.0-r2'), ecosystem.sort_key('1.0.0-r1')) + + # Should work with generic versions + self.assertGreater(ecosystem.sort_key('2.0.0'), ecosystem.sort_key('1.0.0')) + + def test_github_issue_4396(self): + """Test the specific versions from GitHub issue #4396.""" + ecosystem = root.Root(suffix=':Debian:12') + + # The problematic comparison that used to crash + key1 = ecosystem.sort_key('22.12.0-2.root.io.1') + key2 = ecosystem.sort_key('22.12.0-2+deb12u1.root.io.5') + + # Should not crash and should compare correctly + self.assertLess(key1, key2) + + def test_root_suffix_extraction(self): + """Test extraction of Root-specific version suffixes.""" + ecosystem = root.Root(suffix=':PyPI') + + # Python format: +root.io. + key = ecosystem.sort_key('1.0.0+root.io.5') + self.assertIsNotNone(key) + + # Generic format: .root.io. + key = ecosystem.sort_key('1.0.0.root.io.5') + self.assertIsNotNone(key) + + def test_invalid_versions(self): + """Test that invalid versions raise appropriate errors.""" + # Alpine ecosystem with invalid version + ecosystem_alpine = root.Root(suffix=':Alpine:3.18') + key = ecosystem_alpine.sort_key('invalid-version!@#') + self.assertTrue(key.is_invalid) + + # Debian ecosystem with empty version + ecosystem_debian = root.Root(suffix=':Debian:12') + key = ecosystem_debian.sort_key('') + self.assertTrue(key.is_invalid) + + def test_sub_ecosystem_extraction(self): + """Test _get_sub_ecosystem method.""" + # Test various suffix formats + # pylint: disable=protected-access + ecosystem = root.Root(suffix=':Alpine:3.18') + self.assertEqual(ecosystem._get_sub_ecosystem(), 'Alpine') + + ecosystem = root.Root(suffix=':Debian:12') + self.assertEqual(ecosystem._get_sub_ecosystem(), 'Debian') + + ecosystem = root.Root(suffix=':npm') + self.assertEqual(ecosystem._get_sub_ecosystem(), 'npm') + + ecosystem = root.Root(suffix=None) + self.assertEqual(ecosystem._get_sub_ecosystem(), 'unknown') + + +if __name__ == '__main__': + unittest.main() diff --git a/osv/ecosystems/rubygems.py b/osv/ecosystems/rubygems.py index dc4abf8e9b9..868f8786bdf 100644 --- a/osv/ecosystems/rubygems.py +++ b/osv/ecosystems/rubygems.py @@ -18,7 +18,11 @@ from ..third_party.univers.gem import GemVersion, InvalidVersionError from . import config -from .ecosystems_base import EnumerableEcosystem, EnumerateError +from .ecosystems_base import ( + coarse_version_generic, + EnumerableEcosystem, + EnumerateError, +) class RubyGems(EnumerableEcosystem): @@ -32,8 +36,24 @@ def _sort_key(self, version): # version then sort it to the last/largest element try: return GemVersion(version) - except InvalidVersionError: - return GemVersion('9999999999') + except InvalidVersionError as exc: + raise ValueError(f'Invalid version: {version}') from exc + + def coarse_version(self, version: str) -> str: + """Coarse version. + + Treats version as dot-separated integers. + Trims at hyphens to ensure monotonicity (e.g. 1.2-3 < 1.2). + """ + # Call sort key to validate the version + self._sort_key(version) + + return coarse_version_generic( + version.strip(), + separators_regex=r'[.]', + truncate_regex=r'[-]', + implicit_split=True, + empty_as='') def enumerate_versions(self, package, diff --git a/osv/ecosystems/rubygems_test.py b/osv/ecosystems/rubygems_test.py index 172836a5f00..c99dac36da8 100644 --- a/osv/ecosystems/rubygems_test.py +++ b/osv/ecosystems/rubygems_test.py @@ -52,3 +52,11 @@ def test_sort_key(self): ecosystem.sort_key('1.2.0.rc1'), ecosystem.sort_key('1.10.0.rc1')) # Check the 0 sentinel value self.assertLess(ecosystem.sort_key('0'), ecosystem.sort_key('0.0.0.rc0')) + + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = ecosystems.get('RubyGems') + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1.2.3.4')) + self.assertEqual('00:00000010.00000002.00000000', + ecosystem.coarse_version('10.2a.3')) diff --git a/osv/ecosystems/semver_ecosystem_helper.py b/osv/ecosystems/semver_ecosystem_helper.py index 974dc9e4c64..00db6c9687e 100644 --- a/osv/ecosystems/semver_ecosystem_helper.py +++ b/osv/ecosystems/semver_ecosystem_helper.py @@ -14,7 +14,7 @@ """Ecosystem helper for ecosystems using SemVer.""" from warnings import deprecated -from .ecosystems_base import OrderedEcosystem +from .ecosystems_base import coarse_version_generic, OrderedEcosystem from .. import semver_index @@ -24,12 +24,28 @@ class SemverLike(OrderedEcosystem): def _sort_key(self, version): """Sort key.""" + return semver_index.parse(version) + + def coarse_version(self, version): + """Coarse version. + + Treats version as dot-separated integers. + Trims prerelease/build suffixes to ensure monotonicity + (e.g. 1.0.0-rc1 < 1.0.0). + """ + # Make sure the version is valid before trying to make it coarse. try: - return semver_index.parse(version) - except ValueError: - # If a user gives us an unparsable semver version, - # treat it as a very large version so as to not match anything. - return semver_index.parse('9999999999') + semver_index.parse(version) + except ValueError as e: + raise ValueError(f'Invalid version: {version}') from e + if version[0] == 'v': + version = version[1:] + return coarse_version_generic( + version, + separators_regex=r'[.]', + truncate_regex=r'[-+]', + implicit_split=True, + empty_as=None) class SemverEcosystem(SemverLike): diff --git a/osv/ecosystems/semver_ecosystem_helper_test.py b/osv/ecosystems/semver_ecosystem_helper_test.py index 0f1cd85e35e..a40df45e7a0 100644 --- a/osv/ecosystems/semver_ecosystem_helper_test.py +++ b/osv/ecosystems/semver_ecosystem_helper_test.py @@ -38,3 +38,28 @@ def test_sort_key(self): ecosystem = semver_ecosystem_helper.SemverLike('') # Check the 0 sentinel value self.assertLess(ecosystem.sort_key('0'), ecosystem.sort_key('0.0.0-0.0')) + + # Check invalid version + invalid_key = ecosystem.sort_key('invalid') + valid_key = ecosystem.sort_key('1.0.0') + # Invalid versions should be greater than valid versions + self.assertLess(valid_key, invalid_key) + self.assertGreater(invalid_key, valid_key) + # Invalid versions should be equal to other invalid versions (for stability) + self.assertEqual(invalid_key, ecosystem.sort_key('also-invalid')) + + def test_coarse_version(self): + """Test coarse_version""" + ecosystem = semver_ecosystem_helper.SemverLike('') + self.assertEqual('00:00000000.00000000.00000000', + ecosystem.coarse_version('0')) + self.assertEqual('00:00000001.00000002.00000003', + ecosystem.coarse_version('1.2.3')) + self.assertEqual('00:00000010.00000020.00000030', + ecosystem.coarse_version('10.20.30-alpha.1')) + self.assertEqual('00:00000000.00000002.00000000', + ecosystem.coarse_version('0.2.0+a')) + self.assertEqual('00:00000000.00000000.00000099', + ecosystem.coarse_version('0.0.99-pre+b')) + self.assertEqual('00:00000002.99999999.99999999', + ecosystem.coarse_version('2.100000000.1')) diff --git a/osv/ecosystems/ubuntu.py b/osv/ecosystems/ubuntu.py index 5dffbbbe9fa..66fd42f0ac9 100644 --- a/osv/ecosystems/ubuntu.py +++ b/osv/ecosystems/ubuntu.py @@ -11,17 +11,9 @@ # 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. -"""Ubuntu ecosystem helper.""" +"""Ubuntu ecosystem helper. (DEPRECATED)""" -from ..third_party.univers.debian import Version as UbuntuVersion +from .debian import DPKG -from .ecosystems_base import OrderedEcosystem - - -class Ubuntu(OrderedEcosystem): - """Ubuntu ecosystem""" - - def _sort_key(self, version): - if not UbuntuVersion.is_valid(version): - return UbuntuVersion(9999999999, '9999999999') - return UbuntuVersion.from_string(version) +# DEPRECATED +Ubuntu = DPKG diff --git a/osv/ecosystems/ubuntu_test.py b/osv/ecosystems/ubuntu_test.py deleted file mode 100644 index 9ac4685e27d..00000000000 --- a/osv/ecosystems/ubuntu_test.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2025 Google LLC -# -# 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. -"""Ubuntu ecosystem helper tests.""" - -import unittest -from .. import ecosystems - - -class UbuntuEcosystemTest(unittest.TestCase): - """Ubuntu ecosystem helper tests.""" - - def test_ubuntu(self): - """Test sort_key""" - ecosystem = ecosystems.get('Ubuntu') - self.assertGreater( - ecosystem.sort_key('2.42.8+dfsg-1ubuntu0.3'), - ecosystem.sort_key('2.40.0+dfsg-3ubuntu0.5')) - self.assertGreater( - ecosystem.sort_key('2.42.8+dfsg-1ubuntu0.3'), - ecosystem.sort_key('2.42.8+dfsg-1ubuntu0.2')) - self.assertGreater(ecosystem.sort_key('5.4.13-1'), ecosystem.sort_key('0')) - - # Check the 0 sentinel value. - self.assertLess(ecosystem.sort_key('0'), ecosystem.sort_key('0:0~0-0')) - - self.assertGreater( - ecosystem.sort_key('5.4.13-1'), ecosystem.sort_key('3.2.30-1')) - self.assertGreater( - ecosystem.sort_key('invalid'), ecosystem.sort_key('3.2.30-1')) - # Check >= / <= methods - self.assertGreaterEqual( - ecosystem.sort_key('2.10.8+dfsg-1ubuntu0.3'), - ecosystem.sort_key('2.2.8+dfsg-1ubuntu0.3')) - self.assertLessEqual( - ecosystem.sort_key('2.2.8+dfsg-1ubuntu0.3'), - ecosystem.sort_key('2.10.8+dfsg-1ubuntu0.3')) diff --git a/osv/models.py b/osv/models.py index b46c85c33f2..0473bc13fa3 100644 --- a/osv/models.py +++ b/osv/models.py @@ -29,6 +29,11 @@ # pylint: disable=relative-beyond-top-level from . import bug from . import ecosystems +from .ecosystems.ecosystems_base import ( + coarse_version_from_ints, + MAX_COARSE_PART, + MAX_COARSE_EPOCH, +) from . import gcs from . import pubsub from . import purl_helpers @@ -40,6 +45,10 @@ _MAX_GIT_VERSIONS_TO_INDEX = 5000 +MIN_COARSE_VERSION = coarse_version_from_ints((0,), 0) +MAX_COARSE_VERSION = coarse_version_from_ints((MAX_COARSE_PART + 1,), + MAX_COARSE_EPOCH + 1) + _EVENT_ORDER = { 'introduced': 0, 'last_affected': 1, @@ -72,7 +81,7 @@ def _check_valid_event_type(prop, value): raise ValueError('Invalid event type: ' + value) -def utcnow(): +def utcnow() -> datetime.datetime: """For mocking.""" return datetime.datetime.now(datetime.UTC) @@ -951,7 +960,6 @@ class Vulnerability(ndb.Model): # When this record was truly last modified (including e.g. aliases/upstream). modified: datetime.datetime = ndb.DateTimeProperty(tzinfo=datetime.UTC) # Whether this record has been withdrawn - # TODO(michaelkedar): I don't think this is necessary is_withdrawn: bool = ndb.BooleanProperty() # Raw fields from the original source. @@ -999,6 +1007,13 @@ class AffectedVersions(ndb.Model): events: list[AffectedEvent] = ndb.LocalStructuredProperty( AffectedEvent, repeated=True) + # Coarse, string-comparable version bounds + # for pre-filtering affected versions. + # minimum: 00:00000000.00000000.00000000 + # maximum: 99:99999999.99999999.99999999 + coarse_min: str = ndb.StringProperty() + coarse_max: str = ndb.StringProperty() + def sort_key(self): """Key function for comparison and deduplication.""" return (self.vuln_id, self.ecosystem, self.name, tuple(self.versions), @@ -1124,8 +1139,6 @@ def populate_entities_from_bug(entity: Bug): include_source=True, include_alias=True, include_upstream=True) def transaction(): - to_put = [] - to_delete = [] vuln = Vulnerability.get_by_id(entity.db_id) if vuln is None: vuln = Vulnerability(id=entity.db_id) @@ -1137,23 +1150,7 @@ def transaction(): vuln.alias_raw = entity.aliases vuln.related_raw = entity.related vuln.upstream_raw = entity.upstream_raw - to_put.append(vuln) - - old_affected = AffectedVersions.query( - AffectedVersions.vuln_id == entity.db_id).fetch() - if vuln.is_withdrawn: - # We do not want the vuln to be searchable if it's been withdrawn. - to_delete.append(ndb.Key(ListedVulnerability, vuln_pb.id)) - to_delete.extend(av.key for av in old_affected) - else: - to_put.append(ListedVulnerability.from_vulnerability(vuln_pb)) - new_affected = affected_from_bug(entity) - added, removed = diff_affected_versions(old_affected, new_affected) - to_put.extend(added) - to_delete.extend(r.key for r in removed) - - ndb.put_multi(to_put) - ndb.delete_multi(to_delete) + put_entities(vuln, vuln_pb) ndb.transaction(transaction) try: @@ -1165,92 +1162,187 @@ def transaction(): pubsub.publish_failure(data, type='gcs_retry') -def affected_from_bug(entity: Bug) -> list[AffectedVersions]: - """Compute the AffectedVersions from a Bug entity.""" +def put_entities(ds_vuln: Vulnerability, + vuln_pb: vulnerability_pb2.Vulnerability): + """Puts entities (Vulnerability, ListedVulnerability, AffectedVersions) from + a given Vulnerability entity and proto into Datastore. + + Does not write to GCS.""" + to_put = [ds_vuln] + to_delete = [] + old_affected = AffectedVersions.query( + AffectedVersions.vuln_id == vuln_pb.id).fetch() + if ds_vuln.is_withdrawn: + to_delete.append(ndb.Key(ListedVulnerability, vuln_pb.id)) + to_delete.extend(av.key for av in old_affected) + else: + to_put.append(ListedVulnerability.from_vulnerability(vuln_pb)) + new_affected = affected_from_proto(vuln_pb) + added, removed = diff_affected_versions(old_affected, new_affected) + to_put.extend(added) + to_delete.extend(r.key for r in removed) + + ndb.put_multi(to_put) + ndb.delete_multi(to_delete) + + +def _get_coarse_min_max(events: list[AffectedEvent], + e_helper: ecosystems.OrderedEcosystem, + db_id: str) -> tuple[str, str]: + """Get coarse min and max from sorted events.""" + coarse_min = MIN_COARSE_VERSION + coarse_max = MAX_COARSE_VERSION + try: + # Find the lowest introduced event for coarse min + # (in case, for some reason, the first event is not introduced) + for e in events: + if e.type == 'introduced': + coarse_min = e_helper.coarse_version(e.value) + # Only if we found an introduced version, update coarse_max + # And only if the range is bounded. + last = events[-1] + if last.type != 'introduced': + coarse_max = e_helper.coarse_version(last.value) + break + except NotImplementedError: + # Coarse versioning not yet implemented for this ecosystem. + pass + except ValueError: + logging.warning('Invalid version in %s %s', db_id, events) + coarse_min = MIN_COARSE_VERSION + coarse_max = MAX_COARSE_VERSION + + return coarse_min, coarse_max + + +def _affected_versions_from_affected_proto( + affected: vulnerability_pb2.Affected, db_id: str) -> list[AffectedVersions]: + """Compute AffectedVersions for a single affected package.""" affected_versions = [] - for affected in entity.affected_packages: - pkg_ecosystem = affected.package.ecosystem - # Make sure we capture all possible ecosystem variants for matching. - # e.g. {'Ubuntu:22.04:LTS', 'Ubuntu:22.04', 'Ubuntu'} - all_pkg_ecosystems = {pkg_ecosystem, ecosystems.normalize(pkg_ecosystem)} - if (e := ecosystems.remove_variants(pkg_ecosystem)) is not None: - all_pkg_ecosystems.add(e) - - pkg_name = ecosystems.maybe_normalize_package_names(affected.package.name, - pkg_ecosystem) - - # Ecosystem helper for sorting the events. - e_helper = ecosystems.get(pkg_ecosystem) - # TODO(michaelkedar): I am matching the current behaviour of the API, - # where GIT tags match to the first git repo in the ranges list, even if - # there are non-git ranges or multiple git repos in a range. - repo_url = '' - pkg_has_affected = False - for r in affected.ranges: - if r.type == 'GIT': - if not repo_url: - repo_url = r.repo_url - continue - if r.type not in ('SEMVER', 'ECOSYSTEM'): - logging.warning('Unknown range type "%s" in %s', r.type, entity.db_id) - continue - events = r.events - if not events: - continue - pkg_has_affected = True - if e_helper is not None: - # If we have an ecosystem helper sort the events to help with querying. - events.sort(key=lambda e, sort_key=e_helper.sort_key: - (sort_key(e.value), _EVENT_ORDER.get(e.type, -1))) - # If we don't have an ecosystem helper, assume the events are in order. - for e in all_pkg_ecosystems: - affected_versions.append( - AffectedVersions( - vuln_id=entity.db_id, - ecosystem=e, - name=pkg_name, - events=events, - )) - - # Add the enumerated versions - # We need at least a package name to perform matching. - if pkg_name and affected.versions: - pkg_has_affected = True - for e in all_pkg_ecosystems: - affected_versions.append( - AffectedVersions( - vuln_id=entity.db_id, - ecosystem=e, - name=pkg_name, - versions=affected.versions, - )) - if pkg_name and not pkg_has_affected: - # We have a package that does not have any affected ranges or versions, - # which doesn't really make sense. - # Add an empty AffectedVersions entry so that this vuln is returned when - # querying the API with no version specified. - logging.warning('Vuln has empty affected ranges and versions: %s, %s/%s', - entity.db_id, pkg_ecosystem, pkg_name) - for e in all_pkg_ecosystems: - affected_versions.append( - AffectedVersions( - vuln_id=entity.db_id, - ecosystem=e, - name=pkg_name, - )) - - if repo_url: - # If we have a repository, always add a GIT entry. - # Even if affected.versions is empty, we still want to return this vuln - # for the API queries with no versions specified. + pkg_ecosystem = affected.package.ecosystem + # Make sure we capture all possible ecosystem variants for matching. + # e.g. {'Ubuntu:22.04:LTS', 'Ubuntu:22.04', 'Ubuntu'} + all_pkg_ecosystems = {pkg_ecosystem, ecosystems.normalize(pkg_ecosystem)} + if (e := ecosystems.remove_variants(pkg_ecosystem)) is not None: + all_pkg_ecosystems.add(e) + + pkg_name = ecosystems.maybe_normalize_package_names(affected.package.name, + pkg_ecosystem) + + # Ecosystem helper for sorting the events. + e_helper = ecosystems.get(pkg_ecosystem) + # TODO(michaelkedar): I am matching the current behaviour of the API, + # where GIT tags match to the first git repo in the ranges list, even if + # there are non-git ranges or multiple git repos in a range. + repo_url = '' + pkg_has_affected = False + for r in affected.ranges: + if r.type == vulnerability_pb2.Range.Type.GIT: + if not repo_url: + repo_url = r.repo + continue + if r.type not in (vulnerability_pb2.Range.Type.SEMVER, + vulnerability_pb2.Range.Type.ECOSYSTEM): + logging.warning('Unknown range type "%d" in %s', r.type, db_id) + continue + if not r.events: + continue + events = [] + for e in r.events: + if e.introduced: + events.append(AffectedEvent(type='introduced', value=e.introduced)) + elif e.fixed: + events.append(AffectedEvent(type='fixed', value=e.fixed)) + elif e.limit: + events.append(AffectedEvent(type='limit', value=e.limit)) + elif e.last_affected: + events.append( + AffectedEvent(type='last_affected', value=e.last_affected)) + pkg_has_affected = True + coarse_min = MIN_COARSE_VERSION + coarse_max = MAX_COARSE_VERSION + if e_helper is not None: + # If we have an ecosystem helper sort the events to help with querying. + events.sort(key=lambda e, sort_key=e_helper.sort_key: + (sort_key(e.value), _EVENT_ORDER.get(e.type, -1))) + coarse_min, coarse_max = _get_coarse_min_max(events, e_helper, db_id) + + # If we don't have an ecosystem helper, assume the events are in order. + for e in all_pkg_ecosystems: affected_versions.append( AffectedVersions( - vuln_id=entity.db_id, - ecosystem='GIT', - name=normalize_repo_package(repo_url), - versions=affected.versions, + vuln_id=db_id, + ecosystem=e, + name=pkg_name, + coarse_min=coarse_min, + coarse_max=coarse_max, + events=events, )) + # Add the enumerated versions + # We need at least a package name to perform matching. + if pkg_name and affected.versions: + pkg_has_affected = True + coarse_min = MIN_COARSE_VERSION + coarse_max = MAX_COARSE_VERSION + if e_helper is not None: + try: + all_coarse = [e_helper.coarse_version(v) for v in affected.versions] + coarse_min = min(all_coarse) + coarse_max = max(all_coarse) + except NotImplementedError: + # Coarse versioning not yet implemented for this ecosystem. + pass + except ValueError: + logging.warning('Invalid version in %s', db_id) + for e in all_pkg_ecosystems: + affected_versions.append( + AffectedVersions( + vuln_id=db_id, + ecosystem=e, + name=pkg_name, + versions=list(affected.versions), + coarse_min=coarse_min, + coarse_max=coarse_max, + )) + if pkg_name and not pkg_has_affected: + # We have a package that does not have any affected ranges or versions, + # which doesn't really make sense. + # Add an empty AffectedVersions entry so that this vuln is returned when + # querying the API with no version specified. + logging.warning('Vuln has empty affected ranges and versions: %s, %s/%s', + db_id, pkg_ecosystem, pkg_name) + for e in all_pkg_ecosystems: + affected_versions.append( + AffectedVersions( + vuln_id=db_id, + ecosystem=e, + name=pkg_name, + )) + + if repo_url: + # If we have a repository, always add a GIT entry. + # Even if affected.versions is empty, we still want to return this vuln + # for the API queries with no versions specified. + affected_versions.append( + AffectedVersions( + vuln_id=db_id, + ecosystem='GIT', + name=normalize_repo_package(repo_url), + versions=list(affected.versions), + )) + + return affected_versions + + +def affected_from_proto( + vuln_pb: vulnerability_pb2.Vulnerability) -> list[AffectedVersions]: + """Compute the AffectedVersions from a Vulnerability proto.""" + affected_versions = [] + for affected in vuln_pb.affected: + affected_versions.extend( + _affected_versions_from_affected_proto(affected, vuln_pb.id)) + # Deduplicate and sort the affected_versions unique_affected_dict = {av.sort_key(): av for av in affected_versions} affected_versions = sorted( diff --git a/osv/models_test.py b/osv/models_test.py index 87c54a59b5a..371a0006bc5 100644 --- a/osv/models_test.py +++ b/osv/models_test.py @@ -192,12 +192,16 @@ def test_bug_post_put(self): events=[ models.AffectedEvent(type='introduced', value='0'), models.AffectedEvent(type='fixed', value='1.0.0-3') - ]), + ], + coarse_min=models.MIN_COARSE_VERSION, + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='Ubuntu', name='test', - versions=['1.0.0-1', '1.0.0-2']), + versions=['1.0.0-1', '1.0.0-2'], + coarse_min='00:00000001.00000000.00000000', + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='Ubuntu:24.04', @@ -205,12 +209,16 @@ def test_bug_post_put(self): events=[ models.AffectedEvent(type='introduced', value='0'), models.AffectedEvent(type='fixed', value='1.0.0-3') - ]), + ], + coarse_min=models.MIN_COARSE_VERSION, + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='Ubuntu:24.04', name='test', - versions=['1.0.0-1', '1.0.0-2']), + versions=['1.0.0-1', '1.0.0-2'], + coarse_min='00:00000001.00000000.00000000', + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='Ubuntu:24.04:LTS', @@ -218,12 +226,16 @@ def test_bug_post_put(self): events=[ models.AffectedEvent(type='introduced', value='0'), models.AffectedEvent(type='fixed', value='1.0.0-3') - ]), + ], + coarse_min=models.MIN_COARSE_VERSION, + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='Ubuntu:24.04:LTS', name='test', - versions=['1.0.0-1', '1.0.0-2']), + versions=['1.0.0-1', '1.0.0-2'], + coarse_min='00:00000001.00000000.00000000', + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='Ubuntu:25.04', @@ -231,12 +243,16 @@ def test_bug_post_put(self): events=[ models.AffectedEvent(type='introduced', value='0'), models.AffectedEvent(type='fixed', value='1.0.0-3') - ]), + ], + coarse_min=models.MIN_COARSE_VERSION, + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='Ubuntu:25.04', name='test', - versions=['1.0.0-1', '1.0.0-2']), + versions=['1.0.0-1', '1.0.0-2'], + coarse_min='00:00000001.00000000.00000000', + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='npm', @@ -244,7 +260,9 @@ def test_bug_post_put(self): events=[ models.AffectedEvent(type='introduced', value='0'), models.AffectedEvent(type='fixed', value='1.0.0') - ]), + ], + coarse_min=models.MIN_COARSE_VERSION, + coarse_max='00:00000001.00000000.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='npm', @@ -252,12 +270,16 @@ def test_bug_post_put(self): events=[ models.AffectedEvent(type='introduced', value='2.0.0'), models.AffectedEvent(type='last_affected', value='2.2.0') - ]), + ], + coarse_min='00:00000002.00000000.00000000', + coarse_max='00:00000002.00000002.00000000'), models.AffectedVersions( vuln_id=vuln_id, ecosystem='npm', name='testjs', - versions=['0.1.0', '0.2.0', '0.3.0', '2.0.0', '2.1.0', '2.2.0']), + versions=['0.1.0', '0.2.0', '0.3.0', '2.0.0', '2.1.0', '2.2.0'], + coarse_min='00:00000000.00000001.00000000', + coarse_max='00:00000002.00000002.00000000'), ] self.assertListEqual([a.to_dict() for a in want], [a.to_dict() for a in affected]) diff --git a/osv/osv-schema b/osv/osv-schema index 88c48750dda..fe5c3a64c8f 160000 --- a/osv/osv-schema +++ b/osv/osv-schema @@ -1 +1 @@ -Subproject commit 88c48750ddae8c47a59fc8412c72ebb885d0bdc3 +Subproject commit fe5c3a64c8f43962c7821a38a9d57770a0a0ddb1 diff --git a/osv/purl_helpers.py b/osv/purl_helpers.py index a44be1b8bb0..d9fc5690df2 100644 --- a/osv/purl_helpers.py +++ b/osv/purl_helpers.py @@ -48,6 +48,8 @@ EcosystemPURL('deb', 'echo'), 'Debian': EcosystemPURL('deb', 'debian'), + 'Docker Hardened Images': + EcosystemPURL('dhi', None), # GHC # GIT # GitHub Actions @@ -70,6 +72,8 @@ EcosystemPURL('npm', None), 'NuGet': EcosystemPURL('nuget', None), + 'opam': + EcosystemPURL('opam', None), 'openEuler': EcosystemPURL('rpm', 'openeuler'), 'openSUSE': @@ -87,8 +91,9 @@ EcosystemPURL('rpm', 'redhat'), 'Rocky Linux': EcosystemPURL('rpm', 'rocky-linux'), - 'Root': - EcosystemPURL('generic', 'root'), + # Note: Root ecosystem does not generate PURLs as Root packages are not + # published to public registries (npm, PyPI, Maven Central, etc.). + # Users can query Root vulnerabilities using ecosystem and package name. 'RubyGems': EcosystemPURL('gem', None), 'SUSE': @@ -142,8 +147,10 @@ def package_to_purl(ecosystem: str, package_name: str) -> str | None: 'BellSoft Hardened Containers'): suffix = '?arch=source' - # Encode package name: preserve '/' only when no namespace is defined - safe_chars = '' if purl_namespace else '/' + # Encode package name: preserve '/' in specific cases + # - When no namespace is defined + # - For maven type (uses / to separate group ID and artifact ID) + safe_chars = '' if (purl_namespace and purl_type != 'maven') else '/' encoded_name = quote(package_name, safe=safe_chars) return f'pkg:{purl_ecosystem}/{encoded_name}{suffix}' diff --git a/osv/purl_helpers_test.py b/osv/purl_helpers_test.py index 10130d39da3..f0abe5c681e 100644 --- a/osv/purl_helpers_test.py +++ b/osv/purl_helpers_test.py @@ -98,6 +98,32 @@ def tests_package_to_purl(self): self.assertEqual('pkg:hex/acme/foo', purl_helpers.package_to_purl('Hex', 'acme/foo')) + # Root ecosystem does not generate PURLs + # Root packages are not published to public registries + self.assertIsNone( + purl_helpers.package_to_purl('Root:Alpine:3.18', 'rootio-curl')) + self.assertIsNone( + purl_helpers.package_to_purl('Root:Debian:12', 'rootio-curl')) + self.assertIsNone( + purl_helpers.package_to_purl('Root:Ubuntu:22.04', 'rootio-curl')) + self.assertIsNone( + purl_helpers.package_to_purl('Root:PyPI', 'rootio-requests')) + self.assertIsNone( + purl_helpers.package_to_purl('Root:npm', '@rootio/lodash')) + self.assertIsNone( + purl_helpers.package_to_purl('Root:Maven', 'io.root.example:mylib')) + self.assertIsNone(purl_helpers.package_to_purl('Root', 'root-nginx')) + + def test_root_purl_no_generation(self): + """Test that Root ecosystem does not generate PURLs.""" + # Root packages should return None as they're not in public registries + self.assertIsNone( + purl_helpers.package_to_purl('Root:Alpine:3.18', 'rootio-curl')) + self.assertIsNone( + purl_helpers.package_to_purl('Root:Debian:12', 'rootio-curl')) + self.assertIsNone( + purl_helpers.package_to_purl('Root:Ubuntu:22.04', 'rootio-curl')) + self.assertEqual('pkg:julia/Example', purl_helpers.package_to_purl('Julia', 'Example')) @@ -134,12 +160,6 @@ def tests_package_to_purl(self): 'pkg:rpm/rocky-linux/test-package', purl_helpers.package_to_purl('Rocky Linux', 'test-package')) - self.assertEqual('pkg:generic/root/root-nginx', - purl_helpers.package_to_purl('Root', 'root-nginx')) - - self.assertEqual('pkg:generic/root/%40root%2Flodash', - purl_helpers.package_to_purl('Root', '@root/lodash')) - self.assertEqual('pkg:gem/test-package', purl_helpers.package_to_purl('RubyGems', 'test-package')) @@ -291,14 +311,6 @@ def test_parse_purl(self): ('Rocky Linux', 'test-package', '1.2.3'), purl_helpers.parse_purl('pkg:rpm/rocky-linux/test-package@1.2.3')) - self.assertEqual( - ('Root', 'root-nginx', '1.0.0-r10071'), - purl_helpers.parse_purl('pkg:generic/root/root-nginx@1.0.0-r10071')) - - self.assertEqual( - ('Root', '@root/lodash', '4.17.21'), - purl_helpers.parse_purl('pkg:generic/root/%40root%2Flodash@4.17.21')) - self.assertEqual(('RubyGems', 'test-package', '1.2.3'), purl_helpers.parse_purl('pkg:gem/test-package@1.2.3')) diff --git a/osv/repos.py b/osv/repos.py index 78da8c93292..03a29e159c4 100644 --- a/osv/repos.py +++ b/osv/repos.py @@ -115,9 +115,18 @@ class RepoInaccessibleError(Exception): """Git repository cannot be cloned due to being deleted or requiring auth.""" +def open_repo(checkout_dir): + try: + repo = pygit2.Repository(checkout_dir) + except: + repo = pygit2.Repository(checkout_dir, pygit2.enums.RepositoryOpenFlag.BARE) + return repo + + def clone(git_url, checkout_dir, git_callbacks=None, blobless=False): """Perform a clone.""" # Don't user Gitter for oss-fuzz-vulns repo because it requires auth + logging.info('Cloning %s to %s.', git_url, checkout_dir) if GITTER_HOST and git_url != 'ssh://github.com/google/oss-fuzz-vulns': try: os.makedirs(checkout_dir, exist_ok=True) @@ -132,17 +141,21 @@ def clone(git_url, checkout_dir, git_callbacks=None, blobless=False): if resp.status_code == 400: raise GitCloneError(f'Failed to clone repo: {resp.text}') - resp.raise_for_status() - - with open(f'{checkout_dir}.zst', 'wb') as f: - shutil.copyfileobj(resp.raw, f) - - cmd = ['tar', '-xf', f'{checkout_dir}.zst', '-C', checkout_dir] - subprocess.run(cmd, check=True) - # Remove after extraction. - os.remove(f'{checkout_dir}.zst') - - return pygit2.Repository(checkout_dir) + # If return is successful write out the repo, otherwise fall back to + # original cloning method + if resp.status_code == 200: + with open(f'{checkout_dir}.zst', 'wb') as f: + shutil.copyfileobj(resp.raw, f) + + cmd = ['tar', '-xf', f'{checkout_dir}.zst', '-C', checkout_dir] + subprocess.run(cmd, check=True) + # Remove after extraction. + os.remove(f'{checkout_dir}.zst') + + return open_repo(checkout_dir) + logging.error( + 'Failed to clone repo through gitter, ' + 'status: %d, response: %s', resp.status_code, resp.text) except requests.RequestException as e: raise GitCloneError(f'Failed to clone repo: {e}') from e except subprocess.CalledProcessError as e: @@ -158,7 +171,7 @@ def clone(git_url, checkout_dir, git_callbacks=None, blobless=False): cmd.append('--filter=blob:none') cmd.extend([_git_mirror(git_url), checkout_dir]) subprocess.run(cmd, env=env, capture_output=True, check=True) - return pygit2.Repository(checkout_dir) + return open_repo(checkout_dir) except subprocess.CalledProcessError as e: stderr = e.stderr.decode(errors='ignore') if ('could not read Username' in stderr or @@ -205,7 +218,7 @@ def _use_existing_checkout(git_url, git_callbacks=None, branch=None): """Update and use existing checkout.""" - repo = pygit2.Repository(checkout_dir) + repo = open_repo(checkout_dir) repo.cache = {} if repo.remotes['origin'].url != _git_mirror(git_url): # The URL in the code is the source of truth, diff --git a/osv/semver_index.py b/osv/semver_index.py index b8a4f5040ba..83c10e584ab 100644 --- a/osv/semver_index.py +++ b/osv/semver_index.py @@ -61,7 +61,7 @@ def _coerce_suffix(suffix): for component in match.group(1)[1:].split('.'): if not component: pre_components.append('-') - elif component.isdigit(): + elif component.isdecimal(): pre_components.append(_remove_leading_zero(component)) else: pre_components.append(component) @@ -156,7 +156,7 @@ def normalize_prerelease(prerelease): # # Normalization: Pad numeric components with '0', and prefix alphanumeric # with a single '1' (to ensure they always come after). - if component.isdigit(): + if component.isdecimal(): # 1. Identifiers consisting of only digits are compared numerically. pre_components.append(component.rjust(_PAD_WIDTH, '0')) else: diff --git a/osv/sources.py b/osv/sources.py index f6fe6e98156..8dde830fac1 100644 --- a/osv/sources.py +++ b/osv/sources.py @@ -90,7 +90,7 @@ def remove_implicit_resolver(cls, tag_to_remove): NoDatesSafeLoader.remove_implicit_resolver('tag:yaml.org,2002:timestamp') -def _parse_vulnerability_dict(path): +def _parse_vulnerability_dict(path: str) -> dict: """Parse a vulnerability file into a dict.""" with open(path) as f: ext = os.path.splitext(path)[1] @@ -106,7 +106,7 @@ def _parse_vulnerability_dict(path): @cache.cached(shared_cache) -def load_schema(): +def load_schema() -> dict: path = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'osv-schema', 'validation', 'schema.json') @@ -115,13 +115,18 @@ def load_schema(): return json.loads(text) -def parse_vulnerability(path, key_path=None, strict=False): +def parse_vulnerability(path: str, + key_path=None, + strict=False) -> vulnerability_pb2.Vulnerability: """Parse vulnerability YAML/JSON.""" data = _parse_vulnerability_dict(path) return parse_vulnerability_from_dict(data, key_path, strict) -def _parse_vulnerabilities(data, key_path, strict=False): +def _parse_vulnerabilities( + data: dict | list[dict], + key_path, + strict=False) -> list[vulnerability_pb2.Vulnerability]: """Parse multiple vulnerabilities.""" if isinstance(data, list): return [parse_vulnerability_from_dict(v, key_path, strict) for v in data] @@ -129,16 +134,20 @@ def _parse_vulnerabilities(data, key_path, strict=False): return [parse_vulnerability_from_dict(data, key_path, strict)] -def parse_vulnerabilities(path, key_path=None, strict=False): +def parse_vulnerabilities( + path: str, + key_path=None, + strict=False) -> list[vulnerability_pb2.Vulnerability]: """Parse vulnerabilities (potentially multiple in a list).""" return _parse_vulnerabilities( _parse_vulnerability_dict(path), key_path, strict) -def parse_vulnerabilities_from_data(data_text, - extension, - key_path=None, - strict=False): +def parse_vulnerabilities_from_data( + data_text: str | bytes, + extension: str, + key_path=None, + strict=False) -> list[vulnerability_pb2.Vulnerability]: """Parse vulnerabilities from data.""" if extension in YAML_EXTENSIONS: data = yaml.load(data_text, Loader=NoDatesSafeLoader) @@ -150,7 +159,7 @@ def parse_vulnerabilities_from_data(data_text, return _parse_vulnerabilities(data, key_path, strict) -def _get_nested_vulnerability(data, key_path=None): +def _get_nested_vulnerability(data: dict, key_path=None) -> dict: """Get nested vulnerability.""" if key_path: try: @@ -162,7 +171,10 @@ def _get_nested_vulnerability(data, key_path=None): return data -def parse_vulnerability_from_dict(data, key_path=None, strict=False): +def parse_vulnerability_from_dict(data: dict, + key_path=None, + strict=False + ) -> vulnerability_pb2.Vulnerability: """Parse vulnerability from dict.""" data = _get_nested_vulnerability(data, key_path) try: @@ -195,7 +207,8 @@ class YamlDumper(yaml.SafeDumper): YamlDumper.add_representer(str, _yaml_str_representer) -def vulnerability_to_dict(vulnerability): +def vulnerability_to_dict( + vulnerability: vulnerability_pb2.Vulnerability) -> dict: """Convert Vulnerability to a dict.""" result = json_format.MessageToDict( vulnerability, preserving_proto_field_name=True) @@ -215,7 +228,7 @@ def vulnerability_to_dict(vulnerability): return result -def _write_vulnerability_dict(data, output_path, +def _write_vulnerability_dict(data: dict, output_path: str, modified_date_timestamp: float): """Write a vulnerability dict to disk.""" with open(output_path, 'w') as f: @@ -231,7 +244,7 @@ def _write_vulnerability_dict(data, output_path, def write_vulnerability(vulnerability: vulnerability_pb2.Vulnerability, - output_path, + output_path: str, key_path=None): """Update a vulnerability file on disk.""" if os.path.exists(output_path): diff --git a/osv/third_party/univers/alpine.py b/osv/third_party/univers/alpine.py index 16ae54def5f..8491399cf70 100644 --- a/osv/third_party/univers/alpine.py +++ b/osv/third_party/univers/alpine.py @@ -20,28 +20,29 @@ class InvalidVersion(ValueError): def is_valid_alpine_version(s: str): """ Return True is the string `s` is a valid Alpine version. - We do not support yet version strings that start with + We do support version strings that start with non-significant zeros. For example: >>> is_valid_alpine_version("006") - False + True >>> is_valid_alpine_version("1.2.3") True >>> is_valid_alpine_version("02-r1") True """ search = AlpineLinuxVersion.version_extractor.search(s) - if not search: - return False - - s = search.group(1) - left, _, _ = s.partition(".") - # handle the suffix case - left, _, _ = left.partition("-") - if not left.isdigit(): - return True - i = int(left) - return str(i) == left + return bool(search) + # if not search: + # return False + + # s = search.group(1) + # left, _, _ = s.partition(".") + # # handle the suffix case + # left, _, _ = left.partition("-") + # if not left.isdecimal(): + # return True + # i = int(left) + # return str(i) == left @attr.s(frozen=True, order=False, hash=True) diff --git a/osv/third_party/univers/debian.py b/osv/third_party/univers/debian.py index ae90c596d0e..209a1af90c0 100644 --- a/osv/third_party/univers/debian.py +++ b/osv/third_party/univers/debian.py @@ -357,7 +357,7 @@ def get_digit_prefix(characters): Return the digit prefix from a list of characters. """ value = 0 - while characters and characters[0].isdigit(): + while characters and characters[0].isdecimal(): value = value * 10 + int(characters.pop(0)) return value @@ -367,7 +367,7 @@ def get_non_digit_prefix(characters): Return the non-digit prefix from a list of characters. """ prefix = [] - while characters and not characters[0].isdigit(): + while characters and not characters[0].isdecimal(): prefix.append(characters.pop(0)) return prefix diff --git a/osv/third_party/univers/gem.py b/osv/third_party/univers/gem.py index b59d32aafb1..b0d5d0d4b27 100644 --- a/osv/third_party/univers/gem.py +++ b/osv/third_party/univers/gem.py @@ -292,7 +292,7 @@ def prerelease(self): Return True if this is considered as a prerelease version. A version is considered a prerelease if it contains a letter. """ - return any(not str(s).isdigit() for s in self.segments) + return any(not str(s).isdecimal() for s in self.segments) @property def segments(self): @@ -312,7 +312,7 @@ def get_segments(self): find_segments = re.compile(r"[0-9]+|[a-z]+", re.IGNORECASE).findall segments = [] for seg in find_segments(self.version): - if seg.isdigit(): + if seg.isdecimal(): seg = int(seg) segments.append(seg) return tuple(segments) diff --git a/osv/third_party/univers/gentoo.py b/osv/third_party/univers/gentoo.py index 1d875a98df3..32752687b9d 100644 --- a/osv/third_party/univers/gentoo.py +++ b/osv/third_party/univers/gentoo.py @@ -39,6 +39,9 @@ def parse_version_and_revision(version_string): revision = int(match.group(1)[2:]) version = version_string[:match.span(1)[0]] + # strip leading 0's from the first component only + version = re.sub(r"^0+(\d)", r"\1", version) + return version, revision diff --git a/poetry.lock b/poetry.lock index d2a77cbe0d8..67e06723783 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "astroid" @@ -24,18 +24,6 @@ files = [ {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] -[[package]] -name = "cachetools" -version = "6.2.4" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "cachetools-6.2.4-py3-none-any.whl", hash = "sha256:69a7a52634fed8b8bf6e24a050fb60bff1c9bd8f6d24572b99c32d4e71e62a51"}, - {file = "cachetools-6.2.4.tar.gz", hash = "sha256:82c5c05585e70b6ba2d3ae09ea60b79548872185d2f24ae1f2709d37299fd607"}, -] - [[package]] name = "certifi" version = "2026.1.4" @@ -281,16 +269,93 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "cryptography" +version = "46.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, + {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, + {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, + {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, + {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, + {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, + {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, + {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, + {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, + {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, + {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, +] + +[package.dependencies] +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" description = "serialize all of Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, - {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, ] [package.extras] @@ -299,26 +364,26 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "google-api-core" -version = "2.28.1" +version = "2.29.0" description = "Google API client core library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c"}, - {file = "google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8"}, + {file = "google_api_core-2.29.0-py3-none-any.whl", hash = "sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9"}, + {file = "google_api_core-2.29.0.tar.gz", hash = "sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7"}, ] [package.dependencies] google-auth = ">=2.14.1,<3.0.0" googleapis-common-protos = ">=1.56.2,<2.0.0" grpcio = [ - {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, {version = ">=1.75.1,<2.0.0", optional = true, markers = "python_version >= \"3.14\" and extra == \"grpc\""}, + {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\" and python_version < \"3.14\""}, ] grpcio-status = [ - {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, {version = ">=1.75.1,<2.0.0", optional = true, markers = "python_version >= \"3.14\" and extra == \"grpc\""}, + {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, ] proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" @@ -332,50 +397,50 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] [[package]] name = "google-auth" -version = "2.45.0" +version = "2.48.0" description = "Google Authentication Library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "google_auth-2.45.0-py2.py3-none-any.whl", hash = "sha256:82344e86dc00410ef5382d99be677c6043d72e502b625aa4f4afa0bdacca0f36"}, - {file = "google_auth-2.45.0.tar.gz", hash = "sha256:90d3f41b6b72ea72dd9811e765699ee491ab24139f34ebf1ca2b9cc0c38708f3"}, + {file = "google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f"}, + {file = "google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce"}, ] [package.dependencies] -cachetools = ">=2.0.0,<7.0" +cryptography = ">=38.0.3" pyasn1-modules = ">=0.2.1" rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] -cryptography = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)"] -enterprise-cert = ["cryptography", "pyopenssl"] -pyjwt = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyjwt (>=2.0)"] -pyopenssl = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +cryptography = ["cryptography (>=38.0.3)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0)"] -testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "mock", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] urllib3 = ["packaging", "urllib3"] [[package]] name = "google-cloud-appengine-logging" -version = "1.7.0" +version = "1.8.0" description = "Google Cloud Appengine Logging API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_appengine_logging-1.7.0-py3-none-any.whl", hash = "sha256:cfd28bc61a030008381a646d112ebe2734bf72abc8c12afc47d035a2c9b041fe"}, - {file = "google_cloud_appengine_logging-1.7.0.tar.gz", hash = "sha256:ea9ce73430cfc99f8957fd7df97733f9a759d4caab65e19d63a7474f012ffd94"}, + {file = "google_cloud_appengine_logging-1.8.0-py3-none-any.whl", hash = "sha256:a4ce9ce94a9fd8c89ed07fa0b06fcf9ea3642f9532a1be1a8c7b5f82c0a70ec6"}, + {file = "google_cloud_appengine_logging-1.8.0.tar.gz", hash = "sha256:84b705a69e4109fc2f68dfe36ce3df6a34d5c3d989eee6d0ac1b024dda0ba6f5"}, ] [package.dependencies] google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras = ["grpc"]} google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" grpcio = [ - {version = ">=1.33.2,<2.0.0"}, {version = ">=1.75.1,<2.0.0", markers = "python_version >= \"3.14\""}, + {version = ">=1.33.2,<2.0.0"}, ] proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" @@ -432,8 +497,8 @@ google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0" google-cloud-core = ">=1.4.0,<3.0.0" grpcio = [ - {version = ">=1.38.0,<2.0.0"}, {version = ">=1.75.1,<2.0.0", markers = "python_version >= \"3.14\""}, + {version = ">=1.38.0,<2.0.0"}, ] proto-plus = {version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""} protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" @@ -501,8 +566,8 @@ google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras google-auth = ">=2.14.1,<3.0.0" grpc-google-iam-v1 = ">=0.12.4,<1.0.0" grpcio = [ - {version = ">=1.51.3,<2.0.0", markers = "python_version < \"3.14\""}, {version = ">=1.75.1,<2.0.0", markers = "python_version >= \"3.14\""}, + {version = ">=1.51.3,<2.0.0", markers = "python_version < \"3.14\""}, ] grpcio-status = ">=1.33.2" opentelemetry-api = {version = ">=1.27.0", markers = "python_version >= \"3.8\""} @@ -515,14 +580,14 @@ libcst = ["libcst (>=0.3.10)"] [[package]] name = "google-cloud-storage" -version = "3.7.0" +version = "3.8.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_storage-3.7.0-py3-none-any.whl", hash = "sha256:469bc9540936e02f8a4bfd1619e9dca1e42dec48f95e4204d783b36476a15093"}, - {file = "google_cloud_storage-3.7.0.tar.gz", hash = "sha256:9ce59c65f4d6e372effcecc0456680a8d73cef4f2dc9212a0704799cb3d69237"}, + {file = "google_cloud_storage-3.8.0-py3-none-any.whl", hash = "sha256:78cfeae7cac2ca9441d0d0271c2eb4ebfa21aa4c6944dd0ccac0389e81d955a7"}, + {file = "google_cloud_storage-3.8.0.tar.gz", hash = "sha256:cc67952dce84ebc9d44970e24647a58260630b7b64d72360cedaf422d6727f28"}, ] [package.dependencies] @@ -806,6 +871,39 @@ grpcio = ">=1.76.0" protobuf = ">=6.31.1,<7.0.0" setuptools = "*" +[[package]] +name = "hypothesis" +version = "6.151.2" +description = "The property-based testing library for Python" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "hypothesis-6.151.2-py3-none-any.whl", hash = "sha256:909d2b5f0dc80640561bb2c3859f3c56a52ed8d1cc589e5e6450362ced8c31a0"}, + {file = "hypothesis-6.151.2.tar.gz", hash = "sha256:fc91f88a77074b31c7ab871eebab3d2e0210fd3095f1d1ecbd9440c1c6bc06d9"}, +] + +[package.dependencies] +sortedcontainers = ">=2.1.0,<3.0.0" + +[package.extras] +all = ["black (>=20.8b0)", "click (>=7.0)", "crosshair-tool (>=0.0.102)", "django (>=4.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.27)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.21.6)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2025.3) ; sys_platform == \"win32\" or sys_platform == \"emscripten\"", "watchdog (>=4.0.0)"] +cli = ["black (>=20.8b0)", "click (>=7.0)", "rich (>=9.0.0)"] +codemods = ["libcst (>=0.3.16)"] +crosshair = ["crosshair-tool (>=0.0.102)", "hypothesis-crosshair (>=0.0.27)"] +dateutil = ["python-dateutil (>=1.4)"] +django = ["django (>=4.2)"] +dpcontracts = ["dpcontracts (>=0.4)"] +ghostwriter = ["black (>=20.8b0)"] +lark = ["lark (>=0.10.1)"] +numpy = ["numpy (>=1.21.6)"] +pandas = ["pandas (>=1.1)"] +pytest = ["pytest (>=4.6)"] +pytz = ["pytz (>=2014.1)"] +redis = ["redis (>=3.0.0)"] +watchdog = ["watchdog (>=4.0.0)"] +zoneinfo = ["tzdata (>=2025.3) ; sys_platform == \"win32\" or sys_platform == \"emscripten\""] + [[package]] name = "idna" version = "3.11" @@ -863,21 +961,21 @@ plugins = ["setuptools"] [[package]] name = "jsonschema" -version = "4.25.1" +version = "4.26.0" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, - {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, ] [package.dependencies] attrs = ">=22.2.0" jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" -rpds-py = ">=0.7.1" +rpds-py = ">=0.25.0" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -912,14 +1010,14 @@ files = [ [[package]] name = "mypy-protobuf" -version = "3.7.0" +version = "5.0.0" description = "Generate mypy stub files from protobuf specs" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "mypy_protobuf-3.7.0-py3-none-any.whl", hash = "sha256:85256e9d4da935722ce8fbaa8d19397e1a2989aa8075c96577987de9fe7cea4d"}, - {file = "mypy_protobuf-3.7.0.tar.gz", hash = "sha256:912fb281f7c7b3e3a7c9b8695712618a716fddbab70f6ad63eaf68eda80c5efe"}, + {file = "mypy_protobuf-5.0.0-py3-none-any.whl", hash = "sha256:3a7dd753ef3e3b8783a824eb51f07983f62812f9ec066e4fbb1b22d6c5dc36d0"}, + {file = "mypy_protobuf-5.0.0.tar.gz", hash = "sha256:6fdd1cfdbb4419c713291d800a332d4bba6510dbd1341ed95e0bcc82fcadb6b5"}, ] [package.dependencies] @@ -995,14 +1093,14 @@ test = ["pytest"] [[package]] name = "packaging" -version = "25.0" +version = "26.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, ] [[package]] @@ -1057,34 +1155,34 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "6.33.2" +version = "6.33.4" description = "" optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d"}, - {file = "protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4"}, - {file = "protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f"}, - {file = "protobuf-6.33.2-cp39-cp39-win32.whl", hash = "sha256:7109dcc38a680d033ffb8bf896727423528db9163be1b6a02d6a49606dcadbfe"}, - {file = "protobuf-6.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:2981c58f582f44b6b13173e12bb8656711189c2a70250845f264b877f00b1913"}, - {file = "protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c"}, - {file = "protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4"}, + {file = "protobuf-6.33.4-cp310-abi3-win32.whl", hash = "sha256:918966612c8232fc6c24c78e1cd89784307f5814ad7506c308ee3cf86662850d"}, + {file = "protobuf-6.33.4-cp310-abi3-win_amd64.whl", hash = "sha256:8f11ffae31ec67fc2554c2ef891dcb561dae9a2a3ed941f9e134c2db06657dbc"}, + {file = "protobuf-6.33.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2fe67f6c014c84f655ee06f6f66213f9254b3a8b6bda6cda0ccd4232c73c06f0"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:757c978f82e74d75cba88eddec479df9b99a42b31193313b75e492c06a51764e"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c7c64f259c618f0bef7bee042075e390debbf9682334be2b67408ec7c1c09ee6"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:3df850c2f8db9934de4cf8f9152f8dc2558f49f298f37f90c517e8e5c84c30e9"}, + {file = "protobuf-6.33.4-cp39-cp39-win32.whl", hash = "sha256:955478a89559fa4568f5a81dce77260eabc5c686f9e8366219ebd30debf06aa6"}, + {file = "protobuf-6.33.4-cp39-cp39-win_amd64.whl", hash = "sha256:0f12ddbf96912690c3582f9dffb55530ef32015ad8e678cd494312bd78314c4f"}, + {file = "protobuf-6.33.4-py3-none-any.whl", hash = "sha256:1fe3730068fcf2e595816a6c34fe66eeedd37d51d0400b72fabc848811fdc1bc"}, + {file = "protobuf-6.33.4.tar.gz", hash = "sha256:dc2e61bca3b10470c1912d166fe0af67bfc20eb55971dcef8dfa48ce14f0ed91"}, ] [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, - {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, + {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"}, + {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"}, ] [[package]] @@ -1104,15 +1202,15 @@ pyasn1 = ">=0.6.1,<0.7.0" [[package]] name = "pycparser" -version = "2.23" +version = "3.0" description = "C parser in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] markers = "implementation_name != \"PyPy\"" files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, ] [[package]] @@ -1525,14 +1623,14 @@ files = [ [[package]] name = "setuptools" -version = "80.9.0" +version = "80.10.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, - {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, + {file = "setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173"}, + {file = "setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70"}, ] [package.extras] @@ -1544,16 +1642,28 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] +[[package]] +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, +] + [[package]] name = "tomlkit" -version = "0.13.3" +version = "0.14.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, ] [[package]] @@ -1582,14 +1692,14 @@ files = [ [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] @@ -1775,4 +1885,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.13,<4.0" -content-hash = "c09baabd568a3e965aac12a39b2e95eb2dfbca5ed1bdfec61a5f47dec30313d9" +content-hash = "3caf0812744d2d7e8a05bae891d3573aba444ae59f1d71d4f3d9e67f969e67cf" diff --git a/pyproject.toml b/pyproject.toml index 97b7947dd5d..371bbc838a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,8 +29,9 @@ dependencies = [ yapf = "*" pylint = "*" grpcio-tools = "*" -mypy-protobuf = "^3.6.0" +mypy-protobuf = "^5.0.0" vcrpy = "*" +hypothesis = "*" [tool.pyright] executionEnvironments = [ diff --git a/renovate.json b/renovate.json index 17787551015..ea29028fb0a 100644 --- a/renovate.json +++ b/renovate.json @@ -31,7 +31,7 @@ "matchUpdateTypes": [ "major" ], - "enabled": false + "enabled": true }, { "matchDepNames": [ @@ -43,19 +43,7 @@ "matchFileNames": [ "gcp/website/**" ], - "matchCategories": [ - "python" - ], - "groupName": "website-backend" - }, - { - "matchFileNames": [ - "gcp/website/**" - ], - "matchCategories": [ - "js" - ], - "groupName": "website-frontend" + "groupName": "website" }, { "matchFileNames": [ @@ -68,33 +56,12 @@ }, { "matchFileNames": [ - "gcp/api/**" - ], - "groupName": "api" - }, - { - "matchFileNames": [ - "gcp/functions/**" - ], - "groupName": "functions" - }, - { - "matchFileNames": [ - "gcp/workers/**" - ], - "matchCategories": [ - "python" - ], - "groupName": "workers" - }, - { - "matchFileNames": [ + "gcp/api/**", + "gcp/functions/**", + "gcp/workers/**", "gcp/indexer/**" ], - "matchCategories": [ - "golang" - ], - "groupName": "indexer" + "groupName": "gcp-services" }, { "matchFileNames": [ @@ -141,6 +108,40 @@ ], "enabled": false }, + { + "matchDatasources": [ + "docker" + ], + "groupName": "docker" + }, + { + "matchFileNames": [ + "docker/**" + ], + "groupName": "docker" + }, + { + "matchManagers": [ + "git-submodules" + ], + "groupName": "submodules" + }, + { + "matchDatasources": [ + "git-refs" + ], + "groupName": "submodules" + }, + { + "matchFileNames": [ + "bindings/**", + "go/**" + ], + "matchCategories": [ + "golang" + ], + "groupName": "go-libraries" + }, { "matchDepTypes": ["uses-with"], "enabled": false diff --git a/run_tests.sh b/run_tests.sh index a37f84d6718..43b6cc19c44 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,6 +1,9 @@ #!/bin/bash -ex -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python -m unittest osv.bug_test poetry run python -m unittest osv.purl_helpers_test poetry run python -m unittest osv.request_helper_test diff --git a/source.yaml b/source.yaml index 9131af96fe3..ed5804861d8 100644 --- a/source.yaml +++ b/source.yaml @@ -141,7 +141,7 @@ bucket: 'cve-osv-conversion' db_prefix: ['CVE-'] ignore_git: False - human_link: 'https://nvd.nist.gov/vuln/detail/{{ BUG_ID }}' + human_link: 'https://cve.org/CVERecord?id={{ BUG_ID }}' link: 'https://storage.googleapis.com/cve-osv-conversion/' editable: False strict_validation: True diff --git a/source_test.yaml b/source_test.yaml index dfc162ef2f5..4dcc793856a 100644 --- a/source_test.yaml +++ b/source_test.yaml @@ -141,7 +141,7 @@ bucket: 'osv-test-cve-osv-conversion' db_prefix: ['CVE-'] ignore_git: False - human_link: 'https://nvd.nist.gov/vuln/detail/{{ BUG_ID }}' + human_link: 'https://cve.org/CVERecord?id={{ BUG_ID }}' link: 'https://storage.googleapis.com/osv-test-cve-osv-conversion/' editable: False strict_validation: True @@ -352,6 +352,21 @@ editable: False strict_validation: True +- name: 'opam' + versions_from_repo: False + type: 0 + ignore_patterns: ['^(?!OSEC-).*$'] + repo_branch: 'generated-osv' + repo_url: 'https://github.com/ocaml/security-advisories.git' + detect_cherrypicks: False + extension: '.json' + db_prefix: ['OSEC-'] + ignore_git: False + link: 'https://github.com/ocaml/security-advisories/blob/generated-osv/' + editable: False + repo_username: 'git' + strict_validation: True + - name: 'openeuler' versions_from_repo: False rest_api_url: 'https://repo.openeuler.org/security/data/osv/all.json' diff --git a/tools/apitester/README.md b/tools/apitester/README.md index 6b7d142f140..719ae68737a 100644 --- a/tools/apitester/README.md +++ b/tools/apitester/README.md @@ -46,4 +46,5 @@ Before the test suite is actually run, the cassettes will be "cleaned" so that - the `response` is property is not present, to reduce the size of each cassette By default, requests are made against the local instance of the API, but you can -use the `OSV_API_BASE_URL` to point it against other instances. +use the `OSV_API_BASE_URL` to point it against other instances. +E.g. `OSV_API_BASE_URL=api.test.osv.dev go test ./...` diff --git a/tools/apitester/__snapshots__/cassette_TestCommand.snap b/tools/apitester/__snapshots__/cassette_TestCommand.snap index 59066590159..208c0e4bda7 100755 --- a/tools/apitester/__snapshots__/cassette_TestCommand.snap +++ b/tools/apitester/__snapshots__/cassette_TestCommand.snap @@ -61,35 +61,35 @@ "vulns": [ { "id": "GO-2024-2598", - "modified": "" + "modified": "" }, { "id": "GO-2024-2599", - "modified": "" + "modified": "" }, { "id": "GO-2024-2600", - "modified": "" + "modified": "" }, { "id": "GO-2024-2609", - "modified": "" + "modified": "" }, { "id": "GO-2024-2610", - "modified": "" + "modified": "" }, { "id": "GO-2024-2687", - "modified": "" + "modified": "" }, { "id": "GO-2024-2887", - "modified": "" + "modified": "" }, { "id": "GO-2024-2888", - "modified": "" + "modified": "" }, { "id": "GO-2024-2963", @@ -117,7 +117,7 @@ }, { "id": "GO-2025-3447", - "modified": "" + "modified": "" }, { "id": "GO-2025-3563", @@ -133,51 +133,51 @@ }, { "id": "GO-2025-3849", - "modified": "" + "modified": "" }, { "id": "GO-2025-3956", - "modified": "" + "modified": "" }, { "id": "GO-2025-4006", - "modified": "" + "modified": "" }, { "id": "GO-2025-4007", - "modified": "" + "modified": "" }, { "id": "GO-2025-4008", - "modified": "" + "modified": "" }, { "id": "GO-2025-4009", - "modified": "" + "modified": "" }, { "id": "GO-2025-4010", - "modified": "" + "modified": "" }, { "id": "GO-2025-4011", - "modified": "" + "modified": "" }, { "id": "GO-2025-4012", - "modified": "" + "modified": "" }, { "id": "GO-2025-4013", - "modified": "" + "modified": "" }, { "id": "GO-2025-4014", - "modified": "" + "modified": "" }, { "id": "GO-2025-4015", - "modified": "" + "modified": "" }, { "id": "GO-2025-4155", @@ -201,35 +201,35 @@ "vulns": [ { "id": "GO-2024-2598", - "modified": "" + "modified": "" }, { "id": "GO-2024-2599", - "modified": "" + "modified": "" }, { "id": "GO-2024-2600", - "modified": "" + "modified": "" }, { "id": "GO-2024-2609", - "modified": "" + "modified": "" }, { "id": "GO-2024-2610", - "modified": "" + "modified": "" }, { "id": "GO-2024-2687", - "modified": "" + "modified": "" }, { "id": "GO-2024-2887", - "modified": "" + "modified": "" }, { "id": "GO-2024-2888", - "modified": "" + "modified": "" }, { "id": "GO-2024-2963", @@ -257,7 +257,7 @@ }, { "id": "GO-2025-3447", - "modified": "" + "modified": "" }, { "id": "GO-2025-3563", @@ -273,51 +273,51 @@ }, { "id": "GO-2025-3849", - "modified": "" + "modified": "" }, { "id": "GO-2025-3956", - "modified": "" + "modified": "" }, { "id": "GO-2025-4006", - "modified": "" + "modified": "" }, { "id": "GO-2025-4007", - "modified": "" + "modified": "" }, { "id": "GO-2025-4008", - "modified": "" + "modified": "" }, { "id": "GO-2025-4009", - "modified": "" + "modified": "" }, { "id": "GO-2025-4010", - "modified": "" + "modified": "" }, { "id": "GO-2025-4011", - "modified": "" + "modified": "" }, { "id": "GO-2025-4012", - "modified": "" + "modified": "" }, { "id": "GO-2025-4013", - "modified": "" + "modified": "" }, { "id": "GO-2025-4014", - "modified": "" + "modified": "" }, { "id": "GO-2025-4015", - "modified": "" + "modified": "" }, { "id": "GO-2025-4155", @@ -333,35 +333,35 @@ "vulns": [ { "id": "GO-2024-2598", - "modified": "" + "modified": "" }, { "id": "GO-2024-2599", - "modified": "" + "modified": "" }, { "id": "GO-2024-2600", - "modified": "" + "modified": "" }, { "id": "GO-2024-2609", - "modified": "" + "modified": "" }, { "id": "GO-2024-2610", - "modified": "" + "modified": "" }, { "id": "GO-2024-2687", - "modified": "" + "modified": "" }, { "id": "GO-2024-2887", - "modified": "" + "modified": "" }, { "id": "GO-2024-2888", - "modified": "" + "modified": "" }, { "id": "GO-2024-2963", @@ -389,7 +389,7 @@ }, { "id": "GO-2025-3447", - "modified": "" + "modified": "" }, { "id": "GO-2025-3563", @@ -405,51 +405,51 @@ }, { "id": "GO-2025-3849", - "modified": "" + "modified": "" }, { "id": "GO-2025-3956", - "modified": "" + "modified": "" }, { "id": "GO-2025-4006", - "modified": "" + "modified": "" }, { "id": "GO-2025-4007", - "modified": "" + "modified": "" }, { "id": "GO-2025-4008", - "modified": "" + "modified": "" }, { "id": "GO-2025-4009", - "modified": "" + "modified": "" }, { "id": "GO-2025-4010", - "modified": "" + "modified": "" }, { "id": "GO-2025-4011", - "modified": "" + "modified": "" }, { "id": "GO-2025-4012", - "modified": "" + "modified": "" }, { "id": "GO-2025-4013", - "modified": "" + "modified": "" }, { "id": "GO-2025-4014", - "modified": "" + "modified": "" }, { "id": "GO-2025-4015", - "modified": "" + "modified": "" }, { "id": "GO-2025-4155", @@ -473,35 +473,35 @@ "vulns": [ { "id": "GO-2024-2598", - "modified": "" + "modified": "" }, { "id": "GO-2024-2599", - "modified": "" + "modified": "" }, { "id": "GO-2024-2600", - "modified": "" + "modified": "" }, { "id": "GO-2024-2609", - "modified": "" + "modified": "" }, { "id": "GO-2024-2610", - "modified": "" + "modified": "" }, { "id": "GO-2024-2687", - "modified": "" + "modified": "" }, { "id": "GO-2024-2887", - "modified": "" + "modified": "" }, { "id": "GO-2024-2888", - "modified": "" + "modified": "" }, { "id": "GO-2024-2963", @@ -529,7 +529,7 @@ }, { "id": "GO-2025-3447", - "modified": "" + "modified": "" }, { "id": "GO-2025-3563", @@ -545,51 +545,51 @@ }, { "id": "GO-2025-3849", - "modified": "" + "modified": "" }, { "id": "GO-2025-3956", - "modified": "" + "modified": "" }, { "id": "GO-2025-4006", - "modified": "" + "modified": "" }, { "id": "GO-2025-4007", - "modified": "" + "modified": "" }, { "id": "GO-2025-4008", - "modified": "" + "modified": "" }, { "id": "GO-2025-4009", - "modified": "" + "modified": "" }, { "id": "GO-2025-4010", - "modified": "" + "modified": "" }, { "id": "GO-2025-4011", - "modified": "" + "modified": "" }, { "id": "GO-2025-4012", - "modified": "" + "modified": "" }, { "id": "GO-2025-4013", - "modified": "" + "modified": "" }, { "id": "GO-2025-4014", - "modified": "" + "modified": "" }, { "id": "GO-2025-4015", - "modified": "" + "modified": "" }, { "id": "GO-2025-4155", @@ -887,7 +887,7 @@ "vulns": [ { "id": "UBUNTU-CVE-2017-11164", - "modified": "" + "modified": "" } ] } @@ -903,7 +903,7 @@ "vulns": [ { "id": "UBUNTU-CVE-2017-11164", - "modified": "" + "modified": "" } ] } @@ -1307,6 +1307,10 @@ "id": "DEBIAN-CVE-2024-12133", "modified": "" }, + { + "id": "DEBIAN-CVE-2025-13151", + "modified": "" + }, { "id": "DLA-3263-1", "modified": "" @@ -1487,10 +1491,6 @@ "id": "DEBIAN-CVE-2024-56171", "modified": "" }, - { - "id": "DEBIAN-CVE-2025-12863", - "modified": "" - }, { "id": "DEBIAN-CVE-2025-24928", "modified": "" @@ -1529,7 +1529,19 @@ }, { "id": "DEBIAN-CVE-2025-9714", - "modified": "" + "modified": "" + }, + { + "id": "DEBIAN-CVE-2026-0989", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2026-0990", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2026-0992", + "modified": "" }, { "id": "DLA-3012-1", @@ -1815,7 +1827,7 @@ }, { "id": "DEBIAN-CVE-2024-13176", - "modified": "" + "modified": "" }, { "id": "DEBIAN-CVE-2024-2511", @@ -1841,6 +1853,22 @@ "id": "DEBIAN-CVE-2024-9143", "modified": "" }, + { + "id": "DEBIAN-CVE-2025-11187", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-15467", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-15468", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-15469", + "modified": "" + }, { "id": "DEBIAN-CVE-2025-27587", "modified": "" @@ -1849,6 +1877,30 @@ "id": "DEBIAN-CVE-2025-4575", "modified": "" }, + { + "id": "DEBIAN-CVE-2025-66199", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-68160", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-69418", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-69419", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-69420", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2025-69421", + "modified": "" + }, { "id": "DEBIAN-CVE-2025-9230", "modified": "" @@ -1861,6 +1913,14 @@ "id": "DEBIAN-CVE-2025-9232", "modified": "" }, + { + "id": "DEBIAN-CVE-2026-22795", + "modified": "" + }, + { + "id": "DEBIAN-CVE-2026-22796", + "modified": "" + }, { "id": "DLA-3008-1", "modified": "" @@ -1952,6 +2012,10 @@ { "id": "DSA-6015-1", "modified": "" + }, + { + "id": "DSA-6113-1", + "modified": "" } ] }, @@ -1960,7 +2024,7 @@ "vulns": [ { "id": "UBUNTU-CVE-2017-11164", - "modified": "" + "modified": "" } ] }, @@ -2359,51 +2423,51 @@ "vulns": [ { "id": "GO-2025-3849", - "modified": "" + "modified": "" }, { "id": "GO-2025-3956", - "modified": "" + "modified": "" }, { "id": "GO-2025-4006", - "modified": "" + "modified": "" }, { "id": "GO-2025-4007", - "modified": "" + "modified": "" }, { "id": "GO-2025-4008", - "modified": "" + "modified": "" }, { "id": "GO-2025-4009", - "modified": "" + "modified": "" }, { "id": "GO-2025-4010", - "modified": "" + "modified": "" }, { "id": "GO-2025-4011", - "modified": "" + "modified": "" }, { "id": "GO-2025-4012", - "modified": "" + "modified": "" }, { "id": "GO-2025-4013", - "modified": "" + "modified": "" }, { "id": "GO-2025-4014", - "modified": "" + "modified": "" }, { "id": "GO-2025-4015", - "modified": "" + "modified": "" }, { "id": "GO-2025-4155", @@ -2419,7 +2483,7 @@ "vulns": [ { "id": "GO-2025-3828", - "modified": "" + "modified": "" } ] } @@ -2928,11 +2992,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -2940,11 +3004,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -2952,11 +3016,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -2964,11 +3028,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -3012,11 +3076,11 @@ "vulns": [ { "id": "GHSA-jjg7-2v4v-x38h", - "modified": "" + "modified": "" }, { "id": "PYSEC-2024-60", - "modified": "" + "modified": "" } ] }, @@ -3024,11 +3088,11 @@ "vulns": [ { "id": "GHSA-jjg7-2v4v-x38h", - "modified": "" + "modified": "" }, { "id": "PYSEC-2024-60", - "modified": "" + "modified": "" } ] }, @@ -3062,19 +3126,19 @@ "vulns": [ { "id": "GHSA-9hjg-9r4m-mvj7", - "modified": "" + "modified": "" }, { "id": "GHSA-9wx4-h78v-vm56", - "modified": "" + "modified": "" }, { "id": "GHSA-j8r2-6x86-q33q", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-74", - "modified": "" + "modified": "" } ] }, @@ -3082,19 +3146,19 @@ "vulns": [ { "id": "GHSA-9hjg-9r4m-mvj7", - "modified": "" + "modified": "" }, { "id": "GHSA-9wx4-h78v-vm56", - "modified": "" + "modified": "" }, { "id": "GHSA-j8r2-6x86-q33q", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-74", - "modified": "" + "modified": "" } ] }, @@ -3105,27 +3169,31 @@ "vulns": [ { "id": "GHSA-2xpw-w6gg-jr37", - "modified": "" + "modified": "" }, { "id": "GHSA-34jh-p97f-mpxf", - "modified": "" + "modified": "" + }, + { + "id": "GHSA-38jv-5279-wg99", + "modified": "" }, { "id": "GHSA-g4mx-q9vg-27p4", - "modified": "" + "modified": "" }, { "id": "GHSA-gm62-xv2j-4w53", - "modified": "" + "modified": "" }, { "id": "GHSA-pq67-6m6q-mj2v", - "modified": "" + "modified": "" }, { "id": "GHSA-v845-jxx5-vc9f", - "modified": "" + "modified": "" }, { "id": "GHSA-wqvq-5m8c-6g24", @@ -3141,11 +3209,11 @@ }, { "id": "PYSEC-2023-192", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-212", - "modified": "" + "modified": "" } ] }, @@ -3153,27 +3221,31 @@ "vulns": [ { "id": "GHSA-2xpw-w6gg-jr37", - "modified": "" + "modified": "" }, { "id": "GHSA-34jh-p97f-mpxf", - "modified": "" + "modified": "" + }, + { + "id": "GHSA-38jv-5279-wg99", + "modified": "" }, { "id": "GHSA-g4mx-q9vg-27p4", - "modified": "" + "modified": "" }, { "id": "GHSA-gm62-xv2j-4w53", - "modified": "" + "modified": "" }, { "id": "GHSA-pq67-6m6q-mj2v", - "modified": "" + "modified": "" }, { "id": "GHSA-v845-jxx5-vc9f", - "modified": "" + "modified": "" }, { "id": "GHSA-wqvq-5m8c-6g24", @@ -3189,35 +3261,47 @@ }, { "id": "PYSEC-2023-192", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-212", - "modified": "" + "modified": "" } ] }, { "vulns": [ + { + "id": "GHSA-87hc-h4r5-73f7", + "modified": "" + }, { "id": "GHSA-hgf8-39gv-g3f2", - "modified": "" + "modified": "" } ] }, { "vulns": [ + { + "id": "GHSA-87hc-h4r5-73f7", + "modified": "" + }, { "id": "GHSA-hgf8-39gv-g3f2", - "modified": "" + "modified": "" } ] }, { "vulns": [ + { + "id": "GHSA-87hc-h4r5-73f7", + "modified": "" + }, { "id": "GHSA-hgf8-39gv-g3f2", - "modified": "" + "modified": "" } ] } @@ -3406,11 +3490,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -3418,11 +3502,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -3430,11 +3514,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -3442,11 +3526,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -3490,11 +3574,11 @@ "vulns": [ { "id": "GHSA-jjg7-2v4v-x38h", - "modified": "" + "modified": "" }, { "id": "PYSEC-2024-60", - "modified": "" + "modified": "" } ] }, @@ -3502,11 +3586,11 @@ "vulns": [ { "id": "GHSA-jjg7-2v4v-x38h", - "modified": "" + "modified": "" }, { "id": "PYSEC-2024-60", - "modified": "" + "modified": "" } ] }, @@ -3540,19 +3624,19 @@ "vulns": [ { "id": "GHSA-9hjg-9r4m-mvj7", - "modified": "" + "modified": "" }, { "id": "GHSA-9wx4-h78v-vm56", - "modified": "" + "modified": "" }, { "id": "GHSA-j8r2-6x86-q33q", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-74", - "modified": "" + "modified": "" } ] }, @@ -3560,19 +3644,19 @@ "vulns": [ { "id": "GHSA-9hjg-9r4m-mvj7", - "modified": "" + "modified": "" }, { "id": "GHSA-9wx4-h78v-vm56", - "modified": "" + "modified": "" }, { "id": "GHSA-j8r2-6x86-q33q", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-74", - "modified": "" + "modified": "" } ] }, @@ -3583,27 +3667,31 @@ "vulns": [ { "id": "GHSA-2xpw-w6gg-jr37", - "modified": "" + "modified": "" }, { "id": "GHSA-34jh-p97f-mpxf", - "modified": "" + "modified": "" + }, + { + "id": "GHSA-38jv-5279-wg99", + "modified": "" }, { "id": "GHSA-g4mx-q9vg-27p4", - "modified": "" + "modified": "" }, { "id": "GHSA-gm62-xv2j-4w53", - "modified": "" + "modified": "" }, { "id": "GHSA-pq67-6m6q-mj2v", - "modified": "" + "modified": "" }, { "id": "GHSA-v845-jxx5-vc9f", - "modified": "" + "modified": "" }, { "id": "GHSA-wqvq-5m8c-6g24", @@ -3619,11 +3707,11 @@ }, { "id": "PYSEC-2023-192", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-212", - "modified": "" + "modified": "" } ] }, @@ -3631,27 +3719,31 @@ "vulns": [ { "id": "GHSA-2xpw-w6gg-jr37", - "modified": "" + "modified": "" }, { "id": "GHSA-34jh-p97f-mpxf", - "modified": "" + "modified": "" + }, + { + "id": "GHSA-38jv-5279-wg99", + "modified": "" }, { "id": "GHSA-g4mx-q9vg-27p4", - "modified": "" + "modified": "" }, { "id": "GHSA-gm62-xv2j-4w53", - "modified": "" + "modified": "" }, { "id": "GHSA-pq67-6m6q-mj2v", - "modified": "" + "modified": "" }, { "id": "GHSA-v845-jxx5-vc9f", - "modified": "" + "modified": "" }, { "id": "GHSA-wqvq-5m8c-6g24", @@ -3667,35 +3759,47 @@ }, { "id": "PYSEC-2023-192", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-212", - "modified": "" + "modified": "" } ] }, { "vulns": [ + { + "id": "GHSA-87hc-h4r5-73f7", + "modified": "" + }, { "id": "GHSA-hgf8-39gv-g3f2", - "modified": "" + "modified": "" } ] }, { "vulns": [ + { + "id": "GHSA-87hc-h4r5-73f7", + "modified": "" + }, { "id": "GHSA-hgf8-39gv-g3f2", - "modified": "" + "modified": "" } ] }, { "vulns": [ + { + "id": "GHSA-87hc-h4r5-73f7", + "modified": "" + }, { "id": "GHSA-hgf8-39gv-g3f2", - "modified": "" + "modified": "" } ] } diff --git a/tools/apitester/__snapshots__/cassette_TestCommand_CallAnalysis.snap b/tools/apitester/__snapshots__/cassette_TestCommand_CallAnalysis.snap index c7fa922010d..012857de860 100755 --- a/tools/apitester/__snapshots__/cassette_TestCommand_CallAnalysis.snap +++ b/tools/apitester/__snapshots__/cassette_TestCommand_CallAnalysis.snap @@ -6,7 +6,7 @@ "vulns": [ { "id": "GHSA-c3h9-896r-86jm", - "modified": "" + "modified": "" }, { "id": "GO-2021-0053", @@ -74,7 +74,7 @@ "vulns": [ { "id": "GHSA-c3h9-896r-86jm", - "modified": "" + "modified": "" }, { "id": "GO-2021-0053", @@ -94,7 +94,7 @@ "vulns": [ { "id": "GHSA-c3h9-896r-86jm", - "modified": "" + "modified": "" }, { "id": "GO-2021-0053", diff --git a/tools/apitester/__snapshots__/cassette_TestCommand_JavareachArchive.snap b/tools/apitester/__snapshots__/cassette_TestCommand_JavareachArchive.snap index 194e20f8c60..783c963fe76 100755 --- a/tools/apitester/__snapshots__/cassette_TestCommand_JavareachArchive.snap +++ b/tools/apitester/__snapshots__/cassette_TestCommand_JavareachArchive.snap @@ -27,7 +27,7 @@ "vulns": [ { "id": "GHSA-288c-cq4h-88gq", - "modified": "" + "modified": "" }, { "id": "GHSA-4gq5-ch57-c2mg", @@ -39,7 +39,7 @@ }, { "id": "GHSA-57j2-w4cx-62h2", - "modified": "" + "modified": "" }, { "id": "GHSA-5949-rw7g-wx7w", @@ -151,7 +151,7 @@ }, { "id": "GHSA-jjjh-jjxp-wpff", - "modified": "" + "modified": "" }, { "id": "GHSA-m6x4-97wx-4q27", @@ -195,7 +195,7 @@ }, { "id": "GHSA-rgv9-q543-rqg4", - "modified": "" + "modified": "" }, { "id": "GHSA-rpr3-cw39-3pxh", @@ -316,7 +316,7 @@ "vulns": [ { "id": "GHSA-288c-cq4h-88gq", - "modified": "" + "modified": "" }, { "id": "GHSA-4gq5-ch57-c2mg", @@ -328,7 +328,7 @@ }, { "id": "GHSA-57j2-w4cx-62h2", - "modified": "" + "modified": "" }, { "id": "GHSA-5949-rw7g-wx7w", @@ -440,7 +440,7 @@ }, { "id": "GHSA-jjjh-jjxp-wpff", - "modified": "" + "modified": "" }, { "id": "GHSA-m6x4-97wx-4q27", @@ -484,7 +484,7 @@ }, { "id": "GHSA-rgv9-q543-rqg4", - "modified": "" + "modified": "" }, { "id": "GHSA-rpr3-cw39-3pxh", diff --git a/tools/apitester/__snapshots__/cassette_TestCommand_MoreLockfiles.snap b/tools/apitester/__snapshots__/cassette_TestCommand_MoreLockfiles.snap index bc802edcf12..233fe9e22c0 100755 --- a/tools/apitester/__snapshots__/cassette_TestCommand_MoreLockfiles.snap +++ b/tools/apitester/__snapshots__/cassette_TestCommand_MoreLockfiles.snap @@ -135,9 +135,13 @@ {}, { "vulns": [ + { + "id": "GHSA-7gcm-g887-7qv7", + "modified": "" + }, { "id": "GHSA-8qvm-5x2c-j2w7", - "modified": "" + "modified": "" } ] } diff --git a/tools/apitester/__snapshots__/cassette_TestCommand_Transitive.snap b/tools/apitester/__snapshots__/cassette_TestCommand_Transitive.snap index 66c1c427573..31d87aa9714 100755 --- a/tools/apitester/__snapshots__/cassette_TestCommand_Transitive.snap +++ b/tools/apitester/__snapshots__/cassette_TestCommand_Transitive.snap @@ -51,11 +51,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -63,19 +63,19 @@ "vulns": [ { "id": "GHSA-9hjg-9r4m-mvj7", - "modified": "" + "modified": "" }, { "id": "GHSA-9wx4-h78v-vm56", - "modified": "" + "modified": "" }, { "id": "GHSA-j8r2-6x86-q33q", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-74", - "modified": "" + "modified": "" } ] } @@ -91,11 +91,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -288,11 +288,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -301,19 +301,19 @@ "vulns": [ { "id": "GHSA-9hjg-9r4m-mvj7", - "modified": "" + "modified": "" }, { "id": "GHSA-9wx4-h78v-vm56", - "modified": "" + "modified": "" }, { "id": "GHSA-j8r2-6x86-q33q", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-74", - "modified": "" + "modified": "" } ] } @@ -550,11 +550,11 @@ "vulns": [ { "id": "GHSA-m2qf-hxjv-5gpq", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-62", - "modified": "" + "modified": "" } ] }, @@ -562,11 +562,11 @@ "vulns": [ { "id": "GHSA-jjg7-2v4v-x38h", - "modified": "" + "modified": "" }, { "id": "PYSEC-2024-60", - "modified": "" + "modified": "" } ] }, @@ -578,19 +578,19 @@ "vulns": [ { "id": "GHSA-9hjg-9r4m-mvj7", - "modified": "" + "modified": "" }, { "id": "GHSA-9wx4-h78v-vm56", - "modified": "" + "modified": "" }, { "id": "GHSA-j8r2-6x86-q33q", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-74", - "modified": "" + "modified": "" } ] }, @@ -598,27 +598,31 @@ "vulns": [ { "id": "GHSA-2xpw-w6gg-jr37", - "modified": "" + "modified": "" }, { "id": "GHSA-34jh-p97f-mpxf", - "modified": "" + "modified": "" + }, + { + "id": "GHSA-38jv-5279-wg99", + "modified": "" }, { "id": "GHSA-g4mx-q9vg-27p4", - "modified": "" + "modified": "" }, { "id": "GHSA-gm62-xv2j-4w53", - "modified": "" + "modified": "" }, { "id": "GHSA-pq67-6m6q-mj2v", - "modified": "" + "modified": "" }, { "id": "GHSA-v845-jxx5-vc9f", - "modified": "" + "modified": "" }, { "id": "GHSA-wqvq-5m8c-6g24", @@ -634,19 +638,23 @@ }, { "id": "PYSEC-2023-192", - "modified": "" + "modified": "" }, { "id": "PYSEC-2023-212", - "modified": "" + "modified": "" } ] }, { "vulns": [ + { + "id": "GHSA-87hc-h4r5-73f7", + "modified": "" + }, { "id": "GHSA-hgf8-39gv-g3f2", - "modified": "" + "modified": "" } ] } diff --git a/tools/apitester/__snapshots__/cassette_single_query.snap b/tools/apitester/__snapshots__/cassette_single_query.snap index 680b407c069..389fc69a66c 100755 --- a/tools/apitester/__snapshots__/cassette_single_query.snap +++ b/tools/apitester/__snapshots__/cassette_single_query.snap @@ -82,7 +82,11 @@ { "id": "CVE-2022-33068", "details": "An integer overflow in the component hb-ot-shape-fallback.cc of Harfbuzz v4.3.0 allows attackers to cause a Denial of Service (DoS) via unspecified vectors.", - "modified": "", + "aliases": [ + "ROOT-OS-DEBIAN-11-CVE-2022-33068", + "ROOT-OS-DEBIAN-bullseye-CVE-2022-33068" + ], + "modified": "", "published": "2022-06-23T17:15:14.350Z", "related": [ "ALSA-2022:8384", @@ -163,7 +167,13 @@ { "id": "CVE-2023-25193", "details": "hb-ot-layout-gsubgpos.hh in HarfBuzz through 6.0.0 allows attackers to trigger O(n^2) growth via consecutive marks during the process of looking back for base glyphs when attaching marks.", - "modified": "", + "aliases": [ + "ROOT-OS-DEBIAN-11-CVE-2023-25193", + "ROOT-OS-DEBIAN-12-CVE-2023-25193", + "ROOT-OS-DEBIAN-bookworm-CVE-2023-25193", + "ROOT-OS-DEBIAN-bullseye-CVE-2023-25193" + ], + "modified": "", "published": "2023-02-04T20:15:08.027Z", "related": [ "ALSA-2023:4158", @@ -264,11 +274,73 @@ } ] }, + { + "id": "CVE-2026-22693", + "summary": "Null Pointer Dereference in SubtableUnicodesCache::create leading to DoS", + "details": "HarfBuzz is a text shaping engine. Prior to version 12.3.0, a null pointer dereference vulnerability exists in the SubtableUnicodesCache::create function located in src/hb-ot-cmap-table.hh. The function fails to check if hb_malloc returns NULL before using placement new to construct an object at the returned pointer address. When hb_malloc fails to allocate memory (which can occur in low-memory conditions or when using custom allocators that simulate allocation failures), it returns NULL. The code then attempts to call the constructor on this null pointer using placement new syntax, resulting in undefined behavior and a Segmentation Fault. This issue has been patched in version 12.3.0.", + "aliases": ["GHSA-xvjr-f2r9-c7ww", "ROOT-OS-DEBIAN-13-CVE-2026-22693"], + "modified": "", + "published": "2026-01-10T05:53:21.019Z", + "database_specific": "", + "references": [ + { + "type": "WEB", + "url": "http://www.openwall.com/lists/oss-security/2026/01/11/1" + }, + { + "type": "WEB", + "url": "http://www.openwall.com/lists/oss-security/2026/01/12/1" + }, + { + "type": "ADVISORY", + "url": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/22xxx/CVE-2026-22693.json" + }, + { + "type": "FIX", + "url": "https://github.com/harfbuzz/harfbuzz/commit/1265ff8d990284f04d8768f35b0e20ae5f60daae" + }, + { + "type": "ADVISORY", + "url": "https://github.com/harfbuzz/harfbuzz/security/advisories/GHSA-xvjr-f2r9-c7ww" + }, + { + "type": "ADVISORY", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-22693" + } + ], + "affected": [ + { + "ranges": [ + { + "type": "GIT", + "repo": "https://github.com/harfbuzz/harfbuzz", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "b0af59229cc233a66106c696534ac39be56093d8" + } + ] + } + ], + "versions": 206, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "severity": [ + { + "type": "CVSS_V3", + "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L" + } + ] + }, { "id": "OSV-2020-484", "summary": "Heap-buffer-overflow in AAT::KerxSubTableFormat4\u003cAAT::KerxSubTableHeader\u003e::driver_context_t::transition", "details": "OSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12532\n\n```\nCrash type: Heap-buffer-overflow READ 4\nCrash state:\nAAT::KerxSubTableFormat4\u003cAAT::KerxSubTableHeader\u003e::driver_context_t::transition\nvoid AAT::StateTableDriver\u003cAAT::ExtendedTypes, AAT::KerxSubTableFormat4\u003cAAT::Ker\nAAT::KerxSubTableFormat4\u003cAAT::KerxSubTableHeader\u003e::apply\n```\n", - "modified": "", + "modified": "", "published": "2020-07-01T00:00:12.297418Z", "references": [ { @@ -675,8 +747,12 @@ "id": "CURL-CVE-2024-9681", "summary": "HSTS subdomain overwrites parent cache entry", "details": "When curl is asked to use HSTS, the expiry time for a subdomain might\noverwrite a parent domain's cache entry, making it end sooner or later than\notherwise intended.\n\nThis affects curl using applications that enable HSTS and use URLs with the\ninsecure `HTTP://` scheme and perform transfers with hosts like\n`x.example.com` as well as `example.com` where the first host is a subdomain\nof the second host.\n\n(The HSTS cache either needs to have been populated manually or there needs to\nhave been previous HTTPS accesses done as the cache needs to have entries for\nthe domains involved to trigger this problem.)\n\nWhen `x.example.com` responds with `Strict-Transport-Security:` headers, this\nbug can make the subdomain's expiry timeout *bleed over* and get set for the\nparent domain `example.com` in curl's HSTS cache.\n\nThe result of a triggered bug is that HTTP accesses to `example.com` get\nconverted to HTTPS for a different period of time than what was asked for by\nthe origin server. If `example.com` for example stops supporting HTTPS at its\nexpiry time, curl might then fail to access `http://example.com` until the\n(wrongly set) timeout expires. This bug can also expire the parent's entry\n*earlier*, thus making curl inadvertently switch back to insecure HTTP earlier\nthan otherwise intended.", - "aliases": ["CVE-2024-9681"], - "modified": "", + "aliases": [ + "CVE-2024-9681", + "ROOT-OS-DEBIAN-11-CVE-2024-9681", + "ROOT-OS-DEBIAN-bullseye-CVE-2024-9681" + ], + "modified": "", "published": "2024-11-05T08:00:00Z", "database_specific": "", "affected": [ @@ -876,12 +952,12 @@ ] }, { - "id": "CURL-CVE-2025-5025", - "summary": "No QUIC certificate pinning with wolfSSL", - "details": "libcurl supports *pinning* of the server certificate public key for HTTPS\ntransfers. Due to an omission, this check is not performed when connecting\nwith QUIC for HTTP/3, when the TLS backend is wolfSSL.\n\nDocumentation says the option works with wolfSSL, failing to specify that it\ndoes not for QUIC and HTTP/3.\n\nSince pinning makes the transfer succeed if the pin is fine, users could\nunwittingly connect to an impostor server without noticing.", - "aliases": ["CVE-2025-5025"], - "modified": "", - "published": "2025-05-28T08:00:00Z", + "id": "CURL-CVE-2025-14017", + "summary": "broken TLS options for threaded LDAPS", + "details": "When doing multi-threaded LDAPS transfers (LDAP over TLS) with libcurl,\nchanging TLS options in one thread would inadvertently change them globally\nand therefore possibly also affect other concurrently setup transfers.\n\nDisabling certificate verification for a specific transfer could\nunintentionally disable the feature for other threads as well.", + "aliases": ["CVE-2025-14017"], + "modified": "", + "published": "2026-01-07T08:00:00Z", "database_specific": "", "affected": [ { @@ -890,10 +966,10 @@ "type": "SEMVER", "events": [ { - "introduced": "8.5.0" + "introduced": "7.17.0" }, { - "fixed": "8.14.0" + "fixed": "8.18.0" } ] }, @@ -902,37 +978,37 @@ "repo": "https://github.com/curl/curl.git", "events": [ { - "introduced": "5f78cf503c786a1d48d13528dde038bccfa6c67c" + "introduced": "ccba0d10b6baf5c73cae8cf4fb3f29f0f55c5a34" }, { - "fixed": "e1f65937a96a451292e9231339672797da86ecc5" + "fixed": "39d1976b7f709a516e3243338ebc0443bdd8d56d" } ] } ], - "versions": 14, + "versions": 143, "database_specific": "" } ], "schema_version": "1.7.3", "credits": [ { - "name": "Hiroki Kurosawa", + "name": "Stanislav Fort (Aisle Research)", "type": "FINDER" }, { - "name": "Stefan Eissing", + "name": "Daniel Stenberg", "type": "REMEDIATION_DEVELOPER" } ] }, { - "id": "CURL-CVE-2025-9086", - "summary": "Out of bounds read for cookie path", - "details": "1. A cookie is set using the `secure` keyword for `https://target`\n2. curl is redirected to or otherwise made to speak with `http://target` (same\n hostname, but using clear text HTTP) using the same cookie set\n3. The same cookie name is set - but with just a slash as path (`path=\"/\"`).\n Since this site is not secure, the cookie *should* just be ignored.\n4. A bug in the path comparison logic makes curl read outside a heap buffer\n boundary\n\nThe bug either causes a crash or it potentially makes the comparison come to\nthe wrong conclusion and lets the clear-text site override the contents of the\nsecure cookie, contrary to expectations and depending on the memory contents\nimmediately following the single-byte allocation that holds the path.\n\nThe presumed and correct behavior would be to plainly ignore the second set of\nthe cookie since it was already set as secure on a secure host so overriding\nit on an insecure host should not be okay.", - "aliases": ["CVE-2025-9086"], - "modified": "", - "published": "2025-09-10T08:00:00Z", + "id": "CURL-CVE-2025-14524", + "summary": "bearer token leak on cross-protocol redirect", + "details": "When an OAuth2 bearer token is used for an HTTP(S) transfer, and that transfer\nperforms a cross-protocol redirect to a second URL that uses an IMAP, LDAP,\nPOP3 or SMTP scheme, curl might wrongly pass on the bearer token to the new\ntarget host.", + "aliases": ["CVE-2025-14524"], + "modified": "", + "published": "2026-01-06T08:00:00Z", "database_specific": "", "affected": [ { @@ -941,10 +1017,10 @@ "type": "SEMVER", "events": [ { - "introduced": "7.31.0" + "introduced": "7.33.0" }, { - "fixed": "8.16.0" + "fixed": "8.18.0" } ] }, @@ -953,10 +1029,10 @@ "repo": "https://github.com/curl/curl.git", "events": [ { - "introduced": "f24dc09d209a2f91ca38d854f0c15ad93f3d7e2d" + "introduced": "06c1bea72faabb6fad4b7ef818aafaa336c9a7aa" }, { - "fixed": "c6ae07c6a541e0e96d0040afb62b45dd37711300" + "fixed": "1a822275d333dc6da6043497160fd04c8fa48640" } ] } @@ -968,7 +1044,58 @@ "schema_version": "1.7.3", "credits": [ { - "name": "Google Big Sleep", + "name": "anonymous237 on hackerone", + "type": "FINDER" + }, + { + "name": "Daniel Stenberg", + "type": "REMEDIATION_DEVELOPER" + } + ] + }, + { + "id": "CURL-CVE-2025-14819", + "summary": "OpenSSL partial chain store policy bypass", + "details": "When doing TLS related transfers with reused easy or multi handles and\naltering the `CURLSSLOPT_NO_PARTIALCHAIN` option, libcurl could accidentally\nreuse a CA store cached in memory for which the partial chain option was\nreversed. Contrary to the user's wishes and expectations. This could make\nlibcurl find and accept a trust chain that it otherwise would not.", + "aliases": ["CVE-2025-14819"], + "modified": "", + "published": "2026-01-07T08:00:00Z", + "database_specific": "", + "affected": [ + { + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "7.87.0" + }, + { + "fixed": "8.18.0" + } + ] + }, + { + "type": "GIT", + "repo": "https://github.com/curl/curl.git", + "events": [ + { + "introduced": "3c16697ebd796f799227be293e8689aec5f8190d" + }, + { + "fixed": "cd046f6c93b39d673a58c18648d8906e954c4f5d" + } + ] + } + ], + "versions": 31, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "credits": [ + { + "name": "Stanislav Fort (Aisle Research)", "type": "FINDER" }, { @@ -977,6 +1104,159 @@ } ] }, + { + "id": "CURL-CVE-2025-15079", + "summary": "libssh global known_hosts override", + "details": "When doing SSH-based transfers using either SCP or SFTP, and setting the\nknown_hosts file, libcurl could still mistakenly accept connecting to hosts\n*not present* in the specified file if they were added as recognized in the\nlibssh *global* known_hosts file.", + "aliases": ["CVE-2025-15079"], + "modified": "", + "published": "2026-01-07T08:00:00Z", + "database_specific": "", + "affected": [ + { + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "7.58.0" + }, + { + "fixed": "8.18.0" + } + ] + }, + { + "type": "GIT", + "repo": "https://github.com/curl/curl.git", + "events": [ + { + "introduced": "c92d2e14cfb0db662f958effd2ac86f995cf1b5a" + }, + { + "fixed": "adca486c125d9a6d9565b9607a19dce803a8b479" + } + ] + } + ], + "versions": 70, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "credits": [ + { + "name": "Harry Sintonen", + "type": "FINDER" + }, + { + "name": "Daniel Stenberg", + "type": "REMEDIATION_DEVELOPER" + } + ] + }, + { + "id": "CURL-CVE-2025-15224", + "summary": "libssh key passphrase bypass without agent set", + "details": "When doing SSH-based transfers using either SCP or SFTP, and asked to do\npublic key authentication, curl would wrongly still ask and authenticate using\na locally running SSH agent.", + "aliases": ["CVE-2025-15224"], + "modified": "", + "published": "2026-01-07T08:00:00Z", + "database_specific": "", + "affected": [ + { + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "7.58.0" + }, + { + "fixed": "8.18.0" + } + ] + }, + { + "type": "GIT", + "repo": "https://github.com/curl/curl.git", + "events": [ + { + "introduced": "c92d2e14cfb0db662f958effd2ac86f995cf1b5a" + }, + { + "fixed": "16d5f2a5660c61cc27bd5f1c7f512391d1c927aa" + } + ] + } + ], + "versions": 70, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "credits": [ + { + "name": "Harry Sintonen", + "type": "FINDER" + }, + { + "name": "Harry Sintonen", + "type": "REMEDIATION_DEVELOPER" + } + ] + }, + { + "id": "CURL-CVE-2025-5025", + "summary": "No QUIC certificate pinning with wolfSSL", + "details": "libcurl supports *pinning* of the server certificate public key for HTTPS\ntransfers. Due to an omission, this check is not performed when connecting\nwith QUIC for HTTP/3, when the TLS backend is wolfSSL.\n\nDocumentation says the option works with wolfSSL, failing to specify that it\ndoes not for QUIC and HTTP/3.\n\nSince pinning makes the transfer succeed if the pin is fine, users could\nunwittingly connect to an impostor server without noticing.", + "aliases": ["CVE-2025-5025"], + "modified": "", + "published": "2025-05-28T08:00:00Z", + "database_specific": "", + "affected": [ + { + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "8.5.0" + }, + { + "fixed": "8.14.0" + } + ] + }, + { + "type": "GIT", + "repo": "https://github.com/curl/curl.git", + "events": [ + { + "introduced": "5f78cf503c786a1d48d13528dde038bccfa6c67c" + }, + { + "fixed": "e1f65937a96a451292e9231339672797da86ecc5" + } + ] + } + ], + "versions": 14, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "credits": [ + { + "name": "Hiroki Kurosawa", + "type": "FINDER" + }, + { + "name": "Stefan Eissing", + "type": "REMEDIATION_DEVELOPER" + } + ] + }, { "id": "CVE-2024-0853", "details": "curl inadvertently kept the SSL session ID for connections in its cache even when the verify status (*OCSP stapling*) test failed. A subsequent transfer to\nthe same hostname could then succeed if the session ID cache was still fresh, which then skipped the verify status check.", @@ -1467,7 +1747,6 @@ "related": [ "ALSA-2025:1671", "ALSA-2025:1673", - "CGA-962m-89hc-rmjq", "RLSA-2025:1673", "SUSE-SU-2024:2784-1", "SUSE-SU-2024:2930-1", @@ -1546,7 +1825,6 @@ "modified": "", "published": "2024-09-11T10:15:02.883Z", "related": [ - "CGA-g55g-qx76-5fjj", "SUSE-SU-2024:3202-1", "SUSE-SU-2024:3203-1", "SUSE-SU-2024:3204-1", @@ -1610,8 +1888,12 @@ { "id": "CVE-2024-9681", "details": "When curl is asked to use HSTS, the expiry time for a subdomain might\noverwrite a parent domain's cache entry, making it end sooner or later than\notherwise intended.\n\nThis affects curl using applications that enable HSTS and use URLs with the\ninsecure `HTTP://` scheme and perform transfers with hosts like\n`x.example.com` as well as `example.com` where the first host is a subdomain\nof the second host.\n\n(The HSTS cache either needs to have been populated manually or there needs to\nhave been previous HTTPS accesses done as the cache needs to have entries for\nthe domains involved to trigger this problem.)\n\nWhen `x.example.com` responds with `Strict-Transport-Security:` headers, this\nbug can make the subdomain's expiry timeout *bleed over* and get set for the\nparent domain `example.com` in curl's HSTS cache.\n\nThe result of a triggered bug is that HTTP accesses to `example.com` get\nconverted to HTTPS for a different period of time than what was asked for by\nthe origin server. If `example.com` for example stops supporting HTTPS at its\nexpiry time, curl might then fail to access `http://example.com` until the\n(wrongly set) timeout expires. This bug can also expire the parent's entry\n*earlier*, thus making curl inadvertently switch back to insecure HTTP earlier\nthan otherwise intended.", - "aliases": ["CURL-CVE-2024-9681"], - "modified": "", + "aliases": [ + "CURL-CVE-2024-9681", + "ROOT-OS-DEBIAN-11-CVE-2024-9681", + "ROOT-OS-DEBIAN-bullseye-CVE-2024-9681" + ], + "modified": "", "published": "2024-11-06T08:15:03.740Z", "related": [ "MGASA-2024-0360", @@ -1710,6 +1992,7 @@ "modified": "", "published": "2025-02-05T10:15:22.710Z", "related": [ + "CGA-gr5c-pjrp-3fmw", "MGASA-2025-0123", "SUSE-SU-2025:0369-1", "SUSE-SU-2025:0370-1", @@ -1768,7 +2051,11 @@ "aliases": ["CURL-CVE-2025-0665"], "modified": "", "published": "2025-02-05T10:15:22.857Z", - "related": ["MGASA-2025-0123", "openSUSE-SU-2025:14809-1"], + "related": [ + "CGA-h2f8-6v5h-2qcp", + "MGASA-2025-0123", + "openSUSE-SU-2025:14809-1" + ], "references": [ { "type": "ADVISORY", @@ -1830,6 +2117,7 @@ "modified": "", "published": "2025-02-05T10:15:22.980Z", "related": [ + "CGA-378j-cghq-mmhg", "MGASA-2025-0123", "SUSE-SU-2025:0369-1", "SUSE-SU-2025:0370-1", @@ -1898,6 +2186,266 @@ } ] }, + { + "id": "CVE-2025-10966", + "details": "curl's code for managing SSH connections when SFTP was done using the wolfSSH\npowered backend was flawed and missed host verification mechanisms.\n\nThis prevents curl from detecting MITM attackers and more.", + "aliases": ["CURL-CVE-2025-10966"], + "modified": "", + "published": "2025-11-07T08:15:39.617Z", + "references": [ + { + "type": "FIX", + "url": "https://curl.se/docs/CVE-2025-10966.html" + }, + { + "type": "ADVISORY", + "url": "https://curl.se/docs/CVE-2025-10966.json" + }, + { + "type": "EVIDENCE", + "url": "https://hackerone.com/reports/3355218" + }, + { + "type": "ARTICLE", + "url": "http://www.openwall.com/lists/oss-security/2025/11/05/2" + } + ], + "affected": [ + { + "ranges": [ + { + "type": "GIT", + "repo": "https://github.com/curl/curl", + "events": [ + { + "introduced": "b8d1366852fd0034374c5de1e4968c7a224f77cc" + }, + { + "fixed": "400fffa90f30c7a2dc762fa33009d24851bd2016" + } + ] + } + ], + "versions": 53, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "severity": [ + { + "type": "CVSS_V3", + "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N" + } + ] + }, + { + "id": "CVE-2025-14524", + "details": "When an OAuth2 bearer token is used for an HTTP(S) transfer, and that transfer\nperforms a cross-protocol redirect to a second URL that uses an IMAP, LDAP,\nPOP3 or SMTP scheme, curl might wrongly pass on the bearer token to the new\ntarget host.", + "aliases": ["CURL-CVE-2025-14524"], + "modified": "", + "published": "2026-01-08T10:15:46.607Z", + "related": ["MGASA-2026-0003"], + "references": [ + { + "type": "FIX", + "url": "https://curl.se/docs/CVE-2025-14524.html" + }, + { + "type": "ADVISORY", + "url": "https://curl.se/docs/CVE-2025-14524.json" + }, + { + "type": "EVIDENCE", + "url": "https://hackerone.com/reports/3459417" + }, + { + "type": "ARTICLE", + "url": "http://www.openwall.com/lists/oss-security/2026/01/07/4" + } + ], + "affected": [ + { + "ranges": [ + { + "type": "GIT", + "repo": "https://github.com/curl/curl", + "events": [ + { + "introduced": "f77e89c5d20db09eaebf378ec036a7e796932810" + }, + { + "fixed": "2eebc58c4b8d68c98c8344381a9f6df4cca838fd" + } + ] + } + ], + "versions": 109, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "severity": [ + { + "type": "CVSS_V3", + "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N" + } + ] + }, + { + "id": "CVE-2025-14819", + "details": "When doing TLS related transfers with reused easy or multi handles and\naltering the `CURLSSLOPT_NO_PARTIALCHAIN` option, libcurl could accidentally\nreuse a CA store cached in memory for which the partial chain option was\nreversed. Contrary to the user's wishes and expectations. This could make\nlibcurl find and accept a trust chain that it otherwise would not.", + "aliases": ["CURL-CVE-2025-14819"], + "modified": "", + "published": "2026-01-08T10:15:46.730Z", + "related": ["MGASA-2026-0003"], + "references": [ + { + "type": "FIX", + "url": "https://curl.se/docs/CVE-2025-14819.html" + }, + { + "type": "ARTICLE", + "url": "http://www.openwall.com/lists/oss-security/2026/01/07/5" + }, + { + "type": "ADVISORY", + "url": "https://curl.se/docs/CVE-2025-14819.json" + } + ], + "affected": [ + { + "ranges": [ + { + "type": "GIT", + "repo": "https://github.com/curl/curl", + "events": [ + { + "introduced": "c12fb3ddaf48e709a7a4deaa55ec485e4df163ee" + }, + { + "fixed": "2eebc58c4b8d68c98c8344381a9f6df4cca838fd" + } + ] + } + ], + "versions": 34, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "severity": [ + { + "type": "CVSS_V3", + "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N" + } + ] + }, + { + "id": "CVE-2025-15079", + "details": "When doing SSH-based transfers using either SCP or SFTP, and setting the\nknown_hosts file, libcurl could still mistakenly accept connecting to hosts\n*not present* in the specified file if they were added as recognized in the\nlibssh *global* known_hosts file.", + "aliases": ["CURL-CVE-2025-15079"], + "modified": "", + "published": "2026-01-08T10:15:47.100Z", + "related": ["MGASA-2026-0003"], + "references": [ + { + "type": "FIX", + "url": "https://curl.se/docs/CVE-2025-15079.html" + }, + { + "type": "ADVISORY", + "url": "https://curl.se/docs/CVE-2025-15079.json" + }, + { + "type": "EVIDENCE", + "url": "https://hackerone.com/reports/3477116" + }, + { + "type": "ARTICLE", + "url": "http://www.openwall.com/lists/oss-security/2026/01/07/6" + } + ], + "affected": [ + { + "ranges": [ + { + "type": "GIT", + "repo": "https://github.com/curl/curl", + "events": [ + { + "introduced": "d6c21c8eec597a925d2b647cff3d58ac69de01a0" + }, + { + "fixed": "2eebc58c4b8d68c98c8344381a9f6df4cca838fd" + } + ] + } + ], + "versions": 73, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "severity": [ + { + "type": "CVSS_V3", + "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N" + } + ] + }, + { + "id": "CVE-2025-15224", + "details": "When doing SSH-based transfers using either SCP or SFTP, and asked to do\npublic key authentication, curl would wrongly still ask and authenticate using\na locally running SSH agent.", + "aliases": ["CURL-CVE-2025-15224"], + "modified": "", + "published": "2026-01-08T10:15:47.207Z", + "related": ["MGASA-2026-0003"], + "references": [ + { + "type": "FIX", + "url": "https://curl.se/docs/CVE-2025-15224.html" + }, + { + "type": "ADVISORY", + "url": "https://curl.se/docs/CVE-2025-15224.json" + }, + { + "type": "EVIDENCE", + "url": "https://hackerone.com/reports/3480925" + }, + { + "type": "ARTICLE", + "url": "http://www.openwall.com/lists/oss-security/2026/01/07/7" + } + ], + "affected": [ + { + "ranges": [ + { + "type": "GIT", + "repo": "https://github.com/curl/curl", + "events": [ + { + "introduced": "d6c21c8eec597a925d2b647cff3d58ac69de01a0" + }, + { + "fixed": "2eebc58c4b8d68c98c8344381a9f6df4cca838fd" + } + ] + } + ], + "versions": 73, + "database_specific": "" + } + ], + "schema_version": "1.7.3", + "severity": [ + { + "type": "CVSS_V3", + "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:L/A:N" + } + ] + }, { "id": "CVE-2025-5025", "details": "libcurl supports *pinning* of the server certificate public key for HTTPS transfers. Due to an omission, this check is not performed when connecting with QUIC for HTTP/3, when the TLS backend is wolfSSL. Documentation says the option works with wolfSSL, failing to specify that it does not for QUIC and HTTP/3. Since pinning makes the transfer succeed if the pin is fine, users could unwittingly connect to an impostor server without noticing.", @@ -2247,8 +2795,8 @@ "id": "GHSA-cpwx-vrp4-4pq7", "summary": "Jinja2 vulnerable to sandbox breakout through attr filter selecting format method", "details": "An oversight in how the Jinja sandboxed environment interacts with the `|attr` filter allows an attacker that controls the content of a template to execute arbitrary Python code.\n\nTo exploit the vulnerability, an attacker needs to control the content of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates.\n\nJinja's sandbox does catch calls to `str.format` and ensures they don't escape the sandbox. However, it's possible to use the `|attr` filter to get a reference to a string's plain format method, bypassing the sandbox. After the fix, the `|attr` filter no longer bypasses the environment's attribute lookup.", - "aliases": ["CVE-2025-27516"], - "modified": "", + "aliases": ["CVE-2025-27516", "ROOT-APP-PYPI-CVE-2025-27516"], + "modified": "", "published": "2025-03-05T20:40:14Z", "related": [ "CGA-2h34-36gr-7wjw", @@ -2331,8 +2879,8 @@ "id": "GHSA-gmj6-6f8f-6699", "summary": "Jinja has a sandbox breakout through malicious filenames", "details": "A bug in the Jinja compiler allows an attacker that controls both the content and filename of a template to execute arbitrary Python code, regardless of if Jinja's sandbox is used.\n\nTo exploit the vulnerability, an attacker needs to control both the filename and the contents of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates where the template author can also choose the template filename.", - "aliases": ["CVE-2024-56201"], - "modified": "", + "aliases": ["CVE-2024-56201", "ROOT-APP-PYPI-CVE-2024-56201"], + "modified": "", "published": "2024-12-23T17:54:12Z", "related": [ "CGA-2589-9xpr-fmp7", @@ -2420,8 +2968,8 @@ "id": "GHSA-q2x7-8rv6-6q7h", "summary": "Jinja has a sandbox breakout through indirect reference to format method", "details": "An oversight in how the Jinja sandboxed environment detects calls to `str.format` allows an attacker that controls the content of a template to execute arbitrary Python code.\n\nTo exploit the vulnerability, an attacker needs to control the content of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates.\n\nJinja's sandbox does catch calls to `str.format` and ensures they don't escape the sandbox. However, it's possible to store a reference to a malicious string's `format` method, then pass that to a filter that calls it. No such filters are built-in to Jinja, but could be present through custom filters in an application. After the fix, such indirect calls are also handled by the sandbox.", - "aliases": ["CVE-2024-56326"], - "modified": "", + "aliases": ["CVE-2024-56326", "ROOT-APP-PYPI-CVE-2024-56326"], + "modified": "", "published": "2024-12-23T17:56:08Z", "related": [ "CGA-3cj4-2jg2-4qm3", @@ -2518,8 +3066,8 @@ "id": "GHSA-cpwx-vrp4-4pq7", "summary": "Jinja2 vulnerable to sandbox breakout through attr filter selecting format method", "details": "An oversight in how the Jinja sandboxed environment interacts with the `|attr` filter allows an attacker that controls the content of a template to execute arbitrary Python code.\n\nTo exploit the vulnerability, an attacker needs to control the content of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates.\n\nJinja's sandbox does catch calls to `str.format` and ensures they don't escape the sandbox. However, it's possible to use the `|attr` filter to get a reference to a string's plain format method, bypassing the sandbox. After the fix, the `|attr` filter no longer bypasses the environment's attribute lookup.", - "aliases": ["CVE-2025-27516"], - "modified": "", + "aliases": ["CVE-2025-27516", "ROOT-APP-PYPI-CVE-2025-27516"], + "modified": "", "published": "2025-03-05T20:40:14Z", "related": [ "CGA-2h34-36gr-7wjw", @@ -2602,8 +3150,8 @@ "id": "GHSA-gmj6-6f8f-6699", "summary": "Jinja has a sandbox breakout through malicious filenames", "details": "A bug in the Jinja compiler allows an attacker that controls both the content and filename of a template to execute arbitrary Python code, regardless of if Jinja's sandbox is used.\n\nTo exploit the vulnerability, an attacker needs to control both the filename and the contents of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates where the template author can also choose the template filename.", - "aliases": ["CVE-2024-56201"], - "modified": "", + "aliases": ["CVE-2024-56201", "ROOT-APP-PYPI-CVE-2024-56201"], + "modified": "", "published": "2024-12-23T17:54:12Z", "related": [ "CGA-2589-9xpr-fmp7", @@ -2691,8 +3239,8 @@ "id": "GHSA-q2x7-8rv6-6q7h", "summary": "Jinja has a sandbox breakout through indirect reference to format method", "details": "An oversight in how the Jinja sandboxed environment detects calls to `str.format` allows an attacker that controls the content of a template to execute arbitrary Python code.\n\nTo exploit the vulnerability, an attacker needs to control the content of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates.\n\nJinja's sandbox does catch calls to `str.format` and ensures they don't escape the sandbox. However, it's possible to store a reference to a malicious string's `format` method, then pass that to a filter that calls it. No such filters are built-in to Jinja, but could be present through custom filters in an application. After the fix, such indirect calls are also handled by the sandbox.", - "aliases": ["CVE-2024-56326"], - "modified": "", + "aliases": ["CVE-2024-56326", "ROOT-APP-PYPI-CVE-2024-56326"], + "modified": "", "published": "2024-12-23T17:56:08Z", "related": [ "CGA-3cj4-2jg2-4qm3", @@ -2789,8 +3337,8 @@ "id": "GHSA-cpwx-vrp4-4pq7", "summary": "Jinja2 vulnerable to sandbox breakout through attr filter selecting format method", "details": "An oversight in how the Jinja sandboxed environment interacts with the `|attr` filter allows an attacker that controls the content of a template to execute arbitrary Python code.\n\nTo exploit the vulnerability, an attacker needs to control the content of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates.\n\nJinja's sandbox does catch calls to `str.format` and ensures they don't escape the sandbox. However, it's possible to use the `|attr` filter to get a reference to a string's plain format method, bypassing the sandbox. After the fix, the `|attr` filter no longer bypasses the environment's attribute lookup.", - "aliases": ["CVE-2025-27516"], - "modified": "", + "aliases": ["CVE-2025-27516", "ROOT-APP-PYPI-CVE-2025-27516"], + "modified": "", "published": "2025-03-05T20:40:14Z", "related": [ "CGA-2h34-36gr-7wjw", @@ -2873,8 +3421,8 @@ "id": "GHSA-gmj6-6f8f-6699", "summary": "Jinja has a sandbox breakout through malicious filenames", "details": "A bug in the Jinja compiler allows an attacker that controls both the content and filename of a template to execute arbitrary Python code, regardless of if Jinja's sandbox is used.\n\nTo exploit the vulnerability, an attacker needs to control both the filename and the contents of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates where the template author can also choose the template filename.", - "aliases": ["CVE-2024-56201"], - "modified": "", + "aliases": ["CVE-2024-56201", "ROOT-APP-PYPI-CVE-2024-56201"], + "modified": "", "published": "2024-12-23T17:54:12Z", "related": [ "CGA-2589-9xpr-fmp7", @@ -2962,8 +3510,8 @@ "id": "GHSA-q2x7-8rv6-6q7h", "summary": "Jinja has a sandbox breakout through indirect reference to format method", "details": "An oversight in how the Jinja sandboxed environment detects calls to `str.format` allows an attacker that controls the content of a template to execute arbitrary Python code.\n\nTo exploit the vulnerability, an attacker needs to control the content of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates.\n\nJinja's sandbox does catch calls to `str.format` and ensures they don't escape the sandbox. However, it's possible to store a reference to a malicious string's `format` method, then pass that to a filter that calls it. No such filters are built-in to Jinja, but could be present through custom filters in an application. After the fix, such indirect calls are also handled by the sandbox.", - "aliases": ["CVE-2024-56326"], - "modified": "", + "aliases": ["CVE-2024-56326", "ROOT-APP-PYPI-CVE-2024-56326"], + "modified": "", "published": "2024-12-23T17:56:08Z", "related": [ "CGA-3cj4-2jg2-4qm3", diff --git a/tools/apitester/go.mod b/tools/apitester/go.mod index 7fc12e2c178..0911265f9be 100644 --- a/tools/apitester/go.mod +++ b/tools/apitester/go.mod @@ -1,6 +1,6 @@ module github.com/google/apitester -go 1.25.5 +go 1.25.6 require ( github.com/gkampitakis/go-snaps v0.5.19 diff --git a/tools/apitester/internal/vcr/interactions.go b/tools/apitester/internal/vcr/interactions.go index b61b1bdbc6b..c3d41e49961 100644 --- a/tools/apitester/internal/vcr/interactions.go +++ b/tools/apitester/internal/vcr/interactions.go @@ -3,6 +3,7 @@ package vcr import ( "net/http" "os" + "strings" "testing" "gopkg.in/dnaeon/go-vcr.v4/pkg/cassette" @@ -32,10 +33,11 @@ func Play(t *testing.T, interaction *cassette.Interaction) *http.Response { } req.URL.Host = fetchAPIBaseURL() + req.Host = req.URL.Host req.Header.Set("User-Agent", "osv.dev/apitester") req.ContentLength = -1 - if req.URL.Hostname() == "localhost" || req.URL.Hostname() == "127.0.0.1" { + if req.URL.Hostname() == "localhost" || req.URL.Hostname() == "127.0.0.1" || strings.HasPrefix(req.URL.Hostname(), "192.168.") { req.URL.Scheme = "http" } diff --git a/tools/datafix/list_ids_for_source.py b/tools/datafix/list_ids_for_source.py index 009640b943e..eeb321b8403 100755 --- a/tools/datafix/list_ids_for_source.py +++ b/tools/datafix/list_ids_for_source.py @@ -45,25 +45,27 @@ def main() -> None: ds_client = datastore.Client(project=args.project) - query = ds_client.query(kind="Bug") - query.add_filter(filter=PropertyFilter("source", "=", args.source_id)) - query.add_filter(filter=PropertyFilter("status", "=", 1)) + query = ds_client.query(kind="Vulnerability") + query.add_filter( + filter=PropertyFilter("source_id", ">", args.source_id + ':')) + query.add_filter( + filter=PropertyFilter("source_id", "<", args.source_id + ';')) print(f"Running query {query.filters} " f"on {query.kind} (in {query.project})...") result = list(query.fetch()) - print(f"Retrieved {len(result)} bugs") + print(f"Retrieved {len(result)} vulnerabilities") - bugs = [] + vulnerabilities = [] # Chunk the results to modify in acceptibly sized batches for the API. for batch in range(0, len(result), MAX_BATCH_SIZE): - for bug in result[batch:batch + MAX_BATCH_SIZE]: - print(f"{bug['db_id']}") - bugs.append(bug['db_id']) + for vuln in result[batch:batch + MAX_BATCH_SIZE]: + print(f"{vuln.key.name}") + vulnerabilities.append(vuln.key.name) if args.txt: - with open('bug_ids.txt', 'w') as f: - for bug in bugs: - f.write(f'{bug}\n') + with open('vuln_ids.txt', 'w') as f: + for vuln in vulnerabilities: + f.write(f'{vuln}\n') if __name__ == "__main__": diff --git a/tools/datafix/old/README.md b/tools/datafix/old/README.md new file mode 100644 index 00000000000..2939ad91fc6 --- /dev/null +++ b/tools/datafix/old/README.md @@ -0,0 +1,5 @@ +The scripts in this folder all operate on the old Bug data model. + +OSV.dev has moved away from using Bugs as the source of truth for vulnerabilities, so these scripts are no longer useful, or will need to be rewritten. + +They are retained for historical/documentational purposes. diff --git a/tools/datafix/delete_bugs.py b/tools/datafix/old/delete_bugs.py similarity index 100% rename from tools/datafix/delete_bugs.py rename to tools/datafix/old/delete_bugs.py diff --git a/tools/datafix/delete_invalid.py b/tools/datafix/old/delete_invalid.py similarity index 100% rename from tools/datafix/delete_invalid.py rename to tools/datafix/old/delete_invalid.py diff --git a/tools/datafix/reput_all.py b/tools/datafix/old/reput_all.py similarity index 100% rename from tools/datafix/reput_all.py rename to tools/datafix/old/reput_all.py diff --git a/tools/datafix/reput_bugs.py b/tools/datafix/old/reput_bugs.py similarity index 100% rename from tools/datafix/reput_bugs.py rename to tools/datafix/old/reput_bugs.py diff --git a/tools/datafix/reput_helper.py b/tools/datafix/old/reput_helper.py similarity index 100% rename from tools/datafix/reput_helper.py rename to tools/datafix/old/reput_helper.py diff --git a/tools/datafix/withdraw_invalid.py b/tools/datafix/old/withdraw_invalid.py similarity index 100% rename from tools/datafix/withdraw_invalid.py rename to tools/datafix/old/withdraw_invalid.py diff --git a/tools/datafix/poetry.lock b/tools/datafix/poetry.lock index ed9aa9e2b2d..76f0104dd2a 100644 --- a/tools/datafix/poetry.lock +++ b/tools/datafix/poetry.lock @@ -24,18 +24,6 @@ files = [ {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] -[[package]] -name = "cachetools" -version = "6.2.4" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "cachetools-6.2.4-py3-none-any.whl", hash = "sha256:69a7a52634fed8b8bf6e24a050fb60bff1c9bd8f6d24572b99c32d4e71e62a51"}, - {file = "cachetools-6.2.4.tar.gz", hash = "sha256:82c5c05585e70b6ba2d3ae09ea60b79548872185d2f24ae1f2709d37299fd607"}, -] - [[package]] name = "certifi" version = "2026.1.4" @@ -281,16 +269,93 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "cryptography" +version = "46.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, + {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, + {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, + {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, + {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, + {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, + {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, + {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, + {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, + {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, + {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, +] + +[package.dependencies] +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" description = "serialize all of Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, - {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, ] [package.extras] @@ -299,14 +364,14 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "google-api-core" -version = "2.28.1" +version = "2.29.0" description = "Google API client core library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c"}, - {file = "google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8"}, + {file = "google_api_core-2.29.0-py3-none-any.whl", hash = "sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9"}, + {file = "google_api_core-2.29.0.tar.gz", hash = "sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7"}, ] [package.dependencies] @@ -332,42 +397,42 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.0)"] [[package]] name = "google-auth" -version = "2.45.0" +version = "2.48.0" description = "Google Authentication Library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "google_auth-2.45.0-py2.py3-none-any.whl", hash = "sha256:82344e86dc00410ef5382d99be677c6043d72e502b625aa4f4afa0bdacca0f36"}, - {file = "google_auth-2.45.0.tar.gz", hash = "sha256:90d3f41b6b72ea72dd9811e765699ee491ab24139f34ebf1ca2b9cc0c38708f3"}, + {file = "google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f"}, + {file = "google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce"}, ] [package.dependencies] -cachetools = ">=2.0.0,<7.0" +cryptography = ">=38.0.3" pyasn1-modules = ">=0.2.1" rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] -cryptography = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)"] -enterprise-cert = ["cryptography", "pyopenssl"] -pyjwt = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyjwt (>=2.0)"] -pyopenssl = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +cryptography = ["cryptography (>=38.0.3)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0)"] -testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "mock", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] urllib3 = ["packaging", "urllib3"] [[package]] name = "google-cloud-appengine-logging" -version = "1.7.0" +version = "1.8.0" description = "Google Cloud Appengine Logging API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_appengine_logging-1.7.0-py3-none-any.whl", hash = "sha256:cfd28bc61a030008381a646d112ebe2734bf72abc8c12afc47d035a2c9b041fe"}, - {file = "google_cloud_appengine_logging-1.7.0.tar.gz", hash = "sha256:ea9ce73430cfc99f8957fd7df97733f9a759d4caab65e19d63a7474f012ffd94"}, + {file = "google_cloud_appengine_logging-1.8.0-py3-none-any.whl", hash = "sha256:a4ce9ce94a9fd8c89ed07fa0b06fcf9ea3642f9532a1be1a8c7b5f82c0a70ec6"}, + {file = "google_cloud_appengine_logging-1.8.0.tar.gz", hash = "sha256:84b705a69e4109fc2f68dfe36ce3df6a34d5c3d989eee6d0ac1b024dda0ba6f5"}, ] [package.dependencies] @@ -515,27 +580,28 @@ libcst = ["libcst (>=0.3.10)"] [[package]] name = "google-cloud-storage" -version = "2.19.0" +version = "3.8.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "google_cloud_storage-2.19.0-py2.py3-none-any.whl", hash = "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba"}, - {file = "google_cloud_storage-2.19.0.tar.gz", hash = "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2"}, + {file = "google_cloud_storage-3.8.0-py3-none-any.whl", hash = "sha256:78cfeae7cac2ca9441d0d0271c2eb4ebfa21aa4c6944dd0ccac0389e81d955a7"}, + {file = "google_cloud_storage-3.8.0.tar.gz", hash = "sha256:cc67952dce84ebc9d44970e24647a58260630b7b64d72360cedaf422d6727f28"}, ] [package.dependencies] -google-api-core = ">=2.15.0,<3.0.0dev" -google-auth = ">=2.26.1,<3.0dev" -google-cloud-core = ">=2.3.0,<3.0dev" -google-crc32c = ">=1.0,<2.0dev" -google-resumable-media = ">=2.7.2" -requests = ">=2.18.0,<3.0.0dev" +google-api-core = ">=2.27.0,<3.0.0" +google-auth = ">=2.26.1,<3.0.0" +google-cloud-core = ">=2.4.2,<3.0.0" +google-crc32c = ">=1.1.3,<2.0.0" +google-resumable-media = ">=2.7.2,<3.0.0" +requests = ">=2.22.0,<3.0.0" [package.extras] -protobuf = ["protobuf (<6.0.0dev)"] -tracing = ["opentelemetry-api (>=1.1.0)"] +grpc = ["google-api-core[grpc] (>=2.27.0,<3.0.0)", "grpc-google-iam-v1 (>=0.14.0,<1.0.0)", "grpcio (>=1.33.2,<2.0.0) ; python_version < \"3.14\"", "grpcio (>=1.75.1,<2.0.0) ; python_version >= \"3.14\"", "grpcio-status (>=1.76.0,<2.0.0)", "proto-plus (>=1.22.3,<2.0.0) ; python_version < \"3.13\"", "proto-plus (>=1.25.0,<2.0.0) ; python_version >= \"3.13\"", "protobuf (>=3.20.2,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0)"] +protobuf = ["protobuf (>=3.20.2,<7.0.0)"] +tracing = ["opentelemetry-api (>=1.1.0,<2.0.0)"] [[package]] name = "google-crc32c" @@ -786,21 +852,21 @@ plugins = ["setuptools"] [[package]] name = "jsonschema" -version = "4.25.1" +version = "4.26.0" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, - {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, ] [package.dependencies] attrs = ">=22.2.0" jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" -rpds-py = ">=0.7.1" +rpds-py = ">=0.25.0" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -931,14 +997,14 @@ test = ["pytest"] [[package]] name = "packaging" -version = "25.0" +version = "26.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, ] [[package]] @@ -993,34 +1059,34 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "6.33.2" +version = "6.33.4" description = "" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d"}, - {file = "protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4"}, - {file = "protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f"}, - {file = "protobuf-6.33.2-cp39-cp39-win32.whl", hash = "sha256:7109dcc38a680d033ffb8bf896727423528db9163be1b6a02d6a49606dcadbfe"}, - {file = "protobuf-6.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:2981c58f582f44b6b13173e12bb8656711189c2a70250845f264b877f00b1913"}, - {file = "protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c"}, - {file = "protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4"}, + {file = "protobuf-6.33.4-cp310-abi3-win32.whl", hash = "sha256:918966612c8232fc6c24c78e1cd89784307f5814ad7506c308ee3cf86662850d"}, + {file = "protobuf-6.33.4-cp310-abi3-win_amd64.whl", hash = "sha256:8f11ffae31ec67fc2554c2ef891dcb561dae9a2a3ed941f9e134c2db06657dbc"}, + {file = "protobuf-6.33.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2fe67f6c014c84f655ee06f6f66213f9254b3a8b6bda6cda0ccd4232c73c06f0"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:757c978f82e74d75cba88eddec479df9b99a42b31193313b75e492c06a51764e"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c7c64f259c618f0bef7bee042075e390debbf9682334be2b67408ec7c1c09ee6"}, + {file = "protobuf-6.33.4-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:3df850c2f8db9934de4cf8f9152f8dc2558f49f298f37f90c517e8e5c84c30e9"}, + {file = "protobuf-6.33.4-cp39-cp39-win32.whl", hash = "sha256:955478a89559fa4568f5a81dce77260eabc5c686f9e8366219ebd30debf06aa6"}, + {file = "protobuf-6.33.4-cp39-cp39-win_amd64.whl", hash = "sha256:0f12ddbf96912690c3582f9dffb55530ef32015ad8e678cd494312bd78314c4f"}, + {file = "protobuf-6.33.4-py3-none-any.whl", hash = "sha256:1fe3730068fcf2e595816a6c34fe66eeedd37d51d0400b72fabc848811fdc1bc"}, + {file = "protobuf-6.33.4.tar.gz", hash = "sha256:dc2e61bca3b10470c1912d166fe0af67bfc20eb55971dcef8dfa48ce14f0ed91"}, ] [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, - {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, + {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"}, + {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"}, ] [[package]] @@ -1040,15 +1106,15 @@ pyasn1 = ">=0.6.1,<0.7.0" [[package]] name = "pycparser" -version = "2.23" +version = "3.0" description = "C parser in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] markers = "implementation_name != \"PyPy\"" files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, + {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, + {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, ] [[package]] @@ -1461,14 +1527,14 @@ files = [ [[package]] name = "tomlkit" -version = "0.13.3" +version = "0.14.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, ] [[package]] @@ -1485,14 +1551,14 @@ files = [ [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] @@ -1539,4 +1605,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.13,<4.0" -content-hash = "d397c84bb05599c9cbb1334e0ba349fd83fa541c6c42cf2d9639a799fe39d8a0" +content-hash = "ae2d04b32456542e10608e6eecbf3cf8dea1d9c6f0a506cd6bc02e07c967a046" diff --git a/tools/datafix/pyproject.toml b/tools/datafix/pyproject.toml index c8fb0817a68..a4caff54e2d 100644 --- a/tools/datafix/pyproject.toml +++ b/tools/datafix/pyproject.toml @@ -3,7 +3,7 @@ name = "datafix" requires-python = ">=3.13,<4.0" dependencies = [ "google-cloud-ndb==2.4.0", - "google-cloud-storage==2.19.0", + "google-cloud-storage==3.8.0", "pyyaml==6.0.3", "osv", "google-cloud-pubsub>=2.25.2", diff --git a/tools/datafix/reimport_gcs_record.py b/tools/datafix/reimport_gcs_record.py index 41270fc23d7..a53e5abdbd0 100755 --- a/tools/datafix/reimport_gcs_record.py +++ b/tools/datafix/reimport_gcs_record.py @@ -6,9 +6,9 @@ * the creation time of the GCS object is newer than the last_update_date for the data source in SourceRepository in Cloud Datastore * either of: - * the vulnerability does not exist in Bug in Cloud Datastore at all, or - * the Modified field of the record differs from the existing Bug's - import_last_modified in Cloud Datastore. + * the vulnerability does not exist in Vulnerability in Datastore at all, or + * the Modified field of the record differs from the existing Vulnerability's + modified_raw in Cloud Datastore. This defaults to running in dry-run mode against the staging instance. It supports an arbitrary number of vulnerability IDs on the command line. @@ -21,6 +21,7 @@ from google.cloud.datastore.query import PropertyFilter import argparse +from datetime import datetime, timezone import os import functools @@ -31,13 +32,13 @@ class UnexpectedSituation(Exception): pass -def objname_for_bug(client: datastore.Client, bug: datastore.entity.Entity, - forced_bucket_name: str) -> dict: - """Returns the GCS object details for a given Bug. +def objname_for_vuln(client: datastore.Client, vuln: datastore.entity.Entity, + forced_bucket_name: str) -> dict: + """Returns the GCS object details for a given Vulnerability. Args: client: an initialized Cloud Datastore client. - bug: a Bug Cloud Datastore entity. + vuln: a Vulnerability Cloud Datastore entity. forced_bucket_name: bucket name (with optional colon-separated path) to forcibly use. @@ -45,7 +46,7 @@ def objname_for_bug(client: datastore.Client, bug: datastore.entity.Entity, A dict with keys for the GCS uri, the bucket name and path within the bucket. """ - source_object_path = bug["source_id"].split(":")[1] + source, _, source_object_path = vuln["source_id"].partition(":") if forced_bucket_name: (bucket, _, bucketpath) = forced_bucket_name.partition(":") @@ -61,7 +62,7 @@ def objname_for_bug(client: datastore.Client, bug: datastore.entity.Entity, os.path.join(bucketpath, os.path.basename(source_object_path)) } - bucket = bucket_for_source(client, bug["source"]) + bucket = bucket_for_source(client, source) return { "uri": "gs://" + os.path.join(bucket, source_object_path), "bucket": bucket, @@ -133,10 +134,10 @@ def main() -> None: parser = argparse.ArgumentParser( description="Trigger the reimport of individual GCS-sourced records") parser.add_argument( - "bugs", + "vulns", action="append", nargs="+", - help=f"The bug IDs to operate on ({MAX_QUERY_SIZE} at most)") + help=f"The vuln IDs to operate on ({MAX_QUERY_SIZE} at most)") parser.add_argument( "--dry-run", action=argparse.BooleanOptionalAction, @@ -170,46 +171,43 @@ def main() -> None: "for the object in GCS (e.g. `cve-osv-conversion:osv-output`)")) args = parser.parse_args() - if len(args.bugs[0]) > MAX_QUERY_SIZE: - parser.error(f"Only {MAX_QUERY_SIZE} bugs can be supplied. " + if len(args.vulns[0]) > MAX_QUERY_SIZE: + parser.error(f"Only {MAX_QUERY_SIZE} vulns can be supplied. " f"Try running with xargs -n {MAX_QUERY_SIZE}") ds_client = datastore.Client(project=args.project) url_base = url_for_project(args.project) - query = ds_client.query(kind="Bug") - query.add_filter(filter=PropertyFilter("db_id", "IN", args.bugs[0])) - print(f"Running query {query.filters[0]} " - f"on {query.kind} (in {query.project})...") - result = list(query.fetch()) - print(f"Retrieved {len(result)} bugs to validate for operating on") - result_to_fix = [r for r in result if r['source_of_truth'] == 2] - print(f"There are {len(result_to_fix)} bugs to operate on...") + print("Running fetch") + result = ds_client.get_multi( + [ds_client.key('Vulnerability', vuln_id) for vuln_id in args.vulns[0]]) + print(f"Retrieved {len(result)} vulns to operate on...") try: with ds_client.transaction() as xact: - for bug in result_to_fix: + for vuln in result: try: - bug_in_gcs = objname_for_bug( - ds_client, bug, forced_bucket_name=args.bucket) + vuln_in_gcs = objname_for_vuln( + ds_client, vuln, forced_bucket_name=args.bucket) except UnexpectedSituation as e: if args.verbose: - print(f"Skipping {bug['db_id']}, got {e}\n") + print(f"Skipping {vuln.key.name}, got {e}\n") continue if args.verbose: - print(f"Resetting modification time for {bug_in_gcs['uri']}") + print(f"Resetting modification time for {vuln_in_gcs['uri']}") if not args.dryrun: try: - reset_object_modification(bug_in_gcs["bucket"], bug_in_gcs["path"]) + reset_object_modification(vuln_in_gcs["bucket"], + vuln_in_gcs["path"]) except NotFound as e: if args.verbose: print(f"Skipping, got {e}\n") continue - bug["import_last_modified"] = None + vuln["modified_raw"] = datetime.fromtimestamp(0, timezone.utc) if args.verbose: - print(f"Resetting import_last_modified for {bug['db_id']}") - print(f"Review at {url_base}{bug['db_id']} when reimport completes.") - xact.put(bug) + print(f"Resetting modified_raw for {vuln.key.name}") + print(f"Review at {url_base}{vuln.key.name} when reimport completes.") + xact.put(vuln) if args.dryrun: raise Exception("Dry run mode. Preventing transaction from commiting") # pylint: disable=broad-exception-raised except Exception as e: diff --git a/tools/datafix/request_worker_update_record.py b/tools/datafix/request_worker_update_record.py index 967847d00e8..b469331b4c1 100755 --- a/tools/datafix/request_worker_update_record.py +++ b/tools/datafix/request_worker_update_record.py @@ -79,7 +79,7 @@ def request_url_update(record_url, project_id, source, path, timeout, if not allow_delete or e.response.status_code != 404: print(e) return - print(f'Bug was deleted: {record_url}') + print(f'Vulnerability was deleted: {record_url}') deleted = True publish_update_message(project_id, PUBSUB_TOPIC_ID, source, path, @@ -101,12 +101,12 @@ def main(): "--allow-delete", action="store_true", default=False, - help="Delete bugs if not found in source (GIT only)") + help="Delete vulns if not found in source (GIT only)") parser.add_argument( - "bugs", + "vulns", action="append", nargs="*", - help="The bug IDs to operate on. If not specified, all bugs from the " + help="The vuln IDs to operate on. If not specified, all vulns from the " "source will be processed.") args = parser.parse_args() @@ -118,32 +118,34 @@ def main(): if not source_repo: raise ValueError(f"Source repository '{args.source}' not found.") - bugs_to_process = [] - if args.bugs and args.bugs[0]: - bugs_to_process = args.bugs[0] + vulns_to_process = [] + if args.vulns and args.vulns[0]: + vulns_to_process = args.vulns[0] else: - print( - f'No bug IDs provided. Querying all bugs for source {args.source}...') - query = osv.Bug.query(osv.Bug.source == args.source) - bugs_to_process = [b.id() for b in query.iter(keys_only=True)] - print(f'Found {len(bugs_to_process)} bugs to update.') + print('No vuln IDs provided. ' + 'Querying all vulns for source {args.source}...') + query = osv.Vulnerability.query( + osv.Vulnerability.source_id > args.source + ':', + osv.Vulnerability.source_id < (args.source + ';')) + vulns_to_process = [b.id() for b in query.iter(keys_only=True)] + print(f'Found {len(vulns_to_process)} bugs to update.') confirm = input('Are you sure you want to proceed? (y/N) ') if confirm.lower() not in ('y', 'yes'): print('Aborting.') return if source_repo.type == osv.SourceRepositoryType.REST_ENDPOINT: - for bug in bugs_to_process: - record_url = f'{source_repo.link}{bug}{source_repo.extension}' - path = f'{bug}{source_repo.extension}' + for vuln in vulns_to_process: + record_url = f'{source_repo.link}{vuln}{source_repo.extension}' + path = f'{vuln}{source_repo.extension}' request_url_update(record_url, args.project_id, args.source, path, args.timeout, False) if source_repo.type == osv.SourceRepositoryType.GIT: - for bug in bugs_to_process: - entity = osv.Bug.get_by_id(bug) + for vuln in vulns_to_process: + entity = osv.Vulnerability.get_by_id(vuln) if not entity: - print(f'Warning: {bug} does not exist in Datastore, skipping.') + print(f'Warning: {vuln} does not exist in Datastore, skipping.') continue path = entity.source_id.split(':')[1] diff --git a/tools/datastore-remover/go.mod b/tools/datastore-remover/go.mod index b8b1d92f3b0..4282950576d 100644 --- a/tools/datastore-remover/go.mod +++ b/tools/datastore-remover/go.mod @@ -1,39 +1,40 @@ module github.com/google/datastore-remover -go 1.25.5 +go 1.25.6 require ( cloud.google.com/go/datastore v1.21.0 - google.golang.org/api v0.259.0 + google.golang.org/api v0.263.0 ) require ( cloud.google.com/go v0.121.6 // indirect - cloud.google.com/go/auth v0.18.0 // indirect + cloud.google.com/go/auth v0.18.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/s2a-go v0.1.9 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect github.com/googleapis/gax-go/v2 v2.16.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect - golang.org/x/crypto v0.46.0 // indirect - golang.org/x/net v0.48.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/net v0.49.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d // indirect google.golang.org/grpc v1.78.0 // indirect google.golang.org/protobuf v1.36.11 // indirect ) diff --git a/tools/datastore-remover/go.sum b/tools/datastore-remover/go.sum index 192b6b33763..a3358fa931f 100644 --- a/tools/datastore-remover/go.sum +++ b/tools/datastore-remover/go.sum @@ -1,13 +1,15 @@ cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c= cloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI= -cloud.google.com/go/auth v0.18.0 h1:wnqy5hrv7p3k7cShwAU/Br3nzod7fxoqG+k0VZ+/Pk0= -cloud.google.com/go/auth v0.18.0/go.mod h1:wwkPM1AgE1f2u6dG443MiWoD8C3BtOywNsUMcUTVDRo= +cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= +cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/datastore v1.21.0 h1:dUrYq47ysCA4nM7u8kRT0WnbfXc6TzX49cP3TCwIiA0= cloud.google.com/go/datastore v1.21.0/go.mod h1:9l+KyAHO+YVVcdBbNQZJu8svF17Nw5sMKuFR0LYf1nY= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -32,8 +34,8 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= +github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y= github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= @@ -48,40 +50,40 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.259.0 h1:90TaGVIxScrh1Vn/XI2426kRpBqHwWIzVBzJsVZ5XrQ= -google.golang.org/api v0.259.0/go.mod h1:LC2ISWGWbRoyQVpxGntWwLWN/vLNxxKBK9KuJRI8Te4= +google.golang.org/api v0.263.0 h1:UFs7qn8gInIdtk1ZA6eXRXp5JDAnS4x9VRsRVCeKdbk= +google.golang.org/api v0.263.0/go.mod h1:fAU1xtNNisHgOF5JooAs8rRaTkl2rT3uaoNGo9NS3R8= google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934= google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d h1:xXzuihhT3gL/ntduUZwHECzAn57E8dA6l8SOtYWdD8Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/tools/indexer-api-caller/go.mod b/tools/indexer-api-caller/go.mod index b1053c0d4bb..fb4f9abad63 100644 --- a/tools/indexer-api-caller/go.mod +++ b/tools/indexer-api-caller/go.mod @@ -1,3 +1,3 @@ module github.com/google/indexer-api-caller -go 1.25.5 +go 1.25.6 diff --git a/tools/sourcerepo-sync/run_tests.sh b/tools/sourcerepo-sync/run_tests.sh index 892f9fd774c..25394b42d26 100644 --- a/tools/sourcerepo-sync/run_tests.sh +++ b/tools/sourcerepo-sync/run_tests.sh @@ -13,6 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -poetry install +# Install dependencies only if not running in Cloud Build +if [ -z "$CLOUDBUILD" ]; then + poetry sync +fi poetry run python source_sync.py --kind SourceRepository --project oss-vdb --file ../../source.yaml --verbose --validate poetry run python source_sync.py --kind SourceRepository --project oss-vdb-test --file ../../source_test.yaml --verbose --validate diff --git a/vulnfeeds/build_and_deploy.sh b/vulnfeeds/build_and_deploy.sh index 15f2ca29f2a..5edb8968aa2 100755 --- a/vulnfeeds/build_and_deploy.sh +++ b/vulnfeeds/build_and_deploy.sh @@ -5,11 +5,11 @@ set -x # Set working dir to script dir cd "$(dirname "$0")" -docker build -t gcr.io/oss-vdb/alpine-cve-convert -f cmd/alpine/Dockerfile . -docker build -t gcr.io/oss-vdb/debian-cve-convert -f cmd/debian/Dockerfile . +docker build -t gcr.io/oss-vdb/alpine-cve-convert -f cmd/converters/alpine/Dockerfile . +docker build -t gcr.io/oss-vdb/debian-cve-convert -f cmd/converters/debian/Dockerfile . docker build -t gcr.io/oss-vdb/combine-to-osv -f cmd/combine-to-osv/Dockerfile . -docker build -t gcr.io/oss-vdb/debian-copyright-mirror -f cmd/debian-copyright-mirror/Dockerfile . -docker build -t gcr.io/oss-vdb/cpe-repo-gen -f cmd/cpe-repo-gen/Dockerfile . +docker build -t gcr.io/oss-vdb/debian-copyright-mirror -f cmd/mirrors/debian-copyright-mirror/Dockerfile . +docker build -t gcr.io/oss-vdb/cpe-repo-gen -f cmd/mirrors/cpe-repo-gen/Dockerfile . if [ "$1" = "deploy" ] then diff --git a/vulnfeeds/cmd/combine-to-osv/Dockerfile b/vulnfeeds/cmd/combine-to-osv/Dockerfile index 546e75367d4..e5f23812808 100644 --- a/vulnfeeds/cmd/combine-to-osv/Dockerfile +++ b/vulnfeeds/cmd/combine-to-osv/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD RUN mkdir /src WORKDIR /src @@ -23,10 +23,10 @@ RUN go mod download COPY ./ /src/ RUN go build -o combine-to-osv ./cmd/combine-to-osv/ -RUN go build -o download-cves ./cmd/download-cves/ +RUN go build -o download-cves ./cmd/mirrors/download-cves/ -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed RUN apk --no-cache add jq WORKDIR /root/ diff --git a/vulnfeeds/cmd/combine-to-osv/README.md b/vulnfeeds/cmd/combine-to-osv/README.md index e9d1471ba0e..6d459f751c0 100644 --- a/vulnfeeds/cmd/combine-to-osv/README.md +++ b/vulnfeeds/cmd/combine-to-osv/README.md @@ -9,14 +9,14 @@ Combine [`PackageInfo`](https://github.com/google/osv.dev/blob/2c22e9534a521c6c6 To address the generation of CVE records from multiple disparate sources (all requiring a common record prefix): * Alpine, by [this code](../alpine) -* the NVD, by [this code](../nvd-cve-osv) +* the NVD, by [this code](../converters/cve/nvd-cve-osv) ## How See [`run_combine_to_osv_convert.sh`](run_combine_to_osv_convert.sh): * Reads from [`gs://cve-osv-conversion/parts`](https://storage.googleapis.com/cve-osv-conversion/index.html?prefix=parts/) -* Merges with CVE data from NVD (obtained from GCS mirror maintained by [`download-cves`](../download-cves/mirror_nvd.sh)) +* Merges with CVE data from NVD (obtained from GCS mirror maintained by [`download-cves`](../mirrors/download-cves/mirror_nvd.sh)) * Writes an OSV record to [`gs://cve-osv-conversion/osv-output`](https://storage.googleapis.com/cve-osv-conversion/index.html?prefix=osv-output/) * This is the import source for [`cve-osv`](https://github.com/google/osv.dev/blob/2c22e9534a521c6c6350275427f80e481065ca39/source.yaml#L96) * What gets written can be overridden by OSV records in [`gs://cve-osv-conversion/osv-output-overrides`](https://storage.googleapis.com/cve-osv-conversion/index.html?prefix=osv-output-overrides/) diff --git a/vulnfeeds/cmd/combine-to-osv/main.go b/vulnfeeds/cmd/combine-to-osv/main.go index a44c3c93d50..ceae14c63a8 100644 --- a/vulnfeeds/cmd/combine-to-osv/main.go +++ b/vulnfeeds/cmd/combine-to-osv/main.go @@ -11,12 +11,12 @@ import ( "log/slog" "os" "path/filepath" - "strings" - "slices" + "strings" "cloud.google.com/go/storage" "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/upload" "github.com/google/osv/vulnfeeds/utility/logger" "github.com/ossf/osv-schema/bindings/go/osvschema" @@ -138,8 +138,8 @@ func listBucketObjects(bucketName string, prefix string) ([]string, error) { // The function returns a map of CVE IDs to their corresponding Vulnerability objects. // Files that are not ".json" files, directories, or files ending in ".metrics.json" are skipped. // The function will log warnings for files that fail to open or decode, and will terminate if it fails to walk the directory. -func loadOSV(osvPath string) map[cves.CVEID]*osvschema.Vulnerability { - allVulns := make(map[cves.CVEID]*osvschema.Vulnerability) +func loadOSV(osvPath string) map[models.CVEID]*osvschema.Vulnerability { + allVulns := make(map[models.CVEID]*osvschema.Vulnerability) logger.Info("Loading OSV records", slog.String("path", osvPath)) err := filepath.WalkDir(osvPath, func(path string, d fs.DirEntry, err error) error { if err != nil { @@ -161,7 +161,7 @@ func loadOSV(osvPath string) map[cves.CVEID]*osvschema.Vulnerability { logger.Error("Failed to decode, skipping", slog.String("file", path), slog.Any("err", decodeErr)) return nil } - allVulns[cves.CVEID(vuln.GetId())] = &vuln + allVulns[models.CVEID(vuln.GetId())] = &vuln return nil }) @@ -174,8 +174,8 @@ func loadOSV(osvPath string) map[cves.CVEID]*osvschema.Vulnerability { } // combineIntoOSV creates OSV entry by combining loaded CVEs from NVD and PackageInfo information from security advisories. -func combineIntoOSV(cve5osv map[cves.CVEID]*osvschema.Vulnerability, nvdosv map[cves.CVEID]*osvschema.Vulnerability, mandatoryCVEIDs []string) map[cves.CVEID]*osvschema.Vulnerability { - osvRecords := make(map[cves.CVEID]*osvschema.Vulnerability) +func combineIntoOSV(cve5osv map[models.CVEID]*osvschema.Vulnerability, nvdosv map[models.CVEID]*osvschema.Vulnerability, mandatoryCVEIDs []string) map[models.CVEID]*osvschema.Vulnerability { + osvRecords := make(map[models.CVEID]*osvschema.Vulnerability) // Iterate through CVEs from security advisories (cve5) as the base for cveID, cve5 := range cve5osv { diff --git a/vulnfeeds/cmd/combine-to-osv/main_test.go b/vulnfeeds/cmd/combine-to-osv/main_test.go index c60794efeb8..6930851b895 100644 --- a/vulnfeeds/cmd/combine-to-osv/main_test.go +++ b/vulnfeeds/cmd/combine-to-osv/main_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/ossf/osv-schema/bindings/go/osvschema" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" @@ -35,7 +35,7 @@ func TestCombineIntoOSV(t *testing.T) { cve5osv := loadOSV(cve5Path) nvdosv := loadOSV(nvdPath) - nvdosvCopy := make(map[cves.CVEID]*osvschema.Vulnerability) + nvdosvCopy := make(map[models.CVEID]*osvschema.Vulnerability) for k, v := range nvdosv { nvdosvCopy[k] = v } diff --git a/vulnfeeds/cmd/alpine/Dockerfile b/vulnfeeds/cmd/converters/alpine/Dockerfile similarity index 75% rename from vulnfeeds/cmd/alpine/Dockerfile rename to vulnfeeds/cmd/converters/alpine/Dockerfile index 150a998d195..1073c62e5e6 100644 --- a/vulnfeeds/cmd/alpine/Dockerfile +++ b/vulnfeeds/cmd/converters/alpine/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD RUN mkdir /src WORKDIR /src @@ -22,13 +22,13 @@ COPY ./go.sum /src/go.sum RUN go mod download COPY ./ /src/ -RUN go build -o alpine-osv ./cmd/alpine/ +RUN go build -o alpine-osv ./cmd/converters/alpine/ -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed WORKDIR /root/ COPY --from=GO_BUILD /src/alpine-osv ./ -COPY ./cmd/alpine/run_alpine_convert.sh ./ +COPY ./cmd/converters/alpine/run_alpine_convert.sh ./ ENTRYPOINT ["/root/run_alpine_convert.sh"] diff --git a/vulnfeeds/cmd/alpine/alpine_secdb.go b/vulnfeeds/cmd/converters/alpine/alpine_secdb.go similarity index 100% rename from vulnfeeds/cmd/alpine/alpine_secdb.go rename to vulnfeeds/cmd/converters/alpine/alpine_secdb.go diff --git a/vulnfeeds/cmd/alpine/fixtures/invalid_versions.txt b/vulnfeeds/cmd/converters/alpine/fixtures/invalid_versions.txt similarity index 100% rename from vulnfeeds/cmd/alpine/fixtures/invalid_versions.txt rename to vulnfeeds/cmd/converters/alpine/fixtures/invalid_versions.txt diff --git a/vulnfeeds/cmd/alpine/fixtures/valid_versions.txt b/vulnfeeds/cmd/converters/alpine/fixtures/valid_versions.txt similarity index 100% rename from vulnfeeds/cmd/alpine/fixtures/valid_versions.txt rename to vulnfeeds/cmd/converters/alpine/fixtures/valid_versions.txt diff --git a/vulnfeeds/cmd/alpine/main.go b/vulnfeeds/cmd/converters/alpine/main.go similarity index 97% rename from vulnfeeds/cmd/alpine/main.go rename to vulnfeeds/cmd/converters/alpine/main.go index eb42b3932d8..adb57a3e3e8 100644 --- a/vulnfeeds/cmd/alpine/main.go +++ b/vulnfeeds/cmd/converters/alpine/main.go @@ -15,7 +15,6 @@ import ( "strings" "time" - "github.com/google/osv/vulnfeeds/cves" "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/upload" "github.com/google/osv/vulnfeeds/utility/logger" @@ -138,7 +137,7 @@ func getAlpineSecDBData() map[string][]VersionAndPkg { } // generateAlpineOSV generates the generic PackageInfo package from the information given by alpine advisory -func generateAlpineOSV(allAlpineSecDb map[string][]VersionAndPkg, allCVEs map[cves.CVEID]cves.Vulnerability) (osvVulnerabilities []*vulns.Vulnerability) { +func generateAlpineOSV(allAlpineSecDb map[string][]VersionAndPkg, allCVEs map[models.CVEID]models.Vulnerability) (osvVulnerabilities []*vulns.Vulnerability) { cveIDs := make([]string, 0, len(allAlpineSecDb)) for cveID := range allAlpineSecDb { cveIDs = append(cveIDs, cveID) @@ -157,7 +156,7 @@ func generateAlpineOSV(allAlpineSecDb map[string][]VersionAndPkg, allCVEs map[cv return verPkgs[i].Ver < verPkgs[j].Ver }) - cve, ok := allCVEs[cves.CVEID(cveID)] + cve, ok := allCVEs[models.CVEID(cveID)] var published time.Time var details string if ok { diff --git a/vulnfeeds/cmd/alpine/run_alpine_convert.sh b/vulnfeeds/cmd/converters/alpine/run_alpine_convert.sh similarity index 100% rename from vulnfeeds/cmd/alpine/run_alpine_convert.sh rename to vulnfeeds/cmd/converters/alpine/run_alpine_convert.sh diff --git a/vulnfeeds/cmd/alpine/verify.go b/vulnfeeds/cmd/converters/alpine/verify.go similarity index 100% rename from vulnfeeds/cmd/alpine/verify.go rename to vulnfeeds/cmd/converters/alpine/verify.go diff --git a/vulnfeeds/cmd/alpine/verify_test.go b/vulnfeeds/cmd/converters/alpine/verify_test.go similarity index 100% rename from vulnfeeds/cmd/alpine/verify_test.go rename to vulnfeeds/cmd/converters/alpine/verify_test.go diff --git a/vulnfeeds/cmd/cve-bulk-converter/Dockerfile b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/Dockerfile similarity index 73% rename from vulnfeeds/cmd/cve-bulk-converter/Dockerfile rename to vulnfeeds/cmd/converters/cve/cve5/bulk-converter/Dockerfile index 249d890dfa4..4819bd8e19d 100644 --- a/vulnfeeds/cmd/cve-bulk-converter/Dockerfile +++ b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS go_build +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS go_build RUN mkdir /src WORKDIR /src @@ -23,13 +23,13 @@ RUN go mod download && go mod verify COPY ./ /src/ -RUN go build -o cve-bulk-converter ./cmd/cve-bulk-converter/ +RUN go build -o cve-bulk-converter ./cmd/converters/cve/cve5/bulk-converter/ -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed RUN apk --no-cache add jq WORKDIR /root/ COPY --from=go_build /src/cve-bulk-converter ./ -COPY ./cmd/cve-bulk-converter/run-cvelist-converter.sh ./ +COPY ./cmd/converters/cve/cve5/bulk-converter/run-cvelist-converter.sh ./ ENTRYPOINT ["/root/run-cvelist-converter.sh"] diff --git a/vulnfeeds/cmd/cve-bulk-converter/cna_allowlist.txt b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/cna_allowlist.txt similarity index 100% rename from vulnfeeds/cmd/cve-bulk-converter/cna_allowlist.txt rename to vulnfeeds/cmd/converters/cve/cve5/bulk-converter/cna_allowlist.txt diff --git a/vulnfeeds/cmd/cve-bulk-converter/main.go b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go similarity index 88% rename from vulnfeeds/cmd/cve-bulk-converter/main.go rename to vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go index 9f34f7c4cf7..436eb93d978 100644 --- a/vulnfeeds/cmd/cve-bulk-converter/main.go +++ b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go @@ -9,18 +9,21 @@ import ( "os" "path/filepath" "slices" + "strconv" "strings" "sync" + "time" + "github.com/google/osv/vulnfeeds/conversion" "github.com/google/osv/vulnfeeds/cvelist2osv" - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility/logger" ) var ( repoDir = flag.String("cve5-repo", "cvelistV5", "CVEListV5 directory path") localOutputDir = flag.String("out-dir", "cvelist2osv", "Path to output results.") - years = flag.String("years", "2022,2023,2024,2025", "A comma-separated list of years to process.") + startYear = flag.String("start-year", "2022", "The first in scope year to process.") workers = flag.Int("workers", 30, "The number of concurrent workers to use for processing CVEs.") cnaAllowList = flag.String("cnas-allowlist", "", "A comma-separated list of CNAs to process. If not provided, defaults to cna_allowlist.txt.") rejectFailed = flag.Bool("reject-failed", false, "If set, OSV records with a failed conversion outcome will not be generated.") @@ -60,9 +63,11 @@ func main() { // Discover files and send them to the workers. logger.Info("Starting conversion of CVEs...") + currentYear := time.Now().Year() + startYearInt, _ := strconv.Atoi(*startYear) - yearList := strings.Split(*years, ",") - for _, year := range yearList { + for year := startYearInt; year <= currentYear; year++ { + year := strconv.Itoa(year) yearDir := filepath.Join(*repoDir, "cves", year) if _, err := os.Stat(yearDir); os.IsNotExist(err) { logger.Info("Directory for year not found, skipping", slog.String("year", year)) @@ -88,7 +93,7 @@ func main() { close(jobs) wg.Wait() - logger.Info("Conversion run complete") + logger.Info("CVE5 Conversion run complete") } // worker is a function that processes CVE files from the jobs channel. @@ -101,7 +106,7 @@ func worker(wg *sync.WaitGroup, jobs <-chan string, outDir string, cnas []string continue } - var cve cves.CVE5 + var cve models.CVE5 if err := json.Unmarshal(data, &cve); err != nil { logger.Info("Failed to unmarshal JSON", slog.String("path", path), slog.Any("err", err)) continue @@ -113,8 +118,8 @@ func worker(wg *sync.WaitGroup, jobs <-chan string, outDir string, cnas []string cveID := cve.Metadata.CVEID logger.Info("Processing "+string(cveID), slog.String("cve", string(cveID))) - osvFile, errCVE := cvelist2osv.CreateOSVFile(cveID, outDir) - metricsFile, errMetrics := cvelist2osv.CreateMetricsFile(cveID, outDir) + osvFile, errCVE := conversion.CreateOSVFile(cveID, outDir) + metricsFile, errMetrics := conversion.CreateMetricsFile(cveID, outDir) if errCVE != nil || errMetrics != nil { logger.Fatal("File failed to be created for CVE", slog.String("cve", string(cveID))) } diff --git a/vulnfeeds/cmd/cve-bulk-converter/run-cvelist-converter.sh b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/run-cvelist-converter.sh similarity index 98% rename from vulnfeeds/cmd/cve-bulk-converter/run-cvelist-converter.sh rename to vulnfeeds/cmd/converters/cve/cve5/bulk-converter/run-cvelist-converter.sh index a035bb9d850..41e182d191a 100755 --- a/vulnfeeds/cmd/cve-bulk-converter/run-cvelist-converter.sh +++ b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/run-cvelist-converter.sh @@ -53,7 +53,7 @@ fi # Convert CVEList records to OSV. echo "Commence CVEList bulk conversion run" ./cve-bulk-converter \ - --years="2022,2023,2024,2025" \ + --start-year="2022" \ --out-dir="${LOCAL_OUT_DIR}/${OSV_OUTPUT_PATH}" \ --workers="${NUM_WORKERS}" diff --git a/vulnfeeds/cmd/cve-single-converter/main.go b/vulnfeeds/cmd/converters/cve/cve5/single-converter/main.go similarity index 86% rename from vulnfeeds/cmd/cve-single-converter/main.go rename to vulnfeeds/cmd/converters/cve/cve5/single-converter/main.go index a2af6573492..682e7feb0a6 100644 --- a/vulnfeeds/cmd/cve-single-converter/main.go +++ b/vulnfeeds/cmd/converters/cve/cve5/single-converter/main.go @@ -7,8 +7,9 @@ import ( "log/slog" "os" + "github.com/google/osv/vulnfeeds/conversion" "github.com/google/osv/vulnfeeds/cvelist2osv" - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility/logger" ) @@ -28,7 +29,7 @@ func main() { logger.Fatal("Failed to open file", slog.Any("err", err)) } - var cve cves.CVE5 + var cve models.CVE5 if err = json.Unmarshal(data, &cve); err != nil { logger.Fatal("Failed to parse CVEList CVE JSON", slog.Any("err", err)) } @@ -44,8 +45,8 @@ func main() { } // create the files - osvFile, errCVE := cvelist2osv.CreateOSVFile(cveID, outDir) - metricsFile, errMetrics := cvelist2osv.CreateMetricsFile(cveID, outDir) + osvFile, errCVE := conversion.CreateOSVFile(cveID, outDir) + metricsFile, errMetrics := conversion.CreateMetricsFile(cveID, outDir) if errCVE != nil || errMetrics != nil { logger.Fatal("File failed to be created for CVE", slog.String("cve", string(cveID))) } diff --git a/vulnfeeds/cmd/nvd-cve-osv/Dockerfile b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/Dockerfile similarity index 68% rename from vulnfeeds/cmd/nvd-cve-osv/Dockerfile rename to vulnfeeds/cmd/converters/cve/nvd-cve-osv/Dockerfile index 333f3a5a664..12e520e2c57 100644 --- a/vulnfeeds/cmd/nvd-cve-osv/Dockerfile +++ b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD WORKDIR /go/src @@ -20,12 +20,12 @@ COPY go.mod go.sum ./ RUN go mod download && go mod verify COPY . . -RUN CGO_ENABLED=0 go build -v -o /usr/local/bin ./cmd/nvd-cve-osv ./cmd/download-cves +RUN CGO_ENABLED=0 go build -v -o /usr/local/bin ./cmd/converters/cve/nvd-cve-osv ./cmd/mirrors/download-cves -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed RUN apk --no-cache add jq COPY --from=GO_BUILD /usr/local/bin/ ./usr/local/bin/ -COPY --from=GO_BUILD /go/src/cmd/nvd-cve-osv/run_cve_to_osv_generation.sh ./usr/local/bin/ +COPY --from=GO_BUILD /go/src/cmd/converters/cve/nvd-cve-osv/run_cve_to_osv_generation.sh ./usr/local/bin/ CMD ["/usr/local/bin/run_cve_to_osv_generation.sh"] diff --git a/vulnfeeds/cmd/nvd-cve-osv/README.md b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/README.md similarity index 100% rename from vulnfeeds/cmd/nvd-cve-osv/README.md rename to vulnfeeds/cmd/converters/cve/nvd-cve-osv/README.md diff --git a/vulnfeeds/cmd/nvd-cve-osv/build.sh b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/build.sh similarity index 93% rename from vulnfeeds/cmd/nvd-cve-osv/build.sh rename to vulnfeeds/cmd/converters/cve/nvd-cve-osv/build.sh index 9720c0dad53..5dc5ba89abb 100755 --- a/vulnfeeds/cmd/nvd-cve-osv/build.sh +++ b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/build.sh @@ -21,5 +21,5 @@ cd ../../ docker build \ -t gcr.io/oss-vdb/nvd-cve-osv:latest \ - -f cmd/nvd-cve-osv/Dockerfile --pull . && \ + -f cmd/cve/nvd-cve-osv/Dockerfile --pull . && \ gcloud docker -- push gcr.io/oss-vdb/nvd-cve-osv:latest diff --git a/vulnfeeds/cmd/converters/cve/nvd-cve-osv/main.go b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/main.go new file mode 100644 index 00000000000..8419f69ba74 --- /dev/null +++ b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/main.go @@ -0,0 +1,136 @@ +// nvd-cve-osv converts NVD CVEs to OSV format. +package main + +import ( + "encoding/json" + "errors" + "flag" + "fmt" + "log/slog" + "os" + "slices" + "sync" + + "github.com/google/osv/vulnfeeds/conversion/nvd" + "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/git" + "github.com/google/osv/vulnfeeds/models" + "github.com/google/osv/vulnfeeds/utility/logger" +) + +var ( + jsonPath = flag.String("nvd-json", "", "Path to NVD CVE JSON to examine.") + parsedCPEDictionary = flag.String("cpe-repos", "", "Path to JSON mapping of CPEs to repos generated by cpe-repo-gen") + outDir = flag.String("out-dir", "", "Path to output results.") + outFormat = flag.String("out-format", "OSV", "Format to output {OSV,PackageInfo}") + workers = flag.Int("workers", 30, "The number of concurrent workers to use for processing CVEs.") +) + +func loadCPEDictionary(productToRepo *cves.VPRepoCache, f string) error { + data, err := os.ReadFile(f) + if err != nil { + return err + } + + var tempMap cves.VendorProductToRepoMap + if err := json.Unmarshal(data, &tempMap); err != nil { + return err + } + productToRepo.Initialize(tempMap) + + return nil +} + +func main() { + flag.Parse() + if !slices.Contains([]string{"OSV", "PackageInfo"}, *outFormat) { + fmt.Fprintf(os.Stderr, "Unsupported output format: %s\n", *outFormat) + os.Exit(1) + } + + logger.InitGlobalLogger() + + data, err := os.ReadFile(*jsonPath) + if err != nil { + logger.Fatal("Failed to open file", slog.Any("err", err)) // double check this is best practice output + } + + var parsed models.CVEAPIJSON20Schema + err = json.Unmarshal(data, &parsed) + if err != nil { + logger.Fatal("Failed to parse NVD CVE JSON", slog.Any("err", err)) + } + + vpRepoCache := cves.NewVPRepoCache() + if *parsedCPEDictionary != "" { + err = loadCPEDictionary(vpRepoCache, *parsedCPEDictionary) + if err != nil { + logger.Fatal("Failed to load parsed CPE dictionary", slog.Any("err", err)) + } + logger.Info("VendorProductToRepoMap cache has entries preloaded") + } + + repoTagsCache := &git.RepoTagsCache{} + + jobs := make(chan models.NVDCVE) + var wg sync.WaitGroup + + for range *workers { + wg.Add(1) + go worker(&wg, jobs, *outDir, vpRepoCache, repoTagsCache) + } + + for _, cve := range parsed.Vulnerabilities { + jobs <- cve.CVE + } + + close(jobs) + wg.Wait() + logger.Info("NVD Conversion run complete") +} + +func processCVE(cve models.NVDCVE, vpRepoCache *cves.VPRepoCache, repoTagsCache *git.RepoTagsCache) error { + metrics := &models.ConversionMetrics{ + CVEID: cve.ID, + CNA: "nvd", + } + repos := nvd.FindRepos(cve, vpRepoCache, metrics) + metrics.Repos = repos + + var err error + switch *outFormat { + case "OSV": + err = nvd.CVEToOSV(cve, repos, repoTagsCache, *outDir, metrics) + case "PackageInfo": + err = nvd.CVEToPackageInfo(cve, repos, repoTagsCache, *outDir, metrics) + } + // Parse this error to determine which failure mode it was + if err != nil { + logger.Warn("Failed to generate an OSV record", slog.String("cve", string(cve.ID)), slog.Any("err", err)) + if errors.Is(err, nvd.ErrNoRanges) { + metrics.Outcome = models.NoRanges + return err + } + if errors.Is(err, nvd.ErrUnresolvedFix) { + metrics.Outcome = models.FixUnresolvable + return err + } + metrics.Outcome = models.ConversionUnknown + + return err + } + metrics.Outcome = models.Successful + + return nil +} + +func worker(wg *sync.WaitGroup, jobs <-chan models.NVDCVE, _ string, vpRepoCache *cves.VPRepoCache, repoTagsCache *git.RepoTagsCache) { + defer wg.Done() + for cve := range jobs { + if err := processCVE(cve, vpRepoCache, repoTagsCache); err != nil { + logger.Warn("Failed to generate an OSV record", slog.String("cve", string(cve.ID)), slog.Any("err", err)) + } else { + logger.Info("Generated OSV record for "+string(cve.ID), slog.String("cve", string(cve.ID))) + } + } +} diff --git a/vulnfeeds/cmd/nvd-cve-osv/run_cve_to_osv_generation.sh b/vulnfeeds/cmd/converters/cve/nvd-cve-osv/run_cve_to_osv_generation.sh similarity index 100% rename from vulnfeeds/cmd/nvd-cve-osv/run_cve_to_osv_generation.sh rename to vulnfeeds/cmd/converters/cve/nvd-cve-osv/run_cve_to_osv_generation.sh diff --git a/vulnfeeds/cmd/debian/Dockerfile b/vulnfeeds/cmd/converters/debian/Dockerfile similarity index 76% rename from vulnfeeds/cmd/debian/Dockerfile rename to vulnfeeds/cmd/converters/debian/Dockerfile index 92e1d5e7a6f..4d73051add8 100644 --- a/vulnfeeds/cmd/debian/Dockerfile +++ b/vulnfeeds/cmd/converters/debian/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD RUN mkdir /src WORKDIR /src @@ -22,14 +22,14 @@ COPY ./go.sum /src/go.sum RUN go mod download COPY ./ /src/ -RUN go build -o debian ./cmd/debian/ +RUN go build -o debian ./cmd/converters/debian/ -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed WORKDIR /root/ COPY --from=GO_BUILD /src/debian ./ -COPY ./cmd/debian/run_debian_convert.sh ./ +COPY ./cmd/converters/debian/run_debian_convert.sh ./ RUN chmod 755 ./run_debian_convert.sh diff --git a/vulnfeeds/cmd/debian/debian_security_tracker.go b/vulnfeeds/cmd/converters/debian/debian_security_tracker.go similarity index 100% rename from vulnfeeds/cmd/debian/debian_security_tracker.go rename to vulnfeeds/cmd/converters/debian/debian_security_tracker.go diff --git a/vulnfeeds/cmd/debian/main.go b/vulnfeeds/cmd/converters/debian/main.go similarity index 97% rename from vulnfeeds/cmd/debian/main.go rename to vulnfeeds/cmd/converters/debian/main.go index 3dad1d64479..6634f88c796 100644 --- a/vulnfeeds/cmd/debian/main.go +++ b/vulnfeeds/cmd/converters/debian/main.go @@ -14,7 +14,6 @@ import ( "strconv" "strings" - "github.com/google/osv/vulnfeeds/cves" "github.com/google/osv/vulnfeeds/faulttolerant" "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/upload" @@ -75,7 +74,7 @@ func main() { } // generateOSVFromDebianTracker converts Debian Security Tracker entries to OSV format. -func generateOSVFromDebianTracker(debianData DebianSecurityTrackerData, debianReleaseMap map[string]string, allCVEs map[cves.CVEID]cves.Vulnerability) map[string]*vulns.Vulnerability { +func generateOSVFromDebianTracker(debianData DebianSecurityTrackerData, debianReleaseMap map[string]string, allCVEs map[models.CVEID]models.Vulnerability) map[string]*vulns.Vulnerability { logger.Info("Converting Debian Security Tracker data to OSV.") osvCves := make(map[string]*vulns.Vulnerability) @@ -107,7 +106,7 @@ func generateOSVFromDebianTracker(debianData DebianSecurityTrackerData, debianRe continue } v, ok := osvCves[cveID] - currentNVDCVE := allCVEs[cves.CVEID(cveID)] + currentNVDCVE := allCVEs[models.CVEID(cveID)] if !ok { v = &vulns.Vulnerability{ Vulnerability: &osvschema.Vulnerability{ diff --git a/vulnfeeds/cmd/debian/main_test.go b/vulnfeeds/cmd/converters/debian/main_test.go similarity index 95% rename from vulnfeeds/cmd/debian/main_test.go rename to vulnfeeds/cmd/converters/debian/main_test.go index 8706a1b75c1..6635ea5e324 100644 --- a/vulnfeeds/cmd/debian/main_test.go +++ b/vulnfeeds/cmd/converters/debian/main_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvschema" "google.golang.org/protobuf/testing/protocmp" @@ -38,14 +38,14 @@ func sortAffected(affected []*osvschema.Affected) { }) } -func loadTestData(t *testing.T, cveName string) cves.Vulnerability { +func loadTestData(t *testing.T, cveName string) models.Vulnerability { t.Helper() - fileName := fmt.Sprintf("../../test_data/nvdcve-2.0/%s.json", cveName) + fileName := fmt.Sprintf("../../../test_data/nvdcve-2.0/%s.json", cveName) file, err := os.Open(fileName) if err != nil { t.Fatalf("Failed to load test data from %q: %#v", fileName, err) } - var nvdCves cves.CVEAPIJSON20Schema + var nvdCves models.CVEAPIJSON20Schema err = json.NewDecoder(file).Decode(&nvdCves) if err != nil { t.Fatalf("Failed to decode %q: %+v", fileName, err) @@ -57,7 +57,7 @@ func loadTestData(t *testing.T, cveName string) cves.Vulnerability { } t.Fatalf("test data doesn't contain %q", cveName) - return cves.Vulnerability{} + return models.Vulnerability{} } func TestGenerateOSVFromDebianTracker(t *testing.T) { @@ -65,7 +65,7 @@ func TestGenerateOSVFromDebianTracker(t *testing.T) { now := time.Date(2024, 7, 1, 0, 0, 0, 0, time.UTC) var trackerData DebianSecurityTrackerData - if err := json.Unmarshal(mustRead(t, "../../test_data/debian/debian_security_tracker_mock.json"), &trackerData); err != nil { + if err := json.Unmarshal(mustRead(t, "../../../test_data/debian/debian_security_tracker_mock.json"), &trackerData); err != nil { t.Fatalf("Failed to unmarshal test data: %v", err) } @@ -77,7 +77,7 @@ func TestGenerateOSVFromDebianTracker(t *testing.T) { "bookworm": "12", "trixie": "13", } - cveStuff := map[cves.CVEID]cves.Vulnerability{ + cveStuff := map[models.CVEID]models.Vulnerability{ "CVE-2014-1424": loadTestData(t, "CVE-2014-1424"), "CVE-2017-6507": loadTestData(t, "CVE-2017-6507"), "CVE-2016-1585": loadTestData(t, "CVE-2016-1585"), diff --git a/vulnfeeds/cmd/debian/run_debian_convert.sh b/vulnfeeds/cmd/converters/debian/run_debian_convert.sh similarity index 100% rename from vulnfeeds/cmd/debian/run_debian_convert.sh rename to vulnfeeds/cmd/converters/debian/run_debian_convert.sh diff --git a/vulnfeeds/cmd/cpe-repo-gen/Dockerfile b/vulnfeeds/cmd/mirrors/cpe-repo-gen/Dockerfile similarity index 74% rename from vulnfeeds/cmd/cpe-repo-gen/Dockerfile rename to vulnfeeds/cmd/mirrors/cpe-repo-gen/Dockerfile index 2f6e29a41fe..d710b2c3bb3 100644 --- a/vulnfeeds/cmd/cpe-repo-gen/Dockerfile +++ b/vulnfeeds/cmd/mirrors/cpe-repo-gen/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD RUN mkdir /src WORKDIR /src @@ -22,13 +22,13 @@ COPY ./go.sum /src/go.sum RUN go mod download COPY ./ /src/ -RUN CGO_ENABLED=0 go build -o cpe-repo-gen ./cmd/cpe-repo-gen +RUN CGO_ENABLED=0 go build -o cpe-repo-gen ./cmd/mirrors/cpe-repo-gen -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed RUN apk add --no-cache unzip COPY --from=GO_BUILD /src/cpe-repo-gen ./ -COPY ./cmd/cpe-repo-gen/cpe-repo-gen_map.sh ./ +COPY ./cmd/mirrors/cpe-repo-gen/cpe-repo-gen_map.sh ./ ENTRYPOINT ["/cpe-repo-gen_map.sh"] diff --git a/vulnfeeds/cmd/cpe-repo-gen/README.md b/vulnfeeds/cmd/mirrors/cpe-repo-gen/README.md similarity index 100% rename from vulnfeeds/cmd/cpe-repo-gen/README.md rename to vulnfeeds/cmd/mirrors/cpe-repo-gen/README.md diff --git a/vulnfeeds/cmd/cpe-repo-gen/build.sh b/vulnfeeds/cmd/mirrors/cpe-repo-gen/build.sh similarity index 100% rename from vulnfeeds/cmd/cpe-repo-gen/build.sh rename to vulnfeeds/cmd/mirrors/cpe-repo-gen/build.sh diff --git a/vulnfeeds/cmd/cpe-repo-gen/cpe-repo-gen_map.sh b/vulnfeeds/cmd/mirrors/cpe-repo-gen/cpe-repo-gen_map.sh similarity index 100% rename from vulnfeeds/cmd/cpe-repo-gen/cpe-repo-gen_map.sh rename to vulnfeeds/cmd/mirrors/cpe-repo-gen/cpe-repo-gen_map.sh diff --git a/vulnfeeds/cmd/cpe-repo-gen/main.go b/vulnfeeds/cmd/mirrors/cpe-repo-gen/main.go similarity index 100% rename from vulnfeeds/cmd/cpe-repo-gen/main.go rename to vulnfeeds/cmd/mirrors/cpe-repo-gen/main.go diff --git a/vulnfeeds/cmd/debian-copyright-mirror/Dockerfile b/vulnfeeds/cmd/mirrors/debian-copyright-mirror/Dockerfile similarity index 91% rename from vulnfeeds/cmd/debian-copyright-mirror/Dockerfile rename to vulnfeeds/cmd/mirrors/debian-copyright-mirror/Dockerfile index 79bf79f2170..e78c74ab7ca 100644 --- a/vulnfeeds/cmd/debian-copyright-mirror/Dockerfile +++ b/vulnfeeds/cmd/mirrors/debian-copyright-mirror/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed RUN apk add py3-yaml diff --git a/vulnfeeds/cmd/debian-copyright-mirror/build.sh b/vulnfeeds/cmd/mirrors/debian-copyright-mirror/build.sh similarity index 100% rename from vulnfeeds/cmd/debian-copyright-mirror/build.sh rename to vulnfeeds/cmd/mirrors/debian-copyright-mirror/build.sh diff --git a/vulnfeeds/cmd/debian-copyright-mirror/debian-copyright-mirror.py b/vulnfeeds/cmd/mirrors/debian-copyright-mirror/debian-copyright-mirror.py similarity index 100% rename from vulnfeeds/cmd/debian-copyright-mirror/debian-copyright-mirror.py rename to vulnfeeds/cmd/mirrors/debian-copyright-mirror/debian-copyright-mirror.py diff --git a/vulnfeeds/cmd/debian-copyright-mirror/debian-copyright-mirror.sh b/vulnfeeds/cmd/mirrors/debian-copyright-mirror/debian-copyright-mirror.sh similarity index 100% rename from vulnfeeds/cmd/debian-copyright-mirror/debian-copyright-mirror.sh rename to vulnfeeds/cmd/mirrors/debian-copyright-mirror/debian-copyright-mirror.sh diff --git a/vulnfeeds/cmd/download-cves/Dockerfile b/vulnfeeds/cmd/mirrors/download-cves/Dockerfile similarity index 75% rename from vulnfeeds/cmd/download-cves/Dockerfile rename to vulnfeeds/cmd/mirrors/download-cves/Dockerfile index ace462db631..947db494682 100644 --- a/vulnfeeds/cmd/download-cves/Dockerfile +++ b/vulnfeeds/cmd/mirrors/download-cves/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS GO_BUILD +FROM golang:1.25.6-alpine@sha256:d9b2e14101f27ec8d09674cd01186798d227bb0daec90e032aeb1cd22ac0f029 AS GO_BUILD RUN mkdir /src WORKDIR /src @@ -22,12 +22,12 @@ COPY ./go.sum /src/go.sum RUN go mod download COPY ./ /src/ -RUN go build -o download-cves ./cmd/download-cves/ +RUN go build -o download-cves ./cmd/mirrors/download-cves/ -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed WORKDIR /usr/local/bin COPY --from=GO_BUILD /src/download-cves ./ -COPY ./cmd/download-cves/mirror_nvd.sh ./ +COPY ./cmd/mirrors/download-cves/mirror_nvd.sh ./ ENTRYPOINT ["/usr/local/bin/mirror_nvd.sh"] diff --git a/vulnfeeds/cmd/download-cves/main.go b/vulnfeeds/cmd/mirrors/download-cves/main.go similarity index 97% rename from vulnfeeds/cmd/download-cves/main.go rename to vulnfeeds/cmd/mirrors/download-cves/main.go index 4a507225966..8df5b63d87a 100644 --- a/vulnfeeds/cmd/download-cves/main.go +++ b/vulnfeeds/cmd/mirrors/download-cves/main.go @@ -17,7 +17,7 @@ import ( "strconv" "time" - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility/logger" "github.com/sethvargo/go-retry" ) @@ -58,7 +58,7 @@ func main() { // Pages are offset based, this assumes the default (and maximum) page size of PageSize // Maintaining the recommended 6 seconds betweens calls is left to the caller. // See https://nvd.nist.gov/developers/vulnerabilities -func downloadCVE2FromAPIWithOffset(apiKey string, offset int) (page *cves.CVEAPIJSON20Schema, err error) { //nolint:unused +func downloadCVE2FromAPIWithOffset(apiKey string, offset int) (page *models.CVEAPIJSON20Schema, err error) { //nolint:unused client := &http.Client{} APIURL, err := url.Parse(NVDAPIEndpoint) if err != nil { @@ -125,8 +125,8 @@ func downloadCVE2FromAPI(apiKey string, cvePath string) { //nolint:unused logger.Fatal("Something went wrong when creating/opening file", slog.Any("err", err)) } defer file.Close() - var vulnerabilities []cves.Vulnerability - var page *cves.CVEAPIJSON20Schema + var vulnerabilities []models.Vulnerability + var page *models.CVEAPIJSON20Schema offset := 0 prevTotal := 0 for { diff --git a/vulnfeeds/cmd/download-cves/mirror_nvd.sh b/vulnfeeds/cmd/mirrors/download-cves/mirror_nvd.sh similarity index 100% rename from vulnfeeds/cmd/download-cves/mirror_nvd.sh rename to vulnfeeds/cmd/mirrors/download-cves/mirror_nvd.sh diff --git a/vulnfeeds/cmd/nvd-cve-osv/main.go b/vulnfeeds/cmd/nvd-cve-osv/main.go deleted file mode 100644 index 2878d2f6468..00000000000 --- a/vulnfeeds/cmd/nvd-cve-osv/main.go +++ /dev/null @@ -1,486 +0,0 @@ -// nvd-cve-osv converts NVD CVEs to OSV format. -package main - -import ( - "encoding/csv" - "encoding/json" - "errors" - "flag" - "fmt" - "log/slog" - "net/http" - "os" - "path/filepath" - "strings" - - "slices" - - "github.com/google/osv/vulnfeeds/cves" - "github.com/google/osv/vulnfeeds/git" - "github.com/google/osv/vulnfeeds/models" - "github.com/google/osv/vulnfeeds/utility/logger" - "github.com/google/osv/vulnfeeds/vulns" -) - -type ConversionOutcome int - -var ErrNoRanges = errors.New("no ranges") - -var ErrUnresolvedFix = errors.New("fixes not resolved to commits") - -func (c ConversionOutcome) String() string { - return [...]string{"ConversionUnknown", "Successful", "Rejected", "NoSoftware", "NoRepos", "NoRanges", "FixUnresolvable"}[c] -} - -const ( - extension = ".json" -) - -const ( - // Set of enums for categorizing conversion outcomes. - ConversionUnknown ConversionOutcome = iota // Shouldn't happen - Successful // It worked! - Rejected // The CVE was rejected - NoSoftware // The CVE had no CPEs relating to software (i.e. Operating Systems or Hardware). - NoRepos // The CPE Vendor/Product had no repositories derived for it. - NoRanges // No viable commit ranges could be calculated from the repository for the CVE's CPE(s). - FixUnresolvable // Partial resolution of versions, resulting in a false positive. -) - -var ( - jsonPath = flag.String("nvd-json", "", "Path to NVD CVE JSON to examine.") - parsedCPEDictionary = flag.String("cpe-repos", "", "Path to JSON mapping of CPEs to repos generated by cpe-repo-gen") - outDir = flag.String("out-dir", "", "Path to output results.") - outFormat = flag.String("out-format", "OSV", "Format to output {OSV,PackageInfo}") -) -var RepoTagsCache git.RepoTagsCache -var Metrics struct { - TotalCVEs int - CVEsForApplications int - CVEsForKnownRepos int - OSVRecordsGenerated int - Outcomes map[cves.CVEID]ConversionOutcome // Per-CVE-ID record of conversion result. -} - -// Takes an NVD CVE record and outputs an OSV file in the specified directory. -func CVEToOSV(cve cves.CVE, repos []string, cache git.RepoTagsCache, directory string) error { - CPEs := cves.CPEs(cve) - // The vendor name and product name are used to construct the output `vulnDir` below, so need to be set to *something* to keep the output tidy. - maybeVendorName := "ENOCPE" - maybeProductName := "ENOCPE" - - if len(CPEs) > 0 { - CPE, err := cves.ParseCPE(CPEs[0]) // For naming the subdirectory used for output. - maybeVendorName = CPE.Vendor - maybeProductName = CPE.Product - if err != nil { - return fmt.Errorf("[%s]: Can't generate an OSV record without valid CPE data", cve.ID) - } - } - - v := vulns.FromNVDCVE(cve.ID, cve) - versions, notes := cves.ExtractVersionInfo(cve, nil, http.DefaultClient) - - if len(versions.AffectedVersions) != 0 { - var err error - // There are some AffectedVersions to try and resolve to AffectedCommits. - if len(repos) == 0 { - return fmt.Errorf("[%s]: No affected ranges for %q, and no repos to try and convert %+v to tags with", cve.ID, maybeProductName, versions.AffectedVersions) - } - logger.Info("Trying to convert version tags to commits", slog.String("cve", string(cve.ID)), slog.Any("versions", versions), slog.Any("repos", repos)) - versions, err = cves.GitVersionsToCommits(cve.ID, versions, repos, cache) - if err != nil { - return fmt.Errorf("[%s]: Failed to convert version tags to commits: %#w", cve.ID, err) - } - hasAnyFixedCommits := false - for _, repo := range repos { - if versions.HasFixedCommits(repo) { - hasAnyFixedCommits = true - break - } - } - - if versions.HasFixedVersions() && !hasAnyFixedCommits { - return fmt.Errorf("[%s]: Failed to convert fixed version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) - } - - hasAnyLastAffectedCommits := false - for _, repo := range repos { - if versions.HasLastAffectedCommits(repo) { - hasAnyLastAffectedCommits = true - break - } - } - - if versions.HasLastAffectedVersions() && !hasAnyLastAffectedCommits && !hasAnyFixedCommits { - return fmt.Errorf("[%s]: Failed to convert last_affected version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) - } - } - - slices.SortStableFunc(versions.AffectedCommits, models.AffectedCommitCompare) - - vulns.AttachExtractedVersionInfo(v, versions) - - if len(v.Affected) == 0 { - return fmt.Errorf("[%s]: No affected ranges detected for %q %w", cve.ID, maybeProductName, ErrNoRanges) - } - - vulnDir := filepath.Join(directory, maybeVendorName, maybeProductName) - err := os.MkdirAll(vulnDir, 0755) - if err != nil { - logger.Warn("Failed to create dir", slog.Any("err", err)) - return fmt.Errorf("failed to create dir: %w", err) - } - outputFile := filepath.Join(vulnDir, v.Id+extension) - notesFile := filepath.Join(vulnDir, v.Id+".notes") - f, err := os.Create(outputFile) - if err != nil { - logger.Warn("Failed to open for writing", slog.String("path", outputFile), slog.Any("err", err)) - return fmt.Errorf("failed to open %s for writing: %w", outputFile, err) - } - defer f.Close() - err = v.ToJSON(f) - if err != nil { - logger.Warn("Failed to write", slog.String("path", outputFile), slog.Any("err", err)) - return fmt.Errorf("failed to write %s: %w", outputFile, err) - } - logger.Info("Generated OSV record", slog.String("cve", string(cve.ID)), slog.String("product", maybeProductName)) - if len(notes) > 0 { - err = os.WriteFile(notesFile, []byte(strings.Join(notes, "\n")), 0600) - if err != nil { - logger.Warn("Failed to write", slog.String("cve", string(cve.ID)), slog.String("path", notesFile), slog.Any("err", err)) - } - } - - return nil -} - -// Takes an NVD CVE record and outputs a PackageInfo struct in a file in the specified directory. -func CVEToPackageInfo(cve cves.CVE, repos []string, cache git.RepoTagsCache, directory string) error { - CPEs := cves.CPEs(cve) - // The vendor name and product name are used to construct the output `vulnDir` below, so need to be set to *something* to keep the output tidy. - maybeVendorName := "ENOCPE" - maybeProductName := "ENOCPE" - - if len(CPEs) > 0 { - CPE, err := cves.ParseCPE(CPEs[0]) // For naming the subdirectory used for output. - maybeVendorName = CPE.Vendor - maybeProductName = CPE.Product - if err != nil { - return fmt.Errorf("[%s]: Can't generate an OSV record without valid CPE data", cve.ID) - } - } - - // more often than not, this yields a VersionInfo with AffectedVersions and no AffectedCommits. - versions, notes := cves.ExtractVersionInfo(cve, nil, http.DefaultClient) - - if len(versions.AffectedVersions) != 0 { - var err error - // There are some AffectedVersions to try and resolve to AffectedCommits. - if len(repos) == 0 { - return fmt.Errorf("[%s]: No affected ranges for %q, and no repos to try and convert %+v to tags with", cve.ID, maybeProductName, versions.AffectedVersions) - } - logger.Info("Trying to convert version tags to commits", slog.String("cve", string(cve.ID)), slog.Any("versions", versions), slog.Any("repos", repos)) - versions, err = cves.GitVersionsToCommits(cve.ID, versions, repos, cache) - if err != nil { - return fmt.Errorf("[%s]: Failed to convert version tags to commits: %#w", cve.ID, err) - } - } - - hasAnyFixedCommits := false - for _, repo := range repos { - if versions.HasFixedCommits(repo) { - hasAnyFixedCommits = true - } - } - - if versions.HasFixedVersions() && !hasAnyFixedCommits { - return fmt.Errorf("[%s]: Failed to convert fixed version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) - } - - hasAnyLastAffectedCommits := false - for _, repo := range repos { - if versions.HasLastAffectedCommits(repo) { - hasAnyLastAffectedCommits = true - } - } - - if versions.HasLastAffectedVersions() && !hasAnyLastAffectedCommits && !hasAnyFixedCommits { - return fmt.Errorf("[%s]: Failed to convert last_affected version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) - } - - if len(versions.AffectedCommits) == 0 { - return fmt.Errorf("[%s]: No affected commit ranges determined for %q %w", cve.ID, maybeProductName, ErrNoRanges) - } - - versions.AffectedVersions = nil // these have served their purpose and are not required in the resulting output. - - slices.SortStableFunc(versions.AffectedCommits, models.AffectedCommitCompare) - - var pkgInfos []vulns.PackageInfo - pi := vulns.PackageInfo{VersionInfo: versions} - pkgInfos = append(pkgInfos, pi) // combine-to-osv expects a serialised *array* of PackageInfo - - vulnDir := filepath.Join(directory, maybeVendorName, maybeProductName) - err := os.MkdirAll(vulnDir, 0755) - if err != nil { - logger.Warn("Failed to create dir", slog.Any("err", err)) - return fmt.Errorf("failed to create dir: %w", err) - } - - outputFile := filepath.Join(vulnDir, string(cve.ID)+".nvd"+extension) - notesFile := filepath.Join(vulnDir, string(cve.ID)+".nvd.notes") - f, err := os.Create(outputFile) - if err != nil { - logger.Warn("Failed to open for writing", slog.String("path", outputFile), slog.Any("err", err)) - return fmt.Errorf("failed to open %s for writing: %w", outputFile, err) - } - defer f.Close() - - encoder := json.NewEncoder(f) - encoder.SetIndent("", " ") - err = encoder.Encode(&pkgInfos) - - if err != nil { - logger.Warn("Failed to encode PackageInfo", slog.String("path", outputFile), slog.Any("err", err)) - return fmt.Errorf("failed to encode PackageInfo to %s: %w", outputFile, err) - } - - logger.Info("Generated PackageInfo record", slog.String("cve", string(cve.ID)), slog.String("product", maybeProductName)) - - if len(notes) > 0 { - err = os.WriteFile(notesFile, []byte(strings.Join(notes, "\n")), 0600) - if err != nil { - logger.Warn("Failed to write", slog.String("cve", string(cve.ID)), slog.String("path", notesFile), slog.Any("err", err)) - } - } - - return nil -} - -func loadCPEDictionary(productToRepo *cves.VendorProductToRepoMap, f string) error { - data, err := os.ReadFile(f) - if err != nil { - return err - } - - return json.Unmarshal(data, &productToRepo) -} - -// Output a CSV summarizing per-CVE how it was handled. -func outputOutcomes(outcomes map[cves.CVEID]ConversionOutcome, reposForCVE map[cves.CVEID][]string, directory string) error { - outcomesFile, err := os.Create(filepath.Join(directory, "outcomes.csv")) - if err != nil { - return err - } - defer outcomesFile.Close() - w := csv.NewWriter(outcomesFile) - if err := w.Write([]string{"CVE", "outcome", "repos"}); err != nil { - return err - } - for CVE, outcome := range outcomes { - // It's conceivable to have more than one repo for a CVE, so concatenate them. - r := "" - if repos, ok := reposForCVE[CVE]; ok { - r = strings.Join(repos, " ") - } - if err := w.Write([]string{string(CVE), outcome.String(), r}); err != nil { - return err - } - } - w.Flush() - - if err = w.Error(); err != nil { - return err - } - - return nil -} - -func main() { - flag.Parse() - if !slices.Contains([]string{"OSV", "PackageInfo"}, *outFormat) { - fmt.Fprintf(os.Stderr, "Unsupported output format: %s\n", *outFormat) - os.Exit(1) - } - - Metrics.Outcomes = make(map[cves.CVEID]ConversionOutcome) - - logger.InitGlobalLogger() - - data, err := os.ReadFile(*jsonPath) - if err != nil { - logger.Fatal("Failed to open file", slog.Any("err", err)) // double check this is best practice output - } - - var parsed cves.CVEAPIJSON20Schema - err = json.Unmarshal(data, &parsed) - if err != nil { - logger.Fatal("Failed to parse NVD CVE JSON", slog.Any("err", err)) - } - - VPRepoCache := make(cves.VendorProductToRepoMap) - - if *parsedCPEDictionary != "" { - err = loadCPEDictionary(&VPRepoCache, *parsedCPEDictionary) - if err != nil { - logger.Fatal("Failed to load parsed CPE dictionary", slog.Any("err", err)) - } - logger.Info("VendorProductToRepoMap cache has entries preloaded", slog.Int("count", len(VPRepoCache))) - } - - ReposForCVE := make(map[cves.CVEID][]string) - - for _, cve := range parsed.Vulnerabilities { - refs := cve.CVE.References - CPEs := cves.CPEs(cve.CVE) - CVEID := cve.CVE.ID - - if len(refs) == 0 && len(CPEs) == 0 { - logger.Info("Skipping due to lack of CPEs and lack of references", slog.String("cve", string(CVEID))) - // 100% of these in 2022 were rejected CVEs - Metrics.Outcomes[CVEID] = Rejected - - continue - } - - // Edge case: No CPEs, but perhaps usable references. - if len(refs) > 0 && len(CPEs) == 0 { - repos := cves.ReposFromReferences(string(CVEID), nil, nil, refs, cves.RefTagDenyList) - if len(repos) == 0 { - logger.Warn("Failed to derive any repos and there were no CPEs", slog.String("cve", string(CVEID))) - continue - } - logger.Info("Derived repos for CVE with no CPEs", slog.String("cve", string(CVEID)), slog.Any("repos", repos)) - ReposForCVE[CVEID] = repos - } - - // Does it have any application CPEs? Look for pre-computed repos based on VendorProduct. - appCPECount := 0 - for _, CPEstr := range cves.CPEs(cve.CVE) { - CPE, err := cves.ParseCPE(CPEstr) - if err != nil { - logger.Warn("Failed to parse CPE", slog.String("cve", string(CVEID)), slog.String("cpe", CPEstr), slog.Any("err", err)) - Metrics.Outcomes[CVEID] = ConversionUnknown - - continue - } - if CPE.Part == "a" { - appCPECount += 1 - } - vendorProductKey := cves.VendorProduct{Vendor: CPE.Vendor, Product: CPE.Product} - if _, ok := VPRepoCache[vendorProductKey]; ok { - logger.Info("Pre-references, derived repos using cache", slog.String("cve", string(CVEID)), slog.Any("repos", VPRepoCache[vendorProductKey]), slog.String("vendor", CPE.Vendor), slog.String("product", CPE.Product)) - if _, ok := ReposForCVE[CVEID]; !ok { - ReposForCVE[CVEID] = VPRepoCache[vendorProductKey] - continue - } - // Don't append duplicates. - for _, repo := range VPRepoCache[vendorProductKey] { - if !slices.Contains(ReposForCVE[CVEID], repo) { - ReposForCVE[CVEID] = append(ReposForCVE[CVEID], repo) - } - } - } - } - - if len(CPEs) > 0 && appCPECount == 0 { - // This CVE is not for software (based on there being CPEs but not any application ones), skip. - Metrics.Outcomes[CVEID] = NoSoftware - continue - } - - if appCPECount > 0 { - Metrics.CVEsForApplications++ - } - - // If there wasn't a repo from the CPE Dictionary, try and derive one from the CVE references. - if _, ok := ReposForCVE[CVEID]; !ok && len(refs) > 0 { - for _, CPEstr := range cves.CPEs(cve.CVE) { - CPE, err := cves.ParseCPE(CPEstr) - if err != nil { - logger.Warn("Failed to parse CPE", slog.String("cve", string(CVEID)), slog.String("cpe", CPEstr), slog.Any("err", err)) - continue - } - // Continue to only focus on application CPEs. - if CPE.Part != "a" { - continue - } - if slices.Contains(cves.VendorProductDenyList, cves.VendorProduct{Vendor: CPE.Vendor, Product: ""}) { - continue - } - if slices.Contains(cves.VendorProductDenyList, cves.VendorProduct{Vendor: CPE.Vendor, Product: CPE.Product}) { - continue - } - repos := cves.ReposFromReferences(string(CVEID), VPRepoCache, &cves.VendorProduct{Vendor: CPE.Vendor, Product: CPE.Product}, refs, cves.RefTagDenyList) - if len(repos) == 0 { - logger.Warn("Failed to derive any repos", slog.String("cve", string(CVEID)), slog.String("vendor", CPE.Vendor), slog.String("product", CPE.Product)) - continue - } - logger.Info("Derived repos", slog.String("cve", string(CVEID)), slog.Any("repos", repos), slog.String("vendor", CPE.Vendor), slog.String("product", CPE.Product)) - ReposForCVE[CVEID] = repos - } - } - - logger.Info("Finished processing "+string(CVEID), - slog.String("cve", string(CVEID)), - slog.Int("cpes", len(CPEs)), - slog.Int("app_cpes", appCPECount), - slog.Int("derived_repos", len(ReposForCVE[CVEID]))) - - // If we've made it to here, we may have a CVE: - // * that has Application-related CPEs (so applies to software) - // * has a reference that is a known repository URL - // OR - // * a derived repository for the software package - // - // We do not yet have: - // * any knowledge of the language used - // * definitive version information - - if _, ok := ReposForCVE[CVEID]; !ok { - // We have nothing useful to work with, so we'll assume it's out of scope - logger.Info("Passing due to lack of viable repository", slog.String("cve", string(CVEID))) - Metrics.Outcomes[CVEID] = NoRepos - - continue - } - - logger.Info("Found Repos for CVE "+string(CVEID), slog.String("cve", string(CVEID)), slog.Any("repos", ReposForCVE[CVEID])) - - Metrics.CVEsForKnownRepos++ - - switch *outFormat { - case "OSV": - err = CVEToOSV(cve.CVE, ReposForCVE[CVEID], RepoTagsCache, *outDir) - case "PackageInfo": - err = CVEToPackageInfo(cve.CVE, ReposForCVE[CVEID], RepoTagsCache, *outDir) - } - // Parse this error to determine which failure mode it was - if err != nil { - logger.Warn("Failed to generate an OSV record", slog.String("cve", string(CVEID)), slog.Any("err", err)) - if errors.Is(err, ErrNoRanges) { - Metrics.Outcomes[CVEID] = NoRanges - continue - } - if errors.Is(err, ErrUnresolvedFix) { - Metrics.Outcomes[CVEID] = FixUnresolvable - continue - } - Metrics.Outcomes[CVEID] = ConversionUnknown - - continue - } - Metrics.OSVRecordsGenerated++ - Metrics.Outcomes[CVEID] = Successful - } - Metrics.TotalCVEs = len(parsed.Vulnerabilities) - err = outputOutcomes(Metrics.Outcomes, ReposForCVE, *outDir) - if err != nil { - // Log entry with size 1.15M exceeds maximum size of 256.0K - fmt.Fprintf(os.Stderr, "Failed to write out metrics: %v", err) - } - // Outcomes is too big to log, so zero it out. - Metrics.Outcomes = nil - logger.Info("Metrics", slog.String("path", filepath.Base(*jsonPath)), slog.Any("metrics", Metrics)) -} diff --git a/vulnfeeds/cmd/pypi/main.go b/vulnfeeds/cmd/pypi/main.go index 10d9050aa20..f1a5f440840 100644 --- a/vulnfeeds/cmd/pypi/main.go +++ b/vulnfeeds/cmd/pypi/main.go @@ -27,6 +27,7 @@ import ( "strings" "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/pypi" "github.com/google/osv/vulnfeeds/triage" "github.com/google/osv/vulnfeeds/utility/logger" @@ -115,7 +116,7 @@ func main() { if err != nil { logger.Fatal("Failed to open file", slog.Any("err", err)) } - var parsed cves.CVEAPIJSON20Schema + var parsed models.CVEAPIJSON20Schema err = json.Unmarshal(data, &parsed) if err != nil { logger.Fatal("Failed to parse NVD CVE JSON", slog.Any("err", err)) @@ -164,10 +165,12 @@ func main() { Ecosystem: "PyPI", PURL: purl, } - + metrics := &models.ConversionMetrics{ + CVEID: cve.CVE.ID, + } v := vulns.FromNVDCVE(id, cve.CVE) v.AddPkgInfo(pkgInfo) - versions, notes := cves.ExtractVersionInfo(cve.CVE, validVersions, http.DefaultClient) + versions := cves.ExtractVersionInfo(cve.CVE, validVersions, http.DefaultClient, metrics) vulns.AttachExtractedVersionInfo(v, versions) if len(v.Affected[0].GetRanges()) == 0 { @@ -191,7 +194,7 @@ func main() { continue } - if len(notes) > 0 && *withoutNotes { + if len(metrics.Notes) > 0 && *withoutNotes { logger.Info("Skipping as there are notes associated with it", slog.String("path", vulnPath)) continue } @@ -207,9 +210,9 @@ func main() { } // If there are notes that require human intervention, write them to the end of the YAML. - if len(notes) > 0 { + if len(metrics.Notes) > 0 { notesPath := filepath.Join(pkgDir, v.Id+".notes") - _, err = f.WriteString("\n# \n# " + strings.Join(notes, "\n# ")) + _, err = f.WriteString("\n# \n# " + strings.Join(metrics.Notes, "\n# ")) if err != nil { logger.Panic("Failed to write", slog.String("path", notesPath), slog.Any("err", err)) } diff --git a/vulnfeeds/conversion/common.go b/vulnfeeds/conversion/common.go new file mode 100644 index 00000000000..22639351f4f --- /dev/null +++ b/vulnfeeds/conversion/common.go @@ -0,0 +1,113 @@ +// Package conversion implements common utilities for converting vulnerability data +// from various sources into the OSV schema. +package conversion + +import ( + "encoding/json" + "fmt" + "log/slog" + "os" + "path/filepath" + "slices" + "strings" + + "github.com/google/osv/vulnfeeds/models" + "github.com/google/osv/vulnfeeds/utility/logger" + "github.com/google/osv/vulnfeeds/vulns" + "github.com/ossf/osv-schema/bindings/go/osvschema" +) + +// AddAffected adds an osvschema.Affected to a vulnerability, ensuring that no duplicate ranges are added. +func AddAffected(v *vulns.Vulnerability, aff *osvschema.Affected, metrics *models.ConversionMetrics) { + allExistingRanges := make(map[string]struct{}) + for _, existingAff := range v.Affected { + for _, r := range existingAff.GetRanges() { + rangeBytes, err := json.Marshal(r) + if err == nil { + allExistingRanges[string(rangeBytes)] = struct{}{} + } + } + } + + uniqueRanges := []*osvschema.Range{} + for _, r := range aff.GetRanges() { + rangeBytes, err := json.Marshal(r) + if err != nil { + metrics.AddNote("Could not marshal range to check for duplicates, adding anyway: %+v", r) + uniqueRanges = append(uniqueRanges, r) + + continue + } + rangeStr := string(rangeBytes) + if _, exists := allExistingRanges[rangeStr]; !exists { + uniqueRanges = append(uniqueRanges, r) + allExistingRanges[rangeStr] = struct{}{} + } else { + metrics.AddNote("Skipping duplicate range: %+v", r) + } + } + + if len(uniqueRanges) > 0 { + newAff := &osvschema.Affected{ + Package: aff.GetPackage(), + Ranges: uniqueRanges, + DatabaseSpecific: aff.GetDatabaseSpecific(), + } + v.Affected = append(v.Affected, newAff) + } +} + +func DeduplicateRefs(refs []models.Reference) []models.Reference { + // Deduplicate references by URL. + slices.SortStableFunc(refs, func(a, b models.Reference) int { + return strings.Compare(a.URL, b.URL) + }) + refs = slices.CompactFunc(refs, func(a, b models.Reference) bool { + return a.URL == b.URL + }) + + return refs +} + +// CreateMetricsFile creates the initial file for the metrics record. +func CreateMetricsFile(id models.CVEID, vulnDir string) (*os.File, error) { + metricsFile := filepath.Join(vulnDir, string(id)+".metrics"+models.Extension) + f, err := os.Create(metricsFile) + if err != nil { + logger.Info("Failed to open for writing "+metricsFile, slog.String("cve", string(id)), slog.String("path", metricsFile), slog.Any("err", err)) + return nil, err + } + + return f, nil +} + +// CreateOSVFile creates the initial file for the OSV record. +func CreateOSVFile(id models.CVEID, vulnDir string) (*os.File, error) { + outputFile := filepath.Join(vulnDir, string(id)+models.Extension) + + f, err := os.Create(outputFile) + if err != nil { + logger.Info("Failed to open for writing "+outputFile, slog.String("cve", string(id)), slog.String("path", outputFile), slog.Any("err", err)) + return nil, err + } + + return f, err +} + +func WriteMetricsFile(metrics *models.ConversionMetrics, metricsFile *os.File) error { + marshalledMetrics, err := json.MarshalIndent(&metrics, "", " ") + if err != nil { + logger.Info("Failed to marshal", slog.Any("err", err)) + return err + } + + _, err = metricsFile.Write(marshalledMetrics) + if err != nil { + logger.Warn("Failed to write", slog.String("path", metricsFile.Name()), slog.Any("err", err)) + return fmt.Errorf("failed to write %s: %w", metricsFile.Name(), err) + } + + metricsFile.Close() + + return nil +} diff --git a/vulnfeeds/cvelist2osv/grouping.go b/vulnfeeds/conversion/grouping.go similarity index 97% rename from vulnfeeds/cvelist2osv/grouping.go rename to vulnfeeds/conversion/grouping.go index d5ff5cfa708..48f0b4546c9 100644 --- a/vulnfeeds/cvelist2osv/grouping.go +++ b/vulnfeeds/conversion/grouping.go @@ -1,4 +1,4 @@ -package cvelist2osv +package conversion import ( "fmt" @@ -11,11 +11,11 @@ import ( "google.golang.org/protobuf/types/known/structpb" ) -// groupAffectedRanges groups ranges that share the same introduced value, type, and repo. +// GroupAffectedRanges groups ranges that share the same introduced value, type, and repo. // This is because having multiple ranges with the same introduced value would act like an // OR condition, rather than AND. // This function modifies in-place -func groupAffectedRanges(affected []*osvschema.Affected) { +func GroupAffectedRanges(affected []*osvschema.Affected) { for _, aff := range affected { if len(aff.GetRanges()) <= 1 { continue diff --git a/vulnfeeds/cvelist2osv/grouping_test.go b/vulnfeeds/conversion/grouping_test.go similarity index 99% rename from vulnfeeds/cvelist2osv/grouping_test.go rename to vulnfeeds/conversion/grouping_test.go index 3d5876e4976..62d057dcc94 100644 --- a/vulnfeeds/cvelist2osv/grouping_test.go +++ b/vulnfeeds/conversion/grouping_test.go @@ -1,4 +1,4 @@ -package cvelist2osv +package conversion import ( "testing" @@ -423,7 +423,7 @@ func TestGroupAffectedRanges(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - groupAffectedRanges(tt.affected) + GroupAffectedRanges(tt.affected) if diff := cmp.Diff(tt.want, tt.affected, protocmp.Transform()); diff != "" { t.Errorf("groupAffectedRanges() mismatch (-want +got):\n%s", diff) } diff --git a/vulnfeeds/conversion/nvd/converter.go b/vulnfeeds/conversion/nvd/converter.go new file mode 100644 index 00000000000..e8a55e6c08f --- /dev/null +++ b/vulnfeeds/conversion/nvd/converter.go @@ -0,0 +1,349 @@ +// Package nvd converts NVD CVEs to OSV format. +package nvd + +import ( + "encoding/json" + "errors" + "fmt" + "log/slog" + "net/http" + "os" + "path/filepath" + "slices" + + "github.com/google/osv/vulnfeeds/conversion" + "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/git" + "github.com/google/osv/vulnfeeds/models" + "github.com/google/osv/vulnfeeds/utility/logger" + "github.com/google/osv/vulnfeeds/vulns" +) + +var ErrNoRanges = errors.New("no ranges") + +var ErrUnresolvedFix = errors.New("fixes not resolved to commits") + +// CVEToOSV Takes an NVD CVE record and outputs an OSV file in the specified directory. +func CVEToOSV(cve models.NVDCVE, repos []string, cache *git.RepoTagsCache, directory string, metrics *models.ConversionMetrics) error { + CPEs := cves.CPEs(cve) + metrics.CPEs = CPEs + // The vendor name and product name are used to construct the output `vulnDir` below, so need to be set to *something* to keep the output tidy. + maybeVendorName := "ENOCPE" + maybeProductName := "ENOCPE" + + if len(CPEs) > 0 { + CPE, err := cves.ParseCPE(CPEs[0]) // For naming the subdirectory used for output. + maybeVendorName = CPE.Vendor + maybeProductName = CPE.Product + if err != nil { + return fmt.Errorf("[%s]: Can't generate an OSV record without valid CPE data", cve.ID) + } + } + + v := vulns.FromNVDCVE(cve.ID, cve) + versions := cves.ExtractVersionInfo(cve, nil, http.DefaultClient, metrics) + + if len(versions.AffectedVersions) != 0 { + var err error + // There are some AffectedVersions to try and resolve to AffectedCommits. + if len(repos) == 0 { + metrics.AddNote("No affected ranges for %q, and no repos to try and convert %+v to tags with", maybeProductName, versions.AffectedVersions) + return fmt.Errorf("[%s]: No affected ranges for %q, and no repos to try and convert %+v to tags with", cve.ID, maybeProductName, versions.AffectedVersions) + } + metrics.AddNote("Trying to convert version tags to commits: %v with repos: %v", versions, repos) + versions, err = cves.GitVersionsToCommits(cve.ID, versions, repos, cache, metrics) + if err != nil { + metrics.AddNote("Failed to convert version tags to commits: %#v", err) + return fmt.Errorf("[%s]: Failed to convert version tags to commits: %#w", cve.ID, err) + } + hasAnyFixedCommits := false + for _, repo := range repos { + if versions.HasFixedCommits(repo) { + hasAnyFixedCommits = true + break + } + } + + if versions.HasFixedVersions() && !hasAnyFixedCommits { + metrics.AddNote("Failed to convert fixed version tags to commits: %#v", versions) + return fmt.Errorf("[%s]: Failed to convert fixed version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) + } + + hasAnyLastAffectedCommits := false + for _, repo := range repos { + if versions.HasLastAffectedCommits(repo) { + hasAnyLastAffectedCommits = true + break + } + } + + if versions.HasLastAffectedVersions() && !hasAnyLastAffectedCommits && !hasAnyFixedCommits { + metrics.AddNote("Failed to convert last_affected version tags to commits: %#v", versions) + return fmt.Errorf("[%s]: Failed to convert last_affected version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) + } + } + + slices.SortStableFunc(versions.AffectedCommits, models.AffectedCommitCompare) + + vulns.AttachExtractedVersionInfo(v, versions) + + if len(v.Affected) == 0 { + metrics.AddNote("No affected ranges detected for %q", maybeProductName) + return fmt.Errorf("[%s]: No affected ranges detected for %q %w", cve.ID, maybeProductName, ErrNoRanges) + } + + vulnDir := filepath.Join(directory, maybeVendorName, maybeProductName) + + if err := os.MkdirAll(vulnDir, 0755); err != nil { + logger.Info("Failed to create directory "+vulnDir, slog.String("cve", string(cve.ID)), slog.String("path", vulnDir), slog.Any("err", err)) + } + osvFile, errCVE := conversion.CreateOSVFile(cve.ID, vulnDir) + metricsFile, errMetrics := conversion.CreateMetricsFile(cve.ID, vulnDir) + if errCVE != nil || errMetrics != nil { + logger.Fatal("File failed to be created for CVE", slog.String("cve", string(cve.ID))) + } + + err := v.ToJSON(osvFile) + if err != nil { + logger.Info("Failed to write", slog.Any("err", err)) + return err + } + + logger.Info("Generated OSV record", slog.String("cve", string(cve.ID)), slog.String("product", maybeProductName)) + osvFile.Close() + + err = conversion.WriteMetricsFile(metrics, metricsFile) + if err != nil { + return err + } + + return nil +} + +// CVEToPackageInfo takes an NVD CVE record and outputs a PackageInfo struct in a file in the specified directory. +func CVEToPackageInfo(cve models.NVDCVE, repos []string, cache *git.RepoTagsCache, directory string, metrics *models.ConversionMetrics) error { + CPEs := cves.CPEs(cve) + // The vendor name and product name are used to construct the output `vulnDir` below, so need to be set to *something* to keep the output tidy. + maybeVendorName := "ENOCPE" + maybeProductName := "ENOCPE" + + if len(CPEs) > 0 { + CPE, err := cves.ParseCPE(CPEs[0]) // For naming the subdirectory used for output. + maybeVendorName = CPE.Vendor + maybeProductName = CPE.Product + if err != nil { + return fmt.Errorf("[%s]: Can't generate an OSV record without valid CPE data", cve.ID) + } + } + + // more often than not, this yields a VersionInfo with AffectedVersions and no AffectedCommits. + versions := cves.ExtractVersionInfo(cve, nil, http.DefaultClient, metrics) + + if len(versions.AffectedVersions) != 0 { + var err error + // There are some AffectedVersions to try and resolve to AffectedCommits. + if len(repos) == 0 { + metrics.AddNote("No affected ranges for %q, and no repos to try and convert %+v to tags with", maybeProductName, versions.AffectedVersions) + return fmt.Errorf("[%s]: No affected ranges for %q, and no repos to try and convert %+v to tags with", cve.ID, maybeProductName, versions.AffectedVersions) + } + logger.Info("Trying to convert version tags to commits", slog.String("cve", string(cve.ID)), slog.Any("versions", versions), slog.Any("repos", repos)) + versions, err = cves.GitVersionsToCommits(cve.ID, versions, repos, cache, metrics) + if err != nil { + metrics.AddNote("Failed to convert version tags to commits: %#v", err) + return fmt.Errorf("[%s]: Failed to convert version tags to commits: %#w", cve.ID, err) + } + } + + hasAnyFixedCommits := false + for _, repo := range repos { + if versions.HasFixedCommits(repo) { + hasAnyFixedCommits = true + } + } + + if versions.HasFixedVersions() && !hasAnyFixedCommits { + metrics.AddNote("Failed to convert fixed version tags to commits: %#v", versions) + return fmt.Errorf("[%s]: Failed to convert fixed version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) + } + + hasAnyLastAffectedCommits := false + for _, repo := range repos { + if versions.HasLastAffectedCommits(repo) { + hasAnyLastAffectedCommits = true + } + } + + if versions.HasLastAffectedVersions() && !hasAnyLastAffectedCommits && !hasAnyFixedCommits { + metrics.AddNote("Failed to convert last_affected version tags to commits: %#v", versions) + return fmt.Errorf("[%s]: Failed to convert last_affected version tags to commits: %#v %w", cve.ID, versions, ErrUnresolvedFix) + } + + if len(versions.AffectedCommits) == 0 { + metrics.AddNote("No affected commit ranges determined for %q", maybeProductName) + return fmt.Errorf("[%s]: No affected commit ranges determined for %q %w", cve.ID, maybeProductName, ErrNoRanges) + } + + versions.AffectedVersions = nil // these have served their purpose and are not required in the resulting output. + + slices.SortStableFunc(versions.AffectedCommits, models.AffectedCommitCompare) + + var pkgInfos []vulns.PackageInfo + pi := vulns.PackageInfo{VersionInfo: versions} + pkgInfos = append(pkgInfos, pi) // combine-to-osv expects a serialised *array* of PackageInfo + + vulnDir := filepath.Join(directory, maybeVendorName, maybeProductName) + err := os.MkdirAll(vulnDir, 0755) + if err != nil { + logger.Warn("Failed to create dir", slog.Any("err", err)) + return fmt.Errorf("failed to create dir: %w", err) + } + + outputFile := filepath.Join(vulnDir, string(cve.ID)+".nvd"+models.Extension) + f, err := os.Create(outputFile) + if err != nil { + logger.Warn("Failed to open for writing", slog.String("path", outputFile), slog.Any("err", err)) + return fmt.Errorf("failed to open %s for writing: %w", outputFile, err) + } + defer f.Close() + + encoder := json.NewEncoder(f) + encoder.SetIndent("", " ") + err = encoder.Encode(&pkgInfos) + + if err != nil { + logger.Warn("Failed to encode PackageInfo", slog.String("path", outputFile), slog.Any("err", err)) + return fmt.Errorf("failed to encode PackageInfo to %s: %w", outputFile, err) + } + + logger.Info("Generated PackageInfo record", slog.String("cve", string(cve.ID)), slog.String("product", maybeProductName)) + + metricsFile, err := conversion.CreateMetricsFile(cve.ID, vulnDir) + if err != nil { + return err + } + err = conversion.WriteMetricsFile(metrics, metricsFile) + if err != nil { + return err + } + + return nil +} + +// FindRepos attempts to find the source code repositories for a given CVE. +func FindRepos(cve models.NVDCVE, vpRepoCache *cves.VPRepoCache, metrics *models.ConversionMetrics) []string { + // Find repos + refs := cve.References + CPEs := cves.CPEs(cve) + CVEID := cve.ID + var reposForCVE []string + + if len(refs) == 0 && len(CPEs) == 0 { + metrics.AddNote("Skipping due to lack of CPEs and lack of references") + // 100% of these in 2022 were rejected CVEs + metrics.Outcome = models.Rejected + + return nil + } + + // Edge case: No CPEs, but perhaps usable references. + if len(refs) > 0 && len(CPEs) == 0 { + repos := cves.ReposFromReferences(nil, nil, refs, cves.RefTagDenyList, metrics) + if len(repos) == 0 { + metrics.AddNote("Failed to derive any repos and there were no CPEs") + return nil + } + metrics.AddNote("Derived repos for CVE with no CPEs: %v", repos) + reposForCVE = repos + } + + // Does it have any application CPEs? Look for pre-computed repos based on VendorProduct. + appCPECount := 0 + for _, CPEstr := range CPEs { + CPE, err := cves.ParseCPE(CPEstr) + if err != nil { + metrics.AddNote("Failed to parse CPE: %v", CPEstr) + metrics.Outcome = models.ConversionUnknown + + continue + } + if CPE.Part == "a" { + appCPECount += 1 + } + vendorProductKey := cves.VendorProduct{Vendor: CPE.Vendor, Product: CPE.Product} + if repos, ok := vpRepoCache.Get(vendorProductKey); ok { + metrics.AddNote("Pre-references, derived repos using cache: %v", repos) + if len(reposForCVE) == 0 { + reposForCVE = repos + continue + } + // Don't append duplicates. + for _, repo := range repos { + if !slices.Contains(reposForCVE, repo) { + reposForCVE = append(reposForCVE, repo) + } + } + } + } + + if len(CPEs) > 0 && appCPECount == 0 { + // This CVE is not for software (based on there being CPEs but not any application ones), skip. + metrics.Outcome = models.NoSoftware + return nil + } + + // If there wasn't a repo from the CPE Dictionary, try and derive one from the CVE references. + if len(reposForCVE) == 0 && len(refs) > 0 { + for _, CPEstr := range cves.CPEs(cve) { + CPE, err := cves.ParseCPE(CPEstr) + if err != nil { + metrics.AddNote("Failed to parse CPE: %v", CPEstr) + continue + } + // Continue to only focus on application CPEs. + if CPE.Part != "a" { + continue + } + if slices.Contains(cves.VendorProductDenyList, cves.VendorProduct{Vendor: CPE.Vendor, Product: ""}) { + continue + } + if slices.Contains(cves.VendorProductDenyList, cves.VendorProduct{Vendor: CPE.Vendor, Product: CPE.Product}) { + continue + } + repos := cves.ReposFromReferences(vpRepoCache, &cves.VendorProduct{Vendor: CPE.Vendor, Product: CPE.Product}, refs, cves.RefTagDenyList, metrics) + if len(repos) == 0 { + metrics.AddNote("Failed to derive any repos: %v", CPE) + continue + } + metrics.AddNote("Derived repos: %v", repos) + reposForCVE = repos + } + } + + logger.Info("Finished processing "+string(CVEID), + slog.String("cve", string(CVEID)), + slog.Int("cpes", len(CPEs)), + slog.Int("app_cpes", appCPECount), + slog.Int("derived_repos", len(reposForCVE))) + + // If we've made it to here, we may have a CVE: + // * that has Application-related CPEs (so applies to software) + // * has a reference that is a known repository URL + // OR + // * a derived repository for the software package + // + // We do not yet have: + // * any knowledge of the language used + // * definitive version information + + if len(reposForCVE) == 0 { + // We have nothing useful to work with, so we'll assume it's out of scope + metrics.AddNote("Passing due to lack of viable repository") + metrics.Outcome = models.NoRepos + + return nil + } + + metrics.AddNote("Found Repos for CVE %s: %v", string(CVEID), reposForCVE) + + return reposForCVE +} diff --git a/vulnfeeds/cvelist2osv/common.go b/vulnfeeds/cvelist2osv/common.go index c853091e176..19361b1bd7b 100644 --- a/vulnfeeds/cvelist2osv/common.go +++ b/vulnfeeds/cvelist2osv/common.go @@ -2,7 +2,6 @@ package cvelist2osv import ( "cmp" - "encoding/json" "errors" "log/slog" "strconv" @@ -10,6 +9,7 @@ import ( "github.com/google/osv/vulnfeeds/cves" "github.com/google/osv/vulnfeeds/git" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility" "github.com/google/osv/vulnfeeds/utility/logger" "github.com/google/osv/vulnfeeds/vulns" @@ -28,52 +28,6 @@ const ( VersionRangeTypeEcosystem ) -// VersionSource indicates the source of the extracted version information. -type VersionSource string - -const ( - VersionSourceNone VersionSource = "NOVERS" - VersionSourceAffected VersionSource = "CVEAFFVERS" - VersionSourceGit VersionSource = "GITVERS" - VersionSourceCPE VersionSource = "CPEVERS" - VersionSourceDescription VersionSource = "DESCRVERS" -) - -type ConversionOutcome int - -const ( - // Set of enums for categorizing conversion outcomes. - ConversionUnknown ConversionOutcome = iota // Shouldn't happen - Successful // It worked! - Rejected // The CVE was rejected - NoSoftware // The CVE had no CPEs relating to software (i.e. Operating Systems or Hardware). - NoRepos // The CPE Vendor/Product had no repositories derived for it. - NoCommitRanges // No viable commit ranges could be calculated from the repository for the CVE's CPE(s). - NoRanges // No version ranges could be extracted from the record. - FixUnresolvable // Partial resolution of versions, resulting in a false positive. -) - -func (c ConversionOutcome) String() string { - switch c { - case Successful: - return "Successful" - case Rejected: - return "Rejected" - case NoSoftware: - return "NoSoftware" - case NoRepos: - return "NoRepos" - case NoCommitRanges: - return "NoCommitRanges" - case NoRanges: - return "NoRanges" - case FixUnresolvable: - return "FixUnresolvable" - default: - return "Unknown" - } -} - // String returns the string representation of a VersionRangeType. func (vrt VersionRangeType) String() string { switch vrt { @@ -103,7 +57,7 @@ func toVersionRangeType(s string) VersionRangeType { // resolveVersionToCommit is a helper to convert a version string to a commit hash. // It logs the outcome of the conversion attempt and returns an empty string on failure. -func resolveVersionToCommit(cveID cves.CVEID, version, versionType, repo string, normalizedTags map[string]git.NormalizedTag) string { +func resolveVersionToCommit(cveID models.CVEID, version, versionType, repo string, normalizedTags map[string]git.NormalizedTag) string { if version == "" { return "" } @@ -122,7 +76,7 @@ func resolveVersionToCommit(cveID cves.CVEID, version, versionType, repo string, // Takes a CVE ID string (for logging), VersionInfo with AffectedVersions and // typically no AffectedCommits and attempts to add AffectedCommits (including Fixed commits) where there aren't any. // Refuses to add the same commit to AffectedCommits more than once. -func gitVersionsToCommits(cveID cves.CVEID, versionRanges []*osvschema.Range, repos []string, metrics *ConversionMetrics, cache git.RepoTagsCache) (*osvschema.Affected, error) { +func gitVersionsToCommits(cveID models.CVEID, versionRanges []*osvschema.Range, repos []string, metrics *models.ConversionMetrics, cache *git.RepoTagsCache) (*osvschema.Affected, error) { var newAff osvschema.Affected var newVersionRanges []*osvschema.Range unresolvedRanges := versionRanges @@ -214,7 +168,7 @@ func gitVersionsToCommits(cveID cves.CVEID, versionRanges []*osvschema.Range, re // findCPEVersionRanges extracts version ranges and CPE strings from the CNA's // CPE applicability statements in a CVE record. -func findCPEVersionRanges(cve cves.CVE5) (versionRanges []*osvschema.Range, cpes []string, err error) { +func findCPEVersionRanges(cve models.CVE5) (versionRanges []*osvschema.Range, cpes []string, err error) { // TODO(jesslowe): Add logic to also extract CPEs from the 'affected' field (e.g., CVE-2025-1110). for _, c := range cve.Containers.CNA.CPEApplicability { for _, node := range c.Nodes { @@ -292,43 +246,3 @@ func compareSemverLike(a, b string) int { // All extra parts were zero, so the versions are effectively equal. return 0 } - -// addAffected adds an osvschema.Affected to a vulnerability, ensuring that no duplicate ranges are added. -func addAffected(v *vulns.Vulnerability, aff *osvschema.Affected, metrics *ConversionMetrics) { - allExistingRanges := make(map[string]struct{}) - for _, existingAff := range v.Affected { - for _, r := range existingAff.GetRanges() { - rangeBytes, err := json.Marshal(r) - if err == nil { - allExistingRanges[string(rangeBytes)] = struct{}{} - } - } - } - - uniqueRanges := []*osvschema.Range{} - for _, r := range aff.GetRanges() { - rangeBytes, err := json.Marshal(r) - if err != nil { - metrics.AddNote("Could not marshal range to check for duplicates, adding anyway: %+v", r) - uniqueRanges = append(uniqueRanges, r) - - continue - } - rangeStr := string(rangeBytes) - if _, exists := allExistingRanges[rangeStr]; !exists { - uniqueRanges = append(uniqueRanges, r) - allExistingRanges[rangeStr] = struct{}{} - } else { - metrics.AddNote("Skipping duplicate range: %+v", r) - } - } - - if len(uniqueRanges) > 0 { - newAff := &osvschema.Affected{ - Package: aff.GetPackage(), - Ranges: uniqueRanges, - DatabaseSpecific: aff.GetDatabaseSpecific(), - } - v.Affected = append(v.Affected, newAff) - } -} diff --git a/vulnfeeds/cvelist2osv/common_test.go b/vulnfeeds/cvelist2osv/common_test.go index f291da87395..92fed895fe7 100644 --- a/vulnfeeds/cvelist2osv/common_test.go +++ b/vulnfeeds/cvelist2osv/common_test.go @@ -4,6 +4,8 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/google/osv/vulnfeeds/conversion" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvschema" "google.golang.org/protobuf/testing/protocmp" @@ -55,9 +57,9 @@ func TestAddAffected(t *testing.T) { }, }, } - metrics := &ConversionMetrics{} + metrics := &models.ConversionMetrics{} - addAffected(v, aff, metrics) + conversion.AddAffected(v, aff, metrics) expectedAffected := []*osvschema.Affected{ { diff --git a/vulnfeeds/cvelist2osv/converter.go b/vulnfeeds/cvelist2osv/converter.go index c525e57a41e..d03b8dca2f9 100644 --- a/vulnfeeds/cvelist2osv/converter.go +++ b/vulnfeeds/cvelist2osv/converter.go @@ -6,14 +6,13 @@ import ( "fmt" "io" "log/slog" - "os" - "path/filepath" "slices" "sort" - "strings" "time" + "github.com/google/osv/vulnfeeds/conversion" "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility" "github.com/google/osv/vulnfeeds/utility/logger" "github.com/google/osv/vulnfeeds/vulns" @@ -22,48 +21,10 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) -const ( - extension = ".json" -) - -// ConversionMetrics holds the collected data about the conversion process for a single CVE. -type ConversionMetrics struct { - CVEID cves.CVEID `json:"id"` // The CVE ID - CNA string `json:"cna"` // The CNA that assigned the CVE. - Outcome ConversionOutcome `json:"outcome"` // The final outcome of the conversion (e.g., "Successful", "Failed"). - Repos []string `json:"repos"` // A list of repositories extracted from the CVE's references. - RefTypesCount map[osvschema.Reference_Type]int `json:"ref_types_count"` // A count of each type of reference found. - VersionSources []VersionSource `json:"version_sources"` // A list of the ways the versions were extracted - Notes []string `json:"notes"` // A collection of notes and warnings generated during conversion. - CPEs []string `json:"cpes"` - UnresolvedRangesCount int `json:"unresolved_ranges_count"` - ResolvedRangesCount int `json:"resolved_ranges_count"` -} - -// AddNote adds a formatted note to the ConversionMetrics. -func (m *ConversionMetrics) AddNote(format string, a ...any) { - m.Notes = append(m.Notes, fmt.Sprintf(format, a...)) - logger.Debug(fmt.Sprintf(format, a...), slog.String("cna", m.CNA), slog.String("cve", string(m.CVEID))) -} - -// AddSource appends a source to the ConversionMetrics -func (m *ConversionMetrics) AddSource(source VersionSource) { - m.VersionSources = append(m.VersionSources, source) -} - -// RefTagDenyList contains reference tags that are often associated with unreliable or -// irrelevant repository URLs. References with these tags are currently ignored -// to avoid incorrect repository associations. -var RefTagDenyList = []string{ - // "Exploit", - // "Third Party Advisory", - "Broken Link", // Actively ignore these. -} - // extractConversionMetrics examines a CVE and its generated OSV references to populate // the ConversionMetrics struct with heuristics about the conversion process. // It captures the assigning CNA and counts the occurrences of each reference type. -func extractConversionMetrics(cve cves.CVE5, refs []*osvschema.Reference, metrics *ConversionMetrics) { +func extractConversionMetrics(cve models.CVE5, refs []*osvschema.Reference, metrics *models.ConversionMetrics) { // Capture the CNA for heuristic analysis. metrics.CNA = cve.Metadata.AssignerShortName // TODO(jesslowe): more CNA based analysis @@ -82,7 +43,7 @@ func extractConversionMetrics(cve cves.CVE5, refs []*osvschema.Reference, metric } // getCWEs extracts and adds CWE IDs from the CVE5 problem-types -func getCWEs(cna cves.CNA, metrics *ConversionMetrics) []string { +func getCWEs(cna models.CNA, metrics *models.ConversionMetrics) []string { var cwes []string for _, pt := range cna.ProblemTypes { @@ -106,30 +67,30 @@ func getCWEs(cna cves.CNA, metrics *ConversionMetrics) []string { return cwes } -// FromCVE5 creates a `vulns.Vulnerability` object from a `cves.CVE5` object. +// FromCVE5 creates a `vulns.Vulnerability` object from a `models.CVE5` object. // It populates the main fields of the OSV record, including ID, summary, details, // references, timestamps, severity, and version information. -func FromCVE5(cve cves.CVE5, refs []cves.Reference, metrics *ConversionMetrics, sourceLink string) *vulns.Vulnerability { +func FromCVE5(cve models.CVE5, refs []models.Reference, metrics *models.ConversionMetrics, sourceLink string) *vulns.Vulnerability { aliases, related := vulns.ExtractReferencedVulns(cve.Metadata.CVEID, cve.Metadata.CVEID, refs) v := vulns.Vulnerability{ Vulnerability: &osvschema.Vulnerability{ SchemaVersion: osvconstants.SchemaVersion, Id: string(cve.Metadata.CVEID), Summary: cve.Containers.CNA.Title, - Details: cves.EnglishDescription(cve.Containers.CNA.Descriptions), + Details: models.EnglishDescription(cve.Containers.CNA.Descriptions), Aliases: aliases, Related: related, References: vulns.ClassifyReferences(refs), }} - published, err := cves.ParseCVE5Timestamp(cve.Metadata.DatePublished) + published, err := models.ParseCVE5Timestamp(cve.Metadata.DatePublished) if err != nil { metrics.AddNote("[%s]: Published date failed to parse, setting time to now", cve.Metadata.CVEID) published = time.Now() } v.Published = timestamppb.New(published) - modified, err := cves.ParseCVE5Timestamp(cve.Metadata.DateUpdated) + modified, err := models.ParseCVE5Timestamp(cve.Metadata.DateUpdated) if err != nil { metrics.AddNote("[%s]: Modified date failed to parse, setting time to now", cve.Metadata.CVEID) modified = time.Now() @@ -137,10 +98,7 @@ func FromCVE5(cve cves.CVE5, refs []cves.Reference, metrics *ConversionMetrics, v.Modified = timestamppb.New(modified) // Try to extract repository URLs from references. - repos, repoNotes := cves.ReposFromReferencesCVEList(string(cve.Metadata.CVEID), refs, RefTagDenyList) - for _, note := range repoNotes { - metrics.AddNote("%s", note) - } + repos := cves.ReposFromReferencesCVEList(refs, models.RefTagDenyList, metrics) metrics.Repos = repos // Create a map to hold DatabaseSpecific fields @@ -165,7 +123,7 @@ func FromCVE5(cve cves.CVE5, refs []cves.Reference, metrics *ConversionMetrics, }) // Combine severity metrics from both CNA and ADP containers. - var severity []cves.Metrics + var severity []models.Metrics if len(cve.Containers.CNA.Metrics) != 0 { severity = append(severity, cve.Containers.CNA.Metrics...) } @@ -183,66 +141,22 @@ func FromCVE5(cve cves.CVE5, refs []cves.Reference, metrics *ConversionMetrics, return &v } -// CreateOSVFile creates the initial file for the OSV record. -func CreateOSVFile(id cves.CVEID, vulnDir string) (*os.File, error) { - outputFile := filepath.Join(vulnDir, string(id)+extension) - - f, err := os.Create(outputFile) - if err != nil { - logger.Info("Failed to open for writing "+outputFile, slog.String("cve", string(id)), slog.String("path", outputFile), slog.Any("err", err)) - return nil, err - } - - return f, err -} - -// CreateMetricsFile saves the collected conversion metrics to a JSON file. -// This file provides data for analyzing the success and characteristics of the -// conversion process for a given CVE. -func CreateMetricsFile(id cves.CVEID, vulnDir string) (*os.File, error) { - metricsFile := filepath.Join(vulnDir, string(id)+".metrics.json") - f, err := os.Create(metricsFile) - if err != nil { - logger.Info("Failed to open for writing "+metricsFile, slog.String("cve", string(id)), slog.String("path", metricsFile), slog.Any("err", err)) - return nil, err - } - - return f, nil -} - -func determineOutcome(metrics *ConversionMetrics) { - // check if we have affected ranges/versions. - if len(metrics.Repos) == 0 { - // Fix unlikely, as no repos to resolve - metrics.Outcome = NoRepos - return - } - - if metrics.ResolvedRangesCount > 0 { - metrics.Outcome = Successful - } else if metrics.UnresolvedRangesCount > 0 { - metrics.Outcome = NoCommitRanges - } else { - metrics.Outcome = NoRanges - } -} - // ConvertAndExportCVEToOSV is the main function for this file. It takes a CVE, // converts it into an OSV record, collects metrics, and writes both to disk. -func ConvertAndExportCVEToOSV(cve cves.CVE5, vulnSink io.Writer, metricsSink io.Writer, sourceLink string) (*ConversionMetrics, error) { +func ConvertAndExportCVEToOSV(cve models.CVE5, vulnSink io.Writer, metricsSink io.Writer, sourceLink string) (*ConversionMetrics, error) { cveID := cve.Metadata.CVEID cnaAssigner := cve.Metadata.AssignerShortName references := identifyPossibleURLs(cve) // Add NVD and computed source link to references - references = append(references, cves.Reference{URL: fmt.Sprintf("https://nvd.nist.gov/vuln/detail/%s", cveID)}) + references = append(references, models.Reference{URL: fmt.Sprintf("https://nvd.nist.gov/vuln/detail/%s", cveID)}) if sourceLink != "" { - references = append(references, cves.Reference{URL: sourceLink}) + references = append(references, models.Reference{URL: sourceLink}) } - references = deduplicateRefs(references) + references = conversion.DeduplicateRefs(references) - metrics := ConversionMetrics{CVEID: cveID, CNA: cnaAssigner, UnresolvedRangesCount: 0, ResolvedRangesCount: 0} + metrics := models.ConversionMetrics{CVEID: cveID, CNA: cnaAssigner, UnresolvedRangesCount: 0, ResolvedRangesCount: 0} // Create a base OSV record from the CVE. v := FromCVE5(cve, references, &metrics, sourceLink) @@ -254,9 +168,9 @@ func ConvertAndExportCVEToOSV(cve cves.CVE5, vulnSink io.Writer, metricsSink io. versionExtractor := GetVersionExtractor(cve.Metadata.AssignerShortName) versionExtractor.ExtractVersions(cve, v, &metrics, metrics.Repos) - groupAffectedRanges(v.Affected) + conversion.GroupAffectedRanges(v.Affected) - determineOutcome(&metrics) + models.DetermineOutcome(&metrics) err := v.ToJSON(vulnSink) if err != nil { @@ -281,7 +195,7 @@ func ConvertAndExportCVEToOSV(cve cves.CVE5, vulnSink io.Writer, metricsSink io. // identifyPossibleURLs extracts all URLs from a CVE object. // It searches for URLs in the CNA and ADP reference sections, as well as in // the 'collectionUrl' and 'repo' fields of the 'affected' entries. -func identifyPossibleURLs(cve cves.CVE5) []cves.Reference { +func identifyPossibleURLs(cve models.CVE5) []models.Reference { refs := cve.Containers.CNA.References for _, adp := range cve.Containers.ADP { @@ -292,15 +206,15 @@ func identifyPossibleURLs(cve cves.CVE5) []cves.Reference { for _, affected := range cve.Containers.CNA.Affected { if affected.CollectionURL != "" { - refs = append(refs, cves.Reference{URL: affected.CollectionURL}) + refs = append(refs, models.Reference{URL: affected.CollectionURL}) } if affected.Repo != "" { - refs = append(refs, cves.Reference{URL: affected.Repo}) + refs = append(refs, models.Reference{URL: affected.Repo}) } } // Filter out empty URLs from CNA references if any - filteredRefs := make([]cves.Reference, 0, len(refs)) + filteredRefs := make([]models.Reference, 0, len(refs)) for _, ref := range refs { if ref.URL != "" { filteredRefs = append(filteredRefs, ref) @@ -311,19 +225,7 @@ func identifyPossibleURLs(cve cves.CVE5) []cves.Reference { return refs } -func deduplicateRefs(refs []cves.Reference) []cves.Reference { - // Deduplicate references by URL. - slices.SortStableFunc(refs, func(a, b cves.Reference) int { - return strings.Compare(a.URL, b.URL) - }) - refs = slices.CompactFunc(refs, func(a, b cves.Reference) bool { - return a.URL == b.URL - }) - - return refs -} - -func buildDBSpecific(cve cves.CVE5, metrics *ConversionMetrics, sourceLink string) map[string]any { +func buildDBSpecific(cve models.CVE5, metrics *models.ConversionMetrics, sourceLink string) map[string]any { dbSpecific := make(map[string]any) if sourceLink != "" { diff --git a/vulnfeeds/cvelist2osv/converter_test.go b/vulnfeeds/cvelist2osv/converter_test.go index 5d73721851d..8e953cc4c59 100644 --- a/vulnfeeds/cvelist2osv/converter_test.go +++ b/vulnfeeds/cvelist2osv/converter_test.go @@ -10,9 +10,8 @@ import ( "testing" "github.com/gkampitakis/go-snaps/snaps" - "github.com/google/go-cmp/cmp" - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvconstants" "github.com/ossf/osv-schema/bindings/go/osvschema" @@ -21,7 +20,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) -func loadTestData(t *testing.T, cveName string) cves.CVE5 { +func loadTestData(t *testing.T, cveName string) models.CVE5 { t.Helper() prefix := strings.Split(cveName, "-")[2] prefixpath := prefix[:len(prefix)-3] + "xxx" @@ -30,14 +29,14 @@ func loadTestData(t *testing.T, cveName string) cves.CVE5 { return loadTestCVE(t, fileName) } -func loadTestCVE(t *testing.T, path string) cves.CVE5 { +func loadTestCVE(t *testing.T, path string) models.CVE5 { t.Helper() file, err := os.Open(path) if err != nil { t.Fatalf("Failed to load test data from %q: %v", path, err) } defer file.Close() - var cve cves.CVE5 + var cve models.CVE5 err = json.NewDecoder(file).Decode(&cve) if err != nil { t.Fatalf("Failed to decode %q: %+v", path, err) @@ -49,31 +48,31 @@ func loadTestCVE(t *testing.T, path string) cves.CVE5 { func TestIdentifyPossibleURLs(t *testing.T) { testCases := []struct { name string - cve cves.CVE5 - expectedRefs []cves.Reference + cve models.CVE5 + expectedRefs []models.Reference }{ { name: "simple case with duplicates", - cve: cves.CVE5{ + cve: models.CVE5{ Containers: struct { - CNA cves.CNA `json:"cna"` - ADP []cves.CNA `json:"adp,omitempty"` + CNA models.CNA `json:"cna"` + ADP []models.CNA `json:"adp,omitempty"` }{ - CNA: cves.CNA{ - References: []cves.Reference{ + CNA: models.CNA{ + References: []models.Reference{ {URL: "http://a.com"}, {URL: "http://b.com"}, }, - Affected: []cves.Affected{ + Affected: []models.Affected{ { CollectionURL: "http://d.com", Repo: "http://b.com", }, }, }, - ADP: []cves.CNA{ + ADP: []models.CNA{ { - References: []cves.Reference{ + References: []models.Reference{ {URL: "http://c.com"}, {URL: "http://a.com"}, }, @@ -81,7 +80,7 @@ func TestIdentifyPossibleURLs(t *testing.T) { }, }, }, - expectedRefs: []cves.Reference{ + expectedRefs: []models.Reference{ {URL: "http://a.com"}, {URL: "http://b.com"}, {URL: "http://c.com"}, @@ -92,53 +91,53 @@ func TestIdentifyPossibleURLs(t *testing.T) { }, { name: "no references and CNA refs is nil", - cve: cves.CVE5{ + cve: models.CVE5{ Containers: struct { - CNA cves.CNA `json:"cna"` - ADP []cves.CNA `json:"adp,omitempty"` + CNA models.CNA `json:"cna"` + ADP []models.CNA `json:"adp,omitempty"` }{ - CNA: cves.CNA{ + CNA: models.CNA{ References: nil, }, }, }, - expectedRefs: []cves.Reference{}, + expectedRefs: []models.Reference{}, }, { name: "no references and CNA refs is empty slice", - cve: cves.CVE5{ + cve: models.CVE5{ Containers: struct { - CNA cves.CNA `json:"cna"` - ADP []cves.CNA `json:"adp,omitempty"` + CNA models.CNA `json:"cna"` + ADP []models.CNA `json:"adp,omitempty"` }{ - CNA: cves.CNA{ - References: []cves.Reference{}, + CNA: models.CNA{ + References: []models.Reference{}, }, }, }, - expectedRefs: []cves.Reference{}, + expectedRefs: []models.Reference{}, }, { name: "empty url string", - cve: cves.CVE5{ + cve: models.CVE5{ Containers: struct { - CNA cves.CNA `json:"cna"` - ADP []cves.CNA `json:"adp,omitempty"` + CNA models.CNA `json:"cna"` + ADP []models.CNA `json:"adp,omitempty"` }{ - CNA: cves.CNA{ - Affected: []cves.Affected{ + CNA: models.CNA{ + Affected: []models.Affected{ { CollectionURL: "", }, }, - References: []cves.Reference{ + References: []models.Reference{ {URL: "http://a.com"}, {URL: ""}, }, }, }, }, - expectedRefs: []cves.Reference{ + expectedRefs: []models.Reference{ {URL: "http://a.com"}, }, }, @@ -155,36 +154,36 @@ func TestIdentifyPossibleURLs(t *testing.T) { } func TestFromCVE5(t *testing.T) { - cve1110Pub, _ := cves.ParseCVE5Timestamp("2025-05-22T14:02:31.385Z") - cve1110Mod, _ := cves.ParseCVE5Timestamp("2025-05-22T14:17:44.379Z") - cve21634Pub, _ := cves.ParseCVE5Timestamp("2024-01-03T22:46:03.585Z") - cve21634Mod, _ := cves.ParseCVE5Timestamp("2025-06-16T19:45:37.088Z") - cve21772Pub, _ := cves.ParseCVE5Timestamp("2025-02-27T02:18:19.528Z") - cve21772Mod, _ := cves.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") - cvePlaceholder, _ := cves.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") + cve1110Pub, _ := models.ParseCVE5Timestamp("2025-05-22T14:02:31.385Z") + cve1110Mod, _ := models.ParseCVE5Timestamp("2025-05-22T14:17:44.379Z") + cve21634Pub, _ := models.ParseCVE5Timestamp("2024-01-03T22:46:03.585Z") + cve21634Mod, _ := models.ParseCVE5Timestamp("2025-06-16T19:45:37.088Z") + cve21772Pub, _ := models.ParseCVE5Timestamp("2025-02-27T02:18:19.528Z") + cve21772Mod, _ := models.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") + cvePlaceholder, _ := models.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") testCases := []struct { name string - cve cves.CVE5 + cve models.CVE5 - refs []cves.Reference + refs []models.Reference expectedVuln *vulns.Vulnerability }{ { name: "disputed record", - cve: cves.CVE5{ - Metadata: cves.CVE5Metadata{ + cve: models.CVE5{ + Metadata: models.CVE5Metadata{ CVEID: "CVE-2025-9999", State: "PUBLISHED", DatePublished: "2025-05-04T07:20:46.575Z", DateUpdated: "2025-05-04T07:20:46.575Z", }, Containers: struct { - CNA cves.CNA `json:"cna"` - ADP []cves.CNA `json:"adp,omitempty"` + CNA models.CNA `json:"cna"` + ADP []models.CNA `json:"adp,omitempty"` }{ - CNA: cves.CNA{ + CNA: models.CNA{ Tags: []string{"disputed"}, - Descriptions: []cves.LangString{ + Descriptions: []models.LangString{ { Lang: "en", Value: "A disputed vulnerability.", @@ -193,7 +192,7 @@ func TestFromCVE5(t *testing.T) { }, }, }, - refs: []cves.Reference{}, + refs: []models.Reference{}, expectedVuln: &vulns.Vulnerability{ Vulnerability: &osvschema.Vulnerability{ Id: "CVE-2025-9999", @@ -213,7 +212,7 @@ func TestFromCVE5(t *testing.T) { { name: "CVE-2025-1110", cve: loadTestData(t, "CVE-2025-1110"), - refs: []cves.Reference{ + refs: []models.Reference{ {URL: "https://gitlab.com/gitlab-org/gitlab/-/issues/517693", Tags: []string{"issue-tracking", "permissions-required"}}, {URL: "https://hackerone.com/reports/2972576", Tags: []string{"technical-description", "exploit", "permissions-required"}}, }, @@ -256,7 +255,7 @@ func TestFromCVE5(t *testing.T) { { name: "CVE-2024-21634", cve: loadTestData(t, "CVE-2024-21634"), - refs: []cves.Reference{ + refs: []models.Reference{ {Tags: []string{"x_refsource_CONFIRM"}, URL: "https://github.com/amazon-ion/ion-java/security/advisories/GHSA-264p-99wq-f4j6"}, }, expectedVuln: &vulns.Vulnerability{ @@ -297,7 +296,7 @@ func TestFromCVE5(t *testing.T) { { name: "CVE-2025-21772", cve: loadTestData(t, "CVE-2025-21772"), - refs: []cves.Reference{ + refs: []models.Reference{ {URL: "https://git.kernel.org/stable/c/a3e77da9f843e4ab93917d30c314f0283e28c124"}, {URL: "https://git.kernel.org/stable/c/213ba5bd81b7e97ac6e6190b8f3bc6ba76123625"}, {URL: "https://git.kernel.org/stable/c/40a35d14f3c0dc72b689061ec72fc9b193f37d1f"}, @@ -340,7 +339,7 @@ func TestFromCVE5(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - metrics := &ConversionMetrics{} + metrics := &models.ConversionMetrics{} vuln := FromCVE5(tc.cve, tc.refs, metrics, "") // Handle non-deterministic time.Now() @@ -392,24 +391,24 @@ func TestFromCVE5(t *testing.T) { } func TestConvertAndExportCVEToOSV(t *testing.T) { - cve1110Pub, _ := cves.ParseCVE5Timestamp("2025-05-22T14:02:31.385Z") - cve1110Mod, _ := cves.ParseCVE5Timestamp("2025-05-22T14:17:44.379Z") - cve21634Pub, _ := cves.ParseCVE5Timestamp("2024-01-03T22:46:03.585Z") - cve21634Mod, _ := cves.ParseCVE5Timestamp("2025-06-16T19:45:37.088Z") - cve21772Pub, _ := cves.ParseCVE5Timestamp("2025-02-27T02:18:19.528Z") - cve21772Mod, _ := cves.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") - cvePlaceholder, _ := cves.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") + cve1110Pub, _ := models.ParseCVE5Timestamp("2025-05-22T14:02:31.385Z") + cve1110Mod, _ := models.ParseCVE5Timestamp("2025-05-22T14:17:44.379Z") + cve21634Pub, _ := models.ParseCVE5Timestamp("2024-01-03T22:46:03.585Z") + cve21634Mod, _ := models.ParseCVE5Timestamp("2025-06-16T19:45:37.088Z") + cve21772Pub, _ := models.ParseCVE5Timestamp("2025-02-27T02:18:19.528Z") + cve21772Mod, _ := models.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") + cvePlaceholder, _ := models.ParseCVE5Timestamp("2025-05-04T07:20:46.575Z") testCases := []struct { name string - cve cves.CVE5 + cve models.CVE5 - refs []cves.Reference + refs []models.Reference expectedVuln *vulns.Vulnerability }{ { name: "disputed record", - cve: cves.CVE5{ - Metadata: cves.CVE5Metadata{ + cve: models.CVE5{ + Metadata: models.CVE5Metadata{ CVEID: "CVE-2025-9999", State: "PUBLISHED", DatePublished: "2025-05-04T07:20:46.575Z", @@ -417,12 +416,12 @@ func TestConvertAndExportCVEToOSV(t *testing.T) { AssignerShortName: "unknown", }, Containers: struct { - CNA cves.CNA `json:"cna"` - ADP []cves.CNA `json:"adp,omitempty"` + CNA models.CNA `json:"cna"` + ADP []models.CNA `json:"adp,omitempty"` }{ - CNA: cves.CNA{ + CNA: models.CNA{ Tags: []string{"disputed"}, - Descriptions: []cves.LangString{ + Descriptions: []models.LangString{ { Lang: "en", Value: "A disputed vulnerability.", @@ -431,7 +430,7 @@ func TestConvertAndExportCVEToOSV(t *testing.T) { }, }, }, - refs: []cves.Reference{}, + refs: []models.Reference{}, expectedVuln: &vulns.Vulnerability{ Vulnerability: &osvschema.Vulnerability{ Id: "CVE-2025-9999", @@ -452,7 +451,7 @@ func TestConvertAndExportCVEToOSV(t *testing.T) { { name: "CVE-2025-1110", cve: loadTestData(t, "CVE-2025-1110"), - refs: []cves.Reference{ + refs: []models.Reference{ {URL: "https://gitlab.com/gitlab-org/gitlab/-/issues/517693", Tags: []string{"issue-tracking", "permissions-required"}}, {URL: "https://hackerone.com/reports/2972576", Tags: []string{"technical-description", "exploit", "permissions-required"}}, }, @@ -497,7 +496,7 @@ func TestConvertAndExportCVEToOSV(t *testing.T) { { name: "CVE-2024-21634", cve: loadTestData(t, "CVE-2024-21634"), - refs: []cves.Reference{ + refs: []models.Reference{ {Tags: []string{"x_refsource_CONFIRM"}, URL: "https://github.com/amazon-ion/ion-java/security/advisories/GHSA-264p-99wq-f4j6"}, }, expectedVuln: &vulns.Vulnerability{ @@ -538,7 +537,7 @@ func TestConvertAndExportCVEToOSV(t *testing.T) { { name: "CVE-2025-21772", cve: loadTestData(t, "CVE-2025-21772"), - refs: []cves.Reference{ + refs: []models.Reference{ {URL: "https://git.kernel.org/stable/c/a3e77da9f843e4ab93917d30c314f0283e28c124"}, {URL: "https://git.kernel.org/stable/c/213ba5bd81b7e97ac6e6190b8f3bc6ba76123625"}, {URL: "https://git.kernel.org/stable/c/40a35d14f3c0dc72b689061ec72fc9b193f37d1f"}, diff --git a/vulnfeeds/cvelist2osv/default_extractor.go b/vulnfeeds/cvelist2osv/default_extractor.go index 8e497c7c175..a9ac0801f6d 100644 --- a/vulnfeeds/cvelist2osv/default_extractor.go +++ b/vulnfeeds/cvelist2osv/default_extractor.go @@ -1,11 +1,12 @@ package cvelist2osv import ( - "fmt" "log/slog" + "github.com/google/osv/vulnfeeds/conversion" "github.com/google/osv/vulnfeeds/cves" "github.com/google/osv/vulnfeeds/git" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility/logger" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvschema" @@ -14,7 +15,7 @@ import ( // DefaultVersionExtractor provides the default version extraction logic. type DefaultVersionExtractor struct{} -func (d *DefaultVersionExtractor) handleAffected(affected []cves.Affected, metrics *ConversionMetrics) []*osvschema.Range { +func (d *DefaultVersionExtractor) handleAffected(affected []models.Affected, metrics *models.ConversionMetrics) []*osvschema.Range { var ranges []*osvschema.Range for _, cveAff := range affected { versionRanges, _ := d.FindNormalAffectedRanges(cveAff, metrics) @@ -23,17 +24,17 @@ func (d *DefaultVersionExtractor) handleAffected(affected []cves.Affected, metri continue } ranges = append(ranges, versionRanges...) - metrics.AddSource(VersionSourceAffected) + metrics.AddSource(models.VersionSourceAffected) } return ranges } // ExtractVersions for DefaultVersionExtractor. -func (d *DefaultVersionExtractor) ExtractVersions(cve cves.CVE5, v *vulns.Vulnerability, metrics *ConversionMetrics, repos []string) { +func (d *DefaultVersionExtractor) ExtractVersions(cve models.CVE5, v *vulns.Vulnerability, metrics *models.ConversionMetrics, repos []string) { gotVersions := false - repoTagsCache := git.RepoTagsCache{} + repoTagsCache := &git.RepoTagsCache{} ranges := d.handleAffected(cve.Containers.CNA.Affected, metrics) @@ -44,7 +45,7 @@ func (d *DefaultVersionExtractor) ExtractVersions(cve cves.CVE5, v *vulns.Vulner } else { gotVersions = true } - addAffected(v, aff, metrics) + conversion.AddAffected(v, aff, metrics) } if !gotVersions { @@ -59,7 +60,7 @@ func (d *DefaultVersionExtractor) ExtractVersions(cve cves.CVE5, v *vulns.Vulner gotVersions = true } - addAffected(v, aff, metrics) + conversion.AddAffected(v, aff, metrics) } } @@ -71,12 +72,12 @@ func (d *DefaultVersionExtractor) ExtractVersions(cve cves.CVE5, v *vulns.Vulner if err != nil { logger.Error("Failed to convert git versions to commits", slog.Any("err", err)) } - addAffected(v, aff, metrics) + conversion.AddAffected(v, aff, metrics) } } } -func (d *DefaultVersionExtractor) FindNormalAffectedRanges(affected cves.Affected, metrics *ConversionMetrics) ([]*osvschema.Range, VersionRangeType) { +func (d *DefaultVersionExtractor) FindNormalAffectedRanges(affected models.Affected, metrics *models.ConversionMetrics) ([]*osvschema.Range, VersionRangeType) { versionTypesCount := make(map[VersionRangeType]int) var versionRanges []*osvschema.Range for _, vers := range affected.Versions { @@ -108,11 +109,7 @@ func (d *DefaultVersionExtractor) FindNormalAffectedRanges(affected cves.Affecte } // Try to extract versions from text like "before 1.4.7". - possibleVersions, notes := cves.ExtractVersionsFromText(nil, vers.Version) - - for _, note := range notes { - metrics.AddNote("%s", note) - } + possibleVersions := cves.ExtractVersionsFromText(nil, vers.Version, metrics) if possibleVersions != nil { metrics.AddNote("Versions retrieved from text but not used CURRENTLY") @@ -122,7 +119,7 @@ func (d *DefaultVersionExtractor) FindNormalAffectedRanges(affected cves.Affecte // As a fallback, assume a single version means it's the last affected version. if vulns.CheckQuality(vers.Version).AtLeast(acceptableQuality) { versionRanges = append(versionRanges, cves.BuildVersionRange("0", vers.Version, "")) - metrics.Notes = append(metrics.Notes, fmt.Sprintf("Single version found %v - Assuming introduced = 0 and last affected = %v", vers.Version, vers.Version)) + metrics.AddNote("Single version found %v - Assuming introduced = 0 and last affected = %v", vers.Version, vers.Version) } } diff --git a/vulnfeeds/cvelist2osv/extraction.go b/vulnfeeds/cvelist2osv/extraction.go index fddc1dce961..88387753d95 100644 --- a/vulnfeeds/cvelist2osv/extraction.go +++ b/vulnfeeds/cvelist2osv/extraction.go @@ -1,15 +1,15 @@ package cvelist2osv import ( - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvschema" ) // VersionExtractor defines the interface for different version extraction strategies. type VersionExtractor interface { - ExtractVersions(cve cves.CVE5, v *vulns.Vulnerability, metrics *ConversionMetrics, repos []string) - FindNormalAffectedRanges(affected cves.Affected, metrics *ConversionMetrics) ([]*osvschema.Range, VersionRangeType) + ExtractVersions(cve models.CVE5, v *vulns.Vulnerability, metrics *models.ConversionMetrics, repos []string) + FindNormalAffectedRanges(affected models.Affected, metrics *models.ConversionMetrics) ([]*osvschema.Range, VersionRangeType) } // GetVersionExtractor returns the appropriate VersionExtractor for a given CNA. diff --git a/vulnfeeds/cvelist2osv/linux_extractor.go b/vulnfeeds/cvelist2osv/linux_extractor.go index 266dd9be252..7c4679bcd59 100644 --- a/vulnfeeds/cvelist2osv/linux_extractor.go +++ b/vulnfeeds/cvelist2osv/linux_extractor.go @@ -6,7 +6,9 @@ import ( "strconv" "strings" + "github.com/google/osv/vulnfeeds/conversion" "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvconstants" "github.com/ossf/osv-schema/bindings/go/osvschema" @@ -19,8 +21,8 @@ type LinuxVersionExtractor struct { var _ VersionExtractor = &LinuxVersionExtractor{} -// handleAffected takes an array of cves.Affected and handles how to extract them -func (l *LinuxVersionExtractor) handleAffected(v *vulns.Vulnerability, affected []cves.Affected, metrics *ConversionMetrics) bool { +// handleAffected takes an array of models.Affected and handles how to extract them +func (l *LinuxVersionExtractor) handleAffected(v *vulns.Vulnerability, affected []models.Affected, metrics *models.ConversionMetrics) bool { hasGit := false gotVersions := false for _, cveAff := range affected { @@ -41,15 +43,15 @@ func (l *LinuxVersionExtractor) handleAffected(v *vulns.Vulnerability, affected hasGit = true } aff := createLinuxAffected(versionRanges, versionType, cveAff.Repo) - metrics.AddSource(VersionSourceAffected) - addAffected(v, aff, metrics) + metrics.AddSource(models.VersionSourceAffected) + conversion.AddAffected(v, aff, metrics) } return gotVersions } // ExtractVersions for LinuxVersionExtractor. -func (l *LinuxVersionExtractor) ExtractVersions(cve cves.CVE5, v *vulns.Vulnerability, metrics *ConversionMetrics, _ []string) { +func (l *LinuxVersionExtractor) ExtractVersions(cve models.CVE5, v *vulns.Vulnerability, metrics *models.ConversionMetrics, _ []string) { gotVersions := l.handleAffected(v, cve.Containers.CNA.Affected, metrics) if !gotVersions { @@ -88,7 +90,7 @@ func createLinuxAffected(versionRanges []*osvschema.Range, versionType VersionRa // of 'unaffected' versions. This is common in Linux kernel CVEs where a product is // considered affected by default, and only unaffected versions are listed. // It sorts the introduced and fixed versions to create chronological ranges. -func findInverseAffectedRanges(cveAff cves.Affected, metrics *ConversionMetrics) (ranges []*osvschema.Range, versType VersionRangeType) { +func findInverseAffectedRanges(cveAff models.Affected, metrics *models.ConversionMetrics) (ranges []*osvschema.Range, versType VersionRangeType) { var introduced []string fixed := make([]string, 0, len(cveAff.Versions)) for _, vers := range cveAff.Versions { @@ -149,7 +151,7 @@ func findInverseAffectedRanges(cveAff cves.Affected, metrics *ConversionMetrics) return nil, VersionRangeTypeUnknown } -func (l *LinuxVersionExtractor) FindNormalAffectedRanges(affected cves.Affected, metrics *ConversionMetrics) ([]*osvschema.Range, VersionRangeType) { +func (l *LinuxVersionExtractor) FindNormalAffectedRanges(affected models.Affected, metrics *models.ConversionMetrics) ([]*osvschema.Range, VersionRangeType) { versionTypesCount := make(map[VersionRangeType]int) var versionRanges []*osvschema.Range for _, vers := range affected.Versions { @@ -171,7 +173,7 @@ func (l *LinuxVersionExtractor) FindNormalAffectedRanges(affected cves.Affected, // As a fallback, assume a single version means it's the last affected version. if vulns.CheckQuality(vers.Version).AtLeast(acceptableQuality) { versionRanges = append(versionRanges, cves.BuildVersionRange("0", vers.Version, "")) - metrics.Notes = append(metrics.Notes, fmt.Sprintf("Single version found %v - Assuming introduced = 0 and last affected = %v", vers.Version, vers.Version)) + metrics.AddNote("Single version found %v - Assuming introduced = 0 and last affected = %v", vers.Version, vers.Version) } } diff --git a/vulnfeeds/cvelist2osv/strategies.go b/vulnfeeds/cvelist2osv/strategies.go index f6f25b9b801..51cb4d59adb 100644 --- a/vulnfeeds/cvelist2osv/strategies.go +++ b/vulnfeeds/cvelist2osv/strategies.go @@ -2,14 +2,15 @@ package cvelist2osv import ( "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvschema" ) -func cpeVersionExtraction(cve cves.CVE5, metrics *ConversionMetrics) ([]*osvschema.Range, error) { +func cpeVersionExtraction(cve models.CVE5, metrics *models.ConversionMetrics) ([]*osvschema.Range, error) { cpeRanges, cpeStrings, err := findCPEVersionRanges(cve) if err == nil && len(cpeRanges) > 0 { - metrics.VersionSources = append(metrics.VersionSources, VersionSourceCPE) + metrics.VersionSources = append(metrics.VersionSources, models.VersionSourceCPE) metrics.CPEs = vulns.Unique(cpeStrings) return cpeRanges, nil @@ -21,15 +22,12 @@ func cpeVersionExtraction(cve cves.CVE5, metrics *ConversionMetrics) ([]*osvsche } // textVersionExtraction is a helper function for CPE and description extraction. -func textVersionExtraction(cve cves.CVE5, metrics *ConversionMetrics) []*osvschema.Range { +func textVersionExtraction(cve models.CVE5, metrics *models.ConversionMetrics) []*osvschema.Range { // As a last resort, try extracting versions from the description text. - versions, extractNotes := cves.ExtractVersionsFromText(nil, cves.EnglishDescription(cve.Containers.CNA.Descriptions)) - for _, note := range extractNotes { - metrics.AddNote("%s", note) - } + versions := cves.ExtractVersionsFromText(nil, models.EnglishDescription(cve.Containers.CNA.Descriptions), metrics) if len(versions) > 0 { // NOTE: These versions are not currently saved due to the need for better validation. - metrics.VersionSources = append(metrics.VersionSources, VersionSourceDescription) + metrics.VersionSources = append(metrics.VersionSources, models.VersionSourceDescription) metrics.AddNote("Extracted versions from description but did not save them: %+v", versions) } @@ -37,7 +35,7 @@ func textVersionExtraction(cve cves.CVE5, metrics *ConversionMetrics) []*osvsche } // initialNormalExtraction handles an expected case of version ranges in the affected field of CVE5 -func initialNormalExtraction(vers cves.Versions, metrics *ConversionMetrics, versionTypesCount map[VersionRangeType]int) ([]*osvschema.Range, VersionRangeType, bool) { +func initialNormalExtraction(vers models.Versions, metrics *models.ConversionMetrics, versionTypesCount map[VersionRangeType]int) ([]*osvschema.Range, VersionRangeType, bool) { if vers.Status != "affected" { return nil, VersionRangeTypeUnknown, true } diff --git a/vulnfeeds/cvelist2osv/version_extraction_test.go b/vulnfeeds/cvelist2osv/version_extraction_test.go index a1e87c8a4de..e1080681a0e 100644 --- a/vulnfeeds/cvelist2osv/version_extraction_test.go +++ b/vulnfeeds/cvelist2osv/version_extraction_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/vulns" "github.com/ossf/osv-schema/bindings/go/osvschema" "google.golang.org/protobuf/testing/protocmp" @@ -39,15 +40,15 @@ func TestToVersionRangeType(t *testing.T) { func TestFindNormalAffectedRanges(t *testing.T) { tests := []struct { name string - affected cves.Affected + affected models.Affected cnaAssigner string wantRanges []*osvschema.Range wantRangeType VersionRangeType }{ { name: "simple range", - affected: cves.Affected{ - Versions: []cves.Versions{ + affected: models.Affected{ + Versions: []models.Versions{ { Status: "affected", Version: "1.0", @@ -63,8 +64,8 @@ func TestFindNormalAffectedRanges(t *testing.T) { }, { name: "single version fallback", - affected: cves.Affected{ - Versions: []cves.Versions{ + affected: models.Affected{ + Versions: []models.Versions{ { Status: "affected", Version: "2.0", @@ -79,8 +80,8 @@ func TestFindNormalAffectedRanges(t *testing.T) { }, { name: "github range", - affected: cves.Affected{ - Versions: []cves.Versions{ + affected: models.Affected{ + Versions: []models.Versions{ { Status: "affected", Version: ">= 2.0, < 2.5", @@ -94,8 +95,8 @@ func TestFindNormalAffectedRanges(t *testing.T) { }, { name: "git commit", - affected: cves.Affected{ - Versions: []cves.Versions{ + affected: models.Affected{ + Versions: []models.Versions{ { Status: "affected", Version: "deadbeef", @@ -113,7 +114,7 @@ func TestFindNormalAffectedRanges(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { versionExtractor := &DefaultVersionExtractor{} - gotRanges, gotRangeType := versionExtractor.FindNormalAffectedRanges(tt.affected, &ConversionMetrics{}) + gotRanges, gotRangeType := versionExtractor.FindNormalAffectedRanges(tt.affected, &models.ConversionMetrics{}) if diff := cmp.Diff(tt.wantRanges, gotRanges, protocmp.Transform()); diff != "" { t.Errorf("findNormalAffectedRanges() ranges mismatch (-want +got):\n%s", diff) } @@ -149,15 +150,15 @@ func TestCompareSemverLike(t *testing.T) { func TestFindInverseAffectedRanges(t *testing.T) { tests := []struct { name string - affected cves.Affected + affected models.Affected versionType VersionRangeType cnaAssigner string want []*osvschema.Range }{ { name: "linux with wildcard", - affected: cves.Affected{ - Versions: []cves.Versions{ + affected: models.Affected{ + Versions: []models.Versions{ { Status: "affected", Version: "5.0", @@ -179,8 +180,8 @@ func TestFindInverseAffectedRanges(t *testing.T) { }, { name: "not linux", - affected: cves.Affected{ - Versions: []cves.Versions{ + affected: models.Affected{ + Versions: []models.Versions{ { Status: "unaffected", Version: "1.0", @@ -195,8 +196,8 @@ func TestFindInverseAffectedRanges(t *testing.T) { }, { name: "linux no wildcard", - affected: cves.Affected{ - Versions: []cves.Versions{ + affected: models.Affected{ + Versions: []models.Versions{ { Status: "affected", Version: "4.0", @@ -220,7 +221,7 @@ func TestFindInverseAffectedRanges(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - metrics := &ConversionMetrics{} + metrics := &models.ConversionMetrics{} gotRanges, gotVersionType := findInverseAffectedRanges(tt.affected, metrics) if diff := cmp.Diff(tt.want, gotRanges, protocmp.Transform()); diff != "" { t.Errorf("findInverseAffectedRanges() ranges mismatch (-want +got):\n%s", diff) @@ -235,7 +236,7 @@ func TestFindInverseAffectedRanges(t *testing.T) { func TestRealWorldFindInverseAffectedRanges(t *testing.T) { testCases := []struct { name string - cve cves.CVE5 + cve models.CVE5 expectedRanges []*osvschema.Range }{ { @@ -265,7 +266,7 @@ func TestRealWorldFindInverseAffectedRanges(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - var affectedBlock cves.Affected + var affectedBlock models.Affected // Find the specific affected block with defaultStatus: "affected". for _, affected := range tc.cve.Containers.CNA.Affected { if affected.DefaultStatus == "affected" { @@ -279,7 +280,7 @@ func TestRealWorldFindInverseAffectedRanges(t *testing.T) { } // Run the function under test. - gotRanges, _ := findInverseAffectedRanges(affectedBlock, &ConversionMetrics{}) + gotRanges, _ := findInverseAffectedRanges(affectedBlock, &models.ConversionMetrics{}) // Sort slices for deterministic comparison. sort.Slice(gotRanges, func(i, j int) bool { @@ -324,13 +325,13 @@ func TestRealWorldFindInverseAffectedRanges(t *testing.T) { func TestGetVersionExtractor(t *testing.T) { testCases := []struct { name string - cve cves.CVE5 + cve models.CVE5 expectedType reflect.Type }{ { name: "Linux CVE", - cve: cves.CVE5{ - Metadata: cves.CVE5Metadata{ + cve: models.CVE5{ + Metadata: models.CVE5Metadata{ AssignerShortName: "Linux", }, }, @@ -338,8 +339,8 @@ func TestGetVersionExtractor(t *testing.T) { }, { name: "Default CVE", - cve: cves.CVE5{ - Metadata: cves.CVE5Metadata{ + cve: models.CVE5{ + Metadata: models.CVE5Metadata{ AssignerShortName: "Anything", }, }, @@ -347,7 +348,7 @@ func TestGetVersionExtractor(t *testing.T) { }, { name: "Empty provider", - cve: cves.CVE5{}, + cve: models.CVE5{}, expectedType: reflect.TypeOf(&DefaultVersionExtractor{}), }, } @@ -365,7 +366,7 @@ func TestGetVersionExtractor(t *testing.T) { func TestExtractVersions(t *testing.T) { testCases := []struct { name string - cve cves.CVE5 + cve models.CVE5 cnaAssigner string repos []string expectedAffected []*osvschema.Affected @@ -550,7 +551,7 @@ func TestExtractVersions(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - metrics := &ConversionMetrics{} + metrics := &models.ConversionMetrics{} v := vulns.Vulnerability{ Vulnerability: &osvschema.Vulnerability{}, } diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache.yaml deleted file mode 100644 index e4d691f88f4..00000000000 --- a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -version: 2 -interactions: - - id: 0 - request: - proto: HTTP/1.1 - proto_major: 1 - proto_minor: 1 - content_length: 0 - host: github.com - form: - service: - - git-upload-pack - headers: - Accept: - - '*/*' - Host: - - github.com - User-Agent: - - go-git/5.x - url: https://github.com/google/osv.dev/info/refs?service=git-upload-pack - method: GET - response: - proto: HTTP/2.0 - proto_major: 2 - proto_minor: 0 - content_length: -1 - body: "001e# service=git-upload-pack\n0000015500685b36c023563ff36d728d4f1a3490e8d2fdad HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter object-format=sha1 agent=git/github-e744e5203bf9\n00693fdf840caa2a15aa1b02ad63edbe37f14c25ad04 refs/heads/dependabot/pip/gcp/functions/pypi/pip-ef11913619\n003f00685b36c023563ff36d728d4f1a3490e8d2fdad refs/heads/master\n005372fd51767b95fa0ab298d580c1214d8b7ba67a34 refs/heads/promote_prefix_ignore_prod\n00529df6f14b0eee5aff3241ca2b6c6680174a9747f2 refs/heads/refactor-vulnfeeds-little\n0049c718cee0e2409df8bd503255fc60c21bb6d661fe refs/heads/reproducable-zip\n0062536d8403169585521583475f89d6ce5aa03e0a92 refs/heads/temporary_modifications_for_mass_reimport\n004e2c85053cfa420c869bae7ef023c52300eaa0ad2c refs/heads/update-pr-permissions\n00472c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/heads/upgrade-schema\n003e7588d54370e7336f1063b3ef96112797016c521a refs/pull/1/head\n003fa2ac801881f48bf9047dc4ca68f9587a4781bd7a refs/pull/10/head\n00407cb597c5a84af14690b0ea49312ed7eda06552fe refs/pull/100/head\n0041f8bcb25186df1323e6fdb712e580556202656a9d refs/pull/1004/head\n00417a8c671bc9e97f92924965851b471c8aab1ee8ca refs/pull/1006/head\n0041bd500a4044afbf9d5c49977fada634356c4fc101 refs/pull/1008/head\n0041605331fd14e43a8e905cea5164a62387afd51d71 refs/pull/1009/head\n0040e0cb2c344ca0730320533a43b10071b7f4312473 refs/pull/101/head\n0041485f2b6da3d617788879c786212a58557c12c5cf refs/pull/1010/head\n0041f94d9c56ce66d401e2ea5d53f3d9addf6a218fdf refs/pull/1011/head\n0041e20794697e7cc44aba013c331af176cb811ad551 refs/pull/1012/head\n0041694cd5f0828ac7cb3e2d9b320515b8ef03c2606e refs/pull/1014/head\n0041d52d02ff5c97f677510c7bb9b2985db39c6fe796 refs/pull/1015/head\n00419feb39025a7cf0fc86cb6ab0cea814e3c53c674d refs/pull/1017/head\n00401349f69d688fc7a509215f9432ec73dfb46b8a61 refs/pull/102/head\n00414c5f3de7c47d6688f77c4237bd2d5f60cae0cf7b refs/pull/1021/head\n00413809cd3109f476a78e197446c08bf33a4ca55c00 refs/pull/1022/head\n0041b13a6f1110ec13e0a8bdc0c01a6916ff0e354d3b refs/pull/1023/head\n00411eec3164523b5821d4c5f011871871b15fab207b refs/pull/1025/head\n00413348d2f75453c4e73887799b3acfab01a6bd73e7 refs/pull/1026/head\n0041b53cbd1cb21af23acc46a7954291b63dd5c3ac95 refs/pull/1027/head\n0041933eb1962638d9dafecde200304b15fb5408d3b6 refs/pull/1028/head\n00410a12cc1f3413dae4d84d63ad8ed1c6061b329347 refs/pull/1029/head\n0040cac8c823c650078345e35c8a813f38599775b833 refs/pull/103/head\n00411098e2c8c83ac74d287172b8e0fef6f68a1b1b65 refs/pull/1030/head\n00413b911bc5ce4f58aaec84b36fa7221c9e6b8aeeb8 refs/pull/1031/head\n0041ae07ed72ea2cf91193f8641ab0171b81d226879d refs/pull/1032/head\n0041911aac60254233f36c9fa8b352d9b8af3659a2b5 refs/pull/1033/head\n0041188ddfb6d0fe396bc04f255d7a397da940cc80fa refs/pull/1034/head\n004133f110d8a987995a37085a6f749731ba6079d10b refs/pull/1035/head\n004120360a60cb396c3d3e70dfa97c221426e651f9b9 refs/pull/1036/head\n00419b7028075b186cb85fb1162626bc8d35ab190945 refs/pull/1037/head\n004118fc7c0fd0e0add81d729d5e94ad8752c1c57190 refs/pull/1038/head\n00410804317ab3de7d5f993fdac0a0a43896862a6ef0 refs/pull/1039/head\n004053587e5a82398d23e39165d358f8093f797c5aa2 refs/pull/104/head\n0041fd4f821b02dae483809871416ac633e45836f6c7 refs/pull/1040/head\n0041032ece4b67ad99947c5c87d22e7474bad94521f8 refs/pull/1041/head\n004124080a2e01350075cefb33f912d77193d1f4de03 refs/pull/1042/head\n004136143d4cadc1bb7ab1fdc4d0dc7746dd19eeda97 refs/pull/1043/head\n00415b400eba34551913d34764cb8d5acca6f0a4f3ae refs/pull/1044/head\n00418fabf11f241e11624c91601a0596491ffa3c0d96 refs/pull/1046/head\n0041e3432ab171ecea3f25eeed5caebd19365f2753d9 refs/pull/1047/head\n004155ffff4042fa481e0ad1842f711a9f17c4cf5329 refs/pull/1049/head\n00402bc665af22bd913071393eeb5b56f8eb8afdc032 refs/pull/105/head\n0041a0c78dc0629761e3d567b8a268b433bb336019c6 refs/pull/1050/head\n004116b14e3bfddfb2bc8a0823d218c9fb55c35caf51 refs/pull/1051/head\n004149a52d949c8c923a33f8714a2175ad46b5e57db3 refs/pull/1052/head\n00410376002d2b38a6232eaa8a66cbfba525befe984e refs/pull/1056/head\n004195c7d0521ed2ea24906a34903e6f2469d4fead2d refs/pull/1057/head\n0041c30a6319d0e78c5694e2049aa9592bbc549adca1 refs/pull/1058/head\n004168154d8f0d81656f0ce6c8dd682d62fb307537c7 refs/pull/1059/head\n0041d16773aa81db518a3a2d92c90f3e0c97dab5287e refs/pull/1061/head\n0041e28509db3aab8aa7529d0795237be7eba62081e7 refs/pull/1063/head\n00414388c2adc25321d6a6006b5e5a5c32ec4b667bca refs/pull/1064/head\n00413844a6050bc4d2e8a90a28ea675e75f07283892b refs/pull/1065/head\n00412d68c51e1abeaa462580db118c06976cae5757e6 refs/pull/1066/head\n0041765995426c75aca4ffeea95f17c9029833ca8ff1 refs/pull/1068/head\n004137c97f269ed9064f88019191bdfcefc7618f22ec refs/pull/1069/head\n0040e822ea91aa0806b3de8ad8c307653ac7ade7fce0 refs/pull/107/head\n00410408805073cb0949236ca0700989510dbc7a240e refs/pull/1070/head\n0041d5e2603a21f3a25aed411d6b306702b67b1234cd refs/pull/1071/head\n00419c0c3019d9151e70b86eb3fce732f67f002d1d85 refs/pull/1075/head\n0041655ae019e7dc23f7d0f0053ad0ab4b216ca8101e refs/pull/1076/head\n00418d05e98430ef70cfb241571300687e3d0b2da4dc refs/pull/1077/head\n004190a77a72bf7b1514f8d91f1e2e10dd27b685cddd refs/pull/1078/head\n0041ba4517b948d070865726525ce8f6f92bc082f74a refs/pull/1079/head\n00402ada540e49327edd5997909ef4c3bd9965fef118 refs/pull/108/head\n0041989ed566cf6bea122ad73b4ff33ec8f10277e923 refs/pull/1082/head\n004103380f4390ab124fb1e93dc866643794e852a1b2 refs/pull/1083/head\n00413791ee0d863a87b8569332494539fc64509b870b refs/pull/1085/head\n004194059682ef11325cf7295e0168965353b96e72c3 refs/pull/1086/head\n0041f1d03baec460b46b46334f40e9b6c0722f9a8548 refs/pull/1087/head\n00415b8db3e7470201d7b3e755144c413dbd55ce6f81 refs/pull/1088/head\n00417621c0df9aa340cc08461ad41a171cac9948df96 refs/pull/1089/head\n0041a201dd01dbbd2fe51655c2b5a772c94f07925fca refs/pull/1090/head\n0041c6183a91fa972b2b28978cd34bbc4ece0c93d034 refs/pull/1091/head\n004100fc04e29e3d78ed91f9713fdc9a207e24f4ee2b refs/pull/1092/head\n0041c1fb4fb270577a0fd2634c149f6d4de024fdf1ee refs/pull/1094/head\n00414b1f9f0b4053dedfbcd1094f9fe134a8a7591a1b refs/pull/1095/head\n00417ea4d86462f7299ad5e017bc8ca69c4970addb59 refs/pull/1099/head\n003ffe47213e95bdcc488ada1849e9a510bd6d2e36bb refs/pull/11/head\n004057843634a14a6b67f8e75e8493a36398f88c6061 refs/pull/110/head\n004130eb8f7bf2c089a49f240ec7d69918c0e2949e70 refs/pull/1100/head\n0041be9176bb6398a4305e45af0ba76f8c816618f2f5 refs/pull/1101/head\n0041839788f01f9d6c4bc25f7f2c599ccd4da8cbf03b refs/pull/1103/head\n0041cf14188cc12ef4de9d966a7f42165cefd46bdfa5 refs/pull/1104/head\n00421fb31e43d570a544d62c175fa325f27e25afb552 refs/pull/1104/merge\n004133f55e55ccd34157da77fc2ed8143f75a681fab3 refs/pull/1105/head\n00417795cd32bbb6492eb117e45001b498d3c4de704d refs/pull/1107/head\n00414ff9acaceaa374fd68c248096e24b0fbe6477c37 refs/pull/1108/head\n004179cfd7131dc021a00a1fc78262a56edabe4e8acd refs/pull/1109/head\n00400a5b4257ff2e70b78134c8c41067928b65d650d4 refs/pull/111/head\n0041e2043c6fd2f27b60945c85d68dd81f59c765cc94 refs/pull/1110/head\n0041a087b854e11a5bb8b43f79bb9c3c2cad81f0fa75 refs/pull/1111/head\n0041c88dcd99d1d61ce90db741986178851e94dde070 refs/pull/1112/head\n0041e394a186b01d402a32a06803e79041c4aac015f8 refs/pull/1114/head\n004137f9c94f61d6a9407286f144870376e8d0907779 refs/pull/1115/head\n00415b470a1df2c11ca8c7283f7dae08a5e689e7a67a refs/pull/1116/head\n0041ad2cfe753e9ad1405b82344b7e5d248a9fd23432 refs/pull/1118/head\n0041527139dfdfdc3872980f2cc48f88c1685702b5f6 refs/pull/1119/head\n00407d0bc21474662422503c1fed2f6efd38f29987e1 refs/pull/112/head\n00411db7266b0d3dc2060e099d33ed2d621b82c638cf refs/pull/1120/head\n0041c22baac1c31c2282b9c81f02b2d297e943e715e5 refs/pull/1121/head\n0041717810817a0a2b2878efbf4d655a5f3f02bdb4ca refs/pull/1122/head\n00415b047abac2af8c3454aa3f5d9e3f4fd336248091 refs/pull/1123/head\n004187bdc6bbe11b1f7111cb45b231e77cb543c03b7c refs/pull/1125/head\n00418ed6125c3266ee5fe16d90e8f0db26bdd21e9a06 refs/pull/1126/head\n004198b17c26f503a5bb857ea3435240a45f584d236e refs/pull/1127/head\n004145c24a202a91fce5c1f3f18a28ae2c328fb07fcd refs/pull/1128/head\n0041d89e784013fa44af219af4c59318ce60f8f05fdd refs/pull/1129/head\n0040a8e64b67ee50fdc923b4dfca8a026bb7b7e0f9e9 refs/pull/113/head\n004142ec9e39e560a60028b64ecbaf2bf9ffaea9acaf refs/pull/1130/head\n0041e90b84e7aeab7edf3bc569ea7b445e511c88d303 refs/pull/1132/head\n0041c1d699e161bc1bbfd7d57be2712c8ee1546db0b2 refs/pull/1133/head\n0041153b7f21669004864a63efceb934ac9247c43b44 refs/pull/1134/head\n00418a6b4659ba4a39a9f18d938a1303f35962bd2c63 refs/pull/1135/head\n00414b9e30d2079123127d445c57ef866691c2612c15 refs/pull/1136/head\n0041064e0107b717f35d289c101a8df5aa6aa49c14d2 refs/pull/1137/head\n0041a68a0cd38ab4f489191912d992c1d4b7fb598201 refs/pull/1138/head\n004196c4267fdd5ebc5a11abf2afde34952d11fa0e3d refs/pull/1139/head\n0040ad040b0e9fb545a5e5e72cab06eeed0457350efe refs/pull/114/head\n004168459aa29ef3251223f574b7902bae78890c3800 refs/pull/1140/head\n004158e5151180e67e209a300f98b10c8bd91d2f10d3 refs/pull/1141/head\n004197e7609dd55ff381e8b645373b38ecddf3615ad8 refs/pull/1142/head\n0041693895fd032c51b0c75036d9c41c6586ea59b306 refs/pull/1143/head\n00413665ffa0765a44fe402d9aded1e0997952d97bfe refs/pull/1144/head\n0041045004f0080fa316da50ca631055923d8383a910 refs/pull/1145/head\n00419c4c3d9bc4df26168813861503ae0920f7281907 refs/pull/1146/head\n0041c5b17cb731e4037a8b729ae71e18e267e0378f86 refs/pull/1147/head\n00411daf35f02314a6d03fc13e62beba958e2d504b4c refs/pull/1148/head\n004184160b5e6ed474b28230dce53c64b4de2be56660 refs/pull/1149/head\n0040efcb738cdef73909a1514edea0a2c3fc279fd0a5 refs/pull/115/head\n00416167e16bee3e6f04a58ee6e31717c1610e139f9e refs/pull/1150/head\n00414d3249741636a1311a19d70f2af571f9f69e2e70 refs/pull/1151/head\n00419b2fa3ecb7cf81be6030c621c98e1aaee8103839 refs/pull/1152/head\n004258fae47d57833a93c2114f003486a178c7fe4565 refs/pull/1152/merge\n004170972ff2903159bb09ef351d62f1f8a056b8cb2e refs/pull/1156/head\n0041949f1218bfc1a4a43ecc024517745812f8da30a1 refs/pull/1157/head\n00410b5fcb4e937e813c777bd6a1cee272e8ecb5c69e refs/pull/1158/head\n0041378637ce104c9282207fa33f33ef2a167fe430d5 refs/pull/1159/head\n0040853201302c759848d37893d94ba11ea590d61958 refs/pull/116/head\n0041e09188102ad3986443886927e92966e9e7592cc3 refs/pull/1160/head\n0041700d09bf5a8f85ccc34818ec42b6a546128138b6 refs/pull/1161/head\n0041d9ae5ece28cd3744db4545fafc3e91ef1bff6f2b refs/pull/1162/head\n0041850c562b1c00fbbaf6a88dd8193de3963a820620 refs/pull/1163/head\n0041e662a66092408df23b3d993227fa931b6c18bccb refs/pull/1164/head\n0041f47b8a51d42a9afdcf61d31088ee3d4d67a38ad1 refs/pull/1165/head\n0041bc14f54a67add60193012a25131e046ced831b7c refs/pull/1167/head\n0041f04422a14208718301ea5ab6edeaa9bcd8bb0b18 refs/pull/1168/head\n0041c4527fa17adf08abf20e61de87fb7a9cfebde6bb refs/pull/1169/head\n0040f2193ca860f0648ffc8f2e6de877f92a363e89f9 refs/pull/117/head\n0041d7e54154d56ac72520daded39ada968082c9063a refs/pull/1170/head\n0041b43ea6c0af5ec6a0ba59691044fc4f168993808f refs/pull/1171/head\n0041e573127901d5456835c3a14581dac8317df14710 refs/pull/1172/head\n00419eb7982d800aa6d091a70e1d66a025e86b0fdced refs/pull/1173/head\n00411e10841edcb227d69ce075d0023c1519e6b61899 refs/pull/1174/head\n0041165a91da2ba287ec682f675235313e0ffffc221c refs/pull/1175/head\n004156a22734341963ec2726e9eabaa51d7c0bbf9f57 refs/pull/1176/head\n004101a728fefcdf53a12d4190159ef3dd413e726d1c refs/pull/1177/head\n0042a37bb2235324744350d465f23b7ff91bfd16f36c refs/pull/1177/merge\n0041645b3c4efecc4799fe6e40282c2b86b941e58903 refs/pull/1178/head\n0041da3ae6f7076eced3e1905f2345136d0ff6f3dc9e refs/pull/1179/head\n00407485aac97090584e3815fbbc2273d97634e1e687 refs/pull/118/head\n0041fc120ce5c94b1a168b89a9664b75e703c00170f3 refs/pull/1180/head\n004131eb3dc0538687ab2714afb69fb4408e438db967 refs/pull/1181/head\n0041c9f32af3b88f879262a81554a5cf87f0d72fdafd refs/pull/1182/head\n00410e896c2d535ae2d5f1a0abe24c8185b60e50b4ba refs/pull/1183/head\n00413f8e4d222485db16dd53a82c1aa8d53dca62606a refs/pull/1184/head\n0041902cf79cf6c7107315190d647ce9afe83a1f46c4 refs/pull/1185/head\n004101021d07febbe1dc0964c3f3a4fe25bf2c864670 refs/pull/1186/head\n0041f40ed0b4032dffabc9edb601e3bcee77922d07d2 refs/pull/1187/head\n0041149fee3f435468ea5ba248158eef48bc6ab59243 refs/pull/1188/head\n004192a96024812d7a9471598ca7509577eb6f81448b refs/pull/1189/head\n0040fa878cbaca3a34c3a27763118e5b0d947aef3337 refs/pull/119/head\n00412745cac3b81bc800037aff2b3ab37709d37a7921 refs/pull/1190/head\n00415c4c55133d0640b0e2f6abbee881b1fd3a3356f6 refs/pull/1191/head\n0041cd47d6beab06c76d3a11d158c93ca20f09ba4177 refs/pull/1192/head\n004113d6b7545444c47dfd08faf6aa2b9e1ed6a8dcf7 refs/pull/1193/head\n0041a686ab68d088b2a72080224afa23f590c8e83a0f refs/pull/1194/head\n0041f97c4cecf158db398a7557d46233224436e88ac6 refs/pull/1195/head\n0041e010e5b0b1c0e50753277540087df697bbbddbe5 refs/pull/1196/head\n0041208f300c2b85b19840e4a105bfe1747cdb31be0f refs/pull/1197/head\n00416f67f17c15194150c498445ac4bb7f6b3cf2806f refs/pull/1198/head\n003fd90d93044396651a5760ab8619869f3ffa7e28a2 refs/pull/12/head\n0040d4fb3e5bf442245bdead885901391d6448f036c4 refs/pull/120/head\n004140a9bf1f01f1fcaff780c463653753b4b7b44789 refs/pull/1200/head\n00414e3c6c4f74cd604ee2c988d663a4f0bd5084936a refs/pull/1201/head\n004110475df37c8747ce46e549d8967bd366ae74bd4a refs/pull/1202/head\n0042d8416218ba39f441d66806e5e0b036e175c68d7b refs/pull/1202/merge\n0041a700e380ac386cc24c1054bb871d5293ac54276e refs/pull/1203/head\n0041f0e9d7ca384d95b257676adbe5db549b206888b9 refs/pull/1204/head\n0041e75b7e3be1f8eb593039e71c68c620ddca416555 refs/pull/1205/head\n00416d54b8e24ca11529459c8304de1d1775c21544f4 refs/pull/1206/head\n00410632e7fb91e7a0fed85c55fba17f03ffbca4ca4b refs/pull/1207/head\n0041b4179c0e8f91a580c494380568cc755b830cb0e4 refs/pull/1208/head\n0041d9a46d372622a55840ff16e713574aa5aa589078 refs/pull/1210/head\n00415f7ae1d59f7216a4e69bd9658878445f8354f379 refs/pull/1212/head\n0041ec47072f7b589b5076bca86e80a50b4ef0e4a67a refs/pull/1213/head\n00417a8297543e96cbfdca35deaf7ef482a887d82641 refs/pull/1214/head\n004129f6cd65449e9fce1dc070e03c5a0fd5d011c65c refs/pull/1216/head\n004188f0ba0dbdd1920ffe0212466eb97a47dbaf88e9 refs/pull/1218/head\n0041fab2e73d54951557743573f70d6eea1da3060157 refs/pull/1219/head\n00408b7243382787f405189d5180c5a574b3d725449a refs/pull/122/head\n004188a45b1b0f86c9d89061ef74d669e35f4a12a419 refs/pull/1220/head\n00418a99741ae7e5fd4f7904a0ab39bebf9c52347dff refs/pull/1221/head\n0041417322b4e9949268a0dc74de31e5157f85874fb0 refs/pull/1222/head\n0041a96feac6ea2180d6765f714dbf4ff177bf87ab7d refs/pull/1223/head\n0041c5fe75fcdd34799ea08d44f755f0fcdb8d874690 refs/pull/1224/head\n00418dac58da823f0c0370fff98e5f3d893cbedff65d refs/pull/1225/head\n0041c026d87119a26050ce707fd46d8e39a3648e46fd refs/pull/1227/head\n004122c1aba51dfe449915b86a8e89804362326ed46a refs/pull/1228/head\n00414d86f314d4f11c630f48fed1294af87fe4083f95 refs/pull/1229/head\n004095972d7b95720065b9ad13946c2f19e7940fe074 refs/pull/123/head\n0041a15cc8d82d9531f7a3c7062c5a44e1d74962db27 refs/pull/1230/head\n0041608a8693561c85a4519bad15d4477760b1213f52 refs/pull/1231/head\n00418499cabe2d26bdf79362cf5848d2d6c5feb4f3e0 refs/pull/1232/head\n0041097ff7d5dff9e064297f16888e671c1a8b20a54d refs/pull/1236/head\n00411ff8266b09309ce473a5fdfde6b23df95d91c4bc refs/pull/1237/head\n0041041c24c794f085f187c8b2626568c1ce9addc431 refs/pull/1238/head\n00417941b0db3a95531936ed7d492199e1c506f4b693 refs/pull/1239/head\n004092350c4dc465cc0e1b34e5f6c95379a19a88fe7b refs/pull/124/head\n004144e9933cfcd6f810b8c84a49654495b08aa96443 refs/pull/1241/head\n0041e3aeb1a51d39c98fe2d05d6a4e56881b8f308e98 refs/pull/1242/head\n0041297bc99ce0f1fe0c722646e878c48ca1b7359f54 refs/pull/1244/head\n0041ab57c19fb6878591469153a6b43cd200e5056ad7 refs/pull/1246/head\n00416bbbd03d1f609db86085779327329af0b870df5e refs/pull/1247/head\n0040ba000c0f39d232ea471959ade31d5bf2644e44b5 refs/pull/125/head\n0041121e405182ebc1747bc4b70ee51f1ad515eccbec refs/pull/1250/head\n00412a64d4bf9067530451df1015757b964dfe1a14e2 refs/pull/1251/head\n004138777fdb3a08b8fa21b046cc3f99ed080b773cc3 refs/pull/1252/head\n004189a916d3fa0e29776db1dca2cfd496040b7f59ab refs/pull/1253/head\n0041b90f19856b5d540108a64072c2deac6b1cd78963 refs/pull/1254/head\n00419b6edb6b82873b174431d6fdd2176c56f24120e4 refs/pull/1255/head\n00416256217be5d1950457e58da0bae4bf04f2213719 refs/pull/1256/head\n0041881388e2752e4f3dd131e8a1f8bae279d2f120df refs/pull/1257/head\n004191315d3344d7b85173da33c9f3f2b43d6b27f355 refs/pull/1258/head\n0041be6ea4d8245ececbe374dc0dd1d809cb94b073f6 refs/pull/1259/head\n004005a29c8ff1ca492bc90f87070fd303a8110e63cf refs/pull/126/head\n00412ac78599f1db05f40ae306d6b9ae7c56a3710044 refs/pull/1260/head\n0041253384d79ca6561d4f3c81f4e41514470026c6c3 refs/pull/1261/head\n0041e96f52adadd2e3f7f64715f3e9c4c0638e0fca9f refs/pull/1262/head\n0041129c977415a332d4a850ead18bbbcabb3022494f refs/pull/1263/head\n004152b028520be76bac86f78d8c684c2c5ed9cccc50 refs/pull/1264/head\n004186f9391f84fcca2c177eb788a56ae8b7e543d902 refs/pull/1265/head\n00414d3590834890a95113490d5040225fb270b5b7d3 refs/pull/1266/head\n004181622365cbead4b2326525b2601da753a24a5e55 refs/pull/1267/head\n0041117f2cce652b5628970d0977266f55eaa55cb407 refs/pull/1268/head\n00418bf7be7eb05fcca77f395a59a02e4b1e1860b469 refs/pull/1269/head\n0040b87fb4478b446f4ff48ac78beafb90fa37054b41 refs/pull/127/head\n0041c386d3a3fd7dd25d1c088999350621015b934231 refs/pull/1270/head\n004196c88193e27d33fe815eb0551d8087c8f08968fa refs/pull/1272/head\n004158ef639deb89f9d5517c308e977dc683f0c0168c refs/pull/1276/head\n004150328a328d6100da7adb817b253bb006d7c0c046 refs/pull/1277/head\n00410dfc3535eb0c29e638e9d7371fbc84f356c80aeb refs/pull/1278/head\n0041133f337708f4da78c753d8607f35590d9d0f36cd refs/pull/1279/head\n0040c79671a08acdfa73c90d555e0065ec3e108e2214 refs/pull/128/head\n00414a3f1930fa113df2b198bf7e6b4bf2753cb08c06 refs/pull/1280/head\n00417326ff73868061c78efdca1d22bdbc93f4dbc060 refs/pull/1282/head\n00414b592a00998dd4c4a9cca11be7979eeff9c1709d refs/pull/1284/head\n00410a19b05580dc24028dacf4f568529b24bc76f8cb refs/pull/1285/head\n0041e43a40ae80d2e8a6a0abaaa31ce4763d146430b8 refs/pull/1286/head\n0041fc7e59d29509405c92fd972087e6094f93f02184 refs/pull/1287/head\n0041add1a8d02937b9f518ab45756f4ed93e0ed2a7e6 refs/pull/1288/head\n004173ea6713b3e09df07ee64563409a3a711524ae4a refs/pull/1289/head\n004079f203e8674a264ca918ad0a59b52720c5053bba refs/pull/129/head\n00412ea3e74c9fa834f044e3ae49533106a4513a1c07 refs/pull/1290/head\n0041207fcb2a7a6053f40a9a570bf4ce711fcae705d7 refs/pull/1291/head\n0041215e33c64e886aa92446ff82a8bdc48bdd92bdd5 refs/pull/1294/head\n004173c35234a9984cf83a5eb299dd2db138c048f6e0 refs/pull/1295/head\n0041cb236ea352e1e55ff844930a0ae81158768fd7b9 refs/pull/1296/head\n0041436a8602956ae04dac1f0b04770ce06112938929 refs/pull/1297/head\n0041618ac0ded5bd906e79bb7b784f29846eb3af9fcd refs/pull/1298/head\n0041d6e19fb7845e1ee98706ee8f3a36f0d97e5b952b refs/pull/1299/head\n003f3a8412073dcc1900bd009153b7c0bd40d59710a3 refs/pull/13/head\n004143294d0e607f85a1ed7ce9c504e6bdbf768b3d78 refs/pull/1300/head\n00413adf485f0e8226a37911538dcee7d1f0a252ea60 refs/pull/1301/head\n00417113d61286fb327c585ee08a12b25117245767ed refs/pull/1302/head\n004120bc1bfe5d146d7a453f501c3f59d08ce3972b98 refs/pull/1303/head\n0041911566620041bd942966b0fdf5bd53ee8c220755 refs/pull/1304/head\n004285b19a8198bfab56e74c4efaa5dd3573fb44430a refs/pull/1304/merge\n0041bb833df0473c9e06a15fa30931f62f43f8fa41df refs/pull/1305/head\n0041c1dcd02d5aeeaedfbe9a47719bdcf0517287064e refs/pull/1306/head\n0041bed15155e558a64bd7e1d023f0f6c01e4e89cc22 refs/pull/1307/head\n0041ae7549465893029628571539475cab50a5f88b29 refs/pull/1308/head\n0041fdd103ee379731772968bc0fa4abce0a222c482e refs/pull/1309/head\n004052355df83bd1f16a0d6cfdf839014d0f6a0d1742 refs/pull/131/head\n00412e0d369368249bfc6c27477840adfd1745067f43 refs/pull/1310/head\n00412ede4b86018662df57603431a2ca06f0e63fe0ab refs/pull/1311/head\n0041ffe128c7f53f9261c2e478ba220ab8c2bce7586c refs/pull/1312/head\n004110564b2cf9d3e0af7986404100358a81095fc991 refs/pull/1313/head\n00415d4eeedceccda7c2e4e55857b5a6adfae318248a refs/pull/1314/head\n0041a839faa175e5f0f8c1773cb5dc565771eb4b9f5f refs/pull/1315/head\n0041e1d82ae78462eb11827aceb7100afc9e6580bc3e refs/pull/1316/head\n0041b1d8d0975cf7e2cc0cffdb1e9d861f9ec3c8a464 refs/pull/1317/head\n0041cd7839e83d0fa2c941902e812164e8919eeb6add refs/pull/1318/head\n0041b729510125f5038236e9c2f739a0344813040023 refs/pull/1319/head\n0040de13fa317c1f5f068676066815c089d2dc6147d4 refs/pull/132/head\n0041734cdc193dfaa3632bd6bd1e116d1bae62f9a44b refs/pull/1320/head\n004169f6a1f844f349c8ba3a32a3c5da1096567c65ff refs/pull/1322/head\n004157dac2df4e12ac5ac067549fdcfc33f3625a68e4 refs/pull/1323/head\n00410449ab5546a48274f8db2472e8b21f90da47f1ba refs/pull/1324/head\n004126c21c1ca66e207f17944073b90c943e0447d5ac refs/pull/1325/head\n00410525f3fce77b48be23f56df109940605c512a64e refs/pull/1326/head\n0041ff220eaa3867738f3db0eb193b4b64b358ceb636 refs/pull/1327/head\n0041b7507c4ce4d7050d93cce250f9420bf499dcf79c refs/pull/1328/head\n0041c66c75f095bdbdc61c9f6a7918250bb35d11c27c refs/pull/1329/head\n0040189e780a8f8800d4a0d3bc302e046fd6de7a2193 refs/pull/133/head\n0041961a6e96dff63ee0143258b0c085d0902187a58d refs/pull/1330/head\n004145df50f1f4d0e6d4c0a0119a259beace2112bd53 refs/pull/1331/head\n00417ab9a1982ce11b5f59474d9d1c4290deb3cd66e7 refs/pull/1332/head\n00419ced3c989395984365a5cd2c756124a292692d05 refs/pull/1333/head\n0041290599c46d3019e2faf2c278c11a534ca383a8ed refs/pull/1334/head\n0041faecb02327ed55b78f3f52895749c9d5c83b5d79 refs/pull/1335/head\n004104a4c755a57d4eabcaeacfac73ae163261e2dcf1 refs/pull/1336/head\n00419e97654e7bd49474a89cf9ad0139bda19dc1e5a9 refs/pull/1337/head\n0041fc6fba1f9f88b4eec99b5222a1431f13b74456ec refs/pull/1338/head\n0041f1bab89b149ef99141a371a872979a47de900ce3 refs/pull/1339/head\n0040f2340c7785b24944f55d7e97e27b347be8df3a97 refs/pull/134/head\n00415a06f626752062956a8a1381504662c2d7ebd629 refs/pull/1340/head\n0041ea595ee08864ca521498095f830189a7c9df36a8 refs/pull/1341/head\n0041257c3048815f335b9f0a22fd4854b1237aaf0e05 refs/pull/1342/head\n0041bafbee83538cf951f538ca7ad13779f59f164d71 refs/pull/1343/head\n00412fd3ce652de76465b0f42f488020dc954885d2d0 refs/pull/1344/head\n0041c64bdb1c7e57087ed8d84e221de17d758391f2c9 refs/pull/1345/head\n0041747c018e63c009b2155bb4f6deb6a583d3caf22e refs/pull/1346/head\n00414e30fe74d61b9166b308ddc6ca31248ad92c0574 refs/pull/1347/head\n0041c3fc7f915e82757460710c0e8128ee5b36911035 refs/pull/1349/head\n0040edc675a835d97be1fca5e3cba3de1d92690395da refs/pull/135/head\n0041a0b692649edbd8b4d3e4fc273edb51b90dab4226 refs/pull/1350/head\n0041bee1b515d3eac86a33be45b026744db3594701f5 refs/pull/1351/head\n00417a8e666d0bd3aa6de59703c76d327d023e855eb4 refs/pull/1352/head\n0041b4c0c67c083c3f3d9275dfb2f3e3f30b014598f3 refs/pull/1353/head\n00416cc04160395a02237ea60fcb56369dcc2af898bc refs/pull/1354/head\n00417b5d44de35d37ec6af061e835241251cf0600906 refs/pull/1356/head\n00410ddb923bb03a95e57aa0e591c9d79a6bbc042ccd refs/pull/1357/head\n00415f4e98aebd5c88b1f31d0dc5fe89d756e4836657 refs/pull/1358/head\n00410b6677fdfa4169e0426b59f2b811c633848cef5d refs/pull/1359/head\n0040e9437545a50ce325010edce479c33fdb5fb8e911 refs/pull/136/head\n0041da17b72261b13286aec80d2720d55ded18ac9c20 refs/pull/1360/head\n004175df95cb365bf57e6605ec4768f11ad6cad1c5d9 refs/pull/1361/head\n004161ede2f2c9831b2ad582dd0b46b668e8f53eda44 refs/pull/1362/head\n0041afba174909676dd33be7a4004636350c0c4866a0 refs/pull/1364/head\n0041e2196d07a5f82f433a3d45db1ad79dd073fed364 refs/pull/1365/head\n0041d8202d6c7c333bd3cdd030884261af6f8af1edc7 refs/pull/1367/head\n004100eba200a2fdcd297b2aca58a6ba86eabaeb2b4a refs/pull/1368/head\n0041831e8fbd68217ff1d460dd4df4b21f7c22b6c7bd refs/pull/1369/head\n00409626f978d682ed60c4f361078d5add6f4794914a refs/pull/137/head\n0041ce2ad323892dc3a11963c9968da41582fa403fa9 refs/pull/1370/head\n00411a47355f103ecf545a1bb3a498f1a0b5b76b2fef refs/pull/1371/head\n0041762fae248f54871949683a7fe74bb3ed1d04f1b5 refs/pull/1373/head\n00416980afeb6774a3f8ef05834d8baf2df6a0f9bcde refs/pull/1374/head\n004144bbac892c3674e04a4c22107572fdb70870291e refs/pull/1375/head\n0041ca65a6f8e68e7c84b0845ae551ded0955b65dfd1 refs/pull/1376/head\n0041a6e1d21fc5b0fe82b02eac25b2ad3e06f5b7d851 refs/pull/1377/head\n004177404b3cbb5f0c567e9923373363670b107cb7dd refs/pull/1378/head\n0041e10cc0588b127c0a7a345708ca4694b23b27a42e refs/pull/1379/head\n0040e07f89546938680d414fd7b9485f3c0aa7ec0232 refs/pull/138/head\n0041dff810775dad1f692e87bf9411750c8ce22c8976 refs/pull/1381/head\n00416278f3cfc933a1a2fa5fe4c1006a8f3353e24b0a refs/pull/1382/head\n004103e3e96fb3dba1d920fd58fabdd6fbeb7c99bb69 refs/pull/1383/head\n0041e215906b2e757daf6f9cdf479c6ad074b965ea37 refs/pull/1384/head\n0041f60c4322be9edafb23af08c9be6c20c9f85108d5 refs/pull/1385/head\n0041b246f36763b355cbb9cc093783ca6f13f9cdc4c3 refs/pull/1386/head\n0041721c39c10965b428e222283aa864f06bb154c04a refs/pull/1387/head\n004171afc34970336601672c9edfbd3999e924a448db refs/pull/1388/head\n004078ca8ffccb0245a5a61cf24f778008d9787f0998 refs/pull/139/head\n0041e72e66bf5707b31c82e55f3292407daabf66e6b6 refs/pull/1390/head\n004127bed5c648b4c2bdae20ae119e50b968ea79ab1d refs/pull/1392/head\n00419ff43939cf0c8e6986d8e92126e6338863b648f4 refs/pull/1393/head\n00410a552e22b16e6fc24ea55f88d20c7901ad2c3cff refs/pull/1394/head\n0041a21275fef5419e8ec3c8c92826bc05d6f2c645bb refs/pull/1395/head\n004178832b0fc1490907c8fbb936dd7b1c43c5863170 refs/pull/1396/head\n00418951ee20a76f985f31f7adb31d4f3c1990300789 refs/pull/1397/head\n003fc6b4d55a540de28af226e774e0a2a49e70ab02d9 refs/pull/14/head\n004016c45dab0a86a40e2ba16d8efe04e0be57e78cea refs/pull/140/head\n00417dd1f2f0fbd3520d413b1b4a458c0276ca3f05c2 refs/pull/1400/head\n0041da9a726ce2f007ec4ee803ce0bd7157b4421e0be refs/pull/1402/head\n0041186c598fee1c82e4c4e904856d5dbf4fe7b109ad refs/pull/1403/head\n0041d8326a0f09b0ed2aea1a559d6af68458c63bf3f7 refs/pull/1405/head\n0041236c0c3ffc7ae031d21814b583c637cadd989d75 refs/pull/1406/head\n00412ef45eca094f6f574206fabccda2d9ba36ffd7e6 refs/pull/1407/head\n004169dba3b7a359925aafe3d06d7b6c5f0c40f360ef refs/pull/1408/head\n0041fd84167ec1429163534a1c312ea42f7b48fac010 refs/pull/1409/head\n0040ebb6c96b259d1a247c14f0db7adbd63035db97fd refs/pull/141/head\n00415b72bce47ac95923bce868b8fdedc204bdd54af4 refs/pull/1410/head\n00412dd82629ff324d2222d5bcec6fa1df77f023b330 refs/pull/1412/head\n0041566b2cd164e5b92b7c7993d45f367eaa4ac13293 refs/pull/1414/head\n00411f2e4049e40f05de6bc89a4df3b902617cd2c4c7 refs/pull/1415/head\n00411138579a9fa79aab8611dd866a5c7d7b36d5b407 refs/pull/1416/head\n0041520b03ea4d2fe774552ebbf371a546fe16e00d5c refs/pull/1419/head\n00403ea332e3d92983d258198c4944e48f2a679e6705 refs/pull/142/head\n0041cbae00c32292523e1178b7936cb6a0ee0c544ada refs/pull/1420/head\n0041df616c3977bc7a2125170035b062cfb931b39c0d refs/pull/1421/head\n00417cc8172bdb8a34456e676cee0d4ce9084ba7bbea refs/pull/1422/head\n004192677833ea4b356154ce80923125322345e0d4e0 refs/pull/1423/head\n00410cb307fa354bd8e66ae40b7fb3cc537b884c03b2 refs/pull/1424/head\n0041e5cfcb34d6c24a402aabb88f79c321124b89562f refs/pull/1425/head\n004136f4a8e330e49343137e747d02300ad6b352d7eb refs/pull/1428/head\n00414a4e9c9f75a503df0da30240b8dd382811a34448 refs/pull/1429/head\n00401e851bdc987c158bfe0edc3ce66cd3ab32b95efe refs/pull/143/head\n0041640a72f812d1681c148081ce769c94d18089a531 refs/pull/1430/head\n0041768bbbc5e3e37c678dfb001bddbf3c8c4a3feab1 refs/pull/1431/head\n0041e66f71fdd1c431a684a6d96b7b0e02f99e294e8d refs/pull/1432/head\n0041a0e482e060ff55476ca8038cac6e0b7c659c3373 refs/pull/1434/head\n0041fb2e26335ddb51333e162b916156c0884f567c37 refs/pull/1435/head\n0041b1772fe46558e79a885a654ff12d5a2e194c2138 refs/pull/1437/head\n00413681973c9df9739802d4137c63b769054e65ed19 refs/pull/1439/head\n00402e9dce6c48f32267884dd2b28842ec6925b645fa refs/pull/144/head\n004123939d417e265d55ed1fc3aabcd501507ee01ef2 refs/pull/1440/head\n004197c65d1cd8e2c8f901cf5fc86614310abb52fe9f refs/pull/1441/head\n004103dac88c576f8ecab3db909f629585712b8c0eb4 refs/pull/1442/head\n0041a6f76105ef194c3eaf7b4b7912a38f7294c07aae refs/pull/1444/head\n0041fb648a2ea697e46ed51c35f68c8236b3bd10e59c refs/pull/1445/head\n0041afe3ae2d7fe951c37913e38fa09b4fd3a6507008 refs/pull/1446/head\n0041466b94b687fc5518d881f59d1e0372443b841e34 refs/pull/1447/head\n004123532d67a96aeaf8b4a6361a3fadccc6d933f37f refs/pull/1448/head\n0040593ef33d4b5fe2d7feabb021d0972519deb6b744 refs/pull/145/head\n0041ee9ff50c9c2b4ec849994b49738eaadd45df8d11 refs/pull/1450/head\n00414d997c6f83857a7873eb78b0802816a5cba610d2 refs/pull/1453/head\n0041c1b4346191fe2b03d0c41637d53d00a84ed431b6 refs/pull/1454/head\n004119120bfb738b794199bfe5797b8248c6e1920492 refs/pull/1455/head\n00421d489a06e8f566b83feb9b10282434c69a2a848f refs/pull/1455/merge\n0041e93dad30305e69dc20372d1a7684ac76c2b977ee refs/pull/1456/head\n0041a5f94be445a32a0c5991e85d12fdda4a8fa2fc97 refs/pull/1457/head\n0041164d702fdd71ca10606e1701c9ebed15a885da41 refs/pull/1458/head\n0041d342f1d18f88041e3fbacda44330e22d9798e9e7 refs/pull/1459/head\n00406df8b6ad0a9e4dade94f2747d776d7dda1f4e4f8 refs/pull/146/head\n00417647947be27328f428cb50ef77189933561b6990 refs/pull/1460/head\n00418a4b9b4ffe361034167304c74c026ddc6ac4a33f refs/pull/1462/head\n004142813fb3381fa994874cd455ef72b49874ccda7e refs/pull/1463/head\n0041df4c6c121ab7033a14f9bb85f4e7416c8629c06d refs/pull/1464/head\n004105696886d50ce893da5dc7b6917e9947f3bbb835 refs/pull/1465/head\n0041fd3cb207b52d77dddceb45d01c33065f495ef029 refs/pull/1466/head\n00413a659000e96e36927d6edb20fb7361e74300ecf3 refs/pull/1468/head\n0041f49d889a01613f914a8d1768e449fa51a9127c54 refs/pull/1469/head\n004196895dba95749f0b38fb2d49f0506bfbbb9539ed refs/pull/1470/head\n0041f2f5eef8ce350ba79a9cdb67a96e968c3c5c5beb refs/pull/1471/head\n00415d7d6f1f25924dd01528a74cc38877510345299f refs/pull/1472/head\n0041b62dd25e1192be880b8c96e162ae5f6905524084 refs/pull/1473/head\n004164469920f86f96c92a5f69b313990f4b3b08b007 refs/pull/1475/head\n0041ff1fd64690c606dc96f61d599866f1ed7da972c6 refs/pull/1477/head\n00415ca8b4a96239e4feca8336661d98ea495bb1099f refs/pull/1478/head\n00414e696f6e40d363f43a084a0ada2144d8cb86873d refs/pull/1479/head\n00418a2e104021bd2cd6d2b69f606d784d1df6c7b8a9 refs/pull/1480/head\n00414f78a2c9c44eae18251b89aed140f9bf4985d028 refs/pull/1481/head\n0041bb284ef37e8480c03b519560f08f8b38dee5bb98 refs/pull/1482/head\n0041fa1d5b0c70383c08e7ee37bf66485198ff3e7ff8 refs/pull/1483/head\n0041c3a7a260d2f19a4d350e3346d008c776f74e9b98 refs/pull/1484/head\n004110e894be6f4d9b506f5459ea296592c312f5c053 refs/pull/1485/head\n00418d611111423fb3596be120ee6bcde94aeccf3745 refs/pull/1487/head\n0041afefc631fce6dff9770db8867982ffee8b091218 refs/pull/1488/head\n00400b8e4aa1499399f5212fd700cf2f310076ae8010 refs/pull/149/head\n0041ab1a2bc6c7337ace9e89ea483619794ce5a2565b refs/pull/1490/head\n004171ffff50fbf4cad3b72c45644e926b0378005212 refs/pull/1491/head\n0041bb95218921ae7fe9e8b4c3336278e078c315d0fc refs/pull/1492/head\n00415c20d41d46c16bfc6a9e82f744bd9b5541f3fd18 refs/pull/1493/head\n004120eab42cf1a7a89de8ff99af2d73a32d6cd5bfd6 refs/pull/1494/head\n0041a6764c4ed63427a5145422b6f7254ab4529bc8c6 refs/pull/1495/head\n0041c617d48580fe8aa02865fdd3c434d507a5ffe940 refs/pull/1496/head\n00418286eaba5003c774fc206fafdabb0a2f8ee2a50d refs/pull/1497/head\n0041f5f9b82390a6425baab9dd8d7c8937f0d2680b24 refs/pull/1498/head\n0041600434da8ba54186c894f8032da0cae6161d492d refs/pull/1499/head\n003f3c6e266b75f17fa1643a1d0b189b8d350bb8081f refs/pull/15/head\n00409aeaeccd95e696e800e08ccb6fabfedd7ad0e8a7 refs/pull/150/head\n004162a27e278e0cbd969b615943e89f1ed0ba4d76ed refs/pull/1500/head\n0041204898438a43b37fc7c56f5ceb9f2bce1e6d28ef refs/pull/1501/head\n0041f55692ca0190703a2e425672c45580b440a70bd0 refs/pull/1502/head\n0041ae9e151e3c9e7beb6e3acda1f075c928bef0b5ae refs/pull/1503/head\n00415c6a2af85703ae61fb0e53a0c0acc6ce2bd35918 refs/pull/1504/head\n0041908d4fbbd4502e8b6106733f88373ca813fb9dcf refs/pull/1505/head\n00417aab084a2629b0a33c7a314991b38f2bea80af12 refs/pull/1506/head\n0041341380d6aab2b719946ec0c1a5be7c0cd27a0cb3 refs/pull/1508/head\n004173116a39687c8aac406d5f3436ac2382cd67166c refs/pull/1509/head\n00410a69ddfa848b2722f6e019d5c975877d9015ff32 refs/pull/1510/head\n00418b22d1d80d3989e19f6c5c639f1d43756c83c4d6 refs/pull/1512/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1513/head\n004107f645f4d3f21c4a6e5d37dcf9433ccfe16778ff refs/pull/1514/head\n0041b9f8f60c3d32e202f61a38cd9298d498f9d47d6f refs/pull/1515/head\n0041f83d3497ba7dc9e2d636bb2e4ae997d199eac114 refs/pull/1517/head\n00416973913e0ac5903ab71dfbe1b9d36bfaca0e4f15 refs/pull/1518/head\n004116733b33f6b8e22db85c87192bf755b7e5ba9ce9 refs/pull/1519/head\n0040dc7027b6d5069c1decbe4db697f29b71dbedd0d0 refs/pull/152/head\n004169d63353a10a2ccb6bbca0cd8e2ea39f07b473b0 refs/pull/1520/head\n00410d459a3a0d41b09508ea497686d1570c86a1d103 refs/pull/1521/head\n0041d898942392a908832d3665b8c01b1d9a908bb4f8 refs/pull/1522/head\n0041f313b6cb25b09f2b46fe64f73006162494abf44f refs/pull/1523/head\n00413672ab6648e9a5a7be2a98a15ec365a10d2fd64a refs/pull/1524/head\n00410bce19c9b7efd2ff89cd8fe5cf8b745151c0422c refs/pull/1526/head\n0041112afa3e48db0f2de21a6a2eabf87c8eead601a2 refs/pull/1527/head\n0041d96bcd6c259eba410208303f608604f12d94d01f refs/pull/1528/head\n00419691f02b5328cc5cd5bd107c0f9841a0cb98660a refs/pull/1529/head\n0040a482a80f7e437e30efa5eb9fc21c09d025be30d4 refs/pull/153/head\n0041c76aff6be45a0cf7db5c5711e4e40113f64dbc47 refs/pull/1530/head\n004104340dfc2861f9f6f3ef103a0025a4c53a39fca1 refs/pull/1531/head\n0041e64567c751cf73ca090672778776a7175d5fefc3 refs/pull/1532/head\n004185a59eb6f51e25e5ec8671446d376d0f2f7da910 refs/pull/1533/head\n0041f6d77b8c6d7b853ccafb13efddec6462d1aff581 refs/pull/1534/head\n0041da0d3a3a6b2ffe0023b256cb8869931ee9c5b204 refs/pull/1535/head\n0041882e49547e2172435fd055f858a1d68ed0debcc3 refs/pull/1536/head\n0041b441fa217409bd0ce6aa4a837cd3f7447766fb61 refs/pull/1537/head\n00412f834281750332a14fa6c7c60696d1736927c663 refs/pull/1538/head\n004116cd702ae99af2129410201438008c0ed6a88709 refs/pull/1539/head\n0040f78f9c4948f1f81a50d51265a55aa736b01489f3 refs/pull/154/head\n00410c2ceadda13aaf9fe821891c11bc42b28f13c000 refs/pull/1540/head\n0041c6b0b982c9b39b3f31069e60453dae96c10866cb refs/pull/1541/head\n0041d2e4e5e58508c7aff695768346c200d57229a21e refs/pull/1542/head\n0041ee5cd9ad00462ab8b1602c25cce5d57247651ae5 refs/pull/1543/head\n0041db0dd1875b8ba55ae38b0fc205c57462d5264984 refs/pull/1544/head\n0041327590d91f1311a3a6e53cfc48e03b539cc7d955 refs/pull/1545/head\n0041ace6ca433914068b255abafa6fbd0ef16ba2d201 refs/pull/1546/head\n0041f19785406811be353ec421c04bce3f346eded10b refs/pull/1547/head\n004172e13a2121813367053d4ecc963d2305e85bc86b refs/pull/1548/head\n00418c4f183f2f6c6e646979f996b447e05fd2688ec6 refs/pull/1549/head\n00409d5ed41f9d2193e6794deee4f8bb7a813c9343b3 refs/pull/155/head\n004186322a7793fb78f2471a66f28d1380ee2ca72afd refs/pull/1550/head\n004145aaab129c2f7061b129b296c55c7c2ac48132f4 refs/pull/1553/head\n004149d849fd2e1f9614cb537fc19bc54e556c9b09b7 refs/pull/1554/head\n0041bbd33796f3faa42f40b28134ec8b3efc142694f7 refs/pull/1555/head\n004113af1a0f28d8a9bdfcf98c6ac827a6a3ec828baf refs/pull/1557/head\n00413956a7dd8a950fc58241286efda84dcae51abe4d refs/pull/1558/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1559/head\n00407dcd66ee089129b124af8b51b26fb8728af4773a refs/pull/156/head\n0041947083e60bd3c568927ba12314efa05aac5290dd refs/pull/1560/head\n0041f16c2fb4ef30b707b56556b2e2c40ed8cc9adf42 refs/pull/1561/head\n004166ae1b5c1780e6c8444b39ab3f112b7b3e02dda5 refs/pull/1562/head\n0041dceff72b9c029a97e42ec1a5b0769d06f153b8d0 refs/pull/1563/head\n00416a399d6d2ad5dcf71bcc04cd21e939de5e7767aa refs/pull/1564/head\n0041695353bc990ce2a62d31eb1fb13f541d1cd703b7 refs/pull/1565/head\n004152049e0509b4b44daac5b37016b0dbca1fcb37a6 refs/pull/1566/head\n004187d5eaca8701601a39947d440b185d894c737407 refs/pull/1567/head\n004142c31c24b1d69723bbb699578acd02af9f78800d refs/pull/1568/head\n0040c82b8e525303e6fad770e0540dad5dc00d76c83c refs/pull/157/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1570/head\n004192716c0c970fea2ce12cc31832b3f45f3050ca21 refs/pull/1571/head\n0041462f5a219f3f8f78092f98f26c5b58a847db6c7a refs/pull/1572/head\n0041c5b85a430a260fbd9cf2e4f360f8f20d53afdc53 refs/pull/1573/head\n00413019ec74ede79e77d5672fd022ca3177572cd72e refs/pull/1574/head\n0041194db15636a13d052e81164641cb23bb53be4b49 refs/pull/1575/head\n00412b5dafc68d002735348433ae0ed81908ecd785a6 refs/pull/1576/head\n0041f2c653dfbda3bab74478915ada61e0845012bd2a refs/pull/1577/head\n0041d870bf685b2b776ff7ba9eab78ed55505ce57c1a refs/pull/1578/head\n00412fa7f48896e8980b11a2b558ebd6a20e7be292b8 refs/pull/1579/head\n00408068436b2a040871c83cf6f39c2d0d74d4651e47 refs/pull/158/head\n0041d958e812462e34c99c37d217f0f08ae91b3abc03 refs/pull/1580/head\n00415194418a88de9fb53ab6ed80432831331e15bbae refs/pull/1581/head\n0041c3a4e79dbd933fc8e947815c666561d51d795f91 refs/pull/1582/head\n004131da8dad3c1ac11a0e12490fcb6e98fa8f2c28b7 refs/pull/1583/head\n004125ef6c1f49836f51ebff2f4135e4596992d678bb refs/pull/1584/head\n0041e0ae728d9925a62008f60a22e1198f06a6ede5c6 refs/pull/1585/head\n00417fa05c71e0d2b2217facd2bad243781858ed6e9d refs/pull/1586/head\n0041ff5cde817af1c25f5fa26bafc4ac4073bcfb1e09 refs/pull/1587/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1588/head\n0041484995c39c9c8cb99c885903c64a06b782488b00 refs/pull/1589/head\n00406fc981f0f578112dd57d3c9221d8e8607222ea02 refs/pull/159/head\n0041a0dc900a228f0c46f97b3e4c59acfe55c96ef2c6 refs/pull/1591/head\n00417df0c764d7fc60f3b32fdcd11be57d153882902a refs/pull/1592/head\n0041426317bfe888889daedec42b58f58b3e1e2da129 refs/pull/1593/head\n00412c9256efc644bf765c45e5ae8a2a8fa851d37c47 refs/pull/1594/head\n00418405e05a3f332b28d57837397ce28a63e48f795e refs/pull/1595/head\n0041fd766e7699bdaeffaf5625a4a583dbd5d4b68141 refs/pull/1596/head\n0041a1fa4e7ba21116c602b2e2d196eca51caef853d8 refs/pull/1597/head\n0041b7919627c927d8559f12538106956397a3ae92ad refs/pull/1598/head\n0041d796b6f8340e2bdafa4e4073fbda29550b21c90b refs/pull/1599/head\n0042dc55d0d581c9390b6f71cf04de9815c5e77d7771 refs/pull/1599/merge\n003f16b3827af689b39902ef03363e8f06aa8a917b37 refs/pull/16/head\n004048d9e4009aa1d2d8cd18f948ed4549a55eba97b3 refs/pull/160/head\n0041d3f1dc58018d6b40ee2f05e5f6821671b319c3fd refs/pull/1600/head\n004131a64f5e4936499faa79e40018515ea58b3c0302 refs/pull/1601/head\n004100a02591e76295b34878ba180df0b8a9564a3b92 refs/pull/1602/head\n0041f763b73ac812aaafbad92a084773bf1d13f80943 refs/pull/1603/head\n00414359fa74d8b9a01b428f725d692299264e80921e refs/pull/1604/head\n004146d102ceb52c713644eadaa7846118c8aeee3a09 refs/pull/1605/head\n0041e98427ba70a78b5d7a64c427e7a9cd09de7b71ba refs/pull/1609/head\n004007f015f1904e253e994ee240a9615bf16315a5f6 refs/pull/161/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1610/head\n0041f2376611924effe0f0f03c541f480137d78e573b refs/pull/1611/head\n0041a0f7092b2162eafb07afc502fe26c262c75a51af refs/pull/1612/head\n0041e7a8372d6366eb5d6eda0d313e5a0c4d6f2e7b10 refs/pull/1613/head\n004156cf6c79473ddcd9db99668d49a23b29c01a667c refs/pull/1614/head\n0041eaa3e7ffff279d64785a8ec77bf6d7f5df25b7da refs/pull/1615/head\n0041cc8c5840078f65bec296c001effef0c762b990d8 refs/pull/1616/head\n00416b3f053810f3d897cb1c543d109216751697bca0 refs/pull/1617/head\n00412b744813cf6bed7507c0a5003db5df0aba55fb7a refs/pull/1618/head\n0041ca91696bdfb5a59629a3471daefdac6d4e2ab0a7 refs/pull/1620/head\n004174214297869b28ffd536479c068ecaa3997fb7b7 refs/pull/1621/head\n0041be0908a0431c116aca177fb7dfbfc551ccaf5861 refs/pull/1622/head\n0041e5c686a63314322ab70fc59f181733bb23fced34 refs/pull/1623/head\n0041b84b0eb192fd47997e3d508fd2fcfa5b7763e026 refs/pull/1624/head\n0041aa15587ad20ca465e390add59358df0cc2830608 refs/pull/1625/head\n0041414762a65ad10f46b75a95dbbc8e56de95d5344f refs/pull/1626/head\n004131a5726b22a2cb4cb794b01b5d3a75ff934a6ba7 refs/pull/1627/head\n00413691e6cf3f6767d85cdc6dc87de6178d8e00a84b refs/pull/1629/head\n00400110a956f7c25b31435717b7c6f517fbd4ecfc9a refs/pull/163/head\n0041473061e7dabc8c56aae9fe447a3173db6c7c3380 refs/pull/1631/head\n0041320bc9418314813464d0b91d5f820526e6dcaa40 refs/pull/1632/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1633/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1634/head\n0041ced684cd213166117663572f0f13591bf5168ba7 refs/pull/1636/head\n0041653eb97d9afcaab55c7157a3d9a7896f9f8a9cc0 refs/pull/1638/head\n004002c71918d8b56bd9f6137e1a526d1ac481602c25 refs/pull/164/head\n004127a37fb1ab3e5fe5a1e9b11beaad54ce9281e525 refs/pull/1640/head\n0041ad1fdf91c8ee67b0d073a6a438a52209cb15862e refs/pull/1641/head\n0041de207ef037cd5ddc2556df0610a7a172ab51dbc6 refs/pull/1642/head\n004145f73022342a0bdbdac7417629105c4baeafd79c refs/pull/1643/head\n0041b985b6379b054c5adb75044640bf5cb9fedfa4b1 refs/pull/1644/head\n0041843a90655a84ca944e43c96e71557c085e294d9c refs/pull/1646/head\n00416840f1c445eb9105a17e786ce13304d0e4997187 refs/pull/1647/head\n0041b6d6f53c233c8f7b52309335a1f5eca9fc814165 refs/pull/1648/head\n004141d16635e58d5c6179192206758b4270a9e8f965 refs/pull/1649/head\n0040be088688bdaf7b272c7811e4869caffc60a34d87 refs/pull/165/head\n0041511c386150398998d87896badef720e894330987 refs/pull/1650/head\n0041cee9378ac0bb51431bed15a4a4a137820340fb70 refs/pull/1651/head\n004181e9bf6e4bc3d061c601d117692c9dc9fae590b5 refs/pull/1652/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1653/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1654/head\n0041b37b4076f5874c11113b926c8fab9f7dc2444952 refs/pull/1655/head\n00410b9242402f6b614a7a964b191dfd82d91eb807ee refs/pull/1656/head\n004103285c5cc430a2d4d95b25e43c4b9fbfaa66b75d refs/pull/1657/head\n0041cf437402222547477d626343ed0afdf5efc0f8b3 refs/pull/1658/head\n0041fddb6460bf6b561b82bb98f3ece98eda40231dc5 refs/pull/1659/head\n0040c7463a50e9d50aedfb8d2b01f8fc673dc1972f14 refs/pull/166/head\n0041330dcc98ea9fc10d8927d289236eb8c918c4bc51 refs/pull/1660/head\n00413412588e0eb37f94e5a155797d6a223fe049461b refs/pull/1661/head\n0041e3ba44799ec67cc578e33f7e397c529ce919f838 refs/pull/1663/head\n0042daca13a892bfabe2290650e9f908617e47230586 refs/pull/1663/merge\n0041e4571b9e0bb399600daa49e941e0f1e7c487ce2c refs/pull/1664/head\n0041605b1067212bcd7af0737f42280c049283d7f7db refs/pull/1666/head\n0041947c24007cc76d6c31fd44f2849dbc977b4bad0b refs/pull/1667/head\n004171767c8f8d91833961d253863a3bedea974bd26f refs/pull/1668/head\n0041606a2e0d39ebe60e887e64c0e4e33c591e997e19 refs/pull/1669/head\n0040550ded776cafadb014dd81dbaf58c469d5af6ad9 refs/pull/167/head\n0041c0b62b8b28336c5a5086870c3eab71aaaa150c4a refs/pull/1670/head\n0041c02ec43a14e1ec42052ef738745864d69e7eefbc refs/pull/1671/head\n004178391b1c345356ec78e9d6c033d67443952122a6 refs/pull/1672/head\n004179b4e517f71483bac6f33db2c9c070d4abdc0e45 refs/pull/1674/head\n004169a3f0506feb52f5b5705dae8828f1a20c43bd6f refs/pull/1675/head\n00419e54ce53a375d24abc214619b357acbd424e5814 refs/pull/1676/head\n004122a5879e288c1afa2052f715bf6cf92ba93ef076 refs/pull/1678/head\n0040d5ab3681b90575681caa9144bf1bdcdf723150f2 refs/pull/168/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1680/head\n0041b49309b4e8a5a0cda1677745b2941be87a642ff3 refs/pull/1681/head\n0041203cd06339c36b8767e2e60dd55bbc3ac923b645 refs/pull/1682/head\n00419eac881720f2cd451c7b48b3b2dec5fafcfc6acc refs/pull/1683/head\n00412cab290ed8db8ba56e95e12081a24abcb9746ef9 refs/pull/1684/head\n0041bb280dc1a53c81287eda1e678c25629c8ebb8851 refs/pull/1685/head\n00419b5ad70828ca0c941fc424fc35e10eb2eb53d475 refs/pull/1686/head\n0041c2b84a61807bcf11f35dff1aa544b0a92a0c6785 refs/pull/1687/head\n00416f6fbd991bafe78b2b87f92f5c6f8327888dd339 refs/pull/1688/head\n0041d3818b9df267986e07e8df723464e09cd195d583 refs/pull/1689/head\n0040c32413680d38e366510a47a6c150eefede26987a refs/pull/169/head\n0041f7b84db702b7b111c176780a17a24d88c721d49a refs/pull/1690/head\n004133dc34724f0cbe5de45246ecab12c5a3c1ae5602 refs/pull/1691/head\n004158c03b5016c7d62755205a561b10babe4f24b472 refs/pull/1692/head\n004122c16d0528c48509297dec8ad6207ce879f20f07 refs/pull/1693/head\n0041194c74cbf4ee1ec28b85979c2424b73175205375 refs/pull/1695/head\n0041ebf909a4cd8718cc731e498ae9ec5cf11a148e1d refs/pull/1696/head\n004126798baab325cb4720e80dd2bf5ad4d3ddd49995 refs/pull/1699/head\n003f3a4c90b02ad2afbe09997cb3cddea3f2f96cd710 refs/pull/17/head\n0040ed7fbcee57b7f9277ffe1260e3365b4b8c628b26 refs/pull/170/head\n0041f6be2d94e8a159d03682495360a84a99e2849ef7 refs/pull/1700/head\n00414cff272b844f4409267f6d4a0dfc35d522b4b1b5 refs/pull/1701/head\n00417d9cd867535b37dfb109312c118fc1c4d99a1e12 refs/pull/1702/head\n0041402453d160e42a2becf0454355e8f21392436ca0 refs/pull/1703/head\n004166d3d1ece5efadd29e2ed40613080bad24588f00 refs/pull/1704/head\n0041d36a83b869ad816367e3a520df8b34e0fa30063b refs/pull/1705/head\n00412d5d59d0c19aab6f41ef43dfaa5f5dd84ec3635e refs/pull/1706/head\n00411dde7bc4eb32f5229e4395528009a6abff975fee refs/pull/1707/head\n004167a4b8816b0d95195649426e01c2d5a285c87c69 refs/pull/1708/head\n0041583974851f9986aaf9aaae1684ddc7da54061668 refs/pull/1709/head\n00403f8f78a70ddddaa6e381fef4e575e5b0bad9f403 refs/pull/171/head\n00411f78db7c0890d6de7d968b149da0cf6eb44bae16 refs/pull/1710/head\n004181b355fa672aa9f87f78ac1365a9fe4302ae6f26 refs/pull/1711/head\n004147050c34195f06ab88e8b2e5d41491ef82a897c8 refs/pull/1712/head\n0041859de7de8c7b56c46fd0a2afb1a56bf7be4a0efd refs/pull/1713/head\n0041508ee173626f605678598d0363806d452e6546e7 refs/pull/1715/head\n0041e431c79ca359bf4a6dc5e756ca2416867b1f26a2 refs/pull/1716/head\n00419bb401e34362ff8f0ef0c7b1e471126a98e6e72a refs/pull/1717/head\n00414a9f3908193b197e0fac3c04a6820f9947527149 refs/pull/1718/head\n0041c7c27dfedee3c8fcd928c801e7b37f24f3604c40 refs/pull/1719/head\n00416eda4698764d62eb549a653d71fe9c89efbda7ed refs/pull/1720/head\n004147db827f4e9e07495e988979b2bcc5f0f1c3ac5a refs/pull/1721/head\n0041dc37d4ac77c3a83b1209c9ac9d386f7a21164c6e refs/pull/1723/head\n00412856b0618349793952634c56899e3a59cb4bfe4e refs/pull/1724/head\n0041137adae315ed82442e245d922230737921ab8476 refs/pull/1725/head\n00417f6ab1cddbeab54f17621134f12643dcff6e78ae refs/pull/1726/head\n004111a2bf4d085236a9cbe9846ff9f22f9976e853bf refs/pull/1727/head\n00416b9ce0fa8acc5fa39b58c998050507de1eafc74b refs/pull/1728/head\n0041eba0ba181ab8cb8f9bdd603762d9ca1d0ee03e6b refs/pull/1729/head\n00409bd080d1c1e0f331e10ca935b7ae84a67743e00a refs/pull/173/head\n0041621b55a6453ea373b338093a4d6ebb246816dae4 refs/pull/1730/head\n004166cf11882a13aa5ecb9dca3a0856625d40a0661f refs/pull/1731/head\n0041ceb4390ee4f63854ee38c1ceffe09bda29ec19a9 refs/pull/1732/head\n0041f046d5b5e50c64f21d971abdfa97cc7d40bff25d refs/pull/1733/head\n0041299bd320c28aa4aa7a7ec3248ffdceddd791f1b9 refs/pull/1735/head\n0041dbb64a42761a875114e956ec6070defbfe422b26 refs/pull/1736/head\n004168e17a207baa24049da479274cfa34d7432c90ac refs/pull/1737/head\n00414a9f6c8d165fbd1f30eb478e7d09e91c185dc2e7 refs/pull/1739/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1742/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1743/head\n0041efcc272b15e6678ae0b87795b085779de6cc6b64 refs/pull/1744/head\n0041afaa7c3ae485f10eb98db9c9ceb3a1b3b135bdde refs/pull/1745/head\n0041fdf37f671a1e1b7fd1dc183769eebeff9563f252 refs/pull/1746/head\n00412c85053cfa420c869bae7ef023c52300eaa0ad2c refs/pull/1747/head\n0041d28d46d556d50949a51ec2b2b9e736b99947cd36 refs/pull/1748/head\n0041242e8396de3475422e0e4b575d2be8b13acfd504 refs/pull/1749/head\n00404f150c542aa5139058ccf57dcad562890916b477 refs/pull/175/head\n004128b5f8610a75ef7f7eb4d0860391893a023a522b refs/pull/1750/head\n004161121d34173f4e17d2787d9bbb9beb50988e5b0f refs/pull/1751/head\n00412bae8356597b70e2a0ec11fb906c9f4e15b0ca12 refs/pull/1752/head\n0041b1e4f7639d8480a1dd8b2d8b58172b5654bcb5b0 refs/pull/1753/head\n0041e8d8de2b047665e2feee094a948020aab6f0cab1 refs/pull/1754/head\n0041dfe0cb485e1b95fa73d7fc01189d7342336139bb refs/pull/1757/head\n0041af351e06e20230e63147e6f91ec49ff018b6acca refs/pull/1758/head\n0040697026d4e8b2db4ae98b820d3d5219bdf6447016 refs/pull/176/head\n0041e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/pull/1760/head\n004168f6fb1246d1b0fceb91454d4350ec541c5f6c0e refs/pull/1761/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1762/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1763/head\n00411fa8a78eaa5b22679c5eef46216f5188a1d94fa7 refs/pull/1764/head\n0041cbc1038324468952ccd6d73cb8139ac39053a443 refs/pull/1765/head\n004156e0c5dc850587be1566c9f64793d6d6d5d236f5 refs/pull/1768/head\n0041bb81d37d4e36bc8f5ce4bdd330670bcb3e0d50fe refs/pull/1769/head\n004196aa2ba53a2ea486f5a769851a40c6695ae1e49f refs/pull/1770/head\n00412a288c660a53a7e834900ac484b30484ee630045 refs/pull/1771/head\n0041217c352ad074f4d185d93ceebca8eb349ec6c59d refs/pull/1772/head\n00417d78ea23fd1e33058e26271b9314228c52ccfd9d refs/pull/1773/head\n0041bc8e36df01367794ea3ef321187a325a9ac69db4 refs/pull/1775/head\n00417d2c3c8a499807f48617aef10ff2d38777b10e53 refs/pull/1777/head\n0041c25a90ec1432dc8d3bdfd8a4897eec1f79e86a79 refs/pull/1778/head\n0041959f67abee6f9d04caaa8d7f89fb4e4bed97643d refs/pull/1779/head\n0041fd17178287784de7abcab551e8d6a3f307197e6e refs/pull/1780/head\n0041e3ca3320607036d249dbbf26371909c8cdb4e553 refs/pull/1781/head\n0041d51aefbf41e7a618a29bbc5d27e61b3d695b5bfe refs/pull/1782/head\n004185d032609f688eabe9afdd6e913a3eccbf02928c refs/pull/1783/head\n004123ca8b3c69fb1aaa5728473b063576f1b2d39375 refs/pull/1784/head\n004117103ff4a194a539f5c72bea680e96d82fded25c refs/pull/1785/head\n00416ff3ddf670d367e0bb94ac1ecbc16a7b84c44da3 refs/pull/1786/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1787/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1788/head\n0041d780e569beeb0dcbf49dea00227b07e7a0557e07 refs/pull/1789/head\n004138818c7fe460059b864af9fb064ef3b372faa3e8 refs/pull/1790/head\n0041c830fa55637683630dce94d4bd1979bd6eaf19fa refs/pull/1791/head\n0041fd24bcecf02345fad0eafb863c1e1a96b8c690ea refs/pull/1792/head\n0041ef51a60c61079cee1ad74195e7ea775ce69cb4a7 refs/pull/1793/head\n0041151da60d325f776b3dd0aeea7d2b772e19d7d17b refs/pull/1794/head\n0041beced838e4690d90045aa67d95eb354ad8ff22eb refs/pull/1795/head\n004167f820873e8377ea084af14056d22554ca7cc21a refs/pull/1797/head\n00417a0f284b57753f79f3d1613fab4b93c8629e19e3 refs/pull/1798/head\n004175f2c449c009b52d0a603bd3cbe8eeb725f915bb refs/pull/1799/head\n003f53aa980fe3061b5e6040de9c8fb10012bb2f8703 refs/pull/18/head\n0040b1cb385e06354cf99ca214be195c0700ffcbc0cb refs/pull/180/head\n00413eb63513540f6bffdbd231239f42f88ddfebec68 refs/pull/1800/head\n0041643497bf5bcb01d049b74b7256deaccbe7499250 refs/pull/1801/head\n00412f72f7cb650e4bd70af9f952839a0a59869e3a65 refs/pull/1804/head\n0041cb15bb31308c98689ae4eb9146890eb4c4b85076 refs/pull/1805/head\n00414a73eb85606f042cbc4cea9806bb6a5aa8aab684 refs/pull/1806/head\n00417a5731326269b729d41b2ac688e39b590748a842 refs/pull/1807/head\n0041d61d2a12da28c0a67e8b2a6a2901ce3581582bda refs/pull/1808/head\n0041c06ead49f70c83092494dd35de5cc23003373616 refs/pull/1809/head\n0040a93a2680f94ad8e04a1103aeabf2708bd5980e8e refs/pull/181/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1810/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1811/head\n004164c2d8663c768215adc1abfc163b90d8c00f7774 refs/pull/1812/head\n004166ae46ddf21a5c9ea38179ee3cb48e5e0933fb93 refs/pull/1813/head\n004162d8b81f9d11177615ab69ad569599f9749c988f refs/pull/1814/head\n00415784c6de647fb7d0e8667740d784bd6855da89de refs/pull/1816/head\n004140d1eaf19843a7fa8e8aab0f612829d02fef95cb refs/pull/1817/head\n004177db6fea24126618973c77b5d1085b6d731abaf7 refs/pull/1818/head\n0041d218d64ce9526b17ace67ffd6c302cdc0d06b330 refs/pull/1819/head\n00413e4acd6540a4da55ca5e2d8fefef07b740d1c752 refs/pull/1820/head\n004155a2cd3bb64e3040d899bf5cf8f1cd4d6580ca5c refs/pull/1822/head\n00410ec6da65e6e898a079591b57055efc061c9cb6dd refs/pull/1823/head\n00413956b56edf3c580ce664f26ba4a2295204a3b7c0 refs/pull/1824/head\n00414716d0cc284b1741d0d3233c73ea47af5bceecfc refs/pull/1825/head\n00415f788d250cd76b750f76dcc6db2d440bd92fab27 refs/pull/1826/head\n0040c36e358ca340e5143c1bae900f62af9c9992f8b6 refs/pull/183/head\n00419a37f354a6af47436166d5dfe516c3689f402484 refs/pull/1830/head\n0041e075984e4ef6a2a4d844c42cbc18543abe5dd211 refs/pull/1831/head\n00410bbc9e95cffef61511f1de8f830e336caa15a958 refs/pull/1832/head\n0041e5bed10b2bd6973ad2a063fffc38780533f8cd3b refs/pull/1833/head\n00413e0bc06126d76b17038544e765365e04f10f12ad refs/pull/1835/head\n0041ad1e720055786f3cdb9c759e5061343c8d00b279 refs/pull/1836/head\n0041bf17b39beef874e602d3b36861aa1eef469aae3f refs/pull/1837/head\n0041ca50521d299252e3df50cc973da8d58ea17dd9d8 refs/pull/1838/head\n004180a2263da5503241882ca0477ea1d99b4c7a20dd refs/pull/1839/head\n004073c82e133e8dc40db2556497ea58ed1087031505 refs/pull/184/head\n0041dd45b9f4aad94150181247b515d878a258593f65 refs/pull/1840/head\n0041e95f66bf3fae34c9834fe303119f68d09b524c50 refs/pull/1841/head\n00417879e9176124c4e6bc5d7dc9e2aa8d00a2050411 refs/pull/1842/head\n004183fc002b5356265d0459729a76aca21324a27401 refs/pull/1843/head\n0041590f17a7d4c339439cc3a0366c230fe60d0ee52f refs/pull/1844/head\n0041a3e12ab1fc688a3d5d68fb004f034dcd83159e50 refs/pull/1845/head\n0041cc048c4cecbfb81fd68db3de91cab8a6d110a4ef refs/pull/1846/head\n0041694695a536c2feb96e0817856cd3b729017b66db refs/pull/1847/head\n0041dac04009c14513b018b5a47194aa0c45cb15a3d2 refs/pull/1848/head\n0041c53eab92dd9d8f1b20f3ca84fabc29456767c562 refs/pull/1849/head\n0041cf9cb9a57237917ae1ff74f121a1fbd6d8e28581 refs/pull/1850/head\n004139bd4443236a577e81d79eaf2adb56ad5bad7e0b refs/pull/1851/head\n0041ca1234fba4d0f639136a17642bfaf8696100148f refs/pull/1853/head\n0041688edfbf064c5cbd29ccce6683cfff62e2a92841 refs/pull/1854/head\n0041e07806737984c72dd2df3fb62f6aa887074abb28 refs/pull/1855/head\n0041950f94d8447cfe8e381c33003731bab17764fc53 refs/pull/1856/head\n0041c9e6324f270b54ef8528ab8a2e54663cc1522bfc refs/pull/1857/head\n004125ab614caa713ea1b3aa85d6ff477956307fbceb refs/pull/1858/head\n004177d871fe2174230183e7a2c9ca37bfc3147c5dca refs/pull/1860/head\n0041490ca7b0714d188ae4fd43dbbf9f603e257b33d2 refs/pull/1861/head\n0041d401575d9c4480a77ed36f22013cf94ba28766c9 refs/pull/1862/head\n0041245917c80414c327aa4c9b4dccbaa6a8de1ed76e refs/pull/1863/head\n0041775c151f3e1a2deb698444685f477766b2eb7ac7 refs/pull/1864/head\n00419cfa3f62676b13f7e218003e801796ca01a26e8a refs/pull/1865/head\n00411ed057902ab3c93c7bc09b1aea1868ee223204c8 refs/pull/1866/head\n0041bb691dd9c831e92f4d12e842b20ec6b198382030 refs/pull/1867/head\n00414f13093d0a7690cd6f53a8a00eb5e961b450e96e refs/pull/1868/head\n0041be23c09d0085e393c609425c87e91d2ce49e4b4a refs/pull/1869/head\n004094fad49150b1245d6df17ef596ccbfdf5e53e23a refs/pull/187/head\n0041adc617b13cacafc11073da7c987c3b4aeebe7e8c refs/pull/1870/head\n0041e7abbfdf7b7587088aabd9b6e6def35157483259 refs/pull/1872/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1873/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1874/head\n00418e73fddffc8970eec9941c65f48522e41fee367d refs/pull/1875/head\n00417870cf2e5136283da85180aa1a4132d0b945e46d refs/pull/1877/head\n0041d5e7bc7be4b270767aa04de43bc3af305e1827cd refs/pull/1879/head\n0040bfcac75d68e64f860fd27dd089f76f6e076ca1e0 refs/pull/188/head\n00412296fd9ca7299a57fa2e8ecb59623a85653183df refs/pull/1880/head\n00419ab39d23ff2b19fa564815999bf51be509ab7b5b refs/pull/1881/head\n00414cf4e663f58e4f5edacda884bed5c035124dfd6c refs/pull/1882/head\n0041bdc42a80a2a7d0ebec1c9ab90a945f344dfd3f3f refs/pull/1885/head\n0041f3d970e2aed28a290ebdc777b1bd9e2a6c69361f refs/pull/1886/head\n0041f52afdc4daed2649a3bd78782713203bb9ec1787 refs/pull/1887/head\n0041a13e63a984798aa57eedeb629a4e42a059304825 refs/pull/1888/head\n0041f2e2f18765b2d1fd298a58c3ea90283fce07cca9 refs/pull/1889/head\n00407a95f8a55b26adc8f99b9e2c54995c0ee85d8fa5 refs/pull/189/head\n00412ed0a0d114dc10762bf4a4e6ce2572f04d4c6abe refs/pull/1890/head\n0041cca09665a98cffb1de8a990b68eef7ab3f42ae47 refs/pull/1891/head\n0041f209a2ffc58b2c9550528b01e5619bb3cab1d82f refs/pull/1892/head\n004141584ca7cbbbb18f1cde26eabb104249fac64617 refs/pull/1893/head\n0041c3e7497e240bf02819dc7d0bb5e666a48669f0c0 refs/pull/1894/head\n00413eba8f8f280b0be0c274880add862f86a1aaebeb refs/pull/1895/head\n004124242e093ecc652d0419c06cbf0f3cb4336ef76d refs/pull/1896/head\n00418b61b330c72c4c1513cd72ffac2aac293cd3a3b7 refs/pull/1899/head\n003f1a0925b76e59133372fc1ba7ee5599b735be1611 refs/pull/19/head\n0040ff96305637fe8ce3e1f744bfe71eef3bfdde98d1 refs/pull/190/head\n0041cbd943c6525c545cec58af0404e17407bba01195 refs/pull/1901/head\n0041fa6cce474ebdf2ff70cd23969df81b51b28249c0 refs/pull/1902/head\n004191834bb605717048dfcb97d50f1e211b7fe18a10 refs/pull/1903/head\n0041e44a5ef5ff2c9c28c4e4f6e72e57301637991d89 refs/pull/1904/head\n004101318044062e0dcb5c3e49f6536ec235ab23b0c9 refs/pull/1905/head\n00411bc915c5b605eea03cb4a8290ae461462e1ab24f refs/pull/1906/head\n0041cae78e108c9cb5fff71e8cb8741349b94f2ad4ee refs/pull/1907/head\n0041b6b055ed963bfb379183b8c02c6ab208e3d6b473 refs/pull/1908/head\n0041183eddf9cbd560150b934d0f1f4569f1bd882a3d refs/pull/1909/head\n00406ce0980f6d150f2624dcef29836028a2cb1f7870 refs/pull/191/head\n00414402048781f29961cbdb12ddad0ca8d81a196afc refs/pull/1911/head\n004157029178c367dde42ce6ea623fbb49c05e051f22 refs/pull/1913/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1914/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1915/head\n00414fe84f446a4c7ba338e110ed8f61418adc4c022c refs/pull/1916/head\n0041b639422ec1c00424fd896389628e8734902c4f1b refs/pull/1917/head\n004141793010447396bc491832ccb9440144cbf74da0 refs/pull/1918/head\n0041772dc97d1ef15899ffd143c7954ec412b0a416ee refs/pull/1919/head\n0040cea55d539a5935d83a95b3b71e1800a59ca6aadf refs/pull/192/head\n0041faaf7ac71d88129f9d698c85473a5180e0278c83 refs/pull/1920/head\n00418081e72673e2f1a920091f3bf221093d05276dfb refs/pull/1921/head\n00414263ded36f0b487b333e3871ff1e316396fe9ffb refs/pull/1922/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1924/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1925/head\n0041085fd13676bfb1f72c4a45453c77befe939a86ba refs/pull/1927/head\n00412890c32995007b6d48e87e20a853a86b9832ab0b refs/pull/1928/head\n00419e67ae92fc31d9eafb455aab6fe32eb5e125c30b refs/pull/1929/head\n0040c4eaf01af99cc8dadace1d1d127086a392813469 refs/pull/193/head\n0041f68c436ef6c041a988c803ef30185652612a73b8 refs/pull/1930/head\n00419f56be92d5c167c9e54911f073bafb528b18828a refs/pull/1931/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1934/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1935/head\n004128e4a3f2c16e21f20465082e4e63cb8e3503256f refs/pull/1936/head\n00416e9281133ab28e8bad2525600907428b1f70caea refs/pull/1937/head\n0041cf2236dbed3e22d7f04eb2db011b95874674e87f refs/pull/1939/head\n00408863cd9f782c86bfc463f1d8384c89027224aef7 refs/pull/194/head\n0041d49b4addeac1932ce5edc072938940965633e5e3 refs/pull/1941/head\n00418fba4b1e07a31d6eb84de0d3285a230de18ce490 refs/pull/1942/head\n00412d8629e6324a07fa6bcaf99c3d851effe085606e refs/pull/1943/head\n00413d608d7911850e4edf5a9417a8783a0375aa0fce refs/pull/1944/head\n00410e88f4836971e5fd8c9216f9d0a0f62a73109764 refs/pull/1945/head\n0041312e083a7df0caa21a7460b124c131a35540abc3 refs/pull/1947/head\n0041b195aa96dd4c1ed0bfc423396702b7cebd38b64c refs/pull/1949/head\n0040e18c14875dabe2847beccc4ace2c8fdefac4b003 refs/pull/195/head\n00418a89d1ed64499e3e23c85ac1d9fc87b093d88f52 refs/pull/1950/head\n0041eeae4900643721f121259e79c101e7964e7b26e2 refs/pull/1951/head\n004198a7e10c7c548bfab390374855271f4f06dcc94a refs/pull/1952/head\n00418e2e7cdf1a1c84a06c7ac1286063b5184844919a refs/pull/1956/head\n004198385fa0202ba48d9c829bd4cd438ff735c48ae0 refs/pull/1957/head\n00415f02424e5e280ef631ce64faa518a33ec2b356d2 refs/pull/1958/head\n0041c655361c61f4a8d4cc5501559014c4da4352d3cb refs/pull/1959/head\n00400203592563e6188de76fb2e29f4c5a2e5f722626 refs/pull/196/head\n004172d6bdcfffcda628c98c17935d4dddd8724612d6 refs/pull/1962/head\n00412f5322e8632c0ec51dc668b92cfe1164b811c60f refs/pull/1963/head\n0041f33bfb247752d7f00c9854af85f59cf146ce3b2f refs/pull/1964/head\n00410e5a9d1b17f94dd79f1bede6ab86a9ecdad51e4d refs/pull/1965/head\n0041247452069e49b1bc2ddebddb39f4b1a42f7dad33 refs/pull/1967/head\n0041d2b9459487c77b121ebaeb1936c98f6fdc4efd6f refs/pull/1968/head\n0041adfb91949539a56ef5a79dbbf1440d8cb98e48c1 refs/pull/1969/head\n004039610731e0ec8d72c80702b55a15478a948ea7c4 refs/pull/197/head\n004145182d7887e98e3be7b417e1aef6fb5e96c69e4f refs/pull/1970/head\n00411f8c81e7dcf2453dd59ab709d3cf49e8961de5a4 refs/pull/1971/head\n00412fffcbe318fa873851db2b093533787d55af5988 refs/pull/1972/head\n004119b96a70c14221d539217dc123f077fa97afeb94 refs/pull/1973/head\n004188214dc2966923b84c45650d1d2a06d53f8d2d7e refs/pull/1974/head\n0041d0438d88f8318cf279bb6b905aaebef0000fd4b4 refs/pull/1976/head\n00418c6e38f64217d2bfdd5c74b4820542d69312caed refs/pull/1977/head\n00415d11d2ecfa6241332ee224ebe1e3817fd70ce5ed refs/pull/1978/head\n0041b3fcec5942a9e303e7cfc8fa90dfb5aa8548ce0a refs/pull/1979/head\n00402d059659b02a3d4cd478d9cd608ee625f6101623 refs/pull/198/head\n0041f118e38cc79ccd80541d773a73a40f48f730f293 refs/pull/1980/head\n00419a4d3c10c0c76ce56b5393256e582e0f6156a354 refs/pull/1982/head\n00418f8added4c8e79c5df1f09d35161ca44ab42314d refs/pull/1983/head\n00413e9f8f819beec39c2171888cc75bc09eaf682a8e refs/pull/1985/head\n0041ea8a5331c4dfd8ab33559dfd63279c2745a8dab7 refs/pull/1986/head\n00413fbd7bdb7df0c0626e2375262ca831e82ee9694b refs/pull/1988/head\n0040381bdf0fdf166a8efca78ed83aa3729eef57fee6 refs/pull/199/head\n00413b494e299e1bb738432f2da3adbc16a4b9925cb1 refs/pull/1991/head\n00413a5a4ba0f0023ba2be6e8f76e55a59c77e83aab4 refs/pull/1992/head\n00419232e80f273caa3c4e30de4ba2df2b59724f53ba refs/pull/1995/head\n0041931da3b5a36e92341821bb07a6ce12c6e2964ab5 refs/pull/1996/head\n0041756a8bfbf71a83a7830c3704f0826dc5e9363a4e refs/pull/1997/head\n00419054561b3be44b736d0d75c1fe93650c9d72a19a refs/pull/1998/head\n00417224063d42c89b8ed4e88bab92552b683972cf56 refs/pull/1999/head\n003e45ac7a9b17fb34cdf0ea52ab533b70eb4ee60a23 refs/pull/2/head\n003fa89fd2c8ea82bb0ea441e6f8bb2fa16a097fa40a refs/pull/20/head\n00401e54429c2152b4c88a7ffca8d2d3a3da663e7dc9 refs/pull/200/head\n00413db85348aacfb66d3198837378bdf39b2b83b202 refs/pull/2000/head\n004140b3657c0fea727e0fafa0f15e5cac27062c9467 refs/pull/2001/head\n0041b828c1942fc576b764fb501426561645988c5182 refs/pull/2002/head\n00410a633c74dcdc35ea13b1131c185ad038501b9910 refs/pull/2003/head\n004177cea761a0e5d480a0ee655e192f47c3c4995fc1 refs/pull/2004/head\n00419abe4a3186ac55d8fbdef81cf718fad8d1a89079 refs/pull/2005/head\n00413bc50173f33ade9e73e9cd345b96aac6481bcf6d refs/pull/2006/head\n0041e8fb8f5771525831e0ce36e4b590bb7f6d28e436 refs/pull/2007/head\n004093e03d4276610c22a0e92e73012f8a4143e68c5f refs/pull/201/head\n00412a2592576e38d9fb64498661223b0e5d41659e50 refs/pull/2010/head\n00419ed18665d7649950d1f7c5e55d24b5ecdb6ae217 refs/pull/2011/head\n00410bd31f53db252acbb57473024b0e5f62805cd8e2 refs/pull/2012/head\n00412634e09e56a84ac60c8133659e86924db2907754 refs/pull/2013/head\n00414e07d9a95939834719489e7315fa330e0600b60f refs/pull/2014/head\n0041c4f79ae666057aad3ff6dd83878be6ed2fdf3668 refs/pull/2015/head\n00416ccafe45354eaa1a381171f692f3aebdf40e147c refs/pull/2016/head\n004191d2cdb8f126b98e33832a99ee369f8e7d33fa15 refs/pull/2019/head\n00401a57100be071b113f1844f864622afd13e7ba357 refs/pull/202/head\n0041f9f69a443ecabce263829413bb52d40b4f62829c refs/pull/2020/head\n0041276ef05e74f0b36860354051b60734570860cb44 refs/pull/2021/head\n004173b1fe3e8f664a33cda63a888e886a43d1f09453 refs/pull/2022/head\n004162075312fc10fc501a1c8e79109416fcb1d1e0fd refs/pull/2023/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2025/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2026/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2027/head\n00412d365a1a7f06d0c6c0b533a870a06ad947ea93fe refs/pull/2028/head\n00416e8dc9b9791d3d2c32e97a075edc1bacf515f7b8 refs/pull/2029/head\n0041c3f2d82f0160787e23b604ca33bff1c7155452c3 refs/pull/2030/head\n0041f427a8cf2cf8c5a1281b5597c97a7824e081ab41 refs/pull/2031/head\n0041c5c74a89138b010c108b44c04f6b591a5effd6f3 refs/pull/2032/head\n0041c2d191f524e51434cef74087074f695e1a300d1f refs/pull/2034/head\n004136bcd51bf95826cb489f181ca8a20374e2edee7f refs/pull/2035/head\n0041b17a05a6c75c73cf4d7472765dc24c67086d344e refs/pull/2036/head\n00411c841c1e1f263e42179306f8c9c0efdc07ffceac refs/pull/2037/head\n00404d972ac05deac77ffcb2ce21adb2650ed6ea6a3d refs/pull/204/head\n0041fce332fde15b1e5cf8519ca4e41f7dabc15230cc refs/pull/2045/head\n00412e6e93ff444f2db51e2f94b7b4440a6ee599bd40 refs/pull/2046/head\n004177a020b5769f6739f496f57539930e5c3b8cf0c4 refs/pull/2047/head\n0041616ee95df5e755c3464c5ed9d997531da5329ea7 refs/pull/2048/head\n00415da2bc3a293b18f920aa668e4e84fa3a2f54243a refs/pull/2049/head\n00404cb5d471dcfafbc390ddf00de86d2b3273e214b0 refs/pull/205/head\n0041a2766dc2c1f01b71b659a9fe24c24e526f9ea2b7 refs/pull/2050/head\n004165e83af51b80729115b49c787f4c7461561ee600 refs/pull/2051/head\n0041dfe7469fb6f43fe8f147e7ae4f37f4bee4b86efd refs/pull/2052/head\n00410f2c1ec931639bd563db8209bc678eba6bbd316a refs/pull/2053/head\n00412021cf90c380582a43f86948682aba9ed8c6444b refs/pull/2055/head\n00416e6fd0abe0b41abbbcddad8ecf505968252149ff refs/pull/2057/head\n004184e8c2cc730d0c599f182e6f9d1bd1836451a6a2 refs/pull/2058/head\n00402ad69f5897e9dc9fa230f6aff252131a058ac5bb refs/pull/206/head\n0041979cb14b1c89295b411f2cc96698e302b63c869a refs/pull/2060/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2061/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2062/head\n0041fcfed2e6876d14d39cd59b7b5bfb1661de2fbc5d refs/pull/2063/head\n0041dfa203535005df10a8dc405af9e990d1501df161 refs/pull/2064/head\n0041534ef3fe70c9ddf8bb3be2611967a27fdc18af0c refs/pull/2066/head\n0041e3307ccfbe4cfc66099049a0c02447ce4214d28a refs/pull/2067/head\n0041914cd027ad55591aa88c0b458793cf4fa06fc2c6 refs/pull/2069/head\n00401efded0c7da7b9b855dff24b2ef5ae27532496d6 refs/pull/207/head\n0041a97b632eefa842b42c14cd6a738e71ff03615eda refs/pull/2070/head\n0041da57e2de83414be080dbe083665c90008a0562a1 refs/pull/2072/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2073/head\n004174d79dd6aab423b075f15e0577d277ae125cc436 refs/pull/2074/head\n00410928411247b51199daa3bf7d5cda670d216e9d36 refs/pull/2076/head\n0041774d2eea01be83a26f4d857a0da058606e26d3f1 refs/pull/2077/head\n00415671f0abd1b02a8c003aa00accce1600f405c4f1 refs/pull/2079/head\n0040140337e1e1d9af38371be75fa4d5f5a4b239e50f refs/pull/208/head\n004124556f57344c7bbddad2b235f40612fe50abdc8f refs/pull/2082/head\n00415f0956d3fc07895cdce08b590e3a58bec356f5e5 refs/pull/2083/head\n00412f0e6b16a8eba22013463d2f06c29273af6586be refs/pull/2084/head\n0041d97a9b2ba365e6db9d4eff805118536b997c0c1b refs/pull/2086/head\n004166a697f9b0d9a72ebfd04e201ea5ea51bb12079a refs/pull/2087/head\n0040eccc45a3ea6c3ea1ffab1b224e0f38701acae5ce refs/pull/209/head\n00414e252005ddb3f08c77948c828a695f5cc90e10af refs/pull/2090/head\n0041c858aaf921ce8c2323422505bb4250581a9c7213 refs/pull/2091/head\n0041820ae57aa36afa9ca11411ecc74124fa99a5d11f refs/pull/2092/head\n004192c8ff73ddf065aba993496d8b27b313e7702a08 refs/pull/2094/head\n0041cae269ee9de564f8beaee54af3307f62e5b3431d refs/pull/2096/head\n0041aadef428d601202d79299c176e4b41e245ba843d refs/pull/2098/head\n003fdd60e6b515cf2f60a17020ae3c99fc26c48731e0 refs/pull/21/head\n0040b68182934b0c69bfacc4745141c97159263cbafe refs/pull/210/head\n00419bdbf91f4437ca3d3424c25d405f48c7762165e0 refs/pull/2100/head\n00411e05bd5c637cc150c7b0242660a7cc56a57fa45a refs/pull/2102/head\n0041d2b1520f1075eb199d17ebe44029aa429dfa198c refs/pull/2104/head\n00416d8dd63c503812e495e9aa4051931a312e45f3d1 refs/pull/2105/head\n00416c0238bd3f954d95d032ac8699c69c7dbb261ede refs/pull/2107/head\n004125defef4dc82fc1a655825d41fdcc16ff9315c4d refs/pull/2108/head\n0041edd5576921ab95d4230fd39e2c0879ff8a1373aa refs/pull/2109/head\n0040af2477aa12be46101c3d7cd0003e45b17e98a98e refs/pull/211/head\n00410f384635ad38f435e9d342c1d084c8d82d76532d refs/pull/2110/head\n0041e888febafad31e6977fc98801c90d06e3930575d refs/pull/2111/head\n0041f1cc4c719b85eff4d09e262482fe08f2c82b1ec7 refs/pull/2112/head\n0041c215ac334d53aad70c8f49c3ca4469138afb14ea refs/pull/2114/head\n00412846504bcc6555185b6087e2b3df29b20acacee6 refs/pull/2115/head\n0041b15d59d9f159cd31b4389084e6393cc13c89c24f refs/pull/2116/head\n0041a0ccb0b329ec1482e4fb4b357808f69be1d2918a refs/pull/2117/head\n0041d5ec3caab9b15dff0404c53f8503647f0ed9ca8d refs/pull/2118/head\n0041e8b0cbb473269a2ecd82efa821bdceab82cef3bf refs/pull/2119/head\n00400f5e062dd35b9ebef263473fca25512b315a918f refs/pull/212/head\n0041c6506ee1cdf64b1f8e5aee02a68d2373ae93152e refs/pull/2120/head\n0041a46c8c3624067acb6c11e9a8f7b2d55b9b18980a refs/pull/2121/head\n00412a59b5e507bc1618e1a8cab5dead857665cf40a9 refs/pull/2122/head\n00415d69ca46b8216051eaf37047a336912b1123c5a1 refs/pull/2123/head\n004148c3be619b89ba4966499bbcaa4e40bb6af35b48 refs/pull/2124/head\n00419a8d69289230a495f8582cd65eb0dba7d3307620 refs/pull/2125/head\n0041e5eed9e46a09b94567bf86ae4f6d46019ec18faf refs/pull/2126/head\n00410bfb1a4d4902cf9fbf7593f03863dd37b8724ccb refs/pull/2127/head\n0041c54c9f8ec1c7f9ad8ba779671fc710d4a164af0b refs/pull/2129/head\n0040c5e09ae449a74b916851abdde913f3098608905a refs/pull/213/head\n00414728b5044faf129ffd24a985c74cdf31040a3dde refs/pull/2130/head\n00418a24cfd871e0958f9fa723f6c6253952b0deefb7 refs/pull/2131/head\n0041db8349bbf8bcc8a467d116268cabab91145eee0e refs/pull/2132/head\n004171dcb05b8b4671c05f18deb458e5d3aa8f95e86e refs/pull/2133/head\n0041364d95c03b18af27f248bad58a56bbbd2adc19b8 refs/pull/2134/head\n0041159d4dc4ae6f9e9816035ae170f0204043df7a8f refs/pull/2136/head\n0041566aaec5b39a4dccb72e688c105dddeb57cb0f54 refs/pull/2137/head\n0041f3b87b9a1c2db51259d6445e488369fed87788c2 refs/pull/2138/head\n0041517ca96e424138e2f7e09b69440b46846c53ce65 refs/pull/2139/head\n0040e03ffff3d0359f7a13ef512ace8c56c74411b2eb refs/pull/214/head\n004105f77f86e9caf21163e15e1ea8028a9468a781d6 refs/pull/2140/head\n0041223312684d462a1bc67706baccba127b2bbeb1f0 refs/pull/2143/head\n0041a326ddd7e0e2286cd23d9bc38b6f34bd0843cde8 refs/pull/2144/head\n004181aa02647563b8231cb1db035ff97764a4bc4c08 refs/pull/2145/head\n0041fade7728c3f1bb109dbd6a58cc9cb5b5a7244448 refs/pull/2146/head\n0041d0e0731232ebd7711fd7f7d80b4286f4ba97ff70 refs/pull/2148/head\n0041e70a80f91dd512f7380a90b53adc925c132ba932 refs/pull/2149/head\n0041d5a96efa27504a15bf9a03c432088fd8243415cf refs/pull/2150/head\n00415bfc4e906a519270df95056eb9a48b8089f68d56 refs/pull/2151/head\n004126cab433e325e4142045bf6f2f8276071738cbb1 refs/pull/2154/head\n0041db0945190e0388ba27a9bded0314f3016ea6f262 refs/pull/2155/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2156/head\n0041370f57d1ef87a56d7a59f5e7004d413c5cabefeb refs/pull/2157/head\n0041f99c264fe30fe0915efff777bc94dc16df9ab48a refs/pull/2158/head\n0041a10bcf7c8df9f32499ffbb56a13a52d7f8cd64ad refs/pull/2159/head\n0040daaa4a42527acc0ba496672ea2c807412acc1958 refs/pull/216/head\n0041a94c3dfe95cb58665bf4b4c15fd39db98b96ccab refs/pull/2160/head\n0041a3f61afacc7cb29a0643328bead3ae6c08c6c05a refs/pull/2161/head\n0041e9f54cb2fda9cf61d179d1485a0c0aa8f21bf901 refs/pull/2162/head\n0041167f4e6825a414af01e75365d3c87525a214a550 refs/pull/2163/head\n0041e8ace6973134c0829cb1a9c598e447a64a59e2fe refs/pull/2164/head\n00414d66b12e44db8f5abcc2d2a8c319003e185b34c0 refs/pull/2165/head\n00414b2128402627ebb80b7d8d1af8c092c9a119d840 refs/pull/2166/head\n00412917da51a376598d389320da3cc266c082512951 refs/pull/2167/head\n0041c18c08f53377f808d1989402e9ca25a4d4b1517b refs/pull/2168/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2169/head\n0040d3b681cfb9b0a6af09daedd4a3f8ba02ec766e3d refs/pull/217/head\n00417e5bfb0a34444628009a93432b2bcdd765d15de4 refs/pull/2170/head\n00415c6726b2bf8aa3b7ff79bbc6aa971e3082d93504 refs/pull/2171/head\n00414d9d3c0babdfeb31f6eea7cbc66dcb4bca1c70e5 refs/pull/2172/head\n0041ed63121ef55c84127cb5137dc0a650e7cb302571 refs/pull/2173/head\n0041f347c8cea2246a490ac9101188c4f86382be1424 refs/pull/2174/head\n0041013d338151b3156f6bb1d994d2d3d3a5b1c3d0a1 refs/pull/2175/head\n00414e2227162e694ebbd975631a8ac0a65f1a031792 refs/pull/2179/head\n00403931b2f889e2c657f34c3c5167030143489ca091 refs/pull/218/head\n00417e92aaa16538e195547bb6d41198d65dbf1182c9 refs/pull/2180/head\n0041952f05576f2f134514cc91e5b2dd9f4d3dd209ce refs/pull/2181/head\n004128c50d845b49aac26f7cb9df609bae2ab3727190 refs/pull/2182/head\n0041c1a513c3c934135dfc1154f4861bdf7afbdce60e refs/pull/2185/head\n0040fe110eee20684e6f2b05a4c067fb31879e456932 refs/pull/219/head\n0041a1da249964cf146c54539cca524fbd1013d2029d refs/pull/2192/head\n00414ff69d3c81ac79198a4c99a285c66bf68ea4c538 refs/pull/2193/head\n00410ba2eadf30c4637e8dfb9970899564a43aa6281f refs/pull/2194/head\n00416fc5cfc1a359cd30193055997583fe393cee0739 refs/pull/2196/head\n00419bcdec0855ddb161e35d720fd20c9a572061adae refs/pull/2198/head\n00413e9d126a22e958a30ac07045f506ce1f19f4d968 refs/pull/2199/head\n003f985084119b8da35919c3de651e275acc06e1cc2b refs/pull/22/head\n004062ee6c452595eda122ff0e40ca69f8f615b54438 refs/pull/220/head\n0041741ad5fab0aeff22fbbc8663cd51b98a930e7b5d refs/pull/2200/head\n004131f5035ade93af773bc0f352e16b205978ba8288 refs/pull/2201/head\n00416bd63d39f998df7e56a95ce1e678d7e00c1fa86b refs/pull/2202/head\n00410ec8f46347ea4c4b3cfefa672d755302b6bc0195 refs/pull/2203/head\n0041645959293e93b7c41224ca6565d549ec45f20fc5 refs/pull/2204/head\n0041d9d3e311facb95d40ce676157dfc5efb29dc4bb4 refs/pull/2205/head\n0041a1c81c8de57edcf53010d0708f694b1accf8690d refs/pull/2206/head\n004106f20c35e22816059987089b3c2e48ce47798ed3 refs/pull/2207/head\n0041193141017843084d2f272ab8f26a89b6b047302e refs/pull/2208/head\n004176a1a98700ec28446ad7ac165e15ca3880fb0eb1 refs/pull/2209/head\n004048611d3952d8596fe9781d8c8bbc15326690e6a4 refs/pull/221/head\n0041af034a96d6cc19a7fcaf1ef9d0bf3b6b478ece7e refs/pull/2210/head\n00413bf320e9526067c0746dffc1ea8b4daebe2c5bdc refs/pull/2211/head\n00412afae4f3722aa4fc07828ecfb290cc1ba21d4f00 refs/pull/2212/head\n0041ca9da16069d42325e475cc6c343b6f6edb5ce623 refs/pull/2213/head\n0041c7e3aedbb454e839909dc86a0c3d3111117b96fd refs/pull/2214/head\n0041caa0a41f2f4270e59b0120162bad48fecfb4b744 refs/pull/2215/head\n0041ff3e8f0694a4d37576abad605a9e21720174e787 refs/pull/2217/head\n0041aff2b3e908081ccebdee53267b4997f9da5166b0 refs/pull/2218/head\n0041fda0c2e5ecec32a74ab3e1667481f5ad7a696610 refs/pull/2219/head\n004040b3ec19fb72ebf2d0384a6ff5d2f2014d4a6992 refs/pull/222/head\n004180525c230f1caabf56e881ed7ab459df710f57db refs/pull/2221/head\n0041ac9c814844d8656bcd36a929411406594b91b27a refs/pull/2222/head\n004199f27a746f2f16538e241ea4c994a5f3ddcafcf8 refs/pull/2223/head\n00411a3e213541a2de4e0d7d9ddaf4679a20b48405e2 refs/pull/2224/head\n00414f9558a8d2f1b7419e80eae901761c80aa53aa8c refs/pull/2225/head\n00416a253e4d552578539f484b436c32a0eb5a131fa7 refs/pull/2226/head\n00411d10b35abdabbaf3fe8f420992a07f83ce68c614 refs/pull/2227/head\n0041b23d995bd7c7dab28b221c8ce2bee885ab70249b refs/pull/2228/head\n0041ccb42747dc8a368d7084d46d87014b77047ae1a5 refs/pull/2229/head\n0040336503602a15fc771aa1c1c36486ddb77209dfd0 refs/pull/223/head\n00418c3360a8a5d8d531d0f2e447f9e70bdf8f796972 refs/pull/2230/head\n0041ca22722c1dce5a66f5717ca5d62e38a9732596fc refs/pull/2231/head\n0041d80dc2fe58efb2742c955e07a6c07bc1473fed65 refs/pull/2233/head\n0041c3693b5ca51373d28b6b52f004020b4fe518816f refs/pull/2234/head\n0041ee10756deb3286462704eeb4759d78ba10969110 refs/pull/2236/head\n004116222ea878bbe791f998cac019b70bb1765cbe9f refs/pull/2237/head\n004110b241e044a66932cacabd1afc4d3fbb0f35d077 refs/pull/2238/head\n00410da409bee5c8c4f7b82ee5b7f2f8df0331f9bff5 refs/pull/2241/head\n0041fad9c9e4bf307e38cd5c046459e8b2eb9e7553e6 refs/pull/2242/head\n0041b2456b296ce2104856d6a84fcd191cc32406aafe refs/pull/2243/head\n0041de20dcabbbaf0e964744cc56b4c9a20ef7f63b05 refs/pull/2244/head\n0041a4a50c2ef4bd1bb506ae8d7e70ed0095fb2ab0f9 refs/pull/2245/head\n0041388f6d5c12827d5c51d427531f1bd087356fd2b5 refs/pull/2246/head\n00413fd8c2e118cb471d75e559804d7bf7ded4b894df refs/pull/2247/head\n0041a92e4dabef6b5d88e2e5fa79bd46add0a3b0185e refs/pull/2248/head\n00418557ff43e4873f5da41953950105be2565dea53d refs/pull/2249/head\n00402c34baf3b48f0bc9c895ebca5043d0544a4fa601 refs/pull/225/head\n00412984bd8d2522d267b1d8ddc787e33a6f867ab951 refs/pull/2250/head\n00416cbdd8411ba53f845ba6e1e31f0903053bacd683 refs/pull/2253/head\n00410062172b11f98d0980b1d31dc3ed3b8a444ae09e refs/pull/2256/head\n00411f994a25d12eb1cd9afe903a4558092f62f9af8c refs/pull/2257/head\n0041e5bd727e599e58b57680b6af4228456476e6a324 refs/pull/2258/head\n0041490296fa34b945dbac7f68521f5019e3fbc6e010 refs/pull/2259/head\n00403986f1e346f705814c8f76b1e1a1f39f253565e1 refs/pull/226/head\n0041000f12bd3b89f030d08c78d5a9458aede68aa0e0 refs/pull/2260/head\n004150c4ac1ca3ed40862ba9de2e245435245d3f2eef refs/pull/2261/head\n0041c16df2a93b493d1c94e4b1d4b08d89205acaeeff refs/pull/2262/head\n0041d878e3498a22d960dad7f886489a3a43bb644ff5 refs/pull/2263/head\n0041f0c95462867090157886315ce4ab95d2f2624dc0 refs/pull/2264/head\n00412b13b45ea1646421d1bb7841a0aec13a9b232040 refs/pull/2265/head\n0041db2b9a6dd5d89ded180a53cf6a98608216b1cffe refs/pull/2266/head\n0041682844de6e22955ed5a6844ea6bed462308b87dc refs/pull/2267/head\n0041c0071255816784a8e42484060df1f0ac2cf31932 refs/pull/2269/head\n0041e600f3a2159c07215036b540f7ae6a6a7770eb45 refs/pull/2271/head\n0041f3e4189020ed591fe7f3abf1f2e5c98768cdbdb2 refs/pull/2272/head\n00416a7310cbecb14299aa3acd0b3cb8550dc209584a refs/pull/2273/head\n00411aefee6d3342b8b05c326ca8a57136f6f5374806 refs/pull/2274/head\n004146cb03dcaddd28f0c845744bcdd4c499ef4d74bc refs/pull/2275/head\n00412754e0160707967e35faa7943ffbeb00b565831a refs/pull/2277/head\n004137548c1ae7cfb2a024df5e8795eeccdeffb05ae2 refs/pull/2278/head\n004161f534a7e55b4e83460721b951bbf091f3241874 refs/pull/2279/head\n0041f8b616e0a7b1c4ec58a4e1aad97154410fd0f573 refs/pull/2280/head\n0041cd8b16c68ca6e0dfd7a68e0574eec5b56cb3e4c8 refs/pull/2282/head\n00418786f6ff2338f4b3e2153b4155a26ec887bd1ba1 refs/pull/2283/head\n004147859e6f1e02ff5b514f258a5aef89387c6ef8d6 refs/pull/2287/head\n0041b90fc5f656efe508cccbf7c9cac25e96b6819966 refs/pull/2288/head\n004175544cbc15c840a07067f40c54f81b47e966b45a refs/pull/2289/head\n0041927cf2bfcfbfa3688c0d2cc1444161d9124c605d refs/pull/2291/head\n0041541d04c51c2b9515cd75bd6fe53b164faf97a6aa refs/pull/2295/head\n00418cae4953d6b1900dc06d1f7d10d854a7eb96bc78 refs/pull/2296/head\n0041e75fe6a870f8214d2df73b9fd5fe247a36eda287 refs/pull/2297/head\n0041642e6153a9205a47270bbef52d5083bc9402b7e4 refs/pull/2298/head\n00412738976a712891d506de1b2cdf9572e2486b43ec refs/pull/2299/head\n0041102d9ebaf8f6d139d2570fb35367f72d7f842eb9 refs/pull/2301/head\n0041200c1e907e9a9f4061ec24627aec227da40b0dce refs/pull/2302/head\n0041ba4ac9c4029e17faaed41a4c77a49dffc4b137ba refs/pull/2303/head\n004104071d4510e1a9eae2555db2e195d9907c20314b refs/pull/2304/head\n004182296895d676cbeb713f8237fa6c9aa0b55417f6 refs/pull/2305/head\n004163555fe8a246e7024f16d17f969da9d53c0bae0c refs/pull/2306/head\n00413c3c13493aaa9aa000f02a81c3e5079ed28cb133 refs/pull/2307/head\n00418805681354f7bb76c0a7d088ea53362aa4f913d4 refs/pull/2309/head\n00412fee37d27e5dc081565870881b0af98226099b6a refs/pull/2310/head\n00417d3020ae31e7269f666702c5c89cf68747a8357e refs/pull/2311/head\n004194b292ae40c1681ed13df2d2f5d6349bcddaae8e refs/pull/2312/head\n0041a5b3685e7194ced65ad79ef485212a4e1394ae9d refs/pull/2313/head\n0041c7a9bea483be59f447aaaf8fe27bf0051712f093 refs/pull/2314/head\n0041ff3ea7175f824e65b27f28c59142c0039323e179 refs/pull/2315/head\n004152ac0b29edd8fd78ae8f58d9d63a40d5a80cba99 refs/pull/2316/head\n0041c08f32f67aa91a9af146eae74b2e52320a8ef9d0 refs/pull/2317/head\n0041a692921c7d2ee84358d9e40cfb28f5e89f98f238 refs/pull/2318/head\n00418b64c98d985f517087ee4c3137577df0f806a2bf refs/pull/2319/head\n0040a72b0f899bb35939f65c2eee4653a4534fdca938 refs/pull/232/head\n00410e5ecb7666490c0a5dfb73dc97134520970c6872 refs/pull/2320/head\n0041dab1e190e50253fc770f4b4e023cfe6c942088a6 refs/pull/2321/head\n004118d1aa22cbf255b253a972fa17e2a8f19ff11d83 refs/pull/2322/head\n004125207bc51923412606abc8a60c7783afabcfb554 refs/pull/2323/head\n004167aaede68e0e2d8d0325c15eee9efc7eb9acd1fe refs/pull/2324/head\n0041ca8e27a9810a339fb0429cacb004a51e266609d1 refs/pull/2325/head\n004115f4b1cbe50c19a55b6ec61d94f3b8bd5ff9254f refs/pull/2326/head\n0041c8924b63350c65435531a2f16b5062b8e0349d16 refs/pull/2327/head\n0041bd79c21ea0139abbc64a6a79a8d96fbf7181762f refs/pull/2328/head\n0040b8676faacbfc2e6fea33905a6cdce631ff426ed5 refs/pull/233/head\n0041aa40413e669c4e137cd8d39068e8ba99933f95ae refs/pull/2338/head\n00418e378c436c58840a441776e29cf3c7a4f0a1d382 refs/pull/2339/head\n0041419aa71a493e10bad201d1702ef420c9c26399fc refs/pull/2340/head\n0041d71393208f1bc5e9e8d3a22d175c859a13cd180b refs/pull/2341/head\n0041773234bf12f485f32d12854e89ee0ae605a25889 refs/pull/2342/head\n0041d8fd98c896c8af5854915ad1164aeb785d0dbf61 refs/pull/2343/head\n0041d13a8ac8dad35d3ed7e88d79a0209e3619b49530 refs/pull/2344/head\n004125c7038b09a902e14c917a3424b0fb59ae47b908 refs/pull/2345/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2346/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2347/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2348/head\n0041c0d8d5792e9ef5b8c5f5e42de11d9cadf19715ca refs/pull/2349/head\n0041fc2887fef044d0d3f5643b8328acbeb8daeda055 refs/pull/2350/head\n00417e3f756a0239d51869cfb1e766f83aea55bb78d7 refs/pull/2351/head\n00411131f46b62d559ed6349f1886d72998122b904e2 refs/pull/2355/head\n0041a785c0b107b0245aced8ab6444a0dcd554690891 refs/pull/2356/head\n0041fadded923d6b7487a878306b4db76ac2fff66808 refs/pull/2357/head\n0041084bfa051b06e9cdf96eba3b5cd96497dc1fd302 refs/pull/2359/head\n0041a8db307f7d3a457697460ca84a76312de41244e4 refs/pull/2360/head\n00419e7e709fcb8a4aaaa479e7f5045bf031c3ac011e refs/pull/2361/head\n00418b37b80317b9be689039062b3de0a1c3cb886f69 refs/pull/2362/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2363/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2364/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2365/head\n00414f168a73f84b4e8bf2ae582b2aaa22646a9927d6 refs/pull/2366/head\n0041eaa3b70bcd32c7a2fd92ce341a1fc3577a573a0e refs/pull/2368/head\n0041ddcc9575213116fd75c1592f21a1199357c02cd0 refs/pull/2370/head\n00413ca0c78954d8ce2178ca2bd45146236a700a3c5b refs/pull/2371/head\n0041319c369a4ce9c5b2530a5171e22a17974dd6af96 refs/pull/2372/head\n00419ce1728af46e3a005b534308fd6b851174f6607f refs/pull/2373/head\n0041ef84432d4f589990bae9541eee952006fceff4a9 refs/pull/2376/head\n0041138fca28bcfa8a93b3eb5db7f285a37ad8dbd541 refs/pull/2377/head\n00412295d8b3fb84b1b493b39c3810639f46ad042987 refs/pull/2378/head\n00412d7a5cbc3855c9e9c54646e933a7605109a735f0 refs/pull/2379/head\n004001df8689af378f1d9b0123e6797da3e5e73c2e22 refs/pull/238/head\n0041a1cc2ec290ae9e6eae4b8c0feee477b32ac76e7f refs/pull/2381/head\n00416b28bfdafdc0262bb92f67ed21444d6bc589d65a refs/pull/2382/head\n00412fa59043f55f9a6c44243abba66f3541e9f5ae9b refs/pull/2383/head\n0041b997add1e8dca84349e6b571ed0f6dde4119cc8b refs/pull/2384/head\n00416618f3a764a74a0a0552c5ca080bee3d15077eb3 refs/pull/2385/head\n0041d3883c619f08310c58c16691a93a67cf94edd324 refs/pull/2386/head\n0041f39876a2c0ac0f18f7dd42c48859f55626b46fe1 refs/pull/2388/head\n004006ba35b53646c2937bd1fff198b269d1897eb583 refs/pull/239/head\n0041eb33b57255744abfbe557369066619701c0d0f69 refs/pull/2391/head\n00413dc4950c009dde0ab369b2ca459368b953190e40 refs/pull/2392/head\n00415c753f8eac6e9e83a39261373789c09a8299cdf5 refs/pull/2393/head\n00413924c28bcf5f0a53df04ec74b5f6c36b98948dda refs/pull/2394/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2395/head\n004119846ac4836859d8c568239a42b72ca44139742d refs/pull/2396/head\n0041cdf1a7062f8f077d3fa4d6d08dd5459b34880854 refs/pull/2397/head\n0041e368558b630ab18408c79db485a474dfa4683e94 refs/pull/2398/head\n00418f4bb87155757c3a39c3f27aa7a315f34983e3e5 refs/pull/2399/head\n004067e93c659b3fee46070e27c3ec08402a35c82375 refs/pull/240/head\n00415804bb125905a1dcd8b103dfac2ad2b15f811984 refs/pull/2400/head\n00417b80fa5cf0abd102423d5dcb24d7b32bf5212551 refs/pull/2403/head\n00416a76e512e9b58d77a7e5248cb678a4c647f1d669 refs/pull/2405/head\n0041051dca78e7664c9b451670baf44d15851a7d33fd refs/pull/2406/head\n0041f91bbc6c66207b0e908e82733f029c32f1292641 refs/pull/2408/head\n0041a5b9ad92313a57ff2a0f53f2b81aa90b9417d91d refs/pull/2409/head\n00404debd5e8e0860cb57154cfa59525c87bbe9e1021 refs/pull/241/head\n00412c28c867ccebeced01a0f0ce2ecf98f33df27077 refs/pull/2410/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2411/head\n00412184298934e71c29b6d66ed59782938fdaaa0f20 refs/pull/2412/head\n004199325072b64c02fbd888329fba65944e0bf731a2 refs/pull/2414/head\n00410917f9702082147abaa26bb6fcb1357f8a0f31af refs/pull/2416/head\n004195829ab78ed81644b5eb41fbe8409788a9fc7e21 refs/pull/2417/head\n0041c5a219f066e5a874208b2f78033d8ed0f90762b8 refs/pull/2418/head\n0041e28d97d2634995711e5abc794ee6484099128e71 refs/pull/2419/head\n0040d971c87456fbe727730b656e1c6a5de7f7831364 refs/pull/242/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2420/head\n00413ea5d0adbc23cb3059c3297a9be8b854812883dc refs/pull/2421/head\n00411178657965713054cc5790a36b291b30b6d9ca81 refs/pull/2425/head\n0041c9c8d7b7605dbe60cba2eccc00f55723c2acdaee refs/pull/2426/head\n004103549f653ed13a38b886d13855e30c311942d652 refs/pull/2427/head\n00414154a9cbf1c273acd34a5d929adba231b469e629 refs/pull/2428/head\n0041cd93be6a1d7c92ee9f76789fd7c97842b0a7740c refs/pull/2429/head\n0041f733ab04711173a59877d809b2f557a9e3ee4a60 refs/pull/2430/head\n0041c5fa3e53f03ad8e999d57b7f76237617ad4037b6 refs/pull/2431/head\n00419bf72cd1fce073ad01b904fc1ce17773d2d89d6e refs/pull/2432/head\n00410715e65452d2cde3bc2b8bcee1c5a2029ee8afb3 refs/pull/2434/head\n0041794af8c606abf9a5060b9a4442999b9f23431678 refs/pull/2435/head\n0041e87432e66ed5209673cdd0ddb671a8a9a2c03708 refs/pull/2437/head\n0041c4ecded417152c3d5bc809d566769e71780731f5 refs/pull/2438/head\n0041536d8403169585521583475f89d6ce5aa03e0a92 refs/pull/2439/head\n0041ba01d1c94743595ca04e14ec2573dbee254c1c1d refs/pull/2440/head\n0041da45d1e2c8c8c6e3e770b310cf6b050f6da03aa3 refs/pull/2441/head\n004156ef8c622bfbb8376ecb2ebb20ba1668804b461e refs/pull/2442/head\n0041b01339a98647dff2ed86c2d229e23182e57f4a87 refs/pull/2444/head\n0041107392ac7410b8c25028a271523b0f4a050a69d6 refs/pull/2445/head\n00414c66211ac3614faffce5e8e008f16542fcf19019 refs/pull/2446/head\n00415d69266426f17b173056b98b4ed8f01ce0e9caa1 refs/pull/2447/head\n0041b9230a99fa4e2188859f37ced2b7c4427d8b7be8 refs/pull/2448/head\n00418665468e83b5be7770ae198388dcd5ee61dfd5ce refs/pull/2449/head\n00404bdeeb490f450be54f2e73835a76831f332cad8c refs/pull/245/head\n0041244459aa1f47e3433ac537fb89d3dabc7fe23fd9 refs/pull/2450/head\n0041d478b8f397f01d149f8f784a2ac2c95d40412c9d refs/pull/2451/head\n004170decc6cdce3762e1bbeee5e28d5559f80ef8318 refs/pull/2452/head\n0041ca9eed266681e9b352b64c73d5557c15cc38e465 refs/pull/2453/head\n004129c754bf205a00188f6f0a1db1c9f3d82f68815e refs/pull/2454/head\n00416922b4330f05d791b64aa56c40ab953940e71268 refs/pull/2456/head\n004149329a17ed31cfe6fe2dba21b88db58367e7c494 refs/pull/2457/head\n0041f87c0318ffc66e3c82451cebc129ecbc7bb0a933 refs/pull/2458/head\n0041efd8c2b4ca7ee897c0fab7a93ec00bd8cd29c7d5 refs/pull/2459/head\n0040e6a0e38f56d88fe922bfb15e35f05f15daae72d4 refs/pull/246/head\n00415511906fc24b22b252d54f5d2a4b862662510a0e refs/pull/2460/head\n0041ae298fa67b643324650f89628863bcc4dbe1ef7c refs/pull/2461/head\n0041644d27f3c18e9119d1fc471d07279c6e666417d7 refs/pull/2462/head\n0041ce867243c2cdf166b31a687a350c7b9b705c7194 refs/pull/2464/head\n0041f6221e43ecb01c46cf84d2e4938a5c3dcf37a5d7 refs/pull/2466/head\n0041e3567ff0d7f5412ab4135bbd4be8adcdb333b5b7 refs/pull/2467/head\n004153560ba756790c71366a7fb6ed9be8dff4e8ccfe refs/pull/2469/head\n0040c6648aaac24ee53b9933bf43a97aee09dc22c3c1 refs/pull/247/head\n00419d221250b69f232adf7fecd8749cad4f2a40df2f refs/pull/2470/head\n004183dbe9f90092b8e791b9e906138eb3417e838561 refs/pull/2472/head\n0041086f6f183efe4ec20ac643ab2bc5e98677f2d94b refs/pull/2473/head\n00418fc6a5c455a1b4dbc1dbf9869bbe3be6ff82412e refs/pull/2474/head\n004117b37df5d0f231481d6e5b2ada66666f99840fcd refs/pull/2475/head\n00413b2392429fe87cef09e404e695af344e9964370b refs/pull/2476/head\n0041aa0b81d3a6db4bc68a306398c30b473c6309cf58 refs/pull/2477/head\n0041d6d326a4a90095edf0da1d06d3eb48975a29fec1 refs/pull/2479/head\n00404709ec33c18f5c2653efffb908a8b69474fc1deb refs/pull/248/head\n00412af5644abf515b5b8424c8eb7b12faf35be68f07 refs/pull/2480/head\n00416eaa4e79b0e4b1178f5a03e299258632338b781c refs/pull/2481/head\n0041f6cfbd09ca2659675ef5ceca4d9b03b86b42849f refs/pull/2483/head\n0041098f63817e201983078c996ce5b1222aa2be6a01 refs/pull/2484/head\n0041157a47634e6089c7f7938bc7939f0661f5563b14 refs/pull/2486/head\n00412d3046144846d1a981b4ee30db75ac0e0a799f41 refs/pull/2488/head\n004180aa3dc17e885ee35a09ad1488fd18ef42961473 refs/pull/2489/head\n004197094af2d52994da5f658a26372006e0446fad9b refs/pull/2490/head\n0041224485342b1c8b88e4b4c3c48f13c083fcb837ab refs/pull/2492/head\n00419cc699a1c0eff4fb777a32951b06519dd7f25335 refs/pull/2493/head\n00416dbaf17f9a9fbbca7be0d02d5e4e0bdb74b0aa33 refs/pull/2494/head\n00416c1465a055851c726de155021c7284e98b92cc91 refs/pull/2495/head\n0041d302e811976f33178b99b6f15e24c1c23db46da8 refs/pull/2496/head\n0041363d41a21a19b87a0d02a6590d091beeb3eee582 refs/pull/2497/head\n0041568b516d94c9ac0877faffb3dbf13dfd9823246c refs/pull/2498/head\n00410c46bb4025498aa53f8872fab755e8cc02bf2006 refs/pull/2499/head\n003f45d1d4967d81f6ba4e3720a7065a3dc7ad83efd6 refs/pull/25/head\n004073f225e0cd741972f843ead3efd68f3768d32a40 refs/pull/250/head\n00414558a3e87dc35d37be3ecf5804ce499cc7a280c6 refs/pull/2500/head\n004130aadada170106402b84ed7cbc1e3a2be714c261 refs/pull/2501/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2502/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2503/head\n0041c2cdbf33c04c2261bbf13460875dfa96c8d4a900 refs/pull/2504/head\n004131cdc4803c8bc38ad71e14f1177b4dd1e1dbef5a refs/pull/2505/head\n0041cc06e5bbdf95c0e9502e86d24caa07da735e61a2 refs/pull/2506/head\n0041b64512aa5404eb97a175897e819a0a08d8be84bc refs/pull/2507/head\n0041c5fd3054cedd2be85d7e3b7013675990beeb20c5 refs/pull/2508/head\n00417fe9934f21fedf95a3bd95f7a0d7b51ac7425c99 refs/pull/2509/head\n00403444266fc3ee97cf87d942e5c3cfb6adcce0457c refs/pull/251/head\n0041c7c8e84ae2c10084fe1b913262804cdc76591509 refs/pull/2510/head\n00419a05a9350f70a44308e36728775b045eb47931ed refs/pull/2511/head\n00414277918e4a52bb2fe657d9782c40e5ef59678a57 refs/pull/2512/head\n0041c1035ce33537f701f91b7f1bf6df9b943d7eea80 refs/pull/2513/head\n0041a744fde6253c6a98f1b58497ea97d6d7e3c26a59 refs/pull/2514/head\n00419ce7f5a2d56f6a15b084858ad26a26b1b88ba8dd refs/pull/2515/head\n004197e4213204d34947cef09cbe4c16ab83465e9d1c refs/pull/2516/head\n0041ba6b47281628ec355528f1e472fa96d864d2caf9 refs/pull/2517/head\n0041a408bd7d8cfec77a87a9554285045087fc6f87ca refs/pull/2518/head\n004191651d9e6ff7181ed487b6ced372f0bae22d32bb refs/pull/2519/head\n00407f9fb1a86780ddcf6e73c22594f878de5e844f65 refs/pull/252/head\n00410fe7f7663a58e3735fa7f45f46b8ca64b4bf60a7 refs/pull/2520/head\n0041e19697e71d89145a504989888ae3faf0a739a27c refs/pull/2523/head\n004183f32f12b3c992e78c2b96524b4652966367ed3b refs/pull/2524/head\n0041e0bf1f04ecd19faa9d800e5fbc85ab4de3a11f07 refs/pull/2525/head\n004117dd77cdf4cac22f250d00ad1d43f3b928a0a8ff refs/pull/2526/head\n00417260f278cc92a8f2e620c55208c8bb9311c3bbb7 refs/pull/2527/head\n0041b0a9342ef09bd25dca67903d16fffcf45c199e8e refs/pull/2528/head\n0041a06d52e26333b88ae90c515acff70dfb6e5feedc refs/pull/2529/head\n00401cbeaa642c6340f4450ae7baa44745bfa361f16a refs/pull/253/head\n0041016576c8814583b730870f8e2015a023f234712d refs/pull/2530/head\n004174189b5520d233ba50fc975c076aeec7cdaa25af refs/pull/2531/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2532/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2533/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2534/head\n0041feb4d189cb1125b0838cac8b6570a0f8ddd11621 refs/pull/2535/head\n0041a5419a2150dde4d2923f4cdf17a23ef20f6c88bd refs/pull/2536/head\n0041d47dccfce889e6915995d122d04ef363014ed89c refs/pull/2537/head\n0041dc6f679abfd23d56e171946d908b75e5acdce47f refs/pull/2538/head\n0041b72c34c7f9edb9ae8513e95b6d2245c2cb5f54fe refs/pull/2539/head\n0041a2cf07661f649e73475c124118e8cdc334280c1d refs/pull/2540/head\n0041877b62e647862471f1d2b6376773eec2c3a1b211 refs/pull/2541/head\n0041cfc1741a5ded4e6040868b9012629862be1a0077 refs/pull/2542/head\n00412b6a997e296ea3fee132e8b9478d2073849f4e12 refs/pull/2544/head\n00415e8d1a9990b15e0f2219b5897f37424e302ca300 refs/pull/2545/head\n004125f771752f5119e8d697ba008f23e70823d72e8c refs/pull/2546/head\n00413198f8f6b575d2e954b588b4a67e0c123c51c6d1 refs/pull/2547/head\n0041acfcd4bdded2da1570dde992d6e3c15f2b21dc1e refs/pull/2548/head\n004131e9796ed8640c0ac39a81c62bc5b819521e53d3 refs/pull/2549/head\n0040fa95d2cc63ed28380c42e591258a30f607866069 refs/pull/255/head\n004173943f8d9b7d83cfb556848b167fd7c900a7e98c refs/pull/2550/head\n0041bed9872cd09ea6cdd74e31bc0eb4278a1476cf9a refs/pull/2551/head\n0041db7f04921d64675178666b7b2a8489d7ae3ca6e6 refs/pull/2552/head\n00410cd05892dc65cba018f56aad7dcda7cc8c5c4bea refs/pull/2553/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2554/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2555/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2556/head\n0041a84727a064c21268375d16b93feea2c95b038bc2 refs/pull/2557/head\n00418355cc67e9e6e8da93e59c179492d4b0903ab8cf refs/pull/2558/head\n00419c151606c877ad06bf89b3835bc356f0dec77b37 refs/pull/2559/head\n00401a970259913bb7403cdc4608f7fe9e7743f3ca51 refs/pull/256/head\n004147c640f3d31fd87b03010f20f7a4b8bc8640ead6 refs/pull/2560/head\n00410b9b22dd1c444e6ea86560e277d02ce35f0b15cd refs/pull/2561/head\n00410015619ff7aadf7a3004b1d627a1d398e51bb524 refs/pull/2562/head\n00412db5b830eaae0062ad1f518b77ab52bb27d28155 refs/pull/2563/head\n0041de1988eec8f01e838cc5697ebe961b3d07a91e61 refs/pull/2564/head\n0041bcc12ff125f2bac6e2889e144851e9ab056b30ee refs/pull/2565/head\n0041b2defafa31c947d8217a78ee64784d6e99071268 refs/pull/2566/head\n0041be8cf6b0c06195f841c7fc0136c3f4640c2945e5 refs/pull/2569/head\n0041254a670d2cac777740f22c3871b37d41daffdd2e refs/pull/2570/head\n0041c22c95d233964393d44d44c40b905ac16c0b5272 refs/pull/2571/head\n00411cb9ff8dc46e8aea62f8a43288bc84f2252db672 refs/pull/2572/head\n00416e72345f68ad7349d61d4b5cea2cc75d556d808d refs/pull/2573/head\n00412fcd5646c29b6850d656ece947749a865f8479db refs/pull/2574/head\n004142496b7fdc3a1239142d3e2bec836b60a78a472b refs/pull/2578/head\n0041d35db462766019ad82cb1f272f3f2d3e694dcdd5 refs/pull/2579/head\n0041046915c922731515b540ba344e2d420ac4a52fd0 refs/pull/2580/head\n0041546fb5d556524597efdcce7f2fc45a6e2307dd99 refs/pull/2582/head\n0041f2d1e6a62dee228f2f344361ca109cbbf2f0b24c refs/pull/2583/head\n0041dee53b9d72e183c2043edb6a8632365088a5430d refs/pull/2584/head\n0041eff28852d362648c378ee1f14d68eb16ec8d3ac8 refs/pull/2585/head\n0041675f8d051d94f0f000ff8dac8a93eff6458e3616 refs/pull/2586/head\n0041a8a4d03150df75ca23b4aa1fdb09e9da5add83e0 refs/pull/2587/head\n0041246b65dc5814a2a1050db97cfecee77014ec06e1 refs/pull/2588/head\n004181e335000a43373b83522864d2b1729b1d6d6e60 refs/pull/2589/head\n004027b9d604bc4ca31002e242af3eb43a4d26bfbc8d refs/pull/259/head\n0041e0167739ff07740a1565e1b2bbe2a3eaae584e3b refs/pull/2590/head\n0041b94c9ecbe2dbd3f612c4e2caa6886d494be3cf73 refs/pull/2591/head\n0041e57bd03a3b8a26295dc22d092334563a34bfb07e refs/pull/2592/head\n00418ead6a9209d4457843b2ac6e9a7a2549b0886067 refs/pull/2593/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2594/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2595/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2596/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2597/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2598/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2599/head\n003f627e315ddb24233c9159877a91e88faccbeba942 refs/pull/26/head\n0041b3aa240f3cc2cbaf9b810aef9390d3b2ff73a39d refs/pull/2600/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2601/head\n004151fdb7869d6b103c64e96e6a32bc0687431714e9 refs/pull/2602/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2603/head\n004172b478255f01f30aa5b2b33bc697a6216782ce29 refs/pull/2604/head\n00413456c65b5bf8a455ab4be528c932e94e2dbc51b8 refs/pull/2605/head\n00417689490034d5ace342ad180af664d0561dda7fc5 refs/pull/2606/head\n00418f747d48cb81b208e2dd43b2e2399a4e4c9fca16 refs/pull/2607/head\n0041ba522680e8bbf2e06e9844b268ff00147bf5ccc8 refs/pull/2608/head\n0041afaf0c24c73a4ced47abc729116f4e304056d85c refs/pull/2609/head\n00403f9aaf1d6ee0724fb367b8d9badfc153290050a8 refs/pull/261/head\n004125403ed7b2fa54cabe42ad36770b7ded16b17231 refs/pull/2610/head\n004148f4740a642291a6616f29fdbd1e2189449ed149 refs/pull/2611/head\n00419edcc47a2c33ee7c596ee623a34bef3085185446 refs/pull/2612/head\n0041a3fa21166c461cf3c98eef1ccb3ab98bebf0beff refs/pull/2613/head\n0041a23c8b65649e38e68f0c7ac2bf3d583fa278d905 refs/pull/2614/head\n00412a74d38a8465b18f667c93df4a4b9a1688a1621f refs/pull/2615/head\n00411fdcc1587c4182efa6bd6f1a82bd78ed8ab891ad refs/pull/2616/head\n00417581fe8599f89d5424cb3e5fdb82b9d883feff9d refs/pull/2617/head\n004134ea656dc06e0f8b84c07ce9ea716e6227f08597 refs/pull/2618/head\n00411575bd7dec8eac4d7c46a8c60ee1ea8d043909a2 refs/pull/2619/head\n004046c557ad9391746796a00d6ef2ed0d33fa6b46d2 refs/pull/262/head\n00411b72b4bf65fd05a51f3ae039dcf4f4f80c00e85e refs/pull/2620/head\n0041e4cdb49d5a0ec98f63c2d0f5892ae88b76eb131b refs/pull/2621/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2622/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2623/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2624/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2625/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2626/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2627/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2628/head\n004118a33ffec8ba556b2aeca01c69a3f9c1dfbeb194 refs/pull/2629/head\n00403c45a5fa82837ed3281394cf1b141a4565dd3701 refs/pull/263/head\n00412ad5c547030d92c823cf05d33473e5d569896028 refs/pull/2630/head\n004182bcd8510836ce15256951440f1866f56129dee5 refs/pull/2631/head\n0041664c3eacea7aa135815a12b75bc17c1502bc2731 refs/pull/2632/head\n004116630e020ff2f40074480b5e188176ee1f7dbfbc refs/pull/2633/head\n0041afdbef0c49fac58984098b1563bec4b1c94c45e8 refs/pull/2634/head\n0041bfddf1d4a056551c40ccfe9454c0b3cd9693af41 refs/pull/2635/head\n004165e80f09f0a79b12df6beac44abf245151bbfefc refs/pull/2636/head\n004161b021f24ad4fbe29130c0672742a4c1efd31609 refs/pull/2638/head\n00418b76634b8701e90cebb880fc7f8a1faa4e6b46c0 refs/pull/2639/head\n0040b079da3c6af9b1a139db5127457315034abcbbc3 refs/pull/264/head\n0041d2ee349b9919d416260e3717338f9b65e6443b85 refs/pull/2640/head\n0041c86b29e940e3f800f5760f11d41380537a88b131 refs/pull/2641/head\n0041cc703e4f8dbb366e8270a20c0cd91cd53d913a52 refs/pull/2642/head\n0041f3c5d59acfd34527284183af35c2bd0a7b422d8f refs/pull/2644/head\n0041ded67731c579c99af1671e569bbe7e889a633f44 refs/pull/2645/head\n0041b7278b4edf0acfbfd7a0b9230de099e37aad8611 refs/pull/2648/head\n004149585781890214a9f0a08b1dc952bc3cc3d7fd49 refs/pull/2649/head\n0040ecee40da8a3cfd90ad43cd05f7a3f0f47e67a826 refs/pull/265/head\n00418614cbd27dc368dc265816d801ed18e5d00fb760 refs/pull/2650/head\n00415af5d38da5724640f85bc05ba64a1e0bc347e5d7 refs/pull/2651/head\n004115f4b9fd2edee8bb6767003ef2afb27d86ff4c3b refs/pull/2652/head\n0041a1642fb968ee8ba6edd65113bd68e3f396500dae refs/pull/2653/head\n00410d08a2838b3e4741764cdc02cd20fbc164ae60f1 refs/pull/2654/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2655/head\n0041e43f1e2f16a91260fa2b263e8b968a3f535f62f2 refs/pull/2656/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2657/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2658/head\n0041d43b986486789b27ca98202659606351a803cdca refs/pull/2659/head\n0040a1fe55ab948b3507af0e547366e964e6076c0a43 refs/pull/266/head\n0041a5f399a9d582eccb24df4de26c083b04e572e3e8 refs/pull/2660/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2661/head\n00416e4ce8879df1a46060aa7b3a0c05ec18c372ee52 refs/pull/2662/head\n0041db7b359f0e8b3255b22f4cbd1b7ca78685ed381d refs/pull/2663/head\n0041c3ed87788b6021c49c8fc2b9d576b6366537c69a refs/pull/2664/head\n0041f4836610cc31a8a09c823c3fc84599ddb4210720 refs/pull/2665/head\n0041430da5fcc21bc97a11a462c7936f84bfdd1e7d97 refs/pull/2667/head\n0041115f6caf9f2265b6a258ec491d02f6c0b39cffdd refs/pull/2668/head\n004156ed2ad272ee8c04c6be6c1200362aeae05292be refs/pull/2669/head\n00401dfff6435abe32ec18ea4343f41053924ec0bc06 refs/pull/267/head\n0041bc8a9dd8a47a6dcb322502560c6f5a1d65f8aa77 refs/pull/2671/head\n004165d911a77093f0e33f73cd261e754112d094dd1f refs/pull/2672/head\n0041a2521a301d632a896d24596519077bdcc684dba3 refs/pull/2673/head\n00415859aad095aaca071c336ec429c2321951364f87 refs/pull/2674/head\n00412ec5dda14f2593535a8865717ff7f9068737f777 refs/pull/2675/head\n0041775f379dba856e9969c8efd9d84a9c0b34685013 refs/pull/2676/head\n0041ae09e4dc91ab9aea20446af75b61a79092c3d30c refs/pull/2678/head\n0041b6d02fc3a46c7aa43a0ada56a4a05dcf1bff91e4 refs/pull/2679/head\n0040aa35755406731fadfb18212be848b77d5bc133d8 refs/pull/268/head\n0041b678f0620138174c1af1564c46d599ed454ce4c4 refs/pull/2681/head\n004146a6462fd1e901470278e3665d8553037e986977 refs/pull/2682/head\n0041014193bfca96310ed507387a25f064fbf0610cc8 refs/pull/2683/head\n0041847cf4f7afbf164129660be68a389152f32fdc92 refs/pull/2684/head\n00416088aab6a59dfec9d5a9a954dca42c9b3fdab2d8 refs/pull/2685/head\n0041cd156d88f9c8da9fe495b6819e27c8fa332d0ac4 refs/pull/2686/head\n00412d2f49510dbfe5dfc92660ae8278e5c9a26ee2e3 refs/pull/2687/head\n0041d9d09dc8c2a3a4a9eb07acadadb87a928de092e9 refs/pull/2688/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2689/head\n0040df8678d532946bc9d6d1ed59ef24767bba5bf003 refs/pull/269/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2690/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2691/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2692/head\n0041557627d2be80aa8f8337ae5c841c82daf29ad30d refs/pull/2693/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2694/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2695/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2696/head\n00418321be766309bdbdad52f1f91e367589c6be4660 refs/pull/2697/head\n004142cb69954753c00db29bd25f72d8aa21d9466ce5 refs/pull/2698/head\n00411cfde0f7f6ff199b73e233d1e72c7bf3dbf8f2cf refs/pull/2699/head\n003fd12b185990668acabd3be3e2818f5d3154548672 refs/pull/27/head\n0040c60a5854a5f6fd7d431afb69b5b663056a6c9122 refs/pull/270/head\n00414a81447cd5435c74ad91a0fb2d85ce437b82c1cf refs/pull/2700/head\n004110865d01d184ebe325dc402150d8f0b500e22c35 refs/pull/2701/head\n004138262d8cd70f7bfcd9785e9e4be9ee7a075f85b7 refs/pull/2702/head\n0041c37b8f9d2000409e91259278670aa787e5a010b3 refs/pull/2703/head\n00419edeffa512ae514612ff4cf14bb271d03688c0f2 refs/pull/2705/head\n0041c5a80c1bb0cc6865bcc440a6ddce92af5cfd9561 refs/pull/2706/head\n0041b341add1cf7df7dc61b86e99d55b4e14ce2b1f3e refs/pull/2707/head\n00418af58f720a0a05c5fc147052a62899ac2ac0a425 refs/pull/2709/head\n0040cdfced31cbdbf455bdb87427fb458d6709f9df80 refs/pull/271/head\n0041887b5b2bbf1cc4a80cb5abd0c4af99551cd62da7 refs/pull/2710/head\n0041f9af70aa10c9580d624f687ffc071e66e6ae5218 refs/pull/2711/head\n00410c23b69f7b334ac6d4b75644d645ec0a24e72544 refs/pull/2712/head\n004130ed0c4b02a46a20561a5b2123aa08fe1c6e5f8f refs/pull/2713/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2714/head\n00411a91edfa25502cbbba58f8c139744aaef93a4725 refs/pull/2715/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2716/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2717/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2718/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2719/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2720/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2721/head\n004132b09542271b6dc5961ccf6e653d1517fd6180e1 refs/pull/2722/head\n004108a0bb08a6972d4f70752cc6a1d293ae603f07f0 refs/pull/2723/head\n0041d94268f0484742f927ee73bebc05131f09cd37e0 refs/pull/2724/head\n00412c8d08e44698ffb03ae857730ab6b14486bcf0e0 refs/pull/2725/head\n0041ade73c7449073a28fd5bd36a1d48fc9a85d91f0c refs/pull/2726/head\n00411432ffa7f85e9d9b31acbee7f313291a1acf5c5f refs/pull/2727/head\n00414efb6e194aa53d31dd1a5ffcf90e8dc70c9fd31d refs/pull/2728/head\n004089be2b28d522855a7d56d0d6781c841e2d9fe8a4 refs/pull/273/head\n00414a4e64e2fe93ee38e495cb246582f7ba1ce19525 refs/pull/2730/head\n004151b9ae5241247e80b30d68e9b983a8df1ad9f44f refs/pull/2731/head\n0041fc986f627df1f299c03b248a549844df6bb84ac2 refs/pull/2732/head\n0041a05ca8039996626cd40db82aca293ed64a36c439 refs/pull/2734/head\n00417751fbeb2c3e466476dd9b194d8fee925fffdd64 refs/pull/2735/head\n004166968de6c82b4ee867d38d170b5f9d1df9ed93fc refs/pull/2736/head\n0041ef55bd3f7dcfac478506006f469e50f7f0e01268 refs/pull/2738/head\n004160b2751d13b6888d0cd4f2625642f72fcb6dfb13 refs/pull/2739/head\n00413592dc2989ba7b480c78195899aa3a15460c688e refs/pull/2740/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2741/head\n0041d54a91cf61f504a353002f78111cf1a42d5766cb refs/pull/2742/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2743/head\n0041a755ba68a1bf8e48b50e4b5c00a84cfb0b9cb4f1 refs/pull/2744/head\n0041d621f965c8650e6697f74839464a84329f52c460 refs/pull/2745/head\n00415f80f7bda1910871b33cc8568eed9b9e0a067abd refs/pull/2746/head\n004127f34058a675bdba5e5e9ff196293398e560ffed refs/pull/2747/head\n0041ec6a31f01d35bbaf086bcc2098cab5959c632479 refs/pull/2748/head\n00416e76f8d379609f9945377b7045ab308979f816d9 refs/pull/2749/head\n0040abaa66143b82ff64782f3d8e5a726fa3d8ea674d refs/pull/275/head\n0041f5d9e64f8c83fe518d93b584cbb099143745e362 refs/pull/2750/head\n0041c5c4e3f5856a61bef515aa5e0a69b72826f536e5 refs/pull/2751/head\n0041bd209b316901966059e16cc7985122db957e854a refs/pull/2752/head\n00414fb5b70400f425e9b7c52d397373b4563539edd0 refs/pull/2753/head\n0041d344dd1ac65befdb61c7016d1ec2e6b72d42fa0d refs/pull/2754/head\n004119a3f119197386ef948b52e3041356e01cd72455 refs/pull/2755/head\n0041a0816f94ab06d17c770334b5875808ae5dd20dd2 refs/pull/2756/head\n0041d360762d855688c45c934912f14e3e07945d3ced refs/pull/2757/head\n00411a596384bb4ccf7e7a241bd5d4540d98b65ae151 refs/pull/2758/head\n00412031ec5f09cac3612093578697973ec78df3ee7c refs/pull/2759/head\n00407acf9f795de84bc83c6176a6e0332453bbe51fa2 refs/pull/276/head\n00413517588333f1a378675690923792341d2b94f08b refs/pull/2760/head\n00411e29bdcf8ed23a4dc8f043a0963a773c056edd63 refs/pull/2761/head\n004159daa621cf5085f140f7513b12bf98611e8b5582 refs/pull/2762/head\n00412a625ab871036149179a92d70bcedf0a11fff820 refs/pull/2764/head\n0041aabdaa18934aa47b6a1a682d02cdf3fcb974debd refs/pull/2766/head\n0041f9a984e7c1b1faa582cde1ab72fe6e07286bf239 refs/pull/2767/head\n00419cd85f118c2603fd0524f0d9b8b78e265063faa1 refs/pull/2768/head\n004189d47a15013cfb60bfd200cf61c47b62d2de9d5e refs/pull/2769/head\n004104db79d2fc3294c78027967576ab0f886228ddf1 refs/pull/2770/head\n0041bf7e690cc30eb306ea66ea0a7f53eaf21afb2601 refs/pull/2771/head\n0041fd69d044571f9c6daec232fc59bdd9a8d5d4125c refs/pull/2772/head\n004156b14b7449f7e3514178108b5b688ed8797253df refs/pull/2773/head\n00413532e240bfa976ff538013367aa27338b8380921 refs/pull/2774/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2775/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2776/head\n0041d0ada1d23b06bcd3948b924cdf761a8390569550 refs/pull/2777/head\n0041516179e60ccee64e0eff2f405286d3c4513bc459 refs/pull/2778/head\n0041a8e35df702581892410de7d98a5bdf2e53c671f1 refs/pull/2779/head\n00409ef86c610ec21e3a398ed7d7d02ae9b2070d19d7 refs/pull/278/head\n0041efa432d9e9e19623caf79c4dd0b359f6ee0984f2 refs/pull/2780/head\n00417ebc50d417b25a285bbcdc8ba416c390aa0bede4 refs/pull/2781/head\n00418f936d8ca8889845c1a1f3e468388b60b5384ded refs/pull/2782/head\n0041fffef8ed543bec1e79e2f1e3e668c2ad3f7aa1b1 refs/pull/2783/head\n00410c3412a5938c0af7c15a20d95e2b39e65f037a11 refs/pull/2784/head\n004126676724a4bc1eaca84139c94ece9cb77fe9224a refs/pull/2785/head\n00410efae10947090c7e2ba66ce048ee8933569fdfd1 refs/pull/2787/head\n0041eb8724b40c9693ce5cb7ba322c4dc917ec2b0166 refs/pull/2788/head\n0041c46c59fd46e2418d293f3c45575e0c1952c7ebe6 refs/pull/2789/head\n0040387db6d1376294aad267c4927a7abb44cf8c5a31 refs/pull/279/head\n004130f4ed16e3b290acecfd565720ebf92dfa5c69d3 refs/pull/2791/head\n00411b6820e13ffe15956e4973dcc16294c9b9ca9637 refs/pull/2792/head\n00418a10e02c2a94af79e599774ce224d022ad5c6b15 refs/pull/2794/head\n00411024b7d519a107554bc6a5b3c251af71cdd06b9b refs/pull/2796/head\n0041c9520de348b6bf3b70fb7f6db48d26503ed37c5b refs/pull/2797/head\n0041111952e89e593ebf05626dd8d8979745c7f81f79 refs/pull/2798/head\n00415467cccdc73e0dd78c1674d76854bce827bdee62 refs/pull/2799/head\n003ff487a58f5ca9cf47cc62624d6e74f38134172298 refs/pull/28/head\n00400f1e0091747295f93910650e5dc16de612fa20f7 refs/pull/280/head\n00419c1176adeff7fc3e6523c496d40242250e26719c refs/pull/2800/head\n004133a3087a7ea73bb06343884720a8f9f9c62dacae refs/pull/2801/head\n004113b27b8dfafcce495fbe3f919c2a286bd002982d refs/pull/2802/head\n004139de5c14157758242b12e2a1c73fd1bdbde80905 refs/pull/2804/head\n0041b4cb96c9ad88813e5705410a5bfe3b2d86ef0949 refs/pull/2805/head\n00415db28b0a667f51175fc6d808c004534d681e754d refs/pull/2806/head\n0041d748f3ee8c54e343b7bfabb9ea632b6d02a8c337 refs/pull/2807/head\n00414e8a542ed46dd0744ba94717980a42e6334a4c0a refs/pull/2808/head\n0041f9a76ad79b91979aa6ed8bbc9694104a7ae6cfd3 refs/pull/2809/head\n0041f49db036ec837a98011cb28e38804a4fdd57aed9 refs/pull/2810/head\n0041185aff83e2cea035f1f4c0c333eec954fa89d04a refs/pull/2811/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2812/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2813/head\n0041fd94f48443d79da98de552304653b908fe83e6ff refs/pull/2814/head\n004128fd0b9b9ea81ef284a99b149e5a69fb2f2c8e78 refs/pull/2815/head\n0041642bf0504d5dd0fd6160e7b508e546e37b27d905 refs/pull/2816/head\n004106c59993b4c84817b8b8c2a879cfcc5f3fcab8f4 refs/pull/2817/head\n004165dab2740390fae7815d53881b5c0bf6fa8eb583 refs/pull/2818/head\n0041d7956d5236877d7d2f1da49fe75dfd81059119da refs/pull/2819/head\n0040c88914a941222f07a6a29cd9ddfcd782d87ec1fc refs/pull/282/head\n00411cb455b505a3be35bd0696c41ff1ca5cbf113bd9 refs/pull/2821/head\n00418a57d72bc2f5d9182a56e4c882c44f51b994d627 refs/pull/2822/head\n00414dafa11d0222373c698b0ed2668a37112d491bcc refs/pull/2823/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2824/head\n00415dee54879ba73cd0c422fe0a7fc637a9cafa480e refs/pull/2825/head\n0041547568a2d0e54c919284b9a57ebafbd9cfca6a86 refs/pull/2826/head\n0041e0faf86c9025f64d5c083de17f0fcbaf8466cc0b refs/pull/2827/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2828/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2829/head\n0040857891acf88fd5e494c705e44f9721c73a6df2a6 refs/pull/283/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2830/head\n0041190bb1668ce2c7be361faa1a96626d4250f53bb8 refs/pull/2831/head\n0041dee7f03da3553448c024b4ff6ee96da427095779 refs/pull/2832/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2833/head\n00416faf3dd312ced029b468bc8b5bbb9ef12dd80cd4 refs/pull/2834/head\n0041476106a04b739c4a2d9f4106716d70e8c2205af8 refs/pull/2835/head\n00410c33cb5792dca5cffebfa2d9d9102cd51dbaa417 refs/pull/2836/head\n00417472807b8962255ea4eb7c8916c4b42e14872395 refs/pull/2837/head\n004119905886ae56bfffbc8027ce84ee5970e974503c refs/pull/2839/head\n0041c053afe6671014bd97cce4e5cb2189fe186e615d refs/pull/2840/head\n0041995f36545f3f9ce298b63235ab069bc915553ad3 refs/pull/2841/head\n0041611029f7c6bffc2b86c4e2a1fc3adba1dcb6c5ef refs/pull/2844/head\n004190ffe8e4fdf36ec73af89a4c91436c4ed5891b0f refs/pull/2845/head\n004180c8b887ac4cdd4094841524421b22da6b787757 refs/pull/2846/head\n0041c4775008293ae04c32d7c3a36e7ff69b6e6585c4 refs/pull/2847/head\n00417be76c68bf4172bec3b63c337c0d632105cd7dad refs/pull/2848/head\n00410bf3076cdf5cbf1b8d821346ccc8e36425af6447 refs/pull/2849/head\n00408fb04a0898abe7717137ec504546838abf6bdcc2 refs/pull/285/head\n00413dd6b289906a198f9cc4c554dd2d6ef75ad59b0a refs/pull/2850/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2851/head\n00418f8873ed698a9ea5322a04c707b034e5568bcc42 refs/pull/2852/head\n004119e2589154d7fbb20e089788154342e6735bd10a refs/pull/2853/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2854/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2855/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2856/head\n004167aabf6657e3b405f04ce576e39e3f303e4c66d3 refs/pull/2857/head\n004193a63ad748e1d6ff49af3c3f641a4ce09b1c4b0c refs/pull/2858/head\n0041f477c6940ea743f47e8cdb6ec14ba4d5c6f31838 refs/pull/2859/head\n0040ec88cf672778f0d8098070047e7050fd5821723b refs/pull/286/head\n004193d45871f40f122c1494b79931dd732891792064 refs/pull/2860/head\n0041add5751fd0bcd0f1e9ce7e1f414c786110915e14 refs/pull/2861/head\n00417d7c18855c6e7f1b88300c5d2cdeaf33f1cd0c2e refs/pull/2863/head\n0041e1d8affae17cacef6e7c1a01e901b9687538121a refs/pull/2864/head\n0041747e1da71770691f0100fb21f4a9efcd9575183e refs/pull/2865/head\n00413fd074245dcaaf739002d63e7c6a89f39d9bd1ff refs/pull/2866/head\n0041c3523af0d6087b244bae0fd6c6522edd441f011f refs/pull/2867/head\n0041ddcc982004944baa45c53ef7ca1d9bbd2404a40f refs/pull/2868/head\n0041404a259ae62f5ee0537a87a0ba418daff01b1998 refs/pull/2869/head\n0040a865ef6942833d38e5ca4c163e1008c9796eb285 refs/pull/287/head\n00416d2c55e7437107c19210aab82e8cb06479710d96 refs/pull/2870/head\n00418c5bff2b80e1dca212cf32b0541e1db6f439a5e8 refs/pull/2871/head\n0041ee42ed4e2f00d71a99e2e74e497db8b40efe6784 refs/pull/2872/head\n00418acbb8bb927c14c60b5edd34b3b2af09ce999fef refs/pull/2873/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2874/head\n00413f8c12ec2674220d32c8fe644a510fd712336443 refs/pull/2875/head\n0041207eeb6eba7de6c1bf8d6b06ab1d2463935d993c refs/pull/2876/head\n0041ac3717e5ad39d22f94b68123dadefb174cc1c9a8 refs/pull/2877/head\n0041392798ab0a782b71f84ed724a653c3a2ceb28144 refs/pull/2878/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2879/head\n004054a8f8b7ee2cf16d9090585c1aeaa651b1bc64fc refs/pull/288/head\n00418d3e1fe872525cffb71dc18a1baab4e5a437cb91 refs/pull/2880/head\n0041209183bea595553c350bd754b2aff1e42a411973 refs/pull/2881/head\n004182b2f5db7ea4dcc6523a5b3c758fd31f966d4840 refs/pull/2882/head\n0041d94c89dc945512ff6da6dffb573cddc5a82e244e refs/pull/2884/head\n0041a7a391b6b4ad844c44c0aede77ce2d85a00d9b35 refs/pull/2885/head\n004169e6819fea9cf083ab2b8d19a82544fe888e9d62 refs/pull/2886/head\n0041bb2739a9755747176cf784b8c5156d501d8222ea refs/pull/2887/head\n0041bf7c148b090eadb587832531d9bc1a11be06577d refs/pull/2888/head\n0041196dc83ce02e38d56abdc3e9d7fe696fe621b3a0 refs/pull/2889/head\n0040f6d68afa1708059c00684b5d0bd9eb9217661a66 refs/pull/289/head\n0041e9d2a7d9eb40c426e630610c08e2376c82b46278 refs/pull/2890/head\n00419d8f0b1efd8ca12e9a71d3f815cae43f13409a34 refs/pull/2891/head\n00419c7315590feb960dc4b0cb8e87184792d38ff7a0 refs/pull/2894/head\n0041a8a928fbe8ac833540e11569f44fb09c50410d54 refs/pull/2895/head\n0041cdde00b06c74be5bfbf88050cbec722f1462039b refs/pull/2896/head\n0041e51098f495561b99d18218b40c58d18b9e872832 refs/pull/2897/head\n0041b4992ee4dbf990acaec8fea6582fd215d1122921 refs/pull/2898/head\n004163d1a6dc14f8dc2090cac8341fcb3148195ddc75 refs/pull/2899/head\n003f58fce1249ceb5d65b7895d5cdafcdd7821772b6e refs/pull/29/head\n004139309f06c3d1e405348b53877af07335aaba4fab refs/pull/2900/head\n0041a92019df7a4cdc1d55077d35042ec51306378b54 refs/pull/2901/head\n0041d103b346ccb027171f710e21ab4cdfc42618412c refs/pull/2903/head\n0041e3f88cda1e69b25caf64458d0c836408c1d83323 refs/pull/2904/head\n0041a70352aec37960d0e9858a693594a6e2721f5313 refs/pull/2905/head\n0041eb6a90c12145cd3ec1195ed71f34ff63b557ce77 refs/pull/2906/head\n00413a11321134227846f1d78c3835a9237f99726257 refs/pull/2907/head\n0041166a833b8f4f2105c5263e0fbcbb41dd3752a00b refs/pull/2908/head\n0041d958d900898d7f5b612864e6b45751ff1a77b6d8 refs/pull/2909/head\n0040fc0d24e67117833b606a5648b3308f907d3cac34 refs/pull/291/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2910/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2911/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2912/head\n0041eb5efdcb6805ce3702f91409ecc208be8e3d5df7 refs/pull/2913/head\n004199db1b0e45b3889626c09c0386b16f2ccc0dbd4d refs/pull/2914/head\n0041ce58552dbbd96fa34e39f9c256f9c4f3e6417ca8 refs/pull/2915/head\n004139e378db7e1db7e8fbc3ba2dbcaf7e7eed22bcd1 refs/pull/2917/head\n0041d91a2f11298f61a16fdeda77e89811c621b2b56c refs/pull/2918/head\n004188f4b5c486f180f07ec36b145307069a83d71279 refs/pull/2919/head\n0040177b1e72d8561ae95a910e9666f3a446b2d607f2 refs/pull/292/head\n0041c5e9d21e5c514c0aff595aba357a8429d9dd9b81 refs/pull/2920/head\n0041e73a43793254c217f42f4d27ccde56e6e7b9dd62 refs/pull/2921/head\n0041c4151af86b4125532d999f72a5dc0f13c7feac60 refs/pull/2922/head\n0041a311476a5b3f9c34407bb5422ee93f7df236497d refs/pull/2925/head\n0041c73a96b6f7cfef4fd1e1bc00a6686956e58c3879 refs/pull/2926/head\n00418a4f90c0240285aa3638be184a6092b50c49659e refs/pull/2927/head\n00419fd44d4217395b540fda630c64c1e84ff1c532bc refs/pull/2928/head\n00414cc85a0e3d02f0d830721518f6fc02349e71f08a refs/pull/2929/head\n00403504293dbeb6a169d9c51279ee0c9fbbb4dfa58f refs/pull/293/head\n00415234c08ce941b082223c6b7eb15d4e3beb3898e2 refs/pull/2931/head\n0041fe1da8c674e09238c0c12fba310535de7b95dfd1 refs/pull/2932/head\n00412ac962cd4b4bb269bd863fe9b43f0ed894e1eb4c refs/pull/2933/head\n00417ad72d8ae97bae7adfed81b8db0cbffb45ff81c6 refs/pull/2934/head\n004118901307dd712f3d8ebf67544c34626b9c804fef refs/pull/2935/head\n0041838166bbf80143eea1206fc5f06ea0b2ca862d97 refs/pull/2936/head\n0041827912336c7a42090a005dd0630d07fcc23dce01 refs/pull/2937/head\n00413a2b3f7b74d733f29e2d9e485c1a2c433811af9c refs/pull/2938/head\n00413eafc2591f35d5cdbadde5e223332b3c8449f17d refs/pull/2939/head\n0040a91db92ab68ef5abf3590a4c6c1156cb496070b2 refs/pull/294/head\n0041be92d5ced97ef304d5a71685ce704aee8f998376 refs/pull/2940/head\n0041f951db346b984af75f9158473884985dff74f525 refs/pull/2941/head\n0041c355aa304b31f81a1fca44c6c1561c568c761e18 refs/pull/2943/head\n00414fba1b172a8d5a2f68fc5cd6ca12a831c60b1288 refs/pull/2944/head\n00416f3de20c9009f0276b5af06e5ddedf3f1608dad8 refs/pull/2945/head\n00419f1ff0f6391d3f8936872a44e48b686b97fe5ba4 refs/pull/2946/head\n00412599a7dad17dd6e74ee9452026fec56d1f34be11 refs/pull/2947/head\n00419ddcd6e9d446385730a6e688fedf98a689be02b9 refs/pull/2948/head\n00410b2408f69b00465c0d14a7bf4b07ebea2d45bc00 refs/pull/2949/head\n0040d04bf6c58d024bfcb395027a82eca6f95d812607 refs/pull/295/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2950/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2951/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2952/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2953/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2954/head\n004198478706e827d4da7fae302344ae4626f91e216a refs/pull/2955/head\n00412d97411101768867ad72b493c386b087a01f4796 refs/pull/2956/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2957/head\n004116f5297332724a0836ec2c4127680963d2171285 refs/pull/2958/head\n0041f4a55c33a40aef6a4d473a022ea238fa0cfdc6e8 refs/pull/2959/head\n0040ddafd0b526eea0b7449881ab78ccb06e260c2fff refs/pull/296/head\n00414cc577627d5ace18b86335424faa0938de06f09e refs/pull/2961/head\n00412d3a8921f5f49f140c892059bb33191d017d3b37 refs/pull/2962/head\n0041dd37c708309e16a05aba50aa5da35eb51db512ee refs/pull/2964/head\n0041f0be3bc7ccf9429cdc44aaa3b755d1eb1851c9f9 refs/pull/2965/head\n0041dfc0d77ffa7035fa30ac0af4fae7014f963d31c4 refs/pull/2967/head\n0040c6324c7def409e52d2a6a79e986fb1615f5677bc refs/pull/297/head\n0041dc8941aedde75407a3aa51a6c1c74480df6523f4 refs/pull/2970/head\n00410d937d9c75ad6efc0aa2bb61042774b161738f42 refs/pull/2971/head\n004189d5edb9a4181ae87c4903b25195657882bd8652 refs/pull/2973/head\n0041a8a4c03282d2c6a80d164305db1176f8cb4e0fcb refs/pull/2974/head\n0041b909d9da94007f878ce4ab9cd9c851ea8dce0e2d refs/pull/2975/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2976/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2977/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2978/head\n0041395fc6df1a91872baf88e570a89df4b5504d6ae7 refs/pull/2979/head\n0040e51c698385f0ce74c82bfe208d34eb74decd29bf refs/pull/298/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2980/head\n0041fad161ee283b537b0c97e577ae6d89bd371961dc refs/pull/2981/head\n0041ae21d3d15dd77c67430504f7d17fd2477187b397 refs/pull/2982/head\n00414b0249f355d436b42005a3be066bb0422f08af08 refs/pull/2983/head\n00417f0a8fab9dc5d51e07afdc57382825219cd53ac3 refs/pull/2984/head\n0041e5e3efb0e0a28772c2c31ecf3de5a04da09065df refs/pull/2986/head\n004126c0e0a21de2a2c3fc6dcb207347339e6ec3f18a refs/pull/2987/head\n0041c5d867b4caa4836692808d29b74a150d0f7c15b3 refs/pull/2988/head\n004130db1124016097a4d5f1736deb00c48b77410a24 refs/pull/2989/head\n0040eb68f82a1c3356d0ff11637395078512c96697e8 refs/pull/299/head\n004119a07de57a21994b6f1478a8d2410517ad829e1f refs/pull/2990/head\n004167f77272c080407d5a2e01de41af55b59d15d782 refs/pull/2991/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2992/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2993/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2994/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/2995/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/2996/head\n004189007174d4749c0b3343f199e57ae195ff29e6e0 refs/pull/2997/head\n00411645cf0d67d85a94839e05fff2ffc161595db433 refs/pull/2998/head\n0041c30e305ff7f5908e389912f53aa49ee5403e5da4 refs/pull/2999/head\n003ef0cdbde101164b659a1c59b6b400472820703130 refs/pull/3/head\n003f3ff993226b672f16415168f26e670785954c0c48 refs/pull/30/head\n00403ef1b3d7d647af747b2a9e03f17773dddf5f4db4 refs/pull/300/head\n004146c427606410f135353b204dd06affe01c89b7ad refs/pull/3000/head\n0041c6a6b896cf2869a9bfd0dc6b52efbe0e505b4391 refs/pull/3001/head\n00415cb1ddffb06ca75562c641d3f28a5df1a791d5db refs/pull/3003/head\n004168cb24921d8a037f8157f1a503da88d61aceada9 refs/pull/3007/head\n00418f1bdfebbee3aa1af953417f21e4253ba8ccfb74 refs/pull/3008/head\n004106f28780b388130601eee7ae3bc9d0b3d5940663 refs/pull/3009/head\n0040fea7633143d0293f5a61d8aaa49da07e048e6563 refs/pull/301/head\n0041cc697f8c8204edcfae938dd6caf10054f11a43b6 refs/pull/3010/head\n0041d2f0755b32b10522939c79b6e8b4bea541abfcde refs/pull/3011/head\n0041106ab5e40648e8387526abe3de1c8ba4b04e5ff3 refs/pull/3012/head\n00418856379bccf277f9c62464aa427fa0b2d6f67577 refs/pull/3013/head\n00412bdf7f948e06f331ef338ae7db1d57dbaab0e751 refs/pull/3014/head\n0041442efcf258b28b45d96e20a60affc5155c54bffb refs/pull/3015/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/3016/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3017/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3018/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3019/head\n004077abff46e64d91993f117bcde1ce703b89840763 refs/pull/302/head\n004191785546e68c04c40fb754c656227f5fa1c66438 refs/pull/3020/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3021/head\n0041354913c4dd35a4d63665f5b527cb599d5de135fb refs/pull/3022/head\n00419b1873f19a5d21f87641318295f02c13e50f07fd refs/pull/3023/head\n004185625d97bc9d4a09294d098f30425dc5c95ffc03 refs/pull/3024/head\n00410933c86891d7c6f5420e1c41d3b23e79b3744686 refs/pull/3025/head\n0041b47c661a24c4242b795822dd155bb69a2a3b1c82 refs/pull/3026/head\n0041f7e4eb57d8caf0663fe23bbfc9a5aaf9cc514655 refs/pull/3027/head\n004180eceaabfa2e1a4620c0512a85a7af6db45d583b refs/pull/3028/head\n0041c80da837eb9e1438e795105b35d4abf12d38a590 refs/pull/3029/head\n0040dc2df970334ca11c74290d169c70390a8eceaccf refs/pull/303/head\n0041a0860d3c5649616c707f5f0c977e17939245bd6a refs/pull/3030/head\n004113a552ea3fe1288a590f9b931d8371336f1d7b72 refs/pull/3031/head\n00410159e086cfb5918c03061a62d80e15297d6ed927 refs/pull/3032/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3033/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3034/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3035/head\n004107fa0d7988e84f3b3a34ac3dac399ba193887524 refs/pull/3036/head\n004100cb652efbe3060aaeffa5c4f3a7d31e66a0c231 refs/pull/3037/head\n00412b6b3b940c64c5517b64a7c03bb529866a421e10 refs/pull/3038/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3039/head\n0040fade621a7f723174ec82fae918578b84229d858b refs/pull/304/head\n0041f961c3c635c28cac218d79b63e95e01e5d8b810a refs/pull/3040/head\n0041a0214ffea0a79b8e1405df69d708d2dcff505ca9 refs/pull/3041/head\n0041b00ae6ad393dc643ede45c53649e5302e1fe8e20 refs/pull/3042/head\n0041dd25cd187b995f3e81cd26d138c783f52d2ac74b refs/pull/3043/head\n004182de78c184dafbfade5f45c2af21a6c14369b0b9 refs/pull/3044/head\n0041bd501aa0621037cd9004b2702a1e76de442e5965 refs/pull/3047/head\n00409d95fbb972ce3b32fa23eb739dfbd269aad20f3d refs/pull/305/head\n0041e882cd65728241b20bb5017316c286dfcb00dfa9 refs/pull/3050/head\n0041914aac4b7d550541f1b9cbfc7fd9374bb5feb497 refs/pull/3053/head\n004108f216bd6e902609d9aa84f30a50bc6c3bdc3c06 refs/pull/3057/head\n00417286d58bb1c5582b1add8d32d1696d6c8947d093 refs/pull/3058/head\n004132f4c488f7dffa308f82df5827a165e400a5c0c7 refs/pull/3059/head\n0041a5db19432ad9c33ea0d970dbdcd1d431b0e766c3 refs/pull/3060/head\n0041177357fc096b77dba00e31d85d3d3f31e96fe49e refs/pull/3062/head\n0041ab5adc598eaa84daa237eddff158db70bce13f78 refs/pull/3064/head\n00417df290ce8f2f3cf36a6058b7ee72350973fe8f83 refs/pull/3065/head\n00413549c650ccc399f36264c7b1276eb1254f33fa98 refs/pull/3066/head\n00419e4e3ab71e51de615b75393c67b741f316e9e752 refs/pull/3067/head\n0041fa1a05258fcedbc38ad9456165ff83c1cb8f97d4 refs/pull/3068/head\n0041397c82d0de51dd9ad7be2caf64c90bdccffa2023 refs/pull/3069/head\n0040f25a65409dfa4ea967d1b1a7d134da5013287dbc refs/pull/307/head\n004150bac02853af6b495043453ef4c7a50e2931fd64 refs/pull/3070/head\n004109feb895a36ac0927a24e94c297ed03f79b899fa refs/pull/3071/head\n0041ac0931b70d8680b25d430009007e1d9f0970a082 refs/pull/3072/head\n0041d0e784b90d1f359fee5ee6bf20689d6858d3161f refs/pull/3073/head\n0041807a02caee95fba47c7818bdd81030a60ca6ac20 refs/pull/3074/head\n004164711b7a7947fe8f441cbf6bd04b82da41128ff2 refs/pull/3075/head\n004158dd885ff2de27511b331c3bb7e892fc67998935 refs/pull/3076/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3077/head\n00414bc4dc9bb7cd85b5665f08454664843921f196fb refs/pull/3078/head\n0041ea8f0f79cb8433d5456fd82b8c7599ff82cac75b refs/pull/3079/head\n004073411ce4dd3994d9dfe6597388de7781b803e056 refs/pull/308/head\n00413805c23b7f29a1ec1710359c4f1d1e6df31c7ba2 refs/pull/3080/head\n0041925ca8a475d5650662ce8908458863e6b658d6b4 refs/pull/3081/head\n004100c3478e13944f99a154dca4ef7aa289f97fdc19 refs/pull/3083/head\n004158fa551ee7d146fd25770ed5734553f664912794 refs/pull/3084/head\n0041dd4a9fba9528b3cf0f22103d590ae6804ac8ad4e refs/pull/3085/head\n0041c1a75222f07f11b881558cb5ae85db705a13afa6 refs/pull/3088/head\n0041fc3357d173e441a822781fc46288b787cddf8dee refs/pull/3089/head\n0040e3e35a898a1e3a1106095f4094c748e635c54e5c refs/pull/309/head\n004101d7427d06d0aa5aa4795321ce1d9a796a8f72e9 refs/pull/3090/head\n0041f2a910f11286b1fc1781afd9e31eead170e172bd refs/pull/3091/head\n00415c0f8bf021cb2768cbcf264a04229a02cb562e6f refs/pull/3092/head\n004133dd2316429de872f26aa1a3f70db605e636489b refs/pull/3093/head\n00414a943449ddac590474233c569576074bbd67a59e refs/pull/3094/head\n00410cc43c1500774d5ae34950adc14a86a1a50a949a refs/pull/3095/head\n0041222ea10609bc06a812aba8463bc3cbf52d509285 refs/pull/3096/head\n0041c9149607f53d653b6d6869d66d202f915c2082e7 refs/pull/3099/head\n003f03d5ede47071e352bd5c48c69b4156324c71a038 refs/pull/31/head\n00401769ea723a9fb250a7118164ab2effb91e1c3461 refs/pull/310/head\n0041b78711a5ee79bbd7998de91aad6dc1295e22f62e refs/pull/3100/head\n0041ecf58a0c6459d9f245525ab2c253af0a9b6a83ce refs/pull/3101/head\n00412e4e4d113a2fd913d7d304985cf9ccb8b576c766 refs/pull/3102/head\n00418e86f1ef7b8cb02e3ea4a1cccd25144efb99048d refs/pull/3103/head\n00414fc6b776cdf924caf51e2e953108fac00ccf42b6 refs/pull/3104/head\n0041c6a1fbe65b831bf87b3246b1175bf02b2f810bc9 refs/pull/3105/head\n0041630dfc9cc184569e9ebdb67f290c75dae6f9603b refs/pull/3106/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3107/head\n0041f6d4c8fceab5b87f3fef22019f55339a73beb04f refs/pull/3108/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3109/head\n004017d50a8045e6ab6452e1da82f9c2ee2895bcf12c refs/pull/311/head\n0041bf09b2abf49a4f3e2e6602bcaa946962a18047f7 refs/pull/3110/head\n0041c1e468882a3f011e83172b67f225f99315494009 refs/pull/3111/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3112/head\n00415473e50a8182ce99947ff83ce1de10ee3c333fdf refs/pull/3113/head\n0041e103a9d6731021989cbf6d7eb67a196ce58e3837 refs/pull/3114/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3115/head\n0041e564df2a7bd69ce2cb4ac1b501944286e8071b2c refs/pull/3116/head\n00417694475144ef82b5ceca67d9dea29b9b0e2c616b refs/pull/3117/head\n0041782321d204ce8b7a44192878b95272398387cd44 refs/pull/3118/head\n0040188650c8960ee4afdfbc466178bf680e360e74a0 refs/pull/312/head\n00411af0d27a4fe1110f3e723c502227cadeba76d7e9 refs/pull/3120/head\n0041c5f312da17dfa2ef648c188947d0e802b0a0bc5e refs/pull/3121/head\n004170e933c33ad5df01e4cfd13c1f1d638afbfcef60 refs/pull/3122/head\n004123b294193aff6eb042da70f98f0d82fc7ab15f96 refs/pull/3123/head\n00411a8f3cff55c5ef37d9259044a32169b4b2bae1bd refs/pull/3124/head\n0041fcdb11e4df6ea8c0689e5da738599987ccec55b4 refs/pull/3127/head\n00411caa240d65c4dc07de4e1f0260b5aac50aade9f4 refs/pull/3128/head\n00414c34c0b48625de98d87cecd1df9dd2c780d172cf refs/pull/3129/head\n004022094a80c98a2a8e1eed141c4424a82681dcc2ba refs/pull/313/head\n004125119e4da3eb317aa14f22d36e5405bf47801726 refs/pull/3130/head\n0041039259cd1ef4ea16e732e740ff1c4a6938c58964 refs/pull/3131/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3132/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3133/head\n0041527572a2cea9f0e08f0334e74b30db2c741efe12 refs/pull/3134/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3135/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3136/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3137/head\n00413d1aa3e23a2146765bc94d0c9c1056005582eb3b refs/pull/3138/head\n004164f98fedba4b5a2d668dd3942d46d895b64a5713 refs/pull/3139/head\n0040d6aad74d8aca422749b3a63a359460431e624f2f refs/pull/314/head\n00417dd22afa840436ad016a08f9f2588dcf13b7b44e refs/pull/3140/head\n0041f3bc32e8b6482819431640f7ea46152581d804c0 refs/pull/3142/head\n00413f87112df4042dd8a06c27f1c25a14f803a61912 refs/pull/3143/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3144/head\n004157c03567f1b892b18e88bddf1e1166cacfcc123b refs/pull/3145/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3146/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3147/head\n0041c755c5203224f23cbb319b1749783af14f31537d refs/pull/3148/head\n0041b65f27f9e85fd6b0a16a499edd5ba5db3548d7ab refs/pull/3149/head\n00419ceeedd79a55533bbac0e9f6938ff6b1fd1c6114 refs/pull/3150/head\n0041bb1cb86a28fd776afe65757647eb41e2cd14d12b refs/pull/3151/head\n00416c93f87696ee00891b0146ea6f3be8dd53659a6a refs/pull/3152/head\n00413bd8359e38f1c5c33f590ca406dfc1bebc816cb9 refs/pull/3153/head\n0041cd8185fb4a44ed1280f3bcf571279fd40a45494e refs/pull/3154/head\n00411f3639f5dc1f19a3b130079d2aded178820bb80a refs/pull/3157/head\n004193743e8e7ca91fc3f0be3cf5ebd3ee4bb1a16772 refs/pull/3159/head\n00402a2b2599c2ebcf9032b67da26bc4d1816b6315d1 refs/pull/316/head\n0041d8db9e7af6d9b52bdf5b79edc8fe9e27ae7b67a2 refs/pull/3162/head\n00413860c5f8a5afe8107deaa7b6d3e75584441d70af refs/pull/3163/head\n0041a5e1d3c04d2c5df7e6a025c115a86cea71d320fd refs/pull/3164/head\n00421725324530ba9a0a185405ae4f5c4c018f3937db refs/pull/3164/merge\n0041301b76f411c0f8a7245584224a593eb62dc38ead refs/pull/3167/head\n0041f1baa53e91449c83f5a9b39f57bb88ee791a9bb9 refs/pull/3169/head\n0040512f4a594dd01c11dffeb7f3a01f6ee2910e2446 refs/pull/317/head\n00411d75f8cca72cbc4656e4633a5da804d5b8e06e63 refs/pull/3170/head\n00410425c1abacd948dfd9f783f3bc7d1050698cfbab refs/pull/3171/head\n00418897b145798040832c08b182684dd7e9da8ea28f refs/pull/3172/head\n00413870193fe93ad63bb05d4bef5c49845cd2e8be97 refs/pull/3175/head\n004132fa682339d2e337e0a5dd822383329279a6e081 refs/pull/3176/head\n0041d974f9aa07335c498eb3b694024fca4143b15745 refs/pull/3177/head\n0041da97fddd86caf5f4211ff98fea9b79ea16ebb269 refs/pull/3178/head\n00413e5cf953d7d95a1032558f7592844646c1f23282 refs/pull/3179/head\n004115a638b3e5fa3f855c20160fda14eed496fd6a04 refs/pull/3180/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3181/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3182/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3183/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3184/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3185/head\n0041c1cbe6c7da136974a98477bce101eefb7537f08d refs/pull/3186/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3187/head\n0041b0bcc9c9bdd03cdc12018ab04c3bc3189bcb9356 refs/pull/3188/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3189/head\n0041f7576fa840f9fb516a3b7cc04871c1cdbbfcb67b refs/pull/3190/head\n004138c5c17bba807d3cb7fc4172d1729858cac2653e refs/pull/3191/head\n0041caa52c27598fce1d44a2aed4776f509fe601ff50 refs/pull/3192/head\n00412771f72491c813726d134f78bb187d83f529bc87 refs/pull/3193/head\n0041cbb17a81efc093c3ce6889392e84c6692ac54528 refs/pull/3194/head\n0041881b2f0fcba03a8ead11b10a8448db8e9bd9b941 refs/pull/3196/head\n0041c5245cacd191db3a78975f42525953338a012e0d refs/pull/3197/head\n00417bc13b16667fc68a2ea49b2b0e2b6385fea8cfb5 refs/pull/3198/head\n0041e78ba918f91b4ec532200ee53f1da1659fa5019e refs/pull/3199/head\n003fd46883d4f6bd0de3fa54570e25592d65177a8099 refs/pull/32/head\n0040fcf3222be5f9d8cb2e4bc4789a8ed0ee7f8ecee9 refs/pull/320/head\n0041cfc7fd1e75225069ad5be39c99569b2cf3e5c1f6 refs/pull/3200/head\n0041b8fb33785570b28d9d0a64e1bc639538ad9cc050 refs/pull/3201/head\n004187cc5b2deda1e3a5fda04b5eac4790a056880df8 refs/pull/3202/head\n0041676388f4b2034b023016e2739abc4df86a5689e4 refs/pull/3203/head\n0041da4bd851cd5122ec79be4589066b448a692e51fd refs/pull/3205/head\n00410abfbb2eef7681534c04998e97874e955d576b02 refs/pull/3206/head\n004154e7db1008c998c907d4fa79bdb6efefe65f66c1 refs/pull/3207/head\n0041a8d34ae9a573564b7d0f766365af3de1871138a0 refs/pull/3208/head\n00411d546967bf9468228e4caf8f9918fc59637cea8d refs/pull/3209/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3210/head\n0041b2e2a887e2d9479c2dd947d1e586ee6281e35a91 refs/pull/3211/head\n00415db33ba706ebe24708bce88cc944539381844769 refs/pull/3212/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3213/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3214/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3215/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3216/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3217/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3218/head\n0041d68f6f85e95df5e66154c9354efae427d1f1114b refs/pull/3219/head\n00406c285e160a26c4f006c041d13fd6aa15143b3efe refs/pull/322/head\n0041c67e9e47b64228bba5bede93b3bc8c902365e327 refs/pull/3220/head\n00417a0b72b6d3aa7ecfc94b6ca5c4e43683ad5c42c6 refs/pull/3221/head\n0041a724b82a564701bc4b95821a2f04d36257bf14ab refs/pull/3222/head\n0041f3cc09810b6210e0bdfb4f96c81de2aee8939dee refs/pull/3223/head\n0041feb0ad7c5e6e7b550b125dbfd844a6c62918bed7 refs/pull/3224/head\n0041737b75a44263778aa0254a283c6db7a481629b1f refs/pull/3225/head\n00412c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/pull/3226/head\n00410df532eda1cabd74d7117ed65ba361bf85e9d263 refs/pull/3227/head\n0041436a2e9f9931e797729ec45b13edbb507682526d refs/pull/3228/head\n0041fef018091ec9da5147c7da86c75a4d1af44e21c5 refs/pull/3229/head\n0040d0db8c21ce1b0544a59d3b7b5cbd6aa8bd34a46b refs/pull/323/head\n004171410a54a301ff26d732e7ad4bb4ddff8e564f65 refs/pull/3230/head\n004111775b9a66c24572472b9bf58a7471441cf90482 refs/pull/3231/head\n0041c61acf8038b754fa81c6d0376ff29ea861d91b3d refs/pull/3232/head\n00418b5f88169a1a3476b6eeff3eda03c7f9ec66c17b refs/pull/3233/head\n00414a5591f70bb35c6553d449e7d835881a7e623eb1 refs/pull/3234/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3235/head\n0041af460dd7e6b20eff0011b9eab1f60be9c8355e02 refs/pull/3236/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3237/head\n00416ec64a705e1ea95bf760714bc867be48ee1db93a refs/pull/3238/head\n0041ad6fcfae08211757c8b36d14fdacfe54131f9bcb refs/pull/3239/head\n00403dfa0a0b07889e25c08af41775e6c8edaa3df783 refs/pull/324/head\n0041d27aa3dd1a6c7e66c35ea28acf12819be3cb8d30 refs/pull/3240/head\n00410883a7dfc9425531c544cfa19d8bf7aef21679ad refs/pull/3241/head\n0041f09b7a2d5f0b6cf75d93c73dcc0623ccdd11081d refs/pull/3242/head\n0041cb5ec97318f4e2e71218c8092e796601615660e6 refs/pull/3243/head\n0041c0ab597150b894af31fa84b1ef95135b4dc4387f refs/pull/3244/head\n004134c9f03e1f35d94f37be30c1d551a4721eca6639 refs/pull/3246/head\n0041625bbb79540f688d991c9c17cdc61edcf326d238 refs/pull/3247/head\n00419b4db2f8ffd00b1ce51475978c989d65c4ebbdf4 refs/pull/3248/head\n0041cfc81ae68582be96f901b432b88c715885adf462 refs/pull/3249/head\n00400138593116226511e9fdcfd6eac0830600bc74c9 refs/pull/325/head\n004190ebcbd10d637bc1c41b31ac0b1395f3b18817dc refs/pull/3250/head\n004177dc069ce11a0f4613631b8cac4c0e08287f63db refs/pull/3251/head\n0041be5df1340fe1e722ed96bc1c8d2143f8aa72037f refs/pull/3252/head\n00414d9b3d231594bb3a12d149e0acfe9d052fff0457 refs/pull/3253/head\n00411baf5b1f4e6199d36fd7b6c59d58c638c94227e6 refs/pull/3254/head\n0041dd784206b936de3fb626f985a3c2b913ce4206f4 refs/pull/3255/head\n00412fe04363a8e5ef40c220a24c394c32d14adc57b7 refs/pull/3256/head\n00414def6adce8d6e0dfea61f97f2d2ef30c9519c0f5 refs/pull/3257/head\n0041e78313ca42db27b5c006f09b0f0759b85ea8e24b refs/pull/3258/head\n00411486fe15bcc610f171233cc9583d391588e29ca4 refs/pull/3259/head\n00402a83855d83f6b56f76e63113ed2cc5a82ff7fe15 refs/pull/326/head\n0041cc6198702dc46b2be7751a57aa99b04a574814c2 refs/pull/3260/head\n004112c052a038893bc0929e123f0374241fde5cfea1 refs/pull/3261/head\n0041fa7b9e1dad8947edbe6d4454ea2e75c4e91fe775 refs/pull/3262/head\n0041f2ec4d1c728596f42f5a4df1c482752049b418e3 refs/pull/3264/head\n0041ec50b949ac70d8cc72d648af3d2d6393ad95c3c5 refs/pull/3265/head\n00419aa3fba23fb804cde1e65a1b45fd9f319b3977bc refs/pull/3266/head\n0041eb0dd3c5254fd3880fde0e229659f83907b69ae5 refs/pull/3267/head\n0041738ea0ba90d957d0db64b31048ef6f568cfdd387 refs/pull/3268/head\n00417fc5c0a44b0a2594a637765e3b6439f42c875cf2 refs/pull/3269/head\n004042df6533086ebd31dc513f98362ae1b5d227f9f9 refs/pull/327/head\n004126c131d22b50920b39747af79b6479584caf72f5 refs/pull/3270/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3271/head\n0041678fdd47a634f2c65477b9d8db3919cbd6d8baf5 refs/pull/3272/head\n00416ae5d89cd751708da6774342451710b2102f123f refs/pull/3273/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3274/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3275/head\n0041ef5dac2e2660257c90bfb99b1666624ca783288c refs/pull/3276/head\n004100c1ea1992b1272e41648c5d3ffd46d7f078857b refs/pull/3277/head\n00416dd49087b012e7be82fd3c8722976418cbfabe3a refs/pull/3278/head\n0041305e49c61c765c2814662251e615f96c5bcafbf2 refs/pull/3279/head\n0040bc268eb837250fcb91b113b00f86e0546948b971 refs/pull/328/head\n0041f6897c6fb08e2323e3638b86f7f2453ef7dbdc6b refs/pull/3280/head\n004174f122d6052b7b032e69fe9e37247805b2f1f98b refs/pull/3282/head\n0041308704455f5588ff6c780473875a8636a4e7c7a4 refs/pull/3283/head\n00415e0b2423a0b63fd975d40b255dba2a3ee4804d81 refs/pull/3284/head\n0041fd5e607cb9690a658a89fa4554af258e87ccc38e refs/pull/3285/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3286/head\n0041fb862020d928db7bc4e7c80542154ac4671adf14 refs/pull/3287/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3288/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3289/head\n00409a48ac5465f8ac146f2f3838751b9ff39813568c refs/pull/329/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3290/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3291/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3292/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3293/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3294/head\n004119cb466c0cecb33148aa4eb85570bbd896f0c561 refs/pull/3295/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3296/head\n00411b4ea72e09c0bdb92268c7c75c83b686f947b44a refs/pull/3297/head\n0041fad80248eead0ece21b65c060b7e2848943a5e83 refs/pull/3298/head\n0041d4f0d0ee18cd3a3096a60fd4d43b2336d54bf9c2 refs/pull/3299/head\n00403319fb852d36a0ab98729c8024b8abb8ad08f9be refs/pull/330/head\n00410887c622c076680ee77b94c85c56adbbc439b4e7 refs/pull/3300/head\n004163ba7a9e5a1fd4edfa3b19ac9126eab8279851a2 refs/pull/3301/head\n0041c1fb24440a335ef5d06026d52d9e32b23fc453a6 refs/pull/3302/head\n0041cc6a9946247228c4cee1c08702170f3bf5975846 refs/pull/3303/head\n004140ba224a80e301b396de4aad5b60ab053c149940 refs/pull/3306/head\n00414be1679a9401902c1c6983b95f9b8e439d4a34a8 refs/pull/3307/head\n0041531550e76261d5d68bcbbd14b137e1e10d638c9f refs/pull/3308/head\n0041b60a9a4a1368a55a089161ba073516dde4badc5f refs/pull/3309/head\n004052d3516888f1fde9300fd46ef43c0d35fbdc94f8 refs/pull/331/head\n00415ab57c181a2ff7e50bd569c25829b195d2d11298 refs/pull/3310/head\n004157f3141854c7612cd83ec2b67240b1f669310091 refs/pull/3312/head\n0041230e26b3580c46d5ff761f3172eaccca329d1464 refs/pull/3313/head\n0041a3509d4d1770f70757f11e3c8630b8be58c70024 refs/pull/3314/head\n004129dfbdbdce446cb5a85436f7acbd60d72109dba0 refs/pull/3315/head\n0041b17b1537a266a62983c1217c2bb300a3a6ff021b refs/pull/3316/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3317/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3318/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3319/head\n0040f70db31210bb0973824c06b471a699710c676157 refs/pull/332/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3320/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3321/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3322/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3323/head\n0041b34f6c1b69b1b43d8ad39d084c1cd4fdb61a237a refs/pull/3324/head\n0041e27fa0a3451e233334432f70f0862c58bec109ec refs/pull/3325/head\n004182ce5375e0fbdbdaf6dc82753c3c539ac19d2b38 refs/pull/3326/head\n00415be6dc574b3ae8dc190997146b02668e88eb53e9 refs/pull/3328/head\n00419fb7c07ed5c0aa172fe959e1045400ef89943394 refs/pull/3329/head\n00403e3f7cd474fcd238df1e8a1d85d67a1ab0a52684 refs/pull/333/head\n00410ee8e72bb1e9daf79c6423250853894c8ec3a3e8 refs/pull/3332/head\n00415d04ae469c2c8671d527f9953c4c3e3f1b1db4b9 refs/pull/3333/head\n0041b64830c986d329f3229a4092dc7c7c57d1c22b10 refs/pull/3334/head\n004116faa736187a33564513a188a23ac8ffd0642341 refs/pull/3335/head\n0041ce073adbe1be0dbd75fa58909fd3fb111384a4e9 refs/pull/3336/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3337/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3338/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3339/head\n00401876aad84e6175712758ce6d3db16d7b16ed4eb2 refs/pull/334/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3340/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3341/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3342/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3343/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3344/head\n0041e8baef2938dc547bc29b1629d8026c54f4400a36 refs/pull/3345/head\n0041da1202cebc3b5e248ef67e030e6ab86c458c15c9 refs/pull/3346/head\n004102068f861a1ecb6465e26d91a41e48db32f4f074 refs/pull/3349/head\n0040ffe7d673a10f32d59f1cbb96cbe7465c7b5dfe7d refs/pull/335/head\n0041d3c6c60331c3a2acaccbf200e13784b08786b731 refs/pull/3351/head\n0041100704081c253ff7dcfd7b2757f482d3c70c72be refs/pull/3352/head\n0041e5779f2d437ac22e3e52ead7cdb581ebbaf7545e refs/pull/3354/head\n004163330e4e304834f693186981a5320bfe33f6739b refs/pull/3356/head\n00413a25e5b19cc279ce63271224009a48df52f652d1 refs/pull/3358/head\n0041e26969b39d4e86f7ad3fdf337c5bcb79781d855c refs/pull/3359/head\n0040d2e8a62db572f1e557b85563c10e6468397124e1 refs/pull/336/head\n004145846bcef976b27a6c735ded57520b949143cdbc refs/pull/3360/head\n00410e404bb88ae07b8c0bf36a824ad77e49cd79686d refs/pull/3361/head\n00413592d6a7330432e0eb681ff7f30afe267a4f890e refs/pull/3362/head\n0041329aa16ea10c1bb6841a74f2cb7b7977e3ce3dc0 refs/pull/3363/head\n0041537fc5544be92798c1e691bd7c47b2ae5f49e56e refs/pull/3364/head\n0041fbdd56ed156b1e0fc2b12bc9656575ea63b1c826 refs/pull/3366/head\n0041290d0c8d317e2360ac229e70904433c3a3b62e55 refs/pull/3367/head\n00411e9702f14c9d0ddec4d3fe5dcd39bcacf995ead3 refs/pull/3368/head\n004158dd084bec475b82ca7de636ded933e5f26cd0c7 refs/pull/3369/head\n004001277a6291d8d62f4c8fc93e0bd9781987134261 refs/pull/337/head\n00414713dc20935765b3e4235da556ac6417a94b662b refs/pull/3370/head\n00414fc268c46bf699c0a5712870d826499deeed5e38 refs/pull/3371/head\n0041b339ba208c34d4b2ad57e1c22de799c5e6a3746c refs/pull/3372/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3373/head\n0041cb34e3ba48b46fe73b811c05592ce59d5dabf829 refs/pull/3374/head\n00416bbdc88faff9256f7f674f46502c4c4a133f5574 refs/pull/3375/head\n00411f72669b91743bfbfead637ce673ce0c3fa66bb2 refs/pull/3376/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3377/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3378/head\n0041f1097bd38cdc05ad8227ddd3437765c63cde96fa refs/pull/3379/head\n004052f9b1bf33426893d0bc0fdb1b80e02af46f2753 refs/pull/338/head\n0041c96e1f87f3149962b092855ff074173acb7249fd refs/pull/3380/head\n0041f927345a158fa12008caf386921fd97832ab9e2b refs/pull/3381/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3382/head\n00417d58425a9d987d51e44fd45ab6f80cf1891e1a34 refs/pull/3384/head\n004150c773d60e1fd6c361ada093264c327ea4460ee2 refs/pull/3386/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3387/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3388/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3389/head\n00402b3d0479f0eac553ca8005279c7a6a23a8591853 refs/pull/339/head\n0041ed19906a0de53afca8303ab7610c890f9cdf357a refs/pull/3390/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3391/head\n0041f5640385ee6e8caeb0c743e2adfa6cac33850f79 refs/pull/3392/head\n0041d4217e327b35257c89261a25e3dc237f608bec87 refs/pull/3393/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3394/head\n0041e5fcdc6f1692e4c2c746bc12fd1222f88b0144d2 refs/pull/3395/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3396/head\n00415d08b9c9306f10bd548b1c1adfaa182a3ff91ef0 refs/pull/3399/head\n003f23cc473894a09cc2c4051db85fd3a42e4eac77fe refs/pull/34/head\n0040d6c78da57ab21135f81cb5a2b6656dd9309c327a refs/pull/340/head\n00413fde29aad92d9e308929583d45ad89d0d113c5e4 refs/pull/3401/head\n0041da781cab9cd31cb88ba88bc42fc81f3259d8b20a refs/pull/3402/head\n0041d4a3e93868dd08f590b554d696c8887e45c5f3c9 refs/pull/3403/head\n0041728e7e4ce79ebeed7f96d7738e87edb2978c7b03 refs/pull/3404/head\n0041f4c90854fc692525def222597608a2cc2fdc24f1 refs/pull/3405/head\n0041c021ffa6e9a963843d4ba8509124bfbe0d3dfc66 refs/pull/3406/head\n0041eaf6dd8b3583effa6d2fde0ccb5bd73f07dbb2c7 refs/pull/3407/head\n00411f3bb435119dd7e20a349f90c3cf5371f13eff81 refs/pull/3408/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3409/head\n00401afb1ca14319673e1ea619cefe2f4490ad21ac2e refs/pull/341/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3410/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3411/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3412/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3413/head\n0041e5d49e3fa3a9a948e0ad1f1b86d0c9e188f74020 refs/pull/3414/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3415/head\n00412dcd8bb1efb80b4c7ae9087b304847addde347d3 refs/pull/3416/head\n00419d4287fb3ce00b76e352720ff79f96e9b52b0708 refs/pull/3417/head\n0041bcd17fd0a8bd707f36948c48aa7c9103c04fb9ab refs/pull/3418/head\n0041a49ee397c390dd0882b887c23e12e233bc6cc7cc refs/pull/3419/head\n0040019042773f8f8bfaf2fb18422f6e01caac79b615 refs/pull/342/head\n004141bd9e9857fa71d63de0692007c6ca2255b3aabf refs/pull/3421/head\n0041871f3556ce532a963d5a86f8fd0b232adc25dae0 refs/pull/3422/head\n0041e4505bd80502cad6ba66aafd519606f9472196e0 refs/pull/3423/head\n0041cce01256cfbf0f3f395b8d96d484494197196d5d refs/pull/3424/head\n0041dcc3c7ccbf0a1fbb9817a198b4cdc9d62b09168d refs/pull/3425/head\n0041caa0afee00abbc05076d0f52783b7a34310f6f12 refs/pull/3427/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3428/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3429/head\n004083dd27f424abf0abba6a8264fa6924a41c15ec49 refs/pull/343/head\n00417a83a2b622d023fe05a727df97a4b527dbff8eca refs/pull/3430/head\n0041a7701505c0a51e6de0f4c78c1a02f663a727fe28 refs/pull/3432/head\n0041981b8c04c17f2a63d951df37194bdf4817177e6e refs/pull/3433/head\n0042ecb4e7fe091516c36a2eaeec3b1841667ea7dd03 refs/pull/3433/merge\n0041d4390a458767271df36f6ab90c99af6e363268c4 refs/pull/3434/head\n0041bc032d76b0adff18fed5e058e1eef6de3c82286a refs/pull/3435/head\n0041ae608171cee97acbc163c19693951a231a2d4e06 refs/pull/3436/head\n00414e9f15e375eb118fbc7456f1ce75b7fdea960384 refs/pull/3437/head\n0041e79e37c87d28e153d552dfbc93f73111d0a18bc9 refs/pull/3438/head\n0041923f59093eced8ddc607c93353be0014ee88a6ff refs/pull/3439/head\n0040c3ccd3c6e811b6d15026b5cf1853a2f663001a60 refs/pull/344/head\n0041598407dc758dc60d193726d7db5399c4719fd952 refs/pull/3440/head\n00413741e5c083341432c3899d00d93ef84cf7f469de refs/pull/3441/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3442/head\n004154ef244af43a6711eb694021cb81efd25862a095 refs/pull/3443/head\n00417734f6dd3b776a0698e7b32256ca39f57d3078c1 refs/pull/3444/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3445/head\n00416627b1e2424961a3a38ba09e56f1887d7e5b993a refs/pull/3446/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3447/head\n00417f6aa8bf0de045b86129d4228ddfc99bd290af7f refs/pull/3448/head\n004175ebcd5084088481a531a5fa2cb4c0f8c4399942 refs/pull/3449/head\n004004d296631f37bc5d0e2c626fbd73f96427fdb0be refs/pull/345/head\n00416614652415913dd558a7f5e1760f6adac91058d1 refs/pull/3450/head\n0041a30243991efe7657d72e09cdefa0bca512a26a4b refs/pull/3455/head\n0041d613d3081e40ff0a2605553d6df587ed7750f26b refs/pull/3456/head\n00419202976cb63fe40fc20514a9c33f47096cbf4009 refs/pull/3457/head\n0041e1ec445951d86ecc1e953de48d0fbd89c35c351f refs/pull/3458/head\n0040987aa1508bf8d1de2f3dcf2fd010d87e126bb8db refs/pull/346/head\n0041abea6c5f85068528fa575eb4eb756b2ac0e8e92a refs/pull/3461/head\n0041e463b25713c5ada97bc7c09bbc644d8eb35926e9 refs/pull/3462/head\n00418f517991d1cb5e0b703a99e9f5f0356e96fd2b68 refs/pull/3464/head\n0041b341b5aa46fe4c33d29588397dd1bdee9d463b46 refs/pull/3465/head\n0041f44bd5c565c936007b9b937f27db82baedd64b9b refs/pull/3466/head\n004126fcc9f16b76b0925319f6554c6a6aef3b956cfd refs/pull/3467/head\n0041ad902ce2ae444857ba5af2a0575b4023e8694b64 refs/pull/3468/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3469/head\n00405450274ef3e558455c66ada108a0452e4843fdfc refs/pull/347/head\n00417c267cb058520f9d80c081ad44a4ce2864cd7019 refs/pull/3470/head\n00417b2fe16362dd063b59fac2c40d3f28948fbada9f refs/pull/3471/head\n004165252dfc054e98eadf8764745dfc034de989d49e refs/pull/3472/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3473/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3474/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3475/head\n0041cf1931c7276150ed36a4d8e11fd219a5cdc7b181 refs/pull/3476/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3477/head\n0041fc9be78fa0069be51b4cdc434bb06a02cc9a00ca refs/pull/3479/head\n0040bc92b86da455b69be1bd3916273645b337674ca2 refs/pull/348/head\n004138adfc481554517cb4adc7b370e3c231c33132eb refs/pull/3480/head\n004167cc7e37a710e3ea05a75374a506c04c87a89a34 refs/pull/3481/head\n0041603dcca4481fb9e1778f6e81ad048ae73320e30c refs/pull/3482/head\n00413e4197bb97686b43986c05d2e58481bf6280cff9 refs/pull/3483/head\n0041d5715a6a3be4943c0f09eeed95477e21546cf37c refs/pull/3484/head\n00412fc3db5c428f3c2ed1f1d53a6d32eb310ea7a469 refs/pull/3485/head\n0041eb8f7da07c8988a4685f699bc3ad3079b6e5fee6 refs/pull/3486/head\n0041f115d5d4d4655a1f132ea5b50dd2606e8698f8cf refs/pull/3487/head\n004152c3e0913ea564c9528adcd2e5bfb4fa84ba8556 refs/pull/3488/head\n00418c3c4edcb7e294421aba9759fdb033faeb61a5a0 refs/pull/3489/head\n0040df9c85159194003ea1f55d088052eeb60746823e refs/pull/349/head\n0041662b7d2a0f214e1da0510968fdf458c93d225809 refs/pull/3491/head\n004131420ee602fe6de115e4cf32b4dea4d20c37ef92 refs/pull/3493/head\n0041dbf993097c75276c397af40c80a17ab0a85750bf refs/pull/3494/head\n0041b0b0db1b990ace1dcd6a0775fcfe8c03e1c2e98b refs/pull/3495/head\n00419cf8a2f26e3bbf477b68032e0969d08bed9cdcdb refs/pull/3496/head\n0041a886341b602a3cc8278121ab40882b39cd94eb5f refs/pull/3497/head\n00413c0b52d09cb1dc44632bf9009ca51e1409066af0 refs/pull/3499/head\n003f9a6fd6cac6cf82aa4dccfdce615dfecbc76dd28a refs/pull/35/head\n00400454bf6ec1c4e9422765b5f3fbaaffdf15176979 refs/pull/350/head\n00419a6ce09da4d08d9eb8f59f0440c3758234d19e51 refs/pull/3500/head\n0041c546db9b641c145360de3e14ac12d48dbbb6581a refs/pull/3501/head\n00412dc4cfb9803f2aa927953e33bc1f40c3dab44156 refs/pull/3502/head\n00413a11c7356b0077c7c73c2143c05384cea89fae31 refs/pull/3503/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3504/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3505/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3506/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3507/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3508/head\n00419a567192f4142f72d8c0c9c0dfca059c314218d9 refs/pull/3509/head\n00400c699e9bf5b682c91f3bc11a35edf88d6667fa02 refs/pull/351/head\n0041a5c7c58c9c454b44c22238ef04ee3d620487d3c0 refs/pull/3510/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3511/head\n00414100e0af9f9bb6b8326aaa8c56b8ca4217bb5671 refs/pull/3512/head\n00417d9e4c951de40d4d2f4ca5056942b16672711b54 refs/pull/3516/head\n004067eef7352339ed2507d2bac858c9812ac4e046a4 refs/pull/352/head\n004112d4ccf73cafb1c17904c65fc54926d4fc0d2667 refs/pull/3520/head\n0041facd4046a0d547318694a68d1998be9df873a9b8 refs/pull/3524/head\n0041347fc8d5550965e6fbddbe63fd2c6a6af006d694 refs/pull/3526/head\n0041558f36467459b7a7e59af1069dd04a95d628a024 refs/pull/3527/head\n0040cf0c8367e746b2a1ae1a42202ebf11694a5a604e refs/pull/353/head\n00415d50028a97df7729d9a73878bab12a732a4b5438 refs/pull/3531/head\n0041412a32512c3b2888af0d26d8ac77fbedba6b738c refs/pull/3532/head\n0041726d98b08d7796dac5bedd4b9d34202fb4164ae4 refs/pull/3533/head\n0041434abc547f8f844b62c9abea8636adf414ce99b7 refs/pull/3534/head\n00418ec89391bdd972f05bf74daea3bfc5938a8fb2a2 refs/pull/3535/head\n00412aaae4a493ffd4d0af0bb0969c1c876a630e7bdd refs/pull/3536/head\n004126ff86f1c04993f6c36bcfc92edbeee015e189fa refs/pull/3537/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3538/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3539/head\n0040d4e3672671d311513e0efa9afe6c323a661a1e03 refs/pull/354/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3540/head\n00410230d614aea5f85d892fee98dc11ccb917837244 refs/pull/3541/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3542/head\n00411e9b862819e5a01ab7a65c5863c19adc0fbb06a6 refs/pull/3543/head\n0041535d8e0f999d37b0410574258f07fbf1a24d648e refs/pull/3544/head\n004196a3b49d5bbd0b7a6fa8e2b8a7febee215df2bb6 refs/pull/3545/head\n0041ba980971b276451472973c91d8a3599f06d2a790 refs/pull/3546/head\n00414e1501dade292549592c52d957e4fce0b164f5f7 refs/pull/3548/head\n004111556ddafbc6008583a1f421910dae8ad99c6c64 refs/pull/3549/head\n0040600ed28b6bf05e4800518d4299ba993a3de128d5 refs/pull/355/head\n0041fbf37fba1a9c93fa1cde4816d4c2e83de789764e refs/pull/3552/head\n004152880b04b157686ac203e6d1e05553c1554de526 refs/pull/3554/head\n0041a3ff783b82a73d9e590c130ee585935e3c47839c refs/pull/3556/head\n0041f8649f35c73ef8b68b8395b084419c74b1ec13d6 refs/pull/3558/head\n0041ddcd86bcc2937a1ed44480188e648d748253ff7d refs/pull/3559/head\n0040cf1cbc2950c195040601ce36ddb4314e94288711 refs/pull/356/head\n0041b4fe9a998fdb7e9682ea2a112d46b1f7fd1d83b7 refs/pull/3560/head\n004122ae49a865e503352cf40255938e94fc55ca1264 refs/pull/3561/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3562/head\n00411a9e9ab5f77adfee6997e35a99578456af18adff refs/pull/3563/head\n00419f411fd43ad96bcea3b00c2b6b09ba133ad970d6 refs/pull/3564/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3565/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3566/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3567/head\n004137c352279ece36826e0bf6cb7fe474144dbbd03d refs/pull/3568/head\n0041b01ff6cf71861f5b59b406b3b083a6a81cd5b05b refs/pull/3569/head\n004009a3d6def73568852ef4ae16bc83b5dc08bec29a refs/pull/357/head\n00412ef434da9cae143bbd52efd063c07c2365bee95a refs/pull/3570/head\n0041041b7702963bc077080c447a6b2156f5ad54761e refs/pull/3572/head\n0041f32b12df3a4a65424fe1d7656304bdc0d765d0ef refs/pull/3574/head\n0041e60e677527cd031f039fdd2d77859ae42d855f1f refs/pull/3575/head\n00412efaa9bc8c6e2a97f5bfbb231018d4c0f7d32c18 refs/pull/3576/head\n0041f91a700e72fa0ff87d505a5b0d742a32e2bfc666 refs/pull/3577/head\n0041e4969f8cbaef6577d8fdf43bb4cc80bce1dd7fb9 refs/pull/3578/head\n0041dbaa13a50bd43863dfaeaa1a2ba21528abb5d89f refs/pull/3579/head\n0040e933914511cafc5fdfb749ea7b07816fc675706c refs/pull/358/head\n0041aeece857dc9f9b33d18cd90c5c213dfaecb82698 refs/pull/3580/head\n0041e6d34f9b331c5297642565e4ec463d6a001da9f1 refs/pull/3581/head\n00418c84de22a8cdb55b693ecc13bdda3b4b6b384140 refs/pull/3583/head\n0042fbafce5f62a8036ecdeedca5a681856c08c688d4 refs/pull/3583/merge\n004165211f2f09f58fa9453af0005c7ed8d4e43bb67a refs/pull/3584/head\n0041d099eb9a6608a5d0d2aec966f32c467e68604c66 refs/pull/3585/head\n004134589f34e009247cb2eb2d249e57d78a59deaed6 refs/pull/3586/head\n004106a28e3bc4144959441b736e5bb62eacb1f817b1 refs/pull/3587/head\n0040b0d113e1de8d5dea0dad2ba0b112b7a6d7b749e8 refs/pull/359/head\n0041aa9e18358bf55c15e614ebb8ee2741a2f9996048 refs/pull/3590/head\n00414d8f4319eaf3a2634e5aab04ac0ccb706cac6f8a refs/pull/3591/head\n0041cb57473c8df0ff9684a1d88085273ccc71b32be0 refs/pull/3592/head\n0041ed2f8d86aeb2b877ad6e7c5d991a666540212ddf refs/pull/3593/head\n0041139c04ef65a5f7448c76b9ebc2020800570220d3 refs/pull/3594/head\n0041c1aacde188e95d078d945071c89474260f0864dd refs/pull/3595/head\n004116d1ab16fa4d100b903533361c6a34ceb5f4391e refs/pull/3596/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3597/head\n00411c4fe17a54b97737f3671ecaf56bb077f88b9239 refs/pull/3598/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3599/head\n003f33e3ad75825b38db5a4425df6d65e40410a5e9ca refs/pull/36/head\n0040e8f98b0a685b0579043ce7d7c161cf483b71f995 refs/pull/360/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3600/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3601/head\n004117c7f0f8ab0de4cfe8b087a4af2304b9ce86f62a refs/pull/3602/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3603/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3604/head\n00413439bbfaab349c59b0854a9cdcbfb23f46c9ed52 refs/pull/3605/head\n0041d540c1269b98ecede35df9fde66096ba1d9d3072 refs/pull/3606/head\n004133e45f96dcca0bf4978db082599db2a416eb0137 refs/pull/3607/head\n0041a2334377c31a3b8048cb2285ad86649be1acc4be refs/pull/3608/head\n0042764dbf278c5e1ef03e1523eb4f08cb357dfd448a refs/pull/3608/merge\n00413fdf840caa2a15aa1b02ad63edbe37f14c25ad04 refs/pull/3609/head\n00422129cffd63247752f1f8994b7b183789f1af0c4b refs/pull/3609/merge\n0040af341b4f22bbdac128322f76b48e07c31dfdca46 refs/pull/361/head\n00410d61d36d5457e56436939c609274a27d6a3d5939 refs/pull/3610/head\n0041c57018380ecb4a8c65a50a43146b1cd220d14140 refs/pull/3612/head\n0041ee07b5614e1ba16680914490340de597c10bab91 refs/pull/3614/head\n0042a8d6cee1b85df1170f472cefcb2fc8bbf432cf71 refs/pull/3614/merge\n00410e5894deb3711d7ae9d9e1efd62fb3fe718cb00a refs/pull/3615/head\n00416dcc20d5233ea2bdbf24637ab5a3d25e80bf6dcd refs/pull/3616/head\n00411fef6d381571733672f63d65bf555b9801186548 refs/pull/3617/head\n004182e4be020c85e0982b63537075ce4d44d0475dd6 refs/pull/3618/head\n0041356b68503584e33daed2cab24178a20c4d4cbf3a refs/pull/3619/head\n00406a801c7d85ede5c49881e53c45286e78dbf216bf refs/pull/362/head\n00410b26184e36cd97559ecefeffa099217136cf494f refs/pull/3620/head\n004164d1e66d5ad7e27d0fd38c49e0487e5b029b9639 refs/pull/3621/head\n0041758d6def407fe5258665f3b621081171459f9371 refs/pull/3622/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3623/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3624/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3625/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3626/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3627/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3628/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3629/head\n004064cf6dd540ef6a175e26345cde4fc09f98458764 refs/pull/363/head\n00410b3780de33f8385775e0cb2b24a45bbac5824b12 refs/pull/3630/head\n00415e7f9c92ccfed0ca84a87dc0fd1dd8bf962a81b8 refs/pull/3631/head\n004137b8262530715fc69aca96b4ebc28b61abd2fb42 refs/pull/3635/head\n00429885dc7f4a7042dab24fafa8ff7abe447eecb75b refs/pull/3635/merge\n0041020ded73f3db4649327aeda027020a2e37640356 refs/pull/3636/head\n0041378236c3105538906a4258009a87f9a14684f304 refs/pull/3637/head\n004135f6f9c3529b0a143bd93b9ee2d1e8258c2c066a refs/pull/3638/head\n0042cdde83a010d4963e40f0de1b041ee134e6b925f9 refs/pull/3638/merge\n0040cb0bde56c77838a7582b88c6d5e9150d2964e1d6 refs/pull/364/head\n00404b9a948506a09bcb0af3f4a7d34320fcc41cc23b refs/pull/365/head\n00404ebe16b3e179d11c7345ab7e0b5ec7aa262ba9cf refs/pull/366/head\n00400f88251f8707640498665ed86b3493288ea44b86 refs/pull/367/head\n0040daec0467ba809add8287e6e561b207570dfdef9d refs/pull/368/head\n00407e2c699fd73e14c445f1302ff24bed0a2556868c refs/pull/369/head\n003ff8f6f58700a542f06d0796bf7d26e6f39718d2d2 refs/pull/37/head\n00403c7cf0dd53c10c2fe43373d5d9e8e09ae9bd3038 refs/pull/370/head\n0040ffcf21f54d8b285eb6aeda1824f3ce90d85fbb3b refs/pull/371/head\n0040ad8ecd3b9bee94d51170382b695f0c778a497bfc refs/pull/372/head\n0040a54c525503c36c4120616451e4083bc0214b4ee2 refs/pull/373/head\n00400c42f8686a7cbd215a8f24817d7de1355df77b1c refs/pull/374/head\n00404b20f8036316a58b61a3eea85afea53cb054bd66 refs/pull/375/head\n0040df92eca6a3262981465ab6e7c100e740a9a5a613 refs/pull/376/head\n0040f5dc20b5d4e4fdf4699840a9bd90ccb6b51542d1 refs/pull/377/head\n0040125473272cfe458154e9eb689d9263df394d3086 refs/pull/378/head\n0040df8ab034cb5eaddea0415ae9953a6165ecc60549 refs/pull/379/head\n003fa72f79c5064d756b3b1883dda9744549657b333f refs/pull/38/head\n00403d26b83e2b4423e91f1878eebb5320712e41cce0 refs/pull/383/head\n0040b5b94b399d091ef348eea50af8166632d491f2e4 refs/pull/384/head\n0040f29693a20e63c75d1185ffe3852d5e05200365f9 refs/pull/385/head\n0040b7ef5869c878e43bba7533aa9b40988445c0bb5e refs/pull/386/head\n0040623fd65be4741d54bca9d3b919ffa22c5e18d295 refs/pull/388/head\n004020137d68b3d90677ec1a5792fadd7a0b9d5be665 refs/pull/389/head\n003f804148197b274c6129ab2c7d996daa456364c57f refs/pull/39/head\n0040e2654e0a480285bbba9ae0c65f7a48ef813f8d80 refs/pull/390/head\n004057cd1a4180b32268105209699409ee15fd23348d refs/pull/391/head\n00400c0a26a82752908ec2b45b00e052b166bcad1a6e refs/pull/392/head\n00408defc8e7c76da637ab8b3315c82a8f3896d187f6 refs/pull/393/head\n0040e0077f650f0dddd7ceb4160447770c45d0e5972a refs/pull/394/head\n0040a7dca0c16eada7c7f722cc9c91e1fed92a2b318a refs/pull/396/head\n004084445945ed7de7198d9a0066daa0f51438edf947 refs/pull/397/head\n00400844c04becceef49c59f882e131067a946ab732e refs/pull/398/head\n004022f5a39f26c94f295594503e826e7cf470762221 refs/pull/399/head\n003e4a137256b3d2dbbb000152d745bf176d70147e00 refs/pull/4/head\n003f7a793712e2ac08d1a47dd61e24238bf0ffca6063 refs/pull/40/head\n004028e57c8bc46d1d8708ce9c9883be5d924ebbf10e refs/pull/400/head\n0040e485f81fe2dc95638871b436bc5c2169079f7ee1 refs/pull/401/head\n0040ed452dfb3fafc4bf83650096ed88ad57ec4fcbd7 refs/pull/402/head\n0040d0e471fe80170e85ca73a2e1ae9c836d769c2991 refs/pull/403/head\n0040eb8e38a0a9d69ed42989476d22aec692229b4104 refs/pull/404/head\n0040a5da7dc13ec7f46fa0f5e26ca0510c08f9a6f416 refs/pull/405/head\n004017c1e7ec2ae2c06dbc42942ba61098fb5d372c64 refs/pull/406/head\n00409343ab402ad2586f8624a7fb8faca6cedfd57cfe refs/pull/407/head\n00406d0f1c3a7895798088acf0a8a08495056298d244 refs/pull/409/head\n003f91651239dd6d4d47c8d4d8b78d6df7e9925fdddd refs/pull/41/head\n00404102a18a336fafe433d6b2857265e0f0d6b77863 refs/pull/415/head\n004081dd41292c226f014de149a0071296e116d61189 refs/pull/416/head\n00406c31da0bab542b41831b7a82a9e4d14761e820e3 refs/pull/417/head\n0040bc1b44e4879261c92d2b3fffdc9ab647d7c8a1d9 refs/pull/418/head\n004087c749f7431781e754adb61bc61c699fe5d7640d refs/pull/419/head\n003f7645ff6b03ffec78255994ef914a8961c0bb48ab refs/pull/42/head\n00406afc717169d3d59e8bbc2c1fc4cf01bbbc09f96e refs/pull/420/head\n00404831bc8b92e9aecbcd0f128f7e45796bb5f89ebd refs/pull/422/head\n004038871758f59c771bee03cce88b2c9cc99b76793b refs/pull/423/head\n0040cae5daee7deff4cffda76dedaaf1a653e2af3790 refs/pull/424/head\n004000ea2f01026b75a03df999dba8057a2c14ec0d0d refs/pull/425/head\n0040adac66c1741833f79a1a960a6932760ab694b1dd refs/pull/427/head\n0040478d6e2a10cfc44072a3aedba6e921442e155f2f refs/pull/428/head\n0040702b192740ea948214cbdbeb82d38f79405697b6 refs/pull/429/head\n00401652c745526d09ec28dd1bfc8062ddc82a04efa7 refs/pull/433/head\n004037102ca6da3d94dcbe61fd6f00bbcef7843e60fd refs/pull/434/head\n004033bad2b5d92dbfab547fb81ae3bb5e62baa91be8 refs/pull/435/head\n00405cf48a27f88c23526734f137d94195452d923dc2 refs/pull/436/head\n00403dea0ce596c3809f433d67bb2160a8a8af9e590f refs/pull/437/head\n0040e7b69136fd234a5ebaf9e047eb4365c59ad7461b refs/pull/438/head\n00406531bc4aec902c7245c0b5e6ed08f50fff8de7e0 refs/pull/439/head\n0040564ede75518c9e18b7de4b718827ccc62d32c2cd refs/pull/441/head\n0040214f1a3a0b831dae6140f1322d935ec18d1e69f3 refs/pull/442/head\n004031214408ca2213dbecc787791d6481eb8f98318d refs/pull/443/head\n004055e6503606850b8b972554070ac6e6f652744d13 refs/pull/444/head\n0040714567aa8531ac2d5be17d02dc07382c13d314b8 refs/pull/445/head\n0040b9b465c2b3eef979ace3aaf02a7a513e965432a0 refs/pull/447/head\n0040aa975625ea6c2a4c817af8f69ffd733db4782b48 refs/pull/449/head\n003f128c809bb6fca55127f0d89f87ab0b108fc9b036 refs/pull/45/head\n004021a5af031b8b38c19ddf2fba0b2f2623a0a44902 refs/pull/450/head\n004057438b74e79a243fc8337039df968a56a47e1e04 refs/pull/454/head\n0040a0e52ee79ef2775920ac85443863e30b1c1173a8 refs/pull/455/head\n00405cb5971d55f57b60684d9751fd452bc631916934 refs/pull/456/head\n0040ef8e6f6023dafafc83ccf7252ae15b056210fa65 refs/pull/457/head\n004081764eebc88f482aefba3bae569432a017c7e28c refs/pull/458/head\n00407a801651c73cfd940929030a727de719728ce93d refs/pull/459/head\n003f17f025d395375c10d8caf9405f854c3ac2a71029 refs/pull/46/head\n00408e8824a4cea0bbd102d2ecd74bd370b7ee1ea6e5 refs/pull/460/head\n00402ad8115ec45b86b82cc7cb16479c86d27fc2e3ac refs/pull/461/head\n0040645c7a8624ac1a4f14b458244f75cbd7c4e8042b refs/pull/462/head\n004043edd2608e6e8be14b6c71b0805e14736f5c0db2 refs/pull/463/head\n0040a8e02bc9f84fe22f8d5ef368f4bc52a3d51ccecf refs/pull/464/head\n004019e4617dd5586b7379228783a7dafeb3ad5cd6d9 refs/pull/469/head\n003f539bb6345b3c521756c3c68fe01fb5476107f4a5 refs/pull/47/head\n004015b2c3c4fb3212475bb30d16a595d3a48754572a refs/pull/470/head\n00407425fbb17e658c1bee3286023c1be47c1be1a268 refs/pull/475/head\n004009022111d128e5a2b92d7b332bba42b6c0cc9481 refs/pull/476/head\n0040c32943f2eb274bc1228e9e8b963ff23e493c8b06 refs/pull/477/head\n003f7942542b7dd62c0dcfef6d099ad55bd4001e223c refs/pull/48/head\n0040da63d307f10488113dfd52696218ba82e66888a0 refs/pull/480/head\n004008724c7dedf66677e18fb4e877c20b947a4dd280 refs/pull/481/head\n00406f75999d1287efdb029d48e401917387e8176f44 refs/pull/482/head\n004077e6725ade995f3645a437f8f7d01eead3d2c4dd refs/pull/483/head\n0040fa824a4cf86acfc9fc7635f2ca89f578b11a27ff refs/pull/487/head\n00402610a4e0aef51b5b50cfdf88ed6cef4937a1c4c0 refs/pull/489/head\n003f828d3229892fd337355b2856b1e143c9a4094b7b refs/pull/49/head\n00403e436f16bcc8ae364867d9856fa0313f7fe1d465 refs/pull/490/head\n0040898ab0d1f6a863e64cb2c3054352efb975d1d5c6 refs/pull/491/head\n00406afdc81c1d56e7f166b33bc9465bf5735ed07a00 refs/pull/493/head\n0040421a88cac4c87a4199cffc08e7691af1fd094eac refs/pull/494/head\n004026347349cd6a174d168045bd73247df1831fd8df refs/pull/496/head\n00400da1b610c614aaa0bfb1cfc1c10f41080ff9589f refs/pull/499/head\n003e3f49bf73cc697e83b998d15d4c24b3b2c3cb422f refs/pull/5/head\n003f7bc22854376474f99e947eaae5bf55356033295c refs/pull/50/head\n0040bf63148464b0f0fc6c22ad407eeeb9ed1a3fab37 refs/pull/500/head\n0040fbc22f7cdfc425d0366f44dfa63c289f44251fd4 refs/pull/503/head\n0040d44738e6a75cef1e7dc125c06ac945928141f490 refs/pull/504/head\n0040427e5971ce9cf4b05e1588d2066e2538a10f937e refs/pull/505/head\n0040738aa6298e56eae85a6cc212ea98b3ced3018cfe refs/pull/506/head\n0040dcbea96afc409df97fec6a03581268c818928c44 refs/pull/507/head\n0040ea0cd0b85f34b49b41121be2e1fc4d99cd62f95c refs/pull/509/head\n0040252460ebc4d89d1dd62a5e612219d8385649fbcf refs/pull/510/head\n0040a848819f56bd450742ce97cfde7a1b1c795f29c6 refs/pull/511/head\n004030158afd5f5c4314b954c222995dfbe5a0f6df6a refs/pull/512/head\n00406e075100aa09016ef384ec63c236244b32993e7d refs/pull/513/head\n0040ac40a5c9a4856ba3dc47533000c771557539cfe0 refs/pull/514/head\n004019e615fe83f329f04795aa8fd731691151bb114d refs/pull/515/head\n0040d1e6176b7bb89fa6c8ea59bdb94fce36dc20a3c6 refs/pull/516/head\n004023eb7dcaa2cf76e6c3187e95abe5962a5d984b17 refs/pull/517/head\n00408674ea9c7625795693f59620466dd3b91e1acf6c refs/pull/519/head\n003fa5aae997547532051254c3543fda04ecdd19e151 refs/pull/52/head\n0040fc6f375311fba3fb12d1cf6cbeaa642eafd5bac8 refs/pull/520/head\n0040ba7681ee4add1983739689110e7aaae5217bf1bd refs/pull/523/head\n004095935609f8ceaaec8d796ac895526680beae5a73 refs/pull/525/head\n00405f50e2b6afc3c5a97f24e6662359614b880cbeb9 refs/pull/526/head\n0040da429589631564615fa152d04ef8395c05bdc2a3 refs/pull/527/head\n0040a4ec96c9a96bef7a2f2318e1afdeb3e768373713 refs/pull/528/head\n003fd92b753039c86313e6163de3beec7e80e7715409 refs/pull/53/head\n0040b9cc4337fb099d98b1794d6245d2d16413be0843 refs/pull/530/head\n00409a5c0ba757500434d094996c10086fc1f137f26c refs/pull/531/head\n004026bf9a128ff64e0c41da850df451fefc9752b0cd refs/pull/533/head\n0040f641a629b070e48aaa81110f5ede97c6a4c5d74e refs/pull/534/head\n00407f0c4e8bbc6feb8cf54ca2aadf9ec681f79f031c refs/pull/535/head\n0040eeb08949f3b66a5988f2d22a7a09ffdc34c95765 refs/pull/536/head\n0040187e24c0df8e76a9d1221f295451cb5125d19b65 refs/pull/537/head\n004090263ab68bd9a54607c3e087b98b0e615e193c3b refs/pull/538/head\n0040b2f2ba8f1502c725d92632c35307b06223605d5d refs/pull/539/head\n003f4069e9ae46887eaa1ea25c0c41990d4a152aa790 refs/pull/54/head\n004008d0fe5bf8f16f7f129dd6b16c076680fa70bc47 refs/pull/540/head\n0040fa4afd68017c51fa9c8fcb234f7b089a6a6bbe16 refs/pull/541/head\n0040b643a0cb471374c0d4fe2c8bde45f7594e0f808b refs/pull/543/head\n0040fe94b87d5fcb2289f2c49ae49e248fdd8c49b335 refs/pull/544/head\n004022da7087587feb96d7a1d4f179661381d49bb32f refs/pull/547/head\n00400c72efdcae6f3e9587ec6a4b63d1946decbf5fc2 refs/pull/548/head\n0040192ed93b86cb77de447798c3ea78ec0722bc6b83 refs/pull/550/head\n0040db24d8b17db7af20dd8cfdcaedc9af2c78999bc1 refs/pull/551/head\n0040b47ce783b533222dd8cbb1afb6d9751e9b4b5d4a refs/pull/553/head\n0040c2af63cc54340534c6bcf4057d99889b20b47636 refs/pull/554/head\n0040532b5912133864cda5255ab022d4e5a66ad6d26c refs/pull/555/head\n00406ba69f1c26ff46164fba4b7099f3cd7c22ab6dbc refs/pull/556/head\n0040bbdec22161a3f6db0f3b40b8936f4a1adaaa58db refs/pull/557/head\n004056dfbe6300ff4b2063a57341a61f46c7de7a70a0 refs/pull/558/head\n00409ac3f6d893e9ad8f45ab12316f02c6a9ff55319d refs/pull/562/head\n0040ba38432d6c7074beb6eae72d03bdb567b0f713d2 refs/pull/563/head\n0040fc97f30299e11bd3fbafe60764a31731f1634c40 refs/pull/565/head\n00403b36449491233aa92160be5b68dbba193d9076bf refs/pull/566/head\n00404eba0eb5150020b0d69521348d7fbf3a2c44c1d2 refs/pull/568/head\n004049f841c25b74ae3cd508751de9dea5a95791bea5 refs/pull/569/head\n00405eb4c715b6984f702da1623dc8fe3f17345e562e refs/pull/570/head\n0040c8284062668d32d8be4012eb6b3571601d88dc9c refs/pull/571/head\n0040cca202c87decfd33298805d39f1e0ce5d7706e28 refs/pull/572/head\n00400b5104a4cd274324a53d87db88e022db0c0b72d4 refs/pull/574/head\n004020d761e3eb61a0321240c667837033944ef5133e refs/pull/577/head\n0040ffff07627e6003dc180c47795d625265e49eaa64 refs/pull/578/head\n004081ff890139cf9f07319e35b0ff3abadc38171de1 refs/pull/579/head\n0040dc64e918011198790c27d086755312368dca98f6 refs/pull/580/head\n00401765f3e868446b5c3e62da393a56dc09ffc72f49 refs/pull/581/head\n00409d58c1bc6e71cb1642b883bd4dbd0d835de240bf refs/pull/582/head\n0040ab7f0f423544887488e868ed5e550ff354490960 refs/pull/583/head\n004071853facb839d4b1238a354ea0a351d49c1e81ea refs/pull/584/head\n0040f13bae2c6d98b3e4030829b22fc821770ac72bc3 refs/pull/585/head\n004044d51ed2e50cb3e102563d166911eb7f6d2d9429 refs/pull/586/head\n004031c4c6e5672aaa3c0d93fd4bc31f7a104da8d5dd refs/pull/588/head\n00401acb581ec304067bd5f7cc1c714d8627407b62de refs/pull/589/head\n003ffe060d229baecb03798c6da631dfaa440c4363cb refs/pull/59/head\n0040811d28418a43713df02b95fcdea0918e87c27163 refs/pull/590/head\n0040f189aca712ffbce0d7b8f52a2148911ff40d8681 refs/pull/591/head\n0040dab21a93594bd2f83f32d10550737a26220a564f refs/pull/592/head\n0040dd3ec750f2ac746991fad465a44ece6515f30acb refs/pull/593/head\n0040e04698a4f079ef9e47894c77955af5c92b18ed46 refs/pull/594/head\n0040ccabdea034f6711c9da311a6100eca55b6542cbb refs/pull/595/head\n00409b069b5258813122ec05532e1746ac34e457e31e refs/pull/596/head\n004003320f72dba0bf9c4a344710f69b87a157afb22f refs/pull/597/head\n0040be3378dbd616d7b54340c247c1c2b40a5d2dc46b refs/pull/598/head\n0040bfc79659cddb9b15558d224e7adabfc1f8c61a0c refs/pull/599/head\n003ee8c29e0fd94218fe15baad313b095318ca35e4b4 refs/pull/6/head\n0040bae47748988b81977e7c9f971264bd982cfc42f3 refs/pull/600/head\n0040a1207a57be86aa5062efdbe7425f233d2c89e555 refs/pull/601/head\n0040a7a1e4f3ac65de68af18f37122ffd61d17ef68be refs/pull/602/head\n00401ab0afbcd184742884308a6e56a3e33644e54cba refs/pull/604/head\n0040f90a58db535e3ed8615765985e74cf47ce6bfc3c refs/pull/605/head\n0040fce4824468778452a19d54587b292d54fcdee132 refs/pull/606/head\n004086229944c849912189292564b8fae2dceee5e358 refs/pull/607/head\n0040a33c5dc6f1afd4da09eb21b05d8e6b320bcf82f7 refs/pull/608/head\n004005da03548ea276a0e83bd3e09be9834a8335d2b1 refs/pull/609/head\n0040ea7aaf0e0c534a82dfd0d96e5ea91071c244a418 refs/pull/610/head\n0040111df9afcb9f748713819c7c5abd425a97d694fb refs/pull/611/head\n0040988d98f421372ef5d57684393150141159a92940 refs/pull/612/head\n00406b1d7b73a159a3b20822d8fa4b5bc67c9c6471d7 refs/pull/613/head\n0040c4fdd9acb95155be5de54d9f6a658963ca98aeaa refs/pull/614/head\n0040f627af3bf490043922397ce368d3761ddd005506 refs/pull/615/head\n0040135ec824a06ae39f81f8e27c377934d1630166d0 refs/pull/616/head\n0040c4246fbc32020ea7fbbd1605fb2e7ecb7351017d refs/pull/617/head\n0040c79e8f2f0d0dbaccbc95fc72f44bbac936137161 refs/pull/618/head\n00409a6dccd8ac5f09b248d10dc6aa3207d7dcc4f3ab refs/pull/620/head\n0040c16148011d21776980eee0651f63b35d1029e8b4 refs/pull/622/head\n0040ffa7757e6d0de881a130dca0cde5d7963d231ae7 refs/pull/625/head\n004029c076ebeea8b61c3de6c63be1a80b5c36fccbd9 refs/pull/626/head\n0040a6721290f78a1a87be815aaab182427c03a6b6ba refs/pull/627/head\n0040104aa8d0df412d7fa6dd3291ee7c7cd3f9c454e3 refs/pull/628/head\n004083c3e81bc80124a7f6ffab24a6ad363d21ff6ef3 refs/pull/629/head\n00407e27c01c5dc170601315055d1de35e13f9f4fe83 refs/pull/630/head\n004029c1efe8e632d99bc52afb03ba2f8af232646ea4 refs/pull/631/head\n00407dedbb1d778ee611c89e6192a9a9169821ce152f refs/pull/632/head\n00404d2e49cf4853f694ce7623eaf7427b14a9fef8d4 refs/pull/635/head\n0040e7759b9ea0d675599b7821de4ab7fbdebff8ea28 refs/pull/638/head\n0040cce335b1462e95c6a2a34b161dcb90130672ebfc refs/pull/639/head\n0040d0ebfd4e634b2ea6ecb0ef9c24559f928f0899de refs/pull/640/head\n004080c904e3541ff766a774812e6cc07b403ea88f24 refs/pull/641/head\n0040423b62ab04c89caa94f4d2933e50c3559d0fb620 refs/pull/643/head\n004009fd6885d8fed342f58ab5bf86093bedc5f8f73d refs/pull/644/head\n0040fb069a91a9f15fda5a19280f0c99640d467a69ea refs/pull/645/head\n0040e2e6ba84e35ba11a1ea66708250d18520f28a5c7 refs/pull/646/head\n004094492d52f7afdda992c36b0a77f1b3101a45645d refs/pull/647/head\n0040e4d92d4402229891c543908362e34609d1063ea8 refs/pull/648/head\n0040ccd48f7c3bf61e9efcabf76584d188f022399c8a refs/pull/649/head\n003f9114a985e210798208c0a4b006e4ae78090a63dd refs/pull/65/head\n00400efc4177ecd181cab57ebb287ecc28e4fa518e1d refs/pull/650/head\n0040c327d3e2430cdcf6a884e191313eb3dc1b0790d0 refs/pull/651/head\n00405e8bbc98709e96d4cbd9c1b9121d43cce69c0cdf refs/pull/652/head\n004016fd8b268fd8b700dae919c7aa0cca6c949d1d8c refs/pull/653/head\n0040738b63e7bf26a636163f0ade319a0c03257e099f refs/pull/654/head\n0040057b7008fc6d9ab71b28105476c59b8349e2baf9 refs/pull/655/head\n00406ba57fb53fbc2c28bd544b434f2114d0d6419ff2 refs/pull/656/head\n0040431353cf9c9ebb1cfae7f12912175f4d4241f663 refs/pull/657/head\n00409c52bf7f8c21616ff861e18284551f15594d8646 refs/pull/658/head\n0040aa5fe2463c7ff352df80b5e96de7458720b12bec refs/pull/659/head\n003f15492d0d8857c7f1f37cbf4b2eeba4b5fafeed60 refs/pull/66/head\n00409e0f86f98534e7b417f07857bc68f4b7be17b985 refs/pull/660/head\n0040e6e452a01407ab6a5558ff813f40347dd055edbd refs/pull/665/head\n0040cd5983ed4e8ce93df2d7d12dc895f707af7f1bd0 refs/pull/666/head\n0040a66d42daf1fe9876503a21c306118c8b8a30c3e4 refs/pull/667/head\n0040f0ac8954bd8a844cf20dd045c152f807b6c75a92 refs/pull/669/head\n003ffbd97671c4f74a3573ca677cb23aa2e5dc2b730b refs/pull/67/head\n0040f0f09665d993f70d81676fa66f11c19a962278af refs/pull/670/head\n00402efdcc262931d42e199b84a0c4e4dfa8fe296a45 refs/pull/671/head\n0040ab07111508ec90a01e73ad064f5e2fcac05134ef refs/pull/672/head\n0040c525494e4a3caa74a0fb416e1db34d08a85febaf refs/pull/673/head\n004021dc91864b8ba42bdf81fce2494a2d2932d9feb5 refs/pull/674/head\n004034b5a1693bec061f8d13d8a5f7a954ff5af2a5af refs/pull/675/head\n00406fd8ad1d71226e646fc414647feff755eb9d58f6 refs/pull/676/head\n004091d9a183c2c0fdce20ed174b27526b469f82c7df refs/pull/677/head\n0040285d000103910ca736e72f43579e98cab05fc9a1 refs/pull/678/head\n00404fadd0e8495d4dc18a4656cb36bf13d229d65475 refs/pull/679/head\n003f701296e9aab2698626720502d7988f6ec8534900 refs/pull/68/head\n00403d77783d0ccf43a1d2cabbb5cfd769cb5ac08139 refs/pull/680/head\n0040984749296a631d40a888798b9da128c25e38a004 refs/pull/681/head\n0040f323d77eb48e653933df4cb8ca3e7b6d4b445558 refs/pull/682/head\n00408043886ee609e15ac71eddde29f7ad593abdecd4 refs/pull/684/head\n004098f502db014ce6cdfb4cae3bf5d37ffde0f522f1 refs/pull/685/head\n0040c95ac10faee8e9d2b2ccc1c8dc564a2315d5dc73 refs/pull/686/head\n0040a2a04afe106b835d9301cd1f55a6a661a5ec7d1d refs/pull/687/head\n00407b19026b4dd4152f609170c0984ba552770ec2b2 refs/pull/688/head\n004060da188ac6f131ebaf8a0bca72daba511885bdd9 refs/pull/689/head\n003fefc80f95b21903ffcc79f2e3767f216d40d6e973 refs/pull/69/head\n0040c4843689bb037ac6c9351dbb23bdf42920e7523e refs/pull/690/head\n00404aedcc345cd1e3398ec8ebb1dfa6d56c08b3229a refs/pull/691/head\n0040bafe7bf81405775c49d732209f40234d49622c2e refs/pull/692/head\n00400d6d7c66b246d72c0d513a5827c7fc7ca3a5c0f6 refs/pull/693/head\n0040df57af56cc3896f95f502626faf04592cf6e4d8c refs/pull/697/head\n00400d369e0ff56c300f78e1b047b9ba7fd3a6305a1d refs/pull/698/head\n0040f555322ea73895e099bbd25c09c77c3d32742620 refs/pull/699/head\n003ee44f6d00df38bf536dfa16ac854a24b30951a873 refs/pull/7/head\n003f7a275cbf35e020572d4c83f90d0bba774f8151d0 refs/pull/70/head\n004045272168ba25f1d6a15abbb1dd3d25f2df494ca9 refs/pull/702/head\n004097e8173ae22cea5a2a4c1b5d2edeba24d590c4d0 refs/pull/704/head\n0040e7e01e7e31fd80d8560ece85e949bd7ee78df2c2 refs/pull/705/head\n004042536bfa4e70e88579cf472ac13a534dcdee6f12 refs/pull/706/head\n0040a2459380ecc080174e784a92e978dfa7d8d9c475 refs/pull/707/head\n0040fcc04802804190e699b627a9311c7825244f463e refs/pull/709/head\n003fe460077786c95beaf70ca516b10355042df8d0f1 refs/pull/71/head\n004090e7d78e8be39bed87f991fc9078a626e81054a6 refs/pull/710/head\n004006a9b8f4ee2433c22f584a63abcaedc056c4dae4 refs/pull/711/head\n004072d0f4ca688fc020d2689516409e0a0241a00549 refs/pull/712/head\n00402c1924d53a679253d237baa26aa707c4d9da8884 refs/pull/713/head\n0040e65263e40790c2c3c218953acdab20072c15e3e2 refs/pull/715/head\n0040cb40852db455619fd4d11df788f87792fbc50feb refs/pull/716/head\n004025d97b46820caa302f7d73b3fd0d3e480b7d10e8 refs/pull/717/head\n00403d2e5c60f73734d85b8691b4bfe8f3bf9ace2d59 refs/pull/718/head\n0040a7844ac08686fa01bd3945a36c71083eb865035e refs/pull/719/head\n003f0ea877f58dee1d05c10339ebf3e574324992656e refs/pull/72/head\n004077372613c5eeef798728a9acef6b9e6e47d7fef0 refs/pull/720/head\n00408db2f7e637a58b9c7f8de702d7840f855e9aa8ed refs/pull/721/head\n0040177f41beea015317a3eac047648304f31f51f97f refs/pull/722/head\n00404d3481fd5284b4422f6377d83b92dec187576e31 refs/pull/723/head\n00402f2a33ed706a8da32bf11e418f64f0479f19354f refs/pull/724/head\n0040e551d9b972d0789141af4aaa572b578ecdea1da3 refs/pull/725/head\n00404b51a02f4705e9bbd497f9e1e440583ec6ba154d refs/pull/726/head\n004032fcd859db96271b7f7b12858a8ea3ffe8c5a614 refs/pull/727/head\n00404fff6d895a94d46b666e645ec0deae52c1da5fbd refs/pull/728/head\n0040285169615c3f60fdf928a4828a25a8fdaf257dac refs/pull/729/head\n003fb34196165f7f457a62afc293ab4ffed18b95be24 refs/pull/73/head\n004078172ccc0869f65b849cb08d80cfe7a3623f0d93 refs/pull/731/head\n0040928ee035554495b878806ea5493b93748c80c5e7 refs/pull/732/head\n0040d037807f6550280434189d41f4528124b59c65c4 refs/pull/733/head\n004055e2fa977cf848c1e3cb4888135556744584dbe8 refs/pull/735/head\n0040066dfdf51f0ef7968984267bfcf1ddf0013d35cf refs/pull/736/head\n0040a121195bac6e62fc2bb01779aa93339bbde7c12e refs/pull/737/head\n00403e7facbd209ec39d303416abe591c0ebe7ef526b refs/pull/738/head\n0040056bc02fe23dffca388b0c71dc765e26c0ecefe4 refs/pull/739/head\n00402a631151127562c377721506f44e8d6d5464cef2 refs/pull/740/head\n0040d2fbcdaf39656fa110558c97f1ab571591e4a80d refs/pull/741/head\n00405a1114ec4d88ff3668fe0e362dd2b62969813b24 refs/pull/742/head\n0040ed0ced879d819f2e9ed7a2a46a0597bdfd83df67 refs/pull/743/head\n0040f358d39f0c738c2c7c4cf8151bca8f08cf5e103e refs/pull/744/head\n00405b267b0fa6717f2beb2da1be354ec7da6e3d8fe0 refs/pull/745/head\n00403d4dafc7a7f3047623538ef822fe7f93a28e8553 refs/pull/746/head\n0040173c7b2fb299d6d1dfe20349263a54eb7b08bfa9 refs/pull/747/head\n004081cfe17eeabc9775da65b2f15a9cac4c390a2c71 refs/pull/748/head\n003fa2064306c0121b9a1aa51349945f2c0c25183cd9 refs/pull/75/head\n00406275137133743c4310697fdedcff40c627e27c8e refs/pull/750/head\n004068f0993f418e32413af9f50e735ebfb10c94f4ea refs/pull/752/head\n00402b32cec5276d0ae3bc64bc78f8f9fceb83813b1e refs/pull/754/head\n0040f55a27997d1c23c0b386b63e9fff8ea193d6262f refs/pull/755/head\n00408783d3640b8a971fa809dd1cad2a604ff202cde1 refs/pull/756/head\n00401acba9a0352ceaeb95654294bb27410a722648da refs/pull/759/head\n003fcc2a1d6ce103a8495ff4f3b507929029fa1a3dbd refs/pull/76/head\n0040a4aa7c7fbaedcce1f1c68704a9898a2a9b0dbd6e refs/pull/762/head\n0040ca562adde31ebf443bb6f9247f090cb3a2a7de54 refs/pull/763/head\n0040af8fc879f64d994d84db36f6beaa1356304abcea refs/pull/765/head\n00408b031bf4c886555f37f97f9cbb8f5f84ba3e9896 refs/pull/766/head\n004081b890ba1158a718d4df4f03d7c83af82b576a92 refs/pull/767/head\n0040b2d17f6de6288aaebfb19197c68a105d0daba511 refs/pull/768/head\n004001e9d0c6cb2d19a033ac0e6d7bcb88bf2ca40daf refs/pull/769/head\n003feff68e7143fdfd30c275ba516541db0844385e8e refs/pull/77/head\n0040e84a43a470bb7f472d1a49d5fe14c8f89b3fa981 refs/pull/772/head\n0040cb8262e93c0cd4d084f887e1effc050b285d9202 refs/pull/773/head\n004010931bf93d7f9834aeca8777b326f7199cc52595 refs/pull/774/head\n0040445cef5a2eda33abbf056b4e7c3bf37c7d32db14 refs/pull/776/head\n0040d073d3b75f1da574628b0e66aead9986afda42ba refs/pull/777/head\n00407ed9cb607a89a7d57ffae5fd507af7a56db19c38 refs/pull/778/head\n0040dd60736ffe81fe26ed0182e4c7b31b89bd452d91 refs/pull/779/head\n003fdf05d6c2be5809e2d85009f78e79fe33d27da367 refs/pull/78/head\n0040e05028469f918fa3c55b92c66588a53e7e19efcf refs/pull/780/head\n0040bb085e4cf1c3feac099a7ff565053538b608ee3a refs/pull/781/head\n0040118db1a7c25ba4d379b974cb9e79df363e05f10c refs/pull/782/head\n0040e932db9ea7ebf46b55669c7edcaee78d5a35afba refs/pull/785/head\n0040080e8a3a8d8598b786508898e33e6b1eb6a62490 refs/pull/786/head\n00403aca03c675aa27392e84bf20bf551b4f4c1c1e6c refs/pull/788/head\n0040d05b8a4bc1f572927875b238e07596e7e5996a98 refs/pull/789/head\n004018622bc349c54e308084c2d4b34b24aa22943f5b refs/pull/790/head\n00406b09743c2b7d220ba84a454bdbf7416875fe08ee refs/pull/793/head\n0040ae001437ad1fe79c20e10d8713b22e1d0fd77388 refs/pull/794/head\n004046b9797d8cdbd4bcbce41c3d85bc029d7fd04778 refs/pull/795/head\n003e34eaf08d34a89431d5c0882c84b9fa17908caa1b refs/pull/8/head\n0040ce2858dc43ca2f2bb87614399077d66bf9bb24ec refs/pull/800/head\n004070bed40651dbf77b56b8bb1ce937293072819c0a refs/pull/801/head\n00403ed253bef7c27d246c1c456686e95bbdbd80d677 refs/pull/802/head\n0040cdb43d4f1ccbc2292955c2315e5ac8d4d8eea146 refs/pull/803/head\n0040a896b1480f6963ea6cbaaf61415510ddf4df13aa refs/pull/804/head\n0040c36c7b4facf399d85982ca2e5f6a797b3be27ce8 refs/pull/805/head\n0040e2b4856726d3d53aa04854fa9713d27f9b830986 refs/pull/806/head\n0040e563eebdaa0362a95079661b7c22508c8d94e040 refs/pull/807/head\n00400ee37c80c0931d187305f8f7261d2070b8ddd80e refs/pull/808/head\n003fcc8715f28dafd700666d19cc38136cea248b1060 refs/pull/81/head\n004006d7aca733f2a97f169c125bead4fdf9f15f1f37 refs/pull/811/head\n0040bad54eedde4823b02aef76ad29f027b5ec55a847 refs/pull/812/head\n00406323fa304b8d1ea0b30f5255af372ea6c1d342b0 refs/pull/813/head\n00406fe4c87726530f7e1dbfd2da602d68c68db69e7e refs/pull/814/head\n0040d34f6f2d5e2628ba873f74b7432787cd3711b742 refs/pull/815/head\n0040de87980d51fe9110489e5b16eb58db6bbb1f5dc9 refs/pull/816/head\n00406e0613f124704bb9e7f186e591aa83d9343e725b refs/pull/817/head\n004012157a79870d55daba6ec78e8d0a60d7f275bf22 refs/pull/818/head\n0040dd6ce3c6e72b750253e2a63858bbae1093861dda refs/pull/819/head\n003f9d4d998dbb4cc5a5c519e611bb364f75bf34872b refs/pull/82/head\n004034438bebd4d9f64bce4c3560a859e4bd7ca03f57 refs/pull/820/head\n00407207b2633bef006b6cad7f30861be8783788c2f0 refs/pull/822/head\n00406231ac298bf965ade374df6300db26436413c470 refs/pull/823/head\n004062336dd003c07cc5c286ce0f3ab3774a5c31a612 refs/pull/824/head\n004046968d768edfb3f6186dd6dca57916e297c33dd2 refs/pull/825/head\n004097ad5aecced2f2acefe13953362f97bc2cbeda60 refs/pull/826/head\n004059fb92750d43c74758d919bb888106258da5a29b refs/pull/827/head\n004022b377d570d3ab3cf0452bf959730dcaf2825446 refs/pull/828/head\n004009376942a89475fc1ce482dc4532626161f13703 refs/pull/829/head\n003fe621b6b6e656eb468c9706eec994e214cc9f3711 refs/pull/83/head\n00408ad712de7bda9769fe5768094715a00d564c1980 refs/pull/830/head\n0040d5bdf9abbe52f4db1e27e5cd131608eeaae7989a refs/pull/831/head\n0040e05dec0d6e78948e6585f9b317025dd71d9c4fb1 refs/pull/832/head\n00404ed4040f268b03d9659cf4222ed43fc44602902d refs/pull/833/head\n0040a5965a59ba5bcc689d236cfc9616572771758a7d refs/pull/835/head\n00401f4a1d12005e416e3f5b2bc4f3a784c428aab57d refs/pull/836/head\n0040d1bfdaea98d066478100518578ff395acfbaab14 refs/pull/837/head\n0040c518afdc363706a7dceaed72544525b7d8357b95 refs/pull/838/head\n003f9169f1f08ea14d3fbe1b68b53713d28f5248d0e3 refs/pull/84/head\n0040d35da14e7b620f44b1b96c74c609b9b7921032ac refs/pull/842/head\n0040e657966ef3575b05376c51fbe7d40d357876ca48 refs/pull/843/head\n0040ec3cf43d42d8af6018a528f1440999b467b3f388 refs/pull/845/head\n0040115524d3bfee413ea472b6b9f7fc79d85955651a refs/pull/847/head\n0040e22599fd352a978201db471c884575423da0fe97 refs/pull/848/head\n00408fa56e28ad91e4be463f25dc465afcc0857b7669 refs/pull/849/head\n003fac40525168a1bf85ab0ddc2f1a1db98d12f2eda9 refs/pull/85/head\n00400ca5e64a00ed2653963337613893e97fd04e94ad refs/pull/850/head\n004035b917bdcc8dceefef5b948482f1731361832f66 refs/pull/851/head\n00403dafe29588e29ea4c751ea0b8a9abd3dbc18c3c0 refs/pull/852/head\n0040ab29b63a7ae6d672086e812604f58170059140b1 refs/pull/853/head\n004050a4b042a14e4aabd9166c8e64aece2dd3019df2 refs/pull/854/head\n0040d78b460e2fe03f1595d1aaaad5dfa3f2748bbed6 refs/pull/855/head\n0040fc3fa2c8c9d9e1f0e0f8b436793e9792bf2a194e refs/pull/856/head\n00407cdc4a8bbbb549de2f592599ee71eb869dc0f107 refs/pull/858/head\n0040ce4e48b794c9edb5d19dd5a5e1d2704af419105e refs/pull/859/head\n003f048d9dc2d9c48ca2d6d685cfae4cea7d74c075aa refs/pull/86/head\n0040abfb710d9ff916933ba72ac68062d8efe6b245cf refs/pull/860/head\n0040f4f48b5fb1288738e59a56853854930bc02647d2 refs/pull/861/head\n0040c189b851b3d5fe349399d249a90e0e68dc8f83a0 refs/pull/864/head\n0040182e26764f06d5b2be0b7c68715c14ba8d67684c refs/pull/865/head\n0040da8d774b89c336070340292a780d4089406d6e35 refs/pull/866/head\n0040ef83217f1cca19bb55f29ee2aa24630301184dff refs/pull/867/head\n00404cd0f4f6609e0877a22263b6aa8b0097b7600ff0 refs/pull/869/head\n003fc1bd40fff6ddfab1c3b4b0ec7b949b595a37f560 refs/pull/87/head\n004073d3324a956b6255e7057b91bf842c903953aa06 refs/pull/870/head\n0040ca189efb1d2ba63690064760fe4d5f44212d5eed refs/pull/871/head\n00407943f1f3061bab8519c31af04cd2865c5f773412 refs/pull/872/head\n00401a19ed0abc5ee0984002a534d94ad9d13a23cff6 refs/pull/874/head\n00409005e7448f74c76bfca8abd6ccc2eaa8033e3f1b refs/pull/875/head\n0040cb8158aec6e877cc7d19f6b8ce0d76466e9f2de3 refs/pull/877/head\n0040d9e51f14175ddc2e9bbe93dd042e1d6fa5c063e6 refs/pull/878/head\n00401c40b3f421108053afb348d7afa4cf218a1d0f68 refs/pull/879/head\n00409a5882322417a05b4f4e9624af90e4789f3cac9a refs/pull/880/head\n00408d07ee77a55d1e43753eb2f1b595e90dc7807472 refs/pull/881/head\n0040fd9a292f19de446cef18f7598e8aa671e9b8eb5c refs/pull/882/head\n0040360aa2c5e752b5454cbc4a2479d0088b38abc993 refs/pull/883/head\n00409f48dfb7ab50cfadb0b962420dc2925c3c6c0735 refs/pull/885/head\n0040a6ac8158f4df78287d9b9ad1de65dc57dc6a185b refs/pull/890/head\n0040766b544a82088b1431e3dcdd3e1487b9189d6246 refs/pull/891/head\n0040a0a34d7f13509a488214cfd2438f6be0146c1ad9 refs/pull/893/head\n0040afa6a135e83a9912c9f4d15357fc9938bf2b0068 refs/pull/894/head\n0040c2470e34de7765ff88749016b3965464dfd2fa05 refs/pull/895/head\n00401c5b91f0c98a065da1decc046eb7c42f814ac6d5 refs/pull/896/head\n0040107785b88da780305b58fc9c6a7a4ad62429857b refs/pull/897/head\n0040878be2f49793529c5426af095b857d85947dec4d refs/pull/898/head\n00403a3c8842ced25171126744d03956459b96fd2a36 refs/pull/899/head\n003e39a9b3d002d1ccfc40ae9b0ea09180f0ee210fad refs/pull/9/head\n003ff6ccf0665312025f8c067e65aa114f1e560535e4 refs/pull/90/head\n004064263d8202cfa4a6e230d02a85b4ab73f18af28c refs/pull/900/head\n0040b9d98f2c3292e12d1065e89381ecf2aac77b33bb refs/pull/901/head\n00407469149b4624705dc9eebb620bac1347e0a1f900 refs/pull/902/head\n0040758931949bb8fa3e07b86ab0304dbc8a545e4f6a refs/pull/903/head\n00400907842911fae6c1f24f295cfcdc1771316fd729 refs/pull/904/head\n0040d79ecb701961c87061812b420d0315336a5b8589 refs/pull/905/head\n0040004eb238767a74876370927993867203630406e3 refs/pull/906/head\n00407fa47247a434bfd4ea57e05c85d24ae3c8393fb0 refs/pull/907/head\n00402209d27550ca808b5741b75a5ca8f4ee1bfac660 refs/pull/909/head\n003fb9da4fc6bfe0353628c52d6c9909723cd3298a31 refs/pull/91/head\n0040dd96a1ef30474322eeae85b439752a2441648b96 refs/pull/910/head\n00401cafe4142ab230d9f40f7c376c7b2fa7e55275bb refs/pull/911/head\n004037292b1f0175a95556c8ab0496ec833aef6f562f refs/pull/913/head\n00401da7ae60e3d5ddd626f3ae779e14fa35d3920394 refs/pull/914/head\n004055eefd75947c9de22a7ab54aa2e66f9ae2d6d181 refs/pull/916/head\n0040991fd5a796b5a173af26608d89b2523856a8839a refs/pull/917/head\n0040a7092017e6221118f5374b13bdb94dd70cb931ac refs/pull/919/head\n003fcd8a45229c253b2ded996209253f557ebe08ea35 refs/pull/92/head\n0040310531041a9db2b3ea7be5508cba725a31c1e7b2 refs/pull/920/head\n0040103d74ad373eb791086aa36975c558d020329cf1 refs/pull/921/head\n004005a1330cb29ccc7cee7d07f282c9ea3f3ce09e31 refs/pull/922/head\n0040b14cdd5be1e9d43167cf8b45a12a8af94c7ab2f9 refs/pull/923/head\n0040ae5b1da48e019604c2ab11cfda3716bc93127e29 refs/pull/924/head\n00402ecf0d4443aa6fd0670d1258bb44e0502cc25be4 refs/pull/925/head\n0040f8d3be5358543d1e77b11da39ee430bbffaad72f refs/pull/926/head\n004013b646387780724daa44cb53406c374fa7536f5e refs/pull/927/head\n0040c80ddf9150a8a07a438a472b283f17dd432cac83 refs/pull/928/head\n0040c5790e77625a6551eca40f10b1baefed1364fdcd refs/pull/929/head\n003ff104599fd8d9a3e937e6afdbfd23aae03b06e70b refs/pull/93/head\n0040d051eee2415aea7e689f3f803c8b42d05bc7f261 refs/pull/933/head\n004067e4e665bcddd02323994332db1f0b36e9f95850 refs/pull/934/head\n004001c9c34786b8f29badce2ea7b8800d1d29585490 refs/pull/935/head\n004055ce8e32fc4100fcbe08168fa134f152ae03fa06 refs/pull/936/head\n00406e33ac2dc161d71f2093cd4b2069a670641da16b refs/pull/939/head\n003fe8e0531dff3e4ede2702f8a194806b479b6573dc refs/pull/94/head\n00409004fc8b94f17b8eb23f3fac7a40373dcf77370c refs/pull/940/head\n004031389c6fb390c4abf206763035bcc253913cb948 refs/pull/941/head\n00402609a321f2e80669a406d954210fd72be764b551 refs/pull/943/head\n0040d5f662f99a84d64ec471ac1380a5508b5b84cc8c refs/pull/945/head\n0040e9c463d00cdffbff59c5d93db522dcfc4d25a1fb refs/pull/946/head\n0040f192d01fefd5091b9b4ad9b79982485ea8589733 refs/pull/947/head\n0040d83110303c40da1d3625c2369eae7424928bfbed refs/pull/949/head\n003f9f4d26f01eaf7a63153e00738718899718630811 refs/pull/95/head\n004090c651e8a760809d5bb1d000200a51c636a0f054 refs/pull/952/head\n00401aab4ffc6737c651a7022c498da9bbe9d51a94e1 refs/pull/953/head\n0040dfada8bc4d47aee406e8b41ca5dcd37e5a46507f refs/pull/954/head\n004057853d8dfa95aa7e51955cec9f00308118779a75 refs/pull/955/head\n0040b2b34bf2041f3bf6b14c340aa8483b44d60e7ef2 refs/pull/956/head\n004002853eb3413c48d693f761af5d6bad64a794de35 refs/pull/957/head\n004048f6be2dc9e5cdcde851bcc3a36126c115ddc1d9 refs/pull/958/head\n0040ea6cf207519ea325a4db11bd7296ec8e3cc9ac0d refs/pull/959/head\n003f45027e2bbac111be570749575b37e391d01747b9 refs/pull/96/head\n0040c7c55e329178bfbe23eb01699ea2a53f30586fc4 refs/pull/960/head\n0040191e6f1b7e87e904cad92cad5baf2c0a886cab3b refs/pull/961/head\n0040fe2ed02e78802a6b0926426be167acab160c1c0b refs/pull/962/head\n0040a8a849ba63aeba05c5e9dd77b00164cc46b16625 refs/pull/964/head\n0040da9795a9634318e42c37ec19f80599c0edc59b0d refs/pull/965/head\n004037e9c36a577642e5eb7256f44781858b50030935 refs/pull/967/head\n004098d33cfab3240eb4982c3adf17c3a1e6a6dcf600 refs/pull/968/head\n00404c8394c17d6ac8f66dfe8ea52ea4f948021fe8da refs/pull/969/head\n003f4d2fe23287a89f1c5241c5e97a940696a840e17b refs/pull/97/head\n0040491d07d263295fc5aeb810ef76e8f2c6d427b3ef refs/pull/970/head\n0040186fa33372f1e4d38b6d3d5ae39d67a435775ccf refs/pull/971/head\n004066ac8a4f89fc8b05319d9a128f51414cecb940a2 refs/pull/972/head\n0040b9980b71215d670dea3099347dbe8c4218f9f110 refs/pull/974/head\n0040a6906775fd285ed3f2baed9a0e81d44ac0a0b3b2 refs/pull/975/head\n00408514919ec66097b5fb571d0664d96f39d768134c refs/pull/976/head\n00405faac7caaa0dcea41a17de0cee60ed7f06e1f5d4 refs/pull/977/head\n004080a4c2407a618a422fd423a30412788a04909d96 refs/pull/978/head\n0040c1e8209f39d44f5f593ae9294a1577d53bf1d125 refs/pull/979/head\n003f7aec67159650698184e602b4579273031479ba64 refs/pull/98/head\n00403555c83f3f7c24a3bcec994f0b6d5770a8ad2822 refs/pull/980/head\n00402c9160f8b13da1243284a53e6b9f087c822185be refs/pull/981/head\n0040a40a406de8e0cd31f3c5eee473ddf603f341c2f1 refs/pull/982/head\n0040ff4497970acdfdd1068d8e74c9cef8c12a4da5f9 refs/pull/983/head\n0040d13163df761ec75dccb17003c581847d50a2cc0c refs/pull/984/head\n00405b8617a847a2a203e498becbc3c0532748933ce2 refs/pull/986/head\n0040dcffa8e69730e0c02b9aa016461e87968794bb72 refs/pull/987/head\n00403b255d8a8de732f378204b6a875efc1b02e7d77d refs/pull/988/head\n0040a0f3cb6d034272ce93606a67d40df88af496e941 refs/pull/989/head\n003fd878692c990ccb8cc79fe2475f5ff23c27ac0619 refs/pull/99/head\n00405b7f7ceb1a0f94c7eeca65bf89eb14bbc0a59342 refs/pull/990/head\n00407017906a8b42b1ed89f4a460c4240b9e4580b269 refs/pull/991/head\n0040a5fe46e1f7d147ce127de02177289995546d3b97 refs/pull/992/head\n0040d23da7efa002b15768bd46ecb8e093d20371d162 refs/pull/996/head\n0040a512bb48e3b77d921087674f19a7e8b8eadb73e8 refs/pull/999/head\n003fbb69be3fc46bc36dc687a645679a227f7bab9eeb refs/tags/v0.0.10\n003f01277cf0443b8e7cbe8104c8e72bac7aaac15b11 refs/tags/v0.0.11\n003fbc9f4568c6f3fdeb78bf983a3bf3d90bdcccd9c5 refs/tags/v0.0.12\n003f95135bc1a18b70853608d492d6eb82e5702500a4 refs/tags/v0.0.13\n003f8de7697b3b8a73e79a73ec34f17ef0fa842cfbb2 refs/tags/v0.0.14\n003f932929f0f31584734b94339ea9cacf3158fd9bed refs/tags/v0.0.15\n004546391ffda5dbc429cfd440269a4972242bb0cc4e refs/tags/v0.0.15-alpha\n00481eff46c9d7e491d709680cba7e446d1fdcb8223e refs/tags/v0.0.15-alpha^{}\n003f83293a2b3b7931c39214afdbcf30573727891066 refs/tags/v0.0.17\n003f657fe2a8cf60492ae03045e7ca4da22a09be7f58 refs/tags/v0.0.18\n003f28d1e63275538cf8f3c3a5ccb5cf8f87ccf2aee7 refs/tags/v0.0.21\n003f236cdaf0470e94797989d232a85183f66ce6b61b refs/tags/v0.0.22\n003e9aa28d0a130e9174fb217921966b1855c2fd3f19 refs/tags/v0.0.5\n003e12e0175b9303f6ecca1ad8abdb3a28b3c97e7b54 refs/tags/v0.0.6\n003e95862388f4e9835d0b6e8136118e1799a064efe8 refs/tags/v0.0.7\n003e10b90c68bca21c632f4dbfd243aaedce25d00b3a refs/tags/v0.0.8\n003e737948b5060efeffb1cf47fe085d187a3d0304a4 refs/tags/v0.0.9\n00439805438dc8731dabd78c8b3eb6871cb12a5090b5 refs/tags/v2023.02.28\n00438395cba7325954e4b3e3ed4c7ef3bfa82b428bdf refs/tags/v2023.03.07\n004363a89f6b9cafa9105949ba1616824ebbce62d007 refs/tags/v2023.03.15\n00436e19621c3acce9f66a817d0fbd825cd8edbe56ce refs/tags/v2023.03.21\n004329b7f68cc25aef244e46758a4c6548d366256e65 refs/tags/v2023.03.28\n0043ac1b1aa95f204bb6e1c0265a9d24139e9207d1c0 refs/tags/v2023.04.18\n0043adc4f6fa6de0b14e8c0ad9e502434d68ac3ddedc refs/tags/v2023.05.03\n0043ac1e00f9928257d8db85557e92d7efe44f5a828f refs/tags/v2023.05.09\n004310d72617f1ab2fdc9445b99ba18e723f60dc0750 refs/tags/v2023.05.17\n004311260570ad7c022286cc82840bae0cf8b1ee5350 refs/tags/v2023.05.24\n0043a29affe77a4c5de1e5421d9f53a8a0aa749d03cf refs/tags/v2023.05.31\n0043aed410e4badbc073a6910c11c8ca57f9fc49310a refs/tags/v2023.06.07\n0043433e32ef73bf683326d11d06e4f3d0cbe1e58859 refs/tags/v2023.06.14\n00437f4fb14bda2cc9dbbd8294a863092f64c2907c2d refs/tags/v2023.06.21\n0043b23615fb607715133806de0b12decc215cc95c2c refs/tags/v2023.06.22\n0043b937cdb360e93eee61a150c05029eb00cd404486 refs/tags/v2023.06.28\n0043efe2a73c48cfc8f358f304cf6d359d404b9806d8 refs/tags/v2023.07.04\n00438ce4d43aecc3b203df79565cad859d7798735a55 refs/tags/v2023.07.11\n0043cf318991793322189c5e44865a0355fa2ad69123 refs/tags/v2023.07.20\n00430f4e0c28da6fd9535d483ab63584d60a925bb3b9 refs/tags/v2023.07.25\n004338a28cd7123e13f90206872cc2e9af57959cabfa refs/tags/v2023.08.08\n0043064a3cb686cf44a66b061e914e52c9a6d9f4ecd1 refs/tags/v2023.08.16\n0043c6234697916921a270ab73511ae41e9037e15a5c refs/tags/v2023.08.23\n004372824f40c918f75abdb41ea13ce0513ee3d85df5 refs/tags/v2023.08.30\n004381506c929c86ba534d561e4cea236c7b2e1cbd98 refs/tags/v2023.09.05\n004322f7c5adc326fbda035d81fa05e3bfad80bdc9c9 refs/tags/v2023.09.13\n0043eb99b02ec8895fe5b87d1e76675ddad79a15f817 refs/tags/v2023.09.20\n004357316bd49932c8d37661cb03681b9d240079c7bf refs/tags/v2023.10.04\n0043595fc3e8b0210f23eff23ff853474e8700af2b85 refs/tags/v2023.10.10\n0043b374531b8074c41c7842183132e7e2804ebb3e84 refs/tags/v2023.10.19\n0043d26956b07351e0c695723507ad56b0aa59bd759d refs/tags/v2023.10.24\n0043e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/tags/v2023.10.31\n0043eb3b3c75b4b86d0537cbeaae55984ad4bf71a53f refs/tags/v2023.11.08\n004373315181865f9dd465dfea60d8c4a7359bad47a8 refs/tags/v2023.11.15\n004373b75e2c5b3c0e18f20375f4944b30b806b4cf32 refs/tags/v2023.11.21\n0043d039ca1b38f56a6c959eee0982afb69d1e56a65a refs/tags/v2023.11.29\n004381ea8ac55875b68ff236da7f44f91997c7b08925 refs/tags/v2023.11.30\n004392bce01c40ae5c4707aa46371cd31dc34562d88e refs/tags/v2023.12.05\n0043e15fe9260c2f2bff99184ca7a6bf5b8bd4ded5a8 refs/tags/v2023.12.06\n0043bbab1cd3a6494c4fc2101c19a832b52ee78d412f refs/tags/v2023.12.13\n00432a4022c818232b32573841a6f506796a25d13120 refs/tags/v2023.12.19\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.11\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.16\n0043aa584539a6f0085446fa53149a33c9385cecdf35 refs/tags/v2024.01.25\n0043e74a5dd172fada3ffb487d0c7c26db97cf2c3cba refs/tags/v2024.01.30\n0043f853bc9845f76620ec94f3662bf522fea0368a5b refs/tags/v2024.02.06\n004379c07c93dc01ed256032cb790eaae638a4255ee1 refs/tags/v2024.02.20\n00431defc72ba4297632dfb886b829f7a2d5299f06d5 refs/tags/v2024.02.21\n0043678f665a24414c3b425eaf40eb0eec62233aae41 refs/tags/v2024.02.28\n00435a8605df882d8a24c086655338e5f43fbddfe627 refs/tags/v2024.03.06\n004377ae40037a5c92bb3d04775a2fab70043ef7058d refs/tags/v2024.03.13\n0043f532637d69ac886df1fcf7b2e31f90b19df6f351 refs/tags/v2024.03.14\n004367f1b39c7aeee2a28ce5a41cabe113e4b49feb7c refs/tags/v2024.03.19\n004352136b5f1d38e09a5c687bd796feaa54fda7e4fa refs/tags/v2024.03.26\n00432ed3d46bd5c433bbbb06b72d7c0c171546646550 refs/tags/v2024.04.03\n0043927c0cae0f153597bf533032f086442e99a17042 refs/tags/v2024.04.09\n0043bc61579a635c9525a163775e42ae23886960ed7f refs/tags/v2024.04.23\n0043afcc49c52bbd1c6604baaa3a12809a30d5d3ad34 refs/tags/v2024.05.09\n0043fc144b751d26d8fbfc6ba15afc92fdbcd00a4fe3 refs/tags/v2024.05.14\n0043d0b1f72cfa19b5aa73883161682831392d8b5476 refs/tags/v2024.05.22\n00439ec5daa06fdace741958e4a7a20f7d1931948393 refs/tags/v2024.05.29\n0043bcb5dd13096cc0981647b113ca3ea142a7a517b6 refs/tags/v2024.06.04\n0043ccd849542895620faa4f323f44d7ad7ca543b5dc refs/tags/v2024.06.06\n0043d4509b6e3a2a6764c75f7ac316703b538ef3a1c2 refs/tags/v2024.06.12\n0043af23a17b9c54179b2253fccd1da19c38aef1b86c refs/tags/v2024.06.18\n0043fa0672b233985ca2e57f752e1f91542f80b8b22f refs/tags/v2024.06.25\n0043d6938bd6e6f2cba5cabb950fd86086f4c764e8c0 refs/tags/v2024.07.03\n00432cd1236084bcda3c37a80348c0de88c1aa103bb2 refs/tags/v2024.07.09\n00438c2b48a4bf3bd73e9f198966ddbb0bebd3d7cd6b refs/tags/v2024.07.16\n004394f08450539093e3f799533b698ead2f8cafea09 refs/tags/v2024.07.24\n00437295294bbc414041b103a0a296718b14aebd2632 refs/tags/v2024.07.30\n00437ca68fed3cf76d171473970f5bfaa3846a69b635 refs/tags/v2024.08.06\n0043d48073bcbcf12257cc249ff3698fcf94a16ceaaa refs/tags/v2024.08.13\n004380b888fa239ceef4062648f4259a5767f36d1080 refs/tags/v2024.08.19\n0043a81778d470873e2be57d3b8ae4fbf9f942e28c96 refs/tags/v2024.08.27\n00430a526fbafa0a00279ab6a74787ec265d65b8feaa refs/tags/v2024.09.03\n0043431fef648ff9b44f33646ac773abbaca71c48f15 refs/tags/v2024.09.04\n004365076b2b592d4e09bf0be039699969b455bbf4a8 refs/tags/v2024.09.10\n00433dd07d08451a9be3cf4eaf95e3fa0e0d8f3e8a9f refs/tags/v2024.09.18\n00434eadc85640729c2ae55ab05f0040cec03bf3b726 refs/tags/v2024.09.24\n00433508bb45f43df4268a8be3248386b828779cd95c refs/tags/v2024.10.01\n0043081f563d7307950d9c43237ee7cb965261496ca5 refs/tags/v2024.10.09\n0045fa9fc088b7fa8a2b10a479a17bbb9f46e0609d34 refs/tags/v2024.10.09.2\n0043033ea44ceed6bbc972f8f528585d15fc397d2e19 refs/tags/v2024.10.16\n0043af4b18a1540cf73c9ac67d1643b0a5f511d1bc86 refs/tags/v2024.10.22\n0043037050145b4bf7d09d9602e2c8042e4ca8bed9fa refs/tags/v2024.10.29\n0043ee286929b5e18f007d9649afd75c7bc4ce68c2fd refs/tags/v2024.11.05\n0043d58c1f6a1e88c451e168863057fb05fe0d323488 refs/tags/v2024.11.12\n004322cc4bc998323fb7d0bcfe4bb24e3d5715eda849 refs/tags/v2024.11.19\n00432d7b1e03bfd479a58ad56c339cc092669dd64707 refs/tags/v2024.11.26\n004391a0125e55c8902b3d077f4c812284d9116a5bbe refs/tags/v2024.12.04\n0043402f47d4f1fe547ba68ab39ac342b525f4cd7e69 refs/tags/v2024.12.05\n0043a5ef7137a2e3cd5c48e2b7ecccab5722dbf738d4 refs/tags/v2024.12.11\n0043732f08356e5f073aa275d36bff43da6b2b0177c7 refs/tags/v2025.01.07\n00433d55f553e28cc2b16152fb4df8ac53797b9d5c8d refs/tags/v2025.01.14\n0043f53c68fddaf2d760e0a00cca49b4b5313bdb0ad7 refs/tags/v2025.01.22\n004326d49d78a26427a12628cd3a1a4cd49d030c6956 refs/tags/v2025.01.28\n0043a9940a58b48f0a650632c37b44abdee0144d781b refs/tags/v2025.01.29\n00453be0a2314da2bcb3028617e4a05622aafd5beee0 refs/tags/v2025.01.29.2\n0043eb29faa1a45f8983502590b8ca68dcb2692ac68e refs/tags/v2025.02.05\n0043c2e9e5f6e41b61bb18e8e9f20924bd702d9fea47 refs/tags/v2025.02.11\n00436f66b0ed1fcd2394462a4268f2dad26ace3ccc06 refs/tags/v2025.02.18\n0043edde4b267a78ec2452e0ee7afcc21d02d7f18377 refs/tags/v2025.02.25\n0043f7e26092e0e8ced250d6cab7ae7b62343f2b8809 refs/tags/v2025.03.04\n00436dd9a9dd776e2c51c16f359c417256e702fbbe44 refs/tags/v2025.03.12\n00431d0fca0817eab7d932e4673e6837aae320708fa1 refs/tags/v2025.03.18\n00436d7c3dc69bc05e7e1a83f4389e61d430db288416 refs/tags/v2025.03.25\n00432727c77060f0174f96e12dad3070cb504c316ec5 refs/tags/v2025.03.26\n004304979978095630ecf30f6c3ddbc55e07ba8bf7cf refs/tags/v2025.04.01\n00439f7fe3920daf55fb156d8feb6143d939e3d5cd28 refs/tags/v2025.04.08\n0043e28ded887856f77d575be479212490d35e55e08b refs/tags/v2025.04.15\n0043b8445788211b3bcc04c32c77046503b14170c870 refs/tags/v2025.04.29\n0043b8d9f1b5afe0a8cf6ec02354fe2fd4516271b1d3 refs/tags/v2025.05.08\n0043139de7b69a2ea39e2113309b3a0a47aab920ddcf refs/tags/v2025.05.13\n0043b5f70ca94cb7beeb9d01269958275796f1b7189f refs/tags/v2025.05.20\n0043098ed8318399f68a9b2ef4b22c83687cacb85da5 refs/tags/v2025.05.28\n0043f3aa51f0689214ee9ce4e57173e56b933fda3649 refs/tags/v2025.06.04\n0043367e62dc034dae8d6a61362fb0d804906982a18c refs/tags/v2025.06.10\n0043d895bc431dc7c591919e5f1907bee1867eb6a914 refs/tags/v2025.06.17\n00437f39eb683c4de0606f91a1e624f905bae1407899 refs/tags/v2025.06.24\n0043e4f7ccfd19525dcffb1567c992a031bfa50220a3 refs/tags/v2025.07.01\n0000" - headers: - Cache-Control: - - no-cache, max-age=0, must-revalidate - Content-Security-Policy: - - default-src 'none'; sandbox - Content-Type: - - application/x-git-upload-pack-advertisement - Date: - - Mon, 07 Jul 2025 03:38:49 GMT - Expires: - - Fri, 01 Jan 1980 00:00:00 GMT - Pragma: - - no-cache - Server: - - GitHub-Babel/3.0 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Vary: - - Accept-Encoding - X-Frame-Options: - - DENY - X-Github-Request-Id: - - 4439:145DD2:22CF82:274F47:686B4146 - status: 200 OK - code: 200 - duration: 370.771852ms diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_adding_two_values.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_adding_two_values.yaml deleted file mode 100644 index 8b5b7286984..00000000000 --- a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_adding_two_values.yaml +++ /dev/null @@ -1,105 +0,0 @@ ---- -version: 2 -interactions: - - id: 0 - request: - proto: HTTP/1.1 - proto_major: 1 - proto_minor: 1 - content_length: 0 - host: github.com - form: - service: - - git-upload-pack - headers: - Accept: - - '*/*' - Host: - - github.com - User-Agent: - - go-git/5.x - url: https://github.com/google/osv.dev/info/refs?service=git-upload-pack - method: GET - response: - proto: HTTP/2.0 - proto_major: 2 - proto_minor: 0 - content_length: -1 - body: "001e# service=git-upload-pack\n0000015500685b36c023563ff36d728d4f1a3490e8d2fdad HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter object-format=sha1 agent=git/github-e744e5203bf9\n00693fdf840caa2a15aa1b02ad63edbe37f14c25ad04 refs/heads/dependabot/pip/gcp/functions/pypi/pip-ef11913619\n003f00685b36c023563ff36d728d4f1a3490e8d2fdad refs/heads/master\n005372fd51767b95fa0ab298d580c1214d8b7ba67a34 refs/heads/promote_prefix_ignore_prod\n00529df6f14b0eee5aff3241ca2b6c6680174a9747f2 refs/heads/refactor-vulnfeeds-little\n0049c718cee0e2409df8bd503255fc60c21bb6d661fe refs/heads/reproducable-zip\n0062536d8403169585521583475f89d6ce5aa03e0a92 refs/heads/temporary_modifications_for_mass_reimport\n004e2c85053cfa420c869bae7ef023c52300eaa0ad2c refs/heads/update-pr-permissions\n00472c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/heads/upgrade-schema\n003e7588d54370e7336f1063b3ef96112797016c521a refs/pull/1/head\n003fa2ac801881f48bf9047dc4ca68f9587a4781bd7a refs/pull/10/head\n00407cb597c5a84af14690b0ea49312ed7eda06552fe refs/pull/100/head\n0041f8bcb25186df1323e6fdb712e580556202656a9d refs/pull/1004/head\n00417a8c671bc9e97f92924965851b471c8aab1ee8ca refs/pull/1006/head\n0041bd500a4044afbf9d5c49977fada634356c4fc101 refs/pull/1008/head\n0041605331fd14e43a8e905cea5164a62387afd51d71 refs/pull/1009/head\n0040e0cb2c344ca0730320533a43b10071b7f4312473 refs/pull/101/head\n0041485f2b6da3d617788879c786212a58557c12c5cf refs/pull/1010/head\n0041f94d9c56ce66d401e2ea5d53f3d9addf6a218fdf refs/pull/1011/head\n0041e20794697e7cc44aba013c331af176cb811ad551 refs/pull/1012/head\n0041694cd5f0828ac7cb3e2d9b320515b8ef03c2606e refs/pull/1014/head\n0041d52d02ff5c97f677510c7bb9b2985db39c6fe796 refs/pull/1015/head\n00419feb39025a7cf0fc86cb6ab0cea814e3c53c674d refs/pull/1017/head\n00401349f69d688fc7a509215f9432ec73dfb46b8a61 refs/pull/102/head\n00414c5f3de7c47d6688f77c4237bd2d5f60cae0cf7b refs/pull/1021/head\n00413809cd3109f476a78e197446c08bf33a4ca55c00 refs/pull/1022/head\n0041b13a6f1110ec13e0a8bdc0c01a6916ff0e354d3b refs/pull/1023/head\n00411eec3164523b5821d4c5f011871871b15fab207b refs/pull/1025/head\n00413348d2f75453c4e73887799b3acfab01a6bd73e7 refs/pull/1026/head\n0041b53cbd1cb21af23acc46a7954291b63dd5c3ac95 refs/pull/1027/head\n0041933eb1962638d9dafecde200304b15fb5408d3b6 refs/pull/1028/head\n00410a12cc1f3413dae4d84d63ad8ed1c6061b329347 refs/pull/1029/head\n0040cac8c823c650078345e35c8a813f38599775b833 refs/pull/103/head\n00411098e2c8c83ac74d287172b8e0fef6f68a1b1b65 refs/pull/1030/head\n00413b911bc5ce4f58aaec84b36fa7221c9e6b8aeeb8 refs/pull/1031/head\n0041ae07ed72ea2cf91193f8641ab0171b81d226879d refs/pull/1032/head\n0041911aac60254233f36c9fa8b352d9b8af3659a2b5 refs/pull/1033/head\n0041188ddfb6d0fe396bc04f255d7a397da940cc80fa refs/pull/1034/head\n004133f110d8a987995a37085a6f749731ba6079d10b refs/pull/1035/head\n004120360a60cb396c3d3e70dfa97c221426e651f9b9 refs/pull/1036/head\n00419b7028075b186cb85fb1162626bc8d35ab190945 refs/pull/1037/head\n004118fc7c0fd0e0add81d729d5e94ad8752c1c57190 refs/pull/1038/head\n00410804317ab3de7d5f993fdac0a0a43896862a6ef0 refs/pull/1039/head\n004053587e5a82398d23e39165d358f8093f797c5aa2 refs/pull/104/head\n0041fd4f821b02dae483809871416ac633e45836f6c7 refs/pull/1040/head\n0041032ece4b67ad99947c5c87d22e7474bad94521f8 refs/pull/1041/head\n004124080a2e01350075cefb33f912d77193d1f4de03 refs/pull/1042/head\n004136143d4cadc1bb7ab1fdc4d0dc7746dd19eeda97 refs/pull/1043/head\n00415b400eba34551913d34764cb8d5acca6f0a4f3ae refs/pull/1044/head\n00418fabf11f241e11624c91601a0596491ffa3c0d96 refs/pull/1046/head\n0041e3432ab171ecea3f25eeed5caebd19365f2753d9 refs/pull/1047/head\n004155ffff4042fa481e0ad1842f711a9f17c4cf5329 refs/pull/1049/head\n00402bc665af22bd913071393eeb5b56f8eb8afdc032 refs/pull/105/head\n0041a0c78dc0629761e3d567b8a268b433bb336019c6 refs/pull/1050/head\n004116b14e3bfddfb2bc8a0823d218c9fb55c35caf51 refs/pull/1051/head\n004149a52d949c8c923a33f8714a2175ad46b5e57db3 refs/pull/1052/head\n00410376002d2b38a6232eaa8a66cbfba525befe984e refs/pull/1056/head\n004195c7d0521ed2ea24906a34903e6f2469d4fead2d refs/pull/1057/head\n0041c30a6319d0e78c5694e2049aa9592bbc549adca1 refs/pull/1058/head\n004168154d8f0d81656f0ce6c8dd682d62fb307537c7 refs/pull/1059/head\n0041d16773aa81db518a3a2d92c90f3e0c97dab5287e refs/pull/1061/head\n0041e28509db3aab8aa7529d0795237be7eba62081e7 refs/pull/1063/head\n00414388c2adc25321d6a6006b5e5a5c32ec4b667bca refs/pull/1064/head\n00413844a6050bc4d2e8a90a28ea675e75f07283892b refs/pull/1065/head\n00412d68c51e1abeaa462580db118c06976cae5757e6 refs/pull/1066/head\n0041765995426c75aca4ffeea95f17c9029833ca8ff1 refs/pull/1068/head\n004137c97f269ed9064f88019191bdfcefc7618f22ec refs/pull/1069/head\n0040e822ea91aa0806b3de8ad8c307653ac7ade7fce0 refs/pull/107/head\n00410408805073cb0949236ca0700989510dbc7a240e refs/pull/1070/head\n0041d5e2603a21f3a25aed411d6b306702b67b1234cd refs/pull/1071/head\n00419c0c3019d9151e70b86eb3fce732f67f002d1d85 refs/pull/1075/head\n0041655ae019e7dc23f7d0f0053ad0ab4b216ca8101e refs/pull/1076/head\n00418d05e98430ef70cfb241571300687e3d0b2da4dc refs/pull/1077/head\n004190a77a72bf7b1514f8d91f1e2e10dd27b685cddd refs/pull/1078/head\n0041ba4517b948d070865726525ce8f6f92bc082f74a refs/pull/1079/head\n00402ada540e49327edd5997909ef4c3bd9965fef118 refs/pull/108/head\n0041989ed566cf6bea122ad73b4ff33ec8f10277e923 refs/pull/1082/head\n004103380f4390ab124fb1e93dc866643794e852a1b2 refs/pull/1083/head\n00413791ee0d863a87b8569332494539fc64509b870b refs/pull/1085/head\n004194059682ef11325cf7295e0168965353b96e72c3 refs/pull/1086/head\n0041f1d03baec460b46b46334f40e9b6c0722f9a8548 refs/pull/1087/head\n00415b8db3e7470201d7b3e755144c413dbd55ce6f81 refs/pull/1088/head\n00417621c0df9aa340cc08461ad41a171cac9948df96 refs/pull/1089/head\n0041a201dd01dbbd2fe51655c2b5a772c94f07925fca refs/pull/1090/head\n0041c6183a91fa972b2b28978cd34bbc4ece0c93d034 refs/pull/1091/head\n004100fc04e29e3d78ed91f9713fdc9a207e24f4ee2b refs/pull/1092/head\n0041c1fb4fb270577a0fd2634c149f6d4de024fdf1ee refs/pull/1094/head\n00414b1f9f0b4053dedfbcd1094f9fe134a8a7591a1b refs/pull/1095/head\n00417ea4d86462f7299ad5e017bc8ca69c4970addb59 refs/pull/1099/head\n003ffe47213e95bdcc488ada1849e9a510bd6d2e36bb refs/pull/11/head\n004057843634a14a6b67f8e75e8493a36398f88c6061 refs/pull/110/head\n004130eb8f7bf2c089a49f240ec7d69918c0e2949e70 refs/pull/1100/head\n0041be9176bb6398a4305e45af0ba76f8c816618f2f5 refs/pull/1101/head\n0041839788f01f9d6c4bc25f7f2c599ccd4da8cbf03b refs/pull/1103/head\n0041cf14188cc12ef4de9d966a7f42165cefd46bdfa5 refs/pull/1104/head\n00421fb31e43d570a544d62c175fa325f27e25afb552 refs/pull/1104/merge\n004133f55e55ccd34157da77fc2ed8143f75a681fab3 refs/pull/1105/head\n00417795cd32bbb6492eb117e45001b498d3c4de704d refs/pull/1107/head\n00414ff9acaceaa374fd68c248096e24b0fbe6477c37 refs/pull/1108/head\n004179cfd7131dc021a00a1fc78262a56edabe4e8acd refs/pull/1109/head\n00400a5b4257ff2e70b78134c8c41067928b65d650d4 refs/pull/111/head\n0041e2043c6fd2f27b60945c85d68dd81f59c765cc94 refs/pull/1110/head\n0041a087b854e11a5bb8b43f79bb9c3c2cad81f0fa75 refs/pull/1111/head\n0041c88dcd99d1d61ce90db741986178851e94dde070 refs/pull/1112/head\n0041e394a186b01d402a32a06803e79041c4aac015f8 refs/pull/1114/head\n004137f9c94f61d6a9407286f144870376e8d0907779 refs/pull/1115/head\n00415b470a1df2c11ca8c7283f7dae08a5e689e7a67a refs/pull/1116/head\n0041ad2cfe753e9ad1405b82344b7e5d248a9fd23432 refs/pull/1118/head\n0041527139dfdfdc3872980f2cc48f88c1685702b5f6 refs/pull/1119/head\n00407d0bc21474662422503c1fed2f6efd38f29987e1 refs/pull/112/head\n00411db7266b0d3dc2060e099d33ed2d621b82c638cf refs/pull/1120/head\n0041c22baac1c31c2282b9c81f02b2d297e943e715e5 refs/pull/1121/head\n0041717810817a0a2b2878efbf4d655a5f3f02bdb4ca refs/pull/1122/head\n00415b047abac2af8c3454aa3f5d9e3f4fd336248091 refs/pull/1123/head\n004187bdc6bbe11b1f7111cb45b231e77cb543c03b7c refs/pull/1125/head\n00418ed6125c3266ee5fe16d90e8f0db26bdd21e9a06 refs/pull/1126/head\n004198b17c26f503a5bb857ea3435240a45f584d236e refs/pull/1127/head\n004145c24a202a91fce5c1f3f18a28ae2c328fb07fcd refs/pull/1128/head\n0041d89e784013fa44af219af4c59318ce60f8f05fdd refs/pull/1129/head\n0040a8e64b67ee50fdc923b4dfca8a026bb7b7e0f9e9 refs/pull/113/head\n004142ec9e39e560a60028b64ecbaf2bf9ffaea9acaf refs/pull/1130/head\n0041e90b84e7aeab7edf3bc569ea7b445e511c88d303 refs/pull/1132/head\n0041c1d699e161bc1bbfd7d57be2712c8ee1546db0b2 refs/pull/1133/head\n0041153b7f21669004864a63efceb934ac9247c43b44 refs/pull/1134/head\n00418a6b4659ba4a39a9f18d938a1303f35962bd2c63 refs/pull/1135/head\n00414b9e30d2079123127d445c57ef866691c2612c15 refs/pull/1136/head\n0041064e0107b717f35d289c101a8df5aa6aa49c14d2 refs/pull/1137/head\n0041a68a0cd38ab4f489191912d992c1d4b7fb598201 refs/pull/1138/head\n004196c4267fdd5ebc5a11abf2afde34952d11fa0e3d refs/pull/1139/head\n0040ad040b0e9fb545a5e5e72cab06eeed0457350efe refs/pull/114/head\n004168459aa29ef3251223f574b7902bae78890c3800 refs/pull/1140/head\n004158e5151180e67e209a300f98b10c8bd91d2f10d3 refs/pull/1141/head\n004197e7609dd55ff381e8b645373b38ecddf3615ad8 refs/pull/1142/head\n0041693895fd032c51b0c75036d9c41c6586ea59b306 refs/pull/1143/head\n00413665ffa0765a44fe402d9aded1e0997952d97bfe refs/pull/1144/head\n0041045004f0080fa316da50ca631055923d8383a910 refs/pull/1145/head\n00419c4c3d9bc4df26168813861503ae0920f7281907 refs/pull/1146/head\n0041c5b17cb731e4037a8b729ae71e18e267e0378f86 refs/pull/1147/head\n00411daf35f02314a6d03fc13e62beba958e2d504b4c refs/pull/1148/head\n004184160b5e6ed474b28230dce53c64b4de2be56660 refs/pull/1149/head\n0040efcb738cdef73909a1514edea0a2c3fc279fd0a5 refs/pull/115/head\n00416167e16bee3e6f04a58ee6e31717c1610e139f9e refs/pull/1150/head\n00414d3249741636a1311a19d70f2af571f9f69e2e70 refs/pull/1151/head\n00419b2fa3ecb7cf81be6030c621c98e1aaee8103839 refs/pull/1152/head\n004258fae47d57833a93c2114f003486a178c7fe4565 refs/pull/1152/merge\n004170972ff2903159bb09ef351d62f1f8a056b8cb2e refs/pull/1156/head\n0041949f1218bfc1a4a43ecc024517745812f8da30a1 refs/pull/1157/head\n00410b5fcb4e937e813c777bd6a1cee272e8ecb5c69e refs/pull/1158/head\n0041378637ce104c9282207fa33f33ef2a167fe430d5 refs/pull/1159/head\n0040853201302c759848d37893d94ba11ea590d61958 refs/pull/116/head\n0041e09188102ad3986443886927e92966e9e7592cc3 refs/pull/1160/head\n0041700d09bf5a8f85ccc34818ec42b6a546128138b6 refs/pull/1161/head\n0041d9ae5ece28cd3744db4545fafc3e91ef1bff6f2b refs/pull/1162/head\n0041850c562b1c00fbbaf6a88dd8193de3963a820620 refs/pull/1163/head\n0041e662a66092408df23b3d993227fa931b6c18bccb refs/pull/1164/head\n0041f47b8a51d42a9afdcf61d31088ee3d4d67a38ad1 refs/pull/1165/head\n0041bc14f54a67add60193012a25131e046ced831b7c refs/pull/1167/head\n0041f04422a14208718301ea5ab6edeaa9bcd8bb0b18 refs/pull/1168/head\n0041c4527fa17adf08abf20e61de87fb7a9cfebde6bb refs/pull/1169/head\n0040f2193ca860f0648ffc8f2e6de877f92a363e89f9 refs/pull/117/head\n0041d7e54154d56ac72520daded39ada968082c9063a refs/pull/1170/head\n0041b43ea6c0af5ec6a0ba59691044fc4f168993808f refs/pull/1171/head\n0041e573127901d5456835c3a14581dac8317df14710 refs/pull/1172/head\n00419eb7982d800aa6d091a70e1d66a025e86b0fdced refs/pull/1173/head\n00411e10841edcb227d69ce075d0023c1519e6b61899 refs/pull/1174/head\n0041165a91da2ba287ec682f675235313e0ffffc221c refs/pull/1175/head\n004156a22734341963ec2726e9eabaa51d7c0bbf9f57 refs/pull/1176/head\n004101a728fefcdf53a12d4190159ef3dd413e726d1c refs/pull/1177/head\n0042a37bb2235324744350d465f23b7ff91bfd16f36c refs/pull/1177/merge\n0041645b3c4efecc4799fe6e40282c2b86b941e58903 refs/pull/1178/head\n0041da3ae6f7076eced3e1905f2345136d0ff6f3dc9e refs/pull/1179/head\n00407485aac97090584e3815fbbc2273d97634e1e687 refs/pull/118/head\n0041fc120ce5c94b1a168b89a9664b75e703c00170f3 refs/pull/1180/head\n004131eb3dc0538687ab2714afb69fb4408e438db967 refs/pull/1181/head\n0041c9f32af3b88f879262a81554a5cf87f0d72fdafd refs/pull/1182/head\n00410e896c2d535ae2d5f1a0abe24c8185b60e50b4ba refs/pull/1183/head\n00413f8e4d222485db16dd53a82c1aa8d53dca62606a refs/pull/1184/head\n0041902cf79cf6c7107315190d647ce9afe83a1f46c4 refs/pull/1185/head\n004101021d07febbe1dc0964c3f3a4fe25bf2c864670 refs/pull/1186/head\n0041f40ed0b4032dffabc9edb601e3bcee77922d07d2 refs/pull/1187/head\n0041149fee3f435468ea5ba248158eef48bc6ab59243 refs/pull/1188/head\n004192a96024812d7a9471598ca7509577eb6f81448b refs/pull/1189/head\n0040fa878cbaca3a34c3a27763118e5b0d947aef3337 refs/pull/119/head\n00412745cac3b81bc800037aff2b3ab37709d37a7921 refs/pull/1190/head\n00415c4c55133d0640b0e2f6abbee881b1fd3a3356f6 refs/pull/1191/head\n0041cd47d6beab06c76d3a11d158c93ca20f09ba4177 refs/pull/1192/head\n004113d6b7545444c47dfd08faf6aa2b9e1ed6a8dcf7 refs/pull/1193/head\n0041a686ab68d088b2a72080224afa23f590c8e83a0f refs/pull/1194/head\n0041f97c4cecf158db398a7557d46233224436e88ac6 refs/pull/1195/head\n0041e010e5b0b1c0e50753277540087df697bbbddbe5 refs/pull/1196/head\n0041208f300c2b85b19840e4a105bfe1747cdb31be0f refs/pull/1197/head\n00416f67f17c15194150c498445ac4bb7f6b3cf2806f refs/pull/1198/head\n003fd90d93044396651a5760ab8619869f3ffa7e28a2 refs/pull/12/head\n0040d4fb3e5bf442245bdead885901391d6448f036c4 refs/pull/120/head\n004140a9bf1f01f1fcaff780c463653753b4b7b44789 refs/pull/1200/head\n00414e3c6c4f74cd604ee2c988d663a4f0bd5084936a refs/pull/1201/head\n004110475df37c8747ce46e549d8967bd366ae74bd4a refs/pull/1202/head\n0042d8416218ba39f441d66806e5e0b036e175c68d7b refs/pull/1202/merge\n0041a700e380ac386cc24c1054bb871d5293ac54276e refs/pull/1203/head\n0041f0e9d7ca384d95b257676adbe5db549b206888b9 refs/pull/1204/head\n0041e75b7e3be1f8eb593039e71c68c620ddca416555 refs/pull/1205/head\n00416d54b8e24ca11529459c8304de1d1775c21544f4 refs/pull/1206/head\n00410632e7fb91e7a0fed85c55fba17f03ffbca4ca4b refs/pull/1207/head\n0041b4179c0e8f91a580c494380568cc755b830cb0e4 refs/pull/1208/head\n0041d9a46d372622a55840ff16e713574aa5aa589078 refs/pull/1210/head\n00415f7ae1d59f7216a4e69bd9658878445f8354f379 refs/pull/1212/head\n0041ec47072f7b589b5076bca86e80a50b4ef0e4a67a refs/pull/1213/head\n00417a8297543e96cbfdca35deaf7ef482a887d82641 refs/pull/1214/head\n004129f6cd65449e9fce1dc070e03c5a0fd5d011c65c refs/pull/1216/head\n004188f0ba0dbdd1920ffe0212466eb97a47dbaf88e9 refs/pull/1218/head\n0041fab2e73d54951557743573f70d6eea1da3060157 refs/pull/1219/head\n00408b7243382787f405189d5180c5a574b3d725449a refs/pull/122/head\n004188a45b1b0f86c9d89061ef74d669e35f4a12a419 refs/pull/1220/head\n00418a99741ae7e5fd4f7904a0ab39bebf9c52347dff refs/pull/1221/head\n0041417322b4e9949268a0dc74de31e5157f85874fb0 refs/pull/1222/head\n0041a96feac6ea2180d6765f714dbf4ff177bf87ab7d refs/pull/1223/head\n0041c5fe75fcdd34799ea08d44f755f0fcdb8d874690 refs/pull/1224/head\n00418dac58da823f0c0370fff98e5f3d893cbedff65d refs/pull/1225/head\n0041c026d87119a26050ce707fd46d8e39a3648e46fd refs/pull/1227/head\n004122c1aba51dfe449915b86a8e89804362326ed46a refs/pull/1228/head\n00414d86f314d4f11c630f48fed1294af87fe4083f95 refs/pull/1229/head\n004095972d7b95720065b9ad13946c2f19e7940fe074 refs/pull/123/head\n0041a15cc8d82d9531f7a3c7062c5a44e1d74962db27 refs/pull/1230/head\n0041608a8693561c85a4519bad15d4477760b1213f52 refs/pull/1231/head\n00418499cabe2d26bdf79362cf5848d2d6c5feb4f3e0 refs/pull/1232/head\n0041097ff7d5dff9e064297f16888e671c1a8b20a54d refs/pull/1236/head\n00411ff8266b09309ce473a5fdfde6b23df95d91c4bc refs/pull/1237/head\n0041041c24c794f085f187c8b2626568c1ce9addc431 refs/pull/1238/head\n00417941b0db3a95531936ed7d492199e1c506f4b693 refs/pull/1239/head\n004092350c4dc465cc0e1b34e5f6c95379a19a88fe7b refs/pull/124/head\n004144e9933cfcd6f810b8c84a49654495b08aa96443 refs/pull/1241/head\n0041e3aeb1a51d39c98fe2d05d6a4e56881b8f308e98 refs/pull/1242/head\n0041297bc99ce0f1fe0c722646e878c48ca1b7359f54 refs/pull/1244/head\n0041ab57c19fb6878591469153a6b43cd200e5056ad7 refs/pull/1246/head\n00416bbbd03d1f609db86085779327329af0b870df5e refs/pull/1247/head\n0040ba000c0f39d232ea471959ade31d5bf2644e44b5 refs/pull/125/head\n0041121e405182ebc1747bc4b70ee51f1ad515eccbec refs/pull/1250/head\n00412a64d4bf9067530451df1015757b964dfe1a14e2 refs/pull/1251/head\n004138777fdb3a08b8fa21b046cc3f99ed080b773cc3 refs/pull/1252/head\n004189a916d3fa0e29776db1dca2cfd496040b7f59ab refs/pull/1253/head\n0041b90f19856b5d540108a64072c2deac6b1cd78963 refs/pull/1254/head\n00419b6edb6b82873b174431d6fdd2176c56f24120e4 refs/pull/1255/head\n00416256217be5d1950457e58da0bae4bf04f2213719 refs/pull/1256/head\n0041881388e2752e4f3dd131e8a1f8bae279d2f120df refs/pull/1257/head\n004191315d3344d7b85173da33c9f3f2b43d6b27f355 refs/pull/1258/head\n0041be6ea4d8245ececbe374dc0dd1d809cb94b073f6 refs/pull/1259/head\n004005a29c8ff1ca492bc90f87070fd303a8110e63cf refs/pull/126/head\n00412ac78599f1db05f40ae306d6b9ae7c56a3710044 refs/pull/1260/head\n0041253384d79ca6561d4f3c81f4e41514470026c6c3 refs/pull/1261/head\n0041e96f52adadd2e3f7f64715f3e9c4c0638e0fca9f refs/pull/1262/head\n0041129c977415a332d4a850ead18bbbcabb3022494f refs/pull/1263/head\n004152b028520be76bac86f78d8c684c2c5ed9cccc50 refs/pull/1264/head\n004186f9391f84fcca2c177eb788a56ae8b7e543d902 refs/pull/1265/head\n00414d3590834890a95113490d5040225fb270b5b7d3 refs/pull/1266/head\n004181622365cbead4b2326525b2601da753a24a5e55 refs/pull/1267/head\n0041117f2cce652b5628970d0977266f55eaa55cb407 refs/pull/1268/head\n00418bf7be7eb05fcca77f395a59a02e4b1e1860b469 refs/pull/1269/head\n0040b87fb4478b446f4ff48ac78beafb90fa37054b41 refs/pull/127/head\n0041c386d3a3fd7dd25d1c088999350621015b934231 refs/pull/1270/head\n004196c88193e27d33fe815eb0551d8087c8f08968fa refs/pull/1272/head\n004158ef639deb89f9d5517c308e977dc683f0c0168c refs/pull/1276/head\n004150328a328d6100da7adb817b253bb006d7c0c046 refs/pull/1277/head\n00410dfc3535eb0c29e638e9d7371fbc84f356c80aeb refs/pull/1278/head\n0041133f337708f4da78c753d8607f35590d9d0f36cd refs/pull/1279/head\n0040c79671a08acdfa73c90d555e0065ec3e108e2214 refs/pull/128/head\n00414a3f1930fa113df2b198bf7e6b4bf2753cb08c06 refs/pull/1280/head\n00417326ff73868061c78efdca1d22bdbc93f4dbc060 refs/pull/1282/head\n00414b592a00998dd4c4a9cca11be7979eeff9c1709d refs/pull/1284/head\n00410a19b05580dc24028dacf4f568529b24bc76f8cb refs/pull/1285/head\n0041e43a40ae80d2e8a6a0abaaa31ce4763d146430b8 refs/pull/1286/head\n0041fc7e59d29509405c92fd972087e6094f93f02184 refs/pull/1287/head\n0041add1a8d02937b9f518ab45756f4ed93e0ed2a7e6 refs/pull/1288/head\n004173ea6713b3e09df07ee64563409a3a711524ae4a refs/pull/1289/head\n004079f203e8674a264ca918ad0a59b52720c5053bba refs/pull/129/head\n00412ea3e74c9fa834f044e3ae49533106a4513a1c07 refs/pull/1290/head\n0041207fcb2a7a6053f40a9a570bf4ce711fcae705d7 refs/pull/1291/head\n0041215e33c64e886aa92446ff82a8bdc48bdd92bdd5 refs/pull/1294/head\n004173c35234a9984cf83a5eb299dd2db138c048f6e0 refs/pull/1295/head\n0041cb236ea352e1e55ff844930a0ae81158768fd7b9 refs/pull/1296/head\n0041436a8602956ae04dac1f0b04770ce06112938929 refs/pull/1297/head\n0041618ac0ded5bd906e79bb7b784f29846eb3af9fcd refs/pull/1298/head\n0041d6e19fb7845e1ee98706ee8f3a36f0d97e5b952b refs/pull/1299/head\n003f3a8412073dcc1900bd009153b7c0bd40d59710a3 refs/pull/13/head\n004143294d0e607f85a1ed7ce9c504e6bdbf768b3d78 refs/pull/1300/head\n00413adf485f0e8226a37911538dcee7d1f0a252ea60 refs/pull/1301/head\n00417113d61286fb327c585ee08a12b25117245767ed refs/pull/1302/head\n004120bc1bfe5d146d7a453f501c3f59d08ce3972b98 refs/pull/1303/head\n0041911566620041bd942966b0fdf5bd53ee8c220755 refs/pull/1304/head\n004285b19a8198bfab56e74c4efaa5dd3573fb44430a refs/pull/1304/merge\n0041bb833df0473c9e06a15fa30931f62f43f8fa41df refs/pull/1305/head\n0041c1dcd02d5aeeaedfbe9a47719bdcf0517287064e refs/pull/1306/head\n0041bed15155e558a64bd7e1d023f0f6c01e4e89cc22 refs/pull/1307/head\n0041ae7549465893029628571539475cab50a5f88b29 refs/pull/1308/head\n0041fdd103ee379731772968bc0fa4abce0a222c482e refs/pull/1309/head\n004052355df83bd1f16a0d6cfdf839014d0f6a0d1742 refs/pull/131/head\n00412e0d369368249bfc6c27477840adfd1745067f43 refs/pull/1310/head\n00412ede4b86018662df57603431a2ca06f0e63fe0ab refs/pull/1311/head\n0041ffe128c7f53f9261c2e478ba220ab8c2bce7586c refs/pull/1312/head\n004110564b2cf9d3e0af7986404100358a81095fc991 refs/pull/1313/head\n00415d4eeedceccda7c2e4e55857b5a6adfae318248a refs/pull/1314/head\n0041a839faa175e5f0f8c1773cb5dc565771eb4b9f5f refs/pull/1315/head\n0041e1d82ae78462eb11827aceb7100afc9e6580bc3e refs/pull/1316/head\n0041b1d8d0975cf7e2cc0cffdb1e9d861f9ec3c8a464 refs/pull/1317/head\n0041cd7839e83d0fa2c941902e812164e8919eeb6add refs/pull/1318/head\n0041b729510125f5038236e9c2f739a0344813040023 refs/pull/1319/head\n0040de13fa317c1f5f068676066815c089d2dc6147d4 refs/pull/132/head\n0041734cdc193dfaa3632bd6bd1e116d1bae62f9a44b refs/pull/1320/head\n004169f6a1f844f349c8ba3a32a3c5da1096567c65ff refs/pull/1322/head\n004157dac2df4e12ac5ac067549fdcfc33f3625a68e4 refs/pull/1323/head\n00410449ab5546a48274f8db2472e8b21f90da47f1ba refs/pull/1324/head\n004126c21c1ca66e207f17944073b90c943e0447d5ac refs/pull/1325/head\n00410525f3fce77b48be23f56df109940605c512a64e refs/pull/1326/head\n0041ff220eaa3867738f3db0eb193b4b64b358ceb636 refs/pull/1327/head\n0041b7507c4ce4d7050d93cce250f9420bf499dcf79c refs/pull/1328/head\n0041c66c75f095bdbdc61c9f6a7918250bb35d11c27c refs/pull/1329/head\n0040189e780a8f8800d4a0d3bc302e046fd6de7a2193 refs/pull/133/head\n0041961a6e96dff63ee0143258b0c085d0902187a58d refs/pull/1330/head\n004145df50f1f4d0e6d4c0a0119a259beace2112bd53 refs/pull/1331/head\n00417ab9a1982ce11b5f59474d9d1c4290deb3cd66e7 refs/pull/1332/head\n00419ced3c989395984365a5cd2c756124a292692d05 refs/pull/1333/head\n0041290599c46d3019e2faf2c278c11a534ca383a8ed refs/pull/1334/head\n0041faecb02327ed55b78f3f52895749c9d5c83b5d79 refs/pull/1335/head\n004104a4c755a57d4eabcaeacfac73ae163261e2dcf1 refs/pull/1336/head\n00419e97654e7bd49474a89cf9ad0139bda19dc1e5a9 refs/pull/1337/head\n0041fc6fba1f9f88b4eec99b5222a1431f13b74456ec refs/pull/1338/head\n0041f1bab89b149ef99141a371a872979a47de900ce3 refs/pull/1339/head\n0040f2340c7785b24944f55d7e97e27b347be8df3a97 refs/pull/134/head\n00415a06f626752062956a8a1381504662c2d7ebd629 refs/pull/1340/head\n0041ea595ee08864ca521498095f830189a7c9df36a8 refs/pull/1341/head\n0041257c3048815f335b9f0a22fd4854b1237aaf0e05 refs/pull/1342/head\n0041bafbee83538cf951f538ca7ad13779f59f164d71 refs/pull/1343/head\n00412fd3ce652de76465b0f42f488020dc954885d2d0 refs/pull/1344/head\n0041c64bdb1c7e57087ed8d84e221de17d758391f2c9 refs/pull/1345/head\n0041747c018e63c009b2155bb4f6deb6a583d3caf22e refs/pull/1346/head\n00414e30fe74d61b9166b308ddc6ca31248ad92c0574 refs/pull/1347/head\n0041c3fc7f915e82757460710c0e8128ee5b36911035 refs/pull/1349/head\n0040edc675a835d97be1fca5e3cba3de1d92690395da refs/pull/135/head\n0041a0b692649edbd8b4d3e4fc273edb51b90dab4226 refs/pull/1350/head\n0041bee1b515d3eac86a33be45b026744db3594701f5 refs/pull/1351/head\n00417a8e666d0bd3aa6de59703c76d327d023e855eb4 refs/pull/1352/head\n0041b4c0c67c083c3f3d9275dfb2f3e3f30b014598f3 refs/pull/1353/head\n00416cc04160395a02237ea60fcb56369dcc2af898bc refs/pull/1354/head\n00417b5d44de35d37ec6af061e835241251cf0600906 refs/pull/1356/head\n00410ddb923bb03a95e57aa0e591c9d79a6bbc042ccd refs/pull/1357/head\n00415f4e98aebd5c88b1f31d0dc5fe89d756e4836657 refs/pull/1358/head\n00410b6677fdfa4169e0426b59f2b811c633848cef5d refs/pull/1359/head\n0040e9437545a50ce325010edce479c33fdb5fb8e911 refs/pull/136/head\n0041da17b72261b13286aec80d2720d55ded18ac9c20 refs/pull/1360/head\n004175df95cb365bf57e6605ec4768f11ad6cad1c5d9 refs/pull/1361/head\n004161ede2f2c9831b2ad582dd0b46b668e8f53eda44 refs/pull/1362/head\n0041afba174909676dd33be7a4004636350c0c4866a0 refs/pull/1364/head\n0041e2196d07a5f82f433a3d45db1ad79dd073fed364 refs/pull/1365/head\n0041d8202d6c7c333bd3cdd030884261af6f8af1edc7 refs/pull/1367/head\n004100eba200a2fdcd297b2aca58a6ba86eabaeb2b4a refs/pull/1368/head\n0041831e8fbd68217ff1d460dd4df4b21f7c22b6c7bd refs/pull/1369/head\n00409626f978d682ed60c4f361078d5add6f4794914a refs/pull/137/head\n0041ce2ad323892dc3a11963c9968da41582fa403fa9 refs/pull/1370/head\n00411a47355f103ecf545a1bb3a498f1a0b5b76b2fef refs/pull/1371/head\n0041762fae248f54871949683a7fe74bb3ed1d04f1b5 refs/pull/1373/head\n00416980afeb6774a3f8ef05834d8baf2df6a0f9bcde refs/pull/1374/head\n004144bbac892c3674e04a4c22107572fdb70870291e refs/pull/1375/head\n0041ca65a6f8e68e7c84b0845ae551ded0955b65dfd1 refs/pull/1376/head\n0041a6e1d21fc5b0fe82b02eac25b2ad3e06f5b7d851 refs/pull/1377/head\n004177404b3cbb5f0c567e9923373363670b107cb7dd refs/pull/1378/head\n0041e10cc0588b127c0a7a345708ca4694b23b27a42e refs/pull/1379/head\n0040e07f89546938680d414fd7b9485f3c0aa7ec0232 refs/pull/138/head\n0041dff810775dad1f692e87bf9411750c8ce22c8976 refs/pull/1381/head\n00416278f3cfc933a1a2fa5fe4c1006a8f3353e24b0a refs/pull/1382/head\n004103e3e96fb3dba1d920fd58fabdd6fbeb7c99bb69 refs/pull/1383/head\n0041e215906b2e757daf6f9cdf479c6ad074b965ea37 refs/pull/1384/head\n0041f60c4322be9edafb23af08c9be6c20c9f85108d5 refs/pull/1385/head\n0041b246f36763b355cbb9cc093783ca6f13f9cdc4c3 refs/pull/1386/head\n0041721c39c10965b428e222283aa864f06bb154c04a refs/pull/1387/head\n004171afc34970336601672c9edfbd3999e924a448db refs/pull/1388/head\n004078ca8ffccb0245a5a61cf24f778008d9787f0998 refs/pull/139/head\n0041e72e66bf5707b31c82e55f3292407daabf66e6b6 refs/pull/1390/head\n004127bed5c648b4c2bdae20ae119e50b968ea79ab1d refs/pull/1392/head\n00419ff43939cf0c8e6986d8e92126e6338863b648f4 refs/pull/1393/head\n00410a552e22b16e6fc24ea55f88d20c7901ad2c3cff refs/pull/1394/head\n0041a21275fef5419e8ec3c8c92826bc05d6f2c645bb refs/pull/1395/head\n004178832b0fc1490907c8fbb936dd7b1c43c5863170 refs/pull/1396/head\n00418951ee20a76f985f31f7adb31d4f3c1990300789 refs/pull/1397/head\n003fc6b4d55a540de28af226e774e0a2a49e70ab02d9 refs/pull/14/head\n004016c45dab0a86a40e2ba16d8efe04e0be57e78cea refs/pull/140/head\n00417dd1f2f0fbd3520d413b1b4a458c0276ca3f05c2 refs/pull/1400/head\n0041da9a726ce2f007ec4ee803ce0bd7157b4421e0be refs/pull/1402/head\n0041186c598fee1c82e4c4e904856d5dbf4fe7b109ad refs/pull/1403/head\n0041d8326a0f09b0ed2aea1a559d6af68458c63bf3f7 refs/pull/1405/head\n0041236c0c3ffc7ae031d21814b583c637cadd989d75 refs/pull/1406/head\n00412ef45eca094f6f574206fabccda2d9ba36ffd7e6 refs/pull/1407/head\n004169dba3b7a359925aafe3d06d7b6c5f0c40f360ef refs/pull/1408/head\n0041fd84167ec1429163534a1c312ea42f7b48fac010 refs/pull/1409/head\n0040ebb6c96b259d1a247c14f0db7adbd63035db97fd refs/pull/141/head\n00415b72bce47ac95923bce868b8fdedc204bdd54af4 refs/pull/1410/head\n00412dd82629ff324d2222d5bcec6fa1df77f023b330 refs/pull/1412/head\n0041566b2cd164e5b92b7c7993d45f367eaa4ac13293 refs/pull/1414/head\n00411f2e4049e40f05de6bc89a4df3b902617cd2c4c7 refs/pull/1415/head\n00411138579a9fa79aab8611dd866a5c7d7b36d5b407 refs/pull/1416/head\n0041520b03ea4d2fe774552ebbf371a546fe16e00d5c refs/pull/1419/head\n00403ea332e3d92983d258198c4944e48f2a679e6705 refs/pull/142/head\n0041cbae00c32292523e1178b7936cb6a0ee0c544ada refs/pull/1420/head\n0041df616c3977bc7a2125170035b062cfb931b39c0d refs/pull/1421/head\n00417cc8172bdb8a34456e676cee0d4ce9084ba7bbea refs/pull/1422/head\n004192677833ea4b356154ce80923125322345e0d4e0 refs/pull/1423/head\n00410cb307fa354bd8e66ae40b7fb3cc537b884c03b2 refs/pull/1424/head\n0041e5cfcb34d6c24a402aabb88f79c321124b89562f refs/pull/1425/head\n004136f4a8e330e49343137e747d02300ad6b352d7eb refs/pull/1428/head\n00414a4e9c9f75a503df0da30240b8dd382811a34448 refs/pull/1429/head\n00401e851bdc987c158bfe0edc3ce66cd3ab32b95efe refs/pull/143/head\n0041640a72f812d1681c148081ce769c94d18089a531 refs/pull/1430/head\n0041768bbbc5e3e37c678dfb001bddbf3c8c4a3feab1 refs/pull/1431/head\n0041e66f71fdd1c431a684a6d96b7b0e02f99e294e8d refs/pull/1432/head\n0041a0e482e060ff55476ca8038cac6e0b7c659c3373 refs/pull/1434/head\n0041fb2e26335ddb51333e162b916156c0884f567c37 refs/pull/1435/head\n0041b1772fe46558e79a885a654ff12d5a2e194c2138 refs/pull/1437/head\n00413681973c9df9739802d4137c63b769054e65ed19 refs/pull/1439/head\n00402e9dce6c48f32267884dd2b28842ec6925b645fa refs/pull/144/head\n004123939d417e265d55ed1fc3aabcd501507ee01ef2 refs/pull/1440/head\n004197c65d1cd8e2c8f901cf5fc86614310abb52fe9f refs/pull/1441/head\n004103dac88c576f8ecab3db909f629585712b8c0eb4 refs/pull/1442/head\n0041a6f76105ef194c3eaf7b4b7912a38f7294c07aae refs/pull/1444/head\n0041fb648a2ea697e46ed51c35f68c8236b3bd10e59c refs/pull/1445/head\n0041afe3ae2d7fe951c37913e38fa09b4fd3a6507008 refs/pull/1446/head\n0041466b94b687fc5518d881f59d1e0372443b841e34 refs/pull/1447/head\n004123532d67a96aeaf8b4a6361a3fadccc6d933f37f refs/pull/1448/head\n0040593ef33d4b5fe2d7feabb021d0972519deb6b744 refs/pull/145/head\n0041ee9ff50c9c2b4ec849994b49738eaadd45df8d11 refs/pull/1450/head\n00414d997c6f83857a7873eb78b0802816a5cba610d2 refs/pull/1453/head\n0041c1b4346191fe2b03d0c41637d53d00a84ed431b6 refs/pull/1454/head\n004119120bfb738b794199bfe5797b8248c6e1920492 refs/pull/1455/head\n00421d489a06e8f566b83feb9b10282434c69a2a848f refs/pull/1455/merge\n0041e93dad30305e69dc20372d1a7684ac76c2b977ee refs/pull/1456/head\n0041a5f94be445a32a0c5991e85d12fdda4a8fa2fc97 refs/pull/1457/head\n0041164d702fdd71ca10606e1701c9ebed15a885da41 refs/pull/1458/head\n0041d342f1d18f88041e3fbacda44330e22d9798e9e7 refs/pull/1459/head\n00406df8b6ad0a9e4dade94f2747d776d7dda1f4e4f8 refs/pull/146/head\n00417647947be27328f428cb50ef77189933561b6990 refs/pull/1460/head\n00418a4b9b4ffe361034167304c74c026ddc6ac4a33f refs/pull/1462/head\n004142813fb3381fa994874cd455ef72b49874ccda7e refs/pull/1463/head\n0041df4c6c121ab7033a14f9bb85f4e7416c8629c06d refs/pull/1464/head\n004105696886d50ce893da5dc7b6917e9947f3bbb835 refs/pull/1465/head\n0041fd3cb207b52d77dddceb45d01c33065f495ef029 refs/pull/1466/head\n00413a659000e96e36927d6edb20fb7361e74300ecf3 refs/pull/1468/head\n0041f49d889a01613f914a8d1768e449fa51a9127c54 refs/pull/1469/head\n004196895dba95749f0b38fb2d49f0506bfbbb9539ed refs/pull/1470/head\n0041f2f5eef8ce350ba79a9cdb67a96e968c3c5c5beb refs/pull/1471/head\n00415d7d6f1f25924dd01528a74cc38877510345299f refs/pull/1472/head\n0041b62dd25e1192be880b8c96e162ae5f6905524084 refs/pull/1473/head\n004164469920f86f96c92a5f69b313990f4b3b08b007 refs/pull/1475/head\n0041ff1fd64690c606dc96f61d599866f1ed7da972c6 refs/pull/1477/head\n00415ca8b4a96239e4feca8336661d98ea495bb1099f refs/pull/1478/head\n00414e696f6e40d363f43a084a0ada2144d8cb86873d refs/pull/1479/head\n00418a2e104021bd2cd6d2b69f606d784d1df6c7b8a9 refs/pull/1480/head\n00414f78a2c9c44eae18251b89aed140f9bf4985d028 refs/pull/1481/head\n0041bb284ef37e8480c03b519560f08f8b38dee5bb98 refs/pull/1482/head\n0041fa1d5b0c70383c08e7ee37bf66485198ff3e7ff8 refs/pull/1483/head\n0041c3a7a260d2f19a4d350e3346d008c776f74e9b98 refs/pull/1484/head\n004110e894be6f4d9b506f5459ea296592c312f5c053 refs/pull/1485/head\n00418d611111423fb3596be120ee6bcde94aeccf3745 refs/pull/1487/head\n0041afefc631fce6dff9770db8867982ffee8b091218 refs/pull/1488/head\n00400b8e4aa1499399f5212fd700cf2f310076ae8010 refs/pull/149/head\n0041ab1a2bc6c7337ace9e89ea483619794ce5a2565b refs/pull/1490/head\n004171ffff50fbf4cad3b72c45644e926b0378005212 refs/pull/1491/head\n0041bb95218921ae7fe9e8b4c3336278e078c315d0fc refs/pull/1492/head\n00415c20d41d46c16bfc6a9e82f744bd9b5541f3fd18 refs/pull/1493/head\n004120eab42cf1a7a89de8ff99af2d73a32d6cd5bfd6 refs/pull/1494/head\n0041a6764c4ed63427a5145422b6f7254ab4529bc8c6 refs/pull/1495/head\n0041c617d48580fe8aa02865fdd3c434d507a5ffe940 refs/pull/1496/head\n00418286eaba5003c774fc206fafdabb0a2f8ee2a50d refs/pull/1497/head\n0041f5f9b82390a6425baab9dd8d7c8937f0d2680b24 refs/pull/1498/head\n0041600434da8ba54186c894f8032da0cae6161d492d refs/pull/1499/head\n003f3c6e266b75f17fa1643a1d0b189b8d350bb8081f refs/pull/15/head\n00409aeaeccd95e696e800e08ccb6fabfedd7ad0e8a7 refs/pull/150/head\n004162a27e278e0cbd969b615943e89f1ed0ba4d76ed refs/pull/1500/head\n0041204898438a43b37fc7c56f5ceb9f2bce1e6d28ef refs/pull/1501/head\n0041f55692ca0190703a2e425672c45580b440a70bd0 refs/pull/1502/head\n0041ae9e151e3c9e7beb6e3acda1f075c928bef0b5ae refs/pull/1503/head\n00415c6a2af85703ae61fb0e53a0c0acc6ce2bd35918 refs/pull/1504/head\n0041908d4fbbd4502e8b6106733f88373ca813fb9dcf refs/pull/1505/head\n00417aab084a2629b0a33c7a314991b38f2bea80af12 refs/pull/1506/head\n0041341380d6aab2b719946ec0c1a5be7c0cd27a0cb3 refs/pull/1508/head\n004173116a39687c8aac406d5f3436ac2382cd67166c refs/pull/1509/head\n00410a69ddfa848b2722f6e019d5c975877d9015ff32 refs/pull/1510/head\n00418b22d1d80d3989e19f6c5c639f1d43756c83c4d6 refs/pull/1512/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1513/head\n004107f645f4d3f21c4a6e5d37dcf9433ccfe16778ff refs/pull/1514/head\n0041b9f8f60c3d32e202f61a38cd9298d498f9d47d6f refs/pull/1515/head\n0041f83d3497ba7dc9e2d636bb2e4ae997d199eac114 refs/pull/1517/head\n00416973913e0ac5903ab71dfbe1b9d36bfaca0e4f15 refs/pull/1518/head\n004116733b33f6b8e22db85c87192bf755b7e5ba9ce9 refs/pull/1519/head\n0040dc7027b6d5069c1decbe4db697f29b71dbedd0d0 refs/pull/152/head\n004169d63353a10a2ccb6bbca0cd8e2ea39f07b473b0 refs/pull/1520/head\n00410d459a3a0d41b09508ea497686d1570c86a1d103 refs/pull/1521/head\n0041d898942392a908832d3665b8c01b1d9a908bb4f8 refs/pull/1522/head\n0041f313b6cb25b09f2b46fe64f73006162494abf44f refs/pull/1523/head\n00413672ab6648e9a5a7be2a98a15ec365a10d2fd64a refs/pull/1524/head\n00410bce19c9b7efd2ff89cd8fe5cf8b745151c0422c refs/pull/1526/head\n0041112afa3e48db0f2de21a6a2eabf87c8eead601a2 refs/pull/1527/head\n0041d96bcd6c259eba410208303f608604f12d94d01f refs/pull/1528/head\n00419691f02b5328cc5cd5bd107c0f9841a0cb98660a refs/pull/1529/head\n0040a482a80f7e437e30efa5eb9fc21c09d025be30d4 refs/pull/153/head\n0041c76aff6be45a0cf7db5c5711e4e40113f64dbc47 refs/pull/1530/head\n004104340dfc2861f9f6f3ef103a0025a4c53a39fca1 refs/pull/1531/head\n0041e64567c751cf73ca090672778776a7175d5fefc3 refs/pull/1532/head\n004185a59eb6f51e25e5ec8671446d376d0f2f7da910 refs/pull/1533/head\n0041f6d77b8c6d7b853ccafb13efddec6462d1aff581 refs/pull/1534/head\n0041da0d3a3a6b2ffe0023b256cb8869931ee9c5b204 refs/pull/1535/head\n0041882e49547e2172435fd055f858a1d68ed0debcc3 refs/pull/1536/head\n0041b441fa217409bd0ce6aa4a837cd3f7447766fb61 refs/pull/1537/head\n00412f834281750332a14fa6c7c60696d1736927c663 refs/pull/1538/head\n004116cd702ae99af2129410201438008c0ed6a88709 refs/pull/1539/head\n0040f78f9c4948f1f81a50d51265a55aa736b01489f3 refs/pull/154/head\n00410c2ceadda13aaf9fe821891c11bc42b28f13c000 refs/pull/1540/head\n0041c6b0b982c9b39b3f31069e60453dae96c10866cb refs/pull/1541/head\n0041d2e4e5e58508c7aff695768346c200d57229a21e refs/pull/1542/head\n0041ee5cd9ad00462ab8b1602c25cce5d57247651ae5 refs/pull/1543/head\n0041db0dd1875b8ba55ae38b0fc205c57462d5264984 refs/pull/1544/head\n0041327590d91f1311a3a6e53cfc48e03b539cc7d955 refs/pull/1545/head\n0041ace6ca433914068b255abafa6fbd0ef16ba2d201 refs/pull/1546/head\n0041f19785406811be353ec421c04bce3f346eded10b refs/pull/1547/head\n004172e13a2121813367053d4ecc963d2305e85bc86b refs/pull/1548/head\n00418c4f183f2f6c6e646979f996b447e05fd2688ec6 refs/pull/1549/head\n00409d5ed41f9d2193e6794deee4f8bb7a813c9343b3 refs/pull/155/head\n004186322a7793fb78f2471a66f28d1380ee2ca72afd refs/pull/1550/head\n004145aaab129c2f7061b129b296c55c7c2ac48132f4 refs/pull/1553/head\n004149d849fd2e1f9614cb537fc19bc54e556c9b09b7 refs/pull/1554/head\n0041bbd33796f3faa42f40b28134ec8b3efc142694f7 refs/pull/1555/head\n004113af1a0f28d8a9bdfcf98c6ac827a6a3ec828baf refs/pull/1557/head\n00413956a7dd8a950fc58241286efda84dcae51abe4d refs/pull/1558/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1559/head\n00407dcd66ee089129b124af8b51b26fb8728af4773a refs/pull/156/head\n0041947083e60bd3c568927ba12314efa05aac5290dd refs/pull/1560/head\n0041f16c2fb4ef30b707b56556b2e2c40ed8cc9adf42 refs/pull/1561/head\n004166ae1b5c1780e6c8444b39ab3f112b7b3e02dda5 refs/pull/1562/head\n0041dceff72b9c029a97e42ec1a5b0769d06f153b8d0 refs/pull/1563/head\n00416a399d6d2ad5dcf71bcc04cd21e939de5e7767aa refs/pull/1564/head\n0041695353bc990ce2a62d31eb1fb13f541d1cd703b7 refs/pull/1565/head\n004152049e0509b4b44daac5b37016b0dbca1fcb37a6 refs/pull/1566/head\n004187d5eaca8701601a39947d440b185d894c737407 refs/pull/1567/head\n004142c31c24b1d69723bbb699578acd02af9f78800d refs/pull/1568/head\n0040c82b8e525303e6fad770e0540dad5dc00d76c83c refs/pull/157/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1570/head\n004192716c0c970fea2ce12cc31832b3f45f3050ca21 refs/pull/1571/head\n0041462f5a219f3f8f78092f98f26c5b58a847db6c7a refs/pull/1572/head\n0041c5b85a430a260fbd9cf2e4f360f8f20d53afdc53 refs/pull/1573/head\n00413019ec74ede79e77d5672fd022ca3177572cd72e refs/pull/1574/head\n0041194db15636a13d052e81164641cb23bb53be4b49 refs/pull/1575/head\n00412b5dafc68d002735348433ae0ed81908ecd785a6 refs/pull/1576/head\n0041f2c653dfbda3bab74478915ada61e0845012bd2a refs/pull/1577/head\n0041d870bf685b2b776ff7ba9eab78ed55505ce57c1a refs/pull/1578/head\n00412fa7f48896e8980b11a2b558ebd6a20e7be292b8 refs/pull/1579/head\n00408068436b2a040871c83cf6f39c2d0d74d4651e47 refs/pull/158/head\n0041d958e812462e34c99c37d217f0f08ae91b3abc03 refs/pull/1580/head\n00415194418a88de9fb53ab6ed80432831331e15bbae refs/pull/1581/head\n0041c3a4e79dbd933fc8e947815c666561d51d795f91 refs/pull/1582/head\n004131da8dad3c1ac11a0e12490fcb6e98fa8f2c28b7 refs/pull/1583/head\n004125ef6c1f49836f51ebff2f4135e4596992d678bb refs/pull/1584/head\n0041e0ae728d9925a62008f60a22e1198f06a6ede5c6 refs/pull/1585/head\n00417fa05c71e0d2b2217facd2bad243781858ed6e9d refs/pull/1586/head\n0041ff5cde817af1c25f5fa26bafc4ac4073bcfb1e09 refs/pull/1587/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1588/head\n0041484995c39c9c8cb99c885903c64a06b782488b00 refs/pull/1589/head\n00406fc981f0f578112dd57d3c9221d8e8607222ea02 refs/pull/159/head\n0041a0dc900a228f0c46f97b3e4c59acfe55c96ef2c6 refs/pull/1591/head\n00417df0c764d7fc60f3b32fdcd11be57d153882902a refs/pull/1592/head\n0041426317bfe888889daedec42b58f58b3e1e2da129 refs/pull/1593/head\n00412c9256efc644bf765c45e5ae8a2a8fa851d37c47 refs/pull/1594/head\n00418405e05a3f332b28d57837397ce28a63e48f795e refs/pull/1595/head\n0041fd766e7699bdaeffaf5625a4a583dbd5d4b68141 refs/pull/1596/head\n0041a1fa4e7ba21116c602b2e2d196eca51caef853d8 refs/pull/1597/head\n0041b7919627c927d8559f12538106956397a3ae92ad refs/pull/1598/head\n0041d796b6f8340e2bdafa4e4073fbda29550b21c90b refs/pull/1599/head\n0042dc55d0d581c9390b6f71cf04de9815c5e77d7771 refs/pull/1599/merge\n003f16b3827af689b39902ef03363e8f06aa8a917b37 refs/pull/16/head\n004048d9e4009aa1d2d8cd18f948ed4549a55eba97b3 refs/pull/160/head\n0041d3f1dc58018d6b40ee2f05e5f6821671b319c3fd refs/pull/1600/head\n004131a64f5e4936499faa79e40018515ea58b3c0302 refs/pull/1601/head\n004100a02591e76295b34878ba180df0b8a9564a3b92 refs/pull/1602/head\n0041f763b73ac812aaafbad92a084773bf1d13f80943 refs/pull/1603/head\n00414359fa74d8b9a01b428f725d692299264e80921e refs/pull/1604/head\n004146d102ceb52c713644eadaa7846118c8aeee3a09 refs/pull/1605/head\n0041e98427ba70a78b5d7a64c427e7a9cd09de7b71ba refs/pull/1609/head\n004007f015f1904e253e994ee240a9615bf16315a5f6 refs/pull/161/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1610/head\n0041f2376611924effe0f0f03c541f480137d78e573b refs/pull/1611/head\n0041a0f7092b2162eafb07afc502fe26c262c75a51af refs/pull/1612/head\n0041e7a8372d6366eb5d6eda0d313e5a0c4d6f2e7b10 refs/pull/1613/head\n004156cf6c79473ddcd9db99668d49a23b29c01a667c refs/pull/1614/head\n0041eaa3e7ffff279d64785a8ec77bf6d7f5df25b7da refs/pull/1615/head\n0041cc8c5840078f65bec296c001effef0c762b990d8 refs/pull/1616/head\n00416b3f053810f3d897cb1c543d109216751697bca0 refs/pull/1617/head\n00412b744813cf6bed7507c0a5003db5df0aba55fb7a refs/pull/1618/head\n0041ca91696bdfb5a59629a3471daefdac6d4e2ab0a7 refs/pull/1620/head\n004174214297869b28ffd536479c068ecaa3997fb7b7 refs/pull/1621/head\n0041be0908a0431c116aca177fb7dfbfc551ccaf5861 refs/pull/1622/head\n0041e5c686a63314322ab70fc59f181733bb23fced34 refs/pull/1623/head\n0041b84b0eb192fd47997e3d508fd2fcfa5b7763e026 refs/pull/1624/head\n0041aa15587ad20ca465e390add59358df0cc2830608 refs/pull/1625/head\n0041414762a65ad10f46b75a95dbbc8e56de95d5344f refs/pull/1626/head\n004131a5726b22a2cb4cb794b01b5d3a75ff934a6ba7 refs/pull/1627/head\n00413691e6cf3f6767d85cdc6dc87de6178d8e00a84b refs/pull/1629/head\n00400110a956f7c25b31435717b7c6f517fbd4ecfc9a refs/pull/163/head\n0041473061e7dabc8c56aae9fe447a3173db6c7c3380 refs/pull/1631/head\n0041320bc9418314813464d0b91d5f820526e6dcaa40 refs/pull/1632/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1633/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1634/head\n0041ced684cd213166117663572f0f13591bf5168ba7 refs/pull/1636/head\n0041653eb97d9afcaab55c7157a3d9a7896f9f8a9cc0 refs/pull/1638/head\n004002c71918d8b56bd9f6137e1a526d1ac481602c25 refs/pull/164/head\n004127a37fb1ab3e5fe5a1e9b11beaad54ce9281e525 refs/pull/1640/head\n0041ad1fdf91c8ee67b0d073a6a438a52209cb15862e refs/pull/1641/head\n0041de207ef037cd5ddc2556df0610a7a172ab51dbc6 refs/pull/1642/head\n004145f73022342a0bdbdac7417629105c4baeafd79c refs/pull/1643/head\n0041b985b6379b054c5adb75044640bf5cb9fedfa4b1 refs/pull/1644/head\n0041843a90655a84ca944e43c96e71557c085e294d9c refs/pull/1646/head\n00416840f1c445eb9105a17e786ce13304d0e4997187 refs/pull/1647/head\n0041b6d6f53c233c8f7b52309335a1f5eca9fc814165 refs/pull/1648/head\n004141d16635e58d5c6179192206758b4270a9e8f965 refs/pull/1649/head\n0040be088688bdaf7b272c7811e4869caffc60a34d87 refs/pull/165/head\n0041511c386150398998d87896badef720e894330987 refs/pull/1650/head\n0041cee9378ac0bb51431bed15a4a4a137820340fb70 refs/pull/1651/head\n004181e9bf6e4bc3d061c601d117692c9dc9fae590b5 refs/pull/1652/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1653/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1654/head\n0041b37b4076f5874c11113b926c8fab9f7dc2444952 refs/pull/1655/head\n00410b9242402f6b614a7a964b191dfd82d91eb807ee refs/pull/1656/head\n004103285c5cc430a2d4d95b25e43c4b9fbfaa66b75d refs/pull/1657/head\n0041cf437402222547477d626343ed0afdf5efc0f8b3 refs/pull/1658/head\n0041fddb6460bf6b561b82bb98f3ece98eda40231dc5 refs/pull/1659/head\n0040c7463a50e9d50aedfb8d2b01f8fc673dc1972f14 refs/pull/166/head\n0041330dcc98ea9fc10d8927d289236eb8c918c4bc51 refs/pull/1660/head\n00413412588e0eb37f94e5a155797d6a223fe049461b refs/pull/1661/head\n0041e3ba44799ec67cc578e33f7e397c529ce919f838 refs/pull/1663/head\n0042daca13a892bfabe2290650e9f908617e47230586 refs/pull/1663/merge\n0041e4571b9e0bb399600daa49e941e0f1e7c487ce2c refs/pull/1664/head\n0041605b1067212bcd7af0737f42280c049283d7f7db refs/pull/1666/head\n0041947c24007cc76d6c31fd44f2849dbc977b4bad0b refs/pull/1667/head\n004171767c8f8d91833961d253863a3bedea974bd26f refs/pull/1668/head\n0041606a2e0d39ebe60e887e64c0e4e33c591e997e19 refs/pull/1669/head\n0040550ded776cafadb014dd81dbaf58c469d5af6ad9 refs/pull/167/head\n0041c0b62b8b28336c5a5086870c3eab71aaaa150c4a refs/pull/1670/head\n0041c02ec43a14e1ec42052ef738745864d69e7eefbc refs/pull/1671/head\n004178391b1c345356ec78e9d6c033d67443952122a6 refs/pull/1672/head\n004179b4e517f71483bac6f33db2c9c070d4abdc0e45 refs/pull/1674/head\n004169a3f0506feb52f5b5705dae8828f1a20c43bd6f refs/pull/1675/head\n00419e54ce53a375d24abc214619b357acbd424e5814 refs/pull/1676/head\n004122a5879e288c1afa2052f715bf6cf92ba93ef076 refs/pull/1678/head\n0040d5ab3681b90575681caa9144bf1bdcdf723150f2 refs/pull/168/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1680/head\n0041b49309b4e8a5a0cda1677745b2941be87a642ff3 refs/pull/1681/head\n0041203cd06339c36b8767e2e60dd55bbc3ac923b645 refs/pull/1682/head\n00419eac881720f2cd451c7b48b3b2dec5fafcfc6acc refs/pull/1683/head\n00412cab290ed8db8ba56e95e12081a24abcb9746ef9 refs/pull/1684/head\n0041bb280dc1a53c81287eda1e678c25629c8ebb8851 refs/pull/1685/head\n00419b5ad70828ca0c941fc424fc35e10eb2eb53d475 refs/pull/1686/head\n0041c2b84a61807bcf11f35dff1aa544b0a92a0c6785 refs/pull/1687/head\n00416f6fbd991bafe78b2b87f92f5c6f8327888dd339 refs/pull/1688/head\n0041d3818b9df267986e07e8df723464e09cd195d583 refs/pull/1689/head\n0040c32413680d38e366510a47a6c150eefede26987a refs/pull/169/head\n0041f7b84db702b7b111c176780a17a24d88c721d49a refs/pull/1690/head\n004133dc34724f0cbe5de45246ecab12c5a3c1ae5602 refs/pull/1691/head\n004158c03b5016c7d62755205a561b10babe4f24b472 refs/pull/1692/head\n004122c16d0528c48509297dec8ad6207ce879f20f07 refs/pull/1693/head\n0041194c74cbf4ee1ec28b85979c2424b73175205375 refs/pull/1695/head\n0041ebf909a4cd8718cc731e498ae9ec5cf11a148e1d refs/pull/1696/head\n004126798baab325cb4720e80dd2bf5ad4d3ddd49995 refs/pull/1699/head\n003f3a4c90b02ad2afbe09997cb3cddea3f2f96cd710 refs/pull/17/head\n0040ed7fbcee57b7f9277ffe1260e3365b4b8c628b26 refs/pull/170/head\n0041f6be2d94e8a159d03682495360a84a99e2849ef7 refs/pull/1700/head\n00414cff272b844f4409267f6d4a0dfc35d522b4b1b5 refs/pull/1701/head\n00417d9cd867535b37dfb109312c118fc1c4d99a1e12 refs/pull/1702/head\n0041402453d160e42a2becf0454355e8f21392436ca0 refs/pull/1703/head\n004166d3d1ece5efadd29e2ed40613080bad24588f00 refs/pull/1704/head\n0041d36a83b869ad816367e3a520df8b34e0fa30063b refs/pull/1705/head\n00412d5d59d0c19aab6f41ef43dfaa5f5dd84ec3635e refs/pull/1706/head\n00411dde7bc4eb32f5229e4395528009a6abff975fee refs/pull/1707/head\n004167a4b8816b0d95195649426e01c2d5a285c87c69 refs/pull/1708/head\n0041583974851f9986aaf9aaae1684ddc7da54061668 refs/pull/1709/head\n00403f8f78a70ddddaa6e381fef4e575e5b0bad9f403 refs/pull/171/head\n00411f78db7c0890d6de7d968b149da0cf6eb44bae16 refs/pull/1710/head\n004181b355fa672aa9f87f78ac1365a9fe4302ae6f26 refs/pull/1711/head\n004147050c34195f06ab88e8b2e5d41491ef82a897c8 refs/pull/1712/head\n0041859de7de8c7b56c46fd0a2afb1a56bf7be4a0efd refs/pull/1713/head\n0041508ee173626f605678598d0363806d452e6546e7 refs/pull/1715/head\n0041e431c79ca359bf4a6dc5e756ca2416867b1f26a2 refs/pull/1716/head\n00419bb401e34362ff8f0ef0c7b1e471126a98e6e72a refs/pull/1717/head\n00414a9f3908193b197e0fac3c04a6820f9947527149 refs/pull/1718/head\n0041c7c27dfedee3c8fcd928c801e7b37f24f3604c40 refs/pull/1719/head\n00416eda4698764d62eb549a653d71fe9c89efbda7ed refs/pull/1720/head\n004147db827f4e9e07495e988979b2bcc5f0f1c3ac5a refs/pull/1721/head\n0041dc37d4ac77c3a83b1209c9ac9d386f7a21164c6e refs/pull/1723/head\n00412856b0618349793952634c56899e3a59cb4bfe4e refs/pull/1724/head\n0041137adae315ed82442e245d922230737921ab8476 refs/pull/1725/head\n00417f6ab1cddbeab54f17621134f12643dcff6e78ae refs/pull/1726/head\n004111a2bf4d085236a9cbe9846ff9f22f9976e853bf refs/pull/1727/head\n00416b9ce0fa8acc5fa39b58c998050507de1eafc74b refs/pull/1728/head\n0041eba0ba181ab8cb8f9bdd603762d9ca1d0ee03e6b refs/pull/1729/head\n00409bd080d1c1e0f331e10ca935b7ae84a67743e00a refs/pull/173/head\n0041621b55a6453ea373b338093a4d6ebb246816dae4 refs/pull/1730/head\n004166cf11882a13aa5ecb9dca3a0856625d40a0661f refs/pull/1731/head\n0041ceb4390ee4f63854ee38c1ceffe09bda29ec19a9 refs/pull/1732/head\n0041f046d5b5e50c64f21d971abdfa97cc7d40bff25d refs/pull/1733/head\n0041299bd320c28aa4aa7a7ec3248ffdceddd791f1b9 refs/pull/1735/head\n0041dbb64a42761a875114e956ec6070defbfe422b26 refs/pull/1736/head\n004168e17a207baa24049da479274cfa34d7432c90ac refs/pull/1737/head\n00414a9f6c8d165fbd1f30eb478e7d09e91c185dc2e7 refs/pull/1739/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1742/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1743/head\n0041efcc272b15e6678ae0b87795b085779de6cc6b64 refs/pull/1744/head\n0041afaa7c3ae485f10eb98db9c9ceb3a1b3b135bdde refs/pull/1745/head\n0041fdf37f671a1e1b7fd1dc183769eebeff9563f252 refs/pull/1746/head\n00412c85053cfa420c869bae7ef023c52300eaa0ad2c refs/pull/1747/head\n0041d28d46d556d50949a51ec2b2b9e736b99947cd36 refs/pull/1748/head\n0041242e8396de3475422e0e4b575d2be8b13acfd504 refs/pull/1749/head\n00404f150c542aa5139058ccf57dcad562890916b477 refs/pull/175/head\n004128b5f8610a75ef7f7eb4d0860391893a023a522b refs/pull/1750/head\n004161121d34173f4e17d2787d9bbb9beb50988e5b0f refs/pull/1751/head\n00412bae8356597b70e2a0ec11fb906c9f4e15b0ca12 refs/pull/1752/head\n0041b1e4f7639d8480a1dd8b2d8b58172b5654bcb5b0 refs/pull/1753/head\n0041e8d8de2b047665e2feee094a948020aab6f0cab1 refs/pull/1754/head\n0041dfe0cb485e1b95fa73d7fc01189d7342336139bb refs/pull/1757/head\n0041af351e06e20230e63147e6f91ec49ff018b6acca refs/pull/1758/head\n0040697026d4e8b2db4ae98b820d3d5219bdf6447016 refs/pull/176/head\n0041e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/pull/1760/head\n004168f6fb1246d1b0fceb91454d4350ec541c5f6c0e refs/pull/1761/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1762/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1763/head\n00411fa8a78eaa5b22679c5eef46216f5188a1d94fa7 refs/pull/1764/head\n0041cbc1038324468952ccd6d73cb8139ac39053a443 refs/pull/1765/head\n004156e0c5dc850587be1566c9f64793d6d6d5d236f5 refs/pull/1768/head\n0041bb81d37d4e36bc8f5ce4bdd330670bcb3e0d50fe refs/pull/1769/head\n004196aa2ba53a2ea486f5a769851a40c6695ae1e49f refs/pull/1770/head\n00412a288c660a53a7e834900ac484b30484ee630045 refs/pull/1771/head\n0041217c352ad074f4d185d93ceebca8eb349ec6c59d refs/pull/1772/head\n00417d78ea23fd1e33058e26271b9314228c52ccfd9d refs/pull/1773/head\n0041bc8e36df01367794ea3ef321187a325a9ac69db4 refs/pull/1775/head\n00417d2c3c8a499807f48617aef10ff2d38777b10e53 refs/pull/1777/head\n0041c25a90ec1432dc8d3bdfd8a4897eec1f79e86a79 refs/pull/1778/head\n0041959f67abee6f9d04caaa8d7f89fb4e4bed97643d refs/pull/1779/head\n0041fd17178287784de7abcab551e8d6a3f307197e6e refs/pull/1780/head\n0041e3ca3320607036d249dbbf26371909c8cdb4e553 refs/pull/1781/head\n0041d51aefbf41e7a618a29bbc5d27e61b3d695b5bfe refs/pull/1782/head\n004185d032609f688eabe9afdd6e913a3eccbf02928c refs/pull/1783/head\n004123ca8b3c69fb1aaa5728473b063576f1b2d39375 refs/pull/1784/head\n004117103ff4a194a539f5c72bea680e96d82fded25c refs/pull/1785/head\n00416ff3ddf670d367e0bb94ac1ecbc16a7b84c44da3 refs/pull/1786/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1787/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1788/head\n0041d780e569beeb0dcbf49dea00227b07e7a0557e07 refs/pull/1789/head\n004138818c7fe460059b864af9fb064ef3b372faa3e8 refs/pull/1790/head\n0041c830fa55637683630dce94d4bd1979bd6eaf19fa refs/pull/1791/head\n0041fd24bcecf02345fad0eafb863c1e1a96b8c690ea refs/pull/1792/head\n0041ef51a60c61079cee1ad74195e7ea775ce69cb4a7 refs/pull/1793/head\n0041151da60d325f776b3dd0aeea7d2b772e19d7d17b refs/pull/1794/head\n0041beced838e4690d90045aa67d95eb354ad8ff22eb refs/pull/1795/head\n004167f820873e8377ea084af14056d22554ca7cc21a refs/pull/1797/head\n00417a0f284b57753f79f3d1613fab4b93c8629e19e3 refs/pull/1798/head\n004175f2c449c009b52d0a603bd3cbe8eeb725f915bb refs/pull/1799/head\n003f53aa980fe3061b5e6040de9c8fb10012bb2f8703 refs/pull/18/head\n0040b1cb385e06354cf99ca214be195c0700ffcbc0cb refs/pull/180/head\n00413eb63513540f6bffdbd231239f42f88ddfebec68 refs/pull/1800/head\n0041643497bf5bcb01d049b74b7256deaccbe7499250 refs/pull/1801/head\n00412f72f7cb650e4bd70af9f952839a0a59869e3a65 refs/pull/1804/head\n0041cb15bb31308c98689ae4eb9146890eb4c4b85076 refs/pull/1805/head\n00414a73eb85606f042cbc4cea9806bb6a5aa8aab684 refs/pull/1806/head\n00417a5731326269b729d41b2ac688e39b590748a842 refs/pull/1807/head\n0041d61d2a12da28c0a67e8b2a6a2901ce3581582bda refs/pull/1808/head\n0041c06ead49f70c83092494dd35de5cc23003373616 refs/pull/1809/head\n0040a93a2680f94ad8e04a1103aeabf2708bd5980e8e refs/pull/181/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1810/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1811/head\n004164c2d8663c768215adc1abfc163b90d8c00f7774 refs/pull/1812/head\n004166ae46ddf21a5c9ea38179ee3cb48e5e0933fb93 refs/pull/1813/head\n004162d8b81f9d11177615ab69ad569599f9749c988f refs/pull/1814/head\n00415784c6de647fb7d0e8667740d784bd6855da89de refs/pull/1816/head\n004140d1eaf19843a7fa8e8aab0f612829d02fef95cb refs/pull/1817/head\n004177db6fea24126618973c77b5d1085b6d731abaf7 refs/pull/1818/head\n0041d218d64ce9526b17ace67ffd6c302cdc0d06b330 refs/pull/1819/head\n00413e4acd6540a4da55ca5e2d8fefef07b740d1c752 refs/pull/1820/head\n004155a2cd3bb64e3040d899bf5cf8f1cd4d6580ca5c refs/pull/1822/head\n00410ec6da65e6e898a079591b57055efc061c9cb6dd refs/pull/1823/head\n00413956b56edf3c580ce664f26ba4a2295204a3b7c0 refs/pull/1824/head\n00414716d0cc284b1741d0d3233c73ea47af5bceecfc refs/pull/1825/head\n00415f788d250cd76b750f76dcc6db2d440bd92fab27 refs/pull/1826/head\n0040c36e358ca340e5143c1bae900f62af9c9992f8b6 refs/pull/183/head\n00419a37f354a6af47436166d5dfe516c3689f402484 refs/pull/1830/head\n0041e075984e4ef6a2a4d844c42cbc18543abe5dd211 refs/pull/1831/head\n00410bbc9e95cffef61511f1de8f830e336caa15a958 refs/pull/1832/head\n0041e5bed10b2bd6973ad2a063fffc38780533f8cd3b refs/pull/1833/head\n00413e0bc06126d76b17038544e765365e04f10f12ad refs/pull/1835/head\n0041ad1e720055786f3cdb9c759e5061343c8d00b279 refs/pull/1836/head\n0041bf17b39beef874e602d3b36861aa1eef469aae3f refs/pull/1837/head\n0041ca50521d299252e3df50cc973da8d58ea17dd9d8 refs/pull/1838/head\n004180a2263da5503241882ca0477ea1d99b4c7a20dd refs/pull/1839/head\n004073c82e133e8dc40db2556497ea58ed1087031505 refs/pull/184/head\n0041dd45b9f4aad94150181247b515d878a258593f65 refs/pull/1840/head\n0041e95f66bf3fae34c9834fe303119f68d09b524c50 refs/pull/1841/head\n00417879e9176124c4e6bc5d7dc9e2aa8d00a2050411 refs/pull/1842/head\n004183fc002b5356265d0459729a76aca21324a27401 refs/pull/1843/head\n0041590f17a7d4c339439cc3a0366c230fe60d0ee52f refs/pull/1844/head\n0041a3e12ab1fc688a3d5d68fb004f034dcd83159e50 refs/pull/1845/head\n0041cc048c4cecbfb81fd68db3de91cab8a6d110a4ef refs/pull/1846/head\n0041694695a536c2feb96e0817856cd3b729017b66db refs/pull/1847/head\n0041dac04009c14513b018b5a47194aa0c45cb15a3d2 refs/pull/1848/head\n0041c53eab92dd9d8f1b20f3ca84fabc29456767c562 refs/pull/1849/head\n0041cf9cb9a57237917ae1ff74f121a1fbd6d8e28581 refs/pull/1850/head\n004139bd4443236a577e81d79eaf2adb56ad5bad7e0b refs/pull/1851/head\n0041ca1234fba4d0f639136a17642bfaf8696100148f refs/pull/1853/head\n0041688edfbf064c5cbd29ccce6683cfff62e2a92841 refs/pull/1854/head\n0041e07806737984c72dd2df3fb62f6aa887074abb28 refs/pull/1855/head\n0041950f94d8447cfe8e381c33003731bab17764fc53 refs/pull/1856/head\n0041c9e6324f270b54ef8528ab8a2e54663cc1522bfc refs/pull/1857/head\n004125ab614caa713ea1b3aa85d6ff477956307fbceb refs/pull/1858/head\n004177d871fe2174230183e7a2c9ca37bfc3147c5dca refs/pull/1860/head\n0041490ca7b0714d188ae4fd43dbbf9f603e257b33d2 refs/pull/1861/head\n0041d401575d9c4480a77ed36f22013cf94ba28766c9 refs/pull/1862/head\n0041245917c80414c327aa4c9b4dccbaa6a8de1ed76e refs/pull/1863/head\n0041775c151f3e1a2deb698444685f477766b2eb7ac7 refs/pull/1864/head\n00419cfa3f62676b13f7e218003e801796ca01a26e8a refs/pull/1865/head\n00411ed057902ab3c93c7bc09b1aea1868ee223204c8 refs/pull/1866/head\n0041bb691dd9c831e92f4d12e842b20ec6b198382030 refs/pull/1867/head\n00414f13093d0a7690cd6f53a8a00eb5e961b450e96e refs/pull/1868/head\n0041be23c09d0085e393c609425c87e91d2ce49e4b4a refs/pull/1869/head\n004094fad49150b1245d6df17ef596ccbfdf5e53e23a refs/pull/187/head\n0041adc617b13cacafc11073da7c987c3b4aeebe7e8c refs/pull/1870/head\n0041e7abbfdf7b7587088aabd9b6e6def35157483259 refs/pull/1872/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1873/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1874/head\n00418e73fddffc8970eec9941c65f48522e41fee367d refs/pull/1875/head\n00417870cf2e5136283da85180aa1a4132d0b945e46d refs/pull/1877/head\n0041d5e7bc7be4b270767aa04de43bc3af305e1827cd refs/pull/1879/head\n0040bfcac75d68e64f860fd27dd089f76f6e076ca1e0 refs/pull/188/head\n00412296fd9ca7299a57fa2e8ecb59623a85653183df refs/pull/1880/head\n00419ab39d23ff2b19fa564815999bf51be509ab7b5b refs/pull/1881/head\n00414cf4e663f58e4f5edacda884bed5c035124dfd6c refs/pull/1882/head\n0041bdc42a80a2a7d0ebec1c9ab90a945f344dfd3f3f refs/pull/1885/head\n0041f3d970e2aed28a290ebdc777b1bd9e2a6c69361f refs/pull/1886/head\n0041f52afdc4daed2649a3bd78782713203bb9ec1787 refs/pull/1887/head\n0041a13e63a984798aa57eedeb629a4e42a059304825 refs/pull/1888/head\n0041f2e2f18765b2d1fd298a58c3ea90283fce07cca9 refs/pull/1889/head\n00407a95f8a55b26adc8f99b9e2c54995c0ee85d8fa5 refs/pull/189/head\n00412ed0a0d114dc10762bf4a4e6ce2572f04d4c6abe refs/pull/1890/head\n0041cca09665a98cffb1de8a990b68eef7ab3f42ae47 refs/pull/1891/head\n0041f209a2ffc58b2c9550528b01e5619bb3cab1d82f refs/pull/1892/head\n004141584ca7cbbbb18f1cde26eabb104249fac64617 refs/pull/1893/head\n0041c3e7497e240bf02819dc7d0bb5e666a48669f0c0 refs/pull/1894/head\n00413eba8f8f280b0be0c274880add862f86a1aaebeb refs/pull/1895/head\n004124242e093ecc652d0419c06cbf0f3cb4336ef76d refs/pull/1896/head\n00418b61b330c72c4c1513cd72ffac2aac293cd3a3b7 refs/pull/1899/head\n003f1a0925b76e59133372fc1ba7ee5599b735be1611 refs/pull/19/head\n0040ff96305637fe8ce3e1f744bfe71eef3bfdde98d1 refs/pull/190/head\n0041cbd943c6525c545cec58af0404e17407bba01195 refs/pull/1901/head\n0041fa6cce474ebdf2ff70cd23969df81b51b28249c0 refs/pull/1902/head\n004191834bb605717048dfcb97d50f1e211b7fe18a10 refs/pull/1903/head\n0041e44a5ef5ff2c9c28c4e4f6e72e57301637991d89 refs/pull/1904/head\n004101318044062e0dcb5c3e49f6536ec235ab23b0c9 refs/pull/1905/head\n00411bc915c5b605eea03cb4a8290ae461462e1ab24f refs/pull/1906/head\n0041cae78e108c9cb5fff71e8cb8741349b94f2ad4ee refs/pull/1907/head\n0041b6b055ed963bfb379183b8c02c6ab208e3d6b473 refs/pull/1908/head\n0041183eddf9cbd560150b934d0f1f4569f1bd882a3d refs/pull/1909/head\n00406ce0980f6d150f2624dcef29836028a2cb1f7870 refs/pull/191/head\n00414402048781f29961cbdb12ddad0ca8d81a196afc refs/pull/1911/head\n004157029178c367dde42ce6ea623fbb49c05e051f22 refs/pull/1913/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1914/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1915/head\n00414fe84f446a4c7ba338e110ed8f61418adc4c022c refs/pull/1916/head\n0041b639422ec1c00424fd896389628e8734902c4f1b refs/pull/1917/head\n004141793010447396bc491832ccb9440144cbf74da0 refs/pull/1918/head\n0041772dc97d1ef15899ffd143c7954ec412b0a416ee refs/pull/1919/head\n0040cea55d539a5935d83a95b3b71e1800a59ca6aadf refs/pull/192/head\n0041faaf7ac71d88129f9d698c85473a5180e0278c83 refs/pull/1920/head\n00418081e72673e2f1a920091f3bf221093d05276dfb refs/pull/1921/head\n00414263ded36f0b487b333e3871ff1e316396fe9ffb refs/pull/1922/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1924/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1925/head\n0041085fd13676bfb1f72c4a45453c77befe939a86ba refs/pull/1927/head\n00412890c32995007b6d48e87e20a853a86b9832ab0b refs/pull/1928/head\n00419e67ae92fc31d9eafb455aab6fe32eb5e125c30b refs/pull/1929/head\n0040c4eaf01af99cc8dadace1d1d127086a392813469 refs/pull/193/head\n0041f68c436ef6c041a988c803ef30185652612a73b8 refs/pull/1930/head\n00419f56be92d5c167c9e54911f073bafb528b18828a refs/pull/1931/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1934/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1935/head\n004128e4a3f2c16e21f20465082e4e63cb8e3503256f refs/pull/1936/head\n00416e9281133ab28e8bad2525600907428b1f70caea refs/pull/1937/head\n0041cf2236dbed3e22d7f04eb2db011b95874674e87f refs/pull/1939/head\n00408863cd9f782c86bfc463f1d8384c89027224aef7 refs/pull/194/head\n0041d49b4addeac1932ce5edc072938940965633e5e3 refs/pull/1941/head\n00418fba4b1e07a31d6eb84de0d3285a230de18ce490 refs/pull/1942/head\n00412d8629e6324a07fa6bcaf99c3d851effe085606e refs/pull/1943/head\n00413d608d7911850e4edf5a9417a8783a0375aa0fce refs/pull/1944/head\n00410e88f4836971e5fd8c9216f9d0a0f62a73109764 refs/pull/1945/head\n0041312e083a7df0caa21a7460b124c131a35540abc3 refs/pull/1947/head\n0041b195aa96dd4c1ed0bfc423396702b7cebd38b64c refs/pull/1949/head\n0040e18c14875dabe2847beccc4ace2c8fdefac4b003 refs/pull/195/head\n00418a89d1ed64499e3e23c85ac1d9fc87b093d88f52 refs/pull/1950/head\n0041eeae4900643721f121259e79c101e7964e7b26e2 refs/pull/1951/head\n004198a7e10c7c548bfab390374855271f4f06dcc94a refs/pull/1952/head\n00418e2e7cdf1a1c84a06c7ac1286063b5184844919a refs/pull/1956/head\n004198385fa0202ba48d9c829bd4cd438ff735c48ae0 refs/pull/1957/head\n00415f02424e5e280ef631ce64faa518a33ec2b356d2 refs/pull/1958/head\n0041c655361c61f4a8d4cc5501559014c4da4352d3cb refs/pull/1959/head\n00400203592563e6188de76fb2e29f4c5a2e5f722626 refs/pull/196/head\n004172d6bdcfffcda628c98c17935d4dddd8724612d6 refs/pull/1962/head\n00412f5322e8632c0ec51dc668b92cfe1164b811c60f refs/pull/1963/head\n0041f33bfb247752d7f00c9854af85f59cf146ce3b2f refs/pull/1964/head\n00410e5a9d1b17f94dd79f1bede6ab86a9ecdad51e4d refs/pull/1965/head\n0041247452069e49b1bc2ddebddb39f4b1a42f7dad33 refs/pull/1967/head\n0041d2b9459487c77b121ebaeb1936c98f6fdc4efd6f refs/pull/1968/head\n0041adfb91949539a56ef5a79dbbf1440d8cb98e48c1 refs/pull/1969/head\n004039610731e0ec8d72c80702b55a15478a948ea7c4 refs/pull/197/head\n004145182d7887e98e3be7b417e1aef6fb5e96c69e4f refs/pull/1970/head\n00411f8c81e7dcf2453dd59ab709d3cf49e8961de5a4 refs/pull/1971/head\n00412fffcbe318fa873851db2b093533787d55af5988 refs/pull/1972/head\n004119b96a70c14221d539217dc123f077fa97afeb94 refs/pull/1973/head\n004188214dc2966923b84c45650d1d2a06d53f8d2d7e refs/pull/1974/head\n0041d0438d88f8318cf279bb6b905aaebef0000fd4b4 refs/pull/1976/head\n00418c6e38f64217d2bfdd5c74b4820542d69312caed refs/pull/1977/head\n00415d11d2ecfa6241332ee224ebe1e3817fd70ce5ed refs/pull/1978/head\n0041b3fcec5942a9e303e7cfc8fa90dfb5aa8548ce0a refs/pull/1979/head\n00402d059659b02a3d4cd478d9cd608ee625f6101623 refs/pull/198/head\n0041f118e38cc79ccd80541d773a73a40f48f730f293 refs/pull/1980/head\n00419a4d3c10c0c76ce56b5393256e582e0f6156a354 refs/pull/1982/head\n00418f8added4c8e79c5df1f09d35161ca44ab42314d refs/pull/1983/head\n00413e9f8f819beec39c2171888cc75bc09eaf682a8e refs/pull/1985/head\n0041ea8a5331c4dfd8ab33559dfd63279c2745a8dab7 refs/pull/1986/head\n00413fbd7bdb7df0c0626e2375262ca831e82ee9694b refs/pull/1988/head\n0040381bdf0fdf166a8efca78ed83aa3729eef57fee6 refs/pull/199/head\n00413b494e299e1bb738432f2da3adbc16a4b9925cb1 refs/pull/1991/head\n00413a5a4ba0f0023ba2be6e8f76e55a59c77e83aab4 refs/pull/1992/head\n00419232e80f273caa3c4e30de4ba2df2b59724f53ba refs/pull/1995/head\n0041931da3b5a36e92341821bb07a6ce12c6e2964ab5 refs/pull/1996/head\n0041756a8bfbf71a83a7830c3704f0826dc5e9363a4e refs/pull/1997/head\n00419054561b3be44b736d0d75c1fe93650c9d72a19a refs/pull/1998/head\n00417224063d42c89b8ed4e88bab92552b683972cf56 refs/pull/1999/head\n003e45ac7a9b17fb34cdf0ea52ab533b70eb4ee60a23 refs/pull/2/head\n003fa89fd2c8ea82bb0ea441e6f8bb2fa16a097fa40a refs/pull/20/head\n00401e54429c2152b4c88a7ffca8d2d3a3da663e7dc9 refs/pull/200/head\n00413db85348aacfb66d3198837378bdf39b2b83b202 refs/pull/2000/head\n004140b3657c0fea727e0fafa0f15e5cac27062c9467 refs/pull/2001/head\n0041b828c1942fc576b764fb501426561645988c5182 refs/pull/2002/head\n00410a633c74dcdc35ea13b1131c185ad038501b9910 refs/pull/2003/head\n004177cea761a0e5d480a0ee655e192f47c3c4995fc1 refs/pull/2004/head\n00419abe4a3186ac55d8fbdef81cf718fad8d1a89079 refs/pull/2005/head\n00413bc50173f33ade9e73e9cd345b96aac6481bcf6d refs/pull/2006/head\n0041e8fb8f5771525831e0ce36e4b590bb7f6d28e436 refs/pull/2007/head\n004093e03d4276610c22a0e92e73012f8a4143e68c5f refs/pull/201/head\n00412a2592576e38d9fb64498661223b0e5d41659e50 refs/pull/2010/head\n00419ed18665d7649950d1f7c5e55d24b5ecdb6ae217 refs/pull/2011/head\n00410bd31f53db252acbb57473024b0e5f62805cd8e2 refs/pull/2012/head\n00412634e09e56a84ac60c8133659e86924db2907754 refs/pull/2013/head\n00414e07d9a95939834719489e7315fa330e0600b60f refs/pull/2014/head\n0041c4f79ae666057aad3ff6dd83878be6ed2fdf3668 refs/pull/2015/head\n00416ccafe45354eaa1a381171f692f3aebdf40e147c refs/pull/2016/head\n004191d2cdb8f126b98e33832a99ee369f8e7d33fa15 refs/pull/2019/head\n00401a57100be071b113f1844f864622afd13e7ba357 refs/pull/202/head\n0041f9f69a443ecabce263829413bb52d40b4f62829c refs/pull/2020/head\n0041276ef05e74f0b36860354051b60734570860cb44 refs/pull/2021/head\n004173b1fe3e8f664a33cda63a888e886a43d1f09453 refs/pull/2022/head\n004162075312fc10fc501a1c8e79109416fcb1d1e0fd refs/pull/2023/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2025/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2026/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2027/head\n00412d365a1a7f06d0c6c0b533a870a06ad947ea93fe refs/pull/2028/head\n00416e8dc9b9791d3d2c32e97a075edc1bacf515f7b8 refs/pull/2029/head\n0041c3f2d82f0160787e23b604ca33bff1c7155452c3 refs/pull/2030/head\n0041f427a8cf2cf8c5a1281b5597c97a7824e081ab41 refs/pull/2031/head\n0041c5c74a89138b010c108b44c04f6b591a5effd6f3 refs/pull/2032/head\n0041c2d191f524e51434cef74087074f695e1a300d1f refs/pull/2034/head\n004136bcd51bf95826cb489f181ca8a20374e2edee7f refs/pull/2035/head\n0041b17a05a6c75c73cf4d7472765dc24c67086d344e refs/pull/2036/head\n00411c841c1e1f263e42179306f8c9c0efdc07ffceac refs/pull/2037/head\n00404d972ac05deac77ffcb2ce21adb2650ed6ea6a3d refs/pull/204/head\n0041fce332fde15b1e5cf8519ca4e41f7dabc15230cc refs/pull/2045/head\n00412e6e93ff444f2db51e2f94b7b4440a6ee599bd40 refs/pull/2046/head\n004177a020b5769f6739f496f57539930e5c3b8cf0c4 refs/pull/2047/head\n0041616ee95df5e755c3464c5ed9d997531da5329ea7 refs/pull/2048/head\n00415da2bc3a293b18f920aa668e4e84fa3a2f54243a refs/pull/2049/head\n00404cb5d471dcfafbc390ddf00de86d2b3273e214b0 refs/pull/205/head\n0041a2766dc2c1f01b71b659a9fe24c24e526f9ea2b7 refs/pull/2050/head\n004165e83af51b80729115b49c787f4c7461561ee600 refs/pull/2051/head\n0041dfe7469fb6f43fe8f147e7ae4f37f4bee4b86efd refs/pull/2052/head\n00410f2c1ec931639bd563db8209bc678eba6bbd316a refs/pull/2053/head\n00412021cf90c380582a43f86948682aba9ed8c6444b refs/pull/2055/head\n00416e6fd0abe0b41abbbcddad8ecf505968252149ff refs/pull/2057/head\n004184e8c2cc730d0c599f182e6f9d1bd1836451a6a2 refs/pull/2058/head\n00402ad69f5897e9dc9fa230f6aff252131a058ac5bb refs/pull/206/head\n0041979cb14b1c89295b411f2cc96698e302b63c869a refs/pull/2060/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2061/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2062/head\n0041fcfed2e6876d14d39cd59b7b5bfb1661de2fbc5d refs/pull/2063/head\n0041dfa203535005df10a8dc405af9e990d1501df161 refs/pull/2064/head\n0041534ef3fe70c9ddf8bb3be2611967a27fdc18af0c refs/pull/2066/head\n0041e3307ccfbe4cfc66099049a0c02447ce4214d28a refs/pull/2067/head\n0041914cd027ad55591aa88c0b458793cf4fa06fc2c6 refs/pull/2069/head\n00401efded0c7da7b9b855dff24b2ef5ae27532496d6 refs/pull/207/head\n0041a97b632eefa842b42c14cd6a738e71ff03615eda refs/pull/2070/head\n0041da57e2de83414be080dbe083665c90008a0562a1 refs/pull/2072/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2073/head\n004174d79dd6aab423b075f15e0577d277ae125cc436 refs/pull/2074/head\n00410928411247b51199daa3bf7d5cda670d216e9d36 refs/pull/2076/head\n0041774d2eea01be83a26f4d857a0da058606e26d3f1 refs/pull/2077/head\n00415671f0abd1b02a8c003aa00accce1600f405c4f1 refs/pull/2079/head\n0040140337e1e1d9af38371be75fa4d5f5a4b239e50f refs/pull/208/head\n004124556f57344c7bbddad2b235f40612fe50abdc8f refs/pull/2082/head\n00415f0956d3fc07895cdce08b590e3a58bec356f5e5 refs/pull/2083/head\n00412f0e6b16a8eba22013463d2f06c29273af6586be refs/pull/2084/head\n0041d97a9b2ba365e6db9d4eff805118536b997c0c1b refs/pull/2086/head\n004166a697f9b0d9a72ebfd04e201ea5ea51bb12079a refs/pull/2087/head\n0040eccc45a3ea6c3ea1ffab1b224e0f38701acae5ce refs/pull/209/head\n00414e252005ddb3f08c77948c828a695f5cc90e10af refs/pull/2090/head\n0041c858aaf921ce8c2323422505bb4250581a9c7213 refs/pull/2091/head\n0041820ae57aa36afa9ca11411ecc74124fa99a5d11f refs/pull/2092/head\n004192c8ff73ddf065aba993496d8b27b313e7702a08 refs/pull/2094/head\n0041cae269ee9de564f8beaee54af3307f62e5b3431d refs/pull/2096/head\n0041aadef428d601202d79299c176e4b41e245ba843d refs/pull/2098/head\n003fdd60e6b515cf2f60a17020ae3c99fc26c48731e0 refs/pull/21/head\n0040b68182934b0c69bfacc4745141c97159263cbafe refs/pull/210/head\n00419bdbf91f4437ca3d3424c25d405f48c7762165e0 refs/pull/2100/head\n00411e05bd5c637cc150c7b0242660a7cc56a57fa45a refs/pull/2102/head\n0041d2b1520f1075eb199d17ebe44029aa429dfa198c refs/pull/2104/head\n00416d8dd63c503812e495e9aa4051931a312e45f3d1 refs/pull/2105/head\n00416c0238bd3f954d95d032ac8699c69c7dbb261ede refs/pull/2107/head\n004125defef4dc82fc1a655825d41fdcc16ff9315c4d refs/pull/2108/head\n0041edd5576921ab95d4230fd39e2c0879ff8a1373aa refs/pull/2109/head\n0040af2477aa12be46101c3d7cd0003e45b17e98a98e refs/pull/211/head\n00410f384635ad38f435e9d342c1d084c8d82d76532d refs/pull/2110/head\n0041e888febafad31e6977fc98801c90d06e3930575d refs/pull/2111/head\n0041f1cc4c719b85eff4d09e262482fe08f2c82b1ec7 refs/pull/2112/head\n0041c215ac334d53aad70c8f49c3ca4469138afb14ea refs/pull/2114/head\n00412846504bcc6555185b6087e2b3df29b20acacee6 refs/pull/2115/head\n0041b15d59d9f159cd31b4389084e6393cc13c89c24f refs/pull/2116/head\n0041a0ccb0b329ec1482e4fb4b357808f69be1d2918a refs/pull/2117/head\n0041d5ec3caab9b15dff0404c53f8503647f0ed9ca8d refs/pull/2118/head\n0041e8b0cbb473269a2ecd82efa821bdceab82cef3bf refs/pull/2119/head\n00400f5e062dd35b9ebef263473fca25512b315a918f refs/pull/212/head\n0041c6506ee1cdf64b1f8e5aee02a68d2373ae93152e refs/pull/2120/head\n0041a46c8c3624067acb6c11e9a8f7b2d55b9b18980a refs/pull/2121/head\n00412a59b5e507bc1618e1a8cab5dead857665cf40a9 refs/pull/2122/head\n00415d69ca46b8216051eaf37047a336912b1123c5a1 refs/pull/2123/head\n004148c3be619b89ba4966499bbcaa4e40bb6af35b48 refs/pull/2124/head\n00419a8d69289230a495f8582cd65eb0dba7d3307620 refs/pull/2125/head\n0041e5eed9e46a09b94567bf86ae4f6d46019ec18faf refs/pull/2126/head\n00410bfb1a4d4902cf9fbf7593f03863dd37b8724ccb refs/pull/2127/head\n0041c54c9f8ec1c7f9ad8ba779671fc710d4a164af0b refs/pull/2129/head\n0040c5e09ae449a74b916851abdde913f3098608905a refs/pull/213/head\n00414728b5044faf129ffd24a985c74cdf31040a3dde refs/pull/2130/head\n00418a24cfd871e0958f9fa723f6c6253952b0deefb7 refs/pull/2131/head\n0041db8349bbf8bcc8a467d116268cabab91145eee0e refs/pull/2132/head\n004171dcb05b8b4671c05f18deb458e5d3aa8f95e86e refs/pull/2133/head\n0041364d95c03b18af27f248bad58a56bbbd2adc19b8 refs/pull/2134/head\n0041159d4dc4ae6f9e9816035ae170f0204043df7a8f refs/pull/2136/head\n0041566aaec5b39a4dccb72e688c105dddeb57cb0f54 refs/pull/2137/head\n0041f3b87b9a1c2db51259d6445e488369fed87788c2 refs/pull/2138/head\n0041517ca96e424138e2f7e09b69440b46846c53ce65 refs/pull/2139/head\n0040e03ffff3d0359f7a13ef512ace8c56c74411b2eb refs/pull/214/head\n004105f77f86e9caf21163e15e1ea8028a9468a781d6 refs/pull/2140/head\n0041223312684d462a1bc67706baccba127b2bbeb1f0 refs/pull/2143/head\n0041a326ddd7e0e2286cd23d9bc38b6f34bd0843cde8 refs/pull/2144/head\n004181aa02647563b8231cb1db035ff97764a4bc4c08 refs/pull/2145/head\n0041fade7728c3f1bb109dbd6a58cc9cb5b5a7244448 refs/pull/2146/head\n0041d0e0731232ebd7711fd7f7d80b4286f4ba97ff70 refs/pull/2148/head\n0041e70a80f91dd512f7380a90b53adc925c132ba932 refs/pull/2149/head\n0041d5a96efa27504a15bf9a03c432088fd8243415cf refs/pull/2150/head\n00415bfc4e906a519270df95056eb9a48b8089f68d56 refs/pull/2151/head\n004126cab433e325e4142045bf6f2f8276071738cbb1 refs/pull/2154/head\n0041db0945190e0388ba27a9bded0314f3016ea6f262 refs/pull/2155/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2156/head\n0041370f57d1ef87a56d7a59f5e7004d413c5cabefeb refs/pull/2157/head\n0041f99c264fe30fe0915efff777bc94dc16df9ab48a refs/pull/2158/head\n0041a10bcf7c8df9f32499ffbb56a13a52d7f8cd64ad refs/pull/2159/head\n0040daaa4a42527acc0ba496672ea2c807412acc1958 refs/pull/216/head\n0041a94c3dfe95cb58665bf4b4c15fd39db98b96ccab refs/pull/2160/head\n0041a3f61afacc7cb29a0643328bead3ae6c08c6c05a refs/pull/2161/head\n0041e9f54cb2fda9cf61d179d1485a0c0aa8f21bf901 refs/pull/2162/head\n0041167f4e6825a414af01e75365d3c87525a214a550 refs/pull/2163/head\n0041e8ace6973134c0829cb1a9c598e447a64a59e2fe refs/pull/2164/head\n00414d66b12e44db8f5abcc2d2a8c319003e185b34c0 refs/pull/2165/head\n00414b2128402627ebb80b7d8d1af8c092c9a119d840 refs/pull/2166/head\n00412917da51a376598d389320da3cc266c082512951 refs/pull/2167/head\n0041c18c08f53377f808d1989402e9ca25a4d4b1517b refs/pull/2168/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2169/head\n0040d3b681cfb9b0a6af09daedd4a3f8ba02ec766e3d refs/pull/217/head\n00417e5bfb0a34444628009a93432b2bcdd765d15de4 refs/pull/2170/head\n00415c6726b2bf8aa3b7ff79bbc6aa971e3082d93504 refs/pull/2171/head\n00414d9d3c0babdfeb31f6eea7cbc66dcb4bca1c70e5 refs/pull/2172/head\n0041ed63121ef55c84127cb5137dc0a650e7cb302571 refs/pull/2173/head\n0041f347c8cea2246a490ac9101188c4f86382be1424 refs/pull/2174/head\n0041013d338151b3156f6bb1d994d2d3d3a5b1c3d0a1 refs/pull/2175/head\n00414e2227162e694ebbd975631a8ac0a65f1a031792 refs/pull/2179/head\n00403931b2f889e2c657f34c3c5167030143489ca091 refs/pull/218/head\n00417e92aaa16538e195547bb6d41198d65dbf1182c9 refs/pull/2180/head\n0041952f05576f2f134514cc91e5b2dd9f4d3dd209ce refs/pull/2181/head\n004128c50d845b49aac26f7cb9df609bae2ab3727190 refs/pull/2182/head\n0041c1a513c3c934135dfc1154f4861bdf7afbdce60e refs/pull/2185/head\n0040fe110eee20684e6f2b05a4c067fb31879e456932 refs/pull/219/head\n0041a1da249964cf146c54539cca524fbd1013d2029d refs/pull/2192/head\n00414ff69d3c81ac79198a4c99a285c66bf68ea4c538 refs/pull/2193/head\n00410ba2eadf30c4637e8dfb9970899564a43aa6281f refs/pull/2194/head\n00416fc5cfc1a359cd30193055997583fe393cee0739 refs/pull/2196/head\n00419bcdec0855ddb161e35d720fd20c9a572061adae refs/pull/2198/head\n00413e9d126a22e958a30ac07045f506ce1f19f4d968 refs/pull/2199/head\n003f985084119b8da35919c3de651e275acc06e1cc2b refs/pull/22/head\n004062ee6c452595eda122ff0e40ca69f8f615b54438 refs/pull/220/head\n0041741ad5fab0aeff22fbbc8663cd51b98a930e7b5d refs/pull/2200/head\n004131f5035ade93af773bc0f352e16b205978ba8288 refs/pull/2201/head\n00416bd63d39f998df7e56a95ce1e678d7e00c1fa86b refs/pull/2202/head\n00410ec8f46347ea4c4b3cfefa672d755302b6bc0195 refs/pull/2203/head\n0041645959293e93b7c41224ca6565d549ec45f20fc5 refs/pull/2204/head\n0041d9d3e311facb95d40ce676157dfc5efb29dc4bb4 refs/pull/2205/head\n0041a1c81c8de57edcf53010d0708f694b1accf8690d refs/pull/2206/head\n004106f20c35e22816059987089b3c2e48ce47798ed3 refs/pull/2207/head\n0041193141017843084d2f272ab8f26a89b6b047302e refs/pull/2208/head\n004176a1a98700ec28446ad7ac165e15ca3880fb0eb1 refs/pull/2209/head\n004048611d3952d8596fe9781d8c8bbc15326690e6a4 refs/pull/221/head\n0041af034a96d6cc19a7fcaf1ef9d0bf3b6b478ece7e refs/pull/2210/head\n00413bf320e9526067c0746dffc1ea8b4daebe2c5bdc refs/pull/2211/head\n00412afae4f3722aa4fc07828ecfb290cc1ba21d4f00 refs/pull/2212/head\n0041ca9da16069d42325e475cc6c343b6f6edb5ce623 refs/pull/2213/head\n0041c7e3aedbb454e839909dc86a0c3d3111117b96fd refs/pull/2214/head\n0041caa0a41f2f4270e59b0120162bad48fecfb4b744 refs/pull/2215/head\n0041ff3e8f0694a4d37576abad605a9e21720174e787 refs/pull/2217/head\n0041aff2b3e908081ccebdee53267b4997f9da5166b0 refs/pull/2218/head\n0041fda0c2e5ecec32a74ab3e1667481f5ad7a696610 refs/pull/2219/head\n004040b3ec19fb72ebf2d0384a6ff5d2f2014d4a6992 refs/pull/222/head\n004180525c230f1caabf56e881ed7ab459df710f57db refs/pull/2221/head\n0041ac9c814844d8656bcd36a929411406594b91b27a refs/pull/2222/head\n004199f27a746f2f16538e241ea4c994a5f3ddcafcf8 refs/pull/2223/head\n00411a3e213541a2de4e0d7d9ddaf4679a20b48405e2 refs/pull/2224/head\n00414f9558a8d2f1b7419e80eae901761c80aa53aa8c refs/pull/2225/head\n00416a253e4d552578539f484b436c32a0eb5a131fa7 refs/pull/2226/head\n00411d10b35abdabbaf3fe8f420992a07f83ce68c614 refs/pull/2227/head\n0041b23d995bd7c7dab28b221c8ce2bee885ab70249b refs/pull/2228/head\n0041ccb42747dc8a368d7084d46d87014b77047ae1a5 refs/pull/2229/head\n0040336503602a15fc771aa1c1c36486ddb77209dfd0 refs/pull/223/head\n00418c3360a8a5d8d531d0f2e447f9e70bdf8f796972 refs/pull/2230/head\n0041ca22722c1dce5a66f5717ca5d62e38a9732596fc refs/pull/2231/head\n0041d80dc2fe58efb2742c955e07a6c07bc1473fed65 refs/pull/2233/head\n0041c3693b5ca51373d28b6b52f004020b4fe518816f refs/pull/2234/head\n0041ee10756deb3286462704eeb4759d78ba10969110 refs/pull/2236/head\n004116222ea878bbe791f998cac019b70bb1765cbe9f refs/pull/2237/head\n004110b241e044a66932cacabd1afc4d3fbb0f35d077 refs/pull/2238/head\n00410da409bee5c8c4f7b82ee5b7f2f8df0331f9bff5 refs/pull/2241/head\n0041fad9c9e4bf307e38cd5c046459e8b2eb9e7553e6 refs/pull/2242/head\n0041b2456b296ce2104856d6a84fcd191cc32406aafe refs/pull/2243/head\n0041de20dcabbbaf0e964744cc56b4c9a20ef7f63b05 refs/pull/2244/head\n0041a4a50c2ef4bd1bb506ae8d7e70ed0095fb2ab0f9 refs/pull/2245/head\n0041388f6d5c12827d5c51d427531f1bd087356fd2b5 refs/pull/2246/head\n00413fd8c2e118cb471d75e559804d7bf7ded4b894df refs/pull/2247/head\n0041a92e4dabef6b5d88e2e5fa79bd46add0a3b0185e refs/pull/2248/head\n00418557ff43e4873f5da41953950105be2565dea53d refs/pull/2249/head\n00402c34baf3b48f0bc9c895ebca5043d0544a4fa601 refs/pull/225/head\n00412984bd8d2522d267b1d8ddc787e33a6f867ab951 refs/pull/2250/head\n00416cbdd8411ba53f845ba6e1e31f0903053bacd683 refs/pull/2253/head\n00410062172b11f98d0980b1d31dc3ed3b8a444ae09e refs/pull/2256/head\n00411f994a25d12eb1cd9afe903a4558092f62f9af8c refs/pull/2257/head\n0041e5bd727e599e58b57680b6af4228456476e6a324 refs/pull/2258/head\n0041490296fa34b945dbac7f68521f5019e3fbc6e010 refs/pull/2259/head\n00403986f1e346f705814c8f76b1e1a1f39f253565e1 refs/pull/226/head\n0041000f12bd3b89f030d08c78d5a9458aede68aa0e0 refs/pull/2260/head\n004150c4ac1ca3ed40862ba9de2e245435245d3f2eef refs/pull/2261/head\n0041c16df2a93b493d1c94e4b1d4b08d89205acaeeff refs/pull/2262/head\n0041d878e3498a22d960dad7f886489a3a43bb644ff5 refs/pull/2263/head\n0041f0c95462867090157886315ce4ab95d2f2624dc0 refs/pull/2264/head\n00412b13b45ea1646421d1bb7841a0aec13a9b232040 refs/pull/2265/head\n0041db2b9a6dd5d89ded180a53cf6a98608216b1cffe refs/pull/2266/head\n0041682844de6e22955ed5a6844ea6bed462308b87dc refs/pull/2267/head\n0041c0071255816784a8e42484060df1f0ac2cf31932 refs/pull/2269/head\n0041e600f3a2159c07215036b540f7ae6a6a7770eb45 refs/pull/2271/head\n0041f3e4189020ed591fe7f3abf1f2e5c98768cdbdb2 refs/pull/2272/head\n00416a7310cbecb14299aa3acd0b3cb8550dc209584a refs/pull/2273/head\n00411aefee6d3342b8b05c326ca8a57136f6f5374806 refs/pull/2274/head\n004146cb03dcaddd28f0c845744bcdd4c499ef4d74bc refs/pull/2275/head\n00412754e0160707967e35faa7943ffbeb00b565831a refs/pull/2277/head\n004137548c1ae7cfb2a024df5e8795eeccdeffb05ae2 refs/pull/2278/head\n004161f534a7e55b4e83460721b951bbf091f3241874 refs/pull/2279/head\n0041f8b616e0a7b1c4ec58a4e1aad97154410fd0f573 refs/pull/2280/head\n0041cd8b16c68ca6e0dfd7a68e0574eec5b56cb3e4c8 refs/pull/2282/head\n00418786f6ff2338f4b3e2153b4155a26ec887bd1ba1 refs/pull/2283/head\n004147859e6f1e02ff5b514f258a5aef89387c6ef8d6 refs/pull/2287/head\n0041b90fc5f656efe508cccbf7c9cac25e96b6819966 refs/pull/2288/head\n004175544cbc15c840a07067f40c54f81b47e966b45a refs/pull/2289/head\n0041927cf2bfcfbfa3688c0d2cc1444161d9124c605d refs/pull/2291/head\n0041541d04c51c2b9515cd75bd6fe53b164faf97a6aa refs/pull/2295/head\n00418cae4953d6b1900dc06d1f7d10d854a7eb96bc78 refs/pull/2296/head\n0041e75fe6a870f8214d2df73b9fd5fe247a36eda287 refs/pull/2297/head\n0041642e6153a9205a47270bbef52d5083bc9402b7e4 refs/pull/2298/head\n00412738976a712891d506de1b2cdf9572e2486b43ec refs/pull/2299/head\n0041102d9ebaf8f6d139d2570fb35367f72d7f842eb9 refs/pull/2301/head\n0041200c1e907e9a9f4061ec24627aec227da40b0dce refs/pull/2302/head\n0041ba4ac9c4029e17faaed41a4c77a49dffc4b137ba refs/pull/2303/head\n004104071d4510e1a9eae2555db2e195d9907c20314b refs/pull/2304/head\n004182296895d676cbeb713f8237fa6c9aa0b55417f6 refs/pull/2305/head\n004163555fe8a246e7024f16d17f969da9d53c0bae0c refs/pull/2306/head\n00413c3c13493aaa9aa000f02a81c3e5079ed28cb133 refs/pull/2307/head\n00418805681354f7bb76c0a7d088ea53362aa4f913d4 refs/pull/2309/head\n00412fee37d27e5dc081565870881b0af98226099b6a refs/pull/2310/head\n00417d3020ae31e7269f666702c5c89cf68747a8357e refs/pull/2311/head\n004194b292ae40c1681ed13df2d2f5d6349bcddaae8e refs/pull/2312/head\n0041a5b3685e7194ced65ad79ef485212a4e1394ae9d refs/pull/2313/head\n0041c7a9bea483be59f447aaaf8fe27bf0051712f093 refs/pull/2314/head\n0041ff3ea7175f824e65b27f28c59142c0039323e179 refs/pull/2315/head\n004152ac0b29edd8fd78ae8f58d9d63a40d5a80cba99 refs/pull/2316/head\n0041c08f32f67aa91a9af146eae74b2e52320a8ef9d0 refs/pull/2317/head\n0041a692921c7d2ee84358d9e40cfb28f5e89f98f238 refs/pull/2318/head\n00418b64c98d985f517087ee4c3137577df0f806a2bf refs/pull/2319/head\n0040a72b0f899bb35939f65c2eee4653a4534fdca938 refs/pull/232/head\n00410e5ecb7666490c0a5dfb73dc97134520970c6872 refs/pull/2320/head\n0041dab1e190e50253fc770f4b4e023cfe6c942088a6 refs/pull/2321/head\n004118d1aa22cbf255b253a972fa17e2a8f19ff11d83 refs/pull/2322/head\n004125207bc51923412606abc8a60c7783afabcfb554 refs/pull/2323/head\n004167aaede68e0e2d8d0325c15eee9efc7eb9acd1fe refs/pull/2324/head\n0041ca8e27a9810a339fb0429cacb004a51e266609d1 refs/pull/2325/head\n004115f4b1cbe50c19a55b6ec61d94f3b8bd5ff9254f refs/pull/2326/head\n0041c8924b63350c65435531a2f16b5062b8e0349d16 refs/pull/2327/head\n0041bd79c21ea0139abbc64a6a79a8d96fbf7181762f refs/pull/2328/head\n0040b8676faacbfc2e6fea33905a6cdce631ff426ed5 refs/pull/233/head\n0041aa40413e669c4e137cd8d39068e8ba99933f95ae refs/pull/2338/head\n00418e378c436c58840a441776e29cf3c7a4f0a1d382 refs/pull/2339/head\n0041419aa71a493e10bad201d1702ef420c9c26399fc refs/pull/2340/head\n0041d71393208f1bc5e9e8d3a22d175c859a13cd180b refs/pull/2341/head\n0041773234bf12f485f32d12854e89ee0ae605a25889 refs/pull/2342/head\n0041d8fd98c896c8af5854915ad1164aeb785d0dbf61 refs/pull/2343/head\n0041d13a8ac8dad35d3ed7e88d79a0209e3619b49530 refs/pull/2344/head\n004125c7038b09a902e14c917a3424b0fb59ae47b908 refs/pull/2345/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2346/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2347/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2348/head\n0041c0d8d5792e9ef5b8c5f5e42de11d9cadf19715ca refs/pull/2349/head\n0041fc2887fef044d0d3f5643b8328acbeb8daeda055 refs/pull/2350/head\n00417e3f756a0239d51869cfb1e766f83aea55bb78d7 refs/pull/2351/head\n00411131f46b62d559ed6349f1886d72998122b904e2 refs/pull/2355/head\n0041a785c0b107b0245aced8ab6444a0dcd554690891 refs/pull/2356/head\n0041fadded923d6b7487a878306b4db76ac2fff66808 refs/pull/2357/head\n0041084bfa051b06e9cdf96eba3b5cd96497dc1fd302 refs/pull/2359/head\n0041a8db307f7d3a457697460ca84a76312de41244e4 refs/pull/2360/head\n00419e7e709fcb8a4aaaa479e7f5045bf031c3ac011e refs/pull/2361/head\n00418b37b80317b9be689039062b3de0a1c3cb886f69 refs/pull/2362/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2363/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2364/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2365/head\n00414f168a73f84b4e8bf2ae582b2aaa22646a9927d6 refs/pull/2366/head\n0041eaa3b70bcd32c7a2fd92ce341a1fc3577a573a0e refs/pull/2368/head\n0041ddcc9575213116fd75c1592f21a1199357c02cd0 refs/pull/2370/head\n00413ca0c78954d8ce2178ca2bd45146236a700a3c5b refs/pull/2371/head\n0041319c369a4ce9c5b2530a5171e22a17974dd6af96 refs/pull/2372/head\n00419ce1728af46e3a005b534308fd6b851174f6607f refs/pull/2373/head\n0041ef84432d4f589990bae9541eee952006fceff4a9 refs/pull/2376/head\n0041138fca28bcfa8a93b3eb5db7f285a37ad8dbd541 refs/pull/2377/head\n00412295d8b3fb84b1b493b39c3810639f46ad042987 refs/pull/2378/head\n00412d7a5cbc3855c9e9c54646e933a7605109a735f0 refs/pull/2379/head\n004001df8689af378f1d9b0123e6797da3e5e73c2e22 refs/pull/238/head\n0041a1cc2ec290ae9e6eae4b8c0feee477b32ac76e7f refs/pull/2381/head\n00416b28bfdafdc0262bb92f67ed21444d6bc589d65a refs/pull/2382/head\n00412fa59043f55f9a6c44243abba66f3541e9f5ae9b refs/pull/2383/head\n0041b997add1e8dca84349e6b571ed0f6dde4119cc8b refs/pull/2384/head\n00416618f3a764a74a0a0552c5ca080bee3d15077eb3 refs/pull/2385/head\n0041d3883c619f08310c58c16691a93a67cf94edd324 refs/pull/2386/head\n0041f39876a2c0ac0f18f7dd42c48859f55626b46fe1 refs/pull/2388/head\n004006ba35b53646c2937bd1fff198b269d1897eb583 refs/pull/239/head\n0041eb33b57255744abfbe557369066619701c0d0f69 refs/pull/2391/head\n00413dc4950c009dde0ab369b2ca459368b953190e40 refs/pull/2392/head\n00415c753f8eac6e9e83a39261373789c09a8299cdf5 refs/pull/2393/head\n00413924c28bcf5f0a53df04ec74b5f6c36b98948dda refs/pull/2394/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2395/head\n004119846ac4836859d8c568239a42b72ca44139742d refs/pull/2396/head\n0041cdf1a7062f8f077d3fa4d6d08dd5459b34880854 refs/pull/2397/head\n0041e368558b630ab18408c79db485a474dfa4683e94 refs/pull/2398/head\n00418f4bb87155757c3a39c3f27aa7a315f34983e3e5 refs/pull/2399/head\n004067e93c659b3fee46070e27c3ec08402a35c82375 refs/pull/240/head\n00415804bb125905a1dcd8b103dfac2ad2b15f811984 refs/pull/2400/head\n00417b80fa5cf0abd102423d5dcb24d7b32bf5212551 refs/pull/2403/head\n00416a76e512e9b58d77a7e5248cb678a4c647f1d669 refs/pull/2405/head\n0041051dca78e7664c9b451670baf44d15851a7d33fd refs/pull/2406/head\n0041f91bbc6c66207b0e908e82733f029c32f1292641 refs/pull/2408/head\n0041a5b9ad92313a57ff2a0f53f2b81aa90b9417d91d refs/pull/2409/head\n00404debd5e8e0860cb57154cfa59525c87bbe9e1021 refs/pull/241/head\n00412c28c867ccebeced01a0f0ce2ecf98f33df27077 refs/pull/2410/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2411/head\n00412184298934e71c29b6d66ed59782938fdaaa0f20 refs/pull/2412/head\n004199325072b64c02fbd888329fba65944e0bf731a2 refs/pull/2414/head\n00410917f9702082147abaa26bb6fcb1357f8a0f31af refs/pull/2416/head\n004195829ab78ed81644b5eb41fbe8409788a9fc7e21 refs/pull/2417/head\n0041c5a219f066e5a874208b2f78033d8ed0f90762b8 refs/pull/2418/head\n0041e28d97d2634995711e5abc794ee6484099128e71 refs/pull/2419/head\n0040d971c87456fbe727730b656e1c6a5de7f7831364 refs/pull/242/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2420/head\n00413ea5d0adbc23cb3059c3297a9be8b854812883dc refs/pull/2421/head\n00411178657965713054cc5790a36b291b30b6d9ca81 refs/pull/2425/head\n0041c9c8d7b7605dbe60cba2eccc00f55723c2acdaee refs/pull/2426/head\n004103549f653ed13a38b886d13855e30c311942d652 refs/pull/2427/head\n00414154a9cbf1c273acd34a5d929adba231b469e629 refs/pull/2428/head\n0041cd93be6a1d7c92ee9f76789fd7c97842b0a7740c refs/pull/2429/head\n0041f733ab04711173a59877d809b2f557a9e3ee4a60 refs/pull/2430/head\n0041c5fa3e53f03ad8e999d57b7f76237617ad4037b6 refs/pull/2431/head\n00419bf72cd1fce073ad01b904fc1ce17773d2d89d6e refs/pull/2432/head\n00410715e65452d2cde3bc2b8bcee1c5a2029ee8afb3 refs/pull/2434/head\n0041794af8c606abf9a5060b9a4442999b9f23431678 refs/pull/2435/head\n0041e87432e66ed5209673cdd0ddb671a8a9a2c03708 refs/pull/2437/head\n0041c4ecded417152c3d5bc809d566769e71780731f5 refs/pull/2438/head\n0041536d8403169585521583475f89d6ce5aa03e0a92 refs/pull/2439/head\n0041ba01d1c94743595ca04e14ec2573dbee254c1c1d refs/pull/2440/head\n0041da45d1e2c8c8c6e3e770b310cf6b050f6da03aa3 refs/pull/2441/head\n004156ef8c622bfbb8376ecb2ebb20ba1668804b461e refs/pull/2442/head\n0041b01339a98647dff2ed86c2d229e23182e57f4a87 refs/pull/2444/head\n0041107392ac7410b8c25028a271523b0f4a050a69d6 refs/pull/2445/head\n00414c66211ac3614faffce5e8e008f16542fcf19019 refs/pull/2446/head\n00415d69266426f17b173056b98b4ed8f01ce0e9caa1 refs/pull/2447/head\n0041b9230a99fa4e2188859f37ced2b7c4427d8b7be8 refs/pull/2448/head\n00418665468e83b5be7770ae198388dcd5ee61dfd5ce refs/pull/2449/head\n00404bdeeb490f450be54f2e73835a76831f332cad8c refs/pull/245/head\n0041244459aa1f47e3433ac537fb89d3dabc7fe23fd9 refs/pull/2450/head\n0041d478b8f397f01d149f8f784a2ac2c95d40412c9d refs/pull/2451/head\n004170decc6cdce3762e1bbeee5e28d5559f80ef8318 refs/pull/2452/head\n0041ca9eed266681e9b352b64c73d5557c15cc38e465 refs/pull/2453/head\n004129c754bf205a00188f6f0a1db1c9f3d82f68815e refs/pull/2454/head\n00416922b4330f05d791b64aa56c40ab953940e71268 refs/pull/2456/head\n004149329a17ed31cfe6fe2dba21b88db58367e7c494 refs/pull/2457/head\n0041f87c0318ffc66e3c82451cebc129ecbc7bb0a933 refs/pull/2458/head\n0041efd8c2b4ca7ee897c0fab7a93ec00bd8cd29c7d5 refs/pull/2459/head\n0040e6a0e38f56d88fe922bfb15e35f05f15daae72d4 refs/pull/246/head\n00415511906fc24b22b252d54f5d2a4b862662510a0e refs/pull/2460/head\n0041ae298fa67b643324650f89628863bcc4dbe1ef7c refs/pull/2461/head\n0041644d27f3c18e9119d1fc471d07279c6e666417d7 refs/pull/2462/head\n0041ce867243c2cdf166b31a687a350c7b9b705c7194 refs/pull/2464/head\n0041f6221e43ecb01c46cf84d2e4938a5c3dcf37a5d7 refs/pull/2466/head\n0041e3567ff0d7f5412ab4135bbd4be8adcdb333b5b7 refs/pull/2467/head\n004153560ba756790c71366a7fb6ed9be8dff4e8ccfe refs/pull/2469/head\n0040c6648aaac24ee53b9933bf43a97aee09dc22c3c1 refs/pull/247/head\n00419d221250b69f232adf7fecd8749cad4f2a40df2f refs/pull/2470/head\n004183dbe9f90092b8e791b9e906138eb3417e838561 refs/pull/2472/head\n0041086f6f183efe4ec20ac643ab2bc5e98677f2d94b refs/pull/2473/head\n00418fc6a5c455a1b4dbc1dbf9869bbe3be6ff82412e refs/pull/2474/head\n004117b37df5d0f231481d6e5b2ada66666f99840fcd refs/pull/2475/head\n00413b2392429fe87cef09e404e695af344e9964370b refs/pull/2476/head\n0041aa0b81d3a6db4bc68a306398c30b473c6309cf58 refs/pull/2477/head\n0041d6d326a4a90095edf0da1d06d3eb48975a29fec1 refs/pull/2479/head\n00404709ec33c18f5c2653efffb908a8b69474fc1deb refs/pull/248/head\n00412af5644abf515b5b8424c8eb7b12faf35be68f07 refs/pull/2480/head\n00416eaa4e79b0e4b1178f5a03e299258632338b781c refs/pull/2481/head\n0041f6cfbd09ca2659675ef5ceca4d9b03b86b42849f refs/pull/2483/head\n0041098f63817e201983078c996ce5b1222aa2be6a01 refs/pull/2484/head\n0041157a47634e6089c7f7938bc7939f0661f5563b14 refs/pull/2486/head\n00412d3046144846d1a981b4ee30db75ac0e0a799f41 refs/pull/2488/head\n004180aa3dc17e885ee35a09ad1488fd18ef42961473 refs/pull/2489/head\n004197094af2d52994da5f658a26372006e0446fad9b refs/pull/2490/head\n0041224485342b1c8b88e4b4c3c48f13c083fcb837ab refs/pull/2492/head\n00419cc699a1c0eff4fb777a32951b06519dd7f25335 refs/pull/2493/head\n00416dbaf17f9a9fbbca7be0d02d5e4e0bdb74b0aa33 refs/pull/2494/head\n00416c1465a055851c726de155021c7284e98b92cc91 refs/pull/2495/head\n0041d302e811976f33178b99b6f15e24c1c23db46da8 refs/pull/2496/head\n0041363d41a21a19b87a0d02a6590d091beeb3eee582 refs/pull/2497/head\n0041568b516d94c9ac0877faffb3dbf13dfd9823246c refs/pull/2498/head\n00410c46bb4025498aa53f8872fab755e8cc02bf2006 refs/pull/2499/head\n003f45d1d4967d81f6ba4e3720a7065a3dc7ad83efd6 refs/pull/25/head\n004073f225e0cd741972f843ead3efd68f3768d32a40 refs/pull/250/head\n00414558a3e87dc35d37be3ecf5804ce499cc7a280c6 refs/pull/2500/head\n004130aadada170106402b84ed7cbc1e3a2be714c261 refs/pull/2501/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2502/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2503/head\n0041c2cdbf33c04c2261bbf13460875dfa96c8d4a900 refs/pull/2504/head\n004131cdc4803c8bc38ad71e14f1177b4dd1e1dbef5a refs/pull/2505/head\n0041cc06e5bbdf95c0e9502e86d24caa07da735e61a2 refs/pull/2506/head\n0041b64512aa5404eb97a175897e819a0a08d8be84bc refs/pull/2507/head\n0041c5fd3054cedd2be85d7e3b7013675990beeb20c5 refs/pull/2508/head\n00417fe9934f21fedf95a3bd95f7a0d7b51ac7425c99 refs/pull/2509/head\n00403444266fc3ee97cf87d942e5c3cfb6adcce0457c refs/pull/251/head\n0041c7c8e84ae2c10084fe1b913262804cdc76591509 refs/pull/2510/head\n00419a05a9350f70a44308e36728775b045eb47931ed refs/pull/2511/head\n00414277918e4a52bb2fe657d9782c40e5ef59678a57 refs/pull/2512/head\n0041c1035ce33537f701f91b7f1bf6df9b943d7eea80 refs/pull/2513/head\n0041a744fde6253c6a98f1b58497ea97d6d7e3c26a59 refs/pull/2514/head\n00419ce7f5a2d56f6a15b084858ad26a26b1b88ba8dd refs/pull/2515/head\n004197e4213204d34947cef09cbe4c16ab83465e9d1c refs/pull/2516/head\n0041ba6b47281628ec355528f1e472fa96d864d2caf9 refs/pull/2517/head\n0041a408bd7d8cfec77a87a9554285045087fc6f87ca refs/pull/2518/head\n004191651d9e6ff7181ed487b6ced372f0bae22d32bb refs/pull/2519/head\n00407f9fb1a86780ddcf6e73c22594f878de5e844f65 refs/pull/252/head\n00410fe7f7663a58e3735fa7f45f46b8ca64b4bf60a7 refs/pull/2520/head\n0041e19697e71d89145a504989888ae3faf0a739a27c refs/pull/2523/head\n004183f32f12b3c992e78c2b96524b4652966367ed3b refs/pull/2524/head\n0041e0bf1f04ecd19faa9d800e5fbc85ab4de3a11f07 refs/pull/2525/head\n004117dd77cdf4cac22f250d00ad1d43f3b928a0a8ff refs/pull/2526/head\n00417260f278cc92a8f2e620c55208c8bb9311c3bbb7 refs/pull/2527/head\n0041b0a9342ef09bd25dca67903d16fffcf45c199e8e refs/pull/2528/head\n0041a06d52e26333b88ae90c515acff70dfb6e5feedc refs/pull/2529/head\n00401cbeaa642c6340f4450ae7baa44745bfa361f16a refs/pull/253/head\n0041016576c8814583b730870f8e2015a023f234712d refs/pull/2530/head\n004174189b5520d233ba50fc975c076aeec7cdaa25af refs/pull/2531/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2532/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2533/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2534/head\n0041feb4d189cb1125b0838cac8b6570a0f8ddd11621 refs/pull/2535/head\n0041a5419a2150dde4d2923f4cdf17a23ef20f6c88bd refs/pull/2536/head\n0041d47dccfce889e6915995d122d04ef363014ed89c refs/pull/2537/head\n0041dc6f679abfd23d56e171946d908b75e5acdce47f refs/pull/2538/head\n0041b72c34c7f9edb9ae8513e95b6d2245c2cb5f54fe refs/pull/2539/head\n0041a2cf07661f649e73475c124118e8cdc334280c1d refs/pull/2540/head\n0041877b62e647862471f1d2b6376773eec2c3a1b211 refs/pull/2541/head\n0041cfc1741a5ded4e6040868b9012629862be1a0077 refs/pull/2542/head\n00412b6a997e296ea3fee132e8b9478d2073849f4e12 refs/pull/2544/head\n00415e8d1a9990b15e0f2219b5897f37424e302ca300 refs/pull/2545/head\n004125f771752f5119e8d697ba008f23e70823d72e8c refs/pull/2546/head\n00413198f8f6b575d2e954b588b4a67e0c123c51c6d1 refs/pull/2547/head\n0041acfcd4bdded2da1570dde992d6e3c15f2b21dc1e refs/pull/2548/head\n004131e9796ed8640c0ac39a81c62bc5b819521e53d3 refs/pull/2549/head\n0040fa95d2cc63ed28380c42e591258a30f607866069 refs/pull/255/head\n004173943f8d9b7d83cfb556848b167fd7c900a7e98c refs/pull/2550/head\n0041bed9872cd09ea6cdd74e31bc0eb4278a1476cf9a refs/pull/2551/head\n0041db7f04921d64675178666b7b2a8489d7ae3ca6e6 refs/pull/2552/head\n00410cd05892dc65cba018f56aad7dcda7cc8c5c4bea refs/pull/2553/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2554/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2555/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2556/head\n0041a84727a064c21268375d16b93feea2c95b038bc2 refs/pull/2557/head\n00418355cc67e9e6e8da93e59c179492d4b0903ab8cf refs/pull/2558/head\n00419c151606c877ad06bf89b3835bc356f0dec77b37 refs/pull/2559/head\n00401a970259913bb7403cdc4608f7fe9e7743f3ca51 refs/pull/256/head\n004147c640f3d31fd87b03010f20f7a4b8bc8640ead6 refs/pull/2560/head\n00410b9b22dd1c444e6ea86560e277d02ce35f0b15cd refs/pull/2561/head\n00410015619ff7aadf7a3004b1d627a1d398e51bb524 refs/pull/2562/head\n00412db5b830eaae0062ad1f518b77ab52bb27d28155 refs/pull/2563/head\n0041de1988eec8f01e838cc5697ebe961b3d07a91e61 refs/pull/2564/head\n0041bcc12ff125f2bac6e2889e144851e9ab056b30ee refs/pull/2565/head\n0041b2defafa31c947d8217a78ee64784d6e99071268 refs/pull/2566/head\n0041be8cf6b0c06195f841c7fc0136c3f4640c2945e5 refs/pull/2569/head\n0041254a670d2cac777740f22c3871b37d41daffdd2e refs/pull/2570/head\n0041c22c95d233964393d44d44c40b905ac16c0b5272 refs/pull/2571/head\n00411cb9ff8dc46e8aea62f8a43288bc84f2252db672 refs/pull/2572/head\n00416e72345f68ad7349d61d4b5cea2cc75d556d808d refs/pull/2573/head\n00412fcd5646c29b6850d656ece947749a865f8479db refs/pull/2574/head\n004142496b7fdc3a1239142d3e2bec836b60a78a472b refs/pull/2578/head\n0041d35db462766019ad82cb1f272f3f2d3e694dcdd5 refs/pull/2579/head\n0041046915c922731515b540ba344e2d420ac4a52fd0 refs/pull/2580/head\n0041546fb5d556524597efdcce7f2fc45a6e2307dd99 refs/pull/2582/head\n0041f2d1e6a62dee228f2f344361ca109cbbf2f0b24c refs/pull/2583/head\n0041dee53b9d72e183c2043edb6a8632365088a5430d refs/pull/2584/head\n0041eff28852d362648c378ee1f14d68eb16ec8d3ac8 refs/pull/2585/head\n0041675f8d051d94f0f000ff8dac8a93eff6458e3616 refs/pull/2586/head\n0041a8a4d03150df75ca23b4aa1fdb09e9da5add83e0 refs/pull/2587/head\n0041246b65dc5814a2a1050db97cfecee77014ec06e1 refs/pull/2588/head\n004181e335000a43373b83522864d2b1729b1d6d6e60 refs/pull/2589/head\n004027b9d604bc4ca31002e242af3eb43a4d26bfbc8d refs/pull/259/head\n0041e0167739ff07740a1565e1b2bbe2a3eaae584e3b refs/pull/2590/head\n0041b94c9ecbe2dbd3f612c4e2caa6886d494be3cf73 refs/pull/2591/head\n0041e57bd03a3b8a26295dc22d092334563a34bfb07e refs/pull/2592/head\n00418ead6a9209d4457843b2ac6e9a7a2549b0886067 refs/pull/2593/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2594/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2595/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2596/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2597/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2598/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2599/head\n003f627e315ddb24233c9159877a91e88faccbeba942 refs/pull/26/head\n0041b3aa240f3cc2cbaf9b810aef9390d3b2ff73a39d refs/pull/2600/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2601/head\n004151fdb7869d6b103c64e96e6a32bc0687431714e9 refs/pull/2602/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2603/head\n004172b478255f01f30aa5b2b33bc697a6216782ce29 refs/pull/2604/head\n00413456c65b5bf8a455ab4be528c932e94e2dbc51b8 refs/pull/2605/head\n00417689490034d5ace342ad180af664d0561dda7fc5 refs/pull/2606/head\n00418f747d48cb81b208e2dd43b2e2399a4e4c9fca16 refs/pull/2607/head\n0041ba522680e8bbf2e06e9844b268ff00147bf5ccc8 refs/pull/2608/head\n0041afaf0c24c73a4ced47abc729116f4e304056d85c refs/pull/2609/head\n00403f9aaf1d6ee0724fb367b8d9badfc153290050a8 refs/pull/261/head\n004125403ed7b2fa54cabe42ad36770b7ded16b17231 refs/pull/2610/head\n004148f4740a642291a6616f29fdbd1e2189449ed149 refs/pull/2611/head\n00419edcc47a2c33ee7c596ee623a34bef3085185446 refs/pull/2612/head\n0041a3fa21166c461cf3c98eef1ccb3ab98bebf0beff refs/pull/2613/head\n0041a23c8b65649e38e68f0c7ac2bf3d583fa278d905 refs/pull/2614/head\n00412a74d38a8465b18f667c93df4a4b9a1688a1621f refs/pull/2615/head\n00411fdcc1587c4182efa6bd6f1a82bd78ed8ab891ad refs/pull/2616/head\n00417581fe8599f89d5424cb3e5fdb82b9d883feff9d refs/pull/2617/head\n004134ea656dc06e0f8b84c07ce9ea716e6227f08597 refs/pull/2618/head\n00411575bd7dec8eac4d7c46a8c60ee1ea8d043909a2 refs/pull/2619/head\n004046c557ad9391746796a00d6ef2ed0d33fa6b46d2 refs/pull/262/head\n00411b72b4bf65fd05a51f3ae039dcf4f4f80c00e85e refs/pull/2620/head\n0041e4cdb49d5a0ec98f63c2d0f5892ae88b76eb131b refs/pull/2621/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2622/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2623/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2624/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2625/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2626/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2627/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2628/head\n004118a33ffec8ba556b2aeca01c69a3f9c1dfbeb194 refs/pull/2629/head\n00403c45a5fa82837ed3281394cf1b141a4565dd3701 refs/pull/263/head\n00412ad5c547030d92c823cf05d33473e5d569896028 refs/pull/2630/head\n004182bcd8510836ce15256951440f1866f56129dee5 refs/pull/2631/head\n0041664c3eacea7aa135815a12b75bc17c1502bc2731 refs/pull/2632/head\n004116630e020ff2f40074480b5e188176ee1f7dbfbc refs/pull/2633/head\n0041afdbef0c49fac58984098b1563bec4b1c94c45e8 refs/pull/2634/head\n0041bfddf1d4a056551c40ccfe9454c0b3cd9693af41 refs/pull/2635/head\n004165e80f09f0a79b12df6beac44abf245151bbfefc refs/pull/2636/head\n004161b021f24ad4fbe29130c0672742a4c1efd31609 refs/pull/2638/head\n00418b76634b8701e90cebb880fc7f8a1faa4e6b46c0 refs/pull/2639/head\n0040b079da3c6af9b1a139db5127457315034abcbbc3 refs/pull/264/head\n0041d2ee349b9919d416260e3717338f9b65e6443b85 refs/pull/2640/head\n0041c86b29e940e3f800f5760f11d41380537a88b131 refs/pull/2641/head\n0041cc703e4f8dbb366e8270a20c0cd91cd53d913a52 refs/pull/2642/head\n0041f3c5d59acfd34527284183af35c2bd0a7b422d8f refs/pull/2644/head\n0041ded67731c579c99af1671e569bbe7e889a633f44 refs/pull/2645/head\n0041b7278b4edf0acfbfd7a0b9230de099e37aad8611 refs/pull/2648/head\n004149585781890214a9f0a08b1dc952bc3cc3d7fd49 refs/pull/2649/head\n0040ecee40da8a3cfd90ad43cd05f7a3f0f47e67a826 refs/pull/265/head\n00418614cbd27dc368dc265816d801ed18e5d00fb760 refs/pull/2650/head\n00415af5d38da5724640f85bc05ba64a1e0bc347e5d7 refs/pull/2651/head\n004115f4b9fd2edee8bb6767003ef2afb27d86ff4c3b refs/pull/2652/head\n0041a1642fb968ee8ba6edd65113bd68e3f396500dae refs/pull/2653/head\n00410d08a2838b3e4741764cdc02cd20fbc164ae60f1 refs/pull/2654/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2655/head\n0041e43f1e2f16a91260fa2b263e8b968a3f535f62f2 refs/pull/2656/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2657/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2658/head\n0041d43b986486789b27ca98202659606351a803cdca refs/pull/2659/head\n0040a1fe55ab948b3507af0e547366e964e6076c0a43 refs/pull/266/head\n0041a5f399a9d582eccb24df4de26c083b04e572e3e8 refs/pull/2660/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2661/head\n00416e4ce8879df1a46060aa7b3a0c05ec18c372ee52 refs/pull/2662/head\n0041db7b359f0e8b3255b22f4cbd1b7ca78685ed381d refs/pull/2663/head\n0041c3ed87788b6021c49c8fc2b9d576b6366537c69a refs/pull/2664/head\n0041f4836610cc31a8a09c823c3fc84599ddb4210720 refs/pull/2665/head\n0041430da5fcc21bc97a11a462c7936f84bfdd1e7d97 refs/pull/2667/head\n0041115f6caf9f2265b6a258ec491d02f6c0b39cffdd refs/pull/2668/head\n004156ed2ad272ee8c04c6be6c1200362aeae05292be refs/pull/2669/head\n00401dfff6435abe32ec18ea4343f41053924ec0bc06 refs/pull/267/head\n0041bc8a9dd8a47a6dcb322502560c6f5a1d65f8aa77 refs/pull/2671/head\n004165d911a77093f0e33f73cd261e754112d094dd1f refs/pull/2672/head\n0041a2521a301d632a896d24596519077bdcc684dba3 refs/pull/2673/head\n00415859aad095aaca071c336ec429c2321951364f87 refs/pull/2674/head\n00412ec5dda14f2593535a8865717ff7f9068737f777 refs/pull/2675/head\n0041775f379dba856e9969c8efd9d84a9c0b34685013 refs/pull/2676/head\n0041ae09e4dc91ab9aea20446af75b61a79092c3d30c refs/pull/2678/head\n0041b6d02fc3a46c7aa43a0ada56a4a05dcf1bff91e4 refs/pull/2679/head\n0040aa35755406731fadfb18212be848b77d5bc133d8 refs/pull/268/head\n0041b678f0620138174c1af1564c46d599ed454ce4c4 refs/pull/2681/head\n004146a6462fd1e901470278e3665d8553037e986977 refs/pull/2682/head\n0041014193bfca96310ed507387a25f064fbf0610cc8 refs/pull/2683/head\n0041847cf4f7afbf164129660be68a389152f32fdc92 refs/pull/2684/head\n00416088aab6a59dfec9d5a9a954dca42c9b3fdab2d8 refs/pull/2685/head\n0041cd156d88f9c8da9fe495b6819e27c8fa332d0ac4 refs/pull/2686/head\n00412d2f49510dbfe5dfc92660ae8278e5c9a26ee2e3 refs/pull/2687/head\n0041d9d09dc8c2a3a4a9eb07acadadb87a928de092e9 refs/pull/2688/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2689/head\n0040df8678d532946bc9d6d1ed59ef24767bba5bf003 refs/pull/269/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2690/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2691/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2692/head\n0041557627d2be80aa8f8337ae5c841c82daf29ad30d refs/pull/2693/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2694/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2695/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2696/head\n00418321be766309bdbdad52f1f91e367589c6be4660 refs/pull/2697/head\n004142cb69954753c00db29bd25f72d8aa21d9466ce5 refs/pull/2698/head\n00411cfde0f7f6ff199b73e233d1e72c7bf3dbf8f2cf refs/pull/2699/head\n003fd12b185990668acabd3be3e2818f5d3154548672 refs/pull/27/head\n0040c60a5854a5f6fd7d431afb69b5b663056a6c9122 refs/pull/270/head\n00414a81447cd5435c74ad91a0fb2d85ce437b82c1cf refs/pull/2700/head\n004110865d01d184ebe325dc402150d8f0b500e22c35 refs/pull/2701/head\n004138262d8cd70f7bfcd9785e9e4be9ee7a075f85b7 refs/pull/2702/head\n0041c37b8f9d2000409e91259278670aa787e5a010b3 refs/pull/2703/head\n00419edeffa512ae514612ff4cf14bb271d03688c0f2 refs/pull/2705/head\n0041c5a80c1bb0cc6865bcc440a6ddce92af5cfd9561 refs/pull/2706/head\n0041b341add1cf7df7dc61b86e99d55b4e14ce2b1f3e refs/pull/2707/head\n00418af58f720a0a05c5fc147052a62899ac2ac0a425 refs/pull/2709/head\n0040cdfced31cbdbf455bdb87427fb458d6709f9df80 refs/pull/271/head\n0041887b5b2bbf1cc4a80cb5abd0c4af99551cd62da7 refs/pull/2710/head\n0041f9af70aa10c9580d624f687ffc071e66e6ae5218 refs/pull/2711/head\n00410c23b69f7b334ac6d4b75644d645ec0a24e72544 refs/pull/2712/head\n004130ed0c4b02a46a20561a5b2123aa08fe1c6e5f8f refs/pull/2713/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2714/head\n00411a91edfa25502cbbba58f8c139744aaef93a4725 refs/pull/2715/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2716/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2717/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2718/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2719/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2720/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2721/head\n004132b09542271b6dc5961ccf6e653d1517fd6180e1 refs/pull/2722/head\n004108a0bb08a6972d4f70752cc6a1d293ae603f07f0 refs/pull/2723/head\n0041d94268f0484742f927ee73bebc05131f09cd37e0 refs/pull/2724/head\n00412c8d08e44698ffb03ae857730ab6b14486bcf0e0 refs/pull/2725/head\n0041ade73c7449073a28fd5bd36a1d48fc9a85d91f0c refs/pull/2726/head\n00411432ffa7f85e9d9b31acbee7f313291a1acf5c5f refs/pull/2727/head\n00414efb6e194aa53d31dd1a5ffcf90e8dc70c9fd31d refs/pull/2728/head\n004089be2b28d522855a7d56d0d6781c841e2d9fe8a4 refs/pull/273/head\n00414a4e64e2fe93ee38e495cb246582f7ba1ce19525 refs/pull/2730/head\n004151b9ae5241247e80b30d68e9b983a8df1ad9f44f refs/pull/2731/head\n0041fc986f627df1f299c03b248a549844df6bb84ac2 refs/pull/2732/head\n0041a05ca8039996626cd40db82aca293ed64a36c439 refs/pull/2734/head\n00417751fbeb2c3e466476dd9b194d8fee925fffdd64 refs/pull/2735/head\n004166968de6c82b4ee867d38d170b5f9d1df9ed93fc refs/pull/2736/head\n0041ef55bd3f7dcfac478506006f469e50f7f0e01268 refs/pull/2738/head\n004160b2751d13b6888d0cd4f2625642f72fcb6dfb13 refs/pull/2739/head\n00413592dc2989ba7b480c78195899aa3a15460c688e refs/pull/2740/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2741/head\n0041d54a91cf61f504a353002f78111cf1a42d5766cb refs/pull/2742/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2743/head\n0041a755ba68a1bf8e48b50e4b5c00a84cfb0b9cb4f1 refs/pull/2744/head\n0041d621f965c8650e6697f74839464a84329f52c460 refs/pull/2745/head\n00415f80f7bda1910871b33cc8568eed9b9e0a067abd refs/pull/2746/head\n004127f34058a675bdba5e5e9ff196293398e560ffed refs/pull/2747/head\n0041ec6a31f01d35bbaf086bcc2098cab5959c632479 refs/pull/2748/head\n00416e76f8d379609f9945377b7045ab308979f816d9 refs/pull/2749/head\n0040abaa66143b82ff64782f3d8e5a726fa3d8ea674d refs/pull/275/head\n0041f5d9e64f8c83fe518d93b584cbb099143745e362 refs/pull/2750/head\n0041c5c4e3f5856a61bef515aa5e0a69b72826f536e5 refs/pull/2751/head\n0041bd209b316901966059e16cc7985122db957e854a refs/pull/2752/head\n00414fb5b70400f425e9b7c52d397373b4563539edd0 refs/pull/2753/head\n0041d344dd1ac65befdb61c7016d1ec2e6b72d42fa0d refs/pull/2754/head\n004119a3f119197386ef948b52e3041356e01cd72455 refs/pull/2755/head\n0041a0816f94ab06d17c770334b5875808ae5dd20dd2 refs/pull/2756/head\n0041d360762d855688c45c934912f14e3e07945d3ced refs/pull/2757/head\n00411a596384bb4ccf7e7a241bd5d4540d98b65ae151 refs/pull/2758/head\n00412031ec5f09cac3612093578697973ec78df3ee7c refs/pull/2759/head\n00407acf9f795de84bc83c6176a6e0332453bbe51fa2 refs/pull/276/head\n00413517588333f1a378675690923792341d2b94f08b refs/pull/2760/head\n00411e29bdcf8ed23a4dc8f043a0963a773c056edd63 refs/pull/2761/head\n004159daa621cf5085f140f7513b12bf98611e8b5582 refs/pull/2762/head\n00412a625ab871036149179a92d70bcedf0a11fff820 refs/pull/2764/head\n0041aabdaa18934aa47b6a1a682d02cdf3fcb974debd refs/pull/2766/head\n0041f9a984e7c1b1faa582cde1ab72fe6e07286bf239 refs/pull/2767/head\n00419cd85f118c2603fd0524f0d9b8b78e265063faa1 refs/pull/2768/head\n004189d47a15013cfb60bfd200cf61c47b62d2de9d5e refs/pull/2769/head\n004104db79d2fc3294c78027967576ab0f886228ddf1 refs/pull/2770/head\n0041bf7e690cc30eb306ea66ea0a7f53eaf21afb2601 refs/pull/2771/head\n0041fd69d044571f9c6daec232fc59bdd9a8d5d4125c refs/pull/2772/head\n004156b14b7449f7e3514178108b5b688ed8797253df refs/pull/2773/head\n00413532e240bfa976ff538013367aa27338b8380921 refs/pull/2774/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2775/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2776/head\n0041d0ada1d23b06bcd3948b924cdf761a8390569550 refs/pull/2777/head\n0041516179e60ccee64e0eff2f405286d3c4513bc459 refs/pull/2778/head\n0041a8e35df702581892410de7d98a5bdf2e53c671f1 refs/pull/2779/head\n00409ef86c610ec21e3a398ed7d7d02ae9b2070d19d7 refs/pull/278/head\n0041efa432d9e9e19623caf79c4dd0b359f6ee0984f2 refs/pull/2780/head\n00417ebc50d417b25a285bbcdc8ba416c390aa0bede4 refs/pull/2781/head\n00418f936d8ca8889845c1a1f3e468388b60b5384ded refs/pull/2782/head\n0041fffef8ed543bec1e79e2f1e3e668c2ad3f7aa1b1 refs/pull/2783/head\n00410c3412a5938c0af7c15a20d95e2b39e65f037a11 refs/pull/2784/head\n004126676724a4bc1eaca84139c94ece9cb77fe9224a refs/pull/2785/head\n00410efae10947090c7e2ba66ce048ee8933569fdfd1 refs/pull/2787/head\n0041eb8724b40c9693ce5cb7ba322c4dc917ec2b0166 refs/pull/2788/head\n0041c46c59fd46e2418d293f3c45575e0c1952c7ebe6 refs/pull/2789/head\n0040387db6d1376294aad267c4927a7abb44cf8c5a31 refs/pull/279/head\n004130f4ed16e3b290acecfd565720ebf92dfa5c69d3 refs/pull/2791/head\n00411b6820e13ffe15956e4973dcc16294c9b9ca9637 refs/pull/2792/head\n00418a10e02c2a94af79e599774ce224d022ad5c6b15 refs/pull/2794/head\n00411024b7d519a107554bc6a5b3c251af71cdd06b9b refs/pull/2796/head\n0041c9520de348b6bf3b70fb7f6db48d26503ed37c5b refs/pull/2797/head\n0041111952e89e593ebf05626dd8d8979745c7f81f79 refs/pull/2798/head\n00415467cccdc73e0dd78c1674d76854bce827bdee62 refs/pull/2799/head\n003ff487a58f5ca9cf47cc62624d6e74f38134172298 refs/pull/28/head\n00400f1e0091747295f93910650e5dc16de612fa20f7 refs/pull/280/head\n00419c1176adeff7fc3e6523c496d40242250e26719c refs/pull/2800/head\n004133a3087a7ea73bb06343884720a8f9f9c62dacae refs/pull/2801/head\n004113b27b8dfafcce495fbe3f919c2a286bd002982d refs/pull/2802/head\n004139de5c14157758242b12e2a1c73fd1bdbde80905 refs/pull/2804/head\n0041b4cb96c9ad88813e5705410a5bfe3b2d86ef0949 refs/pull/2805/head\n00415db28b0a667f51175fc6d808c004534d681e754d refs/pull/2806/head\n0041d748f3ee8c54e343b7bfabb9ea632b6d02a8c337 refs/pull/2807/head\n00414e8a542ed46dd0744ba94717980a42e6334a4c0a refs/pull/2808/head\n0041f9a76ad79b91979aa6ed8bbc9694104a7ae6cfd3 refs/pull/2809/head\n0041f49db036ec837a98011cb28e38804a4fdd57aed9 refs/pull/2810/head\n0041185aff83e2cea035f1f4c0c333eec954fa89d04a refs/pull/2811/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2812/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2813/head\n0041fd94f48443d79da98de552304653b908fe83e6ff refs/pull/2814/head\n004128fd0b9b9ea81ef284a99b149e5a69fb2f2c8e78 refs/pull/2815/head\n0041642bf0504d5dd0fd6160e7b508e546e37b27d905 refs/pull/2816/head\n004106c59993b4c84817b8b8c2a879cfcc5f3fcab8f4 refs/pull/2817/head\n004165dab2740390fae7815d53881b5c0bf6fa8eb583 refs/pull/2818/head\n0041d7956d5236877d7d2f1da49fe75dfd81059119da refs/pull/2819/head\n0040c88914a941222f07a6a29cd9ddfcd782d87ec1fc refs/pull/282/head\n00411cb455b505a3be35bd0696c41ff1ca5cbf113bd9 refs/pull/2821/head\n00418a57d72bc2f5d9182a56e4c882c44f51b994d627 refs/pull/2822/head\n00414dafa11d0222373c698b0ed2668a37112d491bcc refs/pull/2823/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2824/head\n00415dee54879ba73cd0c422fe0a7fc637a9cafa480e refs/pull/2825/head\n0041547568a2d0e54c919284b9a57ebafbd9cfca6a86 refs/pull/2826/head\n0041e0faf86c9025f64d5c083de17f0fcbaf8466cc0b refs/pull/2827/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2828/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2829/head\n0040857891acf88fd5e494c705e44f9721c73a6df2a6 refs/pull/283/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2830/head\n0041190bb1668ce2c7be361faa1a96626d4250f53bb8 refs/pull/2831/head\n0041dee7f03da3553448c024b4ff6ee96da427095779 refs/pull/2832/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2833/head\n00416faf3dd312ced029b468bc8b5bbb9ef12dd80cd4 refs/pull/2834/head\n0041476106a04b739c4a2d9f4106716d70e8c2205af8 refs/pull/2835/head\n00410c33cb5792dca5cffebfa2d9d9102cd51dbaa417 refs/pull/2836/head\n00417472807b8962255ea4eb7c8916c4b42e14872395 refs/pull/2837/head\n004119905886ae56bfffbc8027ce84ee5970e974503c refs/pull/2839/head\n0041c053afe6671014bd97cce4e5cb2189fe186e615d refs/pull/2840/head\n0041995f36545f3f9ce298b63235ab069bc915553ad3 refs/pull/2841/head\n0041611029f7c6bffc2b86c4e2a1fc3adba1dcb6c5ef refs/pull/2844/head\n004190ffe8e4fdf36ec73af89a4c91436c4ed5891b0f refs/pull/2845/head\n004180c8b887ac4cdd4094841524421b22da6b787757 refs/pull/2846/head\n0041c4775008293ae04c32d7c3a36e7ff69b6e6585c4 refs/pull/2847/head\n00417be76c68bf4172bec3b63c337c0d632105cd7dad refs/pull/2848/head\n00410bf3076cdf5cbf1b8d821346ccc8e36425af6447 refs/pull/2849/head\n00408fb04a0898abe7717137ec504546838abf6bdcc2 refs/pull/285/head\n00413dd6b289906a198f9cc4c554dd2d6ef75ad59b0a refs/pull/2850/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2851/head\n00418f8873ed698a9ea5322a04c707b034e5568bcc42 refs/pull/2852/head\n004119e2589154d7fbb20e089788154342e6735bd10a refs/pull/2853/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2854/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2855/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2856/head\n004167aabf6657e3b405f04ce576e39e3f303e4c66d3 refs/pull/2857/head\n004193a63ad748e1d6ff49af3c3f641a4ce09b1c4b0c refs/pull/2858/head\n0041f477c6940ea743f47e8cdb6ec14ba4d5c6f31838 refs/pull/2859/head\n0040ec88cf672778f0d8098070047e7050fd5821723b refs/pull/286/head\n004193d45871f40f122c1494b79931dd732891792064 refs/pull/2860/head\n0041add5751fd0bcd0f1e9ce7e1f414c786110915e14 refs/pull/2861/head\n00417d7c18855c6e7f1b88300c5d2cdeaf33f1cd0c2e refs/pull/2863/head\n0041e1d8affae17cacef6e7c1a01e901b9687538121a refs/pull/2864/head\n0041747e1da71770691f0100fb21f4a9efcd9575183e refs/pull/2865/head\n00413fd074245dcaaf739002d63e7c6a89f39d9bd1ff refs/pull/2866/head\n0041c3523af0d6087b244bae0fd6c6522edd441f011f refs/pull/2867/head\n0041ddcc982004944baa45c53ef7ca1d9bbd2404a40f refs/pull/2868/head\n0041404a259ae62f5ee0537a87a0ba418daff01b1998 refs/pull/2869/head\n0040a865ef6942833d38e5ca4c163e1008c9796eb285 refs/pull/287/head\n00416d2c55e7437107c19210aab82e8cb06479710d96 refs/pull/2870/head\n00418c5bff2b80e1dca212cf32b0541e1db6f439a5e8 refs/pull/2871/head\n0041ee42ed4e2f00d71a99e2e74e497db8b40efe6784 refs/pull/2872/head\n00418acbb8bb927c14c60b5edd34b3b2af09ce999fef refs/pull/2873/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2874/head\n00413f8c12ec2674220d32c8fe644a510fd712336443 refs/pull/2875/head\n0041207eeb6eba7de6c1bf8d6b06ab1d2463935d993c refs/pull/2876/head\n0041ac3717e5ad39d22f94b68123dadefb174cc1c9a8 refs/pull/2877/head\n0041392798ab0a782b71f84ed724a653c3a2ceb28144 refs/pull/2878/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2879/head\n004054a8f8b7ee2cf16d9090585c1aeaa651b1bc64fc refs/pull/288/head\n00418d3e1fe872525cffb71dc18a1baab4e5a437cb91 refs/pull/2880/head\n0041209183bea595553c350bd754b2aff1e42a411973 refs/pull/2881/head\n004182b2f5db7ea4dcc6523a5b3c758fd31f966d4840 refs/pull/2882/head\n0041d94c89dc945512ff6da6dffb573cddc5a82e244e refs/pull/2884/head\n0041a7a391b6b4ad844c44c0aede77ce2d85a00d9b35 refs/pull/2885/head\n004169e6819fea9cf083ab2b8d19a82544fe888e9d62 refs/pull/2886/head\n0041bb2739a9755747176cf784b8c5156d501d8222ea refs/pull/2887/head\n0041bf7c148b090eadb587832531d9bc1a11be06577d refs/pull/2888/head\n0041196dc83ce02e38d56abdc3e9d7fe696fe621b3a0 refs/pull/2889/head\n0040f6d68afa1708059c00684b5d0bd9eb9217661a66 refs/pull/289/head\n0041e9d2a7d9eb40c426e630610c08e2376c82b46278 refs/pull/2890/head\n00419d8f0b1efd8ca12e9a71d3f815cae43f13409a34 refs/pull/2891/head\n00419c7315590feb960dc4b0cb8e87184792d38ff7a0 refs/pull/2894/head\n0041a8a928fbe8ac833540e11569f44fb09c50410d54 refs/pull/2895/head\n0041cdde00b06c74be5bfbf88050cbec722f1462039b refs/pull/2896/head\n0041e51098f495561b99d18218b40c58d18b9e872832 refs/pull/2897/head\n0041b4992ee4dbf990acaec8fea6582fd215d1122921 refs/pull/2898/head\n004163d1a6dc14f8dc2090cac8341fcb3148195ddc75 refs/pull/2899/head\n003f58fce1249ceb5d65b7895d5cdafcdd7821772b6e refs/pull/29/head\n004139309f06c3d1e405348b53877af07335aaba4fab refs/pull/2900/head\n0041a92019df7a4cdc1d55077d35042ec51306378b54 refs/pull/2901/head\n0041d103b346ccb027171f710e21ab4cdfc42618412c refs/pull/2903/head\n0041e3f88cda1e69b25caf64458d0c836408c1d83323 refs/pull/2904/head\n0041a70352aec37960d0e9858a693594a6e2721f5313 refs/pull/2905/head\n0041eb6a90c12145cd3ec1195ed71f34ff63b557ce77 refs/pull/2906/head\n00413a11321134227846f1d78c3835a9237f99726257 refs/pull/2907/head\n0041166a833b8f4f2105c5263e0fbcbb41dd3752a00b refs/pull/2908/head\n0041d958d900898d7f5b612864e6b45751ff1a77b6d8 refs/pull/2909/head\n0040fc0d24e67117833b606a5648b3308f907d3cac34 refs/pull/291/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2910/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2911/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2912/head\n0041eb5efdcb6805ce3702f91409ecc208be8e3d5df7 refs/pull/2913/head\n004199db1b0e45b3889626c09c0386b16f2ccc0dbd4d refs/pull/2914/head\n0041ce58552dbbd96fa34e39f9c256f9c4f3e6417ca8 refs/pull/2915/head\n004139e378db7e1db7e8fbc3ba2dbcaf7e7eed22bcd1 refs/pull/2917/head\n0041d91a2f11298f61a16fdeda77e89811c621b2b56c refs/pull/2918/head\n004188f4b5c486f180f07ec36b145307069a83d71279 refs/pull/2919/head\n0040177b1e72d8561ae95a910e9666f3a446b2d607f2 refs/pull/292/head\n0041c5e9d21e5c514c0aff595aba357a8429d9dd9b81 refs/pull/2920/head\n0041e73a43793254c217f42f4d27ccde56e6e7b9dd62 refs/pull/2921/head\n0041c4151af86b4125532d999f72a5dc0f13c7feac60 refs/pull/2922/head\n0041a311476a5b3f9c34407bb5422ee93f7df236497d refs/pull/2925/head\n0041c73a96b6f7cfef4fd1e1bc00a6686956e58c3879 refs/pull/2926/head\n00418a4f90c0240285aa3638be184a6092b50c49659e refs/pull/2927/head\n00419fd44d4217395b540fda630c64c1e84ff1c532bc refs/pull/2928/head\n00414cc85a0e3d02f0d830721518f6fc02349e71f08a refs/pull/2929/head\n00403504293dbeb6a169d9c51279ee0c9fbbb4dfa58f refs/pull/293/head\n00415234c08ce941b082223c6b7eb15d4e3beb3898e2 refs/pull/2931/head\n0041fe1da8c674e09238c0c12fba310535de7b95dfd1 refs/pull/2932/head\n00412ac962cd4b4bb269bd863fe9b43f0ed894e1eb4c refs/pull/2933/head\n00417ad72d8ae97bae7adfed81b8db0cbffb45ff81c6 refs/pull/2934/head\n004118901307dd712f3d8ebf67544c34626b9c804fef refs/pull/2935/head\n0041838166bbf80143eea1206fc5f06ea0b2ca862d97 refs/pull/2936/head\n0041827912336c7a42090a005dd0630d07fcc23dce01 refs/pull/2937/head\n00413a2b3f7b74d733f29e2d9e485c1a2c433811af9c refs/pull/2938/head\n00413eafc2591f35d5cdbadde5e223332b3c8449f17d refs/pull/2939/head\n0040a91db92ab68ef5abf3590a4c6c1156cb496070b2 refs/pull/294/head\n0041be92d5ced97ef304d5a71685ce704aee8f998376 refs/pull/2940/head\n0041f951db346b984af75f9158473884985dff74f525 refs/pull/2941/head\n0041c355aa304b31f81a1fca44c6c1561c568c761e18 refs/pull/2943/head\n00414fba1b172a8d5a2f68fc5cd6ca12a831c60b1288 refs/pull/2944/head\n00416f3de20c9009f0276b5af06e5ddedf3f1608dad8 refs/pull/2945/head\n00419f1ff0f6391d3f8936872a44e48b686b97fe5ba4 refs/pull/2946/head\n00412599a7dad17dd6e74ee9452026fec56d1f34be11 refs/pull/2947/head\n00419ddcd6e9d446385730a6e688fedf98a689be02b9 refs/pull/2948/head\n00410b2408f69b00465c0d14a7bf4b07ebea2d45bc00 refs/pull/2949/head\n0040d04bf6c58d024bfcb395027a82eca6f95d812607 refs/pull/295/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2950/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2951/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2952/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2953/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2954/head\n004198478706e827d4da7fae302344ae4626f91e216a refs/pull/2955/head\n00412d97411101768867ad72b493c386b087a01f4796 refs/pull/2956/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2957/head\n004116f5297332724a0836ec2c4127680963d2171285 refs/pull/2958/head\n0041f4a55c33a40aef6a4d473a022ea238fa0cfdc6e8 refs/pull/2959/head\n0040ddafd0b526eea0b7449881ab78ccb06e260c2fff refs/pull/296/head\n00414cc577627d5ace18b86335424faa0938de06f09e refs/pull/2961/head\n00412d3a8921f5f49f140c892059bb33191d017d3b37 refs/pull/2962/head\n0041dd37c708309e16a05aba50aa5da35eb51db512ee refs/pull/2964/head\n0041f0be3bc7ccf9429cdc44aaa3b755d1eb1851c9f9 refs/pull/2965/head\n0041dfc0d77ffa7035fa30ac0af4fae7014f963d31c4 refs/pull/2967/head\n0040c6324c7def409e52d2a6a79e986fb1615f5677bc refs/pull/297/head\n0041dc8941aedde75407a3aa51a6c1c74480df6523f4 refs/pull/2970/head\n00410d937d9c75ad6efc0aa2bb61042774b161738f42 refs/pull/2971/head\n004189d5edb9a4181ae87c4903b25195657882bd8652 refs/pull/2973/head\n0041a8a4c03282d2c6a80d164305db1176f8cb4e0fcb refs/pull/2974/head\n0041b909d9da94007f878ce4ab9cd9c851ea8dce0e2d refs/pull/2975/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2976/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2977/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2978/head\n0041395fc6df1a91872baf88e570a89df4b5504d6ae7 refs/pull/2979/head\n0040e51c698385f0ce74c82bfe208d34eb74decd29bf refs/pull/298/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2980/head\n0041fad161ee283b537b0c97e577ae6d89bd371961dc refs/pull/2981/head\n0041ae21d3d15dd77c67430504f7d17fd2477187b397 refs/pull/2982/head\n00414b0249f355d436b42005a3be066bb0422f08af08 refs/pull/2983/head\n00417f0a8fab9dc5d51e07afdc57382825219cd53ac3 refs/pull/2984/head\n0041e5e3efb0e0a28772c2c31ecf3de5a04da09065df refs/pull/2986/head\n004126c0e0a21de2a2c3fc6dcb207347339e6ec3f18a refs/pull/2987/head\n0041c5d867b4caa4836692808d29b74a150d0f7c15b3 refs/pull/2988/head\n004130db1124016097a4d5f1736deb00c48b77410a24 refs/pull/2989/head\n0040eb68f82a1c3356d0ff11637395078512c96697e8 refs/pull/299/head\n004119a07de57a21994b6f1478a8d2410517ad829e1f refs/pull/2990/head\n004167f77272c080407d5a2e01de41af55b59d15d782 refs/pull/2991/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2992/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2993/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2994/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/2995/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/2996/head\n004189007174d4749c0b3343f199e57ae195ff29e6e0 refs/pull/2997/head\n00411645cf0d67d85a94839e05fff2ffc161595db433 refs/pull/2998/head\n0041c30e305ff7f5908e389912f53aa49ee5403e5da4 refs/pull/2999/head\n003ef0cdbde101164b659a1c59b6b400472820703130 refs/pull/3/head\n003f3ff993226b672f16415168f26e670785954c0c48 refs/pull/30/head\n00403ef1b3d7d647af747b2a9e03f17773dddf5f4db4 refs/pull/300/head\n004146c427606410f135353b204dd06affe01c89b7ad refs/pull/3000/head\n0041c6a6b896cf2869a9bfd0dc6b52efbe0e505b4391 refs/pull/3001/head\n00415cb1ddffb06ca75562c641d3f28a5df1a791d5db refs/pull/3003/head\n004168cb24921d8a037f8157f1a503da88d61aceada9 refs/pull/3007/head\n00418f1bdfebbee3aa1af953417f21e4253ba8ccfb74 refs/pull/3008/head\n004106f28780b388130601eee7ae3bc9d0b3d5940663 refs/pull/3009/head\n0040fea7633143d0293f5a61d8aaa49da07e048e6563 refs/pull/301/head\n0041cc697f8c8204edcfae938dd6caf10054f11a43b6 refs/pull/3010/head\n0041d2f0755b32b10522939c79b6e8b4bea541abfcde refs/pull/3011/head\n0041106ab5e40648e8387526abe3de1c8ba4b04e5ff3 refs/pull/3012/head\n00418856379bccf277f9c62464aa427fa0b2d6f67577 refs/pull/3013/head\n00412bdf7f948e06f331ef338ae7db1d57dbaab0e751 refs/pull/3014/head\n0041442efcf258b28b45d96e20a60affc5155c54bffb refs/pull/3015/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/3016/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3017/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3018/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3019/head\n004077abff46e64d91993f117bcde1ce703b89840763 refs/pull/302/head\n004191785546e68c04c40fb754c656227f5fa1c66438 refs/pull/3020/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3021/head\n0041354913c4dd35a4d63665f5b527cb599d5de135fb refs/pull/3022/head\n00419b1873f19a5d21f87641318295f02c13e50f07fd refs/pull/3023/head\n004185625d97bc9d4a09294d098f30425dc5c95ffc03 refs/pull/3024/head\n00410933c86891d7c6f5420e1c41d3b23e79b3744686 refs/pull/3025/head\n0041b47c661a24c4242b795822dd155bb69a2a3b1c82 refs/pull/3026/head\n0041f7e4eb57d8caf0663fe23bbfc9a5aaf9cc514655 refs/pull/3027/head\n004180eceaabfa2e1a4620c0512a85a7af6db45d583b refs/pull/3028/head\n0041c80da837eb9e1438e795105b35d4abf12d38a590 refs/pull/3029/head\n0040dc2df970334ca11c74290d169c70390a8eceaccf refs/pull/303/head\n0041a0860d3c5649616c707f5f0c977e17939245bd6a refs/pull/3030/head\n004113a552ea3fe1288a590f9b931d8371336f1d7b72 refs/pull/3031/head\n00410159e086cfb5918c03061a62d80e15297d6ed927 refs/pull/3032/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3033/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3034/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3035/head\n004107fa0d7988e84f3b3a34ac3dac399ba193887524 refs/pull/3036/head\n004100cb652efbe3060aaeffa5c4f3a7d31e66a0c231 refs/pull/3037/head\n00412b6b3b940c64c5517b64a7c03bb529866a421e10 refs/pull/3038/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3039/head\n0040fade621a7f723174ec82fae918578b84229d858b refs/pull/304/head\n0041f961c3c635c28cac218d79b63e95e01e5d8b810a refs/pull/3040/head\n0041a0214ffea0a79b8e1405df69d708d2dcff505ca9 refs/pull/3041/head\n0041b00ae6ad393dc643ede45c53649e5302e1fe8e20 refs/pull/3042/head\n0041dd25cd187b995f3e81cd26d138c783f52d2ac74b refs/pull/3043/head\n004182de78c184dafbfade5f45c2af21a6c14369b0b9 refs/pull/3044/head\n0041bd501aa0621037cd9004b2702a1e76de442e5965 refs/pull/3047/head\n00409d95fbb972ce3b32fa23eb739dfbd269aad20f3d refs/pull/305/head\n0041e882cd65728241b20bb5017316c286dfcb00dfa9 refs/pull/3050/head\n0041914aac4b7d550541f1b9cbfc7fd9374bb5feb497 refs/pull/3053/head\n004108f216bd6e902609d9aa84f30a50bc6c3bdc3c06 refs/pull/3057/head\n00417286d58bb1c5582b1add8d32d1696d6c8947d093 refs/pull/3058/head\n004132f4c488f7dffa308f82df5827a165e400a5c0c7 refs/pull/3059/head\n0041a5db19432ad9c33ea0d970dbdcd1d431b0e766c3 refs/pull/3060/head\n0041177357fc096b77dba00e31d85d3d3f31e96fe49e refs/pull/3062/head\n0041ab5adc598eaa84daa237eddff158db70bce13f78 refs/pull/3064/head\n00417df290ce8f2f3cf36a6058b7ee72350973fe8f83 refs/pull/3065/head\n00413549c650ccc399f36264c7b1276eb1254f33fa98 refs/pull/3066/head\n00419e4e3ab71e51de615b75393c67b741f316e9e752 refs/pull/3067/head\n0041fa1a05258fcedbc38ad9456165ff83c1cb8f97d4 refs/pull/3068/head\n0041397c82d0de51dd9ad7be2caf64c90bdccffa2023 refs/pull/3069/head\n0040f25a65409dfa4ea967d1b1a7d134da5013287dbc refs/pull/307/head\n004150bac02853af6b495043453ef4c7a50e2931fd64 refs/pull/3070/head\n004109feb895a36ac0927a24e94c297ed03f79b899fa refs/pull/3071/head\n0041ac0931b70d8680b25d430009007e1d9f0970a082 refs/pull/3072/head\n0041d0e784b90d1f359fee5ee6bf20689d6858d3161f refs/pull/3073/head\n0041807a02caee95fba47c7818bdd81030a60ca6ac20 refs/pull/3074/head\n004164711b7a7947fe8f441cbf6bd04b82da41128ff2 refs/pull/3075/head\n004158dd885ff2de27511b331c3bb7e892fc67998935 refs/pull/3076/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3077/head\n00414bc4dc9bb7cd85b5665f08454664843921f196fb refs/pull/3078/head\n0041ea8f0f79cb8433d5456fd82b8c7599ff82cac75b refs/pull/3079/head\n004073411ce4dd3994d9dfe6597388de7781b803e056 refs/pull/308/head\n00413805c23b7f29a1ec1710359c4f1d1e6df31c7ba2 refs/pull/3080/head\n0041925ca8a475d5650662ce8908458863e6b658d6b4 refs/pull/3081/head\n004100c3478e13944f99a154dca4ef7aa289f97fdc19 refs/pull/3083/head\n004158fa551ee7d146fd25770ed5734553f664912794 refs/pull/3084/head\n0041dd4a9fba9528b3cf0f22103d590ae6804ac8ad4e refs/pull/3085/head\n0041c1a75222f07f11b881558cb5ae85db705a13afa6 refs/pull/3088/head\n0041fc3357d173e441a822781fc46288b787cddf8dee refs/pull/3089/head\n0040e3e35a898a1e3a1106095f4094c748e635c54e5c refs/pull/309/head\n004101d7427d06d0aa5aa4795321ce1d9a796a8f72e9 refs/pull/3090/head\n0041f2a910f11286b1fc1781afd9e31eead170e172bd refs/pull/3091/head\n00415c0f8bf021cb2768cbcf264a04229a02cb562e6f refs/pull/3092/head\n004133dd2316429de872f26aa1a3f70db605e636489b refs/pull/3093/head\n00414a943449ddac590474233c569576074bbd67a59e refs/pull/3094/head\n00410cc43c1500774d5ae34950adc14a86a1a50a949a refs/pull/3095/head\n0041222ea10609bc06a812aba8463bc3cbf52d509285 refs/pull/3096/head\n0041c9149607f53d653b6d6869d66d202f915c2082e7 refs/pull/3099/head\n003f03d5ede47071e352bd5c48c69b4156324c71a038 refs/pull/31/head\n00401769ea723a9fb250a7118164ab2effb91e1c3461 refs/pull/310/head\n0041b78711a5ee79bbd7998de91aad6dc1295e22f62e refs/pull/3100/head\n0041ecf58a0c6459d9f245525ab2c253af0a9b6a83ce refs/pull/3101/head\n00412e4e4d113a2fd913d7d304985cf9ccb8b576c766 refs/pull/3102/head\n00418e86f1ef7b8cb02e3ea4a1cccd25144efb99048d refs/pull/3103/head\n00414fc6b776cdf924caf51e2e953108fac00ccf42b6 refs/pull/3104/head\n0041c6a1fbe65b831bf87b3246b1175bf02b2f810bc9 refs/pull/3105/head\n0041630dfc9cc184569e9ebdb67f290c75dae6f9603b refs/pull/3106/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3107/head\n0041f6d4c8fceab5b87f3fef22019f55339a73beb04f refs/pull/3108/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3109/head\n004017d50a8045e6ab6452e1da82f9c2ee2895bcf12c refs/pull/311/head\n0041bf09b2abf49a4f3e2e6602bcaa946962a18047f7 refs/pull/3110/head\n0041c1e468882a3f011e83172b67f225f99315494009 refs/pull/3111/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3112/head\n00415473e50a8182ce99947ff83ce1de10ee3c333fdf refs/pull/3113/head\n0041e103a9d6731021989cbf6d7eb67a196ce58e3837 refs/pull/3114/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3115/head\n0041e564df2a7bd69ce2cb4ac1b501944286e8071b2c refs/pull/3116/head\n00417694475144ef82b5ceca67d9dea29b9b0e2c616b refs/pull/3117/head\n0041782321d204ce8b7a44192878b95272398387cd44 refs/pull/3118/head\n0040188650c8960ee4afdfbc466178bf680e360e74a0 refs/pull/312/head\n00411af0d27a4fe1110f3e723c502227cadeba76d7e9 refs/pull/3120/head\n0041c5f312da17dfa2ef648c188947d0e802b0a0bc5e refs/pull/3121/head\n004170e933c33ad5df01e4cfd13c1f1d638afbfcef60 refs/pull/3122/head\n004123b294193aff6eb042da70f98f0d82fc7ab15f96 refs/pull/3123/head\n00411a8f3cff55c5ef37d9259044a32169b4b2bae1bd refs/pull/3124/head\n0041fcdb11e4df6ea8c0689e5da738599987ccec55b4 refs/pull/3127/head\n00411caa240d65c4dc07de4e1f0260b5aac50aade9f4 refs/pull/3128/head\n00414c34c0b48625de98d87cecd1df9dd2c780d172cf refs/pull/3129/head\n004022094a80c98a2a8e1eed141c4424a82681dcc2ba refs/pull/313/head\n004125119e4da3eb317aa14f22d36e5405bf47801726 refs/pull/3130/head\n0041039259cd1ef4ea16e732e740ff1c4a6938c58964 refs/pull/3131/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3132/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3133/head\n0041527572a2cea9f0e08f0334e74b30db2c741efe12 refs/pull/3134/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3135/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3136/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3137/head\n00413d1aa3e23a2146765bc94d0c9c1056005582eb3b refs/pull/3138/head\n004164f98fedba4b5a2d668dd3942d46d895b64a5713 refs/pull/3139/head\n0040d6aad74d8aca422749b3a63a359460431e624f2f refs/pull/314/head\n00417dd22afa840436ad016a08f9f2588dcf13b7b44e refs/pull/3140/head\n0041f3bc32e8b6482819431640f7ea46152581d804c0 refs/pull/3142/head\n00413f87112df4042dd8a06c27f1c25a14f803a61912 refs/pull/3143/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3144/head\n004157c03567f1b892b18e88bddf1e1166cacfcc123b refs/pull/3145/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3146/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3147/head\n0041c755c5203224f23cbb319b1749783af14f31537d refs/pull/3148/head\n0041b65f27f9e85fd6b0a16a499edd5ba5db3548d7ab refs/pull/3149/head\n00419ceeedd79a55533bbac0e9f6938ff6b1fd1c6114 refs/pull/3150/head\n0041bb1cb86a28fd776afe65757647eb41e2cd14d12b refs/pull/3151/head\n00416c93f87696ee00891b0146ea6f3be8dd53659a6a refs/pull/3152/head\n00413bd8359e38f1c5c33f590ca406dfc1bebc816cb9 refs/pull/3153/head\n0041cd8185fb4a44ed1280f3bcf571279fd40a45494e refs/pull/3154/head\n00411f3639f5dc1f19a3b130079d2aded178820bb80a refs/pull/3157/head\n004193743e8e7ca91fc3f0be3cf5ebd3ee4bb1a16772 refs/pull/3159/head\n00402a2b2599c2ebcf9032b67da26bc4d1816b6315d1 refs/pull/316/head\n0041d8db9e7af6d9b52bdf5b79edc8fe9e27ae7b67a2 refs/pull/3162/head\n00413860c5f8a5afe8107deaa7b6d3e75584441d70af refs/pull/3163/head\n0041a5e1d3c04d2c5df7e6a025c115a86cea71d320fd refs/pull/3164/head\n00421725324530ba9a0a185405ae4f5c4c018f3937db refs/pull/3164/merge\n0041301b76f411c0f8a7245584224a593eb62dc38ead refs/pull/3167/head\n0041f1baa53e91449c83f5a9b39f57bb88ee791a9bb9 refs/pull/3169/head\n0040512f4a594dd01c11dffeb7f3a01f6ee2910e2446 refs/pull/317/head\n00411d75f8cca72cbc4656e4633a5da804d5b8e06e63 refs/pull/3170/head\n00410425c1abacd948dfd9f783f3bc7d1050698cfbab refs/pull/3171/head\n00418897b145798040832c08b182684dd7e9da8ea28f refs/pull/3172/head\n00413870193fe93ad63bb05d4bef5c49845cd2e8be97 refs/pull/3175/head\n004132fa682339d2e337e0a5dd822383329279a6e081 refs/pull/3176/head\n0041d974f9aa07335c498eb3b694024fca4143b15745 refs/pull/3177/head\n0041da97fddd86caf5f4211ff98fea9b79ea16ebb269 refs/pull/3178/head\n00413e5cf953d7d95a1032558f7592844646c1f23282 refs/pull/3179/head\n004115a638b3e5fa3f855c20160fda14eed496fd6a04 refs/pull/3180/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3181/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3182/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3183/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3184/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3185/head\n0041c1cbe6c7da136974a98477bce101eefb7537f08d refs/pull/3186/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3187/head\n0041b0bcc9c9bdd03cdc12018ab04c3bc3189bcb9356 refs/pull/3188/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3189/head\n0041f7576fa840f9fb516a3b7cc04871c1cdbbfcb67b refs/pull/3190/head\n004138c5c17bba807d3cb7fc4172d1729858cac2653e refs/pull/3191/head\n0041caa52c27598fce1d44a2aed4776f509fe601ff50 refs/pull/3192/head\n00412771f72491c813726d134f78bb187d83f529bc87 refs/pull/3193/head\n0041cbb17a81efc093c3ce6889392e84c6692ac54528 refs/pull/3194/head\n0041881b2f0fcba03a8ead11b10a8448db8e9bd9b941 refs/pull/3196/head\n0041c5245cacd191db3a78975f42525953338a012e0d refs/pull/3197/head\n00417bc13b16667fc68a2ea49b2b0e2b6385fea8cfb5 refs/pull/3198/head\n0041e78ba918f91b4ec532200ee53f1da1659fa5019e refs/pull/3199/head\n003fd46883d4f6bd0de3fa54570e25592d65177a8099 refs/pull/32/head\n0040fcf3222be5f9d8cb2e4bc4789a8ed0ee7f8ecee9 refs/pull/320/head\n0041cfc7fd1e75225069ad5be39c99569b2cf3e5c1f6 refs/pull/3200/head\n0041b8fb33785570b28d9d0a64e1bc639538ad9cc050 refs/pull/3201/head\n004187cc5b2deda1e3a5fda04b5eac4790a056880df8 refs/pull/3202/head\n0041676388f4b2034b023016e2739abc4df86a5689e4 refs/pull/3203/head\n0041da4bd851cd5122ec79be4589066b448a692e51fd refs/pull/3205/head\n00410abfbb2eef7681534c04998e97874e955d576b02 refs/pull/3206/head\n004154e7db1008c998c907d4fa79bdb6efefe65f66c1 refs/pull/3207/head\n0041a8d34ae9a573564b7d0f766365af3de1871138a0 refs/pull/3208/head\n00411d546967bf9468228e4caf8f9918fc59637cea8d refs/pull/3209/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3210/head\n0041b2e2a887e2d9479c2dd947d1e586ee6281e35a91 refs/pull/3211/head\n00415db33ba706ebe24708bce88cc944539381844769 refs/pull/3212/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3213/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3214/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3215/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3216/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3217/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3218/head\n0041d68f6f85e95df5e66154c9354efae427d1f1114b refs/pull/3219/head\n00406c285e160a26c4f006c041d13fd6aa15143b3efe refs/pull/322/head\n0041c67e9e47b64228bba5bede93b3bc8c902365e327 refs/pull/3220/head\n00417a0b72b6d3aa7ecfc94b6ca5c4e43683ad5c42c6 refs/pull/3221/head\n0041a724b82a564701bc4b95821a2f04d36257bf14ab refs/pull/3222/head\n0041f3cc09810b6210e0bdfb4f96c81de2aee8939dee refs/pull/3223/head\n0041feb0ad7c5e6e7b550b125dbfd844a6c62918bed7 refs/pull/3224/head\n0041737b75a44263778aa0254a283c6db7a481629b1f refs/pull/3225/head\n00412c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/pull/3226/head\n00410df532eda1cabd74d7117ed65ba361bf85e9d263 refs/pull/3227/head\n0041436a2e9f9931e797729ec45b13edbb507682526d refs/pull/3228/head\n0041fef018091ec9da5147c7da86c75a4d1af44e21c5 refs/pull/3229/head\n0040d0db8c21ce1b0544a59d3b7b5cbd6aa8bd34a46b refs/pull/323/head\n004171410a54a301ff26d732e7ad4bb4ddff8e564f65 refs/pull/3230/head\n004111775b9a66c24572472b9bf58a7471441cf90482 refs/pull/3231/head\n0041c61acf8038b754fa81c6d0376ff29ea861d91b3d refs/pull/3232/head\n00418b5f88169a1a3476b6eeff3eda03c7f9ec66c17b refs/pull/3233/head\n00414a5591f70bb35c6553d449e7d835881a7e623eb1 refs/pull/3234/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3235/head\n0041af460dd7e6b20eff0011b9eab1f60be9c8355e02 refs/pull/3236/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3237/head\n00416ec64a705e1ea95bf760714bc867be48ee1db93a refs/pull/3238/head\n0041ad6fcfae08211757c8b36d14fdacfe54131f9bcb refs/pull/3239/head\n00403dfa0a0b07889e25c08af41775e6c8edaa3df783 refs/pull/324/head\n0041d27aa3dd1a6c7e66c35ea28acf12819be3cb8d30 refs/pull/3240/head\n00410883a7dfc9425531c544cfa19d8bf7aef21679ad refs/pull/3241/head\n0041f09b7a2d5f0b6cf75d93c73dcc0623ccdd11081d refs/pull/3242/head\n0041cb5ec97318f4e2e71218c8092e796601615660e6 refs/pull/3243/head\n0041c0ab597150b894af31fa84b1ef95135b4dc4387f refs/pull/3244/head\n004134c9f03e1f35d94f37be30c1d551a4721eca6639 refs/pull/3246/head\n0041625bbb79540f688d991c9c17cdc61edcf326d238 refs/pull/3247/head\n00419b4db2f8ffd00b1ce51475978c989d65c4ebbdf4 refs/pull/3248/head\n0041cfc81ae68582be96f901b432b88c715885adf462 refs/pull/3249/head\n00400138593116226511e9fdcfd6eac0830600bc74c9 refs/pull/325/head\n004190ebcbd10d637bc1c41b31ac0b1395f3b18817dc refs/pull/3250/head\n004177dc069ce11a0f4613631b8cac4c0e08287f63db refs/pull/3251/head\n0041be5df1340fe1e722ed96bc1c8d2143f8aa72037f refs/pull/3252/head\n00414d9b3d231594bb3a12d149e0acfe9d052fff0457 refs/pull/3253/head\n00411baf5b1f4e6199d36fd7b6c59d58c638c94227e6 refs/pull/3254/head\n0041dd784206b936de3fb626f985a3c2b913ce4206f4 refs/pull/3255/head\n00412fe04363a8e5ef40c220a24c394c32d14adc57b7 refs/pull/3256/head\n00414def6adce8d6e0dfea61f97f2d2ef30c9519c0f5 refs/pull/3257/head\n0041e78313ca42db27b5c006f09b0f0759b85ea8e24b refs/pull/3258/head\n00411486fe15bcc610f171233cc9583d391588e29ca4 refs/pull/3259/head\n00402a83855d83f6b56f76e63113ed2cc5a82ff7fe15 refs/pull/326/head\n0041cc6198702dc46b2be7751a57aa99b04a574814c2 refs/pull/3260/head\n004112c052a038893bc0929e123f0374241fde5cfea1 refs/pull/3261/head\n0041fa7b9e1dad8947edbe6d4454ea2e75c4e91fe775 refs/pull/3262/head\n0041f2ec4d1c728596f42f5a4df1c482752049b418e3 refs/pull/3264/head\n0041ec50b949ac70d8cc72d648af3d2d6393ad95c3c5 refs/pull/3265/head\n00419aa3fba23fb804cde1e65a1b45fd9f319b3977bc refs/pull/3266/head\n0041eb0dd3c5254fd3880fde0e229659f83907b69ae5 refs/pull/3267/head\n0041738ea0ba90d957d0db64b31048ef6f568cfdd387 refs/pull/3268/head\n00417fc5c0a44b0a2594a637765e3b6439f42c875cf2 refs/pull/3269/head\n004042df6533086ebd31dc513f98362ae1b5d227f9f9 refs/pull/327/head\n004126c131d22b50920b39747af79b6479584caf72f5 refs/pull/3270/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3271/head\n0041678fdd47a634f2c65477b9d8db3919cbd6d8baf5 refs/pull/3272/head\n00416ae5d89cd751708da6774342451710b2102f123f refs/pull/3273/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3274/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3275/head\n0041ef5dac2e2660257c90bfb99b1666624ca783288c refs/pull/3276/head\n004100c1ea1992b1272e41648c5d3ffd46d7f078857b refs/pull/3277/head\n00416dd49087b012e7be82fd3c8722976418cbfabe3a refs/pull/3278/head\n0041305e49c61c765c2814662251e615f96c5bcafbf2 refs/pull/3279/head\n0040bc268eb837250fcb91b113b00f86e0546948b971 refs/pull/328/head\n0041f6897c6fb08e2323e3638b86f7f2453ef7dbdc6b refs/pull/3280/head\n004174f122d6052b7b032e69fe9e37247805b2f1f98b refs/pull/3282/head\n0041308704455f5588ff6c780473875a8636a4e7c7a4 refs/pull/3283/head\n00415e0b2423a0b63fd975d40b255dba2a3ee4804d81 refs/pull/3284/head\n0041fd5e607cb9690a658a89fa4554af258e87ccc38e refs/pull/3285/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3286/head\n0041fb862020d928db7bc4e7c80542154ac4671adf14 refs/pull/3287/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3288/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3289/head\n00409a48ac5465f8ac146f2f3838751b9ff39813568c refs/pull/329/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3290/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3291/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3292/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3293/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3294/head\n004119cb466c0cecb33148aa4eb85570bbd896f0c561 refs/pull/3295/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3296/head\n00411b4ea72e09c0bdb92268c7c75c83b686f947b44a refs/pull/3297/head\n0041fad80248eead0ece21b65c060b7e2848943a5e83 refs/pull/3298/head\n0041d4f0d0ee18cd3a3096a60fd4d43b2336d54bf9c2 refs/pull/3299/head\n00403319fb852d36a0ab98729c8024b8abb8ad08f9be refs/pull/330/head\n00410887c622c076680ee77b94c85c56adbbc439b4e7 refs/pull/3300/head\n004163ba7a9e5a1fd4edfa3b19ac9126eab8279851a2 refs/pull/3301/head\n0041c1fb24440a335ef5d06026d52d9e32b23fc453a6 refs/pull/3302/head\n0041cc6a9946247228c4cee1c08702170f3bf5975846 refs/pull/3303/head\n004140ba224a80e301b396de4aad5b60ab053c149940 refs/pull/3306/head\n00414be1679a9401902c1c6983b95f9b8e439d4a34a8 refs/pull/3307/head\n0041531550e76261d5d68bcbbd14b137e1e10d638c9f refs/pull/3308/head\n0041b60a9a4a1368a55a089161ba073516dde4badc5f refs/pull/3309/head\n004052d3516888f1fde9300fd46ef43c0d35fbdc94f8 refs/pull/331/head\n00415ab57c181a2ff7e50bd569c25829b195d2d11298 refs/pull/3310/head\n004157f3141854c7612cd83ec2b67240b1f669310091 refs/pull/3312/head\n0041230e26b3580c46d5ff761f3172eaccca329d1464 refs/pull/3313/head\n0041a3509d4d1770f70757f11e3c8630b8be58c70024 refs/pull/3314/head\n004129dfbdbdce446cb5a85436f7acbd60d72109dba0 refs/pull/3315/head\n0041b17b1537a266a62983c1217c2bb300a3a6ff021b refs/pull/3316/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3317/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3318/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3319/head\n0040f70db31210bb0973824c06b471a699710c676157 refs/pull/332/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3320/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3321/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3322/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3323/head\n0041b34f6c1b69b1b43d8ad39d084c1cd4fdb61a237a refs/pull/3324/head\n0041e27fa0a3451e233334432f70f0862c58bec109ec refs/pull/3325/head\n004182ce5375e0fbdbdaf6dc82753c3c539ac19d2b38 refs/pull/3326/head\n00415be6dc574b3ae8dc190997146b02668e88eb53e9 refs/pull/3328/head\n00419fb7c07ed5c0aa172fe959e1045400ef89943394 refs/pull/3329/head\n00403e3f7cd474fcd238df1e8a1d85d67a1ab0a52684 refs/pull/333/head\n00410ee8e72bb1e9daf79c6423250853894c8ec3a3e8 refs/pull/3332/head\n00415d04ae469c2c8671d527f9953c4c3e3f1b1db4b9 refs/pull/3333/head\n0041b64830c986d329f3229a4092dc7c7c57d1c22b10 refs/pull/3334/head\n004116faa736187a33564513a188a23ac8ffd0642341 refs/pull/3335/head\n0041ce073adbe1be0dbd75fa58909fd3fb111384a4e9 refs/pull/3336/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3337/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3338/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3339/head\n00401876aad84e6175712758ce6d3db16d7b16ed4eb2 refs/pull/334/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3340/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3341/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3342/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3343/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3344/head\n0041e8baef2938dc547bc29b1629d8026c54f4400a36 refs/pull/3345/head\n0041da1202cebc3b5e248ef67e030e6ab86c458c15c9 refs/pull/3346/head\n004102068f861a1ecb6465e26d91a41e48db32f4f074 refs/pull/3349/head\n0040ffe7d673a10f32d59f1cbb96cbe7465c7b5dfe7d refs/pull/335/head\n0041d3c6c60331c3a2acaccbf200e13784b08786b731 refs/pull/3351/head\n0041100704081c253ff7dcfd7b2757f482d3c70c72be refs/pull/3352/head\n0041e5779f2d437ac22e3e52ead7cdb581ebbaf7545e refs/pull/3354/head\n004163330e4e304834f693186981a5320bfe33f6739b refs/pull/3356/head\n00413a25e5b19cc279ce63271224009a48df52f652d1 refs/pull/3358/head\n0041e26969b39d4e86f7ad3fdf337c5bcb79781d855c refs/pull/3359/head\n0040d2e8a62db572f1e557b85563c10e6468397124e1 refs/pull/336/head\n004145846bcef976b27a6c735ded57520b949143cdbc refs/pull/3360/head\n00410e404bb88ae07b8c0bf36a824ad77e49cd79686d refs/pull/3361/head\n00413592d6a7330432e0eb681ff7f30afe267a4f890e refs/pull/3362/head\n0041329aa16ea10c1bb6841a74f2cb7b7977e3ce3dc0 refs/pull/3363/head\n0041537fc5544be92798c1e691bd7c47b2ae5f49e56e refs/pull/3364/head\n0041fbdd56ed156b1e0fc2b12bc9656575ea63b1c826 refs/pull/3366/head\n0041290d0c8d317e2360ac229e70904433c3a3b62e55 refs/pull/3367/head\n00411e9702f14c9d0ddec4d3fe5dcd39bcacf995ead3 refs/pull/3368/head\n004158dd084bec475b82ca7de636ded933e5f26cd0c7 refs/pull/3369/head\n004001277a6291d8d62f4c8fc93e0bd9781987134261 refs/pull/337/head\n00414713dc20935765b3e4235da556ac6417a94b662b refs/pull/3370/head\n00414fc268c46bf699c0a5712870d826499deeed5e38 refs/pull/3371/head\n0041b339ba208c34d4b2ad57e1c22de799c5e6a3746c refs/pull/3372/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3373/head\n0041cb34e3ba48b46fe73b811c05592ce59d5dabf829 refs/pull/3374/head\n00416bbdc88faff9256f7f674f46502c4c4a133f5574 refs/pull/3375/head\n00411f72669b91743bfbfead637ce673ce0c3fa66bb2 refs/pull/3376/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3377/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3378/head\n0041f1097bd38cdc05ad8227ddd3437765c63cde96fa refs/pull/3379/head\n004052f9b1bf33426893d0bc0fdb1b80e02af46f2753 refs/pull/338/head\n0041c96e1f87f3149962b092855ff074173acb7249fd refs/pull/3380/head\n0041f927345a158fa12008caf386921fd97832ab9e2b refs/pull/3381/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3382/head\n00417d58425a9d987d51e44fd45ab6f80cf1891e1a34 refs/pull/3384/head\n004150c773d60e1fd6c361ada093264c327ea4460ee2 refs/pull/3386/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3387/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3388/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3389/head\n00402b3d0479f0eac553ca8005279c7a6a23a8591853 refs/pull/339/head\n0041ed19906a0de53afca8303ab7610c890f9cdf357a refs/pull/3390/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3391/head\n0041f5640385ee6e8caeb0c743e2adfa6cac33850f79 refs/pull/3392/head\n0041d4217e327b35257c89261a25e3dc237f608bec87 refs/pull/3393/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3394/head\n0041e5fcdc6f1692e4c2c746bc12fd1222f88b0144d2 refs/pull/3395/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3396/head\n00415d08b9c9306f10bd548b1c1adfaa182a3ff91ef0 refs/pull/3399/head\n003f23cc473894a09cc2c4051db85fd3a42e4eac77fe refs/pull/34/head\n0040d6c78da57ab21135f81cb5a2b6656dd9309c327a refs/pull/340/head\n00413fde29aad92d9e308929583d45ad89d0d113c5e4 refs/pull/3401/head\n0041da781cab9cd31cb88ba88bc42fc81f3259d8b20a refs/pull/3402/head\n0041d4a3e93868dd08f590b554d696c8887e45c5f3c9 refs/pull/3403/head\n0041728e7e4ce79ebeed7f96d7738e87edb2978c7b03 refs/pull/3404/head\n0041f4c90854fc692525def222597608a2cc2fdc24f1 refs/pull/3405/head\n0041c021ffa6e9a963843d4ba8509124bfbe0d3dfc66 refs/pull/3406/head\n0041eaf6dd8b3583effa6d2fde0ccb5bd73f07dbb2c7 refs/pull/3407/head\n00411f3bb435119dd7e20a349f90c3cf5371f13eff81 refs/pull/3408/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3409/head\n00401afb1ca14319673e1ea619cefe2f4490ad21ac2e refs/pull/341/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3410/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3411/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3412/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3413/head\n0041e5d49e3fa3a9a948e0ad1f1b86d0c9e188f74020 refs/pull/3414/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3415/head\n00412dcd8bb1efb80b4c7ae9087b304847addde347d3 refs/pull/3416/head\n00419d4287fb3ce00b76e352720ff79f96e9b52b0708 refs/pull/3417/head\n0041bcd17fd0a8bd707f36948c48aa7c9103c04fb9ab refs/pull/3418/head\n0041a49ee397c390dd0882b887c23e12e233bc6cc7cc refs/pull/3419/head\n0040019042773f8f8bfaf2fb18422f6e01caac79b615 refs/pull/342/head\n004141bd9e9857fa71d63de0692007c6ca2255b3aabf refs/pull/3421/head\n0041871f3556ce532a963d5a86f8fd0b232adc25dae0 refs/pull/3422/head\n0041e4505bd80502cad6ba66aafd519606f9472196e0 refs/pull/3423/head\n0041cce01256cfbf0f3f395b8d96d484494197196d5d refs/pull/3424/head\n0041dcc3c7ccbf0a1fbb9817a198b4cdc9d62b09168d refs/pull/3425/head\n0041caa0afee00abbc05076d0f52783b7a34310f6f12 refs/pull/3427/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3428/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3429/head\n004083dd27f424abf0abba6a8264fa6924a41c15ec49 refs/pull/343/head\n00417a83a2b622d023fe05a727df97a4b527dbff8eca refs/pull/3430/head\n0041a7701505c0a51e6de0f4c78c1a02f663a727fe28 refs/pull/3432/head\n0041981b8c04c17f2a63d951df37194bdf4817177e6e refs/pull/3433/head\n0042ecb4e7fe091516c36a2eaeec3b1841667ea7dd03 refs/pull/3433/merge\n0041d4390a458767271df36f6ab90c99af6e363268c4 refs/pull/3434/head\n0041bc032d76b0adff18fed5e058e1eef6de3c82286a refs/pull/3435/head\n0041ae608171cee97acbc163c19693951a231a2d4e06 refs/pull/3436/head\n00414e9f15e375eb118fbc7456f1ce75b7fdea960384 refs/pull/3437/head\n0041e79e37c87d28e153d552dfbc93f73111d0a18bc9 refs/pull/3438/head\n0041923f59093eced8ddc607c93353be0014ee88a6ff refs/pull/3439/head\n0040c3ccd3c6e811b6d15026b5cf1853a2f663001a60 refs/pull/344/head\n0041598407dc758dc60d193726d7db5399c4719fd952 refs/pull/3440/head\n00413741e5c083341432c3899d00d93ef84cf7f469de refs/pull/3441/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3442/head\n004154ef244af43a6711eb694021cb81efd25862a095 refs/pull/3443/head\n00417734f6dd3b776a0698e7b32256ca39f57d3078c1 refs/pull/3444/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3445/head\n00416627b1e2424961a3a38ba09e56f1887d7e5b993a refs/pull/3446/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3447/head\n00417f6aa8bf0de045b86129d4228ddfc99bd290af7f refs/pull/3448/head\n004175ebcd5084088481a531a5fa2cb4c0f8c4399942 refs/pull/3449/head\n004004d296631f37bc5d0e2c626fbd73f96427fdb0be refs/pull/345/head\n00416614652415913dd558a7f5e1760f6adac91058d1 refs/pull/3450/head\n0041a30243991efe7657d72e09cdefa0bca512a26a4b refs/pull/3455/head\n0041d613d3081e40ff0a2605553d6df587ed7750f26b refs/pull/3456/head\n00419202976cb63fe40fc20514a9c33f47096cbf4009 refs/pull/3457/head\n0041e1ec445951d86ecc1e953de48d0fbd89c35c351f refs/pull/3458/head\n0040987aa1508bf8d1de2f3dcf2fd010d87e126bb8db refs/pull/346/head\n0041abea6c5f85068528fa575eb4eb756b2ac0e8e92a refs/pull/3461/head\n0041e463b25713c5ada97bc7c09bbc644d8eb35926e9 refs/pull/3462/head\n00418f517991d1cb5e0b703a99e9f5f0356e96fd2b68 refs/pull/3464/head\n0041b341b5aa46fe4c33d29588397dd1bdee9d463b46 refs/pull/3465/head\n0041f44bd5c565c936007b9b937f27db82baedd64b9b refs/pull/3466/head\n004126fcc9f16b76b0925319f6554c6a6aef3b956cfd refs/pull/3467/head\n0041ad902ce2ae444857ba5af2a0575b4023e8694b64 refs/pull/3468/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3469/head\n00405450274ef3e558455c66ada108a0452e4843fdfc refs/pull/347/head\n00417c267cb058520f9d80c081ad44a4ce2864cd7019 refs/pull/3470/head\n00417b2fe16362dd063b59fac2c40d3f28948fbada9f refs/pull/3471/head\n004165252dfc054e98eadf8764745dfc034de989d49e refs/pull/3472/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3473/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3474/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3475/head\n0041cf1931c7276150ed36a4d8e11fd219a5cdc7b181 refs/pull/3476/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3477/head\n0041fc9be78fa0069be51b4cdc434bb06a02cc9a00ca refs/pull/3479/head\n0040bc92b86da455b69be1bd3916273645b337674ca2 refs/pull/348/head\n004138adfc481554517cb4adc7b370e3c231c33132eb refs/pull/3480/head\n004167cc7e37a710e3ea05a75374a506c04c87a89a34 refs/pull/3481/head\n0041603dcca4481fb9e1778f6e81ad048ae73320e30c refs/pull/3482/head\n00413e4197bb97686b43986c05d2e58481bf6280cff9 refs/pull/3483/head\n0041d5715a6a3be4943c0f09eeed95477e21546cf37c refs/pull/3484/head\n00412fc3db5c428f3c2ed1f1d53a6d32eb310ea7a469 refs/pull/3485/head\n0041eb8f7da07c8988a4685f699bc3ad3079b6e5fee6 refs/pull/3486/head\n0041f115d5d4d4655a1f132ea5b50dd2606e8698f8cf refs/pull/3487/head\n004152c3e0913ea564c9528adcd2e5bfb4fa84ba8556 refs/pull/3488/head\n00418c3c4edcb7e294421aba9759fdb033faeb61a5a0 refs/pull/3489/head\n0040df9c85159194003ea1f55d088052eeb60746823e refs/pull/349/head\n0041662b7d2a0f214e1da0510968fdf458c93d225809 refs/pull/3491/head\n004131420ee602fe6de115e4cf32b4dea4d20c37ef92 refs/pull/3493/head\n0041dbf993097c75276c397af40c80a17ab0a85750bf refs/pull/3494/head\n0041b0b0db1b990ace1dcd6a0775fcfe8c03e1c2e98b refs/pull/3495/head\n00419cf8a2f26e3bbf477b68032e0969d08bed9cdcdb refs/pull/3496/head\n0041a886341b602a3cc8278121ab40882b39cd94eb5f refs/pull/3497/head\n00413c0b52d09cb1dc44632bf9009ca51e1409066af0 refs/pull/3499/head\n003f9a6fd6cac6cf82aa4dccfdce615dfecbc76dd28a refs/pull/35/head\n00400454bf6ec1c4e9422765b5f3fbaaffdf15176979 refs/pull/350/head\n00419a6ce09da4d08d9eb8f59f0440c3758234d19e51 refs/pull/3500/head\n0041c546db9b641c145360de3e14ac12d48dbbb6581a refs/pull/3501/head\n00412dc4cfb9803f2aa927953e33bc1f40c3dab44156 refs/pull/3502/head\n00413a11c7356b0077c7c73c2143c05384cea89fae31 refs/pull/3503/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3504/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3505/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3506/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3507/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3508/head\n00419a567192f4142f72d8c0c9c0dfca059c314218d9 refs/pull/3509/head\n00400c699e9bf5b682c91f3bc11a35edf88d6667fa02 refs/pull/351/head\n0041a5c7c58c9c454b44c22238ef04ee3d620487d3c0 refs/pull/3510/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3511/head\n00414100e0af9f9bb6b8326aaa8c56b8ca4217bb5671 refs/pull/3512/head\n00417d9e4c951de40d4d2f4ca5056942b16672711b54 refs/pull/3516/head\n004067eef7352339ed2507d2bac858c9812ac4e046a4 refs/pull/352/head\n004112d4ccf73cafb1c17904c65fc54926d4fc0d2667 refs/pull/3520/head\n0041facd4046a0d547318694a68d1998be9df873a9b8 refs/pull/3524/head\n0041347fc8d5550965e6fbddbe63fd2c6a6af006d694 refs/pull/3526/head\n0041558f36467459b7a7e59af1069dd04a95d628a024 refs/pull/3527/head\n0040cf0c8367e746b2a1ae1a42202ebf11694a5a604e refs/pull/353/head\n00415d50028a97df7729d9a73878bab12a732a4b5438 refs/pull/3531/head\n0041412a32512c3b2888af0d26d8ac77fbedba6b738c refs/pull/3532/head\n0041726d98b08d7796dac5bedd4b9d34202fb4164ae4 refs/pull/3533/head\n0041434abc547f8f844b62c9abea8636adf414ce99b7 refs/pull/3534/head\n00418ec89391bdd972f05bf74daea3bfc5938a8fb2a2 refs/pull/3535/head\n00412aaae4a493ffd4d0af0bb0969c1c876a630e7bdd refs/pull/3536/head\n004126ff86f1c04993f6c36bcfc92edbeee015e189fa refs/pull/3537/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3538/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3539/head\n0040d4e3672671d311513e0efa9afe6c323a661a1e03 refs/pull/354/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3540/head\n00410230d614aea5f85d892fee98dc11ccb917837244 refs/pull/3541/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3542/head\n00411e9b862819e5a01ab7a65c5863c19adc0fbb06a6 refs/pull/3543/head\n0041535d8e0f999d37b0410574258f07fbf1a24d648e refs/pull/3544/head\n004196a3b49d5bbd0b7a6fa8e2b8a7febee215df2bb6 refs/pull/3545/head\n0041ba980971b276451472973c91d8a3599f06d2a790 refs/pull/3546/head\n00414e1501dade292549592c52d957e4fce0b164f5f7 refs/pull/3548/head\n004111556ddafbc6008583a1f421910dae8ad99c6c64 refs/pull/3549/head\n0040600ed28b6bf05e4800518d4299ba993a3de128d5 refs/pull/355/head\n0041fbf37fba1a9c93fa1cde4816d4c2e83de789764e refs/pull/3552/head\n004152880b04b157686ac203e6d1e05553c1554de526 refs/pull/3554/head\n0041a3ff783b82a73d9e590c130ee585935e3c47839c refs/pull/3556/head\n0041f8649f35c73ef8b68b8395b084419c74b1ec13d6 refs/pull/3558/head\n0041ddcd86bcc2937a1ed44480188e648d748253ff7d refs/pull/3559/head\n0040cf1cbc2950c195040601ce36ddb4314e94288711 refs/pull/356/head\n0041b4fe9a998fdb7e9682ea2a112d46b1f7fd1d83b7 refs/pull/3560/head\n004122ae49a865e503352cf40255938e94fc55ca1264 refs/pull/3561/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3562/head\n00411a9e9ab5f77adfee6997e35a99578456af18adff refs/pull/3563/head\n00419f411fd43ad96bcea3b00c2b6b09ba133ad970d6 refs/pull/3564/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3565/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3566/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3567/head\n004137c352279ece36826e0bf6cb7fe474144dbbd03d refs/pull/3568/head\n0041b01ff6cf71861f5b59b406b3b083a6a81cd5b05b refs/pull/3569/head\n004009a3d6def73568852ef4ae16bc83b5dc08bec29a refs/pull/357/head\n00412ef434da9cae143bbd52efd063c07c2365bee95a refs/pull/3570/head\n0041041b7702963bc077080c447a6b2156f5ad54761e refs/pull/3572/head\n0041f32b12df3a4a65424fe1d7656304bdc0d765d0ef refs/pull/3574/head\n0041e60e677527cd031f039fdd2d77859ae42d855f1f refs/pull/3575/head\n00412efaa9bc8c6e2a97f5bfbb231018d4c0f7d32c18 refs/pull/3576/head\n0041f91a700e72fa0ff87d505a5b0d742a32e2bfc666 refs/pull/3577/head\n0041e4969f8cbaef6577d8fdf43bb4cc80bce1dd7fb9 refs/pull/3578/head\n0041dbaa13a50bd43863dfaeaa1a2ba21528abb5d89f refs/pull/3579/head\n0040e933914511cafc5fdfb749ea7b07816fc675706c refs/pull/358/head\n0041aeece857dc9f9b33d18cd90c5c213dfaecb82698 refs/pull/3580/head\n0041e6d34f9b331c5297642565e4ec463d6a001da9f1 refs/pull/3581/head\n00418c84de22a8cdb55b693ecc13bdda3b4b6b384140 refs/pull/3583/head\n0042fbafce5f62a8036ecdeedca5a681856c08c688d4 refs/pull/3583/merge\n004165211f2f09f58fa9453af0005c7ed8d4e43bb67a refs/pull/3584/head\n0041d099eb9a6608a5d0d2aec966f32c467e68604c66 refs/pull/3585/head\n004134589f34e009247cb2eb2d249e57d78a59deaed6 refs/pull/3586/head\n004106a28e3bc4144959441b736e5bb62eacb1f817b1 refs/pull/3587/head\n0040b0d113e1de8d5dea0dad2ba0b112b7a6d7b749e8 refs/pull/359/head\n0041aa9e18358bf55c15e614ebb8ee2741a2f9996048 refs/pull/3590/head\n00414d8f4319eaf3a2634e5aab04ac0ccb706cac6f8a refs/pull/3591/head\n0041cb57473c8df0ff9684a1d88085273ccc71b32be0 refs/pull/3592/head\n0041ed2f8d86aeb2b877ad6e7c5d991a666540212ddf refs/pull/3593/head\n0041139c04ef65a5f7448c76b9ebc2020800570220d3 refs/pull/3594/head\n0041c1aacde188e95d078d945071c89474260f0864dd refs/pull/3595/head\n004116d1ab16fa4d100b903533361c6a34ceb5f4391e refs/pull/3596/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3597/head\n00411c4fe17a54b97737f3671ecaf56bb077f88b9239 refs/pull/3598/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3599/head\n003f33e3ad75825b38db5a4425df6d65e40410a5e9ca refs/pull/36/head\n0040e8f98b0a685b0579043ce7d7c161cf483b71f995 refs/pull/360/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3600/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3601/head\n004117c7f0f8ab0de4cfe8b087a4af2304b9ce86f62a refs/pull/3602/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3603/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3604/head\n00413439bbfaab349c59b0854a9cdcbfb23f46c9ed52 refs/pull/3605/head\n0041d540c1269b98ecede35df9fde66096ba1d9d3072 refs/pull/3606/head\n004133e45f96dcca0bf4978db082599db2a416eb0137 refs/pull/3607/head\n0041a2334377c31a3b8048cb2285ad86649be1acc4be refs/pull/3608/head\n0042764dbf278c5e1ef03e1523eb4f08cb357dfd448a refs/pull/3608/merge\n00413fdf840caa2a15aa1b02ad63edbe37f14c25ad04 refs/pull/3609/head\n00422129cffd63247752f1f8994b7b183789f1af0c4b refs/pull/3609/merge\n0040af341b4f22bbdac128322f76b48e07c31dfdca46 refs/pull/361/head\n00410d61d36d5457e56436939c609274a27d6a3d5939 refs/pull/3610/head\n0041c57018380ecb4a8c65a50a43146b1cd220d14140 refs/pull/3612/head\n0041ee07b5614e1ba16680914490340de597c10bab91 refs/pull/3614/head\n0042a8d6cee1b85df1170f472cefcb2fc8bbf432cf71 refs/pull/3614/merge\n00410e5894deb3711d7ae9d9e1efd62fb3fe718cb00a refs/pull/3615/head\n00416dcc20d5233ea2bdbf24637ab5a3d25e80bf6dcd refs/pull/3616/head\n00411fef6d381571733672f63d65bf555b9801186548 refs/pull/3617/head\n004182e4be020c85e0982b63537075ce4d44d0475dd6 refs/pull/3618/head\n0041356b68503584e33daed2cab24178a20c4d4cbf3a refs/pull/3619/head\n00406a801c7d85ede5c49881e53c45286e78dbf216bf refs/pull/362/head\n00410b26184e36cd97559ecefeffa099217136cf494f refs/pull/3620/head\n004164d1e66d5ad7e27d0fd38c49e0487e5b029b9639 refs/pull/3621/head\n0041758d6def407fe5258665f3b621081171459f9371 refs/pull/3622/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3623/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3624/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3625/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3626/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3627/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3628/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3629/head\n004064cf6dd540ef6a175e26345cde4fc09f98458764 refs/pull/363/head\n00410b3780de33f8385775e0cb2b24a45bbac5824b12 refs/pull/3630/head\n00415e7f9c92ccfed0ca84a87dc0fd1dd8bf962a81b8 refs/pull/3631/head\n004137b8262530715fc69aca96b4ebc28b61abd2fb42 refs/pull/3635/head\n00429885dc7f4a7042dab24fafa8ff7abe447eecb75b refs/pull/3635/merge\n0041020ded73f3db4649327aeda027020a2e37640356 refs/pull/3636/head\n0041378236c3105538906a4258009a87f9a14684f304 refs/pull/3637/head\n004135f6f9c3529b0a143bd93b9ee2d1e8258c2c066a refs/pull/3638/head\n0042cdde83a010d4963e40f0de1b041ee134e6b925f9 refs/pull/3638/merge\n0040cb0bde56c77838a7582b88c6d5e9150d2964e1d6 refs/pull/364/head\n00404b9a948506a09bcb0af3f4a7d34320fcc41cc23b refs/pull/365/head\n00404ebe16b3e179d11c7345ab7e0b5ec7aa262ba9cf refs/pull/366/head\n00400f88251f8707640498665ed86b3493288ea44b86 refs/pull/367/head\n0040daec0467ba809add8287e6e561b207570dfdef9d refs/pull/368/head\n00407e2c699fd73e14c445f1302ff24bed0a2556868c refs/pull/369/head\n003ff8f6f58700a542f06d0796bf7d26e6f39718d2d2 refs/pull/37/head\n00403c7cf0dd53c10c2fe43373d5d9e8e09ae9bd3038 refs/pull/370/head\n0040ffcf21f54d8b285eb6aeda1824f3ce90d85fbb3b refs/pull/371/head\n0040ad8ecd3b9bee94d51170382b695f0c778a497bfc refs/pull/372/head\n0040a54c525503c36c4120616451e4083bc0214b4ee2 refs/pull/373/head\n00400c42f8686a7cbd215a8f24817d7de1355df77b1c refs/pull/374/head\n00404b20f8036316a58b61a3eea85afea53cb054bd66 refs/pull/375/head\n0040df92eca6a3262981465ab6e7c100e740a9a5a613 refs/pull/376/head\n0040f5dc20b5d4e4fdf4699840a9bd90ccb6b51542d1 refs/pull/377/head\n0040125473272cfe458154e9eb689d9263df394d3086 refs/pull/378/head\n0040df8ab034cb5eaddea0415ae9953a6165ecc60549 refs/pull/379/head\n003fa72f79c5064d756b3b1883dda9744549657b333f refs/pull/38/head\n00403d26b83e2b4423e91f1878eebb5320712e41cce0 refs/pull/383/head\n0040b5b94b399d091ef348eea50af8166632d491f2e4 refs/pull/384/head\n0040f29693a20e63c75d1185ffe3852d5e05200365f9 refs/pull/385/head\n0040b7ef5869c878e43bba7533aa9b40988445c0bb5e refs/pull/386/head\n0040623fd65be4741d54bca9d3b919ffa22c5e18d295 refs/pull/388/head\n004020137d68b3d90677ec1a5792fadd7a0b9d5be665 refs/pull/389/head\n003f804148197b274c6129ab2c7d996daa456364c57f refs/pull/39/head\n0040e2654e0a480285bbba9ae0c65f7a48ef813f8d80 refs/pull/390/head\n004057cd1a4180b32268105209699409ee15fd23348d refs/pull/391/head\n00400c0a26a82752908ec2b45b00e052b166bcad1a6e refs/pull/392/head\n00408defc8e7c76da637ab8b3315c82a8f3896d187f6 refs/pull/393/head\n0040e0077f650f0dddd7ceb4160447770c45d0e5972a refs/pull/394/head\n0040a7dca0c16eada7c7f722cc9c91e1fed92a2b318a refs/pull/396/head\n004084445945ed7de7198d9a0066daa0f51438edf947 refs/pull/397/head\n00400844c04becceef49c59f882e131067a946ab732e refs/pull/398/head\n004022f5a39f26c94f295594503e826e7cf470762221 refs/pull/399/head\n003e4a137256b3d2dbbb000152d745bf176d70147e00 refs/pull/4/head\n003f7a793712e2ac08d1a47dd61e24238bf0ffca6063 refs/pull/40/head\n004028e57c8bc46d1d8708ce9c9883be5d924ebbf10e refs/pull/400/head\n0040e485f81fe2dc95638871b436bc5c2169079f7ee1 refs/pull/401/head\n0040ed452dfb3fafc4bf83650096ed88ad57ec4fcbd7 refs/pull/402/head\n0040d0e471fe80170e85ca73a2e1ae9c836d769c2991 refs/pull/403/head\n0040eb8e38a0a9d69ed42989476d22aec692229b4104 refs/pull/404/head\n0040a5da7dc13ec7f46fa0f5e26ca0510c08f9a6f416 refs/pull/405/head\n004017c1e7ec2ae2c06dbc42942ba61098fb5d372c64 refs/pull/406/head\n00409343ab402ad2586f8624a7fb8faca6cedfd57cfe refs/pull/407/head\n00406d0f1c3a7895798088acf0a8a08495056298d244 refs/pull/409/head\n003f91651239dd6d4d47c8d4d8b78d6df7e9925fdddd refs/pull/41/head\n00404102a18a336fafe433d6b2857265e0f0d6b77863 refs/pull/415/head\n004081dd41292c226f014de149a0071296e116d61189 refs/pull/416/head\n00406c31da0bab542b41831b7a82a9e4d14761e820e3 refs/pull/417/head\n0040bc1b44e4879261c92d2b3fffdc9ab647d7c8a1d9 refs/pull/418/head\n004087c749f7431781e754adb61bc61c699fe5d7640d refs/pull/419/head\n003f7645ff6b03ffec78255994ef914a8961c0bb48ab refs/pull/42/head\n00406afc717169d3d59e8bbc2c1fc4cf01bbbc09f96e refs/pull/420/head\n00404831bc8b92e9aecbcd0f128f7e45796bb5f89ebd refs/pull/422/head\n004038871758f59c771bee03cce88b2c9cc99b76793b refs/pull/423/head\n0040cae5daee7deff4cffda76dedaaf1a653e2af3790 refs/pull/424/head\n004000ea2f01026b75a03df999dba8057a2c14ec0d0d refs/pull/425/head\n0040adac66c1741833f79a1a960a6932760ab694b1dd refs/pull/427/head\n0040478d6e2a10cfc44072a3aedba6e921442e155f2f refs/pull/428/head\n0040702b192740ea948214cbdbeb82d38f79405697b6 refs/pull/429/head\n00401652c745526d09ec28dd1bfc8062ddc82a04efa7 refs/pull/433/head\n004037102ca6da3d94dcbe61fd6f00bbcef7843e60fd refs/pull/434/head\n004033bad2b5d92dbfab547fb81ae3bb5e62baa91be8 refs/pull/435/head\n00405cf48a27f88c23526734f137d94195452d923dc2 refs/pull/436/head\n00403dea0ce596c3809f433d67bb2160a8a8af9e590f refs/pull/437/head\n0040e7b69136fd234a5ebaf9e047eb4365c59ad7461b refs/pull/438/head\n00406531bc4aec902c7245c0b5e6ed08f50fff8de7e0 refs/pull/439/head\n0040564ede75518c9e18b7de4b718827ccc62d32c2cd refs/pull/441/head\n0040214f1a3a0b831dae6140f1322d935ec18d1e69f3 refs/pull/442/head\n004031214408ca2213dbecc787791d6481eb8f98318d refs/pull/443/head\n004055e6503606850b8b972554070ac6e6f652744d13 refs/pull/444/head\n0040714567aa8531ac2d5be17d02dc07382c13d314b8 refs/pull/445/head\n0040b9b465c2b3eef979ace3aaf02a7a513e965432a0 refs/pull/447/head\n0040aa975625ea6c2a4c817af8f69ffd733db4782b48 refs/pull/449/head\n003f128c809bb6fca55127f0d89f87ab0b108fc9b036 refs/pull/45/head\n004021a5af031b8b38c19ddf2fba0b2f2623a0a44902 refs/pull/450/head\n004057438b74e79a243fc8337039df968a56a47e1e04 refs/pull/454/head\n0040a0e52ee79ef2775920ac85443863e30b1c1173a8 refs/pull/455/head\n00405cb5971d55f57b60684d9751fd452bc631916934 refs/pull/456/head\n0040ef8e6f6023dafafc83ccf7252ae15b056210fa65 refs/pull/457/head\n004081764eebc88f482aefba3bae569432a017c7e28c refs/pull/458/head\n00407a801651c73cfd940929030a727de719728ce93d refs/pull/459/head\n003f17f025d395375c10d8caf9405f854c3ac2a71029 refs/pull/46/head\n00408e8824a4cea0bbd102d2ecd74bd370b7ee1ea6e5 refs/pull/460/head\n00402ad8115ec45b86b82cc7cb16479c86d27fc2e3ac refs/pull/461/head\n0040645c7a8624ac1a4f14b458244f75cbd7c4e8042b refs/pull/462/head\n004043edd2608e6e8be14b6c71b0805e14736f5c0db2 refs/pull/463/head\n0040a8e02bc9f84fe22f8d5ef368f4bc52a3d51ccecf refs/pull/464/head\n004019e4617dd5586b7379228783a7dafeb3ad5cd6d9 refs/pull/469/head\n003f539bb6345b3c521756c3c68fe01fb5476107f4a5 refs/pull/47/head\n004015b2c3c4fb3212475bb30d16a595d3a48754572a refs/pull/470/head\n00407425fbb17e658c1bee3286023c1be47c1be1a268 refs/pull/475/head\n004009022111d128e5a2b92d7b332bba42b6c0cc9481 refs/pull/476/head\n0040c32943f2eb274bc1228e9e8b963ff23e493c8b06 refs/pull/477/head\n003f7942542b7dd62c0dcfef6d099ad55bd4001e223c refs/pull/48/head\n0040da63d307f10488113dfd52696218ba82e66888a0 refs/pull/480/head\n004008724c7dedf66677e18fb4e877c20b947a4dd280 refs/pull/481/head\n00406f75999d1287efdb029d48e401917387e8176f44 refs/pull/482/head\n004077e6725ade995f3645a437f8f7d01eead3d2c4dd refs/pull/483/head\n0040fa824a4cf86acfc9fc7635f2ca89f578b11a27ff refs/pull/487/head\n00402610a4e0aef51b5b50cfdf88ed6cef4937a1c4c0 refs/pull/489/head\n003f828d3229892fd337355b2856b1e143c9a4094b7b refs/pull/49/head\n00403e436f16bcc8ae364867d9856fa0313f7fe1d465 refs/pull/490/head\n0040898ab0d1f6a863e64cb2c3054352efb975d1d5c6 refs/pull/491/head\n00406afdc81c1d56e7f166b33bc9465bf5735ed07a00 refs/pull/493/head\n0040421a88cac4c87a4199cffc08e7691af1fd094eac refs/pull/494/head\n004026347349cd6a174d168045bd73247df1831fd8df refs/pull/496/head\n00400da1b610c614aaa0bfb1cfc1c10f41080ff9589f refs/pull/499/head\n003e3f49bf73cc697e83b998d15d4c24b3b2c3cb422f refs/pull/5/head\n003f7bc22854376474f99e947eaae5bf55356033295c refs/pull/50/head\n0040bf63148464b0f0fc6c22ad407eeeb9ed1a3fab37 refs/pull/500/head\n0040fbc22f7cdfc425d0366f44dfa63c289f44251fd4 refs/pull/503/head\n0040d44738e6a75cef1e7dc125c06ac945928141f490 refs/pull/504/head\n0040427e5971ce9cf4b05e1588d2066e2538a10f937e refs/pull/505/head\n0040738aa6298e56eae85a6cc212ea98b3ced3018cfe refs/pull/506/head\n0040dcbea96afc409df97fec6a03581268c818928c44 refs/pull/507/head\n0040ea0cd0b85f34b49b41121be2e1fc4d99cd62f95c refs/pull/509/head\n0040252460ebc4d89d1dd62a5e612219d8385649fbcf refs/pull/510/head\n0040a848819f56bd450742ce97cfde7a1b1c795f29c6 refs/pull/511/head\n004030158afd5f5c4314b954c222995dfbe5a0f6df6a refs/pull/512/head\n00406e075100aa09016ef384ec63c236244b32993e7d refs/pull/513/head\n0040ac40a5c9a4856ba3dc47533000c771557539cfe0 refs/pull/514/head\n004019e615fe83f329f04795aa8fd731691151bb114d refs/pull/515/head\n0040d1e6176b7bb89fa6c8ea59bdb94fce36dc20a3c6 refs/pull/516/head\n004023eb7dcaa2cf76e6c3187e95abe5962a5d984b17 refs/pull/517/head\n00408674ea9c7625795693f59620466dd3b91e1acf6c refs/pull/519/head\n003fa5aae997547532051254c3543fda04ecdd19e151 refs/pull/52/head\n0040fc6f375311fba3fb12d1cf6cbeaa642eafd5bac8 refs/pull/520/head\n0040ba7681ee4add1983739689110e7aaae5217bf1bd refs/pull/523/head\n004095935609f8ceaaec8d796ac895526680beae5a73 refs/pull/525/head\n00405f50e2b6afc3c5a97f24e6662359614b880cbeb9 refs/pull/526/head\n0040da429589631564615fa152d04ef8395c05bdc2a3 refs/pull/527/head\n0040a4ec96c9a96bef7a2f2318e1afdeb3e768373713 refs/pull/528/head\n003fd92b753039c86313e6163de3beec7e80e7715409 refs/pull/53/head\n0040b9cc4337fb099d98b1794d6245d2d16413be0843 refs/pull/530/head\n00409a5c0ba757500434d094996c10086fc1f137f26c refs/pull/531/head\n004026bf9a128ff64e0c41da850df451fefc9752b0cd refs/pull/533/head\n0040f641a629b070e48aaa81110f5ede97c6a4c5d74e refs/pull/534/head\n00407f0c4e8bbc6feb8cf54ca2aadf9ec681f79f031c refs/pull/535/head\n0040eeb08949f3b66a5988f2d22a7a09ffdc34c95765 refs/pull/536/head\n0040187e24c0df8e76a9d1221f295451cb5125d19b65 refs/pull/537/head\n004090263ab68bd9a54607c3e087b98b0e615e193c3b refs/pull/538/head\n0040b2f2ba8f1502c725d92632c35307b06223605d5d refs/pull/539/head\n003f4069e9ae46887eaa1ea25c0c41990d4a152aa790 refs/pull/54/head\n004008d0fe5bf8f16f7f129dd6b16c076680fa70bc47 refs/pull/540/head\n0040fa4afd68017c51fa9c8fcb234f7b089a6a6bbe16 refs/pull/541/head\n0040b643a0cb471374c0d4fe2c8bde45f7594e0f808b refs/pull/543/head\n0040fe94b87d5fcb2289f2c49ae49e248fdd8c49b335 refs/pull/544/head\n004022da7087587feb96d7a1d4f179661381d49bb32f refs/pull/547/head\n00400c72efdcae6f3e9587ec6a4b63d1946decbf5fc2 refs/pull/548/head\n0040192ed93b86cb77de447798c3ea78ec0722bc6b83 refs/pull/550/head\n0040db24d8b17db7af20dd8cfdcaedc9af2c78999bc1 refs/pull/551/head\n0040b47ce783b533222dd8cbb1afb6d9751e9b4b5d4a refs/pull/553/head\n0040c2af63cc54340534c6bcf4057d99889b20b47636 refs/pull/554/head\n0040532b5912133864cda5255ab022d4e5a66ad6d26c refs/pull/555/head\n00406ba69f1c26ff46164fba4b7099f3cd7c22ab6dbc refs/pull/556/head\n0040bbdec22161a3f6db0f3b40b8936f4a1adaaa58db refs/pull/557/head\n004056dfbe6300ff4b2063a57341a61f46c7de7a70a0 refs/pull/558/head\n00409ac3f6d893e9ad8f45ab12316f02c6a9ff55319d refs/pull/562/head\n0040ba38432d6c7074beb6eae72d03bdb567b0f713d2 refs/pull/563/head\n0040fc97f30299e11bd3fbafe60764a31731f1634c40 refs/pull/565/head\n00403b36449491233aa92160be5b68dbba193d9076bf refs/pull/566/head\n00404eba0eb5150020b0d69521348d7fbf3a2c44c1d2 refs/pull/568/head\n004049f841c25b74ae3cd508751de9dea5a95791bea5 refs/pull/569/head\n00405eb4c715b6984f702da1623dc8fe3f17345e562e refs/pull/570/head\n0040c8284062668d32d8be4012eb6b3571601d88dc9c refs/pull/571/head\n0040cca202c87decfd33298805d39f1e0ce5d7706e28 refs/pull/572/head\n00400b5104a4cd274324a53d87db88e022db0c0b72d4 refs/pull/574/head\n004020d761e3eb61a0321240c667837033944ef5133e refs/pull/577/head\n0040ffff07627e6003dc180c47795d625265e49eaa64 refs/pull/578/head\n004081ff890139cf9f07319e35b0ff3abadc38171de1 refs/pull/579/head\n0040dc64e918011198790c27d086755312368dca98f6 refs/pull/580/head\n00401765f3e868446b5c3e62da393a56dc09ffc72f49 refs/pull/581/head\n00409d58c1bc6e71cb1642b883bd4dbd0d835de240bf refs/pull/582/head\n0040ab7f0f423544887488e868ed5e550ff354490960 refs/pull/583/head\n004071853facb839d4b1238a354ea0a351d49c1e81ea refs/pull/584/head\n0040f13bae2c6d98b3e4030829b22fc821770ac72bc3 refs/pull/585/head\n004044d51ed2e50cb3e102563d166911eb7f6d2d9429 refs/pull/586/head\n004031c4c6e5672aaa3c0d93fd4bc31f7a104da8d5dd refs/pull/588/head\n00401acb581ec304067bd5f7cc1c714d8627407b62de refs/pull/589/head\n003ffe060d229baecb03798c6da631dfaa440c4363cb refs/pull/59/head\n0040811d28418a43713df02b95fcdea0918e87c27163 refs/pull/590/head\n0040f189aca712ffbce0d7b8f52a2148911ff40d8681 refs/pull/591/head\n0040dab21a93594bd2f83f32d10550737a26220a564f refs/pull/592/head\n0040dd3ec750f2ac746991fad465a44ece6515f30acb refs/pull/593/head\n0040e04698a4f079ef9e47894c77955af5c92b18ed46 refs/pull/594/head\n0040ccabdea034f6711c9da311a6100eca55b6542cbb refs/pull/595/head\n00409b069b5258813122ec05532e1746ac34e457e31e refs/pull/596/head\n004003320f72dba0bf9c4a344710f69b87a157afb22f refs/pull/597/head\n0040be3378dbd616d7b54340c247c1c2b40a5d2dc46b refs/pull/598/head\n0040bfc79659cddb9b15558d224e7adabfc1f8c61a0c refs/pull/599/head\n003ee8c29e0fd94218fe15baad313b095318ca35e4b4 refs/pull/6/head\n0040bae47748988b81977e7c9f971264bd982cfc42f3 refs/pull/600/head\n0040a1207a57be86aa5062efdbe7425f233d2c89e555 refs/pull/601/head\n0040a7a1e4f3ac65de68af18f37122ffd61d17ef68be refs/pull/602/head\n00401ab0afbcd184742884308a6e56a3e33644e54cba refs/pull/604/head\n0040f90a58db535e3ed8615765985e74cf47ce6bfc3c refs/pull/605/head\n0040fce4824468778452a19d54587b292d54fcdee132 refs/pull/606/head\n004086229944c849912189292564b8fae2dceee5e358 refs/pull/607/head\n0040a33c5dc6f1afd4da09eb21b05d8e6b320bcf82f7 refs/pull/608/head\n004005da03548ea276a0e83bd3e09be9834a8335d2b1 refs/pull/609/head\n0040ea7aaf0e0c534a82dfd0d96e5ea91071c244a418 refs/pull/610/head\n0040111df9afcb9f748713819c7c5abd425a97d694fb refs/pull/611/head\n0040988d98f421372ef5d57684393150141159a92940 refs/pull/612/head\n00406b1d7b73a159a3b20822d8fa4b5bc67c9c6471d7 refs/pull/613/head\n0040c4fdd9acb95155be5de54d9f6a658963ca98aeaa refs/pull/614/head\n0040f627af3bf490043922397ce368d3761ddd005506 refs/pull/615/head\n0040135ec824a06ae39f81f8e27c377934d1630166d0 refs/pull/616/head\n0040c4246fbc32020ea7fbbd1605fb2e7ecb7351017d refs/pull/617/head\n0040c79e8f2f0d0dbaccbc95fc72f44bbac936137161 refs/pull/618/head\n00409a6dccd8ac5f09b248d10dc6aa3207d7dcc4f3ab refs/pull/620/head\n0040c16148011d21776980eee0651f63b35d1029e8b4 refs/pull/622/head\n0040ffa7757e6d0de881a130dca0cde5d7963d231ae7 refs/pull/625/head\n004029c076ebeea8b61c3de6c63be1a80b5c36fccbd9 refs/pull/626/head\n0040a6721290f78a1a87be815aaab182427c03a6b6ba refs/pull/627/head\n0040104aa8d0df412d7fa6dd3291ee7c7cd3f9c454e3 refs/pull/628/head\n004083c3e81bc80124a7f6ffab24a6ad363d21ff6ef3 refs/pull/629/head\n00407e27c01c5dc170601315055d1de35e13f9f4fe83 refs/pull/630/head\n004029c1efe8e632d99bc52afb03ba2f8af232646ea4 refs/pull/631/head\n00407dedbb1d778ee611c89e6192a9a9169821ce152f refs/pull/632/head\n00404d2e49cf4853f694ce7623eaf7427b14a9fef8d4 refs/pull/635/head\n0040e7759b9ea0d675599b7821de4ab7fbdebff8ea28 refs/pull/638/head\n0040cce335b1462e95c6a2a34b161dcb90130672ebfc refs/pull/639/head\n0040d0ebfd4e634b2ea6ecb0ef9c24559f928f0899de refs/pull/640/head\n004080c904e3541ff766a774812e6cc07b403ea88f24 refs/pull/641/head\n0040423b62ab04c89caa94f4d2933e50c3559d0fb620 refs/pull/643/head\n004009fd6885d8fed342f58ab5bf86093bedc5f8f73d refs/pull/644/head\n0040fb069a91a9f15fda5a19280f0c99640d467a69ea refs/pull/645/head\n0040e2e6ba84e35ba11a1ea66708250d18520f28a5c7 refs/pull/646/head\n004094492d52f7afdda992c36b0a77f1b3101a45645d refs/pull/647/head\n0040e4d92d4402229891c543908362e34609d1063ea8 refs/pull/648/head\n0040ccd48f7c3bf61e9efcabf76584d188f022399c8a refs/pull/649/head\n003f9114a985e210798208c0a4b006e4ae78090a63dd refs/pull/65/head\n00400efc4177ecd181cab57ebb287ecc28e4fa518e1d refs/pull/650/head\n0040c327d3e2430cdcf6a884e191313eb3dc1b0790d0 refs/pull/651/head\n00405e8bbc98709e96d4cbd9c1b9121d43cce69c0cdf refs/pull/652/head\n004016fd8b268fd8b700dae919c7aa0cca6c949d1d8c refs/pull/653/head\n0040738b63e7bf26a636163f0ade319a0c03257e099f refs/pull/654/head\n0040057b7008fc6d9ab71b28105476c59b8349e2baf9 refs/pull/655/head\n00406ba57fb53fbc2c28bd544b434f2114d0d6419ff2 refs/pull/656/head\n0040431353cf9c9ebb1cfae7f12912175f4d4241f663 refs/pull/657/head\n00409c52bf7f8c21616ff861e18284551f15594d8646 refs/pull/658/head\n0040aa5fe2463c7ff352df80b5e96de7458720b12bec refs/pull/659/head\n003f15492d0d8857c7f1f37cbf4b2eeba4b5fafeed60 refs/pull/66/head\n00409e0f86f98534e7b417f07857bc68f4b7be17b985 refs/pull/660/head\n0040e6e452a01407ab6a5558ff813f40347dd055edbd refs/pull/665/head\n0040cd5983ed4e8ce93df2d7d12dc895f707af7f1bd0 refs/pull/666/head\n0040a66d42daf1fe9876503a21c306118c8b8a30c3e4 refs/pull/667/head\n0040f0ac8954bd8a844cf20dd045c152f807b6c75a92 refs/pull/669/head\n003ffbd97671c4f74a3573ca677cb23aa2e5dc2b730b refs/pull/67/head\n0040f0f09665d993f70d81676fa66f11c19a962278af refs/pull/670/head\n00402efdcc262931d42e199b84a0c4e4dfa8fe296a45 refs/pull/671/head\n0040ab07111508ec90a01e73ad064f5e2fcac05134ef refs/pull/672/head\n0040c525494e4a3caa74a0fb416e1db34d08a85febaf refs/pull/673/head\n004021dc91864b8ba42bdf81fce2494a2d2932d9feb5 refs/pull/674/head\n004034b5a1693bec061f8d13d8a5f7a954ff5af2a5af refs/pull/675/head\n00406fd8ad1d71226e646fc414647feff755eb9d58f6 refs/pull/676/head\n004091d9a183c2c0fdce20ed174b27526b469f82c7df refs/pull/677/head\n0040285d000103910ca736e72f43579e98cab05fc9a1 refs/pull/678/head\n00404fadd0e8495d4dc18a4656cb36bf13d229d65475 refs/pull/679/head\n003f701296e9aab2698626720502d7988f6ec8534900 refs/pull/68/head\n00403d77783d0ccf43a1d2cabbb5cfd769cb5ac08139 refs/pull/680/head\n0040984749296a631d40a888798b9da128c25e38a004 refs/pull/681/head\n0040f323d77eb48e653933df4cb8ca3e7b6d4b445558 refs/pull/682/head\n00408043886ee609e15ac71eddde29f7ad593abdecd4 refs/pull/684/head\n004098f502db014ce6cdfb4cae3bf5d37ffde0f522f1 refs/pull/685/head\n0040c95ac10faee8e9d2b2ccc1c8dc564a2315d5dc73 refs/pull/686/head\n0040a2a04afe106b835d9301cd1f55a6a661a5ec7d1d refs/pull/687/head\n00407b19026b4dd4152f609170c0984ba552770ec2b2 refs/pull/688/head\n004060da188ac6f131ebaf8a0bca72daba511885bdd9 refs/pull/689/head\n003fefc80f95b21903ffcc79f2e3767f216d40d6e973 refs/pull/69/head\n0040c4843689bb037ac6c9351dbb23bdf42920e7523e refs/pull/690/head\n00404aedcc345cd1e3398ec8ebb1dfa6d56c08b3229a refs/pull/691/head\n0040bafe7bf81405775c49d732209f40234d49622c2e refs/pull/692/head\n00400d6d7c66b246d72c0d513a5827c7fc7ca3a5c0f6 refs/pull/693/head\n0040df57af56cc3896f95f502626faf04592cf6e4d8c refs/pull/697/head\n00400d369e0ff56c300f78e1b047b9ba7fd3a6305a1d refs/pull/698/head\n0040f555322ea73895e099bbd25c09c77c3d32742620 refs/pull/699/head\n003ee44f6d00df38bf536dfa16ac854a24b30951a873 refs/pull/7/head\n003f7a275cbf35e020572d4c83f90d0bba774f8151d0 refs/pull/70/head\n004045272168ba25f1d6a15abbb1dd3d25f2df494ca9 refs/pull/702/head\n004097e8173ae22cea5a2a4c1b5d2edeba24d590c4d0 refs/pull/704/head\n0040e7e01e7e31fd80d8560ece85e949bd7ee78df2c2 refs/pull/705/head\n004042536bfa4e70e88579cf472ac13a534dcdee6f12 refs/pull/706/head\n0040a2459380ecc080174e784a92e978dfa7d8d9c475 refs/pull/707/head\n0040fcc04802804190e699b627a9311c7825244f463e refs/pull/709/head\n003fe460077786c95beaf70ca516b10355042df8d0f1 refs/pull/71/head\n004090e7d78e8be39bed87f991fc9078a626e81054a6 refs/pull/710/head\n004006a9b8f4ee2433c22f584a63abcaedc056c4dae4 refs/pull/711/head\n004072d0f4ca688fc020d2689516409e0a0241a00549 refs/pull/712/head\n00402c1924d53a679253d237baa26aa707c4d9da8884 refs/pull/713/head\n0040e65263e40790c2c3c218953acdab20072c15e3e2 refs/pull/715/head\n0040cb40852db455619fd4d11df788f87792fbc50feb refs/pull/716/head\n004025d97b46820caa302f7d73b3fd0d3e480b7d10e8 refs/pull/717/head\n00403d2e5c60f73734d85b8691b4bfe8f3bf9ace2d59 refs/pull/718/head\n0040a7844ac08686fa01bd3945a36c71083eb865035e refs/pull/719/head\n003f0ea877f58dee1d05c10339ebf3e574324992656e refs/pull/72/head\n004077372613c5eeef798728a9acef6b9e6e47d7fef0 refs/pull/720/head\n00408db2f7e637a58b9c7f8de702d7840f855e9aa8ed refs/pull/721/head\n0040177f41beea015317a3eac047648304f31f51f97f refs/pull/722/head\n00404d3481fd5284b4422f6377d83b92dec187576e31 refs/pull/723/head\n00402f2a33ed706a8da32bf11e418f64f0479f19354f refs/pull/724/head\n0040e551d9b972d0789141af4aaa572b578ecdea1da3 refs/pull/725/head\n00404b51a02f4705e9bbd497f9e1e440583ec6ba154d refs/pull/726/head\n004032fcd859db96271b7f7b12858a8ea3ffe8c5a614 refs/pull/727/head\n00404fff6d895a94d46b666e645ec0deae52c1da5fbd refs/pull/728/head\n0040285169615c3f60fdf928a4828a25a8fdaf257dac refs/pull/729/head\n003fb34196165f7f457a62afc293ab4ffed18b95be24 refs/pull/73/head\n004078172ccc0869f65b849cb08d80cfe7a3623f0d93 refs/pull/731/head\n0040928ee035554495b878806ea5493b93748c80c5e7 refs/pull/732/head\n0040d037807f6550280434189d41f4528124b59c65c4 refs/pull/733/head\n004055e2fa977cf848c1e3cb4888135556744584dbe8 refs/pull/735/head\n0040066dfdf51f0ef7968984267bfcf1ddf0013d35cf refs/pull/736/head\n0040a121195bac6e62fc2bb01779aa93339bbde7c12e refs/pull/737/head\n00403e7facbd209ec39d303416abe591c0ebe7ef526b refs/pull/738/head\n0040056bc02fe23dffca388b0c71dc765e26c0ecefe4 refs/pull/739/head\n00402a631151127562c377721506f44e8d6d5464cef2 refs/pull/740/head\n0040d2fbcdaf39656fa110558c97f1ab571591e4a80d refs/pull/741/head\n00405a1114ec4d88ff3668fe0e362dd2b62969813b24 refs/pull/742/head\n0040ed0ced879d819f2e9ed7a2a46a0597bdfd83df67 refs/pull/743/head\n0040f358d39f0c738c2c7c4cf8151bca8f08cf5e103e refs/pull/744/head\n00405b267b0fa6717f2beb2da1be354ec7da6e3d8fe0 refs/pull/745/head\n00403d4dafc7a7f3047623538ef822fe7f93a28e8553 refs/pull/746/head\n0040173c7b2fb299d6d1dfe20349263a54eb7b08bfa9 refs/pull/747/head\n004081cfe17eeabc9775da65b2f15a9cac4c390a2c71 refs/pull/748/head\n003fa2064306c0121b9a1aa51349945f2c0c25183cd9 refs/pull/75/head\n00406275137133743c4310697fdedcff40c627e27c8e refs/pull/750/head\n004068f0993f418e32413af9f50e735ebfb10c94f4ea refs/pull/752/head\n00402b32cec5276d0ae3bc64bc78f8f9fceb83813b1e refs/pull/754/head\n0040f55a27997d1c23c0b386b63e9fff8ea193d6262f refs/pull/755/head\n00408783d3640b8a971fa809dd1cad2a604ff202cde1 refs/pull/756/head\n00401acba9a0352ceaeb95654294bb27410a722648da refs/pull/759/head\n003fcc2a1d6ce103a8495ff4f3b507929029fa1a3dbd refs/pull/76/head\n0040a4aa7c7fbaedcce1f1c68704a9898a2a9b0dbd6e refs/pull/762/head\n0040ca562adde31ebf443bb6f9247f090cb3a2a7de54 refs/pull/763/head\n0040af8fc879f64d994d84db36f6beaa1356304abcea refs/pull/765/head\n00408b031bf4c886555f37f97f9cbb8f5f84ba3e9896 refs/pull/766/head\n004081b890ba1158a718d4df4f03d7c83af82b576a92 refs/pull/767/head\n0040b2d17f6de6288aaebfb19197c68a105d0daba511 refs/pull/768/head\n004001e9d0c6cb2d19a033ac0e6d7bcb88bf2ca40daf refs/pull/769/head\n003feff68e7143fdfd30c275ba516541db0844385e8e refs/pull/77/head\n0040e84a43a470bb7f472d1a49d5fe14c8f89b3fa981 refs/pull/772/head\n0040cb8262e93c0cd4d084f887e1effc050b285d9202 refs/pull/773/head\n004010931bf93d7f9834aeca8777b326f7199cc52595 refs/pull/774/head\n0040445cef5a2eda33abbf056b4e7c3bf37c7d32db14 refs/pull/776/head\n0040d073d3b75f1da574628b0e66aead9986afda42ba refs/pull/777/head\n00407ed9cb607a89a7d57ffae5fd507af7a56db19c38 refs/pull/778/head\n0040dd60736ffe81fe26ed0182e4c7b31b89bd452d91 refs/pull/779/head\n003fdf05d6c2be5809e2d85009f78e79fe33d27da367 refs/pull/78/head\n0040e05028469f918fa3c55b92c66588a53e7e19efcf refs/pull/780/head\n0040bb085e4cf1c3feac099a7ff565053538b608ee3a refs/pull/781/head\n0040118db1a7c25ba4d379b974cb9e79df363e05f10c refs/pull/782/head\n0040e932db9ea7ebf46b55669c7edcaee78d5a35afba refs/pull/785/head\n0040080e8a3a8d8598b786508898e33e6b1eb6a62490 refs/pull/786/head\n00403aca03c675aa27392e84bf20bf551b4f4c1c1e6c refs/pull/788/head\n0040d05b8a4bc1f572927875b238e07596e7e5996a98 refs/pull/789/head\n004018622bc349c54e308084c2d4b34b24aa22943f5b refs/pull/790/head\n00406b09743c2b7d220ba84a454bdbf7416875fe08ee refs/pull/793/head\n0040ae001437ad1fe79c20e10d8713b22e1d0fd77388 refs/pull/794/head\n004046b9797d8cdbd4bcbce41c3d85bc029d7fd04778 refs/pull/795/head\n003e34eaf08d34a89431d5c0882c84b9fa17908caa1b refs/pull/8/head\n0040ce2858dc43ca2f2bb87614399077d66bf9bb24ec refs/pull/800/head\n004070bed40651dbf77b56b8bb1ce937293072819c0a refs/pull/801/head\n00403ed253bef7c27d246c1c456686e95bbdbd80d677 refs/pull/802/head\n0040cdb43d4f1ccbc2292955c2315e5ac8d4d8eea146 refs/pull/803/head\n0040a896b1480f6963ea6cbaaf61415510ddf4df13aa refs/pull/804/head\n0040c36c7b4facf399d85982ca2e5f6a797b3be27ce8 refs/pull/805/head\n0040e2b4856726d3d53aa04854fa9713d27f9b830986 refs/pull/806/head\n0040e563eebdaa0362a95079661b7c22508c8d94e040 refs/pull/807/head\n00400ee37c80c0931d187305f8f7261d2070b8ddd80e refs/pull/808/head\n003fcc8715f28dafd700666d19cc38136cea248b1060 refs/pull/81/head\n004006d7aca733f2a97f169c125bead4fdf9f15f1f37 refs/pull/811/head\n0040bad54eedde4823b02aef76ad29f027b5ec55a847 refs/pull/812/head\n00406323fa304b8d1ea0b30f5255af372ea6c1d342b0 refs/pull/813/head\n00406fe4c87726530f7e1dbfd2da602d68c68db69e7e refs/pull/814/head\n0040d34f6f2d5e2628ba873f74b7432787cd3711b742 refs/pull/815/head\n0040de87980d51fe9110489e5b16eb58db6bbb1f5dc9 refs/pull/816/head\n00406e0613f124704bb9e7f186e591aa83d9343e725b refs/pull/817/head\n004012157a79870d55daba6ec78e8d0a60d7f275bf22 refs/pull/818/head\n0040dd6ce3c6e72b750253e2a63858bbae1093861dda refs/pull/819/head\n003f9d4d998dbb4cc5a5c519e611bb364f75bf34872b refs/pull/82/head\n004034438bebd4d9f64bce4c3560a859e4bd7ca03f57 refs/pull/820/head\n00407207b2633bef006b6cad7f30861be8783788c2f0 refs/pull/822/head\n00406231ac298bf965ade374df6300db26436413c470 refs/pull/823/head\n004062336dd003c07cc5c286ce0f3ab3774a5c31a612 refs/pull/824/head\n004046968d768edfb3f6186dd6dca57916e297c33dd2 refs/pull/825/head\n004097ad5aecced2f2acefe13953362f97bc2cbeda60 refs/pull/826/head\n004059fb92750d43c74758d919bb888106258da5a29b refs/pull/827/head\n004022b377d570d3ab3cf0452bf959730dcaf2825446 refs/pull/828/head\n004009376942a89475fc1ce482dc4532626161f13703 refs/pull/829/head\n003fe621b6b6e656eb468c9706eec994e214cc9f3711 refs/pull/83/head\n00408ad712de7bda9769fe5768094715a00d564c1980 refs/pull/830/head\n0040d5bdf9abbe52f4db1e27e5cd131608eeaae7989a refs/pull/831/head\n0040e05dec0d6e78948e6585f9b317025dd71d9c4fb1 refs/pull/832/head\n00404ed4040f268b03d9659cf4222ed43fc44602902d refs/pull/833/head\n0040a5965a59ba5bcc689d236cfc9616572771758a7d refs/pull/835/head\n00401f4a1d12005e416e3f5b2bc4f3a784c428aab57d refs/pull/836/head\n0040d1bfdaea98d066478100518578ff395acfbaab14 refs/pull/837/head\n0040c518afdc363706a7dceaed72544525b7d8357b95 refs/pull/838/head\n003f9169f1f08ea14d3fbe1b68b53713d28f5248d0e3 refs/pull/84/head\n0040d35da14e7b620f44b1b96c74c609b9b7921032ac refs/pull/842/head\n0040e657966ef3575b05376c51fbe7d40d357876ca48 refs/pull/843/head\n0040ec3cf43d42d8af6018a528f1440999b467b3f388 refs/pull/845/head\n0040115524d3bfee413ea472b6b9f7fc79d85955651a refs/pull/847/head\n0040e22599fd352a978201db471c884575423da0fe97 refs/pull/848/head\n00408fa56e28ad91e4be463f25dc465afcc0857b7669 refs/pull/849/head\n003fac40525168a1bf85ab0ddc2f1a1db98d12f2eda9 refs/pull/85/head\n00400ca5e64a00ed2653963337613893e97fd04e94ad refs/pull/850/head\n004035b917bdcc8dceefef5b948482f1731361832f66 refs/pull/851/head\n00403dafe29588e29ea4c751ea0b8a9abd3dbc18c3c0 refs/pull/852/head\n0040ab29b63a7ae6d672086e812604f58170059140b1 refs/pull/853/head\n004050a4b042a14e4aabd9166c8e64aece2dd3019df2 refs/pull/854/head\n0040d78b460e2fe03f1595d1aaaad5dfa3f2748bbed6 refs/pull/855/head\n0040fc3fa2c8c9d9e1f0e0f8b436793e9792bf2a194e refs/pull/856/head\n00407cdc4a8bbbb549de2f592599ee71eb869dc0f107 refs/pull/858/head\n0040ce4e48b794c9edb5d19dd5a5e1d2704af419105e refs/pull/859/head\n003f048d9dc2d9c48ca2d6d685cfae4cea7d74c075aa refs/pull/86/head\n0040abfb710d9ff916933ba72ac68062d8efe6b245cf refs/pull/860/head\n0040f4f48b5fb1288738e59a56853854930bc02647d2 refs/pull/861/head\n0040c189b851b3d5fe349399d249a90e0e68dc8f83a0 refs/pull/864/head\n0040182e26764f06d5b2be0b7c68715c14ba8d67684c refs/pull/865/head\n0040da8d774b89c336070340292a780d4089406d6e35 refs/pull/866/head\n0040ef83217f1cca19bb55f29ee2aa24630301184dff refs/pull/867/head\n00404cd0f4f6609e0877a22263b6aa8b0097b7600ff0 refs/pull/869/head\n003fc1bd40fff6ddfab1c3b4b0ec7b949b595a37f560 refs/pull/87/head\n004073d3324a956b6255e7057b91bf842c903953aa06 refs/pull/870/head\n0040ca189efb1d2ba63690064760fe4d5f44212d5eed refs/pull/871/head\n00407943f1f3061bab8519c31af04cd2865c5f773412 refs/pull/872/head\n00401a19ed0abc5ee0984002a534d94ad9d13a23cff6 refs/pull/874/head\n00409005e7448f74c76bfca8abd6ccc2eaa8033e3f1b refs/pull/875/head\n0040cb8158aec6e877cc7d19f6b8ce0d76466e9f2de3 refs/pull/877/head\n0040d9e51f14175ddc2e9bbe93dd042e1d6fa5c063e6 refs/pull/878/head\n00401c40b3f421108053afb348d7afa4cf218a1d0f68 refs/pull/879/head\n00409a5882322417a05b4f4e9624af90e4789f3cac9a refs/pull/880/head\n00408d07ee77a55d1e43753eb2f1b595e90dc7807472 refs/pull/881/head\n0040fd9a292f19de446cef18f7598e8aa671e9b8eb5c refs/pull/882/head\n0040360aa2c5e752b5454cbc4a2479d0088b38abc993 refs/pull/883/head\n00409f48dfb7ab50cfadb0b962420dc2925c3c6c0735 refs/pull/885/head\n0040a6ac8158f4df78287d9b9ad1de65dc57dc6a185b refs/pull/890/head\n0040766b544a82088b1431e3dcdd3e1487b9189d6246 refs/pull/891/head\n0040a0a34d7f13509a488214cfd2438f6be0146c1ad9 refs/pull/893/head\n0040afa6a135e83a9912c9f4d15357fc9938bf2b0068 refs/pull/894/head\n0040c2470e34de7765ff88749016b3965464dfd2fa05 refs/pull/895/head\n00401c5b91f0c98a065da1decc046eb7c42f814ac6d5 refs/pull/896/head\n0040107785b88da780305b58fc9c6a7a4ad62429857b refs/pull/897/head\n0040878be2f49793529c5426af095b857d85947dec4d refs/pull/898/head\n00403a3c8842ced25171126744d03956459b96fd2a36 refs/pull/899/head\n003e39a9b3d002d1ccfc40ae9b0ea09180f0ee210fad refs/pull/9/head\n003ff6ccf0665312025f8c067e65aa114f1e560535e4 refs/pull/90/head\n004064263d8202cfa4a6e230d02a85b4ab73f18af28c refs/pull/900/head\n0040b9d98f2c3292e12d1065e89381ecf2aac77b33bb refs/pull/901/head\n00407469149b4624705dc9eebb620bac1347e0a1f900 refs/pull/902/head\n0040758931949bb8fa3e07b86ab0304dbc8a545e4f6a refs/pull/903/head\n00400907842911fae6c1f24f295cfcdc1771316fd729 refs/pull/904/head\n0040d79ecb701961c87061812b420d0315336a5b8589 refs/pull/905/head\n0040004eb238767a74876370927993867203630406e3 refs/pull/906/head\n00407fa47247a434bfd4ea57e05c85d24ae3c8393fb0 refs/pull/907/head\n00402209d27550ca808b5741b75a5ca8f4ee1bfac660 refs/pull/909/head\n003fb9da4fc6bfe0353628c52d6c9909723cd3298a31 refs/pull/91/head\n0040dd96a1ef30474322eeae85b439752a2441648b96 refs/pull/910/head\n00401cafe4142ab230d9f40f7c376c7b2fa7e55275bb refs/pull/911/head\n004037292b1f0175a95556c8ab0496ec833aef6f562f refs/pull/913/head\n00401da7ae60e3d5ddd626f3ae779e14fa35d3920394 refs/pull/914/head\n004055eefd75947c9de22a7ab54aa2e66f9ae2d6d181 refs/pull/916/head\n0040991fd5a796b5a173af26608d89b2523856a8839a refs/pull/917/head\n0040a7092017e6221118f5374b13bdb94dd70cb931ac refs/pull/919/head\n003fcd8a45229c253b2ded996209253f557ebe08ea35 refs/pull/92/head\n0040310531041a9db2b3ea7be5508cba725a31c1e7b2 refs/pull/920/head\n0040103d74ad373eb791086aa36975c558d020329cf1 refs/pull/921/head\n004005a1330cb29ccc7cee7d07f282c9ea3f3ce09e31 refs/pull/922/head\n0040b14cdd5be1e9d43167cf8b45a12a8af94c7ab2f9 refs/pull/923/head\n0040ae5b1da48e019604c2ab11cfda3716bc93127e29 refs/pull/924/head\n00402ecf0d4443aa6fd0670d1258bb44e0502cc25be4 refs/pull/925/head\n0040f8d3be5358543d1e77b11da39ee430bbffaad72f refs/pull/926/head\n004013b646387780724daa44cb53406c374fa7536f5e refs/pull/927/head\n0040c80ddf9150a8a07a438a472b283f17dd432cac83 refs/pull/928/head\n0040c5790e77625a6551eca40f10b1baefed1364fdcd refs/pull/929/head\n003ff104599fd8d9a3e937e6afdbfd23aae03b06e70b refs/pull/93/head\n0040d051eee2415aea7e689f3f803c8b42d05bc7f261 refs/pull/933/head\n004067e4e665bcddd02323994332db1f0b36e9f95850 refs/pull/934/head\n004001c9c34786b8f29badce2ea7b8800d1d29585490 refs/pull/935/head\n004055ce8e32fc4100fcbe08168fa134f152ae03fa06 refs/pull/936/head\n00406e33ac2dc161d71f2093cd4b2069a670641da16b refs/pull/939/head\n003fe8e0531dff3e4ede2702f8a194806b479b6573dc refs/pull/94/head\n00409004fc8b94f17b8eb23f3fac7a40373dcf77370c refs/pull/940/head\n004031389c6fb390c4abf206763035bcc253913cb948 refs/pull/941/head\n00402609a321f2e80669a406d954210fd72be764b551 refs/pull/943/head\n0040d5f662f99a84d64ec471ac1380a5508b5b84cc8c refs/pull/945/head\n0040e9c463d00cdffbff59c5d93db522dcfc4d25a1fb refs/pull/946/head\n0040f192d01fefd5091b9b4ad9b79982485ea8589733 refs/pull/947/head\n0040d83110303c40da1d3625c2369eae7424928bfbed refs/pull/949/head\n003f9f4d26f01eaf7a63153e00738718899718630811 refs/pull/95/head\n004090c651e8a760809d5bb1d000200a51c636a0f054 refs/pull/952/head\n00401aab4ffc6737c651a7022c498da9bbe9d51a94e1 refs/pull/953/head\n0040dfada8bc4d47aee406e8b41ca5dcd37e5a46507f refs/pull/954/head\n004057853d8dfa95aa7e51955cec9f00308118779a75 refs/pull/955/head\n0040b2b34bf2041f3bf6b14c340aa8483b44d60e7ef2 refs/pull/956/head\n004002853eb3413c48d693f761af5d6bad64a794de35 refs/pull/957/head\n004048f6be2dc9e5cdcde851bcc3a36126c115ddc1d9 refs/pull/958/head\n0040ea6cf207519ea325a4db11bd7296ec8e3cc9ac0d refs/pull/959/head\n003f45027e2bbac111be570749575b37e391d01747b9 refs/pull/96/head\n0040c7c55e329178bfbe23eb01699ea2a53f30586fc4 refs/pull/960/head\n0040191e6f1b7e87e904cad92cad5baf2c0a886cab3b refs/pull/961/head\n0040fe2ed02e78802a6b0926426be167acab160c1c0b refs/pull/962/head\n0040a8a849ba63aeba05c5e9dd77b00164cc46b16625 refs/pull/964/head\n0040da9795a9634318e42c37ec19f80599c0edc59b0d refs/pull/965/head\n004037e9c36a577642e5eb7256f44781858b50030935 refs/pull/967/head\n004098d33cfab3240eb4982c3adf17c3a1e6a6dcf600 refs/pull/968/head\n00404c8394c17d6ac8f66dfe8ea52ea4f948021fe8da refs/pull/969/head\n003f4d2fe23287a89f1c5241c5e97a940696a840e17b refs/pull/97/head\n0040491d07d263295fc5aeb810ef76e8f2c6d427b3ef refs/pull/970/head\n0040186fa33372f1e4d38b6d3d5ae39d67a435775ccf refs/pull/971/head\n004066ac8a4f89fc8b05319d9a128f51414cecb940a2 refs/pull/972/head\n0040b9980b71215d670dea3099347dbe8c4218f9f110 refs/pull/974/head\n0040a6906775fd285ed3f2baed9a0e81d44ac0a0b3b2 refs/pull/975/head\n00408514919ec66097b5fb571d0664d96f39d768134c refs/pull/976/head\n00405faac7caaa0dcea41a17de0cee60ed7f06e1f5d4 refs/pull/977/head\n004080a4c2407a618a422fd423a30412788a04909d96 refs/pull/978/head\n0040c1e8209f39d44f5f593ae9294a1577d53bf1d125 refs/pull/979/head\n003f7aec67159650698184e602b4579273031479ba64 refs/pull/98/head\n00403555c83f3f7c24a3bcec994f0b6d5770a8ad2822 refs/pull/980/head\n00402c9160f8b13da1243284a53e6b9f087c822185be refs/pull/981/head\n0040a40a406de8e0cd31f3c5eee473ddf603f341c2f1 refs/pull/982/head\n0040ff4497970acdfdd1068d8e74c9cef8c12a4da5f9 refs/pull/983/head\n0040d13163df761ec75dccb17003c581847d50a2cc0c refs/pull/984/head\n00405b8617a847a2a203e498becbc3c0532748933ce2 refs/pull/986/head\n0040dcffa8e69730e0c02b9aa016461e87968794bb72 refs/pull/987/head\n00403b255d8a8de732f378204b6a875efc1b02e7d77d refs/pull/988/head\n0040a0f3cb6d034272ce93606a67d40df88af496e941 refs/pull/989/head\n003fd878692c990ccb8cc79fe2475f5ff23c27ac0619 refs/pull/99/head\n00405b7f7ceb1a0f94c7eeca65bf89eb14bbc0a59342 refs/pull/990/head\n00407017906a8b42b1ed89f4a460c4240b9e4580b269 refs/pull/991/head\n0040a5fe46e1f7d147ce127de02177289995546d3b97 refs/pull/992/head\n0040d23da7efa002b15768bd46ecb8e093d20371d162 refs/pull/996/head\n0040a512bb48e3b77d921087674f19a7e8b8eadb73e8 refs/pull/999/head\n003fbb69be3fc46bc36dc687a645679a227f7bab9eeb refs/tags/v0.0.10\n003f01277cf0443b8e7cbe8104c8e72bac7aaac15b11 refs/tags/v0.0.11\n003fbc9f4568c6f3fdeb78bf983a3bf3d90bdcccd9c5 refs/tags/v0.0.12\n003f95135bc1a18b70853608d492d6eb82e5702500a4 refs/tags/v0.0.13\n003f8de7697b3b8a73e79a73ec34f17ef0fa842cfbb2 refs/tags/v0.0.14\n003f932929f0f31584734b94339ea9cacf3158fd9bed refs/tags/v0.0.15\n004546391ffda5dbc429cfd440269a4972242bb0cc4e refs/tags/v0.0.15-alpha\n00481eff46c9d7e491d709680cba7e446d1fdcb8223e refs/tags/v0.0.15-alpha^{}\n003f83293a2b3b7931c39214afdbcf30573727891066 refs/tags/v0.0.17\n003f657fe2a8cf60492ae03045e7ca4da22a09be7f58 refs/tags/v0.0.18\n003f28d1e63275538cf8f3c3a5ccb5cf8f87ccf2aee7 refs/tags/v0.0.21\n003f236cdaf0470e94797989d232a85183f66ce6b61b refs/tags/v0.0.22\n003e9aa28d0a130e9174fb217921966b1855c2fd3f19 refs/tags/v0.0.5\n003e12e0175b9303f6ecca1ad8abdb3a28b3c97e7b54 refs/tags/v0.0.6\n003e95862388f4e9835d0b6e8136118e1799a064efe8 refs/tags/v0.0.7\n003e10b90c68bca21c632f4dbfd243aaedce25d00b3a refs/tags/v0.0.8\n003e737948b5060efeffb1cf47fe085d187a3d0304a4 refs/tags/v0.0.9\n00439805438dc8731dabd78c8b3eb6871cb12a5090b5 refs/tags/v2023.02.28\n00438395cba7325954e4b3e3ed4c7ef3bfa82b428bdf refs/tags/v2023.03.07\n004363a89f6b9cafa9105949ba1616824ebbce62d007 refs/tags/v2023.03.15\n00436e19621c3acce9f66a817d0fbd825cd8edbe56ce refs/tags/v2023.03.21\n004329b7f68cc25aef244e46758a4c6548d366256e65 refs/tags/v2023.03.28\n0043ac1b1aa95f204bb6e1c0265a9d24139e9207d1c0 refs/tags/v2023.04.18\n0043adc4f6fa6de0b14e8c0ad9e502434d68ac3ddedc refs/tags/v2023.05.03\n0043ac1e00f9928257d8db85557e92d7efe44f5a828f refs/tags/v2023.05.09\n004310d72617f1ab2fdc9445b99ba18e723f60dc0750 refs/tags/v2023.05.17\n004311260570ad7c022286cc82840bae0cf8b1ee5350 refs/tags/v2023.05.24\n0043a29affe77a4c5de1e5421d9f53a8a0aa749d03cf refs/tags/v2023.05.31\n0043aed410e4badbc073a6910c11c8ca57f9fc49310a refs/tags/v2023.06.07\n0043433e32ef73bf683326d11d06e4f3d0cbe1e58859 refs/tags/v2023.06.14\n00437f4fb14bda2cc9dbbd8294a863092f64c2907c2d refs/tags/v2023.06.21\n0043b23615fb607715133806de0b12decc215cc95c2c refs/tags/v2023.06.22\n0043b937cdb360e93eee61a150c05029eb00cd404486 refs/tags/v2023.06.28\n0043efe2a73c48cfc8f358f304cf6d359d404b9806d8 refs/tags/v2023.07.04\n00438ce4d43aecc3b203df79565cad859d7798735a55 refs/tags/v2023.07.11\n0043cf318991793322189c5e44865a0355fa2ad69123 refs/tags/v2023.07.20\n00430f4e0c28da6fd9535d483ab63584d60a925bb3b9 refs/tags/v2023.07.25\n004338a28cd7123e13f90206872cc2e9af57959cabfa refs/tags/v2023.08.08\n0043064a3cb686cf44a66b061e914e52c9a6d9f4ecd1 refs/tags/v2023.08.16\n0043c6234697916921a270ab73511ae41e9037e15a5c refs/tags/v2023.08.23\n004372824f40c918f75abdb41ea13ce0513ee3d85df5 refs/tags/v2023.08.30\n004381506c929c86ba534d561e4cea236c7b2e1cbd98 refs/tags/v2023.09.05\n004322f7c5adc326fbda035d81fa05e3bfad80bdc9c9 refs/tags/v2023.09.13\n0043eb99b02ec8895fe5b87d1e76675ddad79a15f817 refs/tags/v2023.09.20\n004357316bd49932c8d37661cb03681b9d240079c7bf refs/tags/v2023.10.04\n0043595fc3e8b0210f23eff23ff853474e8700af2b85 refs/tags/v2023.10.10\n0043b374531b8074c41c7842183132e7e2804ebb3e84 refs/tags/v2023.10.19\n0043d26956b07351e0c695723507ad56b0aa59bd759d refs/tags/v2023.10.24\n0043e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/tags/v2023.10.31\n0043eb3b3c75b4b86d0537cbeaae55984ad4bf71a53f refs/tags/v2023.11.08\n004373315181865f9dd465dfea60d8c4a7359bad47a8 refs/tags/v2023.11.15\n004373b75e2c5b3c0e18f20375f4944b30b806b4cf32 refs/tags/v2023.11.21\n0043d039ca1b38f56a6c959eee0982afb69d1e56a65a refs/tags/v2023.11.29\n004381ea8ac55875b68ff236da7f44f91997c7b08925 refs/tags/v2023.11.30\n004392bce01c40ae5c4707aa46371cd31dc34562d88e refs/tags/v2023.12.05\n0043e15fe9260c2f2bff99184ca7a6bf5b8bd4ded5a8 refs/tags/v2023.12.06\n0043bbab1cd3a6494c4fc2101c19a832b52ee78d412f refs/tags/v2023.12.13\n00432a4022c818232b32573841a6f506796a25d13120 refs/tags/v2023.12.19\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.11\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.16\n0043aa584539a6f0085446fa53149a33c9385cecdf35 refs/tags/v2024.01.25\n0043e74a5dd172fada3ffb487d0c7c26db97cf2c3cba refs/tags/v2024.01.30\n0043f853bc9845f76620ec94f3662bf522fea0368a5b refs/tags/v2024.02.06\n004379c07c93dc01ed256032cb790eaae638a4255ee1 refs/tags/v2024.02.20\n00431defc72ba4297632dfb886b829f7a2d5299f06d5 refs/tags/v2024.02.21\n0043678f665a24414c3b425eaf40eb0eec62233aae41 refs/tags/v2024.02.28\n00435a8605df882d8a24c086655338e5f43fbddfe627 refs/tags/v2024.03.06\n004377ae40037a5c92bb3d04775a2fab70043ef7058d refs/tags/v2024.03.13\n0043f532637d69ac886df1fcf7b2e31f90b19df6f351 refs/tags/v2024.03.14\n004367f1b39c7aeee2a28ce5a41cabe113e4b49feb7c refs/tags/v2024.03.19\n004352136b5f1d38e09a5c687bd796feaa54fda7e4fa refs/tags/v2024.03.26\n00432ed3d46bd5c433bbbb06b72d7c0c171546646550 refs/tags/v2024.04.03\n0043927c0cae0f153597bf533032f086442e99a17042 refs/tags/v2024.04.09\n0043bc61579a635c9525a163775e42ae23886960ed7f refs/tags/v2024.04.23\n0043afcc49c52bbd1c6604baaa3a12809a30d5d3ad34 refs/tags/v2024.05.09\n0043fc144b751d26d8fbfc6ba15afc92fdbcd00a4fe3 refs/tags/v2024.05.14\n0043d0b1f72cfa19b5aa73883161682831392d8b5476 refs/tags/v2024.05.22\n00439ec5daa06fdace741958e4a7a20f7d1931948393 refs/tags/v2024.05.29\n0043bcb5dd13096cc0981647b113ca3ea142a7a517b6 refs/tags/v2024.06.04\n0043ccd849542895620faa4f323f44d7ad7ca543b5dc refs/tags/v2024.06.06\n0043d4509b6e3a2a6764c75f7ac316703b538ef3a1c2 refs/tags/v2024.06.12\n0043af23a17b9c54179b2253fccd1da19c38aef1b86c refs/tags/v2024.06.18\n0043fa0672b233985ca2e57f752e1f91542f80b8b22f refs/tags/v2024.06.25\n0043d6938bd6e6f2cba5cabb950fd86086f4c764e8c0 refs/tags/v2024.07.03\n00432cd1236084bcda3c37a80348c0de88c1aa103bb2 refs/tags/v2024.07.09\n00438c2b48a4bf3bd73e9f198966ddbb0bebd3d7cd6b refs/tags/v2024.07.16\n004394f08450539093e3f799533b698ead2f8cafea09 refs/tags/v2024.07.24\n00437295294bbc414041b103a0a296718b14aebd2632 refs/tags/v2024.07.30\n00437ca68fed3cf76d171473970f5bfaa3846a69b635 refs/tags/v2024.08.06\n0043d48073bcbcf12257cc249ff3698fcf94a16ceaaa refs/tags/v2024.08.13\n004380b888fa239ceef4062648f4259a5767f36d1080 refs/tags/v2024.08.19\n0043a81778d470873e2be57d3b8ae4fbf9f942e28c96 refs/tags/v2024.08.27\n00430a526fbafa0a00279ab6a74787ec265d65b8feaa refs/tags/v2024.09.03\n0043431fef648ff9b44f33646ac773abbaca71c48f15 refs/tags/v2024.09.04\n004365076b2b592d4e09bf0be039699969b455bbf4a8 refs/tags/v2024.09.10\n00433dd07d08451a9be3cf4eaf95e3fa0e0d8f3e8a9f refs/tags/v2024.09.18\n00434eadc85640729c2ae55ab05f0040cec03bf3b726 refs/tags/v2024.09.24\n00433508bb45f43df4268a8be3248386b828779cd95c refs/tags/v2024.10.01\n0043081f563d7307950d9c43237ee7cb965261496ca5 refs/tags/v2024.10.09\n0045fa9fc088b7fa8a2b10a479a17bbb9f46e0609d34 refs/tags/v2024.10.09.2\n0043033ea44ceed6bbc972f8f528585d15fc397d2e19 refs/tags/v2024.10.16\n0043af4b18a1540cf73c9ac67d1643b0a5f511d1bc86 refs/tags/v2024.10.22\n0043037050145b4bf7d09d9602e2c8042e4ca8bed9fa refs/tags/v2024.10.29\n0043ee286929b5e18f007d9649afd75c7bc4ce68c2fd refs/tags/v2024.11.05\n0043d58c1f6a1e88c451e168863057fb05fe0d323488 refs/tags/v2024.11.12\n004322cc4bc998323fb7d0bcfe4bb24e3d5715eda849 refs/tags/v2024.11.19\n00432d7b1e03bfd479a58ad56c339cc092669dd64707 refs/tags/v2024.11.26\n004391a0125e55c8902b3d077f4c812284d9116a5bbe refs/tags/v2024.12.04\n0043402f47d4f1fe547ba68ab39ac342b525f4cd7e69 refs/tags/v2024.12.05\n0043a5ef7137a2e3cd5c48e2b7ecccab5722dbf738d4 refs/tags/v2024.12.11\n0043732f08356e5f073aa275d36bff43da6b2b0177c7 refs/tags/v2025.01.07\n00433d55f553e28cc2b16152fb4df8ac53797b9d5c8d refs/tags/v2025.01.14\n0043f53c68fddaf2d760e0a00cca49b4b5313bdb0ad7 refs/tags/v2025.01.22\n004326d49d78a26427a12628cd3a1a4cd49d030c6956 refs/tags/v2025.01.28\n0043a9940a58b48f0a650632c37b44abdee0144d781b refs/tags/v2025.01.29\n00453be0a2314da2bcb3028617e4a05622aafd5beee0 refs/tags/v2025.01.29.2\n0043eb29faa1a45f8983502590b8ca68dcb2692ac68e refs/tags/v2025.02.05\n0043c2e9e5f6e41b61bb18e8e9f20924bd702d9fea47 refs/tags/v2025.02.11\n00436f66b0ed1fcd2394462a4268f2dad26ace3ccc06 refs/tags/v2025.02.18\n0043edde4b267a78ec2452e0ee7afcc21d02d7f18377 refs/tags/v2025.02.25\n0043f7e26092e0e8ced250d6cab7ae7b62343f2b8809 refs/tags/v2025.03.04\n00436dd9a9dd776e2c51c16f359c417256e702fbbe44 refs/tags/v2025.03.12\n00431d0fca0817eab7d932e4673e6837aae320708fa1 refs/tags/v2025.03.18\n00436d7c3dc69bc05e7e1a83f4389e61d430db288416 refs/tags/v2025.03.25\n00432727c77060f0174f96e12dad3070cb504c316ec5 refs/tags/v2025.03.26\n004304979978095630ecf30f6c3ddbc55e07ba8bf7cf refs/tags/v2025.04.01\n00439f7fe3920daf55fb156d8feb6143d939e3d5cd28 refs/tags/v2025.04.08\n0043e28ded887856f77d575be479212490d35e55e08b refs/tags/v2025.04.15\n0043b8445788211b3bcc04c32c77046503b14170c870 refs/tags/v2025.04.29\n0043b8d9f1b5afe0a8cf6ec02354fe2fd4516271b1d3 refs/tags/v2025.05.08\n0043139de7b69a2ea39e2113309b3a0a47aab920ddcf refs/tags/v2025.05.13\n0043b5f70ca94cb7beeb9d01269958275796f1b7189f refs/tags/v2025.05.20\n0043098ed8318399f68a9b2ef4b22c83687cacb85da5 refs/tags/v2025.05.28\n0043f3aa51f0689214ee9ce4e57173e56b933fda3649 refs/tags/v2025.06.04\n0043367e62dc034dae8d6a61362fb0d804906982a18c refs/tags/v2025.06.10\n0043d895bc431dc7c591919e5f1907bee1867eb6a914 refs/tags/v2025.06.17\n00437f39eb683c4de0606f91a1e624f905bae1407899 refs/tags/v2025.06.24\n0043e4f7ccfd19525dcffb1567c992a031bfa50220a3 refs/tags/v2025.07.01\n0000" - headers: - Cache-Control: - - no-cache, max-age=0, must-revalidate - Content-Security-Policy: - - default-src 'none'; sandbox - Content-Type: - - application/x-git-upload-pack-advertisement - Date: - - Mon, 07 Jul 2025 03:38:51 GMT - Expires: - - Fri, 01 Jan 1980 00:00:00 GMT - Pragma: - - no-cache - Server: - - GitHub-Babel/3.0 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Vary: - - Accept-Encoding - X-Frame-Options: - - DENY - X-Github-Request-Id: - - 4439:145DD2:22D169:275150:686B414B - status: 200 OK - code: 200 - duration: 329.125689ms - - id: 1 - request: - proto: HTTP/1.1 - proto_major: 1 - proto_minor: 1 - content_length: 0 - host: github.com - form: - service: - - git-upload-pack - headers: - Accept: - - '*/*' - Host: - - github.com - User-Agent: - - go-git/5.x - url: https://github.com/google/osv-scanner/info/refs?service=git-upload-pack - method: GET - response: - proto: HTTP/2.0 - proto_major: 2 - proto_minor: 0 - content_length: -1 - body: "001e# service=git-upload-pack\n000001534f1b54bd015c6c672754edf83aaa901689eb57dd HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/main filter object-format=sha1 agent=git/github-e744e5203bf9\n003d82aefd395a8e152af10720b59a606b34ffe1174b refs/heads/docs\n003d4f1b54bd015c6c672754edf83aaa901689eb57dd refs/heads/main\n005090966848c36befc986cf48f30a3fa0672197bc8a refs/heads/patch-test-cov-workflow\n003bb37c83e19af3b2555864457cbd0b08ef0e1f9d7d refs/heads/v1\n003b459ca69939984dc05f15b77720aa81c672aeb5cc refs/heads/v2\n0045e07bdda0f37bd741579e46be40608c65ef8fdd44 refs/heads/v2.0.3-patch\n003edeb877d9e9e5903ded7f86130ee8a2bba1de9418 refs/pull/1/head\n0040a391f89e35b799e631596eabd6e99bd7c37ff359 refs/pull/100/head\n0041f25ebde349d6906ffcd1c9e313752af4c79ecf9c refs/pull/1000/head\n0041bc649da1efe99e7fb302734ec09b611be08348c8 refs/pull/1001/head\n0041dc901f4adfb43f11a97d6fa23842cc6823badaf8 refs/pull/1002/head\n00410c3e76fa4abb53b25c79c75697bb87feccd7f457 refs/pull/1003/head\n004154dcc5a31c3a5b3377f96ae3275d925ee3e9773e refs/pull/1004/head\n00418a1fe256d51dd585ee6dbb2cc966006ff6fb269c refs/pull/1006/head\n004179066e42fee756592da5e477cead1980ec71e34c refs/pull/1007/head\n0041edc44a752b9f9c77ae66ae40ab6fd4d03912672d refs/pull/1008/head\n00416d68a3cd1382a7657f8aba1d743b9e83f18c37db refs/pull/1011/head\n004117ba4664d930f16611e16f760f4279926a6ee4e7 refs/pull/1012/head\n0041eff3a57bfef84a0073b23f7b3990d362afc01c32 refs/pull/1014/head\n00412faec986b74428dbe627f303f4628d25added7e4 refs/pull/1016/head\n004173511f772e1ef2513cbee2f43e3f90600c70434e refs/pull/1017/head\n0041cad99c794525888aede11f92bd936266d05da8a4 refs/pull/1018/head\n0041405facd57b0611263bf05dac83cb4990bc971216 refs/pull/1019/head\n0041e8d4ea7d464cf0e5b32ea1405d031da735852ec9 refs/pull/1020/head\n0041979d2e0004a583bb9a824fb410cf1711a00b641e refs/pull/1022/head\n0041dada9e1f5ca1059abe5d9d176fd2f52a5b880262 refs/pull/1023/head\n00413a1ff30b56ba73b533a7378e57a654dec8aef3f3 refs/pull/1024/head\n00413891cbc53e370d203ccfa25711bf3d22830bc5d4 refs/pull/1025/head\n0041cf8acae39de43327b99c0464783030b3d8de01af refs/pull/1027/head\n004187ce5b1985c1abcaa7337941d0629fc2013c2dff refs/pull/1028/head\n004183ac4f1b7af1d5b3080b5587dd1027cebd1ac4af refs/pull/1029/head\n0040cd6eb8b02933f1c515f22b22d4d60196643ed010 refs/pull/103/head\n004145c69a08c7cb8b9ad5f49de049832662d7fb5596 refs/pull/1030/head\n004139a4a43e9d686194f8bf87b22640275d6898c974 refs/pull/1032/head\n00413efc13fe91382e13a7fa7db33f56d5af24901dd8 refs/pull/1033/head\n0041134ba91d1941c3e8ddb248bdf4877f0948f9b8da refs/pull/1034/head\n00418813d5c1faf2c1b8ac8332b273dee3d98996f77d refs/pull/1035/head\n0041dd87a911bb12a08155f40f7cd080271d7d858cec refs/pull/1036/head\n004165099131e8430832af0e4b688e92fe99857845df refs/pull/1037/head\n00412e72de2d7278cddbec0b02f917ddb3e4fa623d78 refs/pull/1038/head\n0041d9b037c52a95370872c2b639e14496380145bf78 refs/pull/1039/head\n0040bce873c632b00bb26ffb04ca5b56512c5cc588cd refs/pull/104/head\n0041c815f92e90a158bf0f98819d98fc95298d4c702d refs/pull/1040/head\n0041f0a5b399fca77336169a5099122c1c3f6d9786e8 refs/pull/1041/head\n0041c571e7a1999d00ec8e73bac96319119912fcc651 refs/pull/1042/head\n0041445b082f8fb17498523aa22e464eb06d9205fd8b refs/pull/1043/head\n00418959bc2922ff35886b6c37475e42be966a2ad2d0 refs/pull/1044/head\n0041d133fffb1223c353fe853c7288c335f459a79cf5 refs/pull/1046/head\n00414bfcfd8d45552a0558081ecee29cf0130030c101 refs/pull/1047/head\n004173e259495b1b59c248a95506a7dbc8169f60a672 refs/pull/1049/head\n0041e4a30c0b4730b816b4a64256a68ea9e6a78b227e refs/pull/1050/head\n00411787268638442da07a0da0d6959db2ab8360da7d refs/pull/1051/head\n0041b6c00baad38ff80c547805986fa472ac6a931ec7 refs/pull/1052/head\n004145b3e221b39c4045d7754cd2830461b4bbc19fb9 refs/pull/1054/head\n00418a4f3424be29d100df9d16ab6af7bd60e8d921fa refs/pull/1055/head\n0041e52a74fe02f13e4c49ce4a95a7be9df1b146066d refs/pull/1056/head\n004146aee59befed6edb5fc737ef35b5febf987cffa9 refs/pull/1057/head\n00417db4dc3cc71f2c7188b8e7ff40187ff6ce0976e5 refs/pull/1058/head\n004002f2d3a1541918e91bb634c093a8f588b5f724e1 refs/pull/106/head\n00414418e85c4c0ede19fde83af9047ab74455f29ce5 refs/pull/1061/head\n00416630c39aa158eddae0abf9ff3e6d560dfec800cc refs/pull/1062/head\n004103558e2672a2d500a64621ef829828462475077a refs/pull/1063/head\n00412d316b735abbc0533d73e7fb5cd36530803d6075 refs/pull/1064/head\n00411e6c0cf8e25d4ec983ff9e116ca9fe5b4051284b refs/pull/1065/head\n0041e7b146c4dbfc2461e161366f39bf57359b41473e refs/pull/1066/head\n0041f94fedc0ffd685597f21cc132b08807bc4a2bc8c refs/pull/1067/head\n004130165312de801e22db722999e2e31b1c0ab872e4 refs/pull/1068/head\n0041f45c37d02b1237018b424da7644e745b3ae4fa29 refs/pull/1069/head\n0040417538354a2d1b8206b21047463195d0e63833ec refs/pull/107/head\n0041f5e15c258ebd6d3b899da8376d85b34e5fdc5322 refs/pull/1071/head\n0041e6b1130d37421c1750d6aadcafd622dac4f1bd22 refs/pull/1072/head\n0041ff3dcbdb5eece230a9e76ce516c33b7028ebbc8c refs/pull/1073/head\n0041c42a060ca4e670c5f6eead047788d3ba66a624f6 refs/pull/1074/head\n0041abf8f3732189338b9ec6dd0849157c8f012c10a5 refs/pull/1076/head\n004154b4c20f39be518c9564320befba3a752c955a95 refs/pull/1078/head\n004131949d5ee53fe01aab33b186cbad32fbf2d3d1d7 refs/pull/1079/head\n00402dbccfcf4113d7c6981274155e5c7c242c4c8b23 refs/pull/108/head\n004101c0329ad2aa6b7de43c15645f2581b7ef8c690f refs/pull/1080/head\n00414ed4f57bd8d1e7ad8e9007f756bfca75ed99c6ab refs/pull/1081/head\n0041934e83b6c18732e939343be1f6d63ee994816992 refs/pull/1082/head\n0041292bde6461c6674545d6249e58d33650ca3f103e refs/pull/1083/head\n00411a86cd77b171c6eca9f241f4b56f9d2e02e847e5 refs/pull/1084/head\n0041a566698126749fc1de5d522e495adfed74aa63e7 refs/pull/1085/head\n0041b54b8568f1ba511b7680276e3890e9159bb9de16 refs/pull/1086/head\n004186bff5bb894d8e940f35631034a46c277caad53b refs/pull/1087/head\n0041e161a918a5dc08c87139f0f953c63191535309c0 refs/pull/1088/head\n00412130913b3113688700c8a1c214df29354b6544b0 refs/pull/1089/head\n0040efe52963c923ec97ec0e7f823d70519f8afc1301 refs/pull/109/head\n004143a04e48ed25e86d2925774e79ae6e4bc8c6c9e5 refs/pull/1091/head\n0041d3e51e01080d1940692e104bc514733365ea5eb7 refs/pull/1092/head\n0041dff227a1d460cf02cfd3650019b5dd8b0691abc6 refs/pull/1093/head\n00411c07b6a25dd94d49cc0679815e0aa4aeb3a61c96 refs/pull/1094/head\n0041409562060f908ac5f94b44ac0e68aab0f7d52d6e refs/pull/1096/head\n00412b8500391d3df93895706a61043d579e93f53b8d refs/pull/1099/head\n0041aba467c89fb866c51401ff528011689ad768f997 refs/pull/1100/head\n00414d7d179410b09c4594e9c52f7748b079f1bcc89e refs/pull/1101/head\n004138ce57ecd457248e9f11698c72770e9b239741b3 refs/pull/1102/head\n0041c37ab03ea07ff99b1f9af69ef47795cf82c58efd refs/pull/1103/head\n0041063d02a9ed36e7fce9ce3e4f55a310e580da3eba refs/pull/1104/head\n00417177faac71408a3f64973600dd927dff7daa9e7f refs/pull/1105/head\n0041865580eed5d1c65cd617cb05df1b95a80d6f6475 refs/pull/1106/head\n004121070112f28273b4a0e89e08477bd17cfef64355 refs/pull/1107/head\n004163bbf6482bb377b05f9d620ec10ab67c69e244e3 refs/pull/1108/head\n004137a2bfac38496527284133c9b90a9355c93904a1 refs/pull/1109/head\n00418fa27e18df788fdcb00229a7c9a2e02bfe085391 refs/pull/1110/head\n0041c6a342e088c30f21a12044ff42783b5de893ee8f refs/pull/1112/head\n0041bb3976c6735daeceeb96a1461695498d09b92ab1 refs/pull/1113/head\n00418dfb55a6c6a406da3c244783c6e4df7167f8ff9d refs/pull/1114/head\n0041b86b180baeceffbdadaadda02d7dfd51f14fa8de refs/pull/1116/head\n00416ec43bb6687374b8885a6af623e2d4159d74b133 refs/pull/1117/head\n0041e47cf0488f5bd1c156207a17cb2a63332f8c5465 refs/pull/1119/head\n004160d00a1b00d179d5e62b607ad689b81603e8cfb3 refs/pull/1120/head\n0041be4c1511cb9945992ae27ae2ca99a94565aea784 refs/pull/1125/head\n00410aed4352dd2d7fa9eb1be6d623ee875a34c53b4d refs/pull/1126/head\n0041fc7c97dd30f370c79289394eb2c4e2750c9be1c0 refs/pull/1130/head\n0041082984133361132f3b7da7deb989c659e7844359 refs/pull/1131/head\n0041888d30a834cb5872216577da5926f887a2575bb5 refs/pull/1132/head\n004141aca0b4cf0c7f836d2023c26eed5e5fce1f29a4 refs/pull/1133/head\n004103f9a9e28f9121df58c689983b2d69364b54fef8 refs/pull/1134/head\n0041d0038e926e44873980f77566bfdfa2ced2ed04fa refs/pull/1135/head\n0041cfe2c22993c301b2adec721af28530c666fb7b42 refs/pull/1136/head\n00410dbc58619c0809668be780f04a9034490e43f18c refs/pull/1139/head\n0041b3846b125c6c2b4746124144bec86168d8728389 refs/pull/1140/head\n00418b0043f2bb68c82968c4faef65936e1ef319ad1d refs/pull/1142/head\n00415a560fdcc101de924791d1d134ca283bf1610280 refs/pull/1143/head\n0041951ee1cbcc4dc717146491707e6af74f90cfc1c3 refs/pull/1144/head\n004167a68f7c044ebc003d9676dd582ac8c03ea46015 refs/pull/1145/head\n0041e4b00eb8b0e455bf7b299e11a53870403401d15e refs/pull/1146/head\n00417a633fbcff3a162b1f8a5856671d0316de356052 refs/pull/1147/head\n0041c9147b953308f3843c53442a1c17aa36934611fd refs/pull/1148/head\n0041af9d4d8cf408ac7a7d3b9f065173efadfc05ce93 refs/pull/1149/head\n004118ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/pull/1150/head\n00419ed7e6a4606b6f56c867ca0122df3fc3b43cf15e refs/pull/1151/head\n0041b29e4f2d7853e4b8635e885fd5717396922c5800 refs/pull/1152/head\n0041049cae20632df72010d0152ad145fe2c53c0ea7a refs/pull/1153/head\n0041f5748b91249cd51f64ce6024c93e564d36da7660 refs/pull/1154/head\n0041bbe8e0dfd255daa91a917159978ae5eafb0e84ef refs/pull/1156/head\n00413626dc731e649f2c663e2e60000875ef5eecedb1 refs/pull/1157/head\n00416c04fc849888eb29dc0e4261438190aa3694c1ec refs/pull/1158/head\n0041a519b872414443e8156dc4d10f21a4117b564458 refs/pull/1159/head\n00400eeb975ae48214001e9941825c9a749b1c7d391e refs/pull/116/head\n004183fcad5bfc1ee90a46b5d9d5dbcf0e5e9ae8dc0a refs/pull/1160/head\n004192c034b24ad6572c1fff1bf0f0d446a8a5cb5eae refs/pull/1161/head\n0041cbe5f793ac2d9849e408f2ba0855af7f2dd8c0f8 refs/pull/1162/head\n00416ddbf9c9fa623fa7e882bce8137e95c5407cd79b refs/pull/1163/head\n00417c216e1be51960819f1c68c490bb2405d09a8236 refs/pull/1164/head\n00417d1ddb86ca16b3a2f949735d4e45057eb6f04804 refs/pull/1165/head\n00413222d5c3516ce1a96b0ac746d54ee9f8e80272fb refs/pull/1166/head\n00418617d676df88783fc65bd20489ca97200953f506 refs/pull/1167/head\n004164629568f9b9eb49f02b67527bb1624ab92494a4 refs/pull/1168/head\n004140a413bef66c53b2d6a1479b4753605744368b57 refs/pull/1171/head\n00410fd65ae3d1bf6e20ea905918e19713f3de62abe0 refs/pull/1172/head\n004192c034b24ad6572c1fff1bf0f0d446a8a5cb5eae refs/pull/1173/head\n0041cbe5f793ac2d9849e408f2ba0855af7f2dd8c0f8 refs/pull/1174/head\n0041cae28fde3b0739a2f25d99a99c98818f47d3e2bf refs/pull/1175/head\n004117d5536fe26f0bbecbf4a29d362c656971a8d9a1 refs/pull/1176/head\n0041ad1587210218e118ddcd6761e8e4cbc75480d2e6 refs/pull/1178/head\n0040a8afeba5d2335ebc47468154d19dff204ad9b613 refs/pull/118/head\n0041c463e1a594ae0ae9b513c8906334e998927101d3 refs/pull/1180/head\n00418c91a9ef4069448fda215afc0a691fa38316412c refs/pull/1181/head\n00417a847927be170a2deb2e5e2a945f8ccf98f91c14 refs/pull/1182/head\n004103488b1640bf60069e01fac924e97d2574490b6e refs/pull/1185/head\n0041545511100a9da8f5f5960c85ff178dd0369234bd refs/pull/1186/head\n0041e65d709f34eea3aef2269027c591016db5ab107c refs/pull/1187/head\n0041ffef0e2264e4e6d00639a385fa8dcd54e1b4ed37 refs/pull/1188/head\n0041c15d0948990b83575c8185df109ee78a9eca53a8 refs/pull/1189/head\n00419d9a7feafeef27bd32f7953aacec878951803197 refs/pull/1190/head\n0041eee13d0b2da6c19ef6081b7f1783f8e94625115a refs/pull/1191/head\n0041e79c7e2ab11ddacfe9ec48ceb558f0e296838f44 refs/pull/1192/head\n004184fd6e653a980da668b156b5deee26be0e0967ec refs/pull/1193/head\n004139b28f6c60a48fd0da014f7f121df58dde003ff3 refs/pull/1194/head\n0041d3e93e6be83f109e267661ac2aa4b0e3f14a59d8 refs/pull/1195/head\n0041dd4eef1324058fbbe9944909f8f0313617937195 refs/pull/1196/head\n004181e79baae5d66cd9155f46aafbbd56f0211c6aad refs/pull/1197/head\n004118ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/pull/1198/head\n0041ea17adac1c68c8ba7a04416828ab43e325e129cc refs/pull/1199/head\n004050b255408f4f5f98782027a92625ac97efeb8a0f refs/pull/120/head\n00416572931823db1ffb300832370b5db278e087b747 refs/pull/1200/head\n0041ada41b5104beb670322d7ae4a3ba8cf74daf59b4 refs/pull/1201/head\n0041d5330143583beaa96a58e452d72ced83785b5214 refs/pull/1202/head\n004169c1f7bda71f8c29f9fecc385cb65f04cea7693f refs/pull/1204/head\n00411338171fd1c8f545788fe4c14223c94e32443c2a refs/pull/1205/head\n0041f4f08a3b51ac6a60d087c150a5536dd749c01ca6 refs/pull/1206/head\n0041fb08aec4cc27297c2341d8c525b5639f366d7271 refs/pull/1207/head\n0041d39c1c9ed3e6c660d16d66f5f2864c51b74e435d refs/pull/1209/head\n00408a9fceb768f58ef0d65e70a8c9148acc58f55c66 refs/pull/121/head\n00416200dbfb1e586f702433384fc9462c95eed6f795 refs/pull/1210/head\n00417a5ed553932174c0207cfd68a0ce47ca853ef87b refs/pull/1212/head\n0041b8f620908376460ab72847f2fc73e4971df04978 refs/pull/1214/head\n0041f63802d0c7fb90a1c453dfa5d0530a1080d86521 refs/pull/1216/head\n0041ea257edd99d727d70cbafb56094a2eceacecb0bc refs/pull/1217/head\n00416adf5b9ea0eed8c8ff4340002472a6b53220edc5 refs/pull/1218/head\n00412a11fb082ce7cf96848f083c65002a51f3e54617 refs/pull/1219/head\n00416eccd998bbf7a3379a89732a9151ea7ee7222da9 refs/pull/1222/head\n00410c6554d500e645c78c9841cf00362ceba24cfc09 refs/pull/1223/head\n0041a291568e23fcbdecc4fdf5a57e81675eb1e3ac8d refs/pull/1224/head\n0041e9ae9d8fd4b97eccf2834983057a753a6efe9624 refs/pull/1225/head\n0041e2f771ca6d18fdf5282b4b9c3d48ae697c231495 refs/pull/1228/head\n0041315d44f6684182e6ef4d13940b10da4982dfdf11 refs/pull/1230/head\n0041534fe4077f8cbffcb48612a8db6cf58fb619270b refs/pull/1231/head\n00412f25c0586f675337030648e460da55393623f98b refs/pull/1232/head\n00418669c5b02dce839f4cce3ba83641c1f23a6d600a refs/pull/1233/head\n004108737789cf3c1f5cfc7afb96fb3c521758f6c36a refs/pull/1234/head\n0041ac050307e5c0cc6d7347bbfbd3c315c2a37b6ed5 refs/pull/1235/head\n0041225c71adeb9b8fb85b8e38a59706b5f52289a038 refs/pull/1236/head\n0041b38d9be3031e82a6b0f0d03b771e76c2c6602e4c refs/pull/1237/head\n00410167354914b745a448bd1f49cfc003eeb03c41c5 refs/pull/1241/head\n00412236e21a96f17837f3813f95000390169364eb63 refs/pull/1242/head\n00414703d2ad140205d31f89bf6260db52c52aa38e85 refs/pull/1243/head\n00414383f8580dfe6625844aa7d4c64e7d989c2ee72a refs/pull/1245/head\n0041ac8bfefb6bc528d158a5bb2efd1ddd09f9d59fdf refs/pull/1246/head\n0041f0b5858d6155b2bbd492d38bcc76bc4a9f34921b refs/pull/1247/head\n0041475fdc44fa132bf5590b9d1ccea658ce6a28f09e refs/pull/1248/head\n004172f897a002198a41584f38600d16485e524dd07d refs/pull/1249/head\n00406a07233ef752078d694abbd60cdde844e1674caf refs/pull/125/head\n004183ecc28c123d1c718b4c0a9687155f114fc38e9e refs/pull/1250/head\n004157b6ffc3a322ac6916e83cb3193698aa1befaf57 refs/pull/1251/head\n0041f88f82ee8505c4c94bdf75f0deea320af8866689 refs/pull/1252/head\n004180c6f8fda395d0fd8ca3de9f3d5d68cee2ba79d3 refs/pull/1253/head\n0041a1cf3cc412d127a44f8b99e23ec74d3480f56d1c refs/pull/1254/head\n004175c953aaf4439439a7502b427d6b38683c5281dd refs/pull/1255/head\n0041de528bfcfc8bfe071ba0c947e2c11f2c79e2c0f1 refs/pull/1256/head\n004196505fb6b2261b20dae04c55c0a379ea13eb34a5 refs/pull/1258/head\n004191f842d6286dfa26be459843312d62d4e8f7433d refs/pull/1259/head\n0041710aa96e02cf952b35210ea5f899a5fd0e7b8d0c refs/pull/1262/head\n00416e65903bcad7e04e514def27218793c53b1e69d8 refs/pull/1263/head\n0041bd8b8cb78af26a197641a82ae6c115185b96fd4a refs/pull/1264/head\n0041b6282b1fb7835f6f6080a0940f48b41168a8c919 refs/pull/1265/head\n004110ac754b3f2626cc391d7d97f1dc08eb52579eae refs/pull/1267/head\n00418da891eea0e42399a9f899fd8152f33b13b24f00 refs/pull/1268/head\n00401a0a14ce657c6a734ff5b06c81bbdc5277f3eeac refs/pull/127/head\n004163069536655b236a1525dc8bba8a27058fd55909 refs/pull/1270/head\n00417c1f0ad35f808287d2178468670fe058c4e4a6c3 refs/pull/1271/head\n0041b3c382937944a2d89d570c5c9716bafa864d8367 refs/pull/1272/head\n0041235e651de40e076d797c5106c6d47a0bb650f9d8 refs/pull/1276/head\n00413b683d9751c80c079c1e0e825b1a8c9af6ee2b86 refs/pull/1278/head\n0041c04e4c32b9081366ff01f5ac5af7eabfa87d3567 refs/pull/1279/head\n0040a3aa0190ec02fb50a9dc0ca3caa1e16d3551c197 refs/pull/128/head\n004108fba240eeebe70947595650002dcd5284c75e02 refs/pull/1281/head\n0041ebbef8dd520d32bae9adbff1a7b9afd5c297f137 refs/pull/1282/head\n0041462044a0aff0ab62614a85494ae5abcc6ce8f383 refs/pull/1283/head\n0041818ff67309775befc7321334b19244d20eb5ad06 refs/pull/1284/head\n0041b7b439cd14315139a6cff36df561c44b04b48c28 refs/pull/1285/head\n0041b0295ef926958d7b55e81c37de0c30ba067ae9ec refs/pull/1286/head\n004167d190b2d6f2a2ea4010416a8782e77a84944591 refs/pull/1288/head\n0041b0ad3a3c2352b4c9109ad238492e5a46ff318e37 refs/pull/1289/head\n0040217d6ec0d38cb8e49bbc0db6f3163003185cbabd refs/pull/129/head\n004177c1b1512bd9964011504bfd68e38953ae8fb04b refs/pull/1290/head\n0041a9e187010bda994c39a689d9fac4c62e8dff8e4e refs/pull/1292/head\n0041c8293cfa71f6e1a3f116036d6f414934f27dbf45 refs/pull/1294/head\n00417252d799111d4e456a0e4791055759210c19cc5a refs/pull/1296/head\n004164121e70812cb3bbacbc05660f7c6b32a380b37f refs/pull/1297/head\n004069f3513b4283e207b7456f5c97c3965bdcdcea0d refs/pull/130/head\n0041e9d6af87cf13d39f906b3e871449de8be0d9652e refs/pull/1300/head\n0041b701bb932f23723fe23d1c31c986cab6e3a25f16 refs/pull/1301/head\n0041ce44f45d5814d2338b41db6a02b9673a3bcac3e1 refs/pull/1302/head\n00411990166a4d5d917bffef8041c5e759122a5013df refs/pull/1303/head\n004127e78452afa10e75822537c1dc59f6c6e356c595 refs/pull/1304/head\n0041ddfd8b7c2f88d59e30fa17f1de599229257e6065 refs/pull/1306/head\n0041685dcc529073914e74da04846f3b11681d929868 refs/pull/1307/head\n0041399fd2f34cd6b84402f0c13d83f5c32a30869564 refs/pull/1308/head\n00411c7fa1f74a4d8dd784c4f05e9a9935b7a5c57e53 refs/pull/1309/head\n0040d3516d03ffe9f58ccede1ba3f544c574aa42f1ae refs/pull/131/head\n0041847f678420fefdcadfb632c520aecc997fca7ad1 refs/pull/1310/head\n0041c0265ae333dffa5f9cca62ac86f2ad5fec5a1474 refs/pull/1311/head\n0041ce637c03ec641463a65e6b74f29bc37c01ec4e45 refs/pull/1312/head\n004101a835202ec0d542141d210dbfd2f90f66814b9a refs/pull/1313/head\n00410dd20c733ac6ccb111a3330defae5adc6d5bd781 refs/pull/1314/head\n0041e41448722c681fe02b85e191c71e2c6c41519c8f refs/pull/1317/head\n004191473d1e455fa02079f456824b12ef220a1e4669 refs/pull/1318/head\n0041fe26cfde41df51635bd570288417e1b8f900ec06 refs/pull/1319/head\n00406a59ad3005e8b3baa88b54dd78e4279a4ccc1661 refs/pull/132/head\n0041c572a95f0a91d0ba402d87df9df8b81429c1603e refs/pull/1320/head\n0041d7a1dfe27a2ec072b32c04726d1d75210ef458fc refs/pull/1322/head\n0041968219e91fd95d2807d08b2b6408828cf3b9d1ec refs/pull/1323/head\n00414b392829b8b857d0287306b4a777f8bbfac639ba refs/pull/1324/head\n00410d7258d93688371bfe1caafebf1ce25cf2d22c23 refs/pull/1325/head\n004122be1d6029c6800cac1c2d42d83f71d7c2fd0079 refs/pull/1326/head\n0041a848fde40c72868e91d113353040a36dfe66813d refs/pull/1327/head\n004174b9bafc9ef5afb38700b92ccb7910af61796bbe refs/pull/1328/head\n004122a69e7f74563c51baeb8a8a8e1b802cbff1a7c8 refs/pull/1329/head\n00400f26eb0aa416cc1020b34f09af4e3f1e6eae343b refs/pull/133/head\n0041d1e9eb6d2b4f2c9d50a9c7f795f66062b1e1e089 refs/pull/1330/head\n0041c92bc3ee8f289f7e8eb2e9ceb78ab23985187d2b refs/pull/1331/head\n00412e2472b51b6074986ca422c25f98458e545c5487 refs/pull/1333/head\n0041a1083492f1f3b80dd53b3867dfb0e5f3e426f235 refs/pull/1334/head\n0041c700a6d603146f63e1c44653c1c5d40129e41722 refs/pull/1335/head\n00417c38d42344d396e6696a6a2033940b4f035e8e61 refs/pull/1337/head\n004177dd1ab81d345dca937a730341f3ad1c1904f4e9 refs/pull/1338/head\n00401b6c824ec12c00012a6d8427d6b0b34bdab8a034 refs/pull/134/head\n0041d86d572bab3c0671ee27d6336525cc8d55bf14af refs/pull/1340/head\n004155d2b0b1622b1413f489faa2bac980570512dc2e refs/pull/1341/head\n0041aa0a73405e98ae8d7b009e640456e4f571c73d21 refs/pull/1342/head\n004134ec5f9ce21a0e78d8e0d2a4fec8774403f75977 refs/pull/1343/head\n00415e0e19603f2027312246a0893faa8df5a36a2823 refs/pull/1344/head\n004159fd1b67e48574ee67c555bdade0af902e80ba27 refs/pull/1345/head\n00411372c29d076919391d1c695f0e6e76c9b5af343b refs/pull/1346/head\n00415a06b0bf8d3e46f7f31862aae34740269eeb88c1 refs/pull/1347/head\n004151118e711f25f0dce51af42459d39cda11eb5433 refs/pull/1348/head\n00416d14ddfdb397a7398b94152eb232d437a923d596 refs/pull/1349/head\n0040f24cba8f5ff6944a00c8be4c2dad774441035417 refs/pull/135/head\n00413aec658335ca7c5070c983a318398b85355747a7 refs/pull/1350/head\n00419958913d8b7e945d8b6d28d9fae4647febba959d refs/pull/1351/head\n0041e69c278a9b4c732ccb3c7b9ec8efd7f2c7bfe2a5 refs/pull/1353/head\n0041e4111c6737270d759ff61d20fe7ac15809644c62 refs/pull/1354/head\n00414085480a5528f688316d82698bde948ca9ac65ff refs/pull/1355/head\n0041cc321c111f93ef054d10057dbe28c2d9a109adee refs/pull/1356/head\n00411f69d4abd935d0a0d5d0da7837332c86a338a327 refs/pull/1357/head\n004147c580a9c60f044d6422a6d4ea341e8e73a22bec refs/pull/1358/head\n0041da8f4613f1d55a398b248256e1dbb2f9f90c4c5b refs/pull/1359/head\n0040ab796cf9328a5820baffbfdc785c11090e9799c8 refs/pull/136/head\n0041fb5a1d4cfbde3365f9c713b0c5db03218c9585e9 refs/pull/1360/head\n0041e6f77d85c352124f058de4a436cc67d2f2e30b64 refs/pull/1361/head\n004133f44bb126ccac62932b191c35b4f86ff35f2c54 refs/pull/1362/head\n00417d14ca8714a53b43b81fdbaf7dcb4d731e5ec59d refs/pull/1363/head\n0041d6f327bed5d1a899d71f716f1a6ab51df3c988d2 refs/pull/1364/head\n0041fedd017ee04380f5744c0a9a1fc07bd691cdd085 refs/pull/1365/head\n004157602cfa89f24660a262be44f4264afcade40596 refs/pull/1366/head\n0041420883c835fce5c1fdf9e31b2c4b2a1ba45ca3ff refs/pull/1368/head\n004111c85d3805418506d0b619fda3c646a388226d0c refs/pull/1369/head\n0040195ea6539b352979d11678d7731b59e84b976097 refs/pull/137/head\n00415ab467b5f0fefcdd6a0787f0ccd2ca9e97a0cf34 refs/pull/1370/head\n00419da99970b254b871a55c53e1b79d56aa73beb940 refs/pull/1371/head\n0041ed2599f2ed8167bbe784a9959ebe38c56335d518 refs/pull/1372/head\n00417a01ec6defdcce5a201ab284bd6353a71eabd196 refs/pull/1373/head\n00410cc32c70050d32375c9e546a100cd7c7777d80e0 refs/pull/1374/head\n00416816a5a92084da7236800e387a426d5651282a98 refs/pull/1375/head\n00413b1dd44df2530950029c8b9ba57d71255c9c6dbc refs/pull/1376/head\n0041cff37efef97deeb840a05829eba8df1e550b3902 refs/pull/1377/head\n004076f9add1c183150181ef213445762223afc918d5 refs/pull/138/head\n00417ac90975be4b80d894f0eb22fedafc0a57f1ddef refs/pull/1380/head\n004105c7fbc5e16350562f5c8f28c5383536588450f5 refs/pull/1381/head\n00417dfaef3c89adc165462a8ddc3be935e73bd36797 refs/pull/1382/head\n004134b8fc16757f65e7b3e90d439370c3cc39255911 refs/pull/1383/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1384/head\n0041d0f2e9bc0d3264cb1bb2c8f2b4ee906f3e1176de refs/pull/1385/head\n0041c20a188c9aec80c3ede2f7dd2eb87f526473bd65 refs/pull/1386/head\n00411cbf39c1fcfef7798b4813cb32a1376046717e88 refs/pull/1388/head\n00411d73b6292aa98bad2bd03288ad6113bf5f1a60cc refs/pull/1389/head\n0040786a4c116c797f5f052c82cbebdda34a172387c6 refs/pull/139/head\n0041cbc9a5c1531aa5cad02723107561294ca15b331d refs/pull/1390/head\n0041d454468b07554c64b73a0b18ad95ed94981bdc0b refs/pull/1392/head\n0041789fa98adf61b0f1386064ced86159ac9f2553d5 refs/pull/1393/head\n00413344c6fb9adc24e42a8a4bbb8a9072eaadb9392b refs/pull/1394/head\n0041a5db8f658afc1a4f96e972644f39c32c1462a714 refs/pull/1395/head\n0041317dde7e40b174b3cf2839d117ae7a2c5dcbfa1a refs/pull/1396/head\n0041b3bcc7c3801ad5dc9e096beeae896c614a663ed2 refs/pull/1397/head\n00419b26d0971b2e052b10c59a4b179287ae92a7b155 refs/pull/1398/head\n00415e665ee1c2eabbd103cc5d74e5da5228e227dc0e refs/pull/1399/head\n00408abf79b887bdf2b7d970159a720892047c8ebadc refs/pull/140/head\n004136457c0b3d9c3aa47e16a7089bb41dcad6eec907 refs/pull/1401/head\n0041f498a5cfb98dd66ee5163b021488cae184c8d24e refs/pull/1402/head\n0041f1088d092b4df04f4056fca730394c23b3b17573 refs/pull/1403/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1404/head\n0041662715d7828c9853635c002d2100247363424449 refs/pull/1407/head\n0041c64c12b83e9d51511a748a70757f20690ddd3a31 refs/pull/1408/head\n0040913404cad952b608e2517580fa108a81460af531 refs/pull/141/head\n0041d162902a177573ea0341f4fc88b98b1f0f25fc57 refs/pull/1412/head\n00414eb483a1cf40089a2a2d5fa201e8975eb8706e7d refs/pull/1413/head\n0041ac89c5db51165ebfa78349979fea2e5eb166dba8 refs/pull/1414/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1415/head\n0041b9e1c8381ab55609eef988418b70f850c6020de6 refs/pull/1416/head\n004109ad387ef44204b45b792cea92e2df799f3fc640 refs/pull/1418/head\n004167f7c3cb274c2e016881632ec4ff1356de0f8d18 refs/pull/1420/head\n00412af026f9942ab90ec9e698a8ad33803bb281b644 refs/pull/1421/head\n0041e2f40cd5d4b8a0508c2af944c49dffe469c09c3c refs/pull/1422/head\n0041a4a759d446a8aad1a8b12b63a82119a4c96cd23c refs/pull/1424/head\n004158d10f418fcfc6963a61dc845452e67792c07987 refs/pull/1425/head\n00410ba2087323b4e589157f928a5e4687c943b75723 refs/pull/1426/head\n00412a684541e3d2eeb59c2724039ca4559f9f4b94e5 refs/pull/1427/head\n0041c9e37bb52435738984a5cd8103b38b1aaf2c8734 refs/pull/1429/head\n0040255fe11304bf0f866e1a8bd8b9eda301db237693 refs/pull/143/head\n00411db0f8c1bd9adb6d2f759d71bb321a0ffa7791c0 refs/pull/1430/head\n0041b57b16c42a449ed0af7ecefd0e114c1ad15a8a6c refs/pull/1431/head\n0041459ca69939984dc05f15b77720aa81c672aeb5cc refs/pull/1434/head\n00410f37ac0525399c0bdeffbbea32e8f3ee78852a30 refs/pull/1435/head\n0041be6697582272417402c495d8fdebba36e4aa3a2e refs/pull/1436/head\n0041a5ba738874dc0331d3254e80d1f18b8d4efce8c9 refs/pull/1437/head\n004177e7e8ac271c1b9f3c53c374140c44d2513bf037 refs/pull/1438/head\n0041bbb832ba4b2ab40ed39e4e1c1be7c63f5b3f837c refs/pull/1439/head\n0040d5959201463d114551c61c6f096dddd7a8af7e56 refs/pull/144/head\n00419c0cb248c39d172e65a6b9726937f50c9021ffd5 refs/pull/1440/head\n004190f8f453047c16f613e76967b282d07ca6d5f2a4 refs/pull/1441/head\n00418bef7af75b5753b3291a8525458a63b0d01608f1 refs/pull/1444/head\n0041133778dfdd2c7f9998fd305b36c90cd2168bdb14 refs/pull/1445/head\n004167f7c3cb274c2e016881632ec4ff1356de0f8d18 refs/pull/1446/head\n00414f19efb23c7c1be947116d3420f2f840510c4175 refs/pull/1449/head\n0041d35b1fffb1469f0d0cf20dfdc59886d66054888d refs/pull/1450/head\n00412fc1a17c38a1ed301fafb75cf35bb4f2ce8720b8 refs/pull/1451/head\n0041773299d0b951f3402277f8773b651f66dae9405c refs/pull/1452/head\n00410b19d653a8faa1e77ea4552bfd66817420b1dc1b refs/pull/1455/head\n00417afd12d7cf6225b3c991d8d40c11b8c8db61da60 refs/pull/1456/head\n0041d042180adf0d2eb54e75be483337053809010256 refs/pull/1457/head\n0041f0edf0611e71ec179578cccd39b77243e3bdd5a8 refs/pull/1458/head\n0041465f266f9e56f1d58a5b38b86b629dd90f1a4037 refs/pull/1459/head\n0040d87aad784c93c9203eeac218bc8c9e88a3db5cb6 refs/pull/146/head\n0041be9a0dae947de482dd246c4e70666afbe522c619 refs/pull/1461/head\n00417b7150502c0ce679929ef8b2f2ee857664552d23 refs/pull/1462/head\n0041572f35dad64d6588ea96f3bde38a165fee9ff3f9 refs/pull/1463/head\n0041c270c099ad02eb0a23cd8497c4bb4c1dc975f741 refs/pull/1464/head\n0041c422c680a7bbb073523956c926de9310a17b3ff6 refs/pull/1466/head\n004185d6cc2cc79acfdd2061c4fbd600ce4c2f741fee refs/pull/1467/head\n004148ada69b2d8c141901ef529165df93f22d351486 refs/pull/1468/head\n0041be9a0dae947de482dd246c4e70666afbe522c619 refs/pull/1469/head\n004006894e6fec4cc65fc526eea0da822ac85a910f25 refs/pull/147/head\n004168f51c73b84cd2fc045447a09fb539ac912a5d91 refs/pull/1470/head\n0041a65c29ea40b8437572e676e55ae311d14479e9be refs/pull/1472/head\n0041341ace4dd63a182bcc2223f10d17f42aad50a339 refs/pull/1473/head\n00417a099e71b80e8747d27136e7e18409e2070e9b3a refs/pull/1474/head\n0041f170b2ad5d2b4b5477b61658a3c8af36ecc259da refs/pull/1475/head\n00414cf00e7e43cf89136d8aff44e72769efe9976905 refs/pull/1476/head\n0041c7b506f7f2b5425bc9253642b40450abf8269476 refs/pull/1477/head\n0041745d81755163efda96a36c54390c9da367afe86b refs/pull/1478/head\n0041c6d517a24a5781d51d87a484d60873e58a3d3528 refs/pull/1479/head\n004078c4df8242a4962d255d81e4121b14c186461a81 refs/pull/148/head\n004148aa3ce720b918c4d3251b4ada64cceeb33b20a5 refs/pull/1480/head\n0041e18554cc64fc785b79317902fe1fb29df777a7b1 refs/pull/1481/head\n004120b4ff3abaf6f3c5a83428d9293a1d2b51ab5d59 refs/pull/1482/head\n0041c594fbb00b9d4d0e6c0bdee76ef260f1b71aa373 refs/pull/1485/head\n0041231b7cd948eba5f6a67dea0cc433c3d1e83860e5 refs/pull/1487/head\n0041e077713e2fd9260b858e26eb796251d223a22a2c refs/pull/1488/head\n00418d54abb9154b6f8a11daa9a9fe4628399418ab79 refs/pull/1489/head\n00401ad173258d866686cea8878365e007ae56c05536 refs/pull/149/head\n0041b7f85e75a22a60f615bb51396a252ad2226d8b35 refs/pull/1490/head\n004118c31f294a8f038d42c374a4527a791cf11fa8d6 refs/pull/1491/head\n0041680d70c039e5af70ea1f892ebcfd19cb7bbf751f refs/pull/1493/head\n0041ca386287ba9a104728e40da69924e32891a61964 refs/pull/1494/head\n00417a47f4ddb8367212af84b4a14e31bb47d7093a61 refs/pull/1495/head\n0041ea93c334ee1502c974a33f05773e6d6b0be2e44f refs/pull/1496/head\n0041b28e8e652467fe118029756c2b8028e59ecb83f4 refs/pull/1497/head\n0041042076cf5970a4e025941de2a799a8461560ab9c refs/pull/1498/head\n0041c160b6a7ec28855c1273e4d0568ce42a3846450f refs/pull/1499/head\n003f3001a10fb6c4d39f149b8024bd06834d2e0f2bcd refs/pull/15/head\n004115dadb698dd7c9558e5445fa77ed64e3f2621930 refs/pull/1500/head\n0041eb320aed569c5377aa44e11a52feba2548752b03 refs/pull/1501/head\n0041f7f5aa9b3edfb792ecc4da4cbf5f2c6ff6d4cdf1 refs/pull/1502/head\n00415e87da6fcd3a0e9c999a81dbcb749fa8ff41d47e refs/pull/1503/head\n00411f9e058e9511c23323b159db9555807bf0e74787 refs/pull/1504/head\n0041ec5568348734532295ad86143ea119fec68f4ba5 refs/pull/1505/head\n00418b1f30d9b6d5406350deca472cb667e7c46e09b8 refs/pull/1506/head\n0041fb5ad38eeb943393c6af335e89f0ffa22eaf7fac refs/pull/1507/head\n00416c793bfe857449f9a1174643cdf2b9b5ebfe1967 refs/pull/1508/head\n00410e6eebbb86acbc92d6e727bc962be7807b50a765 refs/pull/1509/head\n0041fff0e2e5c58176cc5e4a13a347ce446d76e5c5a9 refs/pull/1510/head\n00412d85a7425c8a13008fbf52b8d45543a1d667175d refs/pull/1511/head\n0041964eb17ceea78e1ec6f495cc5ca324eab3ae12c1 refs/pull/1512/head\n0041e6a3b8bea46f4896b8ac0b92f5dcc042d81b9597 refs/pull/1513/head\n004135aa6907f28c6e6350436053bda59101d55359f3 refs/pull/1514/head\n0041a787cb7fc713f4a381c1281f90bc7a3bfcfcecd0 refs/pull/1515/head\n004128672bde3d91514708f44ae1b71ee780adfc90ac refs/pull/1516/head\n0041a3f9b48f377be38cfa9a9c600b7a73a055424da5 refs/pull/1517/head\n004143a849cfc3f522d10afed28f8136f9f6558aae67 refs/pull/1518/head\n0041f2ea2c03729bd2afb4b2d56321d52809e0bb3c2e refs/pull/1519/head\n0040050259ba69be2b95a70563765a15c42849daaff7 refs/pull/152/head\n00414f55e503a8ab7a7affab771bb1da4993bf61671f refs/pull/1520/head\n00416d07ece41836d1d3df38113c02a49d29bdc0e134 refs/pull/1522/head\n00414b48c91a0a3453090198d11f6a8727842db9d1f0 refs/pull/1523/head\n004138ad3f9aac054ed8871e887c5e0bc3e47cb41f06 refs/pull/1526/head\n004159a6477bf16284b0ed1204c42b490e37021916e2 refs/pull/1527/head\n00417c49448d992a0cbb6c6897bccddbadb62b564817 refs/pull/1530/head\n00419a02ddc6c749dfb28d0fe6cb85a42130c31c62a8 refs/pull/1531/head\n004170b290911ca6bd8796cbc208a11e98510c886f4b refs/pull/1532/head\n004141d92983d7e978b88cd3e49fc276ae059098486b refs/pull/1533/head\n00415c2880379dd3c8f7ceafd8791e17221793b5d980 refs/pull/1534/head\n0041ecf4c8da86c40d510a39b8074c18636b445d3c54 refs/pull/1535/head\n004168158e57f5a7258ff7bb0b9def2e50acc5722bd5 refs/pull/1536/head\n004184ed942ec251f38c8ffabede56aa229674ff4e12 refs/pull/1537/head\n004199cb2854afde5b21790a2384b3e6b7a065d0245d refs/pull/1538/head\n00410ea1a5b8fd2ddad43b9fce09dd4b701eb42f9a7a refs/pull/1539/head\n0041a6602a393c3d8c01feb308e21ae6b7f00e6a65d5 refs/pull/1540/head\n0041a5766dbac237aeb5996e47141547f8403c0bbe54 refs/pull/1541/head\n004160db4ae8523ca3180a50eaf9601ddfa8a9aa343e refs/pull/1542/head\n0041ca31af714a7a0c754d42f14531da4aa6812a27bc refs/pull/1543/head\n004185c8f0287fe9e70649e8e1dc295b10c62f4757a6 refs/pull/1544/head\n004110f90d2558011cb165b5ed8610a93895d14d3540 refs/pull/1545/head\n0041d8a2d1ad19cc557cd8d7dfb71189a50ccc312cab refs/pull/1546/head\n00410b39f6e72317fd3ebed1713f72c3b02e4d5d14da refs/pull/1547/head\n0041c672bf9b5e84698bca8177c2a6d110612484f8a6 refs/pull/1548/head\n004154ffe1e63d69bccaa9c6a22975393dbf20816b85 refs/pull/1549/head\n004180360661d8253639615d914c728179be546b0fde refs/pull/1550/head\n00412f81196691cc6ec6cd61e6879fe7ee719ad58247 refs/pull/1551/head\n00412ce6f5ac188adeed4d94d3296b2c8dfc9e103db7 refs/pull/1552/head\n0041cccacb7e6f96b39e7e452aafa88a540daea45314 refs/pull/1557/head\n0041d84a185ac9b0de0ea518f3c7c61033e8333c29e0 refs/pull/1559/head\n00400d6728af68c3977234c95f97277a9c7e80b26615 refs/pull/156/head\n0041b9c8218ff9aa201c0855be7785850a9689aeaa69 refs/pull/1560/head\n00412a34bbcb74f292c45776917e48bfc8b5fe8c0197 refs/pull/1561/head\n004146229e4e508d6a21436211d7e740f56e0710c2af refs/pull/1562/head\n00415875aa021ddf3961dfe317945b01583c98877bd9 refs/pull/1566/head\n0041207d4f5ec3a726cca709532828999cc5b24298fb refs/pull/1568/head\n00412994d14e821ef14f179da71cc56d6cba60f6d220 refs/pull/1569/head\n0040586de893d3f5a99c4fad86056d2e6f74c62ee729 refs/pull/157/head\n0041f428a60a3252a5223ead6f579817fcbd3909a7dd refs/pull/1579/head\n0040a9cfa8fc63f2cc043e2a9db7b48d8ce5196d99fa refs/pull/158/head\n0041075491fa48e07f794250c751b71420a33d8f1d8d refs/pull/1580/head\n00412b2a1901869811b50dda95b0bbe293bf8ba46844 refs/pull/1581/head\n0041ea8460aa2e510e57710c082cc7f169a00918169a refs/pull/1582/head\n0041f2ae86243215115e28fcfc21c91edbf4d4bc8068 refs/pull/1584/head\n0041ac97b8009acad579563c919ff9e83be8c2708c26 refs/pull/1585/head\n0041f5564caa092815ad5908e376147a84f12a5f4c6d refs/pull/1586/head\n0041a74c74821d1b621a1356e405d2daa9c86cee1821 refs/pull/1587/head\n004177cac1aa0c6d0750997a811dba708a108db0cd8c refs/pull/1588/head\n004178a902ad50439f9a0e05c386194b65cb59e23deb refs/pull/1589/head\n00404bd0fe137d82ed8f3e9c21770a2eb09ff2cdfdb7 refs/pull/159/head\n00415428807637585f9cbce87048220bb65de5b54d19 refs/pull/1590/head\n00412ce86486b53e98596e0aeefba526b36c9584ab05 refs/pull/1591/head\n0041494107c206031c9776d739da0077967f7820bd04 refs/pull/1592/head\n0041f9be7c1a9f2d78a6ebe2e0033446a5ba1226b1af refs/pull/1593/head\n00415b37124f98e48fb4d23b2ca52c9effcb4b6e68a9 refs/pull/1594/head\n00412e9bbdc135b413a81a3954fdf3a250cc221b5d19 refs/pull/1595/head\n00418fa5290952e7225467e22d919cbfdc61f6e5a448 refs/pull/1596/head\n004154ee226ef084e63e134ab7850adf02bd51e2d66c refs/pull/1597/head\n00418400000eb57cca8cc93dca976dd83c43a58b57b3 refs/pull/1598/head\n0041919ce9f657f40f60e49f19cbd389de9e493fffd0 refs/pull/1599/head\n003f04f95077a3d42acaee6213e43b30db43ff5cd0ba refs/pull/16/head\n00402ea858357e472cf6ef44d3e4bb598627c722de0a refs/pull/160/head\n004136d6118e605bc8535f1dde4499865d7ae1dc6f34 refs/pull/1600/head\n00418d40405f430d10f4e55dbbb6575d0c523eb4af90 refs/pull/1601/head\n00417bd61dfa9bece662f00e69ea0fea6694f41d01e3 refs/pull/1602/head\n0041e4259f91ef112baece9a58cd116a311bfbed4643 refs/pull/1603/head\n00414e034afd86bc8d28fa5149a8ed0329204ad84abe refs/pull/1604/head\n004127cf14504c0ed7dee0ed3349de789a6496106294 refs/pull/1605/head\n00412dacbc9290c92d3fa0a01f230487b5c57d63c63c refs/pull/1607/head\n0041938ddcb8ab340d456557f55dba08668b873a347c refs/pull/1609/head\n00422f0243028e21ffd658f4845070c7689b6bb72022 refs/pull/1609/merge\n00407f1fa1358a37f2c66cddff37f41097a7735225ac refs/pull/161/head\n00410ae076547e76efc789fd859b2674802043ed73a6 refs/pull/1610/head\n00414a008ec8fa334dfe9805456d1b369669ccb44670 refs/pull/1611/head\n00414b57135a9c4ccdf02010cc534fba565bde3a50f7 refs/pull/1612/head\n00415ebd98109d619cadc98cb0452a0c6a5b4a6664c0 refs/pull/1613/head\n00414be4b03279e6be0e8eaa5ebce4cc7ed641bbdb39 refs/pull/1614/head\n0041db142dd26ecc2bd285a1b14be7c80f6eec60a3c9 refs/pull/1615/head\n004164c190832746b38c7845752c7d25de7d160fe538 refs/pull/1616/head\n00415d5266e65df25cb90c46c4cbd3d9d6b8b63b592e refs/pull/1618/head\n0041906a1211c6dd202c7c7ede44cd2acdc4189ada66 refs/pull/1619/head\n0040ad263687541f8f83d15c4d1fd4d3971135523341 refs/pull/162/head\n004193546ec70491c29f1da3b234c547773e717db0a1 refs/pull/1620/head\n0041fd5e99a385b9174dc0c56b2eddb2eeb4db0aee1f refs/pull/1621/head\n0041e2afb09f0e0aaa4861d29ba6ae5f583df20f0d9e refs/pull/1622/head\n0041c19ed8d95fd118b1e3fe7c175f7e6f9e087d8a38 refs/pull/1623/head\n0041029b70afc2e78795b7c06d347c885c7f176c08d6 refs/pull/1625/head\n00412784d5f2e6062af40ab5769e75cf9cc52eb0272e refs/pull/1626/head\n00415035da3073ee1ccae17ba8dd4afe8be0a795be31 refs/pull/1627/head\n0041d4deec6d0da7f1ef65c1a779dc19b5d2964fa439 refs/pull/1628/head\n00419f8916a32d63d59bef6fc87287ee68a49dcb1ef5 refs/pull/1629/head\n0041860bbc8abc74b995ca1d0a5f0445a27bfa572654 refs/pull/1630/head\n0041f9f0ff9bc7540c9f48007324a89c79cf9477a51d refs/pull/1631/head\n0041a764c3bf113054896a43dea12d15634ace56c362 refs/pull/1632/head\n004126642c905dc317f9156e8bd3cfd252925ebf44b1 refs/pull/1633/head\n0041e33d72ff1e21534c5452b848a7678cfbbf420efc refs/pull/1634/head\n0041d315ffae02e5a1b69f5d60d6b51df8b1443d5575 refs/pull/1636/head\n0041153b7a6705e7c07598d47af91bcc3c72bd7e6d44 refs/pull/1637/head\n004192084fcf21479110c65a313e8b110246ba3316c4 refs/pull/1638/head\n00417e528b8c9d205d12cef9d93728d1c7f54e31a62f refs/pull/1639/head\n0040037a450c947ad82d0ae9498aeeea1c846dc5df36 refs/pull/164/head\n0041d71725912eb43eb95e649c442b6bbbe503e212e3 refs/pull/1641/head\n0041b1825a135207e352d0658b50f690ffe85594ca3d refs/pull/1642/head\n00414e1b650bde5ecce547d0de96699700b39540f3e0 refs/pull/1645/head\n004167fcafae3f165ff4d9b7fb5735fc1df9dc430fab refs/pull/1647/head\n00419054d4cb61638573789be4c52b101941f4bf3135 refs/pull/1648/head\n0041122e1be663becb68403697a0791fabb8597598f2 refs/pull/1649/head\n00417382850335f92144b964320432decc3bcfa1ee05 refs/pull/1650/head\n0041e2ecb13310305aa67198fe6c7d02259b57695ec5 refs/pull/1651/head\n004171632669bb9aff5abdafab8795ad378a4010d4a8 refs/pull/1653/head\n004154df24a7c12fabb8eb24c3060305f41f4ca4a4cb refs/pull/1654/head\n0041b1761437cfcd1deb82b345e255d6e4be136d59f8 refs/pull/1655/head\n00414b1b668e7d90752de5bc79bef1a7e2a53ec0f147 refs/pull/1656/head\n0041e790e1b260b9a5c3f85f69516b236d1b032240ad refs/pull/1657/head\n00414a07e4096a0bb16d762e5fea9da274c87fd5863c refs/pull/1658/head\n0041a6037a9bbd4d7997b7f97a2a72ae49dec960453d refs/pull/1659/head\n004049d39257f884690d669876986d9be47ac05a72e5 refs/pull/166/head\n00412bb60baa2a4093fb0aff6dd873849b4947ac9813 refs/pull/1661/head\n0041879551b20994b0f30895426d35412f48b8ae2853 refs/pull/1662/head\n00417572fe17a85942268020b9eff6d4d8eac8409839 refs/pull/1663/head\n0041fe61c22d3b2b85426dba27af3f65f16dae16f573 refs/pull/1664/head\n004169c6d4673475f395a00fa9fa7a381f579c1165ab refs/pull/1666/head\n00410cd5e9cc9016ff219b71d7a33c635222fff501e2 refs/pull/1667/head\n00418fdeb541be4aa5878a1e3254311a3f7e1e717bfa refs/pull/1668/head\n0040ae2c13c71b5be6042c70ffc2249767ef2b858087 refs/pull/167/head\n0041c7a2b7555299447ea01a557fafc3df6895c2a798 refs/pull/1670/head\n0041cbd7bdd929809d6c967d8764fdcda4efb6c6b00e refs/pull/1671/head\n0041176ec0475258a2db5d45598d29e0e61ba337ffb0 refs/pull/1672/head\n0041ba7c8e4233ccb9fc0a0d5e46e4f4282772bc842e refs/pull/1673/head\n0041e338570d4d6a9829eb37150f1b625a3800f20a28 refs/pull/1675/head\n0041aff5dc102b097be8863fdea720aef890a253a8a6 refs/pull/1676/head\n0041e43e1be58c45a9e16c4bd9c6f3f651f90562bad4 refs/pull/1677/head\n004129e395a423763120e528f50fe57de2334b73d83b refs/pull/1678/head\n0041db151fda8a8198e428b7cc311f0a1cd6c12c218f refs/pull/1679/head\n0040636ea0a2fb8fd8cc4655f21a9d70ba4f2337c709 refs/pull/168/head\n0041db151fda8a8198e428b7cc311f0a1cd6c12c218f refs/pull/1680/head\n0041813cf8299659c285f90ec25861b6e0db2480f87a refs/pull/1681/head\n004192992ec878d7b5c334fb81e8531eb3b61dcf6e4b refs/pull/1683/head\n0041ba91440d1b5096875a9c40ab141315017a996999 refs/pull/1684/head\n00410d05477509f5697b1af54dd776c81bc023185673 refs/pull/1685/head\n0041d2315bc5b74e20c288544e4b7849453f839df8ad refs/pull/1686/head\n0041d4a1a7d0d3055c20fd25e8f5a0610d5c923e3010 refs/pull/1687/head\n0041d9bf2254fde8d6d2d3d6d2df3282a9f4e5ff49fb refs/pull/1688/head\n00413e3fe1c137c0b23e87cb25411cfc820a6b15ba43 refs/pull/1689/head\n00414e49fdbca2db9c2ffc3ca887aee9ca5149e44299 refs/pull/1691/head\n004190966848c36befc986cf48f30a3fa0672197bc8a refs/pull/1692/head\n00413b16f8c008bcdb3140461c00561f072730e0725e refs/pull/1693/head\n004180532f3b4803483e5c399c91ea86bfebaada9966 refs/pull/1694/head\n00412556da4ddef258757bf420a5023704c3e03a34b7 refs/pull/1695/head\n0041f3be7b24a162e4e0728da3b9bad20b68c7562638 refs/pull/1696/head\n0041f888fa52c83074609d20006ed9433bd498e7dfde refs/pull/1697/head\n0041f21fcc02db695dbdfa3bd43247aef653b7343fff refs/pull/1698/head\n004144066554232f737fb771d3d0fdeb62339366f8f1 refs/pull/1699/head\n003ff5a848d9eacbdd8595a4d5b7b6d96e8e492287e1 refs/pull/17/head\n0041f4a80b262e382a9fc1b6471d53e3f873e6f25115 refs/pull/1702/head\n004175e3d7c121c05c0c60f342fbce1e90412626bd35 refs/pull/1703/head\n004156a6c73ab71c4a801c1636a75024aff41a37927c refs/pull/1704/head\n004125776d93bf74cda5889c41ad51ce190a5afeb436 refs/pull/1705/head\n0041d581d43aa016c297e1f79dbf409f4216ecd890ef refs/pull/1706/head\n0041135f97130a7dd070532c06830ad07c01d4b31923 refs/pull/1708/head\n00418f60ee9054a4b0c870cc2d967642024239d9eb9f refs/pull/1709/head\n00406dc43713b9adf9ff0f0c7c23d79133a7c469b8d3 refs/pull/171/head\n00416aae0ad145d73cd2af095fd61b1f11710c8e72f3 refs/pull/1711/head\n0041aed310703f2169df52902ec48beea4cbdabc8ec1 refs/pull/1712/head\n004145abc4bbaa86f8a93773d9e40a31d3429d4bb8aa refs/pull/1713/head\n004106d8bf018c193e31e72d2a5774a6576e4eb5c95e refs/pull/1714/head\n004141135d1dfc165e4e84138b5ecb6d14f6075e6177 refs/pull/1715/head\n0041b8db64deadee4e03205b02cb7c59be672e667e8c refs/pull/1716/head\n0041108f6bee9d622f10b3b46510f1c02137de860da2 refs/pull/1719/head\n0040aeef4cda0b482f9acc5a06dc7daa7e2ae22efda9 refs/pull/172/head\n0041b69082fd6e7f94208ad15df6b427f8136a8a4313 refs/pull/1720/head\n00427e735c29e45c9ff564f589c18f4725c0568959a4 refs/pull/1720/merge\n004140333ebf9022e2c072b1942a0d01a6d27151ced4 refs/pull/1722/head\n0041062986103eb61b843d6598c572677468945d1e05 refs/pull/1725/head\n004175dc86a4da88a29a6f9541a07866e1198969f886 refs/pull/1726/head\n00417c1c22a4eac54dcdf96557c405a6324faa8f8efc refs/pull/1727/head\n00418b54b9a8573a8a842b4133811fc9f23464701425 refs/pull/1728/head\n0040cfdd598e088b4245671337a5b7ecb36b46545ac8 refs/pull/173/head\n00418ca1c6b27e76e42276e22fc962854b113b5aefb3 refs/pull/1730/head\n00412bf5af86e833f538f47a335000b4a47bf3a38d7c refs/pull/1731/head\n004147cc7cfe9881eb70103c8f91d0e4677d953787ca refs/pull/1732/head\n00427833a8fc1cb02e261942e27af4f6c81bb01ca0af refs/pull/1732/merge\n004102db9f7d0689f13232f019ad2268baab590799c0 refs/pull/1733/head\n0041b032701afec89b78e3fa6a75b6005a8c4720fc89 refs/pull/1734/head\n0041bbdf11b0afd6319b4bfe8772e70f9f908c76c51e refs/pull/1735/head\n004158dfdc7cc6fe48497333ca28f76247c3299a7ade refs/pull/1736/head\n0041a88574270ffaae4fb6830b4a59707e007ff344eb refs/pull/1737/head\n00411c83bb41e7c42ddb272ea5f1728d01153acdc270 refs/pull/1738/head\n0041eba63642ac2b45e2b93e430d94e8693d17d04115 refs/pull/1739/head\n00419d833e552128a464daf6bbd82aaba0e60d59186d refs/pull/1740/head\n004181b64d3b1775f03352c54cb3a2fcd282957eabef refs/pull/1741/head\n0041158051eb777330492e3d2f46910560a6fa1f8abf refs/pull/1742/head\n004105670d6623b95520d638b53cd2ad282cfc50944f refs/pull/1743/head\n00417145fdbc67fffcbda16e97575dadc0f04b8fcf2e refs/pull/1747/head\n0041c0da39cbaf1e01c0833091101fd4ca8bf23e570a refs/pull/1748/head\n00411a44d898f1e4861940a4e4573ffa393060b892a2 refs/pull/1749/head\n004136f92267abdeb2b264ef84cf5f5b576a5943c231 refs/pull/1750/head\n0041e3d45e071f6e08ce7357efd2365d099acad8764b refs/pull/1751/head\n0041916652e2be88a78ddf2407fb692c3f3541ed11cf refs/pull/1752/head\n00418b68c6261756493c7a2dd5d3426f5eb9e553816e refs/pull/1753/head\n00415e5daa71fc8e91a4dd2dcd3f931732fb9f75fef5 refs/pull/1755/head\n004151641d8472d7202d491823a41c851e0ad36ae85b refs/pull/1756/head\n0041449faeade1565751ba6c6c8960b7a4c0952f0e83 refs/pull/1757/head\n00416f50c8a4325582a08bf1a60077103efd7c2a3202 refs/pull/1759/head\n00418390d3e556e27c26d40e9d1c68d9ba4c16d0b9dc refs/pull/1760/head\n0041902821c400c4052f4492975219729d19ac609aba refs/pull/1761/head\n004103f573ce19b4ceb32085185b6d1492d7f370189e refs/pull/1762/head\n0041b3b5bd988db1e4cdef63b6f3355aa8e2b0675831 refs/pull/1763/head\n0041d2e34e21d44bfc343003ac43300cec63dd6d1f96 refs/pull/1764/head\n0041cd318eb017b4a9c1af720552276d1102cdc89570 refs/pull/1765/head\n00415ddab79624857dcd3d1bdaff61ae79fbb0590489 refs/pull/1766/head\n0041e8a11106eb4cd18d5e05bc633e6fa473f14c3840 refs/pull/1770/head\n0041e6acc61e3cce771e712669fccadcac67c9f8ebbf refs/pull/1771/head\n00414a8257ee3922ca8866bdd1632c66b20649b2eb96 refs/pull/1772/head\n0041b5689883415dc3bb142cb78d9f083eef16b4579e refs/pull/1774/head\n00413a0e7ae9a78faf4b75c67d2f6491a32df11d14c1 refs/pull/1775/head\n00415bccc3883a0e68932d68245913de443d76cc5a82 refs/pull/1776/head\n0041d701b83ddc8f85958d1df5a4f1ef32f40f681378 refs/pull/1777/head\n0041591a7eab02b4b54a53186be752ad3e10d12047ae refs/pull/1778/head\n0041c950256f640f6fa96b0d3ce9d16ae6724fab8da5 refs/pull/1779/head\n0040ba57feb1392c5140060d290c456db746b5c6159e refs/pull/178/head\n00413fc708d801d83ba63fe85f1dfd9f3c08ce6fda40 refs/pull/1781/head\n0041bd1439e280fc7b8f76f583884136ce3d00c8a9cd refs/pull/1782/head\n00412c8c4f43d846ecd465698d4eed7c8692e2729c7c refs/pull/1784/head\n00413c132fb87a5f32d8df2ebe16c010f5db333584c9 refs/pull/1785/head\n0041dfef1664ec4a1ec64ec12395f9933b67b27449d0 refs/pull/1786/head\n00415f5bb39927c2b58565012387679555dbc078b8d1 refs/pull/1787/head\n004196823392fb6be48e90f55bbba486ab438a3ccf16 refs/pull/1789/head\n0040e414e0d8f3d323da277ee15476e5ac8ded3b82c5 refs/pull/179/head\n0041dfb5bea5fe9c993ec74061edd2a7d5d421ddb8b2 refs/pull/1792/head\n0041cac286a660ceb89ace7c5a5538f326d954a62d4f refs/pull/1793/head\n00418492757b37431c1977f01663d87cddde073fb33e refs/pull/1796/head\n0041b3e761e5db4d1fca2f8f45bdac17eec48a127ac2 refs/pull/1797/head\n0041d332ebad6c9711349a8a853fb7d1bbf9e248db71 refs/pull/1798/head\n004106e446e39e5a1efc9eb8ad5a300e0ee86ce08657 refs/pull/1799/head\n003f18f7167d53fbab5ab19c3ac36461fa518e59761c refs/pull/18/head\n00401a854ea0decd05e4a9335b3a101be33d9800405e refs/pull/180/head\n0041efe777d8fc625b80c8a08267de799b9f0c09c39f refs/pull/1800/head\n0041007a0118f2956621706c23f26b1cd8075791f9dc refs/pull/1801/head\n0041e494a752fbcea552414a1b6af006fb9a80610cb4 refs/pull/1802/head\n00414355e08bbbb3b6d2b8e116505a8fa1485748cfc3 refs/pull/1803/head\n00413739401fc548f67e699c741b9044fbe213bef387 refs/pull/1804/head\n00414b4688cce5010a2e2837c2094ed492211824b231 refs/pull/1805/head\n0041bf05a4be79e1c79330b47cb046df101ec64c1ff6 refs/pull/1806/head\n004162dc3304c621e5ae13625d5930d2484c9adfa4d0 refs/pull/1807/head\n0041840766f2f861a9d06c769e57d40cf65862b6c675 refs/pull/1809/head\n0040f6b89e763c1ae6f398849e5b94d858e34dff8663 refs/pull/181/head\n0041f474e67aade05636419a2b8396c27fb39cfa9b02 refs/pull/1811/head\n00413369c5f8f0d54f839dd20203d3450d4096c41a3f refs/pull/1812/head\n0041c9b14d17d84e90432afb9246dd9a8377462ac627 refs/pull/1813/head\n004142e7655663ed198fd3c46f6455cea5ac2c40cb83 refs/pull/1814/head\n004172fde249e400bdd09f0ca65f187104e2f7792da7 refs/pull/1815/head\n00417e2776ca22f4537a6fafc0c95ceb0c74c8f341c5 refs/pull/1816/head\n00418ee9da5f84628b5401a8e73cee770397cfe105b9 refs/pull/1817/head\n0041a06e2597ea1692277f8edbc2b643a3e382241e6a refs/pull/1818/head\n00418cf8e86091b471ee1886414cacc1969f05af5ef8 refs/pull/1819/head\n0041dccdafcd455c19b1e6a803e4e94471bbae7eff85 refs/pull/1820/head\n0041b4c17c7eb63e68e5df2d65cac6138a4d56803719 refs/pull/1821/head\n00419c8fdb86ebe6ee0d858312e741ae680a1131ee73 refs/pull/1823/head\n0041342c6564bbf5330cb4ad65ac20b15f2c3de6665c refs/pull/1824/head\n0041519191dcaae36c1587f166e39d114d9fbe200547 refs/pull/1825/head\n00416a70839069b44b5a63e2e6a3e47ed5504158fa72 refs/pull/1827/head\n004101bc8a5883e4478ed31ee7d06cd9b96bcfa436ad refs/pull/1828/head\n00406d813c2208a2326d94036b185b734a6d1d38d7d8 refs/pull/183/head\n0041599f8e1ebe821769299192306a8ea909a5199ea1 refs/pull/1830/head\n0041618a7b7eef4b5fabb31a7e63340e309168e6f45c refs/pull/1831/head\n004157b43516fc128f79431f23271fab622933f2754d refs/pull/1832/head\n0041f860f607fd0e913c0171835f5019195f49a23cd7 refs/pull/1833/head\n0041f237e8d0e9abda367e2c305927b9a1ebd83cdad9 refs/pull/1834/head\n0041638eda44b84d8cc4afb493c11b7ebe33d8e83cb6 refs/pull/1835/head\n0041f2d546ba7c01232604f6be739452773829448ee0 refs/pull/1836/head\n0041d8e9f77faa0c47702d961a62ffbc7ab81362f9b1 refs/pull/1837/head\n0041b7534a9fe65901fd3071f950456085d12c611ca4 refs/pull/1838/head\n004184b27252897a8424d599d97e220d69d4d38b0adc refs/pull/1839/head\n00417144013ab8c98e85af59db288d848dbc666d5258 refs/pull/1841/head\n00417da7fce2d029220b100dba66a7fdfd2f28ea0ba2 refs/pull/1842/head\n0041691f49caa3031ecfc2ead03ec6fdda8b860c3b04 refs/pull/1843/head\n00419bc319a6aa2e212b7493ade763896472cb345ef8 refs/pull/1844/head\n0041c61898f594c8e619dfd59572fffaae1906eecf17 refs/pull/1845/head\n00418edae54f46cb62a34bb4859d2691b0097f5c0c8f refs/pull/1846/head\n00411bc9f9bc308cc69cd1c18ce6b8efa61b9aa745cd refs/pull/1847/head\n0041cd932084db77398e5ff63b3d80c76d943b598212 refs/pull/1848/head\n0040fb5c00d58e188df7ce7231a6018eea17a91ef6ae refs/pull/185/head\n0041238ffde778c5424146ca9c908c897b2356864e2e refs/pull/1850/head\n004128c950302ebd22c56798dfab9bc820349f182c1e refs/pull/1852/head\n00418e6825db704f875085b8fe4359c61baa8bef63a2 refs/pull/1853/head\n004146c9c7e31a9c0295067a22f7e0ab4b1dbf7098c8 refs/pull/1854/head\n0041fd8fc0001fef1272ac97beed2a4050c0c5fd4195 refs/pull/1855/head\n00419211aaae4312dbc64872f6583622bc7061315822 refs/pull/1856/head\n0041d60fd3898289884aed9088d0788fcdd4089af548 refs/pull/1857/head\n00413b079372b7d977aced123b231faf50d0a92057db refs/pull/1859/head\n00426795a093abb0f0a4389743360dc9e1dd1f0ec5a0 refs/pull/1859/merge\n0040faa9d00e7461ebbccef663371a70cddfedee7eff refs/pull/186/head\n004144ea636af4e056a3a4809470e530c7d207705c20 refs/pull/1860/head\n0041934da32ea81e43d81860656a73935d943abb50d4 refs/pull/1863/head\n00413cbc3289eb428cc8cda8bd41701574428c376c14 refs/pull/1864/head\n0041a2d04657c1f761293e5f56dff1ad2af38482119c refs/pull/1866/head\n0041871a044ab84086af69e2fa611087aef94fd5a0af refs/pull/1868/head\n004117a52d99f395378639a108fc4146657ea5e3914c refs/pull/1869/head\n0040178e0c45a481822b42cb9057898909470b354936 refs/pull/187/head\n0041b784710337f716e3fb64be89dc5b78b9fde61d8b refs/pull/1870/head\n0041fac2d682381c1f67c226d2a3673b9330d33e6c03 refs/pull/1871/head\n0041b2ebc60f06bb92c153841ebe0d328be2fa88c7b2 refs/pull/1872/head\n00410a572c2b0d448e9216f371df6404fe69cbd02fcf refs/pull/1873/head\n0041647a1b125de5e4e5dd58e0e5fd82e6d9064af612 refs/pull/1874/head\n0041713d5de37556062cc50ee11421dd549f03a71e94 refs/pull/1876/head\n00417500a942176139d5f95e3347d6ede76b976a0cc9 refs/pull/1877/head\n0041ef86be2b62af481b81d9d44f88a8683e0226cef0 refs/pull/1878/head\n0041b37e23b5130a65abf26d2ee26e0a0a1d37732bf0 refs/pull/1879/head\n0040d6b016681ced68f32ed3d727d32bba5cbcebf48a refs/pull/188/head\n0041592e36c17a02947d83cf9fae2adc0144f48109d2 refs/pull/1880/head\n0041823870c376cb8d401a114e0e49766ba1b316483f refs/pull/1881/head\n0041c0c8d33c548238906e9658a5a8da5d1e9e603136 refs/pull/1882/head\n004192de84d0c303553c56f7573cb7b7136ceab2a31a refs/pull/1883/head\n00415175f29e6048f73fd71711fd3c3d38d1bf1097e4 refs/pull/1884/head\n0041a0f94c499d7d1d45e378cb158b5bcb98b9366196 refs/pull/1885/head\n0041baa5f0ec04243280748d5cffa9e835bc6b0ae675 refs/pull/1889/head\n0040c266a133eae2cd259ac6886be464d835d0b30bae refs/pull/189/head\n004167743d32b235c950e773f5fe796254bd1136f436 refs/pull/1890/head\n0041a54d5e9eb8b055cb99411883b793185a171e36d6 refs/pull/1891/head\n004114510eb2cb5c7f81ff192db3254c2f9d36ab22ae refs/pull/1892/head\n004142f2b477cfbdfb31f89659dedf77f61496745860 refs/pull/1893/head\n0041a49be27eadbd0a14ce9d27f924ab38c7aec660ac refs/pull/1894/head\n0041e2c65a1ab9b5119edad38b3d4a054d949ec27bf6 refs/pull/1895/head\n00414a1eef23e039e45dff6096fb1e4d7038484b1324 refs/pull/1897/head\n00415d68dccbbbcb4cabb6914bcd0f80e96422f0107d refs/pull/1898/head\n00417e9977249bab5f79d036fe5914ed85bd19db5afe refs/pull/1899/head\n004087c95a48cf9b44c8ebfa2a35d37762f6a1572f2c refs/pull/190/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1900/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1901/head\n00411489e5e84754ed3aad329ebc32611cd316761fc5 refs/pull/1902/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1903/head\n004161e7f3064aa96e267ae37ddc2a5c9324fb5eeed6 refs/pull/1904/head\n004161e7f3064aa96e267ae37ddc2a5c9324fb5eeed6 refs/pull/1905/head\n0041224a5a70982da890dbf26f70b45c39cc25a67849 refs/pull/1907/head\n0041a149eaa3775e95374637f017e800dd1b5673094c refs/pull/1908/head\n0041241d011f5c0ac29302b40a25b2a926065d0bdbd8 refs/pull/1909/head\n004049cb864e08b729f52808928a2a9ce557e4b63380 refs/pull/191/head\n00411be286663de204d29d04591ed1daff38ff3f46bc refs/pull/1910/head\n00416298a560d7715a672a847fe5e24614e6bc328db1 refs/pull/1911/head\n00411a0b2221a398e516d6844f77b920f81f008177b4 refs/pull/1912/head\n00410d3d2d5f97113e1b91856f35c20d1fc03c4f1f3a refs/pull/1913/head\n004183bbbae23013931adc38b155b79281c0afc5cf1a refs/pull/1914/head\n00414613952f0071cde9e471b982ae651cb064c62156 refs/pull/1915/head\n004198f0cf7a889941a447d74b18fbd8afc932689496 refs/pull/1916/head\n0041f6f3d4ad945b4742e74821ec2fe57b2c9d75fb6c refs/pull/1917/head\n0041eba4115d19c2142967b2abd3e498317980a7ea0e refs/pull/1919/head\n0040c41aedb6b766c1c5c7c9bf214ed36fd1bf35909f refs/pull/192/head\n0041f2945555e9b6873697e1dc77b2bcb1d529ae61b0 refs/pull/1920/head\n00411bdb2cb54e96bae978e7350a447c870660f3dde8 refs/pull/1921/head\n00412e508356481a07c23a8500c50a86f04f45216753 refs/pull/1922/head\n00410fc002df4fa3b5805d3edcf19e304c4fce3fa112 refs/pull/1924/head\n004133bc22e366f010900c8ca27c6221f8b2b835c858 refs/pull/1925/head\n0041e7fcb811dac1d6c07c171a1ce0d90e38ceba5820 refs/pull/1926/head\n0041c5cc882dc859f67c7bf0220c27cd3888c2c4c138 refs/pull/1927/head\n00414de467d648b6edac48ed3270ef1103fce19f994c refs/pull/1928/head\n0041084a1c5cec5a72081d9458db6a93b6bedff82638 refs/pull/1929/head\n00405cfe80f45ec7a361dd2ed1ad3205a40f922560e0 refs/pull/193/head\n0041d2116ca0179389558d7136d4f344c30dc888763f refs/pull/1931/head\n0041c6f867cfa1cff37f58fc159c9e60b3f996a1b34f refs/pull/1932/head\n0041426246d022ea114825a1c083d765fda9d0e38141 refs/pull/1933/head\n0041382b6f29ad0f337672497a4b0ffa3b19102c219a refs/pull/1934/head\n0041c48c9aef1f349d72a986be344987188e330f8137 refs/pull/1935/head\n0041d31656de65f97bc212cf0d8b4f04918b84d7cf72 refs/pull/1936/head\n0041f87710d03aa8a0cf76be0fe2d7336422e2970435 refs/pull/1937/head\n0041a2d40be8c7c3bc359f55015f12aa4c0d24944e38 refs/pull/1939/head\n00412b35b159e21d96c538037fd25b58325729d28192 refs/pull/1941/head\n0041ab4f2902a774fd8c25f5ee2791bb31ec28ed3148 refs/pull/1942/head\n0041f4067f3ef35612f3d51694ba3dcbada4723f7486 refs/pull/1943/head\n00415cb72fac61a833c529759f0fa647e71f7eee6ae2 refs/pull/1944/head\n00419b847af342a4b727a3b9ed8dc46fb4aeb0f6a2b5 refs/pull/1945/head\n0041293e1b459ba2e76c9c2cd5252263ac795893dbaf refs/pull/1946/head\n00412680c976e27942c3bd91707d46c27b1beb8142be refs/pull/1947/head\n004173f816cb70d1e8c0c94d503463a0b08b105e0b49 refs/pull/1949/head\n0040e3257a8fe4c5df589abf5be7eb115bd472bf877b refs/pull/195/head\n0041b4fe07c1984372d91cda304769214afdf87b9b80 refs/pull/1951/head\n0041b73b5b4e9dc9591299ee67c0aeb7fceee06f3af1 refs/pull/1952/head\n0041a9d7ec3526fa15d9537dda54147f648cf9399b00 refs/pull/1953/head\n0041d27a5e3328e2606726bf0f8e62f09dcff05f1c09 refs/pull/1954/head\n0041bc78d3470d7a521c7cf24b5cc4406e97a52e31d7 refs/pull/1955/head\n00419d6429cb59ebe9a2f13a20c7f795858ffc123440 refs/pull/1956/head\n00418aed1058a87d17a67a6e54d875fb81206a85dcc6 refs/pull/1957/head\n0041ee161fd069b80bfbb1292a6f27f1ffc7f2ba22a5 refs/pull/1959/head\n00410474edf70992688d398b983af52a87d4a03a371a refs/pull/1961/head\n0041c86ffbab0f0c9c5ce7729eb393184ba20ce40fce refs/pull/1962/head\n0041956e85c8b84f417b302eeb4d645d1f5df5428513 refs/pull/1963/head\n0041104ec733d3c19dd9d679617df07e2f6231267693 refs/pull/1965/head\n00414447c9e617f14f32acdce6bcc771807d81ad3a54 refs/pull/1966/head\n0041d7672253927e948e6f18dc6277d9b6021b2a250b refs/pull/1967/head\n00400cb945b59925f3612ea2f24630617eb7b10a0fab refs/pull/197/head\n004119891269aa3a37277b394227fbcd7eb154289a70 refs/pull/1970/head\n0041acd7a8aa665b2135ed007af4f6ea67eb01fa4008 refs/pull/1971/head\n0041239e81f8fb51a5aa77e21f47517a4ca8b6e12dfa refs/pull/1973/head\n00415877e42abc56eb8bfbd3eaafce72645d4b3f6cef refs/pull/1974/head\n00414747a7fdfce35ebf31be8179b83c9edacfe8d4e8 refs/pull/1977/head\n00428c8ba4b230e5cfdf2a0c5f3dcdab40bb03a0a16e refs/pull/1977/merge\n0041fab3819ed8176c96379df3a96fc060c6bd36f4e4 refs/pull/1978/head\n0041781c0b371217c18f55466eb507522cb228474ceb refs/pull/1979/head\n0040403251a233aa9572cf5a1f57af8281b1441bd744 refs/pull/198/head\n004169792ce2495948ae2d086548d53aa3f290de6698 refs/pull/1980/head\n0041750e03e96927d3b78a6016d64a17698305136ca6 refs/pull/1981/head\n0041dccc8f2bd46a549aee8cd5535782d04cf4712ba4 refs/pull/1982/head\n004116f4f86033cd44dc9d599b6bd44bbd16de63f12f refs/pull/1983/head\n004106b3ca51b04bb5fb1d45da88c4adaced62f1ab72 refs/pull/1984/head\n0041fdcba2deead127853858d88adad54911f6e97ad1 refs/pull/1985/head\n00416545f54c7866be12e4267735f98771c52109404c refs/pull/1987/head\n00417ac50201a25d62bf105f60efa768b52377939fc0 refs/pull/1988/head\n004136ddfb58948a39a7ed85e6e1ee52449beace1555 refs/pull/1989/head\n00411aa0110d1eb87b2d05063c4828468943243b7fcb refs/pull/1990/head\n0041ef723c65f4a172daba2f1a1e135c556f6596bab4 refs/pull/1991/head\n00417fcd080ce9e3471e06dd0276cf59d0c4ca71fdba refs/pull/1992/head\n0041e738213271e263b02ebfc938faf72cce645375ef refs/pull/1993/head\n0041cea3f7fcf79ad3cd6b2b28bc0294e864b3a5a05f refs/pull/1994/head\n0041687cae8512e398f298488eea297f73dfe53072ac refs/pull/1996/head\n00416629856ab6b7b0a32076c47bfc85011f20ee33ef refs/pull/1997/head\n0041bb915dc2f5b2d12605f37262e392f8ebf4dc6235 refs/pull/1999/head\n003e227289e2e18325309196e553f26cf06741e5a871 refs/pull/2/head\n0040ac897909866cef27ee70748dac547290e8339b5f refs/pull/200/head\n0041c13380af413e66bc91d76d77cf3531e7140c5db1 refs/pull/2000/head\n0041400d01e27e6e77c6459a3f7324d531add8e46a87 refs/pull/2001/head\n0041d5de53fb00ce28af6e9364bb3182ff6af9b30743 refs/pull/2003/head\n00411a17fd60b55f021fc1a84bc06d1475c4ed78cc82 refs/pull/2004/head\n0041f3cb06daa4dbe5411c65e35e8bfbfa37dc7fbec5 refs/pull/2005/head\n004161b1b3b78a534a0184cc77e86f33709e6be1bd6a refs/pull/2006/head\n0041b6f189b0beefe056d6dab787ddc74a807ffd9184 refs/pull/2008/head\n00413b80b5f5f8a59cd6aa0b3101a358e48293d14c5c refs/pull/2010/head\n004107f397ba9a967171f4afcdb3b1b8970b69e9c9e3 refs/pull/2011/head\n0041d16293f947aa812b4b2b4d1ebfbb0c89c210a050 refs/pull/2012/head\n00419ff5de4e3b6b25f950ec5434744c7c133935a5d3 refs/pull/2013/head\n004124dbffe5565019bec56b4c22c2bc5f4a13aa8fd9 refs/pull/2015/head\n00419e147c97b5f8b278393343d4b8bb677f7eb0484a refs/pull/2016/head\n0041c1adcdcf02d6893489bb66db2bc5e15989362962 refs/pull/2017/head\n0042843e8a1c7442b51022506746015c4bd21a65832f refs/pull/2017/merge\n0041836e42fef0c279835268be30efd3464e25922110 refs/pull/2018/head\n00421aee22907b4122dc19d852195cb93dabcdf34667 refs/pull/2018/merge\n004165406a5f6751e7f3cedeccef122ad18c83947a7c refs/pull/2019/head\n004100e067a8552159498597321528fbcdba02a8570f refs/pull/2020/head\n00416935cce17323111b68c5aa93c64b2592f8968395 refs/pull/2021/head\n0042771ff68a56721a103d3d659328d1a240c27a7b22 refs/pull/2021/merge\n004081633dd80a91de8da7c784ae4226d1ac2e4294e7 refs/pull/203/head\n00400782f673e6e8e4cb46798e1f1fc1c7bb43b87e89 refs/pull/204/head\n00400043e0c42496c1115bd3d15f1832048c5ec728ed refs/pull/205/head\n004087f71a39fbd1b7ad9c0bc082c1e1bd73e625903e refs/pull/206/head\n0040cd338722bbfbe9cafc040fd4a58cebbd80d6a605 refs/pull/208/head\n0040c828bf499e0a54feed38c3efc5afc2fe5fc59700 refs/pull/210/head\n0040b4fdd96948f5b8f5c4c41ff5e277d8ae84863dda refs/pull/211/head\n0040f5ffa2b991257acf59ad9bc4ddc87de714ce5c3c refs/pull/212/head\n00409a693cb5810151a780868e3d43436e9510c6f62a refs/pull/215/head\n003fd59e57cfe4a038bdb858fc152cd2214704df1af3 refs/pull/22/head\n00406091d46d9c655897ba91cfa65c8004e75b98b424 refs/pull/220/head\n0040f77dcc094a5589ce0d13396121fdc307b184d9be refs/pull/221/head\n0040765c274e85c240ca6a3366c6f0ad1bc6ac452d2a refs/pull/222/head\n0040de452c4fd1246cf52bbd9c4645ceda3de6c963fb refs/pull/223/head\n0040e32f4c7c941701878876c9de2e08518ba91602ea refs/pull/224/head\n00401269a63bcafa0a92f2e1829aef42820fe5454553 refs/pull/225/head\n0040804c300357e5ea865b1f0734ca1b288b9824e0f3 refs/pull/226/head\n0040cd3c3579d2e91ab8315033d631ac0ffd09c1b122 refs/pull/227/head\n0040a685f1407043126b0f9a58178ef646114ee519b5 refs/pull/228/head\n0040cec929e0700eec11fcb037af820b866732aaad09 refs/pull/229/head\n00400475ac938bbb5cb40197427ada059eb5243b7de8 refs/pull/230/head\n00402aeb755fba4bf6a99f61bfe6956ab96a7fb830ae refs/pull/231/head\n004028c2539e557607f01af2209e84acd9e686270fac refs/pull/233/head\n00403244b527077764e80b45b3db7578d73d2c9f5ceb refs/pull/234/head\n00407e700c03f3ea4b69e9d5231aace0f674f2d63b52 refs/pull/235/head\n0040e80445c3c1e0763c426f7b92d78f091b23380b5c refs/pull/236/head\n003fde471304b8809039fa0eeac16dd7b0be485ff4ed refs/pull/24/head\n0040e9db3e9b11ec62a54c3d577611ab731304399ce1 refs/pull/241/head\n00401deb6dfe2f4fc45c29c0b8d71b56844537b1c67c refs/pull/242/head\n00407829710f4a46c40f293bec37928b367c59d68356 refs/pull/243/head\n00402f3c672384d91312a1f8eff3a96a8aa23f34d4ba refs/pull/244/head\n00406e26224a25fd1ce7a69fa5a553f0742da30b3954 refs/pull/245/head\n0040a14d46ec3fd2d50347228b6ec12e2ea49fa1d3bb refs/pull/246/head\n0040bd318a9946c88a8bad7b7db9e3c7d309df7fb714 refs/pull/247/head\n004081c462de5b4be77a18f6502d55134651af4e775f refs/pull/248/head\n0040df4007f74aa72f3d1c03d1ce0daff237761d088a refs/pull/250/head\n00401635f714a5495f687e45782b4ab66eb42d0c7a08 refs/pull/251/head\n00405111aa6f732a44a92f5fd0c19d8186b9671894ca refs/pull/253/head\n0040a4581e8e3febeab26d866ef77ae26f9c8f8a26d4 refs/pull/255/head\n00403c14d051f305a0be658ecf6c98642517847c8f80 refs/pull/258/head\n0040bded0848d146eb0c233aa9c181326d4680ac3e8f refs/pull/259/head\n003f79a28b7545d178137db83f3f8adf14455feb0793 refs/pull/26/head\n00406f31d66051f2490c45b29e9d6c84eb08e5544417 refs/pull/260/head\n0040cbeaab2a51502e8fbb829d84104739850f50f068 refs/pull/261/head\n0040188d8414f7cc1aeb0a9e1e7668184aa56b33b2eb refs/pull/262/head\n0040ebc362b72806ffbfd769c3d19cc7f204173a4c4a refs/pull/263/head\n00400b1c90c84ac51778da84eeb8a9b9689416443f31 refs/pull/264/head\n0040b682d5096051e654e480cf40db1107376dedd37b refs/pull/265/head\n0040ade33a76ac1418ebe9b2f6ba5b3f1d776d024819 refs/pull/266/head\n004062da54e9be99730f0d89ce47f4d71f473e50b6cf refs/pull/267/head\n0040cd4ff5624fd65157528f2243cb21902ef82a6ad1 refs/pull/268/head\n00404edc393c56d4a2c0b4c7c8125752a8959cd3c965 refs/pull/269/head\n003fd665b8e6478068d649547bc2d36001d73163d35c refs/pull/27/head\n004090196e06eb596a8146b654fdef4865f90b7365f2 refs/pull/270/head\n0040355fab7e85adc982f1b4c6882b1d14ef73044e3f refs/pull/272/head\n004031f12be9970ed4d54045ceafaf65e0bcbdc9060c refs/pull/275/head\n0040a56387b3d0238a7cb9caa890fcf9150431729069 refs/pull/276/head\n0040a56387b3d0238a7cb9caa890fcf9150431729069 refs/pull/277/head\n0040f4e8069053317029a562949ecef0588e673abf61 refs/pull/278/head\n00402c1324f1a384dc7a18da5813abe5eda51093d3bf refs/pull/279/head\n003f70245086ba4738f4266d106af3b6429eb8c3ce56 refs/pull/28/head\n004044bdc18aea9dbb0349b32632f14f023f8eefd97a refs/pull/280/head\n0040ffe0898a49f91a88b5fdc9a963f94f5f5c5ab18f refs/pull/282/head\n00409dad380b4cab356a4d2b6395385b574eadd1f5d8 refs/pull/283/head\n004045715a32c2c17873335d8395f7bd43e82350fcb0 refs/pull/284/head\n0040f0ee734e0d67527235535c6655e886502521999d refs/pull/285/head\n004002202ee16193ae99ed3e9bc0f3ec883817dd05f0 refs/pull/287/head\n00404af00d86c44190de13b0e33f7dd6124ec77a29c0 refs/pull/288/head\n0040b195c1fd6d2482925035f697f217858c13b53a0b refs/pull/289/head\n00405f5747b92835d52d3032a26b48dacfb9ee2e16e9 refs/pull/291/head\n00408ad902c7c63a0f8e8d61f6fe04db1b33d4d7f005 refs/pull/292/head\n0040228ce21d0de6ebdf1952339796217012eadb01b8 refs/pull/294/head\n0040f9f993d981188015c1fab9e172c311de87082969 refs/pull/295/head\n004013bd1e82b3c584406aba45e1946ce294741e5bbf refs/pull/297/head\n0040ba3899886a590ca291ac8f7fe8d7fcd283b2bdaa refs/pull/299/head\n003eb0925e528c75d05cdc7b8f16ac500a7d3912560e refs/pull/3/head\n0040244efc9e6c61ed99462fa3e0bcc384ced1cca269 refs/pull/300/head\n0040452885a114b0fac92a7e845d2cc569af066be57e refs/pull/301/head\n00403cfedab773da858feee8541a4d738c7c73cb7165 refs/pull/302/head\n0040a176487c59caa1e9624b2d6406fead6aeca35067 refs/pull/304/head\n0040578b91862234ed8650ad5b03d7914d321c5f25f3 refs/pull/305/head\n0040d162837f8c08ddd7f6c9fb0e57c5c54e716db886 refs/pull/306/head\n0040518a444c79e345c0af1fcb4a4ab6574bef9e2acd refs/pull/307/head\n0040bfa275ba908f2fc6c9e4c209a06fd0f3f5905945 refs/pull/308/head\n0040c4c262a69c96ef6baaaee4fec325dcc5c536fa73 refs/pull/309/head\n003f90a7b27592c16171aef9a594392bd29164fff1d3 refs/pull/31/head\n004069940c13df4aeedd8d1adadbb4da52d2c4a94c77 refs/pull/310/head\n0040ac5232576700b8417ff859ab5f30a2c001653fc8 refs/pull/311/head\n0040fb0320867173cac3d6f85975b6b7bda9e298c83a refs/pull/312/head\n0040367f11a8e1bd75b36ee23b4c2277038e9dd2e1ae refs/pull/313/head\n00401af06d7061c8516c463eae852b60e4ad9f46ea25 refs/pull/314/head\n0040679e0336f1392f76424b5f0672e0af7fff45167c refs/pull/315/head\n00408da272d57f0f39905dd31aca1b6ff13e7b1f6554 refs/pull/316/head\n0040cfe6d7502821f60c09be0f6de2548ac952b01696 refs/pull/318/head\n003fb0aba74dee21251e105f3067868cc12278b5c528 refs/pull/32/head\n0040c4b08a881d301278195a9a902e4440d69b62f4c0 refs/pull/320/head\n00406e1e91f74fe00bb7254b52f514c106c2750f7ccf refs/pull/321/head\n00406cb0397d29f40047caaf1afe3cc671ecc9a490e6 refs/pull/322/head\n0040197ba229808a1f56d29682b95604d0bd6dc07335 refs/pull/325/head\n0040ad1da8a30d85ee2f2fb9aa118306c7bd6d83a013 refs/pull/326/head\n00403b3acfb7788ea4ddc1d6bfb98be03010f990264c refs/pull/327/head\n0040296d51fce4ae51ebb86c55829540678e60086e69 refs/pull/328/head\n00404af7cfdb68e5f3873f3eb2951af1369124988998 refs/pull/329/head\n003f818b4acf27ea1a15cdc1044330644c1cfa73b538 refs/pull/33/head\n004016e40c6af662eccd5bac877efd8cb6cad6501abc refs/pull/331/head\n00406f61a385ea76b457e49c89c0fe763836ee64352b refs/pull/334/head\n00400fb139e0f229bc3bee5f9d1c2b69fc3df2613408 refs/pull/337/head\n0040483bedf9124ca525337bf7a51194d6a352b3fa86 refs/pull/338/head\n0040ec31c6ccba4495a70e8e4eee3c9f35d5774a2bb6 refs/pull/339/head\n0040aceaf23725e2998c8f1ee4256ec1e98e837c751a refs/pull/340/head\n0040dab94e2d57cf5268aa46731e32be1cabc696a10b refs/pull/341/head\n004094b2648690bdd3d0e7701bda97012daac2bec1fd refs/pull/342/head\n0041367ed8cf1af506c62f5805340135b1616a33cf84 refs/pull/342/merge\n00405e5f6f1b00ed85e49ceafa6f092a9c73cd03c0a6 refs/pull/343/head\n004053721a8c18d17db62e3b579b9d51445a1d15ced7 refs/pull/344/head\n004000238d08c4a3a69d06adfe671928d21fdc5a4966 refs/pull/345/head\n00409e295e32d9aee35e3b7b82fbb5cf10237082cc55 refs/pull/346/head\n0040569b889262dd6e9d0ed31c3ad1a32647699cf6bf refs/pull/349/head\n004020eb0206c2f505cc055a4b012dea2d990848f585 refs/pull/350/head\n0040675c714afd33ad8bae20c1fdec1b89ad4123fefd refs/pull/357/head\n0040447943be37d3912c234716fee8c1c0e41f9d29bf refs/pull/358/head\n0040c5be3aefedf19e587aab82d3091efa8d45f5754f refs/pull/359/head\n003f2226ed66e79beb15cc0aa6a1f599ad999d829026 refs/pull/36/head\n0040d02d40447e6e1f04697e71e23043dadb54336fca refs/pull/360/head\n0040c6d02d122f65ce3550eb002e4cbff6f1307aaa6a refs/pull/361/head\n0040eb3e1ddd638cfeca39122a136c247d1dc4f639db refs/pull/362/head\n0040e74d30f2000b48af90ed4d40333618a50ecf9292 refs/pull/363/head\n0040f505c84f7c30558bf21fc55c88e021aae320b4ea refs/pull/365/head\n00400cd0f763dd8e79f247086d2718f636f139b63360 refs/pull/366/head\n00406f850b316daee1310b1b7f5af78a1efbb297db2c refs/pull/367/head\n004031c5b475c76fc045af9a0c78a20ebcca0e983e14 refs/pull/368/head\n003ff1b5f2257493f1769c4b87cbc89e7d7ce11dcd5e refs/pull/37/head\n00403910ca66b0bdcaefc605889f8a425a7fcb1fc682 refs/pull/372/head\n0040795ff641608bc1c23fbf30494e5d869c9da8cfa2 refs/pull/373/head\n0040a649e78a5ecf126e7d2b3aed6d65e0015b0337ab refs/pull/374/head\n004078e74531d1bbf5545f54294cb5b131c47eeb2bb2 refs/pull/375/head\n0040d0ac99e0512f68372640dc79713a4fdcf8559924 refs/pull/377/head\n0040bda25dfdceef3467a832680f34bfe0cb0e912097 refs/pull/378/head\n0040630295e76f43697299d8628ac7fb1ef95f30a7f0 refs/pull/379/head\n003fa870caf05460b3bbbe2eb448b6c0d18bb263ed5a refs/pull/38/head\n0040f64c8f85cf710376d0f9c07b200deae640baf566 refs/pull/380/head\n00401cbd09531c7d54743f1318badde9b419a63b1ef7 refs/pull/381/head\n004067f69495b71106e669ca7e0862dbcf64dacb078a refs/pull/382/head\n00408ceedaae6815215d6ececd8f210bbf9eb22d868f refs/pull/383/head\n00403b04d0aa87bbbcc628a31e4d69e829e7a7deb866 refs/pull/384/head\n004018467496d52836381889895ff676a9a87ec4918d refs/pull/385/head\n00403088dc4790b8831c4c62746d69b22bdb3bfa8469 refs/pull/387/head\n003fca28eb9ea1cf459ddcf751ffb0bd705837469ce8 refs/pull/39/head\n0040bff474ba2e69f0fb335be9d77bb49252dffb3ac2 refs/pull/390/head\n0040c56da2f6a8cd95e3f902847db9ad69eb92732813 refs/pull/391/head\n0040ce1db0fb6a3040392e4104434db266b01af4ee2e refs/pull/392/head\n0040d6b8f53795a4b4a4ce35f780ca0f86995bf7c93d refs/pull/393/head\n00402a7d3a655048ac0962dab5e722b0b04413a05502 refs/pull/394/head\n004055d36bbb2cc26ab2f52ed1eaf8f8ebce95415ed5 refs/pull/395/head\n0040b0e9a00ae59ec00c720301e0cc4db28dde5b4370 refs/pull/397/head\n00401e1dbb6849844d4083414fcf7c3db45d9564c324 refs/pull/398/head\n0040a2af12c43c384e72e328807f5053f05dfc2c02fa refs/pull/399/head\n003e6cb9d7bef7abd32798513d84a8c314dba0b4e812 refs/pull/4/head\n003fd25e61e807da4721c86ee9b36c89a80be8dfe526 refs/pull/40/head\n0040dbd66fcd24b4da5ee22b8beed51b1f06d3a69b92 refs/pull/400/head\n0040242969ab05f09e456b757c5e1245524579d9e3ae refs/pull/401/head\n0040b5af6c719caf8f4e51b3195039a7de926a0066eb refs/pull/402/head\n004087147fa1361efac6e22afff849f0840977a9c60f refs/pull/403/head\n004025308263154455941508385550e41dbfddb025bb refs/pull/404/head\n00409da0dc32c7654dec5b99387398653c4fbe1b5018 refs/pull/405/head\n004073e271dc130e54179aacf5ce46330e15dd9f1fc7 refs/pull/406/head\n0040713e8e5584e0182509291b17432573ce7892fb85 refs/pull/407/head\n00404d4bfee2296419d539fb971e814f675ac8214aa3 refs/pull/408/head\n0040118362bebf75f74e303a3f935d68769043a2f211 refs/pull/409/head\n003fe5050b593f17f4ce4431237656be76fe82ff852f refs/pull/41/head\n004035d293d2aab96ccd85208099e10c59b17ab1ceff refs/pull/412/head\n0040f13fb6e6fffb48b230951e871eba70b79b661fed refs/pull/413/head\n0040d625d77a400b5d956d84b2da92c480e5503cfe28 refs/pull/414/head\n00407eec67d424846297b7fa4e541f6e9efd41cd954e refs/pull/415/head\n004023fffc505907c6791eab950c89097a2e5f586ed8 refs/pull/417/head\n004003bef894e0bb21f55922dde797566629c68cb5b5 refs/pull/419/head\n0040aa90aa17689f3fdd364b542ae163e8dbbcae95a0 refs/pull/420/head\n004084ed687790904e855be5e1529abe8680402343d0 refs/pull/421/head\n0040fac9453409f869f24ead55efa206c2be2e3b2c25 refs/pull/422/head\n004042ac66f2fbe36b19865ba80e9974a6b7dde24e8d refs/pull/423/head\n0040c6d54fa4b5cab1d706c1a9ec379eb6ef646a8fa4 refs/pull/424/head\n004022155f2840be77e5cdf86e7c0de16e0e525182ed refs/pull/425/head\n00406298f31b4fa7fbce1e485dd4331478c8496bb19a refs/pull/426/head\n0040b25f94af1cddf24dbb394c98b2a27d2c14656ca9 refs/pull/427/head\n0040f88a7c790208a132fc982d9e05b3ebaf6498579f refs/pull/428/head\n0040bc9a53c78de9cf65b4f4c59c6812816fb58acf6f refs/pull/429/head\n003f365fb02ab526ded787f5e7a668b7f556b2a65f0a refs/pull/43/head\n00403adc71e200004feded19aad29f314a8da52211c6 refs/pull/430/head\n0040c302f0a6fa9667c918d50ad58737cdc728ad1d0a refs/pull/431/head\n0040eb065c53919a796a1a759c60da36142f7a950271 refs/pull/432/head\n0040da3fc3288f7a7b38d3ce9c4ccf488ec7102e5b48 refs/pull/433/head\n004053fcef8335dc34ef5d9a7628e6d609b602a0c075 refs/pull/434/head\n00407b822473f9ca8e5d8a2668af42cbfd4ecfcb9008 refs/pull/435/head\n00405370eff763402f14466bb66e492b8494769985ca refs/pull/437/head\n0040fac9453409f869f24ead55efa206c2be2e3b2c25 refs/pull/438/head\n004075277afc9e496dc8e2b9a984debb55c5b143483f refs/pull/439/head\n003fce48f8e7c40dead8e218c54f81ce5d6f553e7ac2 refs/pull/44/head\n0040f9dd53b273558ae02449adb6e60cbe36e3c760f0 refs/pull/440/head\n004083aecd97343321b6dd92a4a9ac753684f5a4545d refs/pull/441/head\n0040e05c257b706461fcaf01b37cf77c8c3b6baa5992 refs/pull/443/head\n00402b016af7334685b7c023c3069680c9aa314f191a refs/pull/444/head\n0040a434231571723de01bda5d058d1c336993aea91a refs/pull/445/head\n004038aa30a94c4be5a2dee06d1317809fdb82023a4e refs/pull/446/head\n004019b4c69d67c02f1ffe97680f69edaff54f853947 refs/pull/447/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/448/head\n00408d72b44f90df3b5478e73a456f36d5e9f579ef95 refs/pull/449/head\n0040a29a32905cb78effcfa3bdd798a23bc671dc388c refs/pull/450/head\n0040be8afa6e456327a7a240289ef3cacd76d6a532b0 refs/pull/451/head\n004094c7eabe76810c3d58aa01d0ad84f3779c5f2810 refs/pull/452/head\n00401735f06d84a1871f51c2796cbc65945e7273d8c8 refs/pull/454/head\n004078b95e7dd680cfcb7b3217152cb13b56a98973a3 refs/pull/455/head\n004005180116843d9e7a5a8e5932c3082f6412cc0dc6 refs/pull/456/head\n0040d26c65041ee8adf4c946334662c27f4400b05728 refs/pull/457/head\n00408c52a688057c76028c19df875c08dac9ff17b263 refs/pull/459/head\n003fccdc7a09a9637b6feb5e189f7816c4254688ab5b refs/pull/46/head\n0040fd5723c5943968c5c2c0786b35753a9a8b6211bb refs/pull/460/head\n00401bf029c2f551f8922cbd63e563f3f369a755d50f refs/pull/461/head\n004027c2db76973e960a21b8fb5bfeec6c9ac021216e refs/pull/462/head\n00404e94e29fdf73f8e68b83a6dc9f44a9264a0c5437 refs/pull/463/head\n0040ec910b56daca04df144df7bb0d956e3df11fa096 refs/pull/465/head\n0040210b8aac249fcbaa441dc78d04fd472d36247d8d refs/pull/466/head\n0040c8d72ac9a6be59939f1c8028e13aefa8909f54d1 refs/pull/467/head\n0040d60ec8fb3d02f056ffb34019ae10c987133e618b refs/pull/468/head\n0040282b6be5935e29bdde741e160bb0d50ea3c5ee8c refs/pull/469/head\n003f744298a098c786b0d529d62aa8d1286249149473 refs/pull/47/head\n0040c2c23687b07c5db83bb4fa6379d690de623c95b0 refs/pull/471/head\n00402b5a5d0a16e95df13594fc277fbe22bf354b6a32 refs/pull/472/head\n004083a39d98ea56e94d3bcd0fe77d29bd0afed9c713 refs/pull/473/head\n004002f214b0b506d99904c6a7236db04f134cec9399 refs/pull/474/head\n0040e7732b81e1d6c1a0331345cef7db8f2bac16cad4 refs/pull/475/head\n003ff7513f6bc6f3035cec70017cea6546b163233a40 refs/pull/48/head\n00407b6f4370182cc851e937c54028f107dea3e59330 refs/pull/480/head\n00402b8d96d7a65bac4e382973fc2bacca904150abd1 refs/pull/481/head\n00409ece98a791d30073ee99a5611ff9272ccb7e5356 refs/pull/482/head\n0040b243c02bc1ad90590f8b7f156c23371c3ea03f2d refs/pull/483/head\n00406df8e7087be81fd4b812fcede11fd0e5674e51db refs/pull/484/head\n0040a9fabce3377f4d18e4cc8a9ddf59e580bf24885c refs/pull/485/head\n00402e8657c8f04d205b670b701cc65f9b381c3ded1f refs/pull/486/head\n0040c00ade840a2d93536862d2efa898f300755af967 refs/pull/487/head\n0040972c5c251a09b49d3f8910473f6a7f85aa8c5798 refs/pull/488/head\n0040003cf8e4c2e814646e035a91c31577eff5459188 refs/pull/489/head\n00400b439745a9bb98fb128b84d88ff8cde4ae56a72e refs/pull/490/head\n004068217e9b5600af99ae2740d872ff9984abae5ede refs/pull/492/head\n0040ce303879a732e57f6c188444228900aae0899b8e refs/pull/493/head\n00409c940744e1bea5251308118716419f17eafd299a refs/pull/494/head\n0040f62e29e13a6ec1390e62fb5dcac3361109c5e86d refs/pull/496/head\n004038e9825184d1515f905fc8fda2c25b18fd0dd763 refs/pull/497/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/498/head\n0040fee783eebdeb9cca8719f6971544275c0b0722e2 refs/pull/499/head\n003e9ad0404fd0837ad18816cdb1b2ed5c06533a8129 refs/pull/5/head\n003f143dd198a6b9757a6a8f5f1b920294b6cf63d157 refs/pull/50/head\n00408911da36d53e42c5adc96017aedae08d808f72ba refs/pull/500/head\n0040288bef9d33623e619288b47931ce149df84ae03d refs/pull/501/head\n0040e287c6818ffffeb6647bd70df1f023b19064cbf2 refs/pull/502/head\n004073737c3d3af14d96f9352cfd919a1009ceb8d4fe refs/pull/503/head\n0040f9b47f3db60daf8416a553502c6942252be7dbea refs/pull/504/head\n00404d6c590eb0919bb7730a491a54287347529712d8 refs/pull/505/head\n0040c5171715f1ee79802025ca334f477abdf171ea10 refs/pull/506/head\n0040bfde45b8014fbe58bf2b62819224135abe40b5ee refs/pull/507/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/508/head\n0040d8c9694e9bece1216f77c4d5762cf7534474c5e7 refs/pull/509/head\n00401eb22e3bd0c9b544e10bc6d6e7f737a3177caec0 refs/pull/510/head\n0040e6675ce73ed0f14639a37e13bd038b67b51b377d refs/pull/512/head\n00406e8a392f238709989a97d3d58e3774eb8769b174 refs/pull/514/head\n00400becef9868dff05709b9535c5c426a8990621995 refs/pull/517/head\n00407a23ecd95e89a06cb2610e7b5a715daba9a03d60 refs/pull/518/head\n0040671d51ef3f2bf051eda2a74827f46ecc670e2601 refs/pull/519/head\n004092e6014653cdc404989ba84a26bf8b4b8902ddc3 refs/pull/520/head\n00409372f0a34f7e8b518b8e1a3c905b59fbee76c23d refs/pull/521/head\n0040f3983205d990edf7852cc471cbbcd0d5b96b9426 refs/pull/522/head\n004050e819818da849783e52a788611bcd772b0dff95 refs/pull/523/head\n00409ef1ff9f8685b666b934233c793c7117ead48de5 refs/pull/524/head\n0040fa66564115190d4b6d9e4f175f2401a3dd97d5ce refs/pull/525/head\n0040db20f4ca5a6a7e64ec2cd3471c9df9e43e43cd0c refs/pull/526/head\n00402a169ed865d0e2061779fac51ce8dc4e0de9aac1 refs/pull/527/head\n0040611a2ce0460467038b2567dca6f55bfd16f57ff6 refs/pull/528/head\n0040dc53775c9a44a88350301e29029f03b02ced623f refs/pull/529/head\n003f2af6d94aa0eb7930fb1fbe6d089f8fabdff11d02 refs/pull/53/head\n004092e6014653cdc404989ba84a26bf8b4b8902ddc3 refs/pull/530/head\n0040e7205c9eb73af5a4d92f7b7a8f176da461321d47 refs/pull/532/head\n0040ab8999e350e2eee93fdfc42bcc6054a6f34ce159 refs/pull/533/head\n0041018853cf7571d2031680de6e71ca7a11f8850890 refs/pull/533/merge\n0040941f031b04f6f7b39ecab9acc4ef4d6ebdfe25af refs/pull/534/head\n00400f5f7deb892f49ec54bb3878f9e3417937b0c347 refs/pull/536/head\n004097e877ac458a0335b541a2eb672a71483d39ed61 refs/pull/537/head\n004046b389d18db064c2edbe426768122cce9778709a refs/pull/538/head\n0040ad815f7e5bddb79d59865a1d91f582ab22df03ad refs/pull/539/head\n003ff6f7855dfb3acfdb0f14cb9215a8e7e8d29eb625 refs/pull/54/head\n00401454913de36b573e23a0aadc0d110009fa0b786f refs/pull/540/head\n0040452ea9a2ee332ba1d508eeb12bcd128ccfbf4eeb refs/pull/541/head\n0040dbc8ec0b247f7d39aea584841510e8b1f6bcdd8f refs/pull/542/head\n004096702db9d37131450a18e2fa4ef2f884cd7d11a2 refs/pull/543/head\n0040b941dc49583d4dfdd536806838fc3ee2c9309381 refs/pull/544/head\n00400d5c78fec78a219b90901036b2ae71137cf4f49a refs/pull/545/head\n00409ae6da12c3e8b0f9e47add5d26ea526be0dc627a refs/pull/546/head\n0040e3fe40ff3a95653d1a73ffc02252081b537cb6cb refs/pull/547/head\n004011fde285f72c89c9eb3a358e44b5a488aa0b6f66 refs/pull/552/head\n0040ce6d89c6ea9a9758d671a55a853f1defb4ff0919 refs/pull/553/head\n004080f883932c1e051f1ad3f72d6714e64c23e12d47 refs/pull/554/head\n0040a8ace595e99e563f8cd6cf3b847f5dfe4fefaece refs/pull/555/head\n004008aa09bb654cfde77261dcbabbc47b12f11b94ac refs/pull/556/head\n004001caa3f704de8f5e4b0bdc470d1e2676378263b9 refs/pull/557/head\n00401af75607f98ed329d14652931c799ed3cc7f7b3f refs/pull/558/head\n004090813a3537904c85edf184c2970211585449f507 refs/pull/559/head\n003f7dfe71ecd46059b7facd8f11fb93a05f1b421050 refs/pull/56/head\n004044cd652740030062b68dda4a8a2b56bc05f207b0 refs/pull/560/head\n00400333e8667a5b82ef1f69545435bca768ab96fc06 refs/pull/561/head\n0040f596832b8f409c22c032f06f0c390a5dfaacb453 refs/pull/562/head\n0040dece033ec7efe073be6c10647630c49066af7820 refs/pull/563/head\n004036db95b603e189a7883c9f8f8bc2c8bd237d94cb refs/pull/564/head\n00403a8dc1fc9d8190fb9dd3e769a0051f0ca58087eb refs/pull/565/head\n00408d8f35aea1b0c6024a29e0eadc2dd1cf6ea61588 refs/pull/566/head\n004039238b7f7a499e03b1f473b86a74dbae40ccc912 refs/pull/567/head\n0040b941dc49583d4dfdd536806838fc3ee2c9309381 refs/pull/568/head\n00404b56f4a28b5d39345eace17e0d5ffb82c0aa475d refs/pull/569/head\n0040b9797f4f65edf2a6d146deeb6bb8402574257cc3 refs/pull/571/head\n004061b9d6fff795b8a874a0cf7ba6a54cd557a207dc refs/pull/572/head\n0040c8c2d067a865421bf9ba2b8b25d27f263117d200 refs/pull/573/head\n00401fd09206f6e244f0099ad1caf2762b45f3f219dc refs/pull/575/head\n00403fb44a5c9ae5532d9b0588f912d3c4fc6907db2b refs/pull/576/head\n004058454406ad2ef5ef4dc7b67c51c0e979ddbc9075 refs/pull/577/head\n0040f936f2fc0d12ad55ed359a587237483cbbfefb42 refs/pull/578/head\n004028f167b17c267c89bd3e7f02759445c20f8bc2bf refs/pull/579/head\n003fb582e52794750d1ccd15c5e702a68467bcbf19f2 refs/pull/58/head\n0040903641cc13760e8c892640cdcc71fb3a79a00b70 refs/pull/580/head\n004089c03a1877f2a7863a28f204473117a234ef7fd2 refs/pull/581/head\n004012d40ad087dc3bcaab323cfe3caa5390c9368427 refs/pull/582/head\n0040e319b913fb9e89a6c74f448bea5772eb1dee3c14 refs/pull/583/head\n004025066b319e0909a1481becb5116e90bd9025454b refs/pull/584/head\n004011542a56a0898605a28c088d7ae6f186fb4b3918 refs/pull/585/head\n0040e69d18e13dc36b2ca7099d3b9223a7041490e4f0 refs/pull/586/head\n00408e430dadefadb1c567902ab96325a81222ae5300 refs/pull/587/head\n003fe4aa79a3295e8000fd1ece79a56e4d3faf8f80ad refs/pull/59/head\n004055fd5ff1c67649944a095fe9b8a82a45f68e3dcb refs/pull/590/head\n004081fbf50e37593dde081ebf0b7b1de2d25880d037 refs/pull/591/head\n0040b21e3b766dc022e144a2b8b67a076a678b932743 refs/pull/592/head\n0040e047d701f4c8ee52b14b87999ffe08b7421705cd refs/pull/593/head\n0040f5babe3c3abea9f48c48f50218673c60d3cfe751 refs/pull/594/head\n0040e35836392fd209337d97336bed2a2906f47580a4 refs/pull/596/head\n004028f167b17c267c89bd3e7f02759445c20f8bc2bf refs/pull/597/head\n0040acee602bebf073fe15335b7c8a79c07fdacb3687 refs/pull/598/head\n004069567222b388afa940bd84190b455fd403f75e9e refs/pull/600/head\n0040d889473e50a94af92096f4f9bd8f2a567c05534a refs/pull/602/head\n004026db8a5a64f7aabf0a5026db611413ff295fbd64 refs/pull/605/head\n004060fe2d5d3466b5e820dd1820fdbb893259745e1e refs/pull/606/head\n00400742c085ee268fd31eaea0dd8da74b0a04d1181a refs/pull/607/head\n004098f261769a6f5b192e8c5e1020bb33c6fbe2a457 refs/pull/608/head\n0040a4ae0bf87f13851dd0fcc0c118e8b2b4323de212 refs/pull/609/head\n00408782289280bee40a4e94b22a37731d349493198f refs/pull/610/head\n00403057d4a45105c7d84baa25a5875dd1484684e337 refs/pull/613/head\n00406b658da55604658b5e8e78d7396f1ee23746f548 refs/pull/614/head\n00403df6522684ebe78a210046331c49a4615e85254c refs/pull/615/head\n004083a576f28c4b6727b27d6d94645b9f3932463787 refs/pull/616/head\n0040b85e4f5d37c8e04d55be31dc14ddd34df2f32e24 refs/pull/617/head\n004005ad248090b82fa57c14e5d9f0499a2cccc3106c refs/pull/618/head\n00402719b26e16e4a529361e35d25c2dad9b41a12ac5 refs/pull/619/head\n0040f6a203eda01006b94f37b53c4e776b6c1a38b7be refs/pull/621/head\n004060a364d8573ce2541bddb70027552ca69cdf8698 refs/pull/622/head\n00403f2a95ae1c6251412179f57508ce34c0827a8cdf refs/pull/625/head\n004004ede1c6a7f8b25aadb264f35efe7594c881ee0d refs/pull/626/head\n004063208318dc286d35a9e774fd203bd2c4a6bfc2f6 refs/pull/627/head\n0040372613e728da9bd97a30d01b60f32bc692fb996a refs/pull/628/head\n00400c4349e90f13c574bf46190fdc8c29efccbf51ff refs/pull/629/head\n003fac28fb90a951fe0a334e8ea974cb9d0830f8acb9 refs/pull/63/head\n0040f320b871049b7a21e25bbd9ecf6628b006e63db4 refs/pull/630/head\n004078004fb399747b6ddeadddb3a38f07a382061f8c refs/pull/631/head\n0040e6aec7aa5cfd7640aa939fb32609085cd9d35257 refs/pull/633/head\n00407b890e47285100f3b8d108033b37759725fe1e48 refs/pull/635/head\n004004ca8160cd3f3fb51d0f0e70dbc83710d954331d refs/pull/637/head\n0040f055bed5b72214f3e25286d69a5ea8696cca7d25 refs/pull/640/head\n0040b8ff2c64f502de807a09adac61b8da0bd7db5ff3 refs/pull/641/head\n0040776d6d46fbe8a70dbaf0791f63c1990bd881a3ac refs/pull/643/head\n0040d5e7494e5045f834569e278a7c1b44c91c53ee4d refs/pull/645/head\n00408caa1bdf24ad0303bd5d51de6984381354e41562 refs/pull/646/head\n004092b454d6524c3ab1eca4d843a37dbece32c418a2 refs/pull/647/head\n00402c4e9ffe944ff579ba992cff67c2130521832b0b refs/pull/648/head\n0040826a3a72341a4062216a56292d9626ff8cc76b6c refs/pull/649/head\n003f936df80471e524ca4e30d4bcd9c6bf2da1619dea refs/pull/65/head\n0040922bd29d0957d2bcecb3a4acf4b88973bed7621c refs/pull/650/head\n004061545d6eb37dba9adad76de739ee55d67aefa497 refs/pull/651/head\n004071302a5f59faae567849835faf47f419473b4d00 refs/pull/652/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/653/head\n004011d7a289c85480c74b3a274f22b99fafde4683a7 refs/pull/655/head\n00403069934324473370c83c8da418df32881dff9d85 refs/pull/656/head\n004085501cab1f30c5fc7475b51c0da19c2c474a53ee refs/pull/658/head\n00401691abc91ed22323c7e4b6517fa9d35aaf08203c refs/pull/659/head\n003f816891117afee70c3b6ccd7a3e4ed1f91bff3ba0 refs/pull/66/head\n00406cd1cecf9f64c545b2458bf2dead4918e2614cb8 refs/pull/660/head\n0040944eb940569b05e656637511b5657f302d14906a refs/pull/661/head\n0040a46f29da0320caf0138193af25b903d78d590bc7 refs/pull/662/head\n004043e604f269b6b07936fab6c787d32305546f7a2a refs/pull/663/head\n0040f37072f8fc388c8e9bd7bdf4a9bc2269e225a5b0 refs/pull/664/head\n004046fe9ce1d6955b1e123a836df17dbfcb9cffcd8c refs/pull/665/head\n0040bf2c8d5ccfa0c12de5874bb0f45e6a5ab9e3afff refs/pull/666/head\n00401de22909ed1996aa641ab70a9c986eb0ede742a2 refs/pull/667/head\n00401ff1cdd255e44061a2f78d235df584da00b5a6ba refs/pull/668/head\n0040892b384ee4a135beeed67fb0176fd6c04b0f83a0 refs/pull/669/head\n004039b922c380d8428d988b190c8c7b94344eef6a5d refs/pull/672/head\n00401b0311dafea5b3dc2f0a58a0635f79dd2b3224e5 refs/pull/673/head\n00403332370700ac736a5f312922303589efc41d8641 refs/pull/674/head\n0040621291bc9ff0cd5b64be7f7a31f33a77ae00c3b6 refs/pull/677/head\n0040840d9fc1b24479dc8adb5c9e0529055b1a1cf05d refs/pull/678/head\n003fa97e2e51ee5589d1ff14c3248043f2f62f8a26e5 refs/pull/68/head\n0040c93e9b5322e726767eb154411faf828e1ebfeab1 refs/pull/680/head\n0040eb439aa8b43ea43350534767e748aa6b8cf89a9d refs/pull/681/head\n0040629fd9edca7e930f1ea146db0becb0698d10e50d refs/pull/682/head\n00408e5a46bdef1cfe0e5705f48a3b18f99bbe78da0f refs/pull/683/head\n004066b76d0333cd0bf7c262dbf354821f7853080a79 refs/pull/684/head\n0040a123ccea8a7e5444faee428d06c0de3daeec4d27 refs/pull/685/head\n0040ed24702a797fee16808e0e2b27299fe63042af08 refs/pull/686/head\n0040973ceecc1638cab69ee6f4d61710f9d7d3d5efd6 refs/pull/687/head\n00409eca1945adb78d495b7ea37f416e2537b4f87562 refs/pull/688/head\n004056a659057ab574138c55b2692ceeae2645d91eab refs/pull/689/head\n003fb6dee38c2d63797fdcec086779098dc843480a69 refs/pull/69/head\n0040fe42f7d66c778a6915978d7e5eaf66b6b82f3b9e refs/pull/690/head\n00404698b3a302ef8ff9f30093cce7866acd06b434d3 refs/pull/691/head\n0040c27e84c8ceb61593314ab913a62b28edf5ec5f08 refs/pull/692/head\n0040f2f4eadb64d52684babf6d2ddb1000b5675366eb refs/pull/693/head\n00402524e022c98d1234669b3455f447478b9c81011e refs/pull/694/head\n00403d337516e9638647ddc1cfd69bf9a66934c242cb refs/pull/695/head\n00400fb585f54f7d8df4f4b73ceeef9eeb23fa3abe20 refs/pull/696/head\n00403bd465be77b51dd671871d913dbec3199b6ce16c refs/pull/697/head\n0040c7b9817cdd0a628e115179b386622e2cc89977da refs/pull/698/head\n0040b2e84be34bba70cc9488b7eca43c8d61aed1795d refs/pull/699/head\n003f9b874c5b0a86f1d65813d47c6dd78a6978754d8d refs/pull/70/head\n00403b4004263226b700f218533a4d5f1fdbe3b9be01 refs/pull/700/head\n0040a831edb9b6a397bd7c3698263e7b13fc495e6711 refs/pull/702/head\n0040f20fb3088846b39a337247e110ea304e19d14380 refs/pull/703/head\n00404e5d20976554ebbc88942d8514a35b9100e2dc09 refs/pull/704/head\n00409aa5d9b5ce1574304e420eb687c343729b204f12 refs/pull/705/head\n0040f9ec83f0c814ad9e737c5297831387adbcbcf0e6 refs/pull/706/head\n004011e1b7f9cfce840f6740cd5d3b91cd0de92a45e4 refs/pull/707/head\n0040a6fd606a568c680ccda176fb957ef4e7b8298603 refs/pull/708/head\n0040e63703543172b39ba8d76ec033ad5f858ea1e3f2 refs/pull/709/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/710/head\n00405292706433f41e67862c2c820b28417ae5a38e6b refs/pull/711/head\n00402cf888c8a56abe135361400475651f5b6ede641e refs/pull/713/head\n00402f795191896af78604cb103ea410ab491ccea85b refs/pull/714/head\n00409e7e84192717765fc65f41f106004429e63f2d0e refs/pull/715/head\n0040b992c004b36fc196874673a908f2d1bd22e318da refs/pull/716/head\n0040d60a5b259927e4f583d50134a96d23474e25620e refs/pull/717/head\n0040345d2baaadcf922efd507f05aa57ca6d8ad5e94f refs/pull/718/head\n0040cf764d67334bcc631c3412fc1e9e3743e20bfd31 refs/pull/719/head\n0040ed8e92f8a37c67095c6a3e2d3b021a9dcea510ae refs/pull/720/head\n0040139a03596c3e6dfb1a80bbc6877893c4c7fa64b4 refs/pull/721/head\n0040267acb6858c99d595411265d0535d3efc6af7f20 refs/pull/722/head\n00408bfca2d6e3018541ca05b8c0e3b6e2fa5512764c refs/pull/723/head\n004091ceea20296f42ee0d8ae56a6b44f676599758b1 refs/pull/724/head\n0040e95b8a788552537f9a11c8d12b118358b650d6c4 refs/pull/725/head\n00400ae9453fac7ae281cf31b35e99e04f8b3f8f15c4 refs/pull/726/head\n004053808a2355467a36667756cf17efde378ee3165d refs/pull/727/head\n00405ef6da531c461b0546345f9fbb25acad3e2255d0 refs/pull/728/head\n0040bb837b452ee7fb7522be487be0232740fabd81b8 refs/pull/729/head\n00402a7655ffe65892c0ce95498a36923db4668f09e8 refs/pull/730/head\n0040aa6378a0c7dd6ddf791933498a4a0eaa2ae1735f refs/pull/732/head\n0040ceb986e61c4838c72c7184baf5f3fb45f0f97429 refs/pull/736/head\n0040cd2b3dfdf10cbfef76d4055a305c336321b148b8 refs/pull/737/head\n0040c769b140bf506c1ee4fa83390dbf497caaf341df refs/pull/738/head\n004061f91c9dc338600307f00571d535983e4ed14929 refs/pull/739/head\n0040acdec9b61fe5fd912a04237663c5ef3f9d847f5c refs/pull/740/head\n004090719f5481ff990bedd7fb7ea94e4b7aeeb0fd4b refs/pull/743/head\n0040a61cbad87cfaea6b145243eb90c5b537e066adc4 refs/pull/744/head\n0040f0fbf6d15624894bace340d7292a18bae49e6b54 refs/pull/745/head\n00406ad567e18284e4ced6c65fb10b49bf6cfd4e890f refs/pull/746/head\n004011bf6277d81e9820c2e36b322f0701818e258156 refs/pull/747/head\n004015ee6b7c0e410dd5fa43236252cec7cd6790ca9c refs/pull/748/head\n0040635a6834b52656e19030b42aab949f7eca986cea refs/pull/749/head\n003f382e0370aa33b5f3901fb4bd9ee5e44890724480 refs/pull/75/head\n0040d6b597a14e84f63242b3f4156de42d09889ee485 refs/pull/750/head\n0040a4ab4739e78d23030b21f0eb902b00d93b005b16 refs/pull/751/head\n0040a5070313a1baf80b93e6dc540b04eb74fc5813fb refs/pull/752/head\n0040d746cb6da820fc16107bbf4ec6d1af30a4710dd5 refs/pull/753/head\n00404ba0154e8ead390b4de23d5cf92d42dd501ef638 refs/pull/754/head\n0040c7e3065a18bd585909f374ac98bab7a085de1f19 refs/pull/756/head\n00404f7a3c06fc89589167534fd08abac1ffbe6e966c refs/pull/757/head\n004054b427be3c11680def676b578fa015f703540c7b refs/pull/758/head\n0040dc5bc42a7e0a72dbe2768dbfefbebb8ea5a992f9 refs/pull/759/head\n003fbfc6aa37be811fc6b7c141083a04f0b1d36a4007 refs/pull/76/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/760/head\n0040084176a1059466af78d1ed41c0968f02f2a6c8c5 refs/pull/761/head\n004050d4e1617c135d42d2fc4df5ea9df169b4c5dc04 refs/pull/763/head\n004081d35661472fe799c41bfe3bf14815d7898be65e refs/pull/764/head\n0040e30eac78b7efd50c1e1664b7ccd6a46cad0c6357 refs/pull/765/head\n0040e2e2b58ecfd46da2250976eef17ba3f17d3ee6a6 refs/pull/766/head\n00409cbe19f019daae3e82614b4fbe4be683462337e6 refs/pull/767/head\n0040d407774ab1f23bccdee67a8f2c5d8b204d293ccd refs/pull/768/head\n003f75bac6c257e11af3dbc6bb3473efb452a8676fa2 refs/pull/77/head\n0040e32a19d8f94dceb03a2f67eaf98b0196f7281a11 refs/pull/770/head\n0040a7015d7091d16d6f426b968c7fa5ab2a0fda5819 refs/pull/771/head\n004091d305f5e791c640e499b3e1336003df515f230f refs/pull/772/head\n0040b15989230f1768a41dd0bf7835732b32be5c8de2 refs/pull/773/head\n004030f09f6a986ace57c20bd098c1bd5a30b09f4839 refs/pull/774/head\n0040477c4fd524718d7cc6cdfaa4a5993861332151e6 refs/pull/775/head\n0040399ba7ef32e0e9edd93eb133380ce8232dd7d4e7 refs/pull/776/head\n004083057171f2f16e65a5a9b712f0c8105a19e24a25 refs/pull/778/head\n004041b8a27767c438488457a6f56ba8a427c7723bfb refs/pull/779/head\n003fe6325cd88200e60ec723e8fb27ca960891569b67 refs/pull/78/head\n00400e622ae0abcce683414a36b55c7b1f7ff05a8b3b refs/pull/780/head\n0040b6ec2183f4168eb94540f19bfebd1a0448cafa61 refs/pull/781/head\n0040ac9d4ddf7c6da9dd254c651c21c991908a3efd23 refs/pull/782/head\n004073d0275a4a51b1eb24476f691c9eb49d0febf5bf refs/pull/783/head\n004074ee9815a27fbc867d66ff56cc0da34638f5413b refs/pull/784/head\n0040e0348f06c231815852cf432dd68c715bb95d7942 refs/pull/785/head\n00409b97eba12029ab017c28d75b0ad6b1c1d9695118 refs/pull/786/head\n0040f1f859d1b1db31ef4d9bb4e49a0fd10b1eade958 refs/pull/787/head\n00407fc32b3f65b240ae060afb3e0f31a7ff2d69f14a refs/pull/788/head\n0040212c57a643dc3b3ddd1b9d211956fd055d78824e refs/pull/789/head\n003f76640aaf845677d939aa5578237974d3fcff27b7 refs/pull/79/head\n0040d1a7093297b0ce3d81db935e4565f56d417c756e refs/pull/792/head\n00406bc5b6dfd36a9cef9b70a9d7bd822ac9154f808f refs/pull/793/head\n0040f40c753b86c6015dd7db80f8dd2867427cd83185 refs/pull/794/head\n0040657a24720972a37343978ab192c8f6f3531695b2 refs/pull/795/head\n0040100f6e334de39c3083ff0ad29986b5ccac9a806f refs/pull/796/head\n0040f38dff092a74670b2ace1a563657388ac5d2b601 refs/pull/797/head\n004080326c5446873cb5497019694aad7186f4f47278 refs/pull/798/head\n003ee54eb95679c706bb9d610481d1d96d5d3659c707 refs/pull/8/head\n003f373b99cbadee55101ed30e9737ec3f68ef2fbbcd refs/pull/80/head\n004006ad66c4f02ff7d48f7f4fe41986a210cbf08ed0 refs/pull/804/head\n004002af4a60e843863487053afa4e16dec87770ed55 refs/pull/805/head\n0040fffe088fa6dfb0e29296e64d689c5a580a6a585b refs/pull/806/head\n0040cf4bac113710693ad48597fac53e003765809d8d refs/pull/807/head\n0040eb9aebb4aa1960a61c86b055d7b43f1bf30dc2ad refs/pull/808/head\n0040e1bd462ccdde72abb307783414f18449ee8f367c refs/pull/810/head\n004000bd42a3359ad1bee3e0f8baa0bf9f6e11f91524 refs/pull/811/head\n0040f88be1e087ce77f11a55b483c325860ef674cb98 refs/pull/813/head\n00403a78548fda6a433b5a7ba85382bd9a3e23336b31 refs/pull/815/head\n0040a23c1ef8a80506bfa41a3f8fbc813305a6ae8eb4 refs/pull/816/head\n0040cff83e26d6b40924c8faa6116588ff70673f6558 refs/pull/817/head\n0040f71da79b826f7e07c1d3d1203b6ef807008aa4d7 refs/pull/818/head\n00402056c1aac5f3fdeb77121701a1ee45e4fa81eb9d refs/pull/819/head\n0040b050172863cc26434c80b2192992149fb53c61f3 refs/pull/821/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/822/head\n0040681c53aea42f51098793bc44f8b5818742bfe2ee refs/pull/823/head\n00400336c7de64f55e57c87009c19b19e2a93f3584ad refs/pull/824/head\n0040ff8aee76ad1ea6d56a2e7e8aac88d3deeee58566 refs/pull/825/head\n0040f33a77df57317329c29d8f4e0ec7536dcceed709 refs/pull/826/head\n004096e6a65699d269443be2fedf2775f95e52f872d7 refs/pull/827/head\n004038a80294dbd30ebb6f7708f5a1c1e15386c25fcf refs/pull/828/head\n0040d7b155f75f5b6a355c22a635df5011b07001b2e7 refs/pull/829/head\n0040432a4bb4c9606e99c41186a49607682da95e937f refs/pull/830/head\n004048da9b8cce538e01570673e1463af2c4e922214c refs/pull/831/head\n00408c427dc8a00c8428c81e0c70775a0b4749361656 refs/pull/832/head\n0040ea4710c0a648cb6534cf1bf2c957d4719524c5b9 refs/pull/833/head\n0040d135a145144fbb70f8a18bb9bb368381cd2e9003 refs/pull/834/head\n0040359f417d5ae56820a247b2d4ab137761be4b7808 refs/pull/835/head\n004024c1a97f28c40fc3ecad10edbeb1d7d7aea65ede refs/pull/836/head\n00405fe7b19a14351516fb514fa5c496d11fa59b8b08 refs/pull/837/head\n00409f0f70d5cc62df3eb070be6a9399a2ea125d0928 refs/pull/838/head\n00401a6c6bfced06a5f8f688f640223ca70ecedd6cea refs/pull/839/head\n003fde384e0d47c73a443be98e1626f4a2030a186b8d refs/pull/84/head\n0040b2a8175b32d930213de109d9fa5d7df6719e5ecf refs/pull/840/head\n0040ae4828d069c8c2a785fb4f5b49ce94cd2db05392 refs/pull/841/head\n0040e1bd462ccdde72abb307783414f18449ee8f367c refs/pull/842/head\n004028a7ffc150194668b70a04912843ecc0d171f7e9 refs/pull/843/head\n0040037c3543ac60359190459b10fbb5331568b4c8f5 refs/pull/844/head\n00405761166dd8ae69272ec0634dbd41e66cca0cfa5f refs/pull/845/head\n0040009f460af86ba742fab59878e9e86567ed46b4d6 refs/pull/846/head\n004045b5a8c5bbb44139e0625b9deb3b6545e74b45f3 refs/pull/847/head\n00402fcd46715333de00a990264ebd3570fced45949e refs/pull/849/head\n004057af90d4022ee5adfdce175ed6d3f01b7659a142 refs/pull/850/head\n00407df4c2642994b77f2b05e764b044c33993616e8c refs/pull/851/head\n0040f2ef83c7825dc0de95479c0888518f3b75beac00 refs/pull/852/head\n0040e9fdc9a0cf3c01c41eb7f648baf4f20dd8b61a64 refs/pull/853/head\n0040c939e15728e43bf1087293161d56ee01bb19695d refs/pull/854/head\n0040011f8c8950e89bb1ad9bdafce8a437473fe39ee9 refs/pull/855/head\n00404ca052c3cfcfe7aa8fed53f6a4957bb3b65cfaaa refs/pull/857/head\n00405769e69b9dc282b0a4c904819e306b82aff4269f refs/pull/858/head\n0040300ce5e2fd07e5cd9d41d112f07e1e2772756ab8 refs/pull/859/head\n0040df89acbaec3c346d36667d2ec049ca309047dac2 refs/pull/860/head\n0040274094a4b067716bc905451e445f854704575419 refs/pull/862/head\n0040d856c4e49b2016abc2905f1f6b24710a9d1063a4 refs/pull/863/head\n004020fca611e5c9da75894779bcdbac190c81a41c58 refs/pull/864/head\n0040ca76ee6811198d38c06b8cf02505b828f293523c refs/pull/865/head\n0040d3185ac93522c480dbaa1e479daccfed0b0e86df refs/pull/866/head\n0040f1aac37fe441c416842dcee21846c976bf82028e refs/pull/867/head\n0040ce2ad9b7b5d24aa337d5305f245335c74b377bf4 refs/pull/869/head\n003f69205fdfb3dbd604a165cbefe7bd116380ddb0b9 refs/pull/87/head\n004074e2029633b59a239aceb2ff9689aab46fb0269f refs/pull/870/head\n004001cb7338bc2915f23629e3b56a9e04feb21a48eb refs/pull/871/head\n0040538e76d99a2ee402145801518e897715561b68c6 refs/pull/872/head\n0040bf2503051b00e2ab16adc77f5d6b920088d2d1e5 refs/pull/873/head\n0040adf23fe73d66bf4a5eb1c28e9202b2ec2b108513 refs/pull/874/head\n00403ba580ead644168aa0fe109fa0c66db43e92d505 refs/pull/875/head\n004091dab8f0ecba342dbb43d92ae5a0ee0b2b9d2a56 refs/pull/876/head\n0040c5bdc6001d2494d8bd85b4c53b44e5a7d17a96fc refs/pull/877/head\n004015fefc390b71f7dec7a5e957b2f7dafc652cd713 refs/pull/878/head\n00409988aa6cb57d99be647b06acb2aee87029ab47d6 refs/pull/879/head\n003f4215fc60b039358b7b25c738f77d0a7b0cafdc74 refs/pull/88/head\n0040fb68f5b16adc288d4c3cc51acff850880339f677 refs/pull/880/head\n004039342563fe83c443c9e896d9f417df8826c65e8a refs/pull/881/head\n0040b049b2af26e1703f0887516356147e0ab1a2c881 refs/pull/882/head\n00406b27d53a4fca05cdd8ea92cf6e20982f10cf261a refs/pull/885/head\n00407c69ffc21e56cfa1e776eec683025b060eb7dedc refs/pull/886/head\n00402ff1267bdb33581baab1b8894e11a9ce45524856 refs/pull/888/head\n0040347ca611bffafaea9a1106716a451540f31d6a60 refs/pull/889/head\n003f237281ebdd37ac26e0c3aae9a0d64be1a96fabf2 refs/pull/89/head\n0040eef642b3533197cf97722797c5ab259a445bee6e refs/pull/890/head\n0040efd820c3b0841736eb6699b1b455924cbcd3099c refs/pull/891/head\n0040c03816f1930f1f18e7aabea7901ce24018e08111 refs/pull/892/head\n004066665868beeb7f8440dcfa44382a55feeea92abd refs/pull/893/head\n0040fa3ba07cecc8904bbdfa869f36f96fd20dafab9c refs/pull/894/head\n004094e7839eb50b5c4f7a1f7b9186b0635e76b89044 refs/pull/895/head\n004042fde53f7fa32eeb6e181d4c44d40b260cfd0b37 refs/pull/896/head\n0040efcfabc77bf51bcfc988608415855110a38d46c8 refs/pull/897/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/898/head\n003f9a1caa6ba84b07b5d56ec3a257e0d4b3234e3c9d refs/pull/90/head\n0040001c99ad363d4c73a0ed2b41a42ef077aa55b908 refs/pull/900/head\n0040743f5f6983b2cf9c209054ddc2bfd073b823e057 refs/pull/901/head\n004062106593de05aebbf1b33e6b55a74249475c81c3 refs/pull/902/head\n0040fa0ab05f34df3053213d9fd2edb5f491372179ec refs/pull/903/head\n0040e482d41641eea8b783edc0f72a83d14335fc4dfb refs/pull/904/head\n0040722ae5807ce8fc540b6e968f65892cb50a5486d4 refs/pull/905/head\n0040984b61467f9613dcc89cca99a6aa5b528db87021 refs/pull/906/head\n004056ab40c293c02a6027ffc9f774016597eaf96b4f refs/pull/907/head\n0040f14aa2b05dc4e742820ca6fd80192b4616195f5f refs/pull/908/head\n0040e3e7b64a3d547fc5a124a77632621749b645f760 refs/pull/909/head\n0040be090e198b6a9d5c5d2572b4298aba6cc26e6bff refs/pull/911/head\n0040d2072e429e9b43577f629099bffd60cfb2589daa refs/pull/912/head\n00403c6c38ad7d4095ce89cb7c6a3ef6d75d8ffd3b7b refs/pull/918/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/919/head\n003f8c665f9bb94f9aca5ff50341e2830cd8a0d52e15 refs/pull/92/head\n0040a51f2e8d03985c7c8bc80b8f3ea4eaf8e5c6ba19 refs/pull/920/head\n0040a89d7976562683919cfddfa363e94efc366ff859 refs/pull/923/head\n004005c9d84d00d53ee8a981e4e215bdc83e9bb22b9f refs/pull/926/head\n004052f5e5412de74d5941e4e511729d1aa9d861c025 refs/pull/927/head\n0040f686754f9c56a7a9261a7b5928c7965201fd5cb0 refs/pull/928/head\n0040e5dac1059eab97466af6c4ca47956fac9b3e24d7 refs/pull/929/head\n004012e841e3603fa5f254038030f5aa3b7977185358 refs/pull/930/head\n00401d48fb2720eb8713115d1266eb9452977b58326f refs/pull/932/head\n004032963c33409075798c3a105cac04d5553ea13102 refs/pull/933/head\n0040d0f4650818b34f9be70b6513998ae84b2c6246c2 refs/pull/934/head\n0040a102582671179e3217c102f23f1d8a04f3edb485 refs/pull/935/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/936/head\n0040e27740039e8bd36e32d2c5d754e6c92c86c5f963 refs/pull/937/head\n0040c4ffa47ff7011b495a146bbaff01b31514b9ee04 refs/pull/938/head\n0040c132a552e0795263438df99eef3b2c4632c93d32 refs/pull/939/head\n003f013774b69b995be5744bd49e0232f3dec0b2a93b refs/pull/94/head\n004077c08a2ab0157524ed6a086006fef76ba4bfb260 refs/pull/940/head\n0040f8d712a563c02e6f3a37702b9f0896fb5f5ef061 refs/pull/941/head\n004098c56e29f1f275209a0d1055d59f70d2a9876a55 refs/pull/942/head\n0040f89731a864346dd51cb1722d1c69d04211c1d485 refs/pull/943/head\n004078fe74df59864017f89cc065bf1e284fbdd5b9cf refs/pull/944/head\n0040dcf3bc2fa1c683634031fb99bff85a33b3010d6a refs/pull/945/head\n004002ada34bea2919fd82260a88a4d0183e32ff4481 refs/pull/946/head\n00407bdd987696b6b35402e77bb0d377cc758f1bf08b refs/pull/947/head\n004007f48ad4782a90046362ad2f15272ee8d6a758bd refs/pull/948/head\n0040c8ebb9c137eb5030bb9f016febe729faa44b39d6 refs/pull/950/head\n00400ddcb393a921f24989318b97b273493d6ead5e3b refs/pull/951/head\n0040eb14d7d144fcc50e521e7c1b42bb666cda0342d6 refs/pull/953/head\n00401b192c378638f9ca47933864d7c221c13391953a refs/pull/954/head\n0040dc08833463c8a6f5c481b525336965481c7e862a refs/pull/955/head\n004046442d0167b0a3eb233796737add2044e5fcee24 refs/pull/956/head\n0040c1beb099fc399ac9bcbbfcaaea445f22d8ae291b refs/pull/957/head\n0040856e26ad1856e68df26e320e8b26766cbc069eed refs/pull/958/head\n004081757df8bf740d6115044ed7be6851a2263fd4c1 refs/pull/959/head\n004061c3abfb301bb6cbfa7609bc10073cad7f1877fa refs/pull/960/head\n0040f472991d4e3bab100a51f00fb39e82a53ebb2c1e refs/pull/961/head\n004009be902bbf925a84c492a353cacd4ea2bc08ef86 refs/pull/962/head\n0040ce718f77c0d6abd993f325626f7371af8af8f818 refs/pull/963/head\n0040a2975709e828fd220c3f34427fdf7b862446921f refs/pull/964/head\n004014da5f6cd993f00995406252c89d021f3b296161 refs/pull/966/head\n0040569e876fce72a7833687aee4bc4f75e73a123113 refs/pull/967/head\n0040533b32d9ac759d1f09d4c7aae5d47615615d9ab9 refs/pull/968/head\n00403636cba6d472a7a5f2f2e772d1152cb8d4d466a0 refs/pull/969/head\n0040686ae85680cb92107a2951849312ef7d449baa58 refs/pull/970/head\n004079f4e14dc8f1c22c606c53dfdacfffa9ec09243c refs/pull/971/head\n0040ce3f784c8c3bb317686ebe242a40ed208281b2ce refs/pull/972/head\n0040ee82da89955148e0f441ef92812f89a43407b945 refs/pull/973/head\n00406f96ecb86ee791b6a76152fab22ebf7918149a04 refs/pull/974/head\n0040b498309092685b6ba33e77c2ea547f7937a54d97 refs/pull/977/head\n00409ecc534fa7187aba7b569abee15bb34b228c6edb refs/pull/978/head\n00404793a46e88f1bbce733c30de062dac6c6a733e41 refs/pull/979/head\n003f7c6f3235fdf07c5112acc071842bad7f18d99df0 refs/pull/98/head\n004003a4545113b883c75a0ca7b2da43b5aa8e44f22c refs/pull/980/head\n004064ea62fdd701be13d140f23585fc684bcff8bda4 refs/pull/981/head\n00404d21a6ee70683d43a9ea02f30241fc7e5de1dc75 refs/pull/982/head\n00407f59b2e565a976f52d2da4a66dc7fb618455ee4c refs/pull/983/head\n00405e2b50db94c7407daee033fe3686e611228ce7b9 refs/pull/984/head\n00408d65fe5f4e56555fcc229fd3be617abc28a43f4c refs/pull/985/head\n004042cfeab1cc55bc73aff5d8171013f16d6a5ecfa5 refs/pull/986/head\n0040db1edfb78e883c898207fdeedec21d7175cd877d refs/pull/987/head\n004068d4dd170aa98cba54eb23e3bd8a43eb112ca5be refs/pull/988/head\n003f134098bf54a9a1f2cbeed7c6f31661e09381070c refs/pull/99/head\n00406229b7a8bd02bfc1f3f714d0450b4123cf89a590 refs/pull/990/head\n004013a3ba837c44252f71c4b3160a19839a16e4fffe refs/pull/992/head\n00405f2db79242337a5d213db9fd6dd521f7794a7d00 refs/pull/993/head\n00408ce1a31e0f5e0a74a28aaa56c8daaa50e21d63ca refs/pull/994/head\n004010c35fdd46012cb957bab469cdded2e58292b198 refs/pull/995/head\n00407c61c0b7caf4705942588301c01b6e9cce7300d9 refs/pull/996/head\n0040dec0a1617e15bb1a2fc89a03ccaaf8806f38a546 refs/pull/997/head\n0040caea5c733154add2b3e83876f04ac455326855ad refs/pull/998/head\n003e194c5efcaed9fed321ba2123745f78827a3eea03 refs/tags/v0.1.0\n0041f3d3ef027896e318b099764bc855062821e1de53 refs/tags/v0.1.0^{}\n003e4a24731816a98853c8b30196635586fa65fe3cfc refs/tags/v0.1.1\n00414057e201dfa8b58656e84789a726919098061025 refs/tags/v0.1.1^{}\n003e0014eb08b942762f103c967e587f9bba6f91fc53 refs/tags/v0.1.2\n003e1ef42d0bd5a7da2b93fb3b3b80b0f8fea50e7600 refs/tags/v1.0.0\n0041c6ed0fabdbe8ad75465bd7eab81ba904a9c89f42 refs/tags/v1.0.0^{}\n003eac28fb90a951fe0a334e8ea974cb9d0830f8acb9 refs/tags/v1.0.1\n003ee20621776bbd2e799537eb3b0328398ccd5e9fdb refs/tags/v1.0.2\n003ea6c6cd756e0cf4fd858398976208145cb23e707b refs/tags/v1.1.0\n003eb33258df779c4cf0fe02961874dfb1bec16080f5 refs/tags/v1.2.0\n00419647b493034ab334e071921becde06bad8de059e refs/tags/v1.2.0^{}\n003ecfe6d7502821f60c09be0f6de2548ac952b01696 refs/tags/v1.3.0\n003e7c08000dc3a0b1a690d46f70fa97b3fd87cb926b refs/tags/v1.3.1\n003ec6d02d122f65ce3550eb002e4cbff6f1307aaa6a refs/tags/v1.3.2\n003edbeaddee112d005d950988cf07c09d91a4966fa8 refs/tags/v1.3.3\n003eb5af6c719caf8f4e51b3195039a7de926a0066eb refs/tags/v1.3.4\n003e62df1c5366410936e29a986e73362afc9f3a5cb7 refs/tags/v1.3.5\n003eb5f7502d2b76b1b84201937aa759299d23e02c48 refs/tags/v1.3.6\n003e51fc4fd651c23e5c7e209db1fcc8d6ed68d07789 refs/tags/v1.4.0\n003ec50977954ca3d2cc4cf37c52d2dec3e75a97b7a5 refs/tags/v1.4.1\n003e137255296e89d6baa9df9c7f7e950a28c1db5c74 refs/tags/v1.4.2\n003e6316373e47d7e3e4b4fd3630c4bbc10987738de6 refs/tags/v1.4.3\n003e060799ca816dfa40afa05e48c895c0c9fd79b90b refs/tags/v1.5.0\n003e114c256d14e094ec5874cd9d14d03d27c4086b90 refs/tags/v1.6.0\n0044fa8e74ec2517b1bb371b4e7c739fe1efa4175532 refs/tags/v1.6.0-alpha\n0045cb3eeb25026a6da102d2f2835af053c48c55a901 refs/tags/v1.6.0-alpha2\n0045f6b044300bf29d0b7ea3cc036715e6fc32ecf134 refs/tags/v1.6.0-alpha3\n003ef6b044300bf29d0b7ea3cc036715e6fc32ecf134 refs/tags/v1.6.1\n003e5b4066c7351b045a433b1fe3554260c6f06b7237 refs/tags/v1.6.2\n003e037c3543ac60359190459b10fbb5331568b4c8f5 refs/tags/v1.7.0\n003e43dda7afea9d267f5d448709e75e2ae7147c29d4 refs/tags/v1.7.1\n003e032296dfeda9ceef9fc46ffba9d032cc52f3428a refs/tags/v1.7.2\n003e645d5b0bb9c14741b2147a5305b684e4abc039e0 refs/tags/v1.7.3\n003ed4657bf46aea52834c5148b25fb6cab132c69af5 refs/tags/v1.7.4\n003e2d1181a69fdf3263083dd8e3c7ae0feceae859fb refs/tags/v1.8.0\n003e46aee59befed6edb5fc737ef35b5febf987cffa9 refs/tags/v1.8.1\n003e1ea785e56de9f7817c57266025f0a56279141053 refs/tags/v1.8.2\n003e18ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/tags/v1.8.3\n003e4a318af4a84899723625da2927c30fcfb7247126 refs/tags/v1.8.4\n003e6f61445b22e99d3a0a3ffb5dad7b723a9fa84964 refs/tags/v1.8.5\n003e1386406b64edd4544696183f273139ef9298f5df refs/tags/v1.9.0\n003eb13f37e1a1e4cb98556c1d34cd3256a876929be1 refs/tags/v1.9.1\n003e1e295ee11c5e107886e58bacb04228325082146f refs/tags/v1.9.2\n003e0e986b49c4e7ee5aa545531c4a8908455f8a9e82 refs/tags/v2.0.0\n00442821e79ec1d938ddeab00522619c3a67520f6c56 refs/tags/v2.0.0-beta1\n004429aaf53c46427b2fde72f7aa7a62992dfad0e9be refs/tags/v2.0.0-beta2\n0042baab0d06596a51f593aeefcbf089527f2d3e194a refs/tags/v2.0.0-rc1\n003ebe9015f3256940e63d99b9d1a009f99c7dc4d8ec refs/tags/v2.0.1\n003ea2a23858b9650035f019219937f91ae615474b4d refs/tags/v2.0.2\n003e4f77b30556bb6d171b5d55f01da4fb0261b9da7d refs/tags/v2.0.3\n0000" - headers: - Cache-Control: - - no-cache, max-age=0, must-revalidate - Content-Security-Policy: - - default-src 'none'; sandbox - Content-Type: - - application/x-git-upload-pack-advertisement - Date: - - Mon, 07 Jul 2025 03:38:52 GMT - Expires: - - Fri, 01 Jan 1980 00:00:00 GMT - Pragma: - - no-cache - Server: - - GitHub-Babel/3.0 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Vary: - - Accept-Encoding - X-Frame-Options: - - DENY - X-Github-Request-Id: - - 4439:145DD2:22D1DF:2751D1:686B414C - status: 200 OK - code: 200 - duration: 331.568748ms diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_existing_cache.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_existing_cache.yaml deleted file mode 100644 index 22982c4648e..00000000000 --- a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_existing_cache.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -version: 2 -interactions: - - id: 0 - request: - proto: HTTP/1.1 - proto_major: 1 - proto_minor: 1 - content_length: 0 - host: github.com - form: - service: - - git-upload-pack - headers: - Accept: - - '*/*' - Host: - - github.com - User-Agent: - - go-git/5.x - url: https://github.com/google/osv-scanner/info/refs?service=git-upload-pack - method: GET - response: - proto: HTTP/2.0 - proto_major: 2 - proto_minor: 0 - content_length: -1 - body: "001e# service=git-upload-pack\n000001534f1b54bd015c6c672754edf83aaa901689eb57dd HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/main filter object-format=sha1 agent=git/github-e744e5203bf9\n003d82aefd395a8e152af10720b59a606b34ffe1174b refs/heads/docs\n003d4f1b54bd015c6c672754edf83aaa901689eb57dd refs/heads/main\n005090966848c36befc986cf48f30a3fa0672197bc8a refs/heads/patch-test-cov-workflow\n003bb37c83e19af3b2555864457cbd0b08ef0e1f9d7d refs/heads/v1\n003b459ca69939984dc05f15b77720aa81c672aeb5cc refs/heads/v2\n0045e07bdda0f37bd741579e46be40608c65ef8fdd44 refs/heads/v2.0.3-patch\n003edeb877d9e9e5903ded7f86130ee8a2bba1de9418 refs/pull/1/head\n0040a391f89e35b799e631596eabd6e99bd7c37ff359 refs/pull/100/head\n0041f25ebde349d6906ffcd1c9e313752af4c79ecf9c refs/pull/1000/head\n0041bc649da1efe99e7fb302734ec09b611be08348c8 refs/pull/1001/head\n0041dc901f4adfb43f11a97d6fa23842cc6823badaf8 refs/pull/1002/head\n00410c3e76fa4abb53b25c79c75697bb87feccd7f457 refs/pull/1003/head\n004154dcc5a31c3a5b3377f96ae3275d925ee3e9773e refs/pull/1004/head\n00418a1fe256d51dd585ee6dbb2cc966006ff6fb269c refs/pull/1006/head\n004179066e42fee756592da5e477cead1980ec71e34c refs/pull/1007/head\n0041edc44a752b9f9c77ae66ae40ab6fd4d03912672d refs/pull/1008/head\n00416d68a3cd1382a7657f8aba1d743b9e83f18c37db refs/pull/1011/head\n004117ba4664d930f16611e16f760f4279926a6ee4e7 refs/pull/1012/head\n0041eff3a57bfef84a0073b23f7b3990d362afc01c32 refs/pull/1014/head\n00412faec986b74428dbe627f303f4628d25added7e4 refs/pull/1016/head\n004173511f772e1ef2513cbee2f43e3f90600c70434e refs/pull/1017/head\n0041cad99c794525888aede11f92bd936266d05da8a4 refs/pull/1018/head\n0041405facd57b0611263bf05dac83cb4990bc971216 refs/pull/1019/head\n0041e8d4ea7d464cf0e5b32ea1405d031da735852ec9 refs/pull/1020/head\n0041979d2e0004a583bb9a824fb410cf1711a00b641e refs/pull/1022/head\n0041dada9e1f5ca1059abe5d9d176fd2f52a5b880262 refs/pull/1023/head\n00413a1ff30b56ba73b533a7378e57a654dec8aef3f3 refs/pull/1024/head\n00413891cbc53e370d203ccfa25711bf3d22830bc5d4 refs/pull/1025/head\n0041cf8acae39de43327b99c0464783030b3d8de01af refs/pull/1027/head\n004187ce5b1985c1abcaa7337941d0629fc2013c2dff refs/pull/1028/head\n004183ac4f1b7af1d5b3080b5587dd1027cebd1ac4af refs/pull/1029/head\n0040cd6eb8b02933f1c515f22b22d4d60196643ed010 refs/pull/103/head\n004145c69a08c7cb8b9ad5f49de049832662d7fb5596 refs/pull/1030/head\n004139a4a43e9d686194f8bf87b22640275d6898c974 refs/pull/1032/head\n00413efc13fe91382e13a7fa7db33f56d5af24901dd8 refs/pull/1033/head\n0041134ba91d1941c3e8ddb248bdf4877f0948f9b8da refs/pull/1034/head\n00418813d5c1faf2c1b8ac8332b273dee3d98996f77d refs/pull/1035/head\n0041dd87a911bb12a08155f40f7cd080271d7d858cec refs/pull/1036/head\n004165099131e8430832af0e4b688e92fe99857845df refs/pull/1037/head\n00412e72de2d7278cddbec0b02f917ddb3e4fa623d78 refs/pull/1038/head\n0041d9b037c52a95370872c2b639e14496380145bf78 refs/pull/1039/head\n0040bce873c632b00bb26ffb04ca5b56512c5cc588cd refs/pull/104/head\n0041c815f92e90a158bf0f98819d98fc95298d4c702d refs/pull/1040/head\n0041f0a5b399fca77336169a5099122c1c3f6d9786e8 refs/pull/1041/head\n0041c571e7a1999d00ec8e73bac96319119912fcc651 refs/pull/1042/head\n0041445b082f8fb17498523aa22e464eb06d9205fd8b refs/pull/1043/head\n00418959bc2922ff35886b6c37475e42be966a2ad2d0 refs/pull/1044/head\n0041d133fffb1223c353fe853c7288c335f459a79cf5 refs/pull/1046/head\n00414bfcfd8d45552a0558081ecee29cf0130030c101 refs/pull/1047/head\n004173e259495b1b59c248a95506a7dbc8169f60a672 refs/pull/1049/head\n0041e4a30c0b4730b816b4a64256a68ea9e6a78b227e refs/pull/1050/head\n00411787268638442da07a0da0d6959db2ab8360da7d refs/pull/1051/head\n0041b6c00baad38ff80c547805986fa472ac6a931ec7 refs/pull/1052/head\n004145b3e221b39c4045d7754cd2830461b4bbc19fb9 refs/pull/1054/head\n00418a4f3424be29d100df9d16ab6af7bd60e8d921fa refs/pull/1055/head\n0041e52a74fe02f13e4c49ce4a95a7be9df1b146066d refs/pull/1056/head\n004146aee59befed6edb5fc737ef35b5febf987cffa9 refs/pull/1057/head\n00417db4dc3cc71f2c7188b8e7ff40187ff6ce0976e5 refs/pull/1058/head\n004002f2d3a1541918e91bb634c093a8f588b5f724e1 refs/pull/106/head\n00414418e85c4c0ede19fde83af9047ab74455f29ce5 refs/pull/1061/head\n00416630c39aa158eddae0abf9ff3e6d560dfec800cc refs/pull/1062/head\n004103558e2672a2d500a64621ef829828462475077a refs/pull/1063/head\n00412d316b735abbc0533d73e7fb5cd36530803d6075 refs/pull/1064/head\n00411e6c0cf8e25d4ec983ff9e116ca9fe5b4051284b refs/pull/1065/head\n0041e7b146c4dbfc2461e161366f39bf57359b41473e refs/pull/1066/head\n0041f94fedc0ffd685597f21cc132b08807bc4a2bc8c refs/pull/1067/head\n004130165312de801e22db722999e2e31b1c0ab872e4 refs/pull/1068/head\n0041f45c37d02b1237018b424da7644e745b3ae4fa29 refs/pull/1069/head\n0040417538354a2d1b8206b21047463195d0e63833ec refs/pull/107/head\n0041f5e15c258ebd6d3b899da8376d85b34e5fdc5322 refs/pull/1071/head\n0041e6b1130d37421c1750d6aadcafd622dac4f1bd22 refs/pull/1072/head\n0041ff3dcbdb5eece230a9e76ce516c33b7028ebbc8c refs/pull/1073/head\n0041c42a060ca4e670c5f6eead047788d3ba66a624f6 refs/pull/1074/head\n0041abf8f3732189338b9ec6dd0849157c8f012c10a5 refs/pull/1076/head\n004154b4c20f39be518c9564320befba3a752c955a95 refs/pull/1078/head\n004131949d5ee53fe01aab33b186cbad32fbf2d3d1d7 refs/pull/1079/head\n00402dbccfcf4113d7c6981274155e5c7c242c4c8b23 refs/pull/108/head\n004101c0329ad2aa6b7de43c15645f2581b7ef8c690f refs/pull/1080/head\n00414ed4f57bd8d1e7ad8e9007f756bfca75ed99c6ab refs/pull/1081/head\n0041934e83b6c18732e939343be1f6d63ee994816992 refs/pull/1082/head\n0041292bde6461c6674545d6249e58d33650ca3f103e refs/pull/1083/head\n00411a86cd77b171c6eca9f241f4b56f9d2e02e847e5 refs/pull/1084/head\n0041a566698126749fc1de5d522e495adfed74aa63e7 refs/pull/1085/head\n0041b54b8568f1ba511b7680276e3890e9159bb9de16 refs/pull/1086/head\n004186bff5bb894d8e940f35631034a46c277caad53b refs/pull/1087/head\n0041e161a918a5dc08c87139f0f953c63191535309c0 refs/pull/1088/head\n00412130913b3113688700c8a1c214df29354b6544b0 refs/pull/1089/head\n0040efe52963c923ec97ec0e7f823d70519f8afc1301 refs/pull/109/head\n004143a04e48ed25e86d2925774e79ae6e4bc8c6c9e5 refs/pull/1091/head\n0041d3e51e01080d1940692e104bc514733365ea5eb7 refs/pull/1092/head\n0041dff227a1d460cf02cfd3650019b5dd8b0691abc6 refs/pull/1093/head\n00411c07b6a25dd94d49cc0679815e0aa4aeb3a61c96 refs/pull/1094/head\n0041409562060f908ac5f94b44ac0e68aab0f7d52d6e refs/pull/1096/head\n00412b8500391d3df93895706a61043d579e93f53b8d refs/pull/1099/head\n0041aba467c89fb866c51401ff528011689ad768f997 refs/pull/1100/head\n00414d7d179410b09c4594e9c52f7748b079f1bcc89e refs/pull/1101/head\n004138ce57ecd457248e9f11698c72770e9b239741b3 refs/pull/1102/head\n0041c37ab03ea07ff99b1f9af69ef47795cf82c58efd refs/pull/1103/head\n0041063d02a9ed36e7fce9ce3e4f55a310e580da3eba refs/pull/1104/head\n00417177faac71408a3f64973600dd927dff7daa9e7f refs/pull/1105/head\n0041865580eed5d1c65cd617cb05df1b95a80d6f6475 refs/pull/1106/head\n004121070112f28273b4a0e89e08477bd17cfef64355 refs/pull/1107/head\n004163bbf6482bb377b05f9d620ec10ab67c69e244e3 refs/pull/1108/head\n004137a2bfac38496527284133c9b90a9355c93904a1 refs/pull/1109/head\n00418fa27e18df788fdcb00229a7c9a2e02bfe085391 refs/pull/1110/head\n0041c6a342e088c30f21a12044ff42783b5de893ee8f refs/pull/1112/head\n0041bb3976c6735daeceeb96a1461695498d09b92ab1 refs/pull/1113/head\n00418dfb55a6c6a406da3c244783c6e4df7167f8ff9d refs/pull/1114/head\n0041b86b180baeceffbdadaadda02d7dfd51f14fa8de refs/pull/1116/head\n00416ec43bb6687374b8885a6af623e2d4159d74b133 refs/pull/1117/head\n0041e47cf0488f5bd1c156207a17cb2a63332f8c5465 refs/pull/1119/head\n004160d00a1b00d179d5e62b607ad689b81603e8cfb3 refs/pull/1120/head\n0041be4c1511cb9945992ae27ae2ca99a94565aea784 refs/pull/1125/head\n00410aed4352dd2d7fa9eb1be6d623ee875a34c53b4d refs/pull/1126/head\n0041fc7c97dd30f370c79289394eb2c4e2750c9be1c0 refs/pull/1130/head\n0041082984133361132f3b7da7deb989c659e7844359 refs/pull/1131/head\n0041888d30a834cb5872216577da5926f887a2575bb5 refs/pull/1132/head\n004141aca0b4cf0c7f836d2023c26eed5e5fce1f29a4 refs/pull/1133/head\n004103f9a9e28f9121df58c689983b2d69364b54fef8 refs/pull/1134/head\n0041d0038e926e44873980f77566bfdfa2ced2ed04fa refs/pull/1135/head\n0041cfe2c22993c301b2adec721af28530c666fb7b42 refs/pull/1136/head\n00410dbc58619c0809668be780f04a9034490e43f18c refs/pull/1139/head\n0041b3846b125c6c2b4746124144bec86168d8728389 refs/pull/1140/head\n00418b0043f2bb68c82968c4faef65936e1ef319ad1d refs/pull/1142/head\n00415a560fdcc101de924791d1d134ca283bf1610280 refs/pull/1143/head\n0041951ee1cbcc4dc717146491707e6af74f90cfc1c3 refs/pull/1144/head\n004167a68f7c044ebc003d9676dd582ac8c03ea46015 refs/pull/1145/head\n0041e4b00eb8b0e455bf7b299e11a53870403401d15e refs/pull/1146/head\n00417a633fbcff3a162b1f8a5856671d0316de356052 refs/pull/1147/head\n0041c9147b953308f3843c53442a1c17aa36934611fd refs/pull/1148/head\n0041af9d4d8cf408ac7a7d3b9f065173efadfc05ce93 refs/pull/1149/head\n004118ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/pull/1150/head\n00419ed7e6a4606b6f56c867ca0122df3fc3b43cf15e refs/pull/1151/head\n0041b29e4f2d7853e4b8635e885fd5717396922c5800 refs/pull/1152/head\n0041049cae20632df72010d0152ad145fe2c53c0ea7a refs/pull/1153/head\n0041f5748b91249cd51f64ce6024c93e564d36da7660 refs/pull/1154/head\n0041bbe8e0dfd255daa91a917159978ae5eafb0e84ef refs/pull/1156/head\n00413626dc731e649f2c663e2e60000875ef5eecedb1 refs/pull/1157/head\n00416c04fc849888eb29dc0e4261438190aa3694c1ec refs/pull/1158/head\n0041a519b872414443e8156dc4d10f21a4117b564458 refs/pull/1159/head\n00400eeb975ae48214001e9941825c9a749b1c7d391e refs/pull/116/head\n004183fcad5bfc1ee90a46b5d9d5dbcf0e5e9ae8dc0a refs/pull/1160/head\n004192c034b24ad6572c1fff1bf0f0d446a8a5cb5eae refs/pull/1161/head\n0041cbe5f793ac2d9849e408f2ba0855af7f2dd8c0f8 refs/pull/1162/head\n00416ddbf9c9fa623fa7e882bce8137e95c5407cd79b refs/pull/1163/head\n00417c216e1be51960819f1c68c490bb2405d09a8236 refs/pull/1164/head\n00417d1ddb86ca16b3a2f949735d4e45057eb6f04804 refs/pull/1165/head\n00413222d5c3516ce1a96b0ac746d54ee9f8e80272fb refs/pull/1166/head\n00418617d676df88783fc65bd20489ca97200953f506 refs/pull/1167/head\n004164629568f9b9eb49f02b67527bb1624ab92494a4 refs/pull/1168/head\n004140a413bef66c53b2d6a1479b4753605744368b57 refs/pull/1171/head\n00410fd65ae3d1bf6e20ea905918e19713f3de62abe0 refs/pull/1172/head\n004192c034b24ad6572c1fff1bf0f0d446a8a5cb5eae refs/pull/1173/head\n0041cbe5f793ac2d9849e408f2ba0855af7f2dd8c0f8 refs/pull/1174/head\n0041cae28fde3b0739a2f25d99a99c98818f47d3e2bf refs/pull/1175/head\n004117d5536fe26f0bbecbf4a29d362c656971a8d9a1 refs/pull/1176/head\n0041ad1587210218e118ddcd6761e8e4cbc75480d2e6 refs/pull/1178/head\n0040a8afeba5d2335ebc47468154d19dff204ad9b613 refs/pull/118/head\n0041c463e1a594ae0ae9b513c8906334e998927101d3 refs/pull/1180/head\n00418c91a9ef4069448fda215afc0a691fa38316412c refs/pull/1181/head\n00417a847927be170a2deb2e5e2a945f8ccf98f91c14 refs/pull/1182/head\n004103488b1640bf60069e01fac924e97d2574490b6e refs/pull/1185/head\n0041545511100a9da8f5f5960c85ff178dd0369234bd refs/pull/1186/head\n0041e65d709f34eea3aef2269027c591016db5ab107c refs/pull/1187/head\n0041ffef0e2264e4e6d00639a385fa8dcd54e1b4ed37 refs/pull/1188/head\n0041c15d0948990b83575c8185df109ee78a9eca53a8 refs/pull/1189/head\n00419d9a7feafeef27bd32f7953aacec878951803197 refs/pull/1190/head\n0041eee13d0b2da6c19ef6081b7f1783f8e94625115a refs/pull/1191/head\n0041e79c7e2ab11ddacfe9ec48ceb558f0e296838f44 refs/pull/1192/head\n004184fd6e653a980da668b156b5deee26be0e0967ec refs/pull/1193/head\n004139b28f6c60a48fd0da014f7f121df58dde003ff3 refs/pull/1194/head\n0041d3e93e6be83f109e267661ac2aa4b0e3f14a59d8 refs/pull/1195/head\n0041dd4eef1324058fbbe9944909f8f0313617937195 refs/pull/1196/head\n004181e79baae5d66cd9155f46aafbbd56f0211c6aad refs/pull/1197/head\n004118ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/pull/1198/head\n0041ea17adac1c68c8ba7a04416828ab43e325e129cc refs/pull/1199/head\n004050b255408f4f5f98782027a92625ac97efeb8a0f refs/pull/120/head\n00416572931823db1ffb300832370b5db278e087b747 refs/pull/1200/head\n0041ada41b5104beb670322d7ae4a3ba8cf74daf59b4 refs/pull/1201/head\n0041d5330143583beaa96a58e452d72ced83785b5214 refs/pull/1202/head\n004169c1f7bda71f8c29f9fecc385cb65f04cea7693f refs/pull/1204/head\n00411338171fd1c8f545788fe4c14223c94e32443c2a refs/pull/1205/head\n0041f4f08a3b51ac6a60d087c150a5536dd749c01ca6 refs/pull/1206/head\n0041fb08aec4cc27297c2341d8c525b5639f366d7271 refs/pull/1207/head\n0041d39c1c9ed3e6c660d16d66f5f2864c51b74e435d refs/pull/1209/head\n00408a9fceb768f58ef0d65e70a8c9148acc58f55c66 refs/pull/121/head\n00416200dbfb1e586f702433384fc9462c95eed6f795 refs/pull/1210/head\n00417a5ed553932174c0207cfd68a0ce47ca853ef87b refs/pull/1212/head\n0041b8f620908376460ab72847f2fc73e4971df04978 refs/pull/1214/head\n0041f63802d0c7fb90a1c453dfa5d0530a1080d86521 refs/pull/1216/head\n0041ea257edd99d727d70cbafb56094a2eceacecb0bc refs/pull/1217/head\n00416adf5b9ea0eed8c8ff4340002472a6b53220edc5 refs/pull/1218/head\n00412a11fb082ce7cf96848f083c65002a51f3e54617 refs/pull/1219/head\n00416eccd998bbf7a3379a89732a9151ea7ee7222da9 refs/pull/1222/head\n00410c6554d500e645c78c9841cf00362ceba24cfc09 refs/pull/1223/head\n0041a291568e23fcbdecc4fdf5a57e81675eb1e3ac8d refs/pull/1224/head\n0041e9ae9d8fd4b97eccf2834983057a753a6efe9624 refs/pull/1225/head\n0041e2f771ca6d18fdf5282b4b9c3d48ae697c231495 refs/pull/1228/head\n0041315d44f6684182e6ef4d13940b10da4982dfdf11 refs/pull/1230/head\n0041534fe4077f8cbffcb48612a8db6cf58fb619270b refs/pull/1231/head\n00412f25c0586f675337030648e460da55393623f98b refs/pull/1232/head\n00418669c5b02dce839f4cce3ba83641c1f23a6d600a refs/pull/1233/head\n004108737789cf3c1f5cfc7afb96fb3c521758f6c36a refs/pull/1234/head\n0041ac050307e5c0cc6d7347bbfbd3c315c2a37b6ed5 refs/pull/1235/head\n0041225c71adeb9b8fb85b8e38a59706b5f52289a038 refs/pull/1236/head\n0041b38d9be3031e82a6b0f0d03b771e76c2c6602e4c refs/pull/1237/head\n00410167354914b745a448bd1f49cfc003eeb03c41c5 refs/pull/1241/head\n00412236e21a96f17837f3813f95000390169364eb63 refs/pull/1242/head\n00414703d2ad140205d31f89bf6260db52c52aa38e85 refs/pull/1243/head\n00414383f8580dfe6625844aa7d4c64e7d989c2ee72a refs/pull/1245/head\n0041ac8bfefb6bc528d158a5bb2efd1ddd09f9d59fdf refs/pull/1246/head\n0041f0b5858d6155b2bbd492d38bcc76bc4a9f34921b refs/pull/1247/head\n0041475fdc44fa132bf5590b9d1ccea658ce6a28f09e refs/pull/1248/head\n004172f897a002198a41584f38600d16485e524dd07d refs/pull/1249/head\n00406a07233ef752078d694abbd60cdde844e1674caf refs/pull/125/head\n004183ecc28c123d1c718b4c0a9687155f114fc38e9e refs/pull/1250/head\n004157b6ffc3a322ac6916e83cb3193698aa1befaf57 refs/pull/1251/head\n0041f88f82ee8505c4c94bdf75f0deea320af8866689 refs/pull/1252/head\n004180c6f8fda395d0fd8ca3de9f3d5d68cee2ba79d3 refs/pull/1253/head\n0041a1cf3cc412d127a44f8b99e23ec74d3480f56d1c refs/pull/1254/head\n004175c953aaf4439439a7502b427d6b38683c5281dd refs/pull/1255/head\n0041de528bfcfc8bfe071ba0c947e2c11f2c79e2c0f1 refs/pull/1256/head\n004196505fb6b2261b20dae04c55c0a379ea13eb34a5 refs/pull/1258/head\n004191f842d6286dfa26be459843312d62d4e8f7433d refs/pull/1259/head\n0041710aa96e02cf952b35210ea5f899a5fd0e7b8d0c refs/pull/1262/head\n00416e65903bcad7e04e514def27218793c53b1e69d8 refs/pull/1263/head\n0041bd8b8cb78af26a197641a82ae6c115185b96fd4a refs/pull/1264/head\n0041b6282b1fb7835f6f6080a0940f48b41168a8c919 refs/pull/1265/head\n004110ac754b3f2626cc391d7d97f1dc08eb52579eae refs/pull/1267/head\n00418da891eea0e42399a9f899fd8152f33b13b24f00 refs/pull/1268/head\n00401a0a14ce657c6a734ff5b06c81bbdc5277f3eeac refs/pull/127/head\n004163069536655b236a1525dc8bba8a27058fd55909 refs/pull/1270/head\n00417c1f0ad35f808287d2178468670fe058c4e4a6c3 refs/pull/1271/head\n0041b3c382937944a2d89d570c5c9716bafa864d8367 refs/pull/1272/head\n0041235e651de40e076d797c5106c6d47a0bb650f9d8 refs/pull/1276/head\n00413b683d9751c80c079c1e0e825b1a8c9af6ee2b86 refs/pull/1278/head\n0041c04e4c32b9081366ff01f5ac5af7eabfa87d3567 refs/pull/1279/head\n0040a3aa0190ec02fb50a9dc0ca3caa1e16d3551c197 refs/pull/128/head\n004108fba240eeebe70947595650002dcd5284c75e02 refs/pull/1281/head\n0041ebbef8dd520d32bae9adbff1a7b9afd5c297f137 refs/pull/1282/head\n0041462044a0aff0ab62614a85494ae5abcc6ce8f383 refs/pull/1283/head\n0041818ff67309775befc7321334b19244d20eb5ad06 refs/pull/1284/head\n0041b7b439cd14315139a6cff36df561c44b04b48c28 refs/pull/1285/head\n0041b0295ef926958d7b55e81c37de0c30ba067ae9ec refs/pull/1286/head\n004167d190b2d6f2a2ea4010416a8782e77a84944591 refs/pull/1288/head\n0041b0ad3a3c2352b4c9109ad238492e5a46ff318e37 refs/pull/1289/head\n0040217d6ec0d38cb8e49bbc0db6f3163003185cbabd refs/pull/129/head\n004177c1b1512bd9964011504bfd68e38953ae8fb04b refs/pull/1290/head\n0041a9e187010bda994c39a689d9fac4c62e8dff8e4e refs/pull/1292/head\n0041c8293cfa71f6e1a3f116036d6f414934f27dbf45 refs/pull/1294/head\n00417252d799111d4e456a0e4791055759210c19cc5a refs/pull/1296/head\n004164121e70812cb3bbacbc05660f7c6b32a380b37f refs/pull/1297/head\n004069f3513b4283e207b7456f5c97c3965bdcdcea0d refs/pull/130/head\n0041e9d6af87cf13d39f906b3e871449de8be0d9652e refs/pull/1300/head\n0041b701bb932f23723fe23d1c31c986cab6e3a25f16 refs/pull/1301/head\n0041ce44f45d5814d2338b41db6a02b9673a3bcac3e1 refs/pull/1302/head\n00411990166a4d5d917bffef8041c5e759122a5013df refs/pull/1303/head\n004127e78452afa10e75822537c1dc59f6c6e356c595 refs/pull/1304/head\n0041ddfd8b7c2f88d59e30fa17f1de599229257e6065 refs/pull/1306/head\n0041685dcc529073914e74da04846f3b11681d929868 refs/pull/1307/head\n0041399fd2f34cd6b84402f0c13d83f5c32a30869564 refs/pull/1308/head\n00411c7fa1f74a4d8dd784c4f05e9a9935b7a5c57e53 refs/pull/1309/head\n0040d3516d03ffe9f58ccede1ba3f544c574aa42f1ae refs/pull/131/head\n0041847f678420fefdcadfb632c520aecc997fca7ad1 refs/pull/1310/head\n0041c0265ae333dffa5f9cca62ac86f2ad5fec5a1474 refs/pull/1311/head\n0041ce637c03ec641463a65e6b74f29bc37c01ec4e45 refs/pull/1312/head\n004101a835202ec0d542141d210dbfd2f90f66814b9a refs/pull/1313/head\n00410dd20c733ac6ccb111a3330defae5adc6d5bd781 refs/pull/1314/head\n0041e41448722c681fe02b85e191c71e2c6c41519c8f refs/pull/1317/head\n004191473d1e455fa02079f456824b12ef220a1e4669 refs/pull/1318/head\n0041fe26cfde41df51635bd570288417e1b8f900ec06 refs/pull/1319/head\n00406a59ad3005e8b3baa88b54dd78e4279a4ccc1661 refs/pull/132/head\n0041c572a95f0a91d0ba402d87df9df8b81429c1603e refs/pull/1320/head\n0041d7a1dfe27a2ec072b32c04726d1d75210ef458fc refs/pull/1322/head\n0041968219e91fd95d2807d08b2b6408828cf3b9d1ec refs/pull/1323/head\n00414b392829b8b857d0287306b4a777f8bbfac639ba refs/pull/1324/head\n00410d7258d93688371bfe1caafebf1ce25cf2d22c23 refs/pull/1325/head\n004122be1d6029c6800cac1c2d42d83f71d7c2fd0079 refs/pull/1326/head\n0041a848fde40c72868e91d113353040a36dfe66813d refs/pull/1327/head\n004174b9bafc9ef5afb38700b92ccb7910af61796bbe refs/pull/1328/head\n004122a69e7f74563c51baeb8a8a8e1b802cbff1a7c8 refs/pull/1329/head\n00400f26eb0aa416cc1020b34f09af4e3f1e6eae343b refs/pull/133/head\n0041d1e9eb6d2b4f2c9d50a9c7f795f66062b1e1e089 refs/pull/1330/head\n0041c92bc3ee8f289f7e8eb2e9ceb78ab23985187d2b refs/pull/1331/head\n00412e2472b51b6074986ca422c25f98458e545c5487 refs/pull/1333/head\n0041a1083492f1f3b80dd53b3867dfb0e5f3e426f235 refs/pull/1334/head\n0041c700a6d603146f63e1c44653c1c5d40129e41722 refs/pull/1335/head\n00417c38d42344d396e6696a6a2033940b4f035e8e61 refs/pull/1337/head\n004177dd1ab81d345dca937a730341f3ad1c1904f4e9 refs/pull/1338/head\n00401b6c824ec12c00012a6d8427d6b0b34bdab8a034 refs/pull/134/head\n0041d86d572bab3c0671ee27d6336525cc8d55bf14af refs/pull/1340/head\n004155d2b0b1622b1413f489faa2bac980570512dc2e refs/pull/1341/head\n0041aa0a73405e98ae8d7b009e640456e4f571c73d21 refs/pull/1342/head\n004134ec5f9ce21a0e78d8e0d2a4fec8774403f75977 refs/pull/1343/head\n00415e0e19603f2027312246a0893faa8df5a36a2823 refs/pull/1344/head\n004159fd1b67e48574ee67c555bdade0af902e80ba27 refs/pull/1345/head\n00411372c29d076919391d1c695f0e6e76c9b5af343b refs/pull/1346/head\n00415a06b0bf8d3e46f7f31862aae34740269eeb88c1 refs/pull/1347/head\n004151118e711f25f0dce51af42459d39cda11eb5433 refs/pull/1348/head\n00416d14ddfdb397a7398b94152eb232d437a923d596 refs/pull/1349/head\n0040f24cba8f5ff6944a00c8be4c2dad774441035417 refs/pull/135/head\n00413aec658335ca7c5070c983a318398b85355747a7 refs/pull/1350/head\n00419958913d8b7e945d8b6d28d9fae4647febba959d refs/pull/1351/head\n0041e69c278a9b4c732ccb3c7b9ec8efd7f2c7bfe2a5 refs/pull/1353/head\n0041e4111c6737270d759ff61d20fe7ac15809644c62 refs/pull/1354/head\n00414085480a5528f688316d82698bde948ca9ac65ff refs/pull/1355/head\n0041cc321c111f93ef054d10057dbe28c2d9a109adee refs/pull/1356/head\n00411f69d4abd935d0a0d5d0da7837332c86a338a327 refs/pull/1357/head\n004147c580a9c60f044d6422a6d4ea341e8e73a22bec refs/pull/1358/head\n0041da8f4613f1d55a398b248256e1dbb2f9f90c4c5b refs/pull/1359/head\n0040ab796cf9328a5820baffbfdc785c11090e9799c8 refs/pull/136/head\n0041fb5a1d4cfbde3365f9c713b0c5db03218c9585e9 refs/pull/1360/head\n0041e6f77d85c352124f058de4a436cc67d2f2e30b64 refs/pull/1361/head\n004133f44bb126ccac62932b191c35b4f86ff35f2c54 refs/pull/1362/head\n00417d14ca8714a53b43b81fdbaf7dcb4d731e5ec59d refs/pull/1363/head\n0041d6f327bed5d1a899d71f716f1a6ab51df3c988d2 refs/pull/1364/head\n0041fedd017ee04380f5744c0a9a1fc07bd691cdd085 refs/pull/1365/head\n004157602cfa89f24660a262be44f4264afcade40596 refs/pull/1366/head\n0041420883c835fce5c1fdf9e31b2c4b2a1ba45ca3ff refs/pull/1368/head\n004111c85d3805418506d0b619fda3c646a388226d0c refs/pull/1369/head\n0040195ea6539b352979d11678d7731b59e84b976097 refs/pull/137/head\n00415ab467b5f0fefcdd6a0787f0ccd2ca9e97a0cf34 refs/pull/1370/head\n00419da99970b254b871a55c53e1b79d56aa73beb940 refs/pull/1371/head\n0041ed2599f2ed8167bbe784a9959ebe38c56335d518 refs/pull/1372/head\n00417a01ec6defdcce5a201ab284bd6353a71eabd196 refs/pull/1373/head\n00410cc32c70050d32375c9e546a100cd7c7777d80e0 refs/pull/1374/head\n00416816a5a92084da7236800e387a426d5651282a98 refs/pull/1375/head\n00413b1dd44df2530950029c8b9ba57d71255c9c6dbc refs/pull/1376/head\n0041cff37efef97deeb840a05829eba8df1e550b3902 refs/pull/1377/head\n004076f9add1c183150181ef213445762223afc918d5 refs/pull/138/head\n00417ac90975be4b80d894f0eb22fedafc0a57f1ddef refs/pull/1380/head\n004105c7fbc5e16350562f5c8f28c5383536588450f5 refs/pull/1381/head\n00417dfaef3c89adc165462a8ddc3be935e73bd36797 refs/pull/1382/head\n004134b8fc16757f65e7b3e90d439370c3cc39255911 refs/pull/1383/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1384/head\n0041d0f2e9bc0d3264cb1bb2c8f2b4ee906f3e1176de refs/pull/1385/head\n0041c20a188c9aec80c3ede2f7dd2eb87f526473bd65 refs/pull/1386/head\n00411cbf39c1fcfef7798b4813cb32a1376046717e88 refs/pull/1388/head\n00411d73b6292aa98bad2bd03288ad6113bf5f1a60cc refs/pull/1389/head\n0040786a4c116c797f5f052c82cbebdda34a172387c6 refs/pull/139/head\n0041cbc9a5c1531aa5cad02723107561294ca15b331d refs/pull/1390/head\n0041d454468b07554c64b73a0b18ad95ed94981bdc0b refs/pull/1392/head\n0041789fa98adf61b0f1386064ced86159ac9f2553d5 refs/pull/1393/head\n00413344c6fb9adc24e42a8a4bbb8a9072eaadb9392b refs/pull/1394/head\n0041a5db8f658afc1a4f96e972644f39c32c1462a714 refs/pull/1395/head\n0041317dde7e40b174b3cf2839d117ae7a2c5dcbfa1a refs/pull/1396/head\n0041b3bcc7c3801ad5dc9e096beeae896c614a663ed2 refs/pull/1397/head\n00419b26d0971b2e052b10c59a4b179287ae92a7b155 refs/pull/1398/head\n00415e665ee1c2eabbd103cc5d74e5da5228e227dc0e refs/pull/1399/head\n00408abf79b887bdf2b7d970159a720892047c8ebadc refs/pull/140/head\n004136457c0b3d9c3aa47e16a7089bb41dcad6eec907 refs/pull/1401/head\n0041f498a5cfb98dd66ee5163b021488cae184c8d24e refs/pull/1402/head\n0041f1088d092b4df04f4056fca730394c23b3b17573 refs/pull/1403/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1404/head\n0041662715d7828c9853635c002d2100247363424449 refs/pull/1407/head\n0041c64c12b83e9d51511a748a70757f20690ddd3a31 refs/pull/1408/head\n0040913404cad952b608e2517580fa108a81460af531 refs/pull/141/head\n0041d162902a177573ea0341f4fc88b98b1f0f25fc57 refs/pull/1412/head\n00414eb483a1cf40089a2a2d5fa201e8975eb8706e7d refs/pull/1413/head\n0041ac89c5db51165ebfa78349979fea2e5eb166dba8 refs/pull/1414/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1415/head\n0041b9e1c8381ab55609eef988418b70f850c6020de6 refs/pull/1416/head\n004109ad387ef44204b45b792cea92e2df799f3fc640 refs/pull/1418/head\n004167f7c3cb274c2e016881632ec4ff1356de0f8d18 refs/pull/1420/head\n00412af026f9942ab90ec9e698a8ad33803bb281b644 refs/pull/1421/head\n0041e2f40cd5d4b8a0508c2af944c49dffe469c09c3c refs/pull/1422/head\n0041a4a759d446a8aad1a8b12b63a82119a4c96cd23c refs/pull/1424/head\n004158d10f418fcfc6963a61dc845452e67792c07987 refs/pull/1425/head\n00410ba2087323b4e589157f928a5e4687c943b75723 refs/pull/1426/head\n00412a684541e3d2eeb59c2724039ca4559f9f4b94e5 refs/pull/1427/head\n0041c9e37bb52435738984a5cd8103b38b1aaf2c8734 refs/pull/1429/head\n0040255fe11304bf0f866e1a8bd8b9eda301db237693 refs/pull/143/head\n00411db0f8c1bd9adb6d2f759d71bb321a0ffa7791c0 refs/pull/1430/head\n0041b57b16c42a449ed0af7ecefd0e114c1ad15a8a6c refs/pull/1431/head\n0041459ca69939984dc05f15b77720aa81c672aeb5cc refs/pull/1434/head\n00410f37ac0525399c0bdeffbbea32e8f3ee78852a30 refs/pull/1435/head\n0041be6697582272417402c495d8fdebba36e4aa3a2e refs/pull/1436/head\n0041a5ba738874dc0331d3254e80d1f18b8d4efce8c9 refs/pull/1437/head\n004177e7e8ac271c1b9f3c53c374140c44d2513bf037 refs/pull/1438/head\n0041bbb832ba4b2ab40ed39e4e1c1be7c63f5b3f837c refs/pull/1439/head\n0040d5959201463d114551c61c6f096dddd7a8af7e56 refs/pull/144/head\n00419c0cb248c39d172e65a6b9726937f50c9021ffd5 refs/pull/1440/head\n004190f8f453047c16f613e76967b282d07ca6d5f2a4 refs/pull/1441/head\n00418bef7af75b5753b3291a8525458a63b0d01608f1 refs/pull/1444/head\n0041133778dfdd2c7f9998fd305b36c90cd2168bdb14 refs/pull/1445/head\n004167f7c3cb274c2e016881632ec4ff1356de0f8d18 refs/pull/1446/head\n00414f19efb23c7c1be947116d3420f2f840510c4175 refs/pull/1449/head\n0041d35b1fffb1469f0d0cf20dfdc59886d66054888d refs/pull/1450/head\n00412fc1a17c38a1ed301fafb75cf35bb4f2ce8720b8 refs/pull/1451/head\n0041773299d0b951f3402277f8773b651f66dae9405c refs/pull/1452/head\n00410b19d653a8faa1e77ea4552bfd66817420b1dc1b refs/pull/1455/head\n00417afd12d7cf6225b3c991d8d40c11b8c8db61da60 refs/pull/1456/head\n0041d042180adf0d2eb54e75be483337053809010256 refs/pull/1457/head\n0041f0edf0611e71ec179578cccd39b77243e3bdd5a8 refs/pull/1458/head\n0041465f266f9e56f1d58a5b38b86b629dd90f1a4037 refs/pull/1459/head\n0040d87aad784c93c9203eeac218bc8c9e88a3db5cb6 refs/pull/146/head\n0041be9a0dae947de482dd246c4e70666afbe522c619 refs/pull/1461/head\n00417b7150502c0ce679929ef8b2f2ee857664552d23 refs/pull/1462/head\n0041572f35dad64d6588ea96f3bde38a165fee9ff3f9 refs/pull/1463/head\n0041c270c099ad02eb0a23cd8497c4bb4c1dc975f741 refs/pull/1464/head\n0041c422c680a7bbb073523956c926de9310a17b3ff6 refs/pull/1466/head\n004185d6cc2cc79acfdd2061c4fbd600ce4c2f741fee refs/pull/1467/head\n004148ada69b2d8c141901ef529165df93f22d351486 refs/pull/1468/head\n0041be9a0dae947de482dd246c4e70666afbe522c619 refs/pull/1469/head\n004006894e6fec4cc65fc526eea0da822ac85a910f25 refs/pull/147/head\n004168f51c73b84cd2fc045447a09fb539ac912a5d91 refs/pull/1470/head\n0041a65c29ea40b8437572e676e55ae311d14479e9be refs/pull/1472/head\n0041341ace4dd63a182bcc2223f10d17f42aad50a339 refs/pull/1473/head\n00417a099e71b80e8747d27136e7e18409e2070e9b3a refs/pull/1474/head\n0041f170b2ad5d2b4b5477b61658a3c8af36ecc259da refs/pull/1475/head\n00414cf00e7e43cf89136d8aff44e72769efe9976905 refs/pull/1476/head\n0041c7b506f7f2b5425bc9253642b40450abf8269476 refs/pull/1477/head\n0041745d81755163efda96a36c54390c9da367afe86b refs/pull/1478/head\n0041c6d517a24a5781d51d87a484d60873e58a3d3528 refs/pull/1479/head\n004078c4df8242a4962d255d81e4121b14c186461a81 refs/pull/148/head\n004148aa3ce720b918c4d3251b4ada64cceeb33b20a5 refs/pull/1480/head\n0041e18554cc64fc785b79317902fe1fb29df777a7b1 refs/pull/1481/head\n004120b4ff3abaf6f3c5a83428d9293a1d2b51ab5d59 refs/pull/1482/head\n0041c594fbb00b9d4d0e6c0bdee76ef260f1b71aa373 refs/pull/1485/head\n0041231b7cd948eba5f6a67dea0cc433c3d1e83860e5 refs/pull/1487/head\n0041e077713e2fd9260b858e26eb796251d223a22a2c refs/pull/1488/head\n00418d54abb9154b6f8a11daa9a9fe4628399418ab79 refs/pull/1489/head\n00401ad173258d866686cea8878365e007ae56c05536 refs/pull/149/head\n0041b7f85e75a22a60f615bb51396a252ad2226d8b35 refs/pull/1490/head\n004118c31f294a8f038d42c374a4527a791cf11fa8d6 refs/pull/1491/head\n0041680d70c039e5af70ea1f892ebcfd19cb7bbf751f refs/pull/1493/head\n0041ca386287ba9a104728e40da69924e32891a61964 refs/pull/1494/head\n00417a47f4ddb8367212af84b4a14e31bb47d7093a61 refs/pull/1495/head\n0041ea93c334ee1502c974a33f05773e6d6b0be2e44f refs/pull/1496/head\n0041b28e8e652467fe118029756c2b8028e59ecb83f4 refs/pull/1497/head\n0041042076cf5970a4e025941de2a799a8461560ab9c refs/pull/1498/head\n0041c160b6a7ec28855c1273e4d0568ce42a3846450f refs/pull/1499/head\n003f3001a10fb6c4d39f149b8024bd06834d2e0f2bcd refs/pull/15/head\n004115dadb698dd7c9558e5445fa77ed64e3f2621930 refs/pull/1500/head\n0041eb320aed569c5377aa44e11a52feba2548752b03 refs/pull/1501/head\n0041f7f5aa9b3edfb792ecc4da4cbf5f2c6ff6d4cdf1 refs/pull/1502/head\n00415e87da6fcd3a0e9c999a81dbcb749fa8ff41d47e refs/pull/1503/head\n00411f9e058e9511c23323b159db9555807bf0e74787 refs/pull/1504/head\n0041ec5568348734532295ad86143ea119fec68f4ba5 refs/pull/1505/head\n00418b1f30d9b6d5406350deca472cb667e7c46e09b8 refs/pull/1506/head\n0041fb5ad38eeb943393c6af335e89f0ffa22eaf7fac refs/pull/1507/head\n00416c793bfe857449f9a1174643cdf2b9b5ebfe1967 refs/pull/1508/head\n00410e6eebbb86acbc92d6e727bc962be7807b50a765 refs/pull/1509/head\n0041fff0e2e5c58176cc5e4a13a347ce446d76e5c5a9 refs/pull/1510/head\n00412d85a7425c8a13008fbf52b8d45543a1d667175d refs/pull/1511/head\n0041964eb17ceea78e1ec6f495cc5ca324eab3ae12c1 refs/pull/1512/head\n0041e6a3b8bea46f4896b8ac0b92f5dcc042d81b9597 refs/pull/1513/head\n004135aa6907f28c6e6350436053bda59101d55359f3 refs/pull/1514/head\n0041a787cb7fc713f4a381c1281f90bc7a3bfcfcecd0 refs/pull/1515/head\n004128672bde3d91514708f44ae1b71ee780adfc90ac refs/pull/1516/head\n0041a3f9b48f377be38cfa9a9c600b7a73a055424da5 refs/pull/1517/head\n004143a849cfc3f522d10afed28f8136f9f6558aae67 refs/pull/1518/head\n0041f2ea2c03729bd2afb4b2d56321d52809e0bb3c2e refs/pull/1519/head\n0040050259ba69be2b95a70563765a15c42849daaff7 refs/pull/152/head\n00414f55e503a8ab7a7affab771bb1da4993bf61671f refs/pull/1520/head\n00416d07ece41836d1d3df38113c02a49d29bdc0e134 refs/pull/1522/head\n00414b48c91a0a3453090198d11f6a8727842db9d1f0 refs/pull/1523/head\n004138ad3f9aac054ed8871e887c5e0bc3e47cb41f06 refs/pull/1526/head\n004159a6477bf16284b0ed1204c42b490e37021916e2 refs/pull/1527/head\n00417c49448d992a0cbb6c6897bccddbadb62b564817 refs/pull/1530/head\n00419a02ddc6c749dfb28d0fe6cb85a42130c31c62a8 refs/pull/1531/head\n004170b290911ca6bd8796cbc208a11e98510c886f4b refs/pull/1532/head\n004141d92983d7e978b88cd3e49fc276ae059098486b refs/pull/1533/head\n00415c2880379dd3c8f7ceafd8791e17221793b5d980 refs/pull/1534/head\n0041ecf4c8da86c40d510a39b8074c18636b445d3c54 refs/pull/1535/head\n004168158e57f5a7258ff7bb0b9def2e50acc5722bd5 refs/pull/1536/head\n004184ed942ec251f38c8ffabede56aa229674ff4e12 refs/pull/1537/head\n004199cb2854afde5b21790a2384b3e6b7a065d0245d refs/pull/1538/head\n00410ea1a5b8fd2ddad43b9fce09dd4b701eb42f9a7a refs/pull/1539/head\n0041a6602a393c3d8c01feb308e21ae6b7f00e6a65d5 refs/pull/1540/head\n0041a5766dbac237aeb5996e47141547f8403c0bbe54 refs/pull/1541/head\n004160db4ae8523ca3180a50eaf9601ddfa8a9aa343e refs/pull/1542/head\n0041ca31af714a7a0c754d42f14531da4aa6812a27bc refs/pull/1543/head\n004185c8f0287fe9e70649e8e1dc295b10c62f4757a6 refs/pull/1544/head\n004110f90d2558011cb165b5ed8610a93895d14d3540 refs/pull/1545/head\n0041d8a2d1ad19cc557cd8d7dfb71189a50ccc312cab refs/pull/1546/head\n00410b39f6e72317fd3ebed1713f72c3b02e4d5d14da refs/pull/1547/head\n0041c672bf9b5e84698bca8177c2a6d110612484f8a6 refs/pull/1548/head\n004154ffe1e63d69bccaa9c6a22975393dbf20816b85 refs/pull/1549/head\n004180360661d8253639615d914c728179be546b0fde refs/pull/1550/head\n00412f81196691cc6ec6cd61e6879fe7ee719ad58247 refs/pull/1551/head\n00412ce6f5ac188adeed4d94d3296b2c8dfc9e103db7 refs/pull/1552/head\n0041cccacb7e6f96b39e7e452aafa88a540daea45314 refs/pull/1557/head\n0041d84a185ac9b0de0ea518f3c7c61033e8333c29e0 refs/pull/1559/head\n00400d6728af68c3977234c95f97277a9c7e80b26615 refs/pull/156/head\n0041b9c8218ff9aa201c0855be7785850a9689aeaa69 refs/pull/1560/head\n00412a34bbcb74f292c45776917e48bfc8b5fe8c0197 refs/pull/1561/head\n004146229e4e508d6a21436211d7e740f56e0710c2af refs/pull/1562/head\n00415875aa021ddf3961dfe317945b01583c98877bd9 refs/pull/1566/head\n0041207d4f5ec3a726cca709532828999cc5b24298fb refs/pull/1568/head\n00412994d14e821ef14f179da71cc56d6cba60f6d220 refs/pull/1569/head\n0040586de893d3f5a99c4fad86056d2e6f74c62ee729 refs/pull/157/head\n0041f428a60a3252a5223ead6f579817fcbd3909a7dd refs/pull/1579/head\n0040a9cfa8fc63f2cc043e2a9db7b48d8ce5196d99fa refs/pull/158/head\n0041075491fa48e07f794250c751b71420a33d8f1d8d refs/pull/1580/head\n00412b2a1901869811b50dda95b0bbe293bf8ba46844 refs/pull/1581/head\n0041ea8460aa2e510e57710c082cc7f169a00918169a refs/pull/1582/head\n0041f2ae86243215115e28fcfc21c91edbf4d4bc8068 refs/pull/1584/head\n0041ac97b8009acad579563c919ff9e83be8c2708c26 refs/pull/1585/head\n0041f5564caa092815ad5908e376147a84f12a5f4c6d refs/pull/1586/head\n0041a74c74821d1b621a1356e405d2daa9c86cee1821 refs/pull/1587/head\n004177cac1aa0c6d0750997a811dba708a108db0cd8c refs/pull/1588/head\n004178a902ad50439f9a0e05c386194b65cb59e23deb refs/pull/1589/head\n00404bd0fe137d82ed8f3e9c21770a2eb09ff2cdfdb7 refs/pull/159/head\n00415428807637585f9cbce87048220bb65de5b54d19 refs/pull/1590/head\n00412ce86486b53e98596e0aeefba526b36c9584ab05 refs/pull/1591/head\n0041494107c206031c9776d739da0077967f7820bd04 refs/pull/1592/head\n0041f9be7c1a9f2d78a6ebe2e0033446a5ba1226b1af refs/pull/1593/head\n00415b37124f98e48fb4d23b2ca52c9effcb4b6e68a9 refs/pull/1594/head\n00412e9bbdc135b413a81a3954fdf3a250cc221b5d19 refs/pull/1595/head\n00418fa5290952e7225467e22d919cbfdc61f6e5a448 refs/pull/1596/head\n004154ee226ef084e63e134ab7850adf02bd51e2d66c refs/pull/1597/head\n00418400000eb57cca8cc93dca976dd83c43a58b57b3 refs/pull/1598/head\n0041919ce9f657f40f60e49f19cbd389de9e493fffd0 refs/pull/1599/head\n003f04f95077a3d42acaee6213e43b30db43ff5cd0ba refs/pull/16/head\n00402ea858357e472cf6ef44d3e4bb598627c722de0a refs/pull/160/head\n004136d6118e605bc8535f1dde4499865d7ae1dc6f34 refs/pull/1600/head\n00418d40405f430d10f4e55dbbb6575d0c523eb4af90 refs/pull/1601/head\n00417bd61dfa9bece662f00e69ea0fea6694f41d01e3 refs/pull/1602/head\n0041e4259f91ef112baece9a58cd116a311bfbed4643 refs/pull/1603/head\n00414e034afd86bc8d28fa5149a8ed0329204ad84abe refs/pull/1604/head\n004127cf14504c0ed7dee0ed3349de789a6496106294 refs/pull/1605/head\n00412dacbc9290c92d3fa0a01f230487b5c57d63c63c refs/pull/1607/head\n0041938ddcb8ab340d456557f55dba08668b873a347c refs/pull/1609/head\n00422f0243028e21ffd658f4845070c7689b6bb72022 refs/pull/1609/merge\n00407f1fa1358a37f2c66cddff37f41097a7735225ac refs/pull/161/head\n00410ae076547e76efc789fd859b2674802043ed73a6 refs/pull/1610/head\n00414a008ec8fa334dfe9805456d1b369669ccb44670 refs/pull/1611/head\n00414b57135a9c4ccdf02010cc534fba565bde3a50f7 refs/pull/1612/head\n00415ebd98109d619cadc98cb0452a0c6a5b4a6664c0 refs/pull/1613/head\n00414be4b03279e6be0e8eaa5ebce4cc7ed641bbdb39 refs/pull/1614/head\n0041db142dd26ecc2bd285a1b14be7c80f6eec60a3c9 refs/pull/1615/head\n004164c190832746b38c7845752c7d25de7d160fe538 refs/pull/1616/head\n00415d5266e65df25cb90c46c4cbd3d9d6b8b63b592e refs/pull/1618/head\n0041906a1211c6dd202c7c7ede44cd2acdc4189ada66 refs/pull/1619/head\n0040ad263687541f8f83d15c4d1fd4d3971135523341 refs/pull/162/head\n004193546ec70491c29f1da3b234c547773e717db0a1 refs/pull/1620/head\n0041fd5e99a385b9174dc0c56b2eddb2eeb4db0aee1f refs/pull/1621/head\n0041e2afb09f0e0aaa4861d29ba6ae5f583df20f0d9e refs/pull/1622/head\n0041c19ed8d95fd118b1e3fe7c175f7e6f9e087d8a38 refs/pull/1623/head\n0041029b70afc2e78795b7c06d347c885c7f176c08d6 refs/pull/1625/head\n00412784d5f2e6062af40ab5769e75cf9cc52eb0272e refs/pull/1626/head\n00415035da3073ee1ccae17ba8dd4afe8be0a795be31 refs/pull/1627/head\n0041d4deec6d0da7f1ef65c1a779dc19b5d2964fa439 refs/pull/1628/head\n00419f8916a32d63d59bef6fc87287ee68a49dcb1ef5 refs/pull/1629/head\n0041860bbc8abc74b995ca1d0a5f0445a27bfa572654 refs/pull/1630/head\n0041f9f0ff9bc7540c9f48007324a89c79cf9477a51d refs/pull/1631/head\n0041a764c3bf113054896a43dea12d15634ace56c362 refs/pull/1632/head\n004126642c905dc317f9156e8bd3cfd252925ebf44b1 refs/pull/1633/head\n0041e33d72ff1e21534c5452b848a7678cfbbf420efc refs/pull/1634/head\n0041d315ffae02e5a1b69f5d60d6b51df8b1443d5575 refs/pull/1636/head\n0041153b7a6705e7c07598d47af91bcc3c72bd7e6d44 refs/pull/1637/head\n004192084fcf21479110c65a313e8b110246ba3316c4 refs/pull/1638/head\n00417e528b8c9d205d12cef9d93728d1c7f54e31a62f refs/pull/1639/head\n0040037a450c947ad82d0ae9498aeeea1c846dc5df36 refs/pull/164/head\n0041d71725912eb43eb95e649c442b6bbbe503e212e3 refs/pull/1641/head\n0041b1825a135207e352d0658b50f690ffe85594ca3d refs/pull/1642/head\n00414e1b650bde5ecce547d0de96699700b39540f3e0 refs/pull/1645/head\n004167fcafae3f165ff4d9b7fb5735fc1df9dc430fab refs/pull/1647/head\n00419054d4cb61638573789be4c52b101941f4bf3135 refs/pull/1648/head\n0041122e1be663becb68403697a0791fabb8597598f2 refs/pull/1649/head\n00417382850335f92144b964320432decc3bcfa1ee05 refs/pull/1650/head\n0041e2ecb13310305aa67198fe6c7d02259b57695ec5 refs/pull/1651/head\n004171632669bb9aff5abdafab8795ad378a4010d4a8 refs/pull/1653/head\n004154df24a7c12fabb8eb24c3060305f41f4ca4a4cb refs/pull/1654/head\n0041b1761437cfcd1deb82b345e255d6e4be136d59f8 refs/pull/1655/head\n00414b1b668e7d90752de5bc79bef1a7e2a53ec0f147 refs/pull/1656/head\n0041e790e1b260b9a5c3f85f69516b236d1b032240ad refs/pull/1657/head\n00414a07e4096a0bb16d762e5fea9da274c87fd5863c refs/pull/1658/head\n0041a6037a9bbd4d7997b7f97a2a72ae49dec960453d refs/pull/1659/head\n004049d39257f884690d669876986d9be47ac05a72e5 refs/pull/166/head\n00412bb60baa2a4093fb0aff6dd873849b4947ac9813 refs/pull/1661/head\n0041879551b20994b0f30895426d35412f48b8ae2853 refs/pull/1662/head\n00417572fe17a85942268020b9eff6d4d8eac8409839 refs/pull/1663/head\n0041fe61c22d3b2b85426dba27af3f65f16dae16f573 refs/pull/1664/head\n004169c6d4673475f395a00fa9fa7a381f579c1165ab refs/pull/1666/head\n00410cd5e9cc9016ff219b71d7a33c635222fff501e2 refs/pull/1667/head\n00418fdeb541be4aa5878a1e3254311a3f7e1e717bfa refs/pull/1668/head\n0040ae2c13c71b5be6042c70ffc2249767ef2b858087 refs/pull/167/head\n0041c7a2b7555299447ea01a557fafc3df6895c2a798 refs/pull/1670/head\n0041cbd7bdd929809d6c967d8764fdcda4efb6c6b00e refs/pull/1671/head\n0041176ec0475258a2db5d45598d29e0e61ba337ffb0 refs/pull/1672/head\n0041ba7c8e4233ccb9fc0a0d5e46e4f4282772bc842e refs/pull/1673/head\n0041e338570d4d6a9829eb37150f1b625a3800f20a28 refs/pull/1675/head\n0041aff5dc102b097be8863fdea720aef890a253a8a6 refs/pull/1676/head\n0041e43e1be58c45a9e16c4bd9c6f3f651f90562bad4 refs/pull/1677/head\n004129e395a423763120e528f50fe57de2334b73d83b refs/pull/1678/head\n0041db151fda8a8198e428b7cc311f0a1cd6c12c218f refs/pull/1679/head\n0040636ea0a2fb8fd8cc4655f21a9d70ba4f2337c709 refs/pull/168/head\n0041db151fda8a8198e428b7cc311f0a1cd6c12c218f refs/pull/1680/head\n0041813cf8299659c285f90ec25861b6e0db2480f87a refs/pull/1681/head\n004192992ec878d7b5c334fb81e8531eb3b61dcf6e4b refs/pull/1683/head\n0041ba91440d1b5096875a9c40ab141315017a996999 refs/pull/1684/head\n00410d05477509f5697b1af54dd776c81bc023185673 refs/pull/1685/head\n0041d2315bc5b74e20c288544e4b7849453f839df8ad refs/pull/1686/head\n0041d4a1a7d0d3055c20fd25e8f5a0610d5c923e3010 refs/pull/1687/head\n0041d9bf2254fde8d6d2d3d6d2df3282a9f4e5ff49fb refs/pull/1688/head\n00413e3fe1c137c0b23e87cb25411cfc820a6b15ba43 refs/pull/1689/head\n00414e49fdbca2db9c2ffc3ca887aee9ca5149e44299 refs/pull/1691/head\n004190966848c36befc986cf48f30a3fa0672197bc8a refs/pull/1692/head\n00413b16f8c008bcdb3140461c00561f072730e0725e refs/pull/1693/head\n004180532f3b4803483e5c399c91ea86bfebaada9966 refs/pull/1694/head\n00412556da4ddef258757bf420a5023704c3e03a34b7 refs/pull/1695/head\n0041f3be7b24a162e4e0728da3b9bad20b68c7562638 refs/pull/1696/head\n0041f888fa52c83074609d20006ed9433bd498e7dfde refs/pull/1697/head\n0041f21fcc02db695dbdfa3bd43247aef653b7343fff refs/pull/1698/head\n004144066554232f737fb771d3d0fdeb62339366f8f1 refs/pull/1699/head\n003ff5a848d9eacbdd8595a4d5b7b6d96e8e492287e1 refs/pull/17/head\n0041f4a80b262e382a9fc1b6471d53e3f873e6f25115 refs/pull/1702/head\n004175e3d7c121c05c0c60f342fbce1e90412626bd35 refs/pull/1703/head\n004156a6c73ab71c4a801c1636a75024aff41a37927c refs/pull/1704/head\n004125776d93bf74cda5889c41ad51ce190a5afeb436 refs/pull/1705/head\n0041d581d43aa016c297e1f79dbf409f4216ecd890ef refs/pull/1706/head\n0041135f97130a7dd070532c06830ad07c01d4b31923 refs/pull/1708/head\n00418f60ee9054a4b0c870cc2d967642024239d9eb9f refs/pull/1709/head\n00406dc43713b9adf9ff0f0c7c23d79133a7c469b8d3 refs/pull/171/head\n00416aae0ad145d73cd2af095fd61b1f11710c8e72f3 refs/pull/1711/head\n0041aed310703f2169df52902ec48beea4cbdabc8ec1 refs/pull/1712/head\n004145abc4bbaa86f8a93773d9e40a31d3429d4bb8aa refs/pull/1713/head\n004106d8bf018c193e31e72d2a5774a6576e4eb5c95e refs/pull/1714/head\n004141135d1dfc165e4e84138b5ecb6d14f6075e6177 refs/pull/1715/head\n0041b8db64deadee4e03205b02cb7c59be672e667e8c refs/pull/1716/head\n0041108f6bee9d622f10b3b46510f1c02137de860da2 refs/pull/1719/head\n0040aeef4cda0b482f9acc5a06dc7daa7e2ae22efda9 refs/pull/172/head\n0041b69082fd6e7f94208ad15df6b427f8136a8a4313 refs/pull/1720/head\n00427e735c29e45c9ff564f589c18f4725c0568959a4 refs/pull/1720/merge\n004140333ebf9022e2c072b1942a0d01a6d27151ced4 refs/pull/1722/head\n0041062986103eb61b843d6598c572677468945d1e05 refs/pull/1725/head\n004175dc86a4da88a29a6f9541a07866e1198969f886 refs/pull/1726/head\n00417c1c22a4eac54dcdf96557c405a6324faa8f8efc refs/pull/1727/head\n00418b54b9a8573a8a842b4133811fc9f23464701425 refs/pull/1728/head\n0040cfdd598e088b4245671337a5b7ecb36b46545ac8 refs/pull/173/head\n00418ca1c6b27e76e42276e22fc962854b113b5aefb3 refs/pull/1730/head\n00412bf5af86e833f538f47a335000b4a47bf3a38d7c refs/pull/1731/head\n004147cc7cfe9881eb70103c8f91d0e4677d953787ca refs/pull/1732/head\n00427833a8fc1cb02e261942e27af4f6c81bb01ca0af refs/pull/1732/merge\n004102db9f7d0689f13232f019ad2268baab590799c0 refs/pull/1733/head\n0041b032701afec89b78e3fa6a75b6005a8c4720fc89 refs/pull/1734/head\n0041bbdf11b0afd6319b4bfe8772e70f9f908c76c51e refs/pull/1735/head\n004158dfdc7cc6fe48497333ca28f76247c3299a7ade refs/pull/1736/head\n0041a88574270ffaae4fb6830b4a59707e007ff344eb refs/pull/1737/head\n00411c83bb41e7c42ddb272ea5f1728d01153acdc270 refs/pull/1738/head\n0041eba63642ac2b45e2b93e430d94e8693d17d04115 refs/pull/1739/head\n00419d833e552128a464daf6bbd82aaba0e60d59186d refs/pull/1740/head\n004181b64d3b1775f03352c54cb3a2fcd282957eabef refs/pull/1741/head\n0041158051eb777330492e3d2f46910560a6fa1f8abf refs/pull/1742/head\n004105670d6623b95520d638b53cd2ad282cfc50944f refs/pull/1743/head\n00417145fdbc67fffcbda16e97575dadc0f04b8fcf2e refs/pull/1747/head\n0041c0da39cbaf1e01c0833091101fd4ca8bf23e570a refs/pull/1748/head\n00411a44d898f1e4861940a4e4573ffa393060b892a2 refs/pull/1749/head\n004136f92267abdeb2b264ef84cf5f5b576a5943c231 refs/pull/1750/head\n0041e3d45e071f6e08ce7357efd2365d099acad8764b refs/pull/1751/head\n0041916652e2be88a78ddf2407fb692c3f3541ed11cf refs/pull/1752/head\n00418b68c6261756493c7a2dd5d3426f5eb9e553816e refs/pull/1753/head\n00415e5daa71fc8e91a4dd2dcd3f931732fb9f75fef5 refs/pull/1755/head\n004151641d8472d7202d491823a41c851e0ad36ae85b refs/pull/1756/head\n0041449faeade1565751ba6c6c8960b7a4c0952f0e83 refs/pull/1757/head\n00416f50c8a4325582a08bf1a60077103efd7c2a3202 refs/pull/1759/head\n00418390d3e556e27c26d40e9d1c68d9ba4c16d0b9dc refs/pull/1760/head\n0041902821c400c4052f4492975219729d19ac609aba refs/pull/1761/head\n004103f573ce19b4ceb32085185b6d1492d7f370189e refs/pull/1762/head\n0041b3b5bd988db1e4cdef63b6f3355aa8e2b0675831 refs/pull/1763/head\n0041d2e34e21d44bfc343003ac43300cec63dd6d1f96 refs/pull/1764/head\n0041cd318eb017b4a9c1af720552276d1102cdc89570 refs/pull/1765/head\n00415ddab79624857dcd3d1bdaff61ae79fbb0590489 refs/pull/1766/head\n0041e8a11106eb4cd18d5e05bc633e6fa473f14c3840 refs/pull/1770/head\n0041e6acc61e3cce771e712669fccadcac67c9f8ebbf refs/pull/1771/head\n00414a8257ee3922ca8866bdd1632c66b20649b2eb96 refs/pull/1772/head\n0041b5689883415dc3bb142cb78d9f083eef16b4579e refs/pull/1774/head\n00413a0e7ae9a78faf4b75c67d2f6491a32df11d14c1 refs/pull/1775/head\n00415bccc3883a0e68932d68245913de443d76cc5a82 refs/pull/1776/head\n0041d701b83ddc8f85958d1df5a4f1ef32f40f681378 refs/pull/1777/head\n0041591a7eab02b4b54a53186be752ad3e10d12047ae refs/pull/1778/head\n0041c950256f640f6fa96b0d3ce9d16ae6724fab8da5 refs/pull/1779/head\n0040ba57feb1392c5140060d290c456db746b5c6159e refs/pull/178/head\n00413fc708d801d83ba63fe85f1dfd9f3c08ce6fda40 refs/pull/1781/head\n0041bd1439e280fc7b8f76f583884136ce3d00c8a9cd refs/pull/1782/head\n00412c8c4f43d846ecd465698d4eed7c8692e2729c7c refs/pull/1784/head\n00413c132fb87a5f32d8df2ebe16c010f5db333584c9 refs/pull/1785/head\n0041dfef1664ec4a1ec64ec12395f9933b67b27449d0 refs/pull/1786/head\n00415f5bb39927c2b58565012387679555dbc078b8d1 refs/pull/1787/head\n004196823392fb6be48e90f55bbba486ab438a3ccf16 refs/pull/1789/head\n0040e414e0d8f3d323da277ee15476e5ac8ded3b82c5 refs/pull/179/head\n0041dfb5bea5fe9c993ec74061edd2a7d5d421ddb8b2 refs/pull/1792/head\n0041cac286a660ceb89ace7c5a5538f326d954a62d4f refs/pull/1793/head\n00418492757b37431c1977f01663d87cddde073fb33e refs/pull/1796/head\n0041b3e761e5db4d1fca2f8f45bdac17eec48a127ac2 refs/pull/1797/head\n0041d332ebad6c9711349a8a853fb7d1bbf9e248db71 refs/pull/1798/head\n004106e446e39e5a1efc9eb8ad5a300e0ee86ce08657 refs/pull/1799/head\n003f18f7167d53fbab5ab19c3ac36461fa518e59761c refs/pull/18/head\n00401a854ea0decd05e4a9335b3a101be33d9800405e refs/pull/180/head\n0041efe777d8fc625b80c8a08267de799b9f0c09c39f refs/pull/1800/head\n0041007a0118f2956621706c23f26b1cd8075791f9dc refs/pull/1801/head\n0041e494a752fbcea552414a1b6af006fb9a80610cb4 refs/pull/1802/head\n00414355e08bbbb3b6d2b8e116505a8fa1485748cfc3 refs/pull/1803/head\n00413739401fc548f67e699c741b9044fbe213bef387 refs/pull/1804/head\n00414b4688cce5010a2e2837c2094ed492211824b231 refs/pull/1805/head\n0041bf05a4be79e1c79330b47cb046df101ec64c1ff6 refs/pull/1806/head\n004162dc3304c621e5ae13625d5930d2484c9adfa4d0 refs/pull/1807/head\n0041840766f2f861a9d06c769e57d40cf65862b6c675 refs/pull/1809/head\n0040f6b89e763c1ae6f398849e5b94d858e34dff8663 refs/pull/181/head\n0041f474e67aade05636419a2b8396c27fb39cfa9b02 refs/pull/1811/head\n00413369c5f8f0d54f839dd20203d3450d4096c41a3f refs/pull/1812/head\n0041c9b14d17d84e90432afb9246dd9a8377462ac627 refs/pull/1813/head\n004142e7655663ed198fd3c46f6455cea5ac2c40cb83 refs/pull/1814/head\n004172fde249e400bdd09f0ca65f187104e2f7792da7 refs/pull/1815/head\n00417e2776ca22f4537a6fafc0c95ceb0c74c8f341c5 refs/pull/1816/head\n00418ee9da5f84628b5401a8e73cee770397cfe105b9 refs/pull/1817/head\n0041a06e2597ea1692277f8edbc2b643a3e382241e6a refs/pull/1818/head\n00418cf8e86091b471ee1886414cacc1969f05af5ef8 refs/pull/1819/head\n0041dccdafcd455c19b1e6a803e4e94471bbae7eff85 refs/pull/1820/head\n0041b4c17c7eb63e68e5df2d65cac6138a4d56803719 refs/pull/1821/head\n00419c8fdb86ebe6ee0d858312e741ae680a1131ee73 refs/pull/1823/head\n0041342c6564bbf5330cb4ad65ac20b15f2c3de6665c refs/pull/1824/head\n0041519191dcaae36c1587f166e39d114d9fbe200547 refs/pull/1825/head\n00416a70839069b44b5a63e2e6a3e47ed5504158fa72 refs/pull/1827/head\n004101bc8a5883e4478ed31ee7d06cd9b96bcfa436ad refs/pull/1828/head\n00406d813c2208a2326d94036b185b734a6d1d38d7d8 refs/pull/183/head\n0041599f8e1ebe821769299192306a8ea909a5199ea1 refs/pull/1830/head\n0041618a7b7eef4b5fabb31a7e63340e309168e6f45c refs/pull/1831/head\n004157b43516fc128f79431f23271fab622933f2754d refs/pull/1832/head\n0041f860f607fd0e913c0171835f5019195f49a23cd7 refs/pull/1833/head\n0041f237e8d0e9abda367e2c305927b9a1ebd83cdad9 refs/pull/1834/head\n0041638eda44b84d8cc4afb493c11b7ebe33d8e83cb6 refs/pull/1835/head\n0041f2d546ba7c01232604f6be739452773829448ee0 refs/pull/1836/head\n0041d8e9f77faa0c47702d961a62ffbc7ab81362f9b1 refs/pull/1837/head\n0041b7534a9fe65901fd3071f950456085d12c611ca4 refs/pull/1838/head\n004184b27252897a8424d599d97e220d69d4d38b0adc refs/pull/1839/head\n00417144013ab8c98e85af59db288d848dbc666d5258 refs/pull/1841/head\n00417da7fce2d029220b100dba66a7fdfd2f28ea0ba2 refs/pull/1842/head\n0041691f49caa3031ecfc2ead03ec6fdda8b860c3b04 refs/pull/1843/head\n00419bc319a6aa2e212b7493ade763896472cb345ef8 refs/pull/1844/head\n0041c61898f594c8e619dfd59572fffaae1906eecf17 refs/pull/1845/head\n00418edae54f46cb62a34bb4859d2691b0097f5c0c8f refs/pull/1846/head\n00411bc9f9bc308cc69cd1c18ce6b8efa61b9aa745cd refs/pull/1847/head\n0041cd932084db77398e5ff63b3d80c76d943b598212 refs/pull/1848/head\n0040fb5c00d58e188df7ce7231a6018eea17a91ef6ae refs/pull/185/head\n0041238ffde778c5424146ca9c908c897b2356864e2e refs/pull/1850/head\n004128c950302ebd22c56798dfab9bc820349f182c1e refs/pull/1852/head\n00418e6825db704f875085b8fe4359c61baa8bef63a2 refs/pull/1853/head\n004146c9c7e31a9c0295067a22f7e0ab4b1dbf7098c8 refs/pull/1854/head\n0041fd8fc0001fef1272ac97beed2a4050c0c5fd4195 refs/pull/1855/head\n00419211aaae4312dbc64872f6583622bc7061315822 refs/pull/1856/head\n0041d60fd3898289884aed9088d0788fcdd4089af548 refs/pull/1857/head\n00413b079372b7d977aced123b231faf50d0a92057db refs/pull/1859/head\n00426795a093abb0f0a4389743360dc9e1dd1f0ec5a0 refs/pull/1859/merge\n0040faa9d00e7461ebbccef663371a70cddfedee7eff refs/pull/186/head\n004144ea636af4e056a3a4809470e530c7d207705c20 refs/pull/1860/head\n0041934da32ea81e43d81860656a73935d943abb50d4 refs/pull/1863/head\n00413cbc3289eb428cc8cda8bd41701574428c376c14 refs/pull/1864/head\n0041a2d04657c1f761293e5f56dff1ad2af38482119c refs/pull/1866/head\n0041871a044ab84086af69e2fa611087aef94fd5a0af refs/pull/1868/head\n004117a52d99f395378639a108fc4146657ea5e3914c refs/pull/1869/head\n0040178e0c45a481822b42cb9057898909470b354936 refs/pull/187/head\n0041b784710337f716e3fb64be89dc5b78b9fde61d8b refs/pull/1870/head\n0041fac2d682381c1f67c226d2a3673b9330d33e6c03 refs/pull/1871/head\n0041b2ebc60f06bb92c153841ebe0d328be2fa88c7b2 refs/pull/1872/head\n00410a572c2b0d448e9216f371df6404fe69cbd02fcf refs/pull/1873/head\n0041647a1b125de5e4e5dd58e0e5fd82e6d9064af612 refs/pull/1874/head\n0041713d5de37556062cc50ee11421dd549f03a71e94 refs/pull/1876/head\n00417500a942176139d5f95e3347d6ede76b976a0cc9 refs/pull/1877/head\n0041ef86be2b62af481b81d9d44f88a8683e0226cef0 refs/pull/1878/head\n0041b37e23b5130a65abf26d2ee26e0a0a1d37732bf0 refs/pull/1879/head\n0040d6b016681ced68f32ed3d727d32bba5cbcebf48a refs/pull/188/head\n0041592e36c17a02947d83cf9fae2adc0144f48109d2 refs/pull/1880/head\n0041823870c376cb8d401a114e0e49766ba1b316483f refs/pull/1881/head\n0041c0c8d33c548238906e9658a5a8da5d1e9e603136 refs/pull/1882/head\n004192de84d0c303553c56f7573cb7b7136ceab2a31a refs/pull/1883/head\n00415175f29e6048f73fd71711fd3c3d38d1bf1097e4 refs/pull/1884/head\n0041a0f94c499d7d1d45e378cb158b5bcb98b9366196 refs/pull/1885/head\n0041baa5f0ec04243280748d5cffa9e835bc6b0ae675 refs/pull/1889/head\n0040c266a133eae2cd259ac6886be464d835d0b30bae refs/pull/189/head\n004167743d32b235c950e773f5fe796254bd1136f436 refs/pull/1890/head\n0041a54d5e9eb8b055cb99411883b793185a171e36d6 refs/pull/1891/head\n004114510eb2cb5c7f81ff192db3254c2f9d36ab22ae refs/pull/1892/head\n004142f2b477cfbdfb31f89659dedf77f61496745860 refs/pull/1893/head\n0041a49be27eadbd0a14ce9d27f924ab38c7aec660ac refs/pull/1894/head\n0041e2c65a1ab9b5119edad38b3d4a054d949ec27bf6 refs/pull/1895/head\n00414a1eef23e039e45dff6096fb1e4d7038484b1324 refs/pull/1897/head\n00415d68dccbbbcb4cabb6914bcd0f80e96422f0107d refs/pull/1898/head\n00417e9977249bab5f79d036fe5914ed85bd19db5afe refs/pull/1899/head\n004087c95a48cf9b44c8ebfa2a35d37762f6a1572f2c refs/pull/190/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1900/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1901/head\n00411489e5e84754ed3aad329ebc32611cd316761fc5 refs/pull/1902/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1903/head\n004161e7f3064aa96e267ae37ddc2a5c9324fb5eeed6 refs/pull/1904/head\n004161e7f3064aa96e267ae37ddc2a5c9324fb5eeed6 refs/pull/1905/head\n0041224a5a70982da890dbf26f70b45c39cc25a67849 refs/pull/1907/head\n0041a149eaa3775e95374637f017e800dd1b5673094c refs/pull/1908/head\n0041241d011f5c0ac29302b40a25b2a926065d0bdbd8 refs/pull/1909/head\n004049cb864e08b729f52808928a2a9ce557e4b63380 refs/pull/191/head\n00411be286663de204d29d04591ed1daff38ff3f46bc refs/pull/1910/head\n00416298a560d7715a672a847fe5e24614e6bc328db1 refs/pull/1911/head\n00411a0b2221a398e516d6844f77b920f81f008177b4 refs/pull/1912/head\n00410d3d2d5f97113e1b91856f35c20d1fc03c4f1f3a refs/pull/1913/head\n004183bbbae23013931adc38b155b79281c0afc5cf1a refs/pull/1914/head\n00414613952f0071cde9e471b982ae651cb064c62156 refs/pull/1915/head\n004198f0cf7a889941a447d74b18fbd8afc932689496 refs/pull/1916/head\n0041f6f3d4ad945b4742e74821ec2fe57b2c9d75fb6c refs/pull/1917/head\n0041eba4115d19c2142967b2abd3e498317980a7ea0e refs/pull/1919/head\n0040c41aedb6b766c1c5c7c9bf214ed36fd1bf35909f refs/pull/192/head\n0041f2945555e9b6873697e1dc77b2bcb1d529ae61b0 refs/pull/1920/head\n00411bdb2cb54e96bae978e7350a447c870660f3dde8 refs/pull/1921/head\n00412e508356481a07c23a8500c50a86f04f45216753 refs/pull/1922/head\n00410fc002df4fa3b5805d3edcf19e304c4fce3fa112 refs/pull/1924/head\n004133bc22e366f010900c8ca27c6221f8b2b835c858 refs/pull/1925/head\n0041e7fcb811dac1d6c07c171a1ce0d90e38ceba5820 refs/pull/1926/head\n0041c5cc882dc859f67c7bf0220c27cd3888c2c4c138 refs/pull/1927/head\n00414de467d648b6edac48ed3270ef1103fce19f994c refs/pull/1928/head\n0041084a1c5cec5a72081d9458db6a93b6bedff82638 refs/pull/1929/head\n00405cfe80f45ec7a361dd2ed1ad3205a40f922560e0 refs/pull/193/head\n0041d2116ca0179389558d7136d4f344c30dc888763f refs/pull/1931/head\n0041c6f867cfa1cff37f58fc159c9e60b3f996a1b34f refs/pull/1932/head\n0041426246d022ea114825a1c083d765fda9d0e38141 refs/pull/1933/head\n0041382b6f29ad0f337672497a4b0ffa3b19102c219a refs/pull/1934/head\n0041c48c9aef1f349d72a986be344987188e330f8137 refs/pull/1935/head\n0041d31656de65f97bc212cf0d8b4f04918b84d7cf72 refs/pull/1936/head\n0041f87710d03aa8a0cf76be0fe2d7336422e2970435 refs/pull/1937/head\n0041a2d40be8c7c3bc359f55015f12aa4c0d24944e38 refs/pull/1939/head\n00412b35b159e21d96c538037fd25b58325729d28192 refs/pull/1941/head\n0041ab4f2902a774fd8c25f5ee2791bb31ec28ed3148 refs/pull/1942/head\n0041f4067f3ef35612f3d51694ba3dcbada4723f7486 refs/pull/1943/head\n00415cb72fac61a833c529759f0fa647e71f7eee6ae2 refs/pull/1944/head\n00419b847af342a4b727a3b9ed8dc46fb4aeb0f6a2b5 refs/pull/1945/head\n0041293e1b459ba2e76c9c2cd5252263ac795893dbaf refs/pull/1946/head\n00412680c976e27942c3bd91707d46c27b1beb8142be refs/pull/1947/head\n004173f816cb70d1e8c0c94d503463a0b08b105e0b49 refs/pull/1949/head\n0040e3257a8fe4c5df589abf5be7eb115bd472bf877b refs/pull/195/head\n0041b4fe07c1984372d91cda304769214afdf87b9b80 refs/pull/1951/head\n0041b73b5b4e9dc9591299ee67c0aeb7fceee06f3af1 refs/pull/1952/head\n0041a9d7ec3526fa15d9537dda54147f648cf9399b00 refs/pull/1953/head\n0041d27a5e3328e2606726bf0f8e62f09dcff05f1c09 refs/pull/1954/head\n0041bc78d3470d7a521c7cf24b5cc4406e97a52e31d7 refs/pull/1955/head\n00419d6429cb59ebe9a2f13a20c7f795858ffc123440 refs/pull/1956/head\n00418aed1058a87d17a67a6e54d875fb81206a85dcc6 refs/pull/1957/head\n0041ee161fd069b80bfbb1292a6f27f1ffc7f2ba22a5 refs/pull/1959/head\n00410474edf70992688d398b983af52a87d4a03a371a refs/pull/1961/head\n0041c86ffbab0f0c9c5ce7729eb393184ba20ce40fce refs/pull/1962/head\n0041956e85c8b84f417b302eeb4d645d1f5df5428513 refs/pull/1963/head\n0041104ec733d3c19dd9d679617df07e2f6231267693 refs/pull/1965/head\n00414447c9e617f14f32acdce6bcc771807d81ad3a54 refs/pull/1966/head\n0041d7672253927e948e6f18dc6277d9b6021b2a250b refs/pull/1967/head\n00400cb945b59925f3612ea2f24630617eb7b10a0fab refs/pull/197/head\n004119891269aa3a37277b394227fbcd7eb154289a70 refs/pull/1970/head\n0041acd7a8aa665b2135ed007af4f6ea67eb01fa4008 refs/pull/1971/head\n0041239e81f8fb51a5aa77e21f47517a4ca8b6e12dfa refs/pull/1973/head\n00415877e42abc56eb8bfbd3eaafce72645d4b3f6cef refs/pull/1974/head\n00414747a7fdfce35ebf31be8179b83c9edacfe8d4e8 refs/pull/1977/head\n00428c8ba4b230e5cfdf2a0c5f3dcdab40bb03a0a16e refs/pull/1977/merge\n0041fab3819ed8176c96379df3a96fc060c6bd36f4e4 refs/pull/1978/head\n0041781c0b371217c18f55466eb507522cb228474ceb refs/pull/1979/head\n0040403251a233aa9572cf5a1f57af8281b1441bd744 refs/pull/198/head\n004169792ce2495948ae2d086548d53aa3f290de6698 refs/pull/1980/head\n0041750e03e96927d3b78a6016d64a17698305136ca6 refs/pull/1981/head\n0041dccc8f2bd46a549aee8cd5535782d04cf4712ba4 refs/pull/1982/head\n004116f4f86033cd44dc9d599b6bd44bbd16de63f12f refs/pull/1983/head\n004106b3ca51b04bb5fb1d45da88c4adaced62f1ab72 refs/pull/1984/head\n0041fdcba2deead127853858d88adad54911f6e97ad1 refs/pull/1985/head\n00416545f54c7866be12e4267735f98771c52109404c refs/pull/1987/head\n00417ac50201a25d62bf105f60efa768b52377939fc0 refs/pull/1988/head\n004136ddfb58948a39a7ed85e6e1ee52449beace1555 refs/pull/1989/head\n00411aa0110d1eb87b2d05063c4828468943243b7fcb refs/pull/1990/head\n0041ef723c65f4a172daba2f1a1e135c556f6596bab4 refs/pull/1991/head\n00417fcd080ce9e3471e06dd0276cf59d0c4ca71fdba refs/pull/1992/head\n0041e738213271e263b02ebfc938faf72cce645375ef refs/pull/1993/head\n0041cea3f7fcf79ad3cd6b2b28bc0294e864b3a5a05f refs/pull/1994/head\n0041687cae8512e398f298488eea297f73dfe53072ac refs/pull/1996/head\n00416629856ab6b7b0a32076c47bfc85011f20ee33ef refs/pull/1997/head\n0041bb915dc2f5b2d12605f37262e392f8ebf4dc6235 refs/pull/1999/head\n003e227289e2e18325309196e553f26cf06741e5a871 refs/pull/2/head\n0040ac897909866cef27ee70748dac547290e8339b5f refs/pull/200/head\n0041c13380af413e66bc91d76d77cf3531e7140c5db1 refs/pull/2000/head\n0041400d01e27e6e77c6459a3f7324d531add8e46a87 refs/pull/2001/head\n0041d5de53fb00ce28af6e9364bb3182ff6af9b30743 refs/pull/2003/head\n00411a17fd60b55f021fc1a84bc06d1475c4ed78cc82 refs/pull/2004/head\n0041f3cb06daa4dbe5411c65e35e8bfbfa37dc7fbec5 refs/pull/2005/head\n004161b1b3b78a534a0184cc77e86f33709e6be1bd6a refs/pull/2006/head\n0041b6f189b0beefe056d6dab787ddc74a807ffd9184 refs/pull/2008/head\n00413b80b5f5f8a59cd6aa0b3101a358e48293d14c5c refs/pull/2010/head\n004107f397ba9a967171f4afcdb3b1b8970b69e9c9e3 refs/pull/2011/head\n0041d16293f947aa812b4b2b4d1ebfbb0c89c210a050 refs/pull/2012/head\n00419ff5de4e3b6b25f950ec5434744c7c133935a5d3 refs/pull/2013/head\n004124dbffe5565019bec56b4c22c2bc5f4a13aa8fd9 refs/pull/2015/head\n00419e147c97b5f8b278393343d4b8bb677f7eb0484a refs/pull/2016/head\n0041c1adcdcf02d6893489bb66db2bc5e15989362962 refs/pull/2017/head\n0042843e8a1c7442b51022506746015c4bd21a65832f refs/pull/2017/merge\n0041836e42fef0c279835268be30efd3464e25922110 refs/pull/2018/head\n00421aee22907b4122dc19d852195cb93dabcdf34667 refs/pull/2018/merge\n004165406a5f6751e7f3cedeccef122ad18c83947a7c refs/pull/2019/head\n004100e067a8552159498597321528fbcdba02a8570f refs/pull/2020/head\n00416935cce17323111b68c5aa93c64b2592f8968395 refs/pull/2021/head\n0042771ff68a56721a103d3d659328d1a240c27a7b22 refs/pull/2021/merge\n004081633dd80a91de8da7c784ae4226d1ac2e4294e7 refs/pull/203/head\n00400782f673e6e8e4cb46798e1f1fc1c7bb43b87e89 refs/pull/204/head\n00400043e0c42496c1115bd3d15f1832048c5ec728ed refs/pull/205/head\n004087f71a39fbd1b7ad9c0bc082c1e1bd73e625903e refs/pull/206/head\n0040cd338722bbfbe9cafc040fd4a58cebbd80d6a605 refs/pull/208/head\n0040c828bf499e0a54feed38c3efc5afc2fe5fc59700 refs/pull/210/head\n0040b4fdd96948f5b8f5c4c41ff5e277d8ae84863dda refs/pull/211/head\n0040f5ffa2b991257acf59ad9bc4ddc87de714ce5c3c refs/pull/212/head\n00409a693cb5810151a780868e3d43436e9510c6f62a refs/pull/215/head\n003fd59e57cfe4a038bdb858fc152cd2214704df1af3 refs/pull/22/head\n00406091d46d9c655897ba91cfa65c8004e75b98b424 refs/pull/220/head\n0040f77dcc094a5589ce0d13396121fdc307b184d9be refs/pull/221/head\n0040765c274e85c240ca6a3366c6f0ad1bc6ac452d2a refs/pull/222/head\n0040de452c4fd1246cf52bbd9c4645ceda3de6c963fb refs/pull/223/head\n0040e32f4c7c941701878876c9de2e08518ba91602ea refs/pull/224/head\n00401269a63bcafa0a92f2e1829aef42820fe5454553 refs/pull/225/head\n0040804c300357e5ea865b1f0734ca1b288b9824e0f3 refs/pull/226/head\n0040cd3c3579d2e91ab8315033d631ac0ffd09c1b122 refs/pull/227/head\n0040a685f1407043126b0f9a58178ef646114ee519b5 refs/pull/228/head\n0040cec929e0700eec11fcb037af820b866732aaad09 refs/pull/229/head\n00400475ac938bbb5cb40197427ada059eb5243b7de8 refs/pull/230/head\n00402aeb755fba4bf6a99f61bfe6956ab96a7fb830ae refs/pull/231/head\n004028c2539e557607f01af2209e84acd9e686270fac refs/pull/233/head\n00403244b527077764e80b45b3db7578d73d2c9f5ceb refs/pull/234/head\n00407e700c03f3ea4b69e9d5231aace0f674f2d63b52 refs/pull/235/head\n0040e80445c3c1e0763c426f7b92d78f091b23380b5c refs/pull/236/head\n003fde471304b8809039fa0eeac16dd7b0be485ff4ed refs/pull/24/head\n0040e9db3e9b11ec62a54c3d577611ab731304399ce1 refs/pull/241/head\n00401deb6dfe2f4fc45c29c0b8d71b56844537b1c67c refs/pull/242/head\n00407829710f4a46c40f293bec37928b367c59d68356 refs/pull/243/head\n00402f3c672384d91312a1f8eff3a96a8aa23f34d4ba refs/pull/244/head\n00406e26224a25fd1ce7a69fa5a553f0742da30b3954 refs/pull/245/head\n0040a14d46ec3fd2d50347228b6ec12e2ea49fa1d3bb refs/pull/246/head\n0040bd318a9946c88a8bad7b7db9e3c7d309df7fb714 refs/pull/247/head\n004081c462de5b4be77a18f6502d55134651af4e775f refs/pull/248/head\n0040df4007f74aa72f3d1c03d1ce0daff237761d088a refs/pull/250/head\n00401635f714a5495f687e45782b4ab66eb42d0c7a08 refs/pull/251/head\n00405111aa6f732a44a92f5fd0c19d8186b9671894ca refs/pull/253/head\n0040a4581e8e3febeab26d866ef77ae26f9c8f8a26d4 refs/pull/255/head\n00403c14d051f305a0be658ecf6c98642517847c8f80 refs/pull/258/head\n0040bded0848d146eb0c233aa9c181326d4680ac3e8f refs/pull/259/head\n003f79a28b7545d178137db83f3f8adf14455feb0793 refs/pull/26/head\n00406f31d66051f2490c45b29e9d6c84eb08e5544417 refs/pull/260/head\n0040cbeaab2a51502e8fbb829d84104739850f50f068 refs/pull/261/head\n0040188d8414f7cc1aeb0a9e1e7668184aa56b33b2eb refs/pull/262/head\n0040ebc362b72806ffbfd769c3d19cc7f204173a4c4a refs/pull/263/head\n00400b1c90c84ac51778da84eeb8a9b9689416443f31 refs/pull/264/head\n0040b682d5096051e654e480cf40db1107376dedd37b refs/pull/265/head\n0040ade33a76ac1418ebe9b2f6ba5b3f1d776d024819 refs/pull/266/head\n004062da54e9be99730f0d89ce47f4d71f473e50b6cf refs/pull/267/head\n0040cd4ff5624fd65157528f2243cb21902ef82a6ad1 refs/pull/268/head\n00404edc393c56d4a2c0b4c7c8125752a8959cd3c965 refs/pull/269/head\n003fd665b8e6478068d649547bc2d36001d73163d35c refs/pull/27/head\n004090196e06eb596a8146b654fdef4865f90b7365f2 refs/pull/270/head\n0040355fab7e85adc982f1b4c6882b1d14ef73044e3f refs/pull/272/head\n004031f12be9970ed4d54045ceafaf65e0bcbdc9060c refs/pull/275/head\n0040a56387b3d0238a7cb9caa890fcf9150431729069 refs/pull/276/head\n0040a56387b3d0238a7cb9caa890fcf9150431729069 refs/pull/277/head\n0040f4e8069053317029a562949ecef0588e673abf61 refs/pull/278/head\n00402c1324f1a384dc7a18da5813abe5eda51093d3bf refs/pull/279/head\n003f70245086ba4738f4266d106af3b6429eb8c3ce56 refs/pull/28/head\n004044bdc18aea9dbb0349b32632f14f023f8eefd97a refs/pull/280/head\n0040ffe0898a49f91a88b5fdc9a963f94f5f5c5ab18f refs/pull/282/head\n00409dad380b4cab356a4d2b6395385b574eadd1f5d8 refs/pull/283/head\n004045715a32c2c17873335d8395f7bd43e82350fcb0 refs/pull/284/head\n0040f0ee734e0d67527235535c6655e886502521999d refs/pull/285/head\n004002202ee16193ae99ed3e9bc0f3ec883817dd05f0 refs/pull/287/head\n00404af00d86c44190de13b0e33f7dd6124ec77a29c0 refs/pull/288/head\n0040b195c1fd6d2482925035f697f217858c13b53a0b refs/pull/289/head\n00405f5747b92835d52d3032a26b48dacfb9ee2e16e9 refs/pull/291/head\n00408ad902c7c63a0f8e8d61f6fe04db1b33d4d7f005 refs/pull/292/head\n0040228ce21d0de6ebdf1952339796217012eadb01b8 refs/pull/294/head\n0040f9f993d981188015c1fab9e172c311de87082969 refs/pull/295/head\n004013bd1e82b3c584406aba45e1946ce294741e5bbf refs/pull/297/head\n0040ba3899886a590ca291ac8f7fe8d7fcd283b2bdaa refs/pull/299/head\n003eb0925e528c75d05cdc7b8f16ac500a7d3912560e refs/pull/3/head\n0040244efc9e6c61ed99462fa3e0bcc384ced1cca269 refs/pull/300/head\n0040452885a114b0fac92a7e845d2cc569af066be57e refs/pull/301/head\n00403cfedab773da858feee8541a4d738c7c73cb7165 refs/pull/302/head\n0040a176487c59caa1e9624b2d6406fead6aeca35067 refs/pull/304/head\n0040578b91862234ed8650ad5b03d7914d321c5f25f3 refs/pull/305/head\n0040d162837f8c08ddd7f6c9fb0e57c5c54e716db886 refs/pull/306/head\n0040518a444c79e345c0af1fcb4a4ab6574bef9e2acd refs/pull/307/head\n0040bfa275ba908f2fc6c9e4c209a06fd0f3f5905945 refs/pull/308/head\n0040c4c262a69c96ef6baaaee4fec325dcc5c536fa73 refs/pull/309/head\n003f90a7b27592c16171aef9a594392bd29164fff1d3 refs/pull/31/head\n004069940c13df4aeedd8d1adadbb4da52d2c4a94c77 refs/pull/310/head\n0040ac5232576700b8417ff859ab5f30a2c001653fc8 refs/pull/311/head\n0040fb0320867173cac3d6f85975b6b7bda9e298c83a refs/pull/312/head\n0040367f11a8e1bd75b36ee23b4c2277038e9dd2e1ae refs/pull/313/head\n00401af06d7061c8516c463eae852b60e4ad9f46ea25 refs/pull/314/head\n0040679e0336f1392f76424b5f0672e0af7fff45167c refs/pull/315/head\n00408da272d57f0f39905dd31aca1b6ff13e7b1f6554 refs/pull/316/head\n0040cfe6d7502821f60c09be0f6de2548ac952b01696 refs/pull/318/head\n003fb0aba74dee21251e105f3067868cc12278b5c528 refs/pull/32/head\n0040c4b08a881d301278195a9a902e4440d69b62f4c0 refs/pull/320/head\n00406e1e91f74fe00bb7254b52f514c106c2750f7ccf refs/pull/321/head\n00406cb0397d29f40047caaf1afe3cc671ecc9a490e6 refs/pull/322/head\n0040197ba229808a1f56d29682b95604d0bd6dc07335 refs/pull/325/head\n0040ad1da8a30d85ee2f2fb9aa118306c7bd6d83a013 refs/pull/326/head\n00403b3acfb7788ea4ddc1d6bfb98be03010f990264c refs/pull/327/head\n0040296d51fce4ae51ebb86c55829540678e60086e69 refs/pull/328/head\n00404af7cfdb68e5f3873f3eb2951af1369124988998 refs/pull/329/head\n003f818b4acf27ea1a15cdc1044330644c1cfa73b538 refs/pull/33/head\n004016e40c6af662eccd5bac877efd8cb6cad6501abc refs/pull/331/head\n00406f61a385ea76b457e49c89c0fe763836ee64352b refs/pull/334/head\n00400fb139e0f229bc3bee5f9d1c2b69fc3df2613408 refs/pull/337/head\n0040483bedf9124ca525337bf7a51194d6a352b3fa86 refs/pull/338/head\n0040ec31c6ccba4495a70e8e4eee3c9f35d5774a2bb6 refs/pull/339/head\n0040aceaf23725e2998c8f1ee4256ec1e98e837c751a refs/pull/340/head\n0040dab94e2d57cf5268aa46731e32be1cabc696a10b refs/pull/341/head\n004094b2648690bdd3d0e7701bda97012daac2bec1fd refs/pull/342/head\n0041367ed8cf1af506c62f5805340135b1616a33cf84 refs/pull/342/merge\n00405e5f6f1b00ed85e49ceafa6f092a9c73cd03c0a6 refs/pull/343/head\n004053721a8c18d17db62e3b579b9d51445a1d15ced7 refs/pull/344/head\n004000238d08c4a3a69d06adfe671928d21fdc5a4966 refs/pull/345/head\n00409e295e32d9aee35e3b7b82fbb5cf10237082cc55 refs/pull/346/head\n0040569b889262dd6e9d0ed31c3ad1a32647699cf6bf refs/pull/349/head\n004020eb0206c2f505cc055a4b012dea2d990848f585 refs/pull/350/head\n0040675c714afd33ad8bae20c1fdec1b89ad4123fefd refs/pull/357/head\n0040447943be37d3912c234716fee8c1c0e41f9d29bf refs/pull/358/head\n0040c5be3aefedf19e587aab82d3091efa8d45f5754f refs/pull/359/head\n003f2226ed66e79beb15cc0aa6a1f599ad999d829026 refs/pull/36/head\n0040d02d40447e6e1f04697e71e23043dadb54336fca refs/pull/360/head\n0040c6d02d122f65ce3550eb002e4cbff6f1307aaa6a refs/pull/361/head\n0040eb3e1ddd638cfeca39122a136c247d1dc4f639db refs/pull/362/head\n0040e74d30f2000b48af90ed4d40333618a50ecf9292 refs/pull/363/head\n0040f505c84f7c30558bf21fc55c88e021aae320b4ea refs/pull/365/head\n00400cd0f763dd8e79f247086d2718f636f139b63360 refs/pull/366/head\n00406f850b316daee1310b1b7f5af78a1efbb297db2c refs/pull/367/head\n004031c5b475c76fc045af9a0c78a20ebcca0e983e14 refs/pull/368/head\n003ff1b5f2257493f1769c4b87cbc89e7d7ce11dcd5e refs/pull/37/head\n00403910ca66b0bdcaefc605889f8a425a7fcb1fc682 refs/pull/372/head\n0040795ff641608bc1c23fbf30494e5d869c9da8cfa2 refs/pull/373/head\n0040a649e78a5ecf126e7d2b3aed6d65e0015b0337ab refs/pull/374/head\n004078e74531d1bbf5545f54294cb5b131c47eeb2bb2 refs/pull/375/head\n0040d0ac99e0512f68372640dc79713a4fdcf8559924 refs/pull/377/head\n0040bda25dfdceef3467a832680f34bfe0cb0e912097 refs/pull/378/head\n0040630295e76f43697299d8628ac7fb1ef95f30a7f0 refs/pull/379/head\n003fa870caf05460b3bbbe2eb448b6c0d18bb263ed5a refs/pull/38/head\n0040f64c8f85cf710376d0f9c07b200deae640baf566 refs/pull/380/head\n00401cbd09531c7d54743f1318badde9b419a63b1ef7 refs/pull/381/head\n004067f69495b71106e669ca7e0862dbcf64dacb078a refs/pull/382/head\n00408ceedaae6815215d6ececd8f210bbf9eb22d868f refs/pull/383/head\n00403b04d0aa87bbbcc628a31e4d69e829e7a7deb866 refs/pull/384/head\n004018467496d52836381889895ff676a9a87ec4918d refs/pull/385/head\n00403088dc4790b8831c4c62746d69b22bdb3bfa8469 refs/pull/387/head\n003fca28eb9ea1cf459ddcf751ffb0bd705837469ce8 refs/pull/39/head\n0040bff474ba2e69f0fb335be9d77bb49252dffb3ac2 refs/pull/390/head\n0040c56da2f6a8cd95e3f902847db9ad69eb92732813 refs/pull/391/head\n0040ce1db0fb6a3040392e4104434db266b01af4ee2e refs/pull/392/head\n0040d6b8f53795a4b4a4ce35f780ca0f86995bf7c93d refs/pull/393/head\n00402a7d3a655048ac0962dab5e722b0b04413a05502 refs/pull/394/head\n004055d36bbb2cc26ab2f52ed1eaf8f8ebce95415ed5 refs/pull/395/head\n0040b0e9a00ae59ec00c720301e0cc4db28dde5b4370 refs/pull/397/head\n00401e1dbb6849844d4083414fcf7c3db45d9564c324 refs/pull/398/head\n0040a2af12c43c384e72e328807f5053f05dfc2c02fa refs/pull/399/head\n003e6cb9d7bef7abd32798513d84a8c314dba0b4e812 refs/pull/4/head\n003fd25e61e807da4721c86ee9b36c89a80be8dfe526 refs/pull/40/head\n0040dbd66fcd24b4da5ee22b8beed51b1f06d3a69b92 refs/pull/400/head\n0040242969ab05f09e456b757c5e1245524579d9e3ae refs/pull/401/head\n0040b5af6c719caf8f4e51b3195039a7de926a0066eb refs/pull/402/head\n004087147fa1361efac6e22afff849f0840977a9c60f refs/pull/403/head\n004025308263154455941508385550e41dbfddb025bb refs/pull/404/head\n00409da0dc32c7654dec5b99387398653c4fbe1b5018 refs/pull/405/head\n004073e271dc130e54179aacf5ce46330e15dd9f1fc7 refs/pull/406/head\n0040713e8e5584e0182509291b17432573ce7892fb85 refs/pull/407/head\n00404d4bfee2296419d539fb971e814f675ac8214aa3 refs/pull/408/head\n0040118362bebf75f74e303a3f935d68769043a2f211 refs/pull/409/head\n003fe5050b593f17f4ce4431237656be76fe82ff852f refs/pull/41/head\n004035d293d2aab96ccd85208099e10c59b17ab1ceff refs/pull/412/head\n0040f13fb6e6fffb48b230951e871eba70b79b661fed refs/pull/413/head\n0040d625d77a400b5d956d84b2da92c480e5503cfe28 refs/pull/414/head\n00407eec67d424846297b7fa4e541f6e9efd41cd954e refs/pull/415/head\n004023fffc505907c6791eab950c89097a2e5f586ed8 refs/pull/417/head\n004003bef894e0bb21f55922dde797566629c68cb5b5 refs/pull/419/head\n0040aa90aa17689f3fdd364b542ae163e8dbbcae95a0 refs/pull/420/head\n004084ed687790904e855be5e1529abe8680402343d0 refs/pull/421/head\n0040fac9453409f869f24ead55efa206c2be2e3b2c25 refs/pull/422/head\n004042ac66f2fbe36b19865ba80e9974a6b7dde24e8d refs/pull/423/head\n0040c6d54fa4b5cab1d706c1a9ec379eb6ef646a8fa4 refs/pull/424/head\n004022155f2840be77e5cdf86e7c0de16e0e525182ed refs/pull/425/head\n00406298f31b4fa7fbce1e485dd4331478c8496bb19a refs/pull/426/head\n0040b25f94af1cddf24dbb394c98b2a27d2c14656ca9 refs/pull/427/head\n0040f88a7c790208a132fc982d9e05b3ebaf6498579f refs/pull/428/head\n0040bc9a53c78de9cf65b4f4c59c6812816fb58acf6f refs/pull/429/head\n003f365fb02ab526ded787f5e7a668b7f556b2a65f0a refs/pull/43/head\n00403adc71e200004feded19aad29f314a8da52211c6 refs/pull/430/head\n0040c302f0a6fa9667c918d50ad58737cdc728ad1d0a refs/pull/431/head\n0040eb065c53919a796a1a759c60da36142f7a950271 refs/pull/432/head\n0040da3fc3288f7a7b38d3ce9c4ccf488ec7102e5b48 refs/pull/433/head\n004053fcef8335dc34ef5d9a7628e6d609b602a0c075 refs/pull/434/head\n00407b822473f9ca8e5d8a2668af42cbfd4ecfcb9008 refs/pull/435/head\n00405370eff763402f14466bb66e492b8494769985ca refs/pull/437/head\n0040fac9453409f869f24ead55efa206c2be2e3b2c25 refs/pull/438/head\n004075277afc9e496dc8e2b9a984debb55c5b143483f refs/pull/439/head\n003fce48f8e7c40dead8e218c54f81ce5d6f553e7ac2 refs/pull/44/head\n0040f9dd53b273558ae02449adb6e60cbe36e3c760f0 refs/pull/440/head\n004083aecd97343321b6dd92a4a9ac753684f5a4545d refs/pull/441/head\n0040e05c257b706461fcaf01b37cf77c8c3b6baa5992 refs/pull/443/head\n00402b016af7334685b7c023c3069680c9aa314f191a refs/pull/444/head\n0040a434231571723de01bda5d058d1c336993aea91a refs/pull/445/head\n004038aa30a94c4be5a2dee06d1317809fdb82023a4e refs/pull/446/head\n004019b4c69d67c02f1ffe97680f69edaff54f853947 refs/pull/447/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/448/head\n00408d72b44f90df3b5478e73a456f36d5e9f579ef95 refs/pull/449/head\n0040a29a32905cb78effcfa3bdd798a23bc671dc388c refs/pull/450/head\n0040be8afa6e456327a7a240289ef3cacd76d6a532b0 refs/pull/451/head\n004094c7eabe76810c3d58aa01d0ad84f3779c5f2810 refs/pull/452/head\n00401735f06d84a1871f51c2796cbc65945e7273d8c8 refs/pull/454/head\n004078b95e7dd680cfcb7b3217152cb13b56a98973a3 refs/pull/455/head\n004005180116843d9e7a5a8e5932c3082f6412cc0dc6 refs/pull/456/head\n0040d26c65041ee8adf4c946334662c27f4400b05728 refs/pull/457/head\n00408c52a688057c76028c19df875c08dac9ff17b263 refs/pull/459/head\n003fccdc7a09a9637b6feb5e189f7816c4254688ab5b refs/pull/46/head\n0040fd5723c5943968c5c2c0786b35753a9a8b6211bb refs/pull/460/head\n00401bf029c2f551f8922cbd63e563f3f369a755d50f refs/pull/461/head\n004027c2db76973e960a21b8fb5bfeec6c9ac021216e refs/pull/462/head\n00404e94e29fdf73f8e68b83a6dc9f44a9264a0c5437 refs/pull/463/head\n0040ec910b56daca04df144df7bb0d956e3df11fa096 refs/pull/465/head\n0040210b8aac249fcbaa441dc78d04fd472d36247d8d refs/pull/466/head\n0040c8d72ac9a6be59939f1c8028e13aefa8909f54d1 refs/pull/467/head\n0040d60ec8fb3d02f056ffb34019ae10c987133e618b refs/pull/468/head\n0040282b6be5935e29bdde741e160bb0d50ea3c5ee8c refs/pull/469/head\n003f744298a098c786b0d529d62aa8d1286249149473 refs/pull/47/head\n0040c2c23687b07c5db83bb4fa6379d690de623c95b0 refs/pull/471/head\n00402b5a5d0a16e95df13594fc277fbe22bf354b6a32 refs/pull/472/head\n004083a39d98ea56e94d3bcd0fe77d29bd0afed9c713 refs/pull/473/head\n004002f214b0b506d99904c6a7236db04f134cec9399 refs/pull/474/head\n0040e7732b81e1d6c1a0331345cef7db8f2bac16cad4 refs/pull/475/head\n003ff7513f6bc6f3035cec70017cea6546b163233a40 refs/pull/48/head\n00407b6f4370182cc851e937c54028f107dea3e59330 refs/pull/480/head\n00402b8d96d7a65bac4e382973fc2bacca904150abd1 refs/pull/481/head\n00409ece98a791d30073ee99a5611ff9272ccb7e5356 refs/pull/482/head\n0040b243c02bc1ad90590f8b7f156c23371c3ea03f2d refs/pull/483/head\n00406df8e7087be81fd4b812fcede11fd0e5674e51db refs/pull/484/head\n0040a9fabce3377f4d18e4cc8a9ddf59e580bf24885c refs/pull/485/head\n00402e8657c8f04d205b670b701cc65f9b381c3ded1f refs/pull/486/head\n0040c00ade840a2d93536862d2efa898f300755af967 refs/pull/487/head\n0040972c5c251a09b49d3f8910473f6a7f85aa8c5798 refs/pull/488/head\n0040003cf8e4c2e814646e035a91c31577eff5459188 refs/pull/489/head\n00400b439745a9bb98fb128b84d88ff8cde4ae56a72e refs/pull/490/head\n004068217e9b5600af99ae2740d872ff9984abae5ede refs/pull/492/head\n0040ce303879a732e57f6c188444228900aae0899b8e refs/pull/493/head\n00409c940744e1bea5251308118716419f17eafd299a refs/pull/494/head\n0040f62e29e13a6ec1390e62fb5dcac3361109c5e86d refs/pull/496/head\n004038e9825184d1515f905fc8fda2c25b18fd0dd763 refs/pull/497/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/498/head\n0040fee783eebdeb9cca8719f6971544275c0b0722e2 refs/pull/499/head\n003e9ad0404fd0837ad18816cdb1b2ed5c06533a8129 refs/pull/5/head\n003f143dd198a6b9757a6a8f5f1b920294b6cf63d157 refs/pull/50/head\n00408911da36d53e42c5adc96017aedae08d808f72ba refs/pull/500/head\n0040288bef9d33623e619288b47931ce149df84ae03d refs/pull/501/head\n0040e287c6818ffffeb6647bd70df1f023b19064cbf2 refs/pull/502/head\n004073737c3d3af14d96f9352cfd919a1009ceb8d4fe refs/pull/503/head\n0040f9b47f3db60daf8416a553502c6942252be7dbea refs/pull/504/head\n00404d6c590eb0919bb7730a491a54287347529712d8 refs/pull/505/head\n0040c5171715f1ee79802025ca334f477abdf171ea10 refs/pull/506/head\n0040bfde45b8014fbe58bf2b62819224135abe40b5ee refs/pull/507/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/508/head\n0040d8c9694e9bece1216f77c4d5762cf7534474c5e7 refs/pull/509/head\n00401eb22e3bd0c9b544e10bc6d6e7f737a3177caec0 refs/pull/510/head\n0040e6675ce73ed0f14639a37e13bd038b67b51b377d refs/pull/512/head\n00406e8a392f238709989a97d3d58e3774eb8769b174 refs/pull/514/head\n00400becef9868dff05709b9535c5c426a8990621995 refs/pull/517/head\n00407a23ecd95e89a06cb2610e7b5a715daba9a03d60 refs/pull/518/head\n0040671d51ef3f2bf051eda2a74827f46ecc670e2601 refs/pull/519/head\n004092e6014653cdc404989ba84a26bf8b4b8902ddc3 refs/pull/520/head\n00409372f0a34f7e8b518b8e1a3c905b59fbee76c23d refs/pull/521/head\n0040f3983205d990edf7852cc471cbbcd0d5b96b9426 refs/pull/522/head\n004050e819818da849783e52a788611bcd772b0dff95 refs/pull/523/head\n00409ef1ff9f8685b666b934233c793c7117ead48de5 refs/pull/524/head\n0040fa66564115190d4b6d9e4f175f2401a3dd97d5ce refs/pull/525/head\n0040db20f4ca5a6a7e64ec2cd3471c9df9e43e43cd0c refs/pull/526/head\n00402a169ed865d0e2061779fac51ce8dc4e0de9aac1 refs/pull/527/head\n0040611a2ce0460467038b2567dca6f55bfd16f57ff6 refs/pull/528/head\n0040dc53775c9a44a88350301e29029f03b02ced623f refs/pull/529/head\n003f2af6d94aa0eb7930fb1fbe6d089f8fabdff11d02 refs/pull/53/head\n004092e6014653cdc404989ba84a26bf8b4b8902ddc3 refs/pull/530/head\n0040e7205c9eb73af5a4d92f7b7a8f176da461321d47 refs/pull/532/head\n0040ab8999e350e2eee93fdfc42bcc6054a6f34ce159 refs/pull/533/head\n0041018853cf7571d2031680de6e71ca7a11f8850890 refs/pull/533/merge\n0040941f031b04f6f7b39ecab9acc4ef4d6ebdfe25af refs/pull/534/head\n00400f5f7deb892f49ec54bb3878f9e3417937b0c347 refs/pull/536/head\n004097e877ac458a0335b541a2eb672a71483d39ed61 refs/pull/537/head\n004046b389d18db064c2edbe426768122cce9778709a refs/pull/538/head\n0040ad815f7e5bddb79d59865a1d91f582ab22df03ad refs/pull/539/head\n003ff6f7855dfb3acfdb0f14cb9215a8e7e8d29eb625 refs/pull/54/head\n00401454913de36b573e23a0aadc0d110009fa0b786f refs/pull/540/head\n0040452ea9a2ee332ba1d508eeb12bcd128ccfbf4eeb refs/pull/541/head\n0040dbc8ec0b247f7d39aea584841510e8b1f6bcdd8f refs/pull/542/head\n004096702db9d37131450a18e2fa4ef2f884cd7d11a2 refs/pull/543/head\n0040b941dc49583d4dfdd536806838fc3ee2c9309381 refs/pull/544/head\n00400d5c78fec78a219b90901036b2ae71137cf4f49a refs/pull/545/head\n00409ae6da12c3e8b0f9e47add5d26ea526be0dc627a refs/pull/546/head\n0040e3fe40ff3a95653d1a73ffc02252081b537cb6cb refs/pull/547/head\n004011fde285f72c89c9eb3a358e44b5a488aa0b6f66 refs/pull/552/head\n0040ce6d89c6ea9a9758d671a55a853f1defb4ff0919 refs/pull/553/head\n004080f883932c1e051f1ad3f72d6714e64c23e12d47 refs/pull/554/head\n0040a8ace595e99e563f8cd6cf3b847f5dfe4fefaece refs/pull/555/head\n004008aa09bb654cfde77261dcbabbc47b12f11b94ac refs/pull/556/head\n004001caa3f704de8f5e4b0bdc470d1e2676378263b9 refs/pull/557/head\n00401af75607f98ed329d14652931c799ed3cc7f7b3f refs/pull/558/head\n004090813a3537904c85edf184c2970211585449f507 refs/pull/559/head\n003f7dfe71ecd46059b7facd8f11fb93a05f1b421050 refs/pull/56/head\n004044cd652740030062b68dda4a8a2b56bc05f207b0 refs/pull/560/head\n00400333e8667a5b82ef1f69545435bca768ab96fc06 refs/pull/561/head\n0040f596832b8f409c22c032f06f0c390a5dfaacb453 refs/pull/562/head\n0040dece033ec7efe073be6c10647630c49066af7820 refs/pull/563/head\n004036db95b603e189a7883c9f8f8bc2c8bd237d94cb refs/pull/564/head\n00403a8dc1fc9d8190fb9dd3e769a0051f0ca58087eb refs/pull/565/head\n00408d8f35aea1b0c6024a29e0eadc2dd1cf6ea61588 refs/pull/566/head\n004039238b7f7a499e03b1f473b86a74dbae40ccc912 refs/pull/567/head\n0040b941dc49583d4dfdd536806838fc3ee2c9309381 refs/pull/568/head\n00404b56f4a28b5d39345eace17e0d5ffb82c0aa475d refs/pull/569/head\n0040b9797f4f65edf2a6d146deeb6bb8402574257cc3 refs/pull/571/head\n004061b9d6fff795b8a874a0cf7ba6a54cd557a207dc refs/pull/572/head\n0040c8c2d067a865421bf9ba2b8b25d27f263117d200 refs/pull/573/head\n00401fd09206f6e244f0099ad1caf2762b45f3f219dc refs/pull/575/head\n00403fb44a5c9ae5532d9b0588f912d3c4fc6907db2b refs/pull/576/head\n004058454406ad2ef5ef4dc7b67c51c0e979ddbc9075 refs/pull/577/head\n0040f936f2fc0d12ad55ed359a587237483cbbfefb42 refs/pull/578/head\n004028f167b17c267c89bd3e7f02759445c20f8bc2bf refs/pull/579/head\n003fb582e52794750d1ccd15c5e702a68467bcbf19f2 refs/pull/58/head\n0040903641cc13760e8c892640cdcc71fb3a79a00b70 refs/pull/580/head\n004089c03a1877f2a7863a28f204473117a234ef7fd2 refs/pull/581/head\n004012d40ad087dc3bcaab323cfe3caa5390c9368427 refs/pull/582/head\n0040e319b913fb9e89a6c74f448bea5772eb1dee3c14 refs/pull/583/head\n004025066b319e0909a1481becb5116e90bd9025454b refs/pull/584/head\n004011542a56a0898605a28c088d7ae6f186fb4b3918 refs/pull/585/head\n0040e69d18e13dc36b2ca7099d3b9223a7041490e4f0 refs/pull/586/head\n00408e430dadefadb1c567902ab96325a81222ae5300 refs/pull/587/head\n003fe4aa79a3295e8000fd1ece79a56e4d3faf8f80ad refs/pull/59/head\n004055fd5ff1c67649944a095fe9b8a82a45f68e3dcb refs/pull/590/head\n004081fbf50e37593dde081ebf0b7b1de2d25880d037 refs/pull/591/head\n0040b21e3b766dc022e144a2b8b67a076a678b932743 refs/pull/592/head\n0040e047d701f4c8ee52b14b87999ffe08b7421705cd refs/pull/593/head\n0040f5babe3c3abea9f48c48f50218673c60d3cfe751 refs/pull/594/head\n0040e35836392fd209337d97336bed2a2906f47580a4 refs/pull/596/head\n004028f167b17c267c89bd3e7f02759445c20f8bc2bf refs/pull/597/head\n0040acee602bebf073fe15335b7c8a79c07fdacb3687 refs/pull/598/head\n004069567222b388afa940bd84190b455fd403f75e9e refs/pull/600/head\n0040d889473e50a94af92096f4f9bd8f2a567c05534a refs/pull/602/head\n004026db8a5a64f7aabf0a5026db611413ff295fbd64 refs/pull/605/head\n004060fe2d5d3466b5e820dd1820fdbb893259745e1e refs/pull/606/head\n00400742c085ee268fd31eaea0dd8da74b0a04d1181a refs/pull/607/head\n004098f261769a6f5b192e8c5e1020bb33c6fbe2a457 refs/pull/608/head\n0040a4ae0bf87f13851dd0fcc0c118e8b2b4323de212 refs/pull/609/head\n00408782289280bee40a4e94b22a37731d349493198f refs/pull/610/head\n00403057d4a45105c7d84baa25a5875dd1484684e337 refs/pull/613/head\n00406b658da55604658b5e8e78d7396f1ee23746f548 refs/pull/614/head\n00403df6522684ebe78a210046331c49a4615e85254c refs/pull/615/head\n004083a576f28c4b6727b27d6d94645b9f3932463787 refs/pull/616/head\n0040b85e4f5d37c8e04d55be31dc14ddd34df2f32e24 refs/pull/617/head\n004005ad248090b82fa57c14e5d9f0499a2cccc3106c refs/pull/618/head\n00402719b26e16e4a529361e35d25c2dad9b41a12ac5 refs/pull/619/head\n0040f6a203eda01006b94f37b53c4e776b6c1a38b7be refs/pull/621/head\n004060a364d8573ce2541bddb70027552ca69cdf8698 refs/pull/622/head\n00403f2a95ae1c6251412179f57508ce34c0827a8cdf refs/pull/625/head\n004004ede1c6a7f8b25aadb264f35efe7594c881ee0d refs/pull/626/head\n004063208318dc286d35a9e774fd203bd2c4a6bfc2f6 refs/pull/627/head\n0040372613e728da9bd97a30d01b60f32bc692fb996a refs/pull/628/head\n00400c4349e90f13c574bf46190fdc8c29efccbf51ff refs/pull/629/head\n003fac28fb90a951fe0a334e8ea974cb9d0830f8acb9 refs/pull/63/head\n0040f320b871049b7a21e25bbd9ecf6628b006e63db4 refs/pull/630/head\n004078004fb399747b6ddeadddb3a38f07a382061f8c refs/pull/631/head\n0040e6aec7aa5cfd7640aa939fb32609085cd9d35257 refs/pull/633/head\n00407b890e47285100f3b8d108033b37759725fe1e48 refs/pull/635/head\n004004ca8160cd3f3fb51d0f0e70dbc83710d954331d refs/pull/637/head\n0040f055bed5b72214f3e25286d69a5ea8696cca7d25 refs/pull/640/head\n0040b8ff2c64f502de807a09adac61b8da0bd7db5ff3 refs/pull/641/head\n0040776d6d46fbe8a70dbaf0791f63c1990bd881a3ac refs/pull/643/head\n0040d5e7494e5045f834569e278a7c1b44c91c53ee4d refs/pull/645/head\n00408caa1bdf24ad0303bd5d51de6984381354e41562 refs/pull/646/head\n004092b454d6524c3ab1eca4d843a37dbece32c418a2 refs/pull/647/head\n00402c4e9ffe944ff579ba992cff67c2130521832b0b refs/pull/648/head\n0040826a3a72341a4062216a56292d9626ff8cc76b6c refs/pull/649/head\n003f936df80471e524ca4e30d4bcd9c6bf2da1619dea refs/pull/65/head\n0040922bd29d0957d2bcecb3a4acf4b88973bed7621c refs/pull/650/head\n004061545d6eb37dba9adad76de739ee55d67aefa497 refs/pull/651/head\n004071302a5f59faae567849835faf47f419473b4d00 refs/pull/652/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/653/head\n004011d7a289c85480c74b3a274f22b99fafde4683a7 refs/pull/655/head\n00403069934324473370c83c8da418df32881dff9d85 refs/pull/656/head\n004085501cab1f30c5fc7475b51c0da19c2c474a53ee refs/pull/658/head\n00401691abc91ed22323c7e4b6517fa9d35aaf08203c refs/pull/659/head\n003f816891117afee70c3b6ccd7a3e4ed1f91bff3ba0 refs/pull/66/head\n00406cd1cecf9f64c545b2458bf2dead4918e2614cb8 refs/pull/660/head\n0040944eb940569b05e656637511b5657f302d14906a refs/pull/661/head\n0040a46f29da0320caf0138193af25b903d78d590bc7 refs/pull/662/head\n004043e604f269b6b07936fab6c787d32305546f7a2a refs/pull/663/head\n0040f37072f8fc388c8e9bd7bdf4a9bc2269e225a5b0 refs/pull/664/head\n004046fe9ce1d6955b1e123a836df17dbfcb9cffcd8c refs/pull/665/head\n0040bf2c8d5ccfa0c12de5874bb0f45e6a5ab9e3afff refs/pull/666/head\n00401de22909ed1996aa641ab70a9c986eb0ede742a2 refs/pull/667/head\n00401ff1cdd255e44061a2f78d235df584da00b5a6ba refs/pull/668/head\n0040892b384ee4a135beeed67fb0176fd6c04b0f83a0 refs/pull/669/head\n004039b922c380d8428d988b190c8c7b94344eef6a5d refs/pull/672/head\n00401b0311dafea5b3dc2f0a58a0635f79dd2b3224e5 refs/pull/673/head\n00403332370700ac736a5f312922303589efc41d8641 refs/pull/674/head\n0040621291bc9ff0cd5b64be7f7a31f33a77ae00c3b6 refs/pull/677/head\n0040840d9fc1b24479dc8adb5c9e0529055b1a1cf05d refs/pull/678/head\n003fa97e2e51ee5589d1ff14c3248043f2f62f8a26e5 refs/pull/68/head\n0040c93e9b5322e726767eb154411faf828e1ebfeab1 refs/pull/680/head\n0040eb439aa8b43ea43350534767e748aa6b8cf89a9d refs/pull/681/head\n0040629fd9edca7e930f1ea146db0becb0698d10e50d refs/pull/682/head\n00408e5a46bdef1cfe0e5705f48a3b18f99bbe78da0f refs/pull/683/head\n004066b76d0333cd0bf7c262dbf354821f7853080a79 refs/pull/684/head\n0040a123ccea8a7e5444faee428d06c0de3daeec4d27 refs/pull/685/head\n0040ed24702a797fee16808e0e2b27299fe63042af08 refs/pull/686/head\n0040973ceecc1638cab69ee6f4d61710f9d7d3d5efd6 refs/pull/687/head\n00409eca1945adb78d495b7ea37f416e2537b4f87562 refs/pull/688/head\n004056a659057ab574138c55b2692ceeae2645d91eab refs/pull/689/head\n003fb6dee38c2d63797fdcec086779098dc843480a69 refs/pull/69/head\n0040fe42f7d66c778a6915978d7e5eaf66b6b82f3b9e refs/pull/690/head\n00404698b3a302ef8ff9f30093cce7866acd06b434d3 refs/pull/691/head\n0040c27e84c8ceb61593314ab913a62b28edf5ec5f08 refs/pull/692/head\n0040f2f4eadb64d52684babf6d2ddb1000b5675366eb refs/pull/693/head\n00402524e022c98d1234669b3455f447478b9c81011e refs/pull/694/head\n00403d337516e9638647ddc1cfd69bf9a66934c242cb refs/pull/695/head\n00400fb585f54f7d8df4f4b73ceeef9eeb23fa3abe20 refs/pull/696/head\n00403bd465be77b51dd671871d913dbec3199b6ce16c refs/pull/697/head\n0040c7b9817cdd0a628e115179b386622e2cc89977da refs/pull/698/head\n0040b2e84be34bba70cc9488b7eca43c8d61aed1795d refs/pull/699/head\n003f9b874c5b0a86f1d65813d47c6dd78a6978754d8d refs/pull/70/head\n00403b4004263226b700f218533a4d5f1fdbe3b9be01 refs/pull/700/head\n0040a831edb9b6a397bd7c3698263e7b13fc495e6711 refs/pull/702/head\n0040f20fb3088846b39a337247e110ea304e19d14380 refs/pull/703/head\n00404e5d20976554ebbc88942d8514a35b9100e2dc09 refs/pull/704/head\n00409aa5d9b5ce1574304e420eb687c343729b204f12 refs/pull/705/head\n0040f9ec83f0c814ad9e737c5297831387adbcbcf0e6 refs/pull/706/head\n004011e1b7f9cfce840f6740cd5d3b91cd0de92a45e4 refs/pull/707/head\n0040a6fd606a568c680ccda176fb957ef4e7b8298603 refs/pull/708/head\n0040e63703543172b39ba8d76ec033ad5f858ea1e3f2 refs/pull/709/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/710/head\n00405292706433f41e67862c2c820b28417ae5a38e6b refs/pull/711/head\n00402cf888c8a56abe135361400475651f5b6ede641e refs/pull/713/head\n00402f795191896af78604cb103ea410ab491ccea85b refs/pull/714/head\n00409e7e84192717765fc65f41f106004429e63f2d0e refs/pull/715/head\n0040b992c004b36fc196874673a908f2d1bd22e318da refs/pull/716/head\n0040d60a5b259927e4f583d50134a96d23474e25620e refs/pull/717/head\n0040345d2baaadcf922efd507f05aa57ca6d8ad5e94f refs/pull/718/head\n0040cf764d67334bcc631c3412fc1e9e3743e20bfd31 refs/pull/719/head\n0040ed8e92f8a37c67095c6a3e2d3b021a9dcea510ae refs/pull/720/head\n0040139a03596c3e6dfb1a80bbc6877893c4c7fa64b4 refs/pull/721/head\n0040267acb6858c99d595411265d0535d3efc6af7f20 refs/pull/722/head\n00408bfca2d6e3018541ca05b8c0e3b6e2fa5512764c refs/pull/723/head\n004091ceea20296f42ee0d8ae56a6b44f676599758b1 refs/pull/724/head\n0040e95b8a788552537f9a11c8d12b118358b650d6c4 refs/pull/725/head\n00400ae9453fac7ae281cf31b35e99e04f8b3f8f15c4 refs/pull/726/head\n004053808a2355467a36667756cf17efde378ee3165d refs/pull/727/head\n00405ef6da531c461b0546345f9fbb25acad3e2255d0 refs/pull/728/head\n0040bb837b452ee7fb7522be487be0232740fabd81b8 refs/pull/729/head\n00402a7655ffe65892c0ce95498a36923db4668f09e8 refs/pull/730/head\n0040aa6378a0c7dd6ddf791933498a4a0eaa2ae1735f refs/pull/732/head\n0040ceb986e61c4838c72c7184baf5f3fb45f0f97429 refs/pull/736/head\n0040cd2b3dfdf10cbfef76d4055a305c336321b148b8 refs/pull/737/head\n0040c769b140bf506c1ee4fa83390dbf497caaf341df refs/pull/738/head\n004061f91c9dc338600307f00571d535983e4ed14929 refs/pull/739/head\n0040acdec9b61fe5fd912a04237663c5ef3f9d847f5c refs/pull/740/head\n004090719f5481ff990bedd7fb7ea94e4b7aeeb0fd4b refs/pull/743/head\n0040a61cbad87cfaea6b145243eb90c5b537e066adc4 refs/pull/744/head\n0040f0fbf6d15624894bace340d7292a18bae49e6b54 refs/pull/745/head\n00406ad567e18284e4ced6c65fb10b49bf6cfd4e890f refs/pull/746/head\n004011bf6277d81e9820c2e36b322f0701818e258156 refs/pull/747/head\n004015ee6b7c0e410dd5fa43236252cec7cd6790ca9c refs/pull/748/head\n0040635a6834b52656e19030b42aab949f7eca986cea refs/pull/749/head\n003f382e0370aa33b5f3901fb4bd9ee5e44890724480 refs/pull/75/head\n0040d6b597a14e84f63242b3f4156de42d09889ee485 refs/pull/750/head\n0040a4ab4739e78d23030b21f0eb902b00d93b005b16 refs/pull/751/head\n0040a5070313a1baf80b93e6dc540b04eb74fc5813fb refs/pull/752/head\n0040d746cb6da820fc16107bbf4ec6d1af30a4710dd5 refs/pull/753/head\n00404ba0154e8ead390b4de23d5cf92d42dd501ef638 refs/pull/754/head\n0040c7e3065a18bd585909f374ac98bab7a085de1f19 refs/pull/756/head\n00404f7a3c06fc89589167534fd08abac1ffbe6e966c refs/pull/757/head\n004054b427be3c11680def676b578fa015f703540c7b refs/pull/758/head\n0040dc5bc42a7e0a72dbe2768dbfefbebb8ea5a992f9 refs/pull/759/head\n003fbfc6aa37be811fc6b7c141083a04f0b1d36a4007 refs/pull/76/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/760/head\n0040084176a1059466af78d1ed41c0968f02f2a6c8c5 refs/pull/761/head\n004050d4e1617c135d42d2fc4df5ea9df169b4c5dc04 refs/pull/763/head\n004081d35661472fe799c41bfe3bf14815d7898be65e refs/pull/764/head\n0040e30eac78b7efd50c1e1664b7ccd6a46cad0c6357 refs/pull/765/head\n0040e2e2b58ecfd46da2250976eef17ba3f17d3ee6a6 refs/pull/766/head\n00409cbe19f019daae3e82614b4fbe4be683462337e6 refs/pull/767/head\n0040d407774ab1f23bccdee67a8f2c5d8b204d293ccd refs/pull/768/head\n003f75bac6c257e11af3dbc6bb3473efb452a8676fa2 refs/pull/77/head\n0040e32a19d8f94dceb03a2f67eaf98b0196f7281a11 refs/pull/770/head\n0040a7015d7091d16d6f426b968c7fa5ab2a0fda5819 refs/pull/771/head\n004091d305f5e791c640e499b3e1336003df515f230f refs/pull/772/head\n0040b15989230f1768a41dd0bf7835732b32be5c8de2 refs/pull/773/head\n004030f09f6a986ace57c20bd098c1bd5a30b09f4839 refs/pull/774/head\n0040477c4fd524718d7cc6cdfaa4a5993861332151e6 refs/pull/775/head\n0040399ba7ef32e0e9edd93eb133380ce8232dd7d4e7 refs/pull/776/head\n004083057171f2f16e65a5a9b712f0c8105a19e24a25 refs/pull/778/head\n004041b8a27767c438488457a6f56ba8a427c7723bfb refs/pull/779/head\n003fe6325cd88200e60ec723e8fb27ca960891569b67 refs/pull/78/head\n00400e622ae0abcce683414a36b55c7b1f7ff05a8b3b refs/pull/780/head\n0040b6ec2183f4168eb94540f19bfebd1a0448cafa61 refs/pull/781/head\n0040ac9d4ddf7c6da9dd254c651c21c991908a3efd23 refs/pull/782/head\n004073d0275a4a51b1eb24476f691c9eb49d0febf5bf refs/pull/783/head\n004074ee9815a27fbc867d66ff56cc0da34638f5413b refs/pull/784/head\n0040e0348f06c231815852cf432dd68c715bb95d7942 refs/pull/785/head\n00409b97eba12029ab017c28d75b0ad6b1c1d9695118 refs/pull/786/head\n0040f1f859d1b1db31ef4d9bb4e49a0fd10b1eade958 refs/pull/787/head\n00407fc32b3f65b240ae060afb3e0f31a7ff2d69f14a refs/pull/788/head\n0040212c57a643dc3b3ddd1b9d211956fd055d78824e refs/pull/789/head\n003f76640aaf845677d939aa5578237974d3fcff27b7 refs/pull/79/head\n0040d1a7093297b0ce3d81db935e4565f56d417c756e refs/pull/792/head\n00406bc5b6dfd36a9cef9b70a9d7bd822ac9154f808f refs/pull/793/head\n0040f40c753b86c6015dd7db80f8dd2867427cd83185 refs/pull/794/head\n0040657a24720972a37343978ab192c8f6f3531695b2 refs/pull/795/head\n0040100f6e334de39c3083ff0ad29986b5ccac9a806f refs/pull/796/head\n0040f38dff092a74670b2ace1a563657388ac5d2b601 refs/pull/797/head\n004080326c5446873cb5497019694aad7186f4f47278 refs/pull/798/head\n003ee54eb95679c706bb9d610481d1d96d5d3659c707 refs/pull/8/head\n003f373b99cbadee55101ed30e9737ec3f68ef2fbbcd refs/pull/80/head\n004006ad66c4f02ff7d48f7f4fe41986a210cbf08ed0 refs/pull/804/head\n004002af4a60e843863487053afa4e16dec87770ed55 refs/pull/805/head\n0040fffe088fa6dfb0e29296e64d689c5a580a6a585b refs/pull/806/head\n0040cf4bac113710693ad48597fac53e003765809d8d refs/pull/807/head\n0040eb9aebb4aa1960a61c86b055d7b43f1bf30dc2ad refs/pull/808/head\n0040e1bd462ccdde72abb307783414f18449ee8f367c refs/pull/810/head\n004000bd42a3359ad1bee3e0f8baa0bf9f6e11f91524 refs/pull/811/head\n0040f88be1e087ce77f11a55b483c325860ef674cb98 refs/pull/813/head\n00403a78548fda6a433b5a7ba85382bd9a3e23336b31 refs/pull/815/head\n0040a23c1ef8a80506bfa41a3f8fbc813305a6ae8eb4 refs/pull/816/head\n0040cff83e26d6b40924c8faa6116588ff70673f6558 refs/pull/817/head\n0040f71da79b826f7e07c1d3d1203b6ef807008aa4d7 refs/pull/818/head\n00402056c1aac5f3fdeb77121701a1ee45e4fa81eb9d refs/pull/819/head\n0040b050172863cc26434c80b2192992149fb53c61f3 refs/pull/821/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/822/head\n0040681c53aea42f51098793bc44f8b5818742bfe2ee refs/pull/823/head\n00400336c7de64f55e57c87009c19b19e2a93f3584ad refs/pull/824/head\n0040ff8aee76ad1ea6d56a2e7e8aac88d3deeee58566 refs/pull/825/head\n0040f33a77df57317329c29d8f4e0ec7536dcceed709 refs/pull/826/head\n004096e6a65699d269443be2fedf2775f95e52f872d7 refs/pull/827/head\n004038a80294dbd30ebb6f7708f5a1c1e15386c25fcf refs/pull/828/head\n0040d7b155f75f5b6a355c22a635df5011b07001b2e7 refs/pull/829/head\n0040432a4bb4c9606e99c41186a49607682da95e937f refs/pull/830/head\n004048da9b8cce538e01570673e1463af2c4e922214c refs/pull/831/head\n00408c427dc8a00c8428c81e0c70775a0b4749361656 refs/pull/832/head\n0040ea4710c0a648cb6534cf1bf2c957d4719524c5b9 refs/pull/833/head\n0040d135a145144fbb70f8a18bb9bb368381cd2e9003 refs/pull/834/head\n0040359f417d5ae56820a247b2d4ab137761be4b7808 refs/pull/835/head\n004024c1a97f28c40fc3ecad10edbeb1d7d7aea65ede refs/pull/836/head\n00405fe7b19a14351516fb514fa5c496d11fa59b8b08 refs/pull/837/head\n00409f0f70d5cc62df3eb070be6a9399a2ea125d0928 refs/pull/838/head\n00401a6c6bfced06a5f8f688f640223ca70ecedd6cea refs/pull/839/head\n003fde384e0d47c73a443be98e1626f4a2030a186b8d refs/pull/84/head\n0040b2a8175b32d930213de109d9fa5d7df6719e5ecf refs/pull/840/head\n0040ae4828d069c8c2a785fb4f5b49ce94cd2db05392 refs/pull/841/head\n0040e1bd462ccdde72abb307783414f18449ee8f367c refs/pull/842/head\n004028a7ffc150194668b70a04912843ecc0d171f7e9 refs/pull/843/head\n0040037c3543ac60359190459b10fbb5331568b4c8f5 refs/pull/844/head\n00405761166dd8ae69272ec0634dbd41e66cca0cfa5f refs/pull/845/head\n0040009f460af86ba742fab59878e9e86567ed46b4d6 refs/pull/846/head\n004045b5a8c5bbb44139e0625b9deb3b6545e74b45f3 refs/pull/847/head\n00402fcd46715333de00a990264ebd3570fced45949e refs/pull/849/head\n004057af90d4022ee5adfdce175ed6d3f01b7659a142 refs/pull/850/head\n00407df4c2642994b77f2b05e764b044c33993616e8c refs/pull/851/head\n0040f2ef83c7825dc0de95479c0888518f3b75beac00 refs/pull/852/head\n0040e9fdc9a0cf3c01c41eb7f648baf4f20dd8b61a64 refs/pull/853/head\n0040c939e15728e43bf1087293161d56ee01bb19695d refs/pull/854/head\n0040011f8c8950e89bb1ad9bdafce8a437473fe39ee9 refs/pull/855/head\n00404ca052c3cfcfe7aa8fed53f6a4957bb3b65cfaaa refs/pull/857/head\n00405769e69b9dc282b0a4c904819e306b82aff4269f refs/pull/858/head\n0040300ce5e2fd07e5cd9d41d112f07e1e2772756ab8 refs/pull/859/head\n0040df89acbaec3c346d36667d2ec049ca309047dac2 refs/pull/860/head\n0040274094a4b067716bc905451e445f854704575419 refs/pull/862/head\n0040d856c4e49b2016abc2905f1f6b24710a9d1063a4 refs/pull/863/head\n004020fca611e5c9da75894779bcdbac190c81a41c58 refs/pull/864/head\n0040ca76ee6811198d38c06b8cf02505b828f293523c refs/pull/865/head\n0040d3185ac93522c480dbaa1e479daccfed0b0e86df refs/pull/866/head\n0040f1aac37fe441c416842dcee21846c976bf82028e refs/pull/867/head\n0040ce2ad9b7b5d24aa337d5305f245335c74b377bf4 refs/pull/869/head\n003f69205fdfb3dbd604a165cbefe7bd116380ddb0b9 refs/pull/87/head\n004074e2029633b59a239aceb2ff9689aab46fb0269f refs/pull/870/head\n004001cb7338bc2915f23629e3b56a9e04feb21a48eb refs/pull/871/head\n0040538e76d99a2ee402145801518e897715561b68c6 refs/pull/872/head\n0040bf2503051b00e2ab16adc77f5d6b920088d2d1e5 refs/pull/873/head\n0040adf23fe73d66bf4a5eb1c28e9202b2ec2b108513 refs/pull/874/head\n00403ba580ead644168aa0fe109fa0c66db43e92d505 refs/pull/875/head\n004091dab8f0ecba342dbb43d92ae5a0ee0b2b9d2a56 refs/pull/876/head\n0040c5bdc6001d2494d8bd85b4c53b44e5a7d17a96fc refs/pull/877/head\n004015fefc390b71f7dec7a5e957b2f7dafc652cd713 refs/pull/878/head\n00409988aa6cb57d99be647b06acb2aee87029ab47d6 refs/pull/879/head\n003f4215fc60b039358b7b25c738f77d0a7b0cafdc74 refs/pull/88/head\n0040fb68f5b16adc288d4c3cc51acff850880339f677 refs/pull/880/head\n004039342563fe83c443c9e896d9f417df8826c65e8a refs/pull/881/head\n0040b049b2af26e1703f0887516356147e0ab1a2c881 refs/pull/882/head\n00406b27d53a4fca05cdd8ea92cf6e20982f10cf261a refs/pull/885/head\n00407c69ffc21e56cfa1e776eec683025b060eb7dedc refs/pull/886/head\n00402ff1267bdb33581baab1b8894e11a9ce45524856 refs/pull/888/head\n0040347ca611bffafaea9a1106716a451540f31d6a60 refs/pull/889/head\n003f237281ebdd37ac26e0c3aae9a0d64be1a96fabf2 refs/pull/89/head\n0040eef642b3533197cf97722797c5ab259a445bee6e refs/pull/890/head\n0040efd820c3b0841736eb6699b1b455924cbcd3099c refs/pull/891/head\n0040c03816f1930f1f18e7aabea7901ce24018e08111 refs/pull/892/head\n004066665868beeb7f8440dcfa44382a55feeea92abd refs/pull/893/head\n0040fa3ba07cecc8904bbdfa869f36f96fd20dafab9c refs/pull/894/head\n004094e7839eb50b5c4f7a1f7b9186b0635e76b89044 refs/pull/895/head\n004042fde53f7fa32eeb6e181d4c44d40b260cfd0b37 refs/pull/896/head\n0040efcfabc77bf51bcfc988608415855110a38d46c8 refs/pull/897/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/898/head\n003f9a1caa6ba84b07b5d56ec3a257e0d4b3234e3c9d refs/pull/90/head\n0040001c99ad363d4c73a0ed2b41a42ef077aa55b908 refs/pull/900/head\n0040743f5f6983b2cf9c209054ddc2bfd073b823e057 refs/pull/901/head\n004062106593de05aebbf1b33e6b55a74249475c81c3 refs/pull/902/head\n0040fa0ab05f34df3053213d9fd2edb5f491372179ec refs/pull/903/head\n0040e482d41641eea8b783edc0f72a83d14335fc4dfb refs/pull/904/head\n0040722ae5807ce8fc540b6e968f65892cb50a5486d4 refs/pull/905/head\n0040984b61467f9613dcc89cca99a6aa5b528db87021 refs/pull/906/head\n004056ab40c293c02a6027ffc9f774016597eaf96b4f refs/pull/907/head\n0040f14aa2b05dc4e742820ca6fd80192b4616195f5f refs/pull/908/head\n0040e3e7b64a3d547fc5a124a77632621749b645f760 refs/pull/909/head\n0040be090e198b6a9d5c5d2572b4298aba6cc26e6bff refs/pull/911/head\n0040d2072e429e9b43577f629099bffd60cfb2589daa refs/pull/912/head\n00403c6c38ad7d4095ce89cb7c6a3ef6d75d8ffd3b7b refs/pull/918/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/919/head\n003f8c665f9bb94f9aca5ff50341e2830cd8a0d52e15 refs/pull/92/head\n0040a51f2e8d03985c7c8bc80b8f3ea4eaf8e5c6ba19 refs/pull/920/head\n0040a89d7976562683919cfddfa363e94efc366ff859 refs/pull/923/head\n004005c9d84d00d53ee8a981e4e215bdc83e9bb22b9f refs/pull/926/head\n004052f5e5412de74d5941e4e511729d1aa9d861c025 refs/pull/927/head\n0040f686754f9c56a7a9261a7b5928c7965201fd5cb0 refs/pull/928/head\n0040e5dac1059eab97466af6c4ca47956fac9b3e24d7 refs/pull/929/head\n004012e841e3603fa5f254038030f5aa3b7977185358 refs/pull/930/head\n00401d48fb2720eb8713115d1266eb9452977b58326f refs/pull/932/head\n004032963c33409075798c3a105cac04d5553ea13102 refs/pull/933/head\n0040d0f4650818b34f9be70b6513998ae84b2c6246c2 refs/pull/934/head\n0040a102582671179e3217c102f23f1d8a04f3edb485 refs/pull/935/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/936/head\n0040e27740039e8bd36e32d2c5d754e6c92c86c5f963 refs/pull/937/head\n0040c4ffa47ff7011b495a146bbaff01b31514b9ee04 refs/pull/938/head\n0040c132a552e0795263438df99eef3b2c4632c93d32 refs/pull/939/head\n003f013774b69b995be5744bd49e0232f3dec0b2a93b refs/pull/94/head\n004077c08a2ab0157524ed6a086006fef76ba4bfb260 refs/pull/940/head\n0040f8d712a563c02e6f3a37702b9f0896fb5f5ef061 refs/pull/941/head\n004098c56e29f1f275209a0d1055d59f70d2a9876a55 refs/pull/942/head\n0040f89731a864346dd51cb1722d1c69d04211c1d485 refs/pull/943/head\n004078fe74df59864017f89cc065bf1e284fbdd5b9cf refs/pull/944/head\n0040dcf3bc2fa1c683634031fb99bff85a33b3010d6a refs/pull/945/head\n004002ada34bea2919fd82260a88a4d0183e32ff4481 refs/pull/946/head\n00407bdd987696b6b35402e77bb0d377cc758f1bf08b refs/pull/947/head\n004007f48ad4782a90046362ad2f15272ee8d6a758bd refs/pull/948/head\n0040c8ebb9c137eb5030bb9f016febe729faa44b39d6 refs/pull/950/head\n00400ddcb393a921f24989318b97b273493d6ead5e3b refs/pull/951/head\n0040eb14d7d144fcc50e521e7c1b42bb666cda0342d6 refs/pull/953/head\n00401b192c378638f9ca47933864d7c221c13391953a refs/pull/954/head\n0040dc08833463c8a6f5c481b525336965481c7e862a refs/pull/955/head\n004046442d0167b0a3eb233796737add2044e5fcee24 refs/pull/956/head\n0040c1beb099fc399ac9bcbbfcaaea445f22d8ae291b refs/pull/957/head\n0040856e26ad1856e68df26e320e8b26766cbc069eed refs/pull/958/head\n004081757df8bf740d6115044ed7be6851a2263fd4c1 refs/pull/959/head\n004061c3abfb301bb6cbfa7609bc10073cad7f1877fa refs/pull/960/head\n0040f472991d4e3bab100a51f00fb39e82a53ebb2c1e refs/pull/961/head\n004009be902bbf925a84c492a353cacd4ea2bc08ef86 refs/pull/962/head\n0040ce718f77c0d6abd993f325626f7371af8af8f818 refs/pull/963/head\n0040a2975709e828fd220c3f34427fdf7b862446921f refs/pull/964/head\n004014da5f6cd993f00995406252c89d021f3b296161 refs/pull/966/head\n0040569e876fce72a7833687aee4bc4f75e73a123113 refs/pull/967/head\n0040533b32d9ac759d1f09d4c7aae5d47615615d9ab9 refs/pull/968/head\n00403636cba6d472a7a5f2f2e772d1152cb8d4d466a0 refs/pull/969/head\n0040686ae85680cb92107a2951849312ef7d449baa58 refs/pull/970/head\n004079f4e14dc8f1c22c606c53dfdacfffa9ec09243c refs/pull/971/head\n0040ce3f784c8c3bb317686ebe242a40ed208281b2ce refs/pull/972/head\n0040ee82da89955148e0f441ef92812f89a43407b945 refs/pull/973/head\n00406f96ecb86ee791b6a76152fab22ebf7918149a04 refs/pull/974/head\n0040b498309092685b6ba33e77c2ea547f7937a54d97 refs/pull/977/head\n00409ecc534fa7187aba7b569abee15bb34b228c6edb refs/pull/978/head\n00404793a46e88f1bbce733c30de062dac6c6a733e41 refs/pull/979/head\n003f7c6f3235fdf07c5112acc071842bad7f18d99df0 refs/pull/98/head\n004003a4545113b883c75a0ca7b2da43b5aa8e44f22c refs/pull/980/head\n004064ea62fdd701be13d140f23585fc684bcff8bda4 refs/pull/981/head\n00404d21a6ee70683d43a9ea02f30241fc7e5de1dc75 refs/pull/982/head\n00407f59b2e565a976f52d2da4a66dc7fb618455ee4c refs/pull/983/head\n00405e2b50db94c7407daee033fe3686e611228ce7b9 refs/pull/984/head\n00408d65fe5f4e56555fcc229fd3be617abc28a43f4c refs/pull/985/head\n004042cfeab1cc55bc73aff5d8171013f16d6a5ecfa5 refs/pull/986/head\n0040db1edfb78e883c898207fdeedec21d7175cd877d refs/pull/987/head\n004068d4dd170aa98cba54eb23e3bd8a43eb112ca5be refs/pull/988/head\n003f134098bf54a9a1f2cbeed7c6f31661e09381070c refs/pull/99/head\n00406229b7a8bd02bfc1f3f714d0450b4123cf89a590 refs/pull/990/head\n004013a3ba837c44252f71c4b3160a19839a16e4fffe refs/pull/992/head\n00405f2db79242337a5d213db9fd6dd521f7794a7d00 refs/pull/993/head\n00408ce1a31e0f5e0a74a28aaa56c8daaa50e21d63ca refs/pull/994/head\n004010c35fdd46012cb957bab469cdded2e58292b198 refs/pull/995/head\n00407c61c0b7caf4705942588301c01b6e9cce7300d9 refs/pull/996/head\n0040dec0a1617e15bb1a2fc89a03ccaaf8806f38a546 refs/pull/997/head\n0040caea5c733154add2b3e83876f04ac455326855ad refs/pull/998/head\n003e194c5efcaed9fed321ba2123745f78827a3eea03 refs/tags/v0.1.0\n0041f3d3ef027896e318b099764bc855062821e1de53 refs/tags/v0.1.0^{}\n003e4a24731816a98853c8b30196635586fa65fe3cfc refs/tags/v0.1.1\n00414057e201dfa8b58656e84789a726919098061025 refs/tags/v0.1.1^{}\n003e0014eb08b942762f103c967e587f9bba6f91fc53 refs/tags/v0.1.2\n003e1ef42d0bd5a7da2b93fb3b3b80b0f8fea50e7600 refs/tags/v1.0.0\n0041c6ed0fabdbe8ad75465bd7eab81ba904a9c89f42 refs/tags/v1.0.0^{}\n003eac28fb90a951fe0a334e8ea974cb9d0830f8acb9 refs/tags/v1.0.1\n003ee20621776bbd2e799537eb3b0328398ccd5e9fdb refs/tags/v1.0.2\n003ea6c6cd756e0cf4fd858398976208145cb23e707b refs/tags/v1.1.0\n003eb33258df779c4cf0fe02961874dfb1bec16080f5 refs/tags/v1.2.0\n00419647b493034ab334e071921becde06bad8de059e refs/tags/v1.2.0^{}\n003ecfe6d7502821f60c09be0f6de2548ac952b01696 refs/tags/v1.3.0\n003e7c08000dc3a0b1a690d46f70fa97b3fd87cb926b refs/tags/v1.3.1\n003ec6d02d122f65ce3550eb002e4cbff6f1307aaa6a refs/tags/v1.3.2\n003edbeaddee112d005d950988cf07c09d91a4966fa8 refs/tags/v1.3.3\n003eb5af6c719caf8f4e51b3195039a7de926a0066eb refs/tags/v1.3.4\n003e62df1c5366410936e29a986e73362afc9f3a5cb7 refs/tags/v1.3.5\n003eb5f7502d2b76b1b84201937aa759299d23e02c48 refs/tags/v1.3.6\n003e51fc4fd651c23e5c7e209db1fcc8d6ed68d07789 refs/tags/v1.4.0\n003ec50977954ca3d2cc4cf37c52d2dec3e75a97b7a5 refs/tags/v1.4.1\n003e137255296e89d6baa9df9c7f7e950a28c1db5c74 refs/tags/v1.4.2\n003e6316373e47d7e3e4b4fd3630c4bbc10987738de6 refs/tags/v1.4.3\n003e060799ca816dfa40afa05e48c895c0c9fd79b90b refs/tags/v1.5.0\n003e114c256d14e094ec5874cd9d14d03d27c4086b90 refs/tags/v1.6.0\n0044fa8e74ec2517b1bb371b4e7c739fe1efa4175532 refs/tags/v1.6.0-alpha\n0045cb3eeb25026a6da102d2f2835af053c48c55a901 refs/tags/v1.6.0-alpha2\n0045f6b044300bf29d0b7ea3cc036715e6fc32ecf134 refs/tags/v1.6.0-alpha3\n003ef6b044300bf29d0b7ea3cc036715e6fc32ecf134 refs/tags/v1.6.1\n003e5b4066c7351b045a433b1fe3554260c6f06b7237 refs/tags/v1.6.2\n003e037c3543ac60359190459b10fbb5331568b4c8f5 refs/tags/v1.7.0\n003e43dda7afea9d267f5d448709e75e2ae7147c29d4 refs/tags/v1.7.1\n003e032296dfeda9ceef9fc46ffba9d032cc52f3428a refs/tags/v1.7.2\n003e645d5b0bb9c14741b2147a5305b684e4abc039e0 refs/tags/v1.7.3\n003ed4657bf46aea52834c5148b25fb6cab132c69af5 refs/tags/v1.7.4\n003e2d1181a69fdf3263083dd8e3c7ae0feceae859fb refs/tags/v1.8.0\n003e46aee59befed6edb5fc737ef35b5febf987cffa9 refs/tags/v1.8.1\n003e1ea785e56de9f7817c57266025f0a56279141053 refs/tags/v1.8.2\n003e18ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/tags/v1.8.3\n003e4a318af4a84899723625da2927c30fcfb7247126 refs/tags/v1.8.4\n003e6f61445b22e99d3a0a3ffb5dad7b723a9fa84964 refs/tags/v1.8.5\n003e1386406b64edd4544696183f273139ef9298f5df refs/tags/v1.9.0\n003eb13f37e1a1e4cb98556c1d34cd3256a876929be1 refs/tags/v1.9.1\n003e1e295ee11c5e107886e58bacb04228325082146f refs/tags/v1.9.2\n003e0e986b49c4e7ee5aa545531c4a8908455f8a9e82 refs/tags/v2.0.0\n00442821e79ec1d938ddeab00522619c3a67520f6c56 refs/tags/v2.0.0-beta1\n004429aaf53c46427b2fde72f7aa7a62992dfad0e9be refs/tags/v2.0.0-beta2\n0042baab0d06596a51f593aeefcbf089527f2d3e194a refs/tags/v2.0.0-rc1\n003ebe9015f3256940e63d99b9d1a009f99c7dc4d8ec refs/tags/v2.0.1\n003ea2a23858b9650035f019219937f91ae615474b4d refs/tags/v2.0.2\n003e4f77b30556bb6d171b5d55f01da4fb0261b9da7d refs/tags/v2.0.3\n0000" - headers: - Cache-Control: - - no-cache, max-age=0, must-revalidate - Content-Security-Policy: - - default-src 'none'; sandbox - Content-Type: - - application/x-git-upload-pack-advertisement - Date: - - Mon, 07 Jul 2025 03:38:50 GMT - Expires: - - Fri, 01 Jan 1980 00:00:00 GMT - Pragma: - - no-cache - Server: - - GitHub-Babel/3.0 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Vary: - - Accept-Encoding - X-Frame-Options: - - DENY - X-Github-Request-Id: - - 4439:145DD2:22D0D0:2750A1:686B414A - status: 200 OK - code: 200 - duration: 362.457193ms diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_no_cache.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_no_cache.yaml deleted file mode 100644 index 2797c38e00e..00000000000 --- a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_no_cache.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -version: 2 -interactions: [] diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache.yaml new file mode 100644 index 00000000000..dfcfc51be64 --- /dev/null +++ b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache.yaml @@ -0,0 +1,54 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: github.com + form: + service: + - git-upload-pack + headers: + Accept: + - '*/*' + Host: + - github.com + User-Agent: + - go-git/5.x + url: https://github.com/google/osv.dev/info/refs?service=git-upload-pack + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: "001e# service=git-upload-pack\n0000015b5ffcce399241fd59809e7cc6e0f31a13c28ec017 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter object-format=sha1 agent=git/github-bdd2406f1b30-Linux\n003f5ffcce399241fd59809e7cc6e0f31a13c28ec017 refs/heads/master\n005372fd51767b95fa0ab298d580c1214d8b7ba67a34 refs/heads/promote_prefix_ignore_prod\n006592a9a438fb2a2f8f53f1d6073d7eefd7293da553 refs/heads/reduce-importer-log-spam-8993462065003763829\n0049c718cee0e2409df8bd503255fc60c21bb6d661fe refs/heads/reproducable-zip\n0062536d8403169585521583475f89d6ce5aa03e0a92 refs/heads/temporary_modifications_for_mass_reimport\n004e2c85053cfa420c869bae7ef023c52300eaa0ad2c refs/heads/update-pr-permissions\n00472c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/heads/upgrade-schema\n003e7588d54370e7336f1063b3ef96112797016c521a refs/pull/1/head\n003fa2ac801881f48bf9047dc4ca68f9587a4781bd7a refs/pull/10/head\n00407cb597c5a84af14690b0ea49312ed7eda06552fe refs/pull/100/head\n0041f8bcb25186df1323e6fdb712e580556202656a9d refs/pull/1004/head\n00417a8c671bc9e97f92924965851b471c8aab1ee8ca refs/pull/1006/head\n0041bd500a4044afbf9d5c49977fada634356c4fc101 refs/pull/1008/head\n0041605331fd14e43a8e905cea5164a62387afd51d71 refs/pull/1009/head\n0040e0cb2c344ca0730320533a43b10071b7f4312473 refs/pull/101/head\n0041485f2b6da3d617788879c786212a58557c12c5cf refs/pull/1010/head\n0041f94d9c56ce66d401e2ea5d53f3d9addf6a218fdf refs/pull/1011/head\n0041e20794697e7cc44aba013c331af176cb811ad551 refs/pull/1012/head\n0041694cd5f0828ac7cb3e2d9b320515b8ef03c2606e refs/pull/1014/head\n0041d52d02ff5c97f677510c7bb9b2985db39c6fe796 refs/pull/1015/head\n00419feb39025a7cf0fc86cb6ab0cea814e3c53c674d refs/pull/1017/head\n00401349f69d688fc7a509215f9432ec73dfb46b8a61 refs/pull/102/head\n00414c5f3de7c47d6688f77c4237bd2d5f60cae0cf7b refs/pull/1021/head\n00413809cd3109f476a78e197446c08bf33a4ca55c00 refs/pull/1022/head\n0041b13a6f1110ec13e0a8bdc0c01a6916ff0e354d3b refs/pull/1023/head\n00411eec3164523b5821d4c5f011871871b15fab207b refs/pull/1025/head\n00413348d2f75453c4e73887799b3acfab01a6bd73e7 refs/pull/1026/head\n0041b53cbd1cb21af23acc46a7954291b63dd5c3ac95 refs/pull/1027/head\n0041933eb1962638d9dafecde200304b15fb5408d3b6 refs/pull/1028/head\n00410a12cc1f3413dae4d84d63ad8ed1c6061b329347 refs/pull/1029/head\n0040cac8c823c650078345e35c8a813f38599775b833 refs/pull/103/head\n00411098e2c8c83ac74d287172b8e0fef6f68a1b1b65 refs/pull/1030/head\n00413b911bc5ce4f58aaec84b36fa7221c9e6b8aeeb8 refs/pull/1031/head\n0041ae07ed72ea2cf91193f8641ab0171b81d226879d refs/pull/1032/head\n0041911aac60254233f36c9fa8b352d9b8af3659a2b5 refs/pull/1033/head\n0041188ddfb6d0fe396bc04f255d7a397da940cc80fa refs/pull/1034/head\n004133f110d8a987995a37085a6f749731ba6079d10b refs/pull/1035/head\n004120360a60cb396c3d3e70dfa97c221426e651f9b9 refs/pull/1036/head\n00419b7028075b186cb85fb1162626bc8d35ab190945 refs/pull/1037/head\n004118fc7c0fd0e0add81d729d5e94ad8752c1c57190 refs/pull/1038/head\n00410804317ab3de7d5f993fdac0a0a43896862a6ef0 refs/pull/1039/head\n004053587e5a82398d23e39165d358f8093f797c5aa2 refs/pull/104/head\n0041fd4f821b02dae483809871416ac633e45836f6c7 refs/pull/1040/head\n0041032ece4b67ad99947c5c87d22e7474bad94521f8 refs/pull/1041/head\n004124080a2e01350075cefb33f912d77193d1f4de03 refs/pull/1042/head\n004136143d4cadc1bb7ab1fdc4d0dc7746dd19eeda97 refs/pull/1043/head\n00415b400eba34551913d34764cb8d5acca6f0a4f3ae refs/pull/1044/head\n00418fabf11f241e11624c91601a0596491ffa3c0d96 refs/pull/1046/head\n0041e3432ab171ecea3f25eeed5caebd19365f2753d9 refs/pull/1047/head\n004155ffff4042fa481e0ad1842f711a9f17c4cf5329 refs/pull/1049/head\n00402bc665af22bd913071393eeb5b56f8eb8afdc032 refs/pull/105/head\n0041a0c78dc0629761e3d567b8a268b433bb336019c6 refs/pull/1050/head\n004116b14e3bfddfb2bc8a0823d218c9fb55c35caf51 refs/pull/1051/head\n004149a52d949c8c923a33f8714a2175ad46b5e57db3 refs/pull/1052/head\n00410376002d2b38a6232eaa8a66cbfba525befe984e refs/pull/1056/head\n004195c7d0521ed2ea24906a34903e6f2469d4fead2d refs/pull/1057/head\n0041c30a6319d0e78c5694e2049aa9592bbc549adca1 refs/pull/1058/head\n004168154d8f0d81656f0ce6c8dd682d62fb307537c7 refs/pull/1059/head\n0041d16773aa81db518a3a2d92c90f3e0c97dab5287e refs/pull/1061/head\n0041e28509db3aab8aa7529d0795237be7eba62081e7 refs/pull/1063/head\n00414388c2adc25321d6a6006b5e5a5c32ec4b667bca refs/pull/1064/head\n00413844a6050bc4d2e8a90a28ea675e75f07283892b refs/pull/1065/head\n00412d68c51e1abeaa462580db118c06976cae5757e6 refs/pull/1066/head\n0041765995426c75aca4ffeea95f17c9029833ca8ff1 refs/pull/1068/head\n004137c97f269ed9064f88019191bdfcefc7618f22ec refs/pull/1069/head\n0040e822ea91aa0806b3de8ad8c307653ac7ade7fce0 refs/pull/107/head\n00410408805073cb0949236ca0700989510dbc7a240e refs/pull/1070/head\n0041d5e2603a21f3a25aed411d6b306702b67b1234cd refs/pull/1071/head\n00419c0c3019d9151e70b86eb3fce732f67f002d1d85 refs/pull/1075/head\n0041655ae019e7dc23f7d0f0053ad0ab4b216ca8101e refs/pull/1076/head\n00418d05e98430ef70cfb241571300687e3d0b2da4dc refs/pull/1077/head\n004190a77a72bf7b1514f8d91f1e2e10dd27b685cddd refs/pull/1078/head\n0041ba4517b948d070865726525ce8f6f92bc082f74a refs/pull/1079/head\n00402ada540e49327edd5997909ef4c3bd9965fef118 refs/pull/108/head\n0041989ed566cf6bea122ad73b4ff33ec8f10277e923 refs/pull/1082/head\n004103380f4390ab124fb1e93dc866643794e852a1b2 refs/pull/1083/head\n00413791ee0d863a87b8569332494539fc64509b870b refs/pull/1085/head\n004194059682ef11325cf7295e0168965353b96e72c3 refs/pull/1086/head\n0041f1d03baec460b46b46334f40e9b6c0722f9a8548 refs/pull/1087/head\n00415b8db3e7470201d7b3e755144c413dbd55ce6f81 refs/pull/1088/head\n00417621c0df9aa340cc08461ad41a171cac9948df96 refs/pull/1089/head\n0041a201dd01dbbd2fe51655c2b5a772c94f07925fca refs/pull/1090/head\n0041c6183a91fa972b2b28978cd34bbc4ece0c93d034 refs/pull/1091/head\n004100fc04e29e3d78ed91f9713fdc9a207e24f4ee2b refs/pull/1092/head\n0041c1fb4fb270577a0fd2634c149f6d4de024fdf1ee refs/pull/1094/head\n00414b1f9f0b4053dedfbcd1094f9fe134a8a7591a1b refs/pull/1095/head\n00417ea4d86462f7299ad5e017bc8ca69c4970addb59 refs/pull/1099/head\n003ffe47213e95bdcc488ada1849e9a510bd6d2e36bb refs/pull/11/head\n004057843634a14a6b67f8e75e8493a36398f88c6061 refs/pull/110/head\n004130eb8f7bf2c089a49f240ec7d69918c0e2949e70 refs/pull/1100/head\n0041be9176bb6398a4305e45af0ba76f8c816618f2f5 refs/pull/1101/head\n0041839788f01f9d6c4bc25f7f2c599ccd4da8cbf03b refs/pull/1103/head\n0041cf14188cc12ef4de9d966a7f42165cefd46bdfa5 refs/pull/1104/head\n00421fb31e43d570a544d62c175fa325f27e25afb552 refs/pull/1104/merge\n004133f55e55ccd34157da77fc2ed8143f75a681fab3 refs/pull/1105/head\n00417795cd32bbb6492eb117e45001b498d3c4de704d refs/pull/1107/head\n00414ff9acaceaa374fd68c248096e24b0fbe6477c37 refs/pull/1108/head\n004179cfd7131dc021a00a1fc78262a56edabe4e8acd refs/pull/1109/head\n00400a5b4257ff2e70b78134c8c41067928b65d650d4 refs/pull/111/head\n0041e2043c6fd2f27b60945c85d68dd81f59c765cc94 refs/pull/1110/head\n0041a087b854e11a5bb8b43f79bb9c3c2cad81f0fa75 refs/pull/1111/head\n0041c88dcd99d1d61ce90db741986178851e94dde070 refs/pull/1112/head\n0041e394a186b01d402a32a06803e79041c4aac015f8 refs/pull/1114/head\n004137f9c94f61d6a9407286f144870376e8d0907779 refs/pull/1115/head\n00415b470a1df2c11ca8c7283f7dae08a5e689e7a67a refs/pull/1116/head\n0041ad2cfe753e9ad1405b82344b7e5d248a9fd23432 refs/pull/1118/head\n0041527139dfdfdc3872980f2cc48f88c1685702b5f6 refs/pull/1119/head\n00407d0bc21474662422503c1fed2f6efd38f29987e1 refs/pull/112/head\n00411db7266b0d3dc2060e099d33ed2d621b82c638cf refs/pull/1120/head\n0041c22baac1c31c2282b9c81f02b2d297e943e715e5 refs/pull/1121/head\n0041717810817a0a2b2878efbf4d655a5f3f02bdb4ca refs/pull/1122/head\n00415b047abac2af8c3454aa3f5d9e3f4fd336248091 refs/pull/1123/head\n004187bdc6bbe11b1f7111cb45b231e77cb543c03b7c refs/pull/1125/head\n00418ed6125c3266ee5fe16d90e8f0db26bdd21e9a06 refs/pull/1126/head\n004198b17c26f503a5bb857ea3435240a45f584d236e refs/pull/1127/head\n004145c24a202a91fce5c1f3f18a28ae2c328fb07fcd refs/pull/1128/head\n0041d89e784013fa44af219af4c59318ce60f8f05fdd refs/pull/1129/head\n0040a8e64b67ee50fdc923b4dfca8a026bb7b7e0f9e9 refs/pull/113/head\n004142ec9e39e560a60028b64ecbaf2bf9ffaea9acaf refs/pull/1130/head\n0041e90b84e7aeab7edf3bc569ea7b445e511c88d303 refs/pull/1132/head\n0041c1d699e161bc1bbfd7d57be2712c8ee1546db0b2 refs/pull/1133/head\n0041153b7f21669004864a63efceb934ac9247c43b44 refs/pull/1134/head\n00418a6b4659ba4a39a9f18d938a1303f35962bd2c63 refs/pull/1135/head\n00414b9e30d2079123127d445c57ef866691c2612c15 refs/pull/1136/head\n0041064e0107b717f35d289c101a8df5aa6aa49c14d2 refs/pull/1137/head\n0041a68a0cd38ab4f489191912d992c1d4b7fb598201 refs/pull/1138/head\n004196c4267fdd5ebc5a11abf2afde34952d11fa0e3d refs/pull/1139/head\n0040ad040b0e9fb545a5e5e72cab06eeed0457350efe refs/pull/114/head\n004168459aa29ef3251223f574b7902bae78890c3800 refs/pull/1140/head\n004158e5151180e67e209a300f98b10c8bd91d2f10d3 refs/pull/1141/head\n004197e7609dd55ff381e8b645373b38ecddf3615ad8 refs/pull/1142/head\n0041693895fd032c51b0c75036d9c41c6586ea59b306 refs/pull/1143/head\n00413665ffa0765a44fe402d9aded1e0997952d97bfe refs/pull/1144/head\n0041045004f0080fa316da50ca631055923d8383a910 refs/pull/1145/head\n00419c4c3d9bc4df26168813861503ae0920f7281907 refs/pull/1146/head\n0041c5b17cb731e4037a8b729ae71e18e267e0378f86 refs/pull/1147/head\n00411daf35f02314a6d03fc13e62beba958e2d504b4c refs/pull/1148/head\n004184160b5e6ed474b28230dce53c64b4de2be56660 refs/pull/1149/head\n0040efcb738cdef73909a1514edea0a2c3fc279fd0a5 refs/pull/115/head\n00416167e16bee3e6f04a58ee6e31717c1610e139f9e refs/pull/1150/head\n00414d3249741636a1311a19d70f2af571f9f69e2e70 refs/pull/1151/head\n00419b2fa3ecb7cf81be6030c621c98e1aaee8103839 refs/pull/1152/head\n004258fae47d57833a93c2114f003486a178c7fe4565 refs/pull/1152/merge\n004170972ff2903159bb09ef351d62f1f8a056b8cb2e refs/pull/1156/head\n0041949f1218bfc1a4a43ecc024517745812f8da30a1 refs/pull/1157/head\n00410b5fcb4e937e813c777bd6a1cee272e8ecb5c69e refs/pull/1158/head\n0041378637ce104c9282207fa33f33ef2a167fe430d5 refs/pull/1159/head\n0040853201302c759848d37893d94ba11ea590d61958 refs/pull/116/head\n0041e09188102ad3986443886927e92966e9e7592cc3 refs/pull/1160/head\n0041700d09bf5a8f85ccc34818ec42b6a546128138b6 refs/pull/1161/head\n0041d9ae5ece28cd3744db4545fafc3e91ef1bff6f2b refs/pull/1162/head\n0041850c562b1c00fbbaf6a88dd8193de3963a820620 refs/pull/1163/head\n0041e662a66092408df23b3d993227fa931b6c18bccb refs/pull/1164/head\n0041f47b8a51d42a9afdcf61d31088ee3d4d67a38ad1 refs/pull/1165/head\n0041bc14f54a67add60193012a25131e046ced831b7c refs/pull/1167/head\n0041f04422a14208718301ea5ab6edeaa9bcd8bb0b18 refs/pull/1168/head\n0041c4527fa17adf08abf20e61de87fb7a9cfebde6bb refs/pull/1169/head\n0040f2193ca860f0648ffc8f2e6de877f92a363e89f9 refs/pull/117/head\n0041d7e54154d56ac72520daded39ada968082c9063a refs/pull/1170/head\n0041b43ea6c0af5ec6a0ba59691044fc4f168993808f refs/pull/1171/head\n0041e573127901d5456835c3a14581dac8317df14710 refs/pull/1172/head\n00419eb7982d800aa6d091a70e1d66a025e86b0fdced refs/pull/1173/head\n00411e10841edcb227d69ce075d0023c1519e6b61899 refs/pull/1174/head\n0041165a91da2ba287ec682f675235313e0ffffc221c refs/pull/1175/head\n004156a22734341963ec2726e9eabaa51d7c0bbf9f57 refs/pull/1176/head\n004101a728fefcdf53a12d4190159ef3dd413e726d1c refs/pull/1177/head\n0042a37bb2235324744350d465f23b7ff91bfd16f36c refs/pull/1177/merge\n0041645b3c4efecc4799fe6e40282c2b86b941e58903 refs/pull/1178/head\n0041da3ae6f7076eced3e1905f2345136d0ff6f3dc9e refs/pull/1179/head\n00407485aac97090584e3815fbbc2273d97634e1e687 refs/pull/118/head\n0041fc120ce5c94b1a168b89a9664b75e703c00170f3 refs/pull/1180/head\n004131eb3dc0538687ab2714afb69fb4408e438db967 refs/pull/1181/head\n0041c9f32af3b88f879262a81554a5cf87f0d72fdafd refs/pull/1182/head\n00410e896c2d535ae2d5f1a0abe24c8185b60e50b4ba refs/pull/1183/head\n00413f8e4d222485db16dd53a82c1aa8d53dca62606a refs/pull/1184/head\n0041902cf79cf6c7107315190d647ce9afe83a1f46c4 refs/pull/1185/head\n004101021d07febbe1dc0964c3f3a4fe25bf2c864670 refs/pull/1186/head\n0041f40ed0b4032dffabc9edb601e3bcee77922d07d2 refs/pull/1187/head\n0041149fee3f435468ea5ba248158eef48bc6ab59243 refs/pull/1188/head\n004192a96024812d7a9471598ca7509577eb6f81448b refs/pull/1189/head\n0040fa878cbaca3a34c3a27763118e5b0d947aef3337 refs/pull/119/head\n00412745cac3b81bc800037aff2b3ab37709d37a7921 refs/pull/1190/head\n00415c4c55133d0640b0e2f6abbee881b1fd3a3356f6 refs/pull/1191/head\n0041cd47d6beab06c76d3a11d158c93ca20f09ba4177 refs/pull/1192/head\n004113d6b7545444c47dfd08faf6aa2b9e1ed6a8dcf7 refs/pull/1193/head\n0041a686ab68d088b2a72080224afa23f590c8e83a0f refs/pull/1194/head\n0041f97c4cecf158db398a7557d46233224436e88ac6 refs/pull/1195/head\n0041e010e5b0b1c0e50753277540087df697bbbddbe5 refs/pull/1196/head\n0041208f300c2b85b19840e4a105bfe1747cdb31be0f refs/pull/1197/head\n00416f67f17c15194150c498445ac4bb7f6b3cf2806f refs/pull/1198/head\n003fd90d93044396651a5760ab8619869f3ffa7e28a2 refs/pull/12/head\n0040d4fb3e5bf442245bdead885901391d6448f036c4 refs/pull/120/head\n004140a9bf1f01f1fcaff780c463653753b4b7b44789 refs/pull/1200/head\n00414e3c6c4f74cd604ee2c988d663a4f0bd5084936a refs/pull/1201/head\n004110475df37c8747ce46e549d8967bd366ae74bd4a refs/pull/1202/head\n0042d8416218ba39f441d66806e5e0b036e175c68d7b refs/pull/1202/merge\n0041a700e380ac386cc24c1054bb871d5293ac54276e refs/pull/1203/head\n0041f0e9d7ca384d95b257676adbe5db549b206888b9 refs/pull/1204/head\n0041e75b7e3be1f8eb593039e71c68c620ddca416555 refs/pull/1205/head\n00416d54b8e24ca11529459c8304de1d1775c21544f4 refs/pull/1206/head\n00410632e7fb91e7a0fed85c55fba17f03ffbca4ca4b refs/pull/1207/head\n0041b4179c0e8f91a580c494380568cc755b830cb0e4 refs/pull/1208/head\n0041d9a46d372622a55840ff16e713574aa5aa589078 refs/pull/1210/head\n00415f7ae1d59f7216a4e69bd9658878445f8354f379 refs/pull/1212/head\n0041ec47072f7b589b5076bca86e80a50b4ef0e4a67a refs/pull/1213/head\n00417a8297543e96cbfdca35deaf7ef482a887d82641 refs/pull/1214/head\n004129f6cd65449e9fce1dc070e03c5a0fd5d011c65c refs/pull/1216/head\n004188f0ba0dbdd1920ffe0212466eb97a47dbaf88e9 refs/pull/1218/head\n0041fab2e73d54951557743573f70d6eea1da3060157 refs/pull/1219/head\n00408b7243382787f405189d5180c5a574b3d725449a refs/pull/122/head\n004188a45b1b0f86c9d89061ef74d669e35f4a12a419 refs/pull/1220/head\n00418a99741ae7e5fd4f7904a0ab39bebf9c52347dff refs/pull/1221/head\n0041417322b4e9949268a0dc74de31e5157f85874fb0 refs/pull/1222/head\n0041a96feac6ea2180d6765f714dbf4ff177bf87ab7d refs/pull/1223/head\n0041c5fe75fcdd34799ea08d44f755f0fcdb8d874690 refs/pull/1224/head\n00418dac58da823f0c0370fff98e5f3d893cbedff65d refs/pull/1225/head\n0041c026d87119a26050ce707fd46d8e39a3648e46fd refs/pull/1227/head\n004122c1aba51dfe449915b86a8e89804362326ed46a refs/pull/1228/head\n00414d86f314d4f11c630f48fed1294af87fe4083f95 refs/pull/1229/head\n004095972d7b95720065b9ad13946c2f19e7940fe074 refs/pull/123/head\n0041a15cc8d82d9531f7a3c7062c5a44e1d74962db27 refs/pull/1230/head\n0041608a8693561c85a4519bad15d4477760b1213f52 refs/pull/1231/head\n00418499cabe2d26bdf79362cf5848d2d6c5feb4f3e0 refs/pull/1232/head\n0041097ff7d5dff9e064297f16888e671c1a8b20a54d refs/pull/1236/head\n00411ff8266b09309ce473a5fdfde6b23df95d91c4bc refs/pull/1237/head\n0041041c24c794f085f187c8b2626568c1ce9addc431 refs/pull/1238/head\n00417941b0db3a95531936ed7d492199e1c506f4b693 refs/pull/1239/head\n004092350c4dc465cc0e1b34e5f6c95379a19a88fe7b refs/pull/124/head\n004144e9933cfcd6f810b8c84a49654495b08aa96443 refs/pull/1241/head\n0041e3aeb1a51d39c98fe2d05d6a4e56881b8f308e98 refs/pull/1242/head\n0041297bc99ce0f1fe0c722646e878c48ca1b7359f54 refs/pull/1244/head\n0041ab57c19fb6878591469153a6b43cd200e5056ad7 refs/pull/1246/head\n00416bbbd03d1f609db86085779327329af0b870df5e refs/pull/1247/head\n0040ba000c0f39d232ea471959ade31d5bf2644e44b5 refs/pull/125/head\n0041121e405182ebc1747bc4b70ee51f1ad515eccbec refs/pull/1250/head\n00412a64d4bf9067530451df1015757b964dfe1a14e2 refs/pull/1251/head\n004138777fdb3a08b8fa21b046cc3f99ed080b773cc3 refs/pull/1252/head\n004189a916d3fa0e29776db1dca2cfd496040b7f59ab refs/pull/1253/head\n0041b90f19856b5d540108a64072c2deac6b1cd78963 refs/pull/1254/head\n00419b6edb6b82873b174431d6fdd2176c56f24120e4 refs/pull/1255/head\n00416256217be5d1950457e58da0bae4bf04f2213719 refs/pull/1256/head\n0041881388e2752e4f3dd131e8a1f8bae279d2f120df refs/pull/1257/head\n004191315d3344d7b85173da33c9f3f2b43d6b27f355 refs/pull/1258/head\n0041be6ea4d8245ececbe374dc0dd1d809cb94b073f6 refs/pull/1259/head\n004005a29c8ff1ca492bc90f87070fd303a8110e63cf refs/pull/126/head\n00412ac78599f1db05f40ae306d6b9ae7c56a3710044 refs/pull/1260/head\n0041253384d79ca6561d4f3c81f4e41514470026c6c3 refs/pull/1261/head\n0041e96f52adadd2e3f7f64715f3e9c4c0638e0fca9f refs/pull/1262/head\n0041129c977415a332d4a850ead18bbbcabb3022494f refs/pull/1263/head\n004152b028520be76bac86f78d8c684c2c5ed9cccc50 refs/pull/1264/head\n004186f9391f84fcca2c177eb788a56ae8b7e543d902 refs/pull/1265/head\n00414d3590834890a95113490d5040225fb270b5b7d3 refs/pull/1266/head\n004181622365cbead4b2326525b2601da753a24a5e55 refs/pull/1267/head\n0041117f2cce652b5628970d0977266f55eaa55cb407 refs/pull/1268/head\n00418bf7be7eb05fcca77f395a59a02e4b1e1860b469 refs/pull/1269/head\n0040b87fb4478b446f4ff48ac78beafb90fa37054b41 refs/pull/127/head\n0041c386d3a3fd7dd25d1c088999350621015b934231 refs/pull/1270/head\n004196c88193e27d33fe815eb0551d8087c8f08968fa refs/pull/1272/head\n004158ef639deb89f9d5517c308e977dc683f0c0168c refs/pull/1276/head\n004150328a328d6100da7adb817b253bb006d7c0c046 refs/pull/1277/head\n00410dfc3535eb0c29e638e9d7371fbc84f356c80aeb refs/pull/1278/head\n0041133f337708f4da78c753d8607f35590d9d0f36cd refs/pull/1279/head\n0040c79671a08acdfa73c90d555e0065ec3e108e2214 refs/pull/128/head\n00414a3f1930fa113df2b198bf7e6b4bf2753cb08c06 refs/pull/1280/head\n00417326ff73868061c78efdca1d22bdbc93f4dbc060 refs/pull/1282/head\n00414b592a00998dd4c4a9cca11be7979eeff9c1709d refs/pull/1284/head\n00410a19b05580dc24028dacf4f568529b24bc76f8cb refs/pull/1285/head\n0041e43a40ae80d2e8a6a0abaaa31ce4763d146430b8 refs/pull/1286/head\n0041fc7e59d29509405c92fd972087e6094f93f02184 refs/pull/1287/head\n0041add1a8d02937b9f518ab45756f4ed93e0ed2a7e6 refs/pull/1288/head\n004173ea6713b3e09df07ee64563409a3a711524ae4a refs/pull/1289/head\n004079f203e8674a264ca918ad0a59b52720c5053bba refs/pull/129/head\n00412ea3e74c9fa834f044e3ae49533106a4513a1c07 refs/pull/1290/head\n0041207fcb2a7a6053f40a9a570bf4ce711fcae705d7 refs/pull/1291/head\n0041215e33c64e886aa92446ff82a8bdc48bdd92bdd5 refs/pull/1294/head\n004173c35234a9984cf83a5eb299dd2db138c048f6e0 refs/pull/1295/head\n0041cb236ea352e1e55ff844930a0ae81158768fd7b9 refs/pull/1296/head\n0041436a8602956ae04dac1f0b04770ce06112938929 refs/pull/1297/head\n0041618ac0ded5bd906e79bb7b784f29846eb3af9fcd refs/pull/1298/head\n0041d6e19fb7845e1ee98706ee8f3a36f0d97e5b952b refs/pull/1299/head\n003f3a8412073dcc1900bd009153b7c0bd40d59710a3 refs/pull/13/head\n004143294d0e607f85a1ed7ce9c504e6bdbf768b3d78 refs/pull/1300/head\n00413adf485f0e8226a37911538dcee7d1f0a252ea60 refs/pull/1301/head\n00417113d61286fb327c585ee08a12b25117245767ed refs/pull/1302/head\n004120bc1bfe5d146d7a453f501c3f59d08ce3972b98 refs/pull/1303/head\n0041911566620041bd942966b0fdf5bd53ee8c220755 refs/pull/1304/head\n004285b19a8198bfab56e74c4efaa5dd3573fb44430a refs/pull/1304/merge\n0041bb833df0473c9e06a15fa30931f62f43f8fa41df refs/pull/1305/head\n0041c1dcd02d5aeeaedfbe9a47719bdcf0517287064e refs/pull/1306/head\n0041bed15155e558a64bd7e1d023f0f6c01e4e89cc22 refs/pull/1307/head\n0041ae7549465893029628571539475cab50a5f88b29 refs/pull/1308/head\n0041fdd103ee379731772968bc0fa4abce0a222c482e refs/pull/1309/head\n004052355df83bd1f16a0d6cfdf839014d0f6a0d1742 refs/pull/131/head\n00412e0d369368249bfc6c27477840adfd1745067f43 refs/pull/1310/head\n00412ede4b86018662df57603431a2ca06f0e63fe0ab refs/pull/1311/head\n0041ffe128c7f53f9261c2e478ba220ab8c2bce7586c refs/pull/1312/head\n004110564b2cf9d3e0af7986404100358a81095fc991 refs/pull/1313/head\n00415d4eeedceccda7c2e4e55857b5a6adfae318248a refs/pull/1314/head\n0041a839faa175e5f0f8c1773cb5dc565771eb4b9f5f refs/pull/1315/head\n0041e1d82ae78462eb11827aceb7100afc9e6580bc3e refs/pull/1316/head\n0041b1d8d0975cf7e2cc0cffdb1e9d861f9ec3c8a464 refs/pull/1317/head\n0041cd7839e83d0fa2c941902e812164e8919eeb6add refs/pull/1318/head\n0041b729510125f5038236e9c2f739a0344813040023 refs/pull/1319/head\n0040de13fa317c1f5f068676066815c089d2dc6147d4 refs/pull/132/head\n0041734cdc193dfaa3632bd6bd1e116d1bae62f9a44b refs/pull/1320/head\n004169f6a1f844f349c8ba3a32a3c5da1096567c65ff refs/pull/1322/head\n004157dac2df4e12ac5ac067549fdcfc33f3625a68e4 refs/pull/1323/head\n00410449ab5546a48274f8db2472e8b21f90da47f1ba refs/pull/1324/head\n004126c21c1ca66e207f17944073b90c943e0447d5ac refs/pull/1325/head\n00410525f3fce77b48be23f56df109940605c512a64e refs/pull/1326/head\n0041ff220eaa3867738f3db0eb193b4b64b358ceb636 refs/pull/1327/head\n0041b7507c4ce4d7050d93cce250f9420bf499dcf79c refs/pull/1328/head\n0041c66c75f095bdbdc61c9f6a7918250bb35d11c27c refs/pull/1329/head\n0040189e780a8f8800d4a0d3bc302e046fd6de7a2193 refs/pull/133/head\n0041961a6e96dff63ee0143258b0c085d0902187a58d refs/pull/1330/head\n004145df50f1f4d0e6d4c0a0119a259beace2112bd53 refs/pull/1331/head\n00417ab9a1982ce11b5f59474d9d1c4290deb3cd66e7 refs/pull/1332/head\n00419ced3c989395984365a5cd2c756124a292692d05 refs/pull/1333/head\n0041290599c46d3019e2faf2c278c11a534ca383a8ed refs/pull/1334/head\n0041faecb02327ed55b78f3f52895749c9d5c83b5d79 refs/pull/1335/head\n004104a4c755a57d4eabcaeacfac73ae163261e2dcf1 refs/pull/1336/head\n00419e97654e7bd49474a89cf9ad0139bda19dc1e5a9 refs/pull/1337/head\n0041fc6fba1f9f88b4eec99b5222a1431f13b74456ec refs/pull/1338/head\n0041f1bab89b149ef99141a371a872979a47de900ce3 refs/pull/1339/head\n0040f2340c7785b24944f55d7e97e27b347be8df3a97 refs/pull/134/head\n00415a06f626752062956a8a1381504662c2d7ebd629 refs/pull/1340/head\n0041ea595ee08864ca521498095f830189a7c9df36a8 refs/pull/1341/head\n0041257c3048815f335b9f0a22fd4854b1237aaf0e05 refs/pull/1342/head\n0041bafbee83538cf951f538ca7ad13779f59f164d71 refs/pull/1343/head\n00412fd3ce652de76465b0f42f488020dc954885d2d0 refs/pull/1344/head\n0041c64bdb1c7e57087ed8d84e221de17d758391f2c9 refs/pull/1345/head\n0041747c018e63c009b2155bb4f6deb6a583d3caf22e refs/pull/1346/head\n00414e30fe74d61b9166b308ddc6ca31248ad92c0574 refs/pull/1347/head\n0041c3fc7f915e82757460710c0e8128ee5b36911035 refs/pull/1349/head\n0040edc675a835d97be1fca5e3cba3de1d92690395da refs/pull/135/head\n0041a0b692649edbd8b4d3e4fc273edb51b90dab4226 refs/pull/1350/head\n0041bee1b515d3eac86a33be45b026744db3594701f5 refs/pull/1351/head\n00417a8e666d0bd3aa6de59703c76d327d023e855eb4 refs/pull/1352/head\n0041b4c0c67c083c3f3d9275dfb2f3e3f30b014598f3 refs/pull/1353/head\n00416cc04160395a02237ea60fcb56369dcc2af898bc refs/pull/1354/head\n00417b5d44de35d37ec6af061e835241251cf0600906 refs/pull/1356/head\n00410ddb923bb03a95e57aa0e591c9d79a6bbc042ccd refs/pull/1357/head\n00415f4e98aebd5c88b1f31d0dc5fe89d756e4836657 refs/pull/1358/head\n00410b6677fdfa4169e0426b59f2b811c633848cef5d refs/pull/1359/head\n0040e9437545a50ce325010edce479c33fdb5fb8e911 refs/pull/136/head\n0041da17b72261b13286aec80d2720d55ded18ac9c20 refs/pull/1360/head\n004175df95cb365bf57e6605ec4768f11ad6cad1c5d9 refs/pull/1361/head\n004161ede2f2c9831b2ad582dd0b46b668e8f53eda44 refs/pull/1362/head\n0041afba174909676dd33be7a4004636350c0c4866a0 refs/pull/1364/head\n0041e2196d07a5f82f433a3d45db1ad79dd073fed364 refs/pull/1365/head\n0041d8202d6c7c333bd3cdd030884261af6f8af1edc7 refs/pull/1367/head\n004100eba200a2fdcd297b2aca58a6ba86eabaeb2b4a refs/pull/1368/head\n0041831e8fbd68217ff1d460dd4df4b21f7c22b6c7bd refs/pull/1369/head\n00409626f978d682ed60c4f361078d5add6f4794914a refs/pull/137/head\n0041ce2ad323892dc3a11963c9968da41582fa403fa9 refs/pull/1370/head\n00411a47355f103ecf545a1bb3a498f1a0b5b76b2fef refs/pull/1371/head\n0041762fae248f54871949683a7fe74bb3ed1d04f1b5 refs/pull/1373/head\n00416980afeb6774a3f8ef05834d8baf2df6a0f9bcde refs/pull/1374/head\n004144bbac892c3674e04a4c22107572fdb70870291e refs/pull/1375/head\n0041ca65a6f8e68e7c84b0845ae551ded0955b65dfd1 refs/pull/1376/head\n0041a6e1d21fc5b0fe82b02eac25b2ad3e06f5b7d851 refs/pull/1377/head\n004177404b3cbb5f0c567e9923373363670b107cb7dd refs/pull/1378/head\n0041e10cc0588b127c0a7a345708ca4694b23b27a42e refs/pull/1379/head\n0040e07f89546938680d414fd7b9485f3c0aa7ec0232 refs/pull/138/head\n0041dff810775dad1f692e87bf9411750c8ce22c8976 refs/pull/1381/head\n00416278f3cfc933a1a2fa5fe4c1006a8f3353e24b0a refs/pull/1382/head\n004103e3e96fb3dba1d920fd58fabdd6fbeb7c99bb69 refs/pull/1383/head\n0041e215906b2e757daf6f9cdf479c6ad074b965ea37 refs/pull/1384/head\n0041f60c4322be9edafb23af08c9be6c20c9f85108d5 refs/pull/1385/head\n0041b246f36763b355cbb9cc093783ca6f13f9cdc4c3 refs/pull/1386/head\n0041721c39c10965b428e222283aa864f06bb154c04a refs/pull/1387/head\n004171afc34970336601672c9edfbd3999e924a448db refs/pull/1388/head\n004078ca8ffccb0245a5a61cf24f778008d9787f0998 refs/pull/139/head\n0041e72e66bf5707b31c82e55f3292407daabf66e6b6 refs/pull/1390/head\n004127bed5c648b4c2bdae20ae119e50b968ea79ab1d refs/pull/1392/head\n00419ff43939cf0c8e6986d8e92126e6338863b648f4 refs/pull/1393/head\n00410a552e22b16e6fc24ea55f88d20c7901ad2c3cff refs/pull/1394/head\n0041a21275fef5419e8ec3c8c92826bc05d6f2c645bb refs/pull/1395/head\n004178832b0fc1490907c8fbb936dd7b1c43c5863170 refs/pull/1396/head\n00418951ee20a76f985f31f7adb31d4f3c1990300789 refs/pull/1397/head\n003fc6b4d55a540de28af226e774e0a2a49e70ab02d9 refs/pull/14/head\n004016c45dab0a86a40e2ba16d8efe04e0be57e78cea refs/pull/140/head\n00417dd1f2f0fbd3520d413b1b4a458c0276ca3f05c2 refs/pull/1400/head\n0041da9a726ce2f007ec4ee803ce0bd7157b4421e0be refs/pull/1402/head\n0041186c598fee1c82e4c4e904856d5dbf4fe7b109ad refs/pull/1403/head\n0041d8326a0f09b0ed2aea1a559d6af68458c63bf3f7 refs/pull/1405/head\n0041236c0c3ffc7ae031d21814b583c637cadd989d75 refs/pull/1406/head\n00412ef45eca094f6f574206fabccda2d9ba36ffd7e6 refs/pull/1407/head\n004169dba3b7a359925aafe3d06d7b6c5f0c40f360ef refs/pull/1408/head\n0041fd84167ec1429163534a1c312ea42f7b48fac010 refs/pull/1409/head\n0040ebb6c96b259d1a247c14f0db7adbd63035db97fd refs/pull/141/head\n00415b72bce47ac95923bce868b8fdedc204bdd54af4 refs/pull/1410/head\n00412dd82629ff324d2222d5bcec6fa1df77f023b330 refs/pull/1412/head\n0041566b2cd164e5b92b7c7993d45f367eaa4ac13293 refs/pull/1414/head\n00411f2e4049e40f05de6bc89a4df3b902617cd2c4c7 refs/pull/1415/head\n00411138579a9fa79aab8611dd866a5c7d7b36d5b407 refs/pull/1416/head\n0041520b03ea4d2fe774552ebbf371a546fe16e00d5c refs/pull/1419/head\n00403ea332e3d92983d258198c4944e48f2a679e6705 refs/pull/142/head\n0041cbae00c32292523e1178b7936cb6a0ee0c544ada refs/pull/1420/head\n0041df616c3977bc7a2125170035b062cfb931b39c0d refs/pull/1421/head\n00417cc8172bdb8a34456e676cee0d4ce9084ba7bbea refs/pull/1422/head\n004192677833ea4b356154ce80923125322345e0d4e0 refs/pull/1423/head\n00410cb307fa354bd8e66ae40b7fb3cc537b884c03b2 refs/pull/1424/head\n0041e5cfcb34d6c24a402aabb88f79c321124b89562f refs/pull/1425/head\n004136f4a8e330e49343137e747d02300ad6b352d7eb refs/pull/1428/head\n00414a4e9c9f75a503df0da30240b8dd382811a34448 refs/pull/1429/head\n00401e851bdc987c158bfe0edc3ce66cd3ab32b95efe refs/pull/143/head\n0041640a72f812d1681c148081ce769c94d18089a531 refs/pull/1430/head\n0041768bbbc5e3e37c678dfb001bddbf3c8c4a3feab1 refs/pull/1431/head\n0041e66f71fdd1c431a684a6d96b7b0e02f99e294e8d refs/pull/1432/head\n0041a0e482e060ff55476ca8038cac6e0b7c659c3373 refs/pull/1434/head\n0041fb2e26335ddb51333e162b916156c0884f567c37 refs/pull/1435/head\n0041b1772fe46558e79a885a654ff12d5a2e194c2138 refs/pull/1437/head\n00413681973c9df9739802d4137c63b769054e65ed19 refs/pull/1439/head\n00402e9dce6c48f32267884dd2b28842ec6925b645fa refs/pull/144/head\n004123939d417e265d55ed1fc3aabcd501507ee01ef2 refs/pull/1440/head\n004197c65d1cd8e2c8f901cf5fc86614310abb52fe9f refs/pull/1441/head\n004103dac88c576f8ecab3db909f629585712b8c0eb4 refs/pull/1442/head\n0041a6f76105ef194c3eaf7b4b7912a38f7294c07aae refs/pull/1444/head\n0041fb648a2ea697e46ed51c35f68c8236b3bd10e59c refs/pull/1445/head\n0041afe3ae2d7fe951c37913e38fa09b4fd3a6507008 refs/pull/1446/head\n0041466b94b687fc5518d881f59d1e0372443b841e34 refs/pull/1447/head\n004123532d67a96aeaf8b4a6361a3fadccc6d933f37f refs/pull/1448/head\n0040593ef33d4b5fe2d7feabb021d0972519deb6b744 refs/pull/145/head\n0041ee9ff50c9c2b4ec849994b49738eaadd45df8d11 refs/pull/1450/head\n00414d997c6f83857a7873eb78b0802816a5cba610d2 refs/pull/1453/head\n0041c1b4346191fe2b03d0c41637d53d00a84ed431b6 refs/pull/1454/head\n004119120bfb738b794199bfe5797b8248c6e1920492 refs/pull/1455/head\n00421d489a06e8f566b83feb9b10282434c69a2a848f refs/pull/1455/merge\n0041e93dad30305e69dc20372d1a7684ac76c2b977ee refs/pull/1456/head\n0041a5f94be445a32a0c5991e85d12fdda4a8fa2fc97 refs/pull/1457/head\n0041164d702fdd71ca10606e1701c9ebed15a885da41 refs/pull/1458/head\n0041d342f1d18f88041e3fbacda44330e22d9798e9e7 refs/pull/1459/head\n00406df8b6ad0a9e4dade94f2747d776d7dda1f4e4f8 refs/pull/146/head\n00417647947be27328f428cb50ef77189933561b6990 refs/pull/1460/head\n00418a4b9b4ffe361034167304c74c026ddc6ac4a33f refs/pull/1462/head\n004142813fb3381fa994874cd455ef72b49874ccda7e refs/pull/1463/head\n0041df4c6c121ab7033a14f9bb85f4e7416c8629c06d refs/pull/1464/head\n004105696886d50ce893da5dc7b6917e9947f3bbb835 refs/pull/1465/head\n0041fd3cb207b52d77dddceb45d01c33065f495ef029 refs/pull/1466/head\n00413a659000e96e36927d6edb20fb7361e74300ecf3 refs/pull/1468/head\n0041f49d889a01613f914a8d1768e449fa51a9127c54 refs/pull/1469/head\n004196895dba95749f0b38fb2d49f0506bfbbb9539ed refs/pull/1470/head\n0041f2f5eef8ce350ba79a9cdb67a96e968c3c5c5beb refs/pull/1471/head\n00415d7d6f1f25924dd01528a74cc38877510345299f refs/pull/1472/head\n0041b62dd25e1192be880b8c96e162ae5f6905524084 refs/pull/1473/head\n004164469920f86f96c92a5f69b313990f4b3b08b007 refs/pull/1475/head\n0041ff1fd64690c606dc96f61d599866f1ed7da972c6 refs/pull/1477/head\n00415ca8b4a96239e4feca8336661d98ea495bb1099f refs/pull/1478/head\n00414e696f6e40d363f43a084a0ada2144d8cb86873d refs/pull/1479/head\n00418a2e104021bd2cd6d2b69f606d784d1df6c7b8a9 refs/pull/1480/head\n00414f78a2c9c44eae18251b89aed140f9bf4985d028 refs/pull/1481/head\n0041bb284ef37e8480c03b519560f08f8b38dee5bb98 refs/pull/1482/head\n0041fa1d5b0c70383c08e7ee37bf66485198ff3e7ff8 refs/pull/1483/head\n0041c3a7a260d2f19a4d350e3346d008c776f74e9b98 refs/pull/1484/head\n004110e894be6f4d9b506f5459ea296592c312f5c053 refs/pull/1485/head\n00418d611111423fb3596be120ee6bcde94aeccf3745 refs/pull/1487/head\n0041afefc631fce6dff9770db8867982ffee8b091218 refs/pull/1488/head\n00400b8e4aa1499399f5212fd700cf2f310076ae8010 refs/pull/149/head\n0041ab1a2bc6c7337ace9e89ea483619794ce5a2565b refs/pull/1490/head\n004171ffff50fbf4cad3b72c45644e926b0378005212 refs/pull/1491/head\n0041bb95218921ae7fe9e8b4c3336278e078c315d0fc refs/pull/1492/head\n00415c20d41d46c16bfc6a9e82f744bd9b5541f3fd18 refs/pull/1493/head\n004120eab42cf1a7a89de8ff99af2d73a32d6cd5bfd6 refs/pull/1494/head\n0041a6764c4ed63427a5145422b6f7254ab4529bc8c6 refs/pull/1495/head\n0041c617d48580fe8aa02865fdd3c434d507a5ffe940 refs/pull/1496/head\n00418286eaba5003c774fc206fafdabb0a2f8ee2a50d refs/pull/1497/head\n0041f5f9b82390a6425baab9dd8d7c8937f0d2680b24 refs/pull/1498/head\n0041600434da8ba54186c894f8032da0cae6161d492d refs/pull/1499/head\n003f3c6e266b75f17fa1643a1d0b189b8d350bb8081f refs/pull/15/head\n00409aeaeccd95e696e800e08ccb6fabfedd7ad0e8a7 refs/pull/150/head\n004162a27e278e0cbd969b615943e89f1ed0ba4d76ed refs/pull/1500/head\n0041204898438a43b37fc7c56f5ceb9f2bce1e6d28ef refs/pull/1501/head\n0041f55692ca0190703a2e425672c45580b440a70bd0 refs/pull/1502/head\n0041ae9e151e3c9e7beb6e3acda1f075c928bef0b5ae refs/pull/1503/head\n00415c6a2af85703ae61fb0e53a0c0acc6ce2bd35918 refs/pull/1504/head\n0041908d4fbbd4502e8b6106733f88373ca813fb9dcf refs/pull/1505/head\n00417aab084a2629b0a33c7a314991b38f2bea80af12 refs/pull/1506/head\n0041341380d6aab2b719946ec0c1a5be7c0cd27a0cb3 refs/pull/1508/head\n004173116a39687c8aac406d5f3436ac2382cd67166c refs/pull/1509/head\n00410a69ddfa848b2722f6e019d5c975877d9015ff32 refs/pull/1510/head\n00418b22d1d80d3989e19f6c5c639f1d43756c83c4d6 refs/pull/1512/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1513/head\n004107f645f4d3f21c4a6e5d37dcf9433ccfe16778ff refs/pull/1514/head\n0041b9f8f60c3d32e202f61a38cd9298d498f9d47d6f refs/pull/1515/head\n0041f83d3497ba7dc9e2d636bb2e4ae997d199eac114 refs/pull/1517/head\n00416973913e0ac5903ab71dfbe1b9d36bfaca0e4f15 refs/pull/1518/head\n004116733b33f6b8e22db85c87192bf755b7e5ba9ce9 refs/pull/1519/head\n0040dc7027b6d5069c1decbe4db697f29b71dbedd0d0 refs/pull/152/head\n004169d63353a10a2ccb6bbca0cd8e2ea39f07b473b0 refs/pull/1520/head\n00410d459a3a0d41b09508ea497686d1570c86a1d103 refs/pull/1521/head\n0041d898942392a908832d3665b8c01b1d9a908bb4f8 refs/pull/1522/head\n0041f313b6cb25b09f2b46fe64f73006162494abf44f refs/pull/1523/head\n00413672ab6648e9a5a7be2a98a15ec365a10d2fd64a refs/pull/1524/head\n00410bce19c9b7efd2ff89cd8fe5cf8b745151c0422c refs/pull/1526/head\n0041112afa3e48db0f2de21a6a2eabf87c8eead601a2 refs/pull/1527/head\n0041d96bcd6c259eba410208303f608604f12d94d01f refs/pull/1528/head\n00419691f02b5328cc5cd5bd107c0f9841a0cb98660a refs/pull/1529/head\n0040a482a80f7e437e30efa5eb9fc21c09d025be30d4 refs/pull/153/head\n0041c76aff6be45a0cf7db5c5711e4e40113f64dbc47 refs/pull/1530/head\n004104340dfc2861f9f6f3ef103a0025a4c53a39fca1 refs/pull/1531/head\n0041e64567c751cf73ca090672778776a7175d5fefc3 refs/pull/1532/head\n004185a59eb6f51e25e5ec8671446d376d0f2f7da910 refs/pull/1533/head\n0041f6d77b8c6d7b853ccafb13efddec6462d1aff581 refs/pull/1534/head\n0041da0d3a3a6b2ffe0023b256cb8869931ee9c5b204 refs/pull/1535/head\n0041882e49547e2172435fd055f858a1d68ed0debcc3 refs/pull/1536/head\n0041b441fa217409bd0ce6aa4a837cd3f7447766fb61 refs/pull/1537/head\n00412f834281750332a14fa6c7c60696d1736927c663 refs/pull/1538/head\n004116cd702ae99af2129410201438008c0ed6a88709 refs/pull/1539/head\n0040f78f9c4948f1f81a50d51265a55aa736b01489f3 refs/pull/154/head\n00410c2ceadda13aaf9fe821891c11bc42b28f13c000 refs/pull/1540/head\n0041c6b0b982c9b39b3f31069e60453dae96c10866cb refs/pull/1541/head\n0041d2e4e5e58508c7aff695768346c200d57229a21e refs/pull/1542/head\n0041ee5cd9ad00462ab8b1602c25cce5d57247651ae5 refs/pull/1543/head\n0041db0dd1875b8ba55ae38b0fc205c57462d5264984 refs/pull/1544/head\n0041327590d91f1311a3a6e53cfc48e03b539cc7d955 refs/pull/1545/head\n0041ace6ca433914068b255abafa6fbd0ef16ba2d201 refs/pull/1546/head\n0041f19785406811be353ec421c04bce3f346eded10b refs/pull/1547/head\n004172e13a2121813367053d4ecc963d2305e85bc86b refs/pull/1548/head\n00418c4f183f2f6c6e646979f996b447e05fd2688ec6 refs/pull/1549/head\n00409d5ed41f9d2193e6794deee4f8bb7a813c9343b3 refs/pull/155/head\n004186322a7793fb78f2471a66f28d1380ee2ca72afd refs/pull/1550/head\n004145aaab129c2f7061b129b296c55c7c2ac48132f4 refs/pull/1553/head\n004149d849fd2e1f9614cb537fc19bc54e556c9b09b7 refs/pull/1554/head\n0041bbd33796f3faa42f40b28134ec8b3efc142694f7 refs/pull/1555/head\n004113af1a0f28d8a9bdfcf98c6ac827a6a3ec828baf refs/pull/1557/head\n00413956a7dd8a950fc58241286efda84dcae51abe4d refs/pull/1558/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1559/head\n00407dcd66ee089129b124af8b51b26fb8728af4773a refs/pull/156/head\n0041947083e60bd3c568927ba12314efa05aac5290dd refs/pull/1560/head\n0041f16c2fb4ef30b707b56556b2e2c40ed8cc9adf42 refs/pull/1561/head\n004166ae1b5c1780e6c8444b39ab3f112b7b3e02dda5 refs/pull/1562/head\n0041dceff72b9c029a97e42ec1a5b0769d06f153b8d0 refs/pull/1563/head\n00416a399d6d2ad5dcf71bcc04cd21e939de5e7767aa refs/pull/1564/head\n0041695353bc990ce2a62d31eb1fb13f541d1cd703b7 refs/pull/1565/head\n004152049e0509b4b44daac5b37016b0dbca1fcb37a6 refs/pull/1566/head\n004187d5eaca8701601a39947d440b185d894c737407 refs/pull/1567/head\n004142c31c24b1d69723bbb699578acd02af9f78800d refs/pull/1568/head\n0040c82b8e525303e6fad770e0540dad5dc00d76c83c refs/pull/157/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1570/head\n004192716c0c970fea2ce12cc31832b3f45f3050ca21 refs/pull/1571/head\n0041462f5a219f3f8f78092f98f26c5b58a847db6c7a refs/pull/1572/head\n0041c5b85a430a260fbd9cf2e4f360f8f20d53afdc53 refs/pull/1573/head\n00413019ec74ede79e77d5672fd022ca3177572cd72e refs/pull/1574/head\n0041194db15636a13d052e81164641cb23bb53be4b49 refs/pull/1575/head\n00412b5dafc68d002735348433ae0ed81908ecd785a6 refs/pull/1576/head\n0041f2c653dfbda3bab74478915ada61e0845012bd2a refs/pull/1577/head\n0041d870bf685b2b776ff7ba9eab78ed55505ce57c1a refs/pull/1578/head\n00412fa7f48896e8980b11a2b558ebd6a20e7be292b8 refs/pull/1579/head\n00408068436b2a040871c83cf6f39c2d0d74d4651e47 refs/pull/158/head\n0041d958e812462e34c99c37d217f0f08ae91b3abc03 refs/pull/1580/head\n00415194418a88de9fb53ab6ed80432831331e15bbae refs/pull/1581/head\n0041c3a4e79dbd933fc8e947815c666561d51d795f91 refs/pull/1582/head\n004131da8dad3c1ac11a0e12490fcb6e98fa8f2c28b7 refs/pull/1583/head\n004125ef6c1f49836f51ebff2f4135e4596992d678bb refs/pull/1584/head\n0041e0ae728d9925a62008f60a22e1198f06a6ede5c6 refs/pull/1585/head\n00417fa05c71e0d2b2217facd2bad243781858ed6e9d refs/pull/1586/head\n0041ff5cde817af1c25f5fa26bafc4ac4073bcfb1e09 refs/pull/1587/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1588/head\n0041484995c39c9c8cb99c885903c64a06b782488b00 refs/pull/1589/head\n00406fc981f0f578112dd57d3c9221d8e8607222ea02 refs/pull/159/head\n0041a0dc900a228f0c46f97b3e4c59acfe55c96ef2c6 refs/pull/1591/head\n00417df0c764d7fc60f3b32fdcd11be57d153882902a refs/pull/1592/head\n0041426317bfe888889daedec42b58f58b3e1e2da129 refs/pull/1593/head\n00412c9256efc644bf765c45e5ae8a2a8fa851d37c47 refs/pull/1594/head\n00418405e05a3f332b28d57837397ce28a63e48f795e refs/pull/1595/head\n0041fd766e7699bdaeffaf5625a4a583dbd5d4b68141 refs/pull/1596/head\n0041a1fa4e7ba21116c602b2e2d196eca51caef853d8 refs/pull/1597/head\n0041b7919627c927d8559f12538106956397a3ae92ad refs/pull/1598/head\n0041d796b6f8340e2bdafa4e4073fbda29550b21c90b refs/pull/1599/head\n0042dc55d0d581c9390b6f71cf04de9815c5e77d7771 refs/pull/1599/merge\n003f16b3827af689b39902ef03363e8f06aa8a917b37 refs/pull/16/head\n004048d9e4009aa1d2d8cd18f948ed4549a55eba97b3 refs/pull/160/head\n0041d3f1dc58018d6b40ee2f05e5f6821671b319c3fd refs/pull/1600/head\n004131a64f5e4936499faa79e40018515ea58b3c0302 refs/pull/1601/head\n004100a02591e76295b34878ba180df0b8a9564a3b92 refs/pull/1602/head\n0041f763b73ac812aaafbad92a084773bf1d13f80943 refs/pull/1603/head\n00414359fa74d8b9a01b428f725d692299264e80921e refs/pull/1604/head\n004146d102ceb52c713644eadaa7846118c8aeee3a09 refs/pull/1605/head\n0041e98427ba70a78b5d7a64c427e7a9cd09de7b71ba refs/pull/1609/head\n004007f015f1904e253e994ee240a9615bf16315a5f6 refs/pull/161/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1610/head\n0041f2376611924effe0f0f03c541f480137d78e573b refs/pull/1611/head\n0041a0f7092b2162eafb07afc502fe26c262c75a51af refs/pull/1612/head\n0041e7a8372d6366eb5d6eda0d313e5a0c4d6f2e7b10 refs/pull/1613/head\n004156cf6c79473ddcd9db99668d49a23b29c01a667c refs/pull/1614/head\n0041eaa3e7ffff279d64785a8ec77bf6d7f5df25b7da refs/pull/1615/head\n0041cc8c5840078f65bec296c001effef0c762b990d8 refs/pull/1616/head\n00416b3f053810f3d897cb1c543d109216751697bca0 refs/pull/1617/head\n00412b744813cf6bed7507c0a5003db5df0aba55fb7a refs/pull/1618/head\n0041ca91696bdfb5a59629a3471daefdac6d4e2ab0a7 refs/pull/1620/head\n004174214297869b28ffd536479c068ecaa3997fb7b7 refs/pull/1621/head\n0041be0908a0431c116aca177fb7dfbfc551ccaf5861 refs/pull/1622/head\n0041e5c686a63314322ab70fc59f181733bb23fced34 refs/pull/1623/head\n0041b84b0eb192fd47997e3d508fd2fcfa5b7763e026 refs/pull/1624/head\n0041aa15587ad20ca465e390add59358df0cc2830608 refs/pull/1625/head\n0041414762a65ad10f46b75a95dbbc8e56de95d5344f refs/pull/1626/head\n004131a5726b22a2cb4cb794b01b5d3a75ff934a6ba7 refs/pull/1627/head\n00413691e6cf3f6767d85cdc6dc87de6178d8e00a84b refs/pull/1629/head\n00400110a956f7c25b31435717b7c6f517fbd4ecfc9a refs/pull/163/head\n0041473061e7dabc8c56aae9fe447a3173db6c7c3380 refs/pull/1631/head\n0041320bc9418314813464d0b91d5f820526e6dcaa40 refs/pull/1632/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1633/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1634/head\n0041ced684cd213166117663572f0f13591bf5168ba7 refs/pull/1636/head\n0041653eb97d9afcaab55c7157a3d9a7896f9f8a9cc0 refs/pull/1638/head\n004002c71918d8b56bd9f6137e1a526d1ac481602c25 refs/pull/164/head\n004127a37fb1ab3e5fe5a1e9b11beaad54ce9281e525 refs/pull/1640/head\n0041ad1fdf91c8ee67b0d073a6a438a52209cb15862e refs/pull/1641/head\n0041de207ef037cd5ddc2556df0610a7a172ab51dbc6 refs/pull/1642/head\n004145f73022342a0bdbdac7417629105c4baeafd79c refs/pull/1643/head\n0041b985b6379b054c5adb75044640bf5cb9fedfa4b1 refs/pull/1644/head\n0041843a90655a84ca944e43c96e71557c085e294d9c refs/pull/1646/head\n00416840f1c445eb9105a17e786ce13304d0e4997187 refs/pull/1647/head\n0041b6d6f53c233c8f7b52309335a1f5eca9fc814165 refs/pull/1648/head\n004141d16635e58d5c6179192206758b4270a9e8f965 refs/pull/1649/head\n0040be088688bdaf7b272c7811e4869caffc60a34d87 refs/pull/165/head\n0041511c386150398998d87896badef720e894330987 refs/pull/1650/head\n0041cee9378ac0bb51431bed15a4a4a137820340fb70 refs/pull/1651/head\n004181e9bf6e4bc3d061c601d117692c9dc9fae590b5 refs/pull/1652/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1653/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1654/head\n0041b37b4076f5874c11113b926c8fab9f7dc2444952 refs/pull/1655/head\n00410b9242402f6b614a7a964b191dfd82d91eb807ee refs/pull/1656/head\n004103285c5cc430a2d4d95b25e43c4b9fbfaa66b75d refs/pull/1657/head\n0041cf437402222547477d626343ed0afdf5efc0f8b3 refs/pull/1658/head\n0041fddb6460bf6b561b82bb98f3ece98eda40231dc5 refs/pull/1659/head\n0040c7463a50e9d50aedfb8d2b01f8fc673dc1972f14 refs/pull/166/head\n0041330dcc98ea9fc10d8927d289236eb8c918c4bc51 refs/pull/1660/head\n00413412588e0eb37f94e5a155797d6a223fe049461b refs/pull/1661/head\n0041e3ba44799ec67cc578e33f7e397c529ce919f838 refs/pull/1663/head\n0042daca13a892bfabe2290650e9f908617e47230586 refs/pull/1663/merge\n0041e4571b9e0bb399600daa49e941e0f1e7c487ce2c refs/pull/1664/head\n0041605b1067212bcd7af0737f42280c049283d7f7db refs/pull/1666/head\n0041947c24007cc76d6c31fd44f2849dbc977b4bad0b refs/pull/1667/head\n004171767c8f8d91833961d253863a3bedea974bd26f refs/pull/1668/head\n0041606a2e0d39ebe60e887e64c0e4e33c591e997e19 refs/pull/1669/head\n0040550ded776cafadb014dd81dbaf58c469d5af6ad9 refs/pull/167/head\n0041c0b62b8b28336c5a5086870c3eab71aaaa150c4a refs/pull/1670/head\n0041c02ec43a14e1ec42052ef738745864d69e7eefbc refs/pull/1671/head\n004178391b1c345356ec78e9d6c033d67443952122a6 refs/pull/1672/head\n004179b4e517f71483bac6f33db2c9c070d4abdc0e45 refs/pull/1674/head\n004169a3f0506feb52f5b5705dae8828f1a20c43bd6f refs/pull/1675/head\n00419e54ce53a375d24abc214619b357acbd424e5814 refs/pull/1676/head\n004122a5879e288c1afa2052f715bf6cf92ba93ef076 refs/pull/1678/head\n0040d5ab3681b90575681caa9144bf1bdcdf723150f2 refs/pull/168/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1680/head\n0041b49309b4e8a5a0cda1677745b2941be87a642ff3 refs/pull/1681/head\n0041203cd06339c36b8767e2e60dd55bbc3ac923b645 refs/pull/1682/head\n00419eac881720f2cd451c7b48b3b2dec5fafcfc6acc refs/pull/1683/head\n00412cab290ed8db8ba56e95e12081a24abcb9746ef9 refs/pull/1684/head\n0041bb280dc1a53c81287eda1e678c25629c8ebb8851 refs/pull/1685/head\n00419b5ad70828ca0c941fc424fc35e10eb2eb53d475 refs/pull/1686/head\n0041c2b84a61807bcf11f35dff1aa544b0a92a0c6785 refs/pull/1687/head\n00416f6fbd991bafe78b2b87f92f5c6f8327888dd339 refs/pull/1688/head\n0041d3818b9df267986e07e8df723464e09cd195d583 refs/pull/1689/head\n0040c32413680d38e366510a47a6c150eefede26987a refs/pull/169/head\n0041f7b84db702b7b111c176780a17a24d88c721d49a refs/pull/1690/head\n004133dc34724f0cbe5de45246ecab12c5a3c1ae5602 refs/pull/1691/head\n004158c03b5016c7d62755205a561b10babe4f24b472 refs/pull/1692/head\n004122c16d0528c48509297dec8ad6207ce879f20f07 refs/pull/1693/head\n0041194c74cbf4ee1ec28b85979c2424b73175205375 refs/pull/1695/head\n0041ebf909a4cd8718cc731e498ae9ec5cf11a148e1d refs/pull/1696/head\n004126798baab325cb4720e80dd2bf5ad4d3ddd49995 refs/pull/1699/head\n003f3a4c90b02ad2afbe09997cb3cddea3f2f96cd710 refs/pull/17/head\n0040ed7fbcee57b7f9277ffe1260e3365b4b8c628b26 refs/pull/170/head\n0041f6be2d94e8a159d03682495360a84a99e2849ef7 refs/pull/1700/head\n00414cff272b844f4409267f6d4a0dfc35d522b4b1b5 refs/pull/1701/head\n00417d9cd867535b37dfb109312c118fc1c4d99a1e12 refs/pull/1702/head\n0041402453d160e42a2becf0454355e8f21392436ca0 refs/pull/1703/head\n004166d3d1ece5efadd29e2ed40613080bad24588f00 refs/pull/1704/head\n0041d36a83b869ad816367e3a520df8b34e0fa30063b refs/pull/1705/head\n00412d5d59d0c19aab6f41ef43dfaa5f5dd84ec3635e refs/pull/1706/head\n00411dde7bc4eb32f5229e4395528009a6abff975fee refs/pull/1707/head\n004167a4b8816b0d95195649426e01c2d5a285c87c69 refs/pull/1708/head\n0041583974851f9986aaf9aaae1684ddc7da54061668 refs/pull/1709/head\n00403f8f78a70ddddaa6e381fef4e575e5b0bad9f403 refs/pull/171/head\n00411f78db7c0890d6de7d968b149da0cf6eb44bae16 refs/pull/1710/head\n004181b355fa672aa9f87f78ac1365a9fe4302ae6f26 refs/pull/1711/head\n004147050c34195f06ab88e8b2e5d41491ef82a897c8 refs/pull/1712/head\n0041859de7de8c7b56c46fd0a2afb1a56bf7be4a0efd refs/pull/1713/head\n0041508ee173626f605678598d0363806d452e6546e7 refs/pull/1715/head\n0041e431c79ca359bf4a6dc5e756ca2416867b1f26a2 refs/pull/1716/head\n00419bb401e34362ff8f0ef0c7b1e471126a98e6e72a refs/pull/1717/head\n00414a9f3908193b197e0fac3c04a6820f9947527149 refs/pull/1718/head\n0041c7c27dfedee3c8fcd928c801e7b37f24f3604c40 refs/pull/1719/head\n00416eda4698764d62eb549a653d71fe9c89efbda7ed refs/pull/1720/head\n004147db827f4e9e07495e988979b2bcc5f0f1c3ac5a refs/pull/1721/head\n0041dc37d4ac77c3a83b1209c9ac9d386f7a21164c6e refs/pull/1723/head\n00412856b0618349793952634c56899e3a59cb4bfe4e refs/pull/1724/head\n0041137adae315ed82442e245d922230737921ab8476 refs/pull/1725/head\n00417f6ab1cddbeab54f17621134f12643dcff6e78ae refs/pull/1726/head\n004111a2bf4d085236a9cbe9846ff9f22f9976e853bf refs/pull/1727/head\n00416b9ce0fa8acc5fa39b58c998050507de1eafc74b refs/pull/1728/head\n0041eba0ba181ab8cb8f9bdd603762d9ca1d0ee03e6b refs/pull/1729/head\n00409bd080d1c1e0f331e10ca935b7ae84a67743e00a refs/pull/173/head\n0041621b55a6453ea373b338093a4d6ebb246816dae4 refs/pull/1730/head\n004166cf11882a13aa5ecb9dca3a0856625d40a0661f refs/pull/1731/head\n0041ceb4390ee4f63854ee38c1ceffe09bda29ec19a9 refs/pull/1732/head\n0041f046d5b5e50c64f21d971abdfa97cc7d40bff25d refs/pull/1733/head\n0041299bd320c28aa4aa7a7ec3248ffdceddd791f1b9 refs/pull/1735/head\n0041dbb64a42761a875114e956ec6070defbfe422b26 refs/pull/1736/head\n004168e17a207baa24049da479274cfa34d7432c90ac refs/pull/1737/head\n00414a9f6c8d165fbd1f30eb478e7d09e91c185dc2e7 refs/pull/1739/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1742/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1743/head\n0041efcc272b15e6678ae0b87795b085779de6cc6b64 refs/pull/1744/head\n0041afaa7c3ae485f10eb98db9c9ceb3a1b3b135bdde refs/pull/1745/head\n0041fdf37f671a1e1b7fd1dc183769eebeff9563f252 refs/pull/1746/head\n00412c85053cfa420c869bae7ef023c52300eaa0ad2c refs/pull/1747/head\n0041d28d46d556d50949a51ec2b2b9e736b99947cd36 refs/pull/1748/head\n0041242e8396de3475422e0e4b575d2be8b13acfd504 refs/pull/1749/head\n00404f150c542aa5139058ccf57dcad562890916b477 refs/pull/175/head\n004128b5f8610a75ef7f7eb4d0860391893a023a522b refs/pull/1750/head\n004161121d34173f4e17d2787d9bbb9beb50988e5b0f refs/pull/1751/head\n00412bae8356597b70e2a0ec11fb906c9f4e15b0ca12 refs/pull/1752/head\n0041b1e4f7639d8480a1dd8b2d8b58172b5654bcb5b0 refs/pull/1753/head\n0041e8d8de2b047665e2feee094a948020aab6f0cab1 refs/pull/1754/head\n0041dfe0cb485e1b95fa73d7fc01189d7342336139bb refs/pull/1757/head\n0041af351e06e20230e63147e6f91ec49ff018b6acca refs/pull/1758/head\n0040697026d4e8b2db4ae98b820d3d5219bdf6447016 refs/pull/176/head\n0041e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/pull/1760/head\n004168f6fb1246d1b0fceb91454d4350ec541c5f6c0e refs/pull/1761/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1762/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1763/head\n00411fa8a78eaa5b22679c5eef46216f5188a1d94fa7 refs/pull/1764/head\n0041cbc1038324468952ccd6d73cb8139ac39053a443 refs/pull/1765/head\n004156e0c5dc850587be1566c9f64793d6d6d5d236f5 refs/pull/1768/head\n0041bb81d37d4e36bc8f5ce4bdd330670bcb3e0d50fe refs/pull/1769/head\n004196aa2ba53a2ea486f5a769851a40c6695ae1e49f refs/pull/1770/head\n00412a288c660a53a7e834900ac484b30484ee630045 refs/pull/1771/head\n0041217c352ad074f4d185d93ceebca8eb349ec6c59d refs/pull/1772/head\n00417d78ea23fd1e33058e26271b9314228c52ccfd9d refs/pull/1773/head\n0041bc8e36df01367794ea3ef321187a325a9ac69db4 refs/pull/1775/head\n00417d2c3c8a499807f48617aef10ff2d38777b10e53 refs/pull/1777/head\n0041c25a90ec1432dc8d3bdfd8a4897eec1f79e86a79 refs/pull/1778/head\n0041959f67abee6f9d04caaa8d7f89fb4e4bed97643d refs/pull/1779/head\n0041fd17178287784de7abcab551e8d6a3f307197e6e refs/pull/1780/head\n0041e3ca3320607036d249dbbf26371909c8cdb4e553 refs/pull/1781/head\n0041d51aefbf41e7a618a29bbc5d27e61b3d695b5bfe refs/pull/1782/head\n004185d032609f688eabe9afdd6e913a3eccbf02928c refs/pull/1783/head\n004123ca8b3c69fb1aaa5728473b063576f1b2d39375 refs/pull/1784/head\n004117103ff4a194a539f5c72bea680e96d82fded25c refs/pull/1785/head\n00416ff3ddf670d367e0bb94ac1ecbc16a7b84c44da3 refs/pull/1786/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1787/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1788/head\n0041d780e569beeb0dcbf49dea00227b07e7a0557e07 refs/pull/1789/head\n004138818c7fe460059b864af9fb064ef3b372faa3e8 refs/pull/1790/head\n0041c830fa55637683630dce94d4bd1979bd6eaf19fa refs/pull/1791/head\n0041fd24bcecf02345fad0eafb863c1e1a96b8c690ea refs/pull/1792/head\n0041ef51a60c61079cee1ad74195e7ea775ce69cb4a7 refs/pull/1793/head\n0041151da60d325f776b3dd0aeea7d2b772e19d7d17b refs/pull/1794/head\n0041beced838e4690d90045aa67d95eb354ad8ff22eb refs/pull/1795/head\n004167f820873e8377ea084af14056d22554ca7cc21a refs/pull/1797/head\n00417a0f284b57753f79f3d1613fab4b93c8629e19e3 refs/pull/1798/head\n004175f2c449c009b52d0a603bd3cbe8eeb725f915bb refs/pull/1799/head\n003f53aa980fe3061b5e6040de9c8fb10012bb2f8703 refs/pull/18/head\n0040b1cb385e06354cf99ca214be195c0700ffcbc0cb refs/pull/180/head\n00413eb63513540f6bffdbd231239f42f88ddfebec68 refs/pull/1800/head\n0041643497bf5bcb01d049b74b7256deaccbe7499250 refs/pull/1801/head\n00412f72f7cb650e4bd70af9f952839a0a59869e3a65 refs/pull/1804/head\n0041cb15bb31308c98689ae4eb9146890eb4c4b85076 refs/pull/1805/head\n00414a73eb85606f042cbc4cea9806bb6a5aa8aab684 refs/pull/1806/head\n00417a5731326269b729d41b2ac688e39b590748a842 refs/pull/1807/head\n0041d61d2a12da28c0a67e8b2a6a2901ce3581582bda refs/pull/1808/head\n0041c06ead49f70c83092494dd35de5cc23003373616 refs/pull/1809/head\n0040a93a2680f94ad8e04a1103aeabf2708bd5980e8e refs/pull/181/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1810/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1811/head\n004164c2d8663c768215adc1abfc163b90d8c00f7774 refs/pull/1812/head\n004166ae46ddf21a5c9ea38179ee3cb48e5e0933fb93 refs/pull/1813/head\n004162d8b81f9d11177615ab69ad569599f9749c988f refs/pull/1814/head\n00415784c6de647fb7d0e8667740d784bd6855da89de refs/pull/1816/head\n004140d1eaf19843a7fa8e8aab0f612829d02fef95cb refs/pull/1817/head\n004177db6fea24126618973c77b5d1085b6d731abaf7 refs/pull/1818/head\n0041d218d64ce9526b17ace67ffd6c302cdc0d06b330 refs/pull/1819/head\n00413e4acd6540a4da55ca5e2d8fefef07b740d1c752 refs/pull/1820/head\n004155a2cd3bb64e3040d899bf5cf8f1cd4d6580ca5c refs/pull/1822/head\n00410ec6da65e6e898a079591b57055efc061c9cb6dd refs/pull/1823/head\n00413956b56edf3c580ce664f26ba4a2295204a3b7c0 refs/pull/1824/head\n00414716d0cc284b1741d0d3233c73ea47af5bceecfc refs/pull/1825/head\n00415f788d250cd76b750f76dcc6db2d440bd92fab27 refs/pull/1826/head\n0040c36e358ca340e5143c1bae900f62af9c9992f8b6 refs/pull/183/head\n00419a37f354a6af47436166d5dfe516c3689f402484 refs/pull/1830/head\n0041e075984e4ef6a2a4d844c42cbc18543abe5dd211 refs/pull/1831/head\n00410bbc9e95cffef61511f1de8f830e336caa15a958 refs/pull/1832/head\n0041e5bed10b2bd6973ad2a063fffc38780533f8cd3b refs/pull/1833/head\n00413e0bc06126d76b17038544e765365e04f10f12ad refs/pull/1835/head\n0041ad1e720055786f3cdb9c759e5061343c8d00b279 refs/pull/1836/head\n0041bf17b39beef874e602d3b36861aa1eef469aae3f refs/pull/1837/head\n0041ca50521d299252e3df50cc973da8d58ea17dd9d8 refs/pull/1838/head\n004180a2263da5503241882ca0477ea1d99b4c7a20dd refs/pull/1839/head\n004073c82e133e8dc40db2556497ea58ed1087031505 refs/pull/184/head\n0041dd45b9f4aad94150181247b515d878a258593f65 refs/pull/1840/head\n0041e95f66bf3fae34c9834fe303119f68d09b524c50 refs/pull/1841/head\n00417879e9176124c4e6bc5d7dc9e2aa8d00a2050411 refs/pull/1842/head\n004183fc002b5356265d0459729a76aca21324a27401 refs/pull/1843/head\n0041590f17a7d4c339439cc3a0366c230fe60d0ee52f refs/pull/1844/head\n0041a3e12ab1fc688a3d5d68fb004f034dcd83159e50 refs/pull/1845/head\n0041cc048c4cecbfb81fd68db3de91cab8a6d110a4ef refs/pull/1846/head\n0041694695a536c2feb96e0817856cd3b729017b66db refs/pull/1847/head\n0041dac04009c14513b018b5a47194aa0c45cb15a3d2 refs/pull/1848/head\n0041c53eab92dd9d8f1b20f3ca84fabc29456767c562 refs/pull/1849/head\n0041cf9cb9a57237917ae1ff74f121a1fbd6d8e28581 refs/pull/1850/head\n004139bd4443236a577e81d79eaf2adb56ad5bad7e0b refs/pull/1851/head\n0041ca1234fba4d0f639136a17642bfaf8696100148f refs/pull/1853/head\n0041688edfbf064c5cbd29ccce6683cfff62e2a92841 refs/pull/1854/head\n0041e07806737984c72dd2df3fb62f6aa887074abb28 refs/pull/1855/head\n0041950f94d8447cfe8e381c33003731bab17764fc53 refs/pull/1856/head\n0041c9e6324f270b54ef8528ab8a2e54663cc1522bfc refs/pull/1857/head\n004125ab614caa713ea1b3aa85d6ff477956307fbceb refs/pull/1858/head\n004177d871fe2174230183e7a2c9ca37bfc3147c5dca refs/pull/1860/head\n0041490ca7b0714d188ae4fd43dbbf9f603e257b33d2 refs/pull/1861/head\n0041d401575d9c4480a77ed36f22013cf94ba28766c9 refs/pull/1862/head\n0041245917c80414c327aa4c9b4dccbaa6a8de1ed76e refs/pull/1863/head\n0041775c151f3e1a2deb698444685f477766b2eb7ac7 refs/pull/1864/head\n00419cfa3f62676b13f7e218003e801796ca01a26e8a refs/pull/1865/head\n00411ed057902ab3c93c7bc09b1aea1868ee223204c8 refs/pull/1866/head\n0041bb691dd9c831e92f4d12e842b20ec6b198382030 refs/pull/1867/head\n00414f13093d0a7690cd6f53a8a00eb5e961b450e96e refs/pull/1868/head\n0041be23c09d0085e393c609425c87e91d2ce49e4b4a refs/pull/1869/head\n004094fad49150b1245d6df17ef596ccbfdf5e53e23a refs/pull/187/head\n0041adc617b13cacafc11073da7c987c3b4aeebe7e8c refs/pull/1870/head\n0041e7abbfdf7b7587088aabd9b6e6def35157483259 refs/pull/1872/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1873/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1874/head\n00418e73fddffc8970eec9941c65f48522e41fee367d refs/pull/1875/head\n00417870cf2e5136283da85180aa1a4132d0b945e46d refs/pull/1877/head\n0041d5e7bc7be4b270767aa04de43bc3af305e1827cd refs/pull/1879/head\n0040bfcac75d68e64f860fd27dd089f76f6e076ca1e0 refs/pull/188/head\n00412296fd9ca7299a57fa2e8ecb59623a85653183df refs/pull/1880/head\n00419ab39d23ff2b19fa564815999bf51be509ab7b5b refs/pull/1881/head\n00414cf4e663f58e4f5edacda884bed5c035124dfd6c refs/pull/1882/head\n0041bdc42a80a2a7d0ebec1c9ab90a945f344dfd3f3f refs/pull/1885/head\n0041f3d970e2aed28a290ebdc777b1bd9e2a6c69361f refs/pull/1886/head\n0041f52afdc4daed2649a3bd78782713203bb9ec1787 refs/pull/1887/head\n0041a13e63a984798aa57eedeb629a4e42a059304825 refs/pull/1888/head\n0041f2e2f18765b2d1fd298a58c3ea90283fce07cca9 refs/pull/1889/head\n00407a95f8a55b26adc8f99b9e2c54995c0ee85d8fa5 refs/pull/189/head\n00412ed0a0d114dc10762bf4a4e6ce2572f04d4c6abe refs/pull/1890/head\n0041cca09665a98cffb1de8a990b68eef7ab3f42ae47 refs/pull/1891/head\n0041f209a2ffc58b2c9550528b01e5619bb3cab1d82f refs/pull/1892/head\n004141584ca7cbbbb18f1cde26eabb104249fac64617 refs/pull/1893/head\n0041c3e7497e240bf02819dc7d0bb5e666a48669f0c0 refs/pull/1894/head\n00413eba8f8f280b0be0c274880add862f86a1aaebeb refs/pull/1895/head\n004124242e093ecc652d0419c06cbf0f3cb4336ef76d refs/pull/1896/head\n00418b61b330c72c4c1513cd72ffac2aac293cd3a3b7 refs/pull/1899/head\n003f1a0925b76e59133372fc1ba7ee5599b735be1611 refs/pull/19/head\n0040ff96305637fe8ce3e1f744bfe71eef3bfdde98d1 refs/pull/190/head\n0041cbd943c6525c545cec58af0404e17407bba01195 refs/pull/1901/head\n0041fa6cce474ebdf2ff70cd23969df81b51b28249c0 refs/pull/1902/head\n004191834bb605717048dfcb97d50f1e211b7fe18a10 refs/pull/1903/head\n0041e44a5ef5ff2c9c28c4e4f6e72e57301637991d89 refs/pull/1904/head\n004101318044062e0dcb5c3e49f6536ec235ab23b0c9 refs/pull/1905/head\n00411bc915c5b605eea03cb4a8290ae461462e1ab24f refs/pull/1906/head\n0041cae78e108c9cb5fff71e8cb8741349b94f2ad4ee refs/pull/1907/head\n0041b6b055ed963bfb379183b8c02c6ab208e3d6b473 refs/pull/1908/head\n0041183eddf9cbd560150b934d0f1f4569f1bd882a3d refs/pull/1909/head\n00406ce0980f6d150f2624dcef29836028a2cb1f7870 refs/pull/191/head\n00414402048781f29961cbdb12ddad0ca8d81a196afc refs/pull/1911/head\n004157029178c367dde42ce6ea623fbb49c05e051f22 refs/pull/1913/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1914/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1915/head\n00414fe84f446a4c7ba338e110ed8f61418adc4c022c refs/pull/1916/head\n0041b639422ec1c00424fd896389628e8734902c4f1b refs/pull/1917/head\n004141793010447396bc491832ccb9440144cbf74da0 refs/pull/1918/head\n0041772dc97d1ef15899ffd143c7954ec412b0a416ee refs/pull/1919/head\n0040cea55d539a5935d83a95b3b71e1800a59ca6aadf refs/pull/192/head\n0041faaf7ac71d88129f9d698c85473a5180e0278c83 refs/pull/1920/head\n00418081e72673e2f1a920091f3bf221093d05276dfb refs/pull/1921/head\n00414263ded36f0b487b333e3871ff1e316396fe9ffb refs/pull/1922/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1924/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1925/head\n0041085fd13676bfb1f72c4a45453c77befe939a86ba refs/pull/1927/head\n00412890c32995007b6d48e87e20a853a86b9832ab0b refs/pull/1928/head\n00419e67ae92fc31d9eafb455aab6fe32eb5e125c30b refs/pull/1929/head\n0040c4eaf01af99cc8dadace1d1d127086a392813469 refs/pull/193/head\n0041f68c436ef6c041a988c803ef30185652612a73b8 refs/pull/1930/head\n00419f56be92d5c167c9e54911f073bafb528b18828a refs/pull/1931/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1934/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1935/head\n004128e4a3f2c16e21f20465082e4e63cb8e3503256f refs/pull/1936/head\n00416e9281133ab28e8bad2525600907428b1f70caea refs/pull/1937/head\n0041cf2236dbed3e22d7f04eb2db011b95874674e87f refs/pull/1939/head\n00408863cd9f782c86bfc463f1d8384c89027224aef7 refs/pull/194/head\n0041d49b4addeac1932ce5edc072938940965633e5e3 refs/pull/1941/head\n00418fba4b1e07a31d6eb84de0d3285a230de18ce490 refs/pull/1942/head\n00412d8629e6324a07fa6bcaf99c3d851effe085606e refs/pull/1943/head\n00413d608d7911850e4edf5a9417a8783a0375aa0fce refs/pull/1944/head\n00410e88f4836971e5fd8c9216f9d0a0f62a73109764 refs/pull/1945/head\n0041312e083a7df0caa21a7460b124c131a35540abc3 refs/pull/1947/head\n0041b195aa96dd4c1ed0bfc423396702b7cebd38b64c refs/pull/1949/head\n0040e18c14875dabe2847beccc4ace2c8fdefac4b003 refs/pull/195/head\n00418a89d1ed64499e3e23c85ac1d9fc87b093d88f52 refs/pull/1950/head\n0041eeae4900643721f121259e79c101e7964e7b26e2 refs/pull/1951/head\n004198a7e10c7c548bfab390374855271f4f06dcc94a refs/pull/1952/head\n00418e2e7cdf1a1c84a06c7ac1286063b5184844919a refs/pull/1956/head\n004198385fa0202ba48d9c829bd4cd438ff735c48ae0 refs/pull/1957/head\n00415f02424e5e280ef631ce64faa518a33ec2b356d2 refs/pull/1958/head\n0041c655361c61f4a8d4cc5501559014c4da4352d3cb refs/pull/1959/head\n00400203592563e6188de76fb2e29f4c5a2e5f722626 refs/pull/196/head\n004172d6bdcfffcda628c98c17935d4dddd8724612d6 refs/pull/1962/head\n00412f5322e8632c0ec51dc668b92cfe1164b811c60f refs/pull/1963/head\n0041f33bfb247752d7f00c9854af85f59cf146ce3b2f refs/pull/1964/head\n00410e5a9d1b17f94dd79f1bede6ab86a9ecdad51e4d refs/pull/1965/head\n0041247452069e49b1bc2ddebddb39f4b1a42f7dad33 refs/pull/1967/head\n0041d2b9459487c77b121ebaeb1936c98f6fdc4efd6f refs/pull/1968/head\n0041adfb91949539a56ef5a79dbbf1440d8cb98e48c1 refs/pull/1969/head\n004039610731e0ec8d72c80702b55a15478a948ea7c4 refs/pull/197/head\n004145182d7887e98e3be7b417e1aef6fb5e96c69e4f refs/pull/1970/head\n00411f8c81e7dcf2453dd59ab709d3cf49e8961de5a4 refs/pull/1971/head\n00412fffcbe318fa873851db2b093533787d55af5988 refs/pull/1972/head\n004119b96a70c14221d539217dc123f077fa97afeb94 refs/pull/1973/head\n004188214dc2966923b84c45650d1d2a06d53f8d2d7e refs/pull/1974/head\n0041d0438d88f8318cf279bb6b905aaebef0000fd4b4 refs/pull/1976/head\n00418c6e38f64217d2bfdd5c74b4820542d69312caed refs/pull/1977/head\n00415d11d2ecfa6241332ee224ebe1e3817fd70ce5ed refs/pull/1978/head\n0041b3fcec5942a9e303e7cfc8fa90dfb5aa8548ce0a refs/pull/1979/head\n00402d059659b02a3d4cd478d9cd608ee625f6101623 refs/pull/198/head\n0041f118e38cc79ccd80541d773a73a40f48f730f293 refs/pull/1980/head\n00419a4d3c10c0c76ce56b5393256e582e0f6156a354 refs/pull/1982/head\n00418f8added4c8e79c5df1f09d35161ca44ab42314d refs/pull/1983/head\n00413e9f8f819beec39c2171888cc75bc09eaf682a8e refs/pull/1985/head\n0041ea8a5331c4dfd8ab33559dfd63279c2745a8dab7 refs/pull/1986/head\n00413fbd7bdb7df0c0626e2375262ca831e82ee9694b refs/pull/1988/head\n0040381bdf0fdf166a8efca78ed83aa3729eef57fee6 refs/pull/199/head\n00413b494e299e1bb738432f2da3adbc16a4b9925cb1 refs/pull/1991/head\n00413a5a4ba0f0023ba2be6e8f76e55a59c77e83aab4 refs/pull/1992/head\n00419232e80f273caa3c4e30de4ba2df2b59724f53ba refs/pull/1995/head\n0041931da3b5a36e92341821bb07a6ce12c6e2964ab5 refs/pull/1996/head\n0041756a8bfbf71a83a7830c3704f0826dc5e9363a4e refs/pull/1997/head\n00419054561b3be44b736d0d75c1fe93650c9d72a19a refs/pull/1998/head\n00417224063d42c89b8ed4e88bab92552b683972cf56 refs/pull/1999/head\n003e45ac7a9b17fb34cdf0ea52ab533b70eb4ee60a23 refs/pull/2/head\n003fa89fd2c8ea82bb0ea441e6f8bb2fa16a097fa40a refs/pull/20/head\n00401e54429c2152b4c88a7ffca8d2d3a3da663e7dc9 refs/pull/200/head\n00413db85348aacfb66d3198837378bdf39b2b83b202 refs/pull/2000/head\n004140b3657c0fea727e0fafa0f15e5cac27062c9467 refs/pull/2001/head\n0041b828c1942fc576b764fb501426561645988c5182 refs/pull/2002/head\n00410a633c74dcdc35ea13b1131c185ad038501b9910 refs/pull/2003/head\n004177cea761a0e5d480a0ee655e192f47c3c4995fc1 refs/pull/2004/head\n00419abe4a3186ac55d8fbdef81cf718fad8d1a89079 refs/pull/2005/head\n00413bc50173f33ade9e73e9cd345b96aac6481bcf6d refs/pull/2006/head\n0041e8fb8f5771525831e0ce36e4b590bb7f6d28e436 refs/pull/2007/head\n004093e03d4276610c22a0e92e73012f8a4143e68c5f refs/pull/201/head\n00412a2592576e38d9fb64498661223b0e5d41659e50 refs/pull/2010/head\n00419ed18665d7649950d1f7c5e55d24b5ecdb6ae217 refs/pull/2011/head\n00410bd31f53db252acbb57473024b0e5f62805cd8e2 refs/pull/2012/head\n00412634e09e56a84ac60c8133659e86924db2907754 refs/pull/2013/head\n00414e07d9a95939834719489e7315fa330e0600b60f refs/pull/2014/head\n0041c4f79ae666057aad3ff6dd83878be6ed2fdf3668 refs/pull/2015/head\n00416ccafe45354eaa1a381171f692f3aebdf40e147c refs/pull/2016/head\n004191d2cdb8f126b98e33832a99ee369f8e7d33fa15 refs/pull/2019/head\n00401a57100be071b113f1844f864622afd13e7ba357 refs/pull/202/head\n0041f9f69a443ecabce263829413bb52d40b4f62829c refs/pull/2020/head\n0041276ef05e74f0b36860354051b60734570860cb44 refs/pull/2021/head\n004173b1fe3e8f664a33cda63a888e886a43d1f09453 refs/pull/2022/head\n004162075312fc10fc501a1c8e79109416fcb1d1e0fd refs/pull/2023/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2025/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2026/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2027/head\n00412d365a1a7f06d0c6c0b533a870a06ad947ea93fe refs/pull/2028/head\n00416e8dc9b9791d3d2c32e97a075edc1bacf515f7b8 refs/pull/2029/head\n0041c3f2d82f0160787e23b604ca33bff1c7155452c3 refs/pull/2030/head\n0041f427a8cf2cf8c5a1281b5597c97a7824e081ab41 refs/pull/2031/head\n0041c5c74a89138b010c108b44c04f6b591a5effd6f3 refs/pull/2032/head\n0041c2d191f524e51434cef74087074f695e1a300d1f refs/pull/2034/head\n004136bcd51bf95826cb489f181ca8a20374e2edee7f refs/pull/2035/head\n0041b17a05a6c75c73cf4d7472765dc24c67086d344e refs/pull/2036/head\n00411c841c1e1f263e42179306f8c9c0efdc07ffceac refs/pull/2037/head\n00404d972ac05deac77ffcb2ce21adb2650ed6ea6a3d refs/pull/204/head\n0041fce332fde15b1e5cf8519ca4e41f7dabc15230cc refs/pull/2045/head\n00412e6e93ff444f2db51e2f94b7b4440a6ee599bd40 refs/pull/2046/head\n004177a020b5769f6739f496f57539930e5c3b8cf0c4 refs/pull/2047/head\n0041616ee95df5e755c3464c5ed9d997531da5329ea7 refs/pull/2048/head\n00415da2bc3a293b18f920aa668e4e84fa3a2f54243a refs/pull/2049/head\n00404cb5d471dcfafbc390ddf00de86d2b3273e214b0 refs/pull/205/head\n0041a2766dc2c1f01b71b659a9fe24c24e526f9ea2b7 refs/pull/2050/head\n004165e83af51b80729115b49c787f4c7461561ee600 refs/pull/2051/head\n0041dfe7469fb6f43fe8f147e7ae4f37f4bee4b86efd refs/pull/2052/head\n00410f2c1ec931639bd563db8209bc678eba6bbd316a refs/pull/2053/head\n00412021cf90c380582a43f86948682aba9ed8c6444b refs/pull/2055/head\n00416e6fd0abe0b41abbbcddad8ecf505968252149ff refs/pull/2057/head\n004184e8c2cc730d0c599f182e6f9d1bd1836451a6a2 refs/pull/2058/head\n00402ad69f5897e9dc9fa230f6aff252131a058ac5bb refs/pull/206/head\n0041979cb14b1c89295b411f2cc96698e302b63c869a refs/pull/2060/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2061/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2062/head\n0041fcfed2e6876d14d39cd59b7b5bfb1661de2fbc5d refs/pull/2063/head\n0041dfa203535005df10a8dc405af9e990d1501df161 refs/pull/2064/head\n0041534ef3fe70c9ddf8bb3be2611967a27fdc18af0c refs/pull/2066/head\n0041e3307ccfbe4cfc66099049a0c02447ce4214d28a refs/pull/2067/head\n0041914cd027ad55591aa88c0b458793cf4fa06fc2c6 refs/pull/2069/head\n00401efded0c7da7b9b855dff24b2ef5ae27532496d6 refs/pull/207/head\n0041a97b632eefa842b42c14cd6a738e71ff03615eda refs/pull/2070/head\n0041da57e2de83414be080dbe083665c90008a0562a1 refs/pull/2072/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2073/head\n004174d79dd6aab423b075f15e0577d277ae125cc436 refs/pull/2074/head\n00410928411247b51199daa3bf7d5cda670d216e9d36 refs/pull/2076/head\n0041774d2eea01be83a26f4d857a0da058606e26d3f1 refs/pull/2077/head\n00415671f0abd1b02a8c003aa00accce1600f405c4f1 refs/pull/2079/head\n0040140337e1e1d9af38371be75fa4d5f5a4b239e50f refs/pull/208/head\n004124556f57344c7bbddad2b235f40612fe50abdc8f refs/pull/2082/head\n00415f0956d3fc07895cdce08b590e3a58bec356f5e5 refs/pull/2083/head\n00412f0e6b16a8eba22013463d2f06c29273af6586be refs/pull/2084/head\n0041d97a9b2ba365e6db9d4eff805118536b997c0c1b refs/pull/2086/head\n004166a697f9b0d9a72ebfd04e201ea5ea51bb12079a refs/pull/2087/head\n0040eccc45a3ea6c3ea1ffab1b224e0f38701acae5ce refs/pull/209/head\n00414e252005ddb3f08c77948c828a695f5cc90e10af refs/pull/2090/head\n0041c858aaf921ce8c2323422505bb4250581a9c7213 refs/pull/2091/head\n0041820ae57aa36afa9ca11411ecc74124fa99a5d11f refs/pull/2092/head\n004192c8ff73ddf065aba993496d8b27b313e7702a08 refs/pull/2094/head\n0041cae269ee9de564f8beaee54af3307f62e5b3431d refs/pull/2096/head\n0041aadef428d601202d79299c176e4b41e245ba843d refs/pull/2098/head\n003fdd60e6b515cf2f60a17020ae3c99fc26c48731e0 refs/pull/21/head\n0040b68182934b0c69bfacc4745141c97159263cbafe refs/pull/210/head\n00419bdbf91f4437ca3d3424c25d405f48c7762165e0 refs/pull/2100/head\n00411e05bd5c637cc150c7b0242660a7cc56a57fa45a refs/pull/2102/head\n0041d2b1520f1075eb199d17ebe44029aa429dfa198c refs/pull/2104/head\n00416d8dd63c503812e495e9aa4051931a312e45f3d1 refs/pull/2105/head\n00416c0238bd3f954d95d032ac8699c69c7dbb261ede refs/pull/2107/head\n004125defef4dc82fc1a655825d41fdcc16ff9315c4d refs/pull/2108/head\n0041edd5576921ab95d4230fd39e2c0879ff8a1373aa refs/pull/2109/head\n0040af2477aa12be46101c3d7cd0003e45b17e98a98e refs/pull/211/head\n00410f384635ad38f435e9d342c1d084c8d82d76532d refs/pull/2110/head\n0041e888febafad31e6977fc98801c90d06e3930575d refs/pull/2111/head\n0041f1cc4c719b85eff4d09e262482fe08f2c82b1ec7 refs/pull/2112/head\n0041c215ac334d53aad70c8f49c3ca4469138afb14ea refs/pull/2114/head\n00412846504bcc6555185b6087e2b3df29b20acacee6 refs/pull/2115/head\n0041b15d59d9f159cd31b4389084e6393cc13c89c24f refs/pull/2116/head\n0041a0ccb0b329ec1482e4fb4b357808f69be1d2918a refs/pull/2117/head\n0041d5ec3caab9b15dff0404c53f8503647f0ed9ca8d refs/pull/2118/head\n0041e8b0cbb473269a2ecd82efa821bdceab82cef3bf refs/pull/2119/head\n00400f5e062dd35b9ebef263473fca25512b315a918f refs/pull/212/head\n0041c6506ee1cdf64b1f8e5aee02a68d2373ae93152e refs/pull/2120/head\n0041a46c8c3624067acb6c11e9a8f7b2d55b9b18980a refs/pull/2121/head\n00412a59b5e507bc1618e1a8cab5dead857665cf40a9 refs/pull/2122/head\n00415d69ca46b8216051eaf37047a336912b1123c5a1 refs/pull/2123/head\n004148c3be619b89ba4966499bbcaa4e40bb6af35b48 refs/pull/2124/head\n00419a8d69289230a495f8582cd65eb0dba7d3307620 refs/pull/2125/head\n0041e5eed9e46a09b94567bf86ae4f6d46019ec18faf refs/pull/2126/head\n00410bfb1a4d4902cf9fbf7593f03863dd37b8724ccb refs/pull/2127/head\n0041c54c9f8ec1c7f9ad8ba779671fc710d4a164af0b refs/pull/2129/head\n0040c5e09ae449a74b916851abdde913f3098608905a refs/pull/213/head\n00414728b5044faf129ffd24a985c74cdf31040a3dde refs/pull/2130/head\n00418a24cfd871e0958f9fa723f6c6253952b0deefb7 refs/pull/2131/head\n0041db8349bbf8bcc8a467d116268cabab91145eee0e refs/pull/2132/head\n004171dcb05b8b4671c05f18deb458e5d3aa8f95e86e refs/pull/2133/head\n0041364d95c03b18af27f248bad58a56bbbd2adc19b8 refs/pull/2134/head\n0041159d4dc4ae6f9e9816035ae170f0204043df7a8f refs/pull/2136/head\n0041566aaec5b39a4dccb72e688c105dddeb57cb0f54 refs/pull/2137/head\n0041f3b87b9a1c2db51259d6445e488369fed87788c2 refs/pull/2138/head\n0041517ca96e424138e2f7e09b69440b46846c53ce65 refs/pull/2139/head\n0040e03ffff3d0359f7a13ef512ace8c56c74411b2eb refs/pull/214/head\n004105f77f86e9caf21163e15e1ea8028a9468a781d6 refs/pull/2140/head\n0041223312684d462a1bc67706baccba127b2bbeb1f0 refs/pull/2143/head\n0041a326ddd7e0e2286cd23d9bc38b6f34bd0843cde8 refs/pull/2144/head\n004181aa02647563b8231cb1db035ff97764a4bc4c08 refs/pull/2145/head\n0041fade7728c3f1bb109dbd6a58cc9cb5b5a7244448 refs/pull/2146/head\n0041d0e0731232ebd7711fd7f7d80b4286f4ba97ff70 refs/pull/2148/head\n0041e70a80f91dd512f7380a90b53adc925c132ba932 refs/pull/2149/head\n0041d5a96efa27504a15bf9a03c432088fd8243415cf refs/pull/2150/head\n00415bfc4e906a519270df95056eb9a48b8089f68d56 refs/pull/2151/head\n004126cab433e325e4142045bf6f2f8276071738cbb1 refs/pull/2154/head\n0041db0945190e0388ba27a9bded0314f3016ea6f262 refs/pull/2155/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2156/head\n0041370f57d1ef87a56d7a59f5e7004d413c5cabefeb refs/pull/2157/head\n0041f99c264fe30fe0915efff777bc94dc16df9ab48a refs/pull/2158/head\n0041a10bcf7c8df9f32499ffbb56a13a52d7f8cd64ad refs/pull/2159/head\n0040daaa4a42527acc0ba496672ea2c807412acc1958 refs/pull/216/head\n0041a94c3dfe95cb58665bf4b4c15fd39db98b96ccab refs/pull/2160/head\n0041a3f61afacc7cb29a0643328bead3ae6c08c6c05a refs/pull/2161/head\n0041e9f54cb2fda9cf61d179d1485a0c0aa8f21bf901 refs/pull/2162/head\n0041167f4e6825a414af01e75365d3c87525a214a550 refs/pull/2163/head\n0041e8ace6973134c0829cb1a9c598e447a64a59e2fe refs/pull/2164/head\n00414d66b12e44db8f5abcc2d2a8c319003e185b34c0 refs/pull/2165/head\n00414b2128402627ebb80b7d8d1af8c092c9a119d840 refs/pull/2166/head\n00412917da51a376598d389320da3cc266c082512951 refs/pull/2167/head\n0041c18c08f53377f808d1989402e9ca25a4d4b1517b refs/pull/2168/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2169/head\n0040d3b681cfb9b0a6af09daedd4a3f8ba02ec766e3d refs/pull/217/head\n00417e5bfb0a34444628009a93432b2bcdd765d15de4 refs/pull/2170/head\n00415c6726b2bf8aa3b7ff79bbc6aa971e3082d93504 refs/pull/2171/head\n00414d9d3c0babdfeb31f6eea7cbc66dcb4bca1c70e5 refs/pull/2172/head\n0041ed63121ef55c84127cb5137dc0a650e7cb302571 refs/pull/2173/head\n0041f347c8cea2246a490ac9101188c4f86382be1424 refs/pull/2174/head\n0041013d338151b3156f6bb1d994d2d3d3a5b1c3d0a1 refs/pull/2175/head\n00414e2227162e694ebbd975631a8ac0a65f1a031792 refs/pull/2179/head\n00403931b2f889e2c657f34c3c5167030143489ca091 refs/pull/218/head\n00417e92aaa16538e195547bb6d41198d65dbf1182c9 refs/pull/2180/head\n0041952f05576f2f134514cc91e5b2dd9f4d3dd209ce refs/pull/2181/head\n004128c50d845b49aac26f7cb9df609bae2ab3727190 refs/pull/2182/head\n0041c1a513c3c934135dfc1154f4861bdf7afbdce60e refs/pull/2185/head\n0040fe110eee20684e6f2b05a4c067fb31879e456932 refs/pull/219/head\n0041a1da249964cf146c54539cca524fbd1013d2029d refs/pull/2192/head\n00414ff69d3c81ac79198a4c99a285c66bf68ea4c538 refs/pull/2193/head\n00410ba2eadf30c4637e8dfb9970899564a43aa6281f refs/pull/2194/head\n00416fc5cfc1a359cd30193055997583fe393cee0739 refs/pull/2196/head\n00419bcdec0855ddb161e35d720fd20c9a572061adae refs/pull/2198/head\n00413e9d126a22e958a30ac07045f506ce1f19f4d968 refs/pull/2199/head\n003f985084119b8da35919c3de651e275acc06e1cc2b refs/pull/22/head\n004062ee6c452595eda122ff0e40ca69f8f615b54438 refs/pull/220/head\n0041741ad5fab0aeff22fbbc8663cd51b98a930e7b5d refs/pull/2200/head\n004131f5035ade93af773bc0f352e16b205978ba8288 refs/pull/2201/head\n00416bd63d39f998df7e56a95ce1e678d7e00c1fa86b refs/pull/2202/head\n00410ec8f46347ea4c4b3cfefa672d755302b6bc0195 refs/pull/2203/head\n0041645959293e93b7c41224ca6565d549ec45f20fc5 refs/pull/2204/head\n0041d9d3e311facb95d40ce676157dfc5efb29dc4bb4 refs/pull/2205/head\n0041a1c81c8de57edcf53010d0708f694b1accf8690d refs/pull/2206/head\n004106f20c35e22816059987089b3c2e48ce47798ed3 refs/pull/2207/head\n0041193141017843084d2f272ab8f26a89b6b047302e refs/pull/2208/head\n004176a1a98700ec28446ad7ac165e15ca3880fb0eb1 refs/pull/2209/head\n004048611d3952d8596fe9781d8c8bbc15326690e6a4 refs/pull/221/head\n0041af034a96d6cc19a7fcaf1ef9d0bf3b6b478ece7e refs/pull/2210/head\n00413bf320e9526067c0746dffc1ea8b4daebe2c5bdc refs/pull/2211/head\n00412afae4f3722aa4fc07828ecfb290cc1ba21d4f00 refs/pull/2212/head\n0041ca9da16069d42325e475cc6c343b6f6edb5ce623 refs/pull/2213/head\n0041c7e3aedbb454e839909dc86a0c3d3111117b96fd refs/pull/2214/head\n0041caa0a41f2f4270e59b0120162bad48fecfb4b744 refs/pull/2215/head\n0041ff3e8f0694a4d37576abad605a9e21720174e787 refs/pull/2217/head\n0041aff2b3e908081ccebdee53267b4997f9da5166b0 refs/pull/2218/head\n0041fda0c2e5ecec32a74ab3e1667481f5ad7a696610 refs/pull/2219/head\n004040b3ec19fb72ebf2d0384a6ff5d2f2014d4a6992 refs/pull/222/head\n004180525c230f1caabf56e881ed7ab459df710f57db refs/pull/2221/head\n0041ac9c814844d8656bcd36a929411406594b91b27a refs/pull/2222/head\n004199f27a746f2f16538e241ea4c994a5f3ddcafcf8 refs/pull/2223/head\n00411a3e213541a2de4e0d7d9ddaf4679a20b48405e2 refs/pull/2224/head\n00414f9558a8d2f1b7419e80eae901761c80aa53aa8c refs/pull/2225/head\n00416a253e4d552578539f484b436c32a0eb5a131fa7 refs/pull/2226/head\n00411d10b35abdabbaf3fe8f420992a07f83ce68c614 refs/pull/2227/head\n0041b23d995bd7c7dab28b221c8ce2bee885ab70249b refs/pull/2228/head\n0041ccb42747dc8a368d7084d46d87014b77047ae1a5 refs/pull/2229/head\n0040336503602a15fc771aa1c1c36486ddb77209dfd0 refs/pull/223/head\n00418c3360a8a5d8d531d0f2e447f9e70bdf8f796972 refs/pull/2230/head\n0041ca22722c1dce5a66f5717ca5d62e38a9732596fc refs/pull/2231/head\n0041d80dc2fe58efb2742c955e07a6c07bc1473fed65 refs/pull/2233/head\n0041c3693b5ca51373d28b6b52f004020b4fe518816f refs/pull/2234/head\n0041ee10756deb3286462704eeb4759d78ba10969110 refs/pull/2236/head\n004116222ea878bbe791f998cac019b70bb1765cbe9f refs/pull/2237/head\n004110b241e044a66932cacabd1afc4d3fbb0f35d077 refs/pull/2238/head\n00410da409bee5c8c4f7b82ee5b7f2f8df0331f9bff5 refs/pull/2241/head\n0041fad9c9e4bf307e38cd5c046459e8b2eb9e7553e6 refs/pull/2242/head\n0041b2456b296ce2104856d6a84fcd191cc32406aafe refs/pull/2243/head\n0041de20dcabbbaf0e964744cc56b4c9a20ef7f63b05 refs/pull/2244/head\n0041a4a50c2ef4bd1bb506ae8d7e70ed0095fb2ab0f9 refs/pull/2245/head\n0041388f6d5c12827d5c51d427531f1bd087356fd2b5 refs/pull/2246/head\n00413fd8c2e118cb471d75e559804d7bf7ded4b894df refs/pull/2247/head\n0041a92e4dabef6b5d88e2e5fa79bd46add0a3b0185e refs/pull/2248/head\n00418557ff43e4873f5da41953950105be2565dea53d refs/pull/2249/head\n00402c34baf3b48f0bc9c895ebca5043d0544a4fa601 refs/pull/225/head\n00412984bd8d2522d267b1d8ddc787e33a6f867ab951 refs/pull/2250/head\n00416cbdd8411ba53f845ba6e1e31f0903053bacd683 refs/pull/2253/head\n00410062172b11f98d0980b1d31dc3ed3b8a444ae09e refs/pull/2256/head\n00411f994a25d12eb1cd9afe903a4558092f62f9af8c refs/pull/2257/head\n0041e5bd727e599e58b57680b6af4228456476e6a324 refs/pull/2258/head\n0041490296fa34b945dbac7f68521f5019e3fbc6e010 refs/pull/2259/head\n00403986f1e346f705814c8f76b1e1a1f39f253565e1 refs/pull/226/head\n0041000f12bd3b89f030d08c78d5a9458aede68aa0e0 refs/pull/2260/head\n004150c4ac1ca3ed40862ba9de2e245435245d3f2eef refs/pull/2261/head\n0041c16df2a93b493d1c94e4b1d4b08d89205acaeeff refs/pull/2262/head\n0041d878e3498a22d960dad7f886489a3a43bb644ff5 refs/pull/2263/head\n0041f0c95462867090157886315ce4ab95d2f2624dc0 refs/pull/2264/head\n00412b13b45ea1646421d1bb7841a0aec13a9b232040 refs/pull/2265/head\n0041db2b9a6dd5d89ded180a53cf6a98608216b1cffe refs/pull/2266/head\n0041682844de6e22955ed5a6844ea6bed462308b87dc refs/pull/2267/head\n0041c0071255816784a8e42484060df1f0ac2cf31932 refs/pull/2269/head\n0041e600f3a2159c07215036b540f7ae6a6a7770eb45 refs/pull/2271/head\n0041f3e4189020ed591fe7f3abf1f2e5c98768cdbdb2 refs/pull/2272/head\n00416a7310cbecb14299aa3acd0b3cb8550dc209584a refs/pull/2273/head\n00411aefee6d3342b8b05c326ca8a57136f6f5374806 refs/pull/2274/head\n004146cb03dcaddd28f0c845744bcdd4c499ef4d74bc refs/pull/2275/head\n00412754e0160707967e35faa7943ffbeb00b565831a refs/pull/2277/head\n004137548c1ae7cfb2a024df5e8795eeccdeffb05ae2 refs/pull/2278/head\n004161f534a7e55b4e83460721b951bbf091f3241874 refs/pull/2279/head\n0041f8b616e0a7b1c4ec58a4e1aad97154410fd0f573 refs/pull/2280/head\n0041cd8b16c68ca6e0dfd7a68e0574eec5b56cb3e4c8 refs/pull/2282/head\n00418786f6ff2338f4b3e2153b4155a26ec887bd1ba1 refs/pull/2283/head\n004147859e6f1e02ff5b514f258a5aef89387c6ef8d6 refs/pull/2287/head\n0041b90fc5f656efe508cccbf7c9cac25e96b6819966 refs/pull/2288/head\n004175544cbc15c840a07067f40c54f81b47e966b45a refs/pull/2289/head\n0041927cf2bfcfbfa3688c0d2cc1444161d9124c605d refs/pull/2291/head\n0041541d04c51c2b9515cd75bd6fe53b164faf97a6aa refs/pull/2295/head\n00418cae4953d6b1900dc06d1f7d10d854a7eb96bc78 refs/pull/2296/head\n0041e75fe6a870f8214d2df73b9fd5fe247a36eda287 refs/pull/2297/head\n0041642e6153a9205a47270bbef52d5083bc9402b7e4 refs/pull/2298/head\n00412738976a712891d506de1b2cdf9572e2486b43ec refs/pull/2299/head\n0041102d9ebaf8f6d139d2570fb35367f72d7f842eb9 refs/pull/2301/head\n0041200c1e907e9a9f4061ec24627aec227da40b0dce refs/pull/2302/head\n0041ba4ac9c4029e17faaed41a4c77a49dffc4b137ba refs/pull/2303/head\n004104071d4510e1a9eae2555db2e195d9907c20314b refs/pull/2304/head\n004182296895d676cbeb713f8237fa6c9aa0b55417f6 refs/pull/2305/head\n004163555fe8a246e7024f16d17f969da9d53c0bae0c refs/pull/2306/head\n00413c3c13493aaa9aa000f02a81c3e5079ed28cb133 refs/pull/2307/head\n00418805681354f7bb76c0a7d088ea53362aa4f913d4 refs/pull/2309/head\n00412fee37d27e5dc081565870881b0af98226099b6a refs/pull/2310/head\n00417d3020ae31e7269f666702c5c89cf68747a8357e refs/pull/2311/head\n004194b292ae40c1681ed13df2d2f5d6349bcddaae8e refs/pull/2312/head\n0041a5b3685e7194ced65ad79ef485212a4e1394ae9d refs/pull/2313/head\n0041c7a9bea483be59f447aaaf8fe27bf0051712f093 refs/pull/2314/head\n0041ff3ea7175f824e65b27f28c59142c0039323e179 refs/pull/2315/head\n004152ac0b29edd8fd78ae8f58d9d63a40d5a80cba99 refs/pull/2316/head\n0041c08f32f67aa91a9af146eae74b2e52320a8ef9d0 refs/pull/2317/head\n0041a692921c7d2ee84358d9e40cfb28f5e89f98f238 refs/pull/2318/head\n00418b64c98d985f517087ee4c3137577df0f806a2bf refs/pull/2319/head\n0040a72b0f899bb35939f65c2eee4653a4534fdca938 refs/pull/232/head\n00410e5ecb7666490c0a5dfb73dc97134520970c6872 refs/pull/2320/head\n0041dab1e190e50253fc770f4b4e023cfe6c942088a6 refs/pull/2321/head\n004118d1aa22cbf255b253a972fa17e2a8f19ff11d83 refs/pull/2322/head\n004125207bc51923412606abc8a60c7783afabcfb554 refs/pull/2323/head\n004167aaede68e0e2d8d0325c15eee9efc7eb9acd1fe refs/pull/2324/head\n0041ca8e27a9810a339fb0429cacb004a51e266609d1 refs/pull/2325/head\n004115f4b1cbe50c19a55b6ec61d94f3b8bd5ff9254f refs/pull/2326/head\n0041c8924b63350c65435531a2f16b5062b8e0349d16 refs/pull/2327/head\n0041bd79c21ea0139abbc64a6a79a8d96fbf7181762f refs/pull/2328/head\n0040b8676faacbfc2e6fea33905a6cdce631ff426ed5 refs/pull/233/head\n0041aa40413e669c4e137cd8d39068e8ba99933f95ae refs/pull/2338/head\n00418e378c436c58840a441776e29cf3c7a4f0a1d382 refs/pull/2339/head\n0041419aa71a493e10bad201d1702ef420c9c26399fc refs/pull/2340/head\n0041d71393208f1bc5e9e8d3a22d175c859a13cd180b refs/pull/2341/head\n0041773234bf12f485f32d12854e89ee0ae605a25889 refs/pull/2342/head\n0041d8fd98c896c8af5854915ad1164aeb785d0dbf61 refs/pull/2343/head\n0041d13a8ac8dad35d3ed7e88d79a0209e3619b49530 refs/pull/2344/head\n004125c7038b09a902e14c917a3424b0fb59ae47b908 refs/pull/2345/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2346/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2347/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2348/head\n0041c0d8d5792e9ef5b8c5f5e42de11d9cadf19715ca refs/pull/2349/head\n0041fc2887fef044d0d3f5643b8328acbeb8daeda055 refs/pull/2350/head\n00417e3f756a0239d51869cfb1e766f83aea55bb78d7 refs/pull/2351/head\n00411131f46b62d559ed6349f1886d72998122b904e2 refs/pull/2355/head\n0041a785c0b107b0245aced8ab6444a0dcd554690891 refs/pull/2356/head\n0041fadded923d6b7487a878306b4db76ac2fff66808 refs/pull/2357/head\n0041084bfa051b06e9cdf96eba3b5cd96497dc1fd302 refs/pull/2359/head\n0041a8db307f7d3a457697460ca84a76312de41244e4 refs/pull/2360/head\n00419e7e709fcb8a4aaaa479e7f5045bf031c3ac011e refs/pull/2361/head\n00418b37b80317b9be689039062b3de0a1c3cb886f69 refs/pull/2362/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2363/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2364/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2365/head\n00414f168a73f84b4e8bf2ae582b2aaa22646a9927d6 refs/pull/2366/head\n0041eaa3b70bcd32c7a2fd92ce341a1fc3577a573a0e refs/pull/2368/head\n0041ddcc9575213116fd75c1592f21a1199357c02cd0 refs/pull/2370/head\n00413ca0c78954d8ce2178ca2bd45146236a700a3c5b refs/pull/2371/head\n0041319c369a4ce9c5b2530a5171e22a17974dd6af96 refs/pull/2372/head\n00419ce1728af46e3a005b534308fd6b851174f6607f refs/pull/2373/head\n0041ef84432d4f589990bae9541eee952006fceff4a9 refs/pull/2376/head\n0041138fca28bcfa8a93b3eb5db7f285a37ad8dbd541 refs/pull/2377/head\n00412295d8b3fb84b1b493b39c3810639f46ad042987 refs/pull/2378/head\n00412d7a5cbc3855c9e9c54646e933a7605109a735f0 refs/pull/2379/head\n004001df8689af378f1d9b0123e6797da3e5e73c2e22 refs/pull/238/head\n0041a1cc2ec290ae9e6eae4b8c0feee477b32ac76e7f refs/pull/2381/head\n00416b28bfdafdc0262bb92f67ed21444d6bc589d65a refs/pull/2382/head\n00412fa59043f55f9a6c44243abba66f3541e9f5ae9b refs/pull/2383/head\n0041b997add1e8dca84349e6b571ed0f6dde4119cc8b refs/pull/2384/head\n00416618f3a764a74a0a0552c5ca080bee3d15077eb3 refs/pull/2385/head\n0041d3883c619f08310c58c16691a93a67cf94edd324 refs/pull/2386/head\n0041f39876a2c0ac0f18f7dd42c48859f55626b46fe1 refs/pull/2388/head\n004006ba35b53646c2937bd1fff198b269d1897eb583 refs/pull/239/head\n0041eb33b57255744abfbe557369066619701c0d0f69 refs/pull/2391/head\n00413dc4950c009dde0ab369b2ca459368b953190e40 refs/pull/2392/head\n00415c753f8eac6e9e83a39261373789c09a8299cdf5 refs/pull/2393/head\n00413924c28bcf5f0a53df04ec74b5f6c36b98948dda refs/pull/2394/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2395/head\n004119846ac4836859d8c568239a42b72ca44139742d refs/pull/2396/head\n0041cdf1a7062f8f077d3fa4d6d08dd5459b34880854 refs/pull/2397/head\n0041e368558b630ab18408c79db485a474dfa4683e94 refs/pull/2398/head\n00418f4bb87155757c3a39c3f27aa7a315f34983e3e5 refs/pull/2399/head\n004067e93c659b3fee46070e27c3ec08402a35c82375 refs/pull/240/head\n00415804bb125905a1dcd8b103dfac2ad2b15f811984 refs/pull/2400/head\n00417b80fa5cf0abd102423d5dcb24d7b32bf5212551 refs/pull/2403/head\n00416a76e512e9b58d77a7e5248cb678a4c647f1d669 refs/pull/2405/head\n0041051dca78e7664c9b451670baf44d15851a7d33fd refs/pull/2406/head\n0041f91bbc6c66207b0e908e82733f029c32f1292641 refs/pull/2408/head\n0041a5b9ad92313a57ff2a0f53f2b81aa90b9417d91d refs/pull/2409/head\n00404debd5e8e0860cb57154cfa59525c87bbe9e1021 refs/pull/241/head\n00412c28c867ccebeced01a0f0ce2ecf98f33df27077 refs/pull/2410/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2411/head\n00412184298934e71c29b6d66ed59782938fdaaa0f20 refs/pull/2412/head\n004199325072b64c02fbd888329fba65944e0bf731a2 refs/pull/2414/head\n00410917f9702082147abaa26bb6fcb1357f8a0f31af refs/pull/2416/head\n004195829ab78ed81644b5eb41fbe8409788a9fc7e21 refs/pull/2417/head\n0041c5a219f066e5a874208b2f78033d8ed0f90762b8 refs/pull/2418/head\n0041e28d97d2634995711e5abc794ee6484099128e71 refs/pull/2419/head\n0040d971c87456fbe727730b656e1c6a5de7f7831364 refs/pull/242/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2420/head\n00413ea5d0adbc23cb3059c3297a9be8b854812883dc refs/pull/2421/head\n00411178657965713054cc5790a36b291b30b6d9ca81 refs/pull/2425/head\n0041c9c8d7b7605dbe60cba2eccc00f55723c2acdaee refs/pull/2426/head\n004103549f653ed13a38b886d13855e30c311942d652 refs/pull/2427/head\n00414154a9cbf1c273acd34a5d929adba231b469e629 refs/pull/2428/head\n0041cd93be6a1d7c92ee9f76789fd7c97842b0a7740c refs/pull/2429/head\n0041f733ab04711173a59877d809b2f557a9e3ee4a60 refs/pull/2430/head\n0041c5fa3e53f03ad8e999d57b7f76237617ad4037b6 refs/pull/2431/head\n00419bf72cd1fce073ad01b904fc1ce17773d2d89d6e refs/pull/2432/head\n00410715e65452d2cde3bc2b8bcee1c5a2029ee8afb3 refs/pull/2434/head\n0041794af8c606abf9a5060b9a4442999b9f23431678 refs/pull/2435/head\n0041e87432e66ed5209673cdd0ddb671a8a9a2c03708 refs/pull/2437/head\n0041c4ecded417152c3d5bc809d566769e71780731f5 refs/pull/2438/head\n0041536d8403169585521583475f89d6ce5aa03e0a92 refs/pull/2439/head\n0041ba01d1c94743595ca04e14ec2573dbee254c1c1d refs/pull/2440/head\n0041da45d1e2c8c8c6e3e770b310cf6b050f6da03aa3 refs/pull/2441/head\n004156ef8c622bfbb8376ecb2ebb20ba1668804b461e refs/pull/2442/head\n0041b01339a98647dff2ed86c2d229e23182e57f4a87 refs/pull/2444/head\n0041107392ac7410b8c25028a271523b0f4a050a69d6 refs/pull/2445/head\n00414c66211ac3614faffce5e8e008f16542fcf19019 refs/pull/2446/head\n00415d69266426f17b173056b98b4ed8f01ce0e9caa1 refs/pull/2447/head\n0041b9230a99fa4e2188859f37ced2b7c4427d8b7be8 refs/pull/2448/head\n00418665468e83b5be7770ae198388dcd5ee61dfd5ce refs/pull/2449/head\n00404bdeeb490f450be54f2e73835a76831f332cad8c refs/pull/245/head\n0041244459aa1f47e3433ac537fb89d3dabc7fe23fd9 refs/pull/2450/head\n0041d478b8f397f01d149f8f784a2ac2c95d40412c9d refs/pull/2451/head\n004170decc6cdce3762e1bbeee5e28d5559f80ef8318 refs/pull/2452/head\n0041ca9eed266681e9b352b64c73d5557c15cc38e465 refs/pull/2453/head\n004129c754bf205a00188f6f0a1db1c9f3d82f68815e refs/pull/2454/head\n00416922b4330f05d791b64aa56c40ab953940e71268 refs/pull/2456/head\n004149329a17ed31cfe6fe2dba21b88db58367e7c494 refs/pull/2457/head\n0041f87c0318ffc66e3c82451cebc129ecbc7bb0a933 refs/pull/2458/head\n0041efd8c2b4ca7ee897c0fab7a93ec00bd8cd29c7d5 refs/pull/2459/head\n0040e6a0e38f56d88fe922bfb15e35f05f15daae72d4 refs/pull/246/head\n00415511906fc24b22b252d54f5d2a4b862662510a0e refs/pull/2460/head\n0041ae298fa67b643324650f89628863bcc4dbe1ef7c refs/pull/2461/head\n0041644d27f3c18e9119d1fc471d07279c6e666417d7 refs/pull/2462/head\n0041ce867243c2cdf166b31a687a350c7b9b705c7194 refs/pull/2464/head\n0041f6221e43ecb01c46cf84d2e4938a5c3dcf37a5d7 refs/pull/2466/head\n0041e3567ff0d7f5412ab4135bbd4be8adcdb333b5b7 refs/pull/2467/head\n004153560ba756790c71366a7fb6ed9be8dff4e8ccfe refs/pull/2469/head\n0040c6648aaac24ee53b9933bf43a97aee09dc22c3c1 refs/pull/247/head\n00419d221250b69f232adf7fecd8749cad4f2a40df2f refs/pull/2470/head\n004183dbe9f90092b8e791b9e906138eb3417e838561 refs/pull/2472/head\n0041086f6f183efe4ec20ac643ab2bc5e98677f2d94b refs/pull/2473/head\n00418fc6a5c455a1b4dbc1dbf9869bbe3be6ff82412e refs/pull/2474/head\n004117b37df5d0f231481d6e5b2ada66666f99840fcd refs/pull/2475/head\n00413b2392429fe87cef09e404e695af344e9964370b refs/pull/2476/head\n0041aa0b81d3a6db4bc68a306398c30b473c6309cf58 refs/pull/2477/head\n0041d6d326a4a90095edf0da1d06d3eb48975a29fec1 refs/pull/2479/head\n00404709ec33c18f5c2653efffb908a8b69474fc1deb refs/pull/248/head\n00412af5644abf515b5b8424c8eb7b12faf35be68f07 refs/pull/2480/head\n00416eaa4e79b0e4b1178f5a03e299258632338b781c refs/pull/2481/head\n0041f6cfbd09ca2659675ef5ceca4d9b03b86b42849f refs/pull/2483/head\n0041098f63817e201983078c996ce5b1222aa2be6a01 refs/pull/2484/head\n0041157a47634e6089c7f7938bc7939f0661f5563b14 refs/pull/2486/head\n00412d3046144846d1a981b4ee30db75ac0e0a799f41 refs/pull/2488/head\n004180aa3dc17e885ee35a09ad1488fd18ef42961473 refs/pull/2489/head\n004197094af2d52994da5f658a26372006e0446fad9b refs/pull/2490/head\n0041224485342b1c8b88e4b4c3c48f13c083fcb837ab refs/pull/2492/head\n00419cc699a1c0eff4fb777a32951b06519dd7f25335 refs/pull/2493/head\n00416dbaf17f9a9fbbca7be0d02d5e4e0bdb74b0aa33 refs/pull/2494/head\n00416c1465a055851c726de155021c7284e98b92cc91 refs/pull/2495/head\n0041d302e811976f33178b99b6f15e24c1c23db46da8 refs/pull/2496/head\n0041363d41a21a19b87a0d02a6590d091beeb3eee582 refs/pull/2497/head\n0041568b516d94c9ac0877faffb3dbf13dfd9823246c refs/pull/2498/head\n00410c46bb4025498aa53f8872fab755e8cc02bf2006 refs/pull/2499/head\n003f45d1d4967d81f6ba4e3720a7065a3dc7ad83efd6 refs/pull/25/head\n004073f225e0cd741972f843ead3efd68f3768d32a40 refs/pull/250/head\n00414558a3e87dc35d37be3ecf5804ce499cc7a280c6 refs/pull/2500/head\n004130aadada170106402b84ed7cbc1e3a2be714c261 refs/pull/2501/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2502/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2503/head\n0041c2cdbf33c04c2261bbf13460875dfa96c8d4a900 refs/pull/2504/head\n004131cdc4803c8bc38ad71e14f1177b4dd1e1dbef5a refs/pull/2505/head\n0041cc06e5bbdf95c0e9502e86d24caa07da735e61a2 refs/pull/2506/head\n0041b64512aa5404eb97a175897e819a0a08d8be84bc refs/pull/2507/head\n0041c5fd3054cedd2be85d7e3b7013675990beeb20c5 refs/pull/2508/head\n00417fe9934f21fedf95a3bd95f7a0d7b51ac7425c99 refs/pull/2509/head\n00403444266fc3ee97cf87d942e5c3cfb6adcce0457c refs/pull/251/head\n0041c7c8e84ae2c10084fe1b913262804cdc76591509 refs/pull/2510/head\n00419a05a9350f70a44308e36728775b045eb47931ed refs/pull/2511/head\n00414277918e4a52bb2fe657d9782c40e5ef59678a57 refs/pull/2512/head\n0041c1035ce33537f701f91b7f1bf6df9b943d7eea80 refs/pull/2513/head\n0041a744fde6253c6a98f1b58497ea97d6d7e3c26a59 refs/pull/2514/head\n00419ce7f5a2d56f6a15b084858ad26a26b1b88ba8dd refs/pull/2515/head\n004197e4213204d34947cef09cbe4c16ab83465e9d1c refs/pull/2516/head\n0041ba6b47281628ec355528f1e472fa96d864d2caf9 refs/pull/2517/head\n0041a408bd7d8cfec77a87a9554285045087fc6f87ca refs/pull/2518/head\n004191651d9e6ff7181ed487b6ced372f0bae22d32bb refs/pull/2519/head\n00407f9fb1a86780ddcf6e73c22594f878de5e844f65 refs/pull/252/head\n00410fe7f7663a58e3735fa7f45f46b8ca64b4bf60a7 refs/pull/2520/head\n0041e19697e71d89145a504989888ae3faf0a739a27c refs/pull/2523/head\n004183f32f12b3c992e78c2b96524b4652966367ed3b refs/pull/2524/head\n0041e0bf1f04ecd19faa9d800e5fbc85ab4de3a11f07 refs/pull/2525/head\n004117dd77cdf4cac22f250d00ad1d43f3b928a0a8ff refs/pull/2526/head\n00417260f278cc92a8f2e620c55208c8bb9311c3bbb7 refs/pull/2527/head\n0041b0a9342ef09bd25dca67903d16fffcf45c199e8e refs/pull/2528/head\n0041a06d52e26333b88ae90c515acff70dfb6e5feedc refs/pull/2529/head\n00401cbeaa642c6340f4450ae7baa44745bfa361f16a refs/pull/253/head\n0041016576c8814583b730870f8e2015a023f234712d refs/pull/2530/head\n004174189b5520d233ba50fc975c076aeec7cdaa25af refs/pull/2531/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2532/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2533/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2534/head\n0041feb4d189cb1125b0838cac8b6570a0f8ddd11621 refs/pull/2535/head\n0041a5419a2150dde4d2923f4cdf17a23ef20f6c88bd refs/pull/2536/head\n0041d47dccfce889e6915995d122d04ef363014ed89c refs/pull/2537/head\n0041dc6f679abfd23d56e171946d908b75e5acdce47f refs/pull/2538/head\n0041b72c34c7f9edb9ae8513e95b6d2245c2cb5f54fe refs/pull/2539/head\n0041a2cf07661f649e73475c124118e8cdc334280c1d refs/pull/2540/head\n0041877b62e647862471f1d2b6376773eec2c3a1b211 refs/pull/2541/head\n0041cfc1741a5ded4e6040868b9012629862be1a0077 refs/pull/2542/head\n00412b6a997e296ea3fee132e8b9478d2073849f4e12 refs/pull/2544/head\n00415e8d1a9990b15e0f2219b5897f37424e302ca300 refs/pull/2545/head\n004125f771752f5119e8d697ba008f23e70823d72e8c refs/pull/2546/head\n00413198f8f6b575d2e954b588b4a67e0c123c51c6d1 refs/pull/2547/head\n0041acfcd4bdded2da1570dde992d6e3c15f2b21dc1e refs/pull/2548/head\n004131e9796ed8640c0ac39a81c62bc5b819521e53d3 refs/pull/2549/head\n0040fa95d2cc63ed28380c42e591258a30f607866069 refs/pull/255/head\n004173943f8d9b7d83cfb556848b167fd7c900a7e98c refs/pull/2550/head\n0041bed9872cd09ea6cdd74e31bc0eb4278a1476cf9a refs/pull/2551/head\n0041db7f04921d64675178666b7b2a8489d7ae3ca6e6 refs/pull/2552/head\n00410cd05892dc65cba018f56aad7dcda7cc8c5c4bea refs/pull/2553/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2554/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2555/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2556/head\n0041a84727a064c21268375d16b93feea2c95b038bc2 refs/pull/2557/head\n00418355cc67e9e6e8da93e59c179492d4b0903ab8cf refs/pull/2558/head\n00419c151606c877ad06bf89b3835bc356f0dec77b37 refs/pull/2559/head\n00401a970259913bb7403cdc4608f7fe9e7743f3ca51 refs/pull/256/head\n004147c640f3d31fd87b03010f20f7a4b8bc8640ead6 refs/pull/2560/head\n00410b9b22dd1c444e6ea86560e277d02ce35f0b15cd refs/pull/2561/head\n00410015619ff7aadf7a3004b1d627a1d398e51bb524 refs/pull/2562/head\n00412db5b830eaae0062ad1f518b77ab52bb27d28155 refs/pull/2563/head\n0041de1988eec8f01e838cc5697ebe961b3d07a91e61 refs/pull/2564/head\n0041bcc12ff125f2bac6e2889e144851e9ab056b30ee refs/pull/2565/head\n0041b2defafa31c947d8217a78ee64784d6e99071268 refs/pull/2566/head\n0041be8cf6b0c06195f841c7fc0136c3f4640c2945e5 refs/pull/2569/head\n0041254a670d2cac777740f22c3871b37d41daffdd2e refs/pull/2570/head\n0041c22c95d233964393d44d44c40b905ac16c0b5272 refs/pull/2571/head\n00411cb9ff8dc46e8aea62f8a43288bc84f2252db672 refs/pull/2572/head\n00416e72345f68ad7349d61d4b5cea2cc75d556d808d refs/pull/2573/head\n00412fcd5646c29b6850d656ece947749a865f8479db refs/pull/2574/head\n004142496b7fdc3a1239142d3e2bec836b60a78a472b refs/pull/2578/head\n0041d35db462766019ad82cb1f272f3f2d3e694dcdd5 refs/pull/2579/head\n0041046915c922731515b540ba344e2d420ac4a52fd0 refs/pull/2580/head\n0041546fb5d556524597efdcce7f2fc45a6e2307dd99 refs/pull/2582/head\n0041f2d1e6a62dee228f2f344361ca109cbbf2f0b24c refs/pull/2583/head\n0041dee53b9d72e183c2043edb6a8632365088a5430d refs/pull/2584/head\n0041eff28852d362648c378ee1f14d68eb16ec8d3ac8 refs/pull/2585/head\n0041675f8d051d94f0f000ff8dac8a93eff6458e3616 refs/pull/2586/head\n0041a8a4d03150df75ca23b4aa1fdb09e9da5add83e0 refs/pull/2587/head\n0041246b65dc5814a2a1050db97cfecee77014ec06e1 refs/pull/2588/head\n004181e335000a43373b83522864d2b1729b1d6d6e60 refs/pull/2589/head\n004027b9d604bc4ca31002e242af3eb43a4d26bfbc8d refs/pull/259/head\n0041e0167739ff07740a1565e1b2bbe2a3eaae584e3b refs/pull/2590/head\n0041b94c9ecbe2dbd3f612c4e2caa6886d494be3cf73 refs/pull/2591/head\n0041e57bd03a3b8a26295dc22d092334563a34bfb07e refs/pull/2592/head\n00418ead6a9209d4457843b2ac6e9a7a2549b0886067 refs/pull/2593/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2594/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2595/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2596/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2597/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2598/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2599/head\n003f627e315ddb24233c9159877a91e88faccbeba942 refs/pull/26/head\n0041b3aa240f3cc2cbaf9b810aef9390d3b2ff73a39d refs/pull/2600/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2601/head\n004151fdb7869d6b103c64e96e6a32bc0687431714e9 refs/pull/2602/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2603/head\n004172b478255f01f30aa5b2b33bc697a6216782ce29 refs/pull/2604/head\n00413456c65b5bf8a455ab4be528c932e94e2dbc51b8 refs/pull/2605/head\n00417689490034d5ace342ad180af664d0561dda7fc5 refs/pull/2606/head\n00418f747d48cb81b208e2dd43b2e2399a4e4c9fca16 refs/pull/2607/head\n0041ba522680e8bbf2e06e9844b268ff00147bf5ccc8 refs/pull/2608/head\n0041afaf0c24c73a4ced47abc729116f4e304056d85c refs/pull/2609/head\n00403f9aaf1d6ee0724fb367b8d9badfc153290050a8 refs/pull/261/head\n004125403ed7b2fa54cabe42ad36770b7ded16b17231 refs/pull/2610/head\n004148f4740a642291a6616f29fdbd1e2189449ed149 refs/pull/2611/head\n00419edcc47a2c33ee7c596ee623a34bef3085185446 refs/pull/2612/head\n0041a3fa21166c461cf3c98eef1ccb3ab98bebf0beff refs/pull/2613/head\n0041a23c8b65649e38e68f0c7ac2bf3d583fa278d905 refs/pull/2614/head\n00412a74d38a8465b18f667c93df4a4b9a1688a1621f refs/pull/2615/head\n00411fdcc1587c4182efa6bd6f1a82bd78ed8ab891ad refs/pull/2616/head\n00417581fe8599f89d5424cb3e5fdb82b9d883feff9d refs/pull/2617/head\n004134ea656dc06e0f8b84c07ce9ea716e6227f08597 refs/pull/2618/head\n00411575bd7dec8eac4d7c46a8c60ee1ea8d043909a2 refs/pull/2619/head\n004046c557ad9391746796a00d6ef2ed0d33fa6b46d2 refs/pull/262/head\n00411b72b4bf65fd05a51f3ae039dcf4f4f80c00e85e refs/pull/2620/head\n0041e4cdb49d5a0ec98f63c2d0f5892ae88b76eb131b refs/pull/2621/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2622/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2623/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2624/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2625/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2626/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2627/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2628/head\n004118a33ffec8ba556b2aeca01c69a3f9c1dfbeb194 refs/pull/2629/head\n00403c45a5fa82837ed3281394cf1b141a4565dd3701 refs/pull/263/head\n00412ad5c547030d92c823cf05d33473e5d569896028 refs/pull/2630/head\n004182bcd8510836ce15256951440f1866f56129dee5 refs/pull/2631/head\n0041664c3eacea7aa135815a12b75bc17c1502bc2731 refs/pull/2632/head\n004116630e020ff2f40074480b5e188176ee1f7dbfbc refs/pull/2633/head\n0041afdbef0c49fac58984098b1563bec4b1c94c45e8 refs/pull/2634/head\n0041bfddf1d4a056551c40ccfe9454c0b3cd9693af41 refs/pull/2635/head\n004165e80f09f0a79b12df6beac44abf245151bbfefc refs/pull/2636/head\n004161b021f24ad4fbe29130c0672742a4c1efd31609 refs/pull/2638/head\n00418b76634b8701e90cebb880fc7f8a1faa4e6b46c0 refs/pull/2639/head\n0040b079da3c6af9b1a139db5127457315034abcbbc3 refs/pull/264/head\n0041d2ee349b9919d416260e3717338f9b65e6443b85 refs/pull/2640/head\n0041c86b29e940e3f800f5760f11d41380537a88b131 refs/pull/2641/head\n0041cc703e4f8dbb366e8270a20c0cd91cd53d913a52 refs/pull/2642/head\n0041f3c5d59acfd34527284183af35c2bd0a7b422d8f refs/pull/2644/head\n0041ded67731c579c99af1671e569bbe7e889a633f44 refs/pull/2645/head\n0041b7278b4edf0acfbfd7a0b9230de099e37aad8611 refs/pull/2648/head\n004149585781890214a9f0a08b1dc952bc3cc3d7fd49 refs/pull/2649/head\n0040ecee40da8a3cfd90ad43cd05f7a3f0f47e67a826 refs/pull/265/head\n00418614cbd27dc368dc265816d801ed18e5d00fb760 refs/pull/2650/head\n00415af5d38da5724640f85bc05ba64a1e0bc347e5d7 refs/pull/2651/head\n004115f4b9fd2edee8bb6767003ef2afb27d86ff4c3b refs/pull/2652/head\n0041a1642fb968ee8ba6edd65113bd68e3f396500dae refs/pull/2653/head\n00410d08a2838b3e4741764cdc02cd20fbc164ae60f1 refs/pull/2654/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2655/head\n0041e43f1e2f16a91260fa2b263e8b968a3f535f62f2 refs/pull/2656/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2657/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2658/head\n0041d43b986486789b27ca98202659606351a803cdca refs/pull/2659/head\n0040a1fe55ab948b3507af0e547366e964e6076c0a43 refs/pull/266/head\n0041a5f399a9d582eccb24df4de26c083b04e572e3e8 refs/pull/2660/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2661/head\n00416e4ce8879df1a46060aa7b3a0c05ec18c372ee52 refs/pull/2662/head\n0041db7b359f0e8b3255b22f4cbd1b7ca78685ed381d refs/pull/2663/head\n0041c3ed87788b6021c49c8fc2b9d576b6366537c69a refs/pull/2664/head\n0041f4836610cc31a8a09c823c3fc84599ddb4210720 refs/pull/2665/head\n0041430da5fcc21bc97a11a462c7936f84bfdd1e7d97 refs/pull/2667/head\n0041115f6caf9f2265b6a258ec491d02f6c0b39cffdd refs/pull/2668/head\n004156ed2ad272ee8c04c6be6c1200362aeae05292be refs/pull/2669/head\n00401dfff6435abe32ec18ea4343f41053924ec0bc06 refs/pull/267/head\n0041bc8a9dd8a47a6dcb322502560c6f5a1d65f8aa77 refs/pull/2671/head\n004165d911a77093f0e33f73cd261e754112d094dd1f refs/pull/2672/head\n0041a2521a301d632a896d24596519077bdcc684dba3 refs/pull/2673/head\n00415859aad095aaca071c336ec429c2321951364f87 refs/pull/2674/head\n00412ec5dda14f2593535a8865717ff7f9068737f777 refs/pull/2675/head\n0041775f379dba856e9969c8efd9d84a9c0b34685013 refs/pull/2676/head\n0041ae09e4dc91ab9aea20446af75b61a79092c3d30c refs/pull/2678/head\n0041b6d02fc3a46c7aa43a0ada56a4a05dcf1bff91e4 refs/pull/2679/head\n0040aa35755406731fadfb18212be848b77d5bc133d8 refs/pull/268/head\n0041b678f0620138174c1af1564c46d599ed454ce4c4 refs/pull/2681/head\n004146a6462fd1e901470278e3665d8553037e986977 refs/pull/2682/head\n0041014193bfca96310ed507387a25f064fbf0610cc8 refs/pull/2683/head\n0041847cf4f7afbf164129660be68a389152f32fdc92 refs/pull/2684/head\n00416088aab6a59dfec9d5a9a954dca42c9b3fdab2d8 refs/pull/2685/head\n0041cd156d88f9c8da9fe495b6819e27c8fa332d0ac4 refs/pull/2686/head\n00412d2f49510dbfe5dfc92660ae8278e5c9a26ee2e3 refs/pull/2687/head\n0041d9d09dc8c2a3a4a9eb07acadadb87a928de092e9 refs/pull/2688/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2689/head\n0040df8678d532946bc9d6d1ed59ef24767bba5bf003 refs/pull/269/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2690/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2691/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2692/head\n0041557627d2be80aa8f8337ae5c841c82daf29ad30d refs/pull/2693/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2694/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2695/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2696/head\n00418321be766309bdbdad52f1f91e367589c6be4660 refs/pull/2697/head\n004142cb69954753c00db29bd25f72d8aa21d9466ce5 refs/pull/2698/head\n00411cfde0f7f6ff199b73e233d1e72c7bf3dbf8f2cf refs/pull/2699/head\n003fd12b185990668acabd3be3e2818f5d3154548672 refs/pull/27/head\n0040c60a5854a5f6fd7d431afb69b5b663056a6c9122 refs/pull/270/head\n00414a81447cd5435c74ad91a0fb2d85ce437b82c1cf refs/pull/2700/head\n004110865d01d184ebe325dc402150d8f0b500e22c35 refs/pull/2701/head\n004138262d8cd70f7bfcd9785e9e4be9ee7a075f85b7 refs/pull/2702/head\n0041c37b8f9d2000409e91259278670aa787e5a010b3 refs/pull/2703/head\n00419edeffa512ae514612ff4cf14bb271d03688c0f2 refs/pull/2705/head\n0041c5a80c1bb0cc6865bcc440a6ddce92af5cfd9561 refs/pull/2706/head\n0041b341add1cf7df7dc61b86e99d55b4e14ce2b1f3e refs/pull/2707/head\n00418af58f720a0a05c5fc147052a62899ac2ac0a425 refs/pull/2709/head\n0040cdfced31cbdbf455bdb87427fb458d6709f9df80 refs/pull/271/head\n0041887b5b2bbf1cc4a80cb5abd0c4af99551cd62da7 refs/pull/2710/head\n0041f9af70aa10c9580d624f687ffc071e66e6ae5218 refs/pull/2711/head\n00410c23b69f7b334ac6d4b75644d645ec0a24e72544 refs/pull/2712/head\n004130ed0c4b02a46a20561a5b2123aa08fe1c6e5f8f refs/pull/2713/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2714/head\n00411a91edfa25502cbbba58f8c139744aaef93a4725 refs/pull/2715/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2716/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2717/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2718/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2719/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2720/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2721/head\n004132b09542271b6dc5961ccf6e653d1517fd6180e1 refs/pull/2722/head\n004108a0bb08a6972d4f70752cc6a1d293ae603f07f0 refs/pull/2723/head\n0041d94268f0484742f927ee73bebc05131f09cd37e0 refs/pull/2724/head\n00412c8d08e44698ffb03ae857730ab6b14486bcf0e0 refs/pull/2725/head\n0041ade73c7449073a28fd5bd36a1d48fc9a85d91f0c refs/pull/2726/head\n00411432ffa7f85e9d9b31acbee7f313291a1acf5c5f refs/pull/2727/head\n00414efb6e194aa53d31dd1a5ffcf90e8dc70c9fd31d refs/pull/2728/head\n004089be2b28d522855a7d56d0d6781c841e2d9fe8a4 refs/pull/273/head\n00414a4e64e2fe93ee38e495cb246582f7ba1ce19525 refs/pull/2730/head\n004151b9ae5241247e80b30d68e9b983a8df1ad9f44f refs/pull/2731/head\n0041fc986f627df1f299c03b248a549844df6bb84ac2 refs/pull/2732/head\n0041a05ca8039996626cd40db82aca293ed64a36c439 refs/pull/2734/head\n00417751fbeb2c3e466476dd9b194d8fee925fffdd64 refs/pull/2735/head\n004166968de6c82b4ee867d38d170b5f9d1df9ed93fc refs/pull/2736/head\n0041ef55bd3f7dcfac478506006f469e50f7f0e01268 refs/pull/2738/head\n004160b2751d13b6888d0cd4f2625642f72fcb6dfb13 refs/pull/2739/head\n00413592dc2989ba7b480c78195899aa3a15460c688e refs/pull/2740/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2741/head\n0041d54a91cf61f504a353002f78111cf1a42d5766cb refs/pull/2742/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2743/head\n0041a755ba68a1bf8e48b50e4b5c00a84cfb0b9cb4f1 refs/pull/2744/head\n0041d621f965c8650e6697f74839464a84329f52c460 refs/pull/2745/head\n00415f80f7bda1910871b33cc8568eed9b9e0a067abd refs/pull/2746/head\n004127f34058a675bdba5e5e9ff196293398e560ffed refs/pull/2747/head\n0041ec6a31f01d35bbaf086bcc2098cab5959c632479 refs/pull/2748/head\n00416e76f8d379609f9945377b7045ab308979f816d9 refs/pull/2749/head\n0040abaa66143b82ff64782f3d8e5a726fa3d8ea674d refs/pull/275/head\n0041f5d9e64f8c83fe518d93b584cbb099143745e362 refs/pull/2750/head\n0041c5c4e3f5856a61bef515aa5e0a69b72826f536e5 refs/pull/2751/head\n0041bd209b316901966059e16cc7985122db957e854a refs/pull/2752/head\n00414fb5b70400f425e9b7c52d397373b4563539edd0 refs/pull/2753/head\n0041d344dd1ac65befdb61c7016d1ec2e6b72d42fa0d refs/pull/2754/head\n004119a3f119197386ef948b52e3041356e01cd72455 refs/pull/2755/head\n0041a0816f94ab06d17c770334b5875808ae5dd20dd2 refs/pull/2756/head\n0041d360762d855688c45c934912f14e3e07945d3ced refs/pull/2757/head\n00411a596384bb4ccf7e7a241bd5d4540d98b65ae151 refs/pull/2758/head\n00412031ec5f09cac3612093578697973ec78df3ee7c refs/pull/2759/head\n00407acf9f795de84bc83c6176a6e0332453bbe51fa2 refs/pull/276/head\n00413517588333f1a378675690923792341d2b94f08b refs/pull/2760/head\n00411e29bdcf8ed23a4dc8f043a0963a773c056edd63 refs/pull/2761/head\n004159daa621cf5085f140f7513b12bf98611e8b5582 refs/pull/2762/head\n00412a625ab871036149179a92d70bcedf0a11fff820 refs/pull/2764/head\n0041aabdaa18934aa47b6a1a682d02cdf3fcb974debd refs/pull/2766/head\n0041f9a984e7c1b1faa582cde1ab72fe6e07286bf239 refs/pull/2767/head\n00419cd85f118c2603fd0524f0d9b8b78e265063faa1 refs/pull/2768/head\n004189d47a15013cfb60bfd200cf61c47b62d2de9d5e refs/pull/2769/head\n004104db79d2fc3294c78027967576ab0f886228ddf1 refs/pull/2770/head\n0041bf7e690cc30eb306ea66ea0a7f53eaf21afb2601 refs/pull/2771/head\n0041fd69d044571f9c6daec232fc59bdd9a8d5d4125c refs/pull/2772/head\n004156b14b7449f7e3514178108b5b688ed8797253df refs/pull/2773/head\n00413532e240bfa976ff538013367aa27338b8380921 refs/pull/2774/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2775/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2776/head\n0041d0ada1d23b06bcd3948b924cdf761a8390569550 refs/pull/2777/head\n0041516179e60ccee64e0eff2f405286d3c4513bc459 refs/pull/2778/head\n0041a8e35df702581892410de7d98a5bdf2e53c671f1 refs/pull/2779/head\n00409ef86c610ec21e3a398ed7d7d02ae9b2070d19d7 refs/pull/278/head\n0041efa432d9e9e19623caf79c4dd0b359f6ee0984f2 refs/pull/2780/head\n00417ebc50d417b25a285bbcdc8ba416c390aa0bede4 refs/pull/2781/head\n00418f936d8ca8889845c1a1f3e468388b60b5384ded refs/pull/2782/head\n0041fffef8ed543bec1e79e2f1e3e668c2ad3f7aa1b1 refs/pull/2783/head\n00410c3412a5938c0af7c15a20d95e2b39e65f037a11 refs/pull/2784/head\n004126676724a4bc1eaca84139c94ece9cb77fe9224a refs/pull/2785/head\n00410efae10947090c7e2ba66ce048ee8933569fdfd1 refs/pull/2787/head\n0041eb8724b40c9693ce5cb7ba322c4dc917ec2b0166 refs/pull/2788/head\n0041c46c59fd46e2418d293f3c45575e0c1952c7ebe6 refs/pull/2789/head\n0040387db6d1376294aad267c4927a7abb44cf8c5a31 refs/pull/279/head\n004130f4ed16e3b290acecfd565720ebf92dfa5c69d3 refs/pull/2791/head\n00411b6820e13ffe15956e4973dcc16294c9b9ca9637 refs/pull/2792/head\n00418a10e02c2a94af79e599774ce224d022ad5c6b15 refs/pull/2794/head\n00411024b7d519a107554bc6a5b3c251af71cdd06b9b refs/pull/2796/head\n0041c9520de348b6bf3b70fb7f6db48d26503ed37c5b refs/pull/2797/head\n0041111952e89e593ebf05626dd8d8979745c7f81f79 refs/pull/2798/head\n00415467cccdc73e0dd78c1674d76854bce827bdee62 refs/pull/2799/head\n003ff487a58f5ca9cf47cc62624d6e74f38134172298 refs/pull/28/head\n00400f1e0091747295f93910650e5dc16de612fa20f7 refs/pull/280/head\n00419c1176adeff7fc3e6523c496d40242250e26719c refs/pull/2800/head\n004133a3087a7ea73bb06343884720a8f9f9c62dacae refs/pull/2801/head\n004113b27b8dfafcce495fbe3f919c2a286bd002982d refs/pull/2802/head\n004139de5c14157758242b12e2a1c73fd1bdbde80905 refs/pull/2804/head\n0041b4cb96c9ad88813e5705410a5bfe3b2d86ef0949 refs/pull/2805/head\n00415db28b0a667f51175fc6d808c004534d681e754d refs/pull/2806/head\n0041d748f3ee8c54e343b7bfabb9ea632b6d02a8c337 refs/pull/2807/head\n00414e8a542ed46dd0744ba94717980a42e6334a4c0a refs/pull/2808/head\n0041f9a76ad79b91979aa6ed8bbc9694104a7ae6cfd3 refs/pull/2809/head\n0041f49db036ec837a98011cb28e38804a4fdd57aed9 refs/pull/2810/head\n0041185aff83e2cea035f1f4c0c333eec954fa89d04a refs/pull/2811/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2812/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2813/head\n0041fd94f48443d79da98de552304653b908fe83e6ff refs/pull/2814/head\n004128fd0b9b9ea81ef284a99b149e5a69fb2f2c8e78 refs/pull/2815/head\n0041642bf0504d5dd0fd6160e7b508e546e37b27d905 refs/pull/2816/head\n004106c59993b4c84817b8b8c2a879cfcc5f3fcab8f4 refs/pull/2817/head\n004165dab2740390fae7815d53881b5c0bf6fa8eb583 refs/pull/2818/head\n0041d7956d5236877d7d2f1da49fe75dfd81059119da refs/pull/2819/head\n0040c88914a941222f07a6a29cd9ddfcd782d87ec1fc refs/pull/282/head\n00411cb455b505a3be35bd0696c41ff1ca5cbf113bd9 refs/pull/2821/head\n00418a57d72bc2f5d9182a56e4c882c44f51b994d627 refs/pull/2822/head\n00414dafa11d0222373c698b0ed2668a37112d491bcc refs/pull/2823/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2824/head\n00415dee54879ba73cd0c422fe0a7fc637a9cafa480e refs/pull/2825/head\n0041547568a2d0e54c919284b9a57ebafbd9cfca6a86 refs/pull/2826/head\n0041e0faf86c9025f64d5c083de17f0fcbaf8466cc0b refs/pull/2827/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2828/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2829/head\n0040857891acf88fd5e494c705e44f9721c73a6df2a6 refs/pull/283/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2830/head\n0041190bb1668ce2c7be361faa1a96626d4250f53bb8 refs/pull/2831/head\n0041dee7f03da3553448c024b4ff6ee96da427095779 refs/pull/2832/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2833/head\n00416faf3dd312ced029b468bc8b5bbb9ef12dd80cd4 refs/pull/2834/head\n0041476106a04b739c4a2d9f4106716d70e8c2205af8 refs/pull/2835/head\n00410c33cb5792dca5cffebfa2d9d9102cd51dbaa417 refs/pull/2836/head\n00417472807b8962255ea4eb7c8916c4b42e14872395 refs/pull/2837/head\n004119905886ae56bfffbc8027ce84ee5970e974503c refs/pull/2839/head\n0041c053afe6671014bd97cce4e5cb2189fe186e615d refs/pull/2840/head\n0041995f36545f3f9ce298b63235ab069bc915553ad3 refs/pull/2841/head\n0041611029f7c6bffc2b86c4e2a1fc3adba1dcb6c5ef refs/pull/2844/head\n004190ffe8e4fdf36ec73af89a4c91436c4ed5891b0f refs/pull/2845/head\n004180c8b887ac4cdd4094841524421b22da6b787757 refs/pull/2846/head\n0041c4775008293ae04c32d7c3a36e7ff69b6e6585c4 refs/pull/2847/head\n00417be76c68bf4172bec3b63c337c0d632105cd7dad refs/pull/2848/head\n00410bf3076cdf5cbf1b8d821346ccc8e36425af6447 refs/pull/2849/head\n00408fb04a0898abe7717137ec504546838abf6bdcc2 refs/pull/285/head\n00413dd6b289906a198f9cc4c554dd2d6ef75ad59b0a refs/pull/2850/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2851/head\n00418f8873ed698a9ea5322a04c707b034e5568bcc42 refs/pull/2852/head\n004119e2589154d7fbb20e089788154342e6735bd10a refs/pull/2853/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2854/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2855/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2856/head\n004167aabf6657e3b405f04ce576e39e3f303e4c66d3 refs/pull/2857/head\n004193a63ad748e1d6ff49af3c3f641a4ce09b1c4b0c refs/pull/2858/head\n0041f477c6940ea743f47e8cdb6ec14ba4d5c6f31838 refs/pull/2859/head\n0040ec88cf672778f0d8098070047e7050fd5821723b refs/pull/286/head\n004193d45871f40f122c1494b79931dd732891792064 refs/pull/2860/head\n0041add5751fd0bcd0f1e9ce7e1f414c786110915e14 refs/pull/2861/head\n00417d7c18855c6e7f1b88300c5d2cdeaf33f1cd0c2e refs/pull/2863/head\n0041e1d8affae17cacef6e7c1a01e901b9687538121a refs/pull/2864/head\n0041747e1da71770691f0100fb21f4a9efcd9575183e refs/pull/2865/head\n00413fd074245dcaaf739002d63e7c6a89f39d9bd1ff refs/pull/2866/head\n0041c3523af0d6087b244bae0fd6c6522edd441f011f refs/pull/2867/head\n0041ddcc982004944baa45c53ef7ca1d9bbd2404a40f refs/pull/2868/head\n0041404a259ae62f5ee0537a87a0ba418daff01b1998 refs/pull/2869/head\n0040a865ef6942833d38e5ca4c163e1008c9796eb285 refs/pull/287/head\n00416d2c55e7437107c19210aab82e8cb06479710d96 refs/pull/2870/head\n00418c5bff2b80e1dca212cf32b0541e1db6f439a5e8 refs/pull/2871/head\n0041ee42ed4e2f00d71a99e2e74e497db8b40efe6784 refs/pull/2872/head\n00418acbb8bb927c14c60b5edd34b3b2af09ce999fef refs/pull/2873/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2874/head\n00413f8c12ec2674220d32c8fe644a510fd712336443 refs/pull/2875/head\n0041207eeb6eba7de6c1bf8d6b06ab1d2463935d993c refs/pull/2876/head\n0041ac3717e5ad39d22f94b68123dadefb174cc1c9a8 refs/pull/2877/head\n0041392798ab0a782b71f84ed724a653c3a2ceb28144 refs/pull/2878/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2879/head\n004054a8f8b7ee2cf16d9090585c1aeaa651b1bc64fc refs/pull/288/head\n00418d3e1fe872525cffb71dc18a1baab4e5a437cb91 refs/pull/2880/head\n0041209183bea595553c350bd754b2aff1e42a411973 refs/pull/2881/head\n004182b2f5db7ea4dcc6523a5b3c758fd31f966d4840 refs/pull/2882/head\n0041d94c89dc945512ff6da6dffb573cddc5a82e244e refs/pull/2884/head\n0041a7a391b6b4ad844c44c0aede77ce2d85a00d9b35 refs/pull/2885/head\n004169e6819fea9cf083ab2b8d19a82544fe888e9d62 refs/pull/2886/head\n0041bb2739a9755747176cf784b8c5156d501d8222ea refs/pull/2887/head\n0041bf7c148b090eadb587832531d9bc1a11be06577d refs/pull/2888/head\n0041196dc83ce02e38d56abdc3e9d7fe696fe621b3a0 refs/pull/2889/head\n0040f6d68afa1708059c00684b5d0bd9eb9217661a66 refs/pull/289/head\n0041e9d2a7d9eb40c426e630610c08e2376c82b46278 refs/pull/2890/head\n00419d8f0b1efd8ca12e9a71d3f815cae43f13409a34 refs/pull/2891/head\n00419c7315590feb960dc4b0cb8e87184792d38ff7a0 refs/pull/2894/head\n0041a8a928fbe8ac833540e11569f44fb09c50410d54 refs/pull/2895/head\n0041cdde00b06c74be5bfbf88050cbec722f1462039b refs/pull/2896/head\n0041e51098f495561b99d18218b40c58d18b9e872832 refs/pull/2897/head\n0041b4992ee4dbf990acaec8fea6582fd215d1122921 refs/pull/2898/head\n004163d1a6dc14f8dc2090cac8341fcb3148195ddc75 refs/pull/2899/head\n003f58fce1249ceb5d65b7895d5cdafcdd7821772b6e refs/pull/29/head\n004139309f06c3d1e405348b53877af07335aaba4fab refs/pull/2900/head\n0041a92019df7a4cdc1d55077d35042ec51306378b54 refs/pull/2901/head\n0041d103b346ccb027171f710e21ab4cdfc42618412c refs/pull/2903/head\n0041e3f88cda1e69b25caf64458d0c836408c1d83323 refs/pull/2904/head\n0041a70352aec37960d0e9858a693594a6e2721f5313 refs/pull/2905/head\n0041eb6a90c12145cd3ec1195ed71f34ff63b557ce77 refs/pull/2906/head\n00413a11321134227846f1d78c3835a9237f99726257 refs/pull/2907/head\n0041166a833b8f4f2105c5263e0fbcbb41dd3752a00b refs/pull/2908/head\n0041d958d900898d7f5b612864e6b45751ff1a77b6d8 refs/pull/2909/head\n0040fc0d24e67117833b606a5648b3308f907d3cac34 refs/pull/291/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2910/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2911/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2912/head\n0041eb5efdcb6805ce3702f91409ecc208be8e3d5df7 refs/pull/2913/head\n004199db1b0e45b3889626c09c0386b16f2ccc0dbd4d refs/pull/2914/head\n0041ce58552dbbd96fa34e39f9c256f9c4f3e6417ca8 refs/pull/2915/head\n004139e378db7e1db7e8fbc3ba2dbcaf7e7eed22bcd1 refs/pull/2917/head\n0041d91a2f11298f61a16fdeda77e89811c621b2b56c refs/pull/2918/head\n004188f4b5c486f180f07ec36b145307069a83d71279 refs/pull/2919/head\n0040177b1e72d8561ae95a910e9666f3a446b2d607f2 refs/pull/292/head\n0041c5e9d21e5c514c0aff595aba357a8429d9dd9b81 refs/pull/2920/head\n0041e73a43793254c217f42f4d27ccde56e6e7b9dd62 refs/pull/2921/head\n0041c4151af86b4125532d999f72a5dc0f13c7feac60 refs/pull/2922/head\n0041a311476a5b3f9c34407bb5422ee93f7df236497d refs/pull/2925/head\n0041c73a96b6f7cfef4fd1e1bc00a6686956e58c3879 refs/pull/2926/head\n00418a4f90c0240285aa3638be184a6092b50c49659e refs/pull/2927/head\n00419fd44d4217395b540fda630c64c1e84ff1c532bc refs/pull/2928/head\n00414cc85a0e3d02f0d830721518f6fc02349e71f08a refs/pull/2929/head\n00403504293dbeb6a169d9c51279ee0c9fbbb4dfa58f refs/pull/293/head\n00415234c08ce941b082223c6b7eb15d4e3beb3898e2 refs/pull/2931/head\n0041fe1da8c674e09238c0c12fba310535de7b95dfd1 refs/pull/2932/head\n00412ac962cd4b4bb269bd863fe9b43f0ed894e1eb4c refs/pull/2933/head\n00417ad72d8ae97bae7adfed81b8db0cbffb45ff81c6 refs/pull/2934/head\n004118901307dd712f3d8ebf67544c34626b9c804fef refs/pull/2935/head\n0041838166bbf80143eea1206fc5f06ea0b2ca862d97 refs/pull/2936/head\n0041827912336c7a42090a005dd0630d07fcc23dce01 refs/pull/2937/head\n00413a2b3f7b74d733f29e2d9e485c1a2c433811af9c refs/pull/2938/head\n00413eafc2591f35d5cdbadde5e223332b3c8449f17d refs/pull/2939/head\n0040a91db92ab68ef5abf3590a4c6c1156cb496070b2 refs/pull/294/head\n0041be92d5ced97ef304d5a71685ce704aee8f998376 refs/pull/2940/head\n0041f951db346b984af75f9158473884985dff74f525 refs/pull/2941/head\n0041c355aa304b31f81a1fca44c6c1561c568c761e18 refs/pull/2943/head\n00414fba1b172a8d5a2f68fc5cd6ca12a831c60b1288 refs/pull/2944/head\n00416f3de20c9009f0276b5af06e5ddedf3f1608dad8 refs/pull/2945/head\n00419f1ff0f6391d3f8936872a44e48b686b97fe5ba4 refs/pull/2946/head\n00412599a7dad17dd6e74ee9452026fec56d1f34be11 refs/pull/2947/head\n00419ddcd6e9d446385730a6e688fedf98a689be02b9 refs/pull/2948/head\n00410b2408f69b00465c0d14a7bf4b07ebea2d45bc00 refs/pull/2949/head\n0040d04bf6c58d024bfcb395027a82eca6f95d812607 refs/pull/295/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2950/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2951/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2952/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2953/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2954/head\n004198478706e827d4da7fae302344ae4626f91e216a refs/pull/2955/head\n00412d97411101768867ad72b493c386b087a01f4796 refs/pull/2956/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2957/head\n004116f5297332724a0836ec2c4127680963d2171285 refs/pull/2958/head\n0041f4a55c33a40aef6a4d473a022ea238fa0cfdc6e8 refs/pull/2959/head\n0040ddafd0b526eea0b7449881ab78ccb06e260c2fff refs/pull/296/head\n00414cc577627d5ace18b86335424faa0938de06f09e refs/pull/2961/head\n00412d3a8921f5f49f140c892059bb33191d017d3b37 refs/pull/2962/head\n0041dd37c708309e16a05aba50aa5da35eb51db512ee refs/pull/2964/head\n0041f0be3bc7ccf9429cdc44aaa3b755d1eb1851c9f9 refs/pull/2965/head\n0041dfc0d77ffa7035fa30ac0af4fae7014f963d31c4 refs/pull/2967/head\n0040c6324c7def409e52d2a6a79e986fb1615f5677bc refs/pull/297/head\n0041dc8941aedde75407a3aa51a6c1c74480df6523f4 refs/pull/2970/head\n00410d937d9c75ad6efc0aa2bb61042774b161738f42 refs/pull/2971/head\n004189d5edb9a4181ae87c4903b25195657882bd8652 refs/pull/2973/head\n0041a8a4c03282d2c6a80d164305db1176f8cb4e0fcb refs/pull/2974/head\n0041b909d9da94007f878ce4ab9cd9c851ea8dce0e2d refs/pull/2975/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2976/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2977/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2978/head\n0041395fc6df1a91872baf88e570a89df4b5504d6ae7 refs/pull/2979/head\n0040e51c698385f0ce74c82bfe208d34eb74decd29bf refs/pull/298/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2980/head\n0041fad161ee283b537b0c97e577ae6d89bd371961dc refs/pull/2981/head\n0041ae21d3d15dd77c67430504f7d17fd2477187b397 refs/pull/2982/head\n00414b0249f355d436b42005a3be066bb0422f08af08 refs/pull/2983/head\n00417f0a8fab9dc5d51e07afdc57382825219cd53ac3 refs/pull/2984/head\n0041e5e3efb0e0a28772c2c31ecf3de5a04da09065df refs/pull/2986/head\n004126c0e0a21de2a2c3fc6dcb207347339e6ec3f18a refs/pull/2987/head\n0041c5d867b4caa4836692808d29b74a150d0f7c15b3 refs/pull/2988/head\n004130db1124016097a4d5f1736deb00c48b77410a24 refs/pull/2989/head\n0040eb68f82a1c3356d0ff11637395078512c96697e8 refs/pull/299/head\n004119a07de57a21994b6f1478a8d2410517ad829e1f refs/pull/2990/head\n004167f77272c080407d5a2e01de41af55b59d15d782 refs/pull/2991/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2992/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2993/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2994/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/2995/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/2996/head\n004189007174d4749c0b3343f199e57ae195ff29e6e0 refs/pull/2997/head\n00411645cf0d67d85a94839e05fff2ffc161595db433 refs/pull/2998/head\n0041c30e305ff7f5908e389912f53aa49ee5403e5da4 refs/pull/2999/head\n003ef0cdbde101164b659a1c59b6b400472820703130 refs/pull/3/head\n003f3ff993226b672f16415168f26e670785954c0c48 refs/pull/30/head\n00403ef1b3d7d647af747b2a9e03f17773dddf5f4db4 refs/pull/300/head\n004146c427606410f135353b204dd06affe01c89b7ad refs/pull/3000/head\n0041c6a6b896cf2869a9bfd0dc6b52efbe0e505b4391 refs/pull/3001/head\n00415cb1ddffb06ca75562c641d3f28a5df1a791d5db refs/pull/3003/head\n004168cb24921d8a037f8157f1a503da88d61aceada9 refs/pull/3007/head\n00418f1bdfebbee3aa1af953417f21e4253ba8ccfb74 refs/pull/3008/head\n004106f28780b388130601eee7ae3bc9d0b3d5940663 refs/pull/3009/head\n0040fea7633143d0293f5a61d8aaa49da07e048e6563 refs/pull/301/head\n0041cc697f8c8204edcfae938dd6caf10054f11a43b6 refs/pull/3010/head\n0041d2f0755b32b10522939c79b6e8b4bea541abfcde refs/pull/3011/head\n0041106ab5e40648e8387526abe3de1c8ba4b04e5ff3 refs/pull/3012/head\n00418856379bccf277f9c62464aa427fa0b2d6f67577 refs/pull/3013/head\n00412bdf7f948e06f331ef338ae7db1d57dbaab0e751 refs/pull/3014/head\n0041442efcf258b28b45d96e20a60affc5155c54bffb refs/pull/3015/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/3016/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3017/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3018/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3019/head\n004077abff46e64d91993f117bcde1ce703b89840763 refs/pull/302/head\n004191785546e68c04c40fb754c656227f5fa1c66438 refs/pull/3020/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3021/head\n0041354913c4dd35a4d63665f5b527cb599d5de135fb refs/pull/3022/head\n00419b1873f19a5d21f87641318295f02c13e50f07fd refs/pull/3023/head\n004185625d97bc9d4a09294d098f30425dc5c95ffc03 refs/pull/3024/head\n00410933c86891d7c6f5420e1c41d3b23e79b3744686 refs/pull/3025/head\n0041b47c661a24c4242b795822dd155bb69a2a3b1c82 refs/pull/3026/head\n0041f7e4eb57d8caf0663fe23bbfc9a5aaf9cc514655 refs/pull/3027/head\n004180eceaabfa2e1a4620c0512a85a7af6db45d583b refs/pull/3028/head\n0041c80da837eb9e1438e795105b35d4abf12d38a590 refs/pull/3029/head\n0040dc2df970334ca11c74290d169c70390a8eceaccf refs/pull/303/head\n0041a0860d3c5649616c707f5f0c977e17939245bd6a refs/pull/3030/head\n004113a552ea3fe1288a590f9b931d8371336f1d7b72 refs/pull/3031/head\n00410159e086cfb5918c03061a62d80e15297d6ed927 refs/pull/3032/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3033/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3034/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3035/head\n004107fa0d7988e84f3b3a34ac3dac399ba193887524 refs/pull/3036/head\n004100cb652efbe3060aaeffa5c4f3a7d31e66a0c231 refs/pull/3037/head\n00412b6b3b940c64c5517b64a7c03bb529866a421e10 refs/pull/3038/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3039/head\n0040fade621a7f723174ec82fae918578b84229d858b refs/pull/304/head\n0041f961c3c635c28cac218d79b63e95e01e5d8b810a refs/pull/3040/head\n0041a0214ffea0a79b8e1405df69d708d2dcff505ca9 refs/pull/3041/head\n0041b00ae6ad393dc643ede45c53649e5302e1fe8e20 refs/pull/3042/head\n0041dd25cd187b995f3e81cd26d138c783f52d2ac74b refs/pull/3043/head\n004182de78c184dafbfade5f45c2af21a6c14369b0b9 refs/pull/3044/head\n0041bd501aa0621037cd9004b2702a1e76de442e5965 refs/pull/3047/head\n00409d95fbb972ce3b32fa23eb739dfbd269aad20f3d refs/pull/305/head\n0041e882cd65728241b20bb5017316c286dfcb00dfa9 refs/pull/3050/head\n0041914aac4b7d550541f1b9cbfc7fd9374bb5feb497 refs/pull/3053/head\n004108f216bd6e902609d9aa84f30a50bc6c3bdc3c06 refs/pull/3057/head\n00417286d58bb1c5582b1add8d32d1696d6c8947d093 refs/pull/3058/head\n004132f4c488f7dffa308f82df5827a165e400a5c0c7 refs/pull/3059/head\n0041a5db19432ad9c33ea0d970dbdcd1d431b0e766c3 refs/pull/3060/head\n0041177357fc096b77dba00e31d85d3d3f31e96fe49e refs/pull/3062/head\n0041ab5adc598eaa84daa237eddff158db70bce13f78 refs/pull/3064/head\n00417df290ce8f2f3cf36a6058b7ee72350973fe8f83 refs/pull/3065/head\n00413549c650ccc399f36264c7b1276eb1254f33fa98 refs/pull/3066/head\n00419e4e3ab71e51de615b75393c67b741f316e9e752 refs/pull/3067/head\n0041fa1a05258fcedbc38ad9456165ff83c1cb8f97d4 refs/pull/3068/head\n0041397c82d0de51dd9ad7be2caf64c90bdccffa2023 refs/pull/3069/head\n0040f25a65409dfa4ea967d1b1a7d134da5013287dbc refs/pull/307/head\n004150bac02853af6b495043453ef4c7a50e2931fd64 refs/pull/3070/head\n004109feb895a36ac0927a24e94c297ed03f79b899fa refs/pull/3071/head\n0041ac0931b70d8680b25d430009007e1d9f0970a082 refs/pull/3072/head\n0041d0e784b90d1f359fee5ee6bf20689d6858d3161f refs/pull/3073/head\n0041807a02caee95fba47c7818bdd81030a60ca6ac20 refs/pull/3074/head\n004164711b7a7947fe8f441cbf6bd04b82da41128ff2 refs/pull/3075/head\n004158dd885ff2de27511b331c3bb7e892fc67998935 refs/pull/3076/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3077/head\n00414bc4dc9bb7cd85b5665f08454664843921f196fb refs/pull/3078/head\n0041ea8f0f79cb8433d5456fd82b8c7599ff82cac75b refs/pull/3079/head\n004073411ce4dd3994d9dfe6597388de7781b803e056 refs/pull/308/head\n00413805c23b7f29a1ec1710359c4f1d1e6df31c7ba2 refs/pull/3080/head\n0041925ca8a475d5650662ce8908458863e6b658d6b4 refs/pull/3081/head\n004100c3478e13944f99a154dca4ef7aa289f97fdc19 refs/pull/3083/head\n004158fa551ee7d146fd25770ed5734553f664912794 refs/pull/3084/head\n0041dd4a9fba9528b3cf0f22103d590ae6804ac8ad4e refs/pull/3085/head\n0041c1a75222f07f11b881558cb5ae85db705a13afa6 refs/pull/3088/head\n0041fc3357d173e441a822781fc46288b787cddf8dee refs/pull/3089/head\n0040e3e35a898a1e3a1106095f4094c748e635c54e5c refs/pull/309/head\n004101d7427d06d0aa5aa4795321ce1d9a796a8f72e9 refs/pull/3090/head\n0041f2a910f11286b1fc1781afd9e31eead170e172bd refs/pull/3091/head\n00415c0f8bf021cb2768cbcf264a04229a02cb562e6f refs/pull/3092/head\n004133dd2316429de872f26aa1a3f70db605e636489b refs/pull/3093/head\n00414a943449ddac590474233c569576074bbd67a59e refs/pull/3094/head\n00410cc43c1500774d5ae34950adc14a86a1a50a949a refs/pull/3095/head\n0041222ea10609bc06a812aba8463bc3cbf52d509285 refs/pull/3096/head\n0041c9149607f53d653b6d6869d66d202f915c2082e7 refs/pull/3099/head\n003f03d5ede47071e352bd5c48c69b4156324c71a038 refs/pull/31/head\n00401769ea723a9fb250a7118164ab2effb91e1c3461 refs/pull/310/head\n0041b78711a5ee79bbd7998de91aad6dc1295e22f62e refs/pull/3100/head\n0041ecf58a0c6459d9f245525ab2c253af0a9b6a83ce refs/pull/3101/head\n00412e4e4d113a2fd913d7d304985cf9ccb8b576c766 refs/pull/3102/head\n00418e86f1ef7b8cb02e3ea4a1cccd25144efb99048d refs/pull/3103/head\n00414fc6b776cdf924caf51e2e953108fac00ccf42b6 refs/pull/3104/head\n0041c6a1fbe65b831bf87b3246b1175bf02b2f810bc9 refs/pull/3105/head\n0041630dfc9cc184569e9ebdb67f290c75dae6f9603b refs/pull/3106/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3107/head\n0041f6d4c8fceab5b87f3fef22019f55339a73beb04f refs/pull/3108/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3109/head\n004017d50a8045e6ab6452e1da82f9c2ee2895bcf12c refs/pull/311/head\n0041bf09b2abf49a4f3e2e6602bcaa946962a18047f7 refs/pull/3110/head\n0041c1e468882a3f011e83172b67f225f99315494009 refs/pull/3111/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3112/head\n00415473e50a8182ce99947ff83ce1de10ee3c333fdf refs/pull/3113/head\n0041e103a9d6731021989cbf6d7eb67a196ce58e3837 refs/pull/3114/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3115/head\n0041e564df2a7bd69ce2cb4ac1b501944286e8071b2c refs/pull/3116/head\n00417694475144ef82b5ceca67d9dea29b9b0e2c616b refs/pull/3117/head\n0041782321d204ce8b7a44192878b95272398387cd44 refs/pull/3118/head\n0040188650c8960ee4afdfbc466178bf680e360e74a0 refs/pull/312/head\n00411af0d27a4fe1110f3e723c502227cadeba76d7e9 refs/pull/3120/head\n0041c5f312da17dfa2ef648c188947d0e802b0a0bc5e refs/pull/3121/head\n004170e933c33ad5df01e4cfd13c1f1d638afbfcef60 refs/pull/3122/head\n004123b294193aff6eb042da70f98f0d82fc7ab15f96 refs/pull/3123/head\n00411a8f3cff55c5ef37d9259044a32169b4b2bae1bd refs/pull/3124/head\n0041fcdb11e4df6ea8c0689e5da738599987ccec55b4 refs/pull/3127/head\n00411caa240d65c4dc07de4e1f0260b5aac50aade9f4 refs/pull/3128/head\n00414c34c0b48625de98d87cecd1df9dd2c780d172cf refs/pull/3129/head\n004022094a80c98a2a8e1eed141c4424a82681dcc2ba refs/pull/313/head\n004125119e4da3eb317aa14f22d36e5405bf47801726 refs/pull/3130/head\n0041039259cd1ef4ea16e732e740ff1c4a6938c58964 refs/pull/3131/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3132/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3133/head\n0041527572a2cea9f0e08f0334e74b30db2c741efe12 refs/pull/3134/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3135/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3136/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3137/head\n00413d1aa3e23a2146765bc94d0c9c1056005582eb3b refs/pull/3138/head\n004164f98fedba4b5a2d668dd3942d46d895b64a5713 refs/pull/3139/head\n0040d6aad74d8aca422749b3a63a359460431e624f2f refs/pull/314/head\n00417dd22afa840436ad016a08f9f2588dcf13b7b44e refs/pull/3140/head\n0041f3bc32e8b6482819431640f7ea46152581d804c0 refs/pull/3142/head\n00413f87112df4042dd8a06c27f1c25a14f803a61912 refs/pull/3143/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3144/head\n004157c03567f1b892b18e88bddf1e1166cacfcc123b refs/pull/3145/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3146/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3147/head\n0041c755c5203224f23cbb319b1749783af14f31537d refs/pull/3148/head\n0041b65f27f9e85fd6b0a16a499edd5ba5db3548d7ab refs/pull/3149/head\n00419ceeedd79a55533bbac0e9f6938ff6b1fd1c6114 refs/pull/3150/head\n0041bb1cb86a28fd776afe65757647eb41e2cd14d12b refs/pull/3151/head\n00416c93f87696ee00891b0146ea6f3be8dd53659a6a refs/pull/3152/head\n00413bd8359e38f1c5c33f590ca406dfc1bebc816cb9 refs/pull/3153/head\n0041cd8185fb4a44ed1280f3bcf571279fd40a45494e refs/pull/3154/head\n00411f3639f5dc1f19a3b130079d2aded178820bb80a refs/pull/3157/head\n004193743e8e7ca91fc3f0be3cf5ebd3ee4bb1a16772 refs/pull/3159/head\n00402a2b2599c2ebcf9032b67da26bc4d1816b6315d1 refs/pull/316/head\n0041d8db9e7af6d9b52bdf5b79edc8fe9e27ae7b67a2 refs/pull/3162/head\n00413860c5f8a5afe8107deaa7b6d3e75584441d70af refs/pull/3163/head\n0041a5e1d3c04d2c5df7e6a025c115a86cea71d320fd refs/pull/3164/head\n0041301b76f411c0f8a7245584224a593eb62dc38ead refs/pull/3167/head\n0041f1baa53e91449c83f5a9b39f57bb88ee791a9bb9 refs/pull/3169/head\n0040512f4a594dd01c11dffeb7f3a01f6ee2910e2446 refs/pull/317/head\n00411d75f8cca72cbc4656e4633a5da804d5b8e06e63 refs/pull/3170/head\n00410425c1abacd948dfd9f783f3bc7d1050698cfbab refs/pull/3171/head\n00418897b145798040832c08b182684dd7e9da8ea28f refs/pull/3172/head\n00413870193fe93ad63bb05d4bef5c49845cd2e8be97 refs/pull/3175/head\n004132fa682339d2e337e0a5dd822383329279a6e081 refs/pull/3176/head\n0041d974f9aa07335c498eb3b694024fca4143b15745 refs/pull/3177/head\n0041da97fddd86caf5f4211ff98fea9b79ea16ebb269 refs/pull/3178/head\n00413e5cf953d7d95a1032558f7592844646c1f23282 refs/pull/3179/head\n004115a638b3e5fa3f855c20160fda14eed496fd6a04 refs/pull/3180/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3181/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3182/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3183/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3184/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3185/head\n0041c1cbe6c7da136974a98477bce101eefb7537f08d refs/pull/3186/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3187/head\n0041b0bcc9c9bdd03cdc12018ab04c3bc3189bcb9356 refs/pull/3188/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3189/head\n0041f7576fa840f9fb516a3b7cc04871c1cdbbfcb67b refs/pull/3190/head\n004138c5c17bba807d3cb7fc4172d1729858cac2653e refs/pull/3191/head\n0041caa52c27598fce1d44a2aed4776f509fe601ff50 refs/pull/3192/head\n00412771f72491c813726d134f78bb187d83f529bc87 refs/pull/3193/head\n0041cbb17a81efc093c3ce6889392e84c6692ac54528 refs/pull/3194/head\n0041881b2f0fcba03a8ead11b10a8448db8e9bd9b941 refs/pull/3196/head\n0041c5245cacd191db3a78975f42525953338a012e0d refs/pull/3197/head\n00417bc13b16667fc68a2ea49b2b0e2b6385fea8cfb5 refs/pull/3198/head\n0041e78ba918f91b4ec532200ee53f1da1659fa5019e refs/pull/3199/head\n003fd46883d4f6bd0de3fa54570e25592d65177a8099 refs/pull/32/head\n0040fcf3222be5f9d8cb2e4bc4789a8ed0ee7f8ecee9 refs/pull/320/head\n0041cfc7fd1e75225069ad5be39c99569b2cf3e5c1f6 refs/pull/3200/head\n0041b8fb33785570b28d9d0a64e1bc639538ad9cc050 refs/pull/3201/head\n004187cc5b2deda1e3a5fda04b5eac4790a056880df8 refs/pull/3202/head\n0041676388f4b2034b023016e2739abc4df86a5689e4 refs/pull/3203/head\n0041da4bd851cd5122ec79be4589066b448a692e51fd refs/pull/3205/head\n00410abfbb2eef7681534c04998e97874e955d576b02 refs/pull/3206/head\n004154e7db1008c998c907d4fa79bdb6efefe65f66c1 refs/pull/3207/head\n0041a8d34ae9a573564b7d0f766365af3de1871138a0 refs/pull/3208/head\n00411d546967bf9468228e4caf8f9918fc59637cea8d refs/pull/3209/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3210/head\n0041b2e2a887e2d9479c2dd947d1e586ee6281e35a91 refs/pull/3211/head\n00415db33ba706ebe24708bce88cc944539381844769 refs/pull/3212/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3213/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3214/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3215/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3216/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3217/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3218/head\n0041d68f6f85e95df5e66154c9354efae427d1f1114b refs/pull/3219/head\n00406c285e160a26c4f006c041d13fd6aa15143b3efe refs/pull/322/head\n0041c67e9e47b64228bba5bede93b3bc8c902365e327 refs/pull/3220/head\n00417a0b72b6d3aa7ecfc94b6ca5c4e43683ad5c42c6 refs/pull/3221/head\n0041a724b82a564701bc4b95821a2f04d36257bf14ab refs/pull/3222/head\n0041f3cc09810b6210e0bdfb4f96c81de2aee8939dee refs/pull/3223/head\n0041feb0ad7c5e6e7b550b125dbfd844a6c62918bed7 refs/pull/3224/head\n0041737b75a44263778aa0254a283c6db7a481629b1f refs/pull/3225/head\n00412c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/pull/3226/head\n00410df532eda1cabd74d7117ed65ba361bf85e9d263 refs/pull/3227/head\n0041436a2e9f9931e797729ec45b13edbb507682526d refs/pull/3228/head\n0041fef018091ec9da5147c7da86c75a4d1af44e21c5 refs/pull/3229/head\n0040d0db8c21ce1b0544a59d3b7b5cbd6aa8bd34a46b refs/pull/323/head\n004171410a54a301ff26d732e7ad4bb4ddff8e564f65 refs/pull/3230/head\n004111775b9a66c24572472b9bf58a7471441cf90482 refs/pull/3231/head\n0041c61acf8038b754fa81c6d0376ff29ea861d91b3d refs/pull/3232/head\n00418b5f88169a1a3476b6eeff3eda03c7f9ec66c17b refs/pull/3233/head\n00414a5591f70bb35c6553d449e7d835881a7e623eb1 refs/pull/3234/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3235/head\n0041af460dd7e6b20eff0011b9eab1f60be9c8355e02 refs/pull/3236/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3237/head\n00416ec64a705e1ea95bf760714bc867be48ee1db93a refs/pull/3238/head\n0041ad6fcfae08211757c8b36d14fdacfe54131f9bcb refs/pull/3239/head\n00403dfa0a0b07889e25c08af41775e6c8edaa3df783 refs/pull/324/head\n0041d27aa3dd1a6c7e66c35ea28acf12819be3cb8d30 refs/pull/3240/head\n00410883a7dfc9425531c544cfa19d8bf7aef21679ad refs/pull/3241/head\n0041f09b7a2d5f0b6cf75d93c73dcc0623ccdd11081d refs/pull/3242/head\n0041cb5ec97318f4e2e71218c8092e796601615660e6 refs/pull/3243/head\n0041c0ab597150b894af31fa84b1ef95135b4dc4387f refs/pull/3244/head\n004134c9f03e1f35d94f37be30c1d551a4721eca6639 refs/pull/3246/head\n0041625bbb79540f688d991c9c17cdc61edcf326d238 refs/pull/3247/head\n00419b4db2f8ffd00b1ce51475978c989d65c4ebbdf4 refs/pull/3248/head\n0041cfc81ae68582be96f901b432b88c715885adf462 refs/pull/3249/head\n00400138593116226511e9fdcfd6eac0830600bc74c9 refs/pull/325/head\n004190ebcbd10d637bc1c41b31ac0b1395f3b18817dc refs/pull/3250/head\n004177dc069ce11a0f4613631b8cac4c0e08287f63db refs/pull/3251/head\n0041be5df1340fe1e722ed96bc1c8d2143f8aa72037f refs/pull/3252/head\n00414d9b3d231594bb3a12d149e0acfe9d052fff0457 refs/pull/3253/head\n00411baf5b1f4e6199d36fd7b6c59d58c638c94227e6 refs/pull/3254/head\n0041dd784206b936de3fb626f985a3c2b913ce4206f4 refs/pull/3255/head\n00412fe04363a8e5ef40c220a24c394c32d14adc57b7 refs/pull/3256/head\n00414def6adce8d6e0dfea61f97f2d2ef30c9519c0f5 refs/pull/3257/head\n0041e78313ca42db27b5c006f09b0f0759b85ea8e24b refs/pull/3258/head\n00411486fe15bcc610f171233cc9583d391588e29ca4 refs/pull/3259/head\n00402a83855d83f6b56f76e63113ed2cc5a82ff7fe15 refs/pull/326/head\n0041cc6198702dc46b2be7751a57aa99b04a574814c2 refs/pull/3260/head\n004112c052a038893bc0929e123f0374241fde5cfea1 refs/pull/3261/head\n0041fa7b9e1dad8947edbe6d4454ea2e75c4e91fe775 refs/pull/3262/head\n0041f2ec4d1c728596f42f5a4df1c482752049b418e3 refs/pull/3264/head\n0041ec50b949ac70d8cc72d648af3d2d6393ad95c3c5 refs/pull/3265/head\n00419aa3fba23fb804cde1e65a1b45fd9f319b3977bc refs/pull/3266/head\n0041eb0dd3c5254fd3880fde0e229659f83907b69ae5 refs/pull/3267/head\n0041738ea0ba90d957d0db64b31048ef6f568cfdd387 refs/pull/3268/head\n00417fc5c0a44b0a2594a637765e3b6439f42c875cf2 refs/pull/3269/head\n004042df6533086ebd31dc513f98362ae1b5d227f9f9 refs/pull/327/head\n004126c131d22b50920b39747af79b6479584caf72f5 refs/pull/3270/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3271/head\n0041678fdd47a634f2c65477b9d8db3919cbd6d8baf5 refs/pull/3272/head\n00416ae5d89cd751708da6774342451710b2102f123f refs/pull/3273/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3274/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3275/head\n0041ef5dac2e2660257c90bfb99b1666624ca783288c refs/pull/3276/head\n004100c1ea1992b1272e41648c5d3ffd46d7f078857b refs/pull/3277/head\n00416dd49087b012e7be82fd3c8722976418cbfabe3a refs/pull/3278/head\n0041305e49c61c765c2814662251e615f96c5bcafbf2 refs/pull/3279/head\n0040bc268eb837250fcb91b113b00f86e0546948b971 refs/pull/328/head\n0041f6897c6fb08e2323e3638b86f7f2453ef7dbdc6b refs/pull/3280/head\n004174f122d6052b7b032e69fe9e37247805b2f1f98b refs/pull/3282/head\n0041308704455f5588ff6c780473875a8636a4e7c7a4 refs/pull/3283/head\n00415e0b2423a0b63fd975d40b255dba2a3ee4804d81 refs/pull/3284/head\n0041fd5e607cb9690a658a89fa4554af258e87ccc38e refs/pull/3285/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3286/head\n0041fb862020d928db7bc4e7c80542154ac4671adf14 refs/pull/3287/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3288/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3289/head\n00409a48ac5465f8ac146f2f3838751b9ff39813568c refs/pull/329/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3290/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3291/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3292/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3293/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3294/head\n004119cb466c0cecb33148aa4eb85570bbd896f0c561 refs/pull/3295/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3296/head\n00411b4ea72e09c0bdb92268c7c75c83b686f947b44a refs/pull/3297/head\n0041fad80248eead0ece21b65c060b7e2848943a5e83 refs/pull/3298/head\n0041d4f0d0ee18cd3a3096a60fd4d43b2336d54bf9c2 refs/pull/3299/head\n00403319fb852d36a0ab98729c8024b8abb8ad08f9be refs/pull/330/head\n00410887c622c076680ee77b94c85c56adbbc439b4e7 refs/pull/3300/head\n004163ba7a9e5a1fd4edfa3b19ac9126eab8279851a2 refs/pull/3301/head\n0041c1fb24440a335ef5d06026d52d9e32b23fc453a6 refs/pull/3302/head\n0041cc6a9946247228c4cee1c08702170f3bf5975846 refs/pull/3303/head\n004140ba224a80e301b396de4aad5b60ab053c149940 refs/pull/3306/head\n00414be1679a9401902c1c6983b95f9b8e439d4a34a8 refs/pull/3307/head\n0041531550e76261d5d68bcbbd14b137e1e10d638c9f refs/pull/3308/head\n0041b60a9a4a1368a55a089161ba073516dde4badc5f refs/pull/3309/head\n004052d3516888f1fde9300fd46ef43c0d35fbdc94f8 refs/pull/331/head\n00415ab57c181a2ff7e50bd569c25829b195d2d11298 refs/pull/3310/head\n004157f3141854c7612cd83ec2b67240b1f669310091 refs/pull/3312/head\n0041230e26b3580c46d5ff761f3172eaccca329d1464 refs/pull/3313/head\n0041a3509d4d1770f70757f11e3c8630b8be58c70024 refs/pull/3314/head\n004129dfbdbdce446cb5a85436f7acbd60d72109dba0 refs/pull/3315/head\n0041b17b1537a266a62983c1217c2bb300a3a6ff021b refs/pull/3316/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3317/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3318/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3319/head\n0040f70db31210bb0973824c06b471a699710c676157 refs/pull/332/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3320/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3321/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3322/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3323/head\n0041b34f6c1b69b1b43d8ad39d084c1cd4fdb61a237a refs/pull/3324/head\n0041e27fa0a3451e233334432f70f0862c58bec109ec refs/pull/3325/head\n004182ce5375e0fbdbdaf6dc82753c3c539ac19d2b38 refs/pull/3326/head\n00415be6dc574b3ae8dc190997146b02668e88eb53e9 refs/pull/3328/head\n00419fb7c07ed5c0aa172fe959e1045400ef89943394 refs/pull/3329/head\n00403e3f7cd474fcd238df1e8a1d85d67a1ab0a52684 refs/pull/333/head\n00410ee8e72bb1e9daf79c6423250853894c8ec3a3e8 refs/pull/3332/head\n00415d04ae469c2c8671d527f9953c4c3e3f1b1db4b9 refs/pull/3333/head\n0041b64830c986d329f3229a4092dc7c7c57d1c22b10 refs/pull/3334/head\n004116faa736187a33564513a188a23ac8ffd0642341 refs/pull/3335/head\n0041ce073adbe1be0dbd75fa58909fd3fb111384a4e9 refs/pull/3336/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3337/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3338/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3339/head\n00401876aad84e6175712758ce6d3db16d7b16ed4eb2 refs/pull/334/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3340/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3341/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3342/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3343/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3344/head\n0041e8baef2938dc547bc29b1629d8026c54f4400a36 refs/pull/3345/head\n0041da1202cebc3b5e248ef67e030e6ab86c458c15c9 refs/pull/3346/head\n004102068f861a1ecb6465e26d91a41e48db32f4f074 refs/pull/3349/head\n0040ffe7d673a10f32d59f1cbb96cbe7465c7b5dfe7d refs/pull/335/head\n0041d3c6c60331c3a2acaccbf200e13784b08786b731 refs/pull/3351/head\n0041100704081c253ff7dcfd7b2757f482d3c70c72be refs/pull/3352/head\n0041e5779f2d437ac22e3e52ead7cdb581ebbaf7545e refs/pull/3354/head\n004163330e4e304834f693186981a5320bfe33f6739b refs/pull/3356/head\n00413a25e5b19cc279ce63271224009a48df52f652d1 refs/pull/3358/head\n0041e26969b39d4e86f7ad3fdf337c5bcb79781d855c refs/pull/3359/head\n0040d2e8a62db572f1e557b85563c10e6468397124e1 refs/pull/336/head\n004145846bcef976b27a6c735ded57520b949143cdbc refs/pull/3360/head\n00410e404bb88ae07b8c0bf36a824ad77e49cd79686d refs/pull/3361/head\n00413592d6a7330432e0eb681ff7f30afe267a4f890e refs/pull/3362/head\n0041329aa16ea10c1bb6841a74f2cb7b7977e3ce3dc0 refs/pull/3363/head\n0041537fc5544be92798c1e691bd7c47b2ae5f49e56e refs/pull/3364/head\n0041fbdd56ed156b1e0fc2b12bc9656575ea63b1c826 refs/pull/3366/head\n0041290d0c8d317e2360ac229e70904433c3a3b62e55 refs/pull/3367/head\n00411e9702f14c9d0ddec4d3fe5dcd39bcacf995ead3 refs/pull/3368/head\n004158dd084bec475b82ca7de636ded933e5f26cd0c7 refs/pull/3369/head\n004001277a6291d8d62f4c8fc93e0bd9781987134261 refs/pull/337/head\n00414713dc20935765b3e4235da556ac6417a94b662b refs/pull/3370/head\n00414fc268c46bf699c0a5712870d826499deeed5e38 refs/pull/3371/head\n0041b339ba208c34d4b2ad57e1c22de799c5e6a3746c refs/pull/3372/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3373/head\n0041cb34e3ba48b46fe73b811c05592ce59d5dabf829 refs/pull/3374/head\n00416bbdc88faff9256f7f674f46502c4c4a133f5574 refs/pull/3375/head\n00411f72669b91743bfbfead637ce673ce0c3fa66bb2 refs/pull/3376/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3377/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3378/head\n0041f1097bd38cdc05ad8227ddd3437765c63cde96fa refs/pull/3379/head\n004052f9b1bf33426893d0bc0fdb1b80e02af46f2753 refs/pull/338/head\n0041c96e1f87f3149962b092855ff074173acb7249fd refs/pull/3380/head\n0041f927345a158fa12008caf386921fd97832ab9e2b refs/pull/3381/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3382/head\n00417d58425a9d987d51e44fd45ab6f80cf1891e1a34 refs/pull/3384/head\n004150c773d60e1fd6c361ada093264c327ea4460ee2 refs/pull/3386/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3387/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3388/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3389/head\n00402b3d0479f0eac553ca8005279c7a6a23a8591853 refs/pull/339/head\n0041ed19906a0de53afca8303ab7610c890f9cdf357a refs/pull/3390/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3391/head\n0041f5640385ee6e8caeb0c743e2adfa6cac33850f79 refs/pull/3392/head\n0041d4217e327b35257c89261a25e3dc237f608bec87 refs/pull/3393/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3394/head\n0041e5fcdc6f1692e4c2c746bc12fd1222f88b0144d2 refs/pull/3395/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3396/head\n00415d08b9c9306f10bd548b1c1adfaa182a3ff91ef0 refs/pull/3399/head\n003f23cc473894a09cc2c4051db85fd3a42e4eac77fe refs/pull/34/head\n0040d6c78da57ab21135f81cb5a2b6656dd9309c327a refs/pull/340/head\n00413fde29aad92d9e308929583d45ad89d0d113c5e4 refs/pull/3401/head\n0041da781cab9cd31cb88ba88bc42fc81f3259d8b20a refs/pull/3402/head\n0041d4a3e93868dd08f590b554d696c8887e45c5f3c9 refs/pull/3403/head\n0041728e7e4ce79ebeed7f96d7738e87edb2978c7b03 refs/pull/3404/head\n0041f4c90854fc692525def222597608a2cc2fdc24f1 refs/pull/3405/head\n0041c021ffa6e9a963843d4ba8509124bfbe0d3dfc66 refs/pull/3406/head\n0041eaf6dd8b3583effa6d2fde0ccb5bd73f07dbb2c7 refs/pull/3407/head\n00411f3bb435119dd7e20a349f90c3cf5371f13eff81 refs/pull/3408/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3409/head\n00401afb1ca14319673e1ea619cefe2f4490ad21ac2e refs/pull/341/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3410/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3411/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3412/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3413/head\n0041e5d49e3fa3a9a948e0ad1f1b86d0c9e188f74020 refs/pull/3414/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3415/head\n00412dcd8bb1efb80b4c7ae9087b304847addde347d3 refs/pull/3416/head\n00419d4287fb3ce00b76e352720ff79f96e9b52b0708 refs/pull/3417/head\n0041bcd17fd0a8bd707f36948c48aa7c9103c04fb9ab refs/pull/3418/head\n0041a49ee397c390dd0882b887c23e12e233bc6cc7cc refs/pull/3419/head\n0040019042773f8f8bfaf2fb18422f6e01caac79b615 refs/pull/342/head\n004141bd9e9857fa71d63de0692007c6ca2255b3aabf refs/pull/3421/head\n0041871f3556ce532a963d5a86f8fd0b232adc25dae0 refs/pull/3422/head\n0041e4505bd80502cad6ba66aafd519606f9472196e0 refs/pull/3423/head\n0041cce01256cfbf0f3f395b8d96d484494197196d5d refs/pull/3424/head\n0041dcc3c7ccbf0a1fbb9817a198b4cdc9d62b09168d refs/pull/3425/head\n0041caa0afee00abbc05076d0f52783b7a34310f6f12 refs/pull/3427/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3428/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3429/head\n004083dd27f424abf0abba6a8264fa6924a41c15ec49 refs/pull/343/head\n00417a83a2b622d023fe05a727df97a4b527dbff8eca refs/pull/3430/head\n0041a7701505c0a51e6de0f4c78c1a02f663a727fe28 refs/pull/3432/head\n0041981b8c04c17f2a63d951df37194bdf4817177e6e refs/pull/3433/head\n0041d4390a458767271df36f6ab90c99af6e363268c4 refs/pull/3434/head\n0041bc032d76b0adff18fed5e058e1eef6de3c82286a refs/pull/3435/head\n0041ae608171cee97acbc163c19693951a231a2d4e06 refs/pull/3436/head\n00414e9f15e375eb118fbc7456f1ce75b7fdea960384 refs/pull/3437/head\n0041e79e37c87d28e153d552dfbc93f73111d0a18bc9 refs/pull/3438/head\n0041923f59093eced8ddc607c93353be0014ee88a6ff refs/pull/3439/head\n0040c3ccd3c6e811b6d15026b5cf1853a2f663001a60 refs/pull/344/head\n0041598407dc758dc60d193726d7db5399c4719fd952 refs/pull/3440/head\n00413741e5c083341432c3899d00d93ef84cf7f469de refs/pull/3441/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3442/head\n004154ef244af43a6711eb694021cb81efd25862a095 refs/pull/3443/head\n00417734f6dd3b776a0698e7b32256ca39f57d3078c1 refs/pull/3444/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3445/head\n00416627b1e2424961a3a38ba09e56f1887d7e5b993a refs/pull/3446/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3447/head\n00417f6aa8bf0de045b86129d4228ddfc99bd290af7f refs/pull/3448/head\n004175ebcd5084088481a531a5fa2cb4c0f8c4399942 refs/pull/3449/head\n004004d296631f37bc5d0e2c626fbd73f96427fdb0be refs/pull/345/head\n00416614652415913dd558a7f5e1760f6adac91058d1 refs/pull/3450/head\n0041a30243991efe7657d72e09cdefa0bca512a26a4b refs/pull/3455/head\n0041d613d3081e40ff0a2605553d6df587ed7750f26b refs/pull/3456/head\n00419202976cb63fe40fc20514a9c33f47096cbf4009 refs/pull/3457/head\n0041e1ec445951d86ecc1e953de48d0fbd89c35c351f refs/pull/3458/head\n0040987aa1508bf8d1de2f3dcf2fd010d87e126bb8db refs/pull/346/head\n0041abea6c5f85068528fa575eb4eb756b2ac0e8e92a refs/pull/3461/head\n0041e463b25713c5ada97bc7c09bbc644d8eb35926e9 refs/pull/3462/head\n00418f517991d1cb5e0b703a99e9f5f0356e96fd2b68 refs/pull/3464/head\n0041b341b5aa46fe4c33d29588397dd1bdee9d463b46 refs/pull/3465/head\n0041f44bd5c565c936007b9b937f27db82baedd64b9b refs/pull/3466/head\n004126fcc9f16b76b0925319f6554c6a6aef3b956cfd refs/pull/3467/head\n0041ad902ce2ae444857ba5af2a0575b4023e8694b64 refs/pull/3468/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3469/head\n00405450274ef3e558455c66ada108a0452e4843fdfc refs/pull/347/head\n00417c267cb058520f9d80c081ad44a4ce2864cd7019 refs/pull/3470/head\n00417b2fe16362dd063b59fac2c40d3f28948fbada9f refs/pull/3471/head\n004165252dfc054e98eadf8764745dfc034de989d49e refs/pull/3472/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3473/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3474/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3475/head\n0041cf1931c7276150ed36a4d8e11fd219a5cdc7b181 refs/pull/3476/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3477/head\n0041fc9be78fa0069be51b4cdc434bb06a02cc9a00ca refs/pull/3479/head\n0040bc92b86da455b69be1bd3916273645b337674ca2 refs/pull/348/head\n004138adfc481554517cb4adc7b370e3c231c33132eb refs/pull/3480/head\n004167cc7e37a710e3ea05a75374a506c04c87a89a34 refs/pull/3481/head\n0041603dcca4481fb9e1778f6e81ad048ae73320e30c refs/pull/3482/head\n00413e4197bb97686b43986c05d2e58481bf6280cff9 refs/pull/3483/head\n0041d5715a6a3be4943c0f09eeed95477e21546cf37c refs/pull/3484/head\n00412fc3db5c428f3c2ed1f1d53a6d32eb310ea7a469 refs/pull/3485/head\n0041eb8f7da07c8988a4685f699bc3ad3079b6e5fee6 refs/pull/3486/head\n0041f115d5d4d4655a1f132ea5b50dd2606e8698f8cf refs/pull/3487/head\n004152c3e0913ea564c9528adcd2e5bfb4fa84ba8556 refs/pull/3488/head\n00418c3c4edcb7e294421aba9759fdb033faeb61a5a0 refs/pull/3489/head\n0040df9c85159194003ea1f55d088052eeb60746823e refs/pull/349/head\n0041662b7d2a0f214e1da0510968fdf458c93d225809 refs/pull/3491/head\n004131420ee602fe6de115e4cf32b4dea4d20c37ef92 refs/pull/3493/head\n0041dbf993097c75276c397af40c80a17ab0a85750bf refs/pull/3494/head\n0041b0b0db1b990ace1dcd6a0775fcfe8c03e1c2e98b refs/pull/3495/head\n00419cf8a2f26e3bbf477b68032e0969d08bed9cdcdb refs/pull/3496/head\n0041a886341b602a3cc8278121ab40882b39cd94eb5f refs/pull/3497/head\n00413c0b52d09cb1dc44632bf9009ca51e1409066af0 refs/pull/3499/head\n003f9a6fd6cac6cf82aa4dccfdce615dfecbc76dd28a refs/pull/35/head\n00400454bf6ec1c4e9422765b5f3fbaaffdf15176979 refs/pull/350/head\n00419a6ce09da4d08d9eb8f59f0440c3758234d19e51 refs/pull/3500/head\n0041c546db9b641c145360de3e14ac12d48dbbb6581a refs/pull/3501/head\n00412dc4cfb9803f2aa927953e33bc1f40c3dab44156 refs/pull/3502/head\n00413a11c7356b0077c7c73c2143c05384cea89fae31 refs/pull/3503/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3504/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3505/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3506/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3507/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3508/head\n00419a567192f4142f72d8c0c9c0dfca059c314218d9 refs/pull/3509/head\n00400c699e9bf5b682c91f3bc11a35edf88d6667fa02 refs/pull/351/head\n0041a5c7c58c9c454b44c22238ef04ee3d620487d3c0 refs/pull/3510/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3511/head\n00414100e0af9f9bb6b8326aaa8c56b8ca4217bb5671 refs/pull/3512/head\n00417d9e4c951de40d4d2f4ca5056942b16672711b54 refs/pull/3516/head\n004067eef7352339ed2507d2bac858c9812ac4e046a4 refs/pull/352/head\n004112d4ccf73cafb1c17904c65fc54926d4fc0d2667 refs/pull/3520/head\n0041facd4046a0d547318694a68d1998be9df873a9b8 refs/pull/3524/head\n0041347fc8d5550965e6fbddbe63fd2c6a6af006d694 refs/pull/3526/head\n0041558f36467459b7a7e59af1069dd04a95d628a024 refs/pull/3527/head\n0040cf0c8367e746b2a1ae1a42202ebf11694a5a604e refs/pull/353/head\n00415d50028a97df7729d9a73878bab12a732a4b5438 refs/pull/3531/head\n0041412a32512c3b2888af0d26d8ac77fbedba6b738c refs/pull/3532/head\n0041726d98b08d7796dac5bedd4b9d34202fb4164ae4 refs/pull/3533/head\n0041434abc547f8f844b62c9abea8636adf414ce99b7 refs/pull/3534/head\n00418ec89391bdd972f05bf74daea3bfc5938a8fb2a2 refs/pull/3535/head\n00412aaae4a493ffd4d0af0bb0969c1c876a630e7bdd refs/pull/3536/head\n004126ff86f1c04993f6c36bcfc92edbeee015e189fa refs/pull/3537/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3538/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3539/head\n0040d4e3672671d311513e0efa9afe6c323a661a1e03 refs/pull/354/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3540/head\n00410230d614aea5f85d892fee98dc11ccb917837244 refs/pull/3541/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3542/head\n00411e9b862819e5a01ab7a65c5863c19adc0fbb06a6 refs/pull/3543/head\n0041535d8e0f999d37b0410574258f07fbf1a24d648e refs/pull/3544/head\n004196a3b49d5bbd0b7a6fa8e2b8a7febee215df2bb6 refs/pull/3545/head\n0041ba980971b276451472973c91d8a3599f06d2a790 refs/pull/3546/head\n00414e1501dade292549592c52d957e4fce0b164f5f7 refs/pull/3548/head\n004111556ddafbc6008583a1f421910dae8ad99c6c64 refs/pull/3549/head\n0040600ed28b6bf05e4800518d4299ba993a3de128d5 refs/pull/355/head\n0041fbf37fba1a9c93fa1cde4816d4c2e83de789764e refs/pull/3552/head\n004152880b04b157686ac203e6d1e05553c1554de526 refs/pull/3554/head\n0041a3ff783b82a73d9e590c130ee585935e3c47839c refs/pull/3556/head\n0041f8649f35c73ef8b68b8395b084419c74b1ec13d6 refs/pull/3558/head\n0041ddcd86bcc2937a1ed44480188e648d748253ff7d refs/pull/3559/head\n0040cf1cbc2950c195040601ce36ddb4314e94288711 refs/pull/356/head\n0041b4fe9a998fdb7e9682ea2a112d46b1f7fd1d83b7 refs/pull/3560/head\n004122ae49a865e503352cf40255938e94fc55ca1264 refs/pull/3561/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3562/head\n00411a9e9ab5f77adfee6997e35a99578456af18adff refs/pull/3563/head\n00419f411fd43ad96bcea3b00c2b6b09ba133ad970d6 refs/pull/3564/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3565/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3566/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3567/head\n004137c352279ece36826e0bf6cb7fe474144dbbd03d refs/pull/3568/head\n0041b01ff6cf71861f5b59b406b3b083a6a81cd5b05b refs/pull/3569/head\n004009a3d6def73568852ef4ae16bc83b5dc08bec29a refs/pull/357/head\n00412ef434da9cae143bbd52efd063c07c2365bee95a refs/pull/3570/head\n0041041b7702963bc077080c447a6b2156f5ad54761e refs/pull/3572/head\n0041f32b12df3a4a65424fe1d7656304bdc0d765d0ef refs/pull/3574/head\n0041e60e677527cd031f039fdd2d77859ae42d855f1f refs/pull/3575/head\n00412efaa9bc8c6e2a97f5bfbb231018d4c0f7d32c18 refs/pull/3576/head\n0041f91a700e72fa0ff87d505a5b0d742a32e2bfc666 refs/pull/3577/head\n0041e4969f8cbaef6577d8fdf43bb4cc80bce1dd7fb9 refs/pull/3578/head\n0041dbaa13a50bd43863dfaeaa1a2ba21528abb5d89f refs/pull/3579/head\n0040e933914511cafc5fdfb749ea7b07816fc675706c refs/pull/358/head\n0041aeece857dc9f9b33d18cd90c5c213dfaecb82698 refs/pull/3580/head\n0041e6d34f9b331c5297642565e4ec463d6a001da9f1 refs/pull/3581/head\n00415e1fa71582e8ba6d804ee07c82d1e635ad7a392e refs/pull/3583/head\n004165211f2f09f58fa9453af0005c7ed8d4e43bb67a refs/pull/3584/head\n0041d099eb9a6608a5d0d2aec966f32c467e68604c66 refs/pull/3585/head\n004134589f34e009247cb2eb2d249e57d78a59deaed6 refs/pull/3586/head\n004106a28e3bc4144959441b736e5bb62eacb1f817b1 refs/pull/3587/head\n0040b0d113e1de8d5dea0dad2ba0b112b7a6d7b749e8 refs/pull/359/head\n0041aa9e18358bf55c15e614ebb8ee2741a2f9996048 refs/pull/3590/head\n00414d8f4319eaf3a2634e5aab04ac0ccb706cac6f8a refs/pull/3591/head\n0041cb57473c8df0ff9684a1d88085273ccc71b32be0 refs/pull/3592/head\n0041ed2f8d86aeb2b877ad6e7c5d991a666540212ddf refs/pull/3593/head\n0041139c04ef65a5f7448c76b9ebc2020800570220d3 refs/pull/3594/head\n0041c1aacde188e95d078d945071c89474260f0864dd refs/pull/3595/head\n004116d1ab16fa4d100b903533361c6a34ceb5f4391e refs/pull/3596/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3597/head\n00411c4fe17a54b97737f3671ecaf56bb077f88b9239 refs/pull/3598/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3599/head\n003f33e3ad75825b38db5a4425df6d65e40410a5e9ca refs/pull/36/head\n0040e8f98b0a685b0579043ce7d7c161cf483b71f995 refs/pull/360/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3600/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3601/head\n004117c7f0f8ab0de4cfe8b087a4af2304b9ce86f62a refs/pull/3602/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3603/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3604/head\n00413439bbfaab349c59b0854a9cdcbfb23f46c9ed52 refs/pull/3605/head\n0041d540c1269b98ecede35df9fde66096ba1d9d3072 refs/pull/3606/head\n004133e45f96dcca0bf4978db082599db2a416eb0137 refs/pull/3607/head\n0041f3d15b6378921646c65c17c99bb9c4d5826cf5d8 refs/pull/3608/head\n00413fdf840caa2a15aa1b02ad63edbe37f14c25ad04 refs/pull/3609/head\n0040af341b4f22bbdac128322f76b48e07c31dfdca46 refs/pull/361/head\n00410d61d36d5457e56436939c609274a27d6a3d5939 refs/pull/3610/head\n0041c57018380ecb4a8c65a50a43146b1cd220d14140 refs/pull/3612/head\n0041cfed10e5cd77ce191ed85b3aa1879ffcf78ddedf refs/pull/3614/head\n00410e5894deb3711d7ae9d9e1efd62fb3fe718cb00a refs/pull/3615/head\n00416dcc20d5233ea2bdbf24637ab5a3d25e80bf6dcd refs/pull/3616/head\n00411fef6d381571733672f63d65bf555b9801186548 refs/pull/3617/head\n004182e4be020c85e0982b63537075ce4d44d0475dd6 refs/pull/3618/head\n0041356b68503584e33daed2cab24178a20c4d4cbf3a refs/pull/3619/head\n00406a801c7d85ede5c49881e53c45286e78dbf216bf refs/pull/362/head\n00410b26184e36cd97559ecefeffa099217136cf494f refs/pull/3620/head\n004164d1e66d5ad7e27d0fd38c49e0487e5b029b9639 refs/pull/3621/head\n0041758d6def407fe5258665f3b621081171459f9371 refs/pull/3622/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3623/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3624/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3625/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3626/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3627/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3628/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3629/head\n004064cf6dd540ef6a175e26345cde4fc09f98458764 refs/pull/363/head\n00410b3780de33f8385775e0cb2b24a45bbac5824b12 refs/pull/3630/head\n00415e7f9c92ccfed0ca84a87dc0fd1dd8bf962a81b8 refs/pull/3631/head\n00413766f886f09b0e05c216deec1fca932704faef3f refs/pull/3635/head\n0041020ded73f3db4649327aeda027020a2e37640356 refs/pull/3636/head\n0041378236c3105538906a4258009a87f9a14684f304 refs/pull/3637/head\n004135f6f9c3529b0a143bd93b9ee2d1e8258c2c066a refs/pull/3638/head\n0040cb0bde56c77838a7582b88c6d5e9150d2964e1d6 refs/pull/364/head\n0041cb9695fabc8adcaeb8c2abe4af71e0b916e053e7 refs/pull/3640/head\n004103fa215005ceb3bf5d0feea91a3968e90aa446bd refs/pull/3641/head\n00413f23a4b8dcbcdd6c1fbd8c2adb4a23a0a4ebdb2b refs/pull/3642/head\n0041607063a14d4aaadd1b5670e757b277110a979e97 refs/pull/3643/head\n0041570126ce462da1d39ccb24cac7ce605ff38ca3a9 refs/pull/3644/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3645/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3646/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3647/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3648/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3649/head\n00404b9a948506a09bcb0af3f4a7d34320fcc41cc23b refs/pull/365/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3650/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3651/head\n00416342cfdeb589742ed13452978cccf8e01a318f38 refs/pull/3652/head\n0041cd4ab0e55a184704b00276f26165570ff9ec1444 refs/pull/3653/head\n0041abf79a0cd8df5dd3696d268e9cd102047e1f17aa refs/pull/3654/head\n0041dd56685ca2a38e46298b6d0d2b80736d91d55733 refs/pull/3655/head\n00410ea8372305c0ffbe8c1b7461c480709b51584dcb refs/pull/3656/head\n00419ab03f8dcadf83eb43ddc1d53fcb6777afba2a23 refs/pull/3657/head\n004109a4a53bb0be24011dcecffcc786774e71a2438c refs/pull/3659/head\n00404ebe16b3e179d11c7345ab7e0b5ec7aa262ba9cf refs/pull/366/head\n00418ab8d6ce8416b09773a68b75c3417effe07e0e2b refs/pull/3660/head\n004150188606b6e0c69235544879d1949ceb6d2f7916 refs/pull/3663/head\n0041197e36d47a279ab508c1ca69df636bf0ab04a85c refs/pull/3664/head\n00418994e2c8916d64c554c0d1bd4fddfb3fa86e6037 refs/pull/3665/head\n004197da23582340f68c0e3c4a10331ef3f2dd1d3746 refs/pull/3667/head\n0041e725769a9d44441d3d3b97ea119b5ccc0ec13242 refs/pull/3669/head\n00400f88251f8707640498665ed86b3493288ea44b86 refs/pull/367/head\n0041b129a3fae3f0969918714b600439e83e0f20ad74 refs/pull/3670/head\n0041f9320da0df7f2bc55d6dbac11a195963042aca5e refs/pull/3672/head\n00413a22d2708c6f65fbbb7c396b34d0fb5744ce139a refs/pull/3673/head\n004122f50cd7fff2333b32434e33a4be35d016c8507b refs/pull/3676/head\n00412398aa1e760b6e19934397cf58f8317182a732f5 refs/pull/3677/head\n00413ce3d4adc1cf1cbc99e39de8af86157529b5c96c refs/pull/3678/head\n0041898f7603b40285901c4193006caf5a1a7f865a24 refs/pull/3679/head\n0040daec0467ba809add8287e6e561b207570dfdef9d refs/pull/368/head\n004126482c89d1eef651e3074870a21e691d3ee7d88f refs/pull/3680/head\n0041724e6ba210e3a3e558c8546a64a3b05b88dab32d refs/pull/3681/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3682/head\n0041ca808fc591679ef553b9c217a67b483486ef954d refs/pull/3683/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3684/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3685/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3686/head\n004192d2564fd9ba300f6cbc8186d9948bef96bef29c refs/pull/3687/head\n0041ab3ffa1f942b62e296bf81d1e2f64b750204812f refs/pull/3688/head\n0041f102174f88e790da42947faa3b33b9fbac9c1ad7 refs/pull/3689/head\n00407e2c699fd73e14c445f1302ff24bed0a2556868c refs/pull/369/head\n0041698bffcf6b2e1ee981b74dc56598868c5f0d7690 refs/pull/3690/head\n0041841cf111e57718587a569e44acd3ecf89c2431ec refs/pull/3691/head\n00410af2a89e704fe8fc0c412d3e80c3161b6612c15e refs/pull/3692/head\n0041b86027ff3908261449d64b340f0562c36fb28c50 refs/pull/3693/head\n0041b68d03098b2cfb5be6f7171821194ae555c57dd6 refs/pull/3694/head\n0041bec32d612cfbebce1fcecab7ab2e2dc2bf2c7c83 refs/pull/3695/head\n0041fd0757a0397b6cb2f35aafa75777e02a2aba4b9f refs/pull/3696/head\n0041800efdc97f592673fb325a2e26d62ebdf9f74cbf refs/pull/3697/head\n003ff8f6f58700a542f06d0796bf7d26e6f39718d2d2 refs/pull/37/head\n00403c7cf0dd53c10c2fe43373d5d9e8e09ae9bd3038 refs/pull/370/head\n0041e1ec6f4b87f2c83cf0e569433e92a8b009628b99 refs/pull/3700/head\n0041f9f04b471d186f3269a369eca5ffdab734712eb8 refs/pull/3701/head\n00419597c2daf3838fc16fef732ecd9632e601a004c0 refs/pull/3702/head\n0041a54d68436594c8f418fe7be303d712fcbca76d6e refs/pull/3703/head\n0041814d0792d0046857c1b85ff003d923ce1a4cd761 refs/pull/3704/head\n00412dc6e2a77115edf0ca1f2c7ab2f49b078a5f1f92 refs/pull/3705/head\n004166588e57a6ea366b52febf704b1cc351733e4877 refs/pull/3706/head\n0041a36e364f26ce84a0e07e5bb332dfb6b5d8aaa15a refs/pull/3707/head\n0041620e4bf3d867ebcabdebf4162454d74b06606cd3 refs/pull/3708/head\n00417e8178e30d045e5c8124f618c7c00c08ae1bef3f refs/pull/3709/head\n0040ffcf21f54d8b285eb6aeda1824f3ce90d85fbb3b refs/pull/371/head\n0041fdbdaac9b6d0d67f4e6be5ff17d050dadd957b7e refs/pull/3710/head\n004130297ce4dc62464257ce8f09ba573b9c640a5231 refs/pull/3711/head\n004142a624e0a7acd08547e6ff56f4f7107813463f1b refs/pull/3712/head\n0041c6bb013d0ea2fdd57991b3a87f19ef9713cfa73d refs/pull/3713/head\n00411218898f514d73f9abfaaab3947d799700505a5b refs/pull/3714/head\n0041be76196e8a5c0e6bd0f72c96f193ef655ead9f71 refs/pull/3715/head\n004108fc364d0764d379a956cf1e43269fd97a66202d refs/pull/3716/head\n0041cca07dfb64d644e87ca2a5ed32f22b8a20d96d8e refs/pull/3717/head\n00413a9f1033e39c8f0005f0711a6b6d3e20bd2870bb refs/pull/3718/head\n0041479d99c266d278e38b4183b2b8b9b2ed0f915fc9 refs/pull/3719/head\n0040ad8ecd3b9bee94d51170382b695f0c778a497bfc refs/pull/372/head\n0041b50d321af176b7c7ff6f429cdb77ad6347705c92 refs/pull/3721/head\n00414eaebf897d134d4eb55906bd26a8a4fa485d45ad refs/pull/3723/head\n00417be13b4869c605fe75ce5bded034a1202116e181 refs/pull/3724/head\n0041a7d4cc11edbdc202607e20681e145ce817efd75b refs/pull/3725/head\n004157c67490141d8faa757dfe25def9470ae574c5d3 refs/pull/3727/head\n0041d1de8f55d10a6161e7c42302c02d8d5d2b32cbc6 refs/pull/3728/head\n0041a070a57f1e6fc95ed5d90f34caa3e1825e93b9ef refs/pull/3729/head\n0040a54c525503c36c4120616451e4083bc0214b4ee2 refs/pull/373/head\n0041427b1940b2eb7a5c4783ffa406ff222352ac352a refs/pull/3730/head\n0041876e71218100d13ec9523b1b69b6741bc19e2240 refs/pull/3731/head\n00412b7235d7fd906bb9205d56b04ff19a41e8e3f624 refs/pull/3732/head\n004126c49d4fdb759869ef05b834909a45235c1cbfb6 refs/pull/3733/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3734/head\n00419fb657062b28459e967e6aa9f71b8f5eb1d96613 refs/pull/3735/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3736/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3737/head\n00411042a986854b32d67c047bed251d244383c7f445 refs/pull/3738/head\n004156936b4e650d78b6d44ad24011e781acc50df49c refs/pull/3739/head\n00400c42f8686a7cbd215a8f24817d7de1355df77b1c refs/pull/374/head\n004134cba88931b0c0c9ececda69f6bd56f0ee6132da refs/pull/3740/head\n0041cbeb2bc56e40e89d5d7ed57e73442cb8bc08f033 refs/pull/3741/head\n0041be8f03fb6ff6b368a1b316fe49c2604d8048a878 refs/pull/3742/head\n0041ce0ffaafdcfb9f398fac96394c97f5829f8e64db refs/pull/3743/head\n0041a4de75be38efabd02ec21bb954dcf0d06c383974 refs/pull/3744/head\n004155cadb9f3ddb2181250be8240042556e2aa0accb refs/pull/3746/head\n0041a419f67ff567f18441090d5c27f9fc43f6a8f85e refs/pull/3747/head\n00404b20f8036316a58b61a3eea85afea53cb054bd66 refs/pull/375/head\n0041808af80abe8cb7ef26d5df2c5f14589079967775 refs/pull/3753/head\n00412a4d23c27ad4f3586be87b4b749997a1ecd1b722 refs/pull/3754/head\n0041bec788f16f4be311ac5a4fb1dca48b22020d23d5 refs/pull/3755/head\n0041ad0ddd181dee7c3c2cb1db63b403e7ce9463b411 refs/pull/3756/head\n0041bbc7ca771fb0476a6a4c09f08f90934ce416847b refs/pull/3757/head\n0041464de6c8e3d3b6a544e6a1dfffce2613cd53e4b9 refs/pull/3758/head\n00415b655fe17e896c43f2b28b027217dbd4ee0c7274 refs/pull/3759/head\n0040df92eca6a3262981465ab6e7c100e740a9a5a613 refs/pull/376/head\n004178e8dc574cdd5f9a11e78ebb241e70bde1f10276 refs/pull/3760/head\n004134f398b12b84f860e1078087b5833fb7c1d9f6c7 refs/pull/3761/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3762/head\n00419fb657062b28459e967e6aa9f71b8f5eb1d96613 refs/pull/3763/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3764/head\n00411042a986854b32d67c047bed251d244383c7f445 refs/pull/3765/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3766/head\n0041efe77a86820dd9207412b620fccaef9a716266c0 refs/pull/3767/head\n00415e884e371f05bd80acc4753bb64f826c9bf0c0eb refs/pull/3768/head\n00418daf095a835d28885c16f80f48ab29fabcf2a2d6 refs/pull/3769/head\n0040f5dc20b5d4e4fdf4699840a9bd90ccb6b51542d1 refs/pull/377/head\n0041c2c3b68c6af8ad24f45ce5f35fd3e668ef875c8a refs/pull/3770/head\n00414c283dcbba2a55d0566dfb0a749c0319d8ed5ab8 refs/pull/3771/head\n00418e02e2a9e26af982757ba77bff6f10a61f7b1014 refs/pull/3772/head\n00416e019a2b1169347fc8dad0186e207ac29b57d2ac refs/pull/3773/head\n0041b20cabba84eccb72f769c4da172b9275954bc48b refs/pull/3774/head\n0041b5c42bf8102749ba0f8c43170d11bb30ff19fa8b refs/pull/3775/head\n0041c071914470ae062055c25063050ac61fa77c78d9 refs/pull/3776/head\n0041367660326d80a888842f024118a744e07dbcbda7 refs/pull/3777/head\n0041ee216c0c3db6c068d6fcbcd24298ecdccc766157 refs/pull/3778/head\n0041a73b92f393b8273525970e8e20876b2e9bbafdc6 refs/pull/3779/head\n0040125473272cfe458154e9eb689d9263df394d3086 refs/pull/378/head\n0041276a8ef346cc1169411063ccca224af1d5f3d039 refs/pull/3781/head\n00415676afc7b4a082a7436b7933d2124b88714aa01e refs/pull/3782/head\n004106c4c8650ec6c8eaa6a2fe5956a0e50319b233bc refs/pull/3783/head\n00419dcb8720303c7b6abca6e90867e9c291e3848ba0 refs/pull/3784/head\n00419a31697635c011fd0551c068c403df15d53f8560 refs/pull/3785/head\n004178486fdd63d322cc138b4388a5ad8f266e4ba70c refs/pull/3788/head\n0041effb851f141dcf53f1a332fc3596613761b67c38 refs/pull/3789/head\n0040df8ab034cb5eaddea0415ae9953a6165ecc60549 refs/pull/379/head\n0041204f591530550e4dc88157b9fa3ca8070944cb24 refs/pull/3790/head\n0041c6d02d3781794b908ffc84d27b2f40af07122447 refs/pull/3791/head\n00416d9b9c54be33f1a46e375748b214745c59b0f875 refs/pull/3792/head\n004119350d09e9014b6bdfd955c857e76a9090041667 refs/pull/3793/head\n0041933b0606acdcbdc77e1148cf52b6983208d4cc9a refs/pull/3794/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3795/head\n0041e01dfe987e705ccbe116d3d752c0b1a241f5e760 refs/pull/3796/head\n00410c138fb8a7ec3426340896578d6a965f0e807ff3 refs/pull/3797/head\n0041701ac77c292eeea0e137b37b387a2fa8bc2f641a refs/pull/3798/head\n004142f2e2159fad8dba95888968c6db02124acb0e3f refs/pull/3799/head\n003fa72f79c5064d756b3b1883dda9744549657b333f refs/pull/38/head\n004105e8c4940436783b38d6366b8e953065ac834743 refs/pull/3800/head\n0041ee5a4107f7579d54a78b6361c376e03ac8bfba65 refs/pull/3801/head\n004195238ab119dc3f0e7f1257cc577c89ce7ff9b8b8 refs/pull/3802/head\n004188b849233ee8a636efb68bd65a58f36d29f59e79 refs/pull/3803/head\n0041a6cc50067eb9f7d1d4dd954e527aea508f96c4a9 refs/pull/3804/head\n0041c082e78b164f5823bda75a885301ebdc29a451b9 refs/pull/3805/head\n0041b7021ad3cdbc20907dfe421c86f5f5c991385757 refs/pull/3806/head\n0041061b4527d6bc79e7bf01db1058367b05fe277ab2 refs/pull/3808/head\n0041fb1b7370554c69d44b2ee316a501b460a42a44a8 refs/pull/3809/head\n0041e6e89dd4def50443728ba0425f6098a1e5deca1d refs/pull/3810/head\n004169bb4706258809d92805bcc8034afaab6f7e835e refs/pull/3811/head\n00416a9ed3f31e4927858ea4442ba03491109141a8d2 refs/pull/3813/head\n0041ab836a2f7d8439c87ff40604d8aec5ccaacea7ff refs/pull/3814/head\n0041a9194146c8609d6920361fc66d8ba210a777d65c refs/pull/3815/head\n0041811704ec2f3e4389e8606ece5164dffe32e2a6d3 refs/pull/3817/head\n004174f80ea6be12fe99689eea2472f3feb856fdf1fc refs/pull/3818/head\n0041500443a63b436a12be0e9e1e1c607364eff7f915 refs/pull/3819/head\n0041af64a7c4b96efb3dcaa6d1f5f752b68618453d4f refs/pull/3820/head\n0041d8aaec90e7842479f914b02f56c2711c3b8ff26c refs/pull/3821/head\n0041ca8b4f650897b7403854a651f7a1afeb065fc9e0 refs/pull/3822/head\n004155fb452b42fcd62fd74e662b60095268eae0b940 refs/pull/3823/head\n0041736e3be9329039344741aa74e15a58c318d640f7 refs/pull/3824/head\n00416e26cae18223607f3c2e1811f9f1e67b615dec57 refs/pull/3825/head\n0041e16bf45404fa2e1dcd1737ddb9274bf0dd7e0170 refs/pull/3826/head\n0041d0305ef55d2ff53ea2d066f859814aa2700d7f61 refs/pull/3827/head\n004147d383ffd9944c8cf2ccdd11faf5d440975bea62 refs/pull/3829/head\n00403d26b83e2b4423e91f1878eebb5320712e41cce0 refs/pull/383/head\n004188a65eab60d0f918387708a02e5570de0fc6f7f2 refs/pull/3831/head\n00416bb5605d423259d74e71277fe6f836c87de19846 refs/pull/3832/head\n0041d6f5a96c2096f5e1a70bb4aa582f04fc2d9e82b0 refs/pull/3833/head\n0041f6e9e6e03bba10e4d6780f887307612bc67e1d19 refs/pull/3834/head\n00417195d59fe61b182337f640f9368499d391563bbd refs/pull/3835/head\n0041102f90641b9f6ae36039c7c906609d7d4d9054eb refs/pull/3836/head\n0041c704d63d927519bf34b55325eeb8835d6f789f12 refs/pull/3837/head\n0041614c8e36612b5c92942389799d689a9139aea991 refs/pull/3838/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3839/head\n0040b5b94b399d091ef348eea50af8166632d491f2e4 refs/pull/384/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3840/head\n0041a1a28653323cf3a20cd24667d82c9103fd2a84d0 refs/pull/3841/head\n0041fe05aea385a0ddb93295dff0a77175b82180002b refs/pull/3842/head\n0041db530e4e3c8c851ecad3737337d6db4231cb90e1 refs/pull/3843/head\n00412cba1ca28e2faa75750b291f35db95b269f43fcc refs/pull/3844/head\n0041e3ceaa0b5995ed5af4d2bfc6643f17ad805dea8d refs/pull/3845/head\n00413d63b91177fbeeb521d2203307d2817a6be4c28d refs/pull/3846/head\n0041c63547e6e0bdea773127e2083ce16b215c9d0b61 refs/pull/3848/head\n0040f29693a20e63c75d1185ffe3852d5e05200365f9 refs/pull/385/head\n0041eb80e7a9797b8dd45bd50629942669eb3729b3e7 refs/pull/3851/head\n0041cc49d6896ba8f3ed5a8c5a565e3299fe0d39de28 refs/pull/3852/head\n0041af545ab7517d7f9cfd328e5518351217d06fb0ae refs/pull/3853/head\n00414cdb3a83045d241c6abfd6cc8b67c10493993198 refs/pull/3854/head\n0041d90baf84c2ef89cb16ef27bb8574d92c8f295827 refs/pull/3855/head\n00418cc18a6eaa952502f4ba7b3d9c11025b5b3a8512 refs/pull/3856/head\n0041b2c769a43c127a4ad3a301ce384fc24e76ac378c refs/pull/3857/head\n004150850b1951c108a17bc0db9c312895ded1dd1183 refs/pull/3858/head\n0040b7ef5869c878e43bba7533aa9b40988445c0bb5e refs/pull/386/head\n00415dd1a02a0e4c8ae3215fc09fa4b54aedb0a14eb2 refs/pull/3860/head\n004111362ca89eb07304d63e8225b4fd3e6c9ae0eb78 refs/pull/3861/head\n00417363ff427c719760a4de92b34b548a3a3d8071bd refs/pull/3862/head\n0041f85ba9a74db5729a8c8355ab1b00c68a881185da refs/pull/3863/head\n00411bee5f5f6b97914149e58e36bde8190259dc4792 refs/pull/3864/head\n004179e4032f8ffa02840fece03311c4f49ac1e7295d refs/pull/3865/head\n00411c3ff7ed39a9ee2e3b9978c412788944e94a8fb6 refs/pull/3866/head\n00412c0029bf5574f0ac36ca6cebddba1dc753a2be72 refs/pull/3867/head\n0041ff5a5cace93eca7955893492eefb5a51f295c76f refs/pull/3868/head\n004150ebaeb597549b5551f62a71cc860ca12661e700 refs/pull/3869/head\n0041759f43e9479c5207c92d3070f1647113274725ba refs/pull/3870/head\n004187a1e51128efdb8f1341d53e041431e23fd023bd refs/pull/3871/head\n0041b750dddb72d686afd2d5a3efde0ca11de99e5d89 refs/pull/3872/head\n0041cb8653f0ace7cda384f2b2dbda709bce57430e03 refs/pull/3873/head\n0041102f90641b9f6ae36039c7c906609d7d4d9054eb refs/pull/3874/head\n00417c8f0cb2c18cb6993786dc3d47b7e86258a962ec refs/pull/3875/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3876/head\n0041fe05aea385a0ddb93295dff0a77175b82180002b refs/pull/3877/head\n0041e3ceaa0b5995ed5af4d2bfc6643f17ad805dea8d refs/pull/3878/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3879/head\n0040623fd65be4741d54bca9d3b919ffa22c5e18d295 refs/pull/388/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3880/head\n004111e0a198535389e69ba4bb8839fa23669f2dc4b8 refs/pull/3881/head\n00415261b43facbf54e57857d2724ac5f23c6d00a5e8 refs/pull/3882/head\n004194f6969267b2f5260c90cb832431bdbe10cad548 refs/pull/3883/head\n00415d3eea4188f517c562fe62859a6ac89914bb0a63 refs/pull/3884/head\n00411e4ceeb43f1c8ba954af46556958158b75629d31 refs/pull/3886/head\n004100e968c4155d83f9b4cc100f9b510301d8015711 refs/pull/3887/head\n0041595f91858c4f263488483bab4f4c18eabecb51b5 refs/pull/3888/head\n004184ee0f213da7a839ce977520e53f901c141d1cf0 refs/pull/3889/head\n004020137d68b3d90677ec1a5792fadd7a0b9d5be665 refs/pull/389/head\n0041dd9217bab10ffafb83625720c7976f2f67257b99 refs/pull/3890/head\n00419457e17bf24eeffb0f5a36ba76dc1a752a5afb67 refs/pull/3891/head\n00417cba06455bb3105a5e65a7c8e664f3a9afd06ee0 refs/pull/3892/head\n004157b8170a6f3cc12b069d7e732daa326873b06906 refs/pull/3894/head\n00413e043d22054fe5f137d33453c89687b3d989a28e refs/pull/3895/head\n004117d5741880ed8fc9f47a3c1d4fab945cdd22101e refs/pull/3896/head\n0041c3367da422ec133b5b43aa56e247a235f7202aa3 refs/pull/3897/head\n0041f8cb8eb66e7871eab6205f062313c2c084de375f refs/pull/3898/head\n003f804148197b274c6129ab2c7d996daa456364c57f refs/pull/39/head\n0040e2654e0a480285bbba9ae0c65f7a48ef813f8d80 refs/pull/390/head\n0041eaa51e1dfb48b9f4e3733c94bd1696a8bf941644 refs/pull/3903/head\n00411b0f7a7995523913e78dd9ee49f623807bab26a1 refs/pull/3904/head\n0041e69b7fb5e733c65cc20e5ffd9e22c5cb92e9fd82 refs/pull/3905/head\n004129ef82621e3673342b536c444790f876ac7e67f2 refs/pull/3906/head\n0041e8636b60627bf7740a1003f63c98d947c03c1ef9 refs/pull/3907/head\n00413ac1ec80256d70f3f8bb7e884d9deb9c48d4e44c refs/pull/3908/head\n0041a5379a7b99a1d950c84e7c69bc5baca868b66045 refs/pull/3909/head\n004057cd1a4180b32268105209699409ee15fd23348d refs/pull/391/head\n0041c25e5ebc1a6f585c431c3057001426686a808347 refs/pull/3910/head\n004156c6db5dba84d0f1c34f85dfbc03577c7249b1ec refs/pull/3912/head\n00410682e59821f2d878a2b7399795a08b610ce8c8e5 refs/pull/3913/head\n004170623ca4eab567cab87a6bdd9c3c33f1809b1a57 refs/pull/3914/head\n0041fe546f2e593c84506c99a0c84da6821ff77b38b8 refs/pull/3915/head\n0041b87b2c7a05591e42db578fee5f26b0e7af034182 refs/pull/3916/head\n0041ec890999086a3a042d4a5dfe7480995f63daeca7 refs/pull/3917/head\n004194cfd7cc62e85496c8fabf2a0efd61ec041fbe11 refs/pull/3918/head\n004143798d1d6097e36ebbf3ff866dce07fd2bb2a11a refs/pull/3919/head\n00400c0a26a82752908ec2b45b00e052b166bcad1a6e refs/pull/392/head\n00411ffb1cda6d825a3f2b7975bbf31d7ee2c609d6ea refs/pull/3920/head\n0041616d8a297c117bf39b988e0f50191be88ba727e3 refs/pull/3921/head\n00416e0e9ef0310921cc583beb987013c9a52829e7a1 refs/pull/3922/head\n0041b588efa4c39fd3e1076b7bd34a3affd5e9705f73 refs/pull/3923/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/3924/head\n0041d8e6c8739bc2272484e8c2cf2eae617f53ad10e8 refs/pull/3925/head\n0041e0a3899cba44d3697c3fa5d5cfa67fbb210c6e47 refs/pull/3926/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3927/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3928/head\n004111e0a198535389e69ba4bb8839fa23669f2dc4b8 refs/pull/3929/head\n00408defc8e7c76da637ab8b3315c82a8f3896d187f6 refs/pull/393/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3930/head\n0041eebef3dbccb263f3625759617612165854d9dd9d refs/pull/3931/head\n00413dcbbc6feb6c7b2f4cc671600d3c408b10d32b5c refs/pull/3932/head\n004115a2ee9887ccae26ddec0daaf954ecec46fb3316 refs/pull/3934/head\n0041070cde5d0ae73ccdccf30f1b25ba76bea01d7156 refs/pull/3935/head\n004161e217870dd89215e181eb5198da8211d8e6cdc1 refs/pull/3936/head\n0040e0077f650f0dddd7ceb4160447770c45d0e5972a refs/pull/394/head\n004113c164479d20d8ec7294084f267b16a61f46bfa3 refs/pull/3940/head\n0041b6f1afc80459cea24b4be85ca843417f63c0423a refs/pull/3941/head\n00418b1ff67344b13995e68cf3dc9c8ac58f6f3b87a3 refs/pull/3942/head\n004152eb9f77964b05635e9110dab9aa82716a6ad061 refs/pull/3943/head\n0041189f29b0582fdfc412d147c5e79980244b0916b8 refs/pull/3944/head\n00419ba171f3de14d8e7a0b44b1a092ffffa2e1add7c refs/pull/3945/head\n0041fd0b54edd5ce159b36436c3dd89b8af5c37f58e8 refs/pull/3946/head\n00418ef418b918c995ce37e33f6f89276ae8781f3e78 refs/pull/3947/head\n00416d6d4fe2890b6a1498bfe91526b7a1f6985e8d97 refs/pull/3948/head\n0041da7f3dc8c1032d4b47d88719095df5e9ee394b39 refs/pull/3949/head\n00415eb86678eae2033cfb079a5aae81b459bf516dc8 refs/pull/3950/head\n0041ccf9a28d651ac78a1f4e794cb114ffe16643b2f6 refs/pull/3951/head\n00416286a716ab3c025a7463185b3747a3cde7c49c6c refs/pull/3952/head\n004113a2c5e9bad81285a8e80d24dbcee28512ac45eb refs/pull/3953/head\n0042420bf78527bb0aba9970edfe7d3fee7c8e7941f7 refs/pull/3953/merge\n0041ed787a0805bae8f0c35e5d6b3cf5121695079286 refs/pull/3954/head\n0041e2def17cd2abe3158b014340edb97a8de0f0a7de refs/pull/3955/head\n0041219045203122803b0af860f379fec988b5063857 refs/pull/3957/head\n004194ec0ecba39dd2f91775c94b7262978910c42e23 refs/pull/3958/head\n0041dc13ca51ab5fc58e205c2e1cabbbfd7ee7622054 refs/pull/3959/head\n0040a7dca0c16eada7c7f722cc9c91e1fed92a2b318a refs/pull/396/head\n0041c42b5d0282456dd2ecde7317176d3672a681e8bb refs/pull/3961/head\n00419c20f4579713fca652e34f5df142bceb7777f010 refs/pull/3962/head\n0041d5f57424cd1665e54bc6d076ee94a32f02fe608d refs/pull/3963/head\n00416aa4465662f0ae01ead778d616997f1e46561b4f refs/pull/3964/head\n004193effe1655ef6e07a82bbbef23d9c67daa020fad refs/pull/3965/head\n004136fb882bff830d21fd6abb1edd5e3eb170df4025 refs/pull/3966/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/3967/head\n00413dcbbc6feb6c7b2f4cc671600d3c408b10d32b5c refs/pull/3968/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3969/head\n004084445945ed7de7198d9a0066daa0f51438edf947 refs/pull/397/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3970/head\n0041eebef3dbccb263f3625759617612165854d9dd9d refs/pull/3971/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3972/head\n0041b2a6598cdb211b9287ae9f1d4028141d1ac959ab refs/pull/3973/head\n0041339ac8eba2fc33dabca1539b4cc2fa7b0b694eaf refs/pull/3974/head\n0041ac1de7ed2d2d7dba68afd627892d354361ce8e4e refs/pull/3975/head\n0041511c148a08470ad22951e7e3bd2cd38e522ced1f refs/pull/3976/head\n00414f636407c5bbaee0027a2e7e0318f8dd17e5ce7b refs/pull/3978/head\n0041772f8a51d0202f5c1dfeb1f993eef208830a3829 refs/pull/3979/head\n00400844c04becceef49c59f882e131067a946ab732e refs/pull/398/head\n004169d9a5842c7b8501f4ce26a8cf796118089a29e6 refs/pull/3980/head\n0041358cdaaf3470654629b8070c1c0b16f3ea0af352 refs/pull/3981/head\n0041346f07a7a58d6c5767efc2fa756329c771efb197 refs/pull/3982/head\n0041cf26f76e45970d35c7f96642eff8481f8e4a4080 refs/pull/3985/head\n004184b4f13793df71d9972c40d889b7cf39ed81bf4b refs/pull/3986/head\n00416c28b8631401bcd94a6797537fcf055fd1cf8a38 refs/pull/3987/head\n004134294cfed463b92dc955c131a63c2b35178691c3 refs/pull/3988/head\n00419475d9c86fe0a421d560ee7c0ecd19ff246f0149 refs/pull/3989/head\n004022f5a39f26c94f295594503e826e7cf470762221 refs/pull/399/head\n0041f8541a8e588830e669388f60c14abfd4a2e94148 refs/pull/3990/head\n00417bc326d367e5c6cf4e080aeb50ba7a9efa6d2231 refs/pull/3993/head\n0041741341c6ea0df2ffa59231f8827767abbf3e3d38 refs/pull/3994/head\n0041f2131447b46277eacdcffd60a4592ed2d1e13173 refs/pull/3996/head\n0041c28642f9b3c8d89e62795f4f708b6a83a3381259 refs/pull/3997/head\n0041cb3b9e85802b7084f0bd912353859104ced73a2e refs/pull/3999/head\n003e4a137256b3d2dbbb000152d745bf176d70147e00 refs/pull/4/head\n003f7a793712e2ac08d1a47dd61e24238bf0ffca6063 refs/pull/40/head\n004028e57c8bc46d1d8708ce9c9883be5d924ebbf10e refs/pull/400/head\n0041dcf91e611e46ecbee8674e2b9e20a3efbdbdd801 refs/pull/4001/head\n00410671e04fb737dc0aaaceb6cd16e2f84d8b900d34 refs/pull/4003/head\n004133cd5ecf32890d9c90bb211fa13247aa6f976d0d refs/pull/4005/head\n004140655b050c9d26d32ec622468f2ab6f336d37419 refs/pull/4006/head\n0041582711ecae53a970801c41deb3dd543c0a0017f6 refs/pull/4008/head\n004185830df99b8b87d2c0f2516b0610eb748a6e76db refs/pull/4009/head\n0040e485f81fe2dc95638871b436bc5c2169079f7ee1 refs/pull/401/head\n0041f37610ff5056787b0049db5a2148b72d31ef6872 refs/pull/4010/head\n004124df92e6cc679f9754fa61d678815021da6716bb refs/pull/4011/head\n00415ff229a202bbb25724a937f7ebbf45a67dfeea29 refs/pull/4012/head\n0041c299af1036c6650d5f280ed6a97f2bdcc140ac2a refs/pull/4013/head\n0041045a5fe1feffc3fcf66e0e9416334a5ebff59e6f refs/pull/4014/head\n0041d3d3c3ece200899bfa03b9d6bc7210e547e6b035 refs/pull/4015/head\n0041fd81720da377b33cafc764ec940445c422272984 refs/pull/4016/head\n00414f264d32b7adfa4944b55029ee870f182df1a1fc refs/pull/4017/head\n004148ee714b424076e2a714d5ab3812fc287043956c refs/pull/4018/head\n0041efdf07f93ea4d4c275d9e1832bb0f71940916eee refs/pull/4019/head\n0040ed452dfb3fafc4bf83650096ed88ad57ec4fcbd7 refs/pull/402/head\n00413bf1b3ae65ec763ef33d6de827328dbbfa84f412 refs/pull/4020/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/4021/head\n0041508aef0a6b2172c442e5c8a86e6c7043a7a4325c refs/pull/4022/head\n0041b2a6598cdb211b9287ae9f1d4028141d1ac959ab refs/pull/4023/head\n0041ac1de7ed2d2d7dba68afd627892d354361ce8e4e refs/pull/4024/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4025/head\n00414e96f18b74147ce2c448df232a5fee34035fd8fb refs/pull/4026/head\n0041ceffb14600121d81699a098098fa81c15bb8710f refs/pull/4027/head\n00418094cf87597d3c0bce1e6bcb2a0839484cc13adc refs/pull/4028/head\n00416e7df771e436b5bf524b7b643796c1baa7babc7c refs/pull/4029/head\n0040d0e471fe80170e85ca73a2e1ae9c836d769c2991 refs/pull/403/head\n0041546e846c9d289d9ba339eb60cc90648da9a37bb6 refs/pull/4030/head\n00415326204c817cbbf6168b7fe1b4e488f0121486a9 refs/pull/4031/head\n004135ec9bdadb83d2000d39e23b68926f18cdc7063d refs/pull/4032/head\n0041e1313e13e2285b2ad73401638529f215d3b7578a refs/pull/4033/head\n004141c2b3c104c84a273132900ae759b7d8c41eb14d refs/pull/4034/head\n004171166a0d6a23f7b43af95ed0fc6335f76bfab8a2 refs/pull/4035/head\n00418548fc841b6c33161cffa88a823e4ef98012dfd8 refs/pull/4036/head\n0041d604f023e238abd9fc6556c6078885aee23b188f refs/pull/4038/head\n0041d31d31e8ac29e98d3a27a83b5d45ea921149ca08 refs/pull/4039/head\n0040eb8e38a0a9d69ed42989476d22aec692229b4104 refs/pull/404/head\n00416525f4454d917386b129226dd59d00c53e2843b9 refs/pull/4040/head\n004136b27e35e464c78e7e498971855bbcde054ae5f6 refs/pull/4041/head\n0041814831e3ff9de8cc2e2831994711f29fd4e19537 refs/pull/4042/head\n0041df6b674a9e9ea8a6d42bb312dbac267c8f50c50a refs/pull/4043/head\n00419ab5a3a4757c46850e16b6dd598678b9d9a619c5 refs/pull/4044/head\n00418cf1724e7904751d7955a0b4e22f43600cab320c refs/pull/4045/head\n004180dc2f5ec2a822223edd971abbb008d5ae75d8ba refs/pull/4046/head\n00414223a6b82e81194aeb3465dd1acacb23c7cea579 refs/pull/4047/head\n00414ebbc055f168f25b25a9627d0642f5fffd2cf04e refs/pull/4049/head\n0040a5da7dc13ec7f46fa0f5e26ca0510c08f9a6f416 refs/pull/405/head\n00418f7a1f4a2df5488e7cb76af34140a485d9303be4 refs/pull/4050/head\n0041c60f4d8422b6485b3369585445f262a660c7113e refs/pull/4051/head\n00418e627312c947abd6174a58fcd126fb0886e05f44 refs/pull/4052/head\n0041f0a81947fbcaaddb6c035e4524b0b3b38ba51846 refs/pull/4053/head\n00419c02148c6d6e0fe4fe5be28167662aeea6bafe88 refs/pull/4054/head\n00419755e9fa2144edd64344a10cc1272faef971b267 refs/pull/4056/head\n0041e50b5f96a4c876d6bd0bd2128de031f9bc40e73f refs/pull/4057/head\n00414ef2433e1bf470b7d7847ac9ebd6c568eb71c659 refs/pull/4058/head\n00416ad7b0a64551e6ecd18bcd213cae285db9dae032 refs/pull/4059/head\n004017c1e7ec2ae2c06dbc42942ba61098fb5d372c64 refs/pull/406/head\n004180c200d3f72061337f95f9f062a6be1d07bca435 refs/pull/4060/head\n004148807357148a56fc2fdfb16f3530523d059ea089 refs/pull/4061/head\n00418d7da0ec4b550c610ae4c115e78b3d17dd50d1f5 refs/pull/4062/head\n0041ff226b4004c344c58067080d12111f41029913a1 refs/pull/4063/head\n0041e4681e8db389abcb0265c91723d8168d8148d2b9 refs/pull/4064/head\n0041ea3b782265eff6b9b357746e8800b9f17eff7316 refs/pull/4065/head\n00414abf19bffd321b23cff78c7eeaa9419dff713b2a refs/pull/4066/head\n004122558f6432557ef43e8edf7a0f15c814d8904187 refs/pull/4067/head\n0041657bab31bdc9055499f2f3f54c825c8b4807e49e refs/pull/4068/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/4069/head\n00409343ab402ad2586f8624a7fb8faca6cedfd57cfe refs/pull/407/head\n004145071bebbf81d8a3cb26fe7ae02b54c8121b38d3 refs/pull/4070/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4071/head\n004131afcc8c2027641029ce9b9a10aec3e411a1d07a refs/pull/4072/head\n0041c9f892912fe474c9b6e1ce164733d28ca27c949d refs/pull/4073/head\n0041b6110fffb6a4af391983e93bac55341df64df316 refs/pull/4074/head\n0041c430737d083686a2c81f0e431934700d31e4234b refs/pull/4075/head\n00417e11344eb17c20905860d7e7a36b50dbf44b3a38 refs/pull/4076/head\n0041a26cb6c660645dacf97c6f3d86d0d64b52330000 refs/pull/4077/head\n0041b276fafa473ad8f55f21e804640f7360c8000779 refs/pull/4078/head\n0041f69f47ffb6762f491a3e5bb5972f852423b35b40 refs/pull/4079/head\n00416dbe606370f26f5e91f0047db06b33713fc02014 refs/pull/4080/head\n0041b89ae98f2c937abf50ceafcef261590e353bb663 refs/pull/4081/head\n004163bbe5a79e242be38ac859cd2056438120cb4527 refs/pull/4083/head\n0041af793bdf944b14c6ce8eb60a414704d22479e974 refs/pull/4084/head\n00416b58419828587f15723fa7cca921850d52e7a57e refs/pull/4085/head\n00415b04ec5dcc1d8d8929ff10eb9c2ccd52ca34f99f refs/pull/4086/head\n0041f3db124ccfc14a7740cb8da4ddc8e7bcfdb76753 refs/pull/4089/head\n00406d0f1c3a7895798088acf0a8a08495056298d244 refs/pull/409/head\n0041bd5b692aa4d6518a93270fa9d6c6ffbe02def777 refs/pull/4090/head\n0041bebeadc18df007891b479d5bdb4a2360dd56c20c refs/pull/4091/head\n004140a3ab6a6c643552b81b64da6a3b456fa1b863f4 refs/pull/4092/head\n00411b36e1330ceee9f68b01dfc05c086d1d39586b4a refs/pull/4093/head\n0041eaf9ec2e31b1764e7e1757595ec45d133a51da39 refs/pull/4094/head\n0041bca98ab20df40373301bdc71c2a15d3a1fc8b418 refs/pull/4095/head\n00415507e12b7e085f9df7db65c00e127e91d82abc19 refs/pull/4096/head\n00417ac7a9d84f5e8c16c3512a34ce2eb84f69774f92 refs/pull/4097/head\n0041bb5e56ed293875c45ff6f5bdab3c2313eee02993 refs/pull/4098/head\n0041605048cbbe560c6a33cad899ab6036fd2ca992d8 refs/pull/4099/head\n003f91651239dd6d4d47c8d4d8b78d6df7e9925fdddd refs/pull/41/head\n0041f16f78531c36953bfd52695cd2b05cb4e224b40b refs/pull/4105/head\n0041a71fc86bec92b9e2d2e228f31314de541f936515 refs/pull/4106/head\n0041035da14de4c9bf4671fc6bcc64e7a83190cf1e5d refs/pull/4107/head\n004197b2eb2eb5fd13ce0303f0085c3965b6b3deb396 refs/pull/4108/head\n00410a7b7007e3f21ab4f1f2d5dd1918812fe4a781b9 refs/pull/4109/head\n004148fb24ec1daeecf139b2acd043726b4e3220cbf4 refs/pull/4110/head\n0041ddda7653e9367fea63d66267c04af88b02246d3b refs/pull/4111/head\n00417651c526d952329a8df588614e8c3716736c9bdf refs/pull/4112/head\n004172b7574f41b311abeb9d9b74573c4073058fe0d4 refs/pull/4113/head\n0041ffb9e800e633fc1795c639f76fa3fa86a794ef96 refs/pull/4114/head\n004171a405b3cfba5a6bd608f3bfffdf42b4143bb19e refs/pull/4115/head\n004105c08929ec11360d8cfa425fb1770df12fec9f01 refs/pull/4116/head\n0041a93f546c5aad3efc874888ea30ebe16bbe049d2b refs/pull/4117/head\n004103f1af1874e46d561364092f4ceb5e574e494d76 refs/pull/4118/head\n0041b39045d8e24a3f08951b13d54c260cf2a8e3557f refs/pull/4119/head\n0041426a031bd0cd3672007a16928e83697af3d0e6a4 refs/pull/4120/head\n004131afcc8c2027641029ce9b9a10aec3e411a1d07a refs/pull/4121/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4122/head\n0041793bd043ad71303633efb42100f9faf9bb381d63 refs/pull/4123/head\n0041011b48415cc6bc3aa2fefb766f4796da06a13ec8 refs/pull/4124/head\n0041324662b82050b9ae34eb14a8a87094139d0fdc70 refs/pull/4125/head\n00410c9a0aefa2a741329dbbce3d1dff633ecc045865 refs/pull/4126/head\n0041735e4d1190995a13e8e8307ee4e8455877bcbd96 refs/pull/4127/head\n004187c62cb49f25d05e1544d30a30f6c9f3dfc4e96b refs/pull/4128/head\n004149702d487210729dfbfd7213b1b0422f50e0833a refs/pull/4129/head\n0041c336256869152b1467b19fa98cef5b7d1a1b0d41 refs/pull/4130/head\n0041ccf15c1f6bb206db078ae5e0fecfd006ea563349 refs/pull/4131/head\n0041946bdc651d108fa66e8c81e189232bfc5da85055 refs/pull/4132/head\n0041d97dfdf2f5a81cd1058eeccece2249de001ff672 refs/pull/4133/head\n0041fb53395f827a67fdd76beb97ff4d828c2f6e7c03 refs/pull/4134/head\n00415e491a5804c70c854f398823dcefcdd99d286b18 refs/pull/4135/head\n004139e867fb7ae579904b75478ba14a9af77b771c82 refs/pull/4137/head\n0041a46b95f653938b9636964a9dbe19e39acc183e68 refs/pull/4138/head\n0041fc819913d79ba86f0ea1f619f76ed386e530e987 refs/pull/4139/head\n00412d4e21f4332ba46b2927eee9777c6dd9f7df4118 refs/pull/4142/head\n00419233bff2b768d32d43a61dacd7bbd3492f36ec41 refs/pull/4149/head\n00404102a18a336fafe433d6b2857265e0f0d6b77863 refs/pull/415/head\n0041325767014e1d51f0395fee9112091bbdebfa9578 refs/pull/4150/head\n004199040bfa7220d5d5c4324ddd006426550d71b2d9 refs/pull/4151/head\n00415ae3a0763aa4803fd2242ec786f9c1aea5b3a2cb refs/pull/4152/head\n0041ca331ec7255b817a6c8dba737680cdc17b08edc5 refs/pull/4155/head\n00417975d92c3d81922fb0922751fbdde450f63797b5 refs/pull/4156/head\n00419934b5466c9e17025b837df952aa754ca3b35efb refs/pull/4158/head\n004081dd41292c226f014de149a0071296e116d61189 refs/pull/416/head\n00410b1ed8dcdbcab26ccb2d3d799c43111a67e42dc8 refs/pull/4160/head\n0041f7aade54eefde94dade8029f75851e0678f8c216 refs/pull/4162/head\n0041b18605319dd079c09aaf7f08af9afa9a0d8e5a08 refs/pull/4164/head\n0041b66d9c8c608bfa332053171798db6e8579c5dea2 refs/pull/4167/head\n00406c31da0bab542b41831b7a82a9e4d14761e820e3 refs/pull/417/head\n0041e28815e9c8db98fa3d48c76abc3f23ef1987703c refs/pull/4171/head\n0041afeee52a4b7500d0ee9c0435666b0c1a98b5e03b refs/pull/4172/head\n00414c6c428eac56da2fdb136b5975634bad534e9ba2 refs/pull/4173/head\n0041e4e045bcf0e48528728519046c49342e6b435af6 refs/pull/4174/head\n00419a50e87563202df2dc338fb270f64b592a0524b2 refs/pull/4175/head\n0041f9101a7b9e3c242bf7369a23cfce89b31e890355 refs/pull/4176/head\n0041468332b6a69722b25a4f911d5edd8972453a5ace refs/pull/4177/head\n0041341bdfd038f7c032be5af5c4a98979c49fef2766 refs/pull/4178/head\n0041d0eb7383efe8c5e872422871dd46cd81803598a8 refs/pull/4179/head\n0040bc1b44e4879261c92d2b3fffdc9ab647d7c8a1d9 refs/pull/418/head\n0041e05bb785d508083e16148d0d2f91f109b952c4ea refs/pull/4180/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4181/head\n0041e289b61c0c57472c45188641c0e05452e2ce395c refs/pull/4182/head\n0041450b6076279e484cdacfa0e239d0e1a4468043d8 refs/pull/4183/head\n004109dd25bb2d986ef1596ad0717c6b830af0067bfb refs/pull/4184/head\n0041f77c7f1221a2ef94d852489feb1f64da619cc855 refs/pull/4185/head\n0041069724802e1f8e4daf65269e34bc54ca4e2bad6a refs/pull/4186/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4187/head\n0041c42f88cdadf7a7690aba1a446e06164d3342abcb refs/pull/4188/head\n0041a2e56226bb6c168db9e9999afc1d43d63f673800 refs/pull/4189/head\n004087c749f7431781e754adb61bc61c699fe5d7640d refs/pull/419/head\n0041aa04cfcfb282ddd29fe37ae04298e628bb3d92fb refs/pull/4190/head\n004181a4b6f95775647f71b293af6bcf255067e9fc21 refs/pull/4192/head\n0041e29b44b5fbd605d6e212ddf1b0ceca9565d5529a refs/pull/4194/head\n00410267051aca65a519829ac18ccafb06146006815f refs/pull/4197/head\n00412f5a1bb0efc8756bee679ece015b2e8f009b0716 refs/pull/4199/head\n003f7645ff6b03ffec78255994ef914a8961c0bb48ab refs/pull/42/head\n00406afc717169d3d59e8bbc2c1fc4cf01bbbc09f96e refs/pull/420/head\n00411455c9c6eddd003e10ed7d04f3585f76f747ee26 refs/pull/4201/head\n0041b75e8c48f133abff7febd8d90b477a81e259091f refs/pull/4202/head\n0041f94d78ac37b431339780bd5a19d69dd421fdd99c refs/pull/4203/head\n0041df368dd0660b8b3d4332f951e3877f04a6e39a50 refs/pull/4204/head\n00410dcf9190fe52e458a188dbae195135f7c62cf20e refs/pull/4205/head\n004161e5b322c9fb3682dc8082296e6f8c23fd6b1c97 refs/pull/4206/head\n0041520136a091348dd122ae73b88ef6243a09c22066 refs/pull/4207/head\n004150f9495524108a18f2ca6687a39bf4955bac9e72 refs/pull/4208/head\n004191817407bc0be1d01dab3b79e9e32d72ec3a18e5 refs/pull/4209/head\n00414951b45f4236fa673b427eaf447edfb88b011a76 refs/pull/4210/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4211/head\n00414fa12187e525fe48fc5218f89b04c6677d9ac286 refs/pull/4212/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4213/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4214/head\n004125491e8309b509268d38573920ff441a173bac46 refs/pull/4215/head\n0041f57ffc7300426b6d925980f57e2f2d9673cefa27 refs/pull/4216/head\n00410dff43ddb59bdf036b2ba50f89e7eab8576d7712 refs/pull/4217/head\n0041bd6c7ae718c5c93b239504754c7b6ab81108f56d refs/pull/4218/head\n0041bc002dc9333220eeea243fb432b0b0c521c0d52f refs/pull/4219/head\n00404831bc8b92e9aecbcd0f128f7e45796bb5f89ebd refs/pull/422/head\n0041977e3d1fc39da8615f7ee45b029f871c4066d80f refs/pull/4220/head\n00415530bc9a9edbb13ec51deae96d747ff442c83662 refs/pull/4222/head\n00414207547e4e38e03830909dff6b84c9bfad04940a refs/pull/4223/head\n0041745b933ceca93d7589ee027300c8343fe51e971c refs/pull/4224/head\n004183438f22d3903985c1f0c155906ac2294599b848 refs/pull/4225/head\n0041d6b36deb349f88e5680954d24f714b4c7d1e8d6a refs/pull/4226/head\n0041ee89c8da1262f3c20730187a3c1a79ad91ee4f42 refs/pull/4227/head\n0041589c54bcaf5e6bbdbb2a25e8babb0dd2654d982a refs/pull/4228/head\n004197d8c9c0742269aa84e856793d7ca7f404ab1204 refs/pull/4229/head\n004038871758f59c771bee03cce88b2c9cc99b76793b refs/pull/423/head\n00418666d058e26bc82846f310a1338eb70404088055 refs/pull/4231/head\n004155dc40c8a7d656e104d32f7e8c205af56cd2a0bf refs/pull/4232/head\n0041c368132e3e9de3f111cc49253f94c59c6839560e refs/pull/4234/head\n0041b93f9d9428789c90b8c9d6203581180931183f3e refs/pull/4235/head\n0041bd108d3593f63e0662518db1ea55c84668802242 refs/pull/4239/head\n0040cae5daee7deff4cffda76dedaaf1a653e2af3790 refs/pull/424/head\n00413cdcf410a1c13450527574dff40e152c23aa0fe8 refs/pull/4241/head\n0041d227b5208f951c7b132aa84ed7aff5e408edc550 refs/pull/4242/head\n00410fd1f440fda25e704da3ddccf6c5d8ecf374a85b refs/pull/4245/head\n004187845700c3259b2f3cbdd32d94a29831bc9135d0 refs/pull/4246/head\n004193a0c66066319330e05f0a1d63953f171851c9f6 refs/pull/4247/head\n00413e9dc58f39883d11393e53897d5a62bee2e5ae74 refs/pull/4248/head\n00411f3c10be2db2dbb84d4c331cf10b1dfb2689cf87 refs/pull/4249/head\n004000ea2f01026b75a03df999dba8057a2c14ec0d0d refs/pull/425/head\n00411313dfe68758a4ee4690f5d6e8b27a92bb921648 refs/pull/4250/head\n00414dbb572879002a0d08851d874495dbe009dfe7a5 refs/pull/4251/head\n0041abfbcb60fdfd3087fa29fe2e78ad98912b97905c refs/pull/4252/head\n004174f09ca04f441096a500a228081bb0be818c9491 refs/pull/4253/head\n0041079f1a40fe0f4310e72e08a1751f748a8d694fb5 refs/pull/4254/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4255/head\n00414fa12187e525fe48fc5218f89b04c6677d9ac286 refs/pull/4256/head\n0041b5a24b4f6c4dc5a3e34afecdc31ff2ef2ca9e6a5 refs/pull/4257/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4258/head\n0041a1c6db19bb0c144d67e3bfbf3679f48b5a05fba8 refs/pull/4259/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4260/head\n00419b510e6bed5cb4466e7c112d084b7b00a6faed9b refs/pull/4261/head\n004148f0642dd3159f8f7b8705c6ff83e33aff815277 refs/pull/4262/head\n0041486b8efb7f93c5f228eae6851d8e15c1d94150d3 refs/pull/4263/head\n004157c9e29288e419de839577bdc343358a75f61af7 refs/pull/4265/head\n004149d7b32a34d587b76300e90b7845ee267deef517 refs/pull/4266/head\n00417c3345d97e02332db64fd9fe3b244d78986bff81 refs/pull/4267/head\n0041af4a3832ac8aaff7d11d5ed08cb1f648986e07c1 refs/pull/4268/head\n0041a45bb327f89ef31a8aad1dec35929ca2d35895dc refs/pull/4269/head\n0040adac66c1741833f79a1a960a6932760ab694b1dd refs/pull/427/head\n0041ca050aa79e6a9988df50e50a96fc5f964af847f3 refs/pull/4270/head\n0041730099826e1c762022eb75f5f147351720d5cfe0 refs/pull/4271/head\n00415ef02b59d4d4372226523cbf4c5a1c1419a88552 refs/pull/4272/head\n00415383421b9481772a94a212117943ed862ba40c48 refs/pull/4274/head\n00415bdb2c1256818c354cf15f8f516258c195d040d9 refs/pull/4275/head\n00412f739e7717d0abea9f1a7007135748a84b8570c4 refs/pull/4276/head\n00416ecde25885f6a97cf6bb8adc35193e28fe324bcc refs/pull/4278/head\n0040478d6e2a10cfc44072a3aedba6e921442e155f2f refs/pull/428/head\n00419bf4966688a3e46deb3be128726aa105c9a6c896 refs/pull/4280/head\n0041c53dece390e68991bbe5b80765b80676219f2226 refs/pull/4281/head\n0041a7cdcb54769f35a8dde5b24981acef979e4967d5 refs/pull/4282/head\n004148933b48c2a86c022193c944636f9e51e5c5ac13 refs/pull/4283/head\n0041882c6e214d2527a477b2f96cb3b938ffc83250a4 refs/pull/4284/head\n004199de7c8d3af77d5c29c698342947a44b6a4cee12 refs/pull/4285/head\n00414ab45af81980209deff56da769a250db96f24ec6 refs/pull/4286/head\n0041d32271d8b575539980b22d13f7b49c711205fd1f refs/pull/4287/head\n0041dc8f3942325416f8d04af6d77ed1d1faaf9b3102 refs/pull/4288/head\n004144dbfc666c77644955d9c54066eff274aa9ba463 refs/pull/4289/head\n0040702b192740ea948214cbdbeb82d38f79405697b6 refs/pull/429/head\n004164f261c6e4a2ffdb54c7b7b10e7d4e127cac13bc refs/pull/4290/head\n004152582e2431bee0922d2f932bcf871ee1930227d5 refs/pull/4291/head\n0041ba9ca122c226c4a953c506afab73df5dbaa7bcf7 refs/pull/4292/head\n0041d4f0a911405c270ca27d9e420ddd95cf04e68e97 refs/pull/4293/head\n00410e15ab6348c70ea4d825d0904484c5491c59bfc3 refs/pull/4294/head\n00413d1497f309c730f046d52a0fef4718c764cf0081 refs/pull/4295/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4296/head\n0041b5a24b4f6c4dc5a3e34afecdc31ff2ef2ca9e6a5 refs/pull/4297/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4298/head\n00418c3c0ea8ae4862b829c7122bdabd6f0fd767bb89 refs/pull/4299/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4300/head\n004173c97de91a7eb66cb20ef9b4183c4bd79f042204 refs/pull/4301/head\n0041791ecc4ed2cb35b7b90621754dfca7b681d5dce0 refs/pull/4302/head\n0041f06a7cae3d6fd8243d56e0f018c20f68890223b6 refs/pull/4303/head\n0041faebc0f6408cf78e414be49d93b7bbda69bec2d4 refs/pull/4304/head\n0041f7e2108944564aae08b0f9adae43db5784c9fed2 refs/pull/4305/head\n00418d826b50e698a369f9c3d6bfe36f7c52a209b707 refs/pull/4306/head\n0041e84a2c927d801b8e90ed594c36eee4c169ca9699 refs/pull/4307/head\n0041cba995b840bd791452622ee7fb8dcd0f261cdaa7 refs/pull/4308/head\n0041b86ca2acd3bbe1bc58b5432c1596bedb8d2e1053 refs/pull/4310/head\n004136cb73db1f0a1df44a5662c346a2176ef766e0ba refs/pull/4311/head\n00412891cb4165960c15dfb87ed24f6802db4e679f2f refs/pull/4312/head\n0041effb2783ad7d37e0cf924cb898c637ede68bd4d9 refs/pull/4314/head\n00412213efa9faf4a22b5bbd22dbcce998e7878089c8 refs/pull/4315/head\n0041fc6a35716d0c1e147bba0c763b241526ff8d7e21 refs/pull/4316/head\n00417795fe2118ae03eb745e4acf65e008ceed9faef1 refs/pull/4317/head\n004168cf84ff3b56b98b1bad07bc1e5216d1c4934e64 refs/pull/4320/head\n0042d81d55145c7926d949eaaba972446fd3db59a732 refs/pull/4320/merge\n00417357fbfc817239c300ee3cfefb9d901a6070a916 refs/pull/4321/head\n004177005b107f9201705fb316f7cd0451db6d1c7b13 refs/pull/4322/head\n0041778a8cfa7e02320454f0ddd160d59e5862ac6ea0 refs/pull/4323/head\n0041e5d598889d902ae29a65077e6af5d0146d5ec8e3 refs/pull/4324/head\n00412bd288abac908bb2020c9d21d0e92e370826a25e refs/pull/4325/head\n0041846da5544a85673d81e39a164d0673e8ea99d9a4 refs/pull/4326/head\n004117d729fece0a7b1995ceaae94b4c404dac0c7ce7 refs/pull/4327/head\n00413e62eb95d5570cc4316b0789545494efcadfed7c refs/pull/4328/head\n00413de84d56b6a4a4a096111197bf14822f09fa1b41 refs/pull/4329/head\n00401652c745526d09ec28dd1bfc8062ddc82a04efa7 refs/pull/433/head\n00416aa4f1020b5932f21a737787170b6970ac95865e refs/pull/4330/head\n0041056910dc0c3d996d5dc6fada971656babab4b0d8 refs/pull/4331/head\n004162813f81d9235c4c985a9209e47724168b3f08d2 refs/pull/4332/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4333/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4334/head\n004133f7df4a458779537e841eaeb160b8c36b78ce9b refs/pull/4335/head\n0041f7fed3c07f4b162100c5f3babed9cac14b2a6d0d refs/pull/4336/head\n0041894a48d4007351a085f3573609182976e61559ee refs/pull/4337/head\n00413f4d9e880845265f5458ea33983f24614163105f refs/pull/4338/head\n0041ca687f211ba4cfcde6e6860edc47adbaf3d62dcd refs/pull/4339/head\n004037102ca6da3d94dcbe61fd6f00bbcef7843e60fd refs/pull/434/head\n004158951688bd7b39738e90ea52e27938fc0e71e272 refs/pull/4340/head\n0041b7a013236007fd71a8ef6db7676e61ae92f0e9d4 refs/pull/4341/head\n0041dfbd3be19b707b45b867e1d495c78cfeab0a79ea refs/pull/4344/head\n00415d82849b116aafcfe3b840a3b2cb3a96c72b0c1c refs/pull/4346/head\n0041c95c4dc7c8d77cc218f03f2e512ad131c34454ee refs/pull/4347/head\n0041c025159a0f882c9fdcf352d0d8937c8514e6cf1e refs/pull/4348/head\n0041c8c48c90d5a25cd69dc4f95d19b3ce8c31f55e58 refs/pull/4349/head\n004033bad2b5d92dbfab547fb81ae3bb5e62baa91be8 refs/pull/435/head\n00415a52a7a8297c848d6258d4691e920384524b2ac5 refs/pull/4350/head\n00410dd19ef125a7d7e9edf0a3ce1b83167ee19bc160 refs/pull/4352/head\n0041960851a01e6e85169fc45a599edc706248a6dfc9 refs/pull/4353/head\n00414f9a50b2c1db3828ea92b9062e21e6e928c1aa26 refs/pull/4354/head\n00426e5bfd0c7aacce22347eb83ef297f5c2e3e60149 refs/pull/4354/merge\n0041ab15e312c6e77e5f9663e045b99c855fa4fef9fa refs/pull/4356/head\n0041240d7748022cc5eddc71b055a4de56607f808aa3 refs/pull/4357/head\n004102f239424950db284db5cdaf98cb6c8a01c9ee14 refs/pull/4358/head\n00405cf48a27f88c23526734f137d94195452d923dc2 refs/pull/436/head\n004147a2e9a56a526d1bca7f21a8238125f4eb6d74b5 refs/pull/4360/head\n0041279c4cef7315db382b2de092359578eec04e27c9 refs/pull/4361/head\n0041ba68a768ca2617b68e4501c45bf53add1a56663d refs/pull/4362/head\n0041e8b529654e25575191b947df1da8d91c099c9fb4 refs/pull/4363/head\n0041e4b09b21a6dc647717e2ace56567225e7619653e refs/pull/4364/head\n0041a220812d62e2e42091ec715b57de15185708ba39 refs/pull/4365/head\n004119f1f5bdfd91c1e0f3a3232c7e9fe6cd43be287a refs/pull/4366/head\n0041bff16a47bc1b3905d8b6cbe5ccc7502bde96ee9f refs/pull/4367/head\n0041a14da923ddda5f2c54323fe126097752e1868ae5 refs/pull/4368/head\n0041c186ea5845c74108685e91bba36613c23212684d refs/pull/4369/head\n00403dea0ce596c3809f433d67bb2160a8a8af9e590f refs/pull/437/head\n0041cc2a50ecf69d4802ac52e686b2958e1dfa0a43fe refs/pull/4370/head\n0041123280cb29051b1aff60c6ae37382e8be59ff2dd refs/pull/4371/head\n00417e2a169c274432adc128d93b0b4da7e13a927062 refs/pull/4372/head\n00419322086f4d84da04f578dcbc1c7d60905378bed2 refs/pull/4373/head\n00417d4984faa3fd34d684eb715ef1ef7ecbde94d893 refs/pull/4374/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4375/head\n004140fec103a79693157045eeca1afa45d9b809ce19 refs/pull/4376/head\n00413ab4bd42754e8625516753569a34e5a5b5b2e66b refs/pull/4377/head\n0041d38aa9d9a84691c9a226b38209fc60c3e511c125 refs/pull/4378/head\n0041f6b206dcb529a0be6317a0c6fac208ab1306da98 refs/pull/4379/head\n0040e7b69136fd234a5ebaf9e047eb4365c59ad7461b refs/pull/438/head\n00412e797b98f10f8d4345a8426a37f02724aa3cf9bc refs/pull/4380/head\n00410da6ba3394cfc30e529c25a09f532c7f59d626f8 refs/pull/4381/head\n0041afc420868ef02796f3b2cdf83c1828b9bf53bec6 refs/pull/4382/head\n0041c265e78f41cda5ea210ac0eb48c37d39a5fc3c5e refs/pull/4385/head\n004138cfe7d7650bb417615c5a88de6a56025f070f1b refs/pull/4388/head\n00411765c654486625ac03a728e9e4dd6885a8102ec9 refs/pull/4389/head\n00406531bc4aec902c7245c0b5e6ed08f50fff8de7e0 refs/pull/439/head\n00411133aeb7e723a6aa3ff1b73fa122f562180c6571 refs/pull/4390/head\n004131b702eedd001d3347dc45088e2b118dac3ee5a0 refs/pull/4391/head\n00418b71105e0c36521dae1ad1771df23a90578fe429 refs/pull/4392/head\n00419320ea079550140e74a649d7579909a9b789d19b refs/pull/4393/head\n0041687cecacd9d1f8f608cfbb577b218a59ecb5831b refs/pull/4394/head\n00410118be6593c06e3da81ca22422d48af8b0f8eb5e refs/pull/4395/head\n0041800a52c3964dd335f633f967a2edd253eaae3939 refs/pull/4397/head\n004166b067187c1513f320356b11049d9e3a3ec05ee3 refs/pull/4398/head\n00415c8eaecdeb2dc750cb13759c350d691eba24d035 refs/pull/4399/head\n0041adfb43db240c21a6ddc668e9aef984e94ed161b6 refs/pull/4400/head\n0041929776696972e0e85a4988c2ddddbb0e451ea93a refs/pull/4401/head\n00419e55ac3643f1c67182031fc8a2183fb9ee666600 refs/pull/4402/head\n00416bfa8c455a067f05586e2cd553969339833dba6f refs/pull/4403/head\n00413e1abd1bd236754e6c517bea0f676608f3896979 refs/pull/4404/head\n00419322086f4d84da04f578dcbc1c7d60905378bed2 refs/pull/4405/head\n0041866307738b1ee6a88c33b5e727b72ac3392fba2f refs/pull/4406/head\n004162e1a4b07048aa502628e6831ceed9d69ca4239a refs/pull/4407/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4408/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4409/head\n0040564ede75518c9e18b7de4b718827ccc62d32c2cd refs/pull/441/head\n00411f33c2e270fdebb0daf3f707ecb01907d1d7c268 refs/pull/4410/head\n004290210ca4843705d5f500b0e3583f9ba51b7d090b refs/pull/4410/merge\n00415c4587da625a6adafdf696306c472f43c110ffa7 refs/pull/4411/head\n00416f2cac7ed9aefb82ca5f52d1fbf85718be6ba6e6 refs/pull/4412/head\n00411627bc9b8c18d9423d83f0e3bc4d38944a606805 refs/pull/4413/head\n0041e9f0083db1333300db481783452b8975c6ccce20 refs/pull/4414/head\n0041ac3b48ad45d410f8e91fc0c38b1c039ce145426f refs/pull/4416/head\n0041e1326803ba3257f8e344df1cc213f97018503da1 refs/pull/4417/head\n004171eff47d6a0544d680f5240f1714776c01591c0b refs/pull/4418/head\n00418f3043b5f925b90921303654c6fb60c9d699bbae refs/pull/4419/head\n0040214f1a3a0b831dae6140f1322d935ec18d1e69f3 refs/pull/442/head\n0041bd7995bf6af50db653a7c8221e048bb68f6212fa refs/pull/4420/head\n00415d6798520974b937d5e37714cf674ef5776c6c7e refs/pull/4422/head\n00413108dd5c9c530b29efa786e5a0b64e4989f4f06e refs/pull/4424/head\n0041e9e99d4e0314c7ffaf1f7b99305860bc0d0a7a26 refs/pull/4425/head\n004111bd0c2d250794571e262a8bb7df893ebcfab689 refs/pull/4426/head\n0041c825bc58eddaaa497e63630580d0bc8aecd3d6ed refs/pull/4428/head\n0041cb6b7657c8f65a3c9f437b0eecf6f7e49bd38661 refs/pull/4429/head\n004031214408ca2213dbecc787791d6481eb8f98318d refs/pull/443/head\n0041393b8fbb5c0db752904efe5846b5a19bfe7476a2 refs/pull/4430/head\n0041edb4dc5344139e67215cff2a1c73abdf4e3aa422 refs/pull/4431/head\n00416d29f505e508ab7b7c26fcc92a4bde8193b4bd5c refs/pull/4432/head\n00410026261877dc51f2a42f7180d7b92eb9786accc3 refs/pull/4434/head\n0041a47cc67387d54314db3c2ce06a4ba2a194ae8fcf refs/pull/4435/head\n0041ba3a41b3b80a7f74732ed7d89e6f63ff9a473a2b refs/pull/4436/head\n00417cbd90ef8ecb3dcc43d79be3aa1fa7455ca1cc37 refs/pull/4437/head\n0041e2ee8e3a38d6636614ea927a716b266b90e9189b refs/pull/4438/head\n0041878371c190328ab5f7b7e393461dc4db01f64bec refs/pull/4439/head\n004055e6503606850b8b972554070ac6e6f652744d13 refs/pull/444/head\n00418d1b1e8cb56058ab318a4b3e01ca5b6cc6ef31b8 refs/pull/4440/head\n004118adc77abd42a2a97692dd03ce8a9f24c267024e refs/pull/4441/head\n004151a52d4d44fd3bd3465f4b5931cb5527f34900dc refs/pull/4442/head\n00417357e10e43c97db7999563c361860b0b45cc078c refs/pull/4443/head\n0041223dd8d3ff8e564b20a325d94d99101abab27461 refs/pull/4444/head\n0041866307738b1ee6a88c33b5e727b72ac3392fba2f refs/pull/4445/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4446/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4447/head\n00410250ff18eb930132e38851cc119c066a780f0051 refs/pull/4448/head\n00415127b14a1cc0bf6d1b0ee1788b23253c0d6da3ce refs/pull/4449/head\n0040714567aa8531ac2d5be17d02dc07382c13d314b8 refs/pull/445/head\n0041dc77dbd56c975f38e568ad1f4697c9066130af4f refs/pull/4450/head\n004142510ba93c26ba597694771b2ea1e343ac9665c5 refs/pull/4451/head\n0041597ae4fd7e4bb565e1772d36b8faea33787dcf67 refs/pull/4452/head\n0041cce86f319241ae1b6e863878a78452e2085e0b60 refs/pull/4453/head\n00412e602ad31073d394f5d29df839dd1195c96be8d4 refs/pull/4455/head\n00415a347bfde8e51694fd2ebb33dd4c354d3771ff2c refs/pull/4456/head\n0041ddfb5d83db8185fd2b0d966ddbaa1065167a5aa0 refs/pull/4457/head\n0041b18d19ecff7fc692543bdf0980042a96403a2b4b refs/pull/4458/head\n0041c33c7fccdf65fa4f6999e315f1b503ba53355966 refs/pull/4459/head\n0041f44075bcff294fb816020601a2909b61c7d17bc1 refs/pull/4460/head\n00415b2e18e273f17dc312f569e4bc3bfe914d818ced refs/pull/4461/head\n00415d7647bb1f8ee435b0cd6c241d92452264ad2aa8 refs/pull/4462/head\n0041add6ff4405a5207bcf9458e9f585f3b6a048bf48 refs/pull/4463/head\n0041ff700e139856650fcb9788bb35979d8e7dd42bfa refs/pull/4464/head\n00418d96dbf56723b1bf995cc64c87e9b928172b1c61 refs/pull/4465/head\n0041734609f2e7aaf863c76cf377dcb9210f10be753e refs/pull/4467/head\n00413d668186d21fa0b011d3afaed43c9a0d8188cca5 refs/pull/4468/head\n0041e0cc281310cd3db615ba985889d579d89f12510f refs/pull/4469/head\n0040b9b465c2b3eef979ace3aaf02a7a513e965432a0 refs/pull/447/head\n0041b33f0eca90dd8a9571fa53eb957671885158ba3a refs/pull/4470/head\n00423c62a1a1b8b7367d8c4ff1320105cc02b9ca47c3 refs/pull/4470/merge\n0041619f6c35dcb9357136f547673e39d3a67737e1aa refs/pull/4471/head\n0041147fdfa5f76227c4b253f40f456f191226a6a106 refs/pull/4472/head\n0041867b32ec676d9223452b503ad6437c7be322973f refs/pull/4473/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4474/head\n0041998bf812eb7fb00b02df12e38b1652f893dc634e refs/pull/4475/head\n0041b1d96537b6fe479f0fc974a5d2d46508cbd82d17 refs/pull/4476/head\n004110f37fb948ec36817c3a51a9d5115c45c4812471 refs/pull/4477/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4478/head\n004107b0469490a46e03086955f5b26c8d06a9306800 refs/pull/4480/head\n0041e56fa1bc01c94ffdc8d930f6a4d5f887336cb27a refs/pull/4481/head\n0041cd8b630989c0e20134f07784bfd406e8628f78b1 refs/pull/4482/head\n00418fbe327684b1ffa47c632a59d1cef3fefe4ccd18 refs/pull/4483/head\n00410fce52b2766840f5899ad13d62050013cb948967 refs/pull/4487/head\n0040aa975625ea6c2a4c817af8f69ffd733db4782b48 refs/pull/449/head\n0041e415e72e208d1321739670fe5e9e451c98effbae refs/pull/4491/head\n0041233ebaa10e3d7d23410eb76529b4c2bcb5a7675e refs/pull/4492/head\n00411c5f07cf0df3c3c21abbdd7fc20f373bd814b4be refs/pull/4493/head\n00416ca09316b635624c23590c6d0ff4ab058527151a refs/pull/4494/head\n0041fa4d1b2a0cdee7f99143b08367875d84709692a0 refs/pull/4495/head\n004116a98018d279eac22141ae1ac3949984f4d130ee refs/pull/4496/head\n004161646e86304cdccd9c36fa7ddb179a053a03bf46 refs/pull/4497/head\n0041b212a183ebd36aadc440911b27b8c5d4e11c7f2c refs/pull/4498/head\n0041fc79b5bee6c8f3f4ebb4e23238109fc9276c2dc3 refs/pull/4499/head\n003f128c809bb6fca55127f0d89f87ab0b108fc9b036 refs/pull/45/head\n004021a5af031b8b38c19ddf2fba0b2f2623a0a44902 refs/pull/450/head\n00419a9acfdc9c14a7f5d295eb90b499bf3161f4103d refs/pull/4500/head\n004110ceb6eecada40625780fbf4d0a131ea6355c3cf refs/pull/4501/head\n0041ff6e72e3f0756f2659a002d5e68a90c3b25b34e9 refs/pull/4502/head\n0041b923b5fcd85f2ffd35465a09d19a2e7ef529753f refs/pull/4503/head\n0041899933548672c5430ca15e7dd62c03bc3413ab64 refs/pull/4504/head\n0041cc0f43abeb5999b58248d5444fb0e09418c3a5fe refs/pull/4506/head\n004151afee5f450020764cc181505210d67009242209 refs/pull/4507/head\n0041b24f9c09efde732299593330c8f313b488163064 refs/pull/4508/head\n00417bc8e4743f43034fd97f5bcb04d4808862a0e9be refs/pull/4510/head\n00419d533f916ca0418e4c56eb6d9d1680a831055d6b refs/pull/4511/head\n0041b23b1365e538126b41b429cd7ed8b8013f8b8497 refs/pull/4512/head\n00416296cbed9311b0f6fcb0cec1b530276c40ea9e40 refs/pull/4514/head\n00417acab9dfa400380d509c50fe7ab39aeaa43c13ce refs/pull/4516/head\n0041c6c07de7a470ec7bb2b1a417691e15ad59468b65 refs/pull/4517/head\n0041d7145a70bd77e8e4c69c7df953c0fa0e41d59584 refs/pull/4518/head\n00411c72ff700f8157b4c72fd2d3ceeff4eb6d9ed7dc refs/pull/4519/head\n004100194efa32b0350b4d31b058541e6fe25d92df9a refs/pull/4520/head\n0041d6783f79627838f22e1024e36de509c0f724893a refs/pull/4521/head\n004149a32d99f2e4f1b5550347b7aa0a592356e331ff refs/pull/4522/head\n004197801e05a0a75dd338ea4bb6ae7711446817d6a2 refs/pull/4523/head\n004182c5c5b2dd7467f6b9f6d1df2bb2625ef0b6305b refs/pull/4524/head\n0041d15f3ff9fa9f2b24b33619aaff76eb4f4815a461 refs/pull/4525/head\n0041cd24dfe9717762a3f9590a1d2093accae8d0ecf7 refs/pull/4526/head\n0041b6beef217706fb5f1a339df1aee052e7d00772d1 refs/pull/4527/head\n00412b1a9712618defdf186eab9cd2ea9f96a9e8b00a refs/pull/4528/head\n0041a69afd2ff7d7ed8607a5339e2643bcaefa8b2739 refs/pull/4529/head\n0041ccef4083747c9fcbe128bcd5045e64eb790f5323 refs/pull/4530/head\n0041b7fd051a40f38d76c44a4ace3f93913404ae1e33 refs/pull/4531/head\n0041266004cca3544184a10159381e3cdd75071fc0ea refs/pull/4532/head\n0041d0a9cf0deb9ca1ad06214a29ca6d71354b17f0b6 refs/pull/4533/head\n0041a4aec3c249bbdebe1e5e87c2e8ac64e14b67d2ec refs/pull/4534/head\n00412de6485cd0de281812822091cf7fc7055830fa25 refs/pull/4535/head\n00414b83ee3013338799406862d1d25cbd42825ffef4 refs/pull/4536/head\n0041f166ec43c5d8f611093b4116f96469993f3b3a88 refs/pull/4537/head\n004178757dc74535f4f8289f74edb76dc8fbadd2194c refs/pull/4538/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4539/head\n004057438b74e79a243fc8337039df968a56a47e1e04 refs/pull/454/head\n00411d7fca817eda07c83fb84c950d8325c2f9003158 refs/pull/4540/head\n004288f76b9b99d52db4578994b0f53a606cc7069036 refs/pull/4540/merge\n004145e8f08f97a0f5516ea1d96cd87b7e6253797ce7 refs/pull/4541/head\n00414cb3f8db869a061fb2d8bd10b21851945db27d88 refs/pull/4542/head\n004173d757a4307d837058006943fc8e23f9b300018b refs/pull/4543/head\n00410ae816cc6eb6ddcee5ee9dce6a763599232c85d5 refs/pull/4544/head\n00419f6977f06e96a9f93168ff34c5e0322ba65be3be refs/pull/4545/head\n00414c1da4f045d8a7349a95b62f7da800485f2067ca refs/pull/4546/head\n00423bd03f218c4b85f52d71b62e950d34b468227b35 refs/pull/4546/merge\n0041e07be325c0c0cd8ea0a1e489212428ef8fcbcab3 refs/pull/4547/head\n00428b87511fb05e3258cec90c8ba9730bf66ba23a50 refs/pull/4547/merge\n00410a4eb2562c76879c214839ced806c1b2c1cee89a refs/pull/4548/head\n004119651c0b0a987f650de2aa0c3b23dd238887d222 refs/pull/4549/head\n0040a0e52ee79ef2775920ac85443863e30b1c1173a8 refs/pull/455/head\n0041e1567979f5d8f403d00259b33fc94d7d5d8cfd33 refs/pull/4550/head\n0042ad3bb7df33ce8dd505a341fdb4e009b751986ace refs/pull/4550/merge\n0041b09db91200154e521db1ae9acbcee93a905de457 refs/pull/4551/head\n004235b3f1b514068c1263d8ab1e1e069b77aa75be70 refs/pull/4551/merge\n0041da252021206c06495d714fbca2d7f9eb49e0bede refs/pull/4552/head\n0041b635659866d8fa64c17761d392157de69c299868 refs/pull/4553/head\n0041034c72c9d67ce5836d86937c6193e23e48dc84bb refs/pull/4556/head\n00416a1ba7ffcfa992b6beb258e89e1352c25b2ab6ec refs/pull/4557/head\n00416a293360508ad940fc7fd8dcfbe40516fcc7ce86 refs/pull/4558/head\n004143ba2e3a35a81a8983b7e256c114296f66036628 refs/pull/4559/head\n0042aa2d6a4ad9f7c852e4fd6c22b90731d3cd75ecbc refs/pull/4559/merge\n00405cb5971d55f57b60684d9751fd452bc631916934 refs/pull/456/head\n00411d993a71d58308e5fc6abd5cbcab5558a79d5f1a refs/pull/4560/head\n004113822f7c31b4c4bd18644e23cc0e10febe8193a5 refs/pull/4561/head\n0041aff57c6e4007d6a60e38e3351d765f03b4d35319 refs/pull/4563/head\n0041125abaeebe0a26d5b59db33963725fcfe4dbc291 refs/pull/4564/head\n00413d816c95b3b39a06a387d10209110b8a424125cf refs/pull/4565/head\n0041e5a2d577057ff50f55653eea69a2ae15dbe4872a refs/pull/4566/head\n0040ef8e6f6023dafafc83ccf7252ae15b056210fa65 refs/pull/457/head\n0041ad6b9c3a50675440e93f954406cd2b4db23413b1 refs/pull/4570/head\n00414ef79b0722ab2c04a187b070751746cc8e80b8dc refs/pull/4571/head\n004183dfa578aac70f07a2d7babf99ac05af72470377 refs/pull/4572/head\n004207feaaf039606653aae554618b0a5f1105df525b refs/pull/4572/merge\n0041ca02e192bd9f65d1f3e6b7f4ace40b151cbedd68 refs/pull/4573/head\n004101d2c2b5739af27612ddd00da094e38281b8a9f1 refs/pull/4574/head\n00416657519f3601febcb6343f6f5e3b2fe5d12dc686 refs/pull/4575/head\n00417b1a5c6ca2f8fe930d9eebbeb005e4b53f1cd090 refs/pull/4576/head\n00416040b6747a3e8a7be3193ed779a79f86d9a925c3 refs/pull/4577/head\n0041db669a90ff173429ef00945ffe9dbb9dc1893468 refs/pull/4578/head\n0041fd3d44277c859e7a6ff55572e2877cebe30f1e65 refs/pull/4579/head\n004081764eebc88f482aefba3bae569432a017c7e28c refs/pull/458/head\n00411cf348b2f825eb841cddb8008bf8b479dc5cca50 refs/pull/4580/head\n00416fe139c1e777fcc0b6d0ed3558206a110b5a50e5 refs/pull/4582/head\n0041918099ada2b9d6a14bfb7a6ad492ccd711b800c5 refs/pull/4583/head\n00417ed9aeda5b33f63b880a45fdc5446e5db9549532 refs/pull/4584/head\n004292b16ab7bb17eda0db8475b60fcdedf23d027f3f refs/pull/4584/merge\n004198349f433a09eb4d1b4b356465b9caf3d733c748 refs/pull/4585/head\n0041d62db24488b4b95e44bd232f6b72be3057543cec refs/pull/4586/head\n00410356afecd14dc8c226799107af5f4b36bc08d80e refs/pull/4587/head\n00414e07233f02c18866ba6dce17d99bd5c78b6e4026 refs/pull/4588/head\n0041d2ca8cc64c71dbf05d74224a7a7de449dd697886 refs/pull/4589/head\n00407a801651c73cfd940929030a727de719728ce93d refs/pull/459/head\n0041bdd996ebd52c17aeb08ce5f277a909a72c7d8c30 refs/pull/4590/head\n0041e4327d276694280efa6b74b48cab92be702d7123 refs/pull/4591/head\n0041586b5cf9466d18d7dea895d78753b05b311fec08 refs/pull/4592/head\n0041a48e28d0d3d289262281e402f50edcf652432937 refs/pull/4593/head\n0041924112d93b83dfbdf271e281d4700b2917d929ae refs/pull/4594/head\n0041bcd71108976f129dac0c33b1669c72241f854e22 refs/pull/4595/head\n0041fd9029a6a53e0c53641553111c727cb963b713d3 refs/pull/4596/head\n004153da93dad22db51884a8d846c438b749bf1d26b1 refs/pull/4597/head\n004136b75f633a7b35a3db5135d32b99a256adfad962 refs/pull/4598/head\n00414dc4e04a6909135d3680033601c826e0c62f3593 refs/pull/4599/head\n003f17f025d395375c10d8caf9405f854c3ac2a71029 refs/pull/46/head\n00408e8824a4cea0bbd102d2ecd74bd370b7ee1ea6e5 refs/pull/460/head\n0041bf7bf6157f802f4f7a97749e554cb518058f9a1b refs/pull/4600/head\n00414b83ee3013338799406862d1d25cbd42825ffef4 refs/pull/4601/head\n0041e44f5c1f6651c2351e30344e82d787a8b838df50 refs/pull/4602/head\n0041735064d0700f68cfd763aa2d0ecfcd4ee924e0e0 refs/pull/4603/head\n00410b3e6f42f7e508a65ecb8ec83ff34d26d2794757 refs/pull/4604/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4605/head\n0041d3f49e2ea0b7fccbc9b84c4b41597fd0f3cf32b8 refs/pull/4606/head\n00416767c8ded275dabe2a757cbd7f9319bb9c308f38 refs/pull/4607/head\n0041c3867bf3fd4cba1d08fd14212b6bef0aa63b0660 refs/pull/4608/head\n0041b1b96ba889d85419d557b33e4b3d07a0481a12d0 refs/pull/4609/head\n00402ad8115ec45b86b82cc7cb16479c86d27fc2e3ac refs/pull/461/head\n00410c3b865c16b0a520239924e8e87a95a284e609bd refs/pull/4612/head\n0041f7bfff121303771954c5c9306f4aa847ea184c75 refs/pull/4613/head\n00415b1951316dea5640351ecbbac2cc898564b25202 refs/pull/4614/head\n0041b41d9f8b138d6d57360af78b44d4839e22f38389 refs/pull/4615/head\n0041d0b3a3ddfb64e57b68df40a235ed94509fe8bc46 refs/pull/4616/head\n0041b289320df984eb44e60ebe77ab23070c79ccac32 refs/pull/4617/head\n0041f41a6c96d9b6e071f0cbb6abb50edecd9e03c53c refs/pull/4618/head\n00415a24bdd436ec85faf286ec06875c149e7963246f refs/pull/4619/head\n0040645c7a8624ac1a4f14b458244f75cbd7c4e8042b refs/pull/462/head\n004142531a4b2753f0c21ec9a1b10ef14b157f508a8c refs/pull/4620/head\n0041eae6eda0a590e0ad731462df728bffe5f02035f8 refs/pull/4621/head\n00411d20e0ca1ff1f7775460e67265ef376cd76e7220 refs/pull/4622/head\n0041e89a75b4106589b7f93f87a934d29dcb75c82910 refs/pull/4624/head\n0041d613ce4f1e239f942b8ad135fec5fdb661b28098 refs/pull/4625/head\n0041339f073724613569b5b0a8b69550f5e6f86d4376 refs/pull/4626/head\n0041f17bd6be456e70c1db78eda5965d7c5e869245dd refs/pull/4627/head\n00413e6094791e7f7e2db36a1a2b551da0c1f684d0d3 refs/pull/4628/head\n0041e5e2bfd7d29dc6ee14f50f7fb3cbf8e9fcafb3f6 refs/pull/4629/head\n004043edd2608e6e8be14b6c71b0805e14736f5c0db2 refs/pull/463/head\n00413d193d7877e90df0999787449e5021833e3420e3 refs/pull/4631/head\n0041149c4d4a4352dff2db6acd5247594be51f136a09 refs/pull/4632/head\n0041070a0d2c98c87fd0f3157b64a609f99ba86fa7d4 refs/pull/4633/head\n00411e06341f28d933e446744af72045dbcce01864d5 refs/pull/4634/head\n004153ad7d099b4dec582d4b7bba00cada5660a97270 refs/pull/4635/head\n004157f187ef2130f5b09266e1d581ec880e8bd05466 refs/pull/4636/head\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4637/head\n00419ad501bea8c78e1946dcfef5b362068502dca2c7 refs/pull/4638/head\n0041f1dfd356314caa5d480fa7d27f00c2e3e3767af6 refs/pull/4639/head\n0040a8e02bc9f84fe22f8d5ef368f4bc52a3d51ccecf refs/pull/464/head\n0041ac83a8d0ef16e56b5a2754fcdd31810d1c2f33cf refs/pull/4640/head\n00416015c0ace1b4434337cdbec58555ed4f8c313f73 refs/pull/4641/head\n00411bd7f283688873c2848ca0dfff64d390293269d5 refs/pull/4642/head\n0041b207a94f1772445cfdedbe9a2207ca5335d8db9f refs/pull/4643/head\n00410a1bf6fb84d3ec374fdd66cf2b9726ad80674b06 refs/pull/4645/head\n00414596cbce1bef5f456dd0e26c5b863ae05d00244a refs/pull/4646/head\n0042e9d1fd4a0736292538f936fee2b2b0fa5bea9dca refs/pull/4646/merge\n004152e42b25386c17e03a4e54f929ab753702482966 refs/pull/4647/head\n0042b021cfb7fb16c3618559692ca5dcc2c0082fd94e refs/pull/4647/merge\n0041f3ba778cf6b27bc2944ec5cdafb67a71789d8ad1 refs/pull/4648/head\n00420373e282786505981e8275ae47f4273e6ad7d7f1 refs/pull/4648/merge\n00419da4f74bfb9f43eb713c4cf01b5d3aa70951ee0d refs/pull/4649/head\n0041f07e60b6e8dfbb2b5659b2e02b2c3f678525b394 refs/pull/4650/head\n0041c70033305a3a2879c786521d8f28a3e791ccd2df refs/pull/4651/head\n0042a54abd0abeb402ad871e0c1a1e1a2b628054d1be refs/pull/4651/merge\n0041b5f5b05b4ccbc9125b751c028cc2ca34f251d111 refs/pull/4652/head\n0041f922262ed029bb03359337f676872e77f3817f28 refs/pull/4653/head\n004124ad88a5b05e61c98c04b63e658edc2a9036b9c4 refs/pull/4654/head\n0041857fa943448ac2f300013f6848da1318cf7615c1 refs/pull/4655/head\n00413ed92e000db5f62353d62e735ed3bd99e45c7ede refs/pull/4656/head\n0041dbd849d2d69d52938439c8a4cc21a0c1075f110a refs/pull/4657/head\n0041ee75191c8e58633f70cbb0330914e1426e9989cc refs/pull/4658/head\n0041466874c00046a019399fec843123226063c68c2b refs/pull/4659/head\n0041652cfe101926b48c0348a493db6c60bed37ae204 refs/pull/4660/head\n0041cc28afd832b3d267568dc218f708c0247690ad69 refs/pull/4662/head\n0042ad218eadf50546950ee11a0ad9dbd4239b167d85 refs/pull/4662/merge\n0041ca5c578189e2769aaaa150c9e985f99d9c4c1018 refs/pull/4663/head\n0041a454452752d015434d23f8751175ed3f853958bd refs/pull/4664/head\n004187769ab8edca7b8f7dc66e8afe5d7943a9e38221 refs/pull/4665/head\n00411d732f3fe14108a734008d43d5244c7df243152c refs/pull/4666/head\n004144b3283a3180d2eba0a7da45cab1f15cf43a0b8a refs/pull/4667/head\n00412d3e719533830318162dfc73e232ecf4b8ef80b0 refs/pull/4668/head\n0041a4fc5b66f3b23412b1b7d23dec17c1600c12c3f4 refs/pull/4669/head\n0042dea1ab31ae5bfa554f9ef5545e3e652dd564c962 refs/pull/4669/merge\n00411dcfe152bb9e5f0f109dabd0ba53227994cb0aa4 refs/pull/4670/head\n0042e5d2ddd9756f32ca22fc37e22f2cca52af672d32 refs/pull/4670/merge\n00415e0ed433516a5eff6a33b754f2caef2b4892e410 refs/pull/4671/head\n00423a16c35f98d705649baa17fb703a5e7f4281d5a1 refs/pull/4671/merge\n0041b05ccffa307faa4a2c9c0067e095a64b237561d3 refs/pull/4672/head\n00425cb5b2cfcc9afcc99d28f764cf1cb0573316c0fe refs/pull/4672/merge\n00415a5ff38051a5ca526249a10cda25f0932a8e5bb5 refs/pull/4673/head\n00412470830a0585b755e44a76996e8df6234932659f refs/pull/4674/head\n0042718ba688b6aedd99527bb03fab6d7b7f73b96ea6 refs/pull/4674/merge\n0041c299c85a5d73c9ddb4a631376173f21bf52a6603 refs/pull/4675/head\n00423810d5fea7faae85482d1e42cd419119c0ec1703 refs/pull/4675/merge\n004138019c477faed48bb9834fdf78d761d9bcda2026 refs/pull/4676/head\n00423f0cd5c96095298a47fe4c9db053be43ec934f34 refs/pull/4676/merge\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4677/head\n0041f9f90576bf467876f38e70e014bfeda6775761b4 refs/pull/4678/head\n00410da4547ae37fbc12bf447f522ceffbe99de4154b refs/pull/4679/head\n004166c5a881a5c0a7612af16a07414c78b777036564 refs/pull/4680/head\n0041c193385925c2d0b4109ccd55d2509f71d5c8f775 refs/pull/4681/head\n00419f3705f85cdf31abcd7fafc35bcbea673904fd76 refs/pull/4682/head\n00414069414bd7faf9899ffb83b1f364230ef149d392 refs/pull/4683/head\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4684/head\n0041f9f90576bf467876f38e70e014bfeda6775761b4 refs/pull/4685/head\n0041337773d1f3c26d37ebd4aa94a66e6884c24c4e53 refs/pull/4686/head\n00417e419b3eba7bd83e496a22db2b78917534c46dc8 refs/pull/4687/head\n00415cc2af0e3bab7eab2af1c7b1780ed33149a54780 refs/pull/4688/head\n004191c7be7e6a9d2e4857424142f74b08ce4295ae63 refs/pull/4689/head\n004019e4617dd5586b7379228783a7dafeb3ad5cd6d9 refs/pull/469/head\n0041660485339552438a864a5aa7648299071d85d8e3 refs/pull/4690/head\n00413f9e8926fb6af395c7cb3f798addbc0660a62c92 refs/pull/4691/head\n0041c943a738814c4fd29a8130273ae2e39f43c2bb18 refs/pull/4692/head\n004192a9a438fb2a2f8f53f1d6073d7eefd7293da553 refs/pull/4693/head\n0042c63a5959cda3bcec88d3464acc0f7c66642e34c8 refs/pull/4693/merge\n003f539bb6345b3c521756c3c68fe01fb5476107f4a5 refs/pull/47/head\n004015b2c3c4fb3212475bb30d16a595d3a48754572a refs/pull/470/head\n00407425fbb17e658c1bee3286023c1be47c1be1a268 refs/pull/475/head\n004009022111d128e5a2b92d7b332bba42b6c0cc9481 refs/pull/476/head\n0040c32943f2eb274bc1228e9e8b963ff23e493c8b06 refs/pull/477/head\n003f7942542b7dd62c0dcfef6d099ad55bd4001e223c refs/pull/48/head\n0040da63d307f10488113dfd52696218ba82e66888a0 refs/pull/480/head\n004008724c7dedf66677e18fb4e877c20b947a4dd280 refs/pull/481/head\n00406f75999d1287efdb029d48e401917387e8176f44 refs/pull/482/head\n004077e6725ade995f3645a437f8f7d01eead3d2c4dd refs/pull/483/head\n0040fa824a4cf86acfc9fc7635f2ca89f578b11a27ff refs/pull/487/head\n00402610a4e0aef51b5b50cfdf88ed6cef4937a1c4c0 refs/pull/489/head\n003f828d3229892fd337355b2856b1e143c9a4094b7b refs/pull/49/head\n00403e436f16bcc8ae364867d9856fa0313f7fe1d465 refs/pull/490/head\n0040898ab0d1f6a863e64cb2c3054352efb975d1d5c6 refs/pull/491/head\n00406afdc81c1d56e7f166b33bc9465bf5735ed07a00 refs/pull/493/head\n0040421a88cac4c87a4199cffc08e7691af1fd094eac refs/pull/494/head\n004026347349cd6a174d168045bd73247df1831fd8df refs/pull/496/head\n00400da1b610c614aaa0bfb1cfc1c10f41080ff9589f refs/pull/499/head\n003e3f49bf73cc697e83b998d15d4c24b3b2c3cb422f refs/pull/5/head\n003f7bc22854376474f99e947eaae5bf55356033295c refs/pull/50/head\n0040bf63148464b0f0fc6c22ad407eeeb9ed1a3fab37 refs/pull/500/head\n0040fbc22f7cdfc425d0366f44dfa63c289f44251fd4 refs/pull/503/head\n0040d44738e6a75cef1e7dc125c06ac945928141f490 refs/pull/504/head\n0040427e5971ce9cf4b05e1588d2066e2538a10f937e refs/pull/505/head\n0040738aa6298e56eae85a6cc212ea98b3ced3018cfe refs/pull/506/head\n0040dcbea96afc409df97fec6a03581268c818928c44 refs/pull/507/head\n0040ea0cd0b85f34b49b41121be2e1fc4d99cd62f95c refs/pull/509/head\n0040252460ebc4d89d1dd62a5e612219d8385649fbcf refs/pull/510/head\n0040a848819f56bd450742ce97cfde7a1b1c795f29c6 refs/pull/511/head\n004030158afd5f5c4314b954c222995dfbe5a0f6df6a refs/pull/512/head\n00406e075100aa09016ef384ec63c236244b32993e7d refs/pull/513/head\n0040ac40a5c9a4856ba3dc47533000c771557539cfe0 refs/pull/514/head\n004019e615fe83f329f04795aa8fd731691151bb114d refs/pull/515/head\n0040d1e6176b7bb89fa6c8ea59bdb94fce36dc20a3c6 refs/pull/516/head\n004023eb7dcaa2cf76e6c3187e95abe5962a5d984b17 refs/pull/517/head\n00408674ea9c7625795693f59620466dd3b91e1acf6c refs/pull/519/head\n003fa5aae997547532051254c3543fda04ecdd19e151 refs/pull/52/head\n0040fc6f375311fba3fb12d1cf6cbeaa642eafd5bac8 refs/pull/520/head\n0040ba7681ee4add1983739689110e7aaae5217bf1bd refs/pull/523/head\n004095935609f8ceaaec8d796ac895526680beae5a73 refs/pull/525/head\n00405f50e2b6afc3c5a97f24e6662359614b880cbeb9 refs/pull/526/head\n0040da429589631564615fa152d04ef8395c05bdc2a3 refs/pull/527/head\n0040a4ec96c9a96bef7a2f2318e1afdeb3e768373713 refs/pull/528/head\n003fd92b753039c86313e6163de3beec7e80e7715409 refs/pull/53/head\n0040b9cc4337fb099d98b1794d6245d2d16413be0843 refs/pull/530/head\n00409a5c0ba757500434d094996c10086fc1f137f26c refs/pull/531/head\n004026bf9a128ff64e0c41da850df451fefc9752b0cd refs/pull/533/head\n0040f641a629b070e48aaa81110f5ede97c6a4c5d74e refs/pull/534/head\n00407f0c4e8bbc6feb8cf54ca2aadf9ec681f79f031c refs/pull/535/head\n0040eeb08949f3b66a5988f2d22a7a09ffdc34c95765 refs/pull/536/head\n0040187e24c0df8e76a9d1221f295451cb5125d19b65 refs/pull/537/head\n004090263ab68bd9a54607c3e087b98b0e615e193c3b refs/pull/538/head\n0040b2f2ba8f1502c725d92632c35307b06223605d5d refs/pull/539/head\n003f4069e9ae46887eaa1ea25c0c41990d4a152aa790 refs/pull/54/head\n004008d0fe5bf8f16f7f129dd6b16c076680fa70bc47 refs/pull/540/head\n0040fa4afd68017c51fa9c8fcb234f7b089a6a6bbe16 refs/pull/541/head\n0040b643a0cb471374c0d4fe2c8bde45f7594e0f808b refs/pull/543/head\n0040fe94b87d5fcb2289f2c49ae49e248fdd8c49b335 refs/pull/544/head\n004022da7087587feb96d7a1d4f179661381d49bb32f refs/pull/547/head\n00400c72efdcae6f3e9587ec6a4b63d1946decbf5fc2 refs/pull/548/head\n0040192ed93b86cb77de447798c3ea78ec0722bc6b83 refs/pull/550/head\n0040db24d8b17db7af20dd8cfdcaedc9af2c78999bc1 refs/pull/551/head\n0040b47ce783b533222dd8cbb1afb6d9751e9b4b5d4a refs/pull/553/head\n0040c2af63cc54340534c6bcf4057d99889b20b47636 refs/pull/554/head\n0040532b5912133864cda5255ab022d4e5a66ad6d26c refs/pull/555/head\n00406ba69f1c26ff46164fba4b7099f3cd7c22ab6dbc refs/pull/556/head\n0040bbdec22161a3f6db0f3b40b8936f4a1adaaa58db refs/pull/557/head\n004056dfbe6300ff4b2063a57341a61f46c7de7a70a0 refs/pull/558/head\n00409ac3f6d893e9ad8f45ab12316f02c6a9ff55319d refs/pull/562/head\n0040ba38432d6c7074beb6eae72d03bdb567b0f713d2 refs/pull/563/head\n0040fc97f30299e11bd3fbafe60764a31731f1634c40 refs/pull/565/head\n00403b36449491233aa92160be5b68dbba193d9076bf refs/pull/566/head\n00404eba0eb5150020b0d69521348d7fbf3a2c44c1d2 refs/pull/568/head\n004049f841c25b74ae3cd508751de9dea5a95791bea5 refs/pull/569/head\n00405eb4c715b6984f702da1623dc8fe3f17345e562e refs/pull/570/head\n0040c8284062668d32d8be4012eb6b3571601d88dc9c refs/pull/571/head\n0040cca202c87decfd33298805d39f1e0ce5d7706e28 refs/pull/572/head\n00400b5104a4cd274324a53d87db88e022db0c0b72d4 refs/pull/574/head\n004020d761e3eb61a0321240c667837033944ef5133e refs/pull/577/head\n0040ffff07627e6003dc180c47795d625265e49eaa64 refs/pull/578/head\n004081ff890139cf9f07319e35b0ff3abadc38171de1 refs/pull/579/head\n0040dc64e918011198790c27d086755312368dca98f6 refs/pull/580/head\n00401765f3e868446b5c3e62da393a56dc09ffc72f49 refs/pull/581/head\n00409d58c1bc6e71cb1642b883bd4dbd0d835de240bf refs/pull/582/head\n0040ab7f0f423544887488e868ed5e550ff354490960 refs/pull/583/head\n004071853facb839d4b1238a354ea0a351d49c1e81ea refs/pull/584/head\n0040f13bae2c6d98b3e4030829b22fc821770ac72bc3 refs/pull/585/head\n004044d51ed2e50cb3e102563d166911eb7f6d2d9429 refs/pull/586/head\n004031c4c6e5672aaa3c0d93fd4bc31f7a104da8d5dd refs/pull/588/head\n00401acb581ec304067bd5f7cc1c714d8627407b62de refs/pull/589/head\n003ffe060d229baecb03798c6da631dfaa440c4363cb refs/pull/59/head\n0040811d28418a43713df02b95fcdea0918e87c27163 refs/pull/590/head\n0040f189aca712ffbce0d7b8f52a2148911ff40d8681 refs/pull/591/head\n0040dab21a93594bd2f83f32d10550737a26220a564f refs/pull/592/head\n0040dd3ec750f2ac746991fad465a44ece6515f30acb refs/pull/593/head\n0040e04698a4f079ef9e47894c77955af5c92b18ed46 refs/pull/594/head\n0040ccabdea034f6711c9da311a6100eca55b6542cbb refs/pull/595/head\n00409b069b5258813122ec05532e1746ac34e457e31e refs/pull/596/head\n004003320f72dba0bf9c4a344710f69b87a157afb22f refs/pull/597/head\n0040be3378dbd616d7b54340c247c1c2b40a5d2dc46b refs/pull/598/head\n0040bfc79659cddb9b15558d224e7adabfc1f8c61a0c refs/pull/599/head\n003ee8c29e0fd94218fe15baad313b095318ca35e4b4 refs/pull/6/head\n0040bae47748988b81977e7c9f971264bd982cfc42f3 refs/pull/600/head\n0040a1207a57be86aa5062efdbe7425f233d2c89e555 refs/pull/601/head\n0040a7a1e4f3ac65de68af18f37122ffd61d17ef68be refs/pull/602/head\n00401ab0afbcd184742884308a6e56a3e33644e54cba refs/pull/604/head\n0040f90a58db535e3ed8615765985e74cf47ce6bfc3c refs/pull/605/head\n0040fce4824468778452a19d54587b292d54fcdee132 refs/pull/606/head\n004086229944c849912189292564b8fae2dceee5e358 refs/pull/607/head\n0040a33c5dc6f1afd4da09eb21b05d8e6b320bcf82f7 refs/pull/608/head\n004005da03548ea276a0e83bd3e09be9834a8335d2b1 refs/pull/609/head\n0040ea7aaf0e0c534a82dfd0d96e5ea91071c244a418 refs/pull/610/head\n0040111df9afcb9f748713819c7c5abd425a97d694fb refs/pull/611/head\n0040988d98f421372ef5d57684393150141159a92940 refs/pull/612/head\n00406b1d7b73a159a3b20822d8fa4b5bc67c9c6471d7 refs/pull/613/head\n0040c4fdd9acb95155be5de54d9f6a658963ca98aeaa refs/pull/614/head\n0040f627af3bf490043922397ce368d3761ddd005506 refs/pull/615/head\n0040135ec824a06ae39f81f8e27c377934d1630166d0 refs/pull/616/head\n0040c4246fbc32020ea7fbbd1605fb2e7ecb7351017d refs/pull/617/head\n0040c79e8f2f0d0dbaccbc95fc72f44bbac936137161 refs/pull/618/head\n00409a6dccd8ac5f09b248d10dc6aa3207d7dcc4f3ab refs/pull/620/head\n0040c16148011d21776980eee0651f63b35d1029e8b4 refs/pull/622/head\n0040ffa7757e6d0de881a130dca0cde5d7963d231ae7 refs/pull/625/head\n004029c076ebeea8b61c3de6c63be1a80b5c36fccbd9 refs/pull/626/head\n0040a6721290f78a1a87be815aaab182427c03a6b6ba refs/pull/627/head\n0040104aa8d0df412d7fa6dd3291ee7c7cd3f9c454e3 refs/pull/628/head\n004083c3e81bc80124a7f6ffab24a6ad363d21ff6ef3 refs/pull/629/head\n00407e27c01c5dc170601315055d1de35e13f9f4fe83 refs/pull/630/head\n004029c1efe8e632d99bc52afb03ba2f8af232646ea4 refs/pull/631/head\n00407dedbb1d778ee611c89e6192a9a9169821ce152f refs/pull/632/head\n00404d2e49cf4853f694ce7623eaf7427b14a9fef8d4 refs/pull/635/head\n0040e7759b9ea0d675599b7821de4ab7fbdebff8ea28 refs/pull/638/head\n0040cce335b1462e95c6a2a34b161dcb90130672ebfc refs/pull/639/head\n0040d0ebfd4e634b2ea6ecb0ef9c24559f928f0899de refs/pull/640/head\n004080c904e3541ff766a774812e6cc07b403ea88f24 refs/pull/641/head\n0040423b62ab04c89caa94f4d2933e50c3559d0fb620 refs/pull/643/head\n004009fd6885d8fed342f58ab5bf86093bedc5f8f73d refs/pull/644/head\n0040fb069a91a9f15fda5a19280f0c99640d467a69ea refs/pull/645/head\n0040e2e6ba84e35ba11a1ea66708250d18520f28a5c7 refs/pull/646/head\n004094492d52f7afdda992c36b0a77f1b3101a45645d refs/pull/647/head\n0040e4d92d4402229891c543908362e34609d1063ea8 refs/pull/648/head\n0040ccd48f7c3bf61e9efcabf76584d188f022399c8a refs/pull/649/head\n003f9114a985e210798208c0a4b006e4ae78090a63dd refs/pull/65/head\n00400efc4177ecd181cab57ebb287ecc28e4fa518e1d refs/pull/650/head\n0040c327d3e2430cdcf6a884e191313eb3dc1b0790d0 refs/pull/651/head\n00405e8bbc98709e96d4cbd9c1b9121d43cce69c0cdf refs/pull/652/head\n004016fd8b268fd8b700dae919c7aa0cca6c949d1d8c refs/pull/653/head\n0040738b63e7bf26a636163f0ade319a0c03257e099f refs/pull/654/head\n0040057b7008fc6d9ab71b28105476c59b8349e2baf9 refs/pull/655/head\n00406ba57fb53fbc2c28bd544b434f2114d0d6419ff2 refs/pull/656/head\n0040431353cf9c9ebb1cfae7f12912175f4d4241f663 refs/pull/657/head\n00409c52bf7f8c21616ff861e18284551f15594d8646 refs/pull/658/head\n0040aa5fe2463c7ff352df80b5e96de7458720b12bec refs/pull/659/head\n003f15492d0d8857c7f1f37cbf4b2eeba4b5fafeed60 refs/pull/66/head\n00409e0f86f98534e7b417f07857bc68f4b7be17b985 refs/pull/660/head\n0040e6e452a01407ab6a5558ff813f40347dd055edbd refs/pull/665/head\n0040cd5983ed4e8ce93df2d7d12dc895f707af7f1bd0 refs/pull/666/head\n0040a66d42daf1fe9876503a21c306118c8b8a30c3e4 refs/pull/667/head\n0040f0ac8954bd8a844cf20dd045c152f807b6c75a92 refs/pull/669/head\n003ffbd97671c4f74a3573ca677cb23aa2e5dc2b730b refs/pull/67/head\n0040f0f09665d993f70d81676fa66f11c19a962278af refs/pull/670/head\n00402efdcc262931d42e199b84a0c4e4dfa8fe296a45 refs/pull/671/head\n0040ab07111508ec90a01e73ad064f5e2fcac05134ef refs/pull/672/head\n0040c525494e4a3caa74a0fb416e1db34d08a85febaf refs/pull/673/head\n004021dc91864b8ba42bdf81fce2494a2d2932d9feb5 refs/pull/674/head\n004034b5a1693bec061f8d13d8a5f7a954ff5af2a5af refs/pull/675/head\n00406fd8ad1d71226e646fc414647feff755eb9d58f6 refs/pull/676/head\n004091d9a183c2c0fdce20ed174b27526b469f82c7df refs/pull/677/head\n0040285d000103910ca736e72f43579e98cab05fc9a1 refs/pull/678/head\n00404fadd0e8495d4dc18a4656cb36bf13d229d65475 refs/pull/679/head\n003f701296e9aab2698626720502d7988f6ec8534900 refs/pull/68/head\n00403d77783d0ccf43a1d2cabbb5cfd769cb5ac08139 refs/pull/680/head\n0040984749296a631d40a888798b9da128c25e38a004 refs/pull/681/head\n0040f323d77eb48e653933df4cb8ca3e7b6d4b445558 refs/pull/682/head\n00408043886ee609e15ac71eddde29f7ad593abdecd4 refs/pull/684/head\n004098f502db014ce6cdfb4cae3bf5d37ffde0f522f1 refs/pull/685/head\n0040c95ac10faee8e9d2b2ccc1c8dc564a2315d5dc73 refs/pull/686/head\n0040a2a04afe106b835d9301cd1f55a6a661a5ec7d1d refs/pull/687/head\n00407b19026b4dd4152f609170c0984ba552770ec2b2 refs/pull/688/head\n004060da188ac6f131ebaf8a0bca72daba511885bdd9 refs/pull/689/head\n003fefc80f95b21903ffcc79f2e3767f216d40d6e973 refs/pull/69/head\n0040c4843689bb037ac6c9351dbb23bdf42920e7523e refs/pull/690/head\n00404aedcc345cd1e3398ec8ebb1dfa6d56c08b3229a refs/pull/691/head\n0040bafe7bf81405775c49d732209f40234d49622c2e refs/pull/692/head\n00400d6d7c66b246d72c0d513a5827c7fc7ca3a5c0f6 refs/pull/693/head\n0040df57af56cc3896f95f502626faf04592cf6e4d8c refs/pull/697/head\n00400d369e0ff56c300f78e1b047b9ba7fd3a6305a1d refs/pull/698/head\n0040f555322ea73895e099bbd25c09c77c3d32742620 refs/pull/699/head\n003ee44f6d00df38bf536dfa16ac854a24b30951a873 refs/pull/7/head\n003f7a275cbf35e020572d4c83f90d0bba774f8151d0 refs/pull/70/head\n004045272168ba25f1d6a15abbb1dd3d25f2df494ca9 refs/pull/702/head\n004097e8173ae22cea5a2a4c1b5d2edeba24d590c4d0 refs/pull/704/head\n0040e7e01e7e31fd80d8560ece85e949bd7ee78df2c2 refs/pull/705/head\n004042536bfa4e70e88579cf472ac13a534dcdee6f12 refs/pull/706/head\n0040a2459380ecc080174e784a92e978dfa7d8d9c475 refs/pull/707/head\n0040fcc04802804190e699b627a9311c7825244f463e refs/pull/709/head\n003fe460077786c95beaf70ca516b10355042df8d0f1 refs/pull/71/head\n004090e7d78e8be39bed87f991fc9078a626e81054a6 refs/pull/710/head\n004006a9b8f4ee2433c22f584a63abcaedc056c4dae4 refs/pull/711/head\n004072d0f4ca688fc020d2689516409e0a0241a00549 refs/pull/712/head\n00402c1924d53a679253d237baa26aa707c4d9da8884 refs/pull/713/head\n0040e65263e40790c2c3c218953acdab20072c15e3e2 refs/pull/715/head\n0040cb40852db455619fd4d11df788f87792fbc50feb refs/pull/716/head\n004025d97b46820caa302f7d73b3fd0d3e480b7d10e8 refs/pull/717/head\n00403d2e5c60f73734d85b8691b4bfe8f3bf9ace2d59 refs/pull/718/head\n0040a7844ac08686fa01bd3945a36c71083eb865035e refs/pull/719/head\n003f0ea877f58dee1d05c10339ebf3e574324992656e refs/pull/72/head\n004077372613c5eeef798728a9acef6b9e6e47d7fef0 refs/pull/720/head\n00408db2f7e637a58b9c7f8de702d7840f855e9aa8ed refs/pull/721/head\n0040177f41beea015317a3eac047648304f31f51f97f refs/pull/722/head\n00404d3481fd5284b4422f6377d83b92dec187576e31 refs/pull/723/head\n00402f2a33ed706a8da32bf11e418f64f0479f19354f refs/pull/724/head\n0040e551d9b972d0789141af4aaa572b578ecdea1da3 refs/pull/725/head\n00404b51a02f4705e9bbd497f9e1e440583ec6ba154d refs/pull/726/head\n004032fcd859db96271b7f7b12858a8ea3ffe8c5a614 refs/pull/727/head\n00404fff6d895a94d46b666e645ec0deae52c1da5fbd refs/pull/728/head\n0040285169615c3f60fdf928a4828a25a8fdaf257dac refs/pull/729/head\n003fb34196165f7f457a62afc293ab4ffed18b95be24 refs/pull/73/head\n004078172ccc0869f65b849cb08d80cfe7a3623f0d93 refs/pull/731/head\n0040928ee035554495b878806ea5493b93748c80c5e7 refs/pull/732/head\n0040d037807f6550280434189d41f4528124b59c65c4 refs/pull/733/head\n004055e2fa977cf848c1e3cb4888135556744584dbe8 refs/pull/735/head\n0040066dfdf51f0ef7968984267bfcf1ddf0013d35cf refs/pull/736/head\n0040a121195bac6e62fc2bb01779aa93339bbde7c12e refs/pull/737/head\n00403e7facbd209ec39d303416abe591c0ebe7ef526b refs/pull/738/head\n0040056bc02fe23dffca388b0c71dc765e26c0ecefe4 refs/pull/739/head\n00402a631151127562c377721506f44e8d6d5464cef2 refs/pull/740/head\n0040d2fbcdaf39656fa110558c97f1ab571591e4a80d refs/pull/741/head\n00405a1114ec4d88ff3668fe0e362dd2b62969813b24 refs/pull/742/head\n0040ed0ced879d819f2e9ed7a2a46a0597bdfd83df67 refs/pull/743/head\n0040f358d39f0c738c2c7c4cf8151bca8f08cf5e103e refs/pull/744/head\n00405b267b0fa6717f2beb2da1be354ec7da6e3d8fe0 refs/pull/745/head\n00403d4dafc7a7f3047623538ef822fe7f93a28e8553 refs/pull/746/head\n0040173c7b2fb299d6d1dfe20349263a54eb7b08bfa9 refs/pull/747/head\n004081cfe17eeabc9775da65b2f15a9cac4c390a2c71 refs/pull/748/head\n003fa2064306c0121b9a1aa51349945f2c0c25183cd9 refs/pull/75/head\n00406275137133743c4310697fdedcff40c627e27c8e refs/pull/750/head\n004068f0993f418e32413af9f50e735ebfb10c94f4ea refs/pull/752/head\n00402b32cec5276d0ae3bc64bc78f8f9fceb83813b1e refs/pull/754/head\n0040f55a27997d1c23c0b386b63e9fff8ea193d6262f refs/pull/755/head\n00408783d3640b8a971fa809dd1cad2a604ff202cde1 refs/pull/756/head\n00401acba9a0352ceaeb95654294bb27410a722648da refs/pull/759/head\n003fcc2a1d6ce103a8495ff4f3b507929029fa1a3dbd refs/pull/76/head\n0040a4aa7c7fbaedcce1f1c68704a9898a2a9b0dbd6e refs/pull/762/head\n0040ca562adde31ebf443bb6f9247f090cb3a2a7de54 refs/pull/763/head\n0040af8fc879f64d994d84db36f6beaa1356304abcea refs/pull/765/head\n00408b031bf4c886555f37f97f9cbb8f5f84ba3e9896 refs/pull/766/head\n004081b890ba1158a718d4df4f03d7c83af82b576a92 refs/pull/767/head\n0040b2d17f6de6288aaebfb19197c68a105d0daba511 refs/pull/768/head\n004001e9d0c6cb2d19a033ac0e6d7bcb88bf2ca40daf refs/pull/769/head\n003feff68e7143fdfd30c275ba516541db0844385e8e refs/pull/77/head\n0040e84a43a470bb7f472d1a49d5fe14c8f89b3fa981 refs/pull/772/head\n0040cb8262e93c0cd4d084f887e1effc050b285d9202 refs/pull/773/head\n004010931bf93d7f9834aeca8777b326f7199cc52595 refs/pull/774/head\n0040445cef5a2eda33abbf056b4e7c3bf37c7d32db14 refs/pull/776/head\n0040d073d3b75f1da574628b0e66aead9986afda42ba refs/pull/777/head\n00407ed9cb607a89a7d57ffae5fd507af7a56db19c38 refs/pull/778/head\n0040dd60736ffe81fe26ed0182e4c7b31b89bd452d91 refs/pull/779/head\n003fdf05d6c2be5809e2d85009f78e79fe33d27da367 refs/pull/78/head\n0040e05028469f918fa3c55b92c66588a53e7e19efcf refs/pull/780/head\n0040bb085e4cf1c3feac099a7ff565053538b608ee3a refs/pull/781/head\n0040118db1a7c25ba4d379b974cb9e79df363e05f10c refs/pull/782/head\n0040e932db9ea7ebf46b55669c7edcaee78d5a35afba refs/pull/785/head\n0040080e8a3a8d8598b786508898e33e6b1eb6a62490 refs/pull/786/head\n00403aca03c675aa27392e84bf20bf551b4f4c1c1e6c refs/pull/788/head\n0040d05b8a4bc1f572927875b238e07596e7e5996a98 refs/pull/789/head\n004018622bc349c54e308084c2d4b34b24aa22943f5b refs/pull/790/head\n00406b09743c2b7d220ba84a454bdbf7416875fe08ee refs/pull/793/head\n0040ae001437ad1fe79c20e10d8713b22e1d0fd77388 refs/pull/794/head\n004046b9797d8cdbd4bcbce41c3d85bc029d7fd04778 refs/pull/795/head\n003e34eaf08d34a89431d5c0882c84b9fa17908caa1b refs/pull/8/head\n0040ce2858dc43ca2f2bb87614399077d66bf9bb24ec refs/pull/800/head\n004070bed40651dbf77b56b8bb1ce937293072819c0a refs/pull/801/head\n00403ed253bef7c27d246c1c456686e95bbdbd80d677 refs/pull/802/head\n0040cdb43d4f1ccbc2292955c2315e5ac8d4d8eea146 refs/pull/803/head\n0040a896b1480f6963ea6cbaaf61415510ddf4df13aa refs/pull/804/head\n0040c36c7b4facf399d85982ca2e5f6a797b3be27ce8 refs/pull/805/head\n0040e2b4856726d3d53aa04854fa9713d27f9b830986 refs/pull/806/head\n0040e563eebdaa0362a95079661b7c22508c8d94e040 refs/pull/807/head\n00400ee37c80c0931d187305f8f7261d2070b8ddd80e refs/pull/808/head\n003fcc8715f28dafd700666d19cc38136cea248b1060 refs/pull/81/head\n004006d7aca733f2a97f169c125bead4fdf9f15f1f37 refs/pull/811/head\n0040bad54eedde4823b02aef76ad29f027b5ec55a847 refs/pull/812/head\n00406323fa304b8d1ea0b30f5255af372ea6c1d342b0 refs/pull/813/head\n00406fe4c87726530f7e1dbfd2da602d68c68db69e7e refs/pull/814/head\n0040d34f6f2d5e2628ba873f74b7432787cd3711b742 refs/pull/815/head\n0040de87980d51fe9110489e5b16eb58db6bbb1f5dc9 refs/pull/816/head\n00406e0613f124704bb9e7f186e591aa83d9343e725b refs/pull/817/head\n004012157a79870d55daba6ec78e8d0a60d7f275bf22 refs/pull/818/head\n0040dd6ce3c6e72b750253e2a63858bbae1093861dda refs/pull/819/head\n003f9d4d998dbb4cc5a5c519e611bb364f75bf34872b refs/pull/82/head\n004034438bebd4d9f64bce4c3560a859e4bd7ca03f57 refs/pull/820/head\n00407207b2633bef006b6cad7f30861be8783788c2f0 refs/pull/822/head\n00406231ac298bf965ade374df6300db26436413c470 refs/pull/823/head\n004062336dd003c07cc5c286ce0f3ab3774a5c31a612 refs/pull/824/head\n004046968d768edfb3f6186dd6dca57916e297c33dd2 refs/pull/825/head\n004097ad5aecced2f2acefe13953362f97bc2cbeda60 refs/pull/826/head\n004059fb92750d43c74758d919bb888106258da5a29b refs/pull/827/head\n004022b377d570d3ab3cf0452bf959730dcaf2825446 refs/pull/828/head\n004009376942a89475fc1ce482dc4532626161f13703 refs/pull/829/head\n003fe621b6b6e656eb468c9706eec994e214cc9f3711 refs/pull/83/head\n00408ad712de7bda9769fe5768094715a00d564c1980 refs/pull/830/head\n0040d5bdf9abbe52f4db1e27e5cd131608eeaae7989a refs/pull/831/head\n0040e05dec0d6e78948e6585f9b317025dd71d9c4fb1 refs/pull/832/head\n00404ed4040f268b03d9659cf4222ed43fc44602902d refs/pull/833/head\n0040a5965a59ba5bcc689d236cfc9616572771758a7d refs/pull/835/head\n00401f4a1d12005e416e3f5b2bc4f3a784c428aab57d refs/pull/836/head\n0040d1bfdaea98d066478100518578ff395acfbaab14 refs/pull/837/head\n0040c518afdc363706a7dceaed72544525b7d8357b95 refs/pull/838/head\n003f9169f1f08ea14d3fbe1b68b53713d28f5248d0e3 refs/pull/84/head\n0040d35da14e7b620f44b1b96c74c609b9b7921032ac refs/pull/842/head\n0040e657966ef3575b05376c51fbe7d40d357876ca48 refs/pull/843/head\n0040ec3cf43d42d8af6018a528f1440999b467b3f388 refs/pull/845/head\n0040115524d3bfee413ea472b6b9f7fc79d85955651a refs/pull/847/head\n0040e22599fd352a978201db471c884575423da0fe97 refs/pull/848/head\n00408fa56e28ad91e4be463f25dc465afcc0857b7669 refs/pull/849/head\n003fac40525168a1bf85ab0ddc2f1a1db98d12f2eda9 refs/pull/85/head\n00400ca5e64a00ed2653963337613893e97fd04e94ad refs/pull/850/head\n004035b917bdcc8dceefef5b948482f1731361832f66 refs/pull/851/head\n00403dafe29588e29ea4c751ea0b8a9abd3dbc18c3c0 refs/pull/852/head\n0040ab29b63a7ae6d672086e812604f58170059140b1 refs/pull/853/head\n004050a4b042a14e4aabd9166c8e64aece2dd3019df2 refs/pull/854/head\n0040d78b460e2fe03f1595d1aaaad5dfa3f2748bbed6 refs/pull/855/head\n0040fc3fa2c8c9d9e1f0e0f8b436793e9792bf2a194e refs/pull/856/head\n00407cdc4a8bbbb549de2f592599ee71eb869dc0f107 refs/pull/858/head\n0040ce4e48b794c9edb5d19dd5a5e1d2704af419105e refs/pull/859/head\n003f048d9dc2d9c48ca2d6d685cfae4cea7d74c075aa refs/pull/86/head\n0040abfb710d9ff916933ba72ac68062d8efe6b245cf refs/pull/860/head\n0040f4f48b5fb1288738e59a56853854930bc02647d2 refs/pull/861/head\n0040c189b851b3d5fe349399d249a90e0e68dc8f83a0 refs/pull/864/head\n0040182e26764f06d5b2be0b7c68715c14ba8d67684c refs/pull/865/head\n0040da8d774b89c336070340292a780d4089406d6e35 refs/pull/866/head\n0040ef83217f1cca19bb55f29ee2aa24630301184dff refs/pull/867/head\n00404cd0f4f6609e0877a22263b6aa8b0097b7600ff0 refs/pull/869/head\n003fc1bd40fff6ddfab1c3b4b0ec7b949b595a37f560 refs/pull/87/head\n004073d3324a956b6255e7057b91bf842c903953aa06 refs/pull/870/head\n0040ca189efb1d2ba63690064760fe4d5f44212d5eed refs/pull/871/head\n00407943f1f3061bab8519c31af04cd2865c5f773412 refs/pull/872/head\n00401a19ed0abc5ee0984002a534d94ad9d13a23cff6 refs/pull/874/head\n00409005e7448f74c76bfca8abd6ccc2eaa8033e3f1b refs/pull/875/head\n0040cb8158aec6e877cc7d19f6b8ce0d76466e9f2de3 refs/pull/877/head\n0040d9e51f14175ddc2e9bbe93dd042e1d6fa5c063e6 refs/pull/878/head\n00401c40b3f421108053afb348d7afa4cf218a1d0f68 refs/pull/879/head\n00409a5882322417a05b4f4e9624af90e4789f3cac9a refs/pull/880/head\n00408d07ee77a55d1e43753eb2f1b595e90dc7807472 refs/pull/881/head\n0040fd9a292f19de446cef18f7598e8aa671e9b8eb5c refs/pull/882/head\n0040360aa2c5e752b5454cbc4a2479d0088b38abc993 refs/pull/883/head\n00409f48dfb7ab50cfadb0b962420dc2925c3c6c0735 refs/pull/885/head\n0040a6ac8158f4df78287d9b9ad1de65dc57dc6a185b refs/pull/890/head\n0040766b544a82088b1431e3dcdd3e1487b9189d6246 refs/pull/891/head\n0040a0a34d7f13509a488214cfd2438f6be0146c1ad9 refs/pull/893/head\n0040afa6a135e83a9912c9f4d15357fc9938bf2b0068 refs/pull/894/head\n0040c2470e34de7765ff88749016b3965464dfd2fa05 refs/pull/895/head\n00401c5b91f0c98a065da1decc046eb7c42f814ac6d5 refs/pull/896/head\n0040107785b88da780305b58fc9c6a7a4ad62429857b refs/pull/897/head\n0040878be2f49793529c5426af095b857d85947dec4d refs/pull/898/head\n00403a3c8842ced25171126744d03956459b96fd2a36 refs/pull/899/head\n003e39a9b3d002d1ccfc40ae9b0ea09180f0ee210fad refs/pull/9/head\n003ff6ccf0665312025f8c067e65aa114f1e560535e4 refs/pull/90/head\n004064263d8202cfa4a6e230d02a85b4ab73f18af28c refs/pull/900/head\n0040b9d98f2c3292e12d1065e89381ecf2aac77b33bb refs/pull/901/head\n00407469149b4624705dc9eebb620bac1347e0a1f900 refs/pull/902/head\n0040758931949bb8fa3e07b86ab0304dbc8a545e4f6a refs/pull/903/head\n00400907842911fae6c1f24f295cfcdc1771316fd729 refs/pull/904/head\n0040d79ecb701961c87061812b420d0315336a5b8589 refs/pull/905/head\n0040004eb238767a74876370927993867203630406e3 refs/pull/906/head\n00407fa47247a434bfd4ea57e05c85d24ae3c8393fb0 refs/pull/907/head\n00402209d27550ca808b5741b75a5ca8f4ee1bfac660 refs/pull/909/head\n003fb9da4fc6bfe0353628c52d6c9909723cd3298a31 refs/pull/91/head\n0040dd96a1ef30474322eeae85b439752a2441648b96 refs/pull/910/head\n00401cafe4142ab230d9f40f7c376c7b2fa7e55275bb refs/pull/911/head\n004037292b1f0175a95556c8ab0496ec833aef6f562f refs/pull/913/head\n00401da7ae60e3d5ddd626f3ae779e14fa35d3920394 refs/pull/914/head\n004055eefd75947c9de22a7ab54aa2e66f9ae2d6d181 refs/pull/916/head\n0040991fd5a796b5a173af26608d89b2523856a8839a refs/pull/917/head\n0040a7092017e6221118f5374b13bdb94dd70cb931ac refs/pull/919/head\n003fcd8a45229c253b2ded996209253f557ebe08ea35 refs/pull/92/head\n0040310531041a9db2b3ea7be5508cba725a31c1e7b2 refs/pull/920/head\n0040103d74ad373eb791086aa36975c558d020329cf1 refs/pull/921/head\n004005a1330cb29ccc7cee7d07f282c9ea3f3ce09e31 refs/pull/922/head\n0040b14cdd5be1e9d43167cf8b45a12a8af94c7ab2f9 refs/pull/923/head\n0040ae5b1da48e019604c2ab11cfda3716bc93127e29 refs/pull/924/head\n00402ecf0d4443aa6fd0670d1258bb44e0502cc25be4 refs/pull/925/head\n0040f8d3be5358543d1e77b11da39ee430bbffaad72f refs/pull/926/head\n004013b646387780724daa44cb53406c374fa7536f5e refs/pull/927/head\n0040c80ddf9150a8a07a438a472b283f17dd432cac83 refs/pull/928/head\n0040c5790e77625a6551eca40f10b1baefed1364fdcd refs/pull/929/head\n003ff104599fd8d9a3e937e6afdbfd23aae03b06e70b refs/pull/93/head\n0040d051eee2415aea7e689f3f803c8b42d05bc7f261 refs/pull/933/head\n004067e4e665bcddd02323994332db1f0b36e9f95850 refs/pull/934/head\n004001c9c34786b8f29badce2ea7b8800d1d29585490 refs/pull/935/head\n004055ce8e32fc4100fcbe08168fa134f152ae03fa06 refs/pull/936/head\n00406e33ac2dc161d71f2093cd4b2069a670641da16b refs/pull/939/head\n003fe8e0531dff3e4ede2702f8a194806b479b6573dc refs/pull/94/head\n00409004fc8b94f17b8eb23f3fac7a40373dcf77370c refs/pull/940/head\n004031389c6fb390c4abf206763035bcc253913cb948 refs/pull/941/head\n00402609a321f2e80669a406d954210fd72be764b551 refs/pull/943/head\n0040d5f662f99a84d64ec471ac1380a5508b5b84cc8c refs/pull/945/head\n0040e9c463d00cdffbff59c5d93db522dcfc4d25a1fb refs/pull/946/head\n0040f192d01fefd5091b9b4ad9b79982485ea8589733 refs/pull/947/head\n0040d83110303c40da1d3625c2369eae7424928bfbed refs/pull/949/head\n003f9f4d26f01eaf7a63153e00738718899718630811 refs/pull/95/head\n004090c651e8a760809d5bb1d000200a51c636a0f054 refs/pull/952/head\n00401aab4ffc6737c651a7022c498da9bbe9d51a94e1 refs/pull/953/head\n0040dfada8bc4d47aee406e8b41ca5dcd37e5a46507f refs/pull/954/head\n004057853d8dfa95aa7e51955cec9f00308118779a75 refs/pull/955/head\n0040b2b34bf2041f3bf6b14c340aa8483b44d60e7ef2 refs/pull/956/head\n004002853eb3413c48d693f761af5d6bad64a794de35 refs/pull/957/head\n004048f6be2dc9e5cdcde851bcc3a36126c115ddc1d9 refs/pull/958/head\n0040ea6cf207519ea325a4db11bd7296ec8e3cc9ac0d refs/pull/959/head\n003f45027e2bbac111be570749575b37e391d01747b9 refs/pull/96/head\n0040c7c55e329178bfbe23eb01699ea2a53f30586fc4 refs/pull/960/head\n0040191e6f1b7e87e904cad92cad5baf2c0a886cab3b refs/pull/961/head\n0040fe2ed02e78802a6b0926426be167acab160c1c0b refs/pull/962/head\n0040a8a849ba63aeba05c5e9dd77b00164cc46b16625 refs/pull/964/head\n0040da9795a9634318e42c37ec19f80599c0edc59b0d refs/pull/965/head\n004037e9c36a577642e5eb7256f44781858b50030935 refs/pull/967/head\n004098d33cfab3240eb4982c3adf17c3a1e6a6dcf600 refs/pull/968/head\n00404c8394c17d6ac8f66dfe8ea52ea4f948021fe8da refs/pull/969/head\n003f4d2fe23287a89f1c5241c5e97a940696a840e17b refs/pull/97/head\n0040491d07d263295fc5aeb810ef76e8f2c6d427b3ef refs/pull/970/head\n0040186fa33372f1e4d38b6d3d5ae39d67a435775ccf refs/pull/971/head\n004066ac8a4f89fc8b05319d9a128f51414cecb940a2 refs/pull/972/head\n0040b9980b71215d670dea3099347dbe8c4218f9f110 refs/pull/974/head\n0040a6906775fd285ed3f2baed9a0e81d44ac0a0b3b2 refs/pull/975/head\n00408514919ec66097b5fb571d0664d96f39d768134c refs/pull/976/head\n00405faac7caaa0dcea41a17de0cee60ed7f06e1f5d4 refs/pull/977/head\n004080a4c2407a618a422fd423a30412788a04909d96 refs/pull/978/head\n0040c1e8209f39d44f5f593ae9294a1577d53bf1d125 refs/pull/979/head\n003f7aec67159650698184e602b4579273031479ba64 refs/pull/98/head\n00403555c83f3f7c24a3bcec994f0b6d5770a8ad2822 refs/pull/980/head\n00402c9160f8b13da1243284a53e6b9f087c822185be refs/pull/981/head\n0040a40a406de8e0cd31f3c5eee473ddf603f341c2f1 refs/pull/982/head\n0040ff4497970acdfdd1068d8e74c9cef8c12a4da5f9 refs/pull/983/head\n0040d13163df761ec75dccb17003c581847d50a2cc0c refs/pull/984/head\n00405b8617a847a2a203e498becbc3c0532748933ce2 refs/pull/986/head\n0040dcffa8e69730e0c02b9aa016461e87968794bb72 refs/pull/987/head\n00403b255d8a8de732f378204b6a875efc1b02e7d77d refs/pull/988/head\n0040a0f3cb6d034272ce93606a67d40df88af496e941 refs/pull/989/head\n003fd878692c990ccb8cc79fe2475f5ff23c27ac0619 refs/pull/99/head\n00405b7f7ceb1a0f94c7eeca65bf89eb14bbc0a59342 refs/pull/990/head\n00407017906a8b42b1ed89f4a460c4240b9e4580b269 refs/pull/991/head\n0040a5fe46e1f7d147ce127de02177289995546d3b97 refs/pull/992/head\n0040d23da7efa002b15768bd46ecb8e093d20371d162 refs/pull/996/head\n0040a512bb48e3b77d921087674f19a7e8b8eadb73e8 refs/pull/999/head\n003fbb69be3fc46bc36dc687a645679a227f7bab9eeb refs/tags/v0.0.10\n003f01277cf0443b8e7cbe8104c8e72bac7aaac15b11 refs/tags/v0.0.11\n003fbc9f4568c6f3fdeb78bf983a3bf3d90bdcccd9c5 refs/tags/v0.0.12\n003f95135bc1a18b70853608d492d6eb82e5702500a4 refs/tags/v0.0.13\n003f8de7697b3b8a73e79a73ec34f17ef0fa842cfbb2 refs/tags/v0.0.14\n003f932929f0f31584734b94339ea9cacf3158fd9bed refs/tags/v0.0.15\n004546391ffda5dbc429cfd440269a4972242bb0cc4e refs/tags/v0.0.15-alpha\n00481eff46c9d7e491d709680cba7e446d1fdcb8223e refs/tags/v0.0.15-alpha^{}\n003f83293a2b3b7931c39214afdbcf30573727891066 refs/tags/v0.0.17\n003f657fe2a8cf60492ae03045e7ca4da22a09be7f58 refs/tags/v0.0.18\n003f28d1e63275538cf8f3c3a5ccb5cf8f87ccf2aee7 refs/tags/v0.0.21\n003f236cdaf0470e94797989d232a85183f66ce6b61b refs/tags/v0.0.22\n003e9aa28d0a130e9174fb217921966b1855c2fd3f19 refs/tags/v0.0.5\n003e12e0175b9303f6ecca1ad8abdb3a28b3c97e7b54 refs/tags/v0.0.6\n003e95862388f4e9835d0b6e8136118e1799a064efe8 refs/tags/v0.0.7\n003e10b90c68bca21c632f4dbfd243aaedce25d00b3a refs/tags/v0.0.8\n003e737948b5060efeffb1cf47fe085d187a3d0304a4 refs/tags/v0.0.9\n003e8bc725ef48bc28a085f4a677afb983bae2558959 refs/tags/v0.1.0\n003ebcd7e4b928d8af37e459c2b25e1185e3f5ed4089 refs/tags/v0.1.1\n003ebd0d0261d4a654f8dadf52e66b654786673815df refs/tags/v0.1.2\n00439805438dc8731dabd78c8b3eb6871cb12a5090b5 refs/tags/v2023.02.28\n00438395cba7325954e4b3e3ed4c7ef3bfa82b428bdf refs/tags/v2023.03.07\n004363a89f6b9cafa9105949ba1616824ebbce62d007 refs/tags/v2023.03.15\n00436e19621c3acce9f66a817d0fbd825cd8edbe56ce refs/tags/v2023.03.21\n004329b7f68cc25aef244e46758a4c6548d366256e65 refs/tags/v2023.03.28\n0043ac1b1aa95f204bb6e1c0265a9d24139e9207d1c0 refs/tags/v2023.04.18\n0043adc4f6fa6de0b14e8c0ad9e502434d68ac3ddedc refs/tags/v2023.05.03\n0043ac1e00f9928257d8db85557e92d7efe44f5a828f refs/tags/v2023.05.09\n004310d72617f1ab2fdc9445b99ba18e723f60dc0750 refs/tags/v2023.05.17\n004311260570ad7c022286cc82840bae0cf8b1ee5350 refs/tags/v2023.05.24\n0043a29affe77a4c5de1e5421d9f53a8a0aa749d03cf refs/tags/v2023.05.31\n0043aed410e4badbc073a6910c11c8ca57f9fc49310a refs/tags/v2023.06.07\n0043433e32ef73bf683326d11d06e4f3d0cbe1e58859 refs/tags/v2023.06.14\n00437f4fb14bda2cc9dbbd8294a863092f64c2907c2d refs/tags/v2023.06.21\n0043b23615fb607715133806de0b12decc215cc95c2c refs/tags/v2023.06.22\n0043b937cdb360e93eee61a150c05029eb00cd404486 refs/tags/v2023.06.28\n0043efe2a73c48cfc8f358f304cf6d359d404b9806d8 refs/tags/v2023.07.04\n00438ce4d43aecc3b203df79565cad859d7798735a55 refs/tags/v2023.07.11\n0043cf318991793322189c5e44865a0355fa2ad69123 refs/tags/v2023.07.20\n00430f4e0c28da6fd9535d483ab63584d60a925bb3b9 refs/tags/v2023.07.25\n004338a28cd7123e13f90206872cc2e9af57959cabfa refs/tags/v2023.08.08\n0043064a3cb686cf44a66b061e914e52c9a6d9f4ecd1 refs/tags/v2023.08.16\n0043c6234697916921a270ab73511ae41e9037e15a5c refs/tags/v2023.08.23\n004372824f40c918f75abdb41ea13ce0513ee3d85df5 refs/tags/v2023.08.30\n004381506c929c86ba534d561e4cea236c7b2e1cbd98 refs/tags/v2023.09.05\n004322f7c5adc326fbda035d81fa05e3bfad80bdc9c9 refs/tags/v2023.09.13\n0043eb99b02ec8895fe5b87d1e76675ddad79a15f817 refs/tags/v2023.09.20\n004357316bd49932c8d37661cb03681b9d240079c7bf refs/tags/v2023.10.04\n0043595fc3e8b0210f23eff23ff853474e8700af2b85 refs/tags/v2023.10.10\n0043b374531b8074c41c7842183132e7e2804ebb3e84 refs/tags/v2023.10.19\n0043d26956b07351e0c695723507ad56b0aa59bd759d refs/tags/v2023.10.24\n0043e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/tags/v2023.10.31\n0043eb3b3c75b4b86d0537cbeaae55984ad4bf71a53f refs/tags/v2023.11.08\n004373315181865f9dd465dfea60d8c4a7359bad47a8 refs/tags/v2023.11.15\n004373b75e2c5b3c0e18f20375f4944b30b806b4cf32 refs/tags/v2023.11.21\n0043d039ca1b38f56a6c959eee0982afb69d1e56a65a refs/tags/v2023.11.29\n004381ea8ac55875b68ff236da7f44f91997c7b08925 refs/tags/v2023.11.30\n004392bce01c40ae5c4707aa46371cd31dc34562d88e refs/tags/v2023.12.05\n0043e15fe9260c2f2bff99184ca7a6bf5b8bd4ded5a8 refs/tags/v2023.12.06\n0043bbab1cd3a6494c4fc2101c19a832b52ee78d412f refs/tags/v2023.12.13\n00432a4022c818232b32573841a6f506796a25d13120 refs/tags/v2023.12.19\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.11\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.16\n0043aa584539a6f0085446fa53149a33c9385cecdf35 refs/tags/v2024.01.25\n0043e74a5dd172fada3ffb487d0c7c26db97cf2c3cba refs/tags/v2024.01.30\n0043f853bc9845f76620ec94f3662bf522fea0368a5b refs/tags/v2024.02.06\n004379c07c93dc01ed256032cb790eaae638a4255ee1 refs/tags/v2024.02.20\n00431defc72ba4297632dfb886b829f7a2d5299f06d5 refs/tags/v2024.02.21\n0043678f665a24414c3b425eaf40eb0eec62233aae41 refs/tags/v2024.02.28\n00435a8605df882d8a24c086655338e5f43fbddfe627 refs/tags/v2024.03.06\n004377ae40037a5c92bb3d04775a2fab70043ef7058d refs/tags/v2024.03.13\n0043f532637d69ac886df1fcf7b2e31f90b19df6f351 refs/tags/v2024.03.14\n004367f1b39c7aeee2a28ce5a41cabe113e4b49feb7c refs/tags/v2024.03.19\n004352136b5f1d38e09a5c687bd796feaa54fda7e4fa refs/tags/v2024.03.26\n00432ed3d46bd5c433bbbb06b72d7c0c171546646550 refs/tags/v2024.04.03\n0043927c0cae0f153597bf533032f086442e99a17042 refs/tags/v2024.04.09\n0043bc61579a635c9525a163775e42ae23886960ed7f refs/tags/v2024.04.23\n0043afcc49c52bbd1c6604baaa3a12809a30d5d3ad34 refs/tags/v2024.05.09\n0043fc144b751d26d8fbfc6ba15afc92fdbcd00a4fe3 refs/tags/v2024.05.14\n0043d0b1f72cfa19b5aa73883161682831392d8b5476 refs/tags/v2024.05.22\n00439ec5daa06fdace741958e4a7a20f7d1931948393 refs/tags/v2024.05.29\n0043bcb5dd13096cc0981647b113ca3ea142a7a517b6 refs/tags/v2024.06.04\n0043ccd849542895620faa4f323f44d7ad7ca543b5dc refs/tags/v2024.06.06\n0043d4509b6e3a2a6764c75f7ac316703b538ef3a1c2 refs/tags/v2024.06.12\n0043af23a17b9c54179b2253fccd1da19c38aef1b86c refs/tags/v2024.06.18\n0043fa0672b233985ca2e57f752e1f91542f80b8b22f refs/tags/v2024.06.25\n0043d6938bd6e6f2cba5cabb950fd86086f4c764e8c0 refs/tags/v2024.07.03\n00432cd1236084bcda3c37a80348c0de88c1aa103bb2 refs/tags/v2024.07.09\n00438c2b48a4bf3bd73e9f198966ddbb0bebd3d7cd6b refs/tags/v2024.07.16\n004394f08450539093e3f799533b698ead2f8cafea09 refs/tags/v2024.07.24\n00437295294bbc414041b103a0a296718b14aebd2632 refs/tags/v2024.07.30\n00437ca68fed3cf76d171473970f5bfaa3846a69b635 refs/tags/v2024.08.06\n0043d48073bcbcf12257cc249ff3698fcf94a16ceaaa refs/tags/v2024.08.13\n004380b888fa239ceef4062648f4259a5767f36d1080 refs/tags/v2024.08.19\n0043a81778d470873e2be57d3b8ae4fbf9f942e28c96 refs/tags/v2024.08.27\n00430a526fbafa0a00279ab6a74787ec265d65b8feaa refs/tags/v2024.09.03\n0043431fef648ff9b44f33646ac773abbaca71c48f15 refs/tags/v2024.09.04\n004365076b2b592d4e09bf0be039699969b455bbf4a8 refs/tags/v2024.09.10\n00433dd07d08451a9be3cf4eaf95e3fa0e0d8f3e8a9f refs/tags/v2024.09.18\n00434eadc85640729c2ae55ab05f0040cec03bf3b726 refs/tags/v2024.09.24\n00433508bb45f43df4268a8be3248386b828779cd95c refs/tags/v2024.10.01\n0043081f563d7307950d9c43237ee7cb965261496ca5 refs/tags/v2024.10.09\n0045fa9fc088b7fa8a2b10a479a17bbb9f46e0609d34 refs/tags/v2024.10.09.2\n0043033ea44ceed6bbc972f8f528585d15fc397d2e19 refs/tags/v2024.10.16\n0043af4b18a1540cf73c9ac67d1643b0a5f511d1bc86 refs/tags/v2024.10.22\n0043037050145b4bf7d09d9602e2c8042e4ca8bed9fa refs/tags/v2024.10.29\n0043ee286929b5e18f007d9649afd75c7bc4ce68c2fd refs/tags/v2024.11.05\n0043d58c1f6a1e88c451e168863057fb05fe0d323488 refs/tags/v2024.11.12\n004322cc4bc998323fb7d0bcfe4bb24e3d5715eda849 refs/tags/v2024.11.19\n00432d7b1e03bfd479a58ad56c339cc092669dd64707 refs/tags/v2024.11.26\n004391a0125e55c8902b3d077f4c812284d9116a5bbe refs/tags/v2024.12.04\n0043402f47d4f1fe547ba68ab39ac342b525f4cd7e69 refs/tags/v2024.12.05\n0043a5ef7137a2e3cd5c48e2b7ecccab5722dbf738d4 refs/tags/v2024.12.11\n0043732f08356e5f073aa275d36bff43da6b2b0177c7 refs/tags/v2025.01.07\n00433d55f553e28cc2b16152fb4df8ac53797b9d5c8d refs/tags/v2025.01.14\n0043f53c68fddaf2d760e0a00cca49b4b5313bdb0ad7 refs/tags/v2025.01.22\n004326d49d78a26427a12628cd3a1a4cd49d030c6956 refs/tags/v2025.01.28\n0043a9940a58b48f0a650632c37b44abdee0144d781b refs/tags/v2025.01.29\n00453be0a2314da2bcb3028617e4a05622aafd5beee0 refs/tags/v2025.01.29.2\n0043eb29faa1a45f8983502590b8ca68dcb2692ac68e refs/tags/v2025.02.05\n0043c2e9e5f6e41b61bb18e8e9f20924bd702d9fea47 refs/tags/v2025.02.11\n00436f66b0ed1fcd2394462a4268f2dad26ace3ccc06 refs/tags/v2025.02.18\n0043edde4b267a78ec2452e0ee7afcc21d02d7f18377 refs/tags/v2025.02.25\n0043f7e26092e0e8ced250d6cab7ae7b62343f2b8809 refs/tags/v2025.03.04\n00436dd9a9dd776e2c51c16f359c417256e702fbbe44 refs/tags/v2025.03.12\n00431d0fca0817eab7d932e4673e6837aae320708fa1 refs/tags/v2025.03.18\n00436d7c3dc69bc05e7e1a83f4389e61d430db288416 refs/tags/v2025.03.25\n00432727c77060f0174f96e12dad3070cb504c316ec5 refs/tags/v2025.03.26\n004304979978095630ecf30f6c3ddbc55e07ba8bf7cf refs/tags/v2025.04.01\n00439f7fe3920daf55fb156d8feb6143d939e3d5cd28 refs/tags/v2025.04.08\n0043e28ded887856f77d575be479212490d35e55e08b refs/tags/v2025.04.15\n0043b8445788211b3bcc04c32c77046503b14170c870 refs/tags/v2025.04.29\n0043b8d9f1b5afe0a8cf6ec02354fe2fd4516271b1d3 refs/tags/v2025.05.08\n0043139de7b69a2ea39e2113309b3a0a47aab920ddcf refs/tags/v2025.05.13\n0043b5f70ca94cb7beeb9d01269958275796f1b7189f refs/tags/v2025.05.20\n0043098ed8318399f68a9b2ef4b22c83687cacb85da5 refs/tags/v2025.05.28\n0043f3aa51f0689214ee9ce4e57173e56b933fda3649 refs/tags/v2025.06.04\n0043367e62dc034dae8d6a61362fb0d804906982a18c refs/tags/v2025.06.10\n0043d895bc431dc7c591919e5f1907bee1867eb6a914 refs/tags/v2025.06.17\n00437f39eb683c4de0606f91a1e624f905bae1407899 refs/tags/v2025.06.24\n0043e4f7ccfd19525dcffb1567c992a031bfa50220a3 refs/tags/v2025.07.01\n0043e536895df480f9925d50433216c1f6433d72c595 refs/tags/v2025.07.08\n00437102b14a4e5f4a2143b93b3be87b2d47a72ab8c2 refs/tags/v2025.07.15\n004307053097ab9dc03f53b5bdf787c0980035c87c77 refs/tags/v2025.07.22\n0043b87e0fd6d1c5443c32c36d85f86327a05682bfa8 refs/tags/v2025.07.29\n00431b89e9ca82d67aa78fc13cc0fda6a9bc52444b4a refs/tags/v2025.08.05\n0043becec66fa93053b7e64695306b180bc33834315b refs/tags/v2025.08.12\n0043968eb3f9fdcbd8a2e15b37f6ac8b27ec16f4528e refs/tags/v2025.08.19\n004363cd9d02158a08200ae269fea1a0a313a218d02a refs/tags/v2025.08.26\n00434bf6cd15e8ee92b5a0920996f78bda842ed23399 refs/tags/v2025.09.02\n0043e82714dc6454b7b7c4be0eccbac950c3b1a03006 refs/tags/v2025.09.09\n0043749e06b88234c9316282b9024b603c5c1957e194 refs/tags/v2025.09.16\n0043ad4bb44b99d34d27f5d36e8ab96afadc1fc7e6eb refs/tags/v2025.09.24\n0043bd0d0261d4a654f8dadf52e66b654786673815df refs/tags/v2025.09.25\n004343c5e13b27df13e9676783260963bcb8805bfc6d refs/tags/v2025.09.30\n00438c9069f6f183a02e3c71adc760190ded4331c402 refs/tags/v2025.10.07\n00439025fd1f9db05bb0d2309f616fd668b5b00938f0 refs/tags/v2025.10.14\n00431d9b902945b6ca026720f523329b2f18a4dc8228 refs/tags/v2025.10.21\n00435fc0b2fa2fcb22da1bdb83d287b21bbb39128585 refs/tags/v2025.10.28\n004330bc3412d57931a1fd7b5691922f01a11b811302 refs/tags/v2025.11.04\n00431b9cb07547bd39a376c0c57289db8d0c3740abaf refs/tags/v2025.11.11\n0043ca40ed0d4449c54a23c20dfbea71a841ec0d3a47 refs/tags/v2025.11.19\n004367b4d8b430496b96ad08ef544ad823674763dd8e refs/tags/v2025.11.25\n0043ff13718c6bcd1e67cba5c29768c4945d643078ba refs/tags/v2025.12.04\n004379c63772b6ba332725d1b65524a9850e582c82bb refs/tags/v2025.12.10\n004311ebfd72c6b2e4b45fa84d74598fb35f6a76412c refs/tags/v2026.01.06\n004311dcf751333eaa04f860d989afa334bacb13e397 refs/tags/v2026.01.13\n00430e50a12fcb7d0fd6b22d11930f1b95e65f790326 refs/tags/v2026.01.20\n0043c2bfb64e064cb9ae4462db090f4172e97e81ce94 refs/tags/v2026.01.27\n0000" + headers: + Cache-Control: + - no-cache, max-age=0, must-revalidate + Content-Security-Policy: + - default-src 'none'; sandbox + Content-Type: + - application/x-git-upload-pack-advertisement + Date: + - Wed, 28 Jan 2026 02:57:57 GMT + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Server: + - GitHub-Babel/3.0 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Vary: + - Accept-Encoding + X-Frame-Options: + - DENY + X-Github-Request-Id: + - 3CCC:2C39E9:3E0585:471CC3:69797B31 + status: 200 OK + code: 200 + duration: 322.049144ms diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache_adding_two_values.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache_adding_two_values.yaml new file mode 100644 index 00000000000..e1df54f0472 --- /dev/null +++ b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache_adding_two_values.yaml @@ -0,0 +1,105 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: github.com + form: + service: + - git-upload-pack + headers: + Accept: + - '*/*' + Host: + - github.com + User-Agent: + - go-git/5.x + url: https://github.com/google/osv.dev/info/refs?service=git-upload-pack + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: "001e# service=git-upload-pack\n0000015b5ffcce399241fd59809e7cc6e0f31a13c28ec017 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter object-format=sha1 agent=git/github-bdd2406f1b30-Linux\n003f5ffcce399241fd59809e7cc6e0f31a13c28ec017 refs/heads/master\n005372fd51767b95fa0ab298d580c1214d8b7ba67a34 refs/heads/promote_prefix_ignore_prod\n006592a9a438fb2a2f8f53f1d6073d7eefd7293da553 refs/heads/reduce-importer-log-spam-8993462065003763829\n0049c718cee0e2409df8bd503255fc60c21bb6d661fe refs/heads/reproducable-zip\n0062536d8403169585521583475f89d6ce5aa03e0a92 refs/heads/temporary_modifications_for_mass_reimport\n004e2c85053cfa420c869bae7ef023c52300eaa0ad2c refs/heads/update-pr-permissions\n00472c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/heads/upgrade-schema\n003e7588d54370e7336f1063b3ef96112797016c521a refs/pull/1/head\n003fa2ac801881f48bf9047dc4ca68f9587a4781bd7a refs/pull/10/head\n00407cb597c5a84af14690b0ea49312ed7eda06552fe refs/pull/100/head\n0041f8bcb25186df1323e6fdb712e580556202656a9d refs/pull/1004/head\n00417a8c671bc9e97f92924965851b471c8aab1ee8ca refs/pull/1006/head\n0041bd500a4044afbf9d5c49977fada634356c4fc101 refs/pull/1008/head\n0041605331fd14e43a8e905cea5164a62387afd51d71 refs/pull/1009/head\n0040e0cb2c344ca0730320533a43b10071b7f4312473 refs/pull/101/head\n0041485f2b6da3d617788879c786212a58557c12c5cf refs/pull/1010/head\n0041f94d9c56ce66d401e2ea5d53f3d9addf6a218fdf refs/pull/1011/head\n0041e20794697e7cc44aba013c331af176cb811ad551 refs/pull/1012/head\n0041694cd5f0828ac7cb3e2d9b320515b8ef03c2606e refs/pull/1014/head\n0041d52d02ff5c97f677510c7bb9b2985db39c6fe796 refs/pull/1015/head\n00419feb39025a7cf0fc86cb6ab0cea814e3c53c674d refs/pull/1017/head\n00401349f69d688fc7a509215f9432ec73dfb46b8a61 refs/pull/102/head\n00414c5f3de7c47d6688f77c4237bd2d5f60cae0cf7b refs/pull/1021/head\n00413809cd3109f476a78e197446c08bf33a4ca55c00 refs/pull/1022/head\n0041b13a6f1110ec13e0a8bdc0c01a6916ff0e354d3b refs/pull/1023/head\n00411eec3164523b5821d4c5f011871871b15fab207b refs/pull/1025/head\n00413348d2f75453c4e73887799b3acfab01a6bd73e7 refs/pull/1026/head\n0041b53cbd1cb21af23acc46a7954291b63dd5c3ac95 refs/pull/1027/head\n0041933eb1962638d9dafecde200304b15fb5408d3b6 refs/pull/1028/head\n00410a12cc1f3413dae4d84d63ad8ed1c6061b329347 refs/pull/1029/head\n0040cac8c823c650078345e35c8a813f38599775b833 refs/pull/103/head\n00411098e2c8c83ac74d287172b8e0fef6f68a1b1b65 refs/pull/1030/head\n00413b911bc5ce4f58aaec84b36fa7221c9e6b8aeeb8 refs/pull/1031/head\n0041ae07ed72ea2cf91193f8641ab0171b81d226879d refs/pull/1032/head\n0041911aac60254233f36c9fa8b352d9b8af3659a2b5 refs/pull/1033/head\n0041188ddfb6d0fe396bc04f255d7a397da940cc80fa refs/pull/1034/head\n004133f110d8a987995a37085a6f749731ba6079d10b refs/pull/1035/head\n004120360a60cb396c3d3e70dfa97c221426e651f9b9 refs/pull/1036/head\n00419b7028075b186cb85fb1162626bc8d35ab190945 refs/pull/1037/head\n004118fc7c0fd0e0add81d729d5e94ad8752c1c57190 refs/pull/1038/head\n00410804317ab3de7d5f993fdac0a0a43896862a6ef0 refs/pull/1039/head\n004053587e5a82398d23e39165d358f8093f797c5aa2 refs/pull/104/head\n0041fd4f821b02dae483809871416ac633e45836f6c7 refs/pull/1040/head\n0041032ece4b67ad99947c5c87d22e7474bad94521f8 refs/pull/1041/head\n004124080a2e01350075cefb33f912d77193d1f4de03 refs/pull/1042/head\n004136143d4cadc1bb7ab1fdc4d0dc7746dd19eeda97 refs/pull/1043/head\n00415b400eba34551913d34764cb8d5acca6f0a4f3ae refs/pull/1044/head\n00418fabf11f241e11624c91601a0596491ffa3c0d96 refs/pull/1046/head\n0041e3432ab171ecea3f25eeed5caebd19365f2753d9 refs/pull/1047/head\n004155ffff4042fa481e0ad1842f711a9f17c4cf5329 refs/pull/1049/head\n00402bc665af22bd913071393eeb5b56f8eb8afdc032 refs/pull/105/head\n0041a0c78dc0629761e3d567b8a268b433bb336019c6 refs/pull/1050/head\n004116b14e3bfddfb2bc8a0823d218c9fb55c35caf51 refs/pull/1051/head\n004149a52d949c8c923a33f8714a2175ad46b5e57db3 refs/pull/1052/head\n00410376002d2b38a6232eaa8a66cbfba525befe984e refs/pull/1056/head\n004195c7d0521ed2ea24906a34903e6f2469d4fead2d refs/pull/1057/head\n0041c30a6319d0e78c5694e2049aa9592bbc549adca1 refs/pull/1058/head\n004168154d8f0d81656f0ce6c8dd682d62fb307537c7 refs/pull/1059/head\n0041d16773aa81db518a3a2d92c90f3e0c97dab5287e refs/pull/1061/head\n0041e28509db3aab8aa7529d0795237be7eba62081e7 refs/pull/1063/head\n00414388c2adc25321d6a6006b5e5a5c32ec4b667bca refs/pull/1064/head\n00413844a6050bc4d2e8a90a28ea675e75f07283892b refs/pull/1065/head\n00412d68c51e1abeaa462580db118c06976cae5757e6 refs/pull/1066/head\n0041765995426c75aca4ffeea95f17c9029833ca8ff1 refs/pull/1068/head\n004137c97f269ed9064f88019191bdfcefc7618f22ec refs/pull/1069/head\n0040e822ea91aa0806b3de8ad8c307653ac7ade7fce0 refs/pull/107/head\n00410408805073cb0949236ca0700989510dbc7a240e refs/pull/1070/head\n0041d5e2603a21f3a25aed411d6b306702b67b1234cd refs/pull/1071/head\n00419c0c3019d9151e70b86eb3fce732f67f002d1d85 refs/pull/1075/head\n0041655ae019e7dc23f7d0f0053ad0ab4b216ca8101e refs/pull/1076/head\n00418d05e98430ef70cfb241571300687e3d0b2da4dc refs/pull/1077/head\n004190a77a72bf7b1514f8d91f1e2e10dd27b685cddd refs/pull/1078/head\n0041ba4517b948d070865726525ce8f6f92bc082f74a refs/pull/1079/head\n00402ada540e49327edd5997909ef4c3bd9965fef118 refs/pull/108/head\n0041989ed566cf6bea122ad73b4ff33ec8f10277e923 refs/pull/1082/head\n004103380f4390ab124fb1e93dc866643794e852a1b2 refs/pull/1083/head\n00413791ee0d863a87b8569332494539fc64509b870b refs/pull/1085/head\n004194059682ef11325cf7295e0168965353b96e72c3 refs/pull/1086/head\n0041f1d03baec460b46b46334f40e9b6c0722f9a8548 refs/pull/1087/head\n00415b8db3e7470201d7b3e755144c413dbd55ce6f81 refs/pull/1088/head\n00417621c0df9aa340cc08461ad41a171cac9948df96 refs/pull/1089/head\n0041a201dd01dbbd2fe51655c2b5a772c94f07925fca refs/pull/1090/head\n0041c6183a91fa972b2b28978cd34bbc4ece0c93d034 refs/pull/1091/head\n004100fc04e29e3d78ed91f9713fdc9a207e24f4ee2b refs/pull/1092/head\n0041c1fb4fb270577a0fd2634c149f6d4de024fdf1ee refs/pull/1094/head\n00414b1f9f0b4053dedfbcd1094f9fe134a8a7591a1b refs/pull/1095/head\n00417ea4d86462f7299ad5e017bc8ca69c4970addb59 refs/pull/1099/head\n003ffe47213e95bdcc488ada1849e9a510bd6d2e36bb refs/pull/11/head\n004057843634a14a6b67f8e75e8493a36398f88c6061 refs/pull/110/head\n004130eb8f7bf2c089a49f240ec7d69918c0e2949e70 refs/pull/1100/head\n0041be9176bb6398a4305e45af0ba76f8c816618f2f5 refs/pull/1101/head\n0041839788f01f9d6c4bc25f7f2c599ccd4da8cbf03b refs/pull/1103/head\n0041cf14188cc12ef4de9d966a7f42165cefd46bdfa5 refs/pull/1104/head\n00421fb31e43d570a544d62c175fa325f27e25afb552 refs/pull/1104/merge\n004133f55e55ccd34157da77fc2ed8143f75a681fab3 refs/pull/1105/head\n00417795cd32bbb6492eb117e45001b498d3c4de704d refs/pull/1107/head\n00414ff9acaceaa374fd68c248096e24b0fbe6477c37 refs/pull/1108/head\n004179cfd7131dc021a00a1fc78262a56edabe4e8acd refs/pull/1109/head\n00400a5b4257ff2e70b78134c8c41067928b65d650d4 refs/pull/111/head\n0041e2043c6fd2f27b60945c85d68dd81f59c765cc94 refs/pull/1110/head\n0041a087b854e11a5bb8b43f79bb9c3c2cad81f0fa75 refs/pull/1111/head\n0041c88dcd99d1d61ce90db741986178851e94dde070 refs/pull/1112/head\n0041e394a186b01d402a32a06803e79041c4aac015f8 refs/pull/1114/head\n004137f9c94f61d6a9407286f144870376e8d0907779 refs/pull/1115/head\n00415b470a1df2c11ca8c7283f7dae08a5e689e7a67a refs/pull/1116/head\n0041ad2cfe753e9ad1405b82344b7e5d248a9fd23432 refs/pull/1118/head\n0041527139dfdfdc3872980f2cc48f88c1685702b5f6 refs/pull/1119/head\n00407d0bc21474662422503c1fed2f6efd38f29987e1 refs/pull/112/head\n00411db7266b0d3dc2060e099d33ed2d621b82c638cf refs/pull/1120/head\n0041c22baac1c31c2282b9c81f02b2d297e943e715e5 refs/pull/1121/head\n0041717810817a0a2b2878efbf4d655a5f3f02bdb4ca refs/pull/1122/head\n00415b047abac2af8c3454aa3f5d9e3f4fd336248091 refs/pull/1123/head\n004187bdc6bbe11b1f7111cb45b231e77cb543c03b7c refs/pull/1125/head\n00418ed6125c3266ee5fe16d90e8f0db26bdd21e9a06 refs/pull/1126/head\n004198b17c26f503a5bb857ea3435240a45f584d236e refs/pull/1127/head\n004145c24a202a91fce5c1f3f18a28ae2c328fb07fcd refs/pull/1128/head\n0041d89e784013fa44af219af4c59318ce60f8f05fdd refs/pull/1129/head\n0040a8e64b67ee50fdc923b4dfca8a026bb7b7e0f9e9 refs/pull/113/head\n004142ec9e39e560a60028b64ecbaf2bf9ffaea9acaf refs/pull/1130/head\n0041e90b84e7aeab7edf3bc569ea7b445e511c88d303 refs/pull/1132/head\n0041c1d699e161bc1bbfd7d57be2712c8ee1546db0b2 refs/pull/1133/head\n0041153b7f21669004864a63efceb934ac9247c43b44 refs/pull/1134/head\n00418a6b4659ba4a39a9f18d938a1303f35962bd2c63 refs/pull/1135/head\n00414b9e30d2079123127d445c57ef866691c2612c15 refs/pull/1136/head\n0041064e0107b717f35d289c101a8df5aa6aa49c14d2 refs/pull/1137/head\n0041a68a0cd38ab4f489191912d992c1d4b7fb598201 refs/pull/1138/head\n004196c4267fdd5ebc5a11abf2afde34952d11fa0e3d refs/pull/1139/head\n0040ad040b0e9fb545a5e5e72cab06eeed0457350efe refs/pull/114/head\n004168459aa29ef3251223f574b7902bae78890c3800 refs/pull/1140/head\n004158e5151180e67e209a300f98b10c8bd91d2f10d3 refs/pull/1141/head\n004197e7609dd55ff381e8b645373b38ecddf3615ad8 refs/pull/1142/head\n0041693895fd032c51b0c75036d9c41c6586ea59b306 refs/pull/1143/head\n00413665ffa0765a44fe402d9aded1e0997952d97bfe refs/pull/1144/head\n0041045004f0080fa316da50ca631055923d8383a910 refs/pull/1145/head\n00419c4c3d9bc4df26168813861503ae0920f7281907 refs/pull/1146/head\n0041c5b17cb731e4037a8b729ae71e18e267e0378f86 refs/pull/1147/head\n00411daf35f02314a6d03fc13e62beba958e2d504b4c refs/pull/1148/head\n004184160b5e6ed474b28230dce53c64b4de2be56660 refs/pull/1149/head\n0040efcb738cdef73909a1514edea0a2c3fc279fd0a5 refs/pull/115/head\n00416167e16bee3e6f04a58ee6e31717c1610e139f9e refs/pull/1150/head\n00414d3249741636a1311a19d70f2af571f9f69e2e70 refs/pull/1151/head\n00419b2fa3ecb7cf81be6030c621c98e1aaee8103839 refs/pull/1152/head\n004258fae47d57833a93c2114f003486a178c7fe4565 refs/pull/1152/merge\n004170972ff2903159bb09ef351d62f1f8a056b8cb2e refs/pull/1156/head\n0041949f1218bfc1a4a43ecc024517745812f8da30a1 refs/pull/1157/head\n00410b5fcb4e937e813c777bd6a1cee272e8ecb5c69e refs/pull/1158/head\n0041378637ce104c9282207fa33f33ef2a167fe430d5 refs/pull/1159/head\n0040853201302c759848d37893d94ba11ea590d61958 refs/pull/116/head\n0041e09188102ad3986443886927e92966e9e7592cc3 refs/pull/1160/head\n0041700d09bf5a8f85ccc34818ec42b6a546128138b6 refs/pull/1161/head\n0041d9ae5ece28cd3744db4545fafc3e91ef1bff6f2b refs/pull/1162/head\n0041850c562b1c00fbbaf6a88dd8193de3963a820620 refs/pull/1163/head\n0041e662a66092408df23b3d993227fa931b6c18bccb refs/pull/1164/head\n0041f47b8a51d42a9afdcf61d31088ee3d4d67a38ad1 refs/pull/1165/head\n0041bc14f54a67add60193012a25131e046ced831b7c refs/pull/1167/head\n0041f04422a14208718301ea5ab6edeaa9bcd8bb0b18 refs/pull/1168/head\n0041c4527fa17adf08abf20e61de87fb7a9cfebde6bb refs/pull/1169/head\n0040f2193ca860f0648ffc8f2e6de877f92a363e89f9 refs/pull/117/head\n0041d7e54154d56ac72520daded39ada968082c9063a refs/pull/1170/head\n0041b43ea6c0af5ec6a0ba59691044fc4f168993808f refs/pull/1171/head\n0041e573127901d5456835c3a14581dac8317df14710 refs/pull/1172/head\n00419eb7982d800aa6d091a70e1d66a025e86b0fdced refs/pull/1173/head\n00411e10841edcb227d69ce075d0023c1519e6b61899 refs/pull/1174/head\n0041165a91da2ba287ec682f675235313e0ffffc221c refs/pull/1175/head\n004156a22734341963ec2726e9eabaa51d7c0bbf9f57 refs/pull/1176/head\n004101a728fefcdf53a12d4190159ef3dd413e726d1c refs/pull/1177/head\n0042a37bb2235324744350d465f23b7ff91bfd16f36c refs/pull/1177/merge\n0041645b3c4efecc4799fe6e40282c2b86b941e58903 refs/pull/1178/head\n0041da3ae6f7076eced3e1905f2345136d0ff6f3dc9e refs/pull/1179/head\n00407485aac97090584e3815fbbc2273d97634e1e687 refs/pull/118/head\n0041fc120ce5c94b1a168b89a9664b75e703c00170f3 refs/pull/1180/head\n004131eb3dc0538687ab2714afb69fb4408e438db967 refs/pull/1181/head\n0041c9f32af3b88f879262a81554a5cf87f0d72fdafd refs/pull/1182/head\n00410e896c2d535ae2d5f1a0abe24c8185b60e50b4ba refs/pull/1183/head\n00413f8e4d222485db16dd53a82c1aa8d53dca62606a refs/pull/1184/head\n0041902cf79cf6c7107315190d647ce9afe83a1f46c4 refs/pull/1185/head\n004101021d07febbe1dc0964c3f3a4fe25bf2c864670 refs/pull/1186/head\n0041f40ed0b4032dffabc9edb601e3bcee77922d07d2 refs/pull/1187/head\n0041149fee3f435468ea5ba248158eef48bc6ab59243 refs/pull/1188/head\n004192a96024812d7a9471598ca7509577eb6f81448b refs/pull/1189/head\n0040fa878cbaca3a34c3a27763118e5b0d947aef3337 refs/pull/119/head\n00412745cac3b81bc800037aff2b3ab37709d37a7921 refs/pull/1190/head\n00415c4c55133d0640b0e2f6abbee881b1fd3a3356f6 refs/pull/1191/head\n0041cd47d6beab06c76d3a11d158c93ca20f09ba4177 refs/pull/1192/head\n004113d6b7545444c47dfd08faf6aa2b9e1ed6a8dcf7 refs/pull/1193/head\n0041a686ab68d088b2a72080224afa23f590c8e83a0f refs/pull/1194/head\n0041f97c4cecf158db398a7557d46233224436e88ac6 refs/pull/1195/head\n0041e010e5b0b1c0e50753277540087df697bbbddbe5 refs/pull/1196/head\n0041208f300c2b85b19840e4a105bfe1747cdb31be0f refs/pull/1197/head\n00416f67f17c15194150c498445ac4bb7f6b3cf2806f refs/pull/1198/head\n003fd90d93044396651a5760ab8619869f3ffa7e28a2 refs/pull/12/head\n0040d4fb3e5bf442245bdead885901391d6448f036c4 refs/pull/120/head\n004140a9bf1f01f1fcaff780c463653753b4b7b44789 refs/pull/1200/head\n00414e3c6c4f74cd604ee2c988d663a4f0bd5084936a refs/pull/1201/head\n004110475df37c8747ce46e549d8967bd366ae74bd4a refs/pull/1202/head\n0042d8416218ba39f441d66806e5e0b036e175c68d7b refs/pull/1202/merge\n0041a700e380ac386cc24c1054bb871d5293ac54276e refs/pull/1203/head\n0041f0e9d7ca384d95b257676adbe5db549b206888b9 refs/pull/1204/head\n0041e75b7e3be1f8eb593039e71c68c620ddca416555 refs/pull/1205/head\n00416d54b8e24ca11529459c8304de1d1775c21544f4 refs/pull/1206/head\n00410632e7fb91e7a0fed85c55fba17f03ffbca4ca4b refs/pull/1207/head\n0041b4179c0e8f91a580c494380568cc755b830cb0e4 refs/pull/1208/head\n0041d9a46d372622a55840ff16e713574aa5aa589078 refs/pull/1210/head\n00415f7ae1d59f7216a4e69bd9658878445f8354f379 refs/pull/1212/head\n0041ec47072f7b589b5076bca86e80a50b4ef0e4a67a refs/pull/1213/head\n00417a8297543e96cbfdca35deaf7ef482a887d82641 refs/pull/1214/head\n004129f6cd65449e9fce1dc070e03c5a0fd5d011c65c refs/pull/1216/head\n004188f0ba0dbdd1920ffe0212466eb97a47dbaf88e9 refs/pull/1218/head\n0041fab2e73d54951557743573f70d6eea1da3060157 refs/pull/1219/head\n00408b7243382787f405189d5180c5a574b3d725449a refs/pull/122/head\n004188a45b1b0f86c9d89061ef74d669e35f4a12a419 refs/pull/1220/head\n00418a99741ae7e5fd4f7904a0ab39bebf9c52347dff refs/pull/1221/head\n0041417322b4e9949268a0dc74de31e5157f85874fb0 refs/pull/1222/head\n0041a96feac6ea2180d6765f714dbf4ff177bf87ab7d refs/pull/1223/head\n0041c5fe75fcdd34799ea08d44f755f0fcdb8d874690 refs/pull/1224/head\n00418dac58da823f0c0370fff98e5f3d893cbedff65d refs/pull/1225/head\n0041c026d87119a26050ce707fd46d8e39a3648e46fd refs/pull/1227/head\n004122c1aba51dfe449915b86a8e89804362326ed46a refs/pull/1228/head\n00414d86f314d4f11c630f48fed1294af87fe4083f95 refs/pull/1229/head\n004095972d7b95720065b9ad13946c2f19e7940fe074 refs/pull/123/head\n0041a15cc8d82d9531f7a3c7062c5a44e1d74962db27 refs/pull/1230/head\n0041608a8693561c85a4519bad15d4477760b1213f52 refs/pull/1231/head\n00418499cabe2d26bdf79362cf5848d2d6c5feb4f3e0 refs/pull/1232/head\n0041097ff7d5dff9e064297f16888e671c1a8b20a54d refs/pull/1236/head\n00411ff8266b09309ce473a5fdfde6b23df95d91c4bc refs/pull/1237/head\n0041041c24c794f085f187c8b2626568c1ce9addc431 refs/pull/1238/head\n00417941b0db3a95531936ed7d492199e1c506f4b693 refs/pull/1239/head\n004092350c4dc465cc0e1b34e5f6c95379a19a88fe7b refs/pull/124/head\n004144e9933cfcd6f810b8c84a49654495b08aa96443 refs/pull/1241/head\n0041e3aeb1a51d39c98fe2d05d6a4e56881b8f308e98 refs/pull/1242/head\n0041297bc99ce0f1fe0c722646e878c48ca1b7359f54 refs/pull/1244/head\n0041ab57c19fb6878591469153a6b43cd200e5056ad7 refs/pull/1246/head\n00416bbbd03d1f609db86085779327329af0b870df5e refs/pull/1247/head\n0040ba000c0f39d232ea471959ade31d5bf2644e44b5 refs/pull/125/head\n0041121e405182ebc1747bc4b70ee51f1ad515eccbec refs/pull/1250/head\n00412a64d4bf9067530451df1015757b964dfe1a14e2 refs/pull/1251/head\n004138777fdb3a08b8fa21b046cc3f99ed080b773cc3 refs/pull/1252/head\n004189a916d3fa0e29776db1dca2cfd496040b7f59ab refs/pull/1253/head\n0041b90f19856b5d540108a64072c2deac6b1cd78963 refs/pull/1254/head\n00419b6edb6b82873b174431d6fdd2176c56f24120e4 refs/pull/1255/head\n00416256217be5d1950457e58da0bae4bf04f2213719 refs/pull/1256/head\n0041881388e2752e4f3dd131e8a1f8bae279d2f120df refs/pull/1257/head\n004191315d3344d7b85173da33c9f3f2b43d6b27f355 refs/pull/1258/head\n0041be6ea4d8245ececbe374dc0dd1d809cb94b073f6 refs/pull/1259/head\n004005a29c8ff1ca492bc90f87070fd303a8110e63cf refs/pull/126/head\n00412ac78599f1db05f40ae306d6b9ae7c56a3710044 refs/pull/1260/head\n0041253384d79ca6561d4f3c81f4e41514470026c6c3 refs/pull/1261/head\n0041e96f52adadd2e3f7f64715f3e9c4c0638e0fca9f refs/pull/1262/head\n0041129c977415a332d4a850ead18bbbcabb3022494f refs/pull/1263/head\n004152b028520be76bac86f78d8c684c2c5ed9cccc50 refs/pull/1264/head\n004186f9391f84fcca2c177eb788a56ae8b7e543d902 refs/pull/1265/head\n00414d3590834890a95113490d5040225fb270b5b7d3 refs/pull/1266/head\n004181622365cbead4b2326525b2601da753a24a5e55 refs/pull/1267/head\n0041117f2cce652b5628970d0977266f55eaa55cb407 refs/pull/1268/head\n00418bf7be7eb05fcca77f395a59a02e4b1e1860b469 refs/pull/1269/head\n0040b87fb4478b446f4ff48ac78beafb90fa37054b41 refs/pull/127/head\n0041c386d3a3fd7dd25d1c088999350621015b934231 refs/pull/1270/head\n004196c88193e27d33fe815eb0551d8087c8f08968fa refs/pull/1272/head\n004158ef639deb89f9d5517c308e977dc683f0c0168c refs/pull/1276/head\n004150328a328d6100da7adb817b253bb006d7c0c046 refs/pull/1277/head\n00410dfc3535eb0c29e638e9d7371fbc84f356c80aeb refs/pull/1278/head\n0041133f337708f4da78c753d8607f35590d9d0f36cd refs/pull/1279/head\n0040c79671a08acdfa73c90d555e0065ec3e108e2214 refs/pull/128/head\n00414a3f1930fa113df2b198bf7e6b4bf2753cb08c06 refs/pull/1280/head\n00417326ff73868061c78efdca1d22bdbc93f4dbc060 refs/pull/1282/head\n00414b592a00998dd4c4a9cca11be7979eeff9c1709d refs/pull/1284/head\n00410a19b05580dc24028dacf4f568529b24bc76f8cb refs/pull/1285/head\n0041e43a40ae80d2e8a6a0abaaa31ce4763d146430b8 refs/pull/1286/head\n0041fc7e59d29509405c92fd972087e6094f93f02184 refs/pull/1287/head\n0041add1a8d02937b9f518ab45756f4ed93e0ed2a7e6 refs/pull/1288/head\n004173ea6713b3e09df07ee64563409a3a711524ae4a refs/pull/1289/head\n004079f203e8674a264ca918ad0a59b52720c5053bba refs/pull/129/head\n00412ea3e74c9fa834f044e3ae49533106a4513a1c07 refs/pull/1290/head\n0041207fcb2a7a6053f40a9a570bf4ce711fcae705d7 refs/pull/1291/head\n0041215e33c64e886aa92446ff82a8bdc48bdd92bdd5 refs/pull/1294/head\n004173c35234a9984cf83a5eb299dd2db138c048f6e0 refs/pull/1295/head\n0041cb236ea352e1e55ff844930a0ae81158768fd7b9 refs/pull/1296/head\n0041436a8602956ae04dac1f0b04770ce06112938929 refs/pull/1297/head\n0041618ac0ded5bd906e79bb7b784f29846eb3af9fcd refs/pull/1298/head\n0041d6e19fb7845e1ee98706ee8f3a36f0d97e5b952b refs/pull/1299/head\n003f3a8412073dcc1900bd009153b7c0bd40d59710a3 refs/pull/13/head\n004143294d0e607f85a1ed7ce9c504e6bdbf768b3d78 refs/pull/1300/head\n00413adf485f0e8226a37911538dcee7d1f0a252ea60 refs/pull/1301/head\n00417113d61286fb327c585ee08a12b25117245767ed refs/pull/1302/head\n004120bc1bfe5d146d7a453f501c3f59d08ce3972b98 refs/pull/1303/head\n0041911566620041bd942966b0fdf5bd53ee8c220755 refs/pull/1304/head\n004285b19a8198bfab56e74c4efaa5dd3573fb44430a refs/pull/1304/merge\n0041bb833df0473c9e06a15fa30931f62f43f8fa41df refs/pull/1305/head\n0041c1dcd02d5aeeaedfbe9a47719bdcf0517287064e refs/pull/1306/head\n0041bed15155e558a64bd7e1d023f0f6c01e4e89cc22 refs/pull/1307/head\n0041ae7549465893029628571539475cab50a5f88b29 refs/pull/1308/head\n0041fdd103ee379731772968bc0fa4abce0a222c482e refs/pull/1309/head\n004052355df83bd1f16a0d6cfdf839014d0f6a0d1742 refs/pull/131/head\n00412e0d369368249bfc6c27477840adfd1745067f43 refs/pull/1310/head\n00412ede4b86018662df57603431a2ca06f0e63fe0ab refs/pull/1311/head\n0041ffe128c7f53f9261c2e478ba220ab8c2bce7586c refs/pull/1312/head\n004110564b2cf9d3e0af7986404100358a81095fc991 refs/pull/1313/head\n00415d4eeedceccda7c2e4e55857b5a6adfae318248a refs/pull/1314/head\n0041a839faa175e5f0f8c1773cb5dc565771eb4b9f5f refs/pull/1315/head\n0041e1d82ae78462eb11827aceb7100afc9e6580bc3e refs/pull/1316/head\n0041b1d8d0975cf7e2cc0cffdb1e9d861f9ec3c8a464 refs/pull/1317/head\n0041cd7839e83d0fa2c941902e812164e8919eeb6add refs/pull/1318/head\n0041b729510125f5038236e9c2f739a0344813040023 refs/pull/1319/head\n0040de13fa317c1f5f068676066815c089d2dc6147d4 refs/pull/132/head\n0041734cdc193dfaa3632bd6bd1e116d1bae62f9a44b refs/pull/1320/head\n004169f6a1f844f349c8ba3a32a3c5da1096567c65ff refs/pull/1322/head\n004157dac2df4e12ac5ac067549fdcfc33f3625a68e4 refs/pull/1323/head\n00410449ab5546a48274f8db2472e8b21f90da47f1ba refs/pull/1324/head\n004126c21c1ca66e207f17944073b90c943e0447d5ac refs/pull/1325/head\n00410525f3fce77b48be23f56df109940605c512a64e refs/pull/1326/head\n0041ff220eaa3867738f3db0eb193b4b64b358ceb636 refs/pull/1327/head\n0041b7507c4ce4d7050d93cce250f9420bf499dcf79c refs/pull/1328/head\n0041c66c75f095bdbdc61c9f6a7918250bb35d11c27c refs/pull/1329/head\n0040189e780a8f8800d4a0d3bc302e046fd6de7a2193 refs/pull/133/head\n0041961a6e96dff63ee0143258b0c085d0902187a58d refs/pull/1330/head\n004145df50f1f4d0e6d4c0a0119a259beace2112bd53 refs/pull/1331/head\n00417ab9a1982ce11b5f59474d9d1c4290deb3cd66e7 refs/pull/1332/head\n00419ced3c989395984365a5cd2c756124a292692d05 refs/pull/1333/head\n0041290599c46d3019e2faf2c278c11a534ca383a8ed refs/pull/1334/head\n0041faecb02327ed55b78f3f52895749c9d5c83b5d79 refs/pull/1335/head\n004104a4c755a57d4eabcaeacfac73ae163261e2dcf1 refs/pull/1336/head\n00419e97654e7bd49474a89cf9ad0139bda19dc1e5a9 refs/pull/1337/head\n0041fc6fba1f9f88b4eec99b5222a1431f13b74456ec refs/pull/1338/head\n0041f1bab89b149ef99141a371a872979a47de900ce3 refs/pull/1339/head\n0040f2340c7785b24944f55d7e97e27b347be8df3a97 refs/pull/134/head\n00415a06f626752062956a8a1381504662c2d7ebd629 refs/pull/1340/head\n0041ea595ee08864ca521498095f830189a7c9df36a8 refs/pull/1341/head\n0041257c3048815f335b9f0a22fd4854b1237aaf0e05 refs/pull/1342/head\n0041bafbee83538cf951f538ca7ad13779f59f164d71 refs/pull/1343/head\n00412fd3ce652de76465b0f42f488020dc954885d2d0 refs/pull/1344/head\n0041c64bdb1c7e57087ed8d84e221de17d758391f2c9 refs/pull/1345/head\n0041747c018e63c009b2155bb4f6deb6a583d3caf22e refs/pull/1346/head\n00414e30fe74d61b9166b308ddc6ca31248ad92c0574 refs/pull/1347/head\n0041c3fc7f915e82757460710c0e8128ee5b36911035 refs/pull/1349/head\n0040edc675a835d97be1fca5e3cba3de1d92690395da refs/pull/135/head\n0041a0b692649edbd8b4d3e4fc273edb51b90dab4226 refs/pull/1350/head\n0041bee1b515d3eac86a33be45b026744db3594701f5 refs/pull/1351/head\n00417a8e666d0bd3aa6de59703c76d327d023e855eb4 refs/pull/1352/head\n0041b4c0c67c083c3f3d9275dfb2f3e3f30b014598f3 refs/pull/1353/head\n00416cc04160395a02237ea60fcb56369dcc2af898bc refs/pull/1354/head\n00417b5d44de35d37ec6af061e835241251cf0600906 refs/pull/1356/head\n00410ddb923bb03a95e57aa0e591c9d79a6bbc042ccd refs/pull/1357/head\n00415f4e98aebd5c88b1f31d0dc5fe89d756e4836657 refs/pull/1358/head\n00410b6677fdfa4169e0426b59f2b811c633848cef5d refs/pull/1359/head\n0040e9437545a50ce325010edce479c33fdb5fb8e911 refs/pull/136/head\n0041da17b72261b13286aec80d2720d55ded18ac9c20 refs/pull/1360/head\n004175df95cb365bf57e6605ec4768f11ad6cad1c5d9 refs/pull/1361/head\n004161ede2f2c9831b2ad582dd0b46b668e8f53eda44 refs/pull/1362/head\n0041afba174909676dd33be7a4004636350c0c4866a0 refs/pull/1364/head\n0041e2196d07a5f82f433a3d45db1ad79dd073fed364 refs/pull/1365/head\n0041d8202d6c7c333bd3cdd030884261af6f8af1edc7 refs/pull/1367/head\n004100eba200a2fdcd297b2aca58a6ba86eabaeb2b4a refs/pull/1368/head\n0041831e8fbd68217ff1d460dd4df4b21f7c22b6c7bd refs/pull/1369/head\n00409626f978d682ed60c4f361078d5add6f4794914a refs/pull/137/head\n0041ce2ad323892dc3a11963c9968da41582fa403fa9 refs/pull/1370/head\n00411a47355f103ecf545a1bb3a498f1a0b5b76b2fef refs/pull/1371/head\n0041762fae248f54871949683a7fe74bb3ed1d04f1b5 refs/pull/1373/head\n00416980afeb6774a3f8ef05834d8baf2df6a0f9bcde refs/pull/1374/head\n004144bbac892c3674e04a4c22107572fdb70870291e refs/pull/1375/head\n0041ca65a6f8e68e7c84b0845ae551ded0955b65dfd1 refs/pull/1376/head\n0041a6e1d21fc5b0fe82b02eac25b2ad3e06f5b7d851 refs/pull/1377/head\n004177404b3cbb5f0c567e9923373363670b107cb7dd refs/pull/1378/head\n0041e10cc0588b127c0a7a345708ca4694b23b27a42e refs/pull/1379/head\n0040e07f89546938680d414fd7b9485f3c0aa7ec0232 refs/pull/138/head\n0041dff810775dad1f692e87bf9411750c8ce22c8976 refs/pull/1381/head\n00416278f3cfc933a1a2fa5fe4c1006a8f3353e24b0a refs/pull/1382/head\n004103e3e96fb3dba1d920fd58fabdd6fbeb7c99bb69 refs/pull/1383/head\n0041e215906b2e757daf6f9cdf479c6ad074b965ea37 refs/pull/1384/head\n0041f60c4322be9edafb23af08c9be6c20c9f85108d5 refs/pull/1385/head\n0041b246f36763b355cbb9cc093783ca6f13f9cdc4c3 refs/pull/1386/head\n0041721c39c10965b428e222283aa864f06bb154c04a refs/pull/1387/head\n004171afc34970336601672c9edfbd3999e924a448db refs/pull/1388/head\n004078ca8ffccb0245a5a61cf24f778008d9787f0998 refs/pull/139/head\n0041e72e66bf5707b31c82e55f3292407daabf66e6b6 refs/pull/1390/head\n004127bed5c648b4c2bdae20ae119e50b968ea79ab1d refs/pull/1392/head\n00419ff43939cf0c8e6986d8e92126e6338863b648f4 refs/pull/1393/head\n00410a552e22b16e6fc24ea55f88d20c7901ad2c3cff refs/pull/1394/head\n0041a21275fef5419e8ec3c8c92826bc05d6f2c645bb refs/pull/1395/head\n004178832b0fc1490907c8fbb936dd7b1c43c5863170 refs/pull/1396/head\n00418951ee20a76f985f31f7adb31d4f3c1990300789 refs/pull/1397/head\n003fc6b4d55a540de28af226e774e0a2a49e70ab02d9 refs/pull/14/head\n004016c45dab0a86a40e2ba16d8efe04e0be57e78cea refs/pull/140/head\n00417dd1f2f0fbd3520d413b1b4a458c0276ca3f05c2 refs/pull/1400/head\n0041da9a726ce2f007ec4ee803ce0bd7157b4421e0be refs/pull/1402/head\n0041186c598fee1c82e4c4e904856d5dbf4fe7b109ad refs/pull/1403/head\n0041d8326a0f09b0ed2aea1a559d6af68458c63bf3f7 refs/pull/1405/head\n0041236c0c3ffc7ae031d21814b583c637cadd989d75 refs/pull/1406/head\n00412ef45eca094f6f574206fabccda2d9ba36ffd7e6 refs/pull/1407/head\n004169dba3b7a359925aafe3d06d7b6c5f0c40f360ef refs/pull/1408/head\n0041fd84167ec1429163534a1c312ea42f7b48fac010 refs/pull/1409/head\n0040ebb6c96b259d1a247c14f0db7adbd63035db97fd refs/pull/141/head\n00415b72bce47ac95923bce868b8fdedc204bdd54af4 refs/pull/1410/head\n00412dd82629ff324d2222d5bcec6fa1df77f023b330 refs/pull/1412/head\n0041566b2cd164e5b92b7c7993d45f367eaa4ac13293 refs/pull/1414/head\n00411f2e4049e40f05de6bc89a4df3b902617cd2c4c7 refs/pull/1415/head\n00411138579a9fa79aab8611dd866a5c7d7b36d5b407 refs/pull/1416/head\n0041520b03ea4d2fe774552ebbf371a546fe16e00d5c refs/pull/1419/head\n00403ea332e3d92983d258198c4944e48f2a679e6705 refs/pull/142/head\n0041cbae00c32292523e1178b7936cb6a0ee0c544ada refs/pull/1420/head\n0041df616c3977bc7a2125170035b062cfb931b39c0d refs/pull/1421/head\n00417cc8172bdb8a34456e676cee0d4ce9084ba7bbea refs/pull/1422/head\n004192677833ea4b356154ce80923125322345e0d4e0 refs/pull/1423/head\n00410cb307fa354bd8e66ae40b7fb3cc537b884c03b2 refs/pull/1424/head\n0041e5cfcb34d6c24a402aabb88f79c321124b89562f refs/pull/1425/head\n004136f4a8e330e49343137e747d02300ad6b352d7eb refs/pull/1428/head\n00414a4e9c9f75a503df0da30240b8dd382811a34448 refs/pull/1429/head\n00401e851bdc987c158bfe0edc3ce66cd3ab32b95efe refs/pull/143/head\n0041640a72f812d1681c148081ce769c94d18089a531 refs/pull/1430/head\n0041768bbbc5e3e37c678dfb001bddbf3c8c4a3feab1 refs/pull/1431/head\n0041e66f71fdd1c431a684a6d96b7b0e02f99e294e8d refs/pull/1432/head\n0041a0e482e060ff55476ca8038cac6e0b7c659c3373 refs/pull/1434/head\n0041fb2e26335ddb51333e162b916156c0884f567c37 refs/pull/1435/head\n0041b1772fe46558e79a885a654ff12d5a2e194c2138 refs/pull/1437/head\n00413681973c9df9739802d4137c63b769054e65ed19 refs/pull/1439/head\n00402e9dce6c48f32267884dd2b28842ec6925b645fa refs/pull/144/head\n004123939d417e265d55ed1fc3aabcd501507ee01ef2 refs/pull/1440/head\n004197c65d1cd8e2c8f901cf5fc86614310abb52fe9f refs/pull/1441/head\n004103dac88c576f8ecab3db909f629585712b8c0eb4 refs/pull/1442/head\n0041a6f76105ef194c3eaf7b4b7912a38f7294c07aae refs/pull/1444/head\n0041fb648a2ea697e46ed51c35f68c8236b3bd10e59c refs/pull/1445/head\n0041afe3ae2d7fe951c37913e38fa09b4fd3a6507008 refs/pull/1446/head\n0041466b94b687fc5518d881f59d1e0372443b841e34 refs/pull/1447/head\n004123532d67a96aeaf8b4a6361a3fadccc6d933f37f refs/pull/1448/head\n0040593ef33d4b5fe2d7feabb021d0972519deb6b744 refs/pull/145/head\n0041ee9ff50c9c2b4ec849994b49738eaadd45df8d11 refs/pull/1450/head\n00414d997c6f83857a7873eb78b0802816a5cba610d2 refs/pull/1453/head\n0041c1b4346191fe2b03d0c41637d53d00a84ed431b6 refs/pull/1454/head\n004119120bfb738b794199bfe5797b8248c6e1920492 refs/pull/1455/head\n00421d489a06e8f566b83feb9b10282434c69a2a848f refs/pull/1455/merge\n0041e93dad30305e69dc20372d1a7684ac76c2b977ee refs/pull/1456/head\n0041a5f94be445a32a0c5991e85d12fdda4a8fa2fc97 refs/pull/1457/head\n0041164d702fdd71ca10606e1701c9ebed15a885da41 refs/pull/1458/head\n0041d342f1d18f88041e3fbacda44330e22d9798e9e7 refs/pull/1459/head\n00406df8b6ad0a9e4dade94f2747d776d7dda1f4e4f8 refs/pull/146/head\n00417647947be27328f428cb50ef77189933561b6990 refs/pull/1460/head\n00418a4b9b4ffe361034167304c74c026ddc6ac4a33f refs/pull/1462/head\n004142813fb3381fa994874cd455ef72b49874ccda7e refs/pull/1463/head\n0041df4c6c121ab7033a14f9bb85f4e7416c8629c06d refs/pull/1464/head\n004105696886d50ce893da5dc7b6917e9947f3bbb835 refs/pull/1465/head\n0041fd3cb207b52d77dddceb45d01c33065f495ef029 refs/pull/1466/head\n00413a659000e96e36927d6edb20fb7361e74300ecf3 refs/pull/1468/head\n0041f49d889a01613f914a8d1768e449fa51a9127c54 refs/pull/1469/head\n004196895dba95749f0b38fb2d49f0506bfbbb9539ed refs/pull/1470/head\n0041f2f5eef8ce350ba79a9cdb67a96e968c3c5c5beb refs/pull/1471/head\n00415d7d6f1f25924dd01528a74cc38877510345299f refs/pull/1472/head\n0041b62dd25e1192be880b8c96e162ae5f6905524084 refs/pull/1473/head\n004164469920f86f96c92a5f69b313990f4b3b08b007 refs/pull/1475/head\n0041ff1fd64690c606dc96f61d599866f1ed7da972c6 refs/pull/1477/head\n00415ca8b4a96239e4feca8336661d98ea495bb1099f refs/pull/1478/head\n00414e696f6e40d363f43a084a0ada2144d8cb86873d refs/pull/1479/head\n00418a2e104021bd2cd6d2b69f606d784d1df6c7b8a9 refs/pull/1480/head\n00414f78a2c9c44eae18251b89aed140f9bf4985d028 refs/pull/1481/head\n0041bb284ef37e8480c03b519560f08f8b38dee5bb98 refs/pull/1482/head\n0041fa1d5b0c70383c08e7ee37bf66485198ff3e7ff8 refs/pull/1483/head\n0041c3a7a260d2f19a4d350e3346d008c776f74e9b98 refs/pull/1484/head\n004110e894be6f4d9b506f5459ea296592c312f5c053 refs/pull/1485/head\n00418d611111423fb3596be120ee6bcde94aeccf3745 refs/pull/1487/head\n0041afefc631fce6dff9770db8867982ffee8b091218 refs/pull/1488/head\n00400b8e4aa1499399f5212fd700cf2f310076ae8010 refs/pull/149/head\n0041ab1a2bc6c7337ace9e89ea483619794ce5a2565b refs/pull/1490/head\n004171ffff50fbf4cad3b72c45644e926b0378005212 refs/pull/1491/head\n0041bb95218921ae7fe9e8b4c3336278e078c315d0fc refs/pull/1492/head\n00415c20d41d46c16bfc6a9e82f744bd9b5541f3fd18 refs/pull/1493/head\n004120eab42cf1a7a89de8ff99af2d73a32d6cd5bfd6 refs/pull/1494/head\n0041a6764c4ed63427a5145422b6f7254ab4529bc8c6 refs/pull/1495/head\n0041c617d48580fe8aa02865fdd3c434d507a5ffe940 refs/pull/1496/head\n00418286eaba5003c774fc206fafdabb0a2f8ee2a50d refs/pull/1497/head\n0041f5f9b82390a6425baab9dd8d7c8937f0d2680b24 refs/pull/1498/head\n0041600434da8ba54186c894f8032da0cae6161d492d refs/pull/1499/head\n003f3c6e266b75f17fa1643a1d0b189b8d350bb8081f refs/pull/15/head\n00409aeaeccd95e696e800e08ccb6fabfedd7ad0e8a7 refs/pull/150/head\n004162a27e278e0cbd969b615943e89f1ed0ba4d76ed refs/pull/1500/head\n0041204898438a43b37fc7c56f5ceb9f2bce1e6d28ef refs/pull/1501/head\n0041f55692ca0190703a2e425672c45580b440a70bd0 refs/pull/1502/head\n0041ae9e151e3c9e7beb6e3acda1f075c928bef0b5ae refs/pull/1503/head\n00415c6a2af85703ae61fb0e53a0c0acc6ce2bd35918 refs/pull/1504/head\n0041908d4fbbd4502e8b6106733f88373ca813fb9dcf refs/pull/1505/head\n00417aab084a2629b0a33c7a314991b38f2bea80af12 refs/pull/1506/head\n0041341380d6aab2b719946ec0c1a5be7c0cd27a0cb3 refs/pull/1508/head\n004173116a39687c8aac406d5f3436ac2382cd67166c refs/pull/1509/head\n00410a69ddfa848b2722f6e019d5c975877d9015ff32 refs/pull/1510/head\n00418b22d1d80d3989e19f6c5c639f1d43756c83c4d6 refs/pull/1512/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1513/head\n004107f645f4d3f21c4a6e5d37dcf9433ccfe16778ff refs/pull/1514/head\n0041b9f8f60c3d32e202f61a38cd9298d498f9d47d6f refs/pull/1515/head\n0041f83d3497ba7dc9e2d636bb2e4ae997d199eac114 refs/pull/1517/head\n00416973913e0ac5903ab71dfbe1b9d36bfaca0e4f15 refs/pull/1518/head\n004116733b33f6b8e22db85c87192bf755b7e5ba9ce9 refs/pull/1519/head\n0040dc7027b6d5069c1decbe4db697f29b71dbedd0d0 refs/pull/152/head\n004169d63353a10a2ccb6bbca0cd8e2ea39f07b473b0 refs/pull/1520/head\n00410d459a3a0d41b09508ea497686d1570c86a1d103 refs/pull/1521/head\n0041d898942392a908832d3665b8c01b1d9a908bb4f8 refs/pull/1522/head\n0041f313b6cb25b09f2b46fe64f73006162494abf44f refs/pull/1523/head\n00413672ab6648e9a5a7be2a98a15ec365a10d2fd64a refs/pull/1524/head\n00410bce19c9b7efd2ff89cd8fe5cf8b745151c0422c refs/pull/1526/head\n0041112afa3e48db0f2de21a6a2eabf87c8eead601a2 refs/pull/1527/head\n0041d96bcd6c259eba410208303f608604f12d94d01f refs/pull/1528/head\n00419691f02b5328cc5cd5bd107c0f9841a0cb98660a refs/pull/1529/head\n0040a482a80f7e437e30efa5eb9fc21c09d025be30d4 refs/pull/153/head\n0041c76aff6be45a0cf7db5c5711e4e40113f64dbc47 refs/pull/1530/head\n004104340dfc2861f9f6f3ef103a0025a4c53a39fca1 refs/pull/1531/head\n0041e64567c751cf73ca090672778776a7175d5fefc3 refs/pull/1532/head\n004185a59eb6f51e25e5ec8671446d376d0f2f7da910 refs/pull/1533/head\n0041f6d77b8c6d7b853ccafb13efddec6462d1aff581 refs/pull/1534/head\n0041da0d3a3a6b2ffe0023b256cb8869931ee9c5b204 refs/pull/1535/head\n0041882e49547e2172435fd055f858a1d68ed0debcc3 refs/pull/1536/head\n0041b441fa217409bd0ce6aa4a837cd3f7447766fb61 refs/pull/1537/head\n00412f834281750332a14fa6c7c60696d1736927c663 refs/pull/1538/head\n004116cd702ae99af2129410201438008c0ed6a88709 refs/pull/1539/head\n0040f78f9c4948f1f81a50d51265a55aa736b01489f3 refs/pull/154/head\n00410c2ceadda13aaf9fe821891c11bc42b28f13c000 refs/pull/1540/head\n0041c6b0b982c9b39b3f31069e60453dae96c10866cb refs/pull/1541/head\n0041d2e4e5e58508c7aff695768346c200d57229a21e refs/pull/1542/head\n0041ee5cd9ad00462ab8b1602c25cce5d57247651ae5 refs/pull/1543/head\n0041db0dd1875b8ba55ae38b0fc205c57462d5264984 refs/pull/1544/head\n0041327590d91f1311a3a6e53cfc48e03b539cc7d955 refs/pull/1545/head\n0041ace6ca433914068b255abafa6fbd0ef16ba2d201 refs/pull/1546/head\n0041f19785406811be353ec421c04bce3f346eded10b refs/pull/1547/head\n004172e13a2121813367053d4ecc963d2305e85bc86b refs/pull/1548/head\n00418c4f183f2f6c6e646979f996b447e05fd2688ec6 refs/pull/1549/head\n00409d5ed41f9d2193e6794deee4f8bb7a813c9343b3 refs/pull/155/head\n004186322a7793fb78f2471a66f28d1380ee2ca72afd refs/pull/1550/head\n004145aaab129c2f7061b129b296c55c7c2ac48132f4 refs/pull/1553/head\n004149d849fd2e1f9614cb537fc19bc54e556c9b09b7 refs/pull/1554/head\n0041bbd33796f3faa42f40b28134ec8b3efc142694f7 refs/pull/1555/head\n004113af1a0f28d8a9bdfcf98c6ac827a6a3ec828baf refs/pull/1557/head\n00413956a7dd8a950fc58241286efda84dcae51abe4d refs/pull/1558/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1559/head\n00407dcd66ee089129b124af8b51b26fb8728af4773a refs/pull/156/head\n0041947083e60bd3c568927ba12314efa05aac5290dd refs/pull/1560/head\n0041f16c2fb4ef30b707b56556b2e2c40ed8cc9adf42 refs/pull/1561/head\n004166ae1b5c1780e6c8444b39ab3f112b7b3e02dda5 refs/pull/1562/head\n0041dceff72b9c029a97e42ec1a5b0769d06f153b8d0 refs/pull/1563/head\n00416a399d6d2ad5dcf71bcc04cd21e939de5e7767aa refs/pull/1564/head\n0041695353bc990ce2a62d31eb1fb13f541d1cd703b7 refs/pull/1565/head\n004152049e0509b4b44daac5b37016b0dbca1fcb37a6 refs/pull/1566/head\n004187d5eaca8701601a39947d440b185d894c737407 refs/pull/1567/head\n004142c31c24b1d69723bbb699578acd02af9f78800d refs/pull/1568/head\n0040c82b8e525303e6fad770e0540dad5dc00d76c83c refs/pull/157/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1570/head\n004192716c0c970fea2ce12cc31832b3f45f3050ca21 refs/pull/1571/head\n0041462f5a219f3f8f78092f98f26c5b58a847db6c7a refs/pull/1572/head\n0041c5b85a430a260fbd9cf2e4f360f8f20d53afdc53 refs/pull/1573/head\n00413019ec74ede79e77d5672fd022ca3177572cd72e refs/pull/1574/head\n0041194db15636a13d052e81164641cb23bb53be4b49 refs/pull/1575/head\n00412b5dafc68d002735348433ae0ed81908ecd785a6 refs/pull/1576/head\n0041f2c653dfbda3bab74478915ada61e0845012bd2a refs/pull/1577/head\n0041d870bf685b2b776ff7ba9eab78ed55505ce57c1a refs/pull/1578/head\n00412fa7f48896e8980b11a2b558ebd6a20e7be292b8 refs/pull/1579/head\n00408068436b2a040871c83cf6f39c2d0d74d4651e47 refs/pull/158/head\n0041d958e812462e34c99c37d217f0f08ae91b3abc03 refs/pull/1580/head\n00415194418a88de9fb53ab6ed80432831331e15bbae refs/pull/1581/head\n0041c3a4e79dbd933fc8e947815c666561d51d795f91 refs/pull/1582/head\n004131da8dad3c1ac11a0e12490fcb6e98fa8f2c28b7 refs/pull/1583/head\n004125ef6c1f49836f51ebff2f4135e4596992d678bb refs/pull/1584/head\n0041e0ae728d9925a62008f60a22e1198f06a6ede5c6 refs/pull/1585/head\n00417fa05c71e0d2b2217facd2bad243781858ed6e9d refs/pull/1586/head\n0041ff5cde817af1c25f5fa26bafc4ac4073bcfb1e09 refs/pull/1587/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1588/head\n0041484995c39c9c8cb99c885903c64a06b782488b00 refs/pull/1589/head\n00406fc981f0f578112dd57d3c9221d8e8607222ea02 refs/pull/159/head\n0041a0dc900a228f0c46f97b3e4c59acfe55c96ef2c6 refs/pull/1591/head\n00417df0c764d7fc60f3b32fdcd11be57d153882902a refs/pull/1592/head\n0041426317bfe888889daedec42b58f58b3e1e2da129 refs/pull/1593/head\n00412c9256efc644bf765c45e5ae8a2a8fa851d37c47 refs/pull/1594/head\n00418405e05a3f332b28d57837397ce28a63e48f795e refs/pull/1595/head\n0041fd766e7699bdaeffaf5625a4a583dbd5d4b68141 refs/pull/1596/head\n0041a1fa4e7ba21116c602b2e2d196eca51caef853d8 refs/pull/1597/head\n0041b7919627c927d8559f12538106956397a3ae92ad refs/pull/1598/head\n0041d796b6f8340e2bdafa4e4073fbda29550b21c90b refs/pull/1599/head\n0042dc55d0d581c9390b6f71cf04de9815c5e77d7771 refs/pull/1599/merge\n003f16b3827af689b39902ef03363e8f06aa8a917b37 refs/pull/16/head\n004048d9e4009aa1d2d8cd18f948ed4549a55eba97b3 refs/pull/160/head\n0041d3f1dc58018d6b40ee2f05e5f6821671b319c3fd refs/pull/1600/head\n004131a64f5e4936499faa79e40018515ea58b3c0302 refs/pull/1601/head\n004100a02591e76295b34878ba180df0b8a9564a3b92 refs/pull/1602/head\n0041f763b73ac812aaafbad92a084773bf1d13f80943 refs/pull/1603/head\n00414359fa74d8b9a01b428f725d692299264e80921e refs/pull/1604/head\n004146d102ceb52c713644eadaa7846118c8aeee3a09 refs/pull/1605/head\n0041e98427ba70a78b5d7a64c427e7a9cd09de7b71ba refs/pull/1609/head\n004007f015f1904e253e994ee240a9615bf16315a5f6 refs/pull/161/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1610/head\n0041f2376611924effe0f0f03c541f480137d78e573b refs/pull/1611/head\n0041a0f7092b2162eafb07afc502fe26c262c75a51af refs/pull/1612/head\n0041e7a8372d6366eb5d6eda0d313e5a0c4d6f2e7b10 refs/pull/1613/head\n004156cf6c79473ddcd9db99668d49a23b29c01a667c refs/pull/1614/head\n0041eaa3e7ffff279d64785a8ec77bf6d7f5df25b7da refs/pull/1615/head\n0041cc8c5840078f65bec296c001effef0c762b990d8 refs/pull/1616/head\n00416b3f053810f3d897cb1c543d109216751697bca0 refs/pull/1617/head\n00412b744813cf6bed7507c0a5003db5df0aba55fb7a refs/pull/1618/head\n0041ca91696bdfb5a59629a3471daefdac6d4e2ab0a7 refs/pull/1620/head\n004174214297869b28ffd536479c068ecaa3997fb7b7 refs/pull/1621/head\n0041be0908a0431c116aca177fb7dfbfc551ccaf5861 refs/pull/1622/head\n0041e5c686a63314322ab70fc59f181733bb23fced34 refs/pull/1623/head\n0041b84b0eb192fd47997e3d508fd2fcfa5b7763e026 refs/pull/1624/head\n0041aa15587ad20ca465e390add59358df0cc2830608 refs/pull/1625/head\n0041414762a65ad10f46b75a95dbbc8e56de95d5344f refs/pull/1626/head\n004131a5726b22a2cb4cb794b01b5d3a75ff934a6ba7 refs/pull/1627/head\n00413691e6cf3f6767d85cdc6dc87de6178d8e00a84b refs/pull/1629/head\n00400110a956f7c25b31435717b7c6f517fbd4ecfc9a refs/pull/163/head\n0041473061e7dabc8c56aae9fe447a3173db6c7c3380 refs/pull/1631/head\n0041320bc9418314813464d0b91d5f820526e6dcaa40 refs/pull/1632/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1633/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1634/head\n0041ced684cd213166117663572f0f13591bf5168ba7 refs/pull/1636/head\n0041653eb97d9afcaab55c7157a3d9a7896f9f8a9cc0 refs/pull/1638/head\n004002c71918d8b56bd9f6137e1a526d1ac481602c25 refs/pull/164/head\n004127a37fb1ab3e5fe5a1e9b11beaad54ce9281e525 refs/pull/1640/head\n0041ad1fdf91c8ee67b0d073a6a438a52209cb15862e refs/pull/1641/head\n0041de207ef037cd5ddc2556df0610a7a172ab51dbc6 refs/pull/1642/head\n004145f73022342a0bdbdac7417629105c4baeafd79c refs/pull/1643/head\n0041b985b6379b054c5adb75044640bf5cb9fedfa4b1 refs/pull/1644/head\n0041843a90655a84ca944e43c96e71557c085e294d9c refs/pull/1646/head\n00416840f1c445eb9105a17e786ce13304d0e4997187 refs/pull/1647/head\n0041b6d6f53c233c8f7b52309335a1f5eca9fc814165 refs/pull/1648/head\n004141d16635e58d5c6179192206758b4270a9e8f965 refs/pull/1649/head\n0040be088688bdaf7b272c7811e4869caffc60a34d87 refs/pull/165/head\n0041511c386150398998d87896badef720e894330987 refs/pull/1650/head\n0041cee9378ac0bb51431bed15a4a4a137820340fb70 refs/pull/1651/head\n004181e9bf6e4bc3d061c601d117692c9dc9fae590b5 refs/pull/1652/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1653/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1654/head\n0041b37b4076f5874c11113b926c8fab9f7dc2444952 refs/pull/1655/head\n00410b9242402f6b614a7a964b191dfd82d91eb807ee refs/pull/1656/head\n004103285c5cc430a2d4d95b25e43c4b9fbfaa66b75d refs/pull/1657/head\n0041cf437402222547477d626343ed0afdf5efc0f8b3 refs/pull/1658/head\n0041fddb6460bf6b561b82bb98f3ece98eda40231dc5 refs/pull/1659/head\n0040c7463a50e9d50aedfb8d2b01f8fc673dc1972f14 refs/pull/166/head\n0041330dcc98ea9fc10d8927d289236eb8c918c4bc51 refs/pull/1660/head\n00413412588e0eb37f94e5a155797d6a223fe049461b refs/pull/1661/head\n0041e3ba44799ec67cc578e33f7e397c529ce919f838 refs/pull/1663/head\n0042daca13a892bfabe2290650e9f908617e47230586 refs/pull/1663/merge\n0041e4571b9e0bb399600daa49e941e0f1e7c487ce2c refs/pull/1664/head\n0041605b1067212bcd7af0737f42280c049283d7f7db refs/pull/1666/head\n0041947c24007cc76d6c31fd44f2849dbc977b4bad0b refs/pull/1667/head\n004171767c8f8d91833961d253863a3bedea974bd26f refs/pull/1668/head\n0041606a2e0d39ebe60e887e64c0e4e33c591e997e19 refs/pull/1669/head\n0040550ded776cafadb014dd81dbaf58c469d5af6ad9 refs/pull/167/head\n0041c0b62b8b28336c5a5086870c3eab71aaaa150c4a refs/pull/1670/head\n0041c02ec43a14e1ec42052ef738745864d69e7eefbc refs/pull/1671/head\n004178391b1c345356ec78e9d6c033d67443952122a6 refs/pull/1672/head\n004179b4e517f71483bac6f33db2c9c070d4abdc0e45 refs/pull/1674/head\n004169a3f0506feb52f5b5705dae8828f1a20c43bd6f refs/pull/1675/head\n00419e54ce53a375d24abc214619b357acbd424e5814 refs/pull/1676/head\n004122a5879e288c1afa2052f715bf6cf92ba93ef076 refs/pull/1678/head\n0040d5ab3681b90575681caa9144bf1bdcdf723150f2 refs/pull/168/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1680/head\n0041b49309b4e8a5a0cda1677745b2941be87a642ff3 refs/pull/1681/head\n0041203cd06339c36b8767e2e60dd55bbc3ac923b645 refs/pull/1682/head\n00419eac881720f2cd451c7b48b3b2dec5fafcfc6acc refs/pull/1683/head\n00412cab290ed8db8ba56e95e12081a24abcb9746ef9 refs/pull/1684/head\n0041bb280dc1a53c81287eda1e678c25629c8ebb8851 refs/pull/1685/head\n00419b5ad70828ca0c941fc424fc35e10eb2eb53d475 refs/pull/1686/head\n0041c2b84a61807bcf11f35dff1aa544b0a92a0c6785 refs/pull/1687/head\n00416f6fbd991bafe78b2b87f92f5c6f8327888dd339 refs/pull/1688/head\n0041d3818b9df267986e07e8df723464e09cd195d583 refs/pull/1689/head\n0040c32413680d38e366510a47a6c150eefede26987a refs/pull/169/head\n0041f7b84db702b7b111c176780a17a24d88c721d49a refs/pull/1690/head\n004133dc34724f0cbe5de45246ecab12c5a3c1ae5602 refs/pull/1691/head\n004158c03b5016c7d62755205a561b10babe4f24b472 refs/pull/1692/head\n004122c16d0528c48509297dec8ad6207ce879f20f07 refs/pull/1693/head\n0041194c74cbf4ee1ec28b85979c2424b73175205375 refs/pull/1695/head\n0041ebf909a4cd8718cc731e498ae9ec5cf11a148e1d refs/pull/1696/head\n004126798baab325cb4720e80dd2bf5ad4d3ddd49995 refs/pull/1699/head\n003f3a4c90b02ad2afbe09997cb3cddea3f2f96cd710 refs/pull/17/head\n0040ed7fbcee57b7f9277ffe1260e3365b4b8c628b26 refs/pull/170/head\n0041f6be2d94e8a159d03682495360a84a99e2849ef7 refs/pull/1700/head\n00414cff272b844f4409267f6d4a0dfc35d522b4b1b5 refs/pull/1701/head\n00417d9cd867535b37dfb109312c118fc1c4d99a1e12 refs/pull/1702/head\n0041402453d160e42a2becf0454355e8f21392436ca0 refs/pull/1703/head\n004166d3d1ece5efadd29e2ed40613080bad24588f00 refs/pull/1704/head\n0041d36a83b869ad816367e3a520df8b34e0fa30063b refs/pull/1705/head\n00412d5d59d0c19aab6f41ef43dfaa5f5dd84ec3635e refs/pull/1706/head\n00411dde7bc4eb32f5229e4395528009a6abff975fee refs/pull/1707/head\n004167a4b8816b0d95195649426e01c2d5a285c87c69 refs/pull/1708/head\n0041583974851f9986aaf9aaae1684ddc7da54061668 refs/pull/1709/head\n00403f8f78a70ddddaa6e381fef4e575e5b0bad9f403 refs/pull/171/head\n00411f78db7c0890d6de7d968b149da0cf6eb44bae16 refs/pull/1710/head\n004181b355fa672aa9f87f78ac1365a9fe4302ae6f26 refs/pull/1711/head\n004147050c34195f06ab88e8b2e5d41491ef82a897c8 refs/pull/1712/head\n0041859de7de8c7b56c46fd0a2afb1a56bf7be4a0efd refs/pull/1713/head\n0041508ee173626f605678598d0363806d452e6546e7 refs/pull/1715/head\n0041e431c79ca359bf4a6dc5e756ca2416867b1f26a2 refs/pull/1716/head\n00419bb401e34362ff8f0ef0c7b1e471126a98e6e72a refs/pull/1717/head\n00414a9f3908193b197e0fac3c04a6820f9947527149 refs/pull/1718/head\n0041c7c27dfedee3c8fcd928c801e7b37f24f3604c40 refs/pull/1719/head\n00416eda4698764d62eb549a653d71fe9c89efbda7ed refs/pull/1720/head\n004147db827f4e9e07495e988979b2bcc5f0f1c3ac5a refs/pull/1721/head\n0041dc37d4ac77c3a83b1209c9ac9d386f7a21164c6e refs/pull/1723/head\n00412856b0618349793952634c56899e3a59cb4bfe4e refs/pull/1724/head\n0041137adae315ed82442e245d922230737921ab8476 refs/pull/1725/head\n00417f6ab1cddbeab54f17621134f12643dcff6e78ae refs/pull/1726/head\n004111a2bf4d085236a9cbe9846ff9f22f9976e853bf refs/pull/1727/head\n00416b9ce0fa8acc5fa39b58c998050507de1eafc74b refs/pull/1728/head\n0041eba0ba181ab8cb8f9bdd603762d9ca1d0ee03e6b refs/pull/1729/head\n00409bd080d1c1e0f331e10ca935b7ae84a67743e00a refs/pull/173/head\n0041621b55a6453ea373b338093a4d6ebb246816dae4 refs/pull/1730/head\n004166cf11882a13aa5ecb9dca3a0856625d40a0661f refs/pull/1731/head\n0041ceb4390ee4f63854ee38c1ceffe09bda29ec19a9 refs/pull/1732/head\n0041f046d5b5e50c64f21d971abdfa97cc7d40bff25d refs/pull/1733/head\n0041299bd320c28aa4aa7a7ec3248ffdceddd791f1b9 refs/pull/1735/head\n0041dbb64a42761a875114e956ec6070defbfe422b26 refs/pull/1736/head\n004168e17a207baa24049da479274cfa34d7432c90ac refs/pull/1737/head\n00414a9f6c8d165fbd1f30eb478e7d09e91c185dc2e7 refs/pull/1739/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1742/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1743/head\n0041efcc272b15e6678ae0b87795b085779de6cc6b64 refs/pull/1744/head\n0041afaa7c3ae485f10eb98db9c9ceb3a1b3b135bdde refs/pull/1745/head\n0041fdf37f671a1e1b7fd1dc183769eebeff9563f252 refs/pull/1746/head\n00412c85053cfa420c869bae7ef023c52300eaa0ad2c refs/pull/1747/head\n0041d28d46d556d50949a51ec2b2b9e736b99947cd36 refs/pull/1748/head\n0041242e8396de3475422e0e4b575d2be8b13acfd504 refs/pull/1749/head\n00404f150c542aa5139058ccf57dcad562890916b477 refs/pull/175/head\n004128b5f8610a75ef7f7eb4d0860391893a023a522b refs/pull/1750/head\n004161121d34173f4e17d2787d9bbb9beb50988e5b0f refs/pull/1751/head\n00412bae8356597b70e2a0ec11fb906c9f4e15b0ca12 refs/pull/1752/head\n0041b1e4f7639d8480a1dd8b2d8b58172b5654bcb5b0 refs/pull/1753/head\n0041e8d8de2b047665e2feee094a948020aab6f0cab1 refs/pull/1754/head\n0041dfe0cb485e1b95fa73d7fc01189d7342336139bb refs/pull/1757/head\n0041af351e06e20230e63147e6f91ec49ff018b6acca refs/pull/1758/head\n0040697026d4e8b2db4ae98b820d3d5219bdf6447016 refs/pull/176/head\n0041e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/pull/1760/head\n004168f6fb1246d1b0fceb91454d4350ec541c5f6c0e refs/pull/1761/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1762/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1763/head\n00411fa8a78eaa5b22679c5eef46216f5188a1d94fa7 refs/pull/1764/head\n0041cbc1038324468952ccd6d73cb8139ac39053a443 refs/pull/1765/head\n004156e0c5dc850587be1566c9f64793d6d6d5d236f5 refs/pull/1768/head\n0041bb81d37d4e36bc8f5ce4bdd330670bcb3e0d50fe refs/pull/1769/head\n004196aa2ba53a2ea486f5a769851a40c6695ae1e49f refs/pull/1770/head\n00412a288c660a53a7e834900ac484b30484ee630045 refs/pull/1771/head\n0041217c352ad074f4d185d93ceebca8eb349ec6c59d refs/pull/1772/head\n00417d78ea23fd1e33058e26271b9314228c52ccfd9d refs/pull/1773/head\n0041bc8e36df01367794ea3ef321187a325a9ac69db4 refs/pull/1775/head\n00417d2c3c8a499807f48617aef10ff2d38777b10e53 refs/pull/1777/head\n0041c25a90ec1432dc8d3bdfd8a4897eec1f79e86a79 refs/pull/1778/head\n0041959f67abee6f9d04caaa8d7f89fb4e4bed97643d refs/pull/1779/head\n0041fd17178287784de7abcab551e8d6a3f307197e6e refs/pull/1780/head\n0041e3ca3320607036d249dbbf26371909c8cdb4e553 refs/pull/1781/head\n0041d51aefbf41e7a618a29bbc5d27e61b3d695b5bfe refs/pull/1782/head\n004185d032609f688eabe9afdd6e913a3eccbf02928c refs/pull/1783/head\n004123ca8b3c69fb1aaa5728473b063576f1b2d39375 refs/pull/1784/head\n004117103ff4a194a539f5c72bea680e96d82fded25c refs/pull/1785/head\n00416ff3ddf670d367e0bb94ac1ecbc16a7b84c44da3 refs/pull/1786/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1787/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1788/head\n0041d780e569beeb0dcbf49dea00227b07e7a0557e07 refs/pull/1789/head\n004138818c7fe460059b864af9fb064ef3b372faa3e8 refs/pull/1790/head\n0041c830fa55637683630dce94d4bd1979bd6eaf19fa refs/pull/1791/head\n0041fd24bcecf02345fad0eafb863c1e1a96b8c690ea refs/pull/1792/head\n0041ef51a60c61079cee1ad74195e7ea775ce69cb4a7 refs/pull/1793/head\n0041151da60d325f776b3dd0aeea7d2b772e19d7d17b refs/pull/1794/head\n0041beced838e4690d90045aa67d95eb354ad8ff22eb refs/pull/1795/head\n004167f820873e8377ea084af14056d22554ca7cc21a refs/pull/1797/head\n00417a0f284b57753f79f3d1613fab4b93c8629e19e3 refs/pull/1798/head\n004175f2c449c009b52d0a603bd3cbe8eeb725f915bb refs/pull/1799/head\n003f53aa980fe3061b5e6040de9c8fb10012bb2f8703 refs/pull/18/head\n0040b1cb385e06354cf99ca214be195c0700ffcbc0cb refs/pull/180/head\n00413eb63513540f6bffdbd231239f42f88ddfebec68 refs/pull/1800/head\n0041643497bf5bcb01d049b74b7256deaccbe7499250 refs/pull/1801/head\n00412f72f7cb650e4bd70af9f952839a0a59869e3a65 refs/pull/1804/head\n0041cb15bb31308c98689ae4eb9146890eb4c4b85076 refs/pull/1805/head\n00414a73eb85606f042cbc4cea9806bb6a5aa8aab684 refs/pull/1806/head\n00417a5731326269b729d41b2ac688e39b590748a842 refs/pull/1807/head\n0041d61d2a12da28c0a67e8b2a6a2901ce3581582bda refs/pull/1808/head\n0041c06ead49f70c83092494dd35de5cc23003373616 refs/pull/1809/head\n0040a93a2680f94ad8e04a1103aeabf2708bd5980e8e refs/pull/181/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1810/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1811/head\n004164c2d8663c768215adc1abfc163b90d8c00f7774 refs/pull/1812/head\n004166ae46ddf21a5c9ea38179ee3cb48e5e0933fb93 refs/pull/1813/head\n004162d8b81f9d11177615ab69ad569599f9749c988f refs/pull/1814/head\n00415784c6de647fb7d0e8667740d784bd6855da89de refs/pull/1816/head\n004140d1eaf19843a7fa8e8aab0f612829d02fef95cb refs/pull/1817/head\n004177db6fea24126618973c77b5d1085b6d731abaf7 refs/pull/1818/head\n0041d218d64ce9526b17ace67ffd6c302cdc0d06b330 refs/pull/1819/head\n00413e4acd6540a4da55ca5e2d8fefef07b740d1c752 refs/pull/1820/head\n004155a2cd3bb64e3040d899bf5cf8f1cd4d6580ca5c refs/pull/1822/head\n00410ec6da65e6e898a079591b57055efc061c9cb6dd refs/pull/1823/head\n00413956b56edf3c580ce664f26ba4a2295204a3b7c0 refs/pull/1824/head\n00414716d0cc284b1741d0d3233c73ea47af5bceecfc refs/pull/1825/head\n00415f788d250cd76b750f76dcc6db2d440bd92fab27 refs/pull/1826/head\n0040c36e358ca340e5143c1bae900f62af9c9992f8b6 refs/pull/183/head\n00419a37f354a6af47436166d5dfe516c3689f402484 refs/pull/1830/head\n0041e075984e4ef6a2a4d844c42cbc18543abe5dd211 refs/pull/1831/head\n00410bbc9e95cffef61511f1de8f830e336caa15a958 refs/pull/1832/head\n0041e5bed10b2bd6973ad2a063fffc38780533f8cd3b refs/pull/1833/head\n00413e0bc06126d76b17038544e765365e04f10f12ad refs/pull/1835/head\n0041ad1e720055786f3cdb9c759e5061343c8d00b279 refs/pull/1836/head\n0041bf17b39beef874e602d3b36861aa1eef469aae3f refs/pull/1837/head\n0041ca50521d299252e3df50cc973da8d58ea17dd9d8 refs/pull/1838/head\n004180a2263da5503241882ca0477ea1d99b4c7a20dd refs/pull/1839/head\n004073c82e133e8dc40db2556497ea58ed1087031505 refs/pull/184/head\n0041dd45b9f4aad94150181247b515d878a258593f65 refs/pull/1840/head\n0041e95f66bf3fae34c9834fe303119f68d09b524c50 refs/pull/1841/head\n00417879e9176124c4e6bc5d7dc9e2aa8d00a2050411 refs/pull/1842/head\n004183fc002b5356265d0459729a76aca21324a27401 refs/pull/1843/head\n0041590f17a7d4c339439cc3a0366c230fe60d0ee52f refs/pull/1844/head\n0041a3e12ab1fc688a3d5d68fb004f034dcd83159e50 refs/pull/1845/head\n0041cc048c4cecbfb81fd68db3de91cab8a6d110a4ef refs/pull/1846/head\n0041694695a536c2feb96e0817856cd3b729017b66db refs/pull/1847/head\n0041dac04009c14513b018b5a47194aa0c45cb15a3d2 refs/pull/1848/head\n0041c53eab92dd9d8f1b20f3ca84fabc29456767c562 refs/pull/1849/head\n0041cf9cb9a57237917ae1ff74f121a1fbd6d8e28581 refs/pull/1850/head\n004139bd4443236a577e81d79eaf2adb56ad5bad7e0b refs/pull/1851/head\n0041ca1234fba4d0f639136a17642bfaf8696100148f refs/pull/1853/head\n0041688edfbf064c5cbd29ccce6683cfff62e2a92841 refs/pull/1854/head\n0041e07806737984c72dd2df3fb62f6aa887074abb28 refs/pull/1855/head\n0041950f94d8447cfe8e381c33003731bab17764fc53 refs/pull/1856/head\n0041c9e6324f270b54ef8528ab8a2e54663cc1522bfc refs/pull/1857/head\n004125ab614caa713ea1b3aa85d6ff477956307fbceb refs/pull/1858/head\n004177d871fe2174230183e7a2c9ca37bfc3147c5dca refs/pull/1860/head\n0041490ca7b0714d188ae4fd43dbbf9f603e257b33d2 refs/pull/1861/head\n0041d401575d9c4480a77ed36f22013cf94ba28766c9 refs/pull/1862/head\n0041245917c80414c327aa4c9b4dccbaa6a8de1ed76e refs/pull/1863/head\n0041775c151f3e1a2deb698444685f477766b2eb7ac7 refs/pull/1864/head\n00419cfa3f62676b13f7e218003e801796ca01a26e8a refs/pull/1865/head\n00411ed057902ab3c93c7bc09b1aea1868ee223204c8 refs/pull/1866/head\n0041bb691dd9c831e92f4d12e842b20ec6b198382030 refs/pull/1867/head\n00414f13093d0a7690cd6f53a8a00eb5e961b450e96e refs/pull/1868/head\n0041be23c09d0085e393c609425c87e91d2ce49e4b4a refs/pull/1869/head\n004094fad49150b1245d6df17ef596ccbfdf5e53e23a refs/pull/187/head\n0041adc617b13cacafc11073da7c987c3b4aeebe7e8c refs/pull/1870/head\n0041e7abbfdf7b7587088aabd9b6e6def35157483259 refs/pull/1872/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1873/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1874/head\n00418e73fddffc8970eec9941c65f48522e41fee367d refs/pull/1875/head\n00417870cf2e5136283da85180aa1a4132d0b945e46d refs/pull/1877/head\n0041d5e7bc7be4b270767aa04de43bc3af305e1827cd refs/pull/1879/head\n0040bfcac75d68e64f860fd27dd089f76f6e076ca1e0 refs/pull/188/head\n00412296fd9ca7299a57fa2e8ecb59623a85653183df refs/pull/1880/head\n00419ab39d23ff2b19fa564815999bf51be509ab7b5b refs/pull/1881/head\n00414cf4e663f58e4f5edacda884bed5c035124dfd6c refs/pull/1882/head\n0041bdc42a80a2a7d0ebec1c9ab90a945f344dfd3f3f refs/pull/1885/head\n0041f3d970e2aed28a290ebdc777b1bd9e2a6c69361f refs/pull/1886/head\n0041f52afdc4daed2649a3bd78782713203bb9ec1787 refs/pull/1887/head\n0041a13e63a984798aa57eedeb629a4e42a059304825 refs/pull/1888/head\n0041f2e2f18765b2d1fd298a58c3ea90283fce07cca9 refs/pull/1889/head\n00407a95f8a55b26adc8f99b9e2c54995c0ee85d8fa5 refs/pull/189/head\n00412ed0a0d114dc10762bf4a4e6ce2572f04d4c6abe refs/pull/1890/head\n0041cca09665a98cffb1de8a990b68eef7ab3f42ae47 refs/pull/1891/head\n0041f209a2ffc58b2c9550528b01e5619bb3cab1d82f refs/pull/1892/head\n004141584ca7cbbbb18f1cde26eabb104249fac64617 refs/pull/1893/head\n0041c3e7497e240bf02819dc7d0bb5e666a48669f0c0 refs/pull/1894/head\n00413eba8f8f280b0be0c274880add862f86a1aaebeb refs/pull/1895/head\n004124242e093ecc652d0419c06cbf0f3cb4336ef76d refs/pull/1896/head\n00418b61b330c72c4c1513cd72ffac2aac293cd3a3b7 refs/pull/1899/head\n003f1a0925b76e59133372fc1ba7ee5599b735be1611 refs/pull/19/head\n0040ff96305637fe8ce3e1f744bfe71eef3bfdde98d1 refs/pull/190/head\n0041cbd943c6525c545cec58af0404e17407bba01195 refs/pull/1901/head\n0041fa6cce474ebdf2ff70cd23969df81b51b28249c0 refs/pull/1902/head\n004191834bb605717048dfcb97d50f1e211b7fe18a10 refs/pull/1903/head\n0041e44a5ef5ff2c9c28c4e4f6e72e57301637991d89 refs/pull/1904/head\n004101318044062e0dcb5c3e49f6536ec235ab23b0c9 refs/pull/1905/head\n00411bc915c5b605eea03cb4a8290ae461462e1ab24f refs/pull/1906/head\n0041cae78e108c9cb5fff71e8cb8741349b94f2ad4ee refs/pull/1907/head\n0041b6b055ed963bfb379183b8c02c6ab208e3d6b473 refs/pull/1908/head\n0041183eddf9cbd560150b934d0f1f4569f1bd882a3d refs/pull/1909/head\n00406ce0980f6d150f2624dcef29836028a2cb1f7870 refs/pull/191/head\n00414402048781f29961cbdb12ddad0ca8d81a196afc refs/pull/1911/head\n004157029178c367dde42ce6ea623fbb49c05e051f22 refs/pull/1913/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1914/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1915/head\n00414fe84f446a4c7ba338e110ed8f61418adc4c022c refs/pull/1916/head\n0041b639422ec1c00424fd896389628e8734902c4f1b refs/pull/1917/head\n004141793010447396bc491832ccb9440144cbf74da0 refs/pull/1918/head\n0041772dc97d1ef15899ffd143c7954ec412b0a416ee refs/pull/1919/head\n0040cea55d539a5935d83a95b3b71e1800a59ca6aadf refs/pull/192/head\n0041faaf7ac71d88129f9d698c85473a5180e0278c83 refs/pull/1920/head\n00418081e72673e2f1a920091f3bf221093d05276dfb refs/pull/1921/head\n00414263ded36f0b487b333e3871ff1e316396fe9ffb refs/pull/1922/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1924/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1925/head\n0041085fd13676bfb1f72c4a45453c77befe939a86ba refs/pull/1927/head\n00412890c32995007b6d48e87e20a853a86b9832ab0b refs/pull/1928/head\n00419e67ae92fc31d9eafb455aab6fe32eb5e125c30b refs/pull/1929/head\n0040c4eaf01af99cc8dadace1d1d127086a392813469 refs/pull/193/head\n0041f68c436ef6c041a988c803ef30185652612a73b8 refs/pull/1930/head\n00419f56be92d5c167c9e54911f073bafb528b18828a refs/pull/1931/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1934/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1935/head\n004128e4a3f2c16e21f20465082e4e63cb8e3503256f refs/pull/1936/head\n00416e9281133ab28e8bad2525600907428b1f70caea refs/pull/1937/head\n0041cf2236dbed3e22d7f04eb2db011b95874674e87f refs/pull/1939/head\n00408863cd9f782c86bfc463f1d8384c89027224aef7 refs/pull/194/head\n0041d49b4addeac1932ce5edc072938940965633e5e3 refs/pull/1941/head\n00418fba4b1e07a31d6eb84de0d3285a230de18ce490 refs/pull/1942/head\n00412d8629e6324a07fa6bcaf99c3d851effe085606e refs/pull/1943/head\n00413d608d7911850e4edf5a9417a8783a0375aa0fce refs/pull/1944/head\n00410e88f4836971e5fd8c9216f9d0a0f62a73109764 refs/pull/1945/head\n0041312e083a7df0caa21a7460b124c131a35540abc3 refs/pull/1947/head\n0041b195aa96dd4c1ed0bfc423396702b7cebd38b64c refs/pull/1949/head\n0040e18c14875dabe2847beccc4ace2c8fdefac4b003 refs/pull/195/head\n00418a89d1ed64499e3e23c85ac1d9fc87b093d88f52 refs/pull/1950/head\n0041eeae4900643721f121259e79c101e7964e7b26e2 refs/pull/1951/head\n004198a7e10c7c548bfab390374855271f4f06dcc94a refs/pull/1952/head\n00418e2e7cdf1a1c84a06c7ac1286063b5184844919a refs/pull/1956/head\n004198385fa0202ba48d9c829bd4cd438ff735c48ae0 refs/pull/1957/head\n00415f02424e5e280ef631ce64faa518a33ec2b356d2 refs/pull/1958/head\n0041c655361c61f4a8d4cc5501559014c4da4352d3cb refs/pull/1959/head\n00400203592563e6188de76fb2e29f4c5a2e5f722626 refs/pull/196/head\n004172d6bdcfffcda628c98c17935d4dddd8724612d6 refs/pull/1962/head\n00412f5322e8632c0ec51dc668b92cfe1164b811c60f refs/pull/1963/head\n0041f33bfb247752d7f00c9854af85f59cf146ce3b2f refs/pull/1964/head\n00410e5a9d1b17f94dd79f1bede6ab86a9ecdad51e4d refs/pull/1965/head\n0041247452069e49b1bc2ddebddb39f4b1a42f7dad33 refs/pull/1967/head\n0041d2b9459487c77b121ebaeb1936c98f6fdc4efd6f refs/pull/1968/head\n0041adfb91949539a56ef5a79dbbf1440d8cb98e48c1 refs/pull/1969/head\n004039610731e0ec8d72c80702b55a15478a948ea7c4 refs/pull/197/head\n004145182d7887e98e3be7b417e1aef6fb5e96c69e4f refs/pull/1970/head\n00411f8c81e7dcf2453dd59ab709d3cf49e8961de5a4 refs/pull/1971/head\n00412fffcbe318fa873851db2b093533787d55af5988 refs/pull/1972/head\n004119b96a70c14221d539217dc123f077fa97afeb94 refs/pull/1973/head\n004188214dc2966923b84c45650d1d2a06d53f8d2d7e refs/pull/1974/head\n0041d0438d88f8318cf279bb6b905aaebef0000fd4b4 refs/pull/1976/head\n00418c6e38f64217d2bfdd5c74b4820542d69312caed refs/pull/1977/head\n00415d11d2ecfa6241332ee224ebe1e3817fd70ce5ed refs/pull/1978/head\n0041b3fcec5942a9e303e7cfc8fa90dfb5aa8548ce0a refs/pull/1979/head\n00402d059659b02a3d4cd478d9cd608ee625f6101623 refs/pull/198/head\n0041f118e38cc79ccd80541d773a73a40f48f730f293 refs/pull/1980/head\n00419a4d3c10c0c76ce56b5393256e582e0f6156a354 refs/pull/1982/head\n00418f8added4c8e79c5df1f09d35161ca44ab42314d refs/pull/1983/head\n00413e9f8f819beec39c2171888cc75bc09eaf682a8e refs/pull/1985/head\n0041ea8a5331c4dfd8ab33559dfd63279c2745a8dab7 refs/pull/1986/head\n00413fbd7bdb7df0c0626e2375262ca831e82ee9694b refs/pull/1988/head\n0040381bdf0fdf166a8efca78ed83aa3729eef57fee6 refs/pull/199/head\n00413b494e299e1bb738432f2da3adbc16a4b9925cb1 refs/pull/1991/head\n00413a5a4ba0f0023ba2be6e8f76e55a59c77e83aab4 refs/pull/1992/head\n00419232e80f273caa3c4e30de4ba2df2b59724f53ba refs/pull/1995/head\n0041931da3b5a36e92341821bb07a6ce12c6e2964ab5 refs/pull/1996/head\n0041756a8bfbf71a83a7830c3704f0826dc5e9363a4e refs/pull/1997/head\n00419054561b3be44b736d0d75c1fe93650c9d72a19a refs/pull/1998/head\n00417224063d42c89b8ed4e88bab92552b683972cf56 refs/pull/1999/head\n003e45ac7a9b17fb34cdf0ea52ab533b70eb4ee60a23 refs/pull/2/head\n003fa89fd2c8ea82bb0ea441e6f8bb2fa16a097fa40a refs/pull/20/head\n00401e54429c2152b4c88a7ffca8d2d3a3da663e7dc9 refs/pull/200/head\n00413db85348aacfb66d3198837378bdf39b2b83b202 refs/pull/2000/head\n004140b3657c0fea727e0fafa0f15e5cac27062c9467 refs/pull/2001/head\n0041b828c1942fc576b764fb501426561645988c5182 refs/pull/2002/head\n00410a633c74dcdc35ea13b1131c185ad038501b9910 refs/pull/2003/head\n004177cea761a0e5d480a0ee655e192f47c3c4995fc1 refs/pull/2004/head\n00419abe4a3186ac55d8fbdef81cf718fad8d1a89079 refs/pull/2005/head\n00413bc50173f33ade9e73e9cd345b96aac6481bcf6d refs/pull/2006/head\n0041e8fb8f5771525831e0ce36e4b590bb7f6d28e436 refs/pull/2007/head\n004093e03d4276610c22a0e92e73012f8a4143e68c5f refs/pull/201/head\n00412a2592576e38d9fb64498661223b0e5d41659e50 refs/pull/2010/head\n00419ed18665d7649950d1f7c5e55d24b5ecdb6ae217 refs/pull/2011/head\n00410bd31f53db252acbb57473024b0e5f62805cd8e2 refs/pull/2012/head\n00412634e09e56a84ac60c8133659e86924db2907754 refs/pull/2013/head\n00414e07d9a95939834719489e7315fa330e0600b60f refs/pull/2014/head\n0041c4f79ae666057aad3ff6dd83878be6ed2fdf3668 refs/pull/2015/head\n00416ccafe45354eaa1a381171f692f3aebdf40e147c refs/pull/2016/head\n004191d2cdb8f126b98e33832a99ee369f8e7d33fa15 refs/pull/2019/head\n00401a57100be071b113f1844f864622afd13e7ba357 refs/pull/202/head\n0041f9f69a443ecabce263829413bb52d40b4f62829c refs/pull/2020/head\n0041276ef05e74f0b36860354051b60734570860cb44 refs/pull/2021/head\n004173b1fe3e8f664a33cda63a888e886a43d1f09453 refs/pull/2022/head\n004162075312fc10fc501a1c8e79109416fcb1d1e0fd refs/pull/2023/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2025/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2026/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2027/head\n00412d365a1a7f06d0c6c0b533a870a06ad947ea93fe refs/pull/2028/head\n00416e8dc9b9791d3d2c32e97a075edc1bacf515f7b8 refs/pull/2029/head\n0041c3f2d82f0160787e23b604ca33bff1c7155452c3 refs/pull/2030/head\n0041f427a8cf2cf8c5a1281b5597c97a7824e081ab41 refs/pull/2031/head\n0041c5c74a89138b010c108b44c04f6b591a5effd6f3 refs/pull/2032/head\n0041c2d191f524e51434cef74087074f695e1a300d1f refs/pull/2034/head\n004136bcd51bf95826cb489f181ca8a20374e2edee7f refs/pull/2035/head\n0041b17a05a6c75c73cf4d7472765dc24c67086d344e refs/pull/2036/head\n00411c841c1e1f263e42179306f8c9c0efdc07ffceac refs/pull/2037/head\n00404d972ac05deac77ffcb2ce21adb2650ed6ea6a3d refs/pull/204/head\n0041fce332fde15b1e5cf8519ca4e41f7dabc15230cc refs/pull/2045/head\n00412e6e93ff444f2db51e2f94b7b4440a6ee599bd40 refs/pull/2046/head\n004177a020b5769f6739f496f57539930e5c3b8cf0c4 refs/pull/2047/head\n0041616ee95df5e755c3464c5ed9d997531da5329ea7 refs/pull/2048/head\n00415da2bc3a293b18f920aa668e4e84fa3a2f54243a refs/pull/2049/head\n00404cb5d471dcfafbc390ddf00de86d2b3273e214b0 refs/pull/205/head\n0041a2766dc2c1f01b71b659a9fe24c24e526f9ea2b7 refs/pull/2050/head\n004165e83af51b80729115b49c787f4c7461561ee600 refs/pull/2051/head\n0041dfe7469fb6f43fe8f147e7ae4f37f4bee4b86efd refs/pull/2052/head\n00410f2c1ec931639bd563db8209bc678eba6bbd316a refs/pull/2053/head\n00412021cf90c380582a43f86948682aba9ed8c6444b refs/pull/2055/head\n00416e6fd0abe0b41abbbcddad8ecf505968252149ff refs/pull/2057/head\n004184e8c2cc730d0c599f182e6f9d1bd1836451a6a2 refs/pull/2058/head\n00402ad69f5897e9dc9fa230f6aff252131a058ac5bb refs/pull/206/head\n0041979cb14b1c89295b411f2cc96698e302b63c869a refs/pull/2060/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2061/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2062/head\n0041fcfed2e6876d14d39cd59b7b5bfb1661de2fbc5d refs/pull/2063/head\n0041dfa203535005df10a8dc405af9e990d1501df161 refs/pull/2064/head\n0041534ef3fe70c9ddf8bb3be2611967a27fdc18af0c refs/pull/2066/head\n0041e3307ccfbe4cfc66099049a0c02447ce4214d28a refs/pull/2067/head\n0041914cd027ad55591aa88c0b458793cf4fa06fc2c6 refs/pull/2069/head\n00401efded0c7da7b9b855dff24b2ef5ae27532496d6 refs/pull/207/head\n0041a97b632eefa842b42c14cd6a738e71ff03615eda refs/pull/2070/head\n0041da57e2de83414be080dbe083665c90008a0562a1 refs/pull/2072/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2073/head\n004174d79dd6aab423b075f15e0577d277ae125cc436 refs/pull/2074/head\n00410928411247b51199daa3bf7d5cda670d216e9d36 refs/pull/2076/head\n0041774d2eea01be83a26f4d857a0da058606e26d3f1 refs/pull/2077/head\n00415671f0abd1b02a8c003aa00accce1600f405c4f1 refs/pull/2079/head\n0040140337e1e1d9af38371be75fa4d5f5a4b239e50f refs/pull/208/head\n004124556f57344c7bbddad2b235f40612fe50abdc8f refs/pull/2082/head\n00415f0956d3fc07895cdce08b590e3a58bec356f5e5 refs/pull/2083/head\n00412f0e6b16a8eba22013463d2f06c29273af6586be refs/pull/2084/head\n0041d97a9b2ba365e6db9d4eff805118536b997c0c1b refs/pull/2086/head\n004166a697f9b0d9a72ebfd04e201ea5ea51bb12079a refs/pull/2087/head\n0040eccc45a3ea6c3ea1ffab1b224e0f38701acae5ce refs/pull/209/head\n00414e252005ddb3f08c77948c828a695f5cc90e10af refs/pull/2090/head\n0041c858aaf921ce8c2323422505bb4250581a9c7213 refs/pull/2091/head\n0041820ae57aa36afa9ca11411ecc74124fa99a5d11f refs/pull/2092/head\n004192c8ff73ddf065aba993496d8b27b313e7702a08 refs/pull/2094/head\n0041cae269ee9de564f8beaee54af3307f62e5b3431d refs/pull/2096/head\n0041aadef428d601202d79299c176e4b41e245ba843d refs/pull/2098/head\n003fdd60e6b515cf2f60a17020ae3c99fc26c48731e0 refs/pull/21/head\n0040b68182934b0c69bfacc4745141c97159263cbafe refs/pull/210/head\n00419bdbf91f4437ca3d3424c25d405f48c7762165e0 refs/pull/2100/head\n00411e05bd5c637cc150c7b0242660a7cc56a57fa45a refs/pull/2102/head\n0041d2b1520f1075eb199d17ebe44029aa429dfa198c refs/pull/2104/head\n00416d8dd63c503812e495e9aa4051931a312e45f3d1 refs/pull/2105/head\n00416c0238bd3f954d95d032ac8699c69c7dbb261ede refs/pull/2107/head\n004125defef4dc82fc1a655825d41fdcc16ff9315c4d refs/pull/2108/head\n0041edd5576921ab95d4230fd39e2c0879ff8a1373aa refs/pull/2109/head\n0040af2477aa12be46101c3d7cd0003e45b17e98a98e refs/pull/211/head\n00410f384635ad38f435e9d342c1d084c8d82d76532d refs/pull/2110/head\n0041e888febafad31e6977fc98801c90d06e3930575d refs/pull/2111/head\n0041f1cc4c719b85eff4d09e262482fe08f2c82b1ec7 refs/pull/2112/head\n0041c215ac334d53aad70c8f49c3ca4469138afb14ea refs/pull/2114/head\n00412846504bcc6555185b6087e2b3df29b20acacee6 refs/pull/2115/head\n0041b15d59d9f159cd31b4389084e6393cc13c89c24f refs/pull/2116/head\n0041a0ccb0b329ec1482e4fb4b357808f69be1d2918a refs/pull/2117/head\n0041d5ec3caab9b15dff0404c53f8503647f0ed9ca8d refs/pull/2118/head\n0041e8b0cbb473269a2ecd82efa821bdceab82cef3bf refs/pull/2119/head\n00400f5e062dd35b9ebef263473fca25512b315a918f refs/pull/212/head\n0041c6506ee1cdf64b1f8e5aee02a68d2373ae93152e refs/pull/2120/head\n0041a46c8c3624067acb6c11e9a8f7b2d55b9b18980a refs/pull/2121/head\n00412a59b5e507bc1618e1a8cab5dead857665cf40a9 refs/pull/2122/head\n00415d69ca46b8216051eaf37047a336912b1123c5a1 refs/pull/2123/head\n004148c3be619b89ba4966499bbcaa4e40bb6af35b48 refs/pull/2124/head\n00419a8d69289230a495f8582cd65eb0dba7d3307620 refs/pull/2125/head\n0041e5eed9e46a09b94567bf86ae4f6d46019ec18faf refs/pull/2126/head\n00410bfb1a4d4902cf9fbf7593f03863dd37b8724ccb refs/pull/2127/head\n0041c54c9f8ec1c7f9ad8ba779671fc710d4a164af0b refs/pull/2129/head\n0040c5e09ae449a74b916851abdde913f3098608905a refs/pull/213/head\n00414728b5044faf129ffd24a985c74cdf31040a3dde refs/pull/2130/head\n00418a24cfd871e0958f9fa723f6c6253952b0deefb7 refs/pull/2131/head\n0041db8349bbf8bcc8a467d116268cabab91145eee0e refs/pull/2132/head\n004171dcb05b8b4671c05f18deb458e5d3aa8f95e86e refs/pull/2133/head\n0041364d95c03b18af27f248bad58a56bbbd2adc19b8 refs/pull/2134/head\n0041159d4dc4ae6f9e9816035ae170f0204043df7a8f refs/pull/2136/head\n0041566aaec5b39a4dccb72e688c105dddeb57cb0f54 refs/pull/2137/head\n0041f3b87b9a1c2db51259d6445e488369fed87788c2 refs/pull/2138/head\n0041517ca96e424138e2f7e09b69440b46846c53ce65 refs/pull/2139/head\n0040e03ffff3d0359f7a13ef512ace8c56c74411b2eb refs/pull/214/head\n004105f77f86e9caf21163e15e1ea8028a9468a781d6 refs/pull/2140/head\n0041223312684d462a1bc67706baccba127b2bbeb1f0 refs/pull/2143/head\n0041a326ddd7e0e2286cd23d9bc38b6f34bd0843cde8 refs/pull/2144/head\n004181aa02647563b8231cb1db035ff97764a4bc4c08 refs/pull/2145/head\n0041fade7728c3f1bb109dbd6a58cc9cb5b5a7244448 refs/pull/2146/head\n0041d0e0731232ebd7711fd7f7d80b4286f4ba97ff70 refs/pull/2148/head\n0041e70a80f91dd512f7380a90b53adc925c132ba932 refs/pull/2149/head\n0041d5a96efa27504a15bf9a03c432088fd8243415cf refs/pull/2150/head\n00415bfc4e906a519270df95056eb9a48b8089f68d56 refs/pull/2151/head\n004126cab433e325e4142045bf6f2f8276071738cbb1 refs/pull/2154/head\n0041db0945190e0388ba27a9bded0314f3016ea6f262 refs/pull/2155/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2156/head\n0041370f57d1ef87a56d7a59f5e7004d413c5cabefeb refs/pull/2157/head\n0041f99c264fe30fe0915efff777bc94dc16df9ab48a refs/pull/2158/head\n0041a10bcf7c8df9f32499ffbb56a13a52d7f8cd64ad refs/pull/2159/head\n0040daaa4a42527acc0ba496672ea2c807412acc1958 refs/pull/216/head\n0041a94c3dfe95cb58665bf4b4c15fd39db98b96ccab refs/pull/2160/head\n0041a3f61afacc7cb29a0643328bead3ae6c08c6c05a refs/pull/2161/head\n0041e9f54cb2fda9cf61d179d1485a0c0aa8f21bf901 refs/pull/2162/head\n0041167f4e6825a414af01e75365d3c87525a214a550 refs/pull/2163/head\n0041e8ace6973134c0829cb1a9c598e447a64a59e2fe refs/pull/2164/head\n00414d66b12e44db8f5abcc2d2a8c319003e185b34c0 refs/pull/2165/head\n00414b2128402627ebb80b7d8d1af8c092c9a119d840 refs/pull/2166/head\n00412917da51a376598d389320da3cc266c082512951 refs/pull/2167/head\n0041c18c08f53377f808d1989402e9ca25a4d4b1517b refs/pull/2168/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2169/head\n0040d3b681cfb9b0a6af09daedd4a3f8ba02ec766e3d refs/pull/217/head\n00417e5bfb0a34444628009a93432b2bcdd765d15de4 refs/pull/2170/head\n00415c6726b2bf8aa3b7ff79bbc6aa971e3082d93504 refs/pull/2171/head\n00414d9d3c0babdfeb31f6eea7cbc66dcb4bca1c70e5 refs/pull/2172/head\n0041ed63121ef55c84127cb5137dc0a650e7cb302571 refs/pull/2173/head\n0041f347c8cea2246a490ac9101188c4f86382be1424 refs/pull/2174/head\n0041013d338151b3156f6bb1d994d2d3d3a5b1c3d0a1 refs/pull/2175/head\n00414e2227162e694ebbd975631a8ac0a65f1a031792 refs/pull/2179/head\n00403931b2f889e2c657f34c3c5167030143489ca091 refs/pull/218/head\n00417e92aaa16538e195547bb6d41198d65dbf1182c9 refs/pull/2180/head\n0041952f05576f2f134514cc91e5b2dd9f4d3dd209ce refs/pull/2181/head\n004128c50d845b49aac26f7cb9df609bae2ab3727190 refs/pull/2182/head\n0041c1a513c3c934135dfc1154f4861bdf7afbdce60e refs/pull/2185/head\n0040fe110eee20684e6f2b05a4c067fb31879e456932 refs/pull/219/head\n0041a1da249964cf146c54539cca524fbd1013d2029d refs/pull/2192/head\n00414ff69d3c81ac79198a4c99a285c66bf68ea4c538 refs/pull/2193/head\n00410ba2eadf30c4637e8dfb9970899564a43aa6281f refs/pull/2194/head\n00416fc5cfc1a359cd30193055997583fe393cee0739 refs/pull/2196/head\n00419bcdec0855ddb161e35d720fd20c9a572061adae refs/pull/2198/head\n00413e9d126a22e958a30ac07045f506ce1f19f4d968 refs/pull/2199/head\n003f985084119b8da35919c3de651e275acc06e1cc2b refs/pull/22/head\n004062ee6c452595eda122ff0e40ca69f8f615b54438 refs/pull/220/head\n0041741ad5fab0aeff22fbbc8663cd51b98a930e7b5d refs/pull/2200/head\n004131f5035ade93af773bc0f352e16b205978ba8288 refs/pull/2201/head\n00416bd63d39f998df7e56a95ce1e678d7e00c1fa86b refs/pull/2202/head\n00410ec8f46347ea4c4b3cfefa672d755302b6bc0195 refs/pull/2203/head\n0041645959293e93b7c41224ca6565d549ec45f20fc5 refs/pull/2204/head\n0041d9d3e311facb95d40ce676157dfc5efb29dc4bb4 refs/pull/2205/head\n0041a1c81c8de57edcf53010d0708f694b1accf8690d refs/pull/2206/head\n004106f20c35e22816059987089b3c2e48ce47798ed3 refs/pull/2207/head\n0041193141017843084d2f272ab8f26a89b6b047302e refs/pull/2208/head\n004176a1a98700ec28446ad7ac165e15ca3880fb0eb1 refs/pull/2209/head\n004048611d3952d8596fe9781d8c8bbc15326690e6a4 refs/pull/221/head\n0041af034a96d6cc19a7fcaf1ef9d0bf3b6b478ece7e refs/pull/2210/head\n00413bf320e9526067c0746dffc1ea8b4daebe2c5bdc refs/pull/2211/head\n00412afae4f3722aa4fc07828ecfb290cc1ba21d4f00 refs/pull/2212/head\n0041ca9da16069d42325e475cc6c343b6f6edb5ce623 refs/pull/2213/head\n0041c7e3aedbb454e839909dc86a0c3d3111117b96fd refs/pull/2214/head\n0041caa0a41f2f4270e59b0120162bad48fecfb4b744 refs/pull/2215/head\n0041ff3e8f0694a4d37576abad605a9e21720174e787 refs/pull/2217/head\n0041aff2b3e908081ccebdee53267b4997f9da5166b0 refs/pull/2218/head\n0041fda0c2e5ecec32a74ab3e1667481f5ad7a696610 refs/pull/2219/head\n004040b3ec19fb72ebf2d0384a6ff5d2f2014d4a6992 refs/pull/222/head\n004180525c230f1caabf56e881ed7ab459df710f57db refs/pull/2221/head\n0041ac9c814844d8656bcd36a929411406594b91b27a refs/pull/2222/head\n004199f27a746f2f16538e241ea4c994a5f3ddcafcf8 refs/pull/2223/head\n00411a3e213541a2de4e0d7d9ddaf4679a20b48405e2 refs/pull/2224/head\n00414f9558a8d2f1b7419e80eae901761c80aa53aa8c refs/pull/2225/head\n00416a253e4d552578539f484b436c32a0eb5a131fa7 refs/pull/2226/head\n00411d10b35abdabbaf3fe8f420992a07f83ce68c614 refs/pull/2227/head\n0041b23d995bd7c7dab28b221c8ce2bee885ab70249b refs/pull/2228/head\n0041ccb42747dc8a368d7084d46d87014b77047ae1a5 refs/pull/2229/head\n0040336503602a15fc771aa1c1c36486ddb77209dfd0 refs/pull/223/head\n00418c3360a8a5d8d531d0f2e447f9e70bdf8f796972 refs/pull/2230/head\n0041ca22722c1dce5a66f5717ca5d62e38a9732596fc refs/pull/2231/head\n0041d80dc2fe58efb2742c955e07a6c07bc1473fed65 refs/pull/2233/head\n0041c3693b5ca51373d28b6b52f004020b4fe518816f refs/pull/2234/head\n0041ee10756deb3286462704eeb4759d78ba10969110 refs/pull/2236/head\n004116222ea878bbe791f998cac019b70bb1765cbe9f refs/pull/2237/head\n004110b241e044a66932cacabd1afc4d3fbb0f35d077 refs/pull/2238/head\n00410da409bee5c8c4f7b82ee5b7f2f8df0331f9bff5 refs/pull/2241/head\n0041fad9c9e4bf307e38cd5c046459e8b2eb9e7553e6 refs/pull/2242/head\n0041b2456b296ce2104856d6a84fcd191cc32406aafe refs/pull/2243/head\n0041de20dcabbbaf0e964744cc56b4c9a20ef7f63b05 refs/pull/2244/head\n0041a4a50c2ef4bd1bb506ae8d7e70ed0095fb2ab0f9 refs/pull/2245/head\n0041388f6d5c12827d5c51d427531f1bd087356fd2b5 refs/pull/2246/head\n00413fd8c2e118cb471d75e559804d7bf7ded4b894df refs/pull/2247/head\n0041a92e4dabef6b5d88e2e5fa79bd46add0a3b0185e refs/pull/2248/head\n00418557ff43e4873f5da41953950105be2565dea53d refs/pull/2249/head\n00402c34baf3b48f0bc9c895ebca5043d0544a4fa601 refs/pull/225/head\n00412984bd8d2522d267b1d8ddc787e33a6f867ab951 refs/pull/2250/head\n00416cbdd8411ba53f845ba6e1e31f0903053bacd683 refs/pull/2253/head\n00410062172b11f98d0980b1d31dc3ed3b8a444ae09e refs/pull/2256/head\n00411f994a25d12eb1cd9afe903a4558092f62f9af8c refs/pull/2257/head\n0041e5bd727e599e58b57680b6af4228456476e6a324 refs/pull/2258/head\n0041490296fa34b945dbac7f68521f5019e3fbc6e010 refs/pull/2259/head\n00403986f1e346f705814c8f76b1e1a1f39f253565e1 refs/pull/226/head\n0041000f12bd3b89f030d08c78d5a9458aede68aa0e0 refs/pull/2260/head\n004150c4ac1ca3ed40862ba9de2e245435245d3f2eef refs/pull/2261/head\n0041c16df2a93b493d1c94e4b1d4b08d89205acaeeff refs/pull/2262/head\n0041d878e3498a22d960dad7f886489a3a43bb644ff5 refs/pull/2263/head\n0041f0c95462867090157886315ce4ab95d2f2624dc0 refs/pull/2264/head\n00412b13b45ea1646421d1bb7841a0aec13a9b232040 refs/pull/2265/head\n0041db2b9a6dd5d89ded180a53cf6a98608216b1cffe refs/pull/2266/head\n0041682844de6e22955ed5a6844ea6bed462308b87dc refs/pull/2267/head\n0041c0071255816784a8e42484060df1f0ac2cf31932 refs/pull/2269/head\n0041e600f3a2159c07215036b540f7ae6a6a7770eb45 refs/pull/2271/head\n0041f3e4189020ed591fe7f3abf1f2e5c98768cdbdb2 refs/pull/2272/head\n00416a7310cbecb14299aa3acd0b3cb8550dc209584a refs/pull/2273/head\n00411aefee6d3342b8b05c326ca8a57136f6f5374806 refs/pull/2274/head\n004146cb03dcaddd28f0c845744bcdd4c499ef4d74bc refs/pull/2275/head\n00412754e0160707967e35faa7943ffbeb00b565831a refs/pull/2277/head\n004137548c1ae7cfb2a024df5e8795eeccdeffb05ae2 refs/pull/2278/head\n004161f534a7e55b4e83460721b951bbf091f3241874 refs/pull/2279/head\n0041f8b616e0a7b1c4ec58a4e1aad97154410fd0f573 refs/pull/2280/head\n0041cd8b16c68ca6e0dfd7a68e0574eec5b56cb3e4c8 refs/pull/2282/head\n00418786f6ff2338f4b3e2153b4155a26ec887bd1ba1 refs/pull/2283/head\n004147859e6f1e02ff5b514f258a5aef89387c6ef8d6 refs/pull/2287/head\n0041b90fc5f656efe508cccbf7c9cac25e96b6819966 refs/pull/2288/head\n004175544cbc15c840a07067f40c54f81b47e966b45a refs/pull/2289/head\n0041927cf2bfcfbfa3688c0d2cc1444161d9124c605d refs/pull/2291/head\n0041541d04c51c2b9515cd75bd6fe53b164faf97a6aa refs/pull/2295/head\n00418cae4953d6b1900dc06d1f7d10d854a7eb96bc78 refs/pull/2296/head\n0041e75fe6a870f8214d2df73b9fd5fe247a36eda287 refs/pull/2297/head\n0041642e6153a9205a47270bbef52d5083bc9402b7e4 refs/pull/2298/head\n00412738976a712891d506de1b2cdf9572e2486b43ec refs/pull/2299/head\n0041102d9ebaf8f6d139d2570fb35367f72d7f842eb9 refs/pull/2301/head\n0041200c1e907e9a9f4061ec24627aec227da40b0dce refs/pull/2302/head\n0041ba4ac9c4029e17faaed41a4c77a49dffc4b137ba refs/pull/2303/head\n004104071d4510e1a9eae2555db2e195d9907c20314b refs/pull/2304/head\n004182296895d676cbeb713f8237fa6c9aa0b55417f6 refs/pull/2305/head\n004163555fe8a246e7024f16d17f969da9d53c0bae0c refs/pull/2306/head\n00413c3c13493aaa9aa000f02a81c3e5079ed28cb133 refs/pull/2307/head\n00418805681354f7bb76c0a7d088ea53362aa4f913d4 refs/pull/2309/head\n00412fee37d27e5dc081565870881b0af98226099b6a refs/pull/2310/head\n00417d3020ae31e7269f666702c5c89cf68747a8357e refs/pull/2311/head\n004194b292ae40c1681ed13df2d2f5d6349bcddaae8e refs/pull/2312/head\n0041a5b3685e7194ced65ad79ef485212a4e1394ae9d refs/pull/2313/head\n0041c7a9bea483be59f447aaaf8fe27bf0051712f093 refs/pull/2314/head\n0041ff3ea7175f824e65b27f28c59142c0039323e179 refs/pull/2315/head\n004152ac0b29edd8fd78ae8f58d9d63a40d5a80cba99 refs/pull/2316/head\n0041c08f32f67aa91a9af146eae74b2e52320a8ef9d0 refs/pull/2317/head\n0041a692921c7d2ee84358d9e40cfb28f5e89f98f238 refs/pull/2318/head\n00418b64c98d985f517087ee4c3137577df0f806a2bf refs/pull/2319/head\n0040a72b0f899bb35939f65c2eee4653a4534fdca938 refs/pull/232/head\n00410e5ecb7666490c0a5dfb73dc97134520970c6872 refs/pull/2320/head\n0041dab1e190e50253fc770f4b4e023cfe6c942088a6 refs/pull/2321/head\n004118d1aa22cbf255b253a972fa17e2a8f19ff11d83 refs/pull/2322/head\n004125207bc51923412606abc8a60c7783afabcfb554 refs/pull/2323/head\n004167aaede68e0e2d8d0325c15eee9efc7eb9acd1fe refs/pull/2324/head\n0041ca8e27a9810a339fb0429cacb004a51e266609d1 refs/pull/2325/head\n004115f4b1cbe50c19a55b6ec61d94f3b8bd5ff9254f refs/pull/2326/head\n0041c8924b63350c65435531a2f16b5062b8e0349d16 refs/pull/2327/head\n0041bd79c21ea0139abbc64a6a79a8d96fbf7181762f refs/pull/2328/head\n0040b8676faacbfc2e6fea33905a6cdce631ff426ed5 refs/pull/233/head\n0041aa40413e669c4e137cd8d39068e8ba99933f95ae refs/pull/2338/head\n00418e378c436c58840a441776e29cf3c7a4f0a1d382 refs/pull/2339/head\n0041419aa71a493e10bad201d1702ef420c9c26399fc refs/pull/2340/head\n0041d71393208f1bc5e9e8d3a22d175c859a13cd180b refs/pull/2341/head\n0041773234bf12f485f32d12854e89ee0ae605a25889 refs/pull/2342/head\n0041d8fd98c896c8af5854915ad1164aeb785d0dbf61 refs/pull/2343/head\n0041d13a8ac8dad35d3ed7e88d79a0209e3619b49530 refs/pull/2344/head\n004125c7038b09a902e14c917a3424b0fb59ae47b908 refs/pull/2345/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2346/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2347/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2348/head\n0041c0d8d5792e9ef5b8c5f5e42de11d9cadf19715ca refs/pull/2349/head\n0041fc2887fef044d0d3f5643b8328acbeb8daeda055 refs/pull/2350/head\n00417e3f756a0239d51869cfb1e766f83aea55bb78d7 refs/pull/2351/head\n00411131f46b62d559ed6349f1886d72998122b904e2 refs/pull/2355/head\n0041a785c0b107b0245aced8ab6444a0dcd554690891 refs/pull/2356/head\n0041fadded923d6b7487a878306b4db76ac2fff66808 refs/pull/2357/head\n0041084bfa051b06e9cdf96eba3b5cd96497dc1fd302 refs/pull/2359/head\n0041a8db307f7d3a457697460ca84a76312de41244e4 refs/pull/2360/head\n00419e7e709fcb8a4aaaa479e7f5045bf031c3ac011e refs/pull/2361/head\n00418b37b80317b9be689039062b3de0a1c3cb886f69 refs/pull/2362/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2363/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2364/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2365/head\n00414f168a73f84b4e8bf2ae582b2aaa22646a9927d6 refs/pull/2366/head\n0041eaa3b70bcd32c7a2fd92ce341a1fc3577a573a0e refs/pull/2368/head\n0041ddcc9575213116fd75c1592f21a1199357c02cd0 refs/pull/2370/head\n00413ca0c78954d8ce2178ca2bd45146236a700a3c5b refs/pull/2371/head\n0041319c369a4ce9c5b2530a5171e22a17974dd6af96 refs/pull/2372/head\n00419ce1728af46e3a005b534308fd6b851174f6607f refs/pull/2373/head\n0041ef84432d4f589990bae9541eee952006fceff4a9 refs/pull/2376/head\n0041138fca28bcfa8a93b3eb5db7f285a37ad8dbd541 refs/pull/2377/head\n00412295d8b3fb84b1b493b39c3810639f46ad042987 refs/pull/2378/head\n00412d7a5cbc3855c9e9c54646e933a7605109a735f0 refs/pull/2379/head\n004001df8689af378f1d9b0123e6797da3e5e73c2e22 refs/pull/238/head\n0041a1cc2ec290ae9e6eae4b8c0feee477b32ac76e7f refs/pull/2381/head\n00416b28bfdafdc0262bb92f67ed21444d6bc589d65a refs/pull/2382/head\n00412fa59043f55f9a6c44243abba66f3541e9f5ae9b refs/pull/2383/head\n0041b997add1e8dca84349e6b571ed0f6dde4119cc8b refs/pull/2384/head\n00416618f3a764a74a0a0552c5ca080bee3d15077eb3 refs/pull/2385/head\n0041d3883c619f08310c58c16691a93a67cf94edd324 refs/pull/2386/head\n0041f39876a2c0ac0f18f7dd42c48859f55626b46fe1 refs/pull/2388/head\n004006ba35b53646c2937bd1fff198b269d1897eb583 refs/pull/239/head\n0041eb33b57255744abfbe557369066619701c0d0f69 refs/pull/2391/head\n00413dc4950c009dde0ab369b2ca459368b953190e40 refs/pull/2392/head\n00415c753f8eac6e9e83a39261373789c09a8299cdf5 refs/pull/2393/head\n00413924c28bcf5f0a53df04ec74b5f6c36b98948dda refs/pull/2394/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2395/head\n004119846ac4836859d8c568239a42b72ca44139742d refs/pull/2396/head\n0041cdf1a7062f8f077d3fa4d6d08dd5459b34880854 refs/pull/2397/head\n0041e368558b630ab18408c79db485a474dfa4683e94 refs/pull/2398/head\n00418f4bb87155757c3a39c3f27aa7a315f34983e3e5 refs/pull/2399/head\n004067e93c659b3fee46070e27c3ec08402a35c82375 refs/pull/240/head\n00415804bb125905a1dcd8b103dfac2ad2b15f811984 refs/pull/2400/head\n00417b80fa5cf0abd102423d5dcb24d7b32bf5212551 refs/pull/2403/head\n00416a76e512e9b58d77a7e5248cb678a4c647f1d669 refs/pull/2405/head\n0041051dca78e7664c9b451670baf44d15851a7d33fd refs/pull/2406/head\n0041f91bbc6c66207b0e908e82733f029c32f1292641 refs/pull/2408/head\n0041a5b9ad92313a57ff2a0f53f2b81aa90b9417d91d refs/pull/2409/head\n00404debd5e8e0860cb57154cfa59525c87bbe9e1021 refs/pull/241/head\n00412c28c867ccebeced01a0f0ce2ecf98f33df27077 refs/pull/2410/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2411/head\n00412184298934e71c29b6d66ed59782938fdaaa0f20 refs/pull/2412/head\n004199325072b64c02fbd888329fba65944e0bf731a2 refs/pull/2414/head\n00410917f9702082147abaa26bb6fcb1357f8a0f31af refs/pull/2416/head\n004195829ab78ed81644b5eb41fbe8409788a9fc7e21 refs/pull/2417/head\n0041c5a219f066e5a874208b2f78033d8ed0f90762b8 refs/pull/2418/head\n0041e28d97d2634995711e5abc794ee6484099128e71 refs/pull/2419/head\n0040d971c87456fbe727730b656e1c6a5de7f7831364 refs/pull/242/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2420/head\n00413ea5d0adbc23cb3059c3297a9be8b854812883dc refs/pull/2421/head\n00411178657965713054cc5790a36b291b30b6d9ca81 refs/pull/2425/head\n0041c9c8d7b7605dbe60cba2eccc00f55723c2acdaee refs/pull/2426/head\n004103549f653ed13a38b886d13855e30c311942d652 refs/pull/2427/head\n00414154a9cbf1c273acd34a5d929adba231b469e629 refs/pull/2428/head\n0041cd93be6a1d7c92ee9f76789fd7c97842b0a7740c refs/pull/2429/head\n0041f733ab04711173a59877d809b2f557a9e3ee4a60 refs/pull/2430/head\n0041c5fa3e53f03ad8e999d57b7f76237617ad4037b6 refs/pull/2431/head\n00419bf72cd1fce073ad01b904fc1ce17773d2d89d6e refs/pull/2432/head\n00410715e65452d2cde3bc2b8bcee1c5a2029ee8afb3 refs/pull/2434/head\n0041794af8c606abf9a5060b9a4442999b9f23431678 refs/pull/2435/head\n0041e87432e66ed5209673cdd0ddb671a8a9a2c03708 refs/pull/2437/head\n0041c4ecded417152c3d5bc809d566769e71780731f5 refs/pull/2438/head\n0041536d8403169585521583475f89d6ce5aa03e0a92 refs/pull/2439/head\n0041ba01d1c94743595ca04e14ec2573dbee254c1c1d refs/pull/2440/head\n0041da45d1e2c8c8c6e3e770b310cf6b050f6da03aa3 refs/pull/2441/head\n004156ef8c622bfbb8376ecb2ebb20ba1668804b461e refs/pull/2442/head\n0041b01339a98647dff2ed86c2d229e23182e57f4a87 refs/pull/2444/head\n0041107392ac7410b8c25028a271523b0f4a050a69d6 refs/pull/2445/head\n00414c66211ac3614faffce5e8e008f16542fcf19019 refs/pull/2446/head\n00415d69266426f17b173056b98b4ed8f01ce0e9caa1 refs/pull/2447/head\n0041b9230a99fa4e2188859f37ced2b7c4427d8b7be8 refs/pull/2448/head\n00418665468e83b5be7770ae198388dcd5ee61dfd5ce refs/pull/2449/head\n00404bdeeb490f450be54f2e73835a76831f332cad8c refs/pull/245/head\n0041244459aa1f47e3433ac537fb89d3dabc7fe23fd9 refs/pull/2450/head\n0041d478b8f397f01d149f8f784a2ac2c95d40412c9d refs/pull/2451/head\n004170decc6cdce3762e1bbeee5e28d5559f80ef8318 refs/pull/2452/head\n0041ca9eed266681e9b352b64c73d5557c15cc38e465 refs/pull/2453/head\n004129c754bf205a00188f6f0a1db1c9f3d82f68815e refs/pull/2454/head\n00416922b4330f05d791b64aa56c40ab953940e71268 refs/pull/2456/head\n004149329a17ed31cfe6fe2dba21b88db58367e7c494 refs/pull/2457/head\n0041f87c0318ffc66e3c82451cebc129ecbc7bb0a933 refs/pull/2458/head\n0041efd8c2b4ca7ee897c0fab7a93ec00bd8cd29c7d5 refs/pull/2459/head\n0040e6a0e38f56d88fe922bfb15e35f05f15daae72d4 refs/pull/246/head\n00415511906fc24b22b252d54f5d2a4b862662510a0e refs/pull/2460/head\n0041ae298fa67b643324650f89628863bcc4dbe1ef7c refs/pull/2461/head\n0041644d27f3c18e9119d1fc471d07279c6e666417d7 refs/pull/2462/head\n0041ce867243c2cdf166b31a687a350c7b9b705c7194 refs/pull/2464/head\n0041f6221e43ecb01c46cf84d2e4938a5c3dcf37a5d7 refs/pull/2466/head\n0041e3567ff0d7f5412ab4135bbd4be8adcdb333b5b7 refs/pull/2467/head\n004153560ba756790c71366a7fb6ed9be8dff4e8ccfe refs/pull/2469/head\n0040c6648aaac24ee53b9933bf43a97aee09dc22c3c1 refs/pull/247/head\n00419d221250b69f232adf7fecd8749cad4f2a40df2f refs/pull/2470/head\n004183dbe9f90092b8e791b9e906138eb3417e838561 refs/pull/2472/head\n0041086f6f183efe4ec20ac643ab2bc5e98677f2d94b refs/pull/2473/head\n00418fc6a5c455a1b4dbc1dbf9869bbe3be6ff82412e refs/pull/2474/head\n004117b37df5d0f231481d6e5b2ada66666f99840fcd refs/pull/2475/head\n00413b2392429fe87cef09e404e695af344e9964370b refs/pull/2476/head\n0041aa0b81d3a6db4bc68a306398c30b473c6309cf58 refs/pull/2477/head\n0041d6d326a4a90095edf0da1d06d3eb48975a29fec1 refs/pull/2479/head\n00404709ec33c18f5c2653efffb908a8b69474fc1deb refs/pull/248/head\n00412af5644abf515b5b8424c8eb7b12faf35be68f07 refs/pull/2480/head\n00416eaa4e79b0e4b1178f5a03e299258632338b781c refs/pull/2481/head\n0041f6cfbd09ca2659675ef5ceca4d9b03b86b42849f refs/pull/2483/head\n0041098f63817e201983078c996ce5b1222aa2be6a01 refs/pull/2484/head\n0041157a47634e6089c7f7938bc7939f0661f5563b14 refs/pull/2486/head\n00412d3046144846d1a981b4ee30db75ac0e0a799f41 refs/pull/2488/head\n004180aa3dc17e885ee35a09ad1488fd18ef42961473 refs/pull/2489/head\n004197094af2d52994da5f658a26372006e0446fad9b refs/pull/2490/head\n0041224485342b1c8b88e4b4c3c48f13c083fcb837ab refs/pull/2492/head\n00419cc699a1c0eff4fb777a32951b06519dd7f25335 refs/pull/2493/head\n00416dbaf17f9a9fbbca7be0d02d5e4e0bdb74b0aa33 refs/pull/2494/head\n00416c1465a055851c726de155021c7284e98b92cc91 refs/pull/2495/head\n0041d302e811976f33178b99b6f15e24c1c23db46da8 refs/pull/2496/head\n0041363d41a21a19b87a0d02a6590d091beeb3eee582 refs/pull/2497/head\n0041568b516d94c9ac0877faffb3dbf13dfd9823246c refs/pull/2498/head\n00410c46bb4025498aa53f8872fab755e8cc02bf2006 refs/pull/2499/head\n003f45d1d4967d81f6ba4e3720a7065a3dc7ad83efd6 refs/pull/25/head\n004073f225e0cd741972f843ead3efd68f3768d32a40 refs/pull/250/head\n00414558a3e87dc35d37be3ecf5804ce499cc7a280c6 refs/pull/2500/head\n004130aadada170106402b84ed7cbc1e3a2be714c261 refs/pull/2501/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2502/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2503/head\n0041c2cdbf33c04c2261bbf13460875dfa96c8d4a900 refs/pull/2504/head\n004131cdc4803c8bc38ad71e14f1177b4dd1e1dbef5a refs/pull/2505/head\n0041cc06e5bbdf95c0e9502e86d24caa07da735e61a2 refs/pull/2506/head\n0041b64512aa5404eb97a175897e819a0a08d8be84bc refs/pull/2507/head\n0041c5fd3054cedd2be85d7e3b7013675990beeb20c5 refs/pull/2508/head\n00417fe9934f21fedf95a3bd95f7a0d7b51ac7425c99 refs/pull/2509/head\n00403444266fc3ee97cf87d942e5c3cfb6adcce0457c refs/pull/251/head\n0041c7c8e84ae2c10084fe1b913262804cdc76591509 refs/pull/2510/head\n00419a05a9350f70a44308e36728775b045eb47931ed refs/pull/2511/head\n00414277918e4a52bb2fe657d9782c40e5ef59678a57 refs/pull/2512/head\n0041c1035ce33537f701f91b7f1bf6df9b943d7eea80 refs/pull/2513/head\n0041a744fde6253c6a98f1b58497ea97d6d7e3c26a59 refs/pull/2514/head\n00419ce7f5a2d56f6a15b084858ad26a26b1b88ba8dd refs/pull/2515/head\n004197e4213204d34947cef09cbe4c16ab83465e9d1c refs/pull/2516/head\n0041ba6b47281628ec355528f1e472fa96d864d2caf9 refs/pull/2517/head\n0041a408bd7d8cfec77a87a9554285045087fc6f87ca refs/pull/2518/head\n004191651d9e6ff7181ed487b6ced372f0bae22d32bb refs/pull/2519/head\n00407f9fb1a86780ddcf6e73c22594f878de5e844f65 refs/pull/252/head\n00410fe7f7663a58e3735fa7f45f46b8ca64b4bf60a7 refs/pull/2520/head\n0041e19697e71d89145a504989888ae3faf0a739a27c refs/pull/2523/head\n004183f32f12b3c992e78c2b96524b4652966367ed3b refs/pull/2524/head\n0041e0bf1f04ecd19faa9d800e5fbc85ab4de3a11f07 refs/pull/2525/head\n004117dd77cdf4cac22f250d00ad1d43f3b928a0a8ff refs/pull/2526/head\n00417260f278cc92a8f2e620c55208c8bb9311c3bbb7 refs/pull/2527/head\n0041b0a9342ef09bd25dca67903d16fffcf45c199e8e refs/pull/2528/head\n0041a06d52e26333b88ae90c515acff70dfb6e5feedc refs/pull/2529/head\n00401cbeaa642c6340f4450ae7baa44745bfa361f16a refs/pull/253/head\n0041016576c8814583b730870f8e2015a023f234712d refs/pull/2530/head\n004174189b5520d233ba50fc975c076aeec7cdaa25af refs/pull/2531/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2532/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2533/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2534/head\n0041feb4d189cb1125b0838cac8b6570a0f8ddd11621 refs/pull/2535/head\n0041a5419a2150dde4d2923f4cdf17a23ef20f6c88bd refs/pull/2536/head\n0041d47dccfce889e6915995d122d04ef363014ed89c refs/pull/2537/head\n0041dc6f679abfd23d56e171946d908b75e5acdce47f refs/pull/2538/head\n0041b72c34c7f9edb9ae8513e95b6d2245c2cb5f54fe refs/pull/2539/head\n0041a2cf07661f649e73475c124118e8cdc334280c1d refs/pull/2540/head\n0041877b62e647862471f1d2b6376773eec2c3a1b211 refs/pull/2541/head\n0041cfc1741a5ded4e6040868b9012629862be1a0077 refs/pull/2542/head\n00412b6a997e296ea3fee132e8b9478d2073849f4e12 refs/pull/2544/head\n00415e8d1a9990b15e0f2219b5897f37424e302ca300 refs/pull/2545/head\n004125f771752f5119e8d697ba008f23e70823d72e8c refs/pull/2546/head\n00413198f8f6b575d2e954b588b4a67e0c123c51c6d1 refs/pull/2547/head\n0041acfcd4bdded2da1570dde992d6e3c15f2b21dc1e refs/pull/2548/head\n004131e9796ed8640c0ac39a81c62bc5b819521e53d3 refs/pull/2549/head\n0040fa95d2cc63ed28380c42e591258a30f607866069 refs/pull/255/head\n004173943f8d9b7d83cfb556848b167fd7c900a7e98c refs/pull/2550/head\n0041bed9872cd09ea6cdd74e31bc0eb4278a1476cf9a refs/pull/2551/head\n0041db7f04921d64675178666b7b2a8489d7ae3ca6e6 refs/pull/2552/head\n00410cd05892dc65cba018f56aad7dcda7cc8c5c4bea refs/pull/2553/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2554/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2555/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2556/head\n0041a84727a064c21268375d16b93feea2c95b038bc2 refs/pull/2557/head\n00418355cc67e9e6e8da93e59c179492d4b0903ab8cf refs/pull/2558/head\n00419c151606c877ad06bf89b3835bc356f0dec77b37 refs/pull/2559/head\n00401a970259913bb7403cdc4608f7fe9e7743f3ca51 refs/pull/256/head\n004147c640f3d31fd87b03010f20f7a4b8bc8640ead6 refs/pull/2560/head\n00410b9b22dd1c444e6ea86560e277d02ce35f0b15cd refs/pull/2561/head\n00410015619ff7aadf7a3004b1d627a1d398e51bb524 refs/pull/2562/head\n00412db5b830eaae0062ad1f518b77ab52bb27d28155 refs/pull/2563/head\n0041de1988eec8f01e838cc5697ebe961b3d07a91e61 refs/pull/2564/head\n0041bcc12ff125f2bac6e2889e144851e9ab056b30ee refs/pull/2565/head\n0041b2defafa31c947d8217a78ee64784d6e99071268 refs/pull/2566/head\n0041be8cf6b0c06195f841c7fc0136c3f4640c2945e5 refs/pull/2569/head\n0041254a670d2cac777740f22c3871b37d41daffdd2e refs/pull/2570/head\n0041c22c95d233964393d44d44c40b905ac16c0b5272 refs/pull/2571/head\n00411cb9ff8dc46e8aea62f8a43288bc84f2252db672 refs/pull/2572/head\n00416e72345f68ad7349d61d4b5cea2cc75d556d808d refs/pull/2573/head\n00412fcd5646c29b6850d656ece947749a865f8479db refs/pull/2574/head\n004142496b7fdc3a1239142d3e2bec836b60a78a472b refs/pull/2578/head\n0041d35db462766019ad82cb1f272f3f2d3e694dcdd5 refs/pull/2579/head\n0041046915c922731515b540ba344e2d420ac4a52fd0 refs/pull/2580/head\n0041546fb5d556524597efdcce7f2fc45a6e2307dd99 refs/pull/2582/head\n0041f2d1e6a62dee228f2f344361ca109cbbf2f0b24c refs/pull/2583/head\n0041dee53b9d72e183c2043edb6a8632365088a5430d refs/pull/2584/head\n0041eff28852d362648c378ee1f14d68eb16ec8d3ac8 refs/pull/2585/head\n0041675f8d051d94f0f000ff8dac8a93eff6458e3616 refs/pull/2586/head\n0041a8a4d03150df75ca23b4aa1fdb09e9da5add83e0 refs/pull/2587/head\n0041246b65dc5814a2a1050db97cfecee77014ec06e1 refs/pull/2588/head\n004181e335000a43373b83522864d2b1729b1d6d6e60 refs/pull/2589/head\n004027b9d604bc4ca31002e242af3eb43a4d26bfbc8d refs/pull/259/head\n0041e0167739ff07740a1565e1b2bbe2a3eaae584e3b refs/pull/2590/head\n0041b94c9ecbe2dbd3f612c4e2caa6886d494be3cf73 refs/pull/2591/head\n0041e57bd03a3b8a26295dc22d092334563a34bfb07e refs/pull/2592/head\n00418ead6a9209d4457843b2ac6e9a7a2549b0886067 refs/pull/2593/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2594/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2595/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2596/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2597/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2598/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2599/head\n003f627e315ddb24233c9159877a91e88faccbeba942 refs/pull/26/head\n0041b3aa240f3cc2cbaf9b810aef9390d3b2ff73a39d refs/pull/2600/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2601/head\n004151fdb7869d6b103c64e96e6a32bc0687431714e9 refs/pull/2602/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2603/head\n004172b478255f01f30aa5b2b33bc697a6216782ce29 refs/pull/2604/head\n00413456c65b5bf8a455ab4be528c932e94e2dbc51b8 refs/pull/2605/head\n00417689490034d5ace342ad180af664d0561dda7fc5 refs/pull/2606/head\n00418f747d48cb81b208e2dd43b2e2399a4e4c9fca16 refs/pull/2607/head\n0041ba522680e8bbf2e06e9844b268ff00147bf5ccc8 refs/pull/2608/head\n0041afaf0c24c73a4ced47abc729116f4e304056d85c refs/pull/2609/head\n00403f9aaf1d6ee0724fb367b8d9badfc153290050a8 refs/pull/261/head\n004125403ed7b2fa54cabe42ad36770b7ded16b17231 refs/pull/2610/head\n004148f4740a642291a6616f29fdbd1e2189449ed149 refs/pull/2611/head\n00419edcc47a2c33ee7c596ee623a34bef3085185446 refs/pull/2612/head\n0041a3fa21166c461cf3c98eef1ccb3ab98bebf0beff refs/pull/2613/head\n0041a23c8b65649e38e68f0c7ac2bf3d583fa278d905 refs/pull/2614/head\n00412a74d38a8465b18f667c93df4a4b9a1688a1621f refs/pull/2615/head\n00411fdcc1587c4182efa6bd6f1a82bd78ed8ab891ad refs/pull/2616/head\n00417581fe8599f89d5424cb3e5fdb82b9d883feff9d refs/pull/2617/head\n004134ea656dc06e0f8b84c07ce9ea716e6227f08597 refs/pull/2618/head\n00411575bd7dec8eac4d7c46a8c60ee1ea8d043909a2 refs/pull/2619/head\n004046c557ad9391746796a00d6ef2ed0d33fa6b46d2 refs/pull/262/head\n00411b72b4bf65fd05a51f3ae039dcf4f4f80c00e85e refs/pull/2620/head\n0041e4cdb49d5a0ec98f63c2d0f5892ae88b76eb131b refs/pull/2621/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2622/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2623/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2624/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2625/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2626/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2627/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2628/head\n004118a33ffec8ba556b2aeca01c69a3f9c1dfbeb194 refs/pull/2629/head\n00403c45a5fa82837ed3281394cf1b141a4565dd3701 refs/pull/263/head\n00412ad5c547030d92c823cf05d33473e5d569896028 refs/pull/2630/head\n004182bcd8510836ce15256951440f1866f56129dee5 refs/pull/2631/head\n0041664c3eacea7aa135815a12b75bc17c1502bc2731 refs/pull/2632/head\n004116630e020ff2f40074480b5e188176ee1f7dbfbc refs/pull/2633/head\n0041afdbef0c49fac58984098b1563bec4b1c94c45e8 refs/pull/2634/head\n0041bfddf1d4a056551c40ccfe9454c0b3cd9693af41 refs/pull/2635/head\n004165e80f09f0a79b12df6beac44abf245151bbfefc refs/pull/2636/head\n004161b021f24ad4fbe29130c0672742a4c1efd31609 refs/pull/2638/head\n00418b76634b8701e90cebb880fc7f8a1faa4e6b46c0 refs/pull/2639/head\n0040b079da3c6af9b1a139db5127457315034abcbbc3 refs/pull/264/head\n0041d2ee349b9919d416260e3717338f9b65e6443b85 refs/pull/2640/head\n0041c86b29e940e3f800f5760f11d41380537a88b131 refs/pull/2641/head\n0041cc703e4f8dbb366e8270a20c0cd91cd53d913a52 refs/pull/2642/head\n0041f3c5d59acfd34527284183af35c2bd0a7b422d8f refs/pull/2644/head\n0041ded67731c579c99af1671e569bbe7e889a633f44 refs/pull/2645/head\n0041b7278b4edf0acfbfd7a0b9230de099e37aad8611 refs/pull/2648/head\n004149585781890214a9f0a08b1dc952bc3cc3d7fd49 refs/pull/2649/head\n0040ecee40da8a3cfd90ad43cd05f7a3f0f47e67a826 refs/pull/265/head\n00418614cbd27dc368dc265816d801ed18e5d00fb760 refs/pull/2650/head\n00415af5d38da5724640f85bc05ba64a1e0bc347e5d7 refs/pull/2651/head\n004115f4b9fd2edee8bb6767003ef2afb27d86ff4c3b refs/pull/2652/head\n0041a1642fb968ee8ba6edd65113bd68e3f396500dae refs/pull/2653/head\n00410d08a2838b3e4741764cdc02cd20fbc164ae60f1 refs/pull/2654/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2655/head\n0041e43f1e2f16a91260fa2b263e8b968a3f535f62f2 refs/pull/2656/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2657/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2658/head\n0041d43b986486789b27ca98202659606351a803cdca refs/pull/2659/head\n0040a1fe55ab948b3507af0e547366e964e6076c0a43 refs/pull/266/head\n0041a5f399a9d582eccb24df4de26c083b04e572e3e8 refs/pull/2660/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2661/head\n00416e4ce8879df1a46060aa7b3a0c05ec18c372ee52 refs/pull/2662/head\n0041db7b359f0e8b3255b22f4cbd1b7ca78685ed381d refs/pull/2663/head\n0041c3ed87788b6021c49c8fc2b9d576b6366537c69a refs/pull/2664/head\n0041f4836610cc31a8a09c823c3fc84599ddb4210720 refs/pull/2665/head\n0041430da5fcc21bc97a11a462c7936f84bfdd1e7d97 refs/pull/2667/head\n0041115f6caf9f2265b6a258ec491d02f6c0b39cffdd refs/pull/2668/head\n004156ed2ad272ee8c04c6be6c1200362aeae05292be refs/pull/2669/head\n00401dfff6435abe32ec18ea4343f41053924ec0bc06 refs/pull/267/head\n0041bc8a9dd8a47a6dcb322502560c6f5a1d65f8aa77 refs/pull/2671/head\n004165d911a77093f0e33f73cd261e754112d094dd1f refs/pull/2672/head\n0041a2521a301d632a896d24596519077bdcc684dba3 refs/pull/2673/head\n00415859aad095aaca071c336ec429c2321951364f87 refs/pull/2674/head\n00412ec5dda14f2593535a8865717ff7f9068737f777 refs/pull/2675/head\n0041775f379dba856e9969c8efd9d84a9c0b34685013 refs/pull/2676/head\n0041ae09e4dc91ab9aea20446af75b61a79092c3d30c refs/pull/2678/head\n0041b6d02fc3a46c7aa43a0ada56a4a05dcf1bff91e4 refs/pull/2679/head\n0040aa35755406731fadfb18212be848b77d5bc133d8 refs/pull/268/head\n0041b678f0620138174c1af1564c46d599ed454ce4c4 refs/pull/2681/head\n004146a6462fd1e901470278e3665d8553037e986977 refs/pull/2682/head\n0041014193bfca96310ed507387a25f064fbf0610cc8 refs/pull/2683/head\n0041847cf4f7afbf164129660be68a389152f32fdc92 refs/pull/2684/head\n00416088aab6a59dfec9d5a9a954dca42c9b3fdab2d8 refs/pull/2685/head\n0041cd156d88f9c8da9fe495b6819e27c8fa332d0ac4 refs/pull/2686/head\n00412d2f49510dbfe5dfc92660ae8278e5c9a26ee2e3 refs/pull/2687/head\n0041d9d09dc8c2a3a4a9eb07acadadb87a928de092e9 refs/pull/2688/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2689/head\n0040df8678d532946bc9d6d1ed59ef24767bba5bf003 refs/pull/269/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2690/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2691/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2692/head\n0041557627d2be80aa8f8337ae5c841c82daf29ad30d refs/pull/2693/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2694/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2695/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2696/head\n00418321be766309bdbdad52f1f91e367589c6be4660 refs/pull/2697/head\n004142cb69954753c00db29bd25f72d8aa21d9466ce5 refs/pull/2698/head\n00411cfde0f7f6ff199b73e233d1e72c7bf3dbf8f2cf refs/pull/2699/head\n003fd12b185990668acabd3be3e2818f5d3154548672 refs/pull/27/head\n0040c60a5854a5f6fd7d431afb69b5b663056a6c9122 refs/pull/270/head\n00414a81447cd5435c74ad91a0fb2d85ce437b82c1cf refs/pull/2700/head\n004110865d01d184ebe325dc402150d8f0b500e22c35 refs/pull/2701/head\n004138262d8cd70f7bfcd9785e9e4be9ee7a075f85b7 refs/pull/2702/head\n0041c37b8f9d2000409e91259278670aa787e5a010b3 refs/pull/2703/head\n00419edeffa512ae514612ff4cf14bb271d03688c0f2 refs/pull/2705/head\n0041c5a80c1bb0cc6865bcc440a6ddce92af5cfd9561 refs/pull/2706/head\n0041b341add1cf7df7dc61b86e99d55b4e14ce2b1f3e refs/pull/2707/head\n00418af58f720a0a05c5fc147052a62899ac2ac0a425 refs/pull/2709/head\n0040cdfced31cbdbf455bdb87427fb458d6709f9df80 refs/pull/271/head\n0041887b5b2bbf1cc4a80cb5abd0c4af99551cd62da7 refs/pull/2710/head\n0041f9af70aa10c9580d624f687ffc071e66e6ae5218 refs/pull/2711/head\n00410c23b69f7b334ac6d4b75644d645ec0a24e72544 refs/pull/2712/head\n004130ed0c4b02a46a20561a5b2123aa08fe1c6e5f8f refs/pull/2713/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2714/head\n00411a91edfa25502cbbba58f8c139744aaef93a4725 refs/pull/2715/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2716/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2717/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2718/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2719/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2720/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2721/head\n004132b09542271b6dc5961ccf6e653d1517fd6180e1 refs/pull/2722/head\n004108a0bb08a6972d4f70752cc6a1d293ae603f07f0 refs/pull/2723/head\n0041d94268f0484742f927ee73bebc05131f09cd37e0 refs/pull/2724/head\n00412c8d08e44698ffb03ae857730ab6b14486bcf0e0 refs/pull/2725/head\n0041ade73c7449073a28fd5bd36a1d48fc9a85d91f0c refs/pull/2726/head\n00411432ffa7f85e9d9b31acbee7f313291a1acf5c5f refs/pull/2727/head\n00414efb6e194aa53d31dd1a5ffcf90e8dc70c9fd31d refs/pull/2728/head\n004089be2b28d522855a7d56d0d6781c841e2d9fe8a4 refs/pull/273/head\n00414a4e64e2fe93ee38e495cb246582f7ba1ce19525 refs/pull/2730/head\n004151b9ae5241247e80b30d68e9b983a8df1ad9f44f refs/pull/2731/head\n0041fc986f627df1f299c03b248a549844df6bb84ac2 refs/pull/2732/head\n0041a05ca8039996626cd40db82aca293ed64a36c439 refs/pull/2734/head\n00417751fbeb2c3e466476dd9b194d8fee925fffdd64 refs/pull/2735/head\n004166968de6c82b4ee867d38d170b5f9d1df9ed93fc refs/pull/2736/head\n0041ef55bd3f7dcfac478506006f469e50f7f0e01268 refs/pull/2738/head\n004160b2751d13b6888d0cd4f2625642f72fcb6dfb13 refs/pull/2739/head\n00413592dc2989ba7b480c78195899aa3a15460c688e refs/pull/2740/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2741/head\n0041d54a91cf61f504a353002f78111cf1a42d5766cb refs/pull/2742/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2743/head\n0041a755ba68a1bf8e48b50e4b5c00a84cfb0b9cb4f1 refs/pull/2744/head\n0041d621f965c8650e6697f74839464a84329f52c460 refs/pull/2745/head\n00415f80f7bda1910871b33cc8568eed9b9e0a067abd refs/pull/2746/head\n004127f34058a675bdba5e5e9ff196293398e560ffed refs/pull/2747/head\n0041ec6a31f01d35bbaf086bcc2098cab5959c632479 refs/pull/2748/head\n00416e76f8d379609f9945377b7045ab308979f816d9 refs/pull/2749/head\n0040abaa66143b82ff64782f3d8e5a726fa3d8ea674d refs/pull/275/head\n0041f5d9e64f8c83fe518d93b584cbb099143745e362 refs/pull/2750/head\n0041c5c4e3f5856a61bef515aa5e0a69b72826f536e5 refs/pull/2751/head\n0041bd209b316901966059e16cc7985122db957e854a refs/pull/2752/head\n00414fb5b70400f425e9b7c52d397373b4563539edd0 refs/pull/2753/head\n0041d344dd1ac65befdb61c7016d1ec2e6b72d42fa0d refs/pull/2754/head\n004119a3f119197386ef948b52e3041356e01cd72455 refs/pull/2755/head\n0041a0816f94ab06d17c770334b5875808ae5dd20dd2 refs/pull/2756/head\n0041d360762d855688c45c934912f14e3e07945d3ced refs/pull/2757/head\n00411a596384bb4ccf7e7a241bd5d4540d98b65ae151 refs/pull/2758/head\n00412031ec5f09cac3612093578697973ec78df3ee7c refs/pull/2759/head\n00407acf9f795de84bc83c6176a6e0332453bbe51fa2 refs/pull/276/head\n00413517588333f1a378675690923792341d2b94f08b refs/pull/2760/head\n00411e29bdcf8ed23a4dc8f043a0963a773c056edd63 refs/pull/2761/head\n004159daa621cf5085f140f7513b12bf98611e8b5582 refs/pull/2762/head\n00412a625ab871036149179a92d70bcedf0a11fff820 refs/pull/2764/head\n0041aabdaa18934aa47b6a1a682d02cdf3fcb974debd refs/pull/2766/head\n0041f9a984e7c1b1faa582cde1ab72fe6e07286bf239 refs/pull/2767/head\n00419cd85f118c2603fd0524f0d9b8b78e265063faa1 refs/pull/2768/head\n004189d47a15013cfb60bfd200cf61c47b62d2de9d5e refs/pull/2769/head\n004104db79d2fc3294c78027967576ab0f886228ddf1 refs/pull/2770/head\n0041bf7e690cc30eb306ea66ea0a7f53eaf21afb2601 refs/pull/2771/head\n0041fd69d044571f9c6daec232fc59bdd9a8d5d4125c refs/pull/2772/head\n004156b14b7449f7e3514178108b5b688ed8797253df refs/pull/2773/head\n00413532e240bfa976ff538013367aa27338b8380921 refs/pull/2774/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2775/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2776/head\n0041d0ada1d23b06bcd3948b924cdf761a8390569550 refs/pull/2777/head\n0041516179e60ccee64e0eff2f405286d3c4513bc459 refs/pull/2778/head\n0041a8e35df702581892410de7d98a5bdf2e53c671f1 refs/pull/2779/head\n00409ef86c610ec21e3a398ed7d7d02ae9b2070d19d7 refs/pull/278/head\n0041efa432d9e9e19623caf79c4dd0b359f6ee0984f2 refs/pull/2780/head\n00417ebc50d417b25a285bbcdc8ba416c390aa0bede4 refs/pull/2781/head\n00418f936d8ca8889845c1a1f3e468388b60b5384ded refs/pull/2782/head\n0041fffef8ed543bec1e79e2f1e3e668c2ad3f7aa1b1 refs/pull/2783/head\n00410c3412a5938c0af7c15a20d95e2b39e65f037a11 refs/pull/2784/head\n004126676724a4bc1eaca84139c94ece9cb77fe9224a refs/pull/2785/head\n00410efae10947090c7e2ba66ce048ee8933569fdfd1 refs/pull/2787/head\n0041eb8724b40c9693ce5cb7ba322c4dc917ec2b0166 refs/pull/2788/head\n0041c46c59fd46e2418d293f3c45575e0c1952c7ebe6 refs/pull/2789/head\n0040387db6d1376294aad267c4927a7abb44cf8c5a31 refs/pull/279/head\n004130f4ed16e3b290acecfd565720ebf92dfa5c69d3 refs/pull/2791/head\n00411b6820e13ffe15956e4973dcc16294c9b9ca9637 refs/pull/2792/head\n00418a10e02c2a94af79e599774ce224d022ad5c6b15 refs/pull/2794/head\n00411024b7d519a107554bc6a5b3c251af71cdd06b9b refs/pull/2796/head\n0041c9520de348b6bf3b70fb7f6db48d26503ed37c5b refs/pull/2797/head\n0041111952e89e593ebf05626dd8d8979745c7f81f79 refs/pull/2798/head\n00415467cccdc73e0dd78c1674d76854bce827bdee62 refs/pull/2799/head\n003ff487a58f5ca9cf47cc62624d6e74f38134172298 refs/pull/28/head\n00400f1e0091747295f93910650e5dc16de612fa20f7 refs/pull/280/head\n00419c1176adeff7fc3e6523c496d40242250e26719c refs/pull/2800/head\n004133a3087a7ea73bb06343884720a8f9f9c62dacae refs/pull/2801/head\n004113b27b8dfafcce495fbe3f919c2a286bd002982d refs/pull/2802/head\n004139de5c14157758242b12e2a1c73fd1bdbde80905 refs/pull/2804/head\n0041b4cb96c9ad88813e5705410a5bfe3b2d86ef0949 refs/pull/2805/head\n00415db28b0a667f51175fc6d808c004534d681e754d refs/pull/2806/head\n0041d748f3ee8c54e343b7bfabb9ea632b6d02a8c337 refs/pull/2807/head\n00414e8a542ed46dd0744ba94717980a42e6334a4c0a refs/pull/2808/head\n0041f9a76ad79b91979aa6ed8bbc9694104a7ae6cfd3 refs/pull/2809/head\n0041f49db036ec837a98011cb28e38804a4fdd57aed9 refs/pull/2810/head\n0041185aff83e2cea035f1f4c0c333eec954fa89d04a refs/pull/2811/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2812/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2813/head\n0041fd94f48443d79da98de552304653b908fe83e6ff refs/pull/2814/head\n004128fd0b9b9ea81ef284a99b149e5a69fb2f2c8e78 refs/pull/2815/head\n0041642bf0504d5dd0fd6160e7b508e546e37b27d905 refs/pull/2816/head\n004106c59993b4c84817b8b8c2a879cfcc5f3fcab8f4 refs/pull/2817/head\n004165dab2740390fae7815d53881b5c0bf6fa8eb583 refs/pull/2818/head\n0041d7956d5236877d7d2f1da49fe75dfd81059119da refs/pull/2819/head\n0040c88914a941222f07a6a29cd9ddfcd782d87ec1fc refs/pull/282/head\n00411cb455b505a3be35bd0696c41ff1ca5cbf113bd9 refs/pull/2821/head\n00418a57d72bc2f5d9182a56e4c882c44f51b994d627 refs/pull/2822/head\n00414dafa11d0222373c698b0ed2668a37112d491bcc refs/pull/2823/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2824/head\n00415dee54879ba73cd0c422fe0a7fc637a9cafa480e refs/pull/2825/head\n0041547568a2d0e54c919284b9a57ebafbd9cfca6a86 refs/pull/2826/head\n0041e0faf86c9025f64d5c083de17f0fcbaf8466cc0b refs/pull/2827/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2828/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2829/head\n0040857891acf88fd5e494c705e44f9721c73a6df2a6 refs/pull/283/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2830/head\n0041190bb1668ce2c7be361faa1a96626d4250f53bb8 refs/pull/2831/head\n0041dee7f03da3553448c024b4ff6ee96da427095779 refs/pull/2832/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2833/head\n00416faf3dd312ced029b468bc8b5bbb9ef12dd80cd4 refs/pull/2834/head\n0041476106a04b739c4a2d9f4106716d70e8c2205af8 refs/pull/2835/head\n00410c33cb5792dca5cffebfa2d9d9102cd51dbaa417 refs/pull/2836/head\n00417472807b8962255ea4eb7c8916c4b42e14872395 refs/pull/2837/head\n004119905886ae56bfffbc8027ce84ee5970e974503c refs/pull/2839/head\n0041c053afe6671014bd97cce4e5cb2189fe186e615d refs/pull/2840/head\n0041995f36545f3f9ce298b63235ab069bc915553ad3 refs/pull/2841/head\n0041611029f7c6bffc2b86c4e2a1fc3adba1dcb6c5ef refs/pull/2844/head\n004190ffe8e4fdf36ec73af89a4c91436c4ed5891b0f refs/pull/2845/head\n004180c8b887ac4cdd4094841524421b22da6b787757 refs/pull/2846/head\n0041c4775008293ae04c32d7c3a36e7ff69b6e6585c4 refs/pull/2847/head\n00417be76c68bf4172bec3b63c337c0d632105cd7dad refs/pull/2848/head\n00410bf3076cdf5cbf1b8d821346ccc8e36425af6447 refs/pull/2849/head\n00408fb04a0898abe7717137ec504546838abf6bdcc2 refs/pull/285/head\n00413dd6b289906a198f9cc4c554dd2d6ef75ad59b0a refs/pull/2850/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2851/head\n00418f8873ed698a9ea5322a04c707b034e5568bcc42 refs/pull/2852/head\n004119e2589154d7fbb20e089788154342e6735bd10a refs/pull/2853/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2854/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2855/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2856/head\n004167aabf6657e3b405f04ce576e39e3f303e4c66d3 refs/pull/2857/head\n004193a63ad748e1d6ff49af3c3f641a4ce09b1c4b0c refs/pull/2858/head\n0041f477c6940ea743f47e8cdb6ec14ba4d5c6f31838 refs/pull/2859/head\n0040ec88cf672778f0d8098070047e7050fd5821723b refs/pull/286/head\n004193d45871f40f122c1494b79931dd732891792064 refs/pull/2860/head\n0041add5751fd0bcd0f1e9ce7e1f414c786110915e14 refs/pull/2861/head\n00417d7c18855c6e7f1b88300c5d2cdeaf33f1cd0c2e refs/pull/2863/head\n0041e1d8affae17cacef6e7c1a01e901b9687538121a refs/pull/2864/head\n0041747e1da71770691f0100fb21f4a9efcd9575183e refs/pull/2865/head\n00413fd074245dcaaf739002d63e7c6a89f39d9bd1ff refs/pull/2866/head\n0041c3523af0d6087b244bae0fd6c6522edd441f011f refs/pull/2867/head\n0041ddcc982004944baa45c53ef7ca1d9bbd2404a40f refs/pull/2868/head\n0041404a259ae62f5ee0537a87a0ba418daff01b1998 refs/pull/2869/head\n0040a865ef6942833d38e5ca4c163e1008c9796eb285 refs/pull/287/head\n00416d2c55e7437107c19210aab82e8cb06479710d96 refs/pull/2870/head\n00418c5bff2b80e1dca212cf32b0541e1db6f439a5e8 refs/pull/2871/head\n0041ee42ed4e2f00d71a99e2e74e497db8b40efe6784 refs/pull/2872/head\n00418acbb8bb927c14c60b5edd34b3b2af09ce999fef refs/pull/2873/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2874/head\n00413f8c12ec2674220d32c8fe644a510fd712336443 refs/pull/2875/head\n0041207eeb6eba7de6c1bf8d6b06ab1d2463935d993c refs/pull/2876/head\n0041ac3717e5ad39d22f94b68123dadefb174cc1c9a8 refs/pull/2877/head\n0041392798ab0a782b71f84ed724a653c3a2ceb28144 refs/pull/2878/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2879/head\n004054a8f8b7ee2cf16d9090585c1aeaa651b1bc64fc refs/pull/288/head\n00418d3e1fe872525cffb71dc18a1baab4e5a437cb91 refs/pull/2880/head\n0041209183bea595553c350bd754b2aff1e42a411973 refs/pull/2881/head\n004182b2f5db7ea4dcc6523a5b3c758fd31f966d4840 refs/pull/2882/head\n0041d94c89dc945512ff6da6dffb573cddc5a82e244e refs/pull/2884/head\n0041a7a391b6b4ad844c44c0aede77ce2d85a00d9b35 refs/pull/2885/head\n004169e6819fea9cf083ab2b8d19a82544fe888e9d62 refs/pull/2886/head\n0041bb2739a9755747176cf784b8c5156d501d8222ea refs/pull/2887/head\n0041bf7c148b090eadb587832531d9bc1a11be06577d refs/pull/2888/head\n0041196dc83ce02e38d56abdc3e9d7fe696fe621b3a0 refs/pull/2889/head\n0040f6d68afa1708059c00684b5d0bd9eb9217661a66 refs/pull/289/head\n0041e9d2a7d9eb40c426e630610c08e2376c82b46278 refs/pull/2890/head\n00419d8f0b1efd8ca12e9a71d3f815cae43f13409a34 refs/pull/2891/head\n00419c7315590feb960dc4b0cb8e87184792d38ff7a0 refs/pull/2894/head\n0041a8a928fbe8ac833540e11569f44fb09c50410d54 refs/pull/2895/head\n0041cdde00b06c74be5bfbf88050cbec722f1462039b refs/pull/2896/head\n0041e51098f495561b99d18218b40c58d18b9e872832 refs/pull/2897/head\n0041b4992ee4dbf990acaec8fea6582fd215d1122921 refs/pull/2898/head\n004163d1a6dc14f8dc2090cac8341fcb3148195ddc75 refs/pull/2899/head\n003f58fce1249ceb5d65b7895d5cdafcdd7821772b6e refs/pull/29/head\n004139309f06c3d1e405348b53877af07335aaba4fab refs/pull/2900/head\n0041a92019df7a4cdc1d55077d35042ec51306378b54 refs/pull/2901/head\n0041d103b346ccb027171f710e21ab4cdfc42618412c refs/pull/2903/head\n0041e3f88cda1e69b25caf64458d0c836408c1d83323 refs/pull/2904/head\n0041a70352aec37960d0e9858a693594a6e2721f5313 refs/pull/2905/head\n0041eb6a90c12145cd3ec1195ed71f34ff63b557ce77 refs/pull/2906/head\n00413a11321134227846f1d78c3835a9237f99726257 refs/pull/2907/head\n0041166a833b8f4f2105c5263e0fbcbb41dd3752a00b refs/pull/2908/head\n0041d958d900898d7f5b612864e6b45751ff1a77b6d8 refs/pull/2909/head\n0040fc0d24e67117833b606a5648b3308f907d3cac34 refs/pull/291/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2910/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2911/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2912/head\n0041eb5efdcb6805ce3702f91409ecc208be8e3d5df7 refs/pull/2913/head\n004199db1b0e45b3889626c09c0386b16f2ccc0dbd4d refs/pull/2914/head\n0041ce58552dbbd96fa34e39f9c256f9c4f3e6417ca8 refs/pull/2915/head\n004139e378db7e1db7e8fbc3ba2dbcaf7e7eed22bcd1 refs/pull/2917/head\n0041d91a2f11298f61a16fdeda77e89811c621b2b56c refs/pull/2918/head\n004188f4b5c486f180f07ec36b145307069a83d71279 refs/pull/2919/head\n0040177b1e72d8561ae95a910e9666f3a446b2d607f2 refs/pull/292/head\n0041c5e9d21e5c514c0aff595aba357a8429d9dd9b81 refs/pull/2920/head\n0041e73a43793254c217f42f4d27ccde56e6e7b9dd62 refs/pull/2921/head\n0041c4151af86b4125532d999f72a5dc0f13c7feac60 refs/pull/2922/head\n0041a311476a5b3f9c34407bb5422ee93f7df236497d refs/pull/2925/head\n0041c73a96b6f7cfef4fd1e1bc00a6686956e58c3879 refs/pull/2926/head\n00418a4f90c0240285aa3638be184a6092b50c49659e refs/pull/2927/head\n00419fd44d4217395b540fda630c64c1e84ff1c532bc refs/pull/2928/head\n00414cc85a0e3d02f0d830721518f6fc02349e71f08a refs/pull/2929/head\n00403504293dbeb6a169d9c51279ee0c9fbbb4dfa58f refs/pull/293/head\n00415234c08ce941b082223c6b7eb15d4e3beb3898e2 refs/pull/2931/head\n0041fe1da8c674e09238c0c12fba310535de7b95dfd1 refs/pull/2932/head\n00412ac962cd4b4bb269bd863fe9b43f0ed894e1eb4c refs/pull/2933/head\n00417ad72d8ae97bae7adfed81b8db0cbffb45ff81c6 refs/pull/2934/head\n004118901307dd712f3d8ebf67544c34626b9c804fef refs/pull/2935/head\n0041838166bbf80143eea1206fc5f06ea0b2ca862d97 refs/pull/2936/head\n0041827912336c7a42090a005dd0630d07fcc23dce01 refs/pull/2937/head\n00413a2b3f7b74d733f29e2d9e485c1a2c433811af9c refs/pull/2938/head\n00413eafc2591f35d5cdbadde5e223332b3c8449f17d refs/pull/2939/head\n0040a91db92ab68ef5abf3590a4c6c1156cb496070b2 refs/pull/294/head\n0041be92d5ced97ef304d5a71685ce704aee8f998376 refs/pull/2940/head\n0041f951db346b984af75f9158473884985dff74f525 refs/pull/2941/head\n0041c355aa304b31f81a1fca44c6c1561c568c761e18 refs/pull/2943/head\n00414fba1b172a8d5a2f68fc5cd6ca12a831c60b1288 refs/pull/2944/head\n00416f3de20c9009f0276b5af06e5ddedf3f1608dad8 refs/pull/2945/head\n00419f1ff0f6391d3f8936872a44e48b686b97fe5ba4 refs/pull/2946/head\n00412599a7dad17dd6e74ee9452026fec56d1f34be11 refs/pull/2947/head\n00419ddcd6e9d446385730a6e688fedf98a689be02b9 refs/pull/2948/head\n00410b2408f69b00465c0d14a7bf4b07ebea2d45bc00 refs/pull/2949/head\n0040d04bf6c58d024bfcb395027a82eca6f95d812607 refs/pull/295/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2950/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2951/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2952/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2953/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2954/head\n004198478706e827d4da7fae302344ae4626f91e216a refs/pull/2955/head\n00412d97411101768867ad72b493c386b087a01f4796 refs/pull/2956/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2957/head\n004116f5297332724a0836ec2c4127680963d2171285 refs/pull/2958/head\n0041f4a55c33a40aef6a4d473a022ea238fa0cfdc6e8 refs/pull/2959/head\n0040ddafd0b526eea0b7449881ab78ccb06e260c2fff refs/pull/296/head\n00414cc577627d5ace18b86335424faa0938de06f09e refs/pull/2961/head\n00412d3a8921f5f49f140c892059bb33191d017d3b37 refs/pull/2962/head\n0041dd37c708309e16a05aba50aa5da35eb51db512ee refs/pull/2964/head\n0041f0be3bc7ccf9429cdc44aaa3b755d1eb1851c9f9 refs/pull/2965/head\n0041dfc0d77ffa7035fa30ac0af4fae7014f963d31c4 refs/pull/2967/head\n0040c6324c7def409e52d2a6a79e986fb1615f5677bc refs/pull/297/head\n0041dc8941aedde75407a3aa51a6c1c74480df6523f4 refs/pull/2970/head\n00410d937d9c75ad6efc0aa2bb61042774b161738f42 refs/pull/2971/head\n004189d5edb9a4181ae87c4903b25195657882bd8652 refs/pull/2973/head\n0041a8a4c03282d2c6a80d164305db1176f8cb4e0fcb refs/pull/2974/head\n0041b909d9da94007f878ce4ab9cd9c851ea8dce0e2d refs/pull/2975/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2976/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2977/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2978/head\n0041395fc6df1a91872baf88e570a89df4b5504d6ae7 refs/pull/2979/head\n0040e51c698385f0ce74c82bfe208d34eb74decd29bf refs/pull/298/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2980/head\n0041fad161ee283b537b0c97e577ae6d89bd371961dc refs/pull/2981/head\n0041ae21d3d15dd77c67430504f7d17fd2477187b397 refs/pull/2982/head\n00414b0249f355d436b42005a3be066bb0422f08af08 refs/pull/2983/head\n00417f0a8fab9dc5d51e07afdc57382825219cd53ac3 refs/pull/2984/head\n0041e5e3efb0e0a28772c2c31ecf3de5a04da09065df refs/pull/2986/head\n004126c0e0a21de2a2c3fc6dcb207347339e6ec3f18a refs/pull/2987/head\n0041c5d867b4caa4836692808d29b74a150d0f7c15b3 refs/pull/2988/head\n004130db1124016097a4d5f1736deb00c48b77410a24 refs/pull/2989/head\n0040eb68f82a1c3356d0ff11637395078512c96697e8 refs/pull/299/head\n004119a07de57a21994b6f1478a8d2410517ad829e1f refs/pull/2990/head\n004167f77272c080407d5a2e01de41af55b59d15d782 refs/pull/2991/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2992/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2993/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2994/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/2995/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/2996/head\n004189007174d4749c0b3343f199e57ae195ff29e6e0 refs/pull/2997/head\n00411645cf0d67d85a94839e05fff2ffc161595db433 refs/pull/2998/head\n0041c30e305ff7f5908e389912f53aa49ee5403e5da4 refs/pull/2999/head\n003ef0cdbde101164b659a1c59b6b400472820703130 refs/pull/3/head\n003f3ff993226b672f16415168f26e670785954c0c48 refs/pull/30/head\n00403ef1b3d7d647af747b2a9e03f17773dddf5f4db4 refs/pull/300/head\n004146c427606410f135353b204dd06affe01c89b7ad refs/pull/3000/head\n0041c6a6b896cf2869a9bfd0dc6b52efbe0e505b4391 refs/pull/3001/head\n00415cb1ddffb06ca75562c641d3f28a5df1a791d5db refs/pull/3003/head\n004168cb24921d8a037f8157f1a503da88d61aceada9 refs/pull/3007/head\n00418f1bdfebbee3aa1af953417f21e4253ba8ccfb74 refs/pull/3008/head\n004106f28780b388130601eee7ae3bc9d0b3d5940663 refs/pull/3009/head\n0040fea7633143d0293f5a61d8aaa49da07e048e6563 refs/pull/301/head\n0041cc697f8c8204edcfae938dd6caf10054f11a43b6 refs/pull/3010/head\n0041d2f0755b32b10522939c79b6e8b4bea541abfcde refs/pull/3011/head\n0041106ab5e40648e8387526abe3de1c8ba4b04e5ff3 refs/pull/3012/head\n00418856379bccf277f9c62464aa427fa0b2d6f67577 refs/pull/3013/head\n00412bdf7f948e06f331ef338ae7db1d57dbaab0e751 refs/pull/3014/head\n0041442efcf258b28b45d96e20a60affc5155c54bffb refs/pull/3015/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/3016/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3017/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3018/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3019/head\n004077abff46e64d91993f117bcde1ce703b89840763 refs/pull/302/head\n004191785546e68c04c40fb754c656227f5fa1c66438 refs/pull/3020/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3021/head\n0041354913c4dd35a4d63665f5b527cb599d5de135fb refs/pull/3022/head\n00419b1873f19a5d21f87641318295f02c13e50f07fd refs/pull/3023/head\n004185625d97bc9d4a09294d098f30425dc5c95ffc03 refs/pull/3024/head\n00410933c86891d7c6f5420e1c41d3b23e79b3744686 refs/pull/3025/head\n0041b47c661a24c4242b795822dd155bb69a2a3b1c82 refs/pull/3026/head\n0041f7e4eb57d8caf0663fe23bbfc9a5aaf9cc514655 refs/pull/3027/head\n004180eceaabfa2e1a4620c0512a85a7af6db45d583b refs/pull/3028/head\n0041c80da837eb9e1438e795105b35d4abf12d38a590 refs/pull/3029/head\n0040dc2df970334ca11c74290d169c70390a8eceaccf refs/pull/303/head\n0041a0860d3c5649616c707f5f0c977e17939245bd6a refs/pull/3030/head\n004113a552ea3fe1288a590f9b931d8371336f1d7b72 refs/pull/3031/head\n00410159e086cfb5918c03061a62d80e15297d6ed927 refs/pull/3032/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3033/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3034/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3035/head\n004107fa0d7988e84f3b3a34ac3dac399ba193887524 refs/pull/3036/head\n004100cb652efbe3060aaeffa5c4f3a7d31e66a0c231 refs/pull/3037/head\n00412b6b3b940c64c5517b64a7c03bb529866a421e10 refs/pull/3038/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3039/head\n0040fade621a7f723174ec82fae918578b84229d858b refs/pull/304/head\n0041f961c3c635c28cac218d79b63e95e01e5d8b810a refs/pull/3040/head\n0041a0214ffea0a79b8e1405df69d708d2dcff505ca9 refs/pull/3041/head\n0041b00ae6ad393dc643ede45c53649e5302e1fe8e20 refs/pull/3042/head\n0041dd25cd187b995f3e81cd26d138c783f52d2ac74b refs/pull/3043/head\n004182de78c184dafbfade5f45c2af21a6c14369b0b9 refs/pull/3044/head\n0041bd501aa0621037cd9004b2702a1e76de442e5965 refs/pull/3047/head\n00409d95fbb972ce3b32fa23eb739dfbd269aad20f3d refs/pull/305/head\n0041e882cd65728241b20bb5017316c286dfcb00dfa9 refs/pull/3050/head\n0041914aac4b7d550541f1b9cbfc7fd9374bb5feb497 refs/pull/3053/head\n004108f216bd6e902609d9aa84f30a50bc6c3bdc3c06 refs/pull/3057/head\n00417286d58bb1c5582b1add8d32d1696d6c8947d093 refs/pull/3058/head\n004132f4c488f7dffa308f82df5827a165e400a5c0c7 refs/pull/3059/head\n0041a5db19432ad9c33ea0d970dbdcd1d431b0e766c3 refs/pull/3060/head\n0041177357fc096b77dba00e31d85d3d3f31e96fe49e refs/pull/3062/head\n0041ab5adc598eaa84daa237eddff158db70bce13f78 refs/pull/3064/head\n00417df290ce8f2f3cf36a6058b7ee72350973fe8f83 refs/pull/3065/head\n00413549c650ccc399f36264c7b1276eb1254f33fa98 refs/pull/3066/head\n00419e4e3ab71e51de615b75393c67b741f316e9e752 refs/pull/3067/head\n0041fa1a05258fcedbc38ad9456165ff83c1cb8f97d4 refs/pull/3068/head\n0041397c82d0de51dd9ad7be2caf64c90bdccffa2023 refs/pull/3069/head\n0040f25a65409dfa4ea967d1b1a7d134da5013287dbc refs/pull/307/head\n004150bac02853af6b495043453ef4c7a50e2931fd64 refs/pull/3070/head\n004109feb895a36ac0927a24e94c297ed03f79b899fa refs/pull/3071/head\n0041ac0931b70d8680b25d430009007e1d9f0970a082 refs/pull/3072/head\n0041d0e784b90d1f359fee5ee6bf20689d6858d3161f refs/pull/3073/head\n0041807a02caee95fba47c7818bdd81030a60ca6ac20 refs/pull/3074/head\n004164711b7a7947fe8f441cbf6bd04b82da41128ff2 refs/pull/3075/head\n004158dd885ff2de27511b331c3bb7e892fc67998935 refs/pull/3076/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3077/head\n00414bc4dc9bb7cd85b5665f08454664843921f196fb refs/pull/3078/head\n0041ea8f0f79cb8433d5456fd82b8c7599ff82cac75b refs/pull/3079/head\n004073411ce4dd3994d9dfe6597388de7781b803e056 refs/pull/308/head\n00413805c23b7f29a1ec1710359c4f1d1e6df31c7ba2 refs/pull/3080/head\n0041925ca8a475d5650662ce8908458863e6b658d6b4 refs/pull/3081/head\n004100c3478e13944f99a154dca4ef7aa289f97fdc19 refs/pull/3083/head\n004158fa551ee7d146fd25770ed5734553f664912794 refs/pull/3084/head\n0041dd4a9fba9528b3cf0f22103d590ae6804ac8ad4e refs/pull/3085/head\n0041c1a75222f07f11b881558cb5ae85db705a13afa6 refs/pull/3088/head\n0041fc3357d173e441a822781fc46288b787cddf8dee refs/pull/3089/head\n0040e3e35a898a1e3a1106095f4094c748e635c54e5c refs/pull/309/head\n004101d7427d06d0aa5aa4795321ce1d9a796a8f72e9 refs/pull/3090/head\n0041f2a910f11286b1fc1781afd9e31eead170e172bd refs/pull/3091/head\n00415c0f8bf021cb2768cbcf264a04229a02cb562e6f refs/pull/3092/head\n004133dd2316429de872f26aa1a3f70db605e636489b refs/pull/3093/head\n00414a943449ddac590474233c569576074bbd67a59e refs/pull/3094/head\n00410cc43c1500774d5ae34950adc14a86a1a50a949a refs/pull/3095/head\n0041222ea10609bc06a812aba8463bc3cbf52d509285 refs/pull/3096/head\n0041c9149607f53d653b6d6869d66d202f915c2082e7 refs/pull/3099/head\n003f03d5ede47071e352bd5c48c69b4156324c71a038 refs/pull/31/head\n00401769ea723a9fb250a7118164ab2effb91e1c3461 refs/pull/310/head\n0041b78711a5ee79bbd7998de91aad6dc1295e22f62e refs/pull/3100/head\n0041ecf58a0c6459d9f245525ab2c253af0a9b6a83ce refs/pull/3101/head\n00412e4e4d113a2fd913d7d304985cf9ccb8b576c766 refs/pull/3102/head\n00418e86f1ef7b8cb02e3ea4a1cccd25144efb99048d refs/pull/3103/head\n00414fc6b776cdf924caf51e2e953108fac00ccf42b6 refs/pull/3104/head\n0041c6a1fbe65b831bf87b3246b1175bf02b2f810bc9 refs/pull/3105/head\n0041630dfc9cc184569e9ebdb67f290c75dae6f9603b refs/pull/3106/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3107/head\n0041f6d4c8fceab5b87f3fef22019f55339a73beb04f refs/pull/3108/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3109/head\n004017d50a8045e6ab6452e1da82f9c2ee2895bcf12c refs/pull/311/head\n0041bf09b2abf49a4f3e2e6602bcaa946962a18047f7 refs/pull/3110/head\n0041c1e468882a3f011e83172b67f225f99315494009 refs/pull/3111/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3112/head\n00415473e50a8182ce99947ff83ce1de10ee3c333fdf refs/pull/3113/head\n0041e103a9d6731021989cbf6d7eb67a196ce58e3837 refs/pull/3114/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3115/head\n0041e564df2a7bd69ce2cb4ac1b501944286e8071b2c refs/pull/3116/head\n00417694475144ef82b5ceca67d9dea29b9b0e2c616b refs/pull/3117/head\n0041782321d204ce8b7a44192878b95272398387cd44 refs/pull/3118/head\n0040188650c8960ee4afdfbc466178bf680e360e74a0 refs/pull/312/head\n00411af0d27a4fe1110f3e723c502227cadeba76d7e9 refs/pull/3120/head\n0041c5f312da17dfa2ef648c188947d0e802b0a0bc5e refs/pull/3121/head\n004170e933c33ad5df01e4cfd13c1f1d638afbfcef60 refs/pull/3122/head\n004123b294193aff6eb042da70f98f0d82fc7ab15f96 refs/pull/3123/head\n00411a8f3cff55c5ef37d9259044a32169b4b2bae1bd refs/pull/3124/head\n0041fcdb11e4df6ea8c0689e5da738599987ccec55b4 refs/pull/3127/head\n00411caa240d65c4dc07de4e1f0260b5aac50aade9f4 refs/pull/3128/head\n00414c34c0b48625de98d87cecd1df9dd2c780d172cf refs/pull/3129/head\n004022094a80c98a2a8e1eed141c4424a82681dcc2ba refs/pull/313/head\n004125119e4da3eb317aa14f22d36e5405bf47801726 refs/pull/3130/head\n0041039259cd1ef4ea16e732e740ff1c4a6938c58964 refs/pull/3131/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3132/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3133/head\n0041527572a2cea9f0e08f0334e74b30db2c741efe12 refs/pull/3134/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3135/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3136/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3137/head\n00413d1aa3e23a2146765bc94d0c9c1056005582eb3b refs/pull/3138/head\n004164f98fedba4b5a2d668dd3942d46d895b64a5713 refs/pull/3139/head\n0040d6aad74d8aca422749b3a63a359460431e624f2f refs/pull/314/head\n00417dd22afa840436ad016a08f9f2588dcf13b7b44e refs/pull/3140/head\n0041f3bc32e8b6482819431640f7ea46152581d804c0 refs/pull/3142/head\n00413f87112df4042dd8a06c27f1c25a14f803a61912 refs/pull/3143/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3144/head\n004157c03567f1b892b18e88bddf1e1166cacfcc123b refs/pull/3145/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3146/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3147/head\n0041c755c5203224f23cbb319b1749783af14f31537d refs/pull/3148/head\n0041b65f27f9e85fd6b0a16a499edd5ba5db3548d7ab refs/pull/3149/head\n00419ceeedd79a55533bbac0e9f6938ff6b1fd1c6114 refs/pull/3150/head\n0041bb1cb86a28fd776afe65757647eb41e2cd14d12b refs/pull/3151/head\n00416c93f87696ee00891b0146ea6f3be8dd53659a6a refs/pull/3152/head\n00413bd8359e38f1c5c33f590ca406dfc1bebc816cb9 refs/pull/3153/head\n0041cd8185fb4a44ed1280f3bcf571279fd40a45494e refs/pull/3154/head\n00411f3639f5dc1f19a3b130079d2aded178820bb80a refs/pull/3157/head\n004193743e8e7ca91fc3f0be3cf5ebd3ee4bb1a16772 refs/pull/3159/head\n00402a2b2599c2ebcf9032b67da26bc4d1816b6315d1 refs/pull/316/head\n0041d8db9e7af6d9b52bdf5b79edc8fe9e27ae7b67a2 refs/pull/3162/head\n00413860c5f8a5afe8107deaa7b6d3e75584441d70af refs/pull/3163/head\n0041a5e1d3c04d2c5df7e6a025c115a86cea71d320fd refs/pull/3164/head\n0041301b76f411c0f8a7245584224a593eb62dc38ead refs/pull/3167/head\n0041f1baa53e91449c83f5a9b39f57bb88ee791a9bb9 refs/pull/3169/head\n0040512f4a594dd01c11dffeb7f3a01f6ee2910e2446 refs/pull/317/head\n00411d75f8cca72cbc4656e4633a5da804d5b8e06e63 refs/pull/3170/head\n00410425c1abacd948dfd9f783f3bc7d1050698cfbab refs/pull/3171/head\n00418897b145798040832c08b182684dd7e9da8ea28f refs/pull/3172/head\n00413870193fe93ad63bb05d4bef5c49845cd2e8be97 refs/pull/3175/head\n004132fa682339d2e337e0a5dd822383329279a6e081 refs/pull/3176/head\n0041d974f9aa07335c498eb3b694024fca4143b15745 refs/pull/3177/head\n0041da97fddd86caf5f4211ff98fea9b79ea16ebb269 refs/pull/3178/head\n00413e5cf953d7d95a1032558f7592844646c1f23282 refs/pull/3179/head\n004115a638b3e5fa3f855c20160fda14eed496fd6a04 refs/pull/3180/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3181/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3182/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3183/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3184/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3185/head\n0041c1cbe6c7da136974a98477bce101eefb7537f08d refs/pull/3186/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3187/head\n0041b0bcc9c9bdd03cdc12018ab04c3bc3189bcb9356 refs/pull/3188/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3189/head\n0041f7576fa840f9fb516a3b7cc04871c1cdbbfcb67b refs/pull/3190/head\n004138c5c17bba807d3cb7fc4172d1729858cac2653e refs/pull/3191/head\n0041caa52c27598fce1d44a2aed4776f509fe601ff50 refs/pull/3192/head\n00412771f72491c813726d134f78bb187d83f529bc87 refs/pull/3193/head\n0041cbb17a81efc093c3ce6889392e84c6692ac54528 refs/pull/3194/head\n0041881b2f0fcba03a8ead11b10a8448db8e9bd9b941 refs/pull/3196/head\n0041c5245cacd191db3a78975f42525953338a012e0d refs/pull/3197/head\n00417bc13b16667fc68a2ea49b2b0e2b6385fea8cfb5 refs/pull/3198/head\n0041e78ba918f91b4ec532200ee53f1da1659fa5019e refs/pull/3199/head\n003fd46883d4f6bd0de3fa54570e25592d65177a8099 refs/pull/32/head\n0040fcf3222be5f9d8cb2e4bc4789a8ed0ee7f8ecee9 refs/pull/320/head\n0041cfc7fd1e75225069ad5be39c99569b2cf3e5c1f6 refs/pull/3200/head\n0041b8fb33785570b28d9d0a64e1bc639538ad9cc050 refs/pull/3201/head\n004187cc5b2deda1e3a5fda04b5eac4790a056880df8 refs/pull/3202/head\n0041676388f4b2034b023016e2739abc4df86a5689e4 refs/pull/3203/head\n0041da4bd851cd5122ec79be4589066b448a692e51fd refs/pull/3205/head\n00410abfbb2eef7681534c04998e97874e955d576b02 refs/pull/3206/head\n004154e7db1008c998c907d4fa79bdb6efefe65f66c1 refs/pull/3207/head\n0041a8d34ae9a573564b7d0f766365af3de1871138a0 refs/pull/3208/head\n00411d546967bf9468228e4caf8f9918fc59637cea8d refs/pull/3209/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3210/head\n0041b2e2a887e2d9479c2dd947d1e586ee6281e35a91 refs/pull/3211/head\n00415db33ba706ebe24708bce88cc944539381844769 refs/pull/3212/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3213/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3214/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3215/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3216/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3217/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3218/head\n0041d68f6f85e95df5e66154c9354efae427d1f1114b refs/pull/3219/head\n00406c285e160a26c4f006c041d13fd6aa15143b3efe refs/pull/322/head\n0041c67e9e47b64228bba5bede93b3bc8c902365e327 refs/pull/3220/head\n00417a0b72b6d3aa7ecfc94b6ca5c4e43683ad5c42c6 refs/pull/3221/head\n0041a724b82a564701bc4b95821a2f04d36257bf14ab refs/pull/3222/head\n0041f3cc09810b6210e0bdfb4f96c81de2aee8939dee refs/pull/3223/head\n0041feb0ad7c5e6e7b550b125dbfd844a6c62918bed7 refs/pull/3224/head\n0041737b75a44263778aa0254a283c6db7a481629b1f refs/pull/3225/head\n00412c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/pull/3226/head\n00410df532eda1cabd74d7117ed65ba361bf85e9d263 refs/pull/3227/head\n0041436a2e9f9931e797729ec45b13edbb507682526d refs/pull/3228/head\n0041fef018091ec9da5147c7da86c75a4d1af44e21c5 refs/pull/3229/head\n0040d0db8c21ce1b0544a59d3b7b5cbd6aa8bd34a46b refs/pull/323/head\n004171410a54a301ff26d732e7ad4bb4ddff8e564f65 refs/pull/3230/head\n004111775b9a66c24572472b9bf58a7471441cf90482 refs/pull/3231/head\n0041c61acf8038b754fa81c6d0376ff29ea861d91b3d refs/pull/3232/head\n00418b5f88169a1a3476b6eeff3eda03c7f9ec66c17b refs/pull/3233/head\n00414a5591f70bb35c6553d449e7d835881a7e623eb1 refs/pull/3234/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3235/head\n0041af460dd7e6b20eff0011b9eab1f60be9c8355e02 refs/pull/3236/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3237/head\n00416ec64a705e1ea95bf760714bc867be48ee1db93a refs/pull/3238/head\n0041ad6fcfae08211757c8b36d14fdacfe54131f9bcb refs/pull/3239/head\n00403dfa0a0b07889e25c08af41775e6c8edaa3df783 refs/pull/324/head\n0041d27aa3dd1a6c7e66c35ea28acf12819be3cb8d30 refs/pull/3240/head\n00410883a7dfc9425531c544cfa19d8bf7aef21679ad refs/pull/3241/head\n0041f09b7a2d5f0b6cf75d93c73dcc0623ccdd11081d refs/pull/3242/head\n0041cb5ec97318f4e2e71218c8092e796601615660e6 refs/pull/3243/head\n0041c0ab597150b894af31fa84b1ef95135b4dc4387f refs/pull/3244/head\n004134c9f03e1f35d94f37be30c1d551a4721eca6639 refs/pull/3246/head\n0041625bbb79540f688d991c9c17cdc61edcf326d238 refs/pull/3247/head\n00419b4db2f8ffd00b1ce51475978c989d65c4ebbdf4 refs/pull/3248/head\n0041cfc81ae68582be96f901b432b88c715885adf462 refs/pull/3249/head\n00400138593116226511e9fdcfd6eac0830600bc74c9 refs/pull/325/head\n004190ebcbd10d637bc1c41b31ac0b1395f3b18817dc refs/pull/3250/head\n004177dc069ce11a0f4613631b8cac4c0e08287f63db refs/pull/3251/head\n0041be5df1340fe1e722ed96bc1c8d2143f8aa72037f refs/pull/3252/head\n00414d9b3d231594bb3a12d149e0acfe9d052fff0457 refs/pull/3253/head\n00411baf5b1f4e6199d36fd7b6c59d58c638c94227e6 refs/pull/3254/head\n0041dd784206b936de3fb626f985a3c2b913ce4206f4 refs/pull/3255/head\n00412fe04363a8e5ef40c220a24c394c32d14adc57b7 refs/pull/3256/head\n00414def6adce8d6e0dfea61f97f2d2ef30c9519c0f5 refs/pull/3257/head\n0041e78313ca42db27b5c006f09b0f0759b85ea8e24b refs/pull/3258/head\n00411486fe15bcc610f171233cc9583d391588e29ca4 refs/pull/3259/head\n00402a83855d83f6b56f76e63113ed2cc5a82ff7fe15 refs/pull/326/head\n0041cc6198702dc46b2be7751a57aa99b04a574814c2 refs/pull/3260/head\n004112c052a038893bc0929e123f0374241fde5cfea1 refs/pull/3261/head\n0041fa7b9e1dad8947edbe6d4454ea2e75c4e91fe775 refs/pull/3262/head\n0041f2ec4d1c728596f42f5a4df1c482752049b418e3 refs/pull/3264/head\n0041ec50b949ac70d8cc72d648af3d2d6393ad95c3c5 refs/pull/3265/head\n00419aa3fba23fb804cde1e65a1b45fd9f319b3977bc refs/pull/3266/head\n0041eb0dd3c5254fd3880fde0e229659f83907b69ae5 refs/pull/3267/head\n0041738ea0ba90d957d0db64b31048ef6f568cfdd387 refs/pull/3268/head\n00417fc5c0a44b0a2594a637765e3b6439f42c875cf2 refs/pull/3269/head\n004042df6533086ebd31dc513f98362ae1b5d227f9f9 refs/pull/327/head\n004126c131d22b50920b39747af79b6479584caf72f5 refs/pull/3270/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3271/head\n0041678fdd47a634f2c65477b9d8db3919cbd6d8baf5 refs/pull/3272/head\n00416ae5d89cd751708da6774342451710b2102f123f refs/pull/3273/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3274/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3275/head\n0041ef5dac2e2660257c90bfb99b1666624ca783288c refs/pull/3276/head\n004100c1ea1992b1272e41648c5d3ffd46d7f078857b refs/pull/3277/head\n00416dd49087b012e7be82fd3c8722976418cbfabe3a refs/pull/3278/head\n0041305e49c61c765c2814662251e615f96c5bcafbf2 refs/pull/3279/head\n0040bc268eb837250fcb91b113b00f86e0546948b971 refs/pull/328/head\n0041f6897c6fb08e2323e3638b86f7f2453ef7dbdc6b refs/pull/3280/head\n004174f122d6052b7b032e69fe9e37247805b2f1f98b refs/pull/3282/head\n0041308704455f5588ff6c780473875a8636a4e7c7a4 refs/pull/3283/head\n00415e0b2423a0b63fd975d40b255dba2a3ee4804d81 refs/pull/3284/head\n0041fd5e607cb9690a658a89fa4554af258e87ccc38e refs/pull/3285/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3286/head\n0041fb862020d928db7bc4e7c80542154ac4671adf14 refs/pull/3287/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3288/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3289/head\n00409a48ac5465f8ac146f2f3838751b9ff39813568c refs/pull/329/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3290/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3291/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3292/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3293/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3294/head\n004119cb466c0cecb33148aa4eb85570bbd896f0c561 refs/pull/3295/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3296/head\n00411b4ea72e09c0bdb92268c7c75c83b686f947b44a refs/pull/3297/head\n0041fad80248eead0ece21b65c060b7e2848943a5e83 refs/pull/3298/head\n0041d4f0d0ee18cd3a3096a60fd4d43b2336d54bf9c2 refs/pull/3299/head\n00403319fb852d36a0ab98729c8024b8abb8ad08f9be refs/pull/330/head\n00410887c622c076680ee77b94c85c56adbbc439b4e7 refs/pull/3300/head\n004163ba7a9e5a1fd4edfa3b19ac9126eab8279851a2 refs/pull/3301/head\n0041c1fb24440a335ef5d06026d52d9e32b23fc453a6 refs/pull/3302/head\n0041cc6a9946247228c4cee1c08702170f3bf5975846 refs/pull/3303/head\n004140ba224a80e301b396de4aad5b60ab053c149940 refs/pull/3306/head\n00414be1679a9401902c1c6983b95f9b8e439d4a34a8 refs/pull/3307/head\n0041531550e76261d5d68bcbbd14b137e1e10d638c9f refs/pull/3308/head\n0041b60a9a4a1368a55a089161ba073516dde4badc5f refs/pull/3309/head\n004052d3516888f1fde9300fd46ef43c0d35fbdc94f8 refs/pull/331/head\n00415ab57c181a2ff7e50bd569c25829b195d2d11298 refs/pull/3310/head\n004157f3141854c7612cd83ec2b67240b1f669310091 refs/pull/3312/head\n0041230e26b3580c46d5ff761f3172eaccca329d1464 refs/pull/3313/head\n0041a3509d4d1770f70757f11e3c8630b8be58c70024 refs/pull/3314/head\n004129dfbdbdce446cb5a85436f7acbd60d72109dba0 refs/pull/3315/head\n0041b17b1537a266a62983c1217c2bb300a3a6ff021b refs/pull/3316/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3317/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3318/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3319/head\n0040f70db31210bb0973824c06b471a699710c676157 refs/pull/332/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3320/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3321/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3322/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3323/head\n0041b34f6c1b69b1b43d8ad39d084c1cd4fdb61a237a refs/pull/3324/head\n0041e27fa0a3451e233334432f70f0862c58bec109ec refs/pull/3325/head\n004182ce5375e0fbdbdaf6dc82753c3c539ac19d2b38 refs/pull/3326/head\n00415be6dc574b3ae8dc190997146b02668e88eb53e9 refs/pull/3328/head\n00419fb7c07ed5c0aa172fe959e1045400ef89943394 refs/pull/3329/head\n00403e3f7cd474fcd238df1e8a1d85d67a1ab0a52684 refs/pull/333/head\n00410ee8e72bb1e9daf79c6423250853894c8ec3a3e8 refs/pull/3332/head\n00415d04ae469c2c8671d527f9953c4c3e3f1b1db4b9 refs/pull/3333/head\n0041b64830c986d329f3229a4092dc7c7c57d1c22b10 refs/pull/3334/head\n004116faa736187a33564513a188a23ac8ffd0642341 refs/pull/3335/head\n0041ce073adbe1be0dbd75fa58909fd3fb111384a4e9 refs/pull/3336/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3337/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3338/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3339/head\n00401876aad84e6175712758ce6d3db16d7b16ed4eb2 refs/pull/334/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3340/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3341/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3342/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3343/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3344/head\n0041e8baef2938dc547bc29b1629d8026c54f4400a36 refs/pull/3345/head\n0041da1202cebc3b5e248ef67e030e6ab86c458c15c9 refs/pull/3346/head\n004102068f861a1ecb6465e26d91a41e48db32f4f074 refs/pull/3349/head\n0040ffe7d673a10f32d59f1cbb96cbe7465c7b5dfe7d refs/pull/335/head\n0041d3c6c60331c3a2acaccbf200e13784b08786b731 refs/pull/3351/head\n0041100704081c253ff7dcfd7b2757f482d3c70c72be refs/pull/3352/head\n0041e5779f2d437ac22e3e52ead7cdb581ebbaf7545e refs/pull/3354/head\n004163330e4e304834f693186981a5320bfe33f6739b refs/pull/3356/head\n00413a25e5b19cc279ce63271224009a48df52f652d1 refs/pull/3358/head\n0041e26969b39d4e86f7ad3fdf337c5bcb79781d855c refs/pull/3359/head\n0040d2e8a62db572f1e557b85563c10e6468397124e1 refs/pull/336/head\n004145846bcef976b27a6c735ded57520b949143cdbc refs/pull/3360/head\n00410e404bb88ae07b8c0bf36a824ad77e49cd79686d refs/pull/3361/head\n00413592d6a7330432e0eb681ff7f30afe267a4f890e refs/pull/3362/head\n0041329aa16ea10c1bb6841a74f2cb7b7977e3ce3dc0 refs/pull/3363/head\n0041537fc5544be92798c1e691bd7c47b2ae5f49e56e refs/pull/3364/head\n0041fbdd56ed156b1e0fc2b12bc9656575ea63b1c826 refs/pull/3366/head\n0041290d0c8d317e2360ac229e70904433c3a3b62e55 refs/pull/3367/head\n00411e9702f14c9d0ddec4d3fe5dcd39bcacf995ead3 refs/pull/3368/head\n004158dd084bec475b82ca7de636ded933e5f26cd0c7 refs/pull/3369/head\n004001277a6291d8d62f4c8fc93e0bd9781987134261 refs/pull/337/head\n00414713dc20935765b3e4235da556ac6417a94b662b refs/pull/3370/head\n00414fc268c46bf699c0a5712870d826499deeed5e38 refs/pull/3371/head\n0041b339ba208c34d4b2ad57e1c22de799c5e6a3746c refs/pull/3372/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3373/head\n0041cb34e3ba48b46fe73b811c05592ce59d5dabf829 refs/pull/3374/head\n00416bbdc88faff9256f7f674f46502c4c4a133f5574 refs/pull/3375/head\n00411f72669b91743bfbfead637ce673ce0c3fa66bb2 refs/pull/3376/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3377/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3378/head\n0041f1097bd38cdc05ad8227ddd3437765c63cde96fa refs/pull/3379/head\n004052f9b1bf33426893d0bc0fdb1b80e02af46f2753 refs/pull/338/head\n0041c96e1f87f3149962b092855ff074173acb7249fd refs/pull/3380/head\n0041f927345a158fa12008caf386921fd97832ab9e2b refs/pull/3381/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3382/head\n00417d58425a9d987d51e44fd45ab6f80cf1891e1a34 refs/pull/3384/head\n004150c773d60e1fd6c361ada093264c327ea4460ee2 refs/pull/3386/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3387/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3388/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3389/head\n00402b3d0479f0eac553ca8005279c7a6a23a8591853 refs/pull/339/head\n0041ed19906a0de53afca8303ab7610c890f9cdf357a refs/pull/3390/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3391/head\n0041f5640385ee6e8caeb0c743e2adfa6cac33850f79 refs/pull/3392/head\n0041d4217e327b35257c89261a25e3dc237f608bec87 refs/pull/3393/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3394/head\n0041e5fcdc6f1692e4c2c746bc12fd1222f88b0144d2 refs/pull/3395/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3396/head\n00415d08b9c9306f10bd548b1c1adfaa182a3ff91ef0 refs/pull/3399/head\n003f23cc473894a09cc2c4051db85fd3a42e4eac77fe refs/pull/34/head\n0040d6c78da57ab21135f81cb5a2b6656dd9309c327a refs/pull/340/head\n00413fde29aad92d9e308929583d45ad89d0d113c5e4 refs/pull/3401/head\n0041da781cab9cd31cb88ba88bc42fc81f3259d8b20a refs/pull/3402/head\n0041d4a3e93868dd08f590b554d696c8887e45c5f3c9 refs/pull/3403/head\n0041728e7e4ce79ebeed7f96d7738e87edb2978c7b03 refs/pull/3404/head\n0041f4c90854fc692525def222597608a2cc2fdc24f1 refs/pull/3405/head\n0041c021ffa6e9a963843d4ba8509124bfbe0d3dfc66 refs/pull/3406/head\n0041eaf6dd8b3583effa6d2fde0ccb5bd73f07dbb2c7 refs/pull/3407/head\n00411f3bb435119dd7e20a349f90c3cf5371f13eff81 refs/pull/3408/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3409/head\n00401afb1ca14319673e1ea619cefe2f4490ad21ac2e refs/pull/341/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3410/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3411/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3412/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3413/head\n0041e5d49e3fa3a9a948e0ad1f1b86d0c9e188f74020 refs/pull/3414/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3415/head\n00412dcd8bb1efb80b4c7ae9087b304847addde347d3 refs/pull/3416/head\n00419d4287fb3ce00b76e352720ff79f96e9b52b0708 refs/pull/3417/head\n0041bcd17fd0a8bd707f36948c48aa7c9103c04fb9ab refs/pull/3418/head\n0041a49ee397c390dd0882b887c23e12e233bc6cc7cc refs/pull/3419/head\n0040019042773f8f8bfaf2fb18422f6e01caac79b615 refs/pull/342/head\n004141bd9e9857fa71d63de0692007c6ca2255b3aabf refs/pull/3421/head\n0041871f3556ce532a963d5a86f8fd0b232adc25dae0 refs/pull/3422/head\n0041e4505bd80502cad6ba66aafd519606f9472196e0 refs/pull/3423/head\n0041cce01256cfbf0f3f395b8d96d484494197196d5d refs/pull/3424/head\n0041dcc3c7ccbf0a1fbb9817a198b4cdc9d62b09168d refs/pull/3425/head\n0041caa0afee00abbc05076d0f52783b7a34310f6f12 refs/pull/3427/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3428/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3429/head\n004083dd27f424abf0abba6a8264fa6924a41c15ec49 refs/pull/343/head\n00417a83a2b622d023fe05a727df97a4b527dbff8eca refs/pull/3430/head\n0041a7701505c0a51e6de0f4c78c1a02f663a727fe28 refs/pull/3432/head\n0041981b8c04c17f2a63d951df37194bdf4817177e6e refs/pull/3433/head\n0041d4390a458767271df36f6ab90c99af6e363268c4 refs/pull/3434/head\n0041bc032d76b0adff18fed5e058e1eef6de3c82286a refs/pull/3435/head\n0041ae608171cee97acbc163c19693951a231a2d4e06 refs/pull/3436/head\n00414e9f15e375eb118fbc7456f1ce75b7fdea960384 refs/pull/3437/head\n0041e79e37c87d28e153d552dfbc93f73111d0a18bc9 refs/pull/3438/head\n0041923f59093eced8ddc607c93353be0014ee88a6ff refs/pull/3439/head\n0040c3ccd3c6e811b6d15026b5cf1853a2f663001a60 refs/pull/344/head\n0041598407dc758dc60d193726d7db5399c4719fd952 refs/pull/3440/head\n00413741e5c083341432c3899d00d93ef84cf7f469de refs/pull/3441/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3442/head\n004154ef244af43a6711eb694021cb81efd25862a095 refs/pull/3443/head\n00417734f6dd3b776a0698e7b32256ca39f57d3078c1 refs/pull/3444/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3445/head\n00416627b1e2424961a3a38ba09e56f1887d7e5b993a refs/pull/3446/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3447/head\n00417f6aa8bf0de045b86129d4228ddfc99bd290af7f refs/pull/3448/head\n004175ebcd5084088481a531a5fa2cb4c0f8c4399942 refs/pull/3449/head\n004004d296631f37bc5d0e2c626fbd73f96427fdb0be refs/pull/345/head\n00416614652415913dd558a7f5e1760f6adac91058d1 refs/pull/3450/head\n0041a30243991efe7657d72e09cdefa0bca512a26a4b refs/pull/3455/head\n0041d613d3081e40ff0a2605553d6df587ed7750f26b refs/pull/3456/head\n00419202976cb63fe40fc20514a9c33f47096cbf4009 refs/pull/3457/head\n0041e1ec445951d86ecc1e953de48d0fbd89c35c351f refs/pull/3458/head\n0040987aa1508bf8d1de2f3dcf2fd010d87e126bb8db refs/pull/346/head\n0041abea6c5f85068528fa575eb4eb756b2ac0e8e92a refs/pull/3461/head\n0041e463b25713c5ada97bc7c09bbc644d8eb35926e9 refs/pull/3462/head\n00418f517991d1cb5e0b703a99e9f5f0356e96fd2b68 refs/pull/3464/head\n0041b341b5aa46fe4c33d29588397dd1bdee9d463b46 refs/pull/3465/head\n0041f44bd5c565c936007b9b937f27db82baedd64b9b refs/pull/3466/head\n004126fcc9f16b76b0925319f6554c6a6aef3b956cfd refs/pull/3467/head\n0041ad902ce2ae444857ba5af2a0575b4023e8694b64 refs/pull/3468/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3469/head\n00405450274ef3e558455c66ada108a0452e4843fdfc refs/pull/347/head\n00417c267cb058520f9d80c081ad44a4ce2864cd7019 refs/pull/3470/head\n00417b2fe16362dd063b59fac2c40d3f28948fbada9f refs/pull/3471/head\n004165252dfc054e98eadf8764745dfc034de989d49e refs/pull/3472/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3473/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3474/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3475/head\n0041cf1931c7276150ed36a4d8e11fd219a5cdc7b181 refs/pull/3476/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3477/head\n0041fc9be78fa0069be51b4cdc434bb06a02cc9a00ca refs/pull/3479/head\n0040bc92b86da455b69be1bd3916273645b337674ca2 refs/pull/348/head\n004138adfc481554517cb4adc7b370e3c231c33132eb refs/pull/3480/head\n004167cc7e37a710e3ea05a75374a506c04c87a89a34 refs/pull/3481/head\n0041603dcca4481fb9e1778f6e81ad048ae73320e30c refs/pull/3482/head\n00413e4197bb97686b43986c05d2e58481bf6280cff9 refs/pull/3483/head\n0041d5715a6a3be4943c0f09eeed95477e21546cf37c refs/pull/3484/head\n00412fc3db5c428f3c2ed1f1d53a6d32eb310ea7a469 refs/pull/3485/head\n0041eb8f7da07c8988a4685f699bc3ad3079b6e5fee6 refs/pull/3486/head\n0041f115d5d4d4655a1f132ea5b50dd2606e8698f8cf refs/pull/3487/head\n004152c3e0913ea564c9528adcd2e5bfb4fa84ba8556 refs/pull/3488/head\n00418c3c4edcb7e294421aba9759fdb033faeb61a5a0 refs/pull/3489/head\n0040df9c85159194003ea1f55d088052eeb60746823e refs/pull/349/head\n0041662b7d2a0f214e1da0510968fdf458c93d225809 refs/pull/3491/head\n004131420ee602fe6de115e4cf32b4dea4d20c37ef92 refs/pull/3493/head\n0041dbf993097c75276c397af40c80a17ab0a85750bf refs/pull/3494/head\n0041b0b0db1b990ace1dcd6a0775fcfe8c03e1c2e98b refs/pull/3495/head\n00419cf8a2f26e3bbf477b68032e0969d08bed9cdcdb refs/pull/3496/head\n0041a886341b602a3cc8278121ab40882b39cd94eb5f refs/pull/3497/head\n00413c0b52d09cb1dc44632bf9009ca51e1409066af0 refs/pull/3499/head\n003f9a6fd6cac6cf82aa4dccfdce615dfecbc76dd28a refs/pull/35/head\n00400454bf6ec1c4e9422765b5f3fbaaffdf15176979 refs/pull/350/head\n00419a6ce09da4d08d9eb8f59f0440c3758234d19e51 refs/pull/3500/head\n0041c546db9b641c145360de3e14ac12d48dbbb6581a refs/pull/3501/head\n00412dc4cfb9803f2aa927953e33bc1f40c3dab44156 refs/pull/3502/head\n00413a11c7356b0077c7c73c2143c05384cea89fae31 refs/pull/3503/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3504/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3505/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3506/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3507/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3508/head\n00419a567192f4142f72d8c0c9c0dfca059c314218d9 refs/pull/3509/head\n00400c699e9bf5b682c91f3bc11a35edf88d6667fa02 refs/pull/351/head\n0041a5c7c58c9c454b44c22238ef04ee3d620487d3c0 refs/pull/3510/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3511/head\n00414100e0af9f9bb6b8326aaa8c56b8ca4217bb5671 refs/pull/3512/head\n00417d9e4c951de40d4d2f4ca5056942b16672711b54 refs/pull/3516/head\n004067eef7352339ed2507d2bac858c9812ac4e046a4 refs/pull/352/head\n004112d4ccf73cafb1c17904c65fc54926d4fc0d2667 refs/pull/3520/head\n0041facd4046a0d547318694a68d1998be9df873a9b8 refs/pull/3524/head\n0041347fc8d5550965e6fbddbe63fd2c6a6af006d694 refs/pull/3526/head\n0041558f36467459b7a7e59af1069dd04a95d628a024 refs/pull/3527/head\n0040cf0c8367e746b2a1ae1a42202ebf11694a5a604e refs/pull/353/head\n00415d50028a97df7729d9a73878bab12a732a4b5438 refs/pull/3531/head\n0041412a32512c3b2888af0d26d8ac77fbedba6b738c refs/pull/3532/head\n0041726d98b08d7796dac5bedd4b9d34202fb4164ae4 refs/pull/3533/head\n0041434abc547f8f844b62c9abea8636adf414ce99b7 refs/pull/3534/head\n00418ec89391bdd972f05bf74daea3bfc5938a8fb2a2 refs/pull/3535/head\n00412aaae4a493ffd4d0af0bb0969c1c876a630e7bdd refs/pull/3536/head\n004126ff86f1c04993f6c36bcfc92edbeee015e189fa refs/pull/3537/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3538/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3539/head\n0040d4e3672671d311513e0efa9afe6c323a661a1e03 refs/pull/354/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3540/head\n00410230d614aea5f85d892fee98dc11ccb917837244 refs/pull/3541/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3542/head\n00411e9b862819e5a01ab7a65c5863c19adc0fbb06a6 refs/pull/3543/head\n0041535d8e0f999d37b0410574258f07fbf1a24d648e refs/pull/3544/head\n004196a3b49d5bbd0b7a6fa8e2b8a7febee215df2bb6 refs/pull/3545/head\n0041ba980971b276451472973c91d8a3599f06d2a790 refs/pull/3546/head\n00414e1501dade292549592c52d957e4fce0b164f5f7 refs/pull/3548/head\n004111556ddafbc6008583a1f421910dae8ad99c6c64 refs/pull/3549/head\n0040600ed28b6bf05e4800518d4299ba993a3de128d5 refs/pull/355/head\n0041fbf37fba1a9c93fa1cde4816d4c2e83de789764e refs/pull/3552/head\n004152880b04b157686ac203e6d1e05553c1554de526 refs/pull/3554/head\n0041a3ff783b82a73d9e590c130ee585935e3c47839c refs/pull/3556/head\n0041f8649f35c73ef8b68b8395b084419c74b1ec13d6 refs/pull/3558/head\n0041ddcd86bcc2937a1ed44480188e648d748253ff7d refs/pull/3559/head\n0040cf1cbc2950c195040601ce36ddb4314e94288711 refs/pull/356/head\n0041b4fe9a998fdb7e9682ea2a112d46b1f7fd1d83b7 refs/pull/3560/head\n004122ae49a865e503352cf40255938e94fc55ca1264 refs/pull/3561/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3562/head\n00411a9e9ab5f77adfee6997e35a99578456af18adff refs/pull/3563/head\n00419f411fd43ad96bcea3b00c2b6b09ba133ad970d6 refs/pull/3564/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3565/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3566/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3567/head\n004137c352279ece36826e0bf6cb7fe474144dbbd03d refs/pull/3568/head\n0041b01ff6cf71861f5b59b406b3b083a6a81cd5b05b refs/pull/3569/head\n004009a3d6def73568852ef4ae16bc83b5dc08bec29a refs/pull/357/head\n00412ef434da9cae143bbd52efd063c07c2365bee95a refs/pull/3570/head\n0041041b7702963bc077080c447a6b2156f5ad54761e refs/pull/3572/head\n0041f32b12df3a4a65424fe1d7656304bdc0d765d0ef refs/pull/3574/head\n0041e60e677527cd031f039fdd2d77859ae42d855f1f refs/pull/3575/head\n00412efaa9bc8c6e2a97f5bfbb231018d4c0f7d32c18 refs/pull/3576/head\n0041f91a700e72fa0ff87d505a5b0d742a32e2bfc666 refs/pull/3577/head\n0041e4969f8cbaef6577d8fdf43bb4cc80bce1dd7fb9 refs/pull/3578/head\n0041dbaa13a50bd43863dfaeaa1a2ba21528abb5d89f refs/pull/3579/head\n0040e933914511cafc5fdfb749ea7b07816fc675706c refs/pull/358/head\n0041aeece857dc9f9b33d18cd90c5c213dfaecb82698 refs/pull/3580/head\n0041e6d34f9b331c5297642565e4ec463d6a001da9f1 refs/pull/3581/head\n00415e1fa71582e8ba6d804ee07c82d1e635ad7a392e refs/pull/3583/head\n004165211f2f09f58fa9453af0005c7ed8d4e43bb67a refs/pull/3584/head\n0041d099eb9a6608a5d0d2aec966f32c467e68604c66 refs/pull/3585/head\n004134589f34e009247cb2eb2d249e57d78a59deaed6 refs/pull/3586/head\n004106a28e3bc4144959441b736e5bb62eacb1f817b1 refs/pull/3587/head\n0040b0d113e1de8d5dea0dad2ba0b112b7a6d7b749e8 refs/pull/359/head\n0041aa9e18358bf55c15e614ebb8ee2741a2f9996048 refs/pull/3590/head\n00414d8f4319eaf3a2634e5aab04ac0ccb706cac6f8a refs/pull/3591/head\n0041cb57473c8df0ff9684a1d88085273ccc71b32be0 refs/pull/3592/head\n0041ed2f8d86aeb2b877ad6e7c5d991a666540212ddf refs/pull/3593/head\n0041139c04ef65a5f7448c76b9ebc2020800570220d3 refs/pull/3594/head\n0041c1aacde188e95d078d945071c89474260f0864dd refs/pull/3595/head\n004116d1ab16fa4d100b903533361c6a34ceb5f4391e refs/pull/3596/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3597/head\n00411c4fe17a54b97737f3671ecaf56bb077f88b9239 refs/pull/3598/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3599/head\n003f33e3ad75825b38db5a4425df6d65e40410a5e9ca refs/pull/36/head\n0040e8f98b0a685b0579043ce7d7c161cf483b71f995 refs/pull/360/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3600/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3601/head\n004117c7f0f8ab0de4cfe8b087a4af2304b9ce86f62a refs/pull/3602/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3603/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3604/head\n00413439bbfaab349c59b0854a9cdcbfb23f46c9ed52 refs/pull/3605/head\n0041d540c1269b98ecede35df9fde66096ba1d9d3072 refs/pull/3606/head\n004133e45f96dcca0bf4978db082599db2a416eb0137 refs/pull/3607/head\n0041f3d15b6378921646c65c17c99bb9c4d5826cf5d8 refs/pull/3608/head\n00413fdf840caa2a15aa1b02ad63edbe37f14c25ad04 refs/pull/3609/head\n0040af341b4f22bbdac128322f76b48e07c31dfdca46 refs/pull/361/head\n00410d61d36d5457e56436939c609274a27d6a3d5939 refs/pull/3610/head\n0041c57018380ecb4a8c65a50a43146b1cd220d14140 refs/pull/3612/head\n0041cfed10e5cd77ce191ed85b3aa1879ffcf78ddedf refs/pull/3614/head\n00410e5894deb3711d7ae9d9e1efd62fb3fe718cb00a refs/pull/3615/head\n00416dcc20d5233ea2bdbf24637ab5a3d25e80bf6dcd refs/pull/3616/head\n00411fef6d381571733672f63d65bf555b9801186548 refs/pull/3617/head\n004182e4be020c85e0982b63537075ce4d44d0475dd6 refs/pull/3618/head\n0041356b68503584e33daed2cab24178a20c4d4cbf3a refs/pull/3619/head\n00406a801c7d85ede5c49881e53c45286e78dbf216bf refs/pull/362/head\n00410b26184e36cd97559ecefeffa099217136cf494f refs/pull/3620/head\n004164d1e66d5ad7e27d0fd38c49e0487e5b029b9639 refs/pull/3621/head\n0041758d6def407fe5258665f3b621081171459f9371 refs/pull/3622/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3623/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3624/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3625/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3626/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3627/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3628/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3629/head\n004064cf6dd540ef6a175e26345cde4fc09f98458764 refs/pull/363/head\n00410b3780de33f8385775e0cb2b24a45bbac5824b12 refs/pull/3630/head\n00415e7f9c92ccfed0ca84a87dc0fd1dd8bf962a81b8 refs/pull/3631/head\n00413766f886f09b0e05c216deec1fca932704faef3f refs/pull/3635/head\n0041020ded73f3db4649327aeda027020a2e37640356 refs/pull/3636/head\n0041378236c3105538906a4258009a87f9a14684f304 refs/pull/3637/head\n004135f6f9c3529b0a143bd93b9ee2d1e8258c2c066a refs/pull/3638/head\n0040cb0bde56c77838a7582b88c6d5e9150d2964e1d6 refs/pull/364/head\n0041cb9695fabc8adcaeb8c2abe4af71e0b916e053e7 refs/pull/3640/head\n004103fa215005ceb3bf5d0feea91a3968e90aa446bd refs/pull/3641/head\n00413f23a4b8dcbcdd6c1fbd8c2adb4a23a0a4ebdb2b refs/pull/3642/head\n0041607063a14d4aaadd1b5670e757b277110a979e97 refs/pull/3643/head\n0041570126ce462da1d39ccb24cac7ce605ff38ca3a9 refs/pull/3644/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3645/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3646/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3647/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3648/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3649/head\n00404b9a948506a09bcb0af3f4a7d34320fcc41cc23b refs/pull/365/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3650/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3651/head\n00416342cfdeb589742ed13452978cccf8e01a318f38 refs/pull/3652/head\n0041cd4ab0e55a184704b00276f26165570ff9ec1444 refs/pull/3653/head\n0041abf79a0cd8df5dd3696d268e9cd102047e1f17aa refs/pull/3654/head\n0041dd56685ca2a38e46298b6d0d2b80736d91d55733 refs/pull/3655/head\n00410ea8372305c0ffbe8c1b7461c480709b51584dcb refs/pull/3656/head\n00419ab03f8dcadf83eb43ddc1d53fcb6777afba2a23 refs/pull/3657/head\n004109a4a53bb0be24011dcecffcc786774e71a2438c refs/pull/3659/head\n00404ebe16b3e179d11c7345ab7e0b5ec7aa262ba9cf refs/pull/366/head\n00418ab8d6ce8416b09773a68b75c3417effe07e0e2b refs/pull/3660/head\n004150188606b6e0c69235544879d1949ceb6d2f7916 refs/pull/3663/head\n0041197e36d47a279ab508c1ca69df636bf0ab04a85c refs/pull/3664/head\n00418994e2c8916d64c554c0d1bd4fddfb3fa86e6037 refs/pull/3665/head\n004197da23582340f68c0e3c4a10331ef3f2dd1d3746 refs/pull/3667/head\n0041e725769a9d44441d3d3b97ea119b5ccc0ec13242 refs/pull/3669/head\n00400f88251f8707640498665ed86b3493288ea44b86 refs/pull/367/head\n0041b129a3fae3f0969918714b600439e83e0f20ad74 refs/pull/3670/head\n0041f9320da0df7f2bc55d6dbac11a195963042aca5e refs/pull/3672/head\n00413a22d2708c6f65fbbb7c396b34d0fb5744ce139a refs/pull/3673/head\n004122f50cd7fff2333b32434e33a4be35d016c8507b refs/pull/3676/head\n00412398aa1e760b6e19934397cf58f8317182a732f5 refs/pull/3677/head\n00413ce3d4adc1cf1cbc99e39de8af86157529b5c96c refs/pull/3678/head\n0041898f7603b40285901c4193006caf5a1a7f865a24 refs/pull/3679/head\n0040daec0467ba809add8287e6e561b207570dfdef9d refs/pull/368/head\n004126482c89d1eef651e3074870a21e691d3ee7d88f refs/pull/3680/head\n0041724e6ba210e3a3e558c8546a64a3b05b88dab32d refs/pull/3681/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3682/head\n0041ca808fc591679ef553b9c217a67b483486ef954d refs/pull/3683/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3684/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3685/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3686/head\n004192d2564fd9ba300f6cbc8186d9948bef96bef29c refs/pull/3687/head\n0041ab3ffa1f942b62e296bf81d1e2f64b750204812f refs/pull/3688/head\n0041f102174f88e790da42947faa3b33b9fbac9c1ad7 refs/pull/3689/head\n00407e2c699fd73e14c445f1302ff24bed0a2556868c refs/pull/369/head\n0041698bffcf6b2e1ee981b74dc56598868c5f0d7690 refs/pull/3690/head\n0041841cf111e57718587a569e44acd3ecf89c2431ec refs/pull/3691/head\n00410af2a89e704fe8fc0c412d3e80c3161b6612c15e refs/pull/3692/head\n0041b86027ff3908261449d64b340f0562c36fb28c50 refs/pull/3693/head\n0041b68d03098b2cfb5be6f7171821194ae555c57dd6 refs/pull/3694/head\n0041bec32d612cfbebce1fcecab7ab2e2dc2bf2c7c83 refs/pull/3695/head\n0041fd0757a0397b6cb2f35aafa75777e02a2aba4b9f refs/pull/3696/head\n0041800efdc97f592673fb325a2e26d62ebdf9f74cbf refs/pull/3697/head\n003ff8f6f58700a542f06d0796bf7d26e6f39718d2d2 refs/pull/37/head\n00403c7cf0dd53c10c2fe43373d5d9e8e09ae9bd3038 refs/pull/370/head\n0041e1ec6f4b87f2c83cf0e569433e92a8b009628b99 refs/pull/3700/head\n0041f9f04b471d186f3269a369eca5ffdab734712eb8 refs/pull/3701/head\n00419597c2daf3838fc16fef732ecd9632e601a004c0 refs/pull/3702/head\n0041a54d68436594c8f418fe7be303d712fcbca76d6e refs/pull/3703/head\n0041814d0792d0046857c1b85ff003d923ce1a4cd761 refs/pull/3704/head\n00412dc6e2a77115edf0ca1f2c7ab2f49b078a5f1f92 refs/pull/3705/head\n004166588e57a6ea366b52febf704b1cc351733e4877 refs/pull/3706/head\n0041a36e364f26ce84a0e07e5bb332dfb6b5d8aaa15a refs/pull/3707/head\n0041620e4bf3d867ebcabdebf4162454d74b06606cd3 refs/pull/3708/head\n00417e8178e30d045e5c8124f618c7c00c08ae1bef3f refs/pull/3709/head\n0040ffcf21f54d8b285eb6aeda1824f3ce90d85fbb3b refs/pull/371/head\n0041fdbdaac9b6d0d67f4e6be5ff17d050dadd957b7e refs/pull/3710/head\n004130297ce4dc62464257ce8f09ba573b9c640a5231 refs/pull/3711/head\n004142a624e0a7acd08547e6ff56f4f7107813463f1b refs/pull/3712/head\n0041c6bb013d0ea2fdd57991b3a87f19ef9713cfa73d refs/pull/3713/head\n00411218898f514d73f9abfaaab3947d799700505a5b refs/pull/3714/head\n0041be76196e8a5c0e6bd0f72c96f193ef655ead9f71 refs/pull/3715/head\n004108fc364d0764d379a956cf1e43269fd97a66202d refs/pull/3716/head\n0041cca07dfb64d644e87ca2a5ed32f22b8a20d96d8e refs/pull/3717/head\n00413a9f1033e39c8f0005f0711a6b6d3e20bd2870bb refs/pull/3718/head\n0041479d99c266d278e38b4183b2b8b9b2ed0f915fc9 refs/pull/3719/head\n0040ad8ecd3b9bee94d51170382b695f0c778a497bfc refs/pull/372/head\n0041b50d321af176b7c7ff6f429cdb77ad6347705c92 refs/pull/3721/head\n00414eaebf897d134d4eb55906bd26a8a4fa485d45ad refs/pull/3723/head\n00417be13b4869c605fe75ce5bded034a1202116e181 refs/pull/3724/head\n0041a7d4cc11edbdc202607e20681e145ce817efd75b refs/pull/3725/head\n004157c67490141d8faa757dfe25def9470ae574c5d3 refs/pull/3727/head\n0041d1de8f55d10a6161e7c42302c02d8d5d2b32cbc6 refs/pull/3728/head\n0041a070a57f1e6fc95ed5d90f34caa3e1825e93b9ef refs/pull/3729/head\n0040a54c525503c36c4120616451e4083bc0214b4ee2 refs/pull/373/head\n0041427b1940b2eb7a5c4783ffa406ff222352ac352a refs/pull/3730/head\n0041876e71218100d13ec9523b1b69b6741bc19e2240 refs/pull/3731/head\n00412b7235d7fd906bb9205d56b04ff19a41e8e3f624 refs/pull/3732/head\n004126c49d4fdb759869ef05b834909a45235c1cbfb6 refs/pull/3733/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3734/head\n00419fb657062b28459e967e6aa9f71b8f5eb1d96613 refs/pull/3735/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3736/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3737/head\n00411042a986854b32d67c047bed251d244383c7f445 refs/pull/3738/head\n004156936b4e650d78b6d44ad24011e781acc50df49c refs/pull/3739/head\n00400c42f8686a7cbd215a8f24817d7de1355df77b1c refs/pull/374/head\n004134cba88931b0c0c9ececda69f6bd56f0ee6132da refs/pull/3740/head\n0041cbeb2bc56e40e89d5d7ed57e73442cb8bc08f033 refs/pull/3741/head\n0041be8f03fb6ff6b368a1b316fe49c2604d8048a878 refs/pull/3742/head\n0041ce0ffaafdcfb9f398fac96394c97f5829f8e64db refs/pull/3743/head\n0041a4de75be38efabd02ec21bb954dcf0d06c383974 refs/pull/3744/head\n004155cadb9f3ddb2181250be8240042556e2aa0accb refs/pull/3746/head\n0041a419f67ff567f18441090d5c27f9fc43f6a8f85e refs/pull/3747/head\n00404b20f8036316a58b61a3eea85afea53cb054bd66 refs/pull/375/head\n0041808af80abe8cb7ef26d5df2c5f14589079967775 refs/pull/3753/head\n00412a4d23c27ad4f3586be87b4b749997a1ecd1b722 refs/pull/3754/head\n0041bec788f16f4be311ac5a4fb1dca48b22020d23d5 refs/pull/3755/head\n0041ad0ddd181dee7c3c2cb1db63b403e7ce9463b411 refs/pull/3756/head\n0041bbc7ca771fb0476a6a4c09f08f90934ce416847b refs/pull/3757/head\n0041464de6c8e3d3b6a544e6a1dfffce2613cd53e4b9 refs/pull/3758/head\n00415b655fe17e896c43f2b28b027217dbd4ee0c7274 refs/pull/3759/head\n0040df92eca6a3262981465ab6e7c100e740a9a5a613 refs/pull/376/head\n004178e8dc574cdd5f9a11e78ebb241e70bde1f10276 refs/pull/3760/head\n004134f398b12b84f860e1078087b5833fb7c1d9f6c7 refs/pull/3761/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3762/head\n00419fb657062b28459e967e6aa9f71b8f5eb1d96613 refs/pull/3763/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3764/head\n00411042a986854b32d67c047bed251d244383c7f445 refs/pull/3765/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3766/head\n0041efe77a86820dd9207412b620fccaef9a716266c0 refs/pull/3767/head\n00415e884e371f05bd80acc4753bb64f826c9bf0c0eb refs/pull/3768/head\n00418daf095a835d28885c16f80f48ab29fabcf2a2d6 refs/pull/3769/head\n0040f5dc20b5d4e4fdf4699840a9bd90ccb6b51542d1 refs/pull/377/head\n0041c2c3b68c6af8ad24f45ce5f35fd3e668ef875c8a refs/pull/3770/head\n00414c283dcbba2a55d0566dfb0a749c0319d8ed5ab8 refs/pull/3771/head\n00418e02e2a9e26af982757ba77bff6f10a61f7b1014 refs/pull/3772/head\n00416e019a2b1169347fc8dad0186e207ac29b57d2ac refs/pull/3773/head\n0041b20cabba84eccb72f769c4da172b9275954bc48b refs/pull/3774/head\n0041b5c42bf8102749ba0f8c43170d11bb30ff19fa8b refs/pull/3775/head\n0041c071914470ae062055c25063050ac61fa77c78d9 refs/pull/3776/head\n0041367660326d80a888842f024118a744e07dbcbda7 refs/pull/3777/head\n0041ee216c0c3db6c068d6fcbcd24298ecdccc766157 refs/pull/3778/head\n0041a73b92f393b8273525970e8e20876b2e9bbafdc6 refs/pull/3779/head\n0040125473272cfe458154e9eb689d9263df394d3086 refs/pull/378/head\n0041276a8ef346cc1169411063ccca224af1d5f3d039 refs/pull/3781/head\n00415676afc7b4a082a7436b7933d2124b88714aa01e refs/pull/3782/head\n004106c4c8650ec6c8eaa6a2fe5956a0e50319b233bc refs/pull/3783/head\n00419dcb8720303c7b6abca6e90867e9c291e3848ba0 refs/pull/3784/head\n00419a31697635c011fd0551c068c403df15d53f8560 refs/pull/3785/head\n004178486fdd63d322cc138b4388a5ad8f266e4ba70c refs/pull/3788/head\n0041effb851f141dcf53f1a332fc3596613761b67c38 refs/pull/3789/head\n0040df8ab034cb5eaddea0415ae9953a6165ecc60549 refs/pull/379/head\n0041204f591530550e4dc88157b9fa3ca8070944cb24 refs/pull/3790/head\n0041c6d02d3781794b908ffc84d27b2f40af07122447 refs/pull/3791/head\n00416d9b9c54be33f1a46e375748b214745c59b0f875 refs/pull/3792/head\n004119350d09e9014b6bdfd955c857e76a9090041667 refs/pull/3793/head\n0041933b0606acdcbdc77e1148cf52b6983208d4cc9a refs/pull/3794/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3795/head\n0041e01dfe987e705ccbe116d3d752c0b1a241f5e760 refs/pull/3796/head\n00410c138fb8a7ec3426340896578d6a965f0e807ff3 refs/pull/3797/head\n0041701ac77c292eeea0e137b37b387a2fa8bc2f641a refs/pull/3798/head\n004142f2e2159fad8dba95888968c6db02124acb0e3f refs/pull/3799/head\n003fa72f79c5064d756b3b1883dda9744549657b333f refs/pull/38/head\n004105e8c4940436783b38d6366b8e953065ac834743 refs/pull/3800/head\n0041ee5a4107f7579d54a78b6361c376e03ac8bfba65 refs/pull/3801/head\n004195238ab119dc3f0e7f1257cc577c89ce7ff9b8b8 refs/pull/3802/head\n004188b849233ee8a636efb68bd65a58f36d29f59e79 refs/pull/3803/head\n0041a6cc50067eb9f7d1d4dd954e527aea508f96c4a9 refs/pull/3804/head\n0041c082e78b164f5823bda75a885301ebdc29a451b9 refs/pull/3805/head\n0041b7021ad3cdbc20907dfe421c86f5f5c991385757 refs/pull/3806/head\n0041061b4527d6bc79e7bf01db1058367b05fe277ab2 refs/pull/3808/head\n0041fb1b7370554c69d44b2ee316a501b460a42a44a8 refs/pull/3809/head\n0041e6e89dd4def50443728ba0425f6098a1e5deca1d refs/pull/3810/head\n004169bb4706258809d92805bcc8034afaab6f7e835e refs/pull/3811/head\n00416a9ed3f31e4927858ea4442ba03491109141a8d2 refs/pull/3813/head\n0041ab836a2f7d8439c87ff40604d8aec5ccaacea7ff refs/pull/3814/head\n0041a9194146c8609d6920361fc66d8ba210a777d65c refs/pull/3815/head\n0041811704ec2f3e4389e8606ece5164dffe32e2a6d3 refs/pull/3817/head\n004174f80ea6be12fe99689eea2472f3feb856fdf1fc refs/pull/3818/head\n0041500443a63b436a12be0e9e1e1c607364eff7f915 refs/pull/3819/head\n0041af64a7c4b96efb3dcaa6d1f5f752b68618453d4f refs/pull/3820/head\n0041d8aaec90e7842479f914b02f56c2711c3b8ff26c refs/pull/3821/head\n0041ca8b4f650897b7403854a651f7a1afeb065fc9e0 refs/pull/3822/head\n004155fb452b42fcd62fd74e662b60095268eae0b940 refs/pull/3823/head\n0041736e3be9329039344741aa74e15a58c318d640f7 refs/pull/3824/head\n00416e26cae18223607f3c2e1811f9f1e67b615dec57 refs/pull/3825/head\n0041e16bf45404fa2e1dcd1737ddb9274bf0dd7e0170 refs/pull/3826/head\n0041d0305ef55d2ff53ea2d066f859814aa2700d7f61 refs/pull/3827/head\n004147d383ffd9944c8cf2ccdd11faf5d440975bea62 refs/pull/3829/head\n00403d26b83e2b4423e91f1878eebb5320712e41cce0 refs/pull/383/head\n004188a65eab60d0f918387708a02e5570de0fc6f7f2 refs/pull/3831/head\n00416bb5605d423259d74e71277fe6f836c87de19846 refs/pull/3832/head\n0041d6f5a96c2096f5e1a70bb4aa582f04fc2d9e82b0 refs/pull/3833/head\n0041f6e9e6e03bba10e4d6780f887307612bc67e1d19 refs/pull/3834/head\n00417195d59fe61b182337f640f9368499d391563bbd refs/pull/3835/head\n0041102f90641b9f6ae36039c7c906609d7d4d9054eb refs/pull/3836/head\n0041c704d63d927519bf34b55325eeb8835d6f789f12 refs/pull/3837/head\n0041614c8e36612b5c92942389799d689a9139aea991 refs/pull/3838/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3839/head\n0040b5b94b399d091ef348eea50af8166632d491f2e4 refs/pull/384/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3840/head\n0041a1a28653323cf3a20cd24667d82c9103fd2a84d0 refs/pull/3841/head\n0041fe05aea385a0ddb93295dff0a77175b82180002b refs/pull/3842/head\n0041db530e4e3c8c851ecad3737337d6db4231cb90e1 refs/pull/3843/head\n00412cba1ca28e2faa75750b291f35db95b269f43fcc refs/pull/3844/head\n0041e3ceaa0b5995ed5af4d2bfc6643f17ad805dea8d refs/pull/3845/head\n00413d63b91177fbeeb521d2203307d2817a6be4c28d refs/pull/3846/head\n0041c63547e6e0bdea773127e2083ce16b215c9d0b61 refs/pull/3848/head\n0040f29693a20e63c75d1185ffe3852d5e05200365f9 refs/pull/385/head\n0041eb80e7a9797b8dd45bd50629942669eb3729b3e7 refs/pull/3851/head\n0041cc49d6896ba8f3ed5a8c5a565e3299fe0d39de28 refs/pull/3852/head\n0041af545ab7517d7f9cfd328e5518351217d06fb0ae refs/pull/3853/head\n00414cdb3a83045d241c6abfd6cc8b67c10493993198 refs/pull/3854/head\n0041d90baf84c2ef89cb16ef27bb8574d92c8f295827 refs/pull/3855/head\n00418cc18a6eaa952502f4ba7b3d9c11025b5b3a8512 refs/pull/3856/head\n0041b2c769a43c127a4ad3a301ce384fc24e76ac378c refs/pull/3857/head\n004150850b1951c108a17bc0db9c312895ded1dd1183 refs/pull/3858/head\n0040b7ef5869c878e43bba7533aa9b40988445c0bb5e refs/pull/386/head\n00415dd1a02a0e4c8ae3215fc09fa4b54aedb0a14eb2 refs/pull/3860/head\n004111362ca89eb07304d63e8225b4fd3e6c9ae0eb78 refs/pull/3861/head\n00417363ff427c719760a4de92b34b548a3a3d8071bd refs/pull/3862/head\n0041f85ba9a74db5729a8c8355ab1b00c68a881185da refs/pull/3863/head\n00411bee5f5f6b97914149e58e36bde8190259dc4792 refs/pull/3864/head\n004179e4032f8ffa02840fece03311c4f49ac1e7295d refs/pull/3865/head\n00411c3ff7ed39a9ee2e3b9978c412788944e94a8fb6 refs/pull/3866/head\n00412c0029bf5574f0ac36ca6cebddba1dc753a2be72 refs/pull/3867/head\n0041ff5a5cace93eca7955893492eefb5a51f295c76f refs/pull/3868/head\n004150ebaeb597549b5551f62a71cc860ca12661e700 refs/pull/3869/head\n0041759f43e9479c5207c92d3070f1647113274725ba refs/pull/3870/head\n004187a1e51128efdb8f1341d53e041431e23fd023bd refs/pull/3871/head\n0041b750dddb72d686afd2d5a3efde0ca11de99e5d89 refs/pull/3872/head\n0041cb8653f0ace7cda384f2b2dbda709bce57430e03 refs/pull/3873/head\n0041102f90641b9f6ae36039c7c906609d7d4d9054eb refs/pull/3874/head\n00417c8f0cb2c18cb6993786dc3d47b7e86258a962ec refs/pull/3875/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3876/head\n0041fe05aea385a0ddb93295dff0a77175b82180002b refs/pull/3877/head\n0041e3ceaa0b5995ed5af4d2bfc6643f17ad805dea8d refs/pull/3878/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3879/head\n0040623fd65be4741d54bca9d3b919ffa22c5e18d295 refs/pull/388/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3880/head\n004111e0a198535389e69ba4bb8839fa23669f2dc4b8 refs/pull/3881/head\n00415261b43facbf54e57857d2724ac5f23c6d00a5e8 refs/pull/3882/head\n004194f6969267b2f5260c90cb832431bdbe10cad548 refs/pull/3883/head\n00415d3eea4188f517c562fe62859a6ac89914bb0a63 refs/pull/3884/head\n00411e4ceeb43f1c8ba954af46556958158b75629d31 refs/pull/3886/head\n004100e968c4155d83f9b4cc100f9b510301d8015711 refs/pull/3887/head\n0041595f91858c4f263488483bab4f4c18eabecb51b5 refs/pull/3888/head\n004184ee0f213da7a839ce977520e53f901c141d1cf0 refs/pull/3889/head\n004020137d68b3d90677ec1a5792fadd7a0b9d5be665 refs/pull/389/head\n0041dd9217bab10ffafb83625720c7976f2f67257b99 refs/pull/3890/head\n00419457e17bf24eeffb0f5a36ba76dc1a752a5afb67 refs/pull/3891/head\n00417cba06455bb3105a5e65a7c8e664f3a9afd06ee0 refs/pull/3892/head\n004157b8170a6f3cc12b069d7e732daa326873b06906 refs/pull/3894/head\n00413e043d22054fe5f137d33453c89687b3d989a28e refs/pull/3895/head\n004117d5741880ed8fc9f47a3c1d4fab945cdd22101e refs/pull/3896/head\n0041c3367da422ec133b5b43aa56e247a235f7202aa3 refs/pull/3897/head\n0041f8cb8eb66e7871eab6205f062313c2c084de375f refs/pull/3898/head\n003f804148197b274c6129ab2c7d996daa456364c57f refs/pull/39/head\n0040e2654e0a480285bbba9ae0c65f7a48ef813f8d80 refs/pull/390/head\n0041eaa51e1dfb48b9f4e3733c94bd1696a8bf941644 refs/pull/3903/head\n00411b0f7a7995523913e78dd9ee49f623807bab26a1 refs/pull/3904/head\n0041e69b7fb5e733c65cc20e5ffd9e22c5cb92e9fd82 refs/pull/3905/head\n004129ef82621e3673342b536c444790f876ac7e67f2 refs/pull/3906/head\n0041e8636b60627bf7740a1003f63c98d947c03c1ef9 refs/pull/3907/head\n00413ac1ec80256d70f3f8bb7e884d9deb9c48d4e44c refs/pull/3908/head\n0041a5379a7b99a1d950c84e7c69bc5baca868b66045 refs/pull/3909/head\n004057cd1a4180b32268105209699409ee15fd23348d refs/pull/391/head\n0041c25e5ebc1a6f585c431c3057001426686a808347 refs/pull/3910/head\n004156c6db5dba84d0f1c34f85dfbc03577c7249b1ec refs/pull/3912/head\n00410682e59821f2d878a2b7399795a08b610ce8c8e5 refs/pull/3913/head\n004170623ca4eab567cab87a6bdd9c3c33f1809b1a57 refs/pull/3914/head\n0041fe546f2e593c84506c99a0c84da6821ff77b38b8 refs/pull/3915/head\n0041b87b2c7a05591e42db578fee5f26b0e7af034182 refs/pull/3916/head\n0041ec890999086a3a042d4a5dfe7480995f63daeca7 refs/pull/3917/head\n004194cfd7cc62e85496c8fabf2a0efd61ec041fbe11 refs/pull/3918/head\n004143798d1d6097e36ebbf3ff866dce07fd2bb2a11a refs/pull/3919/head\n00400c0a26a82752908ec2b45b00e052b166bcad1a6e refs/pull/392/head\n00411ffb1cda6d825a3f2b7975bbf31d7ee2c609d6ea refs/pull/3920/head\n0041616d8a297c117bf39b988e0f50191be88ba727e3 refs/pull/3921/head\n00416e0e9ef0310921cc583beb987013c9a52829e7a1 refs/pull/3922/head\n0041b588efa4c39fd3e1076b7bd34a3affd5e9705f73 refs/pull/3923/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/3924/head\n0041d8e6c8739bc2272484e8c2cf2eae617f53ad10e8 refs/pull/3925/head\n0041e0a3899cba44d3697c3fa5d5cfa67fbb210c6e47 refs/pull/3926/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3927/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3928/head\n004111e0a198535389e69ba4bb8839fa23669f2dc4b8 refs/pull/3929/head\n00408defc8e7c76da637ab8b3315c82a8f3896d187f6 refs/pull/393/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3930/head\n0041eebef3dbccb263f3625759617612165854d9dd9d refs/pull/3931/head\n00413dcbbc6feb6c7b2f4cc671600d3c408b10d32b5c refs/pull/3932/head\n004115a2ee9887ccae26ddec0daaf954ecec46fb3316 refs/pull/3934/head\n0041070cde5d0ae73ccdccf30f1b25ba76bea01d7156 refs/pull/3935/head\n004161e217870dd89215e181eb5198da8211d8e6cdc1 refs/pull/3936/head\n0040e0077f650f0dddd7ceb4160447770c45d0e5972a refs/pull/394/head\n004113c164479d20d8ec7294084f267b16a61f46bfa3 refs/pull/3940/head\n0041b6f1afc80459cea24b4be85ca843417f63c0423a refs/pull/3941/head\n00418b1ff67344b13995e68cf3dc9c8ac58f6f3b87a3 refs/pull/3942/head\n004152eb9f77964b05635e9110dab9aa82716a6ad061 refs/pull/3943/head\n0041189f29b0582fdfc412d147c5e79980244b0916b8 refs/pull/3944/head\n00419ba171f3de14d8e7a0b44b1a092ffffa2e1add7c refs/pull/3945/head\n0041fd0b54edd5ce159b36436c3dd89b8af5c37f58e8 refs/pull/3946/head\n00418ef418b918c995ce37e33f6f89276ae8781f3e78 refs/pull/3947/head\n00416d6d4fe2890b6a1498bfe91526b7a1f6985e8d97 refs/pull/3948/head\n0041da7f3dc8c1032d4b47d88719095df5e9ee394b39 refs/pull/3949/head\n00415eb86678eae2033cfb079a5aae81b459bf516dc8 refs/pull/3950/head\n0041ccf9a28d651ac78a1f4e794cb114ffe16643b2f6 refs/pull/3951/head\n00416286a716ab3c025a7463185b3747a3cde7c49c6c refs/pull/3952/head\n004113a2c5e9bad81285a8e80d24dbcee28512ac45eb refs/pull/3953/head\n0042420bf78527bb0aba9970edfe7d3fee7c8e7941f7 refs/pull/3953/merge\n0041ed787a0805bae8f0c35e5d6b3cf5121695079286 refs/pull/3954/head\n0041e2def17cd2abe3158b014340edb97a8de0f0a7de refs/pull/3955/head\n0041219045203122803b0af860f379fec988b5063857 refs/pull/3957/head\n004194ec0ecba39dd2f91775c94b7262978910c42e23 refs/pull/3958/head\n0041dc13ca51ab5fc58e205c2e1cabbbfd7ee7622054 refs/pull/3959/head\n0040a7dca0c16eada7c7f722cc9c91e1fed92a2b318a refs/pull/396/head\n0041c42b5d0282456dd2ecde7317176d3672a681e8bb refs/pull/3961/head\n00419c20f4579713fca652e34f5df142bceb7777f010 refs/pull/3962/head\n0041d5f57424cd1665e54bc6d076ee94a32f02fe608d refs/pull/3963/head\n00416aa4465662f0ae01ead778d616997f1e46561b4f refs/pull/3964/head\n004193effe1655ef6e07a82bbbef23d9c67daa020fad refs/pull/3965/head\n004136fb882bff830d21fd6abb1edd5e3eb170df4025 refs/pull/3966/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/3967/head\n00413dcbbc6feb6c7b2f4cc671600d3c408b10d32b5c refs/pull/3968/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3969/head\n004084445945ed7de7198d9a0066daa0f51438edf947 refs/pull/397/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3970/head\n0041eebef3dbccb263f3625759617612165854d9dd9d refs/pull/3971/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3972/head\n0041b2a6598cdb211b9287ae9f1d4028141d1ac959ab refs/pull/3973/head\n0041339ac8eba2fc33dabca1539b4cc2fa7b0b694eaf refs/pull/3974/head\n0041ac1de7ed2d2d7dba68afd627892d354361ce8e4e refs/pull/3975/head\n0041511c148a08470ad22951e7e3bd2cd38e522ced1f refs/pull/3976/head\n00414f636407c5bbaee0027a2e7e0318f8dd17e5ce7b refs/pull/3978/head\n0041772f8a51d0202f5c1dfeb1f993eef208830a3829 refs/pull/3979/head\n00400844c04becceef49c59f882e131067a946ab732e refs/pull/398/head\n004169d9a5842c7b8501f4ce26a8cf796118089a29e6 refs/pull/3980/head\n0041358cdaaf3470654629b8070c1c0b16f3ea0af352 refs/pull/3981/head\n0041346f07a7a58d6c5767efc2fa756329c771efb197 refs/pull/3982/head\n0041cf26f76e45970d35c7f96642eff8481f8e4a4080 refs/pull/3985/head\n004184b4f13793df71d9972c40d889b7cf39ed81bf4b refs/pull/3986/head\n00416c28b8631401bcd94a6797537fcf055fd1cf8a38 refs/pull/3987/head\n004134294cfed463b92dc955c131a63c2b35178691c3 refs/pull/3988/head\n00419475d9c86fe0a421d560ee7c0ecd19ff246f0149 refs/pull/3989/head\n004022f5a39f26c94f295594503e826e7cf470762221 refs/pull/399/head\n0041f8541a8e588830e669388f60c14abfd4a2e94148 refs/pull/3990/head\n00417bc326d367e5c6cf4e080aeb50ba7a9efa6d2231 refs/pull/3993/head\n0041741341c6ea0df2ffa59231f8827767abbf3e3d38 refs/pull/3994/head\n0041f2131447b46277eacdcffd60a4592ed2d1e13173 refs/pull/3996/head\n0041c28642f9b3c8d89e62795f4f708b6a83a3381259 refs/pull/3997/head\n0041cb3b9e85802b7084f0bd912353859104ced73a2e refs/pull/3999/head\n003e4a137256b3d2dbbb000152d745bf176d70147e00 refs/pull/4/head\n003f7a793712e2ac08d1a47dd61e24238bf0ffca6063 refs/pull/40/head\n004028e57c8bc46d1d8708ce9c9883be5d924ebbf10e refs/pull/400/head\n0041dcf91e611e46ecbee8674e2b9e20a3efbdbdd801 refs/pull/4001/head\n00410671e04fb737dc0aaaceb6cd16e2f84d8b900d34 refs/pull/4003/head\n004133cd5ecf32890d9c90bb211fa13247aa6f976d0d refs/pull/4005/head\n004140655b050c9d26d32ec622468f2ab6f336d37419 refs/pull/4006/head\n0041582711ecae53a970801c41deb3dd543c0a0017f6 refs/pull/4008/head\n004185830df99b8b87d2c0f2516b0610eb748a6e76db refs/pull/4009/head\n0040e485f81fe2dc95638871b436bc5c2169079f7ee1 refs/pull/401/head\n0041f37610ff5056787b0049db5a2148b72d31ef6872 refs/pull/4010/head\n004124df92e6cc679f9754fa61d678815021da6716bb refs/pull/4011/head\n00415ff229a202bbb25724a937f7ebbf45a67dfeea29 refs/pull/4012/head\n0041c299af1036c6650d5f280ed6a97f2bdcc140ac2a refs/pull/4013/head\n0041045a5fe1feffc3fcf66e0e9416334a5ebff59e6f refs/pull/4014/head\n0041d3d3c3ece200899bfa03b9d6bc7210e547e6b035 refs/pull/4015/head\n0041fd81720da377b33cafc764ec940445c422272984 refs/pull/4016/head\n00414f264d32b7adfa4944b55029ee870f182df1a1fc refs/pull/4017/head\n004148ee714b424076e2a714d5ab3812fc287043956c refs/pull/4018/head\n0041efdf07f93ea4d4c275d9e1832bb0f71940916eee refs/pull/4019/head\n0040ed452dfb3fafc4bf83650096ed88ad57ec4fcbd7 refs/pull/402/head\n00413bf1b3ae65ec763ef33d6de827328dbbfa84f412 refs/pull/4020/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/4021/head\n0041508aef0a6b2172c442e5c8a86e6c7043a7a4325c refs/pull/4022/head\n0041b2a6598cdb211b9287ae9f1d4028141d1ac959ab refs/pull/4023/head\n0041ac1de7ed2d2d7dba68afd627892d354361ce8e4e refs/pull/4024/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4025/head\n00414e96f18b74147ce2c448df232a5fee34035fd8fb refs/pull/4026/head\n0041ceffb14600121d81699a098098fa81c15bb8710f refs/pull/4027/head\n00418094cf87597d3c0bce1e6bcb2a0839484cc13adc refs/pull/4028/head\n00416e7df771e436b5bf524b7b643796c1baa7babc7c refs/pull/4029/head\n0040d0e471fe80170e85ca73a2e1ae9c836d769c2991 refs/pull/403/head\n0041546e846c9d289d9ba339eb60cc90648da9a37bb6 refs/pull/4030/head\n00415326204c817cbbf6168b7fe1b4e488f0121486a9 refs/pull/4031/head\n004135ec9bdadb83d2000d39e23b68926f18cdc7063d refs/pull/4032/head\n0041e1313e13e2285b2ad73401638529f215d3b7578a refs/pull/4033/head\n004141c2b3c104c84a273132900ae759b7d8c41eb14d refs/pull/4034/head\n004171166a0d6a23f7b43af95ed0fc6335f76bfab8a2 refs/pull/4035/head\n00418548fc841b6c33161cffa88a823e4ef98012dfd8 refs/pull/4036/head\n0041d604f023e238abd9fc6556c6078885aee23b188f refs/pull/4038/head\n0041d31d31e8ac29e98d3a27a83b5d45ea921149ca08 refs/pull/4039/head\n0040eb8e38a0a9d69ed42989476d22aec692229b4104 refs/pull/404/head\n00416525f4454d917386b129226dd59d00c53e2843b9 refs/pull/4040/head\n004136b27e35e464c78e7e498971855bbcde054ae5f6 refs/pull/4041/head\n0041814831e3ff9de8cc2e2831994711f29fd4e19537 refs/pull/4042/head\n0041df6b674a9e9ea8a6d42bb312dbac267c8f50c50a refs/pull/4043/head\n00419ab5a3a4757c46850e16b6dd598678b9d9a619c5 refs/pull/4044/head\n00418cf1724e7904751d7955a0b4e22f43600cab320c refs/pull/4045/head\n004180dc2f5ec2a822223edd971abbb008d5ae75d8ba refs/pull/4046/head\n00414223a6b82e81194aeb3465dd1acacb23c7cea579 refs/pull/4047/head\n00414ebbc055f168f25b25a9627d0642f5fffd2cf04e refs/pull/4049/head\n0040a5da7dc13ec7f46fa0f5e26ca0510c08f9a6f416 refs/pull/405/head\n00418f7a1f4a2df5488e7cb76af34140a485d9303be4 refs/pull/4050/head\n0041c60f4d8422b6485b3369585445f262a660c7113e refs/pull/4051/head\n00418e627312c947abd6174a58fcd126fb0886e05f44 refs/pull/4052/head\n0041f0a81947fbcaaddb6c035e4524b0b3b38ba51846 refs/pull/4053/head\n00419c02148c6d6e0fe4fe5be28167662aeea6bafe88 refs/pull/4054/head\n00419755e9fa2144edd64344a10cc1272faef971b267 refs/pull/4056/head\n0041e50b5f96a4c876d6bd0bd2128de031f9bc40e73f refs/pull/4057/head\n00414ef2433e1bf470b7d7847ac9ebd6c568eb71c659 refs/pull/4058/head\n00416ad7b0a64551e6ecd18bcd213cae285db9dae032 refs/pull/4059/head\n004017c1e7ec2ae2c06dbc42942ba61098fb5d372c64 refs/pull/406/head\n004180c200d3f72061337f95f9f062a6be1d07bca435 refs/pull/4060/head\n004148807357148a56fc2fdfb16f3530523d059ea089 refs/pull/4061/head\n00418d7da0ec4b550c610ae4c115e78b3d17dd50d1f5 refs/pull/4062/head\n0041ff226b4004c344c58067080d12111f41029913a1 refs/pull/4063/head\n0041e4681e8db389abcb0265c91723d8168d8148d2b9 refs/pull/4064/head\n0041ea3b782265eff6b9b357746e8800b9f17eff7316 refs/pull/4065/head\n00414abf19bffd321b23cff78c7eeaa9419dff713b2a refs/pull/4066/head\n004122558f6432557ef43e8edf7a0f15c814d8904187 refs/pull/4067/head\n0041657bab31bdc9055499f2f3f54c825c8b4807e49e refs/pull/4068/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/4069/head\n00409343ab402ad2586f8624a7fb8faca6cedfd57cfe refs/pull/407/head\n004145071bebbf81d8a3cb26fe7ae02b54c8121b38d3 refs/pull/4070/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4071/head\n004131afcc8c2027641029ce9b9a10aec3e411a1d07a refs/pull/4072/head\n0041c9f892912fe474c9b6e1ce164733d28ca27c949d refs/pull/4073/head\n0041b6110fffb6a4af391983e93bac55341df64df316 refs/pull/4074/head\n0041c430737d083686a2c81f0e431934700d31e4234b refs/pull/4075/head\n00417e11344eb17c20905860d7e7a36b50dbf44b3a38 refs/pull/4076/head\n0041a26cb6c660645dacf97c6f3d86d0d64b52330000 refs/pull/4077/head\n0041b276fafa473ad8f55f21e804640f7360c8000779 refs/pull/4078/head\n0041f69f47ffb6762f491a3e5bb5972f852423b35b40 refs/pull/4079/head\n00416dbe606370f26f5e91f0047db06b33713fc02014 refs/pull/4080/head\n0041b89ae98f2c937abf50ceafcef261590e353bb663 refs/pull/4081/head\n004163bbe5a79e242be38ac859cd2056438120cb4527 refs/pull/4083/head\n0041af793bdf944b14c6ce8eb60a414704d22479e974 refs/pull/4084/head\n00416b58419828587f15723fa7cca921850d52e7a57e refs/pull/4085/head\n00415b04ec5dcc1d8d8929ff10eb9c2ccd52ca34f99f refs/pull/4086/head\n0041f3db124ccfc14a7740cb8da4ddc8e7bcfdb76753 refs/pull/4089/head\n00406d0f1c3a7895798088acf0a8a08495056298d244 refs/pull/409/head\n0041bd5b692aa4d6518a93270fa9d6c6ffbe02def777 refs/pull/4090/head\n0041bebeadc18df007891b479d5bdb4a2360dd56c20c refs/pull/4091/head\n004140a3ab6a6c643552b81b64da6a3b456fa1b863f4 refs/pull/4092/head\n00411b36e1330ceee9f68b01dfc05c086d1d39586b4a refs/pull/4093/head\n0041eaf9ec2e31b1764e7e1757595ec45d133a51da39 refs/pull/4094/head\n0041bca98ab20df40373301bdc71c2a15d3a1fc8b418 refs/pull/4095/head\n00415507e12b7e085f9df7db65c00e127e91d82abc19 refs/pull/4096/head\n00417ac7a9d84f5e8c16c3512a34ce2eb84f69774f92 refs/pull/4097/head\n0041bb5e56ed293875c45ff6f5bdab3c2313eee02993 refs/pull/4098/head\n0041605048cbbe560c6a33cad899ab6036fd2ca992d8 refs/pull/4099/head\n003f91651239dd6d4d47c8d4d8b78d6df7e9925fdddd refs/pull/41/head\n0041f16f78531c36953bfd52695cd2b05cb4e224b40b refs/pull/4105/head\n0041a71fc86bec92b9e2d2e228f31314de541f936515 refs/pull/4106/head\n0041035da14de4c9bf4671fc6bcc64e7a83190cf1e5d refs/pull/4107/head\n004197b2eb2eb5fd13ce0303f0085c3965b6b3deb396 refs/pull/4108/head\n00410a7b7007e3f21ab4f1f2d5dd1918812fe4a781b9 refs/pull/4109/head\n004148fb24ec1daeecf139b2acd043726b4e3220cbf4 refs/pull/4110/head\n0041ddda7653e9367fea63d66267c04af88b02246d3b refs/pull/4111/head\n00417651c526d952329a8df588614e8c3716736c9bdf refs/pull/4112/head\n004172b7574f41b311abeb9d9b74573c4073058fe0d4 refs/pull/4113/head\n0041ffb9e800e633fc1795c639f76fa3fa86a794ef96 refs/pull/4114/head\n004171a405b3cfba5a6bd608f3bfffdf42b4143bb19e refs/pull/4115/head\n004105c08929ec11360d8cfa425fb1770df12fec9f01 refs/pull/4116/head\n0041a93f546c5aad3efc874888ea30ebe16bbe049d2b refs/pull/4117/head\n004103f1af1874e46d561364092f4ceb5e574e494d76 refs/pull/4118/head\n0041b39045d8e24a3f08951b13d54c260cf2a8e3557f refs/pull/4119/head\n0041426a031bd0cd3672007a16928e83697af3d0e6a4 refs/pull/4120/head\n004131afcc8c2027641029ce9b9a10aec3e411a1d07a refs/pull/4121/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4122/head\n0041793bd043ad71303633efb42100f9faf9bb381d63 refs/pull/4123/head\n0041011b48415cc6bc3aa2fefb766f4796da06a13ec8 refs/pull/4124/head\n0041324662b82050b9ae34eb14a8a87094139d0fdc70 refs/pull/4125/head\n00410c9a0aefa2a741329dbbce3d1dff633ecc045865 refs/pull/4126/head\n0041735e4d1190995a13e8e8307ee4e8455877bcbd96 refs/pull/4127/head\n004187c62cb49f25d05e1544d30a30f6c9f3dfc4e96b refs/pull/4128/head\n004149702d487210729dfbfd7213b1b0422f50e0833a refs/pull/4129/head\n0041c336256869152b1467b19fa98cef5b7d1a1b0d41 refs/pull/4130/head\n0041ccf15c1f6bb206db078ae5e0fecfd006ea563349 refs/pull/4131/head\n0041946bdc651d108fa66e8c81e189232bfc5da85055 refs/pull/4132/head\n0041d97dfdf2f5a81cd1058eeccece2249de001ff672 refs/pull/4133/head\n0041fb53395f827a67fdd76beb97ff4d828c2f6e7c03 refs/pull/4134/head\n00415e491a5804c70c854f398823dcefcdd99d286b18 refs/pull/4135/head\n004139e867fb7ae579904b75478ba14a9af77b771c82 refs/pull/4137/head\n0041a46b95f653938b9636964a9dbe19e39acc183e68 refs/pull/4138/head\n0041fc819913d79ba86f0ea1f619f76ed386e530e987 refs/pull/4139/head\n00412d4e21f4332ba46b2927eee9777c6dd9f7df4118 refs/pull/4142/head\n00419233bff2b768d32d43a61dacd7bbd3492f36ec41 refs/pull/4149/head\n00404102a18a336fafe433d6b2857265e0f0d6b77863 refs/pull/415/head\n0041325767014e1d51f0395fee9112091bbdebfa9578 refs/pull/4150/head\n004199040bfa7220d5d5c4324ddd006426550d71b2d9 refs/pull/4151/head\n00415ae3a0763aa4803fd2242ec786f9c1aea5b3a2cb refs/pull/4152/head\n0041ca331ec7255b817a6c8dba737680cdc17b08edc5 refs/pull/4155/head\n00417975d92c3d81922fb0922751fbdde450f63797b5 refs/pull/4156/head\n00419934b5466c9e17025b837df952aa754ca3b35efb refs/pull/4158/head\n004081dd41292c226f014de149a0071296e116d61189 refs/pull/416/head\n00410b1ed8dcdbcab26ccb2d3d799c43111a67e42dc8 refs/pull/4160/head\n0041f7aade54eefde94dade8029f75851e0678f8c216 refs/pull/4162/head\n0041b18605319dd079c09aaf7f08af9afa9a0d8e5a08 refs/pull/4164/head\n0041b66d9c8c608bfa332053171798db6e8579c5dea2 refs/pull/4167/head\n00406c31da0bab542b41831b7a82a9e4d14761e820e3 refs/pull/417/head\n0041e28815e9c8db98fa3d48c76abc3f23ef1987703c refs/pull/4171/head\n0041afeee52a4b7500d0ee9c0435666b0c1a98b5e03b refs/pull/4172/head\n00414c6c428eac56da2fdb136b5975634bad534e9ba2 refs/pull/4173/head\n0041e4e045bcf0e48528728519046c49342e6b435af6 refs/pull/4174/head\n00419a50e87563202df2dc338fb270f64b592a0524b2 refs/pull/4175/head\n0041f9101a7b9e3c242bf7369a23cfce89b31e890355 refs/pull/4176/head\n0041468332b6a69722b25a4f911d5edd8972453a5ace refs/pull/4177/head\n0041341bdfd038f7c032be5af5c4a98979c49fef2766 refs/pull/4178/head\n0041d0eb7383efe8c5e872422871dd46cd81803598a8 refs/pull/4179/head\n0040bc1b44e4879261c92d2b3fffdc9ab647d7c8a1d9 refs/pull/418/head\n0041e05bb785d508083e16148d0d2f91f109b952c4ea refs/pull/4180/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4181/head\n0041e289b61c0c57472c45188641c0e05452e2ce395c refs/pull/4182/head\n0041450b6076279e484cdacfa0e239d0e1a4468043d8 refs/pull/4183/head\n004109dd25bb2d986ef1596ad0717c6b830af0067bfb refs/pull/4184/head\n0041f77c7f1221a2ef94d852489feb1f64da619cc855 refs/pull/4185/head\n0041069724802e1f8e4daf65269e34bc54ca4e2bad6a refs/pull/4186/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4187/head\n0041c42f88cdadf7a7690aba1a446e06164d3342abcb refs/pull/4188/head\n0041a2e56226bb6c168db9e9999afc1d43d63f673800 refs/pull/4189/head\n004087c749f7431781e754adb61bc61c699fe5d7640d refs/pull/419/head\n0041aa04cfcfb282ddd29fe37ae04298e628bb3d92fb refs/pull/4190/head\n004181a4b6f95775647f71b293af6bcf255067e9fc21 refs/pull/4192/head\n0041e29b44b5fbd605d6e212ddf1b0ceca9565d5529a refs/pull/4194/head\n00410267051aca65a519829ac18ccafb06146006815f refs/pull/4197/head\n00412f5a1bb0efc8756bee679ece015b2e8f009b0716 refs/pull/4199/head\n003f7645ff6b03ffec78255994ef914a8961c0bb48ab refs/pull/42/head\n00406afc717169d3d59e8bbc2c1fc4cf01bbbc09f96e refs/pull/420/head\n00411455c9c6eddd003e10ed7d04f3585f76f747ee26 refs/pull/4201/head\n0041b75e8c48f133abff7febd8d90b477a81e259091f refs/pull/4202/head\n0041f94d78ac37b431339780bd5a19d69dd421fdd99c refs/pull/4203/head\n0041df368dd0660b8b3d4332f951e3877f04a6e39a50 refs/pull/4204/head\n00410dcf9190fe52e458a188dbae195135f7c62cf20e refs/pull/4205/head\n004161e5b322c9fb3682dc8082296e6f8c23fd6b1c97 refs/pull/4206/head\n0041520136a091348dd122ae73b88ef6243a09c22066 refs/pull/4207/head\n004150f9495524108a18f2ca6687a39bf4955bac9e72 refs/pull/4208/head\n004191817407bc0be1d01dab3b79e9e32d72ec3a18e5 refs/pull/4209/head\n00414951b45f4236fa673b427eaf447edfb88b011a76 refs/pull/4210/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4211/head\n00414fa12187e525fe48fc5218f89b04c6677d9ac286 refs/pull/4212/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4213/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4214/head\n004125491e8309b509268d38573920ff441a173bac46 refs/pull/4215/head\n0041f57ffc7300426b6d925980f57e2f2d9673cefa27 refs/pull/4216/head\n00410dff43ddb59bdf036b2ba50f89e7eab8576d7712 refs/pull/4217/head\n0041bd6c7ae718c5c93b239504754c7b6ab81108f56d refs/pull/4218/head\n0041bc002dc9333220eeea243fb432b0b0c521c0d52f refs/pull/4219/head\n00404831bc8b92e9aecbcd0f128f7e45796bb5f89ebd refs/pull/422/head\n0041977e3d1fc39da8615f7ee45b029f871c4066d80f refs/pull/4220/head\n00415530bc9a9edbb13ec51deae96d747ff442c83662 refs/pull/4222/head\n00414207547e4e38e03830909dff6b84c9bfad04940a refs/pull/4223/head\n0041745b933ceca93d7589ee027300c8343fe51e971c refs/pull/4224/head\n004183438f22d3903985c1f0c155906ac2294599b848 refs/pull/4225/head\n0041d6b36deb349f88e5680954d24f714b4c7d1e8d6a refs/pull/4226/head\n0041ee89c8da1262f3c20730187a3c1a79ad91ee4f42 refs/pull/4227/head\n0041589c54bcaf5e6bbdbb2a25e8babb0dd2654d982a refs/pull/4228/head\n004197d8c9c0742269aa84e856793d7ca7f404ab1204 refs/pull/4229/head\n004038871758f59c771bee03cce88b2c9cc99b76793b refs/pull/423/head\n00418666d058e26bc82846f310a1338eb70404088055 refs/pull/4231/head\n004155dc40c8a7d656e104d32f7e8c205af56cd2a0bf refs/pull/4232/head\n0041c368132e3e9de3f111cc49253f94c59c6839560e refs/pull/4234/head\n0041b93f9d9428789c90b8c9d6203581180931183f3e refs/pull/4235/head\n0041bd108d3593f63e0662518db1ea55c84668802242 refs/pull/4239/head\n0040cae5daee7deff4cffda76dedaaf1a653e2af3790 refs/pull/424/head\n00413cdcf410a1c13450527574dff40e152c23aa0fe8 refs/pull/4241/head\n0041d227b5208f951c7b132aa84ed7aff5e408edc550 refs/pull/4242/head\n00410fd1f440fda25e704da3ddccf6c5d8ecf374a85b refs/pull/4245/head\n004187845700c3259b2f3cbdd32d94a29831bc9135d0 refs/pull/4246/head\n004193a0c66066319330e05f0a1d63953f171851c9f6 refs/pull/4247/head\n00413e9dc58f39883d11393e53897d5a62bee2e5ae74 refs/pull/4248/head\n00411f3c10be2db2dbb84d4c331cf10b1dfb2689cf87 refs/pull/4249/head\n004000ea2f01026b75a03df999dba8057a2c14ec0d0d refs/pull/425/head\n00411313dfe68758a4ee4690f5d6e8b27a92bb921648 refs/pull/4250/head\n00414dbb572879002a0d08851d874495dbe009dfe7a5 refs/pull/4251/head\n0041abfbcb60fdfd3087fa29fe2e78ad98912b97905c refs/pull/4252/head\n004174f09ca04f441096a500a228081bb0be818c9491 refs/pull/4253/head\n0041079f1a40fe0f4310e72e08a1751f748a8d694fb5 refs/pull/4254/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4255/head\n00414fa12187e525fe48fc5218f89b04c6677d9ac286 refs/pull/4256/head\n0041b5a24b4f6c4dc5a3e34afecdc31ff2ef2ca9e6a5 refs/pull/4257/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4258/head\n0041a1c6db19bb0c144d67e3bfbf3679f48b5a05fba8 refs/pull/4259/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4260/head\n00419b510e6bed5cb4466e7c112d084b7b00a6faed9b refs/pull/4261/head\n004148f0642dd3159f8f7b8705c6ff83e33aff815277 refs/pull/4262/head\n0041486b8efb7f93c5f228eae6851d8e15c1d94150d3 refs/pull/4263/head\n004157c9e29288e419de839577bdc343358a75f61af7 refs/pull/4265/head\n004149d7b32a34d587b76300e90b7845ee267deef517 refs/pull/4266/head\n00417c3345d97e02332db64fd9fe3b244d78986bff81 refs/pull/4267/head\n0041af4a3832ac8aaff7d11d5ed08cb1f648986e07c1 refs/pull/4268/head\n0041a45bb327f89ef31a8aad1dec35929ca2d35895dc refs/pull/4269/head\n0040adac66c1741833f79a1a960a6932760ab694b1dd refs/pull/427/head\n0041ca050aa79e6a9988df50e50a96fc5f964af847f3 refs/pull/4270/head\n0041730099826e1c762022eb75f5f147351720d5cfe0 refs/pull/4271/head\n00415ef02b59d4d4372226523cbf4c5a1c1419a88552 refs/pull/4272/head\n00415383421b9481772a94a212117943ed862ba40c48 refs/pull/4274/head\n00415bdb2c1256818c354cf15f8f516258c195d040d9 refs/pull/4275/head\n00412f739e7717d0abea9f1a7007135748a84b8570c4 refs/pull/4276/head\n00416ecde25885f6a97cf6bb8adc35193e28fe324bcc refs/pull/4278/head\n0040478d6e2a10cfc44072a3aedba6e921442e155f2f refs/pull/428/head\n00419bf4966688a3e46deb3be128726aa105c9a6c896 refs/pull/4280/head\n0041c53dece390e68991bbe5b80765b80676219f2226 refs/pull/4281/head\n0041a7cdcb54769f35a8dde5b24981acef979e4967d5 refs/pull/4282/head\n004148933b48c2a86c022193c944636f9e51e5c5ac13 refs/pull/4283/head\n0041882c6e214d2527a477b2f96cb3b938ffc83250a4 refs/pull/4284/head\n004199de7c8d3af77d5c29c698342947a44b6a4cee12 refs/pull/4285/head\n00414ab45af81980209deff56da769a250db96f24ec6 refs/pull/4286/head\n0041d32271d8b575539980b22d13f7b49c711205fd1f refs/pull/4287/head\n0041dc8f3942325416f8d04af6d77ed1d1faaf9b3102 refs/pull/4288/head\n004144dbfc666c77644955d9c54066eff274aa9ba463 refs/pull/4289/head\n0040702b192740ea948214cbdbeb82d38f79405697b6 refs/pull/429/head\n004164f261c6e4a2ffdb54c7b7b10e7d4e127cac13bc refs/pull/4290/head\n004152582e2431bee0922d2f932bcf871ee1930227d5 refs/pull/4291/head\n0041ba9ca122c226c4a953c506afab73df5dbaa7bcf7 refs/pull/4292/head\n0041d4f0a911405c270ca27d9e420ddd95cf04e68e97 refs/pull/4293/head\n00410e15ab6348c70ea4d825d0904484c5491c59bfc3 refs/pull/4294/head\n00413d1497f309c730f046d52a0fef4718c764cf0081 refs/pull/4295/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4296/head\n0041b5a24b4f6c4dc5a3e34afecdc31ff2ef2ca9e6a5 refs/pull/4297/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4298/head\n00418c3c0ea8ae4862b829c7122bdabd6f0fd767bb89 refs/pull/4299/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4300/head\n004173c97de91a7eb66cb20ef9b4183c4bd79f042204 refs/pull/4301/head\n0041791ecc4ed2cb35b7b90621754dfca7b681d5dce0 refs/pull/4302/head\n0041f06a7cae3d6fd8243d56e0f018c20f68890223b6 refs/pull/4303/head\n0041faebc0f6408cf78e414be49d93b7bbda69bec2d4 refs/pull/4304/head\n0041f7e2108944564aae08b0f9adae43db5784c9fed2 refs/pull/4305/head\n00418d826b50e698a369f9c3d6bfe36f7c52a209b707 refs/pull/4306/head\n0041e84a2c927d801b8e90ed594c36eee4c169ca9699 refs/pull/4307/head\n0041cba995b840bd791452622ee7fb8dcd0f261cdaa7 refs/pull/4308/head\n0041b86ca2acd3bbe1bc58b5432c1596bedb8d2e1053 refs/pull/4310/head\n004136cb73db1f0a1df44a5662c346a2176ef766e0ba refs/pull/4311/head\n00412891cb4165960c15dfb87ed24f6802db4e679f2f refs/pull/4312/head\n0041effb2783ad7d37e0cf924cb898c637ede68bd4d9 refs/pull/4314/head\n00412213efa9faf4a22b5bbd22dbcce998e7878089c8 refs/pull/4315/head\n0041fc6a35716d0c1e147bba0c763b241526ff8d7e21 refs/pull/4316/head\n00417795fe2118ae03eb745e4acf65e008ceed9faef1 refs/pull/4317/head\n004168cf84ff3b56b98b1bad07bc1e5216d1c4934e64 refs/pull/4320/head\n0042d81d55145c7926d949eaaba972446fd3db59a732 refs/pull/4320/merge\n00417357fbfc817239c300ee3cfefb9d901a6070a916 refs/pull/4321/head\n004177005b107f9201705fb316f7cd0451db6d1c7b13 refs/pull/4322/head\n0041778a8cfa7e02320454f0ddd160d59e5862ac6ea0 refs/pull/4323/head\n0041e5d598889d902ae29a65077e6af5d0146d5ec8e3 refs/pull/4324/head\n00412bd288abac908bb2020c9d21d0e92e370826a25e refs/pull/4325/head\n0041846da5544a85673d81e39a164d0673e8ea99d9a4 refs/pull/4326/head\n004117d729fece0a7b1995ceaae94b4c404dac0c7ce7 refs/pull/4327/head\n00413e62eb95d5570cc4316b0789545494efcadfed7c refs/pull/4328/head\n00413de84d56b6a4a4a096111197bf14822f09fa1b41 refs/pull/4329/head\n00401652c745526d09ec28dd1bfc8062ddc82a04efa7 refs/pull/433/head\n00416aa4f1020b5932f21a737787170b6970ac95865e refs/pull/4330/head\n0041056910dc0c3d996d5dc6fada971656babab4b0d8 refs/pull/4331/head\n004162813f81d9235c4c985a9209e47724168b3f08d2 refs/pull/4332/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4333/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4334/head\n004133f7df4a458779537e841eaeb160b8c36b78ce9b refs/pull/4335/head\n0041f7fed3c07f4b162100c5f3babed9cac14b2a6d0d refs/pull/4336/head\n0041894a48d4007351a085f3573609182976e61559ee refs/pull/4337/head\n00413f4d9e880845265f5458ea33983f24614163105f refs/pull/4338/head\n0041ca687f211ba4cfcde6e6860edc47adbaf3d62dcd refs/pull/4339/head\n004037102ca6da3d94dcbe61fd6f00bbcef7843e60fd refs/pull/434/head\n004158951688bd7b39738e90ea52e27938fc0e71e272 refs/pull/4340/head\n0041b7a013236007fd71a8ef6db7676e61ae92f0e9d4 refs/pull/4341/head\n0041dfbd3be19b707b45b867e1d495c78cfeab0a79ea refs/pull/4344/head\n00415d82849b116aafcfe3b840a3b2cb3a96c72b0c1c refs/pull/4346/head\n0041c95c4dc7c8d77cc218f03f2e512ad131c34454ee refs/pull/4347/head\n0041c025159a0f882c9fdcf352d0d8937c8514e6cf1e refs/pull/4348/head\n0041c8c48c90d5a25cd69dc4f95d19b3ce8c31f55e58 refs/pull/4349/head\n004033bad2b5d92dbfab547fb81ae3bb5e62baa91be8 refs/pull/435/head\n00415a52a7a8297c848d6258d4691e920384524b2ac5 refs/pull/4350/head\n00410dd19ef125a7d7e9edf0a3ce1b83167ee19bc160 refs/pull/4352/head\n0041960851a01e6e85169fc45a599edc706248a6dfc9 refs/pull/4353/head\n00414f9a50b2c1db3828ea92b9062e21e6e928c1aa26 refs/pull/4354/head\n00426e5bfd0c7aacce22347eb83ef297f5c2e3e60149 refs/pull/4354/merge\n0041ab15e312c6e77e5f9663e045b99c855fa4fef9fa refs/pull/4356/head\n0041240d7748022cc5eddc71b055a4de56607f808aa3 refs/pull/4357/head\n004102f239424950db284db5cdaf98cb6c8a01c9ee14 refs/pull/4358/head\n00405cf48a27f88c23526734f137d94195452d923dc2 refs/pull/436/head\n004147a2e9a56a526d1bca7f21a8238125f4eb6d74b5 refs/pull/4360/head\n0041279c4cef7315db382b2de092359578eec04e27c9 refs/pull/4361/head\n0041ba68a768ca2617b68e4501c45bf53add1a56663d refs/pull/4362/head\n0041e8b529654e25575191b947df1da8d91c099c9fb4 refs/pull/4363/head\n0041e4b09b21a6dc647717e2ace56567225e7619653e refs/pull/4364/head\n0041a220812d62e2e42091ec715b57de15185708ba39 refs/pull/4365/head\n004119f1f5bdfd91c1e0f3a3232c7e9fe6cd43be287a refs/pull/4366/head\n0041bff16a47bc1b3905d8b6cbe5ccc7502bde96ee9f refs/pull/4367/head\n0041a14da923ddda5f2c54323fe126097752e1868ae5 refs/pull/4368/head\n0041c186ea5845c74108685e91bba36613c23212684d refs/pull/4369/head\n00403dea0ce596c3809f433d67bb2160a8a8af9e590f refs/pull/437/head\n0041cc2a50ecf69d4802ac52e686b2958e1dfa0a43fe refs/pull/4370/head\n0041123280cb29051b1aff60c6ae37382e8be59ff2dd refs/pull/4371/head\n00417e2a169c274432adc128d93b0b4da7e13a927062 refs/pull/4372/head\n00419322086f4d84da04f578dcbc1c7d60905378bed2 refs/pull/4373/head\n00417d4984faa3fd34d684eb715ef1ef7ecbde94d893 refs/pull/4374/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4375/head\n004140fec103a79693157045eeca1afa45d9b809ce19 refs/pull/4376/head\n00413ab4bd42754e8625516753569a34e5a5b5b2e66b refs/pull/4377/head\n0041d38aa9d9a84691c9a226b38209fc60c3e511c125 refs/pull/4378/head\n0041f6b206dcb529a0be6317a0c6fac208ab1306da98 refs/pull/4379/head\n0040e7b69136fd234a5ebaf9e047eb4365c59ad7461b refs/pull/438/head\n00412e797b98f10f8d4345a8426a37f02724aa3cf9bc refs/pull/4380/head\n00410da6ba3394cfc30e529c25a09f532c7f59d626f8 refs/pull/4381/head\n0041afc420868ef02796f3b2cdf83c1828b9bf53bec6 refs/pull/4382/head\n0041c265e78f41cda5ea210ac0eb48c37d39a5fc3c5e refs/pull/4385/head\n004138cfe7d7650bb417615c5a88de6a56025f070f1b refs/pull/4388/head\n00411765c654486625ac03a728e9e4dd6885a8102ec9 refs/pull/4389/head\n00406531bc4aec902c7245c0b5e6ed08f50fff8de7e0 refs/pull/439/head\n00411133aeb7e723a6aa3ff1b73fa122f562180c6571 refs/pull/4390/head\n004131b702eedd001d3347dc45088e2b118dac3ee5a0 refs/pull/4391/head\n00418b71105e0c36521dae1ad1771df23a90578fe429 refs/pull/4392/head\n00419320ea079550140e74a649d7579909a9b789d19b refs/pull/4393/head\n0041687cecacd9d1f8f608cfbb577b218a59ecb5831b refs/pull/4394/head\n00410118be6593c06e3da81ca22422d48af8b0f8eb5e refs/pull/4395/head\n0041800a52c3964dd335f633f967a2edd253eaae3939 refs/pull/4397/head\n004166b067187c1513f320356b11049d9e3a3ec05ee3 refs/pull/4398/head\n00415c8eaecdeb2dc750cb13759c350d691eba24d035 refs/pull/4399/head\n0041adfb43db240c21a6ddc668e9aef984e94ed161b6 refs/pull/4400/head\n0041929776696972e0e85a4988c2ddddbb0e451ea93a refs/pull/4401/head\n00419e55ac3643f1c67182031fc8a2183fb9ee666600 refs/pull/4402/head\n00416bfa8c455a067f05586e2cd553969339833dba6f refs/pull/4403/head\n00413e1abd1bd236754e6c517bea0f676608f3896979 refs/pull/4404/head\n00419322086f4d84da04f578dcbc1c7d60905378bed2 refs/pull/4405/head\n0041866307738b1ee6a88c33b5e727b72ac3392fba2f refs/pull/4406/head\n004162e1a4b07048aa502628e6831ceed9d69ca4239a refs/pull/4407/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4408/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4409/head\n0040564ede75518c9e18b7de4b718827ccc62d32c2cd refs/pull/441/head\n00411f33c2e270fdebb0daf3f707ecb01907d1d7c268 refs/pull/4410/head\n004290210ca4843705d5f500b0e3583f9ba51b7d090b refs/pull/4410/merge\n00415c4587da625a6adafdf696306c472f43c110ffa7 refs/pull/4411/head\n00416f2cac7ed9aefb82ca5f52d1fbf85718be6ba6e6 refs/pull/4412/head\n00411627bc9b8c18d9423d83f0e3bc4d38944a606805 refs/pull/4413/head\n0041e9f0083db1333300db481783452b8975c6ccce20 refs/pull/4414/head\n0041ac3b48ad45d410f8e91fc0c38b1c039ce145426f refs/pull/4416/head\n0041e1326803ba3257f8e344df1cc213f97018503da1 refs/pull/4417/head\n004171eff47d6a0544d680f5240f1714776c01591c0b refs/pull/4418/head\n00418f3043b5f925b90921303654c6fb60c9d699bbae refs/pull/4419/head\n0040214f1a3a0b831dae6140f1322d935ec18d1e69f3 refs/pull/442/head\n0041bd7995bf6af50db653a7c8221e048bb68f6212fa refs/pull/4420/head\n00415d6798520974b937d5e37714cf674ef5776c6c7e refs/pull/4422/head\n00413108dd5c9c530b29efa786e5a0b64e4989f4f06e refs/pull/4424/head\n0041e9e99d4e0314c7ffaf1f7b99305860bc0d0a7a26 refs/pull/4425/head\n004111bd0c2d250794571e262a8bb7df893ebcfab689 refs/pull/4426/head\n0041c825bc58eddaaa497e63630580d0bc8aecd3d6ed refs/pull/4428/head\n0041cb6b7657c8f65a3c9f437b0eecf6f7e49bd38661 refs/pull/4429/head\n004031214408ca2213dbecc787791d6481eb8f98318d refs/pull/443/head\n0041393b8fbb5c0db752904efe5846b5a19bfe7476a2 refs/pull/4430/head\n0041edb4dc5344139e67215cff2a1c73abdf4e3aa422 refs/pull/4431/head\n00416d29f505e508ab7b7c26fcc92a4bde8193b4bd5c refs/pull/4432/head\n00410026261877dc51f2a42f7180d7b92eb9786accc3 refs/pull/4434/head\n0041a47cc67387d54314db3c2ce06a4ba2a194ae8fcf refs/pull/4435/head\n0041ba3a41b3b80a7f74732ed7d89e6f63ff9a473a2b refs/pull/4436/head\n00417cbd90ef8ecb3dcc43d79be3aa1fa7455ca1cc37 refs/pull/4437/head\n0041e2ee8e3a38d6636614ea927a716b266b90e9189b refs/pull/4438/head\n0041878371c190328ab5f7b7e393461dc4db01f64bec refs/pull/4439/head\n004055e6503606850b8b972554070ac6e6f652744d13 refs/pull/444/head\n00418d1b1e8cb56058ab318a4b3e01ca5b6cc6ef31b8 refs/pull/4440/head\n004118adc77abd42a2a97692dd03ce8a9f24c267024e refs/pull/4441/head\n004151a52d4d44fd3bd3465f4b5931cb5527f34900dc refs/pull/4442/head\n00417357e10e43c97db7999563c361860b0b45cc078c refs/pull/4443/head\n0041223dd8d3ff8e564b20a325d94d99101abab27461 refs/pull/4444/head\n0041866307738b1ee6a88c33b5e727b72ac3392fba2f refs/pull/4445/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4446/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4447/head\n00410250ff18eb930132e38851cc119c066a780f0051 refs/pull/4448/head\n00415127b14a1cc0bf6d1b0ee1788b23253c0d6da3ce refs/pull/4449/head\n0040714567aa8531ac2d5be17d02dc07382c13d314b8 refs/pull/445/head\n0041dc77dbd56c975f38e568ad1f4697c9066130af4f refs/pull/4450/head\n004142510ba93c26ba597694771b2ea1e343ac9665c5 refs/pull/4451/head\n0041597ae4fd7e4bb565e1772d36b8faea33787dcf67 refs/pull/4452/head\n0041cce86f319241ae1b6e863878a78452e2085e0b60 refs/pull/4453/head\n00412e602ad31073d394f5d29df839dd1195c96be8d4 refs/pull/4455/head\n00415a347bfde8e51694fd2ebb33dd4c354d3771ff2c refs/pull/4456/head\n0041ddfb5d83db8185fd2b0d966ddbaa1065167a5aa0 refs/pull/4457/head\n0041b18d19ecff7fc692543bdf0980042a96403a2b4b refs/pull/4458/head\n0041c33c7fccdf65fa4f6999e315f1b503ba53355966 refs/pull/4459/head\n0041f44075bcff294fb816020601a2909b61c7d17bc1 refs/pull/4460/head\n00415b2e18e273f17dc312f569e4bc3bfe914d818ced refs/pull/4461/head\n00415d7647bb1f8ee435b0cd6c241d92452264ad2aa8 refs/pull/4462/head\n0041add6ff4405a5207bcf9458e9f585f3b6a048bf48 refs/pull/4463/head\n0041ff700e139856650fcb9788bb35979d8e7dd42bfa refs/pull/4464/head\n00418d96dbf56723b1bf995cc64c87e9b928172b1c61 refs/pull/4465/head\n0041734609f2e7aaf863c76cf377dcb9210f10be753e refs/pull/4467/head\n00413d668186d21fa0b011d3afaed43c9a0d8188cca5 refs/pull/4468/head\n0041e0cc281310cd3db615ba985889d579d89f12510f refs/pull/4469/head\n0040b9b465c2b3eef979ace3aaf02a7a513e965432a0 refs/pull/447/head\n0041b33f0eca90dd8a9571fa53eb957671885158ba3a refs/pull/4470/head\n00423c62a1a1b8b7367d8c4ff1320105cc02b9ca47c3 refs/pull/4470/merge\n0041619f6c35dcb9357136f547673e39d3a67737e1aa refs/pull/4471/head\n0041147fdfa5f76227c4b253f40f456f191226a6a106 refs/pull/4472/head\n0041867b32ec676d9223452b503ad6437c7be322973f refs/pull/4473/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4474/head\n0041998bf812eb7fb00b02df12e38b1652f893dc634e refs/pull/4475/head\n0041b1d96537b6fe479f0fc974a5d2d46508cbd82d17 refs/pull/4476/head\n004110f37fb948ec36817c3a51a9d5115c45c4812471 refs/pull/4477/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4478/head\n004107b0469490a46e03086955f5b26c8d06a9306800 refs/pull/4480/head\n0041e56fa1bc01c94ffdc8d930f6a4d5f887336cb27a refs/pull/4481/head\n0041cd8b630989c0e20134f07784bfd406e8628f78b1 refs/pull/4482/head\n00418fbe327684b1ffa47c632a59d1cef3fefe4ccd18 refs/pull/4483/head\n00410fce52b2766840f5899ad13d62050013cb948967 refs/pull/4487/head\n0040aa975625ea6c2a4c817af8f69ffd733db4782b48 refs/pull/449/head\n0041e415e72e208d1321739670fe5e9e451c98effbae refs/pull/4491/head\n0041233ebaa10e3d7d23410eb76529b4c2bcb5a7675e refs/pull/4492/head\n00411c5f07cf0df3c3c21abbdd7fc20f373bd814b4be refs/pull/4493/head\n00416ca09316b635624c23590c6d0ff4ab058527151a refs/pull/4494/head\n0041fa4d1b2a0cdee7f99143b08367875d84709692a0 refs/pull/4495/head\n004116a98018d279eac22141ae1ac3949984f4d130ee refs/pull/4496/head\n004161646e86304cdccd9c36fa7ddb179a053a03bf46 refs/pull/4497/head\n0041b212a183ebd36aadc440911b27b8c5d4e11c7f2c refs/pull/4498/head\n0041fc79b5bee6c8f3f4ebb4e23238109fc9276c2dc3 refs/pull/4499/head\n003f128c809bb6fca55127f0d89f87ab0b108fc9b036 refs/pull/45/head\n004021a5af031b8b38c19ddf2fba0b2f2623a0a44902 refs/pull/450/head\n00419a9acfdc9c14a7f5d295eb90b499bf3161f4103d refs/pull/4500/head\n004110ceb6eecada40625780fbf4d0a131ea6355c3cf refs/pull/4501/head\n0041ff6e72e3f0756f2659a002d5e68a90c3b25b34e9 refs/pull/4502/head\n0041b923b5fcd85f2ffd35465a09d19a2e7ef529753f refs/pull/4503/head\n0041899933548672c5430ca15e7dd62c03bc3413ab64 refs/pull/4504/head\n0041cc0f43abeb5999b58248d5444fb0e09418c3a5fe refs/pull/4506/head\n004151afee5f450020764cc181505210d67009242209 refs/pull/4507/head\n0041b24f9c09efde732299593330c8f313b488163064 refs/pull/4508/head\n00417bc8e4743f43034fd97f5bcb04d4808862a0e9be refs/pull/4510/head\n00419d533f916ca0418e4c56eb6d9d1680a831055d6b refs/pull/4511/head\n0041b23b1365e538126b41b429cd7ed8b8013f8b8497 refs/pull/4512/head\n00416296cbed9311b0f6fcb0cec1b530276c40ea9e40 refs/pull/4514/head\n00417acab9dfa400380d509c50fe7ab39aeaa43c13ce refs/pull/4516/head\n0041c6c07de7a470ec7bb2b1a417691e15ad59468b65 refs/pull/4517/head\n0041d7145a70bd77e8e4c69c7df953c0fa0e41d59584 refs/pull/4518/head\n00411c72ff700f8157b4c72fd2d3ceeff4eb6d9ed7dc refs/pull/4519/head\n004100194efa32b0350b4d31b058541e6fe25d92df9a refs/pull/4520/head\n0041d6783f79627838f22e1024e36de509c0f724893a refs/pull/4521/head\n004149a32d99f2e4f1b5550347b7aa0a592356e331ff refs/pull/4522/head\n004197801e05a0a75dd338ea4bb6ae7711446817d6a2 refs/pull/4523/head\n004182c5c5b2dd7467f6b9f6d1df2bb2625ef0b6305b refs/pull/4524/head\n0041d15f3ff9fa9f2b24b33619aaff76eb4f4815a461 refs/pull/4525/head\n0041cd24dfe9717762a3f9590a1d2093accae8d0ecf7 refs/pull/4526/head\n0041b6beef217706fb5f1a339df1aee052e7d00772d1 refs/pull/4527/head\n00412b1a9712618defdf186eab9cd2ea9f96a9e8b00a refs/pull/4528/head\n0041a69afd2ff7d7ed8607a5339e2643bcaefa8b2739 refs/pull/4529/head\n0041ccef4083747c9fcbe128bcd5045e64eb790f5323 refs/pull/4530/head\n0041b7fd051a40f38d76c44a4ace3f93913404ae1e33 refs/pull/4531/head\n0041266004cca3544184a10159381e3cdd75071fc0ea refs/pull/4532/head\n0041d0a9cf0deb9ca1ad06214a29ca6d71354b17f0b6 refs/pull/4533/head\n0041a4aec3c249bbdebe1e5e87c2e8ac64e14b67d2ec refs/pull/4534/head\n00412de6485cd0de281812822091cf7fc7055830fa25 refs/pull/4535/head\n00414b83ee3013338799406862d1d25cbd42825ffef4 refs/pull/4536/head\n0041f166ec43c5d8f611093b4116f96469993f3b3a88 refs/pull/4537/head\n004178757dc74535f4f8289f74edb76dc8fbadd2194c refs/pull/4538/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4539/head\n004057438b74e79a243fc8337039df968a56a47e1e04 refs/pull/454/head\n00411d7fca817eda07c83fb84c950d8325c2f9003158 refs/pull/4540/head\n004288f76b9b99d52db4578994b0f53a606cc7069036 refs/pull/4540/merge\n004145e8f08f97a0f5516ea1d96cd87b7e6253797ce7 refs/pull/4541/head\n00414cb3f8db869a061fb2d8bd10b21851945db27d88 refs/pull/4542/head\n004173d757a4307d837058006943fc8e23f9b300018b refs/pull/4543/head\n00410ae816cc6eb6ddcee5ee9dce6a763599232c85d5 refs/pull/4544/head\n00419f6977f06e96a9f93168ff34c5e0322ba65be3be refs/pull/4545/head\n00414c1da4f045d8a7349a95b62f7da800485f2067ca refs/pull/4546/head\n00423bd03f218c4b85f52d71b62e950d34b468227b35 refs/pull/4546/merge\n0041e07be325c0c0cd8ea0a1e489212428ef8fcbcab3 refs/pull/4547/head\n00428b87511fb05e3258cec90c8ba9730bf66ba23a50 refs/pull/4547/merge\n00410a4eb2562c76879c214839ced806c1b2c1cee89a refs/pull/4548/head\n004119651c0b0a987f650de2aa0c3b23dd238887d222 refs/pull/4549/head\n0040a0e52ee79ef2775920ac85443863e30b1c1173a8 refs/pull/455/head\n0041e1567979f5d8f403d00259b33fc94d7d5d8cfd33 refs/pull/4550/head\n0042ad3bb7df33ce8dd505a341fdb4e009b751986ace refs/pull/4550/merge\n0041b09db91200154e521db1ae9acbcee93a905de457 refs/pull/4551/head\n004235b3f1b514068c1263d8ab1e1e069b77aa75be70 refs/pull/4551/merge\n0041da252021206c06495d714fbca2d7f9eb49e0bede refs/pull/4552/head\n0041b635659866d8fa64c17761d392157de69c299868 refs/pull/4553/head\n0041034c72c9d67ce5836d86937c6193e23e48dc84bb refs/pull/4556/head\n00416a1ba7ffcfa992b6beb258e89e1352c25b2ab6ec refs/pull/4557/head\n00416a293360508ad940fc7fd8dcfbe40516fcc7ce86 refs/pull/4558/head\n004143ba2e3a35a81a8983b7e256c114296f66036628 refs/pull/4559/head\n0042aa2d6a4ad9f7c852e4fd6c22b90731d3cd75ecbc refs/pull/4559/merge\n00405cb5971d55f57b60684d9751fd452bc631916934 refs/pull/456/head\n00411d993a71d58308e5fc6abd5cbcab5558a79d5f1a refs/pull/4560/head\n004113822f7c31b4c4bd18644e23cc0e10febe8193a5 refs/pull/4561/head\n0041aff57c6e4007d6a60e38e3351d765f03b4d35319 refs/pull/4563/head\n0041125abaeebe0a26d5b59db33963725fcfe4dbc291 refs/pull/4564/head\n00413d816c95b3b39a06a387d10209110b8a424125cf refs/pull/4565/head\n0041e5a2d577057ff50f55653eea69a2ae15dbe4872a refs/pull/4566/head\n0040ef8e6f6023dafafc83ccf7252ae15b056210fa65 refs/pull/457/head\n0041ad6b9c3a50675440e93f954406cd2b4db23413b1 refs/pull/4570/head\n00414ef79b0722ab2c04a187b070751746cc8e80b8dc refs/pull/4571/head\n004183dfa578aac70f07a2d7babf99ac05af72470377 refs/pull/4572/head\n004207feaaf039606653aae554618b0a5f1105df525b refs/pull/4572/merge\n0041ca02e192bd9f65d1f3e6b7f4ace40b151cbedd68 refs/pull/4573/head\n004101d2c2b5739af27612ddd00da094e38281b8a9f1 refs/pull/4574/head\n00416657519f3601febcb6343f6f5e3b2fe5d12dc686 refs/pull/4575/head\n00417b1a5c6ca2f8fe930d9eebbeb005e4b53f1cd090 refs/pull/4576/head\n00416040b6747a3e8a7be3193ed779a79f86d9a925c3 refs/pull/4577/head\n0041db669a90ff173429ef00945ffe9dbb9dc1893468 refs/pull/4578/head\n0041fd3d44277c859e7a6ff55572e2877cebe30f1e65 refs/pull/4579/head\n004081764eebc88f482aefba3bae569432a017c7e28c refs/pull/458/head\n00411cf348b2f825eb841cddb8008bf8b479dc5cca50 refs/pull/4580/head\n00416fe139c1e777fcc0b6d0ed3558206a110b5a50e5 refs/pull/4582/head\n0041918099ada2b9d6a14bfb7a6ad492ccd711b800c5 refs/pull/4583/head\n00417ed9aeda5b33f63b880a45fdc5446e5db9549532 refs/pull/4584/head\n004292b16ab7bb17eda0db8475b60fcdedf23d027f3f refs/pull/4584/merge\n004198349f433a09eb4d1b4b356465b9caf3d733c748 refs/pull/4585/head\n0041d62db24488b4b95e44bd232f6b72be3057543cec refs/pull/4586/head\n00410356afecd14dc8c226799107af5f4b36bc08d80e refs/pull/4587/head\n00414e07233f02c18866ba6dce17d99bd5c78b6e4026 refs/pull/4588/head\n0041d2ca8cc64c71dbf05d74224a7a7de449dd697886 refs/pull/4589/head\n00407a801651c73cfd940929030a727de719728ce93d refs/pull/459/head\n0041bdd996ebd52c17aeb08ce5f277a909a72c7d8c30 refs/pull/4590/head\n0041e4327d276694280efa6b74b48cab92be702d7123 refs/pull/4591/head\n0041586b5cf9466d18d7dea895d78753b05b311fec08 refs/pull/4592/head\n0041a48e28d0d3d289262281e402f50edcf652432937 refs/pull/4593/head\n0041924112d93b83dfbdf271e281d4700b2917d929ae refs/pull/4594/head\n0041bcd71108976f129dac0c33b1669c72241f854e22 refs/pull/4595/head\n0041fd9029a6a53e0c53641553111c727cb963b713d3 refs/pull/4596/head\n004153da93dad22db51884a8d846c438b749bf1d26b1 refs/pull/4597/head\n004136b75f633a7b35a3db5135d32b99a256adfad962 refs/pull/4598/head\n00414dc4e04a6909135d3680033601c826e0c62f3593 refs/pull/4599/head\n003f17f025d395375c10d8caf9405f854c3ac2a71029 refs/pull/46/head\n00408e8824a4cea0bbd102d2ecd74bd370b7ee1ea6e5 refs/pull/460/head\n0041bf7bf6157f802f4f7a97749e554cb518058f9a1b refs/pull/4600/head\n00414b83ee3013338799406862d1d25cbd42825ffef4 refs/pull/4601/head\n0041e44f5c1f6651c2351e30344e82d787a8b838df50 refs/pull/4602/head\n0041735064d0700f68cfd763aa2d0ecfcd4ee924e0e0 refs/pull/4603/head\n00410b3e6f42f7e508a65ecb8ec83ff34d26d2794757 refs/pull/4604/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4605/head\n0041d3f49e2ea0b7fccbc9b84c4b41597fd0f3cf32b8 refs/pull/4606/head\n00416767c8ded275dabe2a757cbd7f9319bb9c308f38 refs/pull/4607/head\n0041c3867bf3fd4cba1d08fd14212b6bef0aa63b0660 refs/pull/4608/head\n0041b1b96ba889d85419d557b33e4b3d07a0481a12d0 refs/pull/4609/head\n00402ad8115ec45b86b82cc7cb16479c86d27fc2e3ac refs/pull/461/head\n00410c3b865c16b0a520239924e8e87a95a284e609bd refs/pull/4612/head\n0041f7bfff121303771954c5c9306f4aa847ea184c75 refs/pull/4613/head\n00415b1951316dea5640351ecbbac2cc898564b25202 refs/pull/4614/head\n0041b41d9f8b138d6d57360af78b44d4839e22f38389 refs/pull/4615/head\n0041d0b3a3ddfb64e57b68df40a235ed94509fe8bc46 refs/pull/4616/head\n0041b289320df984eb44e60ebe77ab23070c79ccac32 refs/pull/4617/head\n0041f41a6c96d9b6e071f0cbb6abb50edecd9e03c53c refs/pull/4618/head\n00415a24bdd436ec85faf286ec06875c149e7963246f refs/pull/4619/head\n0040645c7a8624ac1a4f14b458244f75cbd7c4e8042b refs/pull/462/head\n004142531a4b2753f0c21ec9a1b10ef14b157f508a8c refs/pull/4620/head\n0041eae6eda0a590e0ad731462df728bffe5f02035f8 refs/pull/4621/head\n00411d20e0ca1ff1f7775460e67265ef376cd76e7220 refs/pull/4622/head\n0041e89a75b4106589b7f93f87a934d29dcb75c82910 refs/pull/4624/head\n0041d613ce4f1e239f942b8ad135fec5fdb661b28098 refs/pull/4625/head\n0041339f073724613569b5b0a8b69550f5e6f86d4376 refs/pull/4626/head\n0041f17bd6be456e70c1db78eda5965d7c5e869245dd refs/pull/4627/head\n00413e6094791e7f7e2db36a1a2b551da0c1f684d0d3 refs/pull/4628/head\n0041e5e2bfd7d29dc6ee14f50f7fb3cbf8e9fcafb3f6 refs/pull/4629/head\n004043edd2608e6e8be14b6c71b0805e14736f5c0db2 refs/pull/463/head\n00413d193d7877e90df0999787449e5021833e3420e3 refs/pull/4631/head\n0041149c4d4a4352dff2db6acd5247594be51f136a09 refs/pull/4632/head\n0041070a0d2c98c87fd0f3157b64a609f99ba86fa7d4 refs/pull/4633/head\n00411e06341f28d933e446744af72045dbcce01864d5 refs/pull/4634/head\n004153ad7d099b4dec582d4b7bba00cada5660a97270 refs/pull/4635/head\n004157f187ef2130f5b09266e1d581ec880e8bd05466 refs/pull/4636/head\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4637/head\n00419ad501bea8c78e1946dcfef5b362068502dca2c7 refs/pull/4638/head\n0041f1dfd356314caa5d480fa7d27f00c2e3e3767af6 refs/pull/4639/head\n0040a8e02bc9f84fe22f8d5ef368f4bc52a3d51ccecf refs/pull/464/head\n0041ac83a8d0ef16e56b5a2754fcdd31810d1c2f33cf refs/pull/4640/head\n00416015c0ace1b4434337cdbec58555ed4f8c313f73 refs/pull/4641/head\n00411bd7f283688873c2848ca0dfff64d390293269d5 refs/pull/4642/head\n0041b207a94f1772445cfdedbe9a2207ca5335d8db9f refs/pull/4643/head\n00410a1bf6fb84d3ec374fdd66cf2b9726ad80674b06 refs/pull/4645/head\n00414596cbce1bef5f456dd0e26c5b863ae05d00244a refs/pull/4646/head\n0042e9d1fd4a0736292538f936fee2b2b0fa5bea9dca refs/pull/4646/merge\n004152e42b25386c17e03a4e54f929ab753702482966 refs/pull/4647/head\n0042b021cfb7fb16c3618559692ca5dcc2c0082fd94e refs/pull/4647/merge\n0041f3ba778cf6b27bc2944ec5cdafb67a71789d8ad1 refs/pull/4648/head\n00420373e282786505981e8275ae47f4273e6ad7d7f1 refs/pull/4648/merge\n00419da4f74bfb9f43eb713c4cf01b5d3aa70951ee0d refs/pull/4649/head\n0041f07e60b6e8dfbb2b5659b2e02b2c3f678525b394 refs/pull/4650/head\n0041c70033305a3a2879c786521d8f28a3e791ccd2df refs/pull/4651/head\n0042a54abd0abeb402ad871e0c1a1e1a2b628054d1be refs/pull/4651/merge\n0041b5f5b05b4ccbc9125b751c028cc2ca34f251d111 refs/pull/4652/head\n0041f922262ed029bb03359337f676872e77f3817f28 refs/pull/4653/head\n004124ad88a5b05e61c98c04b63e658edc2a9036b9c4 refs/pull/4654/head\n0041857fa943448ac2f300013f6848da1318cf7615c1 refs/pull/4655/head\n00413ed92e000db5f62353d62e735ed3bd99e45c7ede refs/pull/4656/head\n0041dbd849d2d69d52938439c8a4cc21a0c1075f110a refs/pull/4657/head\n0041ee75191c8e58633f70cbb0330914e1426e9989cc refs/pull/4658/head\n0041466874c00046a019399fec843123226063c68c2b refs/pull/4659/head\n0041652cfe101926b48c0348a493db6c60bed37ae204 refs/pull/4660/head\n0041cc28afd832b3d267568dc218f708c0247690ad69 refs/pull/4662/head\n0042ad218eadf50546950ee11a0ad9dbd4239b167d85 refs/pull/4662/merge\n0041ca5c578189e2769aaaa150c9e985f99d9c4c1018 refs/pull/4663/head\n0041a454452752d015434d23f8751175ed3f853958bd refs/pull/4664/head\n004187769ab8edca7b8f7dc66e8afe5d7943a9e38221 refs/pull/4665/head\n00411d732f3fe14108a734008d43d5244c7df243152c refs/pull/4666/head\n004144b3283a3180d2eba0a7da45cab1f15cf43a0b8a refs/pull/4667/head\n00412d3e719533830318162dfc73e232ecf4b8ef80b0 refs/pull/4668/head\n0041a4fc5b66f3b23412b1b7d23dec17c1600c12c3f4 refs/pull/4669/head\n0042dea1ab31ae5bfa554f9ef5545e3e652dd564c962 refs/pull/4669/merge\n00411dcfe152bb9e5f0f109dabd0ba53227994cb0aa4 refs/pull/4670/head\n0042e5d2ddd9756f32ca22fc37e22f2cca52af672d32 refs/pull/4670/merge\n00415e0ed433516a5eff6a33b754f2caef2b4892e410 refs/pull/4671/head\n00423a16c35f98d705649baa17fb703a5e7f4281d5a1 refs/pull/4671/merge\n0041b05ccffa307faa4a2c9c0067e095a64b237561d3 refs/pull/4672/head\n00425cb5b2cfcc9afcc99d28f764cf1cb0573316c0fe refs/pull/4672/merge\n00415a5ff38051a5ca526249a10cda25f0932a8e5bb5 refs/pull/4673/head\n00412470830a0585b755e44a76996e8df6234932659f refs/pull/4674/head\n0042718ba688b6aedd99527bb03fab6d7b7f73b96ea6 refs/pull/4674/merge\n0041c299c85a5d73c9ddb4a631376173f21bf52a6603 refs/pull/4675/head\n00423810d5fea7faae85482d1e42cd419119c0ec1703 refs/pull/4675/merge\n004138019c477faed48bb9834fdf78d761d9bcda2026 refs/pull/4676/head\n00423f0cd5c96095298a47fe4c9db053be43ec934f34 refs/pull/4676/merge\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4677/head\n0041f9f90576bf467876f38e70e014bfeda6775761b4 refs/pull/4678/head\n00410da4547ae37fbc12bf447f522ceffbe99de4154b refs/pull/4679/head\n004166c5a881a5c0a7612af16a07414c78b777036564 refs/pull/4680/head\n0041c193385925c2d0b4109ccd55d2509f71d5c8f775 refs/pull/4681/head\n00419f3705f85cdf31abcd7fafc35bcbea673904fd76 refs/pull/4682/head\n00414069414bd7faf9899ffb83b1f364230ef149d392 refs/pull/4683/head\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4684/head\n0041f9f90576bf467876f38e70e014bfeda6775761b4 refs/pull/4685/head\n0041337773d1f3c26d37ebd4aa94a66e6884c24c4e53 refs/pull/4686/head\n00417e419b3eba7bd83e496a22db2b78917534c46dc8 refs/pull/4687/head\n00415cc2af0e3bab7eab2af1c7b1780ed33149a54780 refs/pull/4688/head\n004191c7be7e6a9d2e4857424142f74b08ce4295ae63 refs/pull/4689/head\n004019e4617dd5586b7379228783a7dafeb3ad5cd6d9 refs/pull/469/head\n0041660485339552438a864a5aa7648299071d85d8e3 refs/pull/4690/head\n00413f9e8926fb6af395c7cb3f798addbc0660a62c92 refs/pull/4691/head\n0041c943a738814c4fd29a8130273ae2e39f43c2bb18 refs/pull/4692/head\n004192a9a438fb2a2f8f53f1d6073d7eefd7293da553 refs/pull/4693/head\n0042c63a5959cda3bcec88d3464acc0f7c66642e34c8 refs/pull/4693/merge\n003f539bb6345b3c521756c3c68fe01fb5476107f4a5 refs/pull/47/head\n004015b2c3c4fb3212475bb30d16a595d3a48754572a refs/pull/470/head\n00407425fbb17e658c1bee3286023c1be47c1be1a268 refs/pull/475/head\n004009022111d128e5a2b92d7b332bba42b6c0cc9481 refs/pull/476/head\n0040c32943f2eb274bc1228e9e8b963ff23e493c8b06 refs/pull/477/head\n003f7942542b7dd62c0dcfef6d099ad55bd4001e223c refs/pull/48/head\n0040da63d307f10488113dfd52696218ba82e66888a0 refs/pull/480/head\n004008724c7dedf66677e18fb4e877c20b947a4dd280 refs/pull/481/head\n00406f75999d1287efdb029d48e401917387e8176f44 refs/pull/482/head\n004077e6725ade995f3645a437f8f7d01eead3d2c4dd refs/pull/483/head\n0040fa824a4cf86acfc9fc7635f2ca89f578b11a27ff refs/pull/487/head\n00402610a4e0aef51b5b50cfdf88ed6cef4937a1c4c0 refs/pull/489/head\n003f828d3229892fd337355b2856b1e143c9a4094b7b refs/pull/49/head\n00403e436f16bcc8ae364867d9856fa0313f7fe1d465 refs/pull/490/head\n0040898ab0d1f6a863e64cb2c3054352efb975d1d5c6 refs/pull/491/head\n00406afdc81c1d56e7f166b33bc9465bf5735ed07a00 refs/pull/493/head\n0040421a88cac4c87a4199cffc08e7691af1fd094eac refs/pull/494/head\n004026347349cd6a174d168045bd73247df1831fd8df refs/pull/496/head\n00400da1b610c614aaa0bfb1cfc1c10f41080ff9589f refs/pull/499/head\n003e3f49bf73cc697e83b998d15d4c24b3b2c3cb422f refs/pull/5/head\n003f7bc22854376474f99e947eaae5bf55356033295c refs/pull/50/head\n0040bf63148464b0f0fc6c22ad407eeeb9ed1a3fab37 refs/pull/500/head\n0040fbc22f7cdfc425d0366f44dfa63c289f44251fd4 refs/pull/503/head\n0040d44738e6a75cef1e7dc125c06ac945928141f490 refs/pull/504/head\n0040427e5971ce9cf4b05e1588d2066e2538a10f937e refs/pull/505/head\n0040738aa6298e56eae85a6cc212ea98b3ced3018cfe refs/pull/506/head\n0040dcbea96afc409df97fec6a03581268c818928c44 refs/pull/507/head\n0040ea0cd0b85f34b49b41121be2e1fc4d99cd62f95c refs/pull/509/head\n0040252460ebc4d89d1dd62a5e612219d8385649fbcf refs/pull/510/head\n0040a848819f56bd450742ce97cfde7a1b1c795f29c6 refs/pull/511/head\n004030158afd5f5c4314b954c222995dfbe5a0f6df6a refs/pull/512/head\n00406e075100aa09016ef384ec63c236244b32993e7d refs/pull/513/head\n0040ac40a5c9a4856ba3dc47533000c771557539cfe0 refs/pull/514/head\n004019e615fe83f329f04795aa8fd731691151bb114d refs/pull/515/head\n0040d1e6176b7bb89fa6c8ea59bdb94fce36dc20a3c6 refs/pull/516/head\n004023eb7dcaa2cf76e6c3187e95abe5962a5d984b17 refs/pull/517/head\n00408674ea9c7625795693f59620466dd3b91e1acf6c refs/pull/519/head\n003fa5aae997547532051254c3543fda04ecdd19e151 refs/pull/52/head\n0040fc6f375311fba3fb12d1cf6cbeaa642eafd5bac8 refs/pull/520/head\n0040ba7681ee4add1983739689110e7aaae5217bf1bd refs/pull/523/head\n004095935609f8ceaaec8d796ac895526680beae5a73 refs/pull/525/head\n00405f50e2b6afc3c5a97f24e6662359614b880cbeb9 refs/pull/526/head\n0040da429589631564615fa152d04ef8395c05bdc2a3 refs/pull/527/head\n0040a4ec96c9a96bef7a2f2318e1afdeb3e768373713 refs/pull/528/head\n003fd92b753039c86313e6163de3beec7e80e7715409 refs/pull/53/head\n0040b9cc4337fb099d98b1794d6245d2d16413be0843 refs/pull/530/head\n00409a5c0ba757500434d094996c10086fc1f137f26c refs/pull/531/head\n004026bf9a128ff64e0c41da850df451fefc9752b0cd refs/pull/533/head\n0040f641a629b070e48aaa81110f5ede97c6a4c5d74e refs/pull/534/head\n00407f0c4e8bbc6feb8cf54ca2aadf9ec681f79f031c refs/pull/535/head\n0040eeb08949f3b66a5988f2d22a7a09ffdc34c95765 refs/pull/536/head\n0040187e24c0df8e76a9d1221f295451cb5125d19b65 refs/pull/537/head\n004090263ab68bd9a54607c3e087b98b0e615e193c3b refs/pull/538/head\n0040b2f2ba8f1502c725d92632c35307b06223605d5d refs/pull/539/head\n003f4069e9ae46887eaa1ea25c0c41990d4a152aa790 refs/pull/54/head\n004008d0fe5bf8f16f7f129dd6b16c076680fa70bc47 refs/pull/540/head\n0040fa4afd68017c51fa9c8fcb234f7b089a6a6bbe16 refs/pull/541/head\n0040b643a0cb471374c0d4fe2c8bde45f7594e0f808b refs/pull/543/head\n0040fe94b87d5fcb2289f2c49ae49e248fdd8c49b335 refs/pull/544/head\n004022da7087587feb96d7a1d4f179661381d49bb32f refs/pull/547/head\n00400c72efdcae6f3e9587ec6a4b63d1946decbf5fc2 refs/pull/548/head\n0040192ed93b86cb77de447798c3ea78ec0722bc6b83 refs/pull/550/head\n0040db24d8b17db7af20dd8cfdcaedc9af2c78999bc1 refs/pull/551/head\n0040b47ce783b533222dd8cbb1afb6d9751e9b4b5d4a refs/pull/553/head\n0040c2af63cc54340534c6bcf4057d99889b20b47636 refs/pull/554/head\n0040532b5912133864cda5255ab022d4e5a66ad6d26c refs/pull/555/head\n00406ba69f1c26ff46164fba4b7099f3cd7c22ab6dbc refs/pull/556/head\n0040bbdec22161a3f6db0f3b40b8936f4a1adaaa58db refs/pull/557/head\n004056dfbe6300ff4b2063a57341a61f46c7de7a70a0 refs/pull/558/head\n00409ac3f6d893e9ad8f45ab12316f02c6a9ff55319d refs/pull/562/head\n0040ba38432d6c7074beb6eae72d03bdb567b0f713d2 refs/pull/563/head\n0040fc97f30299e11bd3fbafe60764a31731f1634c40 refs/pull/565/head\n00403b36449491233aa92160be5b68dbba193d9076bf refs/pull/566/head\n00404eba0eb5150020b0d69521348d7fbf3a2c44c1d2 refs/pull/568/head\n004049f841c25b74ae3cd508751de9dea5a95791bea5 refs/pull/569/head\n00405eb4c715b6984f702da1623dc8fe3f17345e562e refs/pull/570/head\n0040c8284062668d32d8be4012eb6b3571601d88dc9c refs/pull/571/head\n0040cca202c87decfd33298805d39f1e0ce5d7706e28 refs/pull/572/head\n00400b5104a4cd274324a53d87db88e022db0c0b72d4 refs/pull/574/head\n004020d761e3eb61a0321240c667837033944ef5133e refs/pull/577/head\n0040ffff07627e6003dc180c47795d625265e49eaa64 refs/pull/578/head\n004081ff890139cf9f07319e35b0ff3abadc38171de1 refs/pull/579/head\n0040dc64e918011198790c27d086755312368dca98f6 refs/pull/580/head\n00401765f3e868446b5c3e62da393a56dc09ffc72f49 refs/pull/581/head\n00409d58c1bc6e71cb1642b883bd4dbd0d835de240bf refs/pull/582/head\n0040ab7f0f423544887488e868ed5e550ff354490960 refs/pull/583/head\n004071853facb839d4b1238a354ea0a351d49c1e81ea refs/pull/584/head\n0040f13bae2c6d98b3e4030829b22fc821770ac72bc3 refs/pull/585/head\n004044d51ed2e50cb3e102563d166911eb7f6d2d9429 refs/pull/586/head\n004031c4c6e5672aaa3c0d93fd4bc31f7a104da8d5dd refs/pull/588/head\n00401acb581ec304067bd5f7cc1c714d8627407b62de refs/pull/589/head\n003ffe060d229baecb03798c6da631dfaa440c4363cb refs/pull/59/head\n0040811d28418a43713df02b95fcdea0918e87c27163 refs/pull/590/head\n0040f189aca712ffbce0d7b8f52a2148911ff40d8681 refs/pull/591/head\n0040dab21a93594bd2f83f32d10550737a26220a564f refs/pull/592/head\n0040dd3ec750f2ac746991fad465a44ece6515f30acb refs/pull/593/head\n0040e04698a4f079ef9e47894c77955af5c92b18ed46 refs/pull/594/head\n0040ccabdea034f6711c9da311a6100eca55b6542cbb refs/pull/595/head\n00409b069b5258813122ec05532e1746ac34e457e31e refs/pull/596/head\n004003320f72dba0bf9c4a344710f69b87a157afb22f refs/pull/597/head\n0040be3378dbd616d7b54340c247c1c2b40a5d2dc46b refs/pull/598/head\n0040bfc79659cddb9b15558d224e7adabfc1f8c61a0c refs/pull/599/head\n003ee8c29e0fd94218fe15baad313b095318ca35e4b4 refs/pull/6/head\n0040bae47748988b81977e7c9f971264bd982cfc42f3 refs/pull/600/head\n0040a1207a57be86aa5062efdbe7425f233d2c89e555 refs/pull/601/head\n0040a7a1e4f3ac65de68af18f37122ffd61d17ef68be refs/pull/602/head\n00401ab0afbcd184742884308a6e56a3e33644e54cba refs/pull/604/head\n0040f90a58db535e3ed8615765985e74cf47ce6bfc3c refs/pull/605/head\n0040fce4824468778452a19d54587b292d54fcdee132 refs/pull/606/head\n004086229944c849912189292564b8fae2dceee5e358 refs/pull/607/head\n0040a33c5dc6f1afd4da09eb21b05d8e6b320bcf82f7 refs/pull/608/head\n004005da03548ea276a0e83bd3e09be9834a8335d2b1 refs/pull/609/head\n0040ea7aaf0e0c534a82dfd0d96e5ea91071c244a418 refs/pull/610/head\n0040111df9afcb9f748713819c7c5abd425a97d694fb refs/pull/611/head\n0040988d98f421372ef5d57684393150141159a92940 refs/pull/612/head\n00406b1d7b73a159a3b20822d8fa4b5bc67c9c6471d7 refs/pull/613/head\n0040c4fdd9acb95155be5de54d9f6a658963ca98aeaa refs/pull/614/head\n0040f627af3bf490043922397ce368d3761ddd005506 refs/pull/615/head\n0040135ec824a06ae39f81f8e27c377934d1630166d0 refs/pull/616/head\n0040c4246fbc32020ea7fbbd1605fb2e7ecb7351017d refs/pull/617/head\n0040c79e8f2f0d0dbaccbc95fc72f44bbac936137161 refs/pull/618/head\n00409a6dccd8ac5f09b248d10dc6aa3207d7dcc4f3ab refs/pull/620/head\n0040c16148011d21776980eee0651f63b35d1029e8b4 refs/pull/622/head\n0040ffa7757e6d0de881a130dca0cde5d7963d231ae7 refs/pull/625/head\n004029c076ebeea8b61c3de6c63be1a80b5c36fccbd9 refs/pull/626/head\n0040a6721290f78a1a87be815aaab182427c03a6b6ba refs/pull/627/head\n0040104aa8d0df412d7fa6dd3291ee7c7cd3f9c454e3 refs/pull/628/head\n004083c3e81bc80124a7f6ffab24a6ad363d21ff6ef3 refs/pull/629/head\n00407e27c01c5dc170601315055d1de35e13f9f4fe83 refs/pull/630/head\n004029c1efe8e632d99bc52afb03ba2f8af232646ea4 refs/pull/631/head\n00407dedbb1d778ee611c89e6192a9a9169821ce152f refs/pull/632/head\n00404d2e49cf4853f694ce7623eaf7427b14a9fef8d4 refs/pull/635/head\n0040e7759b9ea0d675599b7821de4ab7fbdebff8ea28 refs/pull/638/head\n0040cce335b1462e95c6a2a34b161dcb90130672ebfc refs/pull/639/head\n0040d0ebfd4e634b2ea6ecb0ef9c24559f928f0899de refs/pull/640/head\n004080c904e3541ff766a774812e6cc07b403ea88f24 refs/pull/641/head\n0040423b62ab04c89caa94f4d2933e50c3559d0fb620 refs/pull/643/head\n004009fd6885d8fed342f58ab5bf86093bedc5f8f73d refs/pull/644/head\n0040fb069a91a9f15fda5a19280f0c99640d467a69ea refs/pull/645/head\n0040e2e6ba84e35ba11a1ea66708250d18520f28a5c7 refs/pull/646/head\n004094492d52f7afdda992c36b0a77f1b3101a45645d refs/pull/647/head\n0040e4d92d4402229891c543908362e34609d1063ea8 refs/pull/648/head\n0040ccd48f7c3bf61e9efcabf76584d188f022399c8a refs/pull/649/head\n003f9114a985e210798208c0a4b006e4ae78090a63dd refs/pull/65/head\n00400efc4177ecd181cab57ebb287ecc28e4fa518e1d refs/pull/650/head\n0040c327d3e2430cdcf6a884e191313eb3dc1b0790d0 refs/pull/651/head\n00405e8bbc98709e96d4cbd9c1b9121d43cce69c0cdf refs/pull/652/head\n004016fd8b268fd8b700dae919c7aa0cca6c949d1d8c refs/pull/653/head\n0040738b63e7bf26a636163f0ade319a0c03257e099f refs/pull/654/head\n0040057b7008fc6d9ab71b28105476c59b8349e2baf9 refs/pull/655/head\n00406ba57fb53fbc2c28bd544b434f2114d0d6419ff2 refs/pull/656/head\n0040431353cf9c9ebb1cfae7f12912175f4d4241f663 refs/pull/657/head\n00409c52bf7f8c21616ff861e18284551f15594d8646 refs/pull/658/head\n0040aa5fe2463c7ff352df80b5e96de7458720b12bec refs/pull/659/head\n003f15492d0d8857c7f1f37cbf4b2eeba4b5fafeed60 refs/pull/66/head\n00409e0f86f98534e7b417f07857bc68f4b7be17b985 refs/pull/660/head\n0040e6e452a01407ab6a5558ff813f40347dd055edbd refs/pull/665/head\n0040cd5983ed4e8ce93df2d7d12dc895f707af7f1bd0 refs/pull/666/head\n0040a66d42daf1fe9876503a21c306118c8b8a30c3e4 refs/pull/667/head\n0040f0ac8954bd8a844cf20dd045c152f807b6c75a92 refs/pull/669/head\n003ffbd97671c4f74a3573ca677cb23aa2e5dc2b730b refs/pull/67/head\n0040f0f09665d993f70d81676fa66f11c19a962278af refs/pull/670/head\n00402efdcc262931d42e199b84a0c4e4dfa8fe296a45 refs/pull/671/head\n0040ab07111508ec90a01e73ad064f5e2fcac05134ef refs/pull/672/head\n0040c525494e4a3caa74a0fb416e1db34d08a85febaf refs/pull/673/head\n004021dc91864b8ba42bdf81fce2494a2d2932d9feb5 refs/pull/674/head\n004034b5a1693bec061f8d13d8a5f7a954ff5af2a5af refs/pull/675/head\n00406fd8ad1d71226e646fc414647feff755eb9d58f6 refs/pull/676/head\n004091d9a183c2c0fdce20ed174b27526b469f82c7df refs/pull/677/head\n0040285d000103910ca736e72f43579e98cab05fc9a1 refs/pull/678/head\n00404fadd0e8495d4dc18a4656cb36bf13d229d65475 refs/pull/679/head\n003f701296e9aab2698626720502d7988f6ec8534900 refs/pull/68/head\n00403d77783d0ccf43a1d2cabbb5cfd769cb5ac08139 refs/pull/680/head\n0040984749296a631d40a888798b9da128c25e38a004 refs/pull/681/head\n0040f323d77eb48e653933df4cb8ca3e7b6d4b445558 refs/pull/682/head\n00408043886ee609e15ac71eddde29f7ad593abdecd4 refs/pull/684/head\n004098f502db014ce6cdfb4cae3bf5d37ffde0f522f1 refs/pull/685/head\n0040c95ac10faee8e9d2b2ccc1c8dc564a2315d5dc73 refs/pull/686/head\n0040a2a04afe106b835d9301cd1f55a6a661a5ec7d1d refs/pull/687/head\n00407b19026b4dd4152f609170c0984ba552770ec2b2 refs/pull/688/head\n004060da188ac6f131ebaf8a0bca72daba511885bdd9 refs/pull/689/head\n003fefc80f95b21903ffcc79f2e3767f216d40d6e973 refs/pull/69/head\n0040c4843689bb037ac6c9351dbb23bdf42920e7523e refs/pull/690/head\n00404aedcc345cd1e3398ec8ebb1dfa6d56c08b3229a refs/pull/691/head\n0040bafe7bf81405775c49d732209f40234d49622c2e refs/pull/692/head\n00400d6d7c66b246d72c0d513a5827c7fc7ca3a5c0f6 refs/pull/693/head\n0040df57af56cc3896f95f502626faf04592cf6e4d8c refs/pull/697/head\n00400d369e0ff56c300f78e1b047b9ba7fd3a6305a1d refs/pull/698/head\n0040f555322ea73895e099bbd25c09c77c3d32742620 refs/pull/699/head\n003ee44f6d00df38bf536dfa16ac854a24b30951a873 refs/pull/7/head\n003f7a275cbf35e020572d4c83f90d0bba774f8151d0 refs/pull/70/head\n004045272168ba25f1d6a15abbb1dd3d25f2df494ca9 refs/pull/702/head\n004097e8173ae22cea5a2a4c1b5d2edeba24d590c4d0 refs/pull/704/head\n0040e7e01e7e31fd80d8560ece85e949bd7ee78df2c2 refs/pull/705/head\n004042536bfa4e70e88579cf472ac13a534dcdee6f12 refs/pull/706/head\n0040a2459380ecc080174e784a92e978dfa7d8d9c475 refs/pull/707/head\n0040fcc04802804190e699b627a9311c7825244f463e refs/pull/709/head\n003fe460077786c95beaf70ca516b10355042df8d0f1 refs/pull/71/head\n004090e7d78e8be39bed87f991fc9078a626e81054a6 refs/pull/710/head\n004006a9b8f4ee2433c22f584a63abcaedc056c4dae4 refs/pull/711/head\n004072d0f4ca688fc020d2689516409e0a0241a00549 refs/pull/712/head\n00402c1924d53a679253d237baa26aa707c4d9da8884 refs/pull/713/head\n0040e65263e40790c2c3c218953acdab20072c15e3e2 refs/pull/715/head\n0040cb40852db455619fd4d11df788f87792fbc50feb refs/pull/716/head\n004025d97b46820caa302f7d73b3fd0d3e480b7d10e8 refs/pull/717/head\n00403d2e5c60f73734d85b8691b4bfe8f3bf9ace2d59 refs/pull/718/head\n0040a7844ac08686fa01bd3945a36c71083eb865035e refs/pull/719/head\n003f0ea877f58dee1d05c10339ebf3e574324992656e refs/pull/72/head\n004077372613c5eeef798728a9acef6b9e6e47d7fef0 refs/pull/720/head\n00408db2f7e637a58b9c7f8de702d7840f855e9aa8ed refs/pull/721/head\n0040177f41beea015317a3eac047648304f31f51f97f refs/pull/722/head\n00404d3481fd5284b4422f6377d83b92dec187576e31 refs/pull/723/head\n00402f2a33ed706a8da32bf11e418f64f0479f19354f refs/pull/724/head\n0040e551d9b972d0789141af4aaa572b578ecdea1da3 refs/pull/725/head\n00404b51a02f4705e9bbd497f9e1e440583ec6ba154d refs/pull/726/head\n004032fcd859db96271b7f7b12858a8ea3ffe8c5a614 refs/pull/727/head\n00404fff6d895a94d46b666e645ec0deae52c1da5fbd refs/pull/728/head\n0040285169615c3f60fdf928a4828a25a8fdaf257dac refs/pull/729/head\n003fb34196165f7f457a62afc293ab4ffed18b95be24 refs/pull/73/head\n004078172ccc0869f65b849cb08d80cfe7a3623f0d93 refs/pull/731/head\n0040928ee035554495b878806ea5493b93748c80c5e7 refs/pull/732/head\n0040d037807f6550280434189d41f4528124b59c65c4 refs/pull/733/head\n004055e2fa977cf848c1e3cb4888135556744584dbe8 refs/pull/735/head\n0040066dfdf51f0ef7968984267bfcf1ddf0013d35cf refs/pull/736/head\n0040a121195bac6e62fc2bb01779aa93339bbde7c12e refs/pull/737/head\n00403e7facbd209ec39d303416abe591c0ebe7ef526b refs/pull/738/head\n0040056bc02fe23dffca388b0c71dc765e26c0ecefe4 refs/pull/739/head\n00402a631151127562c377721506f44e8d6d5464cef2 refs/pull/740/head\n0040d2fbcdaf39656fa110558c97f1ab571591e4a80d refs/pull/741/head\n00405a1114ec4d88ff3668fe0e362dd2b62969813b24 refs/pull/742/head\n0040ed0ced879d819f2e9ed7a2a46a0597bdfd83df67 refs/pull/743/head\n0040f358d39f0c738c2c7c4cf8151bca8f08cf5e103e refs/pull/744/head\n00405b267b0fa6717f2beb2da1be354ec7da6e3d8fe0 refs/pull/745/head\n00403d4dafc7a7f3047623538ef822fe7f93a28e8553 refs/pull/746/head\n0040173c7b2fb299d6d1dfe20349263a54eb7b08bfa9 refs/pull/747/head\n004081cfe17eeabc9775da65b2f15a9cac4c390a2c71 refs/pull/748/head\n003fa2064306c0121b9a1aa51349945f2c0c25183cd9 refs/pull/75/head\n00406275137133743c4310697fdedcff40c627e27c8e refs/pull/750/head\n004068f0993f418e32413af9f50e735ebfb10c94f4ea refs/pull/752/head\n00402b32cec5276d0ae3bc64bc78f8f9fceb83813b1e refs/pull/754/head\n0040f55a27997d1c23c0b386b63e9fff8ea193d6262f refs/pull/755/head\n00408783d3640b8a971fa809dd1cad2a604ff202cde1 refs/pull/756/head\n00401acba9a0352ceaeb95654294bb27410a722648da refs/pull/759/head\n003fcc2a1d6ce103a8495ff4f3b507929029fa1a3dbd refs/pull/76/head\n0040a4aa7c7fbaedcce1f1c68704a9898a2a9b0dbd6e refs/pull/762/head\n0040ca562adde31ebf443bb6f9247f090cb3a2a7de54 refs/pull/763/head\n0040af8fc879f64d994d84db36f6beaa1356304abcea refs/pull/765/head\n00408b031bf4c886555f37f97f9cbb8f5f84ba3e9896 refs/pull/766/head\n004081b890ba1158a718d4df4f03d7c83af82b576a92 refs/pull/767/head\n0040b2d17f6de6288aaebfb19197c68a105d0daba511 refs/pull/768/head\n004001e9d0c6cb2d19a033ac0e6d7bcb88bf2ca40daf refs/pull/769/head\n003feff68e7143fdfd30c275ba516541db0844385e8e refs/pull/77/head\n0040e84a43a470bb7f472d1a49d5fe14c8f89b3fa981 refs/pull/772/head\n0040cb8262e93c0cd4d084f887e1effc050b285d9202 refs/pull/773/head\n004010931bf93d7f9834aeca8777b326f7199cc52595 refs/pull/774/head\n0040445cef5a2eda33abbf056b4e7c3bf37c7d32db14 refs/pull/776/head\n0040d073d3b75f1da574628b0e66aead9986afda42ba refs/pull/777/head\n00407ed9cb607a89a7d57ffae5fd507af7a56db19c38 refs/pull/778/head\n0040dd60736ffe81fe26ed0182e4c7b31b89bd452d91 refs/pull/779/head\n003fdf05d6c2be5809e2d85009f78e79fe33d27da367 refs/pull/78/head\n0040e05028469f918fa3c55b92c66588a53e7e19efcf refs/pull/780/head\n0040bb085e4cf1c3feac099a7ff565053538b608ee3a refs/pull/781/head\n0040118db1a7c25ba4d379b974cb9e79df363e05f10c refs/pull/782/head\n0040e932db9ea7ebf46b55669c7edcaee78d5a35afba refs/pull/785/head\n0040080e8a3a8d8598b786508898e33e6b1eb6a62490 refs/pull/786/head\n00403aca03c675aa27392e84bf20bf551b4f4c1c1e6c refs/pull/788/head\n0040d05b8a4bc1f572927875b238e07596e7e5996a98 refs/pull/789/head\n004018622bc349c54e308084c2d4b34b24aa22943f5b refs/pull/790/head\n00406b09743c2b7d220ba84a454bdbf7416875fe08ee refs/pull/793/head\n0040ae001437ad1fe79c20e10d8713b22e1d0fd77388 refs/pull/794/head\n004046b9797d8cdbd4bcbce41c3d85bc029d7fd04778 refs/pull/795/head\n003e34eaf08d34a89431d5c0882c84b9fa17908caa1b refs/pull/8/head\n0040ce2858dc43ca2f2bb87614399077d66bf9bb24ec refs/pull/800/head\n004070bed40651dbf77b56b8bb1ce937293072819c0a refs/pull/801/head\n00403ed253bef7c27d246c1c456686e95bbdbd80d677 refs/pull/802/head\n0040cdb43d4f1ccbc2292955c2315e5ac8d4d8eea146 refs/pull/803/head\n0040a896b1480f6963ea6cbaaf61415510ddf4df13aa refs/pull/804/head\n0040c36c7b4facf399d85982ca2e5f6a797b3be27ce8 refs/pull/805/head\n0040e2b4856726d3d53aa04854fa9713d27f9b830986 refs/pull/806/head\n0040e563eebdaa0362a95079661b7c22508c8d94e040 refs/pull/807/head\n00400ee37c80c0931d187305f8f7261d2070b8ddd80e refs/pull/808/head\n003fcc8715f28dafd700666d19cc38136cea248b1060 refs/pull/81/head\n004006d7aca733f2a97f169c125bead4fdf9f15f1f37 refs/pull/811/head\n0040bad54eedde4823b02aef76ad29f027b5ec55a847 refs/pull/812/head\n00406323fa304b8d1ea0b30f5255af372ea6c1d342b0 refs/pull/813/head\n00406fe4c87726530f7e1dbfd2da602d68c68db69e7e refs/pull/814/head\n0040d34f6f2d5e2628ba873f74b7432787cd3711b742 refs/pull/815/head\n0040de87980d51fe9110489e5b16eb58db6bbb1f5dc9 refs/pull/816/head\n00406e0613f124704bb9e7f186e591aa83d9343e725b refs/pull/817/head\n004012157a79870d55daba6ec78e8d0a60d7f275bf22 refs/pull/818/head\n0040dd6ce3c6e72b750253e2a63858bbae1093861dda refs/pull/819/head\n003f9d4d998dbb4cc5a5c519e611bb364f75bf34872b refs/pull/82/head\n004034438bebd4d9f64bce4c3560a859e4bd7ca03f57 refs/pull/820/head\n00407207b2633bef006b6cad7f30861be8783788c2f0 refs/pull/822/head\n00406231ac298bf965ade374df6300db26436413c470 refs/pull/823/head\n004062336dd003c07cc5c286ce0f3ab3774a5c31a612 refs/pull/824/head\n004046968d768edfb3f6186dd6dca57916e297c33dd2 refs/pull/825/head\n004097ad5aecced2f2acefe13953362f97bc2cbeda60 refs/pull/826/head\n004059fb92750d43c74758d919bb888106258da5a29b refs/pull/827/head\n004022b377d570d3ab3cf0452bf959730dcaf2825446 refs/pull/828/head\n004009376942a89475fc1ce482dc4532626161f13703 refs/pull/829/head\n003fe621b6b6e656eb468c9706eec994e214cc9f3711 refs/pull/83/head\n00408ad712de7bda9769fe5768094715a00d564c1980 refs/pull/830/head\n0040d5bdf9abbe52f4db1e27e5cd131608eeaae7989a refs/pull/831/head\n0040e05dec0d6e78948e6585f9b317025dd71d9c4fb1 refs/pull/832/head\n00404ed4040f268b03d9659cf4222ed43fc44602902d refs/pull/833/head\n0040a5965a59ba5bcc689d236cfc9616572771758a7d refs/pull/835/head\n00401f4a1d12005e416e3f5b2bc4f3a784c428aab57d refs/pull/836/head\n0040d1bfdaea98d066478100518578ff395acfbaab14 refs/pull/837/head\n0040c518afdc363706a7dceaed72544525b7d8357b95 refs/pull/838/head\n003f9169f1f08ea14d3fbe1b68b53713d28f5248d0e3 refs/pull/84/head\n0040d35da14e7b620f44b1b96c74c609b9b7921032ac refs/pull/842/head\n0040e657966ef3575b05376c51fbe7d40d357876ca48 refs/pull/843/head\n0040ec3cf43d42d8af6018a528f1440999b467b3f388 refs/pull/845/head\n0040115524d3bfee413ea472b6b9f7fc79d85955651a refs/pull/847/head\n0040e22599fd352a978201db471c884575423da0fe97 refs/pull/848/head\n00408fa56e28ad91e4be463f25dc465afcc0857b7669 refs/pull/849/head\n003fac40525168a1bf85ab0ddc2f1a1db98d12f2eda9 refs/pull/85/head\n00400ca5e64a00ed2653963337613893e97fd04e94ad refs/pull/850/head\n004035b917bdcc8dceefef5b948482f1731361832f66 refs/pull/851/head\n00403dafe29588e29ea4c751ea0b8a9abd3dbc18c3c0 refs/pull/852/head\n0040ab29b63a7ae6d672086e812604f58170059140b1 refs/pull/853/head\n004050a4b042a14e4aabd9166c8e64aece2dd3019df2 refs/pull/854/head\n0040d78b460e2fe03f1595d1aaaad5dfa3f2748bbed6 refs/pull/855/head\n0040fc3fa2c8c9d9e1f0e0f8b436793e9792bf2a194e refs/pull/856/head\n00407cdc4a8bbbb549de2f592599ee71eb869dc0f107 refs/pull/858/head\n0040ce4e48b794c9edb5d19dd5a5e1d2704af419105e refs/pull/859/head\n003f048d9dc2d9c48ca2d6d685cfae4cea7d74c075aa refs/pull/86/head\n0040abfb710d9ff916933ba72ac68062d8efe6b245cf refs/pull/860/head\n0040f4f48b5fb1288738e59a56853854930bc02647d2 refs/pull/861/head\n0040c189b851b3d5fe349399d249a90e0e68dc8f83a0 refs/pull/864/head\n0040182e26764f06d5b2be0b7c68715c14ba8d67684c refs/pull/865/head\n0040da8d774b89c336070340292a780d4089406d6e35 refs/pull/866/head\n0040ef83217f1cca19bb55f29ee2aa24630301184dff refs/pull/867/head\n00404cd0f4f6609e0877a22263b6aa8b0097b7600ff0 refs/pull/869/head\n003fc1bd40fff6ddfab1c3b4b0ec7b949b595a37f560 refs/pull/87/head\n004073d3324a956b6255e7057b91bf842c903953aa06 refs/pull/870/head\n0040ca189efb1d2ba63690064760fe4d5f44212d5eed refs/pull/871/head\n00407943f1f3061bab8519c31af04cd2865c5f773412 refs/pull/872/head\n00401a19ed0abc5ee0984002a534d94ad9d13a23cff6 refs/pull/874/head\n00409005e7448f74c76bfca8abd6ccc2eaa8033e3f1b refs/pull/875/head\n0040cb8158aec6e877cc7d19f6b8ce0d76466e9f2de3 refs/pull/877/head\n0040d9e51f14175ddc2e9bbe93dd042e1d6fa5c063e6 refs/pull/878/head\n00401c40b3f421108053afb348d7afa4cf218a1d0f68 refs/pull/879/head\n00409a5882322417a05b4f4e9624af90e4789f3cac9a refs/pull/880/head\n00408d07ee77a55d1e43753eb2f1b595e90dc7807472 refs/pull/881/head\n0040fd9a292f19de446cef18f7598e8aa671e9b8eb5c refs/pull/882/head\n0040360aa2c5e752b5454cbc4a2479d0088b38abc993 refs/pull/883/head\n00409f48dfb7ab50cfadb0b962420dc2925c3c6c0735 refs/pull/885/head\n0040a6ac8158f4df78287d9b9ad1de65dc57dc6a185b refs/pull/890/head\n0040766b544a82088b1431e3dcdd3e1487b9189d6246 refs/pull/891/head\n0040a0a34d7f13509a488214cfd2438f6be0146c1ad9 refs/pull/893/head\n0040afa6a135e83a9912c9f4d15357fc9938bf2b0068 refs/pull/894/head\n0040c2470e34de7765ff88749016b3965464dfd2fa05 refs/pull/895/head\n00401c5b91f0c98a065da1decc046eb7c42f814ac6d5 refs/pull/896/head\n0040107785b88da780305b58fc9c6a7a4ad62429857b refs/pull/897/head\n0040878be2f49793529c5426af095b857d85947dec4d refs/pull/898/head\n00403a3c8842ced25171126744d03956459b96fd2a36 refs/pull/899/head\n003e39a9b3d002d1ccfc40ae9b0ea09180f0ee210fad refs/pull/9/head\n003ff6ccf0665312025f8c067e65aa114f1e560535e4 refs/pull/90/head\n004064263d8202cfa4a6e230d02a85b4ab73f18af28c refs/pull/900/head\n0040b9d98f2c3292e12d1065e89381ecf2aac77b33bb refs/pull/901/head\n00407469149b4624705dc9eebb620bac1347e0a1f900 refs/pull/902/head\n0040758931949bb8fa3e07b86ab0304dbc8a545e4f6a refs/pull/903/head\n00400907842911fae6c1f24f295cfcdc1771316fd729 refs/pull/904/head\n0040d79ecb701961c87061812b420d0315336a5b8589 refs/pull/905/head\n0040004eb238767a74876370927993867203630406e3 refs/pull/906/head\n00407fa47247a434bfd4ea57e05c85d24ae3c8393fb0 refs/pull/907/head\n00402209d27550ca808b5741b75a5ca8f4ee1bfac660 refs/pull/909/head\n003fb9da4fc6bfe0353628c52d6c9909723cd3298a31 refs/pull/91/head\n0040dd96a1ef30474322eeae85b439752a2441648b96 refs/pull/910/head\n00401cafe4142ab230d9f40f7c376c7b2fa7e55275bb refs/pull/911/head\n004037292b1f0175a95556c8ab0496ec833aef6f562f refs/pull/913/head\n00401da7ae60e3d5ddd626f3ae779e14fa35d3920394 refs/pull/914/head\n004055eefd75947c9de22a7ab54aa2e66f9ae2d6d181 refs/pull/916/head\n0040991fd5a796b5a173af26608d89b2523856a8839a refs/pull/917/head\n0040a7092017e6221118f5374b13bdb94dd70cb931ac refs/pull/919/head\n003fcd8a45229c253b2ded996209253f557ebe08ea35 refs/pull/92/head\n0040310531041a9db2b3ea7be5508cba725a31c1e7b2 refs/pull/920/head\n0040103d74ad373eb791086aa36975c558d020329cf1 refs/pull/921/head\n004005a1330cb29ccc7cee7d07f282c9ea3f3ce09e31 refs/pull/922/head\n0040b14cdd5be1e9d43167cf8b45a12a8af94c7ab2f9 refs/pull/923/head\n0040ae5b1da48e019604c2ab11cfda3716bc93127e29 refs/pull/924/head\n00402ecf0d4443aa6fd0670d1258bb44e0502cc25be4 refs/pull/925/head\n0040f8d3be5358543d1e77b11da39ee430bbffaad72f refs/pull/926/head\n004013b646387780724daa44cb53406c374fa7536f5e refs/pull/927/head\n0040c80ddf9150a8a07a438a472b283f17dd432cac83 refs/pull/928/head\n0040c5790e77625a6551eca40f10b1baefed1364fdcd refs/pull/929/head\n003ff104599fd8d9a3e937e6afdbfd23aae03b06e70b refs/pull/93/head\n0040d051eee2415aea7e689f3f803c8b42d05bc7f261 refs/pull/933/head\n004067e4e665bcddd02323994332db1f0b36e9f95850 refs/pull/934/head\n004001c9c34786b8f29badce2ea7b8800d1d29585490 refs/pull/935/head\n004055ce8e32fc4100fcbe08168fa134f152ae03fa06 refs/pull/936/head\n00406e33ac2dc161d71f2093cd4b2069a670641da16b refs/pull/939/head\n003fe8e0531dff3e4ede2702f8a194806b479b6573dc refs/pull/94/head\n00409004fc8b94f17b8eb23f3fac7a40373dcf77370c refs/pull/940/head\n004031389c6fb390c4abf206763035bcc253913cb948 refs/pull/941/head\n00402609a321f2e80669a406d954210fd72be764b551 refs/pull/943/head\n0040d5f662f99a84d64ec471ac1380a5508b5b84cc8c refs/pull/945/head\n0040e9c463d00cdffbff59c5d93db522dcfc4d25a1fb refs/pull/946/head\n0040f192d01fefd5091b9b4ad9b79982485ea8589733 refs/pull/947/head\n0040d83110303c40da1d3625c2369eae7424928bfbed refs/pull/949/head\n003f9f4d26f01eaf7a63153e00738718899718630811 refs/pull/95/head\n004090c651e8a760809d5bb1d000200a51c636a0f054 refs/pull/952/head\n00401aab4ffc6737c651a7022c498da9bbe9d51a94e1 refs/pull/953/head\n0040dfada8bc4d47aee406e8b41ca5dcd37e5a46507f refs/pull/954/head\n004057853d8dfa95aa7e51955cec9f00308118779a75 refs/pull/955/head\n0040b2b34bf2041f3bf6b14c340aa8483b44d60e7ef2 refs/pull/956/head\n004002853eb3413c48d693f761af5d6bad64a794de35 refs/pull/957/head\n004048f6be2dc9e5cdcde851bcc3a36126c115ddc1d9 refs/pull/958/head\n0040ea6cf207519ea325a4db11bd7296ec8e3cc9ac0d refs/pull/959/head\n003f45027e2bbac111be570749575b37e391d01747b9 refs/pull/96/head\n0040c7c55e329178bfbe23eb01699ea2a53f30586fc4 refs/pull/960/head\n0040191e6f1b7e87e904cad92cad5baf2c0a886cab3b refs/pull/961/head\n0040fe2ed02e78802a6b0926426be167acab160c1c0b refs/pull/962/head\n0040a8a849ba63aeba05c5e9dd77b00164cc46b16625 refs/pull/964/head\n0040da9795a9634318e42c37ec19f80599c0edc59b0d refs/pull/965/head\n004037e9c36a577642e5eb7256f44781858b50030935 refs/pull/967/head\n004098d33cfab3240eb4982c3adf17c3a1e6a6dcf600 refs/pull/968/head\n00404c8394c17d6ac8f66dfe8ea52ea4f948021fe8da refs/pull/969/head\n003f4d2fe23287a89f1c5241c5e97a940696a840e17b refs/pull/97/head\n0040491d07d263295fc5aeb810ef76e8f2c6d427b3ef refs/pull/970/head\n0040186fa33372f1e4d38b6d3d5ae39d67a435775ccf refs/pull/971/head\n004066ac8a4f89fc8b05319d9a128f51414cecb940a2 refs/pull/972/head\n0040b9980b71215d670dea3099347dbe8c4218f9f110 refs/pull/974/head\n0040a6906775fd285ed3f2baed9a0e81d44ac0a0b3b2 refs/pull/975/head\n00408514919ec66097b5fb571d0664d96f39d768134c refs/pull/976/head\n00405faac7caaa0dcea41a17de0cee60ed7f06e1f5d4 refs/pull/977/head\n004080a4c2407a618a422fd423a30412788a04909d96 refs/pull/978/head\n0040c1e8209f39d44f5f593ae9294a1577d53bf1d125 refs/pull/979/head\n003f7aec67159650698184e602b4579273031479ba64 refs/pull/98/head\n00403555c83f3f7c24a3bcec994f0b6d5770a8ad2822 refs/pull/980/head\n00402c9160f8b13da1243284a53e6b9f087c822185be refs/pull/981/head\n0040a40a406de8e0cd31f3c5eee473ddf603f341c2f1 refs/pull/982/head\n0040ff4497970acdfdd1068d8e74c9cef8c12a4da5f9 refs/pull/983/head\n0040d13163df761ec75dccb17003c581847d50a2cc0c refs/pull/984/head\n00405b8617a847a2a203e498becbc3c0532748933ce2 refs/pull/986/head\n0040dcffa8e69730e0c02b9aa016461e87968794bb72 refs/pull/987/head\n00403b255d8a8de732f378204b6a875efc1b02e7d77d refs/pull/988/head\n0040a0f3cb6d034272ce93606a67d40df88af496e941 refs/pull/989/head\n003fd878692c990ccb8cc79fe2475f5ff23c27ac0619 refs/pull/99/head\n00405b7f7ceb1a0f94c7eeca65bf89eb14bbc0a59342 refs/pull/990/head\n00407017906a8b42b1ed89f4a460c4240b9e4580b269 refs/pull/991/head\n0040a5fe46e1f7d147ce127de02177289995546d3b97 refs/pull/992/head\n0040d23da7efa002b15768bd46ecb8e093d20371d162 refs/pull/996/head\n0040a512bb48e3b77d921087674f19a7e8b8eadb73e8 refs/pull/999/head\n003fbb69be3fc46bc36dc687a645679a227f7bab9eeb refs/tags/v0.0.10\n003f01277cf0443b8e7cbe8104c8e72bac7aaac15b11 refs/tags/v0.0.11\n003fbc9f4568c6f3fdeb78bf983a3bf3d90bdcccd9c5 refs/tags/v0.0.12\n003f95135bc1a18b70853608d492d6eb82e5702500a4 refs/tags/v0.0.13\n003f8de7697b3b8a73e79a73ec34f17ef0fa842cfbb2 refs/tags/v0.0.14\n003f932929f0f31584734b94339ea9cacf3158fd9bed refs/tags/v0.0.15\n004546391ffda5dbc429cfd440269a4972242bb0cc4e refs/tags/v0.0.15-alpha\n00481eff46c9d7e491d709680cba7e446d1fdcb8223e refs/tags/v0.0.15-alpha^{}\n003f83293a2b3b7931c39214afdbcf30573727891066 refs/tags/v0.0.17\n003f657fe2a8cf60492ae03045e7ca4da22a09be7f58 refs/tags/v0.0.18\n003f28d1e63275538cf8f3c3a5ccb5cf8f87ccf2aee7 refs/tags/v0.0.21\n003f236cdaf0470e94797989d232a85183f66ce6b61b refs/tags/v0.0.22\n003e9aa28d0a130e9174fb217921966b1855c2fd3f19 refs/tags/v0.0.5\n003e12e0175b9303f6ecca1ad8abdb3a28b3c97e7b54 refs/tags/v0.0.6\n003e95862388f4e9835d0b6e8136118e1799a064efe8 refs/tags/v0.0.7\n003e10b90c68bca21c632f4dbfd243aaedce25d00b3a refs/tags/v0.0.8\n003e737948b5060efeffb1cf47fe085d187a3d0304a4 refs/tags/v0.0.9\n003e8bc725ef48bc28a085f4a677afb983bae2558959 refs/tags/v0.1.0\n003ebcd7e4b928d8af37e459c2b25e1185e3f5ed4089 refs/tags/v0.1.1\n003ebd0d0261d4a654f8dadf52e66b654786673815df refs/tags/v0.1.2\n00439805438dc8731dabd78c8b3eb6871cb12a5090b5 refs/tags/v2023.02.28\n00438395cba7325954e4b3e3ed4c7ef3bfa82b428bdf refs/tags/v2023.03.07\n004363a89f6b9cafa9105949ba1616824ebbce62d007 refs/tags/v2023.03.15\n00436e19621c3acce9f66a817d0fbd825cd8edbe56ce refs/tags/v2023.03.21\n004329b7f68cc25aef244e46758a4c6548d366256e65 refs/tags/v2023.03.28\n0043ac1b1aa95f204bb6e1c0265a9d24139e9207d1c0 refs/tags/v2023.04.18\n0043adc4f6fa6de0b14e8c0ad9e502434d68ac3ddedc refs/tags/v2023.05.03\n0043ac1e00f9928257d8db85557e92d7efe44f5a828f refs/tags/v2023.05.09\n004310d72617f1ab2fdc9445b99ba18e723f60dc0750 refs/tags/v2023.05.17\n004311260570ad7c022286cc82840bae0cf8b1ee5350 refs/tags/v2023.05.24\n0043a29affe77a4c5de1e5421d9f53a8a0aa749d03cf refs/tags/v2023.05.31\n0043aed410e4badbc073a6910c11c8ca57f9fc49310a refs/tags/v2023.06.07\n0043433e32ef73bf683326d11d06e4f3d0cbe1e58859 refs/tags/v2023.06.14\n00437f4fb14bda2cc9dbbd8294a863092f64c2907c2d refs/tags/v2023.06.21\n0043b23615fb607715133806de0b12decc215cc95c2c refs/tags/v2023.06.22\n0043b937cdb360e93eee61a150c05029eb00cd404486 refs/tags/v2023.06.28\n0043efe2a73c48cfc8f358f304cf6d359d404b9806d8 refs/tags/v2023.07.04\n00438ce4d43aecc3b203df79565cad859d7798735a55 refs/tags/v2023.07.11\n0043cf318991793322189c5e44865a0355fa2ad69123 refs/tags/v2023.07.20\n00430f4e0c28da6fd9535d483ab63584d60a925bb3b9 refs/tags/v2023.07.25\n004338a28cd7123e13f90206872cc2e9af57959cabfa refs/tags/v2023.08.08\n0043064a3cb686cf44a66b061e914e52c9a6d9f4ecd1 refs/tags/v2023.08.16\n0043c6234697916921a270ab73511ae41e9037e15a5c refs/tags/v2023.08.23\n004372824f40c918f75abdb41ea13ce0513ee3d85df5 refs/tags/v2023.08.30\n004381506c929c86ba534d561e4cea236c7b2e1cbd98 refs/tags/v2023.09.05\n004322f7c5adc326fbda035d81fa05e3bfad80bdc9c9 refs/tags/v2023.09.13\n0043eb99b02ec8895fe5b87d1e76675ddad79a15f817 refs/tags/v2023.09.20\n004357316bd49932c8d37661cb03681b9d240079c7bf refs/tags/v2023.10.04\n0043595fc3e8b0210f23eff23ff853474e8700af2b85 refs/tags/v2023.10.10\n0043b374531b8074c41c7842183132e7e2804ebb3e84 refs/tags/v2023.10.19\n0043d26956b07351e0c695723507ad56b0aa59bd759d refs/tags/v2023.10.24\n0043e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/tags/v2023.10.31\n0043eb3b3c75b4b86d0537cbeaae55984ad4bf71a53f refs/tags/v2023.11.08\n004373315181865f9dd465dfea60d8c4a7359bad47a8 refs/tags/v2023.11.15\n004373b75e2c5b3c0e18f20375f4944b30b806b4cf32 refs/tags/v2023.11.21\n0043d039ca1b38f56a6c959eee0982afb69d1e56a65a refs/tags/v2023.11.29\n004381ea8ac55875b68ff236da7f44f91997c7b08925 refs/tags/v2023.11.30\n004392bce01c40ae5c4707aa46371cd31dc34562d88e refs/tags/v2023.12.05\n0043e15fe9260c2f2bff99184ca7a6bf5b8bd4ded5a8 refs/tags/v2023.12.06\n0043bbab1cd3a6494c4fc2101c19a832b52ee78d412f refs/tags/v2023.12.13\n00432a4022c818232b32573841a6f506796a25d13120 refs/tags/v2023.12.19\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.11\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.16\n0043aa584539a6f0085446fa53149a33c9385cecdf35 refs/tags/v2024.01.25\n0043e74a5dd172fada3ffb487d0c7c26db97cf2c3cba refs/tags/v2024.01.30\n0043f853bc9845f76620ec94f3662bf522fea0368a5b refs/tags/v2024.02.06\n004379c07c93dc01ed256032cb790eaae638a4255ee1 refs/tags/v2024.02.20\n00431defc72ba4297632dfb886b829f7a2d5299f06d5 refs/tags/v2024.02.21\n0043678f665a24414c3b425eaf40eb0eec62233aae41 refs/tags/v2024.02.28\n00435a8605df882d8a24c086655338e5f43fbddfe627 refs/tags/v2024.03.06\n004377ae40037a5c92bb3d04775a2fab70043ef7058d refs/tags/v2024.03.13\n0043f532637d69ac886df1fcf7b2e31f90b19df6f351 refs/tags/v2024.03.14\n004367f1b39c7aeee2a28ce5a41cabe113e4b49feb7c refs/tags/v2024.03.19\n004352136b5f1d38e09a5c687bd796feaa54fda7e4fa refs/tags/v2024.03.26\n00432ed3d46bd5c433bbbb06b72d7c0c171546646550 refs/tags/v2024.04.03\n0043927c0cae0f153597bf533032f086442e99a17042 refs/tags/v2024.04.09\n0043bc61579a635c9525a163775e42ae23886960ed7f refs/tags/v2024.04.23\n0043afcc49c52bbd1c6604baaa3a12809a30d5d3ad34 refs/tags/v2024.05.09\n0043fc144b751d26d8fbfc6ba15afc92fdbcd00a4fe3 refs/tags/v2024.05.14\n0043d0b1f72cfa19b5aa73883161682831392d8b5476 refs/tags/v2024.05.22\n00439ec5daa06fdace741958e4a7a20f7d1931948393 refs/tags/v2024.05.29\n0043bcb5dd13096cc0981647b113ca3ea142a7a517b6 refs/tags/v2024.06.04\n0043ccd849542895620faa4f323f44d7ad7ca543b5dc refs/tags/v2024.06.06\n0043d4509b6e3a2a6764c75f7ac316703b538ef3a1c2 refs/tags/v2024.06.12\n0043af23a17b9c54179b2253fccd1da19c38aef1b86c refs/tags/v2024.06.18\n0043fa0672b233985ca2e57f752e1f91542f80b8b22f refs/tags/v2024.06.25\n0043d6938bd6e6f2cba5cabb950fd86086f4c764e8c0 refs/tags/v2024.07.03\n00432cd1236084bcda3c37a80348c0de88c1aa103bb2 refs/tags/v2024.07.09\n00438c2b48a4bf3bd73e9f198966ddbb0bebd3d7cd6b refs/tags/v2024.07.16\n004394f08450539093e3f799533b698ead2f8cafea09 refs/tags/v2024.07.24\n00437295294bbc414041b103a0a296718b14aebd2632 refs/tags/v2024.07.30\n00437ca68fed3cf76d171473970f5bfaa3846a69b635 refs/tags/v2024.08.06\n0043d48073bcbcf12257cc249ff3698fcf94a16ceaaa refs/tags/v2024.08.13\n004380b888fa239ceef4062648f4259a5767f36d1080 refs/tags/v2024.08.19\n0043a81778d470873e2be57d3b8ae4fbf9f942e28c96 refs/tags/v2024.08.27\n00430a526fbafa0a00279ab6a74787ec265d65b8feaa refs/tags/v2024.09.03\n0043431fef648ff9b44f33646ac773abbaca71c48f15 refs/tags/v2024.09.04\n004365076b2b592d4e09bf0be039699969b455bbf4a8 refs/tags/v2024.09.10\n00433dd07d08451a9be3cf4eaf95e3fa0e0d8f3e8a9f refs/tags/v2024.09.18\n00434eadc85640729c2ae55ab05f0040cec03bf3b726 refs/tags/v2024.09.24\n00433508bb45f43df4268a8be3248386b828779cd95c refs/tags/v2024.10.01\n0043081f563d7307950d9c43237ee7cb965261496ca5 refs/tags/v2024.10.09\n0045fa9fc088b7fa8a2b10a479a17bbb9f46e0609d34 refs/tags/v2024.10.09.2\n0043033ea44ceed6bbc972f8f528585d15fc397d2e19 refs/tags/v2024.10.16\n0043af4b18a1540cf73c9ac67d1643b0a5f511d1bc86 refs/tags/v2024.10.22\n0043037050145b4bf7d09d9602e2c8042e4ca8bed9fa refs/tags/v2024.10.29\n0043ee286929b5e18f007d9649afd75c7bc4ce68c2fd refs/tags/v2024.11.05\n0043d58c1f6a1e88c451e168863057fb05fe0d323488 refs/tags/v2024.11.12\n004322cc4bc998323fb7d0bcfe4bb24e3d5715eda849 refs/tags/v2024.11.19\n00432d7b1e03bfd479a58ad56c339cc092669dd64707 refs/tags/v2024.11.26\n004391a0125e55c8902b3d077f4c812284d9116a5bbe refs/tags/v2024.12.04\n0043402f47d4f1fe547ba68ab39ac342b525f4cd7e69 refs/tags/v2024.12.05\n0043a5ef7137a2e3cd5c48e2b7ecccab5722dbf738d4 refs/tags/v2024.12.11\n0043732f08356e5f073aa275d36bff43da6b2b0177c7 refs/tags/v2025.01.07\n00433d55f553e28cc2b16152fb4df8ac53797b9d5c8d refs/tags/v2025.01.14\n0043f53c68fddaf2d760e0a00cca49b4b5313bdb0ad7 refs/tags/v2025.01.22\n004326d49d78a26427a12628cd3a1a4cd49d030c6956 refs/tags/v2025.01.28\n0043a9940a58b48f0a650632c37b44abdee0144d781b refs/tags/v2025.01.29\n00453be0a2314da2bcb3028617e4a05622aafd5beee0 refs/tags/v2025.01.29.2\n0043eb29faa1a45f8983502590b8ca68dcb2692ac68e refs/tags/v2025.02.05\n0043c2e9e5f6e41b61bb18e8e9f20924bd702d9fea47 refs/tags/v2025.02.11\n00436f66b0ed1fcd2394462a4268f2dad26ace3ccc06 refs/tags/v2025.02.18\n0043edde4b267a78ec2452e0ee7afcc21d02d7f18377 refs/tags/v2025.02.25\n0043f7e26092e0e8ced250d6cab7ae7b62343f2b8809 refs/tags/v2025.03.04\n00436dd9a9dd776e2c51c16f359c417256e702fbbe44 refs/tags/v2025.03.12\n00431d0fca0817eab7d932e4673e6837aae320708fa1 refs/tags/v2025.03.18\n00436d7c3dc69bc05e7e1a83f4389e61d430db288416 refs/tags/v2025.03.25\n00432727c77060f0174f96e12dad3070cb504c316ec5 refs/tags/v2025.03.26\n004304979978095630ecf30f6c3ddbc55e07ba8bf7cf refs/tags/v2025.04.01\n00439f7fe3920daf55fb156d8feb6143d939e3d5cd28 refs/tags/v2025.04.08\n0043e28ded887856f77d575be479212490d35e55e08b refs/tags/v2025.04.15\n0043b8445788211b3bcc04c32c77046503b14170c870 refs/tags/v2025.04.29\n0043b8d9f1b5afe0a8cf6ec02354fe2fd4516271b1d3 refs/tags/v2025.05.08\n0043139de7b69a2ea39e2113309b3a0a47aab920ddcf refs/tags/v2025.05.13\n0043b5f70ca94cb7beeb9d01269958275796f1b7189f refs/tags/v2025.05.20\n0043098ed8318399f68a9b2ef4b22c83687cacb85da5 refs/tags/v2025.05.28\n0043f3aa51f0689214ee9ce4e57173e56b933fda3649 refs/tags/v2025.06.04\n0043367e62dc034dae8d6a61362fb0d804906982a18c refs/tags/v2025.06.10\n0043d895bc431dc7c591919e5f1907bee1867eb6a914 refs/tags/v2025.06.17\n00437f39eb683c4de0606f91a1e624f905bae1407899 refs/tags/v2025.06.24\n0043e4f7ccfd19525dcffb1567c992a031bfa50220a3 refs/tags/v2025.07.01\n0043e536895df480f9925d50433216c1f6433d72c595 refs/tags/v2025.07.08\n00437102b14a4e5f4a2143b93b3be87b2d47a72ab8c2 refs/tags/v2025.07.15\n004307053097ab9dc03f53b5bdf787c0980035c87c77 refs/tags/v2025.07.22\n0043b87e0fd6d1c5443c32c36d85f86327a05682bfa8 refs/tags/v2025.07.29\n00431b89e9ca82d67aa78fc13cc0fda6a9bc52444b4a refs/tags/v2025.08.05\n0043becec66fa93053b7e64695306b180bc33834315b refs/tags/v2025.08.12\n0043968eb3f9fdcbd8a2e15b37f6ac8b27ec16f4528e refs/tags/v2025.08.19\n004363cd9d02158a08200ae269fea1a0a313a218d02a refs/tags/v2025.08.26\n00434bf6cd15e8ee92b5a0920996f78bda842ed23399 refs/tags/v2025.09.02\n0043e82714dc6454b7b7c4be0eccbac950c3b1a03006 refs/tags/v2025.09.09\n0043749e06b88234c9316282b9024b603c5c1957e194 refs/tags/v2025.09.16\n0043ad4bb44b99d34d27f5d36e8ab96afadc1fc7e6eb refs/tags/v2025.09.24\n0043bd0d0261d4a654f8dadf52e66b654786673815df refs/tags/v2025.09.25\n004343c5e13b27df13e9676783260963bcb8805bfc6d refs/tags/v2025.09.30\n00438c9069f6f183a02e3c71adc760190ded4331c402 refs/tags/v2025.10.07\n00439025fd1f9db05bb0d2309f616fd668b5b00938f0 refs/tags/v2025.10.14\n00431d9b902945b6ca026720f523329b2f18a4dc8228 refs/tags/v2025.10.21\n00435fc0b2fa2fcb22da1bdb83d287b21bbb39128585 refs/tags/v2025.10.28\n004330bc3412d57931a1fd7b5691922f01a11b811302 refs/tags/v2025.11.04\n00431b9cb07547bd39a376c0c57289db8d0c3740abaf refs/tags/v2025.11.11\n0043ca40ed0d4449c54a23c20dfbea71a841ec0d3a47 refs/tags/v2025.11.19\n004367b4d8b430496b96ad08ef544ad823674763dd8e refs/tags/v2025.11.25\n0043ff13718c6bcd1e67cba5c29768c4945d643078ba refs/tags/v2025.12.04\n004379c63772b6ba332725d1b65524a9850e582c82bb refs/tags/v2025.12.10\n004311ebfd72c6b2e4b45fa84d74598fb35f6a76412c refs/tags/v2026.01.06\n004311dcf751333eaa04f860d989afa334bacb13e397 refs/tags/v2026.01.13\n00430e50a12fcb7d0fd6b22d11930f1b95e65f790326 refs/tags/v2026.01.20\n0043c2bfb64e064cb9ae4462db090f4172e97e81ce94 refs/tags/v2026.01.27\n0000" + headers: + Cache-Control: + - no-cache, max-age=0, must-revalidate + Content-Security-Policy: + - default-src 'none'; sandbox + Content-Type: + - application/x-git-upload-pack-advertisement + Date: + - Wed, 28 Jan 2026 02:57:59 GMT + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Server: + - GitHub-Babel/3.0 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Vary: + - Accept-Encoding + X-Frame-Options: + - DENY + X-Github-Request-Id: + - 3CCC:2C39E9:3E07FD:471F66:69797B36 + status: 200 OK + code: 200 + duration: 332.52767ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: github.com + form: + service: + - git-upload-pack + headers: + Accept: + - '*/*' + Host: + - github.com + User-Agent: + - go-git/5.x + url: https://github.com/google/osv-scanner/info/refs?service=git-upload-pack + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: "001e# service=git-upload-pack\n000001598f331748cbf2fe2be094f9a81ba80bd3f792aa82 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/main filter object-format=sha1 agent=git/github-bdd2406f1b30-Linux\n004d757fbb92c2c3359ca69aadc5a85aaa3c5abee052 refs/heads/bot/update-cassettes\n003dfdb259edbbe6f4fa3dde383c68759ece3d54c207 refs/heads/docs\n0070f0edc1825fba3e79d09e15a4cb2b30aed5c130d8 refs/heads/feat/enable-renovate-major-updates-11216662903080576104\n003d8f331748cbf2fe2be094f9a81ba80bd3f792aa82 refs/heads/main\n003cde3fd42ed3747a98612b03de1bd42cfedb741dc6 refs/heads/mcp\n005090966848c36befc986cf48f30a3fa0672197bc8a refs/heads/patch-test-cov-workflow\n004594537957531a848f3d31aa048e5dda0266e9b188 refs/heads/python-reach\n004de8f8dc9e7067c68eefae517e6a8399c7c9e19469 refs/heads/remove-debug-headers\n003bb37c83e19af3b2555864457cbd0b08ef0e1f9d7d refs/heads/v1\n003b459ca69939984dc05f15b77720aa81c672aeb5cc refs/heads/v2\n0045e07bdda0f37bd741579e46be40608c65ef8fdd44 refs/heads/v2.0.3-patch\n003edeb877d9e9e5903ded7f86130ee8a2bba1de9418 refs/pull/1/head\n0040a391f89e35b799e631596eabd6e99bd7c37ff359 refs/pull/100/head\n0041f25ebde349d6906ffcd1c9e313752af4c79ecf9c refs/pull/1000/head\n0041bc649da1efe99e7fb302734ec09b611be08348c8 refs/pull/1001/head\n0041dc901f4adfb43f11a97d6fa23842cc6823badaf8 refs/pull/1002/head\n00410c3e76fa4abb53b25c79c75697bb87feccd7f457 refs/pull/1003/head\n004154dcc5a31c3a5b3377f96ae3275d925ee3e9773e refs/pull/1004/head\n00418a1fe256d51dd585ee6dbb2cc966006ff6fb269c refs/pull/1006/head\n004179066e42fee756592da5e477cead1980ec71e34c refs/pull/1007/head\n0041edc44a752b9f9c77ae66ae40ab6fd4d03912672d refs/pull/1008/head\n00416d68a3cd1382a7657f8aba1d743b9e83f18c37db refs/pull/1011/head\n004117ba4664d930f16611e16f760f4279926a6ee4e7 refs/pull/1012/head\n0041eff3a57bfef84a0073b23f7b3990d362afc01c32 refs/pull/1014/head\n00412faec986b74428dbe627f303f4628d25added7e4 refs/pull/1016/head\n004173511f772e1ef2513cbee2f43e3f90600c70434e refs/pull/1017/head\n0041cad99c794525888aede11f92bd936266d05da8a4 refs/pull/1018/head\n0041405facd57b0611263bf05dac83cb4990bc971216 refs/pull/1019/head\n0041e8d4ea7d464cf0e5b32ea1405d031da735852ec9 refs/pull/1020/head\n0041979d2e0004a583bb9a824fb410cf1711a00b641e refs/pull/1022/head\n0041dada9e1f5ca1059abe5d9d176fd2f52a5b880262 refs/pull/1023/head\n00413a1ff30b56ba73b533a7378e57a654dec8aef3f3 refs/pull/1024/head\n00413891cbc53e370d203ccfa25711bf3d22830bc5d4 refs/pull/1025/head\n0041cf8acae39de43327b99c0464783030b3d8de01af refs/pull/1027/head\n004187ce5b1985c1abcaa7337941d0629fc2013c2dff refs/pull/1028/head\n004183ac4f1b7af1d5b3080b5587dd1027cebd1ac4af refs/pull/1029/head\n0040cd6eb8b02933f1c515f22b22d4d60196643ed010 refs/pull/103/head\n004145c69a08c7cb8b9ad5f49de049832662d7fb5596 refs/pull/1030/head\n004139a4a43e9d686194f8bf87b22640275d6898c974 refs/pull/1032/head\n00413efc13fe91382e13a7fa7db33f56d5af24901dd8 refs/pull/1033/head\n0041134ba91d1941c3e8ddb248bdf4877f0948f9b8da refs/pull/1034/head\n00418813d5c1faf2c1b8ac8332b273dee3d98996f77d refs/pull/1035/head\n0041dd87a911bb12a08155f40f7cd080271d7d858cec refs/pull/1036/head\n004165099131e8430832af0e4b688e92fe99857845df refs/pull/1037/head\n00412e72de2d7278cddbec0b02f917ddb3e4fa623d78 refs/pull/1038/head\n0041d9b037c52a95370872c2b639e14496380145bf78 refs/pull/1039/head\n0040bce873c632b00bb26ffb04ca5b56512c5cc588cd refs/pull/104/head\n0041c815f92e90a158bf0f98819d98fc95298d4c702d refs/pull/1040/head\n0041f0a5b399fca77336169a5099122c1c3f6d9786e8 refs/pull/1041/head\n0041c571e7a1999d00ec8e73bac96319119912fcc651 refs/pull/1042/head\n0041445b082f8fb17498523aa22e464eb06d9205fd8b refs/pull/1043/head\n00418959bc2922ff35886b6c37475e42be966a2ad2d0 refs/pull/1044/head\n0041d133fffb1223c353fe853c7288c335f459a79cf5 refs/pull/1046/head\n00414bfcfd8d45552a0558081ecee29cf0130030c101 refs/pull/1047/head\n004173e259495b1b59c248a95506a7dbc8169f60a672 refs/pull/1049/head\n0041e4a30c0b4730b816b4a64256a68ea9e6a78b227e refs/pull/1050/head\n00411787268638442da07a0da0d6959db2ab8360da7d refs/pull/1051/head\n0041b6c00baad38ff80c547805986fa472ac6a931ec7 refs/pull/1052/head\n004145b3e221b39c4045d7754cd2830461b4bbc19fb9 refs/pull/1054/head\n00418a4f3424be29d100df9d16ab6af7bd60e8d921fa refs/pull/1055/head\n0041e52a74fe02f13e4c49ce4a95a7be9df1b146066d refs/pull/1056/head\n004146aee59befed6edb5fc737ef35b5febf987cffa9 refs/pull/1057/head\n00417db4dc3cc71f2c7188b8e7ff40187ff6ce0976e5 refs/pull/1058/head\n004002f2d3a1541918e91bb634c093a8f588b5f724e1 refs/pull/106/head\n00414418e85c4c0ede19fde83af9047ab74455f29ce5 refs/pull/1061/head\n00416630c39aa158eddae0abf9ff3e6d560dfec800cc refs/pull/1062/head\n004103558e2672a2d500a64621ef829828462475077a refs/pull/1063/head\n00412d316b735abbc0533d73e7fb5cd36530803d6075 refs/pull/1064/head\n00411e6c0cf8e25d4ec983ff9e116ca9fe5b4051284b refs/pull/1065/head\n0041e7b146c4dbfc2461e161366f39bf57359b41473e refs/pull/1066/head\n0041f94fedc0ffd685597f21cc132b08807bc4a2bc8c refs/pull/1067/head\n004130165312de801e22db722999e2e31b1c0ab872e4 refs/pull/1068/head\n0041f45c37d02b1237018b424da7644e745b3ae4fa29 refs/pull/1069/head\n0040417538354a2d1b8206b21047463195d0e63833ec refs/pull/107/head\n0041f5e15c258ebd6d3b899da8376d85b34e5fdc5322 refs/pull/1071/head\n0041e6b1130d37421c1750d6aadcafd622dac4f1bd22 refs/pull/1072/head\n0041ff3dcbdb5eece230a9e76ce516c33b7028ebbc8c refs/pull/1073/head\n0041c42a060ca4e670c5f6eead047788d3ba66a624f6 refs/pull/1074/head\n0041abf8f3732189338b9ec6dd0849157c8f012c10a5 refs/pull/1076/head\n004154b4c20f39be518c9564320befba3a752c955a95 refs/pull/1078/head\n004131949d5ee53fe01aab33b186cbad32fbf2d3d1d7 refs/pull/1079/head\n00402dbccfcf4113d7c6981274155e5c7c242c4c8b23 refs/pull/108/head\n004101c0329ad2aa6b7de43c15645f2581b7ef8c690f refs/pull/1080/head\n00414ed4f57bd8d1e7ad8e9007f756bfca75ed99c6ab refs/pull/1081/head\n0041934e83b6c18732e939343be1f6d63ee994816992 refs/pull/1082/head\n0041292bde6461c6674545d6249e58d33650ca3f103e refs/pull/1083/head\n00411a86cd77b171c6eca9f241f4b56f9d2e02e847e5 refs/pull/1084/head\n0041a566698126749fc1de5d522e495adfed74aa63e7 refs/pull/1085/head\n0041b54b8568f1ba511b7680276e3890e9159bb9de16 refs/pull/1086/head\n004186bff5bb894d8e940f35631034a46c277caad53b refs/pull/1087/head\n0041e161a918a5dc08c87139f0f953c63191535309c0 refs/pull/1088/head\n00412130913b3113688700c8a1c214df29354b6544b0 refs/pull/1089/head\n0040efe52963c923ec97ec0e7f823d70519f8afc1301 refs/pull/109/head\n004143a04e48ed25e86d2925774e79ae6e4bc8c6c9e5 refs/pull/1091/head\n0041d3e51e01080d1940692e104bc514733365ea5eb7 refs/pull/1092/head\n0041dff227a1d460cf02cfd3650019b5dd8b0691abc6 refs/pull/1093/head\n00411c07b6a25dd94d49cc0679815e0aa4aeb3a61c96 refs/pull/1094/head\n0041409562060f908ac5f94b44ac0e68aab0f7d52d6e refs/pull/1096/head\n00412b8500391d3df93895706a61043d579e93f53b8d refs/pull/1099/head\n0041aba467c89fb866c51401ff528011689ad768f997 refs/pull/1100/head\n00414d7d179410b09c4594e9c52f7748b079f1bcc89e refs/pull/1101/head\n004138ce57ecd457248e9f11698c72770e9b239741b3 refs/pull/1102/head\n0041c37ab03ea07ff99b1f9af69ef47795cf82c58efd refs/pull/1103/head\n0041063d02a9ed36e7fce9ce3e4f55a310e580da3eba refs/pull/1104/head\n00417177faac71408a3f64973600dd927dff7daa9e7f refs/pull/1105/head\n0041865580eed5d1c65cd617cb05df1b95a80d6f6475 refs/pull/1106/head\n004121070112f28273b4a0e89e08477bd17cfef64355 refs/pull/1107/head\n004163bbf6482bb377b05f9d620ec10ab67c69e244e3 refs/pull/1108/head\n004137a2bfac38496527284133c9b90a9355c93904a1 refs/pull/1109/head\n00418fa27e18df788fdcb00229a7c9a2e02bfe085391 refs/pull/1110/head\n0041c6a342e088c30f21a12044ff42783b5de893ee8f refs/pull/1112/head\n0041bb3976c6735daeceeb96a1461695498d09b92ab1 refs/pull/1113/head\n00418dfb55a6c6a406da3c244783c6e4df7167f8ff9d refs/pull/1114/head\n0041b86b180baeceffbdadaadda02d7dfd51f14fa8de refs/pull/1116/head\n00416ec43bb6687374b8885a6af623e2d4159d74b133 refs/pull/1117/head\n0041e47cf0488f5bd1c156207a17cb2a63332f8c5465 refs/pull/1119/head\n004160d00a1b00d179d5e62b607ad689b81603e8cfb3 refs/pull/1120/head\n0041be4c1511cb9945992ae27ae2ca99a94565aea784 refs/pull/1125/head\n00410aed4352dd2d7fa9eb1be6d623ee875a34c53b4d refs/pull/1126/head\n0041fc7c97dd30f370c79289394eb2c4e2750c9be1c0 refs/pull/1130/head\n0041082984133361132f3b7da7deb989c659e7844359 refs/pull/1131/head\n0041888d30a834cb5872216577da5926f887a2575bb5 refs/pull/1132/head\n004141aca0b4cf0c7f836d2023c26eed5e5fce1f29a4 refs/pull/1133/head\n004103f9a9e28f9121df58c689983b2d69364b54fef8 refs/pull/1134/head\n0041d0038e926e44873980f77566bfdfa2ced2ed04fa refs/pull/1135/head\n0041cfe2c22993c301b2adec721af28530c666fb7b42 refs/pull/1136/head\n00410dbc58619c0809668be780f04a9034490e43f18c refs/pull/1139/head\n0041b3846b125c6c2b4746124144bec86168d8728389 refs/pull/1140/head\n00418b0043f2bb68c82968c4faef65936e1ef319ad1d refs/pull/1142/head\n00415a560fdcc101de924791d1d134ca283bf1610280 refs/pull/1143/head\n0041951ee1cbcc4dc717146491707e6af74f90cfc1c3 refs/pull/1144/head\n004167a68f7c044ebc003d9676dd582ac8c03ea46015 refs/pull/1145/head\n0041e4b00eb8b0e455bf7b299e11a53870403401d15e refs/pull/1146/head\n00417a633fbcff3a162b1f8a5856671d0316de356052 refs/pull/1147/head\n0041c9147b953308f3843c53442a1c17aa36934611fd refs/pull/1148/head\n0041af9d4d8cf408ac7a7d3b9f065173efadfc05ce93 refs/pull/1149/head\n004118ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/pull/1150/head\n00419ed7e6a4606b6f56c867ca0122df3fc3b43cf15e refs/pull/1151/head\n0041b29e4f2d7853e4b8635e885fd5717396922c5800 refs/pull/1152/head\n0041049cae20632df72010d0152ad145fe2c53c0ea7a refs/pull/1153/head\n0041f5748b91249cd51f64ce6024c93e564d36da7660 refs/pull/1154/head\n0041bbe8e0dfd255daa91a917159978ae5eafb0e84ef refs/pull/1156/head\n00413626dc731e649f2c663e2e60000875ef5eecedb1 refs/pull/1157/head\n00416c04fc849888eb29dc0e4261438190aa3694c1ec refs/pull/1158/head\n0041a519b872414443e8156dc4d10f21a4117b564458 refs/pull/1159/head\n00400eeb975ae48214001e9941825c9a749b1c7d391e refs/pull/116/head\n004183fcad5bfc1ee90a46b5d9d5dbcf0e5e9ae8dc0a refs/pull/1160/head\n004192c034b24ad6572c1fff1bf0f0d446a8a5cb5eae refs/pull/1161/head\n0041cbe5f793ac2d9849e408f2ba0855af7f2dd8c0f8 refs/pull/1162/head\n00416ddbf9c9fa623fa7e882bce8137e95c5407cd79b refs/pull/1163/head\n00417c216e1be51960819f1c68c490bb2405d09a8236 refs/pull/1164/head\n00417d1ddb86ca16b3a2f949735d4e45057eb6f04804 refs/pull/1165/head\n00413222d5c3516ce1a96b0ac746d54ee9f8e80272fb refs/pull/1166/head\n00418617d676df88783fc65bd20489ca97200953f506 refs/pull/1167/head\n004164629568f9b9eb49f02b67527bb1624ab92494a4 refs/pull/1168/head\n004140a413bef66c53b2d6a1479b4753605744368b57 refs/pull/1171/head\n00410fd65ae3d1bf6e20ea905918e19713f3de62abe0 refs/pull/1172/head\n004192c034b24ad6572c1fff1bf0f0d446a8a5cb5eae refs/pull/1173/head\n0041cbe5f793ac2d9849e408f2ba0855af7f2dd8c0f8 refs/pull/1174/head\n0041cae28fde3b0739a2f25d99a99c98818f47d3e2bf refs/pull/1175/head\n004117d5536fe26f0bbecbf4a29d362c656971a8d9a1 refs/pull/1176/head\n0041ad1587210218e118ddcd6761e8e4cbc75480d2e6 refs/pull/1178/head\n0040a8afeba5d2335ebc47468154d19dff204ad9b613 refs/pull/118/head\n0041c463e1a594ae0ae9b513c8906334e998927101d3 refs/pull/1180/head\n00418c91a9ef4069448fda215afc0a691fa38316412c refs/pull/1181/head\n00417a847927be170a2deb2e5e2a945f8ccf98f91c14 refs/pull/1182/head\n004103488b1640bf60069e01fac924e97d2574490b6e refs/pull/1185/head\n0041545511100a9da8f5f5960c85ff178dd0369234bd refs/pull/1186/head\n0041e65d709f34eea3aef2269027c591016db5ab107c refs/pull/1187/head\n0041ffef0e2264e4e6d00639a385fa8dcd54e1b4ed37 refs/pull/1188/head\n0041c15d0948990b83575c8185df109ee78a9eca53a8 refs/pull/1189/head\n00419d9a7feafeef27bd32f7953aacec878951803197 refs/pull/1190/head\n0041eee13d0b2da6c19ef6081b7f1783f8e94625115a refs/pull/1191/head\n0041e79c7e2ab11ddacfe9ec48ceb558f0e296838f44 refs/pull/1192/head\n004184fd6e653a980da668b156b5deee26be0e0967ec refs/pull/1193/head\n004139b28f6c60a48fd0da014f7f121df58dde003ff3 refs/pull/1194/head\n0041d3e93e6be83f109e267661ac2aa4b0e3f14a59d8 refs/pull/1195/head\n0041dd4eef1324058fbbe9944909f8f0313617937195 refs/pull/1196/head\n004181e79baae5d66cd9155f46aafbbd56f0211c6aad refs/pull/1197/head\n004118ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/pull/1198/head\n0041ea17adac1c68c8ba7a04416828ab43e325e129cc refs/pull/1199/head\n004050b255408f4f5f98782027a92625ac97efeb8a0f refs/pull/120/head\n00416572931823db1ffb300832370b5db278e087b747 refs/pull/1200/head\n0041ada41b5104beb670322d7ae4a3ba8cf74daf59b4 refs/pull/1201/head\n0041d5330143583beaa96a58e452d72ced83785b5214 refs/pull/1202/head\n004169c1f7bda71f8c29f9fecc385cb65f04cea7693f refs/pull/1204/head\n00411338171fd1c8f545788fe4c14223c94e32443c2a refs/pull/1205/head\n0041f4f08a3b51ac6a60d087c150a5536dd749c01ca6 refs/pull/1206/head\n0041fb08aec4cc27297c2341d8c525b5639f366d7271 refs/pull/1207/head\n0041d39c1c9ed3e6c660d16d66f5f2864c51b74e435d refs/pull/1209/head\n00408a9fceb768f58ef0d65e70a8c9148acc58f55c66 refs/pull/121/head\n00416200dbfb1e586f702433384fc9462c95eed6f795 refs/pull/1210/head\n00417a5ed553932174c0207cfd68a0ce47ca853ef87b refs/pull/1212/head\n0041b8f620908376460ab72847f2fc73e4971df04978 refs/pull/1214/head\n0041f63802d0c7fb90a1c453dfa5d0530a1080d86521 refs/pull/1216/head\n0041ea257edd99d727d70cbafb56094a2eceacecb0bc refs/pull/1217/head\n00416adf5b9ea0eed8c8ff4340002472a6b53220edc5 refs/pull/1218/head\n00412a11fb082ce7cf96848f083c65002a51f3e54617 refs/pull/1219/head\n00416eccd998bbf7a3379a89732a9151ea7ee7222da9 refs/pull/1222/head\n00410c6554d500e645c78c9841cf00362ceba24cfc09 refs/pull/1223/head\n0041a291568e23fcbdecc4fdf5a57e81675eb1e3ac8d refs/pull/1224/head\n0041e9ae9d8fd4b97eccf2834983057a753a6efe9624 refs/pull/1225/head\n0041e2f771ca6d18fdf5282b4b9c3d48ae697c231495 refs/pull/1228/head\n0041315d44f6684182e6ef4d13940b10da4982dfdf11 refs/pull/1230/head\n0041534fe4077f8cbffcb48612a8db6cf58fb619270b refs/pull/1231/head\n00412f25c0586f675337030648e460da55393623f98b refs/pull/1232/head\n00418669c5b02dce839f4cce3ba83641c1f23a6d600a refs/pull/1233/head\n004108737789cf3c1f5cfc7afb96fb3c521758f6c36a refs/pull/1234/head\n0041ac050307e5c0cc6d7347bbfbd3c315c2a37b6ed5 refs/pull/1235/head\n0041225c71adeb9b8fb85b8e38a59706b5f52289a038 refs/pull/1236/head\n0041b38d9be3031e82a6b0f0d03b771e76c2c6602e4c refs/pull/1237/head\n00410167354914b745a448bd1f49cfc003eeb03c41c5 refs/pull/1241/head\n00412236e21a96f17837f3813f95000390169364eb63 refs/pull/1242/head\n00414703d2ad140205d31f89bf6260db52c52aa38e85 refs/pull/1243/head\n00414383f8580dfe6625844aa7d4c64e7d989c2ee72a refs/pull/1245/head\n0041ac8bfefb6bc528d158a5bb2efd1ddd09f9d59fdf refs/pull/1246/head\n0041f0b5858d6155b2bbd492d38bcc76bc4a9f34921b refs/pull/1247/head\n0041475fdc44fa132bf5590b9d1ccea658ce6a28f09e refs/pull/1248/head\n004172f897a002198a41584f38600d16485e524dd07d refs/pull/1249/head\n00406a07233ef752078d694abbd60cdde844e1674caf refs/pull/125/head\n004183ecc28c123d1c718b4c0a9687155f114fc38e9e refs/pull/1250/head\n004157b6ffc3a322ac6916e83cb3193698aa1befaf57 refs/pull/1251/head\n0041f88f82ee8505c4c94bdf75f0deea320af8866689 refs/pull/1252/head\n004180c6f8fda395d0fd8ca3de9f3d5d68cee2ba79d3 refs/pull/1253/head\n0041a1cf3cc412d127a44f8b99e23ec74d3480f56d1c refs/pull/1254/head\n004175c953aaf4439439a7502b427d6b38683c5281dd refs/pull/1255/head\n0041de528bfcfc8bfe071ba0c947e2c11f2c79e2c0f1 refs/pull/1256/head\n004196505fb6b2261b20dae04c55c0a379ea13eb34a5 refs/pull/1258/head\n004191f842d6286dfa26be459843312d62d4e8f7433d refs/pull/1259/head\n0041710aa96e02cf952b35210ea5f899a5fd0e7b8d0c refs/pull/1262/head\n00416e65903bcad7e04e514def27218793c53b1e69d8 refs/pull/1263/head\n0041bd8b8cb78af26a197641a82ae6c115185b96fd4a refs/pull/1264/head\n0041b6282b1fb7835f6f6080a0940f48b41168a8c919 refs/pull/1265/head\n004110ac754b3f2626cc391d7d97f1dc08eb52579eae refs/pull/1267/head\n00418da891eea0e42399a9f899fd8152f33b13b24f00 refs/pull/1268/head\n00401a0a14ce657c6a734ff5b06c81bbdc5277f3eeac refs/pull/127/head\n004163069536655b236a1525dc8bba8a27058fd55909 refs/pull/1270/head\n00417c1f0ad35f808287d2178468670fe058c4e4a6c3 refs/pull/1271/head\n0041b3c382937944a2d89d570c5c9716bafa864d8367 refs/pull/1272/head\n0041235e651de40e076d797c5106c6d47a0bb650f9d8 refs/pull/1276/head\n00413b683d9751c80c079c1e0e825b1a8c9af6ee2b86 refs/pull/1278/head\n0041c04e4c32b9081366ff01f5ac5af7eabfa87d3567 refs/pull/1279/head\n0040a3aa0190ec02fb50a9dc0ca3caa1e16d3551c197 refs/pull/128/head\n004108fba240eeebe70947595650002dcd5284c75e02 refs/pull/1281/head\n0041ebbef8dd520d32bae9adbff1a7b9afd5c297f137 refs/pull/1282/head\n0041462044a0aff0ab62614a85494ae5abcc6ce8f383 refs/pull/1283/head\n0041818ff67309775befc7321334b19244d20eb5ad06 refs/pull/1284/head\n0041b7b439cd14315139a6cff36df561c44b04b48c28 refs/pull/1285/head\n0041b0295ef926958d7b55e81c37de0c30ba067ae9ec refs/pull/1286/head\n004167d190b2d6f2a2ea4010416a8782e77a84944591 refs/pull/1288/head\n0041b0ad3a3c2352b4c9109ad238492e5a46ff318e37 refs/pull/1289/head\n0040217d6ec0d38cb8e49bbc0db6f3163003185cbabd refs/pull/129/head\n004177c1b1512bd9964011504bfd68e38953ae8fb04b refs/pull/1290/head\n0041a9e187010bda994c39a689d9fac4c62e8dff8e4e refs/pull/1292/head\n0041c8293cfa71f6e1a3f116036d6f414934f27dbf45 refs/pull/1294/head\n00417252d799111d4e456a0e4791055759210c19cc5a refs/pull/1296/head\n004164121e70812cb3bbacbc05660f7c6b32a380b37f refs/pull/1297/head\n004069f3513b4283e207b7456f5c97c3965bdcdcea0d refs/pull/130/head\n0041e9d6af87cf13d39f906b3e871449de8be0d9652e refs/pull/1300/head\n0041b701bb932f23723fe23d1c31c986cab6e3a25f16 refs/pull/1301/head\n0041ce44f45d5814d2338b41db6a02b9673a3bcac3e1 refs/pull/1302/head\n00411990166a4d5d917bffef8041c5e759122a5013df refs/pull/1303/head\n004127e78452afa10e75822537c1dc59f6c6e356c595 refs/pull/1304/head\n0041ddfd8b7c2f88d59e30fa17f1de599229257e6065 refs/pull/1306/head\n0041685dcc529073914e74da04846f3b11681d929868 refs/pull/1307/head\n0041399fd2f34cd6b84402f0c13d83f5c32a30869564 refs/pull/1308/head\n00411c7fa1f74a4d8dd784c4f05e9a9935b7a5c57e53 refs/pull/1309/head\n0040d3516d03ffe9f58ccede1ba3f544c574aa42f1ae refs/pull/131/head\n0041847f678420fefdcadfb632c520aecc997fca7ad1 refs/pull/1310/head\n0041c0265ae333dffa5f9cca62ac86f2ad5fec5a1474 refs/pull/1311/head\n0041ce637c03ec641463a65e6b74f29bc37c01ec4e45 refs/pull/1312/head\n004101a835202ec0d542141d210dbfd2f90f66814b9a refs/pull/1313/head\n00410dd20c733ac6ccb111a3330defae5adc6d5bd781 refs/pull/1314/head\n0041e41448722c681fe02b85e191c71e2c6c41519c8f refs/pull/1317/head\n004191473d1e455fa02079f456824b12ef220a1e4669 refs/pull/1318/head\n0041fe26cfde41df51635bd570288417e1b8f900ec06 refs/pull/1319/head\n00406a59ad3005e8b3baa88b54dd78e4279a4ccc1661 refs/pull/132/head\n0041c572a95f0a91d0ba402d87df9df8b81429c1603e refs/pull/1320/head\n0041d7a1dfe27a2ec072b32c04726d1d75210ef458fc refs/pull/1322/head\n0041968219e91fd95d2807d08b2b6408828cf3b9d1ec refs/pull/1323/head\n00414b392829b8b857d0287306b4a777f8bbfac639ba refs/pull/1324/head\n00410d7258d93688371bfe1caafebf1ce25cf2d22c23 refs/pull/1325/head\n004122be1d6029c6800cac1c2d42d83f71d7c2fd0079 refs/pull/1326/head\n0041a848fde40c72868e91d113353040a36dfe66813d refs/pull/1327/head\n004174b9bafc9ef5afb38700b92ccb7910af61796bbe refs/pull/1328/head\n004122a69e7f74563c51baeb8a8a8e1b802cbff1a7c8 refs/pull/1329/head\n00400f26eb0aa416cc1020b34f09af4e3f1e6eae343b refs/pull/133/head\n0041d1e9eb6d2b4f2c9d50a9c7f795f66062b1e1e089 refs/pull/1330/head\n0041c92bc3ee8f289f7e8eb2e9ceb78ab23985187d2b refs/pull/1331/head\n00412e2472b51b6074986ca422c25f98458e545c5487 refs/pull/1333/head\n0041a1083492f1f3b80dd53b3867dfb0e5f3e426f235 refs/pull/1334/head\n0041c700a6d603146f63e1c44653c1c5d40129e41722 refs/pull/1335/head\n00417c38d42344d396e6696a6a2033940b4f035e8e61 refs/pull/1337/head\n004177dd1ab81d345dca937a730341f3ad1c1904f4e9 refs/pull/1338/head\n00401b6c824ec12c00012a6d8427d6b0b34bdab8a034 refs/pull/134/head\n0041d86d572bab3c0671ee27d6336525cc8d55bf14af refs/pull/1340/head\n004155d2b0b1622b1413f489faa2bac980570512dc2e refs/pull/1341/head\n0041aa0a73405e98ae8d7b009e640456e4f571c73d21 refs/pull/1342/head\n004134ec5f9ce21a0e78d8e0d2a4fec8774403f75977 refs/pull/1343/head\n00415e0e19603f2027312246a0893faa8df5a36a2823 refs/pull/1344/head\n004159fd1b67e48574ee67c555bdade0af902e80ba27 refs/pull/1345/head\n00411372c29d076919391d1c695f0e6e76c9b5af343b refs/pull/1346/head\n00415a06b0bf8d3e46f7f31862aae34740269eeb88c1 refs/pull/1347/head\n004151118e711f25f0dce51af42459d39cda11eb5433 refs/pull/1348/head\n00416d14ddfdb397a7398b94152eb232d437a923d596 refs/pull/1349/head\n0040f24cba8f5ff6944a00c8be4c2dad774441035417 refs/pull/135/head\n00413aec658335ca7c5070c983a318398b85355747a7 refs/pull/1350/head\n00419958913d8b7e945d8b6d28d9fae4647febba959d refs/pull/1351/head\n0041e69c278a9b4c732ccb3c7b9ec8efd7f2c7bfe2a5 refs/pull/1353/head\n0041e4111c6737270d759ff61d20fe7ac15809644c62 refs/pull/1354/head\n00414085480a5528f688316d82698bde948ca9ac65ff refs/pull/1355/head\n0041cc321c111f93ef054d10057dbe28c2d9a109adee refs/pull/1356/head\n00411f69d4abd935d0a0d5d0da7837332c86a338a327 refs/pull/1357/head\n004147c580a9c60f044d6422a6d4ea341e8e73a22bec refs/pull/1358/head\n0041da8f4613f1d55a398b248256e1dbb2f9f90c4c5b refs/pull/1359/head\n0040ab796cf9328a5820baffbfdc785c11090e9799c8 refs/pull/136/head\n0041fb5a1d4cfbde3365f9c713b0c5db03218c9585e9 refs/pull/1360/head\n0041e6f77d85c352124f058de4a436cc67d2f2e30b64 refs/pull/1361/head\n004133f44bb126ccac62932b191c35b4f86ff35f2c54 refs/pull/1362/head\n00417d14ca8714a53b43b81fdbaf7dcb4d731e5ec59d refs/pull/1363/head\n0041d6f327bed5d1a899d71f716f1a6ab51df3c988d2 refs/pull/1364/head\n0041fedd017ee04380f5744c0a9a1fc07bd691cdd085 refs/pull/1365/head\n004157602cfa89f24660a262be44f4264afcade40596 refs/pull/1366/head\n0041420883c835fce5c1fdf9e31b2c4b2a1ba45ca3ff refs/pull/1368/head\n004111c85d3805418506d0b619fda3c646a388226d0c refs/pull/1369/head\n0040195ea6539b352979d11678d7731b59e84b976097 refs/pull/137/head\n00415ab467b5f0fefcdd6a0787f0ccd2ca9e97a0cf34 refs/pull/1370/head\n00419da99970b254b871a55c53e1b79d56aa73beb940 refs/pull/1371/head\n0041ed2599f2ed8167bbe784a9959ebe38c56335d518 refs/pull/1372/head\n00417a01ec6defdcce5a201ab284bd6353a71eabd196 refs/pull/1373/head\n00410cc32c70050d32375c9e546a100cd7c7777d80e0 refs/pull/1374/head\n00416816a5a92084da7236800e387a426d5651282a98 refs/pull/1375/head\n00413b1dd44df2530950029c8b9ba57d71255c9c6dbc refs/pull/1376/head\n0041cff37efef97deeb840a05829eba8df1e550b3902 refs/pull/1377/head\n004076f9add1c183150181ef213445762223afc918d5 refs/pull/138/head\n00417ac90975be4b80d894f0eb22fedafc0a57f1ddef refs/pull/1380/head\n004105c7fbc5e16350562f5c8f28c5383536588450f5 refs/pull/1381/head\n00417dfaef3c89adc165462a8ddc3be935e73bd36797 refs/pull/1382/head\n004134b8fc16757f65e7b3e90d439370c3cc39255911 refs/pull/1383/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1384/head\n0041d0f2e9bc0d3264cb1bb2c8f2b4ee906f3e1176de refs/pull/1385/head\n0041c20a188c9aec80c3ede2f7dd2eb87f526473bd65 refs/pull/1386/head\n00411cbf39c1fcfef7798b4813cb32a1376046717e88 refs/pull/1388/head\n00411d73b6292aa98bad2bd03288ad6113bf5f1a60cc refs/pull/1389/head\n0040786a4c116c797f5f052c82cbebdda34a172387c6 refs/pull/139/head\n0041cbc9a5c1531aa5cad02723107561294ca15b331d refs/pull/1390/head\n0041d454468b07554c64b73a0b18ad95ed94981bdc0b refs/pull/1392/head\n0041789fa98adf61b0f1386064ced86159ac9f2553d5 refs/pull/1393/head\n00413344c6fb9adc24e42a8a4bbb8a9072eaadb9392b refs/pull/1394/head\n0041a5db8f658afc1a4f96e972644f39c32c1462a714 refs/pull/1395/head\n0041317dde7e40b174b3cf2839d117ae7a2c5dcbfa1a refs/pull/1396/head\n0041b3bcc7c3801ad5dc9e096beeae896c614a663ed2 refs/pull/1397/head\n00419b26d0971b2e052b10c59a4b179287ae92a7b155 refs/pull/1398/head\n00415e665ee1c2eabbd103cc5d74e5da5228e227dc0e refs/pull/1399/head\n00408abf79b887bdf2b7d970159a720892047c8ebadc refs/pull/140/head\n004136457c0b3d9c3aa47e16a7089bb41dcad6eec907 refs/pull/1401/head\n0041f498a5cfb98dd66ee5163b021488cae184c8d24e refs/pull/1402/head\n0041f1088d092b4df04f4056fca730394c23b3b17573 refs/pull/1403/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1404/head\n0041662715d7828c9853635c002d2100247363424449 refs/pull/1407/head\n0041c64c12b83e9d51511a748a70757f20690ddd3a31 refs/pull/1408/head\n0040913404cad952b608e2517580fa108a81460af531 refs/pull/141/head\n0041d162902a177573ea0341f4fc88b98b1f0f25fc57 refs/pull/1412/head\n00414eb483a1cf40089a2a2d5fa201e8975eb8706e7d refs/pull/1413/head\n0041ac89c5db51165ebfa78349979fea2e5eb166dba8 refs/pull/1414/head\n00417e07f4badd8465a6af84261cc0a5fbca3266604b refs/pull/1415/head\n0041b9e1c8381ab55609eef988418b70f850c6020de6 refs/pull/1416/head\n004109ad387ef44204b45b792cea92e2df799f3fc640 refs/pull/1418/head\n004167f7c3cb274c2e016881632ec4ff1356de0f8d18 refs/pull/1420/head\n00412af026f9942ab90ec9e698a8ad33803bb281b644 refs/pull/1421/head\n0041e2f40cd5d4b8a0508c2af944c49dffe469c09c3c refs/pull/1422/head\n0041a4a759d446a8aad1a8b12b63a82119a4c96cd23c refs/pull/1424/head\n004158d10f418fcfc6963a61dc845452e67792c07987 refs/pull/1425/head\n00410ba2087323b4e589157f928a5e4687c943b75723 refs/pull/1426/head\n00412a684541e3d2eeb59c2724039ca4559f9f4b94e5 refs/pull/1427/head\n0041c9e37bb52435738984a5cd8103b38b1aaf2c8734 refs/pull/1429/head\n0040255fe11304bf0f866e1a8bd8b9eda301db237693 refs/pull/143/head\n00411db0f8c1bd9adb6d2f759d71bb321a0ffa7791c0 refs/pull/1430/head\n0041b57b16c42a449ed0af7ecefd0e114c1ad15a8a6c refs/pull/1431/head\n0041459ca69939984dc05f15b77720aa81c672aeb5cc refs/pull/1434/head\n00410f37ac0525399c0bdeffbbea32e8f3ee78852a30 refs/pull/1435/head\n0041be6697582272417402c495d8fdebba36e4aa3a2e refs/pull/1436/head\n0041a5ba738874dc0331d3254e80d1f18b8d4efce8c9 refs/pull/1437/head\n004177e7e8ac271c1b9f3c53c374140c44d2513bf037 refs/pull/1438/head\n0041bbb832ba4b2ab40ed39e4e1c1be7c63f5b3f837c refs/pull/1439/head\n0040d5959201463d114551c61c6f096dddd7a8af7e56 refs/pull/144/head\n00419c0cb248c39d172e65a6b9726937f50c9021ffd5 refs/pull/1440/head\n004190f8f453047c16f613e76967b282d07ca6d5f2a4 refs/pull/1441/head\n00418bef7af75b5753b3291a8525458a63b0d01608f1 refs/pull/1444/head\n0041133778dfdd2c7f9998fd305b36c90cd2168bdb14 refs/pull/1445/head\n004167f7c3cb274c2e016881632ec4ff1356de0f8d18 refs/pull/1446/head\n00414f19efb23c7c1be947116d3420f2f840510c4175 refs/pull/1449/head\n0041d35b1fffb1469f0d0cf20dfdc59886d66054888d refs/pull/1450/head\n00412fc1a17c38a1ed301fafb75cf35bb4f2ce8720b8 refs/pull/1451/head\n0041773299d0b951f3402277f8773b651f66dae9405c refs/pull/1452/head\n00410b19d653a8faa1e77ea4552bfd66817420b1dc1b refs/pull/1455/head\n00417afd12d7cf6225b3c991d8d40c11b8c8db61da60 refs/pull/1456/head\n0041d042180adf0d2eb54e75be483337053809010256 refs/pull/1457/head\n0041f0edf0611e71ec179578cccd39b77243e3bdd5a8 refs/pull/1458/head\n0041465f266f9e56f1d58a5b38b86b629dd90f1a4037 refs/pull/1459/head\n0040d87aad784c93c9203eeac218bc8c9e88a3db5cb6 refs/pull/146/head\n0041be9a0dae947de482dd246c4e70666afbe522c619 refs/pull/1461/head\n00417b7150502c0ce679929ef8b2f2ee857664552d23 refs/pull/1462/head\n0041572f35dad64d6588ea96f3bde38a165fee9ff3f9 refs/pull/1463/head\n0041c270c099ad02eb0a23cd8497c4bb4c1dc975f741 refs/pull/1464/head\n0041c422c680a7bbb073523956c926de9310a17b3ff6 refs/pull/1466/head\n004185d6cc2cc79acfdd2061c4fbd600ce4c2f741fee refs/pull/1467/head\n004148ada69b2d8c141901ef529165df93f22d351486 refs/pull/1468/head\n0041be9a0dae947de482dd246c4e70666afbe522c619 refs/pull/1469/head\n004006894e6fec4cc65fc526eea0da822ac85a910f25 refs/pull/147/head\n004168f51c73b84cd2fc045447a09fb539ac912a5d91 refs/pull/1470/head\n0041a65c29ea40b8437572e676e55ae311d14479e9be refs/pull/1472/head\n0041341ace4dd63a182bcc2223f10d17f42aad50a339 refs/pull/1473/head\n00417a099e71b80e8747d27136e7e18409e2070e9b3a refs/pull/1474/head\n0041f170b2ad5d2b4b5477b61658a3c8af36ecc259da refs/pull/1475/head\n00414cf00e7e43cf89136d8aff44e72769efe9976905 refs/pull/1476/head\n0041c7b506f7f2b5425bc9253642b40450abf8269476 refs/pull/1477/head\n0041745d81755163efda96a36c54390c9da367afe86b refs/pull/1478/head\n0041c6d517a24a5781d51d87a484d60873e58a3d3528 refs/pull/1479/head\n004078c4df8242a4962d255d81e4121b14c186461a81 refs/pull/148/head\n004148aa3ce720b918c4d3251b4ada64cceeb33b20a5 refs/pull/1480/head\n0041e18554cc64fc785b79317902fe1fb29df777a7b1 refs/pull/1481/head\n004120b4ff3abaf6f3c5a83428d9293a1d2b51ab5d59 refs/pull/1482/head\n0041c594fbb00b9d4d0e6c0bdee76ef260f1b71aa373 refs/pull/1485/head\n0041231b7cd948eba5f6a67dea0cc433c3d1e83860e5 refs/pull/1487/head\n0041e077713e2fd9260b858e26eb796251d223a22a2c refs/pull/1488/head\n00418d54abb9154b6f8a11daa9a9fe4628399418ab79 refs/pull/1489/head\n00401ad173258d866686cea8878365e007ae56c05536 refs/pull/149/head\n0041b7f85e75a22a60f615bb51396a252ad2226d8b35 refs/pull/1490/head\n004118c31f294a8f038d42c374a4527a791cf11fa8d6 refs/pull/1491/head\n0041680d70c039e5af70ea1f892ebcfd19cb7bbf751f refs/pull/1493/head\n0041ca386287ba9a104728e40da69924e32891a61964 refs/pull/1494/head\n00417a47f4ddb8367212af84b4a14e31bb47d7093a61 refs/pull/1495/head\n0041ea93c334ee1502c974a33f05773e6d6b0be2e44f refs/pull/1496/head\n0041b28e8e652467fe118029756c2b8028e59ecb83f4 refs/pull/1497/head\n0041042076cf5970a4e025941de2a799a8461560ab9c refs/pull/1498/head\n0041c160b6a7ec28855c1273e4d0568ce42a3846450f refs/pull/1499/head\n003f3001a10fb6c4d39f149b8024bd06834d2e0f2bcd refs/pull/15/head\n004115dadb698dd7c9558e5445fa77ed64e3f2621930 refs/pull/1500/head\n0041eb320aed569c5377aa44e11a52feba2548752b03 refs/pull/1501/head\n0041f7f5aa9b3edfb792ecc4da4cbf5f2c6ff6d4cdf1 refs/pull/1502/head\n00415e87da6fcd3a0e9c999a81dbcb749fa8ff41d47e refs/pull/1503/head\n00411f9e058e9511c23323b159db9555807bf0e74787 refs/pull/1504/head\n0041ec5568348734532295ad86143ea119fec68f4ba5 refs/pull/1505/head\n00418b1f30d9b6d5406350deca472cb667e7c46e09b8 refs/pull/1506/head\n0041fb5ad38eeb943393c6af335e89f0ffa22eaf7fac refs/pull/1507/head\n00416c793bfe857449f9a1174643cdf2b9b5ebfe1967 refs/pull/1508/head\n00410e6eebbb86acbc92d6e727bc962be7807b50a765 refs/pull/1509/head\n0041fff0e2e5c58176cc5e4a13a347ce446d76e5c5a9 refs/pull/1510/head\n00412d85a7425c8a13008fbf52b8d45543a1d667175d refs/pull/1511/head\n0041964eb17ceea78e1ec6f495cc5ca324eab3ae12c1 refs/pull/1512/head\n0041e6a3b8bea46f4896b8ac0b92f5dcc042d81b9597 refs/pull/1513/head\n004135aa6907f28c6e6350436053bda59101d55359f3 refs/pull/1514/head\n0041a787cb7fc713f4a381c1281f90bc7a3bfcfcecd0 refs/pull/1515/head\n004128672bde3d91514708f44ae1b71ee780adfc90ac refs/pull/1516/head\n0041a3f9b48f377be38cfa9a9c600b7a73a055424da5 refs/pull/1517/head\n004143a849cfc3f522d10afed28f8136f9f6558aae67 refs/pull/1518/head\n0041f2ea2c03729bd2afb4b2d56321d52809e0bb3c2e refs/pull/1519/head\n0040050259ba69be2b95a70563765a15c42849daaff7 refs/pull/152/head\n00414f55e503a8ab7a7affab771bb1da4993bf61671f refs/pull/1520/head\n00416d07ece41836d1d3df38113c02a49d29bdc0e134 refs/pull/1522/head\n00414b48c91a0a3453090198d11f6a8727842db9d1f0 refs/pull/1523/head\n004138ad3f9aac054ed8871e887c5e0bc3e47cb41f06 refs/pull/1526/head\n004159a6477bf16284b0ed1204c42b490e37021916e2 refs/pull/1527/head\n00417c49448d992a0cbb6c6897bccddbadb62b564817 refs/pull/1530/head\n00419a02ddc6c749dfb28d0fe6cb85a42130c31c62a8 refs/pull/1531/head\n004170b290911ca6bd8796cbc208a11e98510c886f4b refs/pull/1532/head\n004141d92983d7e978b88cd3e49fc276ae059098486b refs/pull/1533/head\n00415c2880379dd3c8f7ceafd8791e17221793b5d980 refs/pull/1534/head\n0041ecf4c8da86c40d510a39b8074c18636b445d3c54 refs/pull/1535/head\n004168158e57f5a7258ff7bb0b9def2e50acc5722bd5 refs/pull/1536/head\n004184ed942ec251f38c8ffabede56aa229674ff4e12 refs/pull/1537/head\n004199cb2854afde5b21790a2384b3e6b7a065d0245d refs/pull/1538/head\n00410ea1a5b8fd2ddad43b9fce09dd4b701eb42f9a7a refs/pull/1539/head\n0041a6602a393c3d8c01feb308e21ae6b7f00e6a65d5 refs/pull/1540/head\n0041a5766dbac237aeb5996e47141547f8403c0bbe54 refs/pull/1541/head\n004160db4ae8523ca3180a50eaf9601ddfa8a9aa343e refs/pull/1542/head\n0041ca31af714a7a0c754d42f14531da4aa6812a27bc refs/pull/1543/head\n004185c8f0287fe9e70649e8e1dc295b10c62f4757a6 refs/pull/1544/head\n004110f90d2558011cb165b5ed8610a93895d14d3540 refs/pull/1545/head\n0041d8a2d1ad19cc557cd8d7dfb71189a50ccc312cab refs/pull/1546/head\n00410b39f6e72317fd3ebed1713f72c3b02e4d5d14da refs/pull/1547/head\n0041c672bf9b5e84698bca8177c2a6d110612484f8a6 refs/pull/1548/head\n004154ffe1e63d69bccaa9c6a22975393dbf20816b85 refs/pull/1549/head\n004180360661d8253639615d914c728179be546b0fde refs/pull/1550/head\n00412f81196691cc6ec6cd61e6879fe7ee719ad58247 refs/pull/1551/head\n00412ce6f5ac188adeed4d94d3296b2c8dfc9e103db7 refs/pull/1552/head\n0041cccacb7e6f96b39e7e452aafa88a540daea45314 refs/pull/1557/head\n0041d84a185ac9b0de0ea518f3c7c61033e8333c29e0 refs/pull/1559/head\n00400d6728af68c3977234c95f97277a9c7e80b26615 refs/pull/156/head\n0041b9c8218ff9aa201c0855be7785850a9689aeaa69 refs/pull/1560/head\n00412a34bbcb74f292c45776917e48bfc8b5fe8c0197 refs/pull/1561/head\n004146229e4e508d6a21436211d7e740f56e0710c2af refs/pull/1562/head\n00415875aa021ddf3961dfe317945b01583c98877bd9 refs/pull/1566/head\n0041207d4f5ec3a726cca709532828999cc5b24298fb refs/pull/1568/head\n00412994d14e821ef14f179da71cc56d6cba60f6d220 refs/pull/1569/head\n0040586de893d3f5a99c4fad86056d2e6f74c62ee729 refs/pull/157/head\n0041f428a60a3252a5223ead6f579817fcbd3909a7dd refs/pull/1579/head\n0040a9cfa8fc63f2cc043e2a9db7b48d8ce5196d99fa refs/pull/158/head\n0041075491fa48e07f794250c751b71420a33d8f1d8d refs/pull/1580/head\n00412b2a1901869811b50dda95b0bbe293bf8ba46844 refs/pull/1581/head\n0041ea8460aa2e510e57710c082cc7f169a00918169a refs/pull/1582/head\n0041f2ae86243215115e28fcfc21c91edbf4d4bc8068 refs/pull/1584/head\n0041ac97b8009acad579563c919ff9e83be8c2708c26 refs/pull/1585/head\n0041f5564caa092815ad5908e376147a84f12a5f4c6d refs/pull/1586/head\n0041a74c74821d1b621a1356e405d2daa9c86cee1821 refs/pull/1587/head\n004177cac1aa0c6d0750997a811dba708a108db0cd8c refs/pull/1588/head\n004178a902ad50439f9a0e05c386194b65cb59e23deb refs/pull/1589/head\n00404bd0fe137d82ed8f3e9c21770a2eb09ff2cdfdb7 refs/pull/159/head\n00415428807637585f9cbce87048220bb65de5b54d19 refs/pull/1590/head\n00412ce86486b53e98596e0aeefba526b36c9584ab05 refs/pull/1591/head\n0041494107c206031c9776d739da0077967f7820bd04 refs/pull/1592/head\n0041f9be7c1a9f2d78a6ebe2e0033446a5ba1226b1af refs/pull/1593/head\n00415b37124f98e48fb4d23b2ca52c9effcb4b6e68a9 refs/pull/1594/head\n00412e9bbdc135b413a81a3954fdf3a250cc221b5d19 refs/pull/1595/head\n00418fa5290952e7225467e22d919cbfdc61f6e5a448 refs/pull/1596/head\n004154ee226ef084e63e134ab7850adf02bd51e2d66c refs/pull/1597/head\n00418400000eb57cca8cc93dca976dd83c43a58b57b3 refs/pull/1598/head\n0041919ce9f657f40f60e49f19cbd389de9e493fffd0 refs/pull/1599/head\n003f04f95077a3d42acaee6213e43b30db43ff5cd0ba refs/pull/16/head\n00402ea858357e472cf6ef44d3e4bb598627c722de0a refs/pull/160/head\n004136d6118e605bc8535f1dde4499865d7ae1dc6f34 refs/pull/1600/head\n00418d40405f430d10f4e55dbbb6575d0c523eb4af90 refs/pull/1601/head\n00417bd61dfa9bece662f00e69ea0fea6694f41d01e3 refs/pull/1602/head\n0041e4259f91ef112baece9a58cd116a311bfbed4643 refs/pull/1603/head\n00414e034afd86bc8d28fa5149a8ed0329204ad84abe refs/pull/1604/head\n004127cf14504c0ed7dee0ed3349de789a6496106294 refs/pull/1605/head\n00412dacbc9290c92d3fa0a01f230487b5c57d63c63c refs/pull/1607/head\n0041938ddcb8ab340d456557f55dba08668b873a347c refs/pull/1609/head\n00407f1fa1358a37f2c66cddff37f41097a7735225ac refs/pull/161/head\n00410ae076547e76efc789fd859b2674802043ed73a6 refs/pull/1610/head\n00414a008ec8fa334dfe9805456d1b369669ccb44670 refs/pull/1611/head\n00414b57135a9c4ccdf02010cc534fba565bde3a50f7 refs/pull/1612/head\n00415ebd98109d619cadc98cb0452a0c6a5b4a6664c0 refs/pull/1613/head\n00414be4b03279e6be0e8eaa5ebce4cc7ed641bbdb39 refs/pull/1614/head\n0041db142dd26ecc2bd285a1b14be7c80f6eec60a3c9 refs/pull/1615/head\n004164c190832746b38c7845752c7d25de7d160fe538 refs/pull/1616/head\n00415d5266e65df25cb90c46c4cbd3d9d6b8b63b592e refs/pull/1618/head\n0041906a1211c6dd202c7c7ede44cd2acdc4189ada66 refs/pull/1619/head\n0040ad263687541f8f83d15c4d1fd4d3971135523341 refs/pull/162/head\n004193546ec70491c29f1da3b234c547773e717db0a1 refs/pull/1620/head\n0041fd5e99a385b9174dc0c56b2eddb2eeb4db0aee1f refs/pull/1621/head\n0041e2afb09f0e0aaa4861d29ba6ae5f583df20f0d9e refs/pull/1622/head\n0041c19ed8d95fd118b1e3fe7c175f7e6f9e087d8a38 refs/pull/1623/head\n0041029b70afc2e78795b7c06d347c885c7f176c08d6 refs/pull/1625/head\n00412784d5f2e6062af40ab5769e75cf9cc52eb0272e refs/pull/1626/head\n00415035da3073ee1ccae17ba8dd4afe8be0a795be31 refs/pull/1627/head\n0041d4deec6d0da7f1ef65c1a779dc19b5d2964fa439 refs/pull/1628/head\n00419f8916a32d63d59bef6fc87287ee68a49dcb1ef5 refs/pull/1629/head\n0041860bbc8abc74b995ca1d0a5f0445a27bfa572654 refs/pull/1630/head\n0041f9f0ff9bc7540c9f48007324a89c79cf9477a51d refs/pull/1631/head\n0041a764c3bf113054896a43dea12d15634ace56c362 refs/pull/1632/head\n004126642c905dc317f9156e8bd3cfd252925ebf44b1 refs/pull/1633/head\n0041e33d72ff1e21534c5452b848a7678cfbbf420efc refs/pull/1634/head\n0041d315ffae02e5a1b69f5d60d6b51df8b1443d5575 refs/pull/1636/head\n0041153b7a6705e7c07598d47af91bcc3c72bd7e6d44 refs/pull/1637/head\n004192084fcf21479110c65a313e8b110246ba3316c4 refs/pull/1638/head\n00417e528b8c9d205d12cef9d93728d1c7f54e31a62f refs/pull/1639/head\n0040037a450c947ad82d0ae9498aeeea1c846dc5df36 refs/pull/164/head\n0041d71725912eb43eb95e649c442b6bbbe503e212e3 refs/pull/1641/head\n0041b1825a135207e352d0658b50f690ffe85594ca3d refs/pull/1642/head\n00414e1b650bde5ecce547d0de96699700b39540f3e0 refs/pull/1645/head\n004167fcafae3f165ff4d9b7fb5735fc1df9dc430fab refs/pull/1647/head\n00419054d4cb61638573789be4c52b101941f4bf3135 refs/pull/1648/head\n0041122e1be663becb68403697a0791fabb8597598f2 refs/pull/1649/head\n00417382850335f92144b964320432decc3bcfa1ee05 refs/pull/1650/head\n0041e2ecb13310305aa67198fe6c7d02259b57695ec5 refs/pull/1651/head\n004171632669bb9aff5abdafab8795ad378a4010d4a8 refs/pull/1653/head\n004154df24a7c12fabb8eb24c3060305f41f4ca4a4cb refs/pull/1654/head\n0041b1761437cfcd1deb82b345e255d6e4be136d59f8 refs/pull/1655/head\n00414b1b668e7d90752de5bc79bef1a7e2a53ec0f147 refs/pull/1656/head\n0041e790e1b260b9a5c3f85f69516b236d1b032240ad refs/pull/1657/head\n00414a07e4096a0bb16d762e5fea9da274c87fd5863c refs/pull/1658/head\n0041a6037a9bbd4d7997b7f97a2a72ae49dec960453d refs/pull/1659/head\n004049d39257f884690d669876986d9be47ac05a72e5 refs/pull/166/head\n00412bb60baa2a4093fb0aff6dd873849b4947ac9813 refs/pull/1661/head\n0041879551b20994b0f30895426d35412f48b8ae2853 refs/pull/1662/head\n00417572fe17a85942268020b9eff6d4d8eac8409839 refs/pull/1663/head\n0041fe61c22d3b2b85426dba27af3f65f16dae16f573 refs/pull/1664/head\n004169c6d4673475f395a00fa9fa7a381f579c1165ab refs/pull/1666/head\n00410cd5e9cc9016ff219b71d7a33c635222fff501e2 refs/pull/1667/head\n00418fdeb541be4aa5878a1e3254311a3f7e1e717bfa refs/pull/1668/head\n0040ae2c13c71b5be6042c70ffc2249767ef2b858087 refs/pull/167/head\n0041c7a2b7555299447ea01a557fafc3df6895c2a798 refs/pull/1670/head\n0041cbd7bdd929809d6c967d8764fdcda4efb6c6b00e refs/pull/1671/head\n0041176ec0475258a2db5d45598d29e0e61ba337ffb0 refs/pull/1672/head\n0041ba7c8e4233ccb9fc0a0d5e46e4f4282772bc842e refs/pull/1673/head\n0041e338570d4d6a9829eb37150f1b625a3800f20a28 refs/pull/1675/head\n0041aff5dc102b097be8863fdea720aef890a253a8a6 refs/pull/1676/head\n0041e43e1be58c45a9e16c4bd9c6f3f651f90562bad4 refs/pull/1677/head\n004129e395a423763120e528f50fe57de2334b73d83b refs/pull/1678/head\n0041db151fda8a8198e428b7cc311f0a1cd6c12c218f refs/pull/1679/head\n0040636ea0a2fb8fd8cc4655f21a9d70ba4f2337c709 refs/pull/168/head\n0041db151fda8a8198e428b7cc311f0a1cd6c12c218f refs/pull/1680/head\n0041813cf8299659c285f90ec25861b6e0db2480f87a refs/pull/1681/head\n004192992ec878d7b5c334fb81e8531eb3b61dcf6e4b refs/pull/1683/head\n0041ba91440d1b5096875a9c40ab141315017a996999 refs/pull/1684/head\n00410d05477509f5697b1af54dd776c81bc023185673 refs/pull/1685/head\n0041d2315bc5b74e20c288544e4b7849453f839df8ad refs/pull/1686/head\n0041d4a1a7d0d3055c20fd25e8f5a0610d5c923e3010 refs/pull/1687/head\n0041d9bf2254fde8d6d2d3d6d2df3282a9f4e5ff49fb refs/pull/1688/head\n00413e3fe1c137c0b23e87cb25411cfc820a6b15ba43 refs/pull/1689/head\n00414e49fdbca2db9c2ffc3ca887aee9ca5149e44299 refs/pull/1691/head\n004190966848c36befc986cf48f30a3fa0672197bc8a refs/pull/1692/head\n00413b16f8c008bcdb3140461c00561f072730e0725e refs/pull/1693/head\n004180532f3b4803483e5c399c91ea86bfebaada9966 refs/pull/1694/head\n00412556da4ddef258757bf420a5023704c3e03a34b7 refs/pull/1695/head\n0041f3be7b24a162e4e0728da3b9bad20b68c7562638 refs/pull/1696/head\n0041f888fa52c83074609d20006ed9433bd498e7dfde refs/pull/1697/head\n0041f21fcc02db695dbdfa3bd43247aef653b7343fff refs/pull/1698/head\n004144066554232f737fb771d3d0fdeb62339366f8f1 refs/pull/1699/head\n003ff5a848d9eacbdd8595a4d5b7b6d96e8e492287e1 refs/pull/17/head\n0041f4a80b262e382a9fc1b6471d53e3f873e6f25115 refs/pull/1702/head\n004175e3d7c121c05c0c60f342fbce1e90412626bd35 refs/pull/1703/head\n004156a6c73ab71c4a801c1636a75024aff41a37927c refs/pull/1704/head\n004125776d93bf74cda5889c41ad51ce190a5afeb436 refs/pull/1705/head\n0041d581d43aa016c297e1f79dbf409f4216ecd890ef refs/pull/1706/head\n0041135f97130a7dd070532c06830ad07c01d4b31923 refs/pull/1708/head\n00418f60ee9054a4b0c870cc2d967642024239d9eb9f refs/pull/1709/head\n00406dc43713b9adf9ff0f0c7c23d79133a7c469b8d3 refs/pull/171/head\n00416aae0ad145d73cd2af095fd61b1f11710c8e72f3 refs/pull/1711/head\n0041aed310703f2169df52902ec48beea4cbdabc8ec1 refs/pull/1712/head\n004145abc4bbaa86f8a93773d9e40a31d3429d4bb8aa refs/pull/1713/head\n004106d8bf018c193e31e72d2a5774a6576e4eb5c95e refs/pull/1714/head\n004141135d1dfc165e4e84138b5ecb6d14f6075e6177 refs/pull/1715/head\n0041b8db64deadee4e03205b02cb7c59be672e667e8c refs/pull/1716/head\n0041108f6bee9d622f10b3b46510f1c02137de860da2 refs/pull/1719/head\n0040aeef4cda0b482f9acc5a06dc7daa7e2ae22efda9 refs/pull/172/head\n00419cb731467d81e358ff3297ceb9913cad9f1ac825 refs/pull/1720/head\n004140333ebf9022e2c072b1942a0d01a6d27151ced4 refs/pull/1722/head\n0041062986103eb61b843d6598c572677468945d1e05 refs/pull/1725/head\n004175dc86a4da88a29a6f9541a07866e1198969f886 refs/pull/1726/head\n00417c1c22a4eac54dcdf96557c405a6324faa8f8efc refs/pull/1727/head\n00418b54b9a8573a8a842b4133811fc9f23464701425 refs/pull/1728/head\n0040cfdd598e088b4245671337a5b7ecb36b46545ac8 refs/pull/173/head\n00418ca1c6b27e76e42276e22fc962854b113b5aefb3 refs/pull/1730/head\n00412bf5af86e833f538f47a335000b4a47bf3a38d7c refs/pull/1731/head\n0041f022aefe34ca5890a262c9a1216c41c196d03806 refs/pull/1732/head\n004102db9f7d0689f13232f019ad2268baab590799c0 refs/pull/1733/head\n0041b032701afec89b78e3fa6a75b6005a8c4720fc89 refs/pull/1734/head\n0041bbdf11b0afd6319b4bfe8772e70f9f908c76c51e refs/pull/1735/head\n004158dfdc7cc6fe48497333ca28f76247c3299a7ade refs/pull/1736/head\n0041a88574270ffaae4fb6830b4a59707e007ff344eb refs/pull/1737/head\n00411c83bb41e7c42ddb272ea5f1728d01153acdc270 refs/pull/1738/head\n0041eba63642ac2b45e2b93e430d94e8693d17d04115 refs/pull/1739/head\n00419d833e552128a464daf6bbd82aaba0e60d59186d refs/pull/1740/head\n004181b64d3b1775f03352c54cb3a2fcd282957eabef refs/pull/1741/head\n0041158051eb777330492e3d2f46910560a6fa1f8abf refs/pull/1742/head\n004105670d6623b95520d638b53cd2ad282cfc50944f refs/pull/1743/head\n00417145fdbc67fffcbda16e97575dadc0f04b8fcf2e refs/pull/1747/head\n0041c0da39cbaf1e01c0833091101fd4ca8bf23e570a refs/pull/1748/head\n00411a44d898f1e4861940a4e4573ffa393060b892a2 refs/pull/1749/head\n004136f92267abdeb2b264ef84cf5f5b576a5943c231 refs/pull/1750/head\n0041e3d45e071f6e08ce7357efd2365d099acad8764b refs/pull/1751/head\n0041916652e2be88a78ddf2407fb692c3f3541ed11cf refs/pull/1752/head\n00418b68c6261756493c7a2dd5d3426f5eb9e553816e refs/pull/1753/head\n00415e5daa71fc8e91a4dd2dcd3f931732fb9f75fef5 refs/pull/1755/head\n004151641d8472d7202d491823a41c851e0ad36ae85b refs/pull/1756/head\n0041449faeade1565751ba6c6c8960b7a4c0952f0e83 refs/pull/1757/head\n00416f50c8a4325582a08bf1a60077103efd7c2a3202 refs/pull/1759/head\n00418390d3e556e27c26d40e9d1c68d9ba4c16d0b9dc refs/pull/1760/head\n0041902821c400c4052f4492975219729d19ac609aba refs/pull/1761/head\n004103f573ce19b4ceb32085185b6d1492d7f370189e refs/pull/1762/head\n0041b3b5bd988db1e4cdef63b6f3355aa8e2b0675831 refs/pull/1763/head\n0041d2e34e21d44bfc343003ac43300cec63dd6d1f96 refs/pull/1764/head\n0041cd318eb017b4a9c1af720552276d1102cdc89570 refs/pull/1765/head\n00415ddab79624857dcd3d1bdaff61ae79fbb0590489 refs/pull/1766/head\n0041e8a11106eb4cd18d5e05bc633e6fa473f14c3840 refs/pull/1770/head\n0041e6acc61e3cce771e712669fccadcac67c9f8ebbf refs/pull/1771/head\n00414a8257ee3922ca8866bdd1632c66b20649b2eb96 refs/pull/1772/head\n0041b5689883415dc3bb142cb78d9f083eef16b4579e refs/pull/1774/head\n00413a0e7ae9a78faf4b75c67d2f6491a32df11d14c1 refs/pull/1775/head\n00415bccc3883a0e68932d68245913de443d76cc5a82 refs/pull/1776/head\n0041d701b83ddc8f85958d1df5a4f1ef32f40f681378 refs/pull/1777/head\n0041591a7eab02b4b54a53186be752ad3e10d12047ae refs/pull/1778/head\n0041c950256f640f6fa96b0d3ce9d16ae6724fab8da5 refs/pull/1779/head\n0040ba57feb1392c5140060d290c456db746b5c6159e refs/pull/178/head\n00413fc708d801d83ba63fe85f1dfd9f3c08ce6fda40 refs/pull/1781/head\n0041bd1439e280fc7b8f76f583884136ce3d00c8a9cd refs/pull/1782/head\n00412c8c4f43d846ecd465698d4eed7c8692e2729c7c refs/pull/1784/head\n00413c132fb87a5f32d8df2ebe16c010f5db333584c9 refs/pull/1785/head\n0041dfef1664ec4a1ec64ec12395f9933b67b27449d0 refs/pull/1786/head\n00415f5bb39927c2b58565012387679555dbc078b8d1 refs/pull/1787/head\n004196823392fb6be48e90f55bbba486ab438a3ccf16 refs/pull/1789/head\n0040e414e0d8f3d323da277ee15476e5ac8ded3b82c5 refs/pull/179/head\n0041dfb5bea5fe9c993ec74061edd2a7d5d421ddb8b2 refs/pull/1792/head\n0041cac286a660ceb89ace7c5a5538f326d954a62d4f refs/pull/1793/head\n00418492757b37431c1977f01663d87cddde073fb33e refs/pull/1796/head\n0041b3e761e5db4d1fca2f8f45bdac17eec48a127ac2 refs/pull/1797/head\n0041d332ebad6c9711349a8a853fb7d1bbf9e248db71 refs/pull/1798/head\n004106e446e39e5a1efc9eb8ad5a300e0ee86ce08657 refs/pull/1799/head\n003f18f7167d53fbab5ab19c3ac36461fa518e59761c refs/pull/18/head\n00401a854ea0decd05e4a9335b3a101be33d9800405e refs/pull/180/head\n0041efe777d8fc625b80c8a08267de799b9f0c09c39f refs/pull/1800/head\n0041007a0118f2956621706c23f26b1cd8075791f9dc refs/pull/1801/head\n0041e494a752fbcea552414a1b6af006fb9a80610cb4 refs/pull/1802/head\n00414355e08bbbb3b6d2b8e116505a8fa1485748cfc3 refs/pull/1803/head\n00413739401fc548f67e699c741b9044fbe213bef387 refs/pull/1804/head\n00414b4688cce5010a2e2837c2094ed492211824b231 refs/pull/1805/head\n0041bf05a4be79e1c79330b47cb046df101ec64c1ff6 refs/pull/1806/head\n004162dc3304c621e5ae13625d5930d2484c9adfa4d0 refs/pull/1807/head\n0041840766f2f861a9d06c769e57d40cf65862b6c675 refs/pull/1809/head\n0040f6b89e763c1ae6f398849e5b94d858e34dff8663 refs/pull/181/head\n0041f474e67aade05636419a2b8396c27fb39cfa9b02 refs/pull/1811/head\n00413369c5f8f0d54f839dd20203d3450d4096c41a3f refs/pull/1812/head\n0041c9b14d17d84e90432afb9246dd9a8377462ac627 refs/pull/1813/head\n004142e7655663ed198fd3c46f6455cea5ac2c40cb83 refs/pull/1814/head\n004172fde249e400bdd09f0ca65f187104e2f7792da7 refs/pull/1815/head\n00417e2776ca22f4537a6fafc0c95ceb0c74c8f341c5 refs/pull/1816/head\n00418ee9da5f84628b5401a8e73cee770397cfe105b9 refs/pull/1817/head\n0041a06e2597ea1692277f8edbc2b643a3e382241e6a refs/pull/1818/head\n00418cf8e86091b471ee1886414cacc1969f05af5ef8 refs/pull/1819/head\n0041dccdafcd455c19b1e6a803e4e94471bbae7eff85 refs/pull/1820/head\n0041b4c17c7eb63e68e5df2d65cac6138a4d56803719 refs/pull/1821/head\n00419c8fdb86ebe6ee0d858312e741ae680a1131ee73 refs/pull/1823/head\n0041342c6564bbf5330cb4ad65ac20b15f2c3de6665c refs/pull/1824/head\n0041519191dcaae36c1587f166e39d114d9fbe200547 refs/pull/1825/head\n00416a70839069b44b5a63e2e6a3e47ed5504158fa72 refs/pull/1827/head\n004101bc8a5883e4478ed31ee7d06cd9b96bcfa436ad refs/pull/1828/head\n00406d813c2208a2326d94036b185b734a6d1d38d7d8 refs/pull/183/head\n0041599f8e1ebe821769299192306a8ea909a5199ea1 refs/pull/1830/head\n0041618a7b7eef4b5fabb31a7e63340e309168e6f45c refs/pull/1831/head\n004157b43516fc128f79431f23271fab622933f2754d refs/pull/1832/head\n0041f860f607fd0e913c0171835f5019195f49a23cd7 refs/pull/1833/head\n0041f237e8d0e9abda367e2c305927b9a1ebd83cdad9 refs/pull/1834/head\n0041638eda44b84d8cc4afb493c11b7ebe33d8e83cb6 refs/pull/1835/head\n0041f2d546ba7c01232604f6be739452773829448ee0 refs/pull/1836/head\n0041d8e9f77faa0c47702d961a62ffbc7ab81362f9b1 refs/pull/1837/head\n0041b7534a9fe65901fd3071f950456085d12c611ca4 refs/pull/1838/head\n004184b27252897a8424d599d97e220d69d4d38b0adc refs/pull/1839/head\n00417144013ab8c98e85af59db288d848dbc666d5258 refs/pull/1841/head\n00417da7fce2d029220b100dba66a7fdfd2f28ea0ba2 refs/pull/1842/head\n0041691f49caa3031ecfc2ead03ec6fdda8b860c3b04 refs/pull/1843/head\n00419bc319a6aa2e212b7493ade763896472cb345ef8 refs/pull/1844/head\n0041c61898f594c8e619dfd59572fffaae1906eecf17 refs/pull/1845/head\n00418edae54f46cb62a34bb4859d2691b0097f5c0c8f refs/pull/1846/head\n00411bc9f9bc308cc69cd1c18ce6b8efa61b9aa745cd refs/pull/1847/head\n0041cd932084db77398e5ff63b3d80c76d943b598212 refs/pull/1848/head\n0040fb5c00d58e188df7ce7231a6018eea17a91ef6ae refs/pull/185/head\n0041238ffde778c5424146ca9c908c897b2356864e2e refs/pull/1850/head\n004128c950302ebd22c56798dfab9bc820349f182c1e refs/pull/1852/head\n00418e6825db704f875085b8fe4359c61baa8bef63a2 refs/pull/1853/head\n004146c9c7e31a9c0295067a22f7e0ab4b1dbf7098c8 refs/pull/1854/head\n0041fd8fc0001fef1272ac97beed2a4050c0c5fd4195 refs/pull/1855/head\n00419211aaae4312dbc64872f6583622bc7061315822 refs/pull/1856/head\n0041d60fd3898289884aed9088d0788fcdd4089af548 refs/pull/1857/head\n00413b079372b7d977aced123b231faf50d0a92057db refs/pull/1859/head\n0042145f70e4540db2c282881595945418c1d2995042 refs/pull/1859/merge\n0040faa9d00e7461ebbccef663371a70cddfedee7eff refs/pull/186/head\n004144ea636af4e056a3a4809470e530c7d207705c20 refs/pull/1860/head\n0041934da32ea81e43d81860656a73935d943abb50d4 refs/pull/1863/head\n00413cbc3289eb428cc8cda8bd41701574428c376c14 refs/pull/1864/head\n0041a2d04657c1f761293e5f56dff1ad2af38482119c refs/pull/1866/head\n0041871a044ab84086af69e2fa611087aef94fd5a0af refs/pull/1868/head\n004117a52d99f395378639a108fc4146657ea5e3914c refs/pull/1869/head\n0040178e0c45a481822b42cb9057898909470b354936 refs/pull/187/head\n0041b784710337f716e3fb64be89dc5b78b9fde61d8b refs/pull/1870/head\n0041fac2d682381c1f67c226d2a3673b9330d33e6c03 refs/pull/1871/head\n0041b2ebc60f06bb92c153841ebe0d328be2fa88c7b2 refs/pull/1872/head\n00410a572c2b0d448e9216f371df6404fe69cbd02fcf refs/pull/1873/head\n0041647a1b125de5e4e5dd58e0e5fd82e6d9064af612 refs/pull/1874/head\n0041713d5de37556062cc50ee11421dd549f03a71e94 refs/pull/1876/head\n00417500a942176139d5f95e3347d6ede76b976a0cc9 refs/pull/1877/head\n0041ef86be2b62af481b81d9d44f88a8683e0226cef0 refs/pull/1878/head\n0041b37e23b5130a65abf26d2ee26e0a0a1d37732bf0 refs/pull/1879/head\n0040d6b016681ced68f32ed3d727d32bba5cbcebf48a refs/pull/188/head\n0041592e36c17a02947d83cf9fae2adc0144f48109d2 refs/pull/1880/head\n0041823870c376cb8d401a114e0e49766ba1b316483f refs/pull/1881/head\n0041c0c8d33c548238906e9658a5a8da5d1e9e603136 refs/pull/1882/head\n004192de84d0c303553c56f7573cb7b7136ceab2a31a refs/pull/1883/head\n00415175f29e6048f73fd71711fd3c3d38d1bf1097e4 refs/pull/1884/head\n0041a0f94c499d7d1d45e378cb158b5bcb98b9366196 refs/pull/1885/head\n0041baa5f0ec04243280748d5cffa9e835bc6b0ae675 refs/pull/1889/head\n0040c266a133eae2cd259ac6886be464d835d0b30bae refs/pull/189/head\n004167743d32b235c950e773f5fe796254bd1136f436 refs/pull/1890/head\n0041a54d5e9eb8b055cb99411883b793185a171e36d6 refs/pull/1891/head\n004114510eb2cb5c7f81ff192db3254c2f9d36ab22ae refs/pull/1892/head\n004142f2b477cfbdfb31f89659dedf77f61496745860 refs/pull/1893/head\n0041a49be27eadbd0a14ce9d27f924ab38c7aec660ac refs/pull/1894/head\n0041e2c65a1ab9b5119edad38b3d4a054d949ec27bf6 refs/pull/1895/head\n00414a1eef23e039e45dff6096fb1e4d7038484b1324 refs/pull/1897/head\n00415d68dccbbbcb4cabb6914bcd0f80e96422f0107d refs/pull/1898/head\n00417e9977249bab5f79d036fe5914ed85bd19db5afe refs/pull/1899/head\n004087c95a48cf9b44c8ebfa2a35d37762f6a1572f2c refs/pull/190/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1900/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1901/head\n00411489e5e84754ed3aad329ebc32611cd316761fc5 refs/pull/1902/head\n004148780eeb5b85de81fa3ddf5345c74f630fcf084b refs/pull/1903/head\n004161e7f3064aa96e267ae37ddc2a5c9324fb5eeed6 refs/pull/1904/head\n004161e7f3064aa96e267ae37ddc2a5c9324fb5eeed6 refs/pull/1905/head\n0041224a5a70982da890dbf26f70b45c39cc25a67849 refs/pull/1907/head\n0041a149eaa3775e95374637f017e800dd1b5673094c refs/pull/1908/head\n0041241d011f5c0ac29302b40a25b2a926065d0bdbd8 refs/pull/1909/head\n004049cb864e08b729f52808928a2a9ce557e4b63380 refs/pull/191/head\n00411be286663de204d29d04591ed1daff38ff3f46bc refs/pull/1910/head\n00416298a560d7715a672a847fe5e24614e6bc328db1 refs/pull/1911/head\n00411a0b2221a398e516d6844f77b920f81f008177b4 refs/pull/1912/head\n00410d3d2d5f97113e1b91856f35c20d1fc03c4f1f3a refs/pull/1913/head\n004183bbbae23013931adc38b155b79281c0afc5cf1a refs/pull/1914/head\n00414613952f0071cde9e471b982ae651cb064c62156 refs/pull/1915/head\n004198f0cf7a889941a447d74b18fbd8afc932689496 refs/pull/1916/head\n0041f6f3d4ad945b4742e74821ec2fe57b2c9d75fb6c refs/pull/1917/head\n0041eba4115d19c2142967b2abd3e498317980a7ea0e refs/pull/1919/head\n0040c41aedb6b766c1c5c7c9bf214ed36fd1bf35909f refs/pull/192/head\n0041f2945555e9b6873697e1dc77b2bcb1d529ae61b0 refs/pull/1920/head\n00411bdb2cb54e96bae978e7350a447c870660f3dde8 refs/pull/1921/head\n00412e508356481a07c23a8500c50a86f04f45216753 refs/pull/1922/head\n00410fc002df4fa3b5805d3edcf19e304c4fce3fa112 refs/pull/1924/head\n004133bc22e366f010900c8ca27c6221f8b2b835c858 refs/pull/1925/head\n0041e7fcb811dac1d6c07c171a1ce0d90e38ceba5820 refs/pull/1926/head\n0041c5cc882dc859f67c7bf0220c27cd3888c2c4c138 refs/pull/1927/head\n00414de467d648b6edac48ed3270ef1103fce19f994c refs/pull/1928/head\n0041084a1c5cec5a72081d9458db6a93b6bedff82638 refs/pull/1929/head\n00405cfe80f45ec7a361dd2ed1ad3205a40f922560e0 refs/pull/193/head\n0041d2116ca0179389558d7136d4f344c30dc888763f refs/pull/1931/head\n0041c6f867cfa1cff37f58fc159c9e60b3f996a1b34f refs/pull/1932/head\n0041426246d022ea114825a1c083d765fda9d0e38141 refs/pull/1933/head\n0041382b6f29ad0f337672497a4b0ffa3b19102c219a refs/pull/1934/head\n0041c48c9aef1f349d72a986be344987188e330f8137 refs/pull/1935/head\n0041d31656de65f97bc212cf0d8b4f04918b84d7cf72 refs/pull/1936/head\n0041f87710d03aa8a0cf76be0fe2d7336422e2970435 refs/pull/1937/head\n0041a2d40be8c7c3bc359f55015f12aa4c0d24944e38 refs/pull/1939/head\n00412b35b159e21d96c538037fd25b58325729d28192 refs/pull/1941/head\n0041ab4f2902a774fd8c25f5ee2791bb31ec28ed3148 refs/pull/1942/head\n0041f4067f3ef35612f3d51694ba3dcbada4723f7486 refs/pull/1943/head\n00415cb72fac61a833c529759f0fa647e71f7eee6ae2 refs/pull/1944/head\n00419b847af342a4b727a3b9ed8dc46fb4aeb0f6a2b5 refs/pull/1945/head\n0041293e1b459ba2e76c9c2cd5252263ac795893dbaf refs/pull/1946/head\n00412680c976e27942c3bd91707d46c27b1beb8142be refs/pull/1947/head\n004173f816cb70d1e8c0c94d503463a0b08b105e0b49 refs/pull/1949/head\n0040e3257a8fe4c5df589abf5be7eb115bd472bf877b refs/pull/195/head\n0041b4fe07c1984372d91cda304769214afdf87b9b80 refs/pull/1951/head\n0041b73b5b4e9dc9591299ee67c0aeb7fceee06f3af1 refs/pull/1952/head\n0041a9d7ec3526fa15d9537dda54147f648cf9399b00 refs/pull/1953/head\n0041d27a5e3328e2606726bf0f8e62f09dcff05f1c09 refs/pull/1954/head\n0041bc78d3470d7a521c7cf24b5cc4406e97a52e31d7 refs/pull/1955/head\n00419d6429cb59ebe9a2f13a20c7f795858ffc123440 refs/pull/1956/head\n00418aed1058a87d17a67a6e54d875fb81206a85dcc6 refs/pull/1957/head\n0041ee161fd069b80bfbb1292a6f27f1ffc7f2ba22a5 refs/pull/1959/head\n00410474edf70992688d398b983af52a87d4a03a371a refs/pull/1961/head\n0041c86ffbab0f0c9c5ce7729eb393184ba20ce40fce refs/pull/1962/head\n0041956e85c8b84f417b302eeb4d645d1f5df5428513 refs/pull/1963/head\n0041104ec733d3c19dd9d679617df07e2f6231267693 refs/pull/1965/head\n00414447c9e617f14f32acdce6bcc771807d81ad3a54 refs/pull/1966/head\n0041d7672253927e948e6f18dc6277d9b6021b2a250b refs/pull/1967/head\n00400cb945b59925f3612ea2f24630617eb7b10a0fab refs/pull/197/head\n004119891269aa3a37277b394227fbcd7eb154289a70 refs/pull/1970/head\n0041acd7a8aa665b2135ed007af4f6ea67eb01fa4008 refs/pull/1971/head\n0041239e81f8fb51a5aa77e21f47517a4ca8b6e12dfa refs/pull/1973/head\n00415877e42abc56eb8bfbd3eaafce72645d4b3f6cef refs/pull/1974/head\n00414747a7fdfce35ebf31be8179b83c9edacfe8d4e8 refs/pull/1977/head\n00428c8ba4b230e5cfdf2a0c5f3dcdab40bb03a0a16e refs/pull/1977/merge\n0041fab3819ed8176c96379df3a96fc060c6bd36f4e4 refs/pull/1978/head\n0041781c0b371217c18f55466eb507522cb228474ceb refs/pull/1979/head\n0040403251a233aa9572cf5a1f57af8281b1441bd744 refs/pull/198/head\n004169792ce2495948ae2d086548d53aa3f290de6698 refs/pull/1980/head\n0041750e03e96927d3b78a6016d64a17698305136ca6 refs/pull/1981/head\n0041dccc8f2bd46a549aee8cd5535782d04cf4712ba4 refs/pull/1982/head\n004116f4f86033cd44dc9d599b6bd44bbd16de63f12f refs/pull/1983/head\n004106b3ca51b04bb5fb1d45da88c4adaced62f1ab72 refs/pull/1984/head\n0041fdcba2deead127853858d88adad54911f6e97ad1 refs/pull/1985/head\n00416545f54c7866be12e4267735f98771c52109404c refs/pull/1987/head\n00417ac50201a25d62bf105f60efa768b52377939fc0 refs/pull/1988/head\n004136ddfb58948a39a7ed85e6e1ee52449beace1555 refs/pull/1989/head\n00411aa0110d1eb87b2d05063c4828468943243b7fcb refs/pull/1990/head\n0041ef723c65f4a172daba2f1a1e135c556f6596bab4 refs/pull/1991/head\n00417fcd080ce9e3471e06dd0276cf59d0c4ca71fdba refs/pull/1992/head\n0041e738213271e263b02ebfc938faf72cce645375ef refs/pull/1993/head\n0041cea3f7fcf79ad3cd6b2b28bc0294e864b3a5a05f refs/pull/1994/head\n0041687cae8512e398f298488eea297f73dfe53072ac refs/pull/1996/head\n00416629856ab6b7b0a32076c47bfc85011f20ee33ef refs/pull/1997/head\n0041bb915dc2f5b2d12605f37262e392f8ebf4dc6235 refs/pull/1999/head\n003e227289e2e18325309196e553f26cf06741e5a871 refs/pull/2/head\n0040ac897909866cef27ee70748dac547290e8339b5f refs/pull/200/head\n0041c13380af413e66bc91d76d77cf3531e7140c5db1 refs/pull/2000/head\n0041400d01e27e6e77c6459a3f7324d531add8e46a87 refs/pull/2001/head\n0041d5de53fb00ce28af6e9364bb3182ff6af9b30743 refs/pull/2003/head\n00411a17fd60b55f021fc1a84bc06d1475c4ed78cc82 refs/pull/2004/head\n0041f3cb06daa4dbe5411c65e35e8bfbfa37dc7fbec5 refs/pull/2005/head\n004161b1b3b78a534a0184cc77e86f33709e6be1bd6a refs/pull/2006/head\n0041b6f189b0beefe056d6dab787ddc74a807ffd9184 refs/pull/2008/head\n00413b80b5f5f8a59cd6aa0b3101a358e48293d14c5c refs/pull/2010/head\n004107f397ba9a967171f4afcdb3b1b8970b69e9c9e3 refs/pull/2011/head\n0041d16293f947aa812b4b2b4d1ebfbb0c89c210a050 refs/pull/2012/head\n00419ff5de4e3b6b25f950ec5434744c7c133935a5d3 refs/pull/2013/head\n004124dbffe5565019bec56b4c22c2bc5f4a13aa8fd9 refs/pull/2015/head\n00419e147c97b5f8b278393343d4b8bb677f7eb0484a refs/pull/2016/head\n0041185837de899d59aa23afc5f31a5a2177c759fc81 refs/pull/2017/head\n0041836e42fef0c279835268be30efd3464e25922110 refs/pull/2018/head\n004165406a5f6751e7f3cedeccef122ad18c83947a7c refs/pull/2019/head\n004100e067a8552159498597321528fbcdba02a8570f refs/pull/2020/head\n004140f449036541883d28e9e9918194e20bc9949411 refs/pull/2021/head\n0041510a2bba0597c21a713eb1fa8b22b30b777ff3d6 refs/pull/2022/head\n004122ce40ca0f4f0b61728abdd34662cabeb4460386 refs/pull/2023/head\n00416e2a8b49d3a907ecc1d03ac34c1be4497acf5dd7 refs/pull/2024/head\n0041f8a40c7274088d5a3f13caf4cad5885fe42bdca7 refs/pull/2026/head\n0041b513d7d65b25cb1a046bcf040d836964bb2ecc03 refs/pull/2029/head\n004081633dd80a91de8da7c784ae4226d1ac2e4294e7 refs/pull/203/head\n00413d8e8b529bc217a58d66c0521a98ff4974f7904a refs/pull/2030/head\n0041677aea2e0281549cf80d3670e37826f2f700fb63 refs/pull/2031/head\n00419dd4acf3c65c2a81b2a9fca2c2660393b4e477bf refs/pull/2032/head\n0041a36e625fb735de66a4f5652ec9db00cdde4b34d2 refs/pull/2033/head\n004110df4acf7461073f38f812543cc1c0dcb070a8a7 refs/pull/2034/head\n00413d4e14ce45a908b0dd997e935ef43cce90a9b1c3 refs/pull/2035/head\n00412e8ca1f968416e0cd1fb94312e193f9cc26b6459 refs/pull/2036/head\n0041ece69ddf2b605781f46df54de473f0f93da3e78b refs/pull/2037/head\n00414d294906704fe8cf9fcfdcf4f22620eff38d3891 refs/pull/2038/head\n00400782f673e6e8e4cb46798e1f1fc1c7bb43b87e89 refs/pull/204/head\n00411ca6912af6d25f1c1893779ee16ddd12ef4a506e refs/pull/2041/head\n004159cb18803072a3e56983d8db9b3cdff39406dade refs/pull/2042/head\n00419a6cbbf1d8a8e4dac3c4a66afc33865c534c606d refs/pull/2043/head\n00410fd87af7099ef4418bef81028072f536f6d18052 refs/pull/2044/head\n0041d33cccfd9283d342416ffa9c08aff403eb84c0d5 refs/pull/2045/head\n0041ba89d6dc7098f52b0d8aa2e29e107743420f1c7d refs/pull/2046/head\n00416911250db2297ec935eb2c7ad172c7674fc90f39 refs/pull/2047/head\n00415b950e1ae43e75f646e6dbcb0fe3dc217ec392c2 refs/pull/2048/head\n00414ec952ce1568d1a48bc89cc1b2aaafe311730c34 refs/pull/2049/head\n00400043e0c42496c1115bd3d15f1832048c5ec728ed refs/pull/205/head\n0041ddf91565ddbc8bf421c2e48d077d03b2c10fe6a1 refs/pull/2050/head\n0041f314ff999cf3d9fc00cfbd3a971f31a2a789db10 refs/pull/2051/head\n0041d5bdc95cef8eb790e545f5f7336283c129fdea6d refs/pull/2052/head\n0041626a49a823474ac51390f4e73ecb7758b04cb37d refs/pull/2053/head\n0041353b55a42cd0c044977819f5dc0d1ca591559f8a refs/pull/2054/head\n0041a6e53c1eec8f831bd6c2fc13733f91184ac32504 refs/pull/2056/head\n0041bca0935434c36a6c49256f2511d424e3e674dd0c refs/pull/2057/head\n0041ab8997460444fc08246bca72937936bfe6380083 refs/pull/2058/head\n00415172cc25a17e7677b9c55f2ec2bcfffc5ff9c71c refs/pull/2059/head\n004087f71a39fbd1b7ad9c0bc082c1e1bd73e625903e refs/pull/206/head\n0041b7b4759a0910526f6de20ca248708dcd79dc199e refs/pull/2060/head\n0041848a1f1b7de98eec4a66ee864cced21716da9243 refs/pull/2061/head\n00419269cd3ba455e24654436fb2a652cc2c231d3de6 refs/pull/2062/head\n0041995b0d7628f405baf57afb3a6e83b223dc1f976f refs/pull/2063/head\n00416b097e721ed325d4e84a97228ce1976d20bca7eb refs/pull/2064/head\n0041cc81f17af26791b292597669e6c3b6c74994757b refs/pull/2065/head\n004193cda3c00720e9145f4bf58cd3e66a5045691a3e refs/pull/2067/head\n00410890c751545fdbbff2a0002a190708fb277fc173 refs/pull/2068/head\n0041cc37888b374df1c684b2c9829aa0ee9bfb3caf9a refs/pull/2069/head\n0041aff3ff06374380b19dc1ea6774d59fc7de882057 refs/pull/2070/head\n00419b5cd15aebefbbf98ba7c5e0963926faeaf4c364 refs/pull/2072/head\n0041dbf6877bacf30bba4c169ee5a796a9e5a7ab6370 refs/pull/2074/head\n0041d0c245dad0259b782076915d3bc802028f1ed336 refs/pull/2075/head\n0041ba74167acb11d1e5c8cd75d52a1574d0c6c7c3c4 refs/pull/2076/head\n00414e6d9ba358c44c4607aecec9437596ec10e7782a refs/pull/2078/head\n0041a7617a15f6704a6e243fe962e7b6be4dfaa8c9f4 refs/pull/2079/head\n0040cd338722bbfbe9cafc040fd4a58cebbd80d6a605 refs/pull/208/head\n004140bd6e616d7c178a03138e0be3c099a3cfdb8100 refs/pull/2080/head\n00413d11a2ea247651ac26ae5795b0673ff1132c6330 refs/pull/2082/head\n00413ecd4afb2d2f7517aa205e3f850baea5581e6a4c refs/pull/2083/head\n004144527137ef45b24c72922b2847005c6656852ad5 refs/pull/2084/head\n0041f4aa6c6d2a7529d4f2a39d1abbd99cf1e53a5f22 refs/pull/2086/head\n00412b044267e52536685371e06bd201b0ade5f1cd18 refs/pull/2087/head\n00415cfe0c4338e011beb2a2706b168695d87d0f87ed refs/pull/2088/head\n00419f58b23677ce365f25c92d8225cb4bb4127cb477 refs/pull/2089/head\n004194e6433d6c2b23ff04ab2ffb0cf58566379ade45 refs/pull/2090/head\n0041df4a4befc61fee3182d2ca7da183348284e6a3af refs/pull/2091/head\n0041fa1ad77bde89c28595e9f0597064e254155e25bc refs/pull/2092/head\n0041fd4947e58c7de72f888fb3dbb1d014e32c051def refs/pull/2093/head\n0041452cd60eba83c9c115d2913fa00a08c713ba2a5c refs/pull/2094/head\n0041203a938707be0fb5c7155ad77d6424f198fe7591 refs/pull/2095/head\n00417cd1312d59887124c5b7ccdba2149ca6c7bcdd94 refs/pull/2096/head\n0041097674a4ba86e62da8896c005d5fe39b99ddfa43 refs/pull/2097/head\n00412da4edff42bdf603ef5231ea5c19c8c2e022c056 refs/pull/2098/head\n00414aaaf927055ae1bde90ae71fff381950dbd13dda refs/pull/2099/head\n0040c828bf499e0a54feed38c3efc5afc2fe5fc59700 refs/pull/210/head\n0041c5fb49f6650e6389f20b7f6d2dffc84c66f33378 refs/pull/2100/head\n0041a3acc4e08ba6169a0a32b8a27097070996f662c8 refs/pull/2101/head\n0041ae604de6a6b51f76bff22f5ad16a8f623bed2117 refs/pull/2102/head\n00411af52dded0e7810e4ef91b50ea65275518cd395e refs/pull/2103/head\n004142f8b28fcea2e5bdc4c71388c4a0e345f2fe3def refs/pull/2104/head\n0041c02776967f5619ff5fc08d0227042aa1ca26d3b8 refs/pull/2105/head\n0041c19873a811e740650320c728b2e3561aa7b0b7cc refs/pull/2106/head\n004181ca007ebce6b4c027cf1b97750858b4da7833d9 refs/pull/2107/head\n004152a09b67dbc33e060e324f230506048cd92a1616 refs/pull/2108/head\n004171882829ee447b0d5c0919669a2d69912e3a8d14 refs/pull/2109/head\n0040b4fdd96948f5b8f5c4c41ff5e277d8ae84863dda refs/pull/211/head\n0041026d1a263cb504fa3a6043e191557d4822372463 refs/pull/2110/head\n0041b7015de9c9a3bba7bb67496f95cb1f595a6cd3a6 refs/pull/2111/head\n004154da224c68fcaee6e8af4d30cf2accf556c9c693 refs/pull/2112/head\n0041eceb53ffa20061bf772fab4a68f142f2f62aceca refs/pull/2113/head\n00410c29f58374e15d3fbed56cf12287fef29dc6d8ee refs/pull/2114/head\n0041ac910bd216a5cb3039066dd2e9a3e4c1f3092b46 refs/pull/2115/head\n00413a6f629e1e86b4329e24b57b1d909941742c85d6 refs/pull/2116/head\n0041db40cea49ae5613ad6302d571e3c26b4a465b257 refs/pull/2117/head\n004185257d5943ce63e4a70797a2f75363720495b92c refs/pull/2118/head\n0041ba3f193cc4c3acc963710cd885621f0465de1d19 refs/pull/2119/head\n0040f5ffa2b991257acf59ad9bc4ddc87de714ce5c3c refs/pull/212/head\n0041481c88f29aff221cf262d2f8d2f966e4fdbb0d23 refs/pull/2120/head\n00419677710a4b8a39d88003952d1ece80ef2441e201 refs/pull/2121/head\n00413cf80b0c43d89661ef8662e08184003cab03d56a refs/pull/2122/head\n0041e2f52a60726bf847806067859096da6e2623e9a1 refs/pull/2123/head\n00414afec63bfc646ac6adac67ad72e6683625a8c1d0 refs/pull/2124/head\n0041637483ea3746fee561dc231d8ce14b20c9ac75d3 refs/pull/2125/head\n004103e10f3950cff1426968011130c64c6968c07fff refs/pull/2126/head\n0041411b0d2fd6be634a81f1ad9e15b222338015441a refs/pull/2127/head\n0041e41c0eecb2a1acc6bc568d2519b2620908fc68bb refs/pull/2128/head\n0041ecc474a4276e566f17e5bc214b57504af1016023 refs/pull/2129/head\n004120374f1d22618314275fe9cb87a09b05c264aa8a refs/pull/2130/head\n0041a652588378d60b448bd1185defccd3ff368bd7b8 refs/pull/2131/head\n00427251a7cef1568ddc05ddc0ddbafd534c9724e59e refs/pull/2131/merge\n004114d193cc8093d6421b6ff872bd9bad537a6ce7b4 refs/pull/2132/head\n00410c6e6b532e70590febc4d7abe757fcade9c0a4fb refs/pull/2133/head\n004103a8f041121bcca58241b8f8896b6becb971bad4 refs/pull/2134/head\n0041b115f52d6653faf5c94dad68fc230f9460752841 refs/pull/2135/head\n00412c1ba195f5e1e9927d26bd8e4e59564968238251 refs/pull/2136/head\n0041a1470a24b17b36cce27dd01ac4be5d1c8bc4ad4a refs/pull/2137/head\n00416b1cae8b9a40703d7f1031e64ee4fca43cdf836f refs/pull/2138/head\n004103ac0a236a7e959e9f6415df0e7583ff185073e2 refs/pull/2140/head\n004182dc63f57ad4bb6f497b9513ab469d172f5a0e0c refs/pull/2141/head\n0041d7c10ddd62245082b232fe6f88bda6c2f9007ec5 refs/pull/2142/head\n00416e63fd48f08de6553481959c0c6b2f49de7d2a82 refs/pull/2143/head\n00418a27e12912bc168c04d6204de4564dc35a7c8ea8 refs/pull/2144/head\n0041677cb71a7fa5812a74ed548d9c6bdd168c2ebe11 refs/pull/2146/head\n00412a48a392fd4403fb5a80ba46caaf25715dd25946 refs/pull/2147/head\n0041559b851642454f22375aa96ef6ff47ebadf2a514 refs/pull/2148/head\n00409a693cb5810151a780868e3d43436e9510c6f62a refs/pull/215/head\n0041cb59b920b98a1ce8f74cbfb6b1cfd3457a39bde3 refs/pull/2150/head\n0041fb2f0291d736de092aa9938980fe4475d19ac7c9 refs/pull/2153/head\n0041fe31eae58bfa294deaa755a3b5d2a61063d868e3 refs/pull/2154/head\n004112965f8d0850a2be345181b85a845a8952dc4216 refs/pull/2155/head\n00415d00427c3856a4f3a44f0ce087ac30a56922f6b9 refs/pull/2156/head\n0041a154da59279b3b8b962f018042dbc9604a5155ae refs/pull/2158/head\n004179f4e14dc8f1c22c606c53dfdacfffa9ec09243c refs/pull/2159/head\n00416b5805774252dd8a9b26fd853ea797f77139c760 refs/pull/2160/head\n00418fe45a437837847b9c7753b32eba4c741272bbf6 refs/pull/2161/head\n0041675786cf89708dcb36300cbd13d2965e0c7a911c refs/pull/2162/head\n0041cef8275b53c1a17c37babc9d974aaa4dcdb3e388 refs/pull/2164/head\n0041b147fc2f2f21beb434885d22f29a3ae94212b46f refs/pull/2165/head\n00418db2e539bd05e35aaa0267f0e65e21103c21a357 refs/pull/2166/head\n00419740535ab1779ffc63c7cb6f9f0668c9cb30d353 refs/pull/2167/head\n0041ba3a823949b19d51ef7e0fbe13d04bbe6d22c374 refs/pull/2168/head\n0041ae2ebd8cef64445eb535417bb4799f6f42961621 refs/pull/2169/head\n0041d0b816590ad049c653425026743c4f62f0882bff refs/pull/2170/head\n0041b0c70826e814bd004a8e44e2b92207eba735dd28 refs/pull/2171/head\n0041275ab5649720f94a7e5c5bc39e38b76ed7992f43 refs/pull/2172/head\n004105c31231a3861f8f0c965a5bef1823b11d93db46 refs/pull/2173/head\n004198524bf2b1473964312bf8503d7faf08c775839e refs/pull/2175/head\n0041e26dc23380507668f324ce5ef57f7ba1201116d7 refs/pull/2176/head\n0041e6f8ef0cc55d38a0b93b11cffb8f371a6c330f8d refs/pull/2177/head\n0041390338bed87730b0a5dee6eec1ebca631c039210 refs/pull/2179/head\n00416be0a369bcacfe1e00fce1476a43cf06384701c2 refs/pull/2180/head\n0041ff1e69e437d118b5f3ac09c43c3d6f889995f0dc refs/pull/2181/head\n00417e9b5e42f90fa6b2a7a1184bd8f4b712dbea065d refs/pull/2183/head\n0041d8b4650356a629c931bd8b90a6d79b5ef4ce761b refs/pull/2184/head\n004172d678066bc6e43c1222224c2559a4733465f3dd refs/pull/2185/head\n00413df6775ff7ee9793e5ee253b87de679a3268af60 refs/pull/2186/head\n00410ae44d68f262ef2f60d137e804b8168d200b98f7 refs/pull/2187/head\n004175546acf17f916db289c902d6ae470fe60cc69e7 refs/pull/2188/head\n0041ee08bf04fac53c1ccc492691d2c47d8a25719bce refs/pull/2189/head\n0041064e856fda34b86f8e475c01275f5986cf8372b2 refs/pull/2190/head\n0041b84be9e308056db985cd99d9993b8a9652a1cacb refs/pull/2193/head\n004117be479789007df59d1a5641085de42e51058304 refs/pull/2195/head\n004109507b7f153b158bd0ce7e6818fda5c62010bd93 refs/pull/2196/head\n0041071d95c2b59fffd856d88cb2d8023f0fc5ef5049 refs/pull/2197/head\n004187c8c0fe27510bd01b9cf7e849383fb126e10826 refs/pull/2199/head\n003fd59e57cfe4a038bdb858fc152cd2214704df1af3 refs/pull/22/head\n00406091d46d9c655897ba91cfa65c8004e75b98b424 refs/pull/220/head\n00413a3e2cad58d9d31ae987e36ed9616805f8229c70 refs/pull/2200/head\n0041f1fb5e238ee43fd3857ac7754a4de08189fd6e98 refs/pull/2202/head\n0041a5218b11a45beb6b86c857006ff5350b5f976b86 refs/pull/2203/head\n0041219eb733539f7fde04c67d24f6ada42c95540fe8 refs/pull/2204/head\n00418545cd25aafe2e77875e3b9d9fbb5e3ba9c0f230 refs/pull/2207/head\n00412fde2f136f5dc6ea2b809fc3e54b07256fd08866 refs/pull/2208/head\n00418b2a2ef83706fe46df0356cb638f00b84ecbc525 refs/pull/2209/head\n0040f77dcc094a5589ce0d13396121fdc307b184d9be refs/pull/221/head\n00411b5718a0306866ad8589dc24dacd0065a61dc213 refs/pull/2210/head\n0041d3c99e8e60bd995e2eb341c332daf4549bd3b2f9 refs/pull/2211/head\n0041de1122d1259506f0ce15a964fa7985a3c47a482e refs/pull/2212/head\n00410061bf3a7b32f413a3563e51542f49916b67f5e9 refs/pull/2213/head\n00418ef2accc79afb1987e4953649337eb0d49ee6028 refs/pull/2214/head\n0041db27c78131d4be384bf6500a60ef8746fa7a8684 refs/pull/2215/head\n0041ade888c8bc8d749fad4c8dca569203bb2cfbede2 refs/pull/2216/head\n0041232bfb449010735eedc365c52bb91924f0dea845 refs/pull/2218/head\n0041496f4584371e1d0f4dc644e8d65c5fe53fdf0063 refs/pull/2219/head\n0040765c274e85c240ca6a3366c6f0ad1bc6ac452d2a refs/pull/222/head\n00414943ba7aa90dbfdefe812a1ccc1635215a8b98cd refs/pull/2220/head\n004180d61e0fd253aa2cc7164e5aac73db55886e3999 refs/pull/2221/head\n0041420e9ad5e9371c107e20567701a9c62bdd586609 refs/pull/2222/head\n0041334b98f26350b08cc361aa60f565a75d9f978baf refs/pull/2223/head\n00410fcb2406605fe89af2170aaa96023955ae5ba58f refs/pull/2224/head\n00417f931591d6598246e1287e639a7c88dbab8769a9 refs/pull/2227/head\n0041636c627c56659abfa94f3b174a955c43431bc962 refs/pull/2228/head\n00410750ec06fdb8a7260551a1418ffed2ec2abf3ee2 refs/pull/2229/head\n0040de452c4fd1246cf52bbd9c4645ceda3de6c963fb refs/pull/223/head\n004129262c9f369a71956672269273591b3df9deb9c0 refs/pull/2230/head\n0041aa6c2cba3baa4f75db6fd1dc9c9c169278675b4f refs/pull/2231/head\n0041e79047468ef8c346007bc49b4ca15462e51052ba refs/pull/2232/head\n004141dbd77d66c8e847ae4a050756fb789661843b45 refs/pull/2233/head\n00414d560813c21b161918dcae608f07d1f9713cbc4e refs/pull/2234/head\n004122f0ebda8c8a3455faebab7103ed4404c9ff7411 refs/pull/2235/head\n00410d17eb49accb16d99fa01bc8d4eb65b46064fd06 refs/pull/2236/head\n0041cd5ff3104a56a38459832b0633f4edcf7ff9aa31 refs/pull/2237/head\n00410a0bc8bd6460a7b25812d983da5db550dc76d9e4 refs/pull/2238/head\n004131a07b2e65aebd4d1d4c906bdeb1fed3c3ef7a7c refs/pull/2239/head\n0040e32f4c7c941701878876c9de2e08518ba91602ea refs/pull/224/head\n00417a1fe55b22e1434a91313c35cbf9cc42b83388dd refs/pull/2240/head\n00413aa885fe00af71417c226b1ec5d0c829d92c68da refs/pull/2241/head\n004100c27b14457adef8126ded51cac0b650e57cfd0f refs/pull/2242/head\n00414b7df140f591afd253524d75448ff1540e11ef19 refs/pull/2243/head\n0041213125f5f428522081e5b0a1fd5ebf2550b245c7 refs/pull/2244/head\n004148c0648928630fd92c05942651c58bb4ba7f1c3e refs/pull/2245/head\n0041133da4a081cda573e356869a8392001cfed4e240 refs/pull/2246/head\n004106100e2fc6697ddc4077f5fec5dbe79fc2dce6e2 refs/pull/2247/head\n0041d8624b9998a711b7cc914e68ba1b8a119594c38f refs/pull/2248/head\n0041e6d5b8bfb744c009ecad0fb24ce276d31e981574 refs/pull/2249/head\n00401269a63bcafa0a92f2e1829aef42820fe5454553 refs/pull/225/head\n00415941bfc3d1a03fa102884c3d613a81f725cb04e3 refs/pull/2250/head\n0041629825f050ff170c95576310afb19823c508567c refs/pull/2251/head\n00417fdd4dfdb1b6e73c6f86953ffc97d5107930fd9b refs/pull/2252/head\n0041fa119a1af06fdeb27b31ac519fd0057fcf0f9475 refs/pull/2253/head\n004171099af334de7a024a4571d0c647cd9a0d5fde8f refs/pull/2254/head\n00412d21b24c66b50082205f782f7344ae4813c45ea7 refs/pull/2255/head\n0041ac4141c55f3f4b5d7d3ff5033a12a1a97e48232a refs/pull/2256/head\n0041f8fac1b3d50f39304d5c7dd42b830099e555967e refs/pull/2257/head\n0041e80c3e46d85327c486f7fce1c227edfe2f47ea03 refs/pull/2258/head\n0041e580a0b41c95799a59de1a6352eb1c136ee6637a refs/pull/2259/head\n0040804c300357e5ea865b1f0734ca1b288b9824e0f3 refs/pull/226/head\n0041e3cb0410979c083c721381b67d078b399af64153 refs/pull/2260/head\n00417b08df0f563c470cff682acc3c0e75ae673f8fda refs/pull/2261/head\n00416a7ce25dd98b7c0f2e1c3a0b46dd6cf93f182322 refs/pull/2262/head\n0041c6a5bb2577cc8bd45d154f88941a44db3b49a7c9 refs/pull/2263/head\n004173ec1005082324b903591006a7a89a4c8dc2c971 refs/pull/2264/head\n004141dbd77d66c8e847ae4a050756fb789661843b45 refs/pull/2265/head\n00413db1c9e8915e7f9d41f86418bb2b528fcf2456eb refs/pull/2266/head\n0041612ec692a1fb65a7f0020893c16173180a44de49 refs/pull/2267/head\n0041398a14981d1b67234ace6833ebb5c6959365d78d refs/pull/2268/head\n0040cd3c3579d2e91ab8315033d631ac0ffd09c1b122 refs/pull/227/head\n0041a082503ddceac7818a48d9d6e11775b9b7abd9ef refs/pull/2270/head\n0041a2755281576682eb3b7a8c432c331fdfd182f2e3 refs/pull/2272/head\n0041bcd08855f4710a216ccf263593a53553da13286b refs/pull/2273/head\n00410eddc1a87b351fe3782d088b93d3f45a298ee96e refs/pull/2275/head\n00415acb9a51b5aba62d03e133713809ce1807068b5d refs/pull/2276/head\n0041a203057cc1610da990adadbe1b2efd8593b49ee0 refs/pull/2277/head\n004197bbd08b60887cef08b16e03d37b866ff03afeb0 refs/pull/2279/head\n0040a685f1407043126b0f9a58178ef646114ee519b5 refs/pull/228/head\n00410eacb75dbef06e696d4abc9e44da44681f18ead8 refs/pull/2280/head\n0041c0a4590e2fc1d34f8c1b9ff7f886f9f37f6998df refs/pull/2281/head\n0041bb68677c498455b5a3a3ecba740690a9031e39dd refs/pull/2282/head\n00417a708facaaeba62c106420fc562daa04b90fcc5f refs/pull/2283/head\n0041eae4cb56493d176a09b87b506ee202502edc42ff refs/pull/2284/head\n0041c660b81f9f64a1e80725dbd2f3344c806b289e1d refs/pull/2285/head\n0041266fecea8de4f0c30626f792d394d0e3eb713eed refs/pull/2286/head\n00419e697b940623bd35e83dde80f470a19d3999c479 refs/pull/2287/head\n0041770c947810a19a91a72fda3b89b55eb890e73093 refs/pull/2288/head\n0040cec929e0700eec11fcb037af820b866732aaad09 refs/pull/229/head\n004158851a2967f85a587f796c859902d5201cb45dc2 refs/pull/2290/head\n0041722966a516334503b056af0f6baf63512870a6ea refs/pull/2292/head\n0041b25a0343a9c5b0a61745992d0f0fcab0353231e3 refs/pull/2293/head\n0041c59dec15dda7f675dfeecae5762e79d5841f0558 refs/pull/2294/head\n00418b89469a6fdcf0ae2f8e9cbf8837519f72e3b4d3 refs/pull/2295/head\n00419e997869128d14f933c8576fa2a81d1c462460ac refs/pull/2296/head\n0041efdca6d57519cd59eab4cdc76b02a5351eedd3d2 refs/pull/2297/head\n0041a360036c0f2a7e5ac0d0b3cf7d0fc94fae0badee refs/pull/2298/head\n0041d262bd9b2e43a2509555606da2e36f6085d8955c refs/pull/2299/head\n00400475ac938bbb5cb40197427ada059eb5243b7de8 refs/pull/230/head\n0041de896066238434c861597f04830e2350ccf14af6 refs/pull/2300/head\n0041a33466756b9a142a551d821012cbbf10657576e0 refs/pull/2301/head\n0041df0b6809d11e355ff1ad89d1d3d1762aa73a07ef refs/pull/2302/head\n0041001683e3de01eac6ccf321c5e4e6cd4fc7cd8aec refs/pull/2304/head\n0041840ef6d2c8c8aff1d34f75f28f90a53165a8866d refs/pull/2305/head\n00419ae397c55ff42bcaee3613ff379d2097474f3a0e refs/pull/2307/head\n0041fb53a4d6a5e169546c3ac6b363eb79ae8518a37c refs/pull/2308/head\n0041c7ce7b31a5f6fa84f67ac9f679a547b3733aeab5 refs/pull/2309/head\n00402aeb755fba4bf6a99f61bfe6956ab96a7fb830ae refs/pull/231/head\n0041a9db0baa0d1a7dda80245c475907dff3bbb256f1 refs/pull/2310/head\n00414ec427e7e9ec750f9feec3f698d358cb883d89b0 refs/pull/2311/head\n0041b62ad3880ae3e9f7fd41477a95d9109202d105fd refs/pull/2312/head\n0041848395d7288d59879150360e19e62644e03692cf refs/pull/2313/head\n0041ba2b695f6ff28240f4515df9e2eaaf1a886b1cb5 refs/pull/2314/head\n004190fdce98cd97191757dbce7c6d57419e3621ff29 refs/pull/2315/head\n004123fde40696ca1064f9b6e0ae484e49ce874b6f96 refs/pull/2316/head\n004193610469ac4954549dfaf9e1feeca5dea4c64223 refs/pull/2317/head\n004134a5d87d55352c3072b6a3c56cc39f6a3c0f65ab refs/pull/2318/head\n0041ff783362dc9d7fdf3fd77c77d9cf7809473cc280 refs/pull/2319/head\n0041cdf30c1ca3370a9a3ad2083fc48a7d502f32a04e refs/pull/2320/head\n0041f59d3c47633d06479548a98927ce06ce68d9ab3f refs/pull/2321/head\n00412e92e42fb216bb31c2325d09f60b0a46b4cdf28b refs/pull/2322/head\n00415ef396e270514a865767c925b1f87ae3e08210ef refs/pull/2323/head\n00412d3d0383b6206c1417a2a722cca358474e05805e refs/pull/2326/head\n0041cdc0dd0c34fa40ca80eedc5eeeebf01bcae2c3f9 refs/pull/2328/head\n00416869265a2942c15ea761e67bc66db9562f67774d refs/pull/2329/head\n004028c2539e557607f01af2209e84acd9e686270fac refs/pull/233/head\n0041f5b98ebd417c7237016f3e854d52b5e08b6a8f3d refs/pull/2332/head\n0041b37363eca51ed2074ba14c783a306950395d6d60 refs/pull/2333/head\n0041caea44c66ec1e894a9ce19b45ba0803e91dcf034 refs/pull/2334/head\n004181699f1b0180d84807d3b271603f198564c0da2f refs/pull/2335/head\n0041670969db5ab91976b7460898133bc082aeb6f0df refs/pull/2336/head\n0041310337b2d15f84cb9aa5f52ec2ace71ad72ca9a1 refs/pull/2337/head\n004127fa8c9e231bdc898c8e443498b78a8b4dbedff7 refs/pull/2338/head\n00413a3ad45a08b61b486413b6e9cb41075ed9df21e7 refs/pull/2339/head\n00403244b527077764e80b45b3db7578d73d2c9f5ceb refs/pull/234/head\n00413acc99cb2a8e5b755936f8203cdba87294c4afa5 refs/pull/2341/head\n0041e823ad2d68d2f5f98c0e29552680329a529b7ec1 refs/pull/2342/head\n0041d2f56211b8d9532368bbdc3ada31ee8dcfb95658 refs/pull/2343/head\n0041171a695cb69631c02a7b7d550f29b30cc8d890bc refs/pull/2344/head\n00419c30b8df05b54ed5ec6977a66a0197325cc40ecc refs/pull/2345/head\n0041a92ceab7664a0d661915416c080a65fed1f49034 refs/pull/2346/head\n00414ab0211fe4793c03e7b80dc80bcbad71dd58f3c7 refs/pull/2347/head\n004137fd1809d654b407b6a90e3faa65c9d7bd767bba refs/pull/2348/head\n00416420f3a095a49d94a9655b52ea1e3ad54fd7a225 refs/pull/2349/head\n00407e700c03f3ea4b69e9d5231aace0f674f2d63b52 refs/pull/235/head\n00414454a155d98b81face0d996f8308fd30e38ae8bc refs/pull/2350/head\n00415dcc4b8d810db023367244a178f9404875221500 refs/pull/2352/head\n0041a6bd9150f09ebeb6174d705e751708bd613156fb refs/pull/2353/head\n00412d01b5dd757716c2eb1c487ebf0ac1bd3e927b20 refs/pull/2355/head\n00413d7510d288fa2de6b381809af97bfc751b1f8703 refs/pull/2357/head\n00411b067d9e86d5c78a980be46e3f98f8af8e5f8875 refs/pull/2359/head\n0040e80445c3c1e0763c426f7b92d78f091b23380b5c refs/pull/236/head\n0041083bcb998cc96cefc53fd93519b4d17564942e83 refs/pull/2360/head\n004125177884880cee0eaea80161ec8ce872db4f25c5 refs/pull/2361/head\n0041b42519882656e187838a6564ab8cdf28d47be6eb refs/pull/2362/head\n0041060afcd84965f417549523ec2b5014922fa8ad17 refs/pull/2364/head\n0041276b568aa4a599cdc51b1625ad0795bfc4213dd6 refs/pull/2365/head\n0041093a85d746876a4b9c2a5acfbfb4578f07e1abda refs/pull/2366/head\n00415fb92a7d0f87fe3b39b35705a550918f2942cbc6 refs/pull/2367/head\n0041d5129b49315371b09b7df4055b9b74f8ad6f0970 refs/pull/2368/head\n004153c8cbd87afdfbd7e4f21fde6f70d3d63f6ff970 refs/pull/2369/head\n0041385deb461cfe75d8f2b49cd79afe85b2f9a3fa30 refs/pull/2370/head\n004169eaf1f98d1e1357aa7bf5b6c4ff18e9c0d2a61e refs/pull/2371/head\n00415f8f47841b92e53fffd580697bf97bfa20e99249 refs/pull/2372/head\n00417d0cec1eea066cd8316e7aa8bfddb9960351eaf1 refs/pull/2373/head\n004198f5b4024878b2b933ff08f1e8ae8db14401dcfa refs/pull/2374/head\n0041723e75415aa9a1d3d51ca2135a5c6f344ed5511a refs/pull/2375/head\n0041f085c773712ff5a61081b2f026e950af43d3f541 refs/pull/2376/head\n00413273c2b532b413ec4e7160b3416c984969e0e5cf refs/pull/2377/head\n00419f466e8c67aad14f737bede8394070c817fb3d7d refs/pull/2378/head\n0041df5ade2b4255fc2ef383b904bac371124b5d6ab6 refs/pull/2379/head\n00411a120f91a8194c37fbe2b3dc492d5bc42a37f979 refs/pull/2380/head\n00419177eb30504073ec873dfbc9bfea30cfa315ec0b refs/pull/2381/head\n00415b36baf01fc4571f0f5a17a04d1fba9af0b707f3 refs/pull/2382/head\n004141823b27a20b40083babf1796adc1084b473c130 refs/pull/2383/head\n00419985707da73b8172441edead4b3311e4eba42df9 refs/pull/2384/head\n00414149c0606e8a1c9c6669c040e411bfa8007f486e refs/pull/2385/head\n004126642f323a2b16895c988c8d3f69a5abea830b72 refs/pull/2386/head\n00418ce847e1e9b52cec2b4f7c76c5c6b553e84b4837 refs/pull/2387/head\n0041af706e5db62b319e36eff1762d72279253491354 refs/pull/2388/head\n004174ddc85e532564929675e22c99f596db8e522d38 refs/pull/2389/head\n0041de884c6d079249833dea66ac47fd101ff49dd690 refs/pull/2390/head\n0041bb8a3cab19f159978fd284cf827e6d3767630727 refs/pull/2391/head\n00410bec7a5ddbd81e5497aadcd97af1d1ffbf65cce6 refs/pull/2392/head\n004187dd40648881b622da286c5604e61fd49126b640 refs/pull/2393/head\n0041e7742bf317d69f809a7b8b2472a1b11b2d2c6799 refs/pull/2394/head\n00416a44a361d9c30e4b273cc3b4cfd8dbba10034299 refs/pull/2395/head\n00414d2e53d46afa334c22a43a04e8a3b2c0400c5ea8 refs/pull/2398/head\n003fde471304b8809039fa0eeac16dd7b0be485ff4ed refs/pull/24/head\n004140f2b8ac721c5c69b9e03e660e45cc31f14ca4c1 refs/pull/2400/head\n00412200403ab1694860dc00c64812f975791ee8b0c3 refs/pull/2401/head\n0041659ba6771f5198061e426dc5f038e8abe4c05184 refs/pull/2402/head\n0041896b7fc1fac744370872f2d02ef22779cbdd5b5d refs/pull/2404/head\n00415fcc1acd354accce2b24fdde17e179a35271e1d1 refs/pull/2405/head\n0041e8f8dc9e7067c68eefae517e6a8399c7c9e19469 refs/pull/2407/head\n004121b1fb2fc8deae71339d215010d7cac1cf211024 refs/pull/2408/head\n0041a1d4c959a6f7ef50e14419e98e79c95d1477524e refs/pull/2409/head\n0040e9db3e9b11ec62a54c3d577611ab731304399ce1 refs/pull/241/head\n0041213f401da51eddf600c31d2146766553ede98336 refs/pull/2410/head\n0041ff4e99158f25a7e4a105c61182d315296f65701b refs/pull/2412/head\n004149822a087e6664e42793e64e7757e8f989e89dbb refs/pull/2413/head\n00429fbf25ea96735d574d397d7d55e08919adcbbdd8 refs/pull/2413/merge\n0041562776e43398c9374c3643d3e4a9c912d6883d9d refs/pull/2414/head\n00418184a3071366b1396eb5e644c094d0dd082a4972 refs/pull/2415/head\n00412f3860931c050a4d27c3612710c09e00a51acd04 refs/pull/2416/head\n004141b429bdf5da33b5186e77e873638678eb1449a6 refs/pull/2417/head\n0041bbb9dd6b8371c70c1b577115d623f602b5531f7f refs/pull/2418/head\n00411b0438d9c66e7953b39e950b44478f124ebe39d1 refs/pull/2419/head\n00401deb6dfe2f4fc45c29c0b8d71b56844537b1c67c refs/pull/242/head\n0041d64b2339f907bc2e87b2099e87864262aaa58e79 refs/pull/2422/head\n0041951eb290146095906b861e40b70011f3af43a2ad refs/pull/2423/head\n0041c45148de971b4a470a6aa59d1259cabc43d04078 refs/pull/2424/head\n0041add35bdf0ce1dcf0542c11bc03a3f621dfa1f7ca refs/pull/2425/head\n004159ab16098fc63de965fda5e26d1ccb80f3bba709 refs/pull/2426/head\n00416517510fd4157aa52bc416a0c0207e851e8c5ac8 refs/pull/2427/head\n004110bb922a48291075198143b9fd480116f9c913b3 refs/pull/2428/head\n004109f79c6c2e646d186b1309692fe952e176ae06a6 refs/pull/2429/head\n00407829710f4a46c40f293bec37928b367c59d68356 refs/pull/243/head\n004198b436b6ce8c261ff22637928904549afe822aab refs/pull/2430/head\n0041547b4ddc5410cb94e7933a75f10c517174cf19da refs/pull/2432/head\n0041292b8f13e9a7f52fe357d5151ee76cf20a4bc118 refs/pull/2433/head\n0041979cc590cf41a0e11cb25bb727a2fdb212b65cdd refs/pull/2434/head\n0042f9f006545e22eade6f64e51c56859e5c07c9c317 refs/pull/2434/merge\n004198868fd44e93cfeaa5764010e8cd0ecb25deb887 refs/pull/2435/head\n0041beec0b50694de441b44bf0c4cff2313f13eef749 refs/pull/2436/head\n0041354b9492efca1b7bc26a58f94cc50ec809d4b607 refs/pull/2437/head\n0041b5ccaaf6d14b340209801310ad9f2aee8f0b9305 refs/pull/2439/head\n00402f3c672384d91312a1f8eff3a96a8aa23f34d4ba refs/pull/244/head\n004163acf86f3d87a0fb4002748294f31bfc674c221e refs/pull/2441/head\n0041d740b3b3072dcb948c5867d0a887250eaa3a7263 refs/pull/2442/head\n0041d1debb6e4f4bd88be6d233416e12868a5e4f0c73 refs/pull/2443/head\n0041126f627a8892ee4bfc8239e2af53fa95cd8480cf refs/pull/2444/head\n004123f4f17eff6b2c1c018024188a10124485187610 refs/pull/2445/head\n004171fe69583a1b13c26855a75e1628307371e63988 refs/pull/2446/head\n0041c8007b462c8879a29ced069dfe457b8ca34333ec refs/pull/2447/head\n0041ba3776c3084c2f1e35a4676ea0b8b5fdd72fcaad refs/pull/2448/head\n00415de8899b83132a61e74b0230a5ef594d5435b70b refs/pull/2449/head\n00426dbc3b3f4114f36c643d3171d02074dc1758a1bd refs/pull/2449/merge\n00406e26224a25fd1ce7a69fa5a553f0742da30b3954 refs/pull/245/head\n0041b6cb3e25af8e2deb466c323aa2e88c3b91b3b9ed refs/pull/2450/head\n004119a7f0d260bf160cf66328e9fcb79720fff383b6 refs/pull/2451/head\n00414bb96a3b23d07cafe787c459c0fad64f02f09580 refs/pull/2452/head\n0042e467f9c0be92ac0c7478e19c8c0c7f99e049b2b8 refs/pull/2452/merge\n00416833a5645861d0a363948dc960e21aae3fb0c35e refs/pull/2453/head\n0041373146d9d49d393d5bd1fa4a9062e0c208378d45 refs/pull/2454/head\n00415a0e8b52b490e8051fd45dbefca805ae27e37d87 refs/pull/2456/head\n0041705c4db3669db09c408b5c6dad9fd19a5e2cdace refs/pull/2457/head\n00413dc8bac8888b8f300fd7a444d505c01fb3d90b6d refs/pull/2458/head\n0042e024717fa3cf7d13750bc6cebd24d02c9d085f58 refs/pull/2458/merge\n0041addd5b86dbd3851aeb2b3fb49e1bc8dea40ab80e refs/pull/2459/head\n0040a14d46ec3fd2d50347228b6ec12e2ea49fa1d3bb refs/pull/246/head\n00410361fdc945acef44b01165a60370ec89f8b22f2d refs/pull/2460/head\n0041fe355ab3587f23606f5cdc1d8ad9deb4f717b03e refs/pull/2461/head\n004173e07238cd5c8292439771ae72bba5d317c6008f refs/pull/2462/head\n00413ea86f3ebfd2c1fff96a46e36e758e5512cd2b63 refs/pull/2463/head\n0041ec6efd970e3e2ccb2ce455252664bacf7bb1098f refs/pull/2464/head\n0041c24df0da096dee8f5d0d586a63528a90225ffa97 refs/pull/2466/head\n0042b2a555e4d6d150a16e20294be939789729364768 refs/pull/2466/merge\n00417ff7113dd174210c8f538aa6224becc9cba0f1b0 refs/pull/2467/head\n004142910f296b74a0f836af130d8e0ffcf314be5a67 refs/pull/2468/head\n00418b7e6faf31e25910ff2279c2ce6f24977bca97fa refs/pull/2469/head\n0040bd318a9946c88a8bad7b7db9e3c7d309df7fb714 refs/pull/247/head\n0041b4c9e650744e0acc623eb20278139bbf486f6af1 refs/pull/2470/head\n0041b34de8305157f4fcc7f9ebb05665e0d3d49ba014 refs/pull/2471/head\n0041fe2fcce2bd43faedff5e2f751799933bcaaf88f3 refs/pull/2473/head\n0041cc35602f4ca4deb16eb47f53ab00e703f68612f6 refs/pull/2474/head\n00414f2347a072172e6dc4be36556e06013b7ef83fe8 refs/pull/2475/head\n00417fd8b4416f15763905a337b73400d04ade1f113a refs/pull/2477/head\n0041da27343a175a6c2d265329acbd24ec6b7d2277d2 refs/pull/2478/head\n0041dc3f2202d944dfdb4dd356d94232ec15300a54a0 refs/pull/2479/head\n004081c462de5b4be77a18f6502d55134651af4e775f refs/pull/248/head\n0041cd5a50b98e5a3c0109bb0f1c320abcf8caebfe01 refs/pull/2480/head\n0041f0edc1825fba3e79d09e15a4cb2b30aed5c130d8 refs/pull/2481/head\n00414cfc46a00d9f61093e5d7438173c8b5c55666552 refs/pull/2482/head\n0041757fbb92c2c3359ca69aadc5a85aaa3c5abee052 refs/pull/2483/head\n00424bd9b89a4723ce56a5f1ad4efa127204512919d2 refs/pull/2483/merge\n0041eb47ac1ecca4c3182241d698b648ef893fcc3f15 refs/pull/2484/head\n0041d7bf31d646f66b46185788f2c6dbeab1b59b308e refs/pull/2485/head\n00418675a0b953266c01bc5d32c8a5e291719a5d0b2d refs/pull/2486/head\n0040df4007f74aa72f3d1c03d1ce0daff237761d088a refs/pull/250/head\n00401635f714a5495f687e45782b4ab66eb42d0c7a08 refs/pull/251/head\n00405111aa6f732a44a92f5fd0c19d8186b9671894ca refs/pull/253/head\n0040a4581e8e3febeab26d866ef77ae26f9c8f8a26d4 refs/pull/255/head\n00403c14d051f305a0be658ecf6c98642517847c8f80 refs/pull/258/head\n0040bded0848d146eb0c233aa9c181326d4680ac3e8f refs/pull/259/head\n003f79a28b7545d178137db83f3f8adf14455feb0793 refs/pull/26/head\n00406f31d66051f2490c45b29e9d6c84eb08e5544417 refs/pull/260/head\n0040cbeaab2a51502e8fbb829d84104739850f50f068 refs/pull/261/head\n0040188d8414f7cc1aeb0a9e1e7668184aa56b33b2eb refs/pull/262/head\n0040ebc362b72806ffbfd769c3d19cc7f204173a4c4a refs/pull/263/head\n00400b1c90c84ac51778da84eeb8a9b9689416443f31 refs/pull/264/head\n0040b682d5096051e654e480cf40db1107376dedd37b refs/pull/265/head\n0040ade33a76ac1418ebe9b2f6ba5b3f1d776d024819 refs/pull/266/head\n004062da54e9be99730f0d89ce47f4d71f473e50b6cf refs/pull/267/head\n0040cd4ff5624fd65157528f2243cb21902ef82a6ad1 refs/pull/268/head\n00404edc393c56d4a2c0b4c7c8125752a8959cd3c965 refs/pull/269/head\n003fd665b8e6478068d649547bc2d36001d73163d35c refs/pull/27/head\n004090196e06eb596a8146b654fdef4865f90b7365f2 refs/pull/270/head\n0040355fab7e85adc982f1b4c6882b1d14ef73044e3f refs/pull/272/head\n004031f12be9970ed4d54045ceafaf65e0bcbdc9060c refs/pull/275/head\n0040a56387b3d0238a7cb9caa890fcf9150431729069 refs/pull/276/head\n0040a56387b3d0238a7cb9caa890fcf9150431729069 refs/pull/277/head\n0040f4e8069053317029a562949ecef0588e673abf61 refs/pull/278/head\n00402c1324f1a384dc7a18da5813abe5eda51093d3bf refs/pull/279/head\n003f70245086ba4738f4266d106af3b6429eb8c3ce56 refs/pull/28/head\n004044bdc18aea9dbb0349b32632f14f023f8eefd97a refs/pull/280/head\n0040ffe0898a49f91a88b5fdc9a963f94f5f5c5ab18f refs/pull/282/head\n00409dad380b4cab356a4d2b6395385b574eadd1f5d8 refs/pull/283/head\n004045715a32c2c17873335d8395f7bd43e82350fcb0 refs/pull/284/head\n0040f0ee734e0d67527235535c6655e886502521999d refs/pull/285/head\n004002202ee16193ae99ed3e9bc0f3ec883817dd05f0 refs/pull/287/head\n00404af00d86c44190de13b0e33f7dd6124ec77a29c0 refs/pull/288/head\n0040b195c1fd6d2482925035f697f217858c13b53a0b refs/pull/289/head\n00405f5747b92835d52d3032a26b48dacfb9ee2e16e9 refs/pull/291/head\n00408ad902c7c63a0f8e8d61f6fe04db1b33d4d7f005 refs/pull/292/head\n0040228ce21d0de6ebdf1952339796217012eadb01b8 refs/pull/294/head\n0040f9f993d981188015c1fab9e172c311de87082969 refs/pull/295/head\n004013bd1e82b3c584406aba45e1946ce294741e5bbf refs/pull/297/head\n0040ba3899886a590ca291ac8f7fe8d7fcd283b2bdaa refs/pull/299/head\n003eb0925e528c75d05cdc7b8f16ac500a7d3912560e refs/pull/3/head\n0040244efc9e6c61ed99462fa3e0bcc384ced1cca269 refs/pull/300/head\n0040452885a114b0fac92a7e845d2cc569af066be57e refs/pull/301/head\n00403cfedab773da858feee8541a4d738c7c73cb7165 refs/pull/302/head\n0040a176487c59caa1e9624b2d6406fead6aeca35067 refs/pull/304/head\n0040578b91862234ed8650ad5b03d7914d321c5f25f3 refs/pull/305/head\n0040d162837f8c08ddd7f6c9fb0e57c5c54e716db886 refs/pull/306/head\n0040518a444c79e345c0af1fcb4a4ab6574bef9e2acd refs/pull/307/head\n0040bfa275ba908f2fc6c9e4c209a06fd0f3f5905945 refs/pull/308/head\n0040c4c262a69c96ef6baaaee4fec325dcc5c536fa73 refs/pull/309/head\n003f90a7b27592c16171aef9a594392bd29164fff1d3 refs/pull/31/head\n004069940c13df4aeedd8d1adadbb4da52d2c4a94c77 refs/pull/310/head\n0040ac5232576700b8417ff859ab5f30a2c001653fc8 refs/pull/311/head\n0040fb0320867173cac3d6f85975b6b7bda9e298c83a refs/pull/312/head\n0040367f11a8e1bd75b36ee23b4c2277038e9dd2e1ae refs/pull/313/head\n00401af06d7061c8516c463eae852b60e4ad9f46ea25 refs/pull/314/head\n0040679e0336f1392f76424b5f0672e0af7fff45167c refs/pull/315/head\n00408da272d57f0f39905dd31aca1b6ff13e7b1f6554 refs/pull/316/head\n0040cfe6d7502821f60c09be0f6de2548ac952b01696 refs/pull/318/head\n003fb0aba74dee21251e105f3067868cc12278b5c528 refs/pull/32/head\n0040c4b08a881d301278195a9a902e4440d69b62f4c0 refs/pull/320/head\n00406e1e91f74fe00bb7254b52f514c106c2750f7ccf refs/pull/321/head\n00406cb0397d29f40047caaf1afe3cc671ecc9a490e6 refs/pull/322/head\n0040197ba229808a1f56d29682b95604d0bd6dc07335 refs/pull/325/head\n0040ad1da8a30d85ee2f2fb9aa118306c7bd6d83a013 refs/pull/326/head\n00403b3acfb7788ea4ddc1d6bfb98be03010f990264c refs/pull/327/head\n0040296d51fce4ae51ebb86c55829540678e60086e69 refs/pull/328/head\n00404af7cfdb68e5f3873f3eb2951af1369124988998 refs/pull/329/head\n003f818b4acf27ea1a15cdc1044330644c1cfa73b538 refs/pull/33/head\n004016e40c6af662eccd5bac877efd8cb6cad6501abc refs/pull/331/head\n00406f61a385ea76b457e49c89c0fe763836ee64352b refs/pull/334/head\n00400fb139e0f229bc3bee5f9d1c2b69fc3df2613408 refs/pull/337/head\n0040483bedf9124ca525337bf7a51194d6a352b3fa86 refs/pull/338/head\n0040ec31c6ccba4495a70e8e4eee3c9f35d5774a2bb6 refs/pull/339/head\n0040aceaf23725e2998c8f1ee4256ec1e98e837c751a refs/pull/340/head\n0040dab94e2d57cf5268aa46731e32be1cabc696a10b refs/pull/341/head\n004094b2648690bdd3d0e7701bda97012daac2bec1fd refs/pull/342/head\n0041367ed8cf1af506c62f5805340135b1616a33cf84 refs/pull/342/merge\n00405e5f6f1b00ed85e49ceafa6f092a9c73cd03c0a6 refs/pull/343/head\n004053721a8c18d17db62e3b579b9d51445a1d15ced7 refs/pull/344/head\n004000238d08c4a3a69d06adfe671928d21fdc5a4966 refs/pull/345/head\n00409e295e32d9aee35e3b7b82fbb5cf10237082cc55 refs/pull/346/head\n0040569b889262dd6e9d0ed31c3ad1a32647699cf6bf refs/pull/349/head\n004020eb0206c2f505cc055a4b012dea2d990848f585 refs/pull/350/head\n0040675c714afd33ad8bae20c1fdec1b89ad4123fefd refs/pull/357/head\n0040447943be37d3912c234716fee8c1c0e41f9d29bf refs/pull/358/head\n0040c5be3aefedf19e587aab82d3091efa8d45f5754f refs/pull/359/head\n003f2226ed66e79beb15cc0aa6a1f599ad999d829026 refs/pull/36/head\n0040d02d40447e6e1f04697e71e23043dadb54336fca refs/pull/360/head\n0040c6d02d122f65ce3550eb002e4cbff6f1307aaa6a refs/pull/361/head\n0040eb3e1ddd638cfeca39122a136c247d1dc4f639db refs/pull/362/head\n0040e74d30f2000b48af90ed4d40333618a50ecf9292 refs/pull/363/head\n0040f505c84f7c30558bf21fc55c88e021aae320b4ea refs/pull/365/head\n00400cd0f763dd8e79f247086d2718f636f139b63360 refs/pull/366/head\n00406f850b316daee1310b1b7f5af78a1efbb297db2c refs/pull/367/head\n004031c5b475c76fc045af9a0c78a20ebcca0e983e14 refs/pull/368/head\n003ff1b5f2257493f1769c4b87cbc89e7d7ce11dcd5e refs/pull/37/head\n00403910ca66b0bdcaefc605889f8a425a7fcb1fc682 refs/pull/372/head\n0040795ff641608bc1c23fbf30494e5d869c9da8cfa2 refs/pull/373/head\n0040a649e78a5ecf126e7d2b3aed6d65e0015b0337ab refs/pull/374/head\n004078e74531d1bbf5545f54294cb5b131c47eeb2bb2 refs/pull/375/head\n0040d0ac99e0512f68372640dc79713a4fdcf8559924 refs/pull/377/head\n0040bda25dfdceef3467a832680f34bfe0cb0e912097 refs/pull/378/head\n0040630295e76f43697299d8628ac7fb1ef95f30a7f0 refs/pull/379/head\n003fa870caf05460b3bbbe2eb448b6c0d18bb263ed5a refs/pull/38/head\n0040f64c8f85cf710376d0f9c07b200deae640baf566 refs/pull/380/head\n00401cbd09531c7d54743f1318badde9b419a63b1ef7 refs/pull/381/head\n004067f69495b71106e669ca7e0862dbcf64dacb078a refs/pull/382/head\n00408ceedaae6815215d6ececd8f210bbf9eb22d868f refs/pull/383/head\n00403b04d0aa87bbbcc628a31e4d69e829e7a7deb866 refs/pull/384/head\n004018467496d52836381889895ff676a9a87ec4918d refs/pull/385/head\n00403088dc4790b8831c4c62746d69b22bdb3bfa8469 refs/pull/387/head\n003fca28eb9ea1cf459ddcf751ffb0bd705837469ce8 refs/pull/39/head\n0040bff474ba2e69f0fb335be9d77bb49252dffb3ac2 refs/pull/390/head\n0040c56da2f6a8cd95e3f902847db9ad69eb92732813 refs/pull/391/head\n0040ce1db0fb6a3040392e4104434db266b01af4ee2e refs/pull/392/head\n0040d6b8f53795a4b4a4ce35f780ca0f86995bf7c93d refs/pull/393/head\n00402a7d3a655048ac0962dab5e722b0b04413a05502 refs/pull/394/head\n004055d36bbb2cc26ab2f52ed1eaf8f8ebce95415ed5 refs/pull/395/head\n0040b0e9a00ae59ec00c720301e0cc4db28dde5b4370 refs/pull/397/head\n00401e1dbb6849844d4083414fcf7c3db45d9564c324 refs/pull/398/head\n0040a2af12c43c384e72e328807f5053f05dfc2c02fa refs/pull/399/head\n003e6cb9d7bef7abd32798513d84a8c314dba0b4e812 refs/pull/4/head\n003fd25e61e807da4721c86ee9b36c89a80be8dfe526 refs/pull/40/head\n0040dbd66fcd24b4da5ee22b8beed51b1f06d3a69b92 refs/pull/400/head\n0040242969ab05f09e456b757c5e1245524579d9e3ae refs/pull/401/head\n0040b5af6c719caf8f4e51b3195039a7de926a0066eb refs/pull/402/head\n004087147fa1361efac6e22afff849f0840977a9c60f refs/pull/403/head\n004025308263154455941508385550e41dbfddb025bb refs/pull/404/head\n00409da0dc32c7654dec5b99387398653c4fbe1b5018 refs/pull/405/head\n004073e271dc130e54179aacf5ce46330e15dd9f1fc7 refs/pull/406/head\n0040713e8e5584e0182509291b17432573ce7892fb85 refs/pull/407/head\n00404d4bfee2296419d539fb971e814f675ac8214aa3 refs/pull/408/head\n0040118362bebf75f74e303a3f935d68769043a2f211 refs/pull/409/head\n003fe5050b593f17f4ce4431237656be76fe82ff852f refs/pull/41/head\n004035d293d2aab96ccd85208099e10c59b17ab1ceff refs/pull/412/head\n0040f13fb6e6fffb48b230951e871eba70b79b661fed refs/pull/413/head\n0040d625d77a400b5d956d84b2da92c480e5503cfe28 refs/pull/414/head\n00407eec67d424846297b7fa4e541f6e9efd41cd954e refs/pull/415/head\n004023fffc505907c6791eab950c89097a2e5f586ed8 refs/pull/417/head\n004003bef894e0bb21f55922dde797566629c68cb5b5 refs/pull/419/head\n0040aa90aa17689f3fdd364b542ae163e8dbbcae95a0 refs/pull/420/head\n004084ed687790904e855be5e1529abe8680402343d0 refs/pull/421/head\n0040fac9453409f869f24ead55efa206c2be2e3b2c25 refs/pull/422/head\n004042ac66f2fbe36b19865ba80e9974a6b7dde24e8d refs/pull/423/head\n0040c6d54fa4b5cab1d706c1a9ec379eb6ef646a8fa4 refs/pull/424/head\n004022155f2840be77e5cdf86e7c0de16e0e525182ed refs/pull/425/head\n00406298f31b4fa7fbce1e485dd4331478c8496bb19a refs/pull/426/head\n0040b25f94af1cddf24dbb394c98b2a27d2c14656ca9 refs/pull/427/head\n0040f88a7c790208a132fc982d9e05b3ebaf6498579f refs/pull/428/head\n0040bc9a53c78de9cf65b4f4c59c6812816fb58acf6f refs/pull/429/head\n003f365fb02ab526ded787f5e7a668b7f556b2a65f0a refs/pull/43/head\n00403adc71e200004feded19aad29f314a8da52211c6 refs/pull/430/head\n0040c302f0a6fa9667c918d50ad58737cdc728ad1d0a refs/pull/431/head\n0040eb065c53919a796a1a759c60da36142f7a950271 refs/pull/432/head\n0040da3fc3288f7a7b38d3ce9c4ccf488ec7102e5b48 refs/pull/433/head\n004053fcef8335dc34ef5d9a7628e6d609b602a0c075 refs/pull/434/head\n00407b822473f9ca8e5d8a2668af42cbfd4ecfcb9008 refs/pull/435/head\n00405370eff763402f14466bb66e492b8494769985ca refs/pull/437/head\n0040fac9453409f869f24ead55efa206c2be2e3b2c25 refs/pull/438/head\n004075277afc9e496dc8e2b9a984debb55c5b143483f refs/pull/439/head\n003fce48f8e7c40dead8e218c54f81ce5d6f553e7ac2 refs/pull/44/head\n0040f9dd53b273558ae02449adb6e60cbe36e3c760f0 refs/pull/440/head\n004083aecd97343321b6dd92a4a9ac753684f5a4545d refs/pull/441/head\n0040e05c257b706461fcaf01b37cf77c8c3b6baa5992 refs/pull/443/head\n00402b016af7334685b7c023c3069680c9aa314f191a refs/pull/444/head\n0040a434231571723de01bda5d058d1c336993aea91a refs/pull/445/head\n004038aa30a94c4be5a2dee06d1317809fdb82023a4e refs/pull/446/head\n004019b4c69d67c02f1ffe97680f69edaff54f853947 refs/pull/447/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/448/head\n00408d72b44f90df3b5478e73a456f36d5e9f579ef95 refs/pull/449/head\n0040a29a32905cb78effcfa3bdd798a23bc671dc388c refs/pull/450/head\n0040be8afa6e456327a7a240289ef3cacd76d6a532b0 refs/pull/451/head\n004094c7eabe76810c3d58aa01d0ad84f3779c5f2810 refs/pull/452/head\n00401735f06d84a1871f51c2796cbc65945e7273d8c8 refs/pull/454/head\n004078b95e7dd680cfcb7b3217152cb13b56a98973a3 refs/pull/455/head\n004005180116843d9e7a5a8e5932c3082f6412cc0dc6 refs/pull/456/head\n0040d26c65041ee8adf4c946334662c27f4400b05728 refs/pull/457/head\n00408c52a688057c76028c19df875c08dac9ff17b263 refs/pull/459/head\n003fccdc7a09a9637b6feb5e189f7816c4254688ab5b refs/pull/46/head\n0040fd5723c5943968c5c2c0786b35753a9a8b6211bb refs/pull/460/head\n00401bf029c2f551f8922cbd63e563f3f369a755d50f refs/pull/461/head\n004027c2db76973e960a21b8fb5bfeec6c9ac021216e refs/pull/462/head\n00404e94e29fdf73f8e68b83a6dc9f44a9264a0c5437 refs/pull/463/head\n0040ec910b56daca04df144df7bb0d956e3df11fa096 refs/pull/465/head\n0040210b8aac249fcbaa441dc78d04fd472d36247d8d refs/pull/466/head\n0040c8d72ac9a6be59939f1c8028e13aefa8909f54d1 refs/pull/467/head\n0040d60ec8fb3d02f056ffb34019ae10c987133e618b refs/pull/468/head\n0040282b6be5935e29bdde741e160bb0d50ea3c5ee8c refs/pull/469/head\n003f744298a098c786b0d529d62aa8d1286249149473 refs/pull/47/head\n0040c2c23687b07c5db83bb4fa6379d690de623c95b0 refs/pull/471/head\n00402b5a5d0a16e95df13594fc277fbe22bf354b6a32 refs/pull/472/head\n004083a39d98ea56e94d3bcd0fe77d29bd0afed9c713 refs/pull/473/head\n004002f214b0b506d99904c6a7236db04f134cec9399 refs/pull/474/head\n0040e7732b81e1d6c1a0331345cef7db8f2bac16cad4 refs/pull/475/head\n003ff7513f6bc6f3035cec70017cea6546b163233a40 refs/pull/48/head\n00407b6f4370182cc851e937c54028f107dea3e59330 refs/pull/480/head\n00402b8d96d7a65bac4e382973fc2bacca904150abd1 refs/pull/481/head\n00409ece98a791d30073ee99a5611ff9272ccb7e5356 refs/pull/482/head\n0040b243c02bc1ad90590f8b7f156c23371c3ea03f2d refs/pull/483/head\n00406df8e7087be81fd4b812fcede11fd0e5674e51db refs/pull/484/head\n0040a9fabce3377f4d18e4cc8a9ddf59e580bf24885c refs/pull/485/head\n00402e8657c8f04d205b670b701cc65f9b381c3ded1f refs/pull/486/head\n0040c00ade840a2d93536862d2efa898f300755af967 refs/pull/487/head\n0040972c5c251a09b49d3f8910473f6a7f85aa8c5798 refs/pull/488/head\n0040003cf8e4c2e814646e035a91c31577eff5459188 refs/pull/489/head\n00400b439745a9bb98fb128b84d88ff8cde4ae56a72e refs/pull/490/head\n004068217e9b5600af99ae2740d872ff9984abae5ede refs/pull/492/head\n0040ce303879a732e57f6c188444228900aae0899b8e refs/pull/493/head\n00409c940744e1bea5251308118716419f17eafd299a refs/pull/494/head\n0040f62e29e13a6ec1390e62fb5dcac3361109c5e86d refs/pull/496/head\n004038e9825184d1515f905fc8fda2c25b18fd0dd763 refs/pull/497/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/498/head\n0040fee783eebdeb9cca8719f6971544275c0b0722e2 refs/pull/499/head\n003e9ad0404fd0837ad18816cdb1b2ed5c06533a8129 refs/pull/5/head\n003f143dd198a6b9757a6a8f5f1b920294b6cf63d157 refs/pull/50/head\n00408911da36d53e42c5adc96017aedae08d808f72ba refs/pull/500/head\n0040288bef9d33623e619288b47931ce149df84ae03d refs/pull/501/head\n0040e287c6818ffffeb6647bd70df1f023b19064cbf2 refs/pull/502/head\n004073737c3d3af14d96f9352cfd919a1009ceb8d4fe refs/pull/503/head\n0040f9b47f3db60daf8416a553502c6942252be7dbea refs/pull/504/head\n00404d6c590eb0919bb7730a491a54287347529712d8 refs/pull/505/head\n0040c5171715f1ee79802025ca334f477abdf171ea10 refs/pull/506/head\n0040bfde45b8014fbe58bf2b62819224135abe40b5ee refs/pull/507/head\n00402394eb9882b57d3f02a3a85e8daba972c6bd3aa3 refs/pull/508/head\n0040d8c9694e9bece1216f77c4d5762cf7534474c5e7 refs/pull/509/head\n00401eb22e3bd0c9b544e10bc6d6e7f737a3177caec0 refs/pull/510/head\n0040e6675ce73ed0f14639a37e13bd038b67b51b377d refs/pull/512/head\n00406e8a392f238709989a97d3d58e3774eb8769b174 refs/pull/514/head\n00400becef9868dff05709b9535c5c426a8990621995 refs/pull/517/head\n00407a23ecd95e89a06cb2610e7b5a715daba9a03d60 refs/pull/518/head\n0040671d51ef3f2bf051eda2a74827f46ecc670e2601 refs/pull/519/head\n004092e6014653cdc404989ba84a26bf8b4b8902ddc3 refs/pull/520/head\n00409372f0a34f7e8b518b8e1a3c905b59fbee76c23d refs/pull/521/head\n0040f3983205d990edf7852cc471cbbcd0d5b96b9426 refs/pull/522/head\n004050e819818da849783e52a788611bcd772b0dff95 refs/pull/523/head\n00409ef1ff9f8685b666b934233c793c7117ead48de5 refs/pull/524/head\n0040fa66564115190d4b6d9e4f175f2401a3dd97d5ce refs/pull/525/head\n0040db20f4ca5a6a7e64ec2cd3471c9df9e43e43cd0c refs/pull/526/head\n00402a169ed865d0e2061779fac51ce8dc4e0de9aac1 refs/pull/527/head\n0040611a2ce0460467038b2567dca6f55bfd16f57ff6 refs/pull/528/head\n0040dc53775c9a44a88350301e29029f03b02ced623f refs/pull/529/head\n003f2af6d94aa0eb7930fb1fbe6d089f8fabdff11d02 refs/pull/53/head\n004092e6014653cdc404989ba84a26bf8b4b8902ddc3 refs/pull/530/head\n0040e7205c9eb73af5a4d92f7b7a8f176da461321d47 refs/pull/532/head\n0040ab8999e350e2eee93fdfc42bcc6054a6f34ce159 refs/pull/533/head\n0041018853cf7571d2031680de6e71ca7a11f8850890 refs/pull/533/merge\n0040941f031b04f6f7b39ecab9acc4ef4d6ebdfe25af refs/pull/534/head\n00400f5f7deb892f49ec54bb3878f9e3417937b0c347 refs/pull/536/head\n004097e877ac458a0335b541a2eb672a71483d39ed61 refs/pull/537/head\n004046b389d18db064c2edbe426768122cce9778709a refs/pull/538/head\n0040ad815f7e5bddb79d59865a1d91f582ab22df03ad refs/pull/539/head\n003ff6f7855dfb3acfdb0f14cb9215a8e7e8d29eb625 refs/pull/54/head\n00401454913de36b573e23a0aadc0d110009fa0b786f refs/pull/540/head\n0040452ea9a2ee332ba1d508eeb12bcd128ccfbf4eeb refs/pull/541/head\n0040dbc8ec0b247f7d39aea584841510e8b1f6bcdd8f refs/pull/542/head\n004096702db9d37131450a18e2fa4ef2f884cd7d11a2 refs/pull/543/head\n0040b941dc49583d4dfdd536806838fc3ee2c9309381 refs/pull/544/head\n00400d5c78fec78a219b90901036b2ae71137cf4f49a refs/pull/545/head\n00409ae6da12c3e8b0f9e47add5d26ea526be0dc627a refs/pull/546/head\n0040e3fe40ff3a95653d1a73ffc02252081b537cb6cb refs/pull/547/head\n004011fde285f72c89c9eb3a358e44b5a488aa0b6f66 refs/pull/552/head\n0040ce6d89c6ea9a9758d671a55a853f1defb4ff0919 refs/pull/553/head\n004080f883932c1e051f1ad3f72d6714e64c23e12d47 refs/pull/554/head\n0040a8ace595e99e563f8cd6cf3b847f5dfe4fefaece refs/pull/555/head\n004008aa09bb654cfde77261dcbabbc47b12f11b94ac refs/pull/556/head\n004001caa3f704de8f5e4b0bdc470d1e2676378263b9 refs/pull/557/head\n00401af75607f98ed329d14652931c799ed3cc7f7b3f refs/pull/558/head\n004090813a3537904c85edf184c2970211585449f507 refs/pull/559/head\n003f7dfe71ecd46059b7facd8f11fb93a05f1b421050 refs/pull/56/head\n004044cd652740030062b68dda4a8a2b56bc05f207b0 refs/pull/560/head\n00400333e8667a5b82ef1f69545435bca768ab96fc06 refs/pull/561/head\n0040f596832b8f409c22c032f06f0c390a5dfaacb453 refs/pull/562/head\n0040dece033ec7efe073be6c10647630c49066af7820 refs/pull/563/head\n004036db95b603e189a7883c9f8f8bc2c8bd237d94cb refs/pull/564/head\n00403a8dc1fc9d8190fb9dd3e769a0051f0ca58087eb refs/pull/565/head\n00408d8f35aea1b0c6024a29e0eadc2dd1cf6ea61588 refs/pull/566/head\n004039238b7f7a499e03b1f473b86a74dbae40ccc912 refs/pull/567/head\n0040b941dc49583d4dfdd536806838fc3ee2c9309381 refs/pull/568/head\n00404b56f4a28b5d39345eace17e0d5ffb82c0aa475d refs/pull/569/head\n0040b9797f4f65edf2a6d146deeb6bb8402574257cc3 refs/pull/571/head\n004061b9d6fff795b8a874a0cf7ba6a54cd557a207dc refs/pull/572/head\n0040c8c2d067a865421bf9ba2b8b25d27f263117d200 refs/pull/573/head\n00401fd09206f6e244f0099ad1caf2762b45f3f219dc refs/pull/575/head\n00403fb44a5c9ae5532d9b0588f912d3c4fc6907db2b refs/pull/576/head\n004058454406ad2ef5ef4dc7b67c51c0e979ddbc9075 refs/pull/577/head\n0040f936f2fc0d12ad55ed359a587237483cbbfefb42 refs/pull/578/head\n004028f167b17c267c89bd3e7f02759445c20f8bc2bf refs/pull/579/head\n003fb582e52794750d1ccd15c5e702a68467bcbf19f2 refs/pull/58/head\n0040903641cc13760e8c892640cdcc71fb3a79a00b70 refs/pull/580/head\n004089c03a1877f2a7863a28f204473117a234ef7fd2 refs/pull/581/head\n004012d40ad087dc3bcaab323cfe3caa5390c9368427 refs/pull/582/head\n0040e319b913fb9e89a6c74f448bea5772eb1dee3c14 refs/pull/583/head\n004025066b319e0909a1481becb5116e90bd9025454b refs/pull/584/head\n004011542a56a0898605a28c088d7ae6f186fb4b3918 refs/pull/585/head\n0040e69d18e13dc36b2ca7099d3b9223a7041490e4f0 refs/pull/586/head\n00408e430dadefadb1c567902ab96325a81222ae5300 refs/pull/587/head\n003fe4aa79a3295e8000fd1ece79a56e4d3faf8f80ad refs/pull/59/head\n004055fd5ff1c67649944a095fe9b8a82a45f68e3dcb refs/pull/590/head\n004081fbf50e37593dde081ebf0b7b1de2d25880d037 refs/pull/591/head\n0040b21e3b766dc022e144a2b8b67a076a678b932743 refs/pull/592/head\n0040e047d701f4c8ee52b14b87999ffe08b7421705cd refs/pull/593/head\n0040f5babe3c3abea9f48c48f50218673c60d3cfe751 refs/pull/594/head\n0040e35836392fd209337d97336bed2a2906f47580a4 refs/pull/596/head\n004028f167b17c267c89bd3e7f02759445c20f8bc2bf refs/pull/597/head\n0040acee602bebf073fe15335b7c8a79c07fdacb3687 refs/pull/598/head\n004069567222b388afa940bd84190b455fd403f75e9e refs/pull/600/head\n0040d889473e50a94af92096f4f9bd8f2a567c05534a refs/pull/602/head\n004026db8a5a64f7aabf0a5026db611413ff295fbd64 refs/pull/605/head\n004060fe2d5d3466b5e820dd1820fdbb893259745e1e refs/pull/606/head\n00400742c085ee268fd31eaea0dd8da74b0a04d1181a refs/pull/607/head\n004098f261769a6f5b192e8c5e1020bb33c6fbe2a457 refs/pull/608/head\n0040a4ae0bf87f13851dd0fcc0c118e8b2b4323de212 refs/pull/609/head\n00408782289280bee40a4e94b22a37731d349493198f refs/pull/610/head\n00403057d4a45105c7d84baa25a5875dd1484684e337 refs/pull/613/head\n00406b658da55604658b5e8e78d7396f1ee23746f548 refs/pull/614/head\n00403df6522684ebe78a210046331c49a4615e85254c refs/pull/615/head\n004083a576f28c4b6727b27d6d94645b9f3932463787 refs/pull/616/head\n0040b85e4f5d37c8e04d55be31dc14ddd34df2f32e24 refs/pull/617/head\n004005ad248090b82fa57c14e5d9f0499a2cccc3106c refs/pull/618/head\n00402719b26e16e4a529361e35d25c2dad9b41a12ac5 refs/pull/619/head\n0040f6a203eda01006b94f37b53c4e776b6c1a38b7be refs/pull/621/head\n004060a364d8573ce2541bddb70027552ca69cdf8698 refs/pull/622/head\n00403f2a95ae1c6251412179f57508ce34c0827a8cdf refs/pull/625/head\n004004ede1c6a7f8b25aadb264f35efe7594c881ee0d refs/pull/626/head\n004063208318dc286d35a9e774fd203bd2c4a6bfc2f6 refs/pull/627/head\n0040372613e728da9bd97a30d01b60f32bc692fb996a refs/pull/628/head\n00400c4349e90f13c574bf46190fdc8c29efccbf51ff refs/pull/629/head\n003fac28fb90a951fe0a334e8ea974cb9d0830f8acb9 refs/pull/63/head\n0040f320b871049b7a21e25bbd9ecf6628b006e63db4 refs/pull/630/head\n004078004fb399747b6ddeadddb3a38f07a382061f8c refs/pull/631/head\n0040e6aec7aa5cfd7640aa939fb32609085cd9d35257 refs/pull/633/head\n00407b890e47285100f3b8d108033b37759725fe1e48 refs/pull/635/head\n004004ca8160cd3f3fb51d0f0e70dbc83710d954331d refs/pull/637/head\n0040f055bed5b72214f3e25286d69a5ea8696cca7d25 refs/pull/640/head\n0040b8ff2c64f502de807a09adac61b8da0bd7db5ff3 refs/pull/641/head\n0040776d6d46fbe8a70dbaf0791f63c1990bd881a3ac refs/pull/643/head\n0040d5e7494e5045f834569e278a7c1b44c91c53ee4d refs/pull/645/head\n00408caa1bdf24ad0303bd5d51de6984381354e41562 refs/pull/646/head\n004092b454d6524c3ab1eca4d843a37dbece32c418a2 refs/pull/647/head\n00402c4e9ffe944ff579ba992cff67c2130521832b0b refs/pull/648/head\n0040826a3a72341a4062216a56292d9626ff8cc76b6c refs/pull/649/head\n003f936df80471e524ca4e30d4bcd9c6bf2da1619dea refs/pull/65/head\n0040922bd29d0957d2bcecb3a4acf4b88973bed7621c refs/pull/650/head\n004061545d6eb37dba9adad76de739ee55d67aefa497 refs/pull/651/head\n004071302a5f59faae567849835faf47f419473b4d00 refs/pull/652/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/653/head\n004011d7a289c85480c74b3a274f22b99fafde4683a7 refs/pull/655/head\n00403069934324473370c83c8da418df32881dff9d85 refs/pull/656/head\n004085501cab1f30c5fc7475b51c0da19c2c474a53ee refs/pull/658/head\n00401691abc91ed22323c7e4b6517fa9d35aaf08203c refs/pull/659/head\n003f816891117afee70c3b6ccd7a3e4ed1f91bff3ba0 refs/pull/66/head\n00406cd1cecf9f64c545b2458bf2dead4918e2614cb8 refs/pull/660/head\n0040944eb940569b05e656637511b5657f302d14906a refs/pull/661/head\n0040a46f29da0320caf0138193af25b903d78d590bc7 refs/pull/662/head\n004043e604f269b6b07936fab6c787d32305546f7a2a refs/pull/663/head\n0040f37072f8fc388c8e9bd7bdf4a9bc2269e225a5b0 refs/pull/664/head\n004046fe9ce1d6955b1e123a836df17dbfcb9cffcd8c refs/pull/665/head\n0040bf2c8d5ccfa0c12de5874bb0f45e6a5ab9e3afff refs/pull/666/head\n00401de22909ed1996aa641ab70a9c986eb0ede742a2 refs/pull/667/head\n00401ff1cdd255e44061a2f78d235df584da00b5a6ba refs/pull/668/head\n0040892b384ee4a135beeed67fb0176fd6c04b0f83a0 refs/pull/669/head\n004039b922c380d8428d988b190c8c7b94344eef6a5d refs/pull/672/head\n00401b0311dafea5b3dc2f0a58a0635f79dd2b3224e5 refs/pull/673/head\n00403332370700ac736a5f312922303589efc41d8641 refs/pull/674/head\n0040621291bc9ff0cd5b64be7f7a31f33a77ae00c3b6 refs/pull/677/head\n0040840d9fc1b24479dc8adb5c9e0529055b1a1cf05d refs/pull/678/head\n003fa97e2e51ee5589d1ff14c3248043f2f62f8a26e5 refs/pull/68/head\n0040c93e9b5322e726767eb154411faf828e1ebfeab1 refs/pull/680/head\n0040eb439aa8b43ea43350534767e748aa6b8cf89a9d refs/pull/681/head\n0040629fd9edca7e930f1ea146db0becb0698d10e50d refs/pull/682/head\n00408e5a46bdef1cfe0e5705f48a3b18f99bbe78da0f refs/pull/683/head\n004066b76d0333cd0bf7c262dbf354821f7853080a79 refs/pull/684/head\n0040a123ccea8a7e5444faee428d06c0de3daeec4d27 refs/pull/685/head\n0040ed24702a797fee16808e0e2b27299fe63042af08 refs/pull/686/head\n0040973ceecc1638cab69ee6f4d61710f9d7d3d5efd6 refs/pull/687/head\n00409eca1945adb78d495b7ea37f416e2537b4f87562 refs/pull/688/head\n004056a659057ab574138c55b2692ceeae2645d91eab refs/pull/689/head\n003fb6dee38c2d63797fdcec086779098dc843480a69 refs/pull/69/head\n0040fe42f7d66c778a6915978d7e5eaf66b6b82f3b9e refs/pull/690/head\n00404698b3a302ef8ff9f30093cce7866acd06b434d3 refs/pull/691/head\n0040c27e84c8ceb61593314ab913a62b28edf5ec5f08 refs/pull/692/head\n0040f2f4eadb64d52684babf6d2ddb1000b5675366eb refs/pull/693/head\n00402524e022c98d1234669b3455f447478b9c81011e refs/pull/694/head\n00403d337516e9638647ddc1cfd69bf9a66934c242cb refs/pull/695/head\n00400fb585f54f7d8df4f4b73ceeef9eeb23fa3abe20 refs/pull/696/head\n00403bd465be77b51dd671871d913dbec3199b6ce16c refs/pull/697/head\n0040c7b9817cdd0a628e115179b386622e2cc89977da refs/pull/698/head\n0040b2e84be34bba70cc9488b7eca43c8d61aed1795d refs/pull/699/head\n003f9b874c5b0a86f1d65813d47c6dd78a6978754d8d refs/pull/70/head\n00403b4004263226b700f218533a4d5f1fdbe3b9be01 refs/pull/700/head\n0040a831edb9b6a397bd7c3698263e7b13fc495e6711 refs/pull/702/head\n0040f20fb3088846b39a337247e110ea304e19d14380 refs/pull/703/head\n00404e5d20976554ebbc88942d8514a35b9100e2dc09 refs/pull/704/head\n00409aa5d9b5ce1574304e420eb687c343729b204f12 refs/pull/705/head\n0040f9ec83f0c814ad9e737c5297831387adbcbcf0e6 refs/pull/706/head\n004011e1b7f9cfce840f6740cd5d3b91cd0de92a45e4 refs/pull/707/head\n0040a6fd606a568c680ccda176fb957ef4e7b8298603 refs/pull/708/head\n0040e63703543172b39ba8d76ec033ad5f858ea1e3f2 refs/pull/709/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/710/head\n00405292706433f41e67862c2c820b28417ae5a38e6b refs/pull/711/head\n00402cf888c8a56abe135361400475651f5b6ede641e refs/pull/713/head\n00402f795191896af78604cb103ea410ab491ccea85b refs/pull/714/head\n00409e7e84192717765fc65f41f106004429e63f2d0e refs/pull/715/head\n0040b992c004b36fc196874673a908f2d1bd22e318da refs/pull/716/head\n0040d60a5b259927e4f583d50134a96d23474e25620e refs/pull/717/head\n0040345d2baaadcf922efd507f05aa57ca6d8ad5e94f refs/pull/718/head\n0040cf764d67334bcc631c3412fc1e9e3743e20bfd31 refs/pull/719/head\n0040ed8e92f8a37c67095c6a3e2d3b021a9dcea510ae refs/pull/720/head\n0040139a03596c3e6dfb1a80bbc6877893c4c7fa64b4 refs/pull/721/head\n0040267acb6858c99d595411265d0535d3efc6af7f20 refs/pull/722/head\n00408bfca2d6e3018541ca05b8c0e3b6e2fa5512764c refs/pull/723/head\n004091ceea20296f42ee0d8ae56a6b44f676599758b1 refs/pull/724/head\n0040e95b8a788552537f9a11c8d12b118358b650d6c4 refs/pull/725/head\n00400ae9453fac7ae281cf31b35e99e04f8b3f8f15c4 refs/pull/726/head\n004053808a2355467a36667756cf17efde378ee3165d refs/pull/727/head\n00405ef6da531c461b0546345f9fbb25acad3e2255d0 refs/pull/728/head\n0040bb837b452ee7fb7522be487be0232740fabd81b8 refs/pull/729/head\n00402a7655ffe65892c0ce95498a36923db4668f09e8 refs/pull/730/head\n0040aa6378a0c7dd6ddf791933498a4a0eaa2ae1735f refs/pull/732/head\n0040ceb986e61c4838c72c7184baf5f3fb45f0f97429 refs/pull/736/head\n0040cd2b3dfdf10cbfef76d4055a305c336321b148b8 refs/pull/737/head\n0040c769b140bf506c1ee4fa83390dbf497caaf341df refs/pull/738/head\n004061f91c9dc338600307f00571d535983e4ed14929 refs/pull/739/head\n0040acdec9b61fe5fd912a04237663c5ef3f9d847f5c refs/pull/740/head\n004090719f5481ff990bedd7fb7ea94e4b7aeeb0fd4b refs/pull/743/head\n0040a61cbad87cfaea6b145243eb90c5b537e066adc4 refs/pull/744/head\n0040f0fbf6d15624894bace340d7292a18bae49e6b54 refs/pull/745/head\n00406ad567e18284e4ced6c65fb10b49bf6cfd4e890f refs/pull/746/head\n004011bf6277d81e9820c2e36b322f0701818e258156 refs/pull/747/head\n004015ee6b7c0e410dd5fa43236252cec7cd6790ca9c refs/pull/748/head\n0040635a6834b52656e19030b42aab949f7eca986cea refs/pull/749/head\n003f382e0370aa33b5f3901fb4bd9ee5e44890724480 refs/pull/75/head\n0040d6b597a14e84f63242b3f4156de42d09889ee485 refs/pull/750/head\n0040a4ab4739e78d23030b21f0eb902b00d93b005b16 refs/pull/751/head\n0040a5070313a1baf80b93e6dc540b04eb74fc5813fb refs/pull/752/head\n0040d746cb6da820fc16107bbf4ec6d1af30a4710dd5 refs/pull/753/head\n00404ba0154e8ead390b4de23d5cf92d42dd501ef638 refs/pull/754/head\n0040c7e3065a18bd585909f374ac98bab7a085de1f19 refs/pull/756/head\n00404f7a3c06fc89589167534fd08abac1ffbe6e966c refs/pull/757/head\n004054b427be3c11680def676b578fa015f703540c7b refs/pull/758/head\n0040dc5bc42a7e0a72dbe2768dbfefbebb8ea5a992f9 refs/pull/759/head\n003fbfc6aa37be811fc6b7c141083a04f0b1d36a4007 refs/pull/76/head\n0040e707d208d104a44505fc1cbfcfa5a377dd675afb refs/pull/760/head\n0040084176a1059466af78d1ed41c0968f02f2a6c8c5 refs/pull/761/head\n004050d4e1617c135d42d2fc4df5ea9df169b4c5dc04 refs/pull/763/head\n004081d35661472fe799c41bfe3bf14815d7898be65e refs/pull/764/head\n0040e30eac78b7efd50c1e1664b7ccd6a46cad0c6357 refs/pull/765/head\n0040e2e2b58ecfd46da2250976eef17ba3f17d3ee6a6 refs/pull/766/head\n00409cbe19f019daae3e82614b4fbe4be683462337e6 refs/pull/767/head\n0040d407774ab1f23bccdee67a8f2c5d8b204d293ccd refs/pull/768/head\n003f75bac6c257e11af3dbc6bb3473efb452a8676fa2 refs/pull/77/head\n0040e32a19d8f94dceb03a2f67eaf98b0196f7281a11 refs/pull/770/head\n0040a7015d7091d16d6f426b968c7fa5ab2a0fda5819 refs/pull/771/head\n004091d305f5e791c640e499b3e1336003df515f230f refs/pull/772/head\n0040b15989230f1768a41dd0bf7835732b32be5c8de2 refs/pull/773/head\n004030f09f6a986ace57c20bd098c1bd5a30b09f4839 refs/pull/774/head\n0040477c4fd524718d7cc6cdfaa4a5993861332151e6 refs/pull/775/head\n0040399ba7ef32e0e9edd93eb133380ce8232dd7d4e7 refs/pull/776/head\n004083057171f2f16e65a5a9b712f0c8105a19e24a25 refs/pull/778/head\n004041b8a27767c438488457a6f56ba8a427c7723bfb refs/pull/779/head\n003fe6325cd88200e60ec723e8fb27ca960891569b67 refs/pull/78/head\n00400e622ae0abcce683414a36b55c7b1f7ff05a8b3b refs/pull/780/head\n0040b6ec2183f4168eb94540f19bfebd1a0448cafa61 refs/pull/781/head\n0040ac9d4ddf7c6da9dd254c651c21c991908a3efd23 refs/pull/782/head\n004073d0275a4a51b1eb24476f691c9eb49d0febf5bf refs/pull/783/head\n004074ee9815a27fbc867d66ff56cc0da34638f5413b refs/pull/784/head\n0040e0348f06c231815852cf432dd68c715bb95d7942 refs/pull/785/head\n00409b97eba12029ab017c28d75b0ad6b1c1d9695118 refs/pull/786/head\n0040f1f859d1b1db31ef4d9bb4e49a0fd10b1eade958 refs/pull/787/head\n00407fc32b3f65b240ae060afb3e0f31a7ff2d69f14a refs/pull/788/head\n0040212c57a643dc3b3ddd1b9d211956fd055d78824e refs/pull/789/head\n003f76640aaf845677d939aa5578237974d3fcff27b7 refs/pull/79/head\n0040d1a7093297b0ce3d81db935e4565f56d417c756e refs/pull/792/head\n00406bc5b6dfd36a9cef9b70a9d7bd822ac9154f808f refs/pull/793/head\n0040f40c753b86c6015dd7db80f8dd2867427cd83185 refs/pull/794/head\n0040657a24720972a37343978ab192c8f6f3531695b2 refs/pull/795/head\n0040100f6e334de39c3083ff0ad29986b5ccac9a806f refs/pull/796/head\n0040f38dff092a74670b2ace1a563657388ac5d2b601 refs/pull/797/head\n004080326c5446873cb5497019694aad7186f4f47278 refs/pull/798/head\n003ee54eb95679c706bb9d610481d1d96d5d3659c707 refs/pull/8/head\n003f373b99cbadee55101ed30e9737ec3f68ef2fbbcd refs/pull/80/head\n004006ad66c4f02ff7d48f7f4fe41986a210cbf08ed0 refs/pull/804/head\n004002af4a60e843863487053afa4e16dec87770ed55 refs/pull/805/head\n0040fffe088fa6dfb0e29296e64d689c5a580a6a585b refs/pull/806/head\n0040cf4bac113710693ad48597fac53e003765809d8d refs/pull/807/head\n0040eb9aebb4aa1960a61c86b055d7b43f1bf30dc2ad refs/pull/808/head\n0040e1bd462ccdde72abb307783414f18449ee8f367c refs/pull/810/head\n004000bd42a3359ad1bee3e0f8baa0bf9f6e11f91524 refs/pull/811/head\n0040f88be1e087ce77f11a55b483c325860ef674cb98 refs/pull/813/head\n00403a78548fda6a433b5a7ba85382bd9a3e23336b31 refs/pull/815/head\n0040a23c1ef8a80506bfa41a3f8fbc813305a6ae8eb4 refs/pull/816/head\n0040cff83e26d6b40924c8faa6116588ff70673f6558 refs/pull/817/head\n0040f71da79b826f7e07c1d3d1203b6ef807008aa4d7 refs/pull/818/head\n00402056c1aac5f3fdeb77121701a1ee45e4fa81eb9d refs/pull/819/head\n0040b050172863cc26434c80b2192992149fb53c61f3 refs/pull/821/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/822/head\n0040681c53aea42f51098793bc44f8b5818742bfe2ee refs/pull/823/head\n00400336c7de64f55e57c87009c19b19e2a93f3584ad refs/pull/824/head\n0040ff8aee76ad1ea6d56a2e7e8aac88d3deeee58566 refs/pull/825/head\n0040f33a77df57317329c29d8f4e0ec7536dcceed709 refs/pull/826/head\n004096e6a65699d269443be2fedf2775f95e52f872d7 refs/pull/827/head\n004038a80294dbd30ebb6f7708f5a1c1e15386c25fcf refs/pull/828/head\n0040d7b155f75f5b6a355c22a635df5011b07001b2e7 refs/pull/829/head\n0040432a4bb4c9606e99c41186a49607682da95e937f refs/pull/830/head\n004048da9b8cce538e01570673e1463af2c4e922214c refs/pull/831/head\n00408c427dc8a00c8428c81e0c70775a0b4749361656 refs/pull/832/head\n0040ea4710c0a648cb6534cf1bf2c957d4719524c5b9 refs/pull/833/head\n0040d135a145144fbb70f8a18bb9bb368381cd2e9003 refs/pull/834/head\n0040359f417d5ae56820a247b2d4ab137761be4b7808 refs/pull/835/head\n004024c1a97f28c40fc3ecad10edbeb1d7d7aea65ede refs/pull/836/head\n00405fe7b19a14351516fb514fa5c496d11fa59b8b08 refs/pull/837/head\n00409f0f70d5cc62df3eb070be6a9399a2ea125d0928 refs/pull/838/head\n00401a6c6bfced06a5f8f688f640223ca70ecedd6cea refs/pull/839/head\n003fde384e0d47c73a443be98e1626f4a2030a186b8d refs/pull/84/head\n0040b2a8175b32d930213de109d9fa5d7df6719e5ecf refs/pull/840/head\n0040ae4828d069c8c2a785fb4f5b49ce94cd2db05392 refs/pull/841/head\n0040e1bd462ccdde72abb307783414f18449ee8f367c refs/pull/842/head\n004028a7ffc150194668b70a04912843ecc0d171f7e9 refs/pull/843/head\n0040037c3543ac60359190459b10fbb5331568b4c8f5 refs/pull/844/head\n00405761166dd8ae69272ec0634dbd41e66cca0cfa5f refs/pull/845/head\n0040009f460af86ba742fab59878e9e86567ed46b4d6 refs/pull/846/head\n004045b5a8c5bbb44139e0625b9deb3b6545e74b45f3 refs/pull/847/head\n00402fcd46715333de00a990264ebd3570fced45949e refs/pull/849/head\n004057af90d4022ee5adfdce175ed6d3f01b7659a142 refs/pull/850/head\n00407df4c2642994b77f2b05e764b044c33993616e8c refs/pull/851/head\n0040f2ef83c7825dc0de95479c0888518f3b75beac00 refs/pull/852/head\n0040e9fdc9a0cf3c01c41eb7f648baf4f20dd8b61a64 refs/pull/853/head\n0040c939e15728e43bf1087293161d56ee01bb19695d refs/pull/854/head\n0040011f8c8950e89bb1ad9bdafce8a437473fe39ee9 refs/pull/855/head\n00404ca052c3cfcfe7aa8fed53f6a4957bb3b65cfaaa refs/pull/857/head\n00405769e69b9dc282b0a4c904819e306b82aff4269f refs/pull/858/head\n0040300ce5e2fd07e5cd9d41d112f07e1e2772756ab8 refs/pull/859/head\n0040df89acbaec3c346d36667d2ec049ca309047dac2 refs/pull/860/head\n0040274094a4b067716bc905451e445f854704575419 refs/pull/862/head\n0040d856c4e49b2016abc2905f1f6b24710a9d1063a4 refs/pull/863/head\n004020fca611e5c9da75894779bcdbac190c81a41c58 refs/pull/864/head\n0040ca76ee6811198d38c06b8cf02505b828f293523c refs/pull/865/head\n0040d3185ac93522c480dbaa1e479daccfed0b0e86df refs/pull/866/head\n0040f1aac37fe441c416842dcee21846c976bf82028e refs/pull/867/head\n0040ce2ad9b7b5d24aa337d5305f245335c74b377bf4 refs/pull/869/head\n003f69205fdfb3dbd604a165cbefe7bd116380ddb0b9 refs/pull/87/head\n004074e2029633b59a239aceb2ff9689aab46fb0269f refs/pull/870/head\n004001cb7338bc2915f23629e3b56a9e04feb21a48eb refs/pull/871/head\n0040538e76d99a2ee402145801518e897715561b68c6 refs/pull/872/head\n0040bf2503051b00e2ab16adc77f5d6b920088d2d1e5 refs/pull/873/head\n0040adf23fe73d66bf4a5eb1c28e9202b2ec2b108513 refs/pull/874/head\n00403ba580ead644168aa0fe109fa0c66db43e92d505 refs/pull/875/head\n004091dab8f0ecba342dbb43d92ae5a0ee0b2b9d2a56 refs/pull/876/head\n0040c5bdc6001d2494d8bd85b4c53b44e5a7d17a96fc refs/pull/877/head\n004015fefc390b71f7dec7a5e957b2f7dafc652cd713 refs/pull/878/head\n00409988aa6cb57d99be647b06acb2aee87029ab47d6 refs/pull/879/head\n003f4215fc60b039358b7b25c738f77d0a7b0cafdc74 refs/pull/88/head\n0040fb68f5b16adc288d4c3cc51acff850880339f677 refs/pull/880/head\n004039342563fe83c443c9e896d9f417df8826c65e8a refs/pull/881/head\n0040b049b2af26e1703f0887516356147e0ab1a2c881 refs/pull/882/head\n00406b27d53a4fca05cdd8ea92cf6e20982f10cf261a refs/pull/885/head\n00407c69ffc21e56cfa1e776eec683025b060eb7dedc refs/pull/886/head\n00402ff1267bdb33581baab1b8894e11a9ce45524856 refs/pull/888/head\n0040347ca611bffafaea9a1106716a451540f31d6a60 refs/pull/889/head\n003f237281ebdd37ac26e0c3aae9a0d64be1a96fabf2 refs/pull/89/head\n0040eef642b3533197cf97722797c5ab259a445bee6e refs/pull/890/head\n0040efd820c3b0841736eb6699b1b455924cbcd3099c refs/pull/891/head\n0040c03816f1930f1f18e7aabea7901ce24018e08111 refs/pull/892/head\n004066665868beeb7f8440dcfa44382a55feeea92abd refs/pull/893/head\n0040fa3ba07cecc8904bbdfa869f36f96fd20dafab9c refs/pull/894/head\n004094e7839eb50b5c4f7a1f7b9186b0635e76b89044 refs/pull/895/head\n004042fde53f7fa32eeb6e181d4c44d40b260cfd0b37 refs/pull/896/head\n0040efcfabc77bf51bcfc988608415855110a38d46c8 refs/pull/897/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/898/head\n003f9a1caa6ba84b07b5d56ec3a257e0d4b3234e3c9d refs/pull/90/head\n0040001c99ad363d4c73a0ed2b41a42ef077aa55b908 refs/pull/900/head\n0040743f5f6983b2cf9c209054ddc2bfd073b823e057 refs/pull/901/head\n004062106593de05aebbf1b33e6b55a74249475c81c3 refs/pull/902/head\n0040fa0ab05f34df3053213d9fd2edb5f491372179ec refs/pull/903/head\n0040e482d41641eea8b783edc0f72a83d14335fc4dfb refs/pull/904/head\n0040722ae5807ce8fc540b6e968f65892cb50a5486d4 refs/pull/905/head\n0040984b61467f9613dcc89cca99a6aa5b528db87021 refs/pull/906/head\n004056ab40c293c02a6027ffc9f774016597eaf96b4f refs/pull/907/head\n0040f14aa2b05dc4e742820ca6fd80192b4616195f5f refs/pull/908/head\n0040e3e7b64a3d547fc5a124a77632621749b645f760 refs/pull/909/head\n0040be090e198b6a9d5c5d2572b4298aba6cc26e6bff refs/pull/911/head\n0040d2072e429e9b43577f629099bffd60cfb2589daa refs/pull/912/head\n00403c6c38ad7d4095ce89cb7c6a3ef6d75d8ffd3b7b refs/pull/918/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/919/head\n003f8c665f9bb94f9aca5ff50341e2830cd8a0d52e15 refs/pull/92/head\n0040a51f2e8d03985c7c8bc80b8f3ea4eaf8e5c6ba19 refs/pull/920/head\n0040a89d7976562683919cfddfa363e94efc366ff859 refs/pull/923/head\n004005c9d84d00d53ee8a981e4e215bdc83e9bb22b9f refs/pull/926/head\n004052f5e5412de74d5941e4e511729d1aa9d861c025 refs/pull/927/head\n0040f686754f9c56a7a9261a7b5928c7965201fd5cb0 refs/pull/928/head\n0040e5dac1059eab97466af6c4ca47956fac9b3e24d7 refs/pull/929/head\n004012e841e3603fa5f254038030f5aa3b7977185358 refs/pull/930/head\n00401d48fb2720eb8713115d1266eb9452977b58326f refs/pull/932/head\n004032963c33409075798c3a105cac04d5553ea13102 refs/pull/933/head\n0040d0f4650818b34f9be70b6513998ae84b2c6246c2 refs/pull/934/head\n0040a102582671179e3217c102f23f1d8a04f3edb485 refs/pull/935/head\n00404e81594d7aca587367eba09b6b4411b321f2ef56 refs/pull/936/head\n0040e27740039e8bd36e32d2c5d754e6c92c86c5f963 refs/pull/937/head\n0040c4ffa47ff7011b495a146bbaff01b31514b9ee04 refs/pull/938/head\n0040c132a552e0795263438df99eef3b2c4632c93d32 refs/pull/939/head\n003f013774b69b995be5744bd49e0232f3dec0b2a93b refs/pull/94/head\n004077c08a2ab0157524ed6a086006fef76ba4bfb260 refs/pull/940/head\n0040f8d712a563c02e6f3a37702b9f0896fb5f5ef061 refs/pull/941/head\n004098c56e29f1f275209a0d1055d59f70d2a9876a55 refs/pull/942/head\n0040f89731a864346dd51cb1722d1c69d04211c1d485 refs/pull/943/head\n004078fe74df59864017f89cc065bf1e284fbdd5b9cf refs/pull/944/head\n0040dcf3bc2fa1c683634031fb99bff85a33b3010d6a refs/pull/945/head\n004002ada34bea2919fd82260a88a4d0183e32ff4481 refs/pull/946/head\n00407bdd987696b6b35402e77bb0d377cc758f1bf08b refs/pull/947/head\n004007f48ad4782a90046362ad2f15272ee8d6a758bd refs/pull/948/head\n0040c8ebb9c137eb5030bb9f016febe729faa44b39d6 refs/pull/950/head\n00400ddcb393a921f24989318b97b273493d6ead5e3b refs/pull/951/head\n0040eb14d7d144fcc50e521e7c1b42bb666cda0342d6 refs/pull/953/head\n00401b192c378638f9ca47933864d7c221c13391953a refs/pull/954/head\n0040dc08833463c8a6f5c481b525336965481c7e862a refs/pull/955/head\n004046442d0167b0a3eb233796737add2044e5fcee24 refs/pull/956/head\n0040c1beb099fc399ac9bcbbfcaaea445f22d8ae291b refs/pull/957/head\n0040856e26ad1856e68df26e320e8b26766cbc069eed refs/pull/958/head\n004081757df8bf740d6115044ed7be6851a2263fd4c1 refs/pull/959/head\n004061c3abfb301bb6cbfa7609bc10073cad7f1877fa refs/pull/960/head\n0040f472991d4e3bab100a51f00fb39e82a53ebb2c1e refs/pull/961/head\n004009be902bbf925a84c492a353cacd4ea2bc08ef86 refs/pull/962/head\n0040ce718f77c0d6abd993f325626f7371af8af8f818 refs/pull/963/head\n0040a2975709e828fd220c3f34427fdf7b862446921f refs/pull/964/head\n004014da5f6cd993f00995406252c89d021f3b296161 refs/pull/966/head\n0040569e876fce72a7833687aee4bc4f75e73a123113 refs/pull/967/head\n0040533b32d9ac759d1f09d4c7aae5d47615615d9ab9 refs/pull/968/head\n00403636cba6d472a7a5f2f2e772d1152cb8d4d466a0 refs/pull/969/head\n0040686ae85680cb92107a2951849312ef7d449baa58 refs/pull/970/head\n004079f4e14dc8f1c22c606c53dfdacfffa9ec09243c refs/pull/971/head\n0040ce3f784c8c3bb317686ebe242a40ed208281b2ce refs/pull/972/head\n0040ee82da89955148e0f441ef92812f89a43407b945 refs/pull/973/head\n00406f96ecb86ee791b6a76152fab22ebf7918149a04 refs/pull/974/head\n0040b498309092685b6ba33e77c2ea547f7937a54d97 refs/pull/977/head\n00409ecc534fa7187aba7b569abee15bb34b228c6edb refs/pull/978/head\n00404793a46e88f1bbce733c30de062dac6c6a733e41 refs/pull/979/head\n003f7c6f3235fdf07c5112acc071842bad7f18d99df0 refs/pull/98/head\n004003a4545113b883c75a0ca7b2da43b5aa8e44f22c refs/pull/980/head\n004064ea62fdd701be13d140f23585fc684bcff8bda4 refs/pull/981/head\n00404d21a6ee70683d43a9ea02f30241fc7e5de1dc75 refs/pull/982/head\n00407f59b2e565a976f52d2da4a66dc7fb618455ee4c refs/pull/983/head\n00405e2b50db94c7407daee033fe3686e611228ce7b9 refs/pull/984/head\n00408d65fe5f4e56555fcc229fd3be617abc28a43f4c refs/pull/985/head\n004042cfeab1cc55bc73aff5d8171013f16d6a5ecfa5 refs/pull/986/head\n0040db1edfb78e883c898207fdeedec21d7175cd877d refs/pull/987/head\n004068d4dd170aa98cba54eb23e3bd8a43eb112ca5be refs/pull/988/head\n003f134098bf54a9a1f2cbeed7c6f31661e09381070c refs/pull/99/head\n00406229b7a8bd02bfc1f3f714d0450b4123cf89a590 refs/pull/990/head\n004013a3ba837c44252f71c4b3160a19839a16e4fffe refs/pull/992/head\n00405f2db79242337a5d213db9fd6dd521f7794a7d00 refs/pull/993/head\n00408ce1a31e0f5e0a74a28aaa56c8daaa50e21d63ca refs/pull/994/head\n004010c35fdd46012cb957bab469cdded2e58292b198 refs/pull/995/head\n00407c61c0b7caf4705942588301c01b6e9cce7300d9 refs/pull/996/head\n0040dec0a1617e15bb1a2fc89a03ccaaf8806f38a546 refs/pull/997/head\n0040caea5c733154add2b3e83876f04ac455326855ad refs/pull/998/head\n003e194c5efcaed9fed321ba2123745f78827a3eea03 refs/tags/v0.1.0\n0041f3d3ef027896e318b099764bc855062821e1de53 refs/tags/v0.1.0^{}\n003e4a24731816a98853c8b30196635586fa65fe3cfc refs/tags/v0.1.1\n00414057e201dfa8b58656e84789a726919098061025 refs/tags/v0.1.1^{}\n003e0014eb08b942762f103c967e587f9bba6f91fc53 refs/tags/v0.1.2\n003e1ef42d0bd5a7da2b93fb3b3b80b0f8fea50e7600 refs/tags/v1.0.0\n0041c6ed0fabdbe8ad75465bd7eab81ba904a9c89f42 refs/tags/v1.0.0^{}\n003eac28fb90a951fe0a334e8ea974cb9d0830f8acb9 refs/tags/v1.0.1\n003ee20621776bbd2e799537eb3b0328398ccd5e9fdb refs/tags/v1.0.2\n003ea6c6cd756e0cf4fd858398976208145cb23e707b refs/tags/v1.1.0\n003eb33258df779c4cf0fe02961874dfb1bec16080f5 refs/tags/v1.2.0\n00419647b493034ab334e071921becde06bad8de059e refs/tags/v1.2.0^{}\n003ecfe6d7502821f60c09be0f6de2548ac952b01696 refs/tags/v1.3.0\n003e7c08000dc3a0b1a690d46f70fa97b3fd87cb926b refs/tags/v1.3.1\n003ec6d02d122f65ce3550eb002e4cbff6f1307aaa6a refs/tags/v1.3.2\n003edbeaddee112d005d950988cf07c09d91a4966fa8 refs/tags/v1.3.3\n003eb5af6c719caf8f4e51b3195039a7de926a0066eb refs/tags/v1.3.4\n003e62df1c5366410936e29a986e73362afc9f3a5cb7 refs/tags/v1.3.5\n003eb5f7502d2b76b1b84201937aa759299d23e02c48 refs/tags/v1.3.6\n003e51fc4fd651c23e5c7e209db1fcc8d6ed68d07789 refs/tags/v1.4.0\n003ec50977954ca3d2cc4cf37c52d2dec3e75a97b7a5 refs/tags/v1.4.1\n003e137255296e89d6baa9df9c7f7e950a28c1db5c74 refs/tags/v1.4.2\n003e6316373e47d7e3e4b4fd3630c4bbc10987738de6 refs/tags/v1.4.3\n003e060799ca816dfa40afa05e48c895c0c9fd79b90b refs/tags/v1.5.0\n003e114c256d14e094ec5874cd9d14d03d27c4086b90 refs/tags/v1.6.0\n0044fa8e74ec2517b1bb371b4e7c739fe1efa4175532 refs/tags/v1.6.0-alpha\n0045cb3eeb25026a6da102d2f2835af053c48c55a901 refs/tags/v1.6.0-alpha2\n0045f6b044300bf29d0b7ea3cc036715e6fc32ecf134 refs/tags/v1.6.0-alpha3\n003ef6b044300bf29d0b7ea3cc036715e6fc32ecf134 refs/tags/v1.6.1\n003e5b4066c7351b045a433b1fe3554260c6f06b7237 refs/tags/v1.6.2\n003e037c3543ac60359190459b10fbb5331568b4c8f5 refs/tags/v1.7.0\n003e43dda7afea9d267f5d448709e75e2ae7147c29d4 refs/tags/v1.7.1\n003e032296dfeda9ceef9fc46ffba9d032cc52f3428a refs/tags/v1.7.2\n003e645d5b0bb9c14741b2147a5305b684e4abc039e0 refs/tags/v1.7.3\n003ed4657bf46aea52834c5148b25fb6cab132c69af5 refs/tags/v1.7.4\n003e2d1181a69fdf3263083dd8e3c7ae0feceae859fb refs/tags/v1.8.0\n003e46aee59befed6edb5fc737ef35b5febf987cffa9 refs/tags/v1.8.1\n003e1ea785e56de9f7817c57266025f0a56279141053 refs/tags/v1.8.2\n003e18ab43f94e2c9dd4477191c82bfdb2d6cc244e11 refs/tags/v1.8.3\n003e4a318af4a84899723625da2927c30fcfb7247126 refs/tags/v1.8.4\n003e6f61445b22e99d3a0a3ffb5dad7b723a9fa84964 refs/tags/v1.8.5\n003e1386406b64edd4544696183f273139ef9298f5df refs/tags/v1.9.0\n003eb13f37e1a1e4cb98556c1d34cd3256a876929be1 refs/tags/v1.9.1\n003e1e295ee11c5e107886e58bacb04228325082146f refs/tags/v1.9.2\n003e0e986b49c4e7ee5aa545531c4a8908455f8a9e82 refs/tags/v2.0.0\n00442821e79ec1d938ddeab00522619c3a67520f6c56 refs/tags/v2.0.0-beta1\n004429aaf53c46427b2fde72f7aa7a62992dfad0e9be refs/tags/v2.0.0-beta2\n0042baab0d06596a51f593aeefcbf089527f2d3e194a refs/tags/v2.0.0-rc1\n003ebe9015f3256940e63d99b9d1a009f99c7dc4d8ec refs/tags/v2.0.1\n003ea2a23858b9650035f019219937f91ae615474b4d refs/tags/v2.0.2\n003e4f77b30556bb6d171b5d55f01da4fb0261b9da7d refs/tags/v2.0.3\n003e9267fda97136812f3217852fd380104487cf4a00 refs/tags/v2.1.0\n003ea14aa98ab8408547083d4411091c5fbaf5b47d8e refs/tags/v2.2.0\n003e04a8728383d8f286cf2b0f110e68482e8773df6e refs/tags/v2.2.1\n003e16ed4529c0d0cc1ddf1bed2fb08deba187339673 refs/tags/v2.2.2\n003ea66ef4bd60622d94e536ee3ee5592ea1e3e9a382 refs/tags/v2.2.3\n003e8b6727b2c439cdea8bc3a033bf7c76d76cbaee08 refs/tags/v2.2.4\n003eb0b6027aa7b2b50fd3fe5fe185d609f481f02a44 refs/tags/v2.3.0\n003ed03774202cbaf17a260c2f4a073585baee524b45 refs/tags/v2.3.1\n003ee2a5d93abd9c85d068755973f014d28d6cec02c1 refs/tags/v2.3.2\n0000" + headers: + Cache-Control: + - no-cache, max-age=0, must-revalidate + Content-Security-Policy: + - default-src 'none'; sandbox + Content-Type: + - application/x-git-upload-pack-advertisement + Date: + - Wed, 28 Jan 2026 02:58:00 GMT + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Server: + - GitHub-Babel/3.0 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Vary: + - Accept-Encoding + X-Frame-Options: + - DENY + X-Github-Request-Id: + - 3CCC:2C39E9:3E08AC:472066:69797B37 + status: 200 OK + code: 200 + duration: 769.955237ms diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_and_an_unusable_repo.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache_and_an_unusable_repo.yaml similarity index 90% rename from vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_and_an_unusable_repo.yaml rename to vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache_and_an_unusable_repo.yaml index a06cdf7beb4..a71477fdfc8 100644 --- a/vulnfeeds/cves/testdata/Test_MaybeUpdateVPRepoCache_Test_with_an_empty_cache_and_an_unusable_repo.yaml +++ b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_empty_cache_and_an_unusable_repo.yaml @@ -34,7 +34,7 @@ interactions: Content-Type: - text/plain; charset=UTF-8 Date: - - Mon, 07 Jul 2025 03:38:50 GMT + - Wed, 28 Jan 2026 02:57:57 GMT Server: - GitHub-Babel/3.0 Strict-Transport-Security: @@ -44,7 +44,7 @@ interactions: X-Frame-Options: - DENY X-Github-Request-Id: - - 4439:145DD2:22D032:274FEC:686B4149 + - 3CCC:2C39E9:3E0659:471DB4:69797B35 status: 401 Unauthorized code: 401 - duration: 359.096713ms + duration: 323.283995ms diff --git a/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_existing_cache.yaml b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_existing_cache.yaml new file mode 100644 index 00000000000..3387f8df67f --- /dev/null +++ b/vulnfeeds/cves/testdata/Test_MaybeUpdate_Test_with_an_existing_cache.yaml @@ -0,0 +1,54 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: github.com + form: + service: + - git-upload-pack + headers: + Accept: + - '*/*' + Host: + - github.com + User-Agent: + - go-git/5.x + url: https://github.com/google/osv.dev/info/refs?service=git-upload-pack + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: "001e# service=git-upload-pack\n0000015b5ffcce399241fd59809e7cc6e0f31a13c28ec017 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter object-format=sha1 agent=git/github-bdd2406f1b30-Linux\n003f5ffcce399241fd59809e7cc6e0f31a13c28ec017 refs/heads/master\n005372fd51767b95fa0ab298d580c1214d8b7ba67a34 refs/heads/promote_prefix_ignore_prod\n006592a9a438fb2a2f8f53f1d6073d7eefd7293da553 refs/heads/reduce-importer-log-spam-8993462065003763829\n0049c718cee0e2409df8bd503255fc60c21bb6d661fe refs/heads/reproducable-zip\n0062536d8403169585521583475f89d6ce5aa03e0a92 refs/heads/temporary_modifications_for_mass_reimport\n004e2c85053cfa420c869bae7ef023c52300eaa0ad2c refs/heads/update-pr-permissions\n00472c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/heads/upgrade-schema\n003e7588d54370e7336f1063b3ef96112797016c521a refs/pull/1/head\n003fa2ac801881f48bf9047dc4ca68f9587a4781bd7a refs/pull/10/head\n00407cb597c5a84af14690b0ea49312ed7eda06552fe refs/pull/100/head\n0041f8bcb25186df1323e6fdb712e580556202656a9d refs/pull/1004/head\n00417a8c671bc9e97f92924965851b471c8aab1ee8ca refs/pull/1006/head\n0041bd500a4044afbf9d5c49977fada634356c4fc101 refs/pull/1008/head\n0041605331fd14e43a8e905cea5164a62387afd51d71 refs/pull/1009/head\n0040e0cb2c344ca0730320533a43b10071b7f4312473 refs/pull/101/head\n0041485f2b6da3d617788879c786212a58557c12c5cf refs/pull/1010/head\n0041f94d9c56ce66d401e2ea5d53f3d9addf6a218fdf refs/pull/1011/head\n0041e20794697e7cc44aba013c331af176cb811ad551 refs/pull/1012/head\n0041694cd5f0828ac7cb3e2d9b320515b8ef03c2606e refs/pull/1014/head\n0041d52d02ff5c97f677510c7bb9b2985db39c6fe796 refs/pull/1015/head\n00419feb39025a7cf0fc86cb6ab0cea814e3c53c674d refs/pull/1017/head\n00401349f69d688fc7a509215f9432ec73dfb46b8a61 refs/pull/102/head\n00414c5f3de7c47d6688f77c4237bd2d5f60cae0cf7b refs/pull/1021/head\n00413809cd3109f476a78e197446c08bf33a4ca55c00 refs/pull/1022/head\n0041b13a6f1110ec13e0a8bdc0c01a6916ff0e354d3b refs/pull/1023/head\n00411eec3164523b5821d4c5f011871871b15fab207b refs/pull/1025/head\n00413348d2f75453c4e73887799b3acfab01a6bd73e7 refs/pull/1026/head\n0041b53cbd1cb21af23acc46a7954291b63dd5c3ac95 refs/pull/1027/head\n0041933eb1962638d9dafecde200304b15fb5408d3b6 refs/pull/1028/head\n00410a12cc1f3413dae4d84d63ad8ed1c6061b329347 refs/pull/1029/head\n0040cac8c823c650078345e35c8a813f38599775b833 refs/pull/103/head\n00411098e2c8c83ac74d287172b8e0fef6f68a1b1b65 refs/pull/1030/head\n00413b911bc5ce4f58aaec84b36fa7221c9e6b8aeeb8 refs/pull/1031/head\n0041ae07ed72ea2cf91193f8641ab0171b81d226879d refs/pull/1032/head\n0041911aac60254233f36c9fa8b352d9b8af3659a2b5 refs/pull/1033/head\n0041188ddfb6d0fe396bc04f255d7a397da940cc80fa refs/pull/1034/head\n004133f110d8a987995a37085a6f749731ba6079d10b refs/pull/1035/head\n004120360a60cb396c3d3e70dfa97c221426e651f9b9 refs/pull/1036/head\n00419b7028075b186cb85fb1162626bc8d35ab190945 refs/pull/1037/head\n004118fc7c0fd0e0add81d729d5e94ad8752c1c57190 refs/pull/1038/head\n00410804317ab3de7d5f993fdac0a0a43896862a6ef0 refs/pull/1039/head\n004053587e5a82398d23e39165d358f8093f797c5aa2 refs/pull/104/head\n0041fd4f821b02dae483809871416ac633e45836f6c7 refs/pull/1040/head\n0041032ece4b67ad99947c5c87d22e7474bad94521f8 refs/pull/1041/head\n004124080a2e01350075cefb33f912d77193d1f4de03 refs/pull/1042/head\n004136143d4cadc1bb7ab1fdc4d0dc7746dd19eeda97 refs/pull/1043/head\n00415b400eba34551913d34764cb8d5acca6f0a4f3ae refs/pull/1044/head\n00418fabf11f241e11624c91601a0596491ffa3c0d96 refs/pull/1046/head\n0041e3432ab171ecea3f25eeed5caebd19365f2753d9 refs/pull/1047/head\n004155ffff4042fa481e0ad1842f711a9f17c4cf5329 refs/pull/1049/head\n00402bc665af22bd913071393eeb5b56f8eb8afdc032 refs/pull/105/head\n0041a0c78dc0629761e3d567b8a268b433bb336019c6 refs/pull/1050/head\n004116b14e3bfddfb2bc8a0823d218c9fb55c35caf51 refs/pull/1051/head\n004149a52d949c8c923a33f8714a2175ad46b5e57db3 refs/pull/1052/head\n00410376002d2b38a6232eaa8a66cbfba525befe984e refs/pull/1056/head\n004195c7d0521ed2ea24906a34903e6f2469d4fead2d refs/pull/1057/head\n0041c30a6319d0e78c5694e2049aa9592bbc549adca1 refs/pull/1058/head\n004168154d8f0d81656f0ce6c8dd682d62fb307537c7 refs/pull/1059/head\n0041d16773aa81db518a3a2d92c90f3e0c97dab5287e refs/pull/1061/head\n0041e28509db3aab8aa7529d0795237be7eba62081e7 refs/pull/1063/head\n00414388c2adc25321d6a6006b5e5a5c32ec4b667bca refs/pull/1064/head\n00413844a6050bc4d2e8a90a28ea675e75f07283892b refs/pull/1065/head\n00412d68c51e1abeaa462580db118c06976cae5757e6 refs/pull/1066/head\n0041765995426c75aca4ffeea95f17c9029833ca8ff1 refs/pull/1068/head\n004137c97f269ed9064f88019191bdfcefc7618f22ec refs/pull/1069/head\n0040e822ea91aa0806b3de8ad8c307653ac7ade7fce0 refs/pull/107/head\n00410408805073cb0949236ca0700989510dbc7a240e refs/pull/1070/head\n0041d5e2603a21f3a25aed411d6b306702b67b1234cd refs/pull/1071/head\n00419c0c3019d9151e70b86eb3fce732f67f002d1d85 refs/pull/1075/head\n0041655ae019e7dc23f7d0f0053ad0ab4b216ca8101e refs/pull/1076/head\n00418d05e98430ef70cfb241571300687e3d0b2da4dc refs/pull/1077/head\n004190a77a72bf7b1514f8d91f1e2e10dd27b685cddd refs/pull/1078/head\n0041ba4517b948d070865726525ce8f6f92bc082f74a refs/pull/1079/head\n00402ada540e49327edd5997909ef4c3bd9965fef118 refs/pull/108/head\n0041989ed566cf6bea122ad73b4ff33ec8f10277e923 refs/pull/1082/head\n004103380f4390ab124fb1e93dc866643794e852a1b2 refs/pull/1083/head\n00413791ee0d863a87b8569332494539fc64509b870b refs/pull/1085/head\n004194059682ef11325cf7295e0168965353b96e72c3 refs/pull/1086/head\n0041f1d03baec460b46b46334f40e9b6c0722f9a8548 refs/pull/1087/head\n00415b8db3e7470201d7b3e755144c413dbd55ce6f81 refs/pull/1088/head\n00417621c0df9aa340cc08461ad41a171cac9948df96 refs/pull/1089/head\n0041a201dd01dbbd2fe51655c2b5a772c94f07925fca refs/pull/1090/head\n0041c6183a91fa972b2b28978cd34bbc4ece0c93d034 refs/pull/1091/head\n004100fc04e29e3d78ed91f9713fdc9a207e24f4ee2b refs/pull/1092/head\n0041c1fb4fb270577a0fd2634c149f6d4de024fdf1ee refs/pull/1094/head\n00414b1f9f0b4053dedfbcd1094f9fe134a8a7591a1b refs/pull/1095/head\n00417ea4d86462f7299ad5e017bc8ca69c4970addb59 refs/pull/1099/head\n003ffe47213e95bdcc488ada1849e9a510bd6d2e36bb refs/pull/11/head\n004057843634a14a6b67f8e75e8493a36398f88c6061 refs/pull/110/head\n004130eb8f7bf2c089a49f240ec7d69918c0e2949e70 refs/pull/1100/head\n0041be9176bb6398a4305e45af0ba76f8c816618f2f5 refs/pull/1101/head\n0041839788f01f9d6c4bc25f7f2c599ccd4da8cbf03b refs/pull/1103/head\n0041cf14188cc12ef4de9d966a7f42165cefd46bdfa5 refs/pull/1104/head\n00421fb31e43d570a544d62c175fa325f27e25afb552 refs/pull/1104/merge\n004133f55e55ccd34157da77fc2ed8143f75a681fab3 refs/pull/1105/head\n00417795cd32bbb6492eb117e45001b498d3c4de704d refs/pull/1107/head\n00414ff9acaceaa374fd68c248096e24b0fbe6477c37 refs/pull/1108/head\n004179cfd7131dc021a00a1fc78262a56edabe4e8acd refs/pull/1109/head\n00400a5b4257ff2e70b78134c8c41067928b65d650d4 refs/pull/111/head\n0041e2043c6fd2f27b60945c85d68dd81f59c765cc94 refs/pull/1110/head\n0041a087b854e11a5bb8b43f79bb9c3c2cad81f0fa75 refs/pull/1111/head\n0041c88dcd99d1d61ce90db741986178851e94dde070 refs/pull/1112/head\n0041e394a186b01d402a32a06803e79041c4aac015f8 refs/pull/1114/head\n004137f9c94f61d6a9407286f144870376e8d0907779 refs/pull/1115/head\n00415b470a1df2c11ca8c7283f7dae08a5e689e7a67a refs/pull/1116/head\n0041ad2cfe753e9ad1405b82344b7e5d248a9fd23432 refs/pull/1118/head\n0041527139dfdfdc3872980f2cc48f88c1685702b5f6 refs/pull/1119/head\n00407d0bc21474662422503c1fed2f6efd38f29987e1 refs/pull/112/head\n00411db7266b0d3dc2060e099d33ed2d621b82c638cf refs/pull/1120/head\n0041c22baac1c31c2282b9c81f02b2d297e943e715e5 refs/pull/1121/head\n0041717810817a0a2b2878efbf4d655a5f3f02bdb4ca refs/pull/1122/head\n00415b047abac2af8c3454aa3f5d9e3f4fd336248091 refs/pull/1123/head\n004187bdc6bbe11b1f7111cb45b231e77cb543c03b7c refs/pull/1125/head\n00418ed6125c3266ee5fe16d90e8f0db26bdd21e9a06 refs/pull/1126/head\n004198b17c26f503a5bb857ea3435240a45f584d236e refs/pull/1127/head\n004145c24a202a91fce5c1f3f18a28ae2c328fb07fcd refs/pull/1128/head\n0041d89e784013fa44af219af4c59318ce60f8f05fdd refs/pull/1129/head\n0040a8e64b67ee50fdc923b4dfca8a026bb7b7e0f9e9 refs/pull/113/head\n004142ec9e39e560a60028b64ecbaf2bf9ffaea9acaf refs/pull/1130/head\n0041e90b84e7aeab7edf3bc569ea7b445e511c88d303 refs/pull/1132/head\n0041c1d699e161bc1bbfd7d57be2712c8ee1546db0b2 refs/pull/1133/head\n0041153b7f21669004864a63efceb934ac9247c43b44 refs/pull/1134/head\n00418a6b4659ba4a39a9f18d938a1303f35962bd2c63 refs/pull/1135/head\n00414b9e30d2079123127d445c57ef866691c2612c15 refs/pull/1136/head\n0041064e0107b717f35d289c101a8df5aa6aa49c14d2 refs/pull/1137/head\n0041a68a0cd38ab4f489191912d992c1d4b7fb598201 refs/pull/1138/head\n004196c4267fdd5ebc5a11abf2afde34952d11fa0e3d refs/pull/1139/head\n0040ad040b0e9fb545a5e5e72cab06eeed0457350efe refs/pull/114/head\n004168459aa29ef3251223f574b7902bae78890c3800 refs/pull/1140/head\n004158e5151180e67e209a300f98b10c8bd91d2f10d3 refs/pull/1141/head\n004197e7609dd55ff381e8b645373b38ecddf3615ad8 refs/pull/1142/head\n0041693895fd032c51b0c75036d9c41c6586ea59b306 refs/pull/1143/head\n00413665ffa0765a44fe402d9aded1e0997952d97bfe refs/pull/1144/head\n0041045004f0080fa316da50ca631055923d8383a910 refs/pull/1145/head\n00419c4c3d9bc4df26168813861503ae0920f7281907 refs/pull/1146/head\n0041c5b17cb731e4037a8b729ae71e18e267e0378f86 refs/pull/1147/head\n00411daf35f02314a6d03fc13e62beba958e2d504b4c refs/pull/1148/head\n004184160b5e6ed474b28230dce53c64b4de2be56660 refs/pull/1149/head\n0040efcb738cdef73909a1514edea0a2c3fc279fd0a5 refs/pull/115/head\n00416167e16bee3e6f04a58ee6e31717c1610e139f9e refs/pull/1150/head\n00414d3249741636a1311a19d70f2af571f9f69e2e70 refs/pull/1151/head\n00419b2fa3ecb7cf81be6030c621c98e1aaee8103839 refs/pull/1152/head\n004258fae47d57833a93c2114f003486a178c7fe4565 refs/pull/1152/merge\n004170972ff2903159bb09ef351d62f1f8a056b8cb2e refs/pull/1156/head\n0041949f1218bfc1a4a43ecc024517745812f8da30a1 refs/pull/1157/head\n00410b5fcb4e937e813c777bd6a1cee272e8ecb5c69e refs/pull/1158/head\n0041378637ce104c9282207fa33f33ef2a167fe430d5 refs/pull/1159/head\n0040853201302c759848d37893d94ba11ea590d61958 refs/pull/116/head\n0041e09188102ad3986443886927e92966e9e7592cc3 refs/pull/1160/head\n0041700d09bf5a8f85ccc34818ec42b6a546128138b6 refs/pull/1161/head\n0041d9ae5ece28cd3744db4545fafc3e91ef1bff6f2b refs/pull/1162/head\n0041850c562b1c00fbbaf6a88dd8193de3963a820620 refs/pull/1163/head\n0041e662a66092408df23b3d993227fa931b6c18bccb refs/pull/1164/head\n0041f47b8a51d42a9afdcf61d31088ee3d4d67a38ad1 refs/pull/1165/head\n0041bc14f54a67add60193012a25131e046ced831b7c refs/pull/1167/head\n0041f04422a14208718301ea5ab6edeaa9bcd8bb0b18 refs/pull/1168/head\n0041c4527fa17adf08abf20e61de87fb7a9cfebde6bb refs/pull/1169/head\n0040f2193ca860f0648ffc8f2e6de877f92a363e89f9 refs/pull/117/head\n0041d7e54154d56ac72520daded39ada968082c9063a refs/pull/1170/head\n0041b43ea6c0af5ec6a0ba59691044fc4f168993808f refs/pull/1171/head\n0041e573127901d5456835c3a14581dac8317df14710 refs/pull/1172/head\n00419eb7982d800aa6d091a70e1d66a025e86b0fdced refs/pull/1173/head\n00411e10841edcb227d69ce075d0023c1519e6b61899 refs/pull/1174/head\n0041165a91da2ba287ec682f675235313e0ffffc221c refs/pull/1175/head\n004156a22734341963ec2726e9eabaa51d7c0bbf9f57 refs/pull/1176/head\n004101a728fefcdf53a12d4190159ef3dd413e726d1c refs/pull/1177/head\n0042a37bb2235324744350d465f23b7ff91bfd16f36c refs/pull/1177/merge\n0041645b3c4efecc4799fe6e40282c2b86b941e58903 refs/pull/1178/head\n0041da3ae6f7076eced3e1905f2345136d0ff6f3dc9e refs/pull/1179/head\n00407485aac97090584e3815fbbc2273d97634e1e687 refs/pull/118/head\n0041fc120ce5c94b1a168b89a9664b75e703c00170f3 refs/pull/1180/head\n004131eb3dc0538687ab2714afb69fb4408e438db967 refs/pull/1181/head\n0041c9f32af3b88f879262a81554a5cf87f0d72fdafd refs/pull/1182/head\n00410e896c2d535ae2d5f1a0abe24c8185b60e50b4ba refs/pull/1183/head\n00413f8e4d222485db16dd53a82c1aa8d53dca62606a refs/pull/1184/head\n0041902cf79cf6c7107315190d647ce9afe83a1f46c4 refs/pull/1185/head\n004101021d07febbe1dc0964c3f3a4fe25bf2c864670 refs/pull/1186/head\n0041f40ed0b4032dffabc9edb601e3bcee77922d07d2 refs/pull/1187/head\n0041149fee3f435468ea5ba248158eef48bc6ab59243 refs/pull/1188/head\n004192a96024812d7a9471598ca7509577eb6f81448b refs/pull/1189/head\n0040fa878cbaca3a34c3a27763118e5b0d947aef3337 refs/pull/119/head\n00412745cac3b81bc800037aff2b3ab37709d37a7921 refs/pull/1190/head\n00415c4c55133d0640b0e2f6abbee881b1fd3a3356f6 refs/pull/1191/head\n0041cd47d6beab06c76d3a11d158c93ca20f09ba4177 refs/pull/1192/head\n004113d6b7545444c47dfd08faf6aa2b9e1ed6a8dcf7 refs/pull/1193/head\n0041a686ab68d088b2a72080224afa23f590c8e83a0f refs/pull/1194/head\n0041f97c4cecf158db398a7557d46233224436e88ac6 refs/pull/1195/head\n0041e010e5b0b1c0e50753277540087df697bbbddbe5 refs/pull/1196/head\n0041208f300c2b85b19840e4a105bfe1747cdb31be0f refs/pull/1197/head\n00416f67f17c15194150c498445ac4bb7f6b3cf2806f refs/pull/1198/head\n003fd90d93044396651a5760ab8619869f3ffa7e28a2 refs/pull/12/head\n0040d4fb3e5bf442245bdead885901391d6448f036c4 refs/pull/120/head\n004140a9bf1f01f1fcaff780c463653753b4b7b44789 refs/pull/1200/head\n00414e3c6c4f74cd604ee2c988d663a4f0bd5084936a refs/pull/1201/head\n004110475df37c8747ce46e549d8967bd366ae74bd4a refs/pull/1202/head\n0042d8416218ba39f441d66806e5e0b036e175c68d7b refs/pull/1202/merge\n0041a700e380ac386cc24c1054bb871d5293ac54276e refs/pull/1203/head\n0041f0e9d7ca384d95b257676adbe5db549b206888b9 refs/pull/1204/head\n0041e75b7e3be1f8eb593039e71c68c620ddca416555 refs/pull/1205/head\n00416d54b8e24ca11529459c8304de1d1775c21544f4 refs/pull/1206/head\n00410632e7fb91e7a0fed85c55fba17f03ffbca4ca4b refs/pull/1207/head\n0041b4179c0e8f91a580c494380568cc755b830cb0e4 refs/pull/1208/head\n0041d9a46d372622a55840ff16e713574aa5aa589078 refs/pull/1210/head\n00415f7ae1d59f7216a4e69bd9658878445f8354f379 refs/pull/1212/head\n0041ec47072f7b589b5076bca86e80a50b4ef0e4a67a refs/pull/1213/head\n00417a8297543e96cbfdca35deaf7ef482a887d82641 refs/pull/1214/head\n004129f6cd65449e9fce1dc070e03c5a0fd5d011c65c refs/pull/1216/head\n004188f0ba0dbdd1920ffe0212466eb97a47dbaf88e9 refs/pull/1218/head\n0041fab2e73d54951557743573f70d6eea1da3060157 refs/pull/1219/head\n00408b7243382787f405189d5180c5a574b3d725449a refs/pull/122/head\n004188a45b1b0f86c9d89061ef74d669e35f4a12a419 refs/pull/1220/head\n00418a99741ae7e5fd4f7904a0ab39bebf9c52347dff refs/pull/1221/head\n0041417322b4e9949268a0dc74de31e5157f85874fb0 refs/pull/1222/head\n0041a96feac6ea2180d6765f714dbf4ff177bf87ab7d refs/pull/1223/head\n0041c5fe75fcdd34799ea08d44f755f0fcdb8d874690 refs/pull/1224/head\n00418dac58da823f0c0370fff98e5f3d893cbedff65d refs/pull/1225/head\n0041c026d87119a26050ce707fd46d8e39a3648e46fd refs/pull/1227/head\n004122c1aba51dfe449915b86a8e89804362326ed46a refs/pull/1228/head\n00414d86f314d4f11c630f48fed1294af87fe4083f95 refs/pull/1229/head\n004095972d7b95720065b9ad13946c2f19e7940fe074 refs/pull/123/head\n0041a15cc8d82d9531f7a3c7062c5a44e1d74962db27 refs/pull/1230/head\n0041608a8693561c85a4519bad15d4477760b1213f52 refs/pull/1231/head\n00418499cabe2d26bdf79362cf5848d2d6c5feb4f3e0 refs/pull/1232/head\n0041097ff7d5dff9e064297f16888e671c1a8b20a54d refs/pull/1236/head\n00411ff8266b09309ce473a5fdfde6b23df95d91c4bc refs/pull/1237/head\n0041041c24c794f085f187c8b2626568c1ce9addc431 refs/pull/1238/head\n00417941b0db3a95531936ed7d492199e1c506f4b693 refs/pull/1239/head\n004092350c4dc465cc0e1b34e5f6c95379a19a88fe7b refs/pull/124/head\n004144e9933cfcd6f810b8c84a49654495b08aa96443 refs/pull/1241/head\n0041e3aeb1a51d39c98fe2d05d6a4e56881b8f308e98 refs/pull/1242/head\n0041297bc99ce0f1fe0c722646e878c48ca1b7359f54 refs/pull/1244/head\n0041ab57c19fb6878591469153a6b43cd200e5056ad7 refs/pull/1246/head\n00416bbbd03d1f609db86085779327329af0b870df5e refs/pull/1247/head\n0040ba000c0f39d232ea471959ade31d5bf2644e44b5 refs/pull/125/head\n0041121e405182ebc1747bc4b70ee51f1ad515eccbec refs/pull/1250/head\n00412a64d4bf9067530451df1015757b964dfe1a14e2 refs/pull/1251/head\n004138777fdb3a08b8fa21b046cc3f99ed080b773cc3 refs/pull/1252/head\n004189a916d3fa0e29776db1dca2cfd496040b7f59ab refs/pull/1253/head\n0041b90f19856b5d540108a64072c2deac6b1cd78963 refs/pull/1254/head\n00419b6edb6b82873b174431d6fdd2176c56f24120e4 refs/pull/1255/head\n00416256217be5d1950457e58da0bae4bf04f2213719 refs/pull/1256/head\n0041881388e2752e4f3dd131e8a1f8bae279d2f120df refs/pull/1257/head\n004191315d3344d7b85173da33c9f3f2b43d6b27f355 refs/pull/1258/head\n0041be6ea4d8245ececbe374dc0dd1d809cb94b073f6 refs/pull/1259/head\n004005a29c8ff1ca492bc90f87070fd303a8110e63cf refs/pull/126/head\n00412ac78599f1db05f40ae306d6b9ae7c56a3710044 refs/pull/1260/head\n0041253384d79ca6561d4f3c81f4e41514470026c6c3 refs/pull/1261/head\n0041e96f52adadd2e3f7f64715f3e9c4c0638e0fca9f refs/pull/1262/head\n0041129c977415a332d4a850ead18bbbcabb3022494f refs/pull/1263/head\n004152b028520be76bac86f78d8c684c2c5ed9cccc50 refs/pull/1264/head\n004186f9391f84fcca2c177eb788a56ae8b7e543d902 refs/pull/1265/head\n00414d3590834890a95113490d5040225fb270b5b7d3 refs/pull/1266/head\n004181622365cbead4b2326525b2601da753a24a5e55 refs/pull/1267/head\n0041117f2cce652b5628970d0977266f55eaa55cb407 refs/pull/1268/head\n00418bf7be7eb05fcca77f395a59a02e4b1e1860b469 refs/pull/1269/head\n0040b87fb4478b446f4ff48ac78beafb90fa37054b41 refs/pull/127/head\n0041c386d3a3fd7dd25d1c088999350621015b934231 refs/pull/1270/head\n004196c88193e27d33fe815eb0551d8087c8f08968fa refs/pull/1272/head\n004158ef639deb89f9d5517c308e977dc683f0c0168c refs/pull/1276/head\n004150328a328d6100da7adb817b253bb006d7c0c046 refs/pull/1277/head\n00410dfc3535eb0c29e638e9d7371fbc84f356c80aeb refs/pull/1278/head\n0041133f337708f4da78c753d8607f35590d9d0f36cd refs/pull/1279/head\n0040c79671a08acdfa73c90d555e0065ec3e108e2214 refs/pull/128/head\n00414a3f1930fa113df2b198bf7e6b4bf2753cb08c06 refs/pull/1280/head\n00417326ff73868061c78efdca1d22bdbc93f4dbc060 refs/pull/1282/head\n00414b592a00998dd4c4a9cca11be7979eeff9c1709d refs/pull/1284/head\n00410a19b05580dc24028dacf4f568529b24bc76f8cb refs/pull/1285/head\n0041e43a40ae80d2e8a6a0abaaa31ce4763d146430b8 refs/pull/1286/head\n0041fc7e59d29509405c92fd972087e6094f93f02184 refs/pull/1287/head\n0041add1a8d02937b9f518ab45756f4ed93e0ed2a7e6 refs/pull/1288/head\n004173ea6713b3e09df07ee64563409a3a711524ae4a refs/pull/1289/head\n004079f203e8674a264ca918ad0a59b52720c5053bba refs/pull/129/head\n00412ea3e74c9fa834f044e3ae49533106a4513a1c07 refs/pull/1290/head\n0041207fcb2a7a6053f40a9a570bf4ce711fcae705d7 refs/pull/1291/head\n0041215e33c64e886aa92446ff82a8bdc48bdd92bdd5 refs/pull/1294/head\n004173c35234a9984cf83a5eb299dd2db138c048f6e0 refs/pull/1295/head\n0041cb236ea352e1e55ff844930a0ae81158768fd7b9 refs/pull/1296/head\n0041436a8602956ae04dac1f0b04770ce06112938929 refs/pull/1297/head\n0041618ac0ded5bd906e79bb7b784f29846eb3af9fcd refs/pull/1298/head\n0041d6e19fb7845e1ee98706ee8f3a36f0d97e5b952b refs/pull/1299/head\n003f3a8412073dcc1900bd009153b7c0bd40d59710a3 refs/pull/13/head\n004143294d0e607f85a1ed7ce9c504e6bdbf768b3d78 refs/pull/1300/head\n00413adf485f0e8226a37911538dcee7d1f0a252ea60 refs/pull/1301/head\n00417113d61286fb327c585ee08a12b25117245767ed refs/pull/1302/head\n004120bc1bfe5d146d7a453f501c3f59d08ce3972b98 refs/pull/1303/head\n0041911566620041bd942966b0fdf5bd53ee8c220755 refs/pull/1304/head\n004285b19a8198bfab56e74c4efaa5dd3573fb44430a refs/pull/1304/merge\n0041bb833df0473c9e06a15fa30931f62f43f8fa41df refs/pull/1305/head\n0041c1dcd02d5aeeaedfbe9a47719bdcf0517287064e refs/pull/1306/head\n0041bed15155e558a64bd7e1d023f0f6c01e4e89cc22 refs/pull/1307/head\n0041ae7549465893029628571539475cab50a5f88b29 refs/pull/1308/head\n0041fdd103ee379731772968bc0fa4abce0a222c482e refs/pull/1309/head\n004052355df83bd1f16a0d6cfdf839014d0f6a0d1742 refs/pull/131/head\n00412e0d369368249bfc6c27477840adfd1745067f43 refs/pull/1310/head\n00412ede4b86018662df57603431a2ca06f0e63fe0ab refs/pull/1311/head\n0041ffe128c7f53f9261c2e478ba220ab8c2bce7586c refs/pull/1312/head\n004110564b2cf9d3e0af7986404100358a81095fc991 refs/pull/1313/head\n00415d4eeedceccda7c2e4e55857b5a6adfae318248a refs/pull/1314/head\n0041a839faa175e5f0f8c1773cb5dc565771eb4b9f5f refs/pull/1315/head\n0041e1d82ae78462eb11827aceb7100afc9e6580bc3e refs/pull/1316/head\n0041b1d8d0975cf7e2cc0cffdb1e9d861f9ec3c8a464 refs/pull/1317/head\n0041cd7839e83d0fa2c941902e812164e8919eeb6add refs/pull/1318/head\n0041b729510125f5038236e9c2f739a0344813040023 refs/pull/1319/head\n0040de13fa317c1f5f068676066815c089d2dc6147d4 refs/pull/132/head\n0041734cdc193dfaa3632bd6bd1e116d1bae62f9a44b refs/pull/1320/head\n004169f6a1f844f349c8ba3a32a3c5da1096567c65ff refs/pull/1322/head\n004157dac2df4e12ac5ac067549fdcfc33f3625a68e4 refs/pull/1323/head\n00410449ab5546a48274f8db2472e8b21f90da47f1ba refs/pull/1324/head\n004126c21c1ca66e207f17944073b90c943e0447d5ac refs/pull/1325/head\n00410525f3fce77b48be23f56df109940605c512a64e refs/pull/1326/head\n0041ff220eaa3867738f3db0eb193b4b64b358ceb636 refs/pull/1327/head\n0041b7507c4ce4d7050d93cce250f9420bf499dcf79c refs/pull/1328/head\n0041c66c75f095bdbdc61c9f6a7918250bb35d11c27c refs/pull/1329/head\n0040189e780a8f8800d4a0d3bc302e046fd6de7a2193 refs/pull/133/head\n0041961a6e96dff63ee0143258b0c085d0902187a58d refs/pull/1330/head\n004145df50f1f4d0e6d4c0a0119a259beace2112bd53 refs/pull/1331/head\n00417ab9a1982ce11b5f59474d9d1c4290deb3cd66e7 refs/pull/1332/head\n00419ced3c989395984365a5cd2c756124a292692d05 refs/pull/1333/head\n0041290599c46d3019e2faf2c278c11a534ca383a8ed refs/pull/1334/head\n0041faecb02327ed55b78f3f52895749c9d5c83b5d79 refs/pull/1335/head\n004104a4c755a57d4eabcaeacfac73ae163261e2dcf1 refs/pull/1336/head\n00419e97654e7bd49474a89cf9ad0139bda19dc1e5a9 refs/pull/1337/head\n0041fc6fba1f9f88b4eec99b5222a1431f13b74456ec refs/pull/1338/head\n0041f1bab89b149ef99141a371a872979a47de900ce3 refs/pull/1339/head\n0040f2340c7785b24944f55d7e97e27b347be8df3a97 refs/pull/134/head\n00415a06f626752062956a8a1381504662c2d7ebd629 refs/pull/1340/head\n0041ea595ee08864ca521498095f830189a7c9df36a8 refs/pull/1341/head\n0041257c3048815f335b9f0a22fd4854b1237aaf0e05 refs/pull/1342/head\n0041bafbee83538cf951f538ca7ad13779f59f164d71 refs/pull/1343/head\n00412fd3ce652de76465b0f42f488020dc954885d2d0 refs/pull/1344/head\n0041c64bdb1c7e57087ed8d84e221de17d758391f2c9 refs/pull/1345/head\n0041747c018e63c009b2155bb4f6deb6a583d3caf22e refs/pull/1346/head\n00414e30fe74d61b9166b308ddc6ca31248ad92c0574 refs/pull/1347/head\n0041c3fc7f915e82757460710c0e8128ee5b36911035 refs/pull/1349/head\n0040edc675a835d97be1fca5e3cba3de1d92690395da refs/pull/135/head\n0041a0b692649edbd8b4d3e4fc273edb51b90dab4226 refs/pull/1350/head\n0041bee1b515d3eac86a33be45b026744db3594701f5 refs/pull/1351/head\n00417a8e666d0bd3aa6de59703c76d327d023e855eb4 refs/pull/1352/head\n0041b4c0c67c083c3f3d9275dfb2f3e3f30b014598f3 refs/pull/1353/head\n00416cc04160395a02237ea60fcb56369dcc2af898bc refs/pull/1354/head\n00417b5d44de35d37ec6af061e835241251cf0600906 refs/pull/1356/head\n00410ddb923bb03a95e57aa0e591c9d79a6bbc042ccd refs/pull/1357/head\n00415f4e98aebd5c88b1f31d0dc5fe89d756e4836657 refs/pull/1358/head\n00410b6677fdfa4169e0426b59f2b811c633848cef5d refs/pull/1359/head\n0040e9437545a50ce325010edce479c33fdb5fb8e911 refs/pull/136/head\n0041da17b72261b13286aec80d2720d55ded18ac9c20 refs/pull/1360/head\n004175df95cb365bf57e6605ec4768f11ad6cad1c5d9 refs/pull/1361/head\n004161ede2f2c9831b2ad582dd0b46b668e8f53eda44 refs/pull/1362/head\n0041afba174909676dd33be7a4004636350c0c4866a0 refs/pull/1364/head\n0041e2196d07a5f82f433a3d45db1ad79dd073fed364 refs/pull/1365/head\n0041d8202d6c7c333bd3cdd030884261af6f8af1edc7 refs/pull/1367/head\n004100eba200a2fdcd297b2aca58a6ba86eabaeb2b4a refs/pull/1368/head\n0041831e8fbd68217ff1d460dd4df4b21f7c22b6c7bd refs/pull/1369/head\n00409626f978d682ed60c4f361078d5add6f4794914a refs/pull/137/head\n0041ce2ad323892dc3a11963c9968da41582fa403fa9 refs/pull/1370/head\n00411a47355f103ecf545a1bb3a498f1a0b5b76b2fef refs/pull/1371/head\n0041762fae248f54871949683a7fe74bb3ed1d04f1b5 refs/pull/1373/head\n00416980afeb6774a3f8ef05834d8baf2df6a0f9bcde refs/pull/1374/head\n004144bbac892c3674e04a4c22107572fdb70870291e refs/pull/1375/head\n0041ca65a6f8e68e7c84b0845ae551ded0955b65dfd1 refs/pull/1376/head\n0041a6e1d21fc5b0fe82b02eac25b2ad3e06f5b7d851 refs/pull/1377/head\n004177404b3cbb5f0c567e9923373363670b107cb7dd refs/pull/1378/head\n0041e10cc0588b127c0a7a345708ca4694b23b27a42e refs/pull/1379/head\n0040e07f89546938680d414fd7b9485f3c0aa7ec0232 refs/pull/138/head\n0041dff810775dad1f692e87bf9411750c8ce22c8976 refs/pull/1381/head\n00416278f3cfc933a1a2fa5fe4c1006a8f3353e24b0a refs/pull/1382/head\n004103e3e96fb3dba1d920fd58fabdd6fbeb7c99bb69 refs/pull/1383/head\n0041e215906b2e757daf6f9cdf479c6ad074b965ea37 refs/pull/1384/head\n0041f60c4322be9edafb23af08c9be6c20c9f85108d5 refs/pull/1385/head\n0041b246f36763b355cbb9cc093783ca6f13f9cdc4c3 refs/pull/1386/head\n0041721c39c10965b428e222283aa864f06bb154c04a refs/pull/1387/head\n004171afc34970336601672c9edfbd3999e924a448db refs/pull/1388/head\n004078ca8ffccb0245a5a61cf24f778008d9787f0998 refs/pull/139/head\n0041e72e66bf5707b31c82e55f3292407daabf66e6b6 refs/pull/1390/head\n004127bed5c648b4c2bdae20ae119e50b968ea79ab1d refs/pull/1392/head\n00419ff43939cf0c8e6986d8e92126e6338863b648f4 refs/pull/1393/head\n00410a552e22b16e6fc24ea55f88d20c7901ad2c3cff refs/pull/1394/head\n0041a21275fef5419e8ec3c8c92826bc05d6f2c645bb refs/pull/1395/head\n004178832b0fc1490907c8fbb936dd7b1c43c5863170 refs/pull/1396/head\n00418951ee20a76f985f31f7adb31d4f3c1990300789 refs/pull/1397/head\n003fc6b4d55a540de28af226e774e0a2a49e70ab02d9 refs/pull/14/head\n004016c45dab0a86a40e2ba16d8efe04e0be57e78cea refs/pull/140/head\n00417dd1f2f0fbd3520d413b1b4a458c0276ca3f05c2 refs/pull/1400/head\n0041da9a726ce2f007ec4ee803ce0bd7157b4421e0be refs/pull/1402/head\n0041186c598fee1c82e4c4e904856d5dbf4fe7b109ad refs/pull/1403/head\n0041d8326a0f09b0ed2aea1a559d6af68458c63bf3f7 refs/pull/1405/head\n0041236c0c3ffc7ae031d21814b583c637cadd989d75 refs/pull/1406/head\n00412ef45eca094f6f574206fabccda2d9ba36ffd7e6 refs/pull/1407/head\n004169dba3b7a359925aafe3d06d7b6c5f0c40f360ef refs/pull/1408/head\n0041fd84167ec1429163534a1c312ea42f7b48fac010 refs/pull/1409/head\n0040ebb6c96b259d1a247c14f0db7adbd63035db97fd refs/pull/141/head\n00415b72bce47ac95923bce868b8fdedc204bdd54af4 refs/pull/1410/head\n00412dd82629ff324d2222d5bcec6fa1df77f023b330 refs/pull/1412/head\n0041566b2cd164e5b92b7c7993d45f367eaa4ac13293 refs/pull/1414/head\n00411f2e4049e40f05de6bc89a4df3b902617cd2c4c7 refs/pull/1415/head\n00411138579a9fa79aab8611dd866a5c7d7b36d5b407 refs/pull/1416/head\n0041520b03ea4d2fe774552ebbf371a546fe16e00d5c refs/pull/1419/head\n00403ea332e3d92983d258198c4944e48f2a679e6705 refs/pull/142/head\n0041cbae00c32292523e1178b7936cb6a0ee0c544ada refs/pull/1420/head\n0041df616c3977bc7a2125170035b062cfb931b39c0d refs/pull/1421/head\n00417cc8172bdb8a34456e676cee0d4ce9084ba7bbea refs/pull/1422/head\n004192677833ea4b356154ce80923125322345e0d4e0 refs/pull/1423/head\n00410cb307fa354bd8e66ae40b7fb3cc537b884c03b2 refs/pull/1424/head\n0041e5cfcb34d6c24a402aabb88f79c321124b89562f refs/pull/1425/head\n004136f4a8e330e49343137e747d02300ad6b352d7eb refs/pull/1428/head\n00414a4e9c9f75a503df0da30240b8dd382811a34448 refs/pull/1429/head\n00401e851bdc987c158bfe0edc3ce66cd3ab32b95efe refs/pull/143/head\n0041640a72f812d1681c148081ce769c94d18089a531 refs/pull/1430/head\n0041768bbbc5e3e37c678dfb001bddbf3c8c4a3feab1 refs/pull/1431/head\n0041e66f71fdd1c431a684a6d96b7b0e02f99e294e8d refs/pull/1432/head\n0041a0e482e060ff55476ca8038cac6e0b7c659c3373 refs/pull/1434/head\n0041fb2e26335ddb51333e162b916156c0884f567c37 refs/pull/1435/head\n0041b1772fe46558e79a885a654ff12d5a2e194c2138 refs/pull/1437/head\n00413681973c9df9739802d4137c63b769054e65ed19 refs/pull/1439/head\n00402e9dce6c48f32267884dd2b28842ec6925b645fa refs/pull/144/head\n004123939d417e265d55ed1fc3aabcd501507ee01ef2 refs/pull/1440/head\n004197c65d1cd8e2c8f901cf5fc86614310abb52fe9f refs/pull/1441/head\n004103dac88c576f8ecab3db909f629585712b8c0eb4 refs/pull/1442/head\n0041a6f76105ef194c3eaf7b4b7912a38f7294c07aae refs/pull/1444/head\n0041fb648a2ea697e46ed51c35f68c8236b3bd10e59c refs/pull/1445/head\n0041afe3ae2d7fe951c37913e38fa09b4fd3a6507008 refs/pull/1446/head\n0041466b94b687fc5518d881f59d1e0372443b841e34 refs/pull/1447/head\n004123532d67a96aeaf8b4a6361a3fadccc6d933f37f refs/pull/1448/head\n0040593ef33d4b5fe2d7feabb021d0972519deb6b744 refs/pull/145/head\n0041ee9ff50c9c2b4ec849994b49738eaadd45df8d11 refs/pull/1450/head\n00414d997c6f83857a7873eb78b0802816a5cba610d2 refs/pull/1453/head\n0041c1b4346191fe2b03d0c41637d53d00a84ed431b6 refs/pull/1454/head\n004119120bfb738b794199bfe5797b8248c6e1920492 refs/pull/1455/head\n00421d489a06e8f566b83feb9b10282434c69a2a848f refs/pull/1455/merge\n0041e93dad30305e69dc20372d1a7684ac76c2b977ee refs/pull/1456/head\n0041a5f94be445a32a0c5991e85d12fdda4a8fa2fc97 refs/pull/1457/head\n0041164d702fdd71ca10606e1701c9ebed15a885da41 refs/pull/1458/head\n0041d342f1d18f88041e3fbacda44330e22d9798e9e7 refs/pull/1459/head\n00406df8b6ad0a9e4dade94f2747d776d7dda1f4e4f8 refs/pull/146/head\n00417647947be27328f428cb50ef77189933561b6990 refs/pull/1460/head\n00418a4b9b4ffe361034167304c74c026ddc6ac4a33f refs/pull/1462/head\n004142813fb3381fa994874cd455ef72b49874ccda7e refs/pull/1463/head\n0041df4c6c121ab7033a14f9bb85f4e7416c8629c06d refs/pull/1464/head\n004105696886d50ce893da5dc7b6917e9947f3bbb835 refs/pull/1465/head\n0041fd3cb207b52d77dddceb45d01c33065f495ef029 refs/pull/1466/head\n00413a659000e96e36927d6edb20fb7361e74300ecf3 refs/pull/1468/head\n0041f49d889a01613f914a8d1768e449fa51a9127c54 refs/pull/1469/head\n004196895dba95749f0b38fb2d49f0506bfbbb9539ed refs/pull/1470/head\n0041f2f5eef8ce350ba79a9cdb67a96e968c3c5c5beb refs/pull/1471/head\n00415d7d6f1f25924dd01528a74cc38877510345299f refs/pull/1472/head\n0041b62dd25e1192be880b8c96e162ae5f6905524084 refs/pull/1473/head\n004164469920f86f96c92a5f69b313990f4b3b08b007 refs/pull/1475/head\n0041ff1fd64690c606dc96f61d599866f1ed7da972c6 refs/pull/1477/head\n00415ca8b4a96239e4feca8336661d98ea495bb1099f refs/pull/1478/head\n00414e696f6e40d363f43a084a0ada2144d8cb86873d refs/pull/1479/head\n00418a2e104021bd2cd6d2b69f606d784d1df6c7b8a9 refs/pull/1480/head\n00414f78a2c9c44eae18251b89aed140f9bf4985d028 refs/pull/1481/head\n0041bb284ef37e8480c03b519560f08f8b38dee5bb98 refs/pull/1482/head\n0041fa1d5b0c70383c08e7ee37bf66485198ff3e7ff8 refs/pull/1483/head\n0041c3a7a260d2f19a4d350e3346d008c776f74e9b98 refs/pull/1484/head\n004110e894be6f4d9b506f5459ea296592c312f5c053 refs/pull/1485/head\n00418d611111423fb3596be120ee6bcde94aeccf3745 refs/pull/1487/head\n0041afefc631fce6dff9770db8867982ffee8b091218 refs/pull/1488/head\n00400b8e4aa1499399f5212fd700cf2f310076ae8010 refs/pull/149/head\n0041ab1a2bc6c7337ace9e89ea483619794ce5a2565b refs/pull/1490/head\n004171ffff50fbf4cad3b72c45644e926b0378005212 refs/pull/1491/head\n0041bb95218921ae7fe9e8b4c3336278e078c315d0fc refs/pull/1492/head\n00415c20d41d46c16bfc6a9e82f744bd9b5541f3fd18 refs/pull/1493/head\n004120eab42cf1a7a89de8ff99af2d73a32d6cd5bfd6 refs/pull/1494/head\n0041a6764c4ed63427a5145422b6f7254ab4529bc8c6 refs/pull/1495/head\n0041c617d48580fe8aa02865fdd3c434d507a5ffe940 refs/pull/1496/head\n00418286eaba5003c774fc206fafdabb0a2f8ee2a50d refs/pull/1497/head\n0041f5f9b82390a6425baab9dd8d7c8937f0d2680b24 refs/pull/1498/head\n0041600434da8ba54186c894f8032da0cae6161d492d refs/pull/1499/head\n003f3c6e266b75f17fa1643a1d0b189b8d350bb8081f refs/pull/15/head\n00409aeaeccd95e696e800e08ccb6fabfedd7ad0e8a7 refs/pull/150/head\n004162a27e278e0cbd969b615943e89f1ed0ba4d76ed refs/pull/1500/head\n0041204898438a43b37fc7c56f5ceb9f2bce1e6d28ef refs/pull/1501/head\n0041f55692ca0190703a2e425672c45580b440a70bd0 refs/pull/1502/head\n0041ae9e151e3c9e7beb6e3acda1f075c928bef0b5ae refs/pull/1503/head\n00415c6a2af85703ae61fb0e53a0c0acc6ce2bd35918 refs/pull/1504/head\n0041908d4fbbd4502e8b6106733f88373ca813fb9dcf refs/pull/1505/head\n00417aab084a2629b0a33c7a314991b38f2bea80af12 refs/pull/1506/head\n0041341380d6aab2b719946ec0c1a5be7c0cd27a0cb3 refs/pull/1508/head\n004173116a39687c8aac406d5f3436ac2382cd67166c refs/pull/1509/head\n00410a69ddfa848b2722f6e019d5c975877d9015ff32 refs/pull/1510/head\n00418b22d1d80d3989e19f6c5c639f1d43756c83c4d6 refs/pull/1512/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1513/head\n004107f645f4d3f21c4a6e5d37dcf9433ccfe16778ff refs/pull/1514/head\n0041b9f8f60c3d32e202f61a38cd9298d498f9d47d6f refs/pull/1515/head\n0041f83d3497ba7dc9e2d636bb2e4ae997d199eac114 refs/pull/1517/head\n00416973913e0ac5903ab71dfbe1b9d36bfaca0e4f15 refs/pull/1518/head\n004116733b33f6b8e22db85c87192bf755b7e5ba9ce9 refs/pull/1519/head\n0040dc7027b6d5069c1decbe4db697f29b71dbedd0d0 refs/pull/152/head\n004169d63353a10a2ccb6bbca0cd8e2ea39f07b473b0 refs/pull/1520/head\n00410d459a3a0d41b09508ea497686d1570c86a1d103 refs/pull/1521/head\n0041d898942392a908832d3665b8c01b1d9a908bb4f8 refs/pull/1522/head\n0041f313b6cb25b09f2b46fe64f73006162494abf44f refs/pull/1523/head\n00413672ab6648e9a5a7be2a98a15ec365a10d2fd64a refs/pull/1524/head\n00410bce19c9b7efd2ff89cd8fe5cf8b745151c0422c refs/pull/1526/head\n0041112afa3e48db0f2de21a6a2eabf87c8eead601a2 refs/pull/1527/head\n0041d96bcd6c259eba410208303f608604f12d94d01f refs/pull/1528/head\n00419691f02b5328cc5cd5bd107c0f9841a0cb98660a refs/pull/1529/head\n0040a482a80f7e437e30efa5eb9fc21c09d025be30d4 refs/pull/153/head\n0041c76aff6be45a0cf7db5c5711e4e40113f64dbc47 refs/pull/1530/head\n004104340dfc2861f9f6f3ef103a0025a4c53a39fca1 refs/pull/1531/head\n0041e64567c751cf73ca090672778776a7175d5fefc3 refs/pull/1532/head\n004185a59eb6f51e25e5ec8671446d376d0f2f7da910 refs/pull/1533/head\n0041f6d77b8c6d7b853ccafb13efddec6462d1aff581 refs/pull/1534/head\n0041da0d3a3a6b2ffe0023b256cb8869931ee9c5b204 refs/pull/1535/head\n0041882e49547e2172435fd055f858a1d68ed0debcc3 refs/pull/1536/head\n0041b441fa217409bd0ce6aa4a837cd3f7447766fb61 refs/pull/1537/head\n00412f834281750332a14fa6c7c60696d1736927c663 refs/pull/1538/head\n004116cd702ae99af2129410201438008c0ed6a88709 refs/pull/1539/head\n0040f78f9c4948f1f81a50d51265a55aa736b01489f3 refs/pull/154/head\n00410c2ceadda13aaf9fe821891c11bc42b28f13c000 refs/pull/1540/head\n0041c6b0b982c9b39b3f31069e60453dae96c10866cb refs/pull/1541/head\n0041d2e4e5e58508c7aff695768346c200d57229a21e refs/pull/1542/head\n0041ee5cd9ad00462ab8b1602c25cce5d57247651ae5 refs/pull/1543/head\n0041db0dd1875b8ba55ae38b0fc205c57462d5264984 refs/pull/1544/head\n0041327590d91f1311a3a6e53cfc48e03b539cc7d955 refs/pull/1545/head\n0041ace6ca433914068b255abafa6fbd0ef16ba2d201 refs/pull/1546/head\n0041f19785406811be353ec421c04bce3f346eded10b refs/pull/1547/head\n004172e13a2121813367053d4ecc963d2305e85bc86b refs/pull/1548/head\n00418c4f183f2f6c6e646979f996b447e05fd2688ec6 refs/pull/1549/head\n00409d5ed41f9d2193e6794deee4f8bb7a813c9343b3 refs/pull/155/head\n004186322a7793fb78f2471a66f28d1380ee2ca72afd refs/pull/1550/head\n004145aaab129c2f7061b129b296c55c7c2ac48132f4 refs/pull/1553/head\n004149d849fd2e1f9614cb537fc19bc54e556c9b09b7 refs/pull/1554/head\n0041bbd33796f3faa42f40b28134ec8b3efc142694f7 refs/pull/1555/head\n004113af1a0f28d8a9bdfcf98c6ac827a6a3ec828baf refs/pull/1557/head\n00413956a7dd8a950fc58241286efda84dcae51abe4d refs/pull/1558/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1559/head\n00407dcd66ee089129b124af8b51b26fb8728af4773a refs/pull/156/head\n0041947083e60bd3c568927ba12314efa05aac5290dd refs/pull/1560/head\n0041f16c2fb4ef30b707b56556b2e2c40ed8cc9adf42 refs/pull/1561/head\n004166ae1b5c1780e6c8444b39ab3f112b7b3e02dda5 refs/pull/1562/head\n0041dceff72b9c029a97e42ec1a5b0769d06f153b8d0 refs/pull/1563/head\n00416a399d6d2ad5dcf71bcc04cd21e939de5e7767aa refs/pull/1564/head\n0041695353bc990ce2a62d31eb1fb13f541d1cd703b7 refs/pull/1565/head\n004152049e0509b4b44daac5b37016b0dbca1fcb37a6 refs/pull/1566/head\n004187d5eaca8701601a39947d440b185d894c737407 refs/pull/1567/head\n004142c31c24b1d69723bbb699578acd02af9f78800d refs/pull/1568/head\n0040c82b8e525303e6fad770e0540dad5dc00d76c83c refs/pull/157/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1570/head\n004192716c0c970fea2ce12cc31832b3f45f3050ca21 refs/pull/1571/head\n0041462f5a219f3f8f78092f98f26c5b58a847db6c7a refs/pull/1572/head\n0041c5b85a430a260fbd9cf2e4f360f8f20d53afdc53 refs/pull/1573/head\n00413019ec74ede79e77d5672fd022ca3177572cd72e refs/pull/1574/head\n0041194db15636a13d052e81164641cb23bb53be4b49 refs/pull/1575/head\n00412b5dafc68d002735348433ae0ed81908ecd785a6 refs/pull/1576/head\n0041f2c653dfbda3bab74478915ada61e0845012bd2a refs/pull/1577/head\n0041d870bf685b2b776ff7ba9eab78ed55505ce57c1a refs/pull/1578/head\n00412fa7f48896e8980b11a2b558ebd6a20e7be292b8 refs/pull/1579/head\n00408068436b2a040871c83cf6f39c2d0d74d4651e47 refs/pull/158/head\n0041d958e812462e34c99c37d217f0f08ae91b3abc03 refs/pull/1580/head\n00415194418a88de9fb53ab6ed80432831331e15bbae refs/pull/1581/head\n0041c3a4e79dbd933fc8e947815c666561d51d795f91 refs/pull/1582/head\n004131da8dad3c1ac11a0e12490fcb6e98fa8f2c28b7 refs/pull/1583/head\n004125ef6c1f49836f51ebff2f4135e4596992d678bb refs/pull/1584/head\n0041e0ae728d9925a62008f60a22e1198f06a6ede5c6 refs/pull/1585/head\n00417fa05c71e0d2b2217facd2bad243781858ed6e9d refs/pull/1586/head\n0041ff5cde817af1c25f5fa26bafc4ac4073bcfb1e09 refs/pull/1587/head\n0041b3d1de916c4ad5c1b4e30594ac7011b4fa5ef4d0 refs/pull/1588/head\n0041484995c39c9c8cb99c885903c64a06b782488b00 refs/pull/1589/head\n00406fc981f0f578112dd57d3c9221d8e8607222ea02 refs/pull/159/head\n0041a0dc900a228f0c46f97b3e4c59acfe55c96ef2c6 refs/pull/1591/head\n00417df0c764d7fc60f3b32fdcd11be57d153882902a refs/pull/1592/head\n0041426317bfe888889daedec42b58f58b3e1e2da129 refs/pull/1593/head\n00412c9256efc644bf765c45e5ae8a2a8fa851d37c47 refs/pull/1594/head\n00418405e05a3f332b28d57837397ce28a63e48f795e refs/pull/1595/head\n0041fd766e7699bdaeffaf5625a4a583dbd5d4b68141 refs/pull/1596/head\n0041a1fa4e7ba21116c602b2e2d196eca51caef853d8 refs/pull/1597/head\n0041b7919627c927d8559f12538106956397a3ae92ad refs/pull/1598/head\n0041d796b6f8340e2bdafa4e4073fbda29550b21c90b refs/pull/1599/head\n0042dc55d0d581c9390b6f71cf04de9815c5e77d7771 refs/pull/1599/merge\n003f16b3827af689b39902ef03363e8f06aa8a917b37 refs/pull/16/head\n004048d9e4009aa1d2d8cd18f948ed4549a55eba97b3 refs/pull/160/head\n0041d3f1dc58018d6b40ee2f05e5f6821671b319c3fd refs/pull/1600/head\n004131a64f5e4936499faa79e40018515ea58b3c0302 refs/pull/1601/head\n004100a02591e76295b34878ba180df0b8a9564a3b92 refs/pull/1602/head\n0041f763b73ac812aaafbad92a084773bf1d13f80943 refs/pull/1603/head\n00414359fa74d8b9a01b428f725d692299264e80921e refs/pull/1604/head\n004146d102ceb52c713644eadaa7846118c8aeee3a09 refs/pull/1605/head\n0041e98427ba70a78b5d7a64c427e7a9cd09de7b71ba refs/pull/1609/head\n004007f015f1904e253e994ee240a9615bf16315a5f6 refs/pull/161/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1610/head\n0041f2376611924effe0f0f03c541f480137d78e573b refs/pull/1611/head\n0041a0f7092b2162eafb07afc502fe26c262c75a51af refs/pull/1612/head\n0041e7a8372d6366eb5d6eda0d313e5a0c4d6f2e7b10 refs/pull/1613/head\n004156cf6c79473ddcd9db99668d49a23b29c01a667c refs/pull/1614/head\n0041eaa3e7ffff279d64785a8ec77bf6d7f5df25b7da refs/pull/1615/head\n0041cc8c5840078f65bec296c001effef0c762b990d8 refs/pull/1616/head\n00416b3f053810f3d897cb1c543d109216751697bca0 refs/pull/1617/head\n00412b744813cf6bed7507c0a5003db5df0aba55fb7a refs/pull/1618/head\n0041ca91696bdfb5a59629a3471daefdac6d4e2ab0a7 refs/pull/1620/head\n004174214297869b28ffd536479c068ecaa3997fb7b7 refs/pull/1621/head\n0041be0908a0431c116aca177fb7dfbfc551ccaf5861 refs/pull/1622/head\n0041e5c686a63314322ab70fc59f181733bb23fced34 refs/pull/1623/head\n0041b84b0eb192fd47997e3d508fd2fcfa5b7763e026 refs/pull/1624/head\n0041aa15587ad20ca465e390add59358df0cc2830608 refs/pull/1625/head\n0041414762a65ad10f46b75a95dbbc8e56de95d5344f refs/pull/1626/head\n004131a5726b22a2cb4cb794b01b5d3a75ff934a6ba7 refs/pull/1627/head\n00413691e6cf3f6767d85cdc6dc87de6178d8e00a84b refs/pull/1629/head\n00400110a956f7c25b31435717b7c6f517fbd4ecfc9a refs/pull/163/head\n0041473061e7dabc8c56aae9fe447a3173db6c7c3380 refs/pull/1631/head\n0041320bc9418314813464d0b91d5f820526e6dcaa40 refs/pull/1632/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1633/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1634/head\n0041ced684cd213166117663572f0f13591bf5168ba7 refs/pull/1636/head\n0041653eb97d9afcaab55c7157a3d9a7896f9f8a9cc0 refs/pull/1638/head\n004002c71918d8b56bd9f6137e1a526d1ac481602c25 refs/pull/164/head\n004127a37fb1ab3e5fe5a1e9b11beaad54ce9281e525 refs/pull/1640/head\n0041ad1fdf91c8ee67b0d073a6a438a52209cb15862e refs/pull/1641/head\n0041de207ef037cd5ddc2556df0610a7a172ab51dbc6 refs/pull/1642/head\n004145f73022342a0bdbdac7417629105c4baeafd79c refs/pull/1643/head\n0041b985b6379b054c5adb75044640bf5cb9fedfa4b1 refs/pull/1644/head\n0041843a90655a84ca944e43c96e71557c085e294d9c refs/pull/1646/head\n00416840f1c445eb9105a17e786ce13304d0e4997187 refs/pull/1647/head\n0041b6d6f53c233c8f7b52309335a1f5eca9fc814165 refs/pull/1648/head\n004141d16635e58d5c6179192206758b4270a9e8f965 refs/pull/1649/head\n0040be088688bdaf7b272c7811e4869caffc60a34d87 refs/pull/165/head\n0041511c386150398998d87896badef720e894330987 refs/pull/1650/head\n0041cee9378ac0bb51431bed15a4a4a137820340fb70 refs/pull/1651/head\n004181e9bf6e4bc3d061c601d117692c9dc9fae590b5 refs/pull/1652/head\n00417ef7d26111ab4722fca4dc3b31b20ec0917647cd refs/pull/1653/head\n004127c62e88c613afbde9923a3a126a78d3eb13e285 refs/pull/1654/head\n0041b37b4076f5874c11113b926c8fab9f7dc2444952 refs/pull/1655/head\n00410b9242402f6b614a7a964b191dfd82d91eb807ee refs/pull/1656/head\n004103285c5cc430a2d4d95b25e43c4b9fbfaa66b75d refs/pull/1657/head\n0041cf437402222547477d626343ed0afdf5efc0f8b3 refs/pull/1658/head\n0041fddb6460bf6b561b82bb98f3ece98eda40231dc5 refs/pull/1659/head\n0040c7463a50e9d50aedfb8d2b01f8fc673dc1972f14 refs/pull/166/head\n0041330dcc98ea9fc10d8927d289236eb8c918c4bc51 refs/pull/1660/head\n00413412588e0eb37f94e5a155797d6a223fe049461b refs/pull/1661/head\n0041e3ba44799ec67cc578e33f7e397c529ce919f838 refs/pull/1663/head\n0042daca13a892bfabe2290650e9f908617e47230586 refs/pull/1663/merge\n0041e4571b9e0bb399600daa49e941e0f1e7c487ce2c refs/pull/1664/head\n0041605b1067212bcd7af0737f42280c049283d7f7db refs/pull/1666/head\n0041947c24007cc76d6c31fd44f2849dbc977b4bad0b refs/pull/1667/head\n004171767c8f8d91833961d253863a3bedea974bd26f refs/pull/1668/head\n0041606a2e0d39ebe60e887e64c0e4e33c591e997e19 refs/pull/1669/head\n0040550ded776cafadb014dd81dbaf58c469d5af6ad9 refs/pull/167/head\n0041c0b62b8b28336c5a5086870c3eab71aaaa150c4a refs/pull/1670/head\n0041c02ec43a14e1ec42052ef738745864d69e7eefbc refs/pull/1671/head\n004178391b1c345356ec78e9d6c033d67443952122a6 refs/pull/1672/head\n004179b4e517f71483bac6f33db2c9c070d4abdc0e45 refs/pull/1674/head\n004169a3f0506feb52f5b5705dae8828f1a20c43bd6f refs/pull/1675/head\n00419e54ce53a375d24abc214619b357acbd424e5814 refs/pull/1676/head\n004122a5879e288c1afa2052f715bf6cf92ba93ef076 refs/pull/1678/head\n0040d5ab3681b90575681caa9144bf1bdcdf723150f2 refs/pull/168/head\n0041b92f701bf0d597c4c50ac752e4536b97efa5e2df refs/pull/1680/head\n0041b49309b4e8a5a0cda1677745b2941be87a642ff3 refs/pull/1681/head\n0041203cd06339c36b8767e2e60dd55bbc3ac923b645 refs/pull/1682/head\n00419eac881720f2cd451c7b48b3b2dec5fafcfc6acc refs/pull/1683/head\n00412cab290ed8db8ba56e95e12081a24abcb9746ef9 refs/pull/1684/head\n0041bb280dc1a53c81287eda1e678c25629c8ebb8851 refs/pull/1685/head\n00419b5ad70828ca0c941fc424fc35e10eb2eb53d475 refs/pull/1686/head\n0041c2b84a61807bcf11f35dff1aa544b0a92a0c6785 refs/pull/1687/head\n00416f6fbd991bafe78b2b87f92f5c6f8327888dd339 refs/pull/1688/head\n0041d3818b9df267986e07e8df723464e09cd195d583 refs/pull/1689/head\n0040c32413680d38e366510a47a6c150eefede26987a refs/pull/169/head\n0041f7b84db702b7b111c176780a17a24d88c721d49a refs/pull/1690/head\n004133dc34724f0cbe5de45246ecab12c5a3c1ae5602 refs/pull/1691/head\n004158c03b5016c7d62755205a561b10babe4f24b472 refs/pull/1692/head\n004122c16d0528c48509297dec8ad6207ce879f20f07 refs/pull/1693/head\n0041194c74cbf4ee1ec28b85979c2424b73175205375 refs/pull/1695/head\n0041ebf909a4cd8718cc731e498ae9ec5cf11a148e1d refs/pull/1696/head\n004126798baab325cb4720e80dd2bf5ad4d3ddd49995 refs/pull/1699/head\n003f3a4c90b02ad2afbe09997cb3cddea3f2f96cd710 refs/pull/17/head\n0040ed7fbcee57b7f9277ffe1260e3365b4b8c628b26 refs/pull/170/head\n0041f6be2d94e8a159d03682495360a84a99e2849ef7 refs/pull/1700/head\n00414cff272b844f4409267f6d4a0dfc35d522b4b1b5 refs/pull/1701/head\n00417d9cd867535b37dfb109312c118fc1c4d99a1e12 refs/pull/1702/head\n0041402453d160e42a2becf0454355e8f21392436ca0 refs/pull/1703/head\n004166d3d1ece5efadd29e2ed40613080bad24588f00 refs/pull/1704/head\n0041d36a83b869ad816367e3a520df8b34e0fa30063b refs/pull/1705/head\n00412d5d59d0c19aab6f41ef43dfaa5f5dd84ec3635e refs/pull/1706/head\n00411dde7bc4eb32f5229e4395528009a6abff975fee refs/pull/1707/head\n004167a4b8816b0d95195649426e01c2d5a285c87c69 refs/pull/1708/head\n0041583974851f9986aaf9aaae1684ddc7da54061668 refs/pull/1709/head\n00403f8f78a70ddddaa6e381fef4e575e5b0bad9f403 refs/pull/171/head\n00411f78db7c0890d6de7d968b149da0cf6eb44bae16 refs/pull/1710/head\n004181b355fa672aa9f87f78ac1365a9fe4302ae6f26 refs/pull/1711/head\n004147050c34195f06ab88e8b2e5d41491ef82a897c8 refs/pull/1712/head\n0041859de7de8c7b56c46fd0a2afb1a56bf7be4a0efd refs/pull/1713/head\n0041508ee173626f605678598d0363806d452e6546e7 refs/pull/1715/head\n0041e431c79ca359bf4a6dc5e756ca2416867b1f26a2 refs/pull/1716/head\n00419bb401e34362ff8f0ef0c7b1e471126a98e6e72a refs/pull/1717/head\n00414a9f3908193b197e0fac3c04a6820f9947527149 refs/pull/1718/head\n0041c7c27dfedee3c8fcd928c801e7b37f24f3604c40 refs/pull/1719/head\n00416eda4698764d62eb549a653d71fe9c89efbda7ed refs/pull/1720/head\n004147db827f4e9e07495e988979b2bcc5f0f1c3ac5a refs/pull/1721/head\n0041dc37d4ac77c3a83b1209c9ac9d386f7a21164c6e refs/pull/1723/head\n00412856b0618349793952634c56899e3a59cb4bfe4e refs/pull/1724/head\n0041137adae315ed82442e245d922230737921ab8476 refs/pull/1725/head\n00417f6ab1cddbeab54f17621134f12643dcff6e78ae refs/pull/1726/head\n004111a2bf4d085236a9cbe9846ff9f22f9976e853bf refs/pull/1727/head\n00416b9ce0fa8acc5fa39b58c998050507de1eafc74b refs/pull/1728/head\n0041eba0ba181ab8cb8f9bdd603762d9ca1d0ee03e6b refs/pull/1729/head\n00409bd080d1c1e0f331e10ca935b7ae84a67743e00a refs/pull/173/head\n0041621b55a6453ea373b338093a4d6ebb246816dae4 refs/pull/1730/head\n004166cf11882a13aa5ecb9dca3a0856625d40a0661f refs/pull/1731/head\n0041ceb4390ee4f63854ee38c1ceffe09bda29ec19a9 refs/pull/1732/head\n0041f046d5b5e50c64f21d971abdfa97cc7d40bff25d refs/pull/1733/head\n0041299bd320c28aa4aa7a7ec3248ffdceddd791f1b9 refs/pull/1735/head\n0041dbb64a42761a875114e956ec6070defbfe422b26 refs/pull/1736/head\n004168e17a207baa24049da479274cfa34d7432c90ac refs/pull/1737/head\n00414a9f6c8d165fbd1f30eb478e7d09e91c185dc2e7 refs/pull/1739/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1742/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1743/head\n0041efcc272b15e6678ae0b87795b085779de6cc6b64 refs/pull/1744/head\n0041afaa7c3ae485f10eb98db9c9ceb3a1b3b135bdde refs/pull/1745/head\n0041fdf37f671a1e1b7fd1dc183769eebeff9563f252 refs/pull/1746/head\n00412c85053cfa420c869bae7ef023c52300eaa0ad2c refs/pull/1747/head\n0041d28d46d556d50949a51ec2b2b9e736b99947cd36 refs/pull/1748/head\n0041242e8396de3475422e0e4b575d2be8b13acfd504 refs/pull/1749/head\n00404f150c542aa5139058ccf57dcad562890916b477 refs/pull/175/head\n004128b5f8610a75ef7f7eb4d0860391893a023a522b refs/pull/1750/head\n004161121d34173f4e17d2787d9bbb9beb50988e5b0f refs/pull/1751/head\n00412bae8356597b70e2a0ec11fb906c9f4e15b0ca12 refs/pull/1752/head\n0041b1e4f7639d8480a1dd8b2d8b58172b5654bcb5b0 refs/pull/1753/head\n0041e8d8de2b047665e2feee094a948020aab6f0cab1 refs/pull/1754/head\n0041dfe0cb485e1b95fa73d7fc01189d7342336139bb refs/pull/1757/head\n0041af351e06e20230e63147e6f91ec49ff018b6acca refs/pull/1758/head\n0040697026d4e8b2db4ae98b820d3d5219bdf6447016 refs/pull/176/head\n0041e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/pull/1760/head\n004168f6fb1246d1b0fceb91454d4350ec541c5f6c0e refs/pull/1761/head\n00413848b7fc07cf9891999bcff66ce0415a3d09d73e refs/pull/1762/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1763/head\n00411fa8a78eaa5b22679c5eef46216f5188a1d94fa7 refs/pull/1764/head\n0041cbc1038324468952ccd6d73cb8139ac39053a443 refs/pull/1765/head\n004156e0c5dc850587be1566c9f64793d6d6d5d236f5 refs/pull/1768/head\n0041bb81d37d4e36bc8f5ce4bdd330670bcb3e0d50fe refs/pull/1769/head\n004196aa2ba53a2ea486f5a769851a40c6695ae1e49f refs/pull/1770/head\n00412a288c660a53a7e834900ac484b30484ee630045 refs/pull/1771/head\n0041217c352ad074f4d185d93ceebca8eb349ec6c59d refs/pull/1772/head\n00417d78ea23fd1e33058e26271b9314228c52ccfd9d refs/pull/1773/head\n0041bc8e36df01367794ea3ef321187a325a9ac69db4 refs/pull/1775/head\n00417d2c3c8a499807f48617aef10ff2d38777b10e53 refs/pull/1777/head\n0041c25a90ec1432dc8d3bdfd8a4897eec1f79e86a79 refs/pull/1778/head\n0041959f67abee6f9d04caaa8d7f89fb4e4bed97643d refs/pull/1779/head\n0041fd17178287784de7abcab551e8d6a3f307197e6e refs/pull/1780/head\n0041e3ca3320607036d249dbbf26371909c8cdb4e553 refs/pull/1781/head\n0041d51aefbf41e7a618a29bbc5d27e61b3d695b5bfe refs/pull/1782/head\n004185d032609f688eabe9afdd6e913a3eccbf02928c refs/pull/1783/head\n004123ca8b3c69fb1aaa5728473b063576f1b2d39375 refs/pull/1784/head\n004117103ff4a194a539f5c72bea680e96d82fded25c refs/pull/1785/head\n00416ff3ddf670d367e0bb94ac1ecbc16a7b84c44da3 refs/pull/1786/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1787/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1788/head\n0041d780e569beeb0dcbf49dea00227b07e7a0557e07 refs/pull/1789/head\n004138818c7fe460059b864af9fb064ef3b372faa3e8 refs/pull/1790/head\n0041c830fa55637683630dce94d4bd1979bd6eaf19fa refs/pull/1791/head\n0041fd24bcecf02345fad0eafb863c1e1a96b8c690ea refs/pull/1792/head\n0041ef51a60c61079cee1ad74195e7ea775ce69cb4a7 refs/pull/1793/head\n0041151da60d325f776b3dd0aeea7d2b772e19d7d17b refs/pull/1794/head\n0041beced838e4690d90045aa67d95eb354ad8ff22eb refs/pull/1795/head\n004167f820873e8377ea084af14056d22554ca7cc21a refs/pull/1797/head\n00417a0f284b57753f79f3d1613fab4b93c8629e19e3 refs/pull/1798/head\n004175f2c449c009b52d0a603bd3cbe8eeb725f915bb refs/pull/1799/head\n003f53aa980fe3061b5e6040de9c8fb10012bb2f8703 refs/pull/18/head\n0040b1cb385e06354cf99ca214be195c0700ffcbc0cb refs/pull/180/head\n00413eb63513540f6bffdbd231239f42f88ddfebec68 refs/pull/1800/head\n0041643497bf5bcb01d049b74b7256deaccbe7499250 refs/pull/1801/head\n00412f72f7cb650e4bd70af9f952839a0a59869e3a65 refs/pull/1804/head\n0041cb15bb31308c98689ae4eb9146890eb4c4b85076 refs/pull/1805/head\n00414a73eb85606f042cbc4cea9806bb6a5aa8aab684 refs/pull/1806/head\n00417a5731326269b729d41b2ac688e39b590748a842 refs/pull/1807/head\n0041d61d2a12da28c0a67e8b2a6a2901ce3581582bda refs/pull/1808/head\n0041c06ead49f70c83092494dd35de5cc23003373616 refs/pull/1809/head\n0040a93a2680f94ad8e04a1103aeabf2708bd5980e8e refs/pull/181/head\n0041666906995dea00187d68f21a86fb6844fa1aa607 refs/pull/1810/head\n00419d7dbaa1580712e31b0e5f38f2d772f4efb8411e refs/pull/1811/head\n004164c2d8663c768215adc1abfc163b90d8c00f7774 refs/pull/1812/head\n004166ae46ddf21a5c9ea38179ee3cb48e5e0933fb93 refs/pull/1813/head\n004162d8b81f9d11177615ab69ad569599f9749c988f refs/pull/1814/head\n00415784c6de647fb7d0e8667740d784bd6855da89de refs/pull/1816/head\n004140d1eaf19843a7fa8e8aab0f612829d02fef95cb refs/pull/1817/head\n004177db6fea24126618973c77b5d1085b6d731abaf7 refs/pull/1818/head\n0041d218d64ce9526b17ace67ffd6c302cdc0d06b330 refs/pull/1819/head\n00413e4acd6540a4da55ca5e2d8fefef07b740d1c752 refs/pull/1820/head\n004155a2cd3bb64e3040d899bf5cf8f1cd4d6580ca5c refs/pull/1822/head\n00410ec6da65e6e898a079591b57055efc061c9cb6dd refs/pull/1823/head\n00413956b56edf3c580ce664f26ba4a2295204a3b7c0 refs/pull/1824/head\n00414716d0cc284b1741d0d3233c73ea47af5bceecfc refs/pull/1825/head\n00415f788d250cd76b750f76dcc6db2d440bd92fab27 refs/pull/1826/head\n0040c36e358ca340e5143c1bae900f62af9c9992f8b6 refs/pull/183/head\n00419a37f354a6af47436166d5dfe516c3689f402484 refs/pull/1830/head\n0041e075984e4ef6a2a4d844c42cbc18543abe5dd211 refs/pull/1831/head\n00410bbc9e95cffef61511f1de8f830e336caa15a958 refs/pull/1832/head\n0041e5bed10b2bd6973ad2a063fffc38780533f8cd3b refs/pull/1833/head\n00413e0bc06126d76b17038544e765365e04f10f12ad refs/pull/1835/head\n0041ad1e720055786f3cdb9c759e5061343c8d00b279 refs/pull/1836/head\n0041bf17b39beef874e602d3b36861aa1eef469aae3f refs/pull/1837/head\n0041ca50521d299252e3df50cc973da8d58ea17dd9d8 refs/pull/1838/head\n004180a2263da5503241882ca0477ea1d99b4c7a20dd refs/pull/1839/head\n004073c82e133e8dc40db2556497ea58ed1087031505 refs/pull/184/head\n0041dd45b9f4aad94150181247b515d878a258593f65 refs/pull/1840/head\n0041e95f66bf3fae34c9834fe303119f68d09b524c50 refs/pull/1841/head\n00417879e9176124c4e6bc5d7dc9e2aa8d00a2050411 refs/pull/1842/head\n004183fc002b5356265d0459729a76aca21324a27401 refs/pull/1843/head\n0041590f17a7d4c339439cc3a0366c230fe60d0ee52f refs/pull/1844/head\n0041a3e12ab1fc688a3d5d68fb004f034dcd83159e50 refs/pull/1845/head\n0041cc048c4cecbfb81fd68db3de91cab8a6d110a4ef refs/pull/1846/head\n0041694695a536c2feb96e0817856cd3b729017b66db refs/pull/1847/head\n0041dac04009c14513b018b5a47194aa0c45cb15a3d2 refs/pull/1848/head\n0041c53eab92dd9d8f1b20f3ca84fabc29456767c562 refs/pull/1849/head\n0041cf9cb9a57237917ae1ff74f121a1fbd6d8e28581 refs/pull/1850/head\n004139bd4443236a577e81d79eaf2adb56ad5bad7e0b refs/pull/1851/head\n0041ca1234fba4d0f639136a17642bfaf8696100148f refs/pull/1853/head\n0041688edfbf064c5cbd29ccce6683cfff62e2a92841 refs/pull/1854/head\n0041e07806737984c72dd2df3fb62f6aa887074abb28 refs/pull/1855/head\n0041950f94d8447cfe8e381c33003731bab17764fc53 refs/pull/1856/head\n0041c9e6324f270b54ef8528ab8a2e54663cc1522bfc refs/pull/1857/head\n004125ab614caa713ea1b3aa85d6ff477956307fbceb refs/pull/1858/head\n004177d871fe2174230183e7a2c9ca37bfc3147c5dca refs/pull/1860/head\n0041490ca7b0714d188ae4fd43dbbf9f603e257b33d2 refs/pull/1861/head\n0041d401575d9c4480a77ed36f22013cf94ba28766c9 refs/pull/1862/head\n0041245917c80414c327aa4c9b4dccbaa6a8de1ed76e refs/pull/1863/head\n0041775c151f3e1a2deb698444685f477766b2eb7ac7 refs/pull/1864/head\n00419cfa3f62676b13f7e218003e801796ca01a26e8a refs/pull/1865/head\n00411ed057902ab3c93c7bc09b1aea1868ee223204c8 refs/pull/1866/head\n0041bb691dd9c831e92f4d12e842b20ec6b198382030 refs/pull/1867/head\n00414f13093d0a7690cd6f53a8a00eb5e961b450e96e refs/pull/1868/head\n0041be23c09d0085e393c609425c87e91d2ce49e4b4a refs/pull/1869/head\n004094fad49150b1245d6df17ef596ccbfdf5e53e23a refs/pull/187/head\n0041adc617b13cacafc11073da7c987c3b4aeebe7e8c refs/pull/1870/head\n0041e7abbfdf7b7587088aabd9b6e6def35157483259 refs/pull/1872/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1873/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1874/head\n00418e73fddffc8970eec9941c65f48522e41fee367d refs/pull/1875/head\n00417870cf2e5136283da85180aa1a4132d0b945e46d refs/pull/1877/head\n0041d5e7bc7be4b270767aa04de43bc3af305e1827cd refs/pull/1879/head\n0040bfcac75d68e64f860fd27dd089f76f6e076ca1e0 refs/pull/188/head\n00412296fd9ca7299a57fa2e8ecb59623a85653183df refs/pull/1880/head\n00419ab39d23ff2b19fa564815999bf51be509ab7b5b refs/pull/1881/head\n00414cf4e663f58e4f5edacda884bed5c035124dfd6c refs/pull/1882/head\n0041bdc42a80a2a7d0ebec1c9ab90a945f344dfd3f3f refs/pull/1885/head\n0041f3d970e2aed28a290ebdc777b1bd9e2a6c69361f refs/pull/1886/head\n0041f52afdc4daed2649a3bd78782713203bb9ec1787 refs/pull/1887/head\n0041a13e63a984798aa57eedeb629a4e42a059304825 refs/pull/1888/head\n0041f2e2f18765b2d1fd298a58c3ea90283fce07cca9 refs/pull/1889/head\n00407a95f8a55b26adc8f99b9e2c54995c0ee85d8fa5 refs/pull/189/head\n00412ed0a0d114dc10762bf4a4e6ce2572f04d4c6abe refs/pull/1890/head\n0041cca09665a98cffb1de8a990b68eef7ab3f42ae47 refs/pull/1891/head\n0041f209a2ffc58b2c9550528b01e5619bb3cab1d82f refs/pull/1892/head\n004141584ca7cbbbb18f1cde26eabb104249fac64617 refs/pull/1893/head\n0041c3e7497e240bf02819dc7d0bb5e666a48669f0c0 refs/pull/1894/head\n00413eba8f8f280b0be0c274880add862f86a1aaebeb refs/pull/1895/head\n004124242e093ecc652d0419c06cbf0f3cb4336ef76d refs/pull/1896/head\n00418b61b330c72c4c1513cd72ffac2aac293cd3a3b7 refs/pull/1899/head\n003f1a0925b76e59133372fc1ba7ee5599b735be1611 refs/pull/19/head\n0040ff96305637fe8ce3e1f744bfe71eef3bfdde98d1 refs/pull/190/head\n0041cbd943c6525c545cec58af0404e17407bba01195 refs/pull/1901/head\n0041fa6cce474ebdf2ff70cd23969df81b51b28249c0 refs/pull/1902/head\n004191834bb605717048dfcb97d50f1e211b7fe18a10 refs/pull/1903/head\n0041e44a5ef5ff2c9c28c4e4f6e72e57301637991d89 refs/pull/1904/head\n004101318044062e0dcb5c3e49f6536ec235ab23b0c9 refs/pull/1905/head\n00411bc915c5b605eea03cb4a8290ae461462e1ab24f refs/pull/1906/head\n0041cae78e108c9cb5fff71e8cb8741349b94f2ad4ee refs/pull/1907/head\n0041b6b055ed963bfb379183b8c02c6ab208e3d6b473 refs/pull/1908/head\n0041183eddf9cbd560150b934d0f1f4569f1bd882a3d refs/pull/1909/head\n00406ce0980f6d150f2624dcef29836028a2cb1f7870 refs/pull/191/head\n00414402048781f29961cbdb12ddad0ca8d81a196afc refs/pull/1911/head\n004157029178c367dde42ce6ea623fbb49c05e051f22 refs/pull/1913/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1914/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1915/head\n00414fe84f446a4c7ba338e110ed8f61418adc4c022c refs/pull/1916/head\n0041b639422ec1c00424fd896389628e8734902c4f1b refs/pull/1917/head\n004141793010447396bc491832ccb9440144cbf74da0 refs/pull/1918/head\n0041772dc97d1ef15899ffd143c7954ec412b0a416ee refs/pull/1919/head\n0040cea55d539a5935d83a95b3b71e1800a59ca6aadf refs/pull/192/head\n0041faaf7ac71d88129f9d698c85473a5180e0278c83 refs/pull/1920/head\n00418081e72673e2f1a920091f3bf221093d05276dfb refs/pull/1921/head\n00414263ded36f0b487b333e3871ff1e316396fe9ffb refs/pull/1922/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1924/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1925/head\n0041085fd13676bfb1f72c4a45453c77befe939a86ba refs/pull/1927/head\n00412890c32995007b6d48e87e20a853a86b9832ab0b refs/pull/1928/head\n00419e67ae92fc31d9eafb455aab6fe32eb5e125c30b refs/pull/1929/head\n0040c4eaf01af99cc8dadace1d1d127086a392813469 refs/pull/193/head\n0041f68c436ef6c041a988c803ef30185652612a73b8 refs/pull/1930/head\n00419f56be92d5c167c9e54911f073bafb528b18828a refs/pull/1931/head\n00415d0918d4342ab99aea71a5390115be195238bbb3 refs/pull/1934/head\n00414cdb4539e7b05d72236eaafdfdaea96761679f38 refs/pull/1935/head\n004128e4a3f2c16e21f20465082e4e63cb8e3503256f refs/pull/1936/head\n00416e9281133ab28e8bad2525600907428b1f70caea refs/pull/1937/head\n0041cf2236dbed3e22d7f04eb2db011b95874674e87f refs/pull/1939/head\n00408863cd9f782c86bfc463f1d8384c89027224aef7 refs/pull/194/head\n0041d49b4addeac1932ce5edc072938940965633e5e3 refs/pull/1941/head\n00418fba4b1e07a31d6eb84de0d3285a230de18ce490 refs/pull/1942/head\n00412d8629e6324a07fa6bcaf99c3d851effe085606e refs/pull/1943/head\n00413d608d7911850e4edf5a9417a8783a0375aa0fce refs/pull/1944/head\n00410e88f4836971e5fd8c9216f9d0a0f62a73109764 refs/pull/1945/head\n0041312e083a7df0caa21a7460b124c131a35540abc3 refs/pull/1947/head\n0041b195aa96dd4c1ed0bfc423396702b7cebd38b64c refs/pull/1949/head\n0040e18c14875dabe2847beccc4ace2c8fdefac4b003 refs/pull/195/head\n00418a89d1ed64499e3e23c85ac1d9fc87b093d88f52 refs/pull/1950/head\n0041eeae4900643721f121259e79c101e7964e7b26e2 refs/pull/1951/head\n004198a7e10c7c548bfab390374855271f4f06dcc94a refs/pull/1952/head\n00418e2e7cdf1a1c84a06c7ac1286063b5184844919a refs/pull/1956/head\n004198385fa0202ba48d9c829bd4cd438ff735c48ae0 refs/pull/1957/head\n00415f02424e5e280ef631ce64faa518a33ec2b356d2 refs/pull/1958/head\n0041c655361c61f4a8d4cc5501559014c4da4352d3cb refs/pull/1959/head\n00400203592563e6188de76fb2e29f4c5a2e5f722626 refs/pull/196/head\n004172d6bdcfffcda628c98c17935d4dddd8724612d6 refs/pull/1962/head\n00412f5322e8632c0ec51dc668b92cfe1164b811c60f refs/pull/1963/head\n0041f33bfb247752d7f00c9854af85f59cf146ce3b2f refs/pull/1964/head\n00410e5a9d1b17f94dd79f1bede6ab86a9ecdad51e4d refs/pull/1965/head\n0041247452069e49b1bc2ddebddb39f4b1a42f7dad33 refs/pull/1967/head\n0041d2b9459487c77b121ebaeb1936c98f6fdc4efd6f refs/pull/1968/head\n0041adfb91949539a56ef5a79dbbf1440d8cb98e48c1 refs/pull/1969/head\n004039610731e0ec8d72c80702b55a15478a948ea7c4 refs/pull/197/head\n004145182d7887e98e3be7b417e1aef6fb5e96c69e4f refs/pull/1970/head\n00411f8c81e7dcf2453dd59ab709d3cf49e8961de5a4 refs/pull/1971/head\n00412fffcbe318fa873851db2b093533787d55af5988 refs/pull/1972/head\n004119b96a70c14221d539217dc123f077fa97afeb94 refs/pull/1973/head\n004188214dc2966923b84c45650d1d2a06d53f8d2d7e refs/pull/1974/head\n0041d0438d88f8318cf279bb6b905aaebef0000fd4b4 refs/pull/1976/head\n00418c6e38f64217d2bfdd5c74b4820542d69312caed refs/pull/1977/head\n00415d11d2ecfa6241332ee224ebe1e3817fd70ce5ed refs/pull/1978/head\n0041b3fcec5942a9e303e7cfc8fa90dfb5aa8548ce0a refs/pull/1979/head\n00402d059659b02a3d4cd478d9cd608ee625f6101623 refs/pull/198/head\n0041f118e38cc79ccd80541d773a73a40f48f730f293 refs/pull/1980/head\n00419a4d3c10c0c76ce56b5393256e582e0f6156a354 refs/pull/1982/head\n00418f8added4c8e79c5df1f09d35161ca44ab42314d refs/pull/1983/head\n00413e9f8f819beec39c2171888cc75bc09eaf682a8e refs/pull/1985/head\n0041ea8a5331c4dfd8ab33559dfd63279c2745a8dab7 refs/pull/1986/head\n00413fbd7bdb7df0c0626e2375262ca831e82ee9694b refs/pull/1988/head\n0040381bdf0fdf166a8efca78ed83aa3729eef57fee6 refs/pull/199/head\n00413b494e299e1bb738432f2da3adbc16a4b9925cb1 refs/pull/1991/head\n00413a5a4ba0f0023ba2be6e8f76e55a59c77e83aab4 refs/pull/1992/head\n00419232e80f273caa3c4e30de4ba2df2b59724f53ba refs/pull/1995/head\n0041931da3b5a36e92341821bb07a6ce12c6e2964ab5 refs/pull/1996/head\n0041756a8bfbf71a83a7830c3704f0826dc5e9363a4e refs/pull/1997/head\n00419054561b3be44b736d0d75c1fe93650c9d72a19a refs/pull/1998/head\n00417224063d42c89b8ed4e88bab92552b683972cf56 refs/pull/1999/head\n003e45ac7a9b17fb34cdf0ea52ab533b70eb4ee60a23 refs/pull/2/head\n003fa89fd2c8ea82bb0ea441e6f8bb2fa16a097fa40a refs/pull/20/head\n00401e54429c2152b4c88a7ffca8d2d3a3da663e7dc9 refs/pull/200/head\n00413db85348aacfb66d3198837378bdf39b2b83b202 refs/pull/2000/head\n004140b3657c0fea727e0fafa0f15e5cac27062c9467 refs/pull/2001/head\n0041b828c1942fc576b764fb501426561645988c5182 refs/pull/2002/head\n00410a633c74dcdc35ea13b1131c185ad038501b9910 refs/pull/2003/head\n004177cea761a0e5d480a0ee655e192f47c3c4995fc1 refs/pull/2004/head\n00419abe4a3186ac55d8fbdef81cf718fad8d1a89079 refs/pull/2005/head\n00413bc50173f33ade9e73e9cd345b96aac6481bcf6d refs/pull/2006/head\n0041e8fb8f5771525831e0ce36e4b590bb7f6d28e436 refs/pull/2007/head\n004093e03d4276610c22a0e92e73012f8a4143e68c5f refs/pull/201/head\n00412a2592576e38d9fb64498661223b0e5d41659e50 refs/pull/2010/head\n00419ed18665d7649950d1f7c5e55d24b5ecdb6ae217 refs/pull/2011/head\n00410bd31f53db252acbb57473024b0e5f62805cd8e2 refs/pull/2012/head\n00412634e09e56a84ac60c8133659e86924db2907754 refs/pull/2013/head\n00414e07d9a95939834719489e7315fa330e0600b60f refs/pull/2014/head\n0041c4f79ae666057aad3ff6dd83878be6ed2fdf3668 refs/pull/2015/head\n00416ccafe45354eaa1a381171f692f3aebdf40e147c refs/pull/2016/head\n004191d2cdb8f126b98e33832a99ee369f8e7d33fa15 refs/pull/2019/head\n00401a57100be071b113f1844f864622afd13e7ba357 refs/pull/202/head\n0041f9f69a443ecabce263829413bb52d40b4f62829c refs/pull/2020/head\n0041276ef05e74f0b36860354051b60734570860cb44 refs/pull/2021/head\n004173b1fe3e8f664a33cda63a888e886a43d1f09453 refs/pull/2022/head\n004162075312fc10fc501a1c8e79109416fcb1d1e0fd refs/pull/2023/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2025/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2026/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2027/head\n00412d365a1a7f06d0c6c0b533a870a06ad947ea93fe refs/pull/2028/head\n00416e8dc9b9791d3d2c32e97a075edc1bacf515f7b8 refs/pull/2029/head\n0041c3f2d82f0160787e23b604ca33bff1c7155452c3 refs/pull/2030/head\n0041f427a8cf2cf8c5a1281b5597c97a7824e081ab41 refs/pull/2031/head\n0041c5c74a89138b010c108b44c04f6b591a5effd6f3 refs/pull/2032/head\n0041c2d191f524e51434cef74087074f695e1a300d1f refs/pull/2034/head\n004136bcd51bf95826cb489f181ca8a20374e2edee7f refs/pull/2035/head\n0041b17a05a6c75c73cf4d7472765dc24c67086d344e refs/pull/2036/head\n00411c841c1e1f263e42179306f8c9c0efdc07ffceac refs/pull/2037/head\n00404d972ac05deac77ffcb2ce21adb2650ed6ea6a3d refs/pull/204/head\n0041fce332fde15b1e5cf8519ca4e41f7dabc15230cc refs/pull/2045/head\n00412e6e93ff444f2db51e2f94b7b4440a6ee599bd40 refs/pull/2046/head\n004177a020b5769f6739f496f57539930e5c3b8cf0c4 refs/pull/2047/head\n0041616ee95df5e755c3464c5ed9d997531da5329ea7 refs/pull/2048/head\n00415da2bc3a293b18f920aa668e4e84fa3a2f54243a refs/pull/2049/head\n00404cb5d471dcfafbc390ddf00de86d2b3273e214b0 refs/pull/205/head\n0041a2766dc2c1f01b71b659a9fe24c24e526f9ea2b7 refs/pull/2050/head\n004165e83af51b80729115b49c787f4c7461561ee600 refs/pull/2051/head\n0041dfe7469fb6f43fe8f147e7ae4f37f4bee4b86efd refs/pull/2052/head\n00410f2c1ec931639bd563db8209bc678eba6bbd316a refs/pull/2053/head\n00412021cf90c380582a43f86948682aba9ed8c6444b refs/pull/2055/head\n00416e6fd0abe0b41abbbcddad8ecf505968252149ff refs/pull/2057/head\n004184e8c2cc730d0c599f182e6f9d1bd1836451a6a2 refs/pull/2058/head\n00402ad69f5897e9dc9fa230f6aff252131a058ac5bb refs/pull/206/head\n0041979cb14b1c89295b411f2cc96698e302b63c869a refs/pull/2060/head\n0041b328c9c84898c5e0b8b55cc82fed3f21175cfd34 refs/pull/2061/head\n004128e2d652c2396e39ba300cd7a7d0afb238abb376 refs/pull/2062/head\n0041fcfed2e6876d14d39cd59b7b5bfb1661de2fbc5d refs/pull/2063/head\n0041dfa203535005df10a8dc405af9e990d1501df161 refs/pull/2064/head\n0041534ef3fe70c9ddf8bb3be2611967a27fdc18af0c refs/pull/2066/head\n0041e3307ccfbe4cfc66099049a0c02447ce4214d28a refs/pull/2067/head\n0041914cd027ad55591aa88c0b458793cf4fa06fc2c6 refs/pull/2069/head\n00401efded0c7da7b9b855dff24b2ef5ae27532496d6 refs/pull/207/head\n0041a97b632eefa842b42c14cd6a738e71ff03615eda refs/pull/2070/head\n0041da57e2de83414be080dbe083665c90008a0562a1 refs/pull/2072/head\n004100e89338da8355b4a971e35d27dca3aa8aba1f34 refs/pull/2073/head\n004174d79dd6aab423b075f15e0577d277ae125cc436 refs/pull/2074/head\n00410928411247b51199daa3bf7d5cda670d216e9d36 refs/pull/2076/head\n0041774d2eea01be83a26f4d857a0da058606e26d3f1 refs/pull/2077/head\n00415671f0abd1b02a8c003aa00accce1600f405c4f1 refs/pull/2079/head\n0040140337e1e1d9af38371be75fa4d5f5a4b239e50f refs/pull/208/head\n004124556f57344c7bbddad2b235f40612fe50abdc8f refs/pull/2082/head\n00415f0956d3fc07895cdce08b590e3a58bec356f5e5 refs/pull/2083/head\n00412f0e6b16a8eba22013463d2f06c29273af6586be refs/pull/2084/head\n0041d97a9b2ba365e6db9d4eff805118536b997c0c1b refs/pull/2086/head\n004166a697f9b0d9a72ebfd04e201ea5ea51bb12079a refs/pull/2087/head\n0040eccc45a3ea6c3ea1ffab1b224e0f38701acae5ce refs/pull/209/head\n00414e252005ddb3f08c77948c828a695f5cc90e10af refs/pull/2090/head\n0041c858aaf921ce8c2323422505bb4250581a9c7213 refs/pull/2091/head\n0041820ae57aa36afa9ca11411ecc74124fa99a5d11f refs/pull/2092/head\n004192c8ff73ddf065aba993496d8b27b313e7702a08 refs/pull/2094/head\n0041cae269ee9de564f8beaee54af3307f62e5b3431d refs/pull/2096/head\n0041aadef428d601202d79299c176e4b41e245ba843d refs/pull/2098/head\n003fdd60e6b515cf2f60a17020ae3c99fc26c48731e0 refs/pull/21/head\n0040b68182934b0c69bfacc4745141c97159263cbafe refs/pull/210/head\n00419bdbf91f4437ca3d3424c25d405f48c7762165e0 refs/pull/2100/head\n00411e05bd5c637cc150c7b0242660a7cc56a57fa45a refs/pull/2102/head\n0041d2b1520f1075eb199d17ebe44029aa429dfa198c refs/pull/2104/head\n00416d8dd63c503812e495e9aa4051931a312e45f3d1 refs/pull/2105/head\n00416c0238bd3f954d95d032ac8699c69c7dbb261ede refs/pull/2107/head\n004125defef4dc82fc1a655825d41fdcc16ff9315c4d refs/pull/2108/head\n0041edd5576921ab95d4230fd39e2c0879ff8a1373aa refs/pull/2109/head\n0040af2477aa12be46101c3d7cd0003e45b17e98a98e refs/pull/211/head\n00410f384635ad38f435e9d342c1d084c8d82d76532d refs/pull/2110/head\n0041e888febafad31e6977fc98801c90d06e3930575d refs/pull/2111/head\n0041f1cc4c719b85eff4d09e262482fe08f2c82b1ec7 refs/pull/2112/head\n0041c215ac334d53aad70c8f49c3ca4469138afb14ea refs/pull/2114/head\n00412846504bcc6555185b6087e2b3df29b20acacee6 refs/pull/2115/head\n0041b15d59d9f159cd31b4389084e6393cc13c89c24f refs/pull/2116/head\n0041a0ccb0b329ec1482e4fb4b357808f69be1d2918a refs/pull/2117/head\n0041d5ec3caab9b15dff0404c53f8503647f0ed9ca8d refs/pull/2118/head\n0041e8b0cbb473269a2ecd82efa821bdceab82cef3bf refs/pull/2119/head\n00400f5e062dd35b9ebef263473fca25512b315a918f refs/pull/212/head\n0041c6506ee1cdf64b1f8e5aee02a68d2373ae93152e refs/pull/2120/head\n0041a46c8c3624067acb6c11e9a8f7b2d55b9b18980a refs/pull/2121/head\n00412a59b5e507bc1618e1a8cab5dead857665cf40a9 refs/pull/2122/head\n00415d69ca46b8216051eaf37047a336912b1123c5a1 refs/pull/2123/head\n004148c3be619b89ba4966499bbcaa4e40bb6af35b48 refs/pull/2124/head\n00419a8d69289230a495f8582cd65eb0dba7d3307620 refs/pull/2125/head\n0041e5eed9e46a09b94567bf86ae4f6d46019ec18faf refs/pull/2126/head\n00410bfb1a4d4902cf9fbf7593f03863dd37b8724ccb refs/pull/2127/head\n0041c54c9f8ec1c7f9ad8ba779671fc710d4a164af0b refs/pull/2129/head\n0040c5e09ae449a74b916851abdde913f3098608905a refs/pull/213/head\n00414728b5044faf129ffd24a985c74cdf31040a3dde refs/pull/2130/head\n00418a24cfd871e0958f9fa723f6c6253952b0deefb7 refs/pull/2131/head\n0041db8349bbf8bcc8a467d116268cabab91145eee0e refs/pull/2132/head\n004171dcb05b8b4671c05f18deb458e5d3aa8f95e86e refs/pull/2133/head\n0041364d95c03b18af27f248bad58a56bbbd2adc19b8 refs/pull/2134/head\n0041159d4dc4ae6f9e9816035ae170f0204043df7a8f refs/pull/2136/head\n0041566aaec5b39a4dccb72e688c105dddeb57cb0f54 refs/pull/2137/head\n0041f3b87b9a1c2db51259d6445e488369fed87788c2 refs/pull/2138/head\n0041517ca96e424138e2f7e09b69440b46846c53ce65 refs/pull/2139/head\n0040e03ffff3d0359f7a13ef512ace8c56c74411b2eb refs/pull/214/head\n004105f77f86e9caf21163e15e1ea8028a9468a781d6 refs/pull/2140/head\n0041223312684d462a1bc67706baccba127b2bbeb1f0 refs/pull/2143/head\n0041a326ddd7e0e2286cd23d9bc38b6f34bd0843cde8 refs/pull/2144/head\n004181aa02647563b8231cb1db035ff97764a4bc4c08 refs/pull/2145/head\n0041fade7728c3f1bb109dbd6a58cc9cb5b5a7244448 refs/pull/2146/head\n0041d0e0731232ebd7711fd7f7d80b4286f4ba97ff70 refs/pull/2148/head\n0041e70a80f91dd512f7380a90b53adc925c132ba932 refs/pull/2149/head\n0041d5a96efa27504a15bf9a03c432088fd8243415cf refs/pull/2150/head\n00415bfc4e906a519270df95056eb9a48b8089f68d56 refs/pull/2151/head\n004126cab433e325e4142045bf6f2f8276071738cbb1 refs/pull/2154/head\n0041db0945190e0388ba27a9bded0314f3016ea6f262 refs/pull/2155/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2156/head\n0041370f57d1ef87a56d7a59f5e7004d413c5cabefeb refs/pull/2157/head\n0041f99c264fe30fe0915efff777bc94dc16df9ab48a refs/pull/2158/head\n0041a10bcf7c8df9f32499ffbb56a13a52d7f8cd64ad refs/pull/2159/head\n0040daaa4a42527acc0ba496672ea2c807412acc1958 refs/pull/216/head\n0041a94c3dfe95cb58665bf4b4c15fd39db98b96ccab refs/pull/2160/head\n0041a3f61afacc7cb29a0643328bead3ae6c08c6c05a refs/pull/2161/head\n0041e9f54cb2fda9cf61d179d1485a0c0aa8f21bf901 refs/pull/2162/head\n0041167f4e6825a414af01e75365d3c87525a214a550 refs/pull/2163/head\n0041e8ace6973134c0829cb1a9c598e447a64a59e2fe refs/pull/2164/head\n00414d66b12e44db8f5abcc2d2a8c319003e185b34c0 refs/pull/2165/head\n00414b2128402627ebb80b7d8d1af8c092c9a119d840 refs/pull/2166/head\n00412917da51a376598d389320da3cc266c082512951 refs/pull/2167/head\n0041c18c08f53377f808d1989402e9ca25a4d4b1517b refs/pull/2168/head\n0041a3b290a240cb6e8363a6931ce9664fc6a7867669 refs/pull/2169/head\n0040d3b681cfb9b0a6af09daedd4a3f8ba02ec766e3d refs/pull/217/head\n00417e5bfb0a34444628009a93432b2bcdd765d15de4 refs/pull/2170/head\n00415c6726b2bf8aa3b7ff79bbc6aa971e3082d93504 refs/pull/2171/head\n00414d9d3c0babdfeb31f6eea7cbc66dcb4bca1c70e5 refs/pull/2172/head\n0041ed63121ef55c84127cb5137dc0a650e7cb302571 refs/pull/2173/head\n0041f347c8cea2246a490ac9101188c4f86382be1424 refs/pull/2174/head\n0041013d338151b3156f6bb1d994d2d3d3a5b1c3d0a1 refs/pull/2175/head\n00414e2227162e694ebbd975631a8ac0a65f1a031792 refs/pull/2179/head\n00403931b2f889e2c657f34c3c5167030143489ca091 refs/pull/218/head\n00417e92aaa16538e195547bb6d41198d65dbf1182c9 refs/pull/2180/head\n0041952f05576f2f134514cc91e5b2dd9f4d3dd209ce refs/pull/2181/head\n004128c50d845b49aac26f7cb9df609bae2ab3727190 refs/pull/2182/head\n0041c1a513c3c934135dfc1154f4861bdf7afbdce60e refs/pull/2185/head\n0040fe110eee20684e6f2b05a4c067fb31879e456932 refs/pull/219/head\n0041a1da249964cf146c54539cca524fbd1013d2029d refs/pull/2192/head\n00414ff69d3c81ac79198a4c99a285c66bf68ea4c538 refs/pull/2193/head\n00410ba2eadf30c4637e8dfb9970899564a43aa6281f refs/pull/2194/head\n00416fc5cfc1a359cd30193055997583fe393cee0739 refs/pull/2196/head\n00419bcdec0855ddb161e35d720fd20c9a572061adae refs/pull/2198/head\n00413e9d126a22e958a30ac07045f506ce1f19f4d968 refs/pull/2199/head\n003f985084119b8da35919c3de651e275acc06e1cc2b refs/pull/22/head\n004062ee6c452595eda122ff0e40ca69f8f615b54438 refs/pull/220/head\n0041741ad5fab0aeff22fbbc8663cd51b98a930e7b5d refs/pull/2200/head\n004131f5035ade93af773bc0f352e16b205978ba8288 refs/pull/2201/head\n00416bd63d39f998df7e56a95ce1e678d7e00c1fa86b refs/pull/2202/head\n00410ec8f46347ea4c4b3cfefa672d755302b6bc0195 refs/pull/2203/head\n0041645959293e93b7c41224ca6565d549ec45f20fc5 refs/pull/2204/head\n0041d9d3e311facb95d40ce676157dfc5efb29dc4bb4 refs/pull/2205/head\n0041a1c81c8de57edcf53010d0708f694b1accf8690d refs/pull/2206/head\n004106f20c35e22816059987089b3c2e48ce47798ed3 refs/pull/2207/head\n0041193141017843084d2f272ab8f26a89b6b047302e refs/pull/2208/head\n004176a1a98700ec28446ad7ac165e15ca3880fb0eb1 refs/pull/2209/head\n004048611d3952d8596fe9781d8c8bbc15326690e6a4 refs/pull/221/head\n0041af034a96d6cc19a7fcaf1ef9d0bf3b6b478ece7e refs/pull/2210/head\n00413bf320e9526067c0746dffc1ea8b4daebe2c5bdc refs/pull/2211/head\n00412afae4f3722aa4fc07828ecfb290cc1ba21d4f00 refs/pull/2212/head\n0041ca9da16069d42325e475cc6c343b6f6edb5ce623 refs/pull/2213/head\n0041c7e3aedbb454e839909dc86a0c3d3111117b96fd refs/pull/2214/head\n0041caa0a41f2f4270e59b0120162bad48fecfb4b744 refs/pull/2215/head\n0041ff3e8f0694a4d37576abad605a9e21720174e787 refs/pull/2217/head\n0041aff2b3e908081ccebdee53267b4997f9da5166b0 refs/pull/2218/head\n0041fda0c2e5ecec32a74ab3e1667481f5ad7a696610 refs/pull/2219/head\n004040b3ec19fb72ebf2d0384a6ff5d2f2014d4a6992 refs/pull/222/head\n004180525c230f1caabf56e881ed7ab459df710f57db refs/pull/2221/head\n0041ac9c814844d8656bcd36a929411406594b91b27a refs/pull/2222/head\n004199f27a746f2f16538e241ea4c994a5f3ddcafcf8 refs/pull/2223/head\n00411a3e213541a2de4e0d7d9ddaf4679a20b48405e2 refs/pull/2224/head\n00414f9558a8d2f1b7419e80eae901761c80aa53aa8c refs/pull/2225/head\n00416a253e4d552578539f484b436c32a0eb5a131fa7 refs/pull/2226/head\n00411d10b35abdabbaf3fe8f420992a07f83ce68c614 refs/pull/2227/head\n0041b23d995bd7c7dab28b221c8ce2bee885ab70249b refs/pull/2228/head\n0041ccb42747dc8a368d7084d46d87014b77047ae1a5 refs/pull/2229/head\n0040336503602a15fc771aa1c1c36486ddb77209dfd0 refs/pull/223/head\n00418c3360a8a5d8d531d0f2e447f9e70bdf8f796972 refs/pull/2230/head\n0041ca22722c1dce5a66f5717ca5d62e38a9732596fc refs/pull/2231/head\n0041d80dc2fe58efb2742c955e07a6c07bc1473fed65 refs/pull/2233/head\n0041c3693b5ca51373d28b6b52f004020b4fe518816f refs/pull/2234/head\n0041ee10756deb3286462704eeb4759d78ba10969110 refs/pull/2236/head\n004116222ea878bbe791f998cac019b70bb1765cbe9f refs/pull/2237/head\n004110b241e044a66932cacabd1afc4d3fbb0f35d077 refs/pull/2238/head\n00410da409bee5c8c4f7b82ee5b7f2f8df0331f9bff5 refs/pull/2241/head\n0041fad9c9e4bf307e38cd5c046459e8b2eb9e7553e6 refs/pull/2242/head\n0041b2456b296ce2104856d6a84fcd191cc32406aafe refs/pull/2243/head\n0041de20dcabbbaf0e964744cc56b4c9a20ef7f63b05 refs/pull/2244/head\n0041a4a50c2ef4bd1bb506ae8d7e70ed0095fb2ab0f9 refs/pull/2245/head\n0041388f6d5c12827d5c51d427531f1bd087356fd2b5 refs/pull/2246/head\n00413fd8c2e118cb471d75e559804d7bf7ded4b894df refs/pull/2247/head\n0041a92e4dabef6b5d88e2e5fa79bd46add0a3b0185e refs/pull/2248/head\n00418557ff43e4873f5da41953950105be2565dea53d refs/pull/2249/head\n00402c34baf3b48f0bc9c895ebca5043d0544a4fa601 refs/pull/225/head\n00412984bd8d2522d267b1d8ddc787e33a6f867ab951 refs/pull/2250/head\n00416cbdd8411ba53f845ba6e1e31f0903053bacd683 refs/pull/2253/head\n00410062172b11f98d0980b1d31dc3ed3b8a444ae09e refs/pull/2256/head\n00411f994a25d12eb1cd9afe903a4558092f62f9af8c refs/pull/2257/head\n0041e5bd727e599e58b57680b6af4228456476e6a324 refs/pull/2258/head\n0041490296fa34b945dbac7f68521f5019e3fbc6e010 refs/pull/2259/head\n00403986f1e346f705814c8f76b1e1a1f39f253565e1 refs/pull/226/head\n0041000f12bd3b89f030d08c78d5a9458aede68aa0e0 refs/pull/2260/head\n004150c4ac1ca3ed40862ba9de2e245435245d3f2eef refs/pull/2261/head\n0041c16df2a93b493d1c94e4b1d4b08d89205acaeeff refs/pull/2262/head\n0041d878e3498a22d960dad7f886489a3a43bb644ff5 refs/pull/2263/head\n0041f0c95462867090157886315ce4ab95d2f2624dc0 refs/pull/2264/head\n00412b13b45ea1646421d1bb7841a0aec13a9b232040 refs/pull/2265/head\n0041db2b9a6dd5d89ded180a53cf6a98608216b1cffe refs/pull/2266/head\n0041682844de6e22955ed5a6844ea6bed462308b87dc refs/pull/2267/head\n0041c0071255816784a8e42484060df1f0ac2cf31932 refs/pull/2269/head\n0041e600f3a2159c07215036b540f7ae6a6a7770eb45 refs/pull/2271/head\n0041f3e4189020ed591fe7f3abf1f2e5c98768cdbdb2 refs/pull/2272/head\n00416a7310cbecb14299aa3acd0b3cb8550dc209584a refs/pull/2273/head\n00411aefee6d3342b8b05c326ca8a57136f6f5374806 refs/pull/2274/head\n004146cb03dcaddd28f0c845744bcdd4c499ef4d74bc refs/pull/2275/head\n00412754e0160707967e35faa7943ffbeb00b565831a refs/pull/2277/head\n004137548c1ae7cfb2a024df5e8795eeccdeffb05ae2 refs/pull/2278/head\n004161f534a7e55b4e83460721b951bbf091f3241874 refs/pull/2279/head\n0041f8b616e0a7b1c4ec58a4e1aad97154410fd0f573 refs/pull/2280/head\n0041cd8b16c68ca6e0dfd7a68e0574eec5b56cb3e4c8 refs/pull/2282/head\n00418786f6ff2338f4b3e2153b4155a26ec887bd1ba1 refs/pull/2283/head\n004147859e6f1e02ff5b514f258a5aef89387c6ef8d6 refs/pull/2287/head\n0041b90fc5f656efe508cccbf7c9cac25e96b6819966 refs/pull/2288/head\n004175544cbc15c840a07067f40c54f81b47e966b45a refs/pull/2289/head\n0041927cf2bfcfbfa3688c0d2cc1444161d9124c605d refs/pull/2291/head\n0041541d04c51c2b9515cd75bd6fe53b164faf97a6aa refs/pull/2295/head\n00418cae4953d6b1900dc06d1f7d10d854a7eb96bc78 refs/pull/2296/head\n0041e75fe6a870f8214d2df73b9fd5fe247a36eda287 refs/pull/2297/head\n0041642e6153a9205a47270bbef52d5083bc9402b7e4 refs/pull/2298/head\n00412738976a712891d506de1b2cdf9572e2486b43ec refs/pull/2299/head\n0041102d9ebaf8f6d139d2570fb35367f72d7f842eb9 refs/pull/2301/head\n0041200c1e907e9a9f4061ec24627aec227da40b0dce refs/pull/2302/head\n0041ba4ac9c4029e17faaed41a4c77a49dffc4b137ba refs/pull/2303/head\n004104071d4510e1a9eae2555db2e195d9907c20314b refs/pull/2304/head\n004182296895d676cbeb713f8237fa6c9aa0b55417f6 refs/pull/2305/head\n004163555fe8a246e7024f16d17f969da9d53c0bae0c refs/pull/2306/head\n00413c3c13493aaa9aa000f02a81c3e5079ed28cb133 refs/pull/2307/head\n00418805681354f7bb76c0a7d088ea53362aa4f913d4 refs/pull/2309/head\n00412fee37d27e5dc081565870881b0af98226099b6a refs/pull/2310/head\n00417d3020ae31e7269f666702c5c89cf68747a8357e refs/pull/2311/head\n004194b292ae40c1681ed13df2d2f5d6349bcddaae8e refs/pull/2312/head\n0041a5b3685e7194ced65ad79ef485212a4e1394ae9d refs/pull/2313/head\n0041c7a9bea483be59f447aaaf8fe27bf0051712f093 refs/pull/2314/head\n0041ff3ea7175f824e65b27f28c59142c0039323e179 refs/pull/2315/head\n004152ac0b29edd8fd78ae8f58d9d63a40d5a80cba99 refs/pull/2316/head\n0041c08f32f67aa91a9af146eae74b2e52320a8ef9d0 refs/pull/2317/head\n0041a692921c7d2ee84358d9e40cfb28f5e89f98f238 refs/pull/2318/head\n00418b64c98d985f517087ee4c3137577df0f806a2bf refs/pull/2319/head\n0040a72b0f899bb35939f65c2eee4653a4534fdca938 refs/pull/232/head\n00410e5ecb7666490c0a5dfb73dc97134520970c6872 refs/pull/2320/head\n0041dab1e190e50253fc770f4b4e023cfe6c942088a6 refs/pull/2321/head\n004118d1aa22cbf255b253a972fa17e2a8f19ff11d83 refs/pull/2322/head\n004125207bc51923412606abc8a60c7783afabcfb554 refs/pull/2323/head\n004167aaede68e0e2d8d0325c15eee9efc7eb9acd1fe refs/pull/2324/head\n0041ca8e27a9810a339fb0429cacb004a51e266609d1 refs/pull/2325/head\n004115f4b1cbe50c19a55b6ec61d94f3b8bd5ff9254f refs/pull/2326/head\n0041c8924b63350c65435531a2f16b5062b8e0349d16 refs/pull/2327/head\n0041bd79c21ea0139abbc64a6a79a8d96fbf7181762f refs/pull/2328/head\n0040b8676faacbfc2e6fea33905a6cdce631ff426ed5 refs/pull/233/head\n0041aa40413e669c4e137cd8d39068e8ba99933f95ae refs/pull/2338/head\n00418e378c436c58840a441776e29cf3c7a4f0a1d382 refs/pull/2339/head\n0041419aa71a493e10bad201d1702ef420c9c26399fc refs/pull/2340/head\n0041d71393208f1bc5e9e8d3a22d175c859a13cd180b refs/pull/2341/head\n0041773234bf12f485f32d12854e89ee0ae605a25889 refs/pull/2342/head\n0041d8fd98c896c8af5854915ad1164aeb785d0dbf61 refs/pull/2343/head\n0041d13a8ac8dad35d3ed7e88d79a0209e3619b49530 refs/pull/2344/head\n004125c7038b09a902e14c917a3424b0fb59ae47b908 refs/pull/2345/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2346/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2347/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2348/head\n0041c0d8d5792e9ef5b8c5f5e42de11d9cadf19715ca refs/pull/2349/head\n0041fc2887fef044d0d3f5643b8328acbeb8daeda055 refs/pull/2350/head\n00417e3f756a0239d51869cfb1e766f83aea55bb78d7 refs/pull/2351/head\n00411131f46b62d559ed6349f1886d72998122b904e2 refs/pull/2355/head\n0041a785c0b107b0245aced8ab6444a0dcd554690891 refs/pull/2356/head\n0041fadded923d6b7487a878306b4db76ac2fff66808 refs/pull/2357/head\n0041084bfa051b06e9cdf96eba3b5cd96497dc1fd302 refs/pull/2359/head\n0041a8db307f7d3a457697460ca84a76312de41244e4 refs/pull/2360/head\n00419e7e709fcb8a4aaaa479e7f5045bf031c3ac011e refs/pull/2361/head\n00418b37b80317b9be689039062b3de0a1c3cb886f69 refs/pull/2362/head\n0041583179f23d48ba01e544476f72b1b659962db3ad refs/pull/2363/head\n0041b6f4a28a221f45f315214114a2878889775a7d32 refs/pull/2364/head\n0041de741e27f5289e1e64d24f0e479c312c5494c1cc refs/pull/2365/head\n00414f168a73f84b4e8bf2ae582b2aaa22646a9927d6 refs/pull/2366/head\n0041eaa3b70bcd32c7a2fd92ce341a1fc3577a573a0e refs/pull/2368/head\n0041ddcc9575213116fd75c1592f21a1199357c02cd0 refs/pull/2370/head\n00413ca0c78954d8ce2178ca2bd45146236a700a3c5b refs/pull/2371/head\n0041319c369a4ce9c5b2530a5171e22a17974dd6af96 refs/pull/2372/head\n00419ce1728af46e3a005b534308fd6b851174f6607f refs/pull/2373/head\n0041ef84432d4f589990bae9541eee952006fceff4a9 refs/pull/2376/head\n0041138fca28bcfa8a93b3eb5db7f285a37ad8dbd541 refs/pull/2377/head\n00412295d8b3fb84b1b493b39c3810639f46ad042987 refs/pull/2378/head\n00412d7a5cbc3855c9e9c54646e933a7605109a735f0 refs/pull/2379/head\n004001df8689af378f1d9b0123e6797da3e5e73c2e22 refs/pull/238/head\n0041a1cc2ec290ae9e6eae4b8c0feee477b32ac76e7f refs/pull/2381/head\n00416b28bfdafdc0262bb92f67ed21444d6bc589d65a refs/pull/2382/head\n00412fa59043f55f9a6c44243abba66f3541e9f5ae9b refs/pull/2383/head\n0041b997add1e8dca84349e6b571ed0f6dde4119cc8b refs/pull/2384/head\n00416618f3a764a74a0a0552c5ca080bee3d15077eb3 refs/pull/2385/head\n0041d3883c619f08310c58c16691a93a67cf94edd324 refs/pull/2386/head\n0041f39876a2c0ac0f18f7dd42c48859f55626b46fe1 refs/pull/2388/head\n004006ba35b53646c2937bd1fff198b269d1897eb583 refs/pull/239/head\n0041eb33b57255744abfbe557369066619701c0d0f69 refs/pull/2391/head\n00413dc4950c009dde0ab369b2ca459368b953190e40 refs/pull/2392/head\n00415c753f8eac6e9e83a39261373789c09a8299cdf5 refs/pull/2393/head\n00413924c28bcf5f0a53df04ec74b5f6c36b98948dda refs/pull/2394/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2395/head\n004119846ac4836859d8c568239a42b72ca44139742d refs/pull/2396/head\n0041cdf1a7062f8f077d3fa4d6d08dd5459b34880854 refs/pull/2397/head\n0041e368558b630ab18408c79db485a474dfa4683e94 refs/pull/2398/head\n00418f4bb87155757c3a39c3f27aa7a315f34983e3e5 refs/pull/2399/head\n004067e93c659b3fee46070e27c3ec08402a35c82375 refs/pull/240/head\n00415804bb125905a1dcd8b103dfac2ad2b15f811984 refs/pull/2400/head\n00417b80fa5cf0abd102423d5dcb24d7b32bf5212551 refs/pull/2403/head\n00416a76e512e9b58d77a7e5248cb678a4c647f1d669 refs/pull/2405/head\n0041051dca78e7664c9b451670baf44d15851a7d33fd refs/pull/2406/head\n0041f91bbc6c66207b0e908e82733f029c32f1292641 refs/pull/2408/head\n0041a5b9ad92313a57ff2a0f53f2b81aa90b9417d91d refs/pull/2409/head\n00404debd5e8e0860cb57154cfa59525c87bbe9e1021 refs/pull/241/head\n00412c28c867ccebeced01a0f0ce2ecf98f33df27077 refs/pull/2410/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2411/head\n00412184298934e71c29b6d66ed59782938fdaaa0f20 refs/pull/2412/head\n004199325072b64c02fbd888329fba65944e0bf731a2 refs/pull/2414/head\n00410917f9702082147abaa26bb6fcb1357f8a0f31af refs/pull/2416/head\n004195829ab78ed81644b5eb41fbe8409788a9fc7e21 refs/pull/2417/head\n0041c5a219f066e5a874208b2f78033d8ed0f90762b8 refs/pull/2418/head\n0041e28d97d2634995711e5abc794ee6484099128e71 refs/pull/2419/head\n0040d971c87456fbe727730b656e1c6a5de7f7831364 refs/pull/242/head\n0041822ac698104cfe1cb51b952003b43cb8b3ef6200 refs/pull/2420/head\n00413ea5d0adbc23cb3059c3297a9be8b854812883dc refs/pull/2421/head\n00411178657965713054cc5790a36b291b30b6d9ca81 refs/pull/2425/head\n0041c9c8d7b7605dbe60cba2eccc00f55723c2acdaee refs/pull/2426/head\n004103549f653ed13a38b886d13855e30c311942d652 refs/pull/2427/head\n00414154a9cbf1c273acd34a5d929adba231b469e629 refs/pull/2428/head\n0041cd93be6a1d7c92ee9f76789fd7c97842b0a7740c refs/pull/2429/head\n0041f733ab04711173a59877d809b2f557a9e3ee4a60 refs/pull/2430/head\n0041c5fa3e53f03ad8e999d57b7f76237617ad4037b6 refs/pull/2431/head\n00419bf72cd1fce073ad01b904fc1ce17773d2d89d6e refs/pull/2432/head\n00410715e65452d2cde3bc2b8bcee1c5a2029ee8afb3 refs/pull/2434/head\n0041794af8c606abf9a5060b9a4442999b9f23431678 refs/pull/2435/head\n0041e87432e66ed5209673cdd0ddb671a8a9a2c03708 refs/pull/2437/head\n0041c4ecded417152c3d5bc809d566769e71780731f5 refs/pull/2438/head\n0041536d8403169585521583475f89d6ce5aa03e0a92 refs/pull/2439/head\n0041ba01d1c94743595ca04e14ec2573dbee254c1c1d refs/pull/2440/head\n0041da45d1e2c8c8c6e3e770b310cf6b050f6da03aa3 refs/pull/2441/head\n004156ef8c622bfbb8376ecb2ebb20ba1668804b461e refs/pull/2442/head\n0041b01339a98647dff2ed86c2d229e23182e57f4a87 refs/pull/2444/head\n0041107392ac7410b8c25028a271523b0f4a050a69d6 refs/pull/2445/head\n00414c66211ac3614faffce5e8e008f16542fcf19019 refs/pull/2446/head\n00415d69266426f17b173056b98b4ed8f01ce0e9caa1 refs/pull/2447/head\n0041b9230a99fa4e2188859f37ced2b7c4427d8b7be8 refs/pull/2448/head\n00418665468e83b5be7770ae198388dcd5ee61dfd5ce refs/pull/2449/head\n00404bdeeb490f450be54f2e73835a76831f332cad8c refs/pull/245/head\n0041244459aa1f47e3433ac537fb89d3dabc7fe23fd9 refs/pull/2450/head\n0041d478b8f397f01d149f8f784a2ac2c95d40412c9d refs/pull/2451/head\n004170decc6cdce3762e1bbeee5e28d5559f80ef8318 refs/pull/2452/head\n0041ca9eed266681e9b352b64c73d5557c15cc38e465 refs/pull/2453/head\n004129c754bf205a00188f6f0a1db1c9f3d82f68815e refs/pull/2454/head\n00416922b4330f05d791b64aa56c40ab953940e71268 refs/pull/2456/head\n004149329a17ed31cfe6fe2dba21b88db58367e7c494 refs/pull/2457/head\n0041f87c0318ffc66e3c82451cebc129ecbc7bb0a933 refs/pull/2458/head\n0041efd8c2b4ca7ee897c0fab7a93ec00bd8cd29c7d5 refs/pull/2459/head\n0040e6a0e38f56d88fe922bfb15e35f05f15daae72d4 refs/pull/246/head\n00415511906fc24b22b252d54f5d2a4b862662510a0e refs/pull/2460/head\n0041ae298fa67b643324650f89628863bcc4dbe1ef7c refs/pull/2461/head\n0041644d27f3c18e9119d1fc471d07279c6e666417d7 refs/pull/2462/head\n0041ce867243c2cdf166b31a687a350c7b9b705c7194 refs/pull/2464/head\n0041f6221e43ecb01c46cf84d2e4938a5c3dcf37a5d7 refs/pull/2466/head\n0041e3567ff0d7f5412ab4135bbd4be8adcdb333b5b7 refs/pull/2467/head\n004153560ba756790c71366a7fb6ed9be8dff4e8ccfe refs/pull/2469/head\n0040c6648aaac24ee53b9933bf43a97aee09dc22c3c1 refs/pull/247/head\n00419d221250b69f232adf7fecd8749cad4f2a40df2f refs/pull/2470/head\n004183dbe9f90092b8e791b9e906138eb3417e838561 refs/pull/2472/head\n0041086f6f183efe4ec20ac643ab2bc5e98677f2d94b refs/pull/2473/head\n00418fc6a5c455a1b4dbc1dbf9869bbe3be6ff82412e refs/pull/2474/head\n004117b37df5d0f231481d6e5b2ada66666f99840fcd refs/pull/2475/head\n00413b2392429fe87cef09e404e695af344e9964370b refs/pull/2476/head\n0041aa0b81d3a6db4bc68a306398c30b473c6309cf58 refs/pull/2477/head\n0041d6d326a4a90095edf0da1d06d3eb48975a29fec1 refs/pull/2479/head\n00404709ec33c18f5c2653efffb908a8b69474fc1deb refs/pull/248/head\n00412af5644abf515b5b8424c8eb7b12faf35be68f07 refs/pull/2480/head\n00416eaa4e79b0e4b1178f5a03e299258632338b781c refs/pull/2481/head\n0041f6cfbd09ca2659675ef5ceca4d9b03b86b42849f refs/pull/2483/head\n0041098f63817e201983078c996ce5b1222aa2be6a01 refs/pull/2484/head\n0041157a47634e6089c7f7938bc7939f0661f5563b14 refs/pull/2486/head\n00412d3046144846d1a981b4ee30db75ac0e0a799f41 refs/pull/2488/head\n004180aa3dc17e885ee35a09ad1488fd18ef42961473 refs/pull/2489/head\n004197094af2d52994da5f658a26372006e0446fad9b refs/pull/2490/head\n0041224485342b1c8b88e4b4c3c48f13c083fcb837ab refs/pull/2492/head\n00419cc699a1c0eff4fb777a32951b06519dd7f25335 refs/pull/2493/head\n00416dbaf17f9a9fbbca7be0d02d5e4e0bdb74b0aa33 refs/pull/2494/head\n00416c1465a055851c726de155021c7284e98b92cc91 refs/pull/2495/head\n0041d302e811976f33178b99b6f15e24c1c23db46da8 refs/pull/2496/head\n0041363d41a21a19b87a0d02a6590d091beeb3eee582 refs/pull/2497/head\n0041568b516d94c9ac0877faffb3dbf13dfd9823246c refs/pull/2498/head\n00410c46bb4025498aa53f8872fab755e8cc02bf2006 refs/pull/2499/head\n003f45d1d4967d81f6ba4e3720a7065a3dc7ad83efd6 refs/pull/25/head\n004073f225e0cd741972f843ead3efd68f3768d32a40 refs/pull/250/head\n00414558a3e87dc35d37be3ecf5804ce499cc7a280c6 refs/pull/2500/head\n004130aadada170106402b84ed7cbc1e3a2be714c261 refs/pull/2501/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2502/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2503/head\n0041c2cdbf33c04c2261bbf13460875dfa96c8d4a900 refs/pull/2504/head\n004131cdc4803c8bc38ad71e14f1177b4dd1e1dbef5a refs/pull/2505/head\n0041cc06e5bbdf95c0e9502e86d24caa07da735e61a2 refs/pull/2506/head\n0041b64512aa5404eb97a175897e819a0a08d8be84bc refs/pull/2507/head\n0041c5fd3054cedd2be85d7e3b7013675990beeb20c5 refs/pull/2508/head\n00417fe9934f21fedf95a3bd95f7a0d7b51ac7425c99 refs/pull/2509/head\n00403444266fc3ee97cf87d942e5c3cfb6adcce0457c refs/pull/251/head\n0041c7c8e84ae2c10084fe1b913262804cdc76591509 refs/pull/2510/head\n00419a05a9350f70a44308e36728775b045eb47931ed refs/pull/2511/head\n00414277918e4a52bb2fe657d9782c40e5ef59678a57 refs/pull/2512/head\n0041c1035ce33537f701f91b7f1bf6df9b943d7eea80 refs/pull/2513/head\n0041a744fde6253c6a98f1b58497ea97d6d7e3c26a59 refs/pull/2514/head\n00419ce7f5a2d56f6a15b084858ad26a26b1b88ba8dd refs/pull/2515/head\n004197e4213204d34947cef09cbe4c16ab83465e9d1c refs/pull/2516/head\n0041ba6b47281628ec355528f1e472fa96d864d2caf9 refs/pull/2517/head\n0041a408bd7d8cfec77a87a9554285045087fc6f87ca refs/pull/2518/head\n004191651d9e6ff7181ed487b6ced372f0bae22d32bb refs/pull/2519/head\n00407f9fb1a86780ddcf6e73c22594f878de5e844f65 refs/pull/252/head\n00410fe7f7663a58e3735fa7f45f46b8ca64b4bf60a7 refs/pull/2520/head\n0041e19697e71d89145a504989888ae3faf0a739a27c refs/pull/2523/head\n004183f32f12b3c992e78c2b96524b4652966367ed3b refs/pull/2524/head\n0041e0bf1f04ecd19faa9d800e5fbc85ab4de3a11f07 refs/pull/2525/head\n004117dd77cdf4cac22f250d00ad1d43f3b928a0a8ff refs/pull/2526/head\n00417260f278cc92a8f2e620c55208c8bb9311c3bbb7 refs/pull/2527/head\n0041b0a9342ef09bd25dca67903d16fffcf45c199e8e refs/pull/2528/head\n0041a06d52e26333b88ae90c515acff70dfb6e5feedc refs/pull/2529/head\n00401cbeaa642c6340f4450ae7baa44745bfa361f16a refs/pull/253/head\n0041016576c8814583b730870f8e2015a023f234712d refs/pull/2530/head\n004174189b5520d233ba50fc975c076aeec7cdaa25af refs/pull/2531/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2532/head\n0041b5293c77b330a226152bc7ccb00f9a8abb9c12a3 refs/pull/2533/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2534/head\n0041feb4d189cb1125b0838cac8b6570a0f8ddd11621 refs/pull/2535/head\n0041a5419a2150dde4d2923f4cdf17a23ef20f6c88bd refs/pull/2536/head\n0041d47dccfce889e6915995d122d04ef363014ed89c refs/pull/2537/head\n0041dc6f679abfd23d56e171946d908b75e5acdce47f refs/pull/2538/head\n0041b72c34c7f9edb9ae8513e95b6d2245c2cb5f54fe refs/pull/2539/head\n0041a2cf07661f649e73475c124118e8cdc334280c1d refs/pull/2540/head\n0041877b62e647862471f1d2b6376773eec2c3a1b211 refs/pull/2541/head\n0041cfc1741a5ded4e6040868b9012629862be1a0077 refs/pull/2542/head\n00412b6a997e296ea3fee132e8b9478d2073849f4e12 refs/pull/2544/head\n00415e8d1a9990b15e0f2219b5897f37424e302ca300 refs/pull/2545/head\n004125f771752f5119e8d697ba008f23e70823d72e8c refs/pull/2546/head\n00413198f8f6b575d2e954b588b4a67e0c123c51c6d1 refs/pull/2547/head\n0041acfcd4bdded2da1570dde992d6e3c15f2b21dc1e refs/pull/2548/head\n004131e9796ed8640c0ac39a81c62bc5b819521e53d3 refs/pull/2549/head\n0040fa95d2cc63ed28380c42e591258a30f607866069 refs/pull/255/head\n004173943f8d9b7d83cfb556848b167fd7c900a7e98c refs/pull/2550/head\n0041bed9872cd09ea6cdd74e31bc0eb4278a1476cf9a refs/pull/2551/head\n0041db7f04921d64675178666b7b2a8489d7ae3ca6e6 refs/pull/2552/head\n00410cd05892dc65cba018f56aad7dcda7cc8c5c4bea refs/pull/2553/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2554/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2555/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2556/head\n0041a84727a064c21268375d16b93feea2c95b038bc2 refs/pull/2557/head\n00418355cc67e9e6e8da93e59c179492d4b0903ab8cf refs/pull/2558/head\n00419c151606c877ad06bf89b3835bc356f0dec77b37 refs/pull/2559/head\n00401a970259913bb7403cdc4608f7fe9e7743f3ca51 refs/pull/256/head\n004147c640f3d31fd87b03010f20f7a4b8bc8640ead6 refs/pull/2560/head\n00410b9b22dd1c444e6ea86560e277d02ce35f0b15cd refs/pull/2561/head\n00410015619ff7aadf7a3004b1d627a1d398e51bb524 refs/pull/2562/head\n00412db5b830eaae0062ad1f518b77ab52bb27d28155 refs/pull/2563/head\n0041de1988eec8f01e838cc5697ebe961b3d07a91e61 refs/pull/2564/head\n0041bcc12ff125f2bac6e2889e144851e9ab056b30ee refs/pull/2565/head\n0041b2defafa31c947d8217a78ee64784d6e99071268 refs/pull/2566/head\n0041be8cf6b0c06195f841c7fc0136c3f4640c2945e5 refs/pull/2569/head\n0041254a670d2cac777740f22c3871b37d41daffdd2e refs/pull/2570/head\n0041c22c95d233964393d44d44c40b905ac16c0b5272 refs/pull/2571/head\n00411cb9ff8dc46e8aea62f8a43288bc84f2252db672 refs/pull/2572/head\n00416e72345f68ad7349d61d4b5cea2cc75d556d808d refs/pull/2573/head\n00412fcd5646c29b6850d656ece947749a865f8479db refs/pull/2574/head\n004142496b7fdc3a1239142d3e2bec836b60a78a472b refs/pull/2578/head\n0041d35db462766019ad82cb1f272f3f2d3e694dcdd5 refs/pull/2579/head\n0041046915c922731515b540ba344e2d420ac4a52fd0 refs/pull/2580/head\n0041546fb5d556524597efdcce7f2fc45a6e2307dd99 refs/pull/2582/head\n0041f2d1e6a62dee228f2f344361ca109cbbf2f0b24c refs/pull/2583/head\n0041dee53b9d72e183c2043edb6a8632365088a5430d refs/pull/2584/head\n0041eff28852d362648c378ee1f14d68eb16ec8d3ac8 refs/pull/2585/head\n0041675f8d051d94f0f000ff8dac8a93eff6458e3616 refs/pull/2586/head\n0041a8a4d03150df75ca23b4aa1fdb09e9da5add83e0 refs/pull/2587/head\n0041246b65dc5814a2a1050db97cfecee77014ec06e1 refs/pull/2588/head\n004181e335000a43373b83522864d2b1729b1d6d6e60 refs/pull/2589/head\n004027b9d604bc4ca31002e242af3eb43a4d26bfbc8d refs/pull/259/head\n0041e0167739ff07740a1565e1b2bbe2a3eaae584e3b refs/pull/2590/head\n0041b94c9ecbe2dbd3f612c4e2caa6886d494be3cf73 refs/pull/2591/head\n0041e57bd03a3b8a26295dc22d092334563a34bfb07e refs/pull/2592/head\n00418ead6a9209d4457843b2ac6e9a7a2549b0886067 refs/pull/2593/head\n0041889401099f1e3c72b7dcf18fec9e7a4617ea3444 refs/pull/2594/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2595/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2596/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2597/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2598/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2599/head\n003f627e315ddb24233c9159877a91e88faccbeba942 refs/pull/26/head\n0041b3aa240f3cc2cbaf9b810aef9390d3b2ff73a39d refs/pull/2600/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2601/head\n004151fdb7869d6b103c64e96e6a32bc0687431714e9 refs/pull/2602/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2603/head\n004172b478255f01f30aa5b2b33bc697a6216782ce29 refs/pull/2604/head\n00413456c65b5bf8a455ab4be528c932e94e2dbc51b8 refs/pull/2605/head\n00417689490034d5ace342ad180af664d0561dda7fc5 refs/pull/2606/head\n00418f747d48cb81b208e2dd43b2e2399a4e4c9fca16 refs/pull/2607/head\n0041ba522680e8bbf2e06e9844b268ff00147bf5ccc8 refs/pull/2608/head\n0041afaf0c24c73a4ced47abc729116f4e304056d85c refs/pull/2609/head\n00403f9aaf1d6ee0724fb367b8d9badfc153290050a8 refs/pull/261/head\n004125403ed7b2fa54cabe42ad36770b7ded16b17231 refs/pull/2610/head\n004148f4740a642291a6616f29fdbd1e2189449ed149 refs/pull/2611/head\n00419edcc47a2c33ee7c596ee623a34bef3085185446 refs/pull/2612/head\n0041a3fa21166c461cf3c98eef1ccb3ab98bebf0beff refs/pull/2613/head\n0041a23c8b65649e38e68f0c7ac2bf3d583fa278d905 refs/pull/2614/head\n00412a74d38a8465b18f667c93df4a4b9a1688a1621f refs/pull/2615/head\n00411fdcc1587c4182efa6bd6f1a82bd78ed8ab891ad refs/pull/2616/head\n00417581fe8599f89d5424cb3e5fdb82b9d883feff9d refs/pull/2617/head\n004134ea656dc06e0f8b84c07ce9ea716e6227f08597 refs/pull/2618/head\n00411575bd7dec8eac4d7c46a8c60ee1ea8d043909a2 refs/pull/2619/head\n004046c557ad9391746796a00d6ef2ed0d33fa6b46d2 refs/pull/262/head\n00411b72b4bf65fd05a51f3ae039dcf4f4f80c00e85e refs/pull/2620/head\n0041e4cdb49d5a0ec98f63c2d0f5892ae88b76eb131b refs/pull/2621/head\n0041543051cc088c663747f39131568f1c51836e940f refs/pull/2622/head\n004176212951be69737dbde4702dce72992817e6fe61 refs/pull/2623/head\n0041a24e343b863c73e5ce712dc5b3d57622f7ed46ae refs/pull/2624/head\n00419a00a85201d32580f57314988ab47acf2ad5a575 refs/pull/2625/head\n00411ffe7670bd91d901abef4d8bc976ce80cf7c187b refs/pull/2626/head\n0041341e0d1d0ee55bd6c91f75b7d499dc05e29af448 refs/pull/2627/head\n00410c7ea41ff4269498985d636c633cc04ead32b0ad refs/pull/2628/head\n004118a33ffec8ba556b2aeca01c69a3f9c1dfbeb194 refs/pull/2629/head\n00403c45a5fa82837ed3281394cf1b141a4565dd3701 refs/pull/263/head\n00412ad5c547030d92c823cf05d33473e5d569896028 refs/pull/2630/head\n004182bcd8510836ce15256951440f1866f56129dee5 refs/pull/2631/head\n0041664c3eacea7aa135815a12b75bc17c1502bc2731 refs/pull/2632/head\n004116630e020ff2f40074480b5e188176ee1f7dbfbc refs/pull/2633/head\n0041afdbef0c49fac58984098b1563bec4b1c94c45e8 refs/pull/2634/head\n0041bfddf1d4a056551c40ccfe9454c0b3cd9693af41 refs/pull/2635/head\n004165e80f09f0a79b12df6beac44abf245151bbfefc refs/pull/2636/head\n004161b021f24ad4fbe29130c0672742a4c1efd31609 refs/pull/2638/head\n00418b76634b8701e90cebb880fc7f8a1faa4e6b46c0 refs/pull/2639/head\n0040b079da3c6af9b1a139db5127457315034abcbbc3 refs/pull/264/head\n0041d2ee349b9919d416260e3717338f9b65e6443b85 refs/pull/2640/head\n0041c86b29e940e3f800f5760f11d41380537a88b131 refs/pull/2641/head\n0041cc703e4f8dbb366e8270a20c0cd91cd53d913a52 refs/pull/2642/head\n0041f3c5d59acfd34527284183af35c2bd0a7b422d8f refs/pull/2644/head\n0041ded67731c579c99af1671e569bbe7e889a633f44 refs/pull/2645/head\n0041b7278b4edf0acfbfd7a0b9230de099e37aad8611 refs/pull/2648/head\n004149585781890214a9f0a08b1dc952bc3cc3d7fd49 refs/pull/2649/head\n0040ecee40da8a3cfd90ad43cd05f7a3f0f47e67a826 refs/pull/265/head\n00418614cbd27dc368dc265816d801ed18e5d00fb760 refs/pull/2650/head\n00415af5d38da5724640f85bc05ba64a1e0bc347e5d7 refs/pull/2651/head\n004115f4b9fd2edee8bb6767003ef2afb27d86ff4c3b refs/pull/2652/head\n0041a1642fb968ee8ba6edd65113bd68e3f396500dae refs/pull/2653/head\n00410d08a2838b3e4741764cdc02cd20fbc164ae60f1 refs/pull/2654/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2655/head\n0041e43f1e2f16a91260fa2b263e8b968a3f535f62f2 refs/pull/2656/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2657/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2658/head\n0041d43b986486789b27ca98202659606351a803cdca refs/pull/2659/head\n0040a1fe55ab948b3507af0e547366e964e6076c0a43 refs/pull/266/head\n0041a5f399a9d582eccb24df4de26c083b04e572e3e8 refs/pull/2660/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2661/head\n00416e4ce8879df1a46060aa7b3a0c05ec18c372ee52 refs/pull/2662/head\n0041db7b359f0e8b3255b22f4cbd1b7ca78685ed381d refs/pull/2663/head\n0041c3ed87788b6021c49c8fc2b9d576b6366537c69a refs/pull/2664/head\n0041f4836610cc31a8a09c823c3fc84599ddb4210720 refs/pull/2665/head\n0041430da5fcc21bc97a11a462c7936f84bfdd1e7d97 refs/pull/2667/head\n0041115f6caf9f2265b6a258ec491d02f6c0b39cffdd refs/pull/2668/head\n004156ed2ad272ee8c04c6be6c1200362aeae05292be refs/pull/2669/head\n00401dfff6435abe32ec18ea4343f41053924ec0bc06 refs/pull/267/head\n0041bc8a9dd8a47a6dcb322502560c6f5a1d65f8aa77 refs/pull/2671/head\n004165d911a77093f0e33f73cd261e754112d094dd1f refs/pull/2672/head\n0041a2521a301d632a896d24596519077bdcc684dba3 refs/pull/2673/head\n00415859aad095aaca071c336ec429c2321951364f87 refs/pull/2674/head\n00412ec5dda14f2593535a8865717ff7f9068737f777 refs/pull/2675/head\n0041775f379dba856e9969c8efd9d84a9c0b34685013 refs/pull/2676/head\n0041ae09e4dc91ab9aea20446af75b61a79092c3d30c refs/pull/2678/head\n0041b6d02fc3a46c7aa43a0ada56a4a05dcf1bff91e4 refs/pull/2679/head\n0040aa35755406731fadfb18212be848b77d5bc133d8 refs/pull/268/head\n0041b678f0620138174c1af1564c46d599ed454ce4c4 refs/pull/2681/head\n004146a6462fd1e901470278e3665d8553037e986977 refs/pull/2682/head\n0041014193bfca96310ed507387a25f064fbf0610cc8 refs/pull/2683/head\n0041847cf4f7afbf164129660be68a389152f32fdc92 refs/pull/2684/head\n00416088aab6a59dfec9d5a9a954dca42c9b3fdab2d8 refs/pull/2685/head\n0041cd156d88f9c8da9fe495b6819e27c8fa332d0ac4 refs/pull/2686/head\n00412d2f49510dbfe5dfc92660ae8278e5c9a26ee2e3 refs/pull/2687/head\n0041d9d09dc8c2a3a4a9eb07acadadb87a928de092e9 refs/pull/2688/head\n00416cc1db59df50ffb407c12dfa1761aea4a48f0fe4 refs/pull/2689/head\n0040df8678d532946bc9d6d1ed59ef24767bba5bf003 refs/pull/269/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2690/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2691/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2692/head\n0041557627d2be80aa8f8337ae5c841c82daf29ad30d refs/pull/2693/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2694/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2695/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2696/head\n00418321be766309bdbdad52f1f91e367589c6be4660 refs/pull/2697/head\n004142cb69954753c00db29bd25f72d8aa21d9466ce5 refs/pull/2698/head\n00411cfde0f7f6ff199b73e233d1e72c7bf3dbf8f2cf refs/pull/2699/head\n003fd12b185990668acabd3be3e2818f5d3154548672 refs/pull/27/head\n0040c60a5854a5f6fd7d431afb69b5b663056a6c9122 refs/pull/270/head\n00414a81447cd5435c74ad91a0fb2d85ce437b82c1cf refs/pull/2700/head\n004110865d01d184ebe325dc402150d8f0b500e22c35 refs/pull/2701/head\n004138262d8cd70f7bfcd9785e9e4be9ee7a075f85b7 refs/pull/2702/head\n0041c37b8f9d2000409e91259278670aa787e5a010b3 refs/pull/2703/head\n00419edeffa512ae514612ff4cf14bb271d03688c0f2 refs/pull/2705/head\n0041c5a80c1bb0cc6865bcc440a6ddce92af5cfd9561 refs/pull/2706/head\n0041b341add1cf7df7dc61b86e99d55b4e14ce2b1f3e refs/pull/2707/head\n00418af58f720a0a05c5fc147052a62899ac2ac0a425 refs/pull/2709/head\n0040cdfced31cbdbf455bdb87427fb458d6709f9df80 refs/pull/271/head\n0041887b5b2bbf1cc4a80cb5abd0c4af99551cd62da7 refs/pull/2710/head\n0041f9af70aa10c9580d624f687ffc071e66e6ae5218 refs/pull/2711/head\n00410c23b69f7b334ac6d4b75644d645ec0a24e72544 refs/pull/2712/head\n004130ed0c4b02a46a20561a5b2123aa08fe1c6e5f8f refs/pull/2713/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2714/head\n00411a91edfa25502cbbba58f8c139744aaef93a4725 refs/pull/2715/head\n0041f2d003cdefc21c6982e316a8d6623a40a7da3149 refs/pull/2716/head\n0041c91b670b72c82dc0e400bf052dd8633c5708f53e refs/pull/2717/head\n0041a5bc0aa6baff0b8c52406e6b9f9c07aa094d6785 refs/pull/2718/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2719/head\n0041a97f8219db1ef056480b89308ed06b2562057922 refs/pull/2720/head\n00415554e5394868a283603f0c341216607217ae14a6 refs/pull/2721/head\n004132b09542271b6dc5961ccf6e653d1517fd6180e1 refs/pull/2722/head\n004108a0bb08a6972d4f70752cc6a1d293ae603f07f0 refs/pull/2723/head\n0041d94268f0484742f927ee73bebc05131f09cd37e0 refs/pull/2724/head\n00412c8d08e44698ffb03ae857730ab6b14486bcf0e0 refs/pull/2725/head\n0041ade73c7449073a28fd5bd36a1d48fc9a85d91f0c refs/pull/2726/head\n00411432ffa7f85e9d9b31acbee7f313291a1acf5c5f refs/pull/2727/head\n00414efb6e194aa53d31dd1a5ffcf90e8dc70c9fd31d refs/pull/2728/head\n004089be2b28d522855a7d56d0d6781c841e2d9fe8a4 refs/pull/273/head\n00414a4e64e2fe93ee38e495cb246582f7ba1ce19525 refs/pull/2730/head\n004151b9ae5241247e80b30d68e9b983a8df1ad9f44f refs/pull/2731/head\n0041fc986f627df1f299c03b248a549844df6bb84ac2 refs/pull/2732/head\n0041a05ca8039996626cd40db82aca293ed64a36c439 refs/pull/2734/head\n00417751fbeb2c3e466476dd9b194d8fee925fffdd64 refs/pull/2735/head\n004166968de6c82b4ee867d38d170b5f9d1df9ed93fc refs/pull/2736/head\n0041ef55bd3f7dcfac478506006f469e50f7f0e01268 refs/pull/2738/head\n004160b2751d13b6888d0cd4f2625642f72fcb6dfb13 refs/pull/2739/head\n00413592dc2989ba7b480c78195899aa3a15460c688e refs/pull/2740/head\n00410e14677735b68823cf8f026c3f75cc50cc7f4070 refs/pull/2741/head\n0041d54a91cf61f504a353002f78111cf1a42d5766cb refs/pull/2742/head\n004195d821ca3a703b890d3f553a22dc76626a5ed579 refs/pull/2743/head\n0041a755ba68a1bf8e48b50e4b5c00a84cfb0b9cb4f1 refs/pull/2744/head\n0041d621f965c8650e6697f74839464a84329f52c460 refs/pull/2745/head\n00415f80f7bda1910871b33cc8568eed9b9e0a067abd refs/pull/2746/head\n004127f34058a675bdba5e5e9ff196293398e560ffed refs/pull/2747/head\n0041ec6a31f01d35bbaf086bcc2098cab5959c632479 refs/pull/2748/head\n00416e76f8d379609f9945377b7045ab308979f816d9 refs/pull/2749/head\n0040abaa66143b82ff64782f3d8e5a726fa3d8ea674d refs/pull/275/head\n0041f5d9e64f8c83fe518d93b584cbb099143745e362 refs/pull/2750/head\n0041c5c4e3f5856a61bef515aa5e0a69b72826f536e5 refs/pull/2751/head\n0041bd209b316901966059e16cc7985122db957e854a refs/pull/2752/head\n00414fb5b70400f425e9b7c52d397373b4563539edd0 refs/pull/2753/head\n0041d344dd1ac65befdb61c7016d1ec2e6b72d42fa0d refs/pull/2754/head\n004119a3f119197386ef948b52e3041356e01cd72455 refs/pull/2755/head\n0041a0816f94ab06d17c770334b5875808ae5dd20dd2 refs/pull/2756/head\n0041d360762d855688c45c934912f14e3e07945d3ced refs/pull/2757/head\n00411a596384bb4ccf7e7a241bd5d4540d98b65ae151 refs/pull/2758/head\n00412031ec5f09cac3612093578697973ec78df3ee7c refs/pull/2759/head\n00407acf9f795de84bc83c6176a6e0332453bbe51fa2 refs/pull/276/head\n00413517588333f1a378675690923792341d2b94f08b refs/pull/2760/head\n00411e29bdcf8ed23a4dc8f043a0963a773c056edd63 refs/pull/2761/head\n004159daa621cf5085f140f7513b12bf98611e8b5582 refs/pull/2762/head\n00412a625ab871036149179a92d70bcedf0a11fff820 refs/pull/2764/head\n0041aabdaa18934aa47b6a1a682d02cdf3fcb974debd refs/pull/2766/head\n0041f9a984e7c1b1faa582cde1ab72fe6e07286bf239 refs/pull/2767/head\n00419cd85f118c2603fd0524f0d9b8b78e265063faa1 refs/pull/2768/head\n004189d47a15013cfb60bfd200cf61c47b62d2de9d5e refs/pull/2769/head\n004104db79d2fc3294c78027967576ab0f886228ddf1 refs/pull/2770/head\n0041bf7e690cc30eb306ea66ea0a7f53eaf21afb2601 refs/pull/2771/head\n0041fd69d044571f9c6daec232fc59bdd9a8d5d4125c refs/pull/2772/head\n004156b14b7449f7e3514178108b5b688ed8797253df refs/pull/2773/head\n00413532e240bfa976ff538013367aa27338b8380921 refs/pull/2774/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2775/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2776/head\n0041d0ada1d23b06bcd3948b924cdf761a8390569550 refs/pull/2777/head\n0041516179e60ccee64e0eff2f405286d3c4513bc459 refs/pull/2778/head\n0041a8e35df702581892410de7d98a5bdf2e53c671f1 refs/pull/2779/head\n00409ef86c610ec21e3a398ed7d7d02ae9b2070d19d7 refs/pull/278/head\n0041efa432d9e9e19623caf79c4dd0b359f6ee0984f2 refs/pull/2780/head\n00417ebc50d417b25a285bbcdc8ba416c390aa0bede4 refs/pull/2781/head\n00418f936d8ca8889845c1a1f3e468388b60b5384ded refs/pull/2782/head\n0041fffef8ed543bec1e79e2f1e3e668c2ad3f7aa1b1 refs/pull/2783/head\n00410c3412a5938c0af7c15a20d95e2b39e65f037a11 refs/pull/2784/head\n004126676724a4bc1eaca84139c94ece9cb77fe9224a refs/pull/2785/head\n00410efae10947090c7e2ba66ce048ee8933569fdfd1 refs/pull/2787/head\n0041eb8724b40c9693ce5cb7ba322c4dc917ec2b0166 refs/pull/2788/head\n0041c46c59fd46e2418d293f3c45575e0c1952c7ebe6 refs/pull/2789/head\n0040387db6d1376294aad267c4927a7abb44cf8c5a31 refs/pull/279/head\n004130f4ed16e3b290acecfd565720ebf92dfa5c69d3 refs/pull/2791/head\n00411b6820e13ffe15956e4973dcc16294c9b9ca9637 refs/pull/2792/head\n00418a10e02c2a94af79e599774ce224d022ad5c6b15 refs/pull/2794/head\n00411024b7d519a107554bc6a5b3c251af71cdd06b9b refs/pull/2796/head\n0041c9520de348b6bf3b70fb7f6db48d26503ed37c5b refs/pull/2797/head\n0041111952e89e593ebf05626dd8d8979745c7f81f79 refs/pull/2798/head\n00415467cccdc73e0dd78c1674d76854bce827bdee62 refs/pull/2799/head\n003ff487a58f5ca9cf47cc62624d6e74f38134172298 refs/pull/28/head\n00400f1e0091747295f93910650e5dc16de612fa20f7 refs/pull/280/head\n00419c1176adeff7fc3e6523c496d40242250e26719c refs/pull/2800/head\n004133a3087a7ea73bb06343884720a8f9f9c62dacae refs/pull/2801/head\n004113b27b8dfafcce495fbe3f919c2a286bd002982d refs/pull/2802/head\n004139de5c14157758242b12e2a1c73fd1bdbde80905 refs/pull/2804/head\n0041b4cb96c9ad88813e5705410a5bfe3b2d86ef0949 refs/pull/2805/head\n00415db28b0a667f51175fc6d808c004534d681e754d refs/pull/2806/head\n0041d748f3ee8c54e343b7bfabb9ea632b6d02a8c337 refs/pull/2807/head\n00414e8a542ed46dd0744ba94717980a42e6334a4c0a refs/pull/2808/head\n0041f9a76ad79b91979aa6ed8bbc9694104a7ae6cfd3 refs/pull/2809/head\n0041f49db036ec837a98011cb28e38804a4fdd57aed9 refs/pull/2810/head\n0041185aff83e2cea035f1f4c0c333eec954fa89d04a refs/pull/2811/head\n00414251dd48538532d206c96882bd0411921ef5e9cb refs/pull/2812/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2813/head\n0041fd94f48443d79da98de552304653b908fe83e6ff refs/pull/2814/head\n004128fd0b9b9ea81ef284a99b149e5a69fb2f2c8e78 refs/pull/2815/head\n0041642bf0504d5dd0fd6160e7b508e546e37b27d905 refs/pull/2816/head\n004106c59993b4c84817b8b8c2a879cfcc5f3fcab8f4 refs/pull/2817/head\n004165dab2740390fae7815d53881b5c0bf6fa8eb583 refs/pull/2818/head\n0041d7956d5236877d7d2f1da49fe75dfd81059119da refs/pull/2819/head\n0040c88914a941222f07a6a29cd9ddfcd782d87ec1fc refs/pull/282/head\n00411cb455b505a3be35bd0696c41ff1ca5cbf113bd9 refs/pull/2821/head\n00418a57d72bc2f5d9182a56e4c882c44f51b994d627 refs/pull/2822/head\n00414dafa11d0222373c698b0ed2668a37112d491bcc refs/pull/2823/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2824/head\n00415dee54879ba73cd0c422fe0a7fc637a9cafa480e refs/pull/2825/head\n0041547568a2d0e54c919284b9a57ebafbd9cfca6a86 refs/pull/2826/head\n0041e0faf86c9025f64d5c083de17f0fcbaf8466cc0b refs/pull/2827/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2828/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2829/head\n0040857891acf88fd5e494c705e44f9721c73a6df2a6 refs/pull/283/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2830/head\n0041190bb1668ce2c7be361faa1a96626d4250f53bb8 refs/pull/2831/head\n0041dee7f03da3553448c024b4ff6ee96da427095779 refs/pull/2832/head\n0041cc358884526ecb24b5901d587632b570134bddaa refs/pull/2833/head\n00416faf3dd312ced029b468bc8b5bbb9ef12dd80cd4 refs/pull/2834/head\n0041476106a04b739c4a2d9f4106716d70e8c2205af8 refs/pull/2835/head\n00410c33cb5792dca5cffebfa2d9d9102cd51dbaa417 refs/pull/2836/head\n00417472807b8962255ea4eb7c8916c4b42e14872395 refs/pull/2837/head\n004119905886ae56bfffbc8027ce84ee5970e974503c refs/pull/2839/head\n0041c053afe6671014bd97cce4e5cb2189fe186e615d refs/pull/2840/head\n0041995f36545f3f9ce298b63235ab069bc915553ad3 refs/pull/2841/head\n0041611029f7c6bffc2b86c4e2a1fc3adba1dcb6c5ef refs/pull/2844/head\n004190ffe8e4fdf36ec73af89a4c91436c4ed5891b0f refs/pull/2845/head\n004180c8b887ac4cdd4094841524421b22da6b787757 refs/pull/2846/head\n0041c4775008293ae04c32d7c3a36e7ff69b6e6585c4 refs/pull/2847/head\n00417be76c68bf4172bec3b63c337c0d632105cd7dad refs/pull/2848/head\n00410bf3076cdf5cbf1b8d821346ccc8e36425af6447 refs/pull/2849/head\n00408fb04a0898abe7717137ec504546838abf6bdcc2 refs/pull/285/head\n00413dd6b289906a198f9cc4c554dd2d6ef75ad59b0a refs/pull/2850/head\n00413d188a188372258cb535ebbf7c9eb1bc735778a4 refs/pull/2851/head\n00418f8873ed698a9ea5322a04c707b034e5568bcc42 refs/pull/2852/head\n004119e2589154d7fbb20e089788154342e6735bd10a refs/pull/2853/head\n004197464e5a921cac24e2666ed0c0c4c1dfa6be23ad refs/pull/2854/head\n00413cce870154a37262df447f809c618ebda905d562 refs/pull/2855/head\n00419deca2fe60fca2d7ce473795b817032da212c0b9 refs/pull/2856/head\n004167aabf6657e3b405f04ce576e39e3f303e4c66d3 refs/pull/2857/head\n004193a63ad748e1d6ff49af3c3f641a4ce09b1c4b0c refs/pull/2858/head\n0041f477c6940ea743f47e8cdb6ec14ba4d5c6f31838 refs/pull/2859/head\n0040ec88cf672778f0d8098070047e7050fd5821723b refs/pull/286/head\n004193d45871f40f122c1494b79931dd732891792064 refs/pull/2860/head\n0041add5751fd0bcd0f1e9ce7e1f414c786110915e14 refs/pull/2861/head\n00417d7c18855c6e7f1b88300c5d2cdeaf33f1cd0c2e refs/pull/2863/head\n0041e1d8affae17cacef6e7c1a01e901b9687538121a refs/pull/2864/head\n0041747e1da71770691f0100fb21f4a9efcd9575183e refs/pull/2865/head\n00413fd074245dcaaf739002d63e7c6a89f39d9bd1ff refs/pull/2866/head\n0041c3523af0d6087b244bae0fd6c6522edd441f011f refs/pull/2867/head\n0041ddcc982004944baa45c53ef7ca1d9bbd2404a40f refs/pull/2868/head\n0041404a259ae62f5ee0537a87a0ba418daff01b1998 refs/pull/2869/head\n0040a865ef6942833d38e5ca4c163e1008c9796eb285 refs/pull/287/head\n00416d2c55e7437107c19210aab82e8cb06479710d96 refs/pull/2870/head\n00418c5bff2b80e1dca212cf32b0541e1db6f439a5e8 refs/pull/2871/head\n0041ee42ed4e2f00d71a99e2e74e497db8b40efe6784 refs/pull/2872/head\n00418acbb8bb927c14c60b5edd34b3b2af09ce999fef refs/pull/2873/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2874/head\n00413f8c12ec2674220d32c8fe644a510fd712336443 refs/pull/2875/head\n0041207eeb6eba7de6c1bf8d6b06ab1d2463935d993c refs/pull/2876/head\n0041ac3717e5ad39d22f94b68123dadefb174cc1c9a8 refs/pull/2877/head\n0041392798ab0a782b71f84ed724a653c3a2ceb28144 refs/pull/2878/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2879/head\n004054a8f8b7ee2cf16d9090585c1aeaa651b1bc64fc refs/pull/288/head\n00418d3e1fe872525cffb71dc18a1baab4e5a437cb91 refs/pull/2880/head\n0041209183bea595553c350bd754b2aff1e42a411973 refs/pull/2881/head\n004182b2f5db7ea4dcc6523a5b3c758fd31f966d4840 refs/pull/2882/head\n0041d94c89dc945512ff6da6dffb573cddc5a82e244e refs/pull/2884/head\n0041a7a391b6b4ad844c44c0aede77ce2d85a00d9b35 refs/pull/2885/head\n004169e6819fea9cf083ab2b8d19a82544fe888e9d62 refs/pull/2886/head\n0041bb2739a9755747176cf784b8c5156d501d8222ea refs/pull/2887/head\n0041bf7c148b090eadb587832531d9bc1a11be06577d refs/pull/2888/head\n0041196dc83ce02e38d56abdc3e9d7fe696fe621b3a0 refs/pull/2889/head\n0040f6d68afa1708059c00684b5d0bd9eb9217661a66 refs/pull/289/head\n0041e9d2a7d9eb40c426e630610c08e2376c82b46278 refs/pull/2890/head\n00419d8f0b1efd8ca12e9a71d3f815cae43f13409a34 refs/pull/2891/head\n00419c7315590feb960dc4b0cb8e87184792d38ff7a0 refs/pull/2894/head\n0041a8a928fbe8ac833540e11569f44fb09c50410d54 refs/pull/2895/head\n0041cdde00b06c74be5bfbf88050cbec722f1462039b refs/pull/2896/head\n0041e51098f495561b99d18218b40c58d18b9e872832 refs/pull/2897/head\n0041b4992ee4dbf990acaec8fea6582fd215d1122921 refs/pull/2898/head\n004163d1a6dc14f8dc2090cac8341fcb3148195ddc75 refs/pull/2899/head\n003f58fce1249ceb5d65b7895d5cdafcdd7821772b6e refs/pull/29/head\n004139309f06c3d1e405348b53877af07335aaba4fab refs/pull/2900/head\n0041a92019df7a4cdc1d55077d35042ec51306378b54 refs/pull/2901/head\n0041d103b346ccb027171f710e21ab4cdfc42618412c refs/pull/2903/head\n0041e3f88cda1e69b25caf64458d0c836408c1d83323 refs/pull/2904/head\n0041a70352aec37960d0e9858a693594a6e2721f5313 refs/pull/2905/head\n0041eb6a90c12145cd3ec1195ed71f34ff63b557ce77 refs/pull/2906/head\n00413a11321134227846f1d78c3835a9237f99726257 refs/pull/2907/head\n0041166a833b8f4f2105c5263e0fbcbb41dd3752a00b refs/pull/2908/head\n0041d958d900898d7f5b612864e6b45751ff1a77b6d8 refs/pull/2909/head\n0040fc0d24e67117833b606a5648b3308f907d3cac34 refs/pull/291/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2910/head\n004120662bbfba75deda0f6afcbbf62dc91bf43042ae refs/pull/2911/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2912/head\n0041eb5efdcb6805ce3702f91409ecc208be8e3d5df7 refs/pull/2913/head\n004199db1b0e45b3889626c09c0386b16f2ccc0dbd4d refs/pull/2914/head\n0041ce58552dbbd96fa34e39f9c256f9c4f3e6417ca8 refs/pull/2915/head\n004139e378db7e1db7e8fbc3ba2dbcaf7e7eed22bcd1 refs/pull/2917/head\n0041d91a2f11298f61a16fdeda77e89811c621b2b56c refs/pull/2918/head\n004188f4b5c486f180f07ec36b145307069a83d71279 refs/pull/2919/head\n0040177b1e72d8561ae95a910e9666f3a446b2d607f2 refs/pull/292/head\n0041c5e9d21e5c514c0aff595aba357a8429d9dd9b81 refs/pull/2920/head\n0041e73a43793254c217f42f4d27ccde56e6e7b9dd62 refs/pull/2921/head\n0041c4151af86b4125532d999f72a5dc0f13c7feac60 refs/pull/2922/head\n0041a311476a5b3f9c34407bb5422ee93f7df236497d refs/pull/2925/head\n0041c73a96b6f7cfef4fd1e1bc00a6686956e58c3879 refs/pull/2926/head\n00418a4f90c0240285aa3638be184a6092b50c49659e refs/pull/2927/head\n00419fd44d4217395b540fda630c64c1e84ff1c532bc refs/pull/2928/head\n00414cc85a0e3d02f0d830721518f6fc02349e71f08a refs/pull/2929/head\n00403504293dbeb6a169d9c51279ee0c9fbbb4dfa58f refs/pull/293/head\n00415234c08ce941b082223c6b7eb15d4e3beb3898e2 refs/pull/2931/head\n0041fe1da8c674e09238c0c12fba310535de7b95dfd1 refs/pull/2932/head\n00412ac962cd4b4bb269bd863fe9b43f0ed894e1eb4c refs/pull/2933/head\n00417ad72d8ae97bae7adfed81b8db0cbffb45ff81c6 refs/pull/2934/head\n004118901307dd712f3d8ebf67544c34626b9c804fef refs/pull/2935/head\n0041838166bbf80143eea1206fc5f06ea0b2ca862d97 refs/pull/2936/head\n0041827912336c7a42090a005dd0630d07fcc23dce01 refs/pull/2937/head\n00413a2b3f7b74d733f29e2d9e485c1a2c433811af9c refs/pull/2938/head\n00413eafc2591f35d5cdbadde5e223332b3c8449f17d refs/pull/2939/head\n0040a91db92ab68ef5abf3590a4c6c1156cb496070b2 refs/pull/294/head\n0041be92d5ced97ef304d5a71685ce704aee8f998376 refs/pull/2940/head\n0041f951db346b984af75f9158473884985dff74f525 refs/pull/2941/head\n0041c355aa304b31f81a1fca44c6c1561c568c761e18 refs/pull/2943/head\n00414fba1b172a8d5a2f68fc5cd6ca12a831c60b1288 refs/pull/2944/head\n00416f3de20c9009f0276b5af06e5ddedf3f1608dad8 refs/pull/2945/head\n00419f1ff0f6391d3f8936872a44e48b686b97fe5ba4 refs/pull/2946/head\n00412599a7dad17dd6e74ee9452026fec56d1f34be11 refs/pull/2947/head\n00419ddcd6e9d446385730a6e688fedf98a689be02b9 refs/pull/2948/head\n00410b2408f69b00465c0d14a7bf4b07ebea2d45bc00 refs/pull/2949/head\n0040d04bf6c58d024bfcb395027a82eca6f95d812607 refs/pull/295/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2950/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2951/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2952/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2953/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2954/head\n004198478706e827d4da7fae302344ae4626f91e216a refs/pull/2955/head\n00412d97411101768867ad72b493c386b087a01f4796 refs/pull/2956/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2957/head\n004116f5297332724a0836ec2c4127680963d2171285 refs/pull/2958/head\n0041f4a55c33a40aef6a4d473a022ea238fa0cfdc6e8 refs/pull/2959/head\n0040ddafd0b526eea0b7449881ab78ccb06e260c2fff refs/pull/296/head\n00414cc577627d5ace18b86335424faa0938de06f09e refs/pull/2961/head\n00412d3a8921f5f49f140c892059bb33191d017d3b37 refs/pull/2962/head\n0041dd37c708309e16a05aba50aa5da35eb51db512ee refs/pull/2964/head\n0041f0be3bc7ccf9429cdc44aaa3b755d1eb1851c9f9 refs/pull/2965/head\n0041dfc0d77ffa7035fa30ac0af4fae7014f963d31c4 refs/pull/2967/head\n0040c6324c7def409e52d2a6a79e986fb1615f5677bc refs/pull/297/head\n0041dc8941aedde75407a3aa51a6c1c74480df6523f4 refs/pull/2970/head\n00410d937d9c75ad6efc0aa2bb61042774b161738f42 refs/pull/2971/head\n004189d5edb9a4181ae87c4903b25195657882bd8652 refs/pull/2973/head\n0041a8a4c03282d2c6a80d164305db1176f8cb4e0fcb refs/pull/2974/head\n0041b909d9da94007f878ce4ab9cd9c851ea8dce0e2d refs/pull/2975/head\n00410f4dd6ed1d9e5ef857b21032606d63270723d716 refs/pull/2976/head\n00413e7aa3ce4ee080aca6e01a11f17e973d5e159d0a refs/pull/2977/head\n0041e21e8228899eb87ce3ca9550893f11aa6df87800 refs/pull/2978/head\n0041395fc6df1a91872baf88e570a89df4b5504d6ae7 refs/pull/2979/head\n0040e51c698385f0ce74c82bfe208d34eb74decd29bf refs/pull/298/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2980/head\n0041fad161ee283b537b0c97e577ae6d89bd371961dc refs/pull/2981/head\n0041ae21d3d15dd77c67430504f7d17fd2477187b397 refs/pull/2982/head\n00414b0249f355d436b42005a3be066bb0422f08af08 refs/pull/2983/head\n00417f0a8fab9dc5d51e07afdc57382825219cd53ac3 refs/pull/2984/head\n0041e5e3efb0e0a28772c2c31ecf3de5a04da09065df refs/pull/2986/head\n004126c0e0a21de2a2c3fc6dcb207347339e6ec3f18a refs/pull/2987/head\n0041c5d867b4caa4836692808d29b74a150d0f7c15b3 refs/pull/2988/head\n004130db1124016097a4d5f1736deb00c48b77410a24 refs/pull/2989/head\n0040eb68f82a1c3356d0ff11637395078512c96697e8 refs/pull/299/head\n004119a07de57a21994b6f1478a8d2410517ad829e1f refs/pull/2990/head\n004167f77272c080407d5a2e01de41af55b59d15d782 refs/pull/2991/head\n0041e74866b5938790334db4a4cbd1e130abb4bb3593 refs/pull/2992/head\n0041a2295951389c702e7476fe9c229e72e44aefe222 refs/pull/2993/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/2994/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/2995/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/2996/head\n004189007174d4749c0b3343f199e57ae195ff29e6e0 refs/pull/2997/head\n00411645cf0d67d85a94839e05fff2ffc161595db433 refs/pull/2998/head\n0041c30e305ff7f5908e389912f53aa49ee5403e5da4 refs/pull/2999/head\n003ef0cdbde101164b659a1c59b6b400472820703130 refs/pull/3/head\n003f3ff993226b672f16415168f26e670785954c0c48 refs/pull/30/head\n00403ef1b3d7d647af747b2a9e03f17773dddf5f4db4 refs/pull/300/head\n004146c427606410f135353b204dd06affe01c89b7ad refs/pull/3000/head\n0041c6a6b896cf2869a9bfd0dc6b52efbe0e505b4391 refs/pull/3001/head\n00415cb1ddffb06ca75562c641d3f28a5df1a791d5db refs/pull/3003/head\n004168cb24921d8a037f8157f1a503da88d61aceada9 refs/pull/3007/head\n00418f1bdfebbee3aa1af953417f21e4253ba8ccfb74 refs/pull/3008/head\n004106f28780b388130601eee7ae3bc9d0b3d5940663 refs/pull/3009/head\n0040fea7633143d0293f5a61d8aaa49da07e048e6563 refs/pull/301/head\n0041cc697f8c8204edcfae938dd6caf10054f11a43b6 refs/pull/3010/head\n0041d2f0755b32b10522939c79b6e8b4bea541abfcde refs/pull/3011/head\n0041106ab5e40648e8387526abe3de1c8ba4b04e5ff3 refs/pull/3012/head\n00418856379bccf277f9c62464aa427fa0b2d6f67577 refs/pull/3013/head\n00412bdf7f948e06f331ef338ae7db1d57dbaab0e751 refs/pull/3014/head\n0041442efcf258b28b45d96e20a60affc5155c54bffb refs/pull/3015/head\n004113f325583ff8883686b27dc23bc608f9edf0376d refs/pull/3016/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3017/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3018/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3019/head\n004077abff46e64d91993f117bcde1ce703b89840763 refs/pull/302/head\n004191785546e68c04c40fb754c656227f5fa1c66438 refs/pull/3020/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3021/head\n0041354913c4dd35a4d63665f5b527cb599d5de135fb refs/pull/3022/head\n00419b1873f19a5d21f87641318295f02c13e50f07fd refs/pull/3023/head\n004185625d97bc9d4a09294d098f30425dc5c95ffc03 refs/pull/3024/head\n00410933c86891d7c6f5420e1c41d3b23e79b3744686 refs/pull/3025/head\n0041b47c661a24c4242b795822dd155bb69a2a3b1c82 refs/pull/3026/head\n0041f7e4eb57d8caf0663fe23bbfc9a5aaf9cc514655 refs/pull/3027/head\n004180eceaabfa2e1a4620c0512a85a7af6db45d583b refs/pull/3028/head\n0041c80da837eb9e1438e795105b35d4abf12d38a590 refs/pull/3029/head\n0040dc2df970334ca11c74290d169c70390a8eceaccf refs/pull/303/head\n0041a0860d3c5649616c707f5f0c977e17939245bd6a refs/pull/3030/head\n004113a552ea3fe1288a590f9b931d8371336f1d7b72 refs/pull/3031/head\n00410159e086cfb5918c03061a62d80e15297d6ed927 refs/pull/3032/head\n00415bd05ba9e5e58dcb91f001d1ad82b68d139b819f refs/pull/3033/head\n004158122c4877303b410a70eeb465bca368392413ea refs/pull/3034/head\n0041fbd288e1fdd18789d64716891d191eeddb6b190f refs/pull/3035/head\n004107fa0d7988e84f3b3a34ac3dac399ba193887524 refs/pull/3036/head\n004100cb652efbe3060aaeffa5c4f3a7d31e66a0c231 refs/pull/3037/head\n00412b6b3b940c64c5517b64a7c03bb529866a421e10 refs/pull/3038/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3039/head\n0040fade621a7f723174ec82fae918578b84229d858b refs/pull/304/head\n0041f961c3c635c28cac218d79b63e95e01e5d8b810a refs/pull/3040/head\n0041a0214ffea0a79b8e1405df69d708d2dcff505ca9 refs/pull/3041/head\n0041b00ae6ad393dc643ede45c53649e5302e1fe8e20 refs/pull/3042/head\n0041dd25cd187b995f3e81cd26d138c783f52d2ac74b refs/pull/3043/head\n004182de78c184dafbfade5f45c2af21a6c14369b0b9 refs/pull/3044/head\n0041bd501aa0621037cd9004b2702a1e76de442e5965 refs/pull/3047/head\n00409d95fbb972ce3b32fa23eb739dfbd269aad20f3d refs/pull/305/head\n0041e882cd65728241b20bb5017316c286dfcb00dfa9 refs/pull/3050/head\n0041914aac4b7d550541f1b9cbfc7fd9374bb5feb497 refs/pull/3053/head\n004108f216bd6e902609d9aa84f30a50bc6c3bdc3c06 refs/pull/3057/head\n00417286d58bb1c5582b1add8d32d1696d6c8947d093 refs/pull/3058/head\n004132f4c488f7dffa308f82df5827a165e400a5c0c7 refs/pull/3059/head\n0041a5db19432ad9c33ea0d970dbdcd1d431b0e766c3 refs/pull/3060/head\n0041177357fc096b77dba00e31d85d3d3f31e96fe49e refs/pull/3062/head\n0041ab5adc598eaa84daa237eddff158db70bce13f78 refs/pull/3064/head\n00417df290ce8f2f3cf36a6058b7ee72350973fe8f83 refs/pull/3065/head\n00413549c650ccc399f36264c7b1276eb1254f33fa98 refs/pull/3066/head\n00419e4e3ab71e51de615b75393c67b741f316e9e752 refs/pull/3067/head\n0041fa1a05258fcedbc38ad9456165ff83c1cb8f97d4 refs/pull/3068/head\n0041397c82d0de51dd9ad7be2caf64c90bdccffa2023 refs/pull/3069/head\n0040f25a65409dfa4ea967d1b1a7d134da5013287dbc refs/pull/307/head\n004150bac02853af6b495043453ef4c7a50e2931fd64 refs/pull/3070/head\n004109feb895a36ac0927a24e94c297ed03f79b899fa refs/pull/3071/head\n0041ac0931b70d8680b25d430009007e1d9f0970a082 refs/pull/3072/head\n0041d0e784b90d1f359fee5ee6bf20689d6858d3161f refs/pull/3073/head\n0041807a02caee95fba47c7818bdd81030a60ca6ac20 refs/pull/3074/head\n004164711b7a7947fe8f441cbf6bd04b82da41128ff2 refs/pull/3075/head\n004158dd885ff2de27511b331c3bb7e892fc67998935 refs/pull/3076/head\n0041a2be44c11ec47085ef054600604ff8757f91f002 refs/pull/3077/head\n00414bc4dc9bb7cd85b5665f08454664843921f196fb refs/pull/3078/head\n0041ea8f0f79cb8433d5456fd82b8c7599ff82cac75b refs/pull/3079/head\n004073411ce4dd3994d9dfe6597388de7781b803e056 refs/pull/308/head\n00413805c23b7f29a1ec1710359c4f1d1e6df31c7ba2 refs/pull/3080/head\n0041925ca8a475d5650662ce8908458863e6b658d6b4 refs/pull/3081/head\n004100c3478e13944f99a154dca4ef7aa289f97fdc19 refs/pull/3083/head\n004158fa551ee7d146fd25770ed5734553f664912794 refs/pull/3084/head\n0041dd4a9fba9528b3cf0f22103d590ae6804ac8ad4e refs/pull/3085/head\n0041c1a75222f07f11b881558cb5ae85db705a13afa6 refs/pull/3088/head\n0041fc3357d173e441a822781fc46288b787cddf8dee refs/pull/3089/head\n0040e3e35a898a1e3a1106095f4094c748e635c54e5c refs/pull/309/head\n004101d7427d06d0aa5aa4795321ce1d9a796a8f72e9 refs/pull/3090/head\n0041f2a910f11286b1fc1781afd9e31eead170e172bd refs/pull/3091/head\n00415c0f8bf021cb2768cbcf264a04229a02cb562e6f refs/pull/3092/head\n004133dd2316429de872f26aa1a3f70db605e636489b refs/pull/3093/head\n00414a943449ddac590474233c569576074bbd67a59e refs/pull/3094/head\n00410cc43c1500774d5ae34950adc14a86a1a50a949a refs/pull/3095/head\n0041222ea10609bc06a812aba8463bc3cbf52d509285 refs/pull/3096/head\n0041c9149607f53d653b6d6869d66d202f915c2082e7 refs/pull/3099/head\n003f03d5ede47071e352bd5c48c69b4156324c71a038 refs/pull/31/head\n00401769ea723a9fb250a7118164ab2effb91e1c3461 refs/pull/310/head\n0041b78711a5ee79bbd7998de91aad6dc1295e22f62e refs/pull/3100/head\n0041ecf58a0c6459d9f245525ab2c253af0a9b6a83ce refs/pull/3101/head\n00412e4e4d113a2fd913d7d304985cf9ccb8b576c766 refs/pull/3102/head\n00418e86f1ef7b8cb02e3ea4a1cccd25144efb99048d refs/pull/3103/head\n00414fc6b776cdf924caf51e2e953108fac00ccf42b6 refs/pull/3104/head\n0041c6a1fbe65b831bf87b3246b1175bf02b2f810bc9 refs/pull/3105/head\n0041630dfc9cc184569e9ebdb67f290c75dae6f9603b refs/pull/3106/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3107/head\n0041f6d4c8fceab5b87f3fef22019f55339a73beb04f refs/pull/3108/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3109/head\n004017d50a8045e6ab6452e1da82f9c2ee2895bcf12c refs/pull/311/head\n0041bf09b2abf49a4f3e2e6602bcaa946962a18047f7 refs/pull/3110/head\n0041c1e468882a3f011e83172b67f225f99315494009 refs/pull/3111/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3112/head\n00415473e50a8182ce99947ff83ce1de10ee3c333fdf refs/pull/3113/head\n0041e103a9d6731021989cbf6d7eb67a196ce58e3837 refs/pull/3114/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3115/head\n0041e564df2a7bd69ce2cb4ac1b501944286e8071b2c refs/pull/3116/head\n00417694475144ef82b5ceca67d9dea29b9b0e2c616b refs/pull/3117/head\n0041782321d204ce8b7a44192878b95272398387cd44 refs/pull/3118/head\n0040188650c8960ee4afdfbc466178bf680e360e74a0 refs/pull/312/head\n00411af0d27a4fe1110f3e723c502227cadeba76d7e9 refs/pull/3120/head\n0041c5f312da17dfa2ef648c188947d0e802b0a0bc5e refs/pull/3121/head\n004170e933c33ad5df01e4cfd13c1f1d638afbfcef60 refs/pull/3122/head\n004123b294193aff6eb042da70f98f0d82fc7ab15f96 refs/pull/3123/head\n00411a8f3cff55c5ef37d9259044a32169b4b2bae1bd refs/pull/3124/head\n0041fcdb11e4df6ea8c0689e5da738599987ccec55b4 refs/pull/3127/head\n00411caa240d65c4dc07de4e1f0260b5aac50aade9f4 refs/pull/3128/head\n00414c34c0b48625de98d87cecd1df9dd2c780d172cf refs/pull/3129/head\n004022094a80c98a2a8e1eed141c4424a82681dcc2ba refs/pull/313/head\n004125119e4da3eb317aa14f22d36e5405bf47801726 refs/pull/3130/head\n0041039259cd1ef4ea16e732e740ff1c4a6938c58964 refs/pull/3131/head\n004129827b90d5480cccbb712488380c646ee008ee21 refs/pull/3132/head\n0041735625e4573dd5b8fe1988f67397308e08f0822f refs/pull/3133/head\n0041527572a2cea9f0e08f0334e74b30db2c741efe12 refs/pull/3134/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3135/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3136/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3137/head\n00413d1aa3e23a2146765bc94d0c9c1056005582eb3b refs/pull/3138/head\n004164f98fedba4b5a2d668dd3942d46d895b64a5713 refs/pull/3139/head\n0040d6aad74d8aca422749b3a63a359460431e624f2f refs/pull/314/head\n00417dd22afa840436ad016a08f9f2588dcf13b7b44e refs/pull/3140/head\n0041f3bc32e8b6482819431640f7ea46152581d804c0 refs/pull/3142/head\n00413f87112df4042dd8a06c27f1c25a14f803a61912 refs/pull/3143/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3144/head\n004157c03567f1b892b18e88bddf1e1166cacfcc123b refs/pull/3145/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3146/head\n0041cc10d5d9a90b7a999c9ed8218cae96f1381b71f4 refs/pull/3147/head\n0041c755c5203224f23cbb319b1749783af14f31537d refs/pull/3148/head\n0041b65f27f9e85fd6b0a16a499edd5ba5db3548d7ab refs/pull/3149/head\n00419ceeedd79a55533bbac0e9f6938ff6b1fd1c6114 refs/pull/3150/head\n0041bb1cb86a28fd776afe65757647eb41e2cd14d12b refs/pull/3151/head\n00416c93f87696ee00891b0146ea6f3be8dd53659a6a refs/pull/3152/head\n00413bd8359e38f1c5c33f590ca406dfc1bebc816cb9 refs/pull/3153/head\n0041cd8185fb4a44ed1280f3bcf571279fd40a45494e refs/pull/3154/head\n00411f3639f5dc1f19a3b130079d2aded178820bb80a refs/pull/3157/head\n004193743e8e7ca91fc3f0be3cf5ebd3ee4bb1a16772 refs/pull/3159/head\n00402a2b2599c2ebcf9032b67da26bc4d1816b6315d1 refs/pull/316/head\n0041d8db9e7af6d9b52bdf5b79edc8fe9e27ae7b67a2 refs/pull/3162/head\n00413860c5f8a5afe8107deaa7b6d3e75584441d70af refs/pull/3163/head\n0041a5e1d3c04d2c5df7e6a025c115a86cea71d320fd refs/pull/3164/head\n0041301b76f411c0f8a7245584224a593eb62dc38ead refs/pull/3167/head\n0041f1baa53e91449c83f5a9b39f57bb88ee791a9bb9 refs/pull/3169/head\n0040512f4a594dd01c11dffeb7f3a01f6ee2910e2446 refs/pull/317/head\n00411d75f8cca72cbc4656e4633a5da804d5b8e06e63 refs/pull/3170/head\n00410425c1abacd948dfd9f783f3bc7d1050698cfbab refs/pull/3171/head\n00418897b145798040832c08b182684dd7e9da8ea28f refs/pull/3172/head\n00413870193fe93ad63bb05d4bef5c49845cd2e8be97 refs/pull/3175/head\n004132fa682339d2e337e0a5dd822383329279a6e081 refs/pull/3176/head\n0041d974f9aa07335c498eb3b694024fca4143b15745 refs/pull/3177/head\n0041da97fddd86caf5f4211ff98fea9b79ea16ebb269 refs/pull/3178/head\n00413e5cf953d7d95a1032558f7592844646c1f23282 refs/pull/3179/head\n004115a638b3e5fa3f855c20160fda14eed496fd6a04 refs/pull/3180/head\n004168341b072a3d036eb97c9b82d247d885ac3d5592 refs/pull/3181/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3182/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3183/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3184/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3185/head\n0041c1cbe6c7da136974a98477bce101eefb7537f08d refs/pull/3186/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3187/head\n0041b0bcc9c9bdd03cdc12018ab04c3bc3189bcb9356 refs/pull/3188/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3189/head\n0041f7576fa840f9fb516a3b7cc04871c1cdbbfcb67b refs/pull/3190/head\n004138c5c17bba807d3cb7fc4172d1729858cac2653e refs/pull/3191/head\n0041caa52c27598fce1d44a2aed4776f509fe601ff50 refs/pull/3192/head\n00412771f72491c813726d134f78bb187d83f529bc87 refs/pull/3193/head\n0041cbb17a81efc093c3ce6889392e84c6692ac54528 refs/pull/3194/head\n0041881b2f0fcba03a8ead11b10a8448db8e9bd9b941 refs/pull/3196/head\n0041c5245cacd191db3a78975f42525953338a012e0d refs/pull/3197/head\n00417bc13b16667fc68a2ea49b2b0e2b6385fea8cfb5 refs/pull/3198/head\n0041e78ba918f91b4ec532200ee53f1da1659fa5019e refs/pull/3199/head\n003fd46883d4f6bd0de3fa54570e25592d65177a8099 refs/pull/32/head\n0040fcf3222be5f9d8cb2e4bc4789a8ed0ee7f8ecee9 refs/pull/320/head\n0041cfc7fd1e75225069ad5be39c99569b2cf3e5c1f6 refs/pull/3200/head\n0041b8fb33785570b28d9d0a64e1bc639538ad9cc050 refs/pull/3201/head\n004187cc5b2deda1e3a5fda04b5eac4790a056880df8 refs/pull/3202/head\n0041676388f4b2034b023016e2739abc4df86a5689e4 refs/pull/3203/head\n0041da4bd851cd5122ec79be4589066b448a692e51fd refs/pull/3205/head\n00410abfbb2eef7681534c04998e97874e955d576b02 refs/pull/3206/head\n004154e7db1008c998c907d4fa79bdb6efefe65f66c1 refs/pull/3207/head\n0041a8d34ae9a573564b7d0f766365af3de1871138a0 refs/pull/3208/head\n00411d546967bf9468228e4caf8f9918fc59637cea8d refs/pull/3209/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3210/head\n0041b2e2a887e2d9479c2dd947d1e586ee6281e35a91 refs/pull/3211/head\n00415db33ba706ebe24708bce88cc944539381844769 refs/pull/3212/head\n004172baa30011829d055ccd2986056f72b9990b6fca refs/pull/3213/head\n00419d911a7f8693b29932a3942670c062ae8377afae refs/pull/3214/head\n00413b1d05be07f9197636b681826210102f3a0f4879 refs/pull/3215/head\n0041002e7ba6aabb97cb4f3df23a244f3a93c379cca7 refs/pull/3216/head\n004185ac74eb0494b3196a9c2f60543d64663c4fb952 refs/pull/3217/head\n004196eed1631cc16f360b9b347779ef9599da0531fb refs/pull/3218/head\n0041d68f6f85e95df5e66154c9354efae427d1f1114b refs/pull/3219/head\n00406c285e160a26c4f006c041d13fd6aa15143b3efe refs/pull/322/head\n0041c67e9e47b64228bba5bede93b3bc8c902365e327 refs/pull/3220/head\n00417a0b72b6d3aa7ecfc94b6ca5c4e43683ad5c42c6 refs/pull/3221/head\n0041a724b82a564701bc4b95821a2f04d36257bf14ab refs/pull/3222/head\n0041f3cc09810b6210e0bdfb4f96c81de2aee8939dee refs/pull/3223/head\n0041feb0ad7c5e6e7b550b125dbfd844a6c62918bed7 refs/pull/3224/head\n0041737b75a44263778aa0254a283c6db7a481629b1f refs/pull/3225/head\n00412c3b82bf1d5e5b1f46506eccef43d273ccdeb563 refs/pull/3226/head\n00410df532eda1cabd74d7117ed65ba361bf85e9d263 refs/pull/3227/head\n0041436a2e9f9931e797729ec45b13edbb507682526d refs/pull/3228/head\n0041fef018091ec9da5147c7da86c75a4d1af44e21c5 refs/pull/3229/head\n0040d0db8c21ce1b0544a59d3b7b5cbd6aa8bd34a46b refs/pull/323/head\n004171410a54a301ff26d732e7ad4bb4ddff8e564f65 refs/pull/3230/head\n004111775b9a66c24572472b9bf58a7471441cf90482 refs/pull/3231/head\n0041c61acf8038b754fa81c6d0376ff29ea861d91b3d refs/pull/3232/head\n00418b5f88169a1a3476b6eeff3eda03c7f9ec66c17b refs/pull/3233/head\n00414a5591f70bb35c6553d449e7d835881a7e623eb1 refs/pull/3234/head\n0041e5129f9f372b0f28a1071cbd8de573ddee40dbc4 refs/pull/3235/head\n0041af460dd7e6b20eff0011b9eab1f60be9c8355e02 refs/pull/3236/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3237/head\n00416ec64a705e1ea95bf760714bc867be48ee1db93a refs/pull/3238/head\n0041ad6fcfae08211757c8b36d14fdacfe54131f9bcb refs/pull/3239/head\n00403dfa0a0b07889e25c08af41775e6c8edaa3df783 refs/pull/324/head\n0041d27aa3dd1a6c7e66c35ea28acf12819be3cb8d30 refs/pull/3240/head\n00410883a7dfc9425531c544cfa19d8bf7aef21679ad refs/pull/3241/head\n0041f09b7a2d5f0b6cf75d93c73dcc0623ccdd11081d refs/pull/3242/head\n0041cb5ec97318f4e2e71218c8092e796601615660e6 refs/pull/3243/head\n0041c0ab597150b894af31fa84b1ef95135b4dc4387f refs/pull/3244/head\n004134c9f03e1f35d94f37be30c1d551a4721eca6639 refs/pull/3246/head\n0041625bbb79540f688d991c9c17cdc61edcf326d238 refs/pull/3247/head\n00419b4db2f8ffd00b1ce51475978c989d65c4ebbdf4 refs/pull/3248/head\n0041cfc81ae68582be96f901b432b88c715885adf462 refs/pull/3249/head\n00400138593116226511e9fdcfd6eac0830600bc74c9 refs/pull/325/head\n004190ebcbd10d637bc1c41b31ac0b1395f3b18817dc refs/pull/3250/head\n004177dc069ce11a0f4613631b8cac4c0e08287f63db refs/pull/3251/head\n0041be5df1340fe1e722ed96bc1c8d2143f8aa72037f refs/pull/3252/head\n00414d9b3d231594bb3a12d149e0acfe9d052fff0457 refs/pull/3253/head\n00411baf5b1f4e6199d36fd7b6c59d58c638c94227e6 refs/pull/3254/head\n0041dd784206b936de3fb626f985a3c2b913ce4206f4 refs/pull/3255/head\n00412fe04363a8e5ef40c220a24c394c32d14adc57b7 refs/pull/3256/head\n00414def6adce8d6e0dfea61f97f2d2ef30c9519c0f5 refs/pull/3257/head\n0041e78313ca42db27b5c006f09b0f0759b85ea8e24b refs/pull/3258/head\n00411486fe15bcc610f171233cc9583d391588e29ca4 refs/pull/3259/head\n00402a83855d83f6b56f76e63113ed2cc5a82ff7fe15 refs/pull/326/head\n0041cc6198702dc46b2be7751a57aa99b04a574814c2 refs/pull/3260/head\n004112c052a038893bc0929e123f0374241fde5cfea1 refs/pull/3261/head\n0041fa7b9e1dad8947edbe6d4454ea2e75c4e91fe775 refs/pull/3262/head\n0041f2ec4d1c728596f42f5a4df1c482752049b418e3 refs/pull/3264/head\n0041ec50b949ac70d8cc72d648af3d2d6393ad95c3c5 refs/pull/3265/head\n00419aa3fba23fb804cde1e65a1b45fd9f319b3977bc refs/pull/3266/head\n0041eb0dd3c5254fd3880fde0e229659f83907b69ae5 refs/pull/3267/head\n0041738ea0ba90d957d0db64b31048ef6f568cfdd387 refs/pull/3268/head\n00417fc5c0a44b0a2594a637765e3b6439f42c875cf2 refs/pull/3269/head\n004042df6533086ebd31dc513f98362ae1b5d227f9f9 refs/pull/327/head\n004126c131d22b50920b39747af79b6479584caf72f5 refs/pull/3270/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3271/head\n0041678fdd47a634f2c65477b9d8db3919cbd6d8baf5 refs/pull/3272/head\n00416ae5d89cd751708da6774342451710b2102f123f refs/pull/3273/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3274/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3275/head\n0041ef5dac2e2660257c90bfb99b1666624ca783288c refs/pull/3276/head\n004100c1ea1992b1272e41648c5d3ffd46d7f078857b refs/pull/3277/head\n00416dd49087b012e7be82fd3c8722976418cbfabe3a refs/pull/3278/head\n0041305e49c61c765c2814662251e615f96c5bcafbf2 refs/pull/3279/head\n0040bc268eb837250fcb91b113b00f86e0546948b971 refs/pull/328/head\n0041f6897c6fb08e2323e3638b86f7f2453ef7dbdc6b refs/pull/3280/head\n004174f122d6052b7b032e69fe9e37247805b2f1f98b refs/pull/3282/head\n0041308704455f5588ff6c780473875a8636a4e7c7a4 refs/pull/3283/head\n00415e0b2423a0b63fd975d40b255dba2a3ee4804d81 refs/pull/3284/head\n0041fd5e607cb9690a658a89fa4554af258e87ccc38e refs/pull/3285/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3286/head\n0041fb862020d928db7bc4e7c80542154ac4671adf14 refs/pull/3287/head\n0041322281e6bd1250f3980ccfa556c778ed8cce035f refs/pull/3288/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3289/head\n00409a48ac5465f8ac146f2f3838751b9ff39813568c refs/pull/329/head\n0041f55b3c2813d66deec0ec55823a1020061468476f refs/pull/3290/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3291/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3292/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3293/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3294/head\n004119cb466c0cecb33148aa4eb85570bbd896f0c561 refs/pull/3295/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3296/head\n00411b4ea72e09c0bdb92268c7c75c83b686f947b44a refs/pull/3297/head\n0041fad80248eead0ece21b65c060b7e2848943a5e83 refs/pull/3298/head\n0041d4f0d0ee18cd3a3096a60fd4d43b2336d54bf9c2 refs/pull/3299/head\n00403319fb852d36a0ab98729c8024b8abb8ad08f9be refs/pull/330/head\n00410887c622c076680ee77b94c85c56adbbc439b4e7 refs/pull/3300/head\n004163ba7a9e5a1fd4edfa3b19ac9126eab8279851a2 refs/pull/3301/head\n0041c1fb24440a335ef5d06026d52d9e32b23fc453a6 refs/pull/3302/head\n0041cc6a9946247228c4cee1c08702170f3bf5975846 refs/pull/3303/head\n004140ba224a80e301b396de4aad5b60ab053c149940 refs/pull/3306/head\n00414be1679a9401902c1c6983b95f9b8e439d4a34a8 refs/pull/3307/head\n0041531550e76261d5d68bcbbd14b137e1e10d638c9f refs/pull/3308/head\n0041b60a9a4a1368a55a089161ba073516dde4badc5f refs/pull/3309/head\n004052d3516888f1fde9300fd46ef43c0d35fbdc94f8 refs/pull/331/head\n00415ab57c181a2ff7e50bd569c25829b195d2d11298 refs/pull/3310/head\n004157f3141854c7612cd83ec2b67240b1f669310091 refs/pull/3312/head\n0041230e26b3580c46d5ff761f3172eaccca329d1464 refs/pull/3313/head\n0041a3509d4d1770f70757f11e3c8630b8be58c70024 refs/pull/3314/head\n004129dfbdbdce446cb5a85436f7acbd60d72109dba0 refs/pull/3315/head\n0041b17b1537a266a62983c1217c2bb300a3a6ff021b refs/pull/3316/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3317/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3318/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3319/head\n0040f70db31210bb0973824c06b471a699710c676157 refs/pull/332/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3320/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3321/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3322/head\n00418205513daa4f12037a9e8173e35e1d4ad7a05653 refs/pull/3323/head\n0041b34f6c1b69b1b43d8ad39d084c1cd4fdb61a237a refs/pull/3324/head\n0041e27fa0a3451e233334432f70f0862c58bec109ec refs/pull/3325/head\n004182ce5375e0fbdbdaf6dc82753c3c539ac19d2b38 refs/pull/3326/head\n00415be6dc574b3ae8dc190997146b02668e88eb53e9 refs/pull/3328/head\n00419fb7c07ed5c0aa172fe959e1045400ef89943394 refs/pull/3329/head\n00403e3f7cd474fcd238df1e8a1d85d67a1ab0a52684 refs/pull/333/head\n00410ee8e72bb1e9daf79c6423250853894c8ec3a3e8 refs/pull/3332/head\n00415d04ae469c2c8671d527f9953c4c3e3f1b1db4b9 refs/pull/3333/head\n0041b64830c986d329f3229a4092dc7c7c57d1c22b10 refs/pull/3334/head\n004116faa736187a33564513a188a23ac8ffd0642341 refs/pull/3335/head\n0041ce073adbe1be0dbd75fa58909fd3fb111384a4e9 refs/pull/3336/head\n0041cf319993a884a7bf8e66558fc3ce6ca982c0155f refs/pull/3337/head\n004153ac1ad640d8326fa9a4ec49eafc4041219f1353 refs/pull/3338/head\n00414c6855aea01260b52d23e8d8ca1a80d035bb2e55 refs/pull/3339/head\n00401876aad84e6175712758ce6d3db16d7b16ed4eb2 refs/pull/334/head\n00413fae4999440349248a9bbc3ac1bf74e44b57f9b5 refs/pull/3340/head\n00415e85806267d289f9fe273bd9174c20c8d1585937 refs/pull/3341/head\n0041e70c7e5889dd075ade519a881381753c949c4d56 refs/pull/3342/head\n0041ed806bb842cb80f662b27b167653b0d4d463d79e refs/pull/3343/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3344/head\n0041e8baef2938dc547bc29b1629d8026c54f4400a36 refs/pull/3345/head\n0041da1202cebc3b5e248ef67e030e6ab86c458c15c9 refs/pull/3346/head\n004102068f861a1ecb6465e26d91a41e48db32f4f074 refs/pull/3349/head\n0040ffe7d673a10f32d59f1cbb96cbe7465c7b5dfe7d refs/pull/335/head\n0041d3c6c60331c3a2acaccbf200e13784b08786b731 refs/pull/3351/head\n0041100704081c253ff7dcfd7b2757f482d3c70c72be refs/pull/3352/head\n0041e5779f2d437ac22e3e52ead7cdb581ebbaf7545e refs/pull/3354/head\n004163330e4e304834f693186981a5320bfe33f6739b refs/pull/3356/head\n00413a25e5b19cc279ce63271224009a48df52f652d1 refs/pull/3358/head\n0041e26969b39d4e86f7ad3fdf337c5bcb79781d855c refs/pull/3359/head\n0040d2e8a62db572f1e557b85563c10e6468397124e1 refs/pull/336/head\n004145846bcef976b27a6c735ded57520b949143cdbc refs/pull/3360/head\n00410e404bb88ae07b8c0bf36a824ad77e49cd79686d refs/pull/3361/head\n00413592d6a7330432e0eb681ff7f30afe267a4f890e refs/pull/3362/head\n0041329aa16ea10c1bb6841a74f2cb7b7977e3ce3dc0 refs/pull/3363/head\n0041537fc5544be92798c1e691bd7c47b2ae5f49e56e refs/pull/3364/head\n0041fbdd56ed156b1e0fc2b12bc9656575ea63b1c826 refs/pull/3366/head\n0041290d0c8d317e2360ac229e70904433c3a3b62e55 refs/pull/3367/head\n00411e9702f14c9d0ddec4d3fe5dcd39bcacf995ead3 refs/pull/3368/head\n004158dd084bec475b82ca7de636ded933e5f26cd0c7 refs/pull/3369/head\n004001277a6291d8d62f4c8fc93e0bd9781987134261 refs/pull/337/head\n00414713dc20935765b3e4235da556ac6417a94b662b refs/pull/3370/head\n00414fc268c46bf699c0a5712870d826499deeed5e38 refs/pull/3371/head\n0041b339ba208c34d4b2ad57e1c22de799c5e6a3746c refs/pull/3372/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3373/head\n0041cb34e3ba48b46fe73b811c05592ce59d5dabf829 refs/pull/3374/head\n00416bbdc88faff9256f7f674f46502c4c4a133f5574 refs/pull/3375/head\n00411f72669b91743bfbfead637ce673ce0c3fa66bb2 refs/pull/3376/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3377/head\n0041e655de4832d64523a52312fd3c011b20c72be07c refs/pull/3378/head\n0041f1097bd38cdc05ad8227ddd3437765c63cde96fa refs/pull/3379/head\n004052f9b1bf33426893d0bc0fdb1b80e02af46f2753 refs/pull/338/head\n0041c96e1f87f3149962b092855ff074173acb7249fd refs/pull/3380/head\n0041f927345a158fa12008caf386921fd97832ab9e2b refs/pull/3381/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3382/head\n00417d58425a9d987d51e44fd45ab6f80cf1891e1a34 refs/pull/3384/head\n004150c773d60e1fd6c361ada093264c327ea4460ee2 refs/pull/3386/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3387/head\n0041c4bb9ce16150550aa74c98e8bbb86f6bc20f0041 refs/pull/3388/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3389/head\n00402b3d0479f0eac553ca8005279c7a6a23a8591853 refs/pull/339/head\n0041ed19906a0de53afca8303ab7610c890f9cdf357a refs/pull/3390/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3391/head\n0041f5640385ee6e8caeb0c743e2adfa6cac33850f79 refs/pull/3392/head\n0041d4217e327b35257c89261a25e3dc237f608bec87 refs/pull/3393/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3394/head\n0041e5fcdc6f1692e4c2c746bc12fd1222f88b0144d2 refs/pull/3395/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3396/head\n00415d08b9c9306f10bd548b1c1adfaa182a3ff91ef0 refs/pull/3399/head\n003f23cc473894a09cc2c4051db85fd3a42e4eac77fe refs/pull/34/head\n0040d6c78da57ab21135f81cb5a2b6656dd9309c327a refs/pull/340/head\n00413fde29aad92d9e308929583d45ad89d0d113c5e4 refs/pull/3401/head\n0041da781cab9cd31cb88ba88bc42fc81f3259d8b20a refs/pull/3402/head\n0041d4a3e93868dd08f590b554d696c8887e45c5f3c9 refs/pull/3403/head\n0041728e7e4ce79ebeed7f96d7738e87edb2978c7b03 refs/pull/3404/head\n0041f4c90854fc692525def222597608a2cc2fdc24f1 refs/pull/3405/head\n0041c021ffa6e9a963843d4ba8509124bfbe0d3dfc66 refs/pull/3406/head\n0041eaf6dd8b3583effa6d2fde0ccb5bd73f07dbb2c7 refs/pull/3407/head\n00411f3bb435119dd7e20a349f90c3cf5371f13eff81 refs/pull/3408/head\n0041c5dfebff2ddc88c77afdb313ee4dee0dd8e7fdbf refs/pull/3409/head\n00401afb1ca14319673e1ea619cefe2f4490ad21ac2e refs/pull/341/head\n0041a1c88027f88d7f51cf8baafe0caaf25c09eef276 refs/pull/3410/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3411/head\n00417dc1541fd2cb62ac88db7030fc7643c8f858dce6 refs/pull/3412/head\n00417a16e914b714fa6d4d121dc06d1ccf03cebbdf35 refs/pull/3413/head\n0041e5d49e3fa3a9a948e0ad1f1b86d0c9e188f74020 refs/pull/3414/head\n00417a137aa20b74a2e74ebe4d88d4c3ff06e366245c refs/pull/3415/head\n00412dcd8bb1efb80b4c7ae9087b304847addde347d3 refs/pull/3416/head\n00419d4287fb3ce00b76e352720ff79f96e9b52b0708 refs/pull/3417/head\n0041bcd17fd0a8bd707f36948c48aa7c9103c04fb9ab refs/pull/3418/head\n0041a49ee397c390dd0882b887c23e12e233bc6cc7cc refs/pull/3419/head\n0040019042773f8f8bfaf2fb18422f6e01caac79b615 refs/pull/342/head\n004141bd9e9857fa71d63de0692007c6ca2255b3aabf refs/pull/3421/head\n0041871f3556ce532a963d5a86f8fd0b232adc25dae0 refs/pull/3422/head\n0041e4505bd80502cad6ba66aafd519606f9472196e0 refs/pull/3423/head\n0041cce01256cfbf0f3f395b8d96d484494197196d5d refs/pull/3424/head\n0041dcc3c7ccbf0a1fbb9817a198b4cdc9d62b09168d refs/pull/3425/head\n0041caa0afee00abbc05076d0f52783b7a34310f6f12 refs/pull/3427/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3428/head\n004147185c267aaf4a9e35a4b3fe6f81e5cade4dc936 refs/pull/3429/head\n004083dd27f424abf0abba6a8264fa6924a41c15ec49 refs/pull/343/head\n00417a83a2b622d023fe05a727df97a4b527dbff8eca refs/pull/3430/head\n0041a7701505c0a51e6de0f4c78c1a02f663a727fe28 refs/pull/3432/head\n0041981b8c04c17f2a63d951df37194bdf4817177e6e refs/pull/3433/head\n0041d4390a458767271df36f6ab90c99af6e363268c4 refs/pull/3434/head\n0041bc032d76b0adff18fed5e058e1eef6de3c82286a refs/pull/3435/head\n0041ae608171cee97acbc163c19693951a231a2d4e06 refs/pull/3436/head\n00414e9f15e375eb118fbc7456f1ce75b7fdea960384 refs/pull/3437/head\n0041e79e37c87d28e153d552dfbc93f73111d0a18bc9 refs/pull/3438/head\n0041923f59093eced8ddc607c93353be0014ee88a6ff refs/pull/3439/head\n0040c3ccd3c6e811b6d15026b5cf1853a2f663001a60 refs/pull/344/head\n0041598407dc758dc60d193726d7db5399c4719fd952 refs/pull/3440/head\n00413741e5c083341432c3899d00d93ef84cf7f469de refs/pull/3441/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3442/head\n004154ef244af43a6711eb694021cb81efd25862a095 refs/pull/3443/head\n00417734f6dd3b776a0698e7b32256ca39f57d3078c1 refs/pull/3444/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3445/head\n00416627b1e2424961a3a38ba09e56f1887d7e5b993a refs/pull/3446/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3447/head\n00417f6aa8bf0de045b86129d4228ddfc99bd290af7f refs/pull/3448/head\n004175ebcd5084088481a531a5fa2cb4c0f8c4399942 refs/pull/3449/head\n004004d296631f37bc5d0e2c626fbd73f96427fdb0be refs/pull/345/head\n00416614652415913dd558a7f5e1760f6adac91058d1 refs/pull/3450/head\n0041a30243991efe7657d72e09cdefa0bca512a26a4b refs/pull/3455/head\n0041d613d3081e40ff0a2605553d6df587ed7750f26b refs/pull/3456/head\n00419202976cb63fe40fc20514a9c33f47096cbf4009 refs/pull/3457/head\n0041e1ec445951d86ecc1e953de48d0fbd89c35c351f refs/pull/3458/head\n0040987aa1508bf8d1de2f3dcf2fd010d87e126bb8db refs/pull/346/head\n0041abea6c5f85068528fa575eb4eb756b2ac0e8e92a refs/pull/3461/head\n0041e463b25713c5ada97bc7c09bbc644d8eb35926e9 refs/pull/3462/head\n00418f517991d1cb5e0b703a99e9f5f0356e96fd2b68 refs/pull/3464/head\n0041b341b5aa46fe4c33d29588397dd1bdee9d463b46 refs/pull/3465/head\n0041f44bd5c565c936007b9b937f27db82baedd64b9b refs/pull/3466/head\n004126fcc9f16b76b0925319f6554c6a6aef3b956cfd refs/pull/3467/head\n0041ad902ce2ae444857ba5af2a0575b4023e8694b64 refs/pull/3468/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3469/head\n00405450274ef3e558455c66ada108a0452e4843fdfc refs/pull/347/head\n00417c267cb058520f9d80c081ad44a4ce2864cd7019 refs/pull/3470/head\n00417b2fe16362dd063b59fac2c40d3f28948fbada9f refs/pull/3471/head\n004165252dfc054e98eadf8764745dfc034de989d49e refs/pull/3472/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3473/head\n0041d21b6c6d4cd443bf1d660647fb71f90fcb2ca19e refs/pull/3474/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3475/head\n0041cf1931c7276150ed36a4d8e11fd219a5cdc7b181 refs/pull/3476/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3477/head\n0041fc9be78fa0069be51b4cdc434bb06a02cc9a00ca refs/pull/3479/head\n0040bc92b86da455b69be1bd3916273645b337674ca2 refs/pull/348/head\n004138adfc481554517cb4adc7b370e3c231c33132eb refs/pull/3480/head\n004167cc7e37a710e3ea05a75374a506c04c87a89a34 refs/pull/3481/head\n0041603dcca4481fb9e1778f6e81ad048ae73320e30c refs/pull/3482/head\n00413e4197bb97686b43986c05d2e58481bf6280cff9 refs/pull/3483/head\n0041d5715a6a3be4943c0f09eeed95477e21546cf37c refs/pull/3484/head\n00412fc3db5c428f3c2ed1f1d53a6d32eb310ea7a469 refs/pull/3485/head\n0041eb8f7da07c8988a4685f699bc3ad3079b6e5fee6 refs/pull/3486/head\n0041f115d5d4d4655a1f132ea5b50dd2606e8698f8cf refs/pull/3487/head\n004152c3e0913ea564c9528adcd2e5bfb4fa84ba8556 refs/pull/3488/head\n00418c3c4edcb7e294421aba9759fdb033faeb61a5a0 refs/pull/3489/head\n0040df9c85159194003ea1f55d088052eeb60746823e refs/pull/349/head\n0041662b7d2a0f214e1da0510968fdf458c93d225809 refs/pull/3491/head\n004131420ee602fe6de115e4cf32b4dea4d20c37ef92 refs/pull/3493/head\n0041dbf993097c75276c397af40c80a17ab0a85750bf refs/pull/3494/head\n0041b0b0db1b990ace1dcd6a0775fcfe8c03e1c2e98b refs/pull/3495/head\n00419cf8a2f26e3bbf477b68032e0969d08bed9cdcdb refs/pull/3496/head\n0041a886341b602a3cc8278121ab40882b39cd94eb5f refs/pull/3497/head\n00413c0b52d09cb1dc44632bf9009ca51e1409066af0 refs/pull/3499/head\n003f9a6fd6cac6cf82aa4dccfdce615dfecbc76dd28a refs/pull/35/head\n00400454bf6ec1c4e9422765b5f3fbaaffdf15176979 refs/pull/350/head\n00419a6ce09da4d08d9eb8f59f0440c3758234d19e51 refs/pull/3500/head\n0041c546db9b641c145360de3e14ac12d48dbbb6581a refs/pull/3501/head\n00412dc4cfb9803f2aa927953e33bc1f40c3dab44156 refs/pull/3502/head\n00413a11c7356b0077c7c73c2143c05384cea89fae31 refs/pull/3503/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3504/head\n0041c1314f4ba1c1debb107f88f65e8010673358345c refs/pull/3505/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3506/head\n00412cd8d95e39da15df6fdae1f93c1bdf630d9c0c16 refs/pull/3507/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3508/head\n00419a567192f4142f72d8c0c9c0dfca059c314218d9 refs/pull/3509/head\n00400c699e9bf5b682c91f3bc11a35edf88d6667fa02 refs/pull/351/head\n0041a5c7c58c9c454b44c22238ef04ee3d620487d3c0 refs/pull/3510/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3511/head\n00414100e0af9f9bb6b8326aaa8c56b8ca4217bb5671 refs/pull/3512/head\n00417d9e4c951de40d4d2f4ca5056942b16672711b54 refs/pull/3516/head\n004067eef7352339ed2507d2bac858c9812ac4e046a4 refs/pull/352/head\n004112d4ccf73cafb1c17904c65fc54926d4fc0d2667 refs/pull/3520/head\n0041facd4046a0d547318694a68d1998be9df873a9b8 refs/pull/3524/head\n0041347fc8d5550965e6fbddbe63fd2c6a6af006d694 refs/pull/3526/head\n0041558f36467459b7a7e59af1069dd04a95d628a024 refs/pull/3527/head\n0040cf0c8367e746b2a1ae1a42202ebf11694a5a604e refs/pull/353/head\n00415d50028a97df7729d9a73878bab12a732a4b5438 refs/pull/3531/head\n0041412a32512c3b2888af0d26d8ac77fbedba6b738c refs/pull/3532/head\n0041726d98b08d7796dac5bedd4b9d34202fb4164ae4 refs/pull/3533/head\n0041434abc547f8f844b62c9abea8636adf414ce99b7 refs/pull/3534/head\n00418ec89391bdd972f05bf74daea3bfc5938a8fb2a2 refs/pull/3535/head\n00412aaae4a493ffd4d0af0bb0969c1c876a630e7bdd refs/pull/3536/head\n004126ff86f1c04993f6c36bcfc92edbeee015e189fa refs/pull/3537/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3538/head\n0041c570896bf34f2c3c0fa8ce515715828d02aa52c6 refs/pull/3539/head\n0040d4e3672671d311513e0efa9afe6c323a661a1e03 refs/pull/354/head\n00416e226af76b90979f1512c1a12ed0a262e82f2cc6 refs/pull/3540/head\n00410230d614aea5f85d892fee98dc11ccb917837244 refs/pull/3541/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3542/head\n00411e9b862819e5a01ab7a65c5863c19adc0fbb06a6 refs/pull/3543/head\n0041535d8e0f999d37b0410574258f07fbf1a24d648e refs/pull/3544/head\n004196a3b49d5bbd0b7a6fa8e2b8a7febee215df2bb6 refs/pull/3545/head\n0041ba980971b276451472973c91d8a3599f06d2a790 refs/pull/3546/head\n00414e1501dade292549592c52d957e4fce0b164f5f7 refs/pull/3548/head\n004111556ddafbc6008583a1f421910dae8ad99c6c64 refs/pull/3549/head\n0040600ed28b6bf05e4800518d4299ba993a3de128d5 refs/pull/355/head\n0041fbf37fba1a9c93fa1cde4816d4c2e83de789764e refs/pull/3552/head\n004152880b04b157686ac203e6d1e05553c1554de526 refs/pull/3554/head\n0041a3ff783b82a73d9e590c130ee585935e3c47839c refs/pull/3556/head\n0041f8649f35c73ef8b68b8395b084419c74b1ec13d6 refs/pull/3558/head\n0041ddcd86bcc2937a1ed44480188e648d748253ff7d refs/pull/3559/head\n0040cf1cbc2950c195040601ce36ddb4314e94288711 refs/pull/356/head\n0041b4fe9a998fdb7e9682ea2a112d46b1f7fd1d83b7 refs/pull/3560/head\n004122ae49a865e503352cf40255938e94fc55ca1264 refs/pull/3561/head\n0041bbe3b6a7907f0377863a2d8f5d9c56225dd4b44f refs/pull/3562/head\n00411a9e9ab5f77adfee6997e35a99578456af18adff refs/pull/3563/head\n00419f411fd43ad96bcea3b00c2b6b09ba133ad970d6 refs/pull/3564/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3565/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3566/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3567/head\n004137c352279ece36826e0bf6cb7fe474144dbbd03d refs/pull/3568/head\n0041b01ff6cf71861f5b59b406b3b083a6a81cd5b05b refs/pull/3569/head\n004009a3d6def73568852ef4ae16bc83b5dc08bec29a refs/pull/357/head\n00412ef434da9cae143bbd52efd063c07c2365bee95a refs/pull/3570/head\n0041041b7702963bc077080c447a6b2156f5ad54761e refs/pull/3572/head\n0041f32b12df3a4a65424fe1d7656304bdc0d765d0ef refs/pull/3574/head\n0041e60e677527cd031f039fdd2d77859ae42d855f1f refs/pull/3575/head\n00412efaa9bc8c6e2a97f5bfbb231018d4c0f7d32c18 refs/pull/3576/head\n0041f91a700e72fa0ff87d505a5b0d742a32e2bfc666 refs/pull/3577/head\n0041e4969f8cbaef6577d8fdf43bb4cc80bce1dd7fb9 refs/pull/3578/head\n0041dbaa13a50bd43863dfaeaa1a2ba21528abb5d89f refs/pull/3579/head\n0040e933914511cafc5fdfb749ea7b07816fc675706c refs/pull/358/head\n0041aeece857dc9f9b33d18cd90c5c213dfaecb82698 refs/pull/3580/head\n0041e6d34f9b331c5297642565e4ec463d6a001da9f1 refs/pull/3581/head\n00415e1fa71582e8ba6d804ee07c82d1e635ad7a392e refs/pull/3583/head\n004165211f2f09f58fa9453af0005c7ed8d4e43bb67a refs/pull/3584/head\n0041d099eb9a6608a5d0d2aec966f32c467e68604c66 refs/pull/3585/head\n004134589f34e009247cb2eb2d249e57d78a59deaed6 refs/pull/3586/head\n004106a28e3bc4144959441b736e5bb62eacb1f817b1 refs/pull/3587/head\n0040b0d113e1de8d5dea0dad2ba0b112b7a6d7b749e8 refs/pull/359/head\n0041aa9e18358bf55c15e614ebb8ee2741a2f9996048 refs/pull/3590/head\n00414d8f4319eaf3a2634e5aab04ac0ccb706cac6f8a refs/pull/3591/head\n0041cb57473c8df0ff9684a1d88085273ccc71b32be0 refs/pull/3592/head\n0041ed2f8d86aeb2b877ad6e7c5d991a666540212ddf refs/pull/3593/head\n0041139c04ef65a5f7448c76b9ebc2020800570220d3 refs/pull/3594/head\n0041c1aacde188e95d078d945071c89474260f0864dd refs/pull/3595/head\n004116d1ab16fa4d100b903533361c6a34ceb5f4391e refs/pull/3596/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3597/head\n00411c4fe17a54b97737f3671ecaf56bb077f88b9239 refs/pull/3598/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3599/head\n003f33e3ad75825b38db5a4425df6d65e40410a5e9ca refs/pull/36/head\n0040e8f98b0a685b0579043ce7d7c161cf483b71f995 refs/pull/360/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3600/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3601/head\n004117c7f0f8ab0de4cfe8b087a4af2304b9ce86f62a refs/pull/3602/head\n00419a3e661220e2687b94bf99fa2eb63c0bbac26b2c refs/pull/3603/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3604/head\n00413439bbfaab349c59b0854a9cdcbfb23f46c9ed52 refs/pull/3605/head\n0041d540c1269b98ecede35df9fde66096ba1d9d3072 refs/pull/3606/head\n004133e45f96dcca0bf4978db082599db2a416eb0137 refs/pull/3607/head\n0041f3d15b6378921646c65c17c99bb9c4d5826cf5d8 refs/pull/3608/head\n00413fdf840caa2a15aa1b02ad63edbe37f14c25ad04 refs/pull/3609/head\n0040af341b4f22bbdac128322f76b48e07c31dfdca46 refs/pull/361/head\n00410d61d36d5457e56436939c609274a27d6a3d5939 refs/pull/3610/head\n0041c57018380ecb4a8c65a50a43146b1cd220d14140 refs/pull/3612/head\n0041cfed10e5cd77ce191ed85b3aa1879ffcf78ddedf refs/pull/3614/head\n00410e5894deb3711d7ae9d9e1efd62fb3fe718cb00a refs/pull/3615/head\n00416dcc20d5233ea2bdbf24637ab5a3d25e80bf6dcd refs/pull/3616/head\n00411fef6d381571733672f63d65bf555b9801186548 refs/pull/3617/head\n004182e4be020c85e0982b63537075ce4d44d0475dd6 refs/pull/3618/head\n0041356b68503584e33daed2cab24178a20c4d4cbf3a refs/pull/3619/head\n00406a801c7d85ede5c49881e53c45286e78dbf216bf refs/pull/362/head\n00410b26184e36cd97559ecefeffa099217136cf494f refs/pull/3620/head\n004164d1e66d5ad7e27d0fd38c49e0487e5b029b9639 refs/pull/3621/head\n0041758d6def407fe5258665f3b621081171459f9371 refs/pull/3622/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3623/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3624/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3625/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3626/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3627/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3628/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3629/head\n004064cf6dd540ef6a175e26345cde4fc09f98458764 refs/pull/363/head\n00410b3780de33f8385775e0cb2b24a45bbac5824b12 refs/pull/3630/head\n00415e7f9c92ccfed0ca84a87dc0fd1dd8bf962a81b8 refs/pull/3631/head\n00413766f886f09b0e05c216deec1fca932704faef3f refs/pull/3635/head\n0041020ded73f3db4649327aeda027020a2e37640356 refs/pull/3636/head\n0041378236c3105538906a4258009a87f9a14684f304 refs/pull/3637/head\n004135f6f9c3529b0a143bd93b9ee2d1e8258c2c066a refs/pull/3638/head\n0040cb0bde56c77838a7582b88c6d5e9150d2964e1d6 refs/pull/364/head\n0041cb9695fabc8adcaeb8c2abe4af71e0b916e053e7 refs/pull/3640/head\n004103fa215005ceb3bf5d0feea91a3968e90aa446bd refs/pull/3641/head\n00413f23a4b8dcbcdd6c1fbd8c2adb4a23a0a4ebdb2b refs/pull/3642/head\n0041607063a14d4aaadd1b5670e757b277110a979e97 refs/pull/3643/head\n0041570126ce462da1d39ccb24cac7ce605ff38ca3a9 refs/pull/3644/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3645/head\n00415c40e962442890be528486ba43387afcbd7e7715 refs/pull/3646/head\n004171de082cbe4e4217c78df91b74d2a22c99ecc6d7 refs/pull/3647/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3648/head\n00412726274765c4ed63c82e37a7d0589b5d3142befd refs/pull/3649/head\n00404b9a948506a09bcb0af3f4a7d34320fcc41cc23b refs/pull/365/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3650/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3651/head\n00416342cfdeb589742ed13452978cccf8e01a318f38 refs/pull/3652/head\n0041cd4ab0e55a184704b00276f26165570ff9ec1444 refs/pull/3653/head\n0041abf79a0cd8df5dd3696d268e9cd102047e1f17aa refs/pull/3654/head\n0041dd56685ca2a38e46298b6d0d2b80736d91d55733 refs/pull/3655/head\n00410ea8372305c0ffbe8c1b7461c480709b51584dcb refs/pull/3656/head\n00419ab03f8dcadf83eb43ddc1d53fcb6777afba2a23 refs/pull/3657/head\n004109a4a53bb0be24011dcecffcc786774e71a2438c refs/pull/3659/head\n00404ebe16b3e179d11c7345ab7e0b5ec7aa262ba9cf refs/pull/366/head\n00418ab8d6ce8416b09773a68b75c3417effe07e0e2b refs/pull/3660/head\n004150188606b6e0c69235544879d1949ceb6d2f7916 refs/pull/3663/head\n0041197e36d47a279ab508c1ca69df636bf0ab04a85c refs/pull/3664/head\n00418994e2c8916d64c554c0d1bd4fddfb3fa86e6037 refs/pull/3665/head\n004197da23582340f68c0e3c4a10331ef3f2dd1d3746 refs/pull/3667/head\n0041e725769a9d44441d3d3b97ea119b5ccc0ec13242 refs/pull/3669/head\n00400f88251f8707640498665ed86b3493288ea44b86 refs/pull/367/head\n0041b129a3fae3f0969918714b600439e83e0f20ad74 refs/pull/3670/head\n0041f9320da0df7f2bc55d6dbac11a195963042aca5e refs/pull/3672/head\n00413a22d2708c6f65fbbb7c396b34d0fb5744ce139a refs/pull/3673/head\n004122f50cd7fff2333b32434e33a4be35d016c8507b refs/pull/3676/head\n00412398aa1e760b6e19934397cf58f8317182a732f5 refs/pull/3677/head\n00413ce3d4adc1cf1cbc99e39de8af86157529b5c96c refs/pull/3678/head\n0041898f7603b40285901c4193006caf5a1a7f865a24 refs/pull/3679/head\n0040daec0467ba809add8287e6e561b207570dfdef9d refs/pull/368/head\n004126482c89d1eef651e3074870a21e691d3ee7d88f refs/pull/3680/head\n0041724e6ba210e3a3e558c8546a64a3b05b88dab32d refs/pull/3681/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3682/head\n0041ca808fc591679ef553b9c217a67b483486ef954d refs/pull/3683/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3684/head\n0041283a263182c61dee649166439f94b96820704646 refs/pull/3685/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3686/head\n004192d2564fd9ba300f6cbc8186d9948bef96bef29c refs/pull/3687/head\n0041ab3ffa1f942b62e296bf81d1e2f64b750204812f refs/pull/3688/head\n0041f102174f88e790da42947faa3b33b9fbac9c1ad7 refs/pull/3689/head\n00407e2c699fd73e14c445f1302ff24bed0a2556868c refs/pull/369/head\n0041698bffcf6b2e1ee981b74dc56598868c5f0d7690 refs/pull/3690/head\n0041841cf111e57718587a569e44acd3ecf89c2431ec refs/pull/3691/head\n00410af2a89e704fe8fc0c412d3e80c3161b6612c15e refs/pull/3692/head\n0041b86027ff3908261449d64b340f0562c36fb28c50 refs/pull/3693/head\n0041b68d03098b2cfb5be6f7171821194ae555c57dd6 refs/pull/3694/head\n0041bec32d612cfbebce1fcecab7ab2e2dc2bf2c7c83 refs/pull/3695/head\n0041fd0757a0397b6cb2f35aafa75777e02a2aba4b9f refs/pull/3696/head\n0041800efdc97f592673fb325a2e26d62ebdf9f74cbf refs/pull/3697/head\n003ff8f6f58700a542f06d0796bf7d26e6f39718d2d2 refs/pull/37/head\n00403c7cf0dd53c10c2fe43373d5d9e8e09ae9bd3038 refs/pull/370/head\n0041e1ec6f4b87f2c83cf0e569433e92a8b009628b99 refs/pull/3700/head\n0041f9f04b471d186f3269a369eca5ffdab734712eb8 refs/pull/3701/head\n00419597c2daf3838fc16fef732ecd9632e601a004c0 refs/pull/3702/head\n0041a54d68436594c8f418fe7be303d712fcbca76d6e refs/pull/3703/head\n0041814d0792d0046857c1b85ff003d923ce1a4cd761 refs/pull/3704/head\n00412dc6e2a77115edf0ca1f2c7ab2f49b078a5f1f92 refs/pull/3705/head\n004166588e57a6ea366b52febf704b1cc351733e4877 refs/pull/3706/head\n0041a36e364f26ce84a0e07e5bb332dfb6b5d8aaa15a refs/pull/3707/head\n0041620e4bf3d867ebcabdebf4162454d74b06606cd3 refs/pull/3708/head\n00417e8178e30d045e5c8124f618c7c00c08ae1bef3f refs/pull/3709/head\n0040ffcf21f54d8b285eb6aeda1824f3ce90d85fbb3b refs/pull/371/head\n0041fdbdaac9b6d0d67f4e6be5ff17d050dadd957b7e refs/pull/3710/head\n004130297ce4dc62464257ce8f09ba573b9c640a5231 refs/pull/3711/head\n004142a624e0a7acd08547e6ff56f4f7107813463f1b refs/pull/3712/head\n0041c6bb013d0ea2fdd57991b3a87f19ef9713cfa73d refs/pull/3713/head\n00411218898f514d73f9abfaaab3947d799700505a5b refs/pull/3714/head\n0041be76196e8a5c0e6bd0f72c96f193ef655ead9f71 refs/pull/3715/head\n004108fc364d0764d379a956cf1e43269fd97a66202d refs/pull/3716/head\n0041cca07dfb64d644e87ca2a5ed32f22b8a20d96d8e refs/pull/3717/head\n00413a9f1033e39c8f0005f0711a6b6d3e20bd2870bb refs/pull/3718/head\n0041479d99c266d278e38b4183b2b8b9b2ed0f915fc9 refs/pull/3719/head\n0040ad8ecd3b9bee94d51170382b695f0c778a497bfc refs/pull/372/head\n0041b50d321af176b7c7ff6f429cdb77ad6347705c92 refs/pull/3721/head\n00414eaebf897d134d4eb55906bd26a8a4fa485d45ad refs/pull/3723/head\n00417be13b4869c605fe75ce5bded034a1202116e181 refs/pull/3724/head\n0041a7d4cc11edbdc202607e20681e145ce817efd75b refs/pull/3725/head\n004157c67490141d8faa757dfe25def9470ae574c5d3 refs/pull/3727/head\n0041d1de8f55d10a6161e7c42302c02d8d5d2b32cbc6 refs/pull/3728/head\n0041a070a57f1e6fc95ed5d90f34caa3e1825e93b9ef refs/pull/3729/head\n0040a54c525503c36c4120616451e4083bc0214b4ee2 refs/pull/373/head\n0041427b1940b2eb7a5c4783ffa406ff222352ac352a refs/pull/3730/head\n0041876e71218100d13ec9523b1b69b6741bc19e2240 refs/pull/3731/head\n00412b7235d7fd906bb9205d56b04ff19a41e8e3f624 refs/pull/3732/head\n004126c49d4fdb759869ef05b834909a45235c1cbfb6 refs/pull/3733/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3734/head\n00419fb657062b28459e967e6aa9f71b8f5eb1d96613 refs/pull/3735/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3736/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3737/head\n00411042a986854b32d67c047bed251d244383c7f445 refs/pull/3738/head\n004156936b4e650d78b6d44ad24011e781acc50df49c refs/pull/3739/head\n00400c42f8686a7cbd215a8f24817d7de1355df77b1c refs/pull/374/head\n004134cba88931b0c0c9ececda69f6bd56f0ee6132da refs/pull/3740/head\n0041cbeb2bc56e40e89d5d7ed57e73442cb8bc08f033 refs/pull/3741/head\n0041be8f03fb6ff6b368a1b316fe49c2604d8048a878 refs/pull/3742/head\n0041ce0ffaafdcfb9f398fac96394c97f5829f8e64db refs/pull/3743/head\n0041a4de75be38efabd02ec21bb954dcf0d06c383974 refs/pull/3744/head\n004155cadb9f3ddb2181250be8240042556e2aa0accb refs/pull/3746/head\n0041a419f67ff567f18441090d5c27f9fc43f6a8f85e refs/pull/3747/head\n00404b20f8036316a58b61a3eea85afea53cb054bd66 refs/pull/375/head\n0041808af80abe8cb7ef26d5df2c5f14589079967775 refs/pull/3753/head\n00412a4d23c27ad4f3586be87b4b749997a1ecd1b722 refs/pull/3754/head\n0041bec788f16f4be311ac5a4fb1dca48b22020d23d5 refs/pull/3755/head\n0041ad0ddd181dee7c3c2cb1db63b403e7ce9463b411 refs/pull/3756/head\n0041bbc7ca771fb0476a6a4c09f08f90934ce416847b refs/pull/3757/head\n0041464de6c8e3d3b6a544e6a1dfffce2613cd53e4b9 refs/pull/3758/head\n00415b655fe17e896c43f2b28b027217dbd4ee0c7274 refs/pull/3759/head\n0040df92eca6a3262981465ab6e7c100e740a9a5a613 refs/pull/376/head\n004178e8dc574cdd5f9a11e78ebb241e70bde1f10276 refs/pull/3760/head\n004134f398b12b84f860e1078087b5833fb7c1d9f6c7 refs/pull/3761/head\n00419d380438b36d2f7a3eb5de2ddc2c2c19446bfcbc refs/pull/3762/head\n00419fb657062b28459e967e6aa9f71b8f5eb1d96613 refs/pull/3763/head\n00414acda946c99a73f909670a3d06a746c1b42ac611 refs/pull/3764/head\n00411042a986854b32d67c047bed251d244383c7f445 refs/pull/3765/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3766/head\n0041efe77a86820dd9207412b620fccaef9a716266c0 refs/pull/3767/head\n00415e884e371f05bd80acc4753bb64f826c9bf0c0eb refs/pull/3768/head\n00418daf095a835d28885c16f80f48ab29fabcf2a2d6 refs/pull/3769/head\n0040f5dc20b5d4e4fdf4699840a9bd90ccb6b51542d1 refs/pull/377/head\n0041c2c3b68c6af8ad24f45ce5f35fd3e668ef875c8a refs/pull/3770/head\n00414c283dcbba2a55d0566dfb0a749c0319d8ed5ab8 refs/pull/3771/head\n00418e02e2a9e26af982757ba77bff6f10a61f7b1014 refs/pull/3772/head\n00416e019a2b1169347fc8dad0186e207ac29b57d2ac refs/pull/3773/head\n0041b20cabba84eccb72f769c4da172b9275954bc48b refs/pull/3774/head\n0041b5c42bf8102749ba0f8c43170d11bb30ff19fa8b refs/pull/3775/head\n0041c071914470ae062055c25063050ac61fa77c78d9 refs/pull/3776/head\n0041367660326d80a888842f024118a744e07dbcbda7 refs/pull/3777/head\n0041ee216c0c3db6c068d6fcbcd24298ecdccc766157 refs/pull/3778/head\n0041a73b92f393b8273525970e8e20876b2e9bbafdc6 refs/pull/3779/head\n0040125473272cfe458154e9eb689d9263df394d3086 refs/pull/378/head\n0041276a8ef346cc1169411063ccca224af1d5f3d039 refs/pull/3781/head\n00415676afc7b4a082a7436b7933d2124b88714aa01e refs/pull/3782/head\n004106c4c8650ec6c8eaa6a2fe5956a0e50319b233bc refs/pull/3783/head\n00419dcb8720303c7b6abca6e90867e9c291e3848ba0 refs/pull/3784/head\n00419a31697635c011fd0551c068c403df15d53f8560 refs/pull/3785/head\n004178486fdd63d322cc138b4388a5ad8f266e4ba70c refs/pull/3788/head\n0041effb851f141dcf53f1a332fc3596613761b67c38 refs/pull/3789/head\n0040df8ab034cb5eaddea0415ae9953a6165ecc60549 refs/pull/379/head\n0041204f591530550e4dc88157b9fa3ca8070944cb24 refs/pull/3790/head\n0041c6d02d3781794b908ffc84d27b2f40af07122447 refs/pull/3791/head\n00416d9b9c54be33f1a46e375748b214745c59b0f875 refs/pull/3792/head\n004119350d09e9014b6bdfd955c857e76a9090041667 refs/pull/3793/head\n0041933b0606acdcbdc77e1148cf52b6983208d4cc9a refs/pull/3794/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3795/head\n0041e01dfe987e705ccbe116d3d752c0b1a241f5e760 refs/pull/3796/head\n00410c138fb8a7ec3426340896578d6a965f0e807ff3 refs/pull/3797/head\n0041701ac77c292eeea0e137b37b387a2fa8bc2f641a refs/pull/3798/head\n004142f2e2159fad8dba95888968c6db02124acb0e3f refs/pull/3799/head\n003fa72f79c5064d756b3b1883dda9744549657b333f refs/pull/38/head\n004105e8c4940436783b38d6366b8e953065ac834743 refs/pull/3800/head\n0041ee5a4107f7579d54a78b6361c376e03ac8bfba65 refs/pull/3801/head\n004195238ab119dc3f0e7f1257cc577c89ce7ff9b8b8 refs/pull/3802/head\n004188b849233ee8a636efb68bd65a58f36d29f59e79 refs/pull/3803/head\n0041a6cc50067eb9f7d1d4dd954e527aea508f96c4a9 refs/pull/3804/head\n0041c082e78b164f5823bda75a885301ebdc29a451b9 refs/pull/3805/head\n0041b7021ad3cdbc20907dfe421c86f5f5c991385757 refs/pull/3806/head\n0041061b4527d6bc79e7bf01db1058367b05fe277ab2 refs/pull/3808/head\n0041fb1b7370554c69d44b2ee316a501b460a42a44a8 refs/pull/3809/head\n0041e6e89dd4def50443728ba0425f6098a1e5deca1d refs/pull/3810/head\n004169bb4706258809d92805bcc8034afaab6f7e835e refs/pull/3811/head\n00416a9ed3f31e4927858ea4442ba03491109141a8d2 refs/pull/3813/head\n0041ab836a2f7d8439c87ff40604d8aec5ccaacea7ff refs/pull/3814/head\n0041a9194146c8609d6920361fc66d8ba210a777d65c refs/pull/3815/head\n0041811704ec2f3e4389e8606ece5164dffe32e2a6d3 refs/pull/3817/head\n004174f80ea6be12fe99689eea2472f3feb856fdf1fc refs/pull/3818/head\n0041500443a63b436a12be0e9e1e1c607364eff7f915 refs/pull/3819/head\n0041af64a7c4b96efb3dcaa6d1f5f752b68618453d4f refs/pull/3820/head\n0041d8aaec90e7842479f914b02f56c2711c3b8ff26c refs/pull/3821/head\n0041ca8b4f650897b7403854a651f7a1afeb065fc9e0 refs/pull/3822/head\n004155fb452b42fcd62fd74e662b60095268eae0b940 refs/pull/3823/head\n0041736e3be9329039344741aa74e15a58c318d640f7 refs/pull/3824/head\n00416e26cae18223607f3c2e1811f9f1e67b615dec57 refs/pull/3825/head\n0041e16bf45404fa2e1dcd1737ddb9274bf0dd7e0170 refs/pull/3826/head\n0041d0305ef55d2ff53ea2d066f859814aa2700d7f61 refs/pull/3827/head\n004147d383ffd9944c8cf2ccdd11faf5d440975bea62 refs/pull/3829/head\n00403d26b83e2b4423e91f1878eebb5320712e41cce0 refs/pull/383/head\n004188a65eab60d0f918387708a02e5570de0fc6f7f2 refs/pull/3831/head\n00416bb5605d423259d74e71277fe6f836c87de19846 refs/pull/3832/head\n0041d6f5a96c2096f5e1a70bb4aa582f04fc2d9e82b0 refs/pull/3833/head\n0041f6e9e6e03bba10e4d6780f887307612bc67e1d19 refs/pull/3834/head\n00417195d59fe61b182337f640f9368499d391563bbd refs/pull/3835/head\n0041102f90641b9f6ae36039c7c906609d7d4d9054eb refs/pull/3836/head\n0041c704d63d927519bf34b55325eeb8835d6f789f12 refs/pull/3837/head\n0041614c8e36612b5c92942389799d689a9139aea991 refs/pull/3838/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3839/head\n0040b5b94b399d091ef348eea50af8166632d491f2e4 refs/pull/384/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3840/head\n0041a1a28653323cf3a20cd24667d82c9103fd2a84d0 refs/pull/3841/head\n0041fe05aea385a0ddb93295dff0a77175b82180002b refs/pull/3842/head\n0041db530e4e3c8c851ecad3737337d6db4231cb90e1 refs/pull/3843/head\n00412cba1ca28e2faa75750b291f35db95b269f43fcc refs/pull/3844/head\n0041e3ceaa0b5995ed5af4d2bfc6643f17ad805dea8d refs/pull/3845/head\n00413d63b91177fbeeb521d2203307d2817a6be4c28d refs/pull/3846/head\n0041c63547e6e0bdea773127e2083ce16b215c9d0b61 refs/pull/3848/head\n0040f29693a20e63c75d1185ffe3852d5e05200365f9 refs/pull/385/head\n0041eb80e7a9797b8dd45bd50629942669eb3729b3e7 refs/pull/3851/head\n0041cc49d6896ba8f3ed5a8c5a565e3299fe0d39de28 refs/pull/3852/head\n0041af545ab7517d7f9cfd328e5518351217d06fb0ae refs/pull/3853/head\n00414cdb3a83045d241c6abfd6cc8b67c10493993198 refs/pull/3854/head\n0041d90baf84c2ef89cb16ef27bb8574d92c8f295827 refs/pull/3855/head\n00418cc18a6eaa952502f4ba7b3d9c11025b5b3a8512 refs/pull/3856/head\n0041b2c769a43c127a4ad3a301ce384fc24e76ac378c refs/pull/3857/head\n004150850b1951c108a17bc0db9c312895ded1dd1183 refs/pull/3858/head\n0040b7ef5869c878e43bba7533aa9b40988445c0bb5e refs/pull/386/head\n00415dd1a02a0e4c8ae3215fc09fa4b54aedb0a14eb2 refs/pull/3860/head\n004111362ca89eb07304d63e8225b4fd3e6c9ae0eb78 refs/pull/3861/head\n00417363ff427c719760a4de92b34b548a3a3d8071bd refs/pull/3862/head\n0041f85ba9a74db5729a8c8355ab1b00c68a881185da refs/pull/3863/head\n00411bee5f5f6b97914149e58e36bde8190259dc4792 refs/pull/3864/head\n004179e4032f8ffa02840fece03311c4f49ac1e7295d refs/pull/3865/head\n00411c3ff7ed39a9ee2e3b9978c412788944e94a8fb6 refs/pull/3866/head\n00412c0029bf5574f0ac36ca6cebddba1dc753a2be72 refs/pull/3867/head\n0041ff5a5cace93eca7955893492eefb5a51f295c76f refs/pull/3868/head\n004150ebaeb597549b5551f62a71cc860ca12661e700 refs/pull/3869/head\n0041759f43e9479c5207c92d3070f1647113274725ba refs/pull/3870/head\n004187a1e51128efdb8f1341d53e041431e23fd023bd refs/pull/3871/head\n0041b750dddb72d686afd2d5a3efde0ca11de99e5d89 refs/pull/3872/head\n0041cb8653f0ace7cda384f2b2dbda709bce57430e03 refs/pull/3873/head\n0041102f90641b9f6ae36039c7c906609d7d4d9054eb refs/pull/3874/head\n00417c8f0cb2c18cb6993786dc3d47b7e86258a962ec refs/pull/3875/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3876/head\n0041fe05aea385a0ddb93295dff0a77175b82180002b refs/pull/3877/head\n0041e3ceaa0b5995ed5af4d2bfc6643f17ad805dea8d refs/pull/3878/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3879/head\n0040623fd65be4741d54bca9d3b919ffa22c5e18d295 refs/pull/388/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3880/head\n004111e0a198535389e69ba4bb8839fa23669f2dc4b8 refs/pull/3881/head\n00415261b43facbf54e57857d2724ac5f23c6d00a5e8 refs/pull/3882/head\n004194f6969267b2f5260c90cb832431bdbe10cad548 refs/pull/3883/head\n00415d3eea4188f517c562fe62859a6ac89914bb0a63 refs/pull/3884/head\n00411e4ceeb43f1c8ba954af46556958158b75629d31 refs/pull/3886/head\n004100e968c4155d83f9b4cc100f9b510301d8015711 refs/pull/3887/head\n0041595f91858c4f263488483bab4f4c18eabecb51b5 refs/pull/3888/head\n004184ee0f213da7a839ce977520e53f901c141d1cf0 refs/pull/3889/head\n004020137d68b3d90677ec1a5792fadd7a0b9d5be665 refs/pull/389/head\n0041dd9217bab10ffafb83625720c7976f2f67257b99 refs/pull/3890/head\n00419457e17bf24eeffb0f5a36ba76dc1a752a5afb67 refs/pull/3891/head\n00417cba06455bb3105a5e65a7c8e664f3a9afd06ee0 refs/pull/3892/head\n004157b8170a6f3cc12b069d7e732daa326873b06906 refs/pull/3894/head\n00413e043d22054fe5f137d33453c89687b3d989a28e refs/pull/3895/head\n004117d5741880ed8fc9f47a3c1d4fab945cdd22101e refs/pull/3896/head\n0041c3367da422ec133b5b43aa56e247a235f7202aa3 refs/pull/3897/head\n0041f8cb8eb66e7871eab6205f062313c2c084de375f refs/pull/3898/head\n003f804148197b274c6129ab2c7d996daa456364c57f refs/pull/39/head\n0040e2654e0a480285bbba9ae0c65f7a48ef813f8d80 refs/pull/390/head\n0041eaa51e1dfb48b9f4e3733c94bd1696a8bf941644 refs/pull/3903/head\n00411b0f7a7995523913e78dd9ee49f623807bab26a1 refs/pull/3904/head\n0041e69b7fb5e733c65cc20e5ffd9e22c5cb92e9fd82 refs/pull/3905/head\n004129ef82621e3673342b536c444790f876ac7e67f2 refs/pull/3906/head\n0041e8636b60627bf7740a1003f63c98d947c03c1ef9 refs/pull/3907/head\n00413ac1ec80256d70f3f8bb7e884d9deb9c48d4e44c refs/pull/3908/head\n0041a5379a7b99a1d950c84e7c69bc5baca868b66045 refs/pull/3909/head\n004057cd1a4180b32268105209699409ee15fd23348d refs/pull/391/head\n0041c25e5ebc1a6f585c431c3057001426686a808347 refs/pull/3910/head\n004156c6db5dba84d0f1c34f85dfbc03577c7249b1ec refs/pull/3912/head\n00410682e59821f2d878a2b7399795a08b610ce8c8e5 refs/pull/3913/head\n004170623ca4eab567cab87a6bdd9c3c33f1809b1a57 refs/pull/3914/head\n0041fe546f2e593c84506c99a0c84da6821ff77b38b8 refs/pull/3915/head\n0041b87b2c7a05591e42db578fee5f26b0e7af034182 refs/pull/3916/head\n0041ec890999086a3a042d4a5dfe7480995f63daeca7 refs/pull/3917/head\n004194cfd7cc62e85496c8fabf2a0efd61ec041fbe11 refs/pull/3918/head\n004143798d1d6097e36ebbf3ff866dce07fd2bb2a11a refs/pull/3919/head\n00400c0a26a82752908ec2b45b00e052b166bcad1a6e refs/pull/392/head\n00411ffb1cda6d825a3f2b7975bbf31d7ee2c609d6ea refs/pull/3920/head\n0041616d8a297c117bf39b988e0f50191be88ba727e3 refs/pull/3921/head\n00416e0e9ef0310921cc583beb987013c9a52829e7a1 refs/pull/3922/head\n0041b588efa4c39fd3e1076b7bd34a3affd5e9705f73 refs/pull/3923/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/3924/head\n0041d8e6c8739bc2272484e8c2cf2eae617f53ad10e8 refs/pull/3925/head\n0041e0a3899cba44d3697c3fa5d5cfa67fbb210c6e47 refs/pull/3926/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3927/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3928/head\n004111e0a198535389e69ba4bb8839fa23669f2dc4b8 refs/pull/3929/head\n00408defc8e7c76da637ab8b3315c82a8f3896d187f6 refs/pull/393/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3930/head\n0041eebef3dbccb263f3625759617612165854d9dd9d refs/pull/3931/head\n00413dcbbc6feb6c7b2f4cc671600d3c408b10d32b5c refs/pull/3932/head\n004115a2ee9887ccae26ddec0daaf954ecec46fb3316 refs/pull/3934/head\n0041070cde5d0ae73ccdccf30f1b25ba76bea01d7156 refs/pull/3935/head\n004161e217870dd89215e181eb5198da8211d8e6cdc1 refs/pull/3936/head\n0040e0077f650f0dddd7ceb4160447770c45d0e5972a refs/pull/394/head\n004113c164479d20d8ec7294084f267b16a61f46bfa3 refs/pull/3940/head\n0041b6f1afc80459cea24b4be85ca843417f63c0423a refs/pull/3941/head\n00418b1ff67344b13995e68cf3dc9c8ac58f6f3b87a3 refs/pull/3942/head\n004152eb9f77964b05635e9110dab9aa82716a6ad061 refs/pull/3943/head\n0041189f29b0582fdfc412d147c5e79980244b0916b8 refs/pull/3944/head\n00419ba171f3de14d8e7a0b44b1a092ffffa2e1add7c refs/pull/3945/head\n0041fd0b54edd5ce159b36436c3dd89b8af5c37f58e8 refs/pull/3946/head\n00418ef418b918c995ce37e33f6f89276ae8781f3e78 refs/pull/3947/head\n00416d6d4fe2890b6a1498bfe91526b7a1f6985e8d97 refs/pull/3948/head\n0041da7f3dc8c1032d4b47d88719095df5e9ee394b39 refs/pull/3949/head\n00415eb86678eae2033cfb079a5aae81b459bf516dc8 refs/pull/3950/head\n0041ccf9a28d651ac78a1f4e794cb114ffe16643b2f6 refs/pull/3951/head\n00416286a716ab3c025a7463185b3747a3cde7c49c6c refs/pull/3952/head\n004113a2c5e9bad81285a8e80d24dbcee28512ac45eb refs/pull/3953/head\n0042420bf78527bb0aba9970edfe7d3fee7c8e7941f7 refs/pull/3953/merge\n0041ed787a0805bae8f0c35e5d6b3cf5121695079286 refs/pull/3954/head\n0041e2def17cd2abe3158b014340edb97a8de0f0a7de refs/pull/3955/head\n0041219045203122803b0af860f379fec988b5063857 refs/pull/3957/head\n004194ec0ecba39dd2f91775c94b7262978910c42e23 refs/pull/3958/head\n0041dc13ca51ab5fc58e205c2e1cabbbfd7ee7622054 refs/pull/3959/head\n0040a7dca0c16eada7c7f722cc9c91e1fed92a2b318a refs/pull/396/head\n0041c42b5d0282456dd2ecde7317176d3672a681e8bb refs/pull/3961/head\n00419c20f4579713fca652e34f5df142bceb7777f010 refs/pull/3962/head\n0041d5f57424cd1665e54bc6d076ee94a32f02fe608d refs/pull/3963/head\n00416aa4465662f0ae01ead778d616997f1e46561b4f refs/pull/3964/head\n004193effe1655ef6e07a82bbbef23d9c67daa020fad refs/pull/3965/head\n004136fb882bff830d21fd6abb1edd5e3eb170df4025 refs/pull/3966/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/3967/head\n00413dcbbc6feb6c7b2f4cc671600d3c408b10d32b5c refs/pull/3968/head\n00418ec3699efccf485ae037b167580c7a993fe95227 refs/pull/3969/head\n004084445945ed7de7198d9a0066daa0f51438edf947 refs/pull/397/head\n0041472cf88d7ac097df3878aed10502705b18d2c31e refs/pull/3970/head\n0041eebef3dbccb263f3625759617612165854d9dd9d refs/pull/3971/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/3972/head\n0041b2a6598cdb211b9287ae9f1d4028141d1ac959ab refs/pull/3973/head\n0041339ac8eba2fc33dabca1539b4cc2fa7b0b694eaf refs/pull/3974/head\n0041ac1de7ed2d2d7dba68afd627892d354361ce8e4e refs/pull/3975/head\n0041511c148a08470ad22951e7e3bd2cd38e522ced1f refs/pull/3976/head\n00414f636407c5bbaee0027a2e7e0318f8dd17e5ce7b refs/pull/3978/head\n0041772f8a51d0202f5c1dfeb1f993eef208830a3829 refs/pull/3979/head\n00400844c04becceef49c59f882e131067a946ab732e refs/pull/398/head\n004169d9a5842c7b8501f4ce26a8cf796118089a29e6 refs/pull/3980/head\n0041358cdaaf3470654629b8070c1c0b16f3ea0af352 refs/pull/3981/head\n0041346f07a7a58d6c5767efc2fa756329c771efb197 refs/pull/3982/head\n0041cf26f76e45970d35c7f96642eff8481f8e4a4080 refs/pull/3985/head\n004184b4f13793df71d9972c40d889b7cf39ed81bf4b refs/pull/3986/head\n00416c28b8631401bcd94a6797537fcf055fd1cf8a38 refs/pull/3987/head\n004134294cfed463b92dc955c131a63c2b35178691c3 refs/pull/3988/head\n00419475d9c86fe0a421d560ee7c0ecd19ff246f0149 refs/pull/3989/head\n004022f5a39f26c94f295594503e826e7cf470762221 refs/pull/399/head\n0041f8541a8e588830e669388f60c14abfd4a2e94148 refs/pull/3990/head\n00417bc326d367e5c6cf4e080aeb50ba7a9efa6d2231 refs/pull/3993/head\n0041741341c6ea0df2ffa59231f8827767abbf3e3d38 refs/pull/3994/head\n0041f2131447b46277eacdcffd60a4592ed2d1e13173 refs/pull/3996/head\n0041c28642f9b3c8d89e62795f4f708b6a83a3381259 refs/pull/3997/head\n0041cb3b9e85802b7084f0bd912353859104ced73a2e refs/pull/3999/head\n003e4a137256b3d2dbbb000152d745bf176d70147e00 refs/pull/4/head\n003f7a793712e2ac08d1a47dd61e24238bf0ffca6063 refs/pull/40/head\n004028e57c8bc46d1d8708ce9c9883be5d924ebbf10e refs/pull/400/head\n0041dcf91e611e46ecbee8674e2b9e20a3efbdbdd801 refs/pull/4001/head\n00410671e04fb737dc0aaaceb6cd16e2f84d8b900d34 refs/pull/4003/head\n004133cd5ecf32890d9c90bb211fa13247aa6f976d0d refs/pull/4005/head\n004140655b050c9d26d32ec622468f2ab6f336d37419 refs/pull/4006/head\n0041582711ecae53a970801c41deb3dd543c0a0017f6 refs/pull/4008/head\n004185830df99b8b87d2c0f2516b0610eb748a6e76db refs/pull/4009/head\n0040e485f81fe2dc95638871b436bc5c2169079f7ee1 refs/pull/401/head\n0041f37610ff5056787b0049db5a2148b72d31ef6872 refs/pull/4010/head\n004124df92e6cc679f9754fa61d678815021da6716bb refs/pull/4011/head\n00415ff229a202bbb25724a937f7ebbf45a67dfeea29 refs/pull/4012/head\n0041c299af1036c6650d5f280ed6a97f2bdcc140ac2a refs/pull/4013/head\n0041045a5fe1feffc3fcf66e0e9416334a5ebff59e6f refs/pull/4014/head\n0041d3d3c3ece200899bfa03b9d6bc7210e547e6b035 refs/pull/4015/head\n0041fd81720da377b33cafc764ec940445c422272984 refs/pull/4016/head\n00414f264d32b7adfa4944b55029ee870f182df1a1fc refs/pull/4017/head\n004148ee714b424076e2a714d5ab3812fc287043956c refs/pull/4018/head\n0041efdf07f93ea4d4c275d9e1832bb0f71940916eee refs/pull/4019/head\n0040ed452dfb3fafc4bf83650096ed88ad57ec4fcbd7 refs/pull/402/head\n00413bf1b3ae65ec763ef33d6de827328dbbfa84f412 refs/pull/4020/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/4021/head\n0041508aef0a6b2172c442e5c8a86e6c7043a7a4325c refs/pull/4022/head\n0041b2a6598cdb211b9287ae9f1d4028141d1ac959ab refs/pull/4023/head\n0041ac1de7ed2d2d7dba68afd627892d354361ce8e4e refs/pull/4024/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4025/head\n00414e96f18b74147ce2c448df232a5fee34035fd8fb refs/pull/4026/head\n0041ceffb14600121d81699a098098fa81c15bb8710f refs/pull/4027/head\n00418094cf87597d3c0bce1e6bcb2a0839484cc13adc refs/pull/4028/head\n00416e7df771e436b5bf524b7b643796c1baa7babc7c refs/pull/4029/head\n0040d0e471fe80170e85ca73a2e1ae9c836d769c2991 refs/pull/403/head\n0041546e846c9d289d9ba339eb60cc90648da9a37bb6 refs/pull/4030/head\n00415326204c817cbbf6168b7fe1b4e488f0121486a9 refs/pull/4031/head\n004135ec9bdadb83d2000d39e23b68926f18cdc7063d refs/pull/4032/head\n0041e1313e13e2285b2ad73401638529f215d3b7578a refs/pull/4033/head\n004141c2b3c104c84a273132900ae759b7d8c41eb14d refs/pull/4034/head\n004171166a0d6a23f7b43af95ed0fc6335f76bfab8a2 refs/pull/4035/head\n00418548fc841b6c33161cffa88a823e4ef98012dfd8 refs/pull/4036/head\n0041d604f023e238abd9fc6556c6078885aee23b188f refs/pull/4038/head\n0041d31d31e8ac29e98d3a27a83b5d45ea921149ca08 refs/pull/4039/head\n0040eb8e38a0a9d69ed42989476d22aec692229b4104 refs/pull/404/head\n00416525f4454d917386b129226dd59d00c53e2843b9 refs/pull/4040/head\n004136b27e35e464c78e7e498971855bbcde054ae5f6 refs/pull/4041/head\n0041814831e3ff9de8cc2e2831994711f29fd4e19537 refs/pull/4042/head\n0041df6b674a9e9ea8a6d42bb312dbac267c8f50c50a refs/pull/4043/head\n00419ab5a3a4757c46850e16b6dd598678b9d9a619c5 refs/pull/4044/head\n00418cf1724e7904751d7955a0b4e22f43600cab320c refs/pull/4045/head\n004180dc2f5ec2a822223edd971abbb008d5ae75d8ba refs/pull/4046/head\n00414223a6b82e81194aeb3465dd1acacb23c7cea579 refs/pull/4047/head\n00414ebbc055f168f25b25a9627d0642f5fffd2cf04e refs/pull/4049/head\n0040a5da7dc13ec7f46fa0f5e26ca0510c08f9a6f416 refs/pull/405/head\n00418f7a1f4a2df5488e7cb76af34140a485d9303be4 refs/pull/4050/head\n0041c60f4d8422b6485b3369585445f262a660c7113e refs/pull/4051/head\n00418e627312c947abd6174a58fcd126fb0886e05f44 refs/pull/4052/head\n0041f0a81947fbcaaddb6c035e4524b0b3b38ba51846 refs/pull/4053/head\n00419c02148c6d6e0fe4fe5be28167662aeea6bafe88 refs/pull/4054/head\n00419755e9fa2144edd64344a10cc1272faef971b267 refs/pull/4056/head\n0041e50b5f96a4c876d6bd0bd2128de031f9bc40e73f refs/pull/4057/head\n00414ef2433e1bf470b7d7847ac9ebd6c568eb71c659 refs/pull/4058/head\n00416ad7b0a64551e6ecd18bcd213cae285db9dae032 refs/pull/4059/head\n004017c1e7ec2ae2c06dbc42942ba61098fb5d372c64 refs/pull/406/head\n004180c200d3f72061337f95f9f062a6be1d07bca435 refs/pull/4060/head\n004148807357148a56fc2fdfb16f3530523d059ea089 refs/pull/4061/head\n00418d7da0ec4b550c610ae4c115e78b3d17dd50d1f5 refs/pull/4062/head\n0041ff226b4004c344c58067080d12111f41029913a1 refs/pull/4063/head\n0041e4681e8db389abcb0265c91723d8168d8148d2b9 refs/pull/4064/head\n0041ea3b782265eff6b9b357746e8800b9f17eff7316 refs/pull/4065/head\n00414abf19bffd321b23cff78c7eeaa9419dff713b2a refs/pull/4066/head\n004122558f6432557ef43e8edf7a0f15c814d8904187 refs/pull/4067/head\n0041657bab31bdc9055499f2f3f54c825c8b4807e49e refs/pull/4068/head\n0041a63a4e92591212a858b964f91d2ecf3420b4dd03 refs/pull/4069/head\n00409343ab402ad2586f8624a7fb8faca6cedfd57cfe refs/pull/407/head\n004145071bebbf81d8a3cb26fe7ae02b54c8121b38d3 refs/pull/4070/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4071/head\n004131afcc8c2027641029ce9b9a10aec3e411a1d07a refs/pull/4072/head\n0041c9f892912fe474c9b6e1ce164733d28ca27c949d refs/pull/4073/head\n0041b6110fffb6a4af391983e93bac55341df64df316 refs/pull/4074/head\n0041c430737d083686a2c81f0e431934700d31e4234b refs/pull/4075/head\n00417e11344eb17c20905860d7e7a36b50dbf44b3a38 refs/pull/4076/head\n0041a26cb6c660645dacf97c6f3d86d0d64b52330000 refs/pull/4077/head\n0041b276fafa473ad8f55f21e804640f7360c8000779 refs/pull/4078/head\n0041f69f47ffb6762f491a3e5bb5972f852423b35b40 refs/pull/4079/head\n00416dbe606370f26f5e91f0047db06b33713fc02014 refs/pull/4080/head\n0041b89ae98f2c937abf50ceafcef261590e353bb663 refs/pull/4081/head\n004163bbe5a79e242be38ac859cd2056438120cb4527 refs/pull/4083/head\n0041af793bdf944b14c6ce8eb60a414704d22479e974 refs/pull/4084/head\n00416b58419828587f15723fa7cca921850d52e7a57e refs/pull/4085/head\n00415b04ec5dcc1d8d8929ff10eb9c2ccd52ca34f99f refs/pull/4086/head\n0041f3db124ccfc14a7740cb8da4ddc8e7bcfdb76753 refs/pull/4089/head\n00406d0f1c3a7895798088acf0a8a08495056298d244 refs/pull/409/head\n0041bd5b692aa4d6518a93270fa9d6c6ffbe02def777 refs/pull/4090/head\n0041bebeadc18df007891b479d5bdb4a2360dd56c20c refs/pull/4091/head\n004140a3ab6a6c643552b81b64da6a3b456fa1b863f4 refs/pull/4092/head\n00411b36e1330ceee9f68b01dfc05c086d1d39586b4a refs/pull/4093/head\n0041eaf9ec2e31b1764e7e1757595ec45d133a51da39 refs/pull/4094/head\n0041bca98ab20df40373301bdc71c2a15d3a1fc8b418 refs/pull/4095/head\n00415507e12b7e085f9df7db65c00e127e91d82abc19 refs/pull/4096/head\n00417ac7a9d84f5e8c16c3512a34ce2eb84f69774f92 refs/pull/4097/head\n0041bb5e56ed293875c45ff6f5bdab3c2313eee02993 refs/pull/4098/head\n0041605048cbbe560c6a33cad899ab6036fd2ca992d8 refs/pull/4099/head\n003f91651239dd6d4d47c8d4d8b78d6df7e9925fdddd refs/pull/41/head\n0041f16f78531c36953bfd52695cd2b05cb4e224b40b refs/pull/4105/head\n0041a71fc86bec92b9e2d2e228f31314de541f936515 refs/pull/4106/head\n0041035da14de4c9bf4671fc6bcc64e7a83190cf1e5d refs/pull/4107/head\n004197b2eb2eb5fd13ce0303f0085c3965b6b3deb396 refs/pull/4108/head\n00410a7b7007e3f21ab4f1f2d5dd1918812fe4a781b9 refs/pull/4109/head\n004148fb24ec1daeecf139b2acd043726b4e3220cbf4 refs/pull/4110/head\n0041ddda7653e9367fea63d66267c04af88b02246d3b refs/pull/4111/head\n00417651c526d952329a8df588614e8c3716736c9bdf refs/pull/4112/head\n004172b7574f41b311abeb9d9b74573c4073058fe0d4 refs/pull/4113/head\n0041ffb9e800e633fc1795c639f76fa3fa86a794ef96 refs/pull/4114/head\n004171a405b3cfba5a6bd608f3bfffdf42b4143bb19e refs/pull/4115/head\n004105c08929ec11360d8cfa425fb1770df12fec9f01 refs/pull/4116/head\n0041a93f546c5aad3efc874888ea30ebe16bbe049d2b refs/pull/4117/head\n004103f1af1874e46d561364092f4ceb5e574e494d76 refs/pull/4118/head\n0041b39045d8e24a3f08951b13d54c260cf2a8e3557f refs/pull/4119/head\n0041426a031bd0cd3672007a16928e83697af3d0e6a4 refs/pull/4120/head\n004131afcc8c2027641029ce9b9a10aec3e411a1d07a refs/pull/4121/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4122/head\n0041793bd043ad71303633efb42100f9faf9bb381d63 refs/pull/4123/head\n0041011b48415cc6bc3aa2fefb766f4796da06a13ec8 refs/pull/4124/head\n0041324662b82050b9ae34eb14a8a87094139d0fdc70 refs/pull/4125/head\n00410c9a0aefa2a741329dbbce3d1dff633ecc045865 refs/pull/4126/head\n0041735e4d1190995a13e8e8307ee4e8455877bcbd96 refs/pull/4127/head\n004187c62cb49f25d05e1544d30a30f6c9f3dfc4e96b refs/pull/4128/head\n004149702d487210729dfbfd7213b1b0422f50e0833a refs/pull/4129/head\n0041c336256869152b1467b19fa98cef5b7d1a1b0d41 refs/pull/4130/head\n0041ccf15c1f6bb206db078ae5e0fecfd006ea563349 refs/pull/4131/head\n0041946bdc651d108fa66e8c81e189232bfc5da85055 refs/pull/4132/head\n0041d97dfdf2f5a81cd1058eeccece2249de001ff672 refs/pull/4133/head\n0041fb53395f827a67fdd76beb97ff4d828c2f6e7c03 refs/pull/4134/head\n00415e491a5804c70c854f398823dcefcdd99d286b18 refs/pull/4135/head\n004139e867fb7ae579904b75478ba14a9af77b771c82 refs/pull/4137/head\n0041a46b95f653938b9636964a9dbe19e39acc183e68 refs/pull/4138/head\n0041fc819913d79ba86f0ea1f619f76ed386e530e987 refs/pull/4139/head\n00412d4e21f4332ba46b2927eee9777c6dd9f7df4118 refs/pull/4142/head\n00419233bff2b768d32d43a61dacd7bbd3492f36ec41 refs/pull/4149/head\n00404102a18a336fafe433d6b2857265e0f0d6b77863 refs/pull/415/head\n0041325767014e1d51f0395fee9112091bbdebfa9578 refs/pull/4150/head\n004199040bfa7220d5d5c4324ddd006426550d71b2d9 refs/pull/4151/head\n00415ae3a0763aa4803fd2242ec786f9c1aea5b3a2cb refs/pull/4152/head\n0041ca331ec7255b817a6c8dba737680cdc17b08edc5 refs/pull/4155/head\n00417975d92c3d81922fb0922751fbdde450f63797b5 refs/pull/4156/head\n00419934b5466c9e17025b837df952aa754ca3b35efb refs/pull/4158/head\n004081dd41292c226f014de149a0071296e116d61189 refs/pull/416/head\n00410b1ed8dcdbcab26ccb2d3d799c43111a67e42dc8 refs/pull/4160/head\n0041f7aade54eefde94dade8029f75851e0678f8c216 refs/pull/4162/head\n0041b18605319dd079c09aaf7f08af9afa9a0d8e5a08 refs/pull/4164/head\n0041b66d9c8c608bfa332053171798db6e8579c5dea2 refs/pull/4167/head\n00406c31da0bab542b41831b7a82a9e4d14761e820e3 refs/pull/417/head\n0041e28815e9c8db98fa3d48c76abc3f23ef1987703c refs/pull/4171/head\n0041afeee52a4b7500d0ee9c0435666b0c1a98b5e03b refs/pull/4172/head\n00414c6c428eac56da2fdb136b5975634bad534e9ba2 refs/pull/4173/head\n0041e4e045bcf0e48528728519046c49342e6b435af6 refs/pull/4174/head\n00419a50e87563202df2dc338fb270f64b592a0524b2 refs/pull/4175/head\n0041f9101a7b9e3c242bf7369a23cfce89b31e890355 refs/pull/4176/head\n0041468332b6a69722b25a4f911d5edd8972453a5ace refs/pull/4177/head\n0041341bdfd038f7c032be5af5c4a98979c49fef2766 refs/pull/4178/head\n0041d0eb7383efe8c5e872422871dd46cd81803598a8 refs/pull/4179/head\n0040bc1b44e4879261c92d2b3fffdc9ab647d7c8a1d9 refs/pull/418/head\n0041e05bb785d508083e16148d0d2f91f109b952c4ea refs/pull/4180/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4181/head\n0041e289b61c0c57472c45188641c0e05452e2ce395c refs/pull/4182/head\n0041450b6076279e484cdacfa0e239d0e1a4468043d8 refs/pull/4183/head\n004109dd25bb2d986ef1596ad0717c6b830af0067bfb refs/pull/4184/head\n0041f77c7f1221a2ef94d852489feb1f64da619cc855 refs/pull/4185/head\n0041069724802e1f8e4daf65269e34bc54ca4e2bad6a refs/pull/4186/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4187/head\n0041c42f88cdadf7a7690aba1a446e06164d3342abcb refs/pull/4188/head\n0041a2e56226bb6c168db9e9999afc1d43d63f673800 refs/pull/4189/head\n004087c749f7431781e754adb61bc61c699fe5d7640d refs/pull/419/head\n0041aa04cfcfb282ddd29fe37ae04298e628bb3d92fb refs/pull/4190/head\n004181a4b6f95775647f71b293af6bcf255067e9fc21 refs/pull/4192/head\n0041e29b44b5fbd605d6e212ddf1b0ceca9565d5529a refs/pull/4194/head\n00410267051aca65a519829ac18ccafb06146006815f refs/pull/4197/head\n00412f5a1bb0efc8756bee679ece015b2e8f009b0716 refs/pull/4199/head\n003f7645ff6b03ffec78255994ef914a8961c0bb48ab refs/pull/42/head\n00406afc717169d3d59e8bbc2c1fc4cf01bbbc09f96e refs/pull/420/head\n00411455c9c6eddd003e10ed7d04f3585f76f747ee26 refs/pull/4201/head\n0041b75e8c48f133abff7febd8d90b477a81e259091f refs/pull/4202/head\n0041f94d78ac37b431339780bd5a19d69dd421fdd99c refs/pull/4203/head\n0041df368dd0660b8b3d4332f951e3877f04a6e39a50 refs/pull/4204/head\n00410dcf9190fe52e458a188dbae195135f7c62cf20e refs/pull/4205/head\n004161e5b322c9fb3682dc8082296e6f8c23fd6b1c97 refs/pull/4206/head\n0041520136a091348dd122ae73b88ef6243a09c22066 refs/pull/4207/head\n004150f9495524108a18f2ca6687a39bf4955bac9e72 refs/pull/4208/head\n004191817407bc0be1d01dab3b79e9e32d72ec3a18e5 refs/pull/4209/head\n00414951b45f4236fa673b427eaf447edfb88b011a76 refs/pull/4210/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4211/head\n00414fa12187e525fe48fc5218f89b04c6677d9ac286 refs/pull/4212/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4213/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4214/head\n004125491e8309b509268d38573920ff441a173bac46 refs/pull/4215/head\n0041f57ffc7300426b6d925980f57e2f2d9673cefa27 refs/pull/4216/head\n00410dff43ddb59bdf036b2ba50f89e7eab8576d7712 refs/pull/4217/head\n0041bd6c7ae718c5c93b239504754c7b6ab81108f56d refs/pull/4218/head\n0041bc002dc9333220eeea243fb432b0b0c521c0d52f refs/pull/4219/head\n00404831bc8b92e9aecbcd0f128f7e45796bb5f89ebd refs/pull/422/head\n0041977e3d1fc39da8615f7ee45b029f871c4066d80f refs/pull/4220/head\n00415530bc9a9edbb13ec51deae96d747ff442c83662 refs/pull/4222/head\n00414207547e4e38e03830909dff6b84c9bfad04940a refs/pull/4223/head\n0041745b933ceca93d7589ee027300c8343fe51e971c refs/pull/4224/head\n004183438f22d3903985c1f0c155906ac2294599b848 refs/pull/4225/head\n0041d6b36deb349f88e5680954d24f714b4c7d1e8d6a refs/pull/4226/head\n0041ee89c8da1262f3c20730187a3c1a79ad91ee4f42 refs/pull/4227/head\n0041589c54bcaf5e6bbdbb2a25e8babb0dd2654d982a refs/pull/4228/head\n004197d8c9c0742269aa84e856793d7ca7f404ab1204 refs/pull/4229/head\n004038871758f59c771bee03cce88b2c9cc99b76793b refs/pull/423/head\n00418666d058e26bc82846f310a1338eb70404088055 refs/pull/4231/head\n004155dc40c8a7d656e104d32f7e8c205af56cd2a0bf refs/pull/4232/head\n0041c368132e3e9de3f111cc49253f94c59c6839560e refs/pull/4234/head\n0041b93f9d9428789c90b8c9d6203581180931183f3e refs/pull/4235/head\n0041bd108d3593f63e0662518db1ea55c84668802242 refs/pull/4239/head\n0040cae5daee7deff4cffda76dedaaf1a653e2af3790 refs/pull/424/head\n00413cdcf410a1c13450527574dff40e152c23aa0fe8 refs/pull/4241/head\n0041d227b5208f951c7b132aa84ed7aff5e408edc550 refs/pull/4242/head\n00410fd1f440fda25e704da3ddccf6c5d8ecf374a85b refs/pull/4245/head\n004187845700c3259b2f3cbdd32d94a29831bc9135d0 refs/pull/4246/head\n004193a0c66066319330e05f0a1d63953f171851c9f6 refs/pull/4247/head\n00413e9dc58f39883d11393e53897d5a62bee2e5ae74 refs/pull/4248/head\n00411f3c10be2db2dbb84d4c331cf10b1dfb2689cf87 refs/pull/4249/head\n004000ea2f01026b75a03df999dba8057a2c14ec0d0d refs/pull/425/head\n00411313dfe68758a4ee4690f5d6e8b27a92bb921648 refs/pull/4250/head\n00414dbb572879002a0d08851d874495dbe009dfe7a5 refs/pull/4251/head\n0041abfbcb60fdfd3087fa29fe2e78ad98912b97905c refs/pull/4252/head\n004174f09ca04f441096a500a228081bb0be818c9491 refs/pull/4253/head\n0041079f1a40fe0f4310e72e08a1751f748a8d694fb5 refs/pull/4254/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4255/head\n00414fa12187e525fe48fc5218f89b04c6677d9ac286 refs/pull/4256/head\n0041b5a24b4f6c4dc5a3e34afecdc31ff2ef2ca9e6a5 refs/pull/4257/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4258/head\n0041a1c6db19bb0c144d67e3bfbf3679f48b5a05fba8 refs/pull/4259/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4260/head\n00419b510e6bed5cb4466e7c112d084b7b00a6faed9b refs/pull/4261/head\n004148f0642dd3159f8f7b8705c6ff83e33aff815277 refs/pull/4262/head\n0041486b8efb7f93c5f228eae6851d8e15c1d94150d3 refs/pull/4263/head\n004157c9e29288e419de839577bdc343358a75f61af7 refs/pull/4265/head\n004149d7b32a34d587b76300e90b7845ee267deef517 refs/pull/4266/head\n00417c3345d97e02332db64fd9fe3b244d78986bff81 refs/pull/4267/head\n0041af4a3832ac8aaff7d11d5ed08cb1f648986e07c1 refs/pull/4268/head\n0041a45bb327f89ef31a8aad1dec35929ca2d35895dc refs/pull/4269/head\n0040adac66c1741833f79a1a960a6932760ab694b1dd refs/pull/427/head\n0041ca050aa79e6a9988df50e50a96fc5f964af847f3 refs/pull/4270/head\n0041730099826e1c762022eb75f5f147351720d5cfe0 refs/pull/4271/head\n00415ef02b59d4d4372226523cbf4c5a1c1419a88552 refs/pull/4272/head\n00415383421b9481772a94a212117943ed862ba40c48 refs/pull/4274/head\n00415bdb2c1256818c354cf15f8f516258c195d040d9 refs/pull/4275/head\n00412f739e7717d0abea9f1a7007135748a84b8570c4 refs/pull/4276/head\n00416ecde25885f6a97cf6bb8adc35193e28fe324bcc refs/pull/4278/head\n0040478d6e2a10cfc44072a3aedba6e921442e155f2f refs/pull/428/head\n00419bf4966688a3e46deb3be128726aa105c9a6c896 refs/pull/4280/head\n0041c53dece390e68991bbe5b80765b80676219f2226 refs/pull/4281/head\n0041a7cdcb54769f35a8dde5b24981acef979e4967d5 refs/pull/4282/head\n004148933b48c2a86c022193c944636f9e51e5c5ac13 refs/pull/4283/head\n0041882c6e214d2527a477b2f96cb3b938ffc83250a4 refs/pull/4284/head\n004199de7c8d3af77d5c29c698342947a44b6a4cee12 refs/pull/4285/head\n00414ab45af81980209deff56da769a250db96f24ec6 refs/pull/4286/head\n0041d32271d8b575539980b22d13f7b49c711205fd1f refs/pull/4287/head\n0041dc8f3942325416f8d04af6d77ed1d1faaf9b3102 refs/pull/4288/head\n004144dbfc666c77644955d9c54066eff274aa9ba463 refs/pull/4289/head\n0040702b192740ea948214cbdbeb82d38f79405697b6 refs/pull/429/head\n004164f261c6e4a2ffdb54c7b7b10e7d4e127cac13bc refs/pull/4290/head\n004152582e2431bee0922d2f932bcf871ee1930227d5 refs/pull/4291/head\n0041ba9ca122c226c4a953c506afab73df5dbaa7bcf7 refs/pull/4292/head\n0041d4f0a911405c270ca27d9e420ddd95cf04e68e97 refs/pull/4293/head\n00410e15ab6348c70ea4d825d0904484c5491c59bfc3 refs/pull/4294/head\n00413d1497f309c730f046d52a0fef4718c764cf0081 refs/pull/4295/head\n004183401a5f10cc9bf768838589452ccee91cf3bd13 refs/pull/4296/head\n0041b5a24b4f6c4dc5a3e34afecdc31ff2ef2ca9e6a5 refs/pull/4297/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4298/head\n00418c3c0ea8ae4862b829c7122bdabd6f0fd767bb89 refs/pull/4299/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4300/head\n004173c97de91a7eb66cb20ef9b4183c4bd79f042204 refs/pull/4301/head\n0041791ecc4ed2cb35b7b90621754dfca7b681d5dce0 refs/pull/4302/head\n0041f06a7cae3d6fd8243d56e0f018c20f68890223b6 refs/pull/4303/head\n0041faebc0f6408cf78e414be49d93b7bbda69bec2d4 refs/pull/4304/head\n0041f7e2108944564aae08b0f9adae43db5784c9fed2 refs/pull/4305/head\n00418d826b50e698a369f9c3d6bfe36f7c52a209b707 refs/pull/4306/head\n0041e84a2c927d801b8e90ed594c36eee4c169ca9699 refs/pull/4307/head\n0041cba995b840bd791452622ee7fb8dcd0f261cdaa7 refs/pull/4308/head\n0041b86ca2acd3bbe1bc58b5432c1596bedb8d2e1053 refs/pull/4310/head\n004136cb73db1f0a1df44a5662c346a2176ef766e0ba refs/pull/4311/head\n00412891cb4165960c15dfb87ed24f6802db4e679f2f refs/pull/4312/head\n0041effb2783ad7d37e0cf924cb898c637ede68bd4d9 refs/pull/4314/head\n00412213efa9faf4a22b5bbd22dbcce998e7878089c8 refs/pull/4315/head\n0041fc6a35716d0c1e147bba0c763b241526ff8d7e21 refs/pull/4316/head\n00417795fe2118ae03eb745e4acf65e008ceed9faef1 refs/pull/4317/head\n004168cf84ff3b56b98b1bad07bc1e5216d1c4934e64 refs/pull/4320/head\n0042d81d55145c7926d949eaaba972446fd3db59a732 refs/pull/4320/merge\n00417357fbfc817239c300ee3cfefb9d901a6070a916 refs/pull/4321/head\n004177005b107f9201705fb316f7cd0451db6d1c7b13 refs/pull/4322/head\n0041778a8cfa7e02320454f0ddd160d59e5862ac6ea0 refs/pull/4323/head\n0041e5d598889d902ae29a65077e6af5d0146d5ec8e3 refs/pull/4324/head\n00412bd288abac908bb2020c9d21d0e92e370826a25e refs/pull/4325/head\n0041846da5544a85673d81e39a164d0673e8ea99d9a4 refs/pull/4326/head\n004117d729fece0a7b1995ceaae94b4c404dac0c7ce7 refs/pull/4327/head\n00413e62eb95d5570cc4316b0789545494efcadfed7c refs/pull/4328/head\n00413de84d56b6a4a4a096111197bf14822f09fa1b41 refs/pull/4329/head\n00401652c745526d09ec28dd1bfc8062ddc82a04efa7 refs/pull/433/head\n00416aa4f1020b5932f21a737787170b6970ac95865e refs/pull/4330/head\n0041056910dc0c3d996d5dc6fada971656babab4b0d8 refs/pull/4331/head\n004162813f81d9235c4c985a9209e47724168b3f08d2 refs/pull/4332/head\n00415e07765804cdcbe84fdfa45e36fe8fd7f982f7ab refs/pull/4333/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4334/head\n004133f7df4a458779537e841eaeb160b8c36b78ce9b refs/pull/4335/head\n0041f7fed3c07f4b162100c5f3babed9cac14b2a6d0d refs/pull/4336/head\n0041894a48d4007351a085f3573609182976e61559ee refs/pull/4337/head\n00413f4d9e880845265f5458ea33983f24614163105f refs/pull/4338/head\n0041ca687f211ba4cfcde6e6860edc47adbaf3d62dcd refs/pull/4339/head\n004037102ca6da3d94dcbe61fd6f00bbcef7843e60fd refs/pull/434/head\n004158951688bd7b39738e90ea52e27938fc0e71e272 refs/pull/4340/head\n0041b7a013236007fd71a8ef6db7676e61ae92f0e9d4 refs/pull/4341/head\n0041dfbd3be19b707b45b867e1d495c78cfeab0a79ea refs/pull/4344/head\n00415d82849b116aafcfe3b840a3b2cb3a96c72b0c1c refs/pull/4346/head\n0041c95c4dc7c8d77cc218f03f2e512ad131c34454ee refs/pull/4347/head\n0041c025159a0f882c9fdcf352d0d8937c8514e6cf1e refs/pull/4348/head\n0041c8c48c90d5a25cd69dc4f95d19b3ce8c31f55e58 refs/pull/4349/head\n004033bad2b5d92dbfab547fb81ae3bb5e62baa91be8 refs/pull/435/head\n00415a52a7a8297c848d6258d4691e920384524b2ac5 refs/pull/4350/head\n00410dd19ef125a7d7e9edf0a3ce1b83167ee19bc160 refs/pull/4352/head\n0041960851a01e6e85169fc45a599edc706248a6dfc9 refs/pull/4353/head\n00414f9a50b2c1db3828ea92b9062e21e6e928c1aa26 refs/pull/4354/head\n00426e5bfd0c7aacce22347eb83ef297f5c2e3e60149 refs/pull/4354/merge\n0041ab15e312c6e77e5f9663e045b99c855fa4fef9fa refs/pull/4356/head\n0041240d7748022cc5eddc71b055a4de56607f808aa3 refs/pull/4357/head\n004102f239424950db284db5cdaf98cb6c8a01c9ee14 refs/pull/4358/head\n00405cf48a27f88c23526734f137d94195452d923dc2 refs/pull/436/head\n004147a2e9a56a526d1bca7f21a8238125f4eb6d74b5 refs/pull/4360/head\n0041279c4cef7315db382b2de092359578eec04e27c9 refs/pull/4361/head\n0041ba68a768ca2617b68e4501c45bf53add1a56663d refs/pull/4362/head\n0041e8b529654e25575191b947df1da8d91c099c9fb4 refs/pull/4363/head\n0041e4b09b21a6dc647717e2ace56567225e7619653e refs/pull/4364/head\n0041a220812d62e2e42091ec715b57de15185708ba39 refs/pull/4365/head\n004119f1f5bdfd91c1e0f3a3232c7e9fe6cd43be287a refs/pull/4366/head\n0041bff16a47bc1b3905d8b6cbe5ccc7502bde96ee9f refs/pull/4367/head\n0041a14da923ddda5f2c54323fe126097752e1868ae5 refs/pull/4368/head\n0041c186ea5845c74108685e91bba36613c23212684d refs/pull/4369/head\n00403dea0ce596c3809f433d67bb2160a8a8af9e590f refs/pull/437/head\n0041cc2a50ecf69d4802ac52e686b2958e1dfa0a43fe refs/pull/4370/head\n0041123280cb29051b1aff60c6ae37382e8be59ff2dd refs/pull/4371/head\n00417e2a169c274432adc128d93b0b4da7e13a927062 refs/pull/4372/head\n00419322086f4d84da04f578dcbc1c7d60905378bed2 refs/pull/4373/head\n00417d4984faa3fd34d684eb715ef1ef7ecbde94d893 refs/pull/4374/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4375/head\n004140fec103a79693157045eeca1afa45d9b809ce19 refs/pull/4376/head\n00413ab4bd42754e8625516753569a34e5a5b5b2e66b refs/pull/4377/head\n0041d38aa9d9a84691c9a226b38209fc60c3e511c125 refs/pull/4378/head\n0041f6b206dcb529a0be6317a0c6fac208ab1306da98 refs/pull/4379/head\n0040e7b69136fd234a5ebaf9e047eb4365c59ad7461b refs/pull/438/head\n00412e797b98f10f8d4345a8426a37f02724aa3cf9bc refs/pull/4380/head\n00410da6ba3394cfc30e529c25a09f532c7f59d626f8 refs/pull/4381/head\n0041afc420868ef02796f3b2cdf83c1828b9bf53bec6 refs/pull/4382/head\n0041c265e78f41cda5ea210ac0eb48c37d39a5fc3c5e refs/pull/4385/head\n004138cfe7d7650bb417615c5a88de6a56025f070f1b refs/pull/4388/head\n00411765c654486625ac03a728e9e4dd6885a8102ec9 refs/pull/4389/head\n00406531bc4aec902c7245c0b5e6ed08f50fff8de7e0 refs/pull/439/head\n00411133aeb7e723a6aa3ff1b73fa122f562180c6571 refs/pull/4390/head\n004131b702eedd001d3347dc45088e2b118dac3ee5a0 refs/pull/4391/head\n00418b71105e0c36521dae1ad1771df23a90578fe429 refs/pull/4392/head\n00419320ea079550140e74a649d7579909a9b789d19b refs/pull/4393/head\n0041687cecacd9d1f8f608cfbb577b218a59ecb5831b refs/pull/4394/head\n00410118be6593c06e3da81ca22422d48af8b0f8eb5e refs/pull/4395/head\n0041800a52c3964dd335f633f967a2edd253eaae3939 refs/pull/4397/head\n004166b067187c1513f320356b11049d9e3a3ec05ee3 refs/pull/4398/head\n00415c8eaecdeb2dc750cb13759c350d691eba24d035 refs/pull/4399/head\n0041adfb43db240c21a6ddc668e9aef984e94ed161b6 refs/pull/4400/head\n0041929776696972e0e85a4988c2ddddbb0e451ea93a refs/pull/4401/head\n00419e55ac3643f1c67182031fc8a2183fb9ee666600 refs/pull/4402/head\n00416bfa8c455a067f05586e2cd553969339833dba6f refs/pull/4403/head\n00413e1abd1bd236754e6c517bea0f676608f3896979 refs/pull/4404/head\n00419322086f4d84da04f578dcbc1c7d60905378bed2 refs/pull/4405/head\n0041866307738b1ee6a88c33b5e727b72ac3392fba2f refs/pull/4406/head\n004162e1a4b07048aa502628e6831ceed9d69ca4239a refs/pull/4407/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4408/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4409/head\n0040564ede75518c9e18b7de4b718827ccc62d32c2cd refs/pull/441/head\n00411f33c2e270fdebb0daf3f707ecb01907d1d7c268 refs/pull/4410/head\n004290210ca4843705d5f500b0e3583f9ba51b7d090b refs/pull/4410/merge\n00415c4587da625a6adafdf696306c472f43c110ffa7 refs/pull/4411/head\n00416f2cac7ed9aefb82ca5f52d1fbf85718be6ba6e6 refs/pull/4412/head\n00411627bc9b8c18d9423d83f0e3bc4d38944a606805 refs/pull/4413/head\n0041e9f0083db1333300db481783452b8975c6ccce20 refs/pull/4414/head\n0041ac3b48ad45d410f8e91fc0c38b1c039ce145426f refs/pull/4416/head\n0041e1326803ba3257f8e344df1cc213f97018503da1 refs/pull/4417/head\n004171eff47d6a0544d680f5240f1714776c01591c0b refs/pull/4418/head\n00418f3043b5f925b90921303654c6fb60c9d699bbae refs/pull/4419/head\n0040214f1a3a0b831dae6140f1322d935ec18d1e69f3 refs/pull/442/head\n0041bd7995bf6af50db653a7c8221e048bb68f6212fa refs/pull/4420/head\n00415d6798520974b937d5e37714cf674ef5776c6c7e refs/pull/4422/head\n00413108dd5c9c530b29efa786e5a0b64e4989f4f06e refs/pull/4424/head\n0041e9e99d4e0314c7ffaf1f7b99305860bc0d0a7a26 refs/pull/4425/head\n004111bd0c2d250794571e262a8bb7df893ebcfab689 refs/pull/4426/head\n0041c825bc58eddaaa497e63630580d0bc8aecd3d6ed refs/pull/4428/head\n0041cb6b7657c8f65a3c9f437b0eecf6f7e49bd38661 refs/pull/4429/head\n004031214408ca2213dbecc787791d6481eb8f98318d refs/pull/443/head\n0041393b8fbb5c0db752904efe5846b5a19bfe7476a2 refs/pull/4430/head\n0041edb4dc5344139e67215cff2a1c73abdf4e3aa422 refs/pull/4431/head\n00416d29f505e508ab7b7c26fcc92a4bde8193b4bd5c refs/pull/4432/head\n00410026261877dc51f2a42f7180d7b92eb9786accc3 refs/pull/4434/head\n0041a47cc67387d54314db3c2ce06a4ba2a194ae8fcf refs/pull/4435/head\n0041ba3a41b3b80a7f74732ed7d89e6f63ff9a473a2b refs/pull/4436/head\n00417cbd90ef8ecb3dcc43d79be3aa1fa7455ca1cc37 refs/pull/4437/head\n0041e2ee8e3a38d6636614ea927a716b266b90e9189b refs/pull/4438/head\n0041878371c190328ab5f7b7e393461dc4db01f64bec refs/pull/4439/head\n004055e6503606850b8b972554070ac6e6f652744d13 refs/pull/444/head\n00418d1b1e8cb56058ab318a4b3e01ca5b6cc6ef31b8 refs/pull/4440/head\n004118adc77abd42a2a97692dd03ce8a9f24c267024e refs/pull/4441/head\n004151a52d4d44fd3bd3465f4b5931cb5527f34900dc refs/pull/4442/head\n00417357e10e43c97db7999563c361860b0b45cc078c refs/pull/4443/head\n0041223dd8d3ff8e564b20a325d94d99101abab27461 refs/pull/4444/head\n0041866307738b1ee6a88c33b5e727b72ac3392fba2f refs/pull/4445/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4446/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4447/head\n00410250ff18eb930132e38851cc119c066a780f0051 refs/pull/4448/head\n00415127b14a1cc0bf6d1b0ee1788b23253c0d6da3ce refs/pull/4449/head\n0040714567aa8531ac2d5be17d02dc07382c13d314b8 refs/pull/445/head\n0041dc77dbd56c975f38e568ad1f4697c9066130af4f refs/pull/4450/head\n004142510ba93c26ba597694771b2ea1e343ac9665c5 refs/pull/4451/head\n0041597ae4fd7e4bb565e1772d36b8faea33787dcf67 refs/pull/4452/head\n0041cce86f319241ae1b6e863878a78452e2085e0b60 refs/pull/4453/head\n00412e602ad31073d394f5d29df839dd1195c96be8d4 refs/pull/4455/head\n00415a347bfde8e51694fd2ebb33dd4c354d3771ff2c refs/pull/4456/head\n0041ddfb5d83db8185fd2b0d966ddbaa1065167a5aa0 refs/pull/4457/head\n0041b18d19ecff7fc692543bdf0980042a96403a2b4b refs/pull/4458/head\n0041c33c7fccdf65fa4f6999e315f1b503ba53355966 refs/pull/4459/head\n0041f44075bcff294fb816020601a2909b61c7d17bc1 refs/pull/4460/head\n00415b2e18e273f17dc312f569e4bc3bfe914d818ced refs/pull/4461/head\n00415d7647bb1f8ee435b0cd6c241d92452264ad2aa8 refs/pull/4462/head\n0041add6ff4405a5207bcf9458e9f585f3b6a048bf48 refs/pull/4463/head\n0041ff700e139856650fcb9788bb35979d8e7dd42bfa refs/pull/4464/head\n00418d96dbf56723b1bf995cc64c87e9b928172b1c61 refs/pull/4465/head\n0041734609f2e7aaf863c76cf377dcb9210f10be753e refs/pull/4467/head\n00413d668186d21fa0b011d3afaed43c9a0d8188cca5 refs/pull/4468/head\n0041e0cc281310cd3db615ba985889d579d89f12510f refs/pull/4469/head\n0040b9b465c2b3eef979ace3aaf02a7a513e965432a0 refs/pull/447/head\n0041b33f0eca90dd8a9571fa53eb957671885158ba3a refs/pull/4470/head\n00423c62a1a1b8b7367d8c4ff1320105cc02b9ca47c3 refs/pull/4470/merge\n0041619f6c35dcb9357136f547673e39d3a67737e1aa refs/pull/4471/head\n0041147fdfa5f76227c4b253f40f456f191226a6a106 refs/pull/4472/head\n0041867b32ec676d9223452b503ad6437c7be322973f refs/pull/4473/head\n00418d46f3192149759c1e4afe47e5c2277bf8ba376e refs/pull/4474/head\n0041998bf812eb7fb00b02df12e38b1652f893dc634e refs/pull/4475/head\n0041b1d96537b6fe479f0fc974a5d2d46508cbd82d17 refs/pull/4476/head\n004110f37fb948ec36817c3a51a9d5115c45c4812471 refs/pull/4477/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4478/head\n004107b0469490a46e03086955f5b26c8d06a9306800 refs/pull/4480/head\n0041e56fa1bc01c94ffdc8d930f6a4d5f887336cb27a refs/pull/4481/head\n0041cd8b630989c0e20134f07784bfd406e8628f78b1 refs/pull/4482/head\n00418fbe327684b1ffa47c632a59d1cef3fefe4ccd18 refs/pull/4483/head\n00410fce52b2766840f5899ad13d62050013cb948967 refs/pull/4487/head\n0040aa975625ea6c2a4c817af8f69ffd733db4782b48 refs/pull/449/head\n0041e415e72e208d1321739670fe5e9e451c98effbae refs/pull/4491/head\n0041233ebaa10e3d7d23410eb76529b4c2bcb5a7675e refs/pull/4492/head\n00411c5f07cf0df3c3c21abbdd7fc20f373bd814b4be refs/pull/4493/head\n00416ca09316b635624c23590c6d0ff4ab058527151a refs/pull/4494/head\n0041fa4d1b2a0cdee7f99143b08367875d84709692a0 refs/pull/4495/head\n004116a98018d279eac22141ae1ac3949984f4d130ee refs/pull/4496/head\n004161646e86304cdccd9c36fa7ddb179a053a03bf46 refs/pull/4497/head\n0041b212a183ebd36aadc440911b27b8c5d4e11c7f2c refs/pull/4498/head\n0041fc79b5bee6c8f3f4ebb4e23238109fc9276c2dc3 refs/pull/4499/head\n003f128c809bb6fca55127f0d89f87ab0b108fc9b036 refs/pull/45/head\n004021a5af031b8b38c19ddf2fba0b2f2623a0a44902 refs/pull/450/head\n00419a9acfdc9c14a7f5d295eb90b499bf3161f4103d refs/pull/4500/head\n004110ceb6eecada40625780fbf4d0a131ea6355c3cf refs/pull/4501/head\n0041ff6e72e3f0756f2659a002d5e68a90c3b25b34e9 refs/pull/4502/head\n0041b923b5fcd85f2ffd35465a09d19a2e7ef529753f refs/pull/4503/head\n0041899933548672c5430ca15e7dd62c03bc3413ab64 refs/pull/4504/head\n0041cc0f43abeb5999b58248d5444fb0e09418c3a5fe refs/pull/4506/head\n004151afee5f450020764cc181505210d67009242209 refs/pull/4507/head\n0041b24f9c09efde732299593330c8f313b488163064 refs/pull/4508/head\n00417bc8e4743f43034fd97f5bcb04d4808862a0e9be refs/pull/4510/head\n00419d533f916ca0418e4c56eb6d9d1680a831055d6b refs/pull/4511/head\n0041b23b1365e538126b41b429cd7ed8b8013f8b8497 refs/pull/4512/head\n00416296cbed9311b0f6fcb0cec1b530276c40ea9e40 refs/pull/4514/head\n00417acab9dfa400380d509c50fe7ab39aeaa43c13ce refs/pull/4516/head\n0041c6c07de7a470ec7bb2b1a417691e15ad59468b65 refs/pull/4517/head\n0041d7145a70bd77e8e4c69c7df953c0fa0e41d59584 refs/pull/4518/head\n00411c72ff700f8157b4c72fd2d3ceeff4eb6d9ed7dc refs/pull/4519/head\n004100194efa32b0350b4d31b058541e6fe25d92df9a refs/pull/4520/head\n0041d6783f79627838f22e1024e36de509c0f724893a refs/pull/4521/head\n004149a32d99f2e4f1b5550347b7aa0a592356e331ff refs/pull/4522/head\n004197801e05a0a75dd338ea4bb6ae7711446817d6a2 refs/pull/4523/head\n004182c5c5b2dd7467f6b9f6d1df2bb2625ef0b6305b refs/pull/4524/head\n0041d15f3ff9fa9f2b24b33619aaff76eb4f4815a461 refs/pull/4525/head\n0041cd24dfe9717762a3f9590a1d2093accae8d0ecf7 refs/pull/4526/head\n0041b6beef217706fb5f1a339df1aee052e7d00772d1 refs/pull/4527/head\n00412b1a9712618defdf186eab9cd2ea9f96a9e8b00a refs/pull/4528/head\n0041a69afd2ff7d7ed8607a5339e2643bcaefa8b2739 refs/pull/4529/head\n0041ccef4083747c9fcbe128bcd5045e64eb790f5323 refs/pull/4530/head\n0041b7fd051a40f38d76c44a4ace3f93913404ae1e33 refs/pull/4531/head\n0041266004cca3544184a10159381e3cdd75071fc0ea refs/pull/4532/head\n0041d0a9cf0deb9ca1ad06214a29ca6d71354b17f0b6 refs/pull/4533/head\n0041a4aec3c249bbdebe1e5e87c2e8ac64e14b67d2ec refs/pull/4534/head\n00412de6485cd0de281812822091cf7fc7055830fa25 refs/pull/4535/head\n00414b83ee3013338799406862d1d25cbd42825ffef4 refs/pull/4536/head\n0041f166ec43c5d8f611093b4116f96469993f3b3a88 refs/pull/4537/head\n004178757dc74535f4f8289f74edb76dc8fbadd2194c refs/pull/4538/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4539/head\n004057438b74e79a243fc8337039df968a56a47e1e04 refs/pull/454/head\n00411d7fca817eda07c83fb84c950d8325c2f9003158 refs/pull/4540/head\n004288f76b9b99d52db4578994b0f53a606cc7069036 refs/pull/4540/merge\n004145e8f08f97a0f5516ea1d96cd87b7e6253797ce7 refs/pull/4541/head\n00414cb3f8db869a061fb2d8bd10b21851945db27d88 refs/pull/4542/head\n004173d757a4307d837058006943fc8e23f9b300018b refs/pull/4543/head\n00410ae816cc6eb6ddcee5ee9dce6a763599232c85d5 refs/pull/4544/head\n00419f6977f06e96a9f93168ff34c5e0322ba65be3be refs/pull/4545/head\n00414c1da4f045d8a7349a95b62f7da800485f2067ca refs/pull/4546/head\n00423bd03f218c4b85f52d71b62e950d34b468227b35 refs/pull/4546/merge\n0041e07be325c0c0cd8ea0a1e489212428ef8fcbcab3 refs/pull/4547/head\n00428b87511fb05e3258cec90c8ba9730bf66ba23a50 refs/pull/4547/merge\n00410a4eb2562c76879c214839ced806c1b2c1cee89a refs/pull/4548/head\n004119651c0b0a987f650de2aa0c3b23dd238887d222 refs/pull/4549/head\n0040a0e52ee79ef2775920ac85443863e30b1c1173a8 refs/pull/455/head\n0041e1567979f5d8f403d00259b33fc94d7d5d8cfd33 refs/pull/4550/head\n0042ad3bb7df33ce8dd505a341fdb4e009b751986ace refs/pull/4550/merge\n0041b09db91200154e521db1ae9acbcee93a905de457 refs/pull/4551/head\n004235b3f1b514068c1263d8ab1e1e069b77aa75be70 refs/pull/4551/merge\n0041da252021206c06495d714fbca2d7f9eb49e0bede refs/pull/4552/head\n0041b635659866d8fa64c17761d392157de69c299868 refs/pull/4553/head\n0041034c72c9d67ce5836d86937c6193e23e48dc84bb refs/pull/4556/head\n00416a1ba7ffcfa992b6beb258e89e1352c25b2ab6ec refs/pull/4557/head\n00416a293360508ad940fc7fd8dcfbe40516fcc7ce86 refs/pull/4558/head\n004143ba2e3a35a81a8983b7e256c114296f66036628 refs/pull/4559/head\n0042aa2d6a4ad9f7c852e4fd6c22b90731d3cd75ecbc refs/pull/4559/merge\n00405cb5971d55f57b60684d9751fd452bc631916934 refs/pull/456/head\n00411d993a71d58308e5fc6abd5cbcab5558a79d5f1a refs/pull/4560/head\n004113822f7c31b4c4bd18644e23cc0e10febe8193a5 refs/pull/4561/head\n0041aff57c6e4007d6a60e38e3351d765f03b4d35319 refs/pull/4563/head\n0041125abaeebe0a26d5b59db33963725fcfe4dbc291 refs/pull/4564/head\n00413d816c95b3b39a06a387d10209110b8a424125cf refs/pull/4565/head\n0041e5a2d577057ff50f55653eea69a2ae15dbe4872a refs/pull/4566/head\n0040ef8e6f6023dafafc83ccf7252ae15b056210fa65 refs/pull/457/head\n0041ad6b9c3a50675440e93f954406cd2b4db23413b1 refs/pull/4570/head\n00414ef79b0722ab2c04a187b070751746cc8e80b8dc refs/pull/4571/head\n004183dfa578aac70f07a2d7babf99ac05af72470377 refs/pull/4572/head\n004207feaaf039606653aae554618b0a5f1105df525b refs/pull/4572/merge\n0041ca02e192bd9f65d1f3e6b7f4ace40b151cbedd68 refs/pull/4573/head\n004101d2c2b5739af27612ddd00da094e38281b8a9f1 refs/pull/4574/head\n00416657519f3601febcb6343f6f5e3b2fe5d12dc686 refs/pull/4575/head\n00417b1a5c6ca2f8fe930d9eebbeb005e4b53f1cd090 refs/pull/4576/head\n00416040b6747a3e8a7be3193ed779a79f86d9a925c3 refs/pull/4577/head\n0041db669a90ff173429ef00945ffe9dbb9dc1893468 refs/pull/4578/head\n0041fd3d44277c859e7a6ff55572e2877cebe30f1e65 refs/pull/4579/head\n004081764eebc88f482aefba3bae569432a017c7e28c refs/pull/458/head\n00411cf348b2f825eb841cddb8008bf8b479dc5cca50 refs/pull/4580/head\n00416fe139c1e777fcc0b6d0ed3558206a110b5a50e5 refs/pull/4582/head\n0041918099ada2b9d6a14bfb7a6ad492ccd711b800c5 refs/pull/4583/head\n00417ed9aeda5b33f63b880a45fdc5446e5db9549532 refs/pull/4584/head\n004292b16ab7bb17eda0db8475b60fcdedf23d027f3f refs/pull/4584/merge\n004198349f433a09eb4d1b4b356465b9caf3d733c748 refs/pull/4585/head\n0041d62db24488b4b95e44bd232f6b72be3057543cec refs/pull/4586/head\n00410356afecd14dc8c226799107af5f4b36bc08d80e refs/pull/4587/head\n00414e07233f02c18866ba6dce17d99bd5c78b6e4026 refs/pull/4588/head\n0041d2ca8cc64c71dbf05d74224a7a7de449dd697886 refs/pull/4589/head\n00407a801651c73cfd940929030a727de719728ce93d refs/pull/459/head\n0041bdd996ebd52c17aeb08ce5f277a909a72c7d8c30 refs/pull/4590/head\n0041e4327d276694280efa6b74b48cab92be702d7123 refs/pull/4591/head\n0041586b5cf9466d18d7dea895d78753b05b311fec08 refs/pull/4592/head\n0041a48e28d0d3d289262281e402f50edcf652432937 refs/pull/4593/head\n0041924112d93b83dfbdf271e281d4700b2917d929ae refs/pull/4594/head\n0041bcd71108976f129dac0c33b1669c72241f854e22 refs/pull/4595/head\n0041fd9029a6a53e0c53641553111c727cb963b713d3 refs/pull/4596/head\n004153da93dad22db51884a8d846c438b749bf1d26b1 refs/pull/4597/head\n004136b75f633a7b35a3db5135d32b99a256adfad962 refs/pull/4598/head\n00414dc4e04a6909135d3680033601c826e0c62f3593 refs/pull/4599/head\n003f17f025d395375c10d8caf9405f854c3ac2a71029 refs/pull/46/head\n00408e8824a4cea0bbd102d2ecd74bd370b7ee1ea6e5 refs/pull/460/head\n0041bf7bf6157f802f4f7a97749e554cb518058f9a1b refs/pull/4600/head\n00414b83ee3013338799406862d1d25cbd42825ffef4 refs/pull/4601/head\n0041e44f5c1f6651c2351e30344e82d787a8b838df50 refs/pull/4602/head\n0041735064d0700f68cfd763aa2d0ecfcd4ee924e0e0 refs/pull/4603/head\n00410b3e6f42f7e508a65ecb8ec83ff34d26d2794757 refs/pull/4604/head\n0041c646e347c7744780fc6a0c52635f136b0f8dff22 refs/pull/4605/head\n0041d3f49e2ea0b7fccbc9b84c4b41597fd0f3cf32b8 refs/pull/4606/head\n00416767c8ded275dabe2a757cbd7f9319bb9c308f38 refs/pull/4607/head\n0041c3867bf3fd4cba1d08fd14212b6bef0aa63b0660 refs/pull/4608/head\n0041b1b96ba889d85419d557b33e4b3d07a0481a12d0 refs/pull/4609/head\n00402ad8115ec45b86b82cc7cb16479c86d27fc2e3ac refs/pull/461/head\n00410c3b865c16b0a520239924e8e87a95a284e609bd refs/pull/4612/head\n0041f7bfff121303771954c5c9306f4aa847ea184c75 refs/pull/4613/head\n00415b1951316dea5640351ecbbac2cc898564b25202 refs/pull/4614/head\n0041b41d9f8b138d6d57360af78b44d4839e22f38389 refs/pull/4615/head\n0041d0b3a3ddfb64e57b68df40a235ed94509fe8bc46 refs/pull/4616/head\n0041b289320df984eb44e60ebe77ab23070c79ccac32 refs/pull/4617/head\n0041f41a6c96d9b6e071f0cbb6abb50edecd9e03c53c refs/pull/4618/head\n00415a24bdd436ec85faf286ec06875c149e7963246f refs/pull/4619/head\n0040645c7a8624ac1a4f14b458244f75cbd7c4e8042b refs/pull/462/head\n004142531a4b2753f0c21ec9a1b10ef14b157f508a8c refs/pull/4620/head\n0041eae6eda0a590e0ad731462df728bffe5f02035f8 refs/pull/4621/head\n00411d20e0ca1ff1f7775460e67265ef376cd76e7220 refs/pull/4622/head\n0041e89a75b4106589b7f93f87a934d29dcb75c82910 refs/pull/4624/head\n0041d613ce4f1e239f942b8ad135fec5fdb661b28098 refs/pull/4625/head\n0041339f073724613569b5b0a8b69550f5e6f86d4376 refs/pull/4626/head\n0041f17bd6be456e70c1db78eda5965d7c5e869245dd refs/pull/4627/head\n00413e6094791e7f7e2db36a1a2b551da0c1f684d0d3 refs/pull/4628/head\n0041e5e2bfd7d29dc6ee14f50f7fb3cbf8e9fcafb3f6 refs/pull/4629/head\n004043edd2608e6e8be14b6c71b0805e14736f5c0db2 refs/pull/463/head\n00413d193d7877e90df0999787449e5021833e3420e3 refs/pull/4631/head\n0041149c4d4a4352dff2db6acd5247594be51f136a09 refs/pull/4632/head\n0041070a0d2c98c87fd0f3157b64a609f99ba86fa7d4 refs/pull/4633/head\n00411e06341f28d933e446744af72045dbcce01864d5 refs/pull/4634/head\n004153ad7d099b4dec582d4b7bba00cada5660a97270 refs/pull/4635/head\n004157f187ef2130f5b09266e1d581ec880e8bd05466 refs/pull/4636/head\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4637/head\n00419ad501bea8c78e1946dcfef5b362068502dca2c7 refs/pull/4638/head\n0041f1dfd356314caa5d480fa7d27f00c2e3e3767af6 refs/pull/4639/head\n0040a8e02bc9f84fe22f8d5ef368f4bc52a3d51ccecf refs/pull/464/head\n0041ac83a8d0ef16e56b5a2754fcdd31810d1c2f33cf refs/pull/4640/head\n00416015c0ace1b4434337cdbec58555ed4f8c313f73 refs/pull/4641/head\n00411bd7f283688873c2848ca0dfff64d390293269d5 refs/pull/4642/head\n0041b207a94f1772445cfdedbe9a2207ca5335d8db9f refs/pull/4643/head\n00410a1bf6fb84d3ec374fdd66cf2b9726ad80674b06 refs/pull/4645/head\n00414596cbce1bef5f456dd0e26c5b863ae05d00244a refs/pull/4646/head\n0042e9d1fd4a0736292538f936fee2b2b0fa5bea9dca refs/pull/4646/merge\n004152e42b25386c17e03a4e54f929ab753702482966 refs/pull/4647/head\n0042b021cfb7fb16c3618559692ca5dcc2c0082fd94e refs/pull/4647/merge\n0041f3ba778cf6b27bc2944ec5cdafb67a71789d8ad1 refs/pull/4648/head\n00420373e282786505981e8275ae47f4273e6ad7d7f1 refs/pull/4648/merge\n00419da4f74bfb9f43eb713c4cf01b5d3aa70951ee0d refs/pull/4649/head\n0041f07e60b6e8dfbb2b5659b2e02b2c3f678525b394 refs/pull/4650/head\n0041c70033305a3a2879c786521d8f28a3e791ccd2df refs/pull/4651/head\n0042a54abd0abeb402ad871e0c1a1e1a2b628054d1be refs/pull/4651/merge\n0041b5f5b05b4ccbc9125b751c028cc2ca34f251d111 refs/pull/4652/head\n0041f922262ed029bb03359337f676872e77f3817f28 refs/pull/4653/head\n004124ad88a5b05e61c98c04b63e658edc2a9036b9c4 refs/pull/4654/head\n0041857fa943448ac2f300013f6848da1318cf7615c1 refs/pull/4655/head\n00413ed92e000db5f62353d62e735ed3bd99e45c7ede refs/pull/4656/head\n0041dbd849d2d69d52938439c8a4cc21a0c1075f110a refs/pull/4657/head\n0041ee75191c8e58633f70cbb0330914e1426e9989cc refs/pull/4658/head\n0041466874c00046a019399fec843123226063c68c2b refs/pull/4659/head\n0041652cfe101926b48c0348a493db6c60bed37ae204 refs/pull/4660/head\n0041cc28afd832b3d267568dc218f708c0247690ad69 refs/pull/4662/head\n0042ad218eadf50546950ee11a0ad9dbd4239b167d85 refs/pull/4662/merge\n0041ca5c578189e2769aaaa150c9e985f99d9c4c1018 refs/pull/4663/head\n0041a454452752d015434d23f8751175ed3f853958bd refs/pull/4664/head\n004187769ab8edca7b8f7dc66e8afe5d7943a9e38221 refs/pull/4665/head\n00411d732f3fe14108a734008d43d5244c7df243152c refs/pull/4666/head\n004144b3283a3180d2eba0a7da45cab1f15cf43a0b8a refs/pull/4667/head\n00412d3e719533830318162dfc73e232ecf4b8ef80b0 refs/pull/4668/head\n0041a4fc5b66f3b23412b1b7d23dec17c1600c12c3f4 refs/pull/4669/head\n0042dea1ab31ae5bfa554f9ef5545e3e652dd564c962 refs/pull/4669/merge\n00411dcfe152bb9e5f0f109dabd0ba53227994cb0aa4 refs/pull/4670/head\n0042e5d2ddd9756f32ca22fc37e22f2cca52af672d32 refs/pull/4670/merge\n00415e0ed433516a5eff6a33b754f2caef2b4892e410 refs/pull/4671/head\n00423a16c35f98d705649baa17fb703a5e7f4281d5a1 refs/pull/4671/merge\n0041b05ccffa307faa4a2c9c0067e095a64b237561d3 refs/pull/4672/head\n00425cb5b2cfcc9afcc99d28f764cf1cb0573316c0fe refs/pull/4672/merge\n00415a5ff38051a5ca526249a10cda25f0932a8e5bb5 refs/pull/4673/head\n00412470830a0585b755e44a76996e8df6234932659f refs/pull/4674/head\n0042718ba688b6aedd99527bb03fab6d7b7f73b96ea6 refs/pull/4674/merge\n0041c299c85a5d73c9ddb4a631376173f21bf52a6603 refs/pull/4675/head\n00423810d5fea7faae85482d1e42cd419119c0ec1703 refs/pull/4675/merge\n004138019c477faed48bb9834fdf78d761d9bcda2026 refs/pull/4676/head\n00423f0cd5c96095298a47fe4c9db053be43ec934f34 refs/pull/4676/merge\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4677/head\n0041f9f90576bf467876f38e70e014bfeda6775761b4 refs/pull/4678/head\n00410da4547ae37fbc12bf447f522ceffbe99de4154b refs/pull/4679/head\n004166c5a881a5c0a7612af16a07414c78b777036564 refs/pull/4680/head\n0041c193385925c2d0b4109ccd55d2509f71d5c8f775 refs/pull/4681/head\n00419f3705f85cdf31abcd7fafc35bcbea673904fd76 refs/pull/4682/head\n00414069414bd7faf9899ffb83b1f364230ef149d392 refs/pull/4683/head\n00412f574c4088f002052f61a8e41e7c77da1d029099 refs/pull/4684/head\n0041f9f90576bf467876f38e70e014bfeda6775761b4 refs/pull/4685/head\n0041337773d1f3c26d37ebd4aa94a66e6884c24c4e53 refs/pull/4686/head\n00417e419b3eba7bd83e496a22db2b78917534c46dc8 refs/pull/4687/head\n00415cc2af0e3bab7eab2af1c7b1780ed33149a54780 refs/pull/4688/head\n004191c7be7e6a9d2e4857424142f74b08ce4295ae63 refs/pull/4689/head\n004019e4617dd5586b7379228783a7dafeb3ad5cd6d9 refs/pull/469/head\n0041660485339552438a864a5aa7648299071d85d8e3 refs/pull/4690/head\n00413f9e8926fb6af395c7cb3f798addbc0660a62c92 refs/pull/4691/head\n0041c943a738814c4fd29a8130273ae2e39f43c2bb18 refs/pull/4692/head\n004192a9a438fb2a2f8f53f1d6073d7eefd7293da553 refs/pull/4693/head\n0042c63a5959cda3bcec88d3464acc0f7c66642e34c8 refs/pull/4693/merge\n003f539bb6345b3c521756c3c68fe01fb5476107f4a5 refs/pull/47/head\n004015b2c3c4fb3212475bb30d16a595d3a48754572a refs/pull/470/head\n00407425fbb17e658c1bee3286023c1be47c1be1a268 refs/pull/475/head\n004009022111d128e5a2b92d7b332bba42b6c0cc9481 refs/pull/476/head\n0040c32943f2eb274bc1228e9e8b963ff23e493c8b06 refs/pull/477/head\n003f7942542b7dd62c0dcfef6d099ad55bd4001e223c refs/pull/48/head\n0040da63d307f10488113dfd52696218ba82e66888a0 refs/pull/480/head\n004008724c7dedf66677e18fb4e877c20b947a4dd280 refs/pull/481/head\n00406f75999d1287efdb029d48e401917387e8176f44 refs/pull/482/head\n004077e6725ade995f3645a437f8f7d01eead3d2c4dd refs/pull/483/head\n0040fa824a4cf86acfc9fc7635f2ca89f578b11a27ff refs/pull/487/head\n00402610a4e0aef51b5b50cfdf88ed6cef4937a1c4c0 refs/pull/489/head\n003f828d3229892fd337355b2856b1e143c9a4094b7b refs/pull/49/head\n00403e436f16bcc8ae364867d9856fa0313f7fe1d465 refs/pull/490/head\n0040898ab0d1f6a863e64cb2c3054352efb975d1d5c6 refs/pull/491/head\n00406afdc81c1d56e7f166b33bc9465bf5735ed07a00 refs/pull/493/head\n0040421a88cac4c87a4199cffc08e7691af1fd094eac refs/pull/494/head\n004026347349cd6a174d168045bd73247df1831fd8df refs/pull/496/head\n00400da1b610c614aaa0bfb1cfc1c10f41080ff9589f refs/pull/499/head\n003e3f49bf73cc697e83b998d15d4c24b3b2c3cb422f refs/pull/5/head\n003f7bc22854376474f99e947eaae5bf55356033295c refs/pull/50/head\n0040bf63148464b0f0fc6c22ad407eeeb9ed1a3fab37 refs/pull/500/head\n0040fbc22f7cdfc425d0366f44dfa63c289f44251fd4 refs/pull/503/head\n0040d44738e6a75cef1e7dc125c06ac945928141f490 refs/pull/504/head\n0040427e5971ce9cf4b05e1588d2066e2538a10f937e refs/pull/505/head\n0040738aa6298e56eae85a6cc212ea98b3ced3018cfe refs/pull/506/head\n0040dcbea96afc409df97fec6a03581268c818928c44 refs/pull/507/head\n0040ea0cd0b85f34b49b41121be2e1fc4d99cd62f95c refs/pull/509/head\n0040252460ebc4d89d1dd62a5e612219d8385649fbcf refs/pull/510/head\n0040a848819f56bd450742ce97cfde7a1b1c795f29c6 refs/pull/511/head\n004030158afd5f5c4314b954c222995dfbe5a0f6df6a refs/pull/512/head\n00406e075100aa09016ef384ec63c236244b32993e7d refs/pull/513/head\n0040ac40a5c9a4856ba3dc47533000c771557539cfe0 refs/pull/514/head\n004019e615fe83f329f04795aa8fd731691151bb114d refs/pull/515/head\n0040d1e6176b7bb89fa6c8ea59bdb94fce36dc20a3c6 refs/pull/516/head\n004023eb7dcaa2cf76e6c3187e95abe5962a5d984b17 refs/pull/517/head\n00408674ea9c7625795693f59620466dd3b91e1acf6c refs/pull/519/head\n003fa5aae997547532051254c3543fda04ecdd19e151 refs/pull/52/head\n0040fc6f375311fba3fb12d1cf6cbeaa642eafd5bac8 refs/pull/520/head\n0040ba7681ee4add1983739689110e7aaae5217bf1bd refs/pull/523/head\n004095935609f8ceaaec8d796ac895526680beae5a73 refs/pull/525/head\n00405f50e2b6afc3c5a97f24e6662359614b880cbeb9 refs/pull/526/head\n0040da429589631564615fa152d04ef8395c05bdc2a3 refs/pull/527/head\n0040a4ec96c9a96bef7a2f2318e1afdeb3e768373713 refs/pull/528/head\n003fd92b753039c86313e6163de3beec7e80e7715409 refs/pull/53/head\n0040b9cc4337fb099d98b1794d6245d2d16413be0843 refs/pull/530/head\n00409a5c0ba757500434d094996c10086fc1f137f26c refs/pull/531/head\n004026bf9a128ff64e0c41da850df451fefc9752b0cd refs/pull/533/head\n0040f641a629b070e48aaa81110f5ede97c6a4c5d74e refs/pull/534/head\n00407f0c4e8bbc6feb8cf54ca2aadf9ec681f79f031c refs/pull/535/head\n0040eeb08949f3b66a5988f2d22a7a09ffdc34c95765 refs/pull/536/head\n0040187e24c0df8e76a9d1221f295451cb5125d19b65 refs/pull/537/head\n004090263ab68bd9a54607c3e087b98b0e615e193c3b refs/pull/538/head\n0040b2f2ba8f1502c725d92632c35307b06223605d5d refs/pull/539/head\n003f4069e9ae46887eaa1ea25c0c41990d4a152aa790 refs/pull/54/head\n004008d0fe5bf8f16f7f129dd6b16c076680fa70bc47 refs/pull/540/head\n0040fa4afd68017c51fa9c8fcb234f7b089a6a6bbe16 refs/pull/541/head\n0040b643a0cb471374c0d4fe2c8bde45f7594e0f808b refs/pull/543/head\n0040fe94b87d5fcb2289f2c49ae49e248fdd8c49b335 refs/pull/544/head\n004022da7087587feb96d7a1d4f179661381d49bb32f refs/pull/547/head\n00400c72efdcae6f3e9587ec6a4b63d1946decbf5fc2 refs/pull/548/head\n0040192ed93b86cb77de447798c3ea78ec0722bc6b83 refs/pull/550/head\n0040db24d8b17db7af20dd8cfdcaedc9af2c78999bc1 refs/pull/551/head\n0040b47ce783b533222dd8cbb1afb6d9751e9b4b5d4a refs/pull/553/head\n0040c2af63cc54340534c6bcf4057d99889b20b47636 refs/pull/554/head\n0040532b5912133864cda5255ab022d4e5a66ad6d26c refs/pull/555/head\n00406ba69f1c26ff46164fba4b7099f3cd7c22ab6dbc refs/pull/556/head\n0040bbdec22161a3f6db0f3b40b8936f4a1adaaa58db refs/pull/557/head\n004056dfbe6300ff4b2063a57341a61f46c7de7a70a0 refs/pull/558/head\n00409ac3f6d893e9ad8f45ab12316f02c6a9ff55319d refs/pull/562/head\n0040ba38432d6c7074beb6eae72d03bdb567b0f713d2 refs/pull/563/head\n0040fc97f30299e11bd3fbafe60764a31731f1634c40 refs/pull/565/head\n00403b36449491233aa92160be5b68dbba193d9076bf refs/pull/566/head\n00404eba0eb5150020b0d69521348d7fbf3a2c44c1d2 refs/pull/568/head\n004049f841c25b74ae3cd508751de9dea5a95791bea5 refs/pull/569/head\n00405eb4c715b6984f702da1623dc8fe3f17345e562e refs/pull/570/head\n0040c8284062668d32d8be4012eb6b3571601d88dc9c refs/pull/571/head\n0040cca202c87decfd33298805d39f1e0ce5d7706e28 refs/pull/572/head\n00400b5104a4cd274324a53d87db88e022db0c0b72d4 refs/pull/574/head\n004020d761e3eb61a0321240c667837033944ef5133e refs/pull/577/head\n0040ffff07627e6003dc180c47795d625265e49eaa64 refs/pull/578/head\n004081ff890139cf9f07319e35b0ff3abadc38171de1 refs/pull/579/head\n0040dc64e918011198790c27d086755312368dca98f6 refs/pull/580/head\n00401765f3e868446b5c3e62da393a56dc09ffc72f49 refs/pull/581/head\n00409d58c1bc6e71cb1642b883bd4dbd0d835de240bf refs/pull/582/head\n0040ab7f0f423544887488e868ed5e550ff354490960 refs/pull/583/head\n004071853facb839d4b1238a354ea0a351d49c1e81ea refs/pull/584/head\n0040f13bae2c6d98b3e4030829b22fc821770ac72bc3 refs/pull/585/head\n004044d51ed2e50cb3e102563d166911eb7f6d2d9429 refs/pull/586/head\n004031c4c6e5672aaa3c0d93fd4bc31f7a104da8d5dd refs/pull/588/head\n00401acb581ec304067bd5f7cc1c714d8627407b62de refs/pull/589/head\n003ffe060d229baecb03798c6da631dfaa440c4363cb refs/pull/59/head\n0040811d28418a43713df02b95fcdea0918e87c27163 refs/pull/590/head\n0040f189aca712ffbce0d7b8f52a2148911ff40d8681 refs/pull/591/head\n0040dab21a93594bd2f83f32d10550737a26220a564f refs/pull/592/head\n0040dd3ec750f2ac746991fad465a44ece6515f30acb refs/pull/593/head\n0040e04698a4f079ef9e47894c77955af5c92b18ed46 refs/pull/594/head\n0040ccabdea034f6711c9da311a6100eca55b6542cbb refs/pull/595/head\n00409b069b5258813122ec05532e1746ac34e457e31e refs/pull/596/head\n004003320f72dba0bf9c4a344710f69b87a157afb22f refs/pull/597/head\n0040be3378dbd616d7b54340c247c1c2b40a5d2dc46b refs/pull/598/head\n0040bfc79659cddb9b15558d224e7adabfc1f8c61a0c refs/pull/599/head\n003ee8c29e0fd94218fe15baad313b095318ca35e4b4 refs/pull/6/head\n0040bae47748988b81977e7c9f971264bd982cfc42f3 refs/pull/600/head\n0040a1207a57be86aa5062efdbe7425f233d2c89e555 refs/pull/601/head\n0040a7a1e4f3ac65de68af18f37122ffd61d17ef68be refs/pull/602/head\n00401ab0afbcd184742884308a6e56a3e33644e54cba refs/pull/604/head\n0040f90a58db535e3ed8615765985e74cf47ce6bfc3c refs/pull/605/head\n0040fce4824468778452a19d54587b292d54fcdee132 refs/pull/606/head\n004086229944c849912189292564b8fae2dceee5e358 refs/pull/607/head\n0040a33c5dc6f1afd4da09eb21b05d8e6b320bcf82f7 refs/pull/608/head\n004005da03548ea276a0e83bd3e09be9834a8335d2b1 refs/pull/609/head\n0040ea7aaf0e0c534a82dfd0d96e5ea91071c244a418 refs/pull/610/head\n0040111df9afcb9f748713819c7c5abd425a97d694fb refs/pull/611/head\n0040988d98f421372ef5d57684393150141159a92940 refs/pull/612/head\n00406b1d7b73a159a3b20822d8fa4b5bc67c9c6471d7 refs/pull/613/head\n0040c4fdd9acb95155be5de54d9f6a658963ca98aeaa refs/pull/614/head\n0040f627af3bf490043922397ce368d3761ddd005506 refs/pull/615/head\n0040135ec824a06ae39f81f8e27c377934d1630166d0 refs/pull/616/head\n0040c4246fbc32020ea7fbbd1605fb2e7ecb7351017d refs/pull/617/head\n0040c79e8f2f0d0dbaccbc95fc72f44bbac936137161 refs/pull/618/head\n00409a6dccd8ac5f09b248d10dc6aa3207d7dcc4f3ab refs/pull/620/head\n0040c16148011d21776980eee0651f63b35d1029e8b4 refs/pull/622/head\n0040ffa7757e6d0de881a130dca0cde5d7963d231ae7 refs/pull/625/head\n004029c076ebeea8b61c3de6c63be1a80b5c36fccbd9 refs/pull/626/head\n0040a6721290f78a1a87be815aaab182427c03a6b6ba refs/pull/627/head\n0040104aa8d0df412d7fa6dd3291ee7c7cd3f9c454e3 refs/pull/628/head\n004083c3e81bc80124a7f6ffab24a6ad363d21ff6ef3 refs/pull/629/head\n00407e27c01c5dc170601315055d1de35e13f9f4fe83 refs/pull/630/head\n004029c1efe8e632d99bc52afb03ba2f8af232646ea4 refs/pull/631/head\n00407dedbb1d778ee611c89e6192a9a9169821ce152f refs/pull/632/head\n00404d2e49cf4853f694ce7623eaf7427b14a9fef8d4 refs/pull/635/head\n0040e7759b9ea0d675599b7821de4ab7fbdebff8ea28 refs/pull/638/head\n0040cce335b1462e95c6a2a34b161dcb90130672ebfc refs/pull/639/head\n0040d0ebfd4e634b2ea6ecb0ef9c24559f928f0899de refs/pull/640/head\n004080c904e3541ff766a774812e6cc07b403ea88f24 refs/pull/641/head\n0040423b62ab04c89caa94f4d2933e50c3559d0fb620 refs/pull/643/head\n004009fd6885d8fed342f58ab5bf86093bedc5f8f73d refs/pull/644/head\n0040fb069a91a9f15fda5a19280f0c99640d467a69ea refs/pull/645/head\n0040e2e6ba84e35ba11a1ea66708250d18520f28a5c7 refs/pull/646/head\n004094492d52f7afdda992c36b0a77f1b3101a45645d refs/pull/647/head\n0040e4d92d4402229891c543908362e34609d1063ea8 refs/pull/648/head\n0040ccd48f7c3bf61e9efcabf76584d188f022399c8a refs/pull/649/head\n003f9114a985e210798208c0a4b006e4ae78090a63dd refs/pull/65/head\n00400efc4177ecd181cab57ebb287ecc28e4fa518e1d refs/pull/650/head\n0040c327d3e2430cdcf6a884e191313eb3dc1b0790d0 refs/pull/651/head\n00405e8bbc98709e96d4cbd9c1b9121d43cce69c0cdf refs/pull/652/head\n004016fd8b268fd8b700dae919c7aa0cca6c949d1d8c refs/pull/653/head\n0040738b63e7bf26a636163f0ade319a0c03257e099f refs/pull/654/head\n0040057b7008fc6d9ab71b28105476c59b8349e2baf9 refs/pull/655/head\n00406ba57fb53fbc2c28bd544b434f2114d0d6419ff2 refs/pull/656/head\n0040431353cf9c9ebb1cfae7f12912175f4d4241f663 refs/pull/657/head\n00409c52bf7f8c21616ff861e18284551f15594d8646 refs/pull/658/head\n0040aa5fe2463c7ff352df80b5e96de7458720b12bec refs/pull/659/head\n003f15492d0d8857c7f1f37cbf4b2eeba4b5fafeed60 refs/pull/66/head\n00409e0f86f98534e7b417f07857bc68f4b7be17b985 refs/pull/660/head\n0040e6e452a01407ab6a5558ff813f40347dd055edbd refs/pull/665/head\n0040cd5983ed4e8ce93df2d7d12dc895f707af7f1bd0 refs/pull/666/head\n0040a66d42daf1fe9876503a21c306118c8b8a30c3e4 refs/pull/667/head\n0040f0ac8954bd8a844cf20dd045c152f807b6c75a92 refs/pull/669/head\n003ffbd97671c4f74a3573ca677cb23aa2e5dc2b730b refs/pull/67/head\n0040f0f09665d993f70d81676fa66f11c19a962278af refs/pull/670/head\n00402efdcc262931d42e199b84a0c4e4dfa8fe296a45 refs/pull/671/head\n0040ab07111508ec90a01e73ad064f5e2fcac05134ef refs/pull/672/head\n0040c525494e4a3caa74a0fb416e1db34d08a85febaf refs/pull/673/head\n004021dc91864b8ba42bdf81fce2494a2d2932d9feb5 refs/pull/674/head\n004034b5a1693bec061f8d13d8a5f7a954ff5af2a5af refs/pull/675/head\n00406fd8ad1d71226e646fc414647feff755eb9d58f6 refs/pull/676/head\n004091d9a183c2c0fdce20ed174b27526b469f82c7df refs/pull/677/head\n0040285d000103910ca736e72f43579e98cab05fc9a1 refs/pull/678/head\n00404fadd0e8495d4dc18a4656cb36bf13d229d65475 refs/pull/679/head\n003f701296e9aab2698626720502d7988f6ec8534900 refs/pull/68/head\n00403d77783d0ccf43a1d2cabbb5cfd769cb5ac08139 refs/pull/680/head\n0040984749296a631d40a888798b9da128c25e38a004 refs/pull/681/head\n0040f323d77eb48e653933df4cb8ca3e7b6d4b445558 refs/pull/682/head\n00408043886ee609e15ac71eddde29f7ad593abdecd4 refs/pull/684/head\n004098f502db014ce6cdfb4cae3bf5d37ffde0f522f1 refs/pull/685/head\n0040c95ac10faee8e9d2b2ccc1c8dc564a2315d5dc73 refs/pull/686/head\n0040a2a04afe106b835d9301cd1f55a6a661a5ec7d1d refs/pull/687/head\n00407b19026b4dd4152f609170c0984ba552770ec2b2 refs/pull/688/head\n004060da188ac6f131ebaf8a0bca72daba511885bdd9 refs/pull/689/head\n003fefc80f95b21903ffcc79f2e3767f216d40d6e973 refs/pull/69/head\n0040c4843689bb037ac6c9351dbb23bdf42920e7523e refs/pull/690/head\n00404aedcc345cd1e3398ec8ebb1dfa6d56c08b3229a refs/pull/691/head\n0040bafe7bf81405775c49d732209f40234d49622c2e refs/pull/692/head\n00400d6d7c66b246d72c0d513a5827c7fc7ca3a5c0f6 refs/pull/693/head\n0040df57af56cc3896f95f502626faf04592cf6e4d8c refs/pull/697/head\n00400d369e0ff56c300f78e1b047b9ba7fd3a6305a1d refs/pull/698/head\n0040f555322ea73895e099bbd25c09c77c3d32742620 refs/pull/699/head\n003ee44f6d00df38bf536dfa16ac854a24b30951a873 refs/pull/7/head\n003f7a275cbf35e020572d4c83f90d0bba774f8151d0 refs/pull/70/head\n004045272168ba25f1d6a15abbb1dd3d25f2df494ca9 refs/pull/702/head\n004097e8173ae22cea5a2a4c1b5d2edeba24d590c4d0 refs/pull/704/head\n0040e7e01e7e31fd80d8560ece85e949bd7ee78df2c2 refs/pull/705/head\n004042536bfa4e70e88579cf472ac13a534dcdee6f12 refs/pull/706/head\n0040a2459380ecc080174e784a92e978dfa7d8d9c475 refs/pull/707/head\n0040fcc04802804190e699b627a9311c7825244f463e refs/pull/709/head\n003fe460077786c95beaf70ca516b10355042df8d0f1 refs/pull/71/head\n004090e7d78e8be39bed87f991fc9078a626e81054a6 refs/pull/710/head\n004006a9b8f4ee2433c22f584a63abcaedc056c4dae4 refs/pull/711/head\n004072d0f4ca688fc020d2689516409e0a0241a00549 refs/pull/712/head\n00402c1924d53a679253d237baa26aa707c4d9da8884 refs/pull/713/head\n0040e65263e40790c2c3c218953acdab20072c15e3e2 refs/pull/715/head\n0040cb40852db455619fd4d11df788f87792fbc50feb refs/pull/716/head\n004025d97b46820caa302f7d73b3fd0d3e480b7d10e8 refs/pull/717/head\n00403d2e5c60f73734d85b8691b4bfe8f3bf9ace2d59 refs/pull/718/head\n0040a7844ac08686fa01bd3945a36c71083eb865035e refs/pull/719/head\n003f0ea877f58dee1d05c10339ebf3e574324992656e refs/pull/72/head\n004077372613c5eeef798728a9acef6b9e6e47d7fef0 refs/pull/720/head\n00408db2f7e637a58b9c7f8de702d7840f855e9aa8ed refs/pull/721/head\n0040177f41beea015317a3eac047648304f31f51f97f refs/pull/722/head\n00404d3481fd5284b4422f6377d83b92dec187576e31 refs/pull/723/head\n00402f2a33ed706a8da32bf11e418f64f0479f19354f refs/pull/724/head\n0040e551d9b972d0789141af4aaa572b578ecdea1da3 refs/pull/725/head\n00404b51a02f4705e9bbd497f9e1e440583ec6ba154d refs/pull/726/head\n004032fcd859db96271b7f7b12858a8ea3ffe8c5a614 refs/pull/727/head\n00404fff6d895a94d46b666e645ec0deae52c1da5fbd refs/pull/728/head\n0040285169615c3f60fdf928a4828a25a8fdaf257dac refs/pull/729/head\n003fb34196165f7f457a62afc293ab4ffed18b95be24 refs/pull/73/head\n004078172ccc0869f65b849cb08d80cfe7a3623f0d93 refs/pull/731/head\n0040928ee035554495b878806ea5493b93748c80c5e7 refs/pull/732/head\n0040d037807f6550280434189d41f4528124b59c65c4 refs/pull/733/head\n004055e2fa977cf848c1e3cb4888135556744584dbe8 refs/pull/735/head\n0040066dfdf51f0ef7968984267bfcf1ddf0013d35cf refs/pull/736/head\n0040a121195bac6e62fc2bb01779aa93339bbde7c12e refs/pull/737/head\n00403e7facbd209ec39d303416abe591c0ebe7ef526b refs/pull/738/head\n0040056bc02fe23dffca388b0c71dc765e26c0ecefe4 refs/pull/739/head\n00402a631151127562c377721506f44e8d6d5464cef2 refs/pull/740/head\n0040d2fbcdaf39656fa110558c97f1ab571591e4a80d refs/pull/741/head\n00405a1114ec4d88ff3668fe0e362dd2b62969813b24 refs/pull/742/head\n0040ed0ced879d819f2e9ed7a2a46a0597bdfd83df67 refs/pull/743/head\n0040f358d39f0c738c2c7c4cf8151bca8f08cf5e103e refs/pull/744/head\n00405b267b0fa6717f2beb2da1be354ec7da6e3d8fe0 refs/pull/745/head\n00403d4dafc7a7f3047623538ef822fe7f93a28e8553 refs/pull/746/head\n0040173c7b2fb299d6d1dfe20349263a54eb7b08bfa9 refs/pull/747/head\n004081cfe17eeabc9775da65b2f15a9cac4c390a2c71 refs/pull/748/head\n003fa2064306c0121b9a1aa51349945f2c0c25183cd9 refs/pull/75/head\n00406275137133743c4310697fdedcff40c627e27c8e refs/pull/750/head\n004068f0993f418e32413af9f50e735ebfb10c94f4ea refs/pull/752/head\n00402b32cec5276d0ae3bc64bc78f8f9fceb83813b1e refs/pull/754/head\n0040f55a27997d1c23c0b386b63e9fff8ea193d6262f refs/pull/755/head\n00408783d3640b8a971fa809dd1cad2a604ff202cde1 refs/pull/756/head\n00401acba9a0352ceaeb95654294bb27410a722648da refs/pull/759/head\n003fcc2a1d6ce103a8495ff4f3b507929029fa1a3dbd refs/pull/76/head\n0040a4aa7c7fbaedcce1f1c68704a9898a2a9b0dbd6e refs/pull/762/head\n0040ca562adde31ebf443bb6f9247f090cb3a2a7de54 refs/pull/763/head\n0040af8fc879f64d994d84db36f6beaa1356304abcea refs/pull/765/head\n00408b031bf4c886555f37f97f9cbb8f5f84ba3e9896 refs/pull/766/head\n004081b890ba1158a718d4df4f03d7c83af82b576a92 refs/pull/767/head\n0040b2d17f6de6288aaebfb19197c68a105d0daba511 refs/pull/768/head\n004001e9d0c6cb2d19a033ac0e6d7bcb88bf2ca40daf refs/pull/769/head\n003feff68e7143fdfd30c275ba516541db0844385e8e refs/pull/77/head\n0040e84a43a470bb7f472d1a49d5fe14c8f89b3fa981 refs/pull/772/head\n0040cb8262e93c0cd4d084f887e1effc050b285d9202 refs/pull/773/head\n004010931bf93d7f9834aeca8777b326f7199cc52595 refs/pull/774/head\n0040445cef5a2eda33abbf056b4e7c3bf37c7d32db14 refs/pull/776/head\n0040d073d3b75f1da574628b0e66aead9986afda42ba refs/pull/777/head\n00407ed9cb607a89a7d57ffae5fd507af7a56db19c38 refs/pull/778/head\n0040dd60736ffe81fe26ed0182e4c7b31b89bd452d91 refs/pull/779/head\n003fdf05d6c2be5809e2d85009f78e79fe33d27da367 refs/pull/78/head\n0040e05028469f918fa3c55b92c66588a53e7e19efcf refs/pull/780/head\n0040bb085e4cf1c3feac099a7ff565053538b608ee3a refs/pull/781/head\n0040118db1a7c25ba4d379b974cb9e79df363e05f10c refs/pull/782/head\n0040e932db9ea7ebf46b55669c7edcaee78d5a35afba refs/pull/785/head\n0040080e8a3a8d8598b786508898e33e6b1eb6a62490 refs/pull/786/head\n00403aca03c675aa27392e84bf20bf551b4f4c1c1e6c refs/pull/788/head\n0040d05b8a4bc1f572927875b238e07596e7e5996a98 refs/pull/789/head\n004018622bc349c54e308084c2d4b34b24aa22943f5b refs/pull/790/head\n00406b09743c2b7d220ba84a454bdbf7416875fe08ee refs/pull/793/head\n0040ae001437ad1fe79c20e10d8713b22e1d0fd77388 refs/pull/794/head\n004046b9797d8cdbd4bcbce41c3d85bc029d7fd04778 refs/pull/795/head\n003e34eaf08d34a89431d5c0882c84b9fa17908caa1b refs/pull/8/head\n0040ce2858dc43ca2f2bb87614399077d66bf9bb24ec refs/pull/800/head\n004070bed40651dbf77b56b8bb1ce937293072819c0a refs/pull/801/head\n00403ed253bef7c27d246c1c456686e95bbdbd80d677 refs/pull/802/head\n0040cdb43d4f1ccbc2292955c2315e5ac8d4d8eea146 refs/pull/803/head\n0040a896b1480f6963ea6cbaaf61415510ddf4df13aa refs/pull/804/head\n0040c36c7b4facf399d85982ca2e5f6a797b3be27ce8 refs/pull/805/head\n0040e2b4856726d3d53aa04854fa9713d27f9b830986 refs/pull/806/head\n0040e563eebdaa0362a95079661b7c22508c8d94e040 refs/pull/807/head\n00400ee37c80c0931d187305f8f7261d2070b8ddd80e refs/pull/808/head\n003fcc8715f28dafd700666d19cc38136cea248b1060 refs/pull/81/head\n004006d7aca733f2a97f169c125bead4fdf9f15f1f37 refs/pull/811/head\n0040bad54eedde4823b02aef76ad29f027b5ec55a847 refs/pull/812/head\n00406323fa304b8d1ea0b30f5255af372ea6c1d342b0 refs/pull/813/head\n00406fe4c87726530f7e1dbfd2da602d68c68db69e7e refs/pull/814/head\n0040d34f6f2d5e2628ba873f74b7432787cd3711b742 refs/pull/815/head\n0040de87980d51fe9110489e5b16eb58db6bbb1f5dc9 refs/pull/816/head\n00406e0613f124704bb9e7f186e591aa83d9343e725b refs/pull/817/head\n004012157a79870d55daba6ec78e8d0a60d7f275bf22 refs/pull/818/head\n0040dd6ce3c6e72b750253e2a63858bbae1093861dda refs/pull/819/head\n003f9d4d998dbb4cc5a5c519e611bb364f75bf34872b refs/pull/82/head\n004034438bebd4d9f64bce4c3560a859e4bd7ca03f57 refs/pull/820/head\n00407207b2633bef006b6cad7f30861be8783788c2f0 refs/pull/822/head\n00406231ac298bf965ade374df6300db26436413c470 refs/pull/823/head\n004062336dd003c07cc5c286ce0f3ab3774a5c31a612 refs/pull/824/head\n004046968d768edfb3f6186dd6dca57916e297c33dd2 refs/pull/825/head\n004097ad5aecced2f2acefe13953362f97bc2cbeda60 refs/pull/826/head\n004059fb92750d43c74758d919bb888106258da5a29b refs/pull/827/head\n004022b377d570d3ab3cf0452bf959730dcaf2825446 refs/pull/828/head\n004009376942a89475fc1ce482dc4532626161f13703 refs/pull/829/head\n003fe621b6b6e656eb468c9706eec994e214cc9f3711 refs/pull/83/head\n00408ad712de7bda9769fe5768094715a00d564c1980 refs/pull/830/head\n0040d5bdf9abbe52f4db1e27e5cd131608eeaae7989a refs/pull/831/head\n0040e05dec0d6e78948e6585f9b317025dd71d9c4fb1 refs/pull/832/head\n00404ed4040f268b03d9659cf4222ed43fc44602902d refs/pull/833/head\n0040a5965a59ba5bcc689d236cfc9616572771758a7d refs/pull/835/head\n00401f4a1d12005e416e3f5b2bc4f3a784c428aab57d refs/pull/836/head\n0040d1bfdaea98d066478100518578ff395acfbaab14 refs/pull/837/head\n0040c518afdc363706a7dceaed72544525b7d8357b95 refs/pull/838/head\n003f9169f1f08ea14d3fbe1b68b53713d28f5248d0e3 refs/pull/84/head\n0040d35da14e7b620f44b1b96c74c609b9b7921032ac refs/pull/842/head\n0040e657966ef3575b05376c51fbe7d40d357876ca48 refs/pull/843/head\n0040ec3cf43d42d8af6018a528f1440999b467b3f388 refs/pull/845/head\n0040115524d3bfee413ea472b6b9f7fc79d85955651a refs/pull/847/head\n0040e22599fd352a978201db471c884575423da0fe97 refs/pull/848/head\n00408fa56e28ad91e4be463f25dc465afcc0857b7669 refs/pull/849/head\n003fac40525168a1bf85ab0ddc2f1a1db98d12f2eda9 refs/pull/85/head\n00400ca5e64a00ed2653963337613893e97fd04e94ad refs/pull/850/head\n004035b917bdcc8dceefef5b948482f1731361832f66 refs/pull/851/head\n00403dafe29588e29ea4c751ea0b8a9abd3dbc18c3c0 refs/pull/852/head\n0040ab29b63a7ae6d672086e812604f58170059140b1 refs/pull/853/head\n004050a4b042a14e4aabd9166c8e64aece2dd3019df2 refs/pull/854/head\n0040d78b460e2fe03f1595d1aaaad5dfa3f2748bbed6 refs/pull/855/head\n0040fc3fa2c8c9d9e1f0e0f8b436793e9792bf2a194e refs/pull/856/head\n00407cdc4a8bbbb549de2f592599ee71eb869dc0f107 refs/pull/858/head\n0040ce4e48b794c9edb5d19dd5a5e1d2704af419105e refs/pull/859/head\n003f048d9dc2d9c48ca2d6d685cfae4cea7d74c075aa refs/pull/86/head\n0040abfb710d9ff916933ba72ac68062d8efe6b245cf refs/pull/860/head\n0040f4f48b5fb1288738e59a56853854930bc02647d2 refs/pull/861/head\n0040c189b851b3d5fe349399d249a90e0e68dc8f83a0 refs/pull/864/head\n0040182e26764f06d5b2be0b7c68715c14ba8d67684c refs/pull/865/head\n0040da8d774b89c336070340292a780d4089406d6e35 refs/pull/866/head\n0040ef83217f1cca19bb55f29ee2aa24630301184dff refs/pull/867/head\n00404cd0f4f6609e0877a22263b6aa8b0097b7600ff0 refs/pull/869/head\n003fc1bd40fff6ddfab1c3b4b0ec7b949b595a37f560 refs/pull/87/head\n004073d3324a956b6255e7057b91bf842c903953aa06 refs/pull/870/head\n0040ca189efb1d2ba63690064760fe4d5f44212d5eed refs/pull/871/head\n00407943f1f3061bab8519c31af04cd2865c5f773412 refs/pull/872/head\n00401a19ed0abc5ee0984002a534d94ad9d13a23cff6 refs/pull/874/head\n00409005e7448f74c76bfca8abd6ccc2eaa8033e3f1b refs/pull/875/head\n0040cb8158aec6e877cc7d19f6b8ce0d76466e9f2de3 refs/pull/877/head\n0040d9e51f14175ddc2e9bbe93dd042e1d6fa5c063e6 refs/pull/878/head\n00401c40b3f421108053afb348d7afa4cf218a1d0f68 refs/pull/879/head\n00409a5882322417a05b4f4e9624af90e4789f3cac9a refs/pull/880/head\n00408d07ee77a55d1e43753eb2f1b595e90dc7807472 refs/pull/881/head\n0040fd9a292f19de446cef18f7598e8aa671e9b8eb5c refs/pull/882/head\n0040360aa2c5e752b5454cbc4a2479d0088b38abc993 refs/pull/883/head\n00409f48dfb7ab50cfadb0b962420dc2925c3c6c0735 refs/pull/885/head\n0040a6ac8158f4df78287d9b9ad1de65dc57dc6a185b refs/pull/890/head\n0040766b544a82088b1431e3dcdd3e1487b9189d6246 refs/pull/891/head\n0040a0a34d7f13509a488214cfd2438f6be0146c1ad9 refs/pull/893/head\n0040afa6a135e83a9912c9f4d15357fc9938bf2b0068 refs/pull/894/head\n0040c2470e34de7765ff88749016b3965464dfd2fa05 refs/pull/895/head\n00401c5b91f0c98a065da1decc046eb7c42f814ac6d5 refs/pull/896/head\n0040107785b88da780305b58fc9c6a7a4ad62429857b refs/pull/897/head\n0040878be2f49793529c5426af095b857d85947dec4d refs/pull/898/head\n00403a3c8842ced25171126744d03956459b96fd2a36 refs/pull/899/head\n003e39a9b3d002d1ccfc40ae9b0ea09180f0ee210fad refs/pull/9/head\n003ff6ccf0665312025f8c067e65aa114f1e560535e4 refs/pull/90/head\n004064263d8202cfa4a6e230d02a85b4ab73f18af28c refs/pull/900/head\n0040b9d98f2c3292e12d1065e89381ecf2aac77b33bb refs/pull/901/head\n00407469149b4624705dc9eebb620bac1347e0a1f900 refs/pull/902/head\n0040758931949bb8fa3e07b86ab0304dbc8a545e4f6a refs/pull/903/head\n00400907842911fae6c1f24f295cfcdc1771316fd729 refs/pull/904/head\n0040d79ecb701961c87061812b420d0315336a5b8589 refs/pull/905/head\n0040004eb238767a74876370927993867203630406e3 refs/pull/906/head\n00407fa47247a434bfd4ea57e05c85d24ae3c8393fb0 refs/pull/907/head\n00402209d27550ca808b5741b75a5ca8f4ee1bfac660 refs/pull/909/head\n003fb9da4fc6bfe0353628c52d6c9909723cd3298a31 refs/pull/91/head\n0040dd96a1ef30474322eeae85b439752a2441648b96 refs/pull/910/head\n00401cafe4142ab230d9f40f7c376c7b2fa7e55275bb refs/pull/911/head\n004037292b1f0175a95556c8ab0496ec833aef6f562f refs/pull/913/head\n00401da7ae60e3d5ddd626f3ae779e14fa35d3920394 refs/pull/914/head\n004055eefd75947c9de22a7ab54aa2e66f9ae2d6d181 refs/pull/916/head\n0040991fd5a796b5a173af26608d89b2523856a8839a refs/pull/917/head\n0040a7092017e6221118f5374b13bdb94dd70cb931ac refs/pull/919/head\n003fcd8a45229c253b2ded996209253f557ebe08ea35 refs/pull/92/head\n0040310531041a9db2b3ea7be5508cba725a31c1e7b2 refs/pull/920/head\n0040103d74ad373eb791086aa36975c558d020329cf1 refs/pull/921/head\n004005a1330cb29ccc7cee7d07f282c9ea3f3ce09e31 refs/pull/922/head\n0040b14cdd5be1e9d43167cf8b45a12a8af94c7ab2f9 refs/pull/923/head\n0040ae5b1da48e019604c2ab11cfda3716bc93127e29 refs/pull/924/head\n00402ecf0d4443aa6fd0670d1258bb44e0502cc25be4 refs/pull/925/head\n0040f8d3be5358543d1e77b11da39ee430bbffaad72f refs/pull/926/head\n004013b646387780724daa44cb53406c374fa7536f5e refs/pull/927/head\n0040c80ddf9150a8a07a438a472b283f17dd432cac83 refs/pull/928/head\n0040c5790e77625a6551eca40f10b1baefed1364fdcd refs/pull/929/head\n003ff104599fd8d9a3e937e6afdbfd23aae03b06e70b refs/pull/93/head\n0040d051eee2415aea7e689f3f803c8b42d05bc7f261 refs/pull/933/head\n004067e4e665bcddd02323994332db1f0b36e9f95850 refs/pull/934/head\n004001c9c34786b8f29badce2ea7b8800d1d29585490 refs/pull/935/head\n004055ce8e32fc4100fcbe08168fa134f152ae03fa06 refs/pull/936/head\n00406e33ac2dc161d71f2093cd4b2069a670641da16b refs/pull/939/head\n003fe8e0531dff3e4ede2702f8a194806b479b6573dc refs/pull/94/head\n00409004fc8b94f17b8eb23f3fac7a40373dcf77370c refs/pull/940/head\n004031389c6fb390c4abf206763035bcc253913cb948 refs/pull/941/head\n00402609a321f2e80669a406d954210fd72be764b551 refs/pull/943/head\n0040d5f662f99a84d64ec471ac1380a5508b5b84cc8c refs/pull/945/head\n0040e9c463d00cdffbff59c5d93db522dcfc4d25a1fb refs/pull/946/head\n0040f192d01fefd5091b9b4ad9b79982485ea8589733 refs/pull/947/head\n0040d83110303c40da1d3625c2369eae7424928bfbed refs/pull/949/head\n003f9f4d26f01eaf7a63153e00738718899718630811 refs/pull/95/head\n004090c651e8a760809d5bb1d000200a51c636a0f054 refs/pull/952/head\n00401aab4ffc6737c651a7022c498da9bbe9d51a94e1 refs/pull/953/head\n0040dfada8bc4d47aee406e8b41ca5dcd37e5a46507f refs/pull/954/head\n004057853d8dfa95aa7e51955cec9f00308118779a75 refs/pull/955/head\n0040b2b34bf2041f3bf6b14c340aa8483b44d60e7ef2 refs/pull/956/head\n004002853eb3413c48d693f761af5d6bad64a794de35 refs/pull/957/head\n004048f6be2dc9e5cdcde851bcc3a36126c115ddc1d9 refs/pull/958/head\n0040ea6cf207519ea325a4db11bd7296ec8e3cc9ac0d refs/pull/959/head\n003f45027e2bbac111be570749575b37e391d01747b9 refs/pull/96/head\n0040c7c55e329178bfbe23eb01699ea2a53f30586fc4 refs/pull/960/head\n0040191e6f1b7e87e904cad92cad5baf2c0a886cab3b refs/pull/961/head\n0040fe2ed02e78802a6b0926426be167acab160c1c0b refs/pull/962/head\n0040a8a849ba63aeba05c5e9dd77b00164cc46b16625 refs/pull/964/head\n0040da9795a9634318e42c37ec19f80599c0edc59b0d refs/pull/965/head\n004037e9c36a577642e5eb7256f44781858b50030935 refs/pull/967/head\n004098d33cfab3240eb4982c3adf17c3a1e6a6dcf600 refs/pull/968/head\n00404c8394c17d6ac8f66dfe8ea52ea4f948021fe8da refs/pull/969/head\n003f4d2fe23287a89f1c5241c5e97a940696a840e17b refs/pull/97/head\n0040491d07d263295fc5aeb810ef76e8f2c6d427b3ef refs/pull/970/head\n0040186fa33372f1e4d38b6d3d5ae39d67a435775ccf refs/pull/971/head\n004066ac8a4f89fc8b05319d9a128f51414cecb940a2 refs/pull/972/head\n0040b9980b71215d670dea3099347dbe8c4218f9f110 refs/pull/974/head\n0040a6906775fd285ed3f2baed9a0e81d44ac0a0b3b2 refs/pull/975/head\n00408514919ec66097b5fb571d0664d96f39d768134c refs/pull/976/head\n00405faac7caaa0dcea41a17de0cee60ed7f06e1f5d4 refs/pull/977/head\n004080a4c2407a618a422fd423a30412788a04909d96 refs/pull/978/head\n0040c1e8209f39d44f5f593ae9294a1577d53bf1d125 refs/pull/979/head\n003f7aec67159650698184e602b4579273031479ba64 refs/pull/98/head\n00403555c83f3f7c24a3bcec994f0b6d5770a8ad2822 refs/pull/980/head\n00402c9160f8b13da1243284a53e6b9f087c822185be refs/pull/981/head\n0040a40a406de8e0cd31f3c5eee473ddf603f341c2f1 refs/pull/982/head\n0040ff4497970acdfdd1068d8e74c9cef8c12a4da5f9 refs/pull/983/head\n0040d13163df761ec75dccb17003c581847d50a2cc0c refs/pull/984/head\n00405b8617a847a2a203e498becbc3c0532748933ce2 refs/pull/986/head\n0040dcffa8e69730e0c02b9aa016461e87968794bb72 refs/pull/987/head\n00403b255d8a8de732f378204b6a875efc1b02e7d77d refs/pull/988/head\n0040a0f3cb6d034272ce93606a67d40df88af496e941 refs/pull/989/head\n003fd878692c990ccb8cc79fe2475f5ff23c27ac0619 refs/pull/99/head\n00405b7f7ceb1a0f94c7eeca65bf89eb14bbc0a59342 refs/pull/990/head\n00407017906a8b42b1ed89f4a460c4240b9e4580b269 refs/pull/991/head\n0040a5fe46e1f7d147ce127de02177289995546d3b97 refs/pull/992/head\n0040d23da7efa002b15768bd46ecb8e093d20371d162 refs/pull/996/head\n0040a512bb48e3b77d921087674f19a7e8b8eadb73e8 refs/pull/999/head\n003fbb69be3fc46bc36dc687a645679a227f7bab9eeb refs/tags/v0.0.10\n003f01277cf0443b8e7cbe8104c8e72bac7aaac15b11 refs/tags/v0.0.11\n003fbc9f4568c6f3fdeb78bf983a3bf3d90bdcccd9c5 refs/tags/v0.0.12\n003f95135bc1a18b70853608d492d6eb82e5702500a4 refs/tags/v0.0.13\n003f8de7697b3b8a73e79a73ec34f17ef0fa842cfbb2 refs/tags/v0.0.14\n003f932929f0f31584734b94339ea9cacf3158fd9bed refs/tags/v0.0.15\n004546391ffda5dbc429cfd440269a4972242bb0cc4e refs/tags/v0.0.15-alpha\n00481eff46c9d7e491d709680cba7e446d1fdcb8223e refs/tags/v0.0.15-alpha^{}\n003f83293a2b3b7931c39214afdbcf30573727891066 refs/tags/v0.0.17\n003f657fe2a8cf60492ae03045e7ca4da22a09be7f58 refs/tags/v0.0.18\n003f28d1e63275538cf8f3c3a5ccb5cf8f87ccf2aee7 refs/tags/v0.0.21\n003f236cdaf0470e94797989d232a85183f66ce6b61b refs/tags/v0.0.22\n003e9aa28d0a130e9174fb217921966b1855c2fd3f19 refs/tags/v0.0.5\n003e12e0175b9303f6ecca1ad8abdb3a28b3c97e7b54 refs/tags/v0.0.6\n003e95862388f4e9835d0b6e8136118e1799a064efe8 refs/tags/v0.0.7\n003e10b90c68bca21c632f4dbfd243aaedce25d00b3a refs/tags/v0.0.8\n003e737948b5060efeffb1cf47fe085d187a3d0304a4 refs/tags/v0.0.9\n003e8bc725ef48bc28a085f4a677afb983bae2558959 refs/tags/v0.1.0\n003ebcd7e4b928d8af37e459c2b25e1185e3f5ed4089 refs/tags/v0.1.1\n003ebd0d0261d4a654f8dadf52e66b654786673815df refs/tags/v0.1.2\n00439805438dc8731dabd78c8b3eb6871cb12a5090b5 refs/tags/v2023.02.28\n00438395cba7325954e4b3e3ed4c7ef3bfa82b428bdf refs/tags/v2023.03.07\n004363a89f6b9cafa9105949ba1616824ebbce62d007 refs/tags/v2023.03.15\n00436e19621c3acce9f66a817d0fbd825cd8edbe56ce refs/tags/v2023.03.21\n004329b7f68cc25aef244e46758a4c6548d366256e65 refs/tags/v2023.03.28\n0043ac1b1aa95f204bb6e1c0265a9d24139e9207d1c0 refs/tags/v2023.04.18\n0043adc4f6fa6de0b14e8c0ad9e502434d68ac3ddedc refs/tags/v2023.05.03\n0043ac1e00f9928257d8db85557e92d7efe44f5a828f refs/tags/v2023.05.09\n004310d72617f1ab2fdc9445b99ba18e723f60dc0750 refs/tags/v2023.05.17\n004311260570ad7c022286cc82840bae0cf8b1ee5350 refs/tags/v2023.05.24\n0043a29affe77a4c5de1e5421d9f53a8a0aa749d03cf refs/tags/v2023.05.31\n0043aed410e4badbc073a6910c11c8ca57f9fc49310a refs/tags/v2023.06.07\n0043433e32ef73bf683326d11d06e4f3d0cbe1e58859 refs/tags/v2023.06.14\n00437f4fb14bda2cc9dbbd8294a863092f64c2907c2d refs/tags/v2023.06.21\n0043b23615fb607715133806de0b12decc215cc95c2c refs/tags/v2023.06.22\n0043b937cdb360e93eee61a150c05029eb00cd404486 refs/tags/v2023.06.28\n0043efe2a73c48cfc8f358f304cf6d359d404b9806d8 refs/tags/v2023.07.04\n00438ce4d43aecc3b203df79565cad859d7798735a55 refs/tags/v2023.07.11\n0043cf318991793322189c5e44865a0355fa2ad69123 refs/tags/v2023.07.20\n00430f4e0c28da6fd9535d483ab63584d60a925bb3b9 refs/tags/v2023.07.25\n004338a28cd7123e13f90206872cc2e9af57959cabfa refs/tags/v2023.08.08\n0043064a3cb686cf44a66b061e914e52c9a6d9f4ecd1 refs/tags/v2023.08.16\n0043c6234697916921a270ab73511ae41e9037e15a5c refs/tags/v2023.08.23\n004372824f40c918f75abdb41ea13ce0513ee3d85df5 refs/tags/v2023.08.30\n004381506c929c86ba534d561e4cea236c7b2e1cbd98 refs/tags/v2023.09.05\n004322f7c5adc326fbda035d81fa05e3bfad80bdc9c9 refs/tags/v2023.09.13\n0043eb99b02ec8895fe5b87d1e76675ddad79a15f817 refs/tags/v2023.09.20\n004357316bd49932c8d37661cb03681b9d240079c7bf refs/tags/v2023.10.04\n0043595fc3e8b0210f23eff23ff853474e8700af2b85 refs/tags/v2023.10.10\n0043b374531b8074c41c7842183132e7e2804ebb3e84 refs/tags/v2023.10.19\n0043d26956b07351e0c695723507ad56b0aa59bd759d refs/tags/v2023.10.24\n0043e151977b4f60ce8d83f7cd2c2735596af419cb6d refs/tags/v2023.10.31\n0043eb3b3c75b4b86d0537cbeaae55984ad4bf71a53f refs/tags/v2023.11.08\n004373315181865f9dd465dfea60d8c4a7359bad47a8 refs/tags/v2023.11.15\n004373b75e2c5b3c0e18f20375f4944b30b806b4cf32 refs/tags/v2023.11.21\n0043d039ca1b38f56a6c959eee0982afb69d1e56a65a refs/tags/v2023.11.29\n004381ea8ac55875b68ff236da7f44f91997c7b08925 refs/tags/v2023.11.30\n004392bce01c40ae5c4707aa46371cd31dc34562d88e refs/tags/v2023.12.05\n0043e15fe9260c2f2bff99184ca7a6bf5b8bd4ded5a8 refs/tags/v2023.12.06\n0043bbab1cd3a6494c4fc2101c19a832b52ee78d412f refs/tags/v2023.12.13\n00432a4022c818232b32573841a6f506796a25d13120 refs/tags/v2023.12.19\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.11\n0043666a43e6ae7690fbfa283e9a6f0b08a986be4d32 refs/tags/v2024.01.16\n0043aa584539a6f0085446fa53149a33c9385cecdf35 refs/tags/v2024.01.25\n0043e74a5dd172fada3ffb487d0c7c26db97cf2c3cba refs/tags/v2024.01.30\n0043f853bc9845f76620ec94f3662bf522fea0368a5b refs/tags/v2024.02.06\n004379c07c93dc01ed256032cb790eaae638a4255ee1 refs/tags/v2024.02.20\n00431defc72ba4297632dfb886b829f7a2d5299f06d5 refs/tags/v2024.02.21\n0043678f665a24414c3b425eaf40eb0eec62233aae41 refs/tags/v2024.02.28\n00435a8605df882d8a24c086655338e5f43fbddfe627 refs/tags/v2024.03.06\n004377ae40037a5c92bb3d04775a2fab70043ef7058d refs/tags/v2024.03.13\n0043f532637d69ac886df1fcf7b2e31f90b19df6f351 refs/tags/v2024.03.14\n004367f1b39c7aeee2a28ce5a41cabe113e4b49feb7c refs/tags/v2024.03.19\n004352136b5f1d38e09a5c687bd796feaa54fda7e4fa refs/tags/v2024.03.26\n00432ed3d46bd5c433bbbb06b72d7c0c171546646550 refs/tags/v2024.04.03\n0043927c0cae0f153597bf533032f086442e99a17042 refs/tags/v2024.04.09\n0043bc61579a635c9525a163775e42ae23886960ed7f refs/tags/v2024.04.23\n0043afcc49c52bbd1c6604baaa3a12809a30d5d3ad34 refs/tags/v2024.05.09\n0043fc144b751d26d8fbfc6ba15afc92fdbcd00a4fe3 refs/tags/v2024.05.14\n0043d0b1f72cfa19b5aa73883161682831392d8b5476 refs/tags/v2024.05.22\n00439ec5daa06fdace741958e4a7a20f7d1931948393 refs/tags/v2024.05.29\n0043bcb5dd13096cc0981647b113ca3ea142a7a517b6 refs/tags/v2024.06.04\n0043ccd849542895620faa4f323f44d7ad7ca543b5dc refs/tags/v2024.06.06\n0043d4509b6e3a2a6764c75f7ac316703b538ef3a1c2 refs/tags/v2024.06.12\n0043af23a17b9c54179b2253fccd1da19c38aef1b86c refs/tags/v2024.06.18\n0043fa0672b233985ca2e57f752e1f91542f80b8b22f refs/tags/v2024.06.25\n0043d6938bd6e6f2cba5cabb950fd86086f4c764e8c0 refs/tags/v2024.07.03\n00432cd1236084bcda3c37a80348c0de88c1aa103bb2 refs/tags/v2024.07.09\n00438c2b48a4bf3bd73e9f198966ddbb0bebd3d7cd6b refs/tags/v2024.07.16\n004394f08450539093e3f799533b698ead2f8cafea09 refs/tags/v2024.07.24\n00437295294bbc414041b103a0a296718b14aebd2632 refs/tags/v2024.07.30\n00437ca68fed3cf76d171473970f5bfaa3846a69b635 refs/tags/v2024.08.06\n0043d48073bcbcf12257cc249ff3698fcf94a16ceaaa refs/tags/v2024.08.13\n004380b888fa239ceef4062648f4259a5767f36d1080 refs/tags/v2024.08.19\n0043a81778d470873e2be57d3b8ae4fbf9f942e28c96 refs/tags/v2024.08.27\n00430a526fbafa0a00279ab6a74787ec265d65b8feaa refs/tags/v2024.09.03\n0043431fef648ff9b44f33646ac773abbaca71c48f15 refs/tags/v2024.09.04\n004365076b2b592d4e09bf0be039699969b455bbf4a8 refs/tags/v2024.09.10\n00433dd07d08451a9be3cf4eaf95e3fa0e0d8f3e8a9f refs/tags/v2024.09.18\n00434eadc85640729c2ae55ab05f0040cec03bf3b726 refs/tags/v2024.09.24\n00433508bb45f43df4268a8be3248386b828779cd95c refs/tags/v2024.10.01\n0043081f563d7307950d9c43237ee7cb965261496ca5 refs/tags/v2024.10.09\n0045fa9fc088b7fa8a2b10a479a17bbb9f46e0609d34 refs/tags/v2024.10.09.2\n0043033ea44ceed6bbc972f8f528585d15fc397d2e19 refs/tags/v2024.10.16\n0043af4b18a1540cf73c9ac67d1643b0a5f511d1bc86 refs/tags/v2024.10.22\n0043037050145b4bf7d09d9602e2c8042e4ca8bed9fa refs/tags/v2024.10.29\n0043ee286929b5e18f007d9649afd75c7bc4ce68c2fd refs/tags/v2024.11.05\n0043d58c1f6a1e88c451e168863057fb05fe0d323488 refs/tags/v2024.11.12\n004322cc4bc998323fb7d0bcfe4bb24e3d5715eda849 refs/tags/v2024.11.19\n00432d7b1e03bfd479a58ad56c339cc092669dd64707 refs/tags/v2024.11.26\n004391a0125e55c8902b3d077f4c812284d9116a5bbe refs/tags/v2024.12.04\n0043402f47d4f1fe547ba68ab39ac342b525f4cd7e69 refs/tags/v2024.12.05\n0043a5ef7137a2e3cd5c48e2b7ecccab5722dbf738d4 refs/tags/v2024.12.11\n0043732f08356e5f073aa275d36bff43da6b2b0177c7 refs/tags/v2025.01.07\n00433d55f553e28cc2b16152fb4df8ac53797b9d5c8d refs/tags/v2025.01.14\n0043f53c68fddaf2d760e0a00cca49b4b5313bdb0ad7 refs/tags/v2025.01.22\n004326d49d78a26427a12628cd3a1a4cd49d030c6956 refs/tags/v2025.01.28\n0043a9940a58b48f0a650632c37b44abdee0144d781b refs/tags/v2025.01.29\n00453be0a2314da2bcb3028617e4a05622aafd5beee0 refs/tags/v2025.01.29.2\n0043eb29faa1a45f8983502590b8ca68dcb2692ac68e refs/tags/v2025.02.05\n0043c2e9e5f6e41b61bb18e8e9f20924bd702d9fea47 refs/tags/v2025.02.11\n00436f66b0ed1fcd2394462a4268f2dad26ace3ccc06 refs/tags/v2025.02.18\n0043edde4b267a78ec2452e0ee7afcc21d02d7f18377 refs/tags/v2025.02.25\n0043f7e26092e0e8ced250d6cab7ae7b62343f2b8809 refs/tags/v2025.03.04\n00436dd9a9dd776e2c51c16f359c417256e702fbbe44 refs/tags/v2025.03.12\n00431d0fca0817eab7d932e4673e6837aae320708fa1 refs/tags/v2025.03.18\n00436d7c3dc69bc05e7e1a83f4389e61d430db288416 refs/tags/v2025.03.25\n00432727c77060f0174f96e12dad3070cb504c316ec5 refs/tags/v2025.03.26\n004304979978095630ecf30f6c3ddbc55e07ba8bf7cf refs/tags/v2025.04.01\n00439f7fe3920daf55fb156d8feb6143d939e3d5cd28 refs/tags/v2025.04.08\n0043e28ded887856f77d575be479212490d35e55e08b refs/tags/v2025.04.15\n0043b8445788211b3bcc04c32c77046503b14170c870 refs/tags/v2025.04.29\n0043b8d9f1b5afe0a8cf6ec02354fe2fd4516271b1d3 refs/tags/v2025.05.08\n0043139de7b69a2ea39e2113309b3a0a47aab920ddcf refs/tags/v2025.05.13\n0043b5f70ca94cb7beeb9d01269958275796f1b7189f refs/tags/v2025.05.20\n0043098ed8318399f68a9b2ef4b22c83687cacb85da5 refs/tags/v2025.05.28\n0043f3aa51f0689214ee9ce4e57173e56b933fda3649 refs/tags/v2025.06.04\n0043367e62dc034dae8d6a61362fb0d804906982a18c refs/tags/v2025.06.10\n0043d895bc431dc7c591919e5f1907bee1867eb6a914 refs/tags/v2025.06.17\n00437f39eb683c4de0606f91a1e624f905bae1407899 refs/tags/v2025.06.24\n0043e4f7ccfd19525dcffb1567c992a031bfa50220a3 refs/tags/v2025.07.01\n0043e536895df480f9925d50433216c1f6433d72c595 refs/tags/v2025.07.08\n00437102b14a4e5f4a2143b93b3be87b2d47a72ab8c2 refs/tags/v2025.07.15\n004307053097ab9dc03f53b5bdf787c0980035c87c77 refs/tags/v2025.07.22\n0043b87e0fd6d1c5443c32c36d85f86327a05682bfa8 refs/tags/v2025.07.29\n00431b89e9ca82d67aa78fc13cc0fda6a9bc52444b4a refs/tags/v2025.08.05\n0043becec66fa93053b7e64695306b180bc33834315b refs/tags/v2025.08.12\n0043968eb3f9fdcbd8a2e15b37f6ac8b27ec16f4528e refs/tags/v2025.08.19\n004363cd9d02158a08200ae269fea1a0a313a218d02a refs/tags/v2025.08.26\n00434bf6cd15e8ee92b5a0920996f78bda842ed23399 refs/tags/v2025.09.02\n0043e82714dc6454b7b7c4be0eccbac950c3b1a03006 refs/tags/v2025.09.09\n0043749e06b88234c9316282b9024b603c5c1957e194 refs/tags/v2025.09.16\n0043ad4bb44b99d34d27f5d36e8ab96afadc1fc7e6eb refs/tags/v2025.09.24\n0043bd0d0261d4a654f8dadf52e66b654786673815df refs/tags/v2025.09.25\n004343c5e13b27df13e9676783260963bcb8805bfc6d refs/tags/v2025.09.30\n00438c9069f6f183a02e3c71adc760190ded4331c402 refs/tags/v2025.10.07\n00439025fd1f9db05bb0d2309f616fd668b5b00938f0 refs/tags/v2025.10.14\n00431d9b902945b6ca026720f523329b2f18a4dc8228 refs/tags/v2025.10.21\n00435fc0b2fa2fcb22da1bdb83d287b21bbb39128585 refs/tags/v2025.10.28\n004330bc3412d57931a1fd7b5691922f01a11b811302 refs/tags/v2025.11.04\n00431b9cb07547bd39a376c0c57289db8d0c3740abaf refs/tags/v2025.11.11\n0043ca40ed0d4449c54a23c20dfbea71a841ec0d3a47 refs/tags/v2025.11.19\n004367b4d8b430496b96ad08ef544ad823674763dd8e refs/tags/v2025.11.25\n0043ff13718c6bcd1e67cba5c29768c4945d643078ba refs/tags/v2025.12.04\n004379c63772b6ba332725d1b65524a9850e582c82bb refs/tags/v2025.12.10\n004311ebfd72c6b2e4b45fa84d74598fb35f6a76412c refs/tags/v2026.01.06\n004311dcf751333eaa04f860d989afa334bacb13e397 refs/tags/v2026.01.13\n00430e50a12fcb7d0fd6b22d11930f1b95e65f790326 refs/tags/v2026.01.20\n0043c2bfb64e064cb9ae4462db090f4172e97e81ce94 refs/tags/v2026.01.27\n0000" + headers: + Cache-Control: + - no-cache, max-age=0, must-revalidate + Content-Security-Policy: + - default-src 'none'; sandbox + Content-Type: + - application/x-git-upload-pack-advertisement + Date: + - Wed, 28 Jan 2026 02:57:58 GMT + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Server: + - GitHub-Babel/3.0 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Vary: + - Accept-Encoding + X-Frame-Options: + - DENY + X-Github-Request-Id: + - 3CCC:2C39E9:3E073C:471E8F:69797B35 + status: 200 OK + code: 200 + duration: 344.367776ms diff --git a/vulnfeeds/cves/versions.go b/vulnfeeds/cves/versions.go index 163c9a229a3..64760ea6afb 100644 --- a/vulnfeeds/cves/versions.go +++ b/vulnfeeds/cves/versions.go @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://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, @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package cves provides utilities for working with CVEs and version information. package cves import ( @@ -25,6 +26,7 @@ import ( "regexp" "slices" "strings" + "sync" "time" "github.com/knqyf263/go-cpe/naming" @@ -67,6 +69,37 @@ type VendorProduct struct { Product string } type VendorProductToRepoMap map[VendorProduct][]string +type VPRepoCache struct { + sync.RWMutex + + m VendorProductToRepoMap +} + +func NewVPRepoCache() *VPRepoCache { + return &VPRepoCache{ + m: make(VendorProductToRepoMap), + } +} + +func (c *VPRepoCache) Get(vp VendorProduct) ([]string, bool) { + c.RLock() + defer c.RUnlock() + if c.m == nil { + return nil, false + } + repos, ok := c.m[vp] + + return repos, ok +} + +func (c *VPRepoCache) Set(vp VendorProduct, repos []string) { + c.Lock() + defer c.Unlock() + if c.m == nil { + c.m = make(VendorProductToRepoMap) + } + c.m[vp] = repos +} // Rewrites known GitWeb URLs to their base repository. func repoGitWeb(parsedURL *url.URL) (string, error) { @@ -607,7 +640,7 @@ func processExtractedVersion(version string) string { return version } -func ExtractVersionsFromText(validVersions []string, text string) ([]models.AffectedVersion, []string) { +func ExtractVersionsFromText(validVersions []string, text string, metrics *models.ConversionMetrics) []models.AffectedVersion { // Match: // - x.x.x before x.x.x // - x.x.x through x.x.x @@ -616,10 +649,10 @@ func ExtractVersionsFromText(validVersions []string, text string) ([]models.Affe pattern := regexp.MustCompile(`(?i)([\w.+\-]+)?\s+(through|before)\s+(?:version\s+)?([\w.+\-]+)`) matches := pattern.FindAllStringSubmatch(text, -1) if matches == nil { - return nil, []string{"Failed to parse versions from text"} + metrics.AddNote("Failed to parse versions from text") + return nil } - var notes []string versions := make([]models.AffectedVersion, 0, len(matches)) for _, match := range matches { @@ -632,26 +665,26 @@ func ExtractVersionsFromText(validVersions []string, text string) ([]models.Affe var err error fixed, err = nextVersion(validVersions, fixed) if err != nil { - notes = append(notes, err.Error()) + metrics.AddNote("Failed to determine next version after %s: %s", fixed, err.Error()) // if that inference failed, we know this version was definitely still vulnerable. lastaffected = cleanVersion(match[3]) - notes = append(notes, fmt.Sprintf("Using %s as last_affected version instead", cleanVersion(match[3]))) + metrics.AddNote("Using %s as last_affected version instead", cleanVersion(match[3])) } } if introduced == "" && fixed == "" && lastaffected == "" { - notes = append(notes, "Failed to match version range from text") + metrics.AddNote("Failed to match version range from text") continue } if introduced != "" && !HasVersion(validVersions, introduced) { - notes = append(notes, fmt.Sprintf("Extracted introduced version %s is not a valid version", introduced)) + metrics.AddNote("Extracted introduced version %s is not a valid version", introduced) } if fixed != "" && !HasVersion(validVersions, fixed) { - notes = append(notes, fmt.Sprintf("Extracted fixed version %s is not a valid version", fixed)) + metrics.AddNote("Extracted fixed version %s is not a valid version", fixed) } if lastaffected != "" && !HasVersion(validVersions, lastaffected) { - notes = append(notes, fmt.Sprintf("Extracted last_affected version %s is not a valid version", lastaffected)) + metrics.AddNote("Extracted last_affected version %s is not a valid version", lastaffected) } // Favour fixed over last_affected for schema compliance. if fixed != "" && lastaffected != "" { @@ -665,7 +698,7 @@ func ExtractVersionsFromText(validVersions []string, text string) ([]models.Affe }) } - return versions, notes + return versions } func cleanVersion(version string) string { @@ -683,7 +716,7 @@ func deduplicateAffectedCommits(commits []models.AffectedCommit) []models.Affect return uniqueCommits } -func ExtractVersionInfo(cve CVE, validVersions []string, httpClient *http.Client) (v models.VersionInfo, notes []string) { +func ExtractVersionInfo(cve models.NVDCVE, validVersions []string, httpClient *http.Client, metrics *models.ConversionMetrics) (v models.VersionInfo) { for _, reference := range cve.References { // (Potentially faulty) Assumption: All viable Git commit reference links are fix commits. if commit, err := extractGitAffectedCommit(reference.URL, models.Fixed, httpClient); err == nil { @@ -715,7 +748,7 @@ func ExtractVersionInfo(cve CVE, validVersions []string, httpClient *http.Client var err error introduced, err = nextVersion(validVersions, cleanVersion(*match.VersionStartExcluding)) if err != nil { - notes = append(notes, err.Error()) + metrics.AddNote("%v", err.Error()) } } @@ -726,10 +759,10 @@ func ExtractVersionInfo(cve CVE, validVersions []string, httpClient *http.Client // Infer the fixed version from the next version after. fixed, err = nextVersion(validVersions, cleanVersion(*match.VersionEndIncluding)) if err != nil { - notes = append(notes, err.Error()) + metrics.AddNote("%v", err.Error()) // if that inference failed, we know this version was definitely still vulnerable. lastaffected = cleanVersion(*match.VersionEndIncluding) - notes = append(notes, fmt.Sprintf("Using %s as last_affected version instead", cleanVersion(*match.VersionEndIncluding))) + metrics.AddNote("Using %s as last_affected version instead", cleanVersion(*match.VersionEndIncluding)) } } @@ -759,11 +792,11 @@ func ExtractVersionInfo(cve CVE, validVersions []string, httpClient *http.Client } if introduced != "" && !HasVersion(validVersions, introduced) { - notes = append(notes, fmt.Sprintf("Warning: %s is not a valid introduced version", introduced)) + metrics.AddNote("Warning: %s is not a valid introduced version", introduced) } if fixed != "" && !HasVersion(validVersions, fixed) { - notes = append(notes, fmt.Sprintf("Warning: %s is not a valid fixed version", fixed)) + metrics.AddNote("Warning: %s is not a valid fixed version", fixed) } gotVersions = true @@ -781,22 +814,20 @@ func ExtractVersionInfo(cve CVE, validVersions []string, httpClient *http.Client } } if !gotVersions { - var extractNotes []string - v.AffectedVersions, extractNotes = ExtractVersionsFromText(validVersions, EnglishDescription(cve.Descriptions)) - notes = append(notes, extractNotes...) + v.AffectedVersions = ExtractVersionsFromText(validVersions, models.EnglishDescription(cve.Descriptions), metrics) if len(v.AffectedVersions) > 0 { - logger.Info("Extracted versions from description", slog.String("cve", string(cve.ID)), slog.Any("versions", v.AffectedVersions)) + metrics.AddNote("Extracted versions from description: %v", v.AffectedVersions) } } if len(v.AffectedVersions) == 0 { - notes = append(notes, "No versions detected.") + metrics.AddNote("No versions detected.") } - if len(notes) != 0 && len(validVersions) > 0 { - notes = append(notes, "Valid versions:") + if len(validVersions) > 0 { + metrics.AddNote("Valid versions:") for _, version := range validVersions { - notes = append(notes, " - "+version) + metrics.AddNote(" - %v", version) } } @@ -812,10 +843,10 @@ func ExtractVersionInfo(cve CVE, validVersions []string, httpClient *http.Client v.AffectedVersions = affectedVersionsWithoutLastAffected } - return v, notes + return v } -func CPEs(cve CVE) []string { +func CPEs(cve models.NVDCVE) []string { var cpes []string for _, config := range cve.Configurations { for _, node := range config.Nodes { @@ -836,7 +867,7 @@ func RemoveQuoting(s string) (result string) { } // Parse a well-formed CPE string into a struct. -func ParseCPE(formattedString string) (*models.CPE, error) { +func ParseCPE(formattedString string) (*models.CPEString, error) { if !strings.HasPrefix(formattedString, "cpe:") { return nil, fmt.Errorf("%q does not have expected 'cpe:' prefix", formattedString) } @@ -847,7 +878,7 @@ func ParseCPE(formattedString string) (*models.CPE, error) { return nil, err } - return &models.CPE{ + return &models.CPEString{ CPEVersion: strings.Split(formattedString, ":")[1], Part: wfn.GetString("part"), Vendor: RemoveQuoting(wfn.GetString("vendor")), @@ -864,13 +895,16 @@ func ParseCPE(formattedString string) (*models.CPE, error) { func (vp *VendorProduct) UnmarshalText(text []byte) error { s := strings.Split(string(text), ":") + if len(s) < 2 { + return fmt.Errorf("expected at least 2 parts, got %d", len(s)) + } vp.Vendor = s[0] vp.Product = s[1] return nil } -func RefAcceptable(ref Reference, tagDenyList []string) bool { +func RefAcceptable(ref models.Reference, tagDenyList []string) bool { for _, deniedTag := range tagDenyList { if slices.Contains(ref.Tags, deniedTag) { return false @@ -881,25 +915,33 @@ func RefAcceptable(ref Reference, tagDenyList []string) bool { } // Adds the repo to the cache for the Vendor/Product combination if not already present. -func MaybeUpdateVPRepoCache(cache VendorProductToRepoMap, vp *VendorProduct, repo string) { - if cache == nil || vp == nil { +func (c *VPRepoCache) MaybeUpdate(vp *VendorProduct, repo string) { + if vp == nil { return } - if slices.Contains(cache[*vp], repo) { + c.Lock() + defer c.Unlock() + + if slices.Contains(c.m[*vp], repo) { return } // Avoid polluting the cache with existent-but-useless repos. if git.ValidRepoAndHasUsableRefs(repo) { - cache[*vp] = append(cache[*vp], repo) + c.m[*vp] = append(c.m[*vp], repo) } } // Removes the repo from the cache for the Vendor/Product combination if already present. -func MaybeRemoveFromVPRepoCache(cache VendorProductToRepoMap, vp *VendorProduct, repo string) { - if cache == nil || vp == nil { +func (c *VPRepoCache) MaybeRemove(vp *VendorProduct, repo string) { + if vp == nil { return } - cacheEntry, ok := cache[*vp] + c.Lock() + defer c.Unlock() + if c.m == nil { + return + } + cacheEntry, ok := c.m[*vp] if !ok { return } @@ -912,18 +954,24 @@ func MaybeRemoveFromVPRepoCache(cache VendorProductToRepoMap, vp *VendorProduct, } // If there is only one entry, delete the entry cache entry. if len(cacheEntry) == 1 { - delete(cache, *vp) + delete(c.m, *vp) return } cacheEntry = slices.Delete(cacheEntry, i, i+1) - cache[*vp] = cacheEntry + c.m[*vp] = cacheEntry +} + +func (c *VPRepoCache) Initialize(vpMap VendorProductToRepoMap) { + c.Lock() + defer c.Unlock() + c.m = vpMap } // Examines repos and tries to convert versions to commits by treating them as Git tags. // Takes a CVE ID string (for logging), VersionInfo with AffectedVersions and // typically no AffectedCommits and attempts to add AffectedCommits (including Fixed commits) where there aren't any. // Refuses to add the same commit to AffectedCommits more than once. -func GitVersionsToCommits(cveID CVEID, versions models.VersionInfo, repos []string, cache git.RepoTagsCache) (v models.VersionInfo, e error) { +func GitVersionsToCommits(cveID models.CVEID, versions models.VersionInfo, repos []string, cache *git.RepoTagsCache, metrics *models.ConversionMetrics) (v models.VersionInfo, e error) { // versions is a VersionInfo with AffectedVersions and typically no AffectedCommits // v is a VersionInfo with AffectedCommits (containing Fixed commits) included v = versions @@ -934,14 +982,14 @@ func GitVersionsToCommits(cveID CVEID, versions models.VersionInfo, repos []stri continue } for _, av := range versions.AffectedVersions { - logger.Info("Attempting version resolution", slog.String("cve", string(cveID)), slog.Any("version", av), slog.String("repo", repo)) + metrics.AddNote("Attempting version resolution for %s in %s", av, repo) introducedEquivalentCommit := "" if av.Introduced != "" { ac, err := git.VersionToAffectedCommit(av.Introduced, repo, models.Introduced, normalizedTags) if err != nil { logger.Warn("Failed to get a Git commit for introduced version", slog.String("cve", string(cveID)), slog.String("version", av.Introduced), slog.String("repo", repo), slog.Any("err", err)) } else { - logger.Info("Successfully derived commit for introduced version", slog.String("cve", string(cveID)), slog.Any("commit", ac), slog.String("version", av.Introduced)) + metrics.AddNote("Successfully derived commit %s for introduced version %s", ac, av.Introduced) introducedEquivalentCommit = ac.Introduced } } @@ -951,13 +999,13 @@ func GitVersionsToCommits(cveID CVEID, versions models.VersionInfo, repos []stri // Fixed commits, they're also assumed to be more precise than what may be derived from tag to commit mapping. fixedEquivalentCommit := "" if v.HasFixedCommits(repo) && av.Fixed != "" { - logger.Info("Using preassumed fixed commits instead of deriving from fixed version", slog.String("cve", string(cveID)), slog.Any("commits", v.FixedCommits(repo)), slog.String("version", av.Fixed)) + metrics.AddNote("Using preassumed fixed commits instead of deriving from fixed version %s", av.Fixed) } else if av.Fixed != "" { ac, err := git.VersionToAffectedCommit(av.Fixed, repo, models.Fixed, normalizedTags) if err != nil { logger.Warn("Failed to get a Git commit for fixed version", slog.String("cve", string(cveID)), slog.String("version", av.Fixed), slog.String("repo", repo), slog.Any("err", err)) } else { - logger.Info("Successfully derived commit for fixed version", slog.String("cve", string(cveID)), slog.Any("commit", ac), slog.String("version", av.Fixed)) + metrics.AddNote("Successfully derived commit %s for fixed version %s", ac, av.Fixed) fixedEquivalentCommit = ac.Fixed } } @@ -970,7 +1018,7 @@ func GitVersionsToCommits(cveID CVEID, versions models.VersionInfo, repos []stri if err != nil { logger.Warn("Failed to get a Git commit for last_affected version", slog.String("cve", string(cveID)), slog.String("version", av.LastAffected), slog.String("repo", repo), slog.Any("err", err)) } else { - logger.Info("Successfully derived commit for last_affected version", slog.String("cve", string(cveID)), slog.Any("commit", ac), slog.String("version", av.LastAffected)) + metrics.AddNote("Successfully derived commit %s for last_affected version %s", ac, av.LastAffected) lastAffectedEquivalentCommit = ac.LastAffected } } @@ -989,15 +1037,15 @@ func GitVersionsToCommits(cveID CVEID, versions models.VersionInfo, repos []stri } if ac == (models.AffectedCommit{}) { // Nothing resolved, move on to the next AffectedVersion - logger.Warn("Sufficient resolution not possible", slog.String("cve", string(cveID)), slog.Any("version", av)) + metrics.AddNote("Sufficient resolution not possible for %s", av) continue } if ac.InvalidRange() { - logger.Warn("Invalid range", slog.String("cve", string(cveID)), slog.Any("commit", ac)) + metrics.AddNote("Invalid range for %s", ac) continue } if v.Duplicated(ac) { - logger.Warn("Duplicate commit", slog.String("cve", string(cveID)), slog.Any("commit", ac), slog.Any("version", v)) + metrics.AddNote("Duplicate commit for %s", ac) continue } v.AffectedCommits = append(v.AffectedCommits, ac) @@ -1009,13 +1057,12 @@ func GitVersionsToCommits(cveID CVEID, versions models.VersionInfo, repos []stri // Examines the CVE references for a CVE and derives repos for it, optionally caching it. // TODO (jesslowe): refactor with below -func ReposFromReferences(cve string, cache VendorProductToRepoMap, vp *VendorProduct, refs []Reference, tagDenyList []string) (repos []string) { +func ReposFromReferences(cache *VPRepoCache, vp *VendorProduct, refs []models.Reference, tagDenyList []string, metrics *models.ConversionMetrics) (repos []string) { for _, ref := range refs { // If any of the denylist tags are in the ref's tag set, it's out of consideration. if !RefAcceptable(ref, tagDenyList) { - // Also remove it if previously added under an acceptable tag. - MaybeRemoveFromVPRepoCache(cache, vp, ref.URL) - logger.Info(fmt.Sprintf("[%s] Disregarding due to a denied tag", cve), slog.String("cve", cve), slog.String("url", ref.URL), slog.Any("product", vp), slog.Any("tags", ref.Tags)) + cache.MaybeRemove(vp, ref.URL) + metrics.AddNote("Disregarding %q due to a denied tag in %q", ref.URL, ref.Tags) continue } @@ -1034,23 +1081,23 @@ func ReposFromReferences(cve string, cache VendorProductToRepoMap, vp *VendorPro continue } repos = append(repos, repo) - MaybeUpdateVPRepoCache(cache, vp, repo) + cache.MaybeUpdate(vp, repo) } if vp != nil && repos != nil { - logger.Info(fmt.Sprintf("[%s] Derived repos using references", cve), slog.String("cve", cve), slog.Any("repos", repos), slog.String("vendor", vp.Vendor), slog.String("product", vp.Product)) + metrics.AddNote("Derived repos using references %q for %q %q", repos, vp.Vendor, vp.Product) } else { - logger.Info(fmt.Sprintf("[%s] Derived repos (no CPEs) using references", cve), slog.String("cve", cve), slog.Any("repos", repos)) + metrics.AddNote("Derived repos (no CPEs) using references: %q", repos) } return repos } // Examines the CVE references for a CVE and derives repos for it, optionally caching it. -func ReposFromReferencesCVEList(cve string, refs []Reference, tagDenyList []string) (repos []string, notes []string) { +func ReposFromReferencesCVEList(refs []models.Reference, tagDenyList []string, metrics *models.ConversionMetrics) (repos []string) { for _, ref := range refs { // If any of the denylist tags are in the ref's tag set, it's out of consideration. if !RefAcceptable(ref, tagDenyList) { - notes = append(notes, fmt.Sprintf("[%s]: disregarding %q due to a denied tag in %q", cve, ref.URL, ref.Tags)) + metrics.AddNote("Disregarding %q due to a denied tag in %q", ref.URL, ref.Tags) continue } // if it ends with .md it is likely a researcher repo and _currently_ useless. @@ -1070,12 +1117,12 @@ func ReposFromReferencesCVEList(cve string, refs []Reference, tagDenyList []stri repos = append(repos, repo) } if len(repos) == 0 { - notes = append(notes, fmt.Sprintf("[%s]: Failed to identify any repos using references", cve)) + metrics.AddNote("Failed to identify any repos using references") } else { - notes = append(notes, fmt.Sprintf("[%s]: Derived %q (no CPEs) using references", cve, repos)) + metrics.AddNote("Derived %q (no CPEs) using references", repos) } - return repos, notes + return repos } // BuildVersionRange is a helper function that adds 'introduced', 'fixed', or 'last_affected' diff --git a/vulnfeeds/cves/versions_test.go b/vulnfeeds/cves/versions_test.go index 69e9bd9411f..d86c79a715b 100644 --- a/vulnfeeds/cves/versions_test.go +++ b/vulnfeeds/cves/versions_test.go @@ -6,11 +6,10 @@ import ( "log" "os" "reflect" + "slices" "testing" "time" - "slices" - "github.com/google/go-cmp/cmp" "github.com/google/osv/vulnfeeds/internal/testutils" "github.com/google/osv/vulnfeeds/models" @@ -18,13 +17,13 @@ import ( "google.golang.org/protobuf/testing/protocmp" ) -func loadTestData2(cveName string) Vulnerability { +func loadTestData2(cveName string) models.Vulnerability { fileName := fmt.Sprintf("../test_data/nvdcve-2.0/%s.json", cveName) file, err := os.Open(fileName) if err != nil { log.Fatalf("Failed to load test data from %q", fileName) } - var nvdCves CVEAPIJSON20Schema + var nvdCves models.CVEAPIJSON20Schema err = json.NewDecoder(file).Decode(&nvdCves) if err != nil { log.Fatalf("Failed to decode %q: %+v", fileName, err) @@ -36,14 +35,14 @@ func loadTestData2(cveName string) Vulnerability { } log.Fatalf("test data doesn't contain %q", cveName) - return Vulnerability{} + return models.Vulnerability{} } func TestParseCPE(t *testing.T) { tests := []struct { description string inputCPEString string - expectedCPEStruct *models.CPE + expectedCPEStruct *models.CPEString expectedOk bool }{ { @@ -67,7 +66,7 @@ func TestParseCPE(t *testing.T) { }, { description: "valid input (hardware)", inputCPEString: "cpe:2.3:h:intel:core_i3-1005g1:-:*:*:*:*:*:*:*", - expectedCPEStruct: &models.CPE{ + expectedCPEStruct: &models.CPEString{ CPEVersion: "2.3", Part: "h", Vendor: "intel", @@ -86,7 +85,7 @@ func TestParseCPE(t *testing.T) { { description: "valid input (software)", inputCPEString: "cpe:2.3:a:gitlab:gitlab:*:*:*:*:community:*:*:*", - expectedCPEStruct: &models.CPE{ + expectedCPEStruct: &models.CPEString{ CPEVersion: "2.3", Part: "a", Vendor: "gitlab", @@ -105,7 +104,7 @@ func TestParseCPE(t *testing.T) { { description: "valid input (software) with embedded colons", inputCPEString: "cpe:2.3:a:http\\:\\:daemon_project:http\\:\\:daemon:*:*:*:*:*:*:*:*", - expectedCPEStruct: &models.CPE{ + expectedCPEStruct: &models.CPEString{ CPEVersion: "2.3", Part: "a", Vendor: "http::daemon_project", @@ -124,7 +123,7 @@ func TestParseCPE(t *testing.T) { { description: "valid input (software) with escaped characters", inputCPEString: "cpe:2.3:a:bloodshed:dev-c\\+\\+:4.9.9.2:*:*:*:*:*:*:*", - expectedCPEStruct: &models.CPE{ + expectedCPEStruct: &models.CPEString{ CPEVersion: "2.3", Part: "a", Vendor: "bloodshed", @@ -710,7 +709,7 @@ func TestExtractGitCommit(t *testing.T) { func TestExtractVersionInfo(t *testing.T) { tests := []struct { description string - inputCVEItem Vulnerability + inputCVEItem models.Vulnerability inputValidVersions []string expectedVersionInfo models.VersionInfo expectedNotes []string @@ -919,7 +918,8 @@ func TestExtractVersionInfo(t *testing.T) { if !tc.disableExpiryDate.IsZero() && time.Now().After(tc.disableExpiryDate) { t.Logf("test %q: VersionInfo for %#v has been enabled on %s.", tc.description, tc.inputCVEItem, tc.disableExpiryDate) } - gotVersionInfo, _ := ExtractVersionInfo(tc.inputCVEItem.CVE, tc.inputValidVersions, client) + metrics := &models.ConversionMetrics{} + gotVersionInfo := ExtractVersionInfo(tc.inputCVEItem.CVE, tc.inputValidVersions, client, metrics) if diff := cmp.Diff(tc.expectedVersionInfo, gotVersionInfo); diff != "" { t.Errorf("test %q: VersionInfo for %#v was incorrect: %s", tc.description, tc.inputCVEItem, diff) } @@ -930,7 +930,7 @@ func TestExtractVersionInfo(t *testing.T) { func TestCPEs(t *testing.T) { tests := []struct { description string - inputCVEItem Vulnerability + inputCVEItem models.Vulnerability expectedCPEs []string }{ { @@ -1284,9 +1284,9 @@ func TestCommit(t *testing.T) { func TestReposFromReferences(t *testing.T) { type args struct { CVE string - cache VendorProductToRepoMap + cache *VPRepoCache vp *VendorProduct - refs []Reference + refs []models.Reference tagDenyList []string } tests := []struct { @@ -1298,9 +1298,9 @@ func TestReposFromReferences(t *testing.T) { name: "A CVE with a repo not already present in the VendorRepo cache (that happens to have a useful commit and a repo that has no tags)", args: args{ CVE: "CVE-2023-0327", - cache: nil, + cache: NewVPRepoCache(), vp: &VendorProduct{"theradsystem_project", "theradsystem"}, - refs: []Reference{ + refs: []models.Reference{ { Source: "cna@vuldb.com", Tags: []string{"Patch", "Third Party Advisory"}, @@ -1313,10 +1313,8 @@ func TestReposFromReferences(t *testing.T) { { name: "A CVE with a useless (vulnerability researcher) repo", args: args{ - CVE: "CVE-2025-0211", - cache: nil, - vp: &VendorProduct{"campcodes", "school_faculty_scheduling_system"}, - refs: []Reference{ + CVE: "CVE-2025-0211", + refs: []models.Reference{ { Source: "cna@vuldb.com", Tags: []string{"Exploit", "Third Party Advisory"}, @@ -1329,10 +1327,8 @@ func TestReposFromReferences(t *testing.T) { { name: "A CVE with a cgit repo reference that does not work without transformation", args: args{ - CVE: "CVE-2025-26519", - cache: nil, - vp: nil, - refs: []Reference{ + CVE: "CVE-2025-26519", + refs: []models.Reference{ { Source: "cna@mitre.org", Tags: nil, @@ -1346,10 +1342,8 @@ func TestReposFromReferences(t *testing.T) { { name: "A CVE with a valid GitHub repo that stopped working", args: args{ - CVE: "CVE-2016-10525", - cache: nil, - vp: nil, - refs: []Reference{ + CVE: "CVE-2016-10525", + refs: []models.Reference{ { Source: "support@hackerone.com", Tags: []string{"Patch", "Third Party Advisory"}, @@ -1361,10 +1355,12 @@ func TestReposFromReferences(t *testing.T) { wantRepos: []string{"https://github.com/dwyl/hapi-auth-jwt2"}, }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { testutils.SetupGitVCR(t) - if gotRepos := ReposFromReferences(tt.args.CVE, tt.args.cache, tt.args.vp, tt.args.refs, tt.args.tagDenyList); !reflect.DeepEqual(gotRepos, tt.wantRepos) { + metrics := &models.ConversionMetrics{} + if gotRepos := ReposFromReferences(tt.args.cache, tt.args.vp, tt.args.refs, tt.args.tagDenyList, metrics); !reflect.DeepEqual(gotRepos, tt.wantRepos) { t.Errorf("ReposFromReferences() = %#v, want %#v", gotRepos, tt.wantRepos) } }) @@ -1374,9 +1370,7 @@ func TestReposFromReferences(t *testing.T) { func TestReposFromReferencesCVEList(t *testing.T) { type args struct { CVE string - cache VendorProductToRepoMap - vp *VendorProduct - refs []Reference + refs []models.Reference tagDenyList []string } tests := []struct { @@ -1387,10 +1381,8 @@ func TestReposFromReferencesCVEList(t *testing.T) { { name: "A CVE with a repo not already present in the VendorRepo cache (that happens to have a useful commit and a repo that has no tags)", args: args{ - CVE: "CVE-2023-0327", - cache: nil, - vp: &VendorProduct{"theradsystem_project", "theradsystem"}, - refs: []Reference{ + CVE: "CVE-2023-0327", + refs: []models.Reference{ { Source: "cna@vuldb.com", Tags: []string{"Patch", "Third Party Advisory"}, @@ -1403,10 +1395,8 @@ func TestReposFromReferencesCVEList(t *testing.T) { { name: "A CVE with a useless (vulnerability researcher) repo", args: args{ - CVE: "CVE-2025-0211", - cache: nil, - vp: &VendorProduct{"campcodes", "school_faculty_scheduling_system"}, - refs: []Reference{ + CVE: "CVE-2025-0211", + refs: []models.Reference{ { Source: "cna@vuldb.com", Tags: []string{"Exploit", "Third Party Advisory"}, @@ -1419,10 +1409,8 @@ func TestReposFromReferencesCVEList(t *testing.T) { { name: "A CVE with a cgit repo reference that does not work without transformation", args: args{ - CVE: "CVE-2025-26519", - cache: nil, - vp: nil, - refs: []Reference{ + CVE: "CVE-2025-26519", + refs: []models.Reference{ { Source: "cna@mitre.org", Tags: nil, @@ -1436,10 +1424,8 @@ func TestReposFromReferencesCVEList(t *testing.T) { { name: "A CVE with a valid GitHub repo that stopped working", args: args{ - CVE: "CVE-2016-10525", - cache: nil, - vp: nil, - refs: []Reference{ + CVE: "CVE-2016-10525", + refs: []models.Reference{ { Source: "support@hackerone.com", Tags: []string{"Patch", "Third Party Advisory"}, @@ -1452,10 +1438,8 @@ func TestReposFromReferencesCVEList(t *testing.T) { }, { name: "A CVE with a repo not already present)", args: args{ - CVE: "CVE-2024-7790", - cache: nil, - vp: &VendorProduct{"Devikia", "DevikaAI"}, - refs: []Reference{ + CVE: "CVE-2024-7790", + refs: []models.Reference{ { Source: "cna@vuldb.com", Tags: []string{"Patch", "Third Party Advisory"}, @@ -1469,16 +1453,17 @@ func TestReposFromReferencesCVEList(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { testutils.SetupGitVCR(t) - if gotRepos, _ := ReposFromReferencesCVEList(tt.args.CVE, tt.args.refs, tt.args.tagDenyList); !reflect.DeepEqual(gotRepos, tt.wantRepos) { - t.Errorf("ReposFromReferences() = %#v, want %#v", gotRepos, tt.wantRepos) + metrics := &models.ConversionMetrics{} + if gotRepos := ReposFromReferencesCVEList(tt.args.refs, tt.args.tagDenyList, metrics); !reflect.DeepEqual(gotRepos, tt.wantRepos) { + t.Errorf("ReposFromReferencesCVEList() = %#v, want %#v", gotRepos, tt.wantRepos) } }) } } -func Test_MaybeUpdateVPRepoCache(t *testing.T) { +func Test_MaybeUpdate(t *testing.T) { type args struct { - cache VendorProductToRepoMap + cache *VPRepoCache vp *VendorProduct repos []string } @@ -1487,19 +1472,10 @@ func Test_MaybeUpdateVPRepoCache(t *testing.T) { args args wantCache VendorProductToRepoMap }{ - { - name: "Test with no cache", - args: args{ - cache: nil, - vp: &VendorProduct{"avendor", "aproduct"}, - repos: []string{"https://github.com/google/osv.dev"}, - }, - wantCache: nil, - }, { name: "Test with an empty cache", args: args{ - cache: VendorProductToRepoMap{}, + cache: NewVPRepoCache(), vp: &VendorProduct{"avendor", "aproduct"}, repos: []string{"https://github.com/google/osv.dev"}, }, @@ -1510,7 +1486,7 @@ func Test_MaybeUpdateVPRepoCache(t *testing.T) { { name: "Test with an empty cache and an unusable repo", args: args{ - cache: VendorProductToRepoMap{}, + cache: NewVPRepoCache(), vp: &VendorProduct{"avendor", "aproduct"}, repos: []string{"https://github.com/vendor/repo"}, }, @@ -1519,20 +1495,25 @@ func Test_MaybeUpdateVPRepoCache(t *testing.T) { { name: "Test with an existing cache", args: args{ - cache: VendorProductToRepoMap{ - VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv.dev"}, + cache: &VPRepoCache{ + m: VendorProductToRepoMap{ + VendorProduct{ + "avendor", + "aproduct", + }: []string{"https://github.com/google/osv-scanner"}, + }, }, vp: &VendorProduct{"avendor", "aproduct"}, - repos: []string{"https://github.com/google/osv-scanner"}, + repos: []string{"https://github.com/google/osv.dev"}, }, wantCache: VendorProductToRepoMap{ - VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv.dev", "https://github.com/google/osv-scanner"}, + VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv-scanner", "https://github.com/google/osv.dev"}, }, }, { name: "Test with an empty cache adding two values", args: args{ - cache: VendorProductToRepoMap{}, + cache: NewVPRepoCache(), vp: &VendorProduct{"avendor", "aproduct"}, repos: []string{"https://github.com/google/osv.dev", "https://github.com/google/osv-scanner"}, }, @@ -1541,14 +1522,98 @@ func Test_MaybeUpdateVPRepoCache(t *testing.T) { }, }, } - for _, tt := range tests { + for i := range tests { + tt := &tests[i] t.Run(tt.name, func(t *testing.T) { testutils.SetupGitVCR(t) + cache := tt.args.cache for _, repo := range tt.args.repos { - MaybeUpdateVPRepoCache(tt.args.cache, tt.args.vp, repo) + cache.MaybeUpdate(tt.args.vp, repo) + } + if !reflect.DeepEqual(cache.m, tt.wantCache) { + t.Errorf("MaybeUpdate() have %#v, wanted %#v", cache.m, tt.wantCache) + } + }) + } +} + +func TestVPRepoCache_MaybeRemove(t *testing.T) { + type args struct { + cache *VPRepoCache + vp *VendorProduct + repo string + } + tests := []struct { + name string + args args + wantCache VendorProductToRepoMap + }{ + { + name: "Test with a nil vp", + args: args{ + cache: NewVPRepoCache(), + vp: nil, + repo: "https://github.com/google/osv.dev", + }, + wantCache: VendorProductToRepoMap{}, + }, + { + name: "Test removing existing repo", + args: args{ + cache: &VPRepoCache{ + m: VendorProductToRepoMap{ + VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv.dev", "https://github.com/google/osv-scanner"}, + }, + }, + vp: &VendorProduct{"avendor", "aproduct"}, + repo: "https://github.com/google/osv.dev", + }, + wantCache: VendorProductToRepoMap{ + VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv-scanner"}, + }, + }, + { + name: "Test removing non-existing repo", + args: args{ + cache: &VPRepoCache{ + m: VendorProductToRepoMap{ + VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv-scanner"}, + }, + }, + vp: &VendorProduct{"avendor", "aproduct"}, + repo: "https://github.com/google/osv.dev", + }, + wantCache: VendorProductToRepoMap{ + VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv-scanner"}, + }, + }, + { + name: "Test removing last repo", + args: args{ + cache: &VPRepoCache{ + m: VendorProductToRepoMap{ + VendorProduct{"avendor", "aproduct"}: []string{"https://github.com/google/osv.dev"}, + }, + }, + vp: &VendorProduct{"avendor", "aproduct"}, + repo: "https://github.com/google/osv.dev", + }, + wantCache: VendorProductToRepoMap{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cache := tt.args.cache + cache.MaybeRemove(tt.args.vp, tt.args.repo) + if cache == nil { + if tt.wantCache != nil { + t.Errorf("MaybeRemove() cache is nil, wanted %#v", tt.wantCache) + } + + return } - if !reflect.DeepEqual(tt.args.cache, tt.wantCache) { - t.Errorf("maybeUpdateVPRepoCache() have %#v, wanted %#v", tt.args.cache, tt.wantCache) + if !reflect.DeepEqual(cache.m, tt.wantCache) { + t.Errorf("MaybeRemove() have %#v, wanted %#v", cache.m, tt.wantCache) } }) } diff --git a/vulnfeeds/git/repository.go b/vulnfeeds/git/repository.go index f5d55d74ead..e40a012987e 100644 --- a/vulnfeeds/git/repository.go +++ b/vulnfeeds/git/repository.go @@ -25,6 +25,7 @@ import ( "slices" "sort" "strings" + "sync" "time" "github.com/go-git/go-git/v5" @@ -64,7 +65,31 @@ type RepoTagsMap struct { } // RepoTags acts as a cache for RepoTags results, keyed on the repo's URL. -type RepoTagsCache map[string]RepoTagsMap +type RepoTagsCache struct { + sync.RWMutex + + m map[string]RepoTagsMap +} + +func (c *RepoTagsCache) Get(repo string) (RepoTagsMap, bool) { + c.RLock() + defer c.RUnlock() + if c.m == nil { + return RepoTagsMap{}, false + } + tags, ok := c.m[repo] + + return tags, ok +} + +func (c *RepoTagsCache) Set(repo string, tags RepoTagsMap) { + c.Lock() + defer c.Unlock() + if c.m == nil { + c.m = make(map[string]RepoTagsMap) + } + c.m[repo] = tags +} // RemoteRepoRefsWithRetry will exponentially retry listing the peeled references of the repoURL up to retries times. func RemoteRepoRefsWithRetry(repoURL string, retries uint64) (refs []*plumbing.Reference, err error) { @@ -113,9 +138,9 @@ func RepoName(repoURL string) (name string, e error) { // RepoTags returns an array of Tag being the (unpeeled, if annotated) tags and associated commits in repoURL. // An optional repoTagsCache can be supplied to reduce repeated remote connections to the same repo. -func RepoTags(repoURL string, repoTagsCache RepoTagsCache) (tags Tags, e error) { +func RepoTags(repoURL string, repoTagsCache *RepoTagsCache) (tags Tags, e error) { if repoTagsCache != nil { - tags, ok := repoTagsCache[repoURL] + tags, ok := repoTagsCache.Get(repoURL) if ok { return slices.Collect(maps.Values(tags.Tag)), nil } @@ -149,7 +174,7 @@ func RepoTags(repoURL string, repoTagsCache RepoTagsCache) (tags Tags, e error) // Sort so that we get consistently ordered output for test validation purposes. sort.Sort(tags) if repoTagsCache != nil { - repoTagsCache[repoURL] = RepoTagsMap{Tag: tagsMap, NormalizedTag: nil} + repoTagsCache.Set(repoURL, RepoTagsMap{Tag: tagsMap, NormalizedTag: nil}) } return tags, nil @@ -186,9 +211,9 @@ func normalizeRepoTag(tag string, reponame string) (normalizedTag string, err er // NormalizeRepoTags returns a map of normalized tags mapping back to original tags and also commit hashes. // An optional repoTagsCache can be supplied to reduce repeated remote connections to the same repo. -func NormalizeRepoTags(repoURL string, repoTagsCache RepoTagsCache) (normalizedTags map[string]NormalizedTag, e error) { +func NormalizeRepoTags(repoURL string, repoTagsCache *RepoTagsCache) (normalizedTags map[string]NormalizedTag, e error) { if repoTagsCache != nil { - tags, ok := repoTagsCache[repoURL] + tags, ok := repoTagsCache.Get(repoURL) if ok && tags.NormalizedTag != nil { return tags.NormalizedTag, nil } @@ -213,8 +238,8 @@ func NormalizeRepoTags(repoURL string, repoTagsCache RepoTagsCache) (normalizedT } if repoTagsCache != nil { // The RepoTags() call above will have cached the Tag map already - tagsMap := repoTagsCache[repoURL].Tag - repoTagsCache[repoURL] = RepoTagsMap{Tag: tagsMap, NormalizedTag: normalizedTags} + repoTagsMap, _ := repoTagsCache.Get(repoURL) + repoTagsCache.Set(repoURL, RepoTagsMap{Tag: repoTagsMap.Tag, NormalizedTag: normalizedTags}) } return normalizedTags, nil diff --git a/vulnfeeds/git/repository_test.go b/vulnfeeds/git/repository_test.go index 7439e5fb81e..ce74f76f1a2 100644 --- a/vulnfeeds/git/repository_test.go +++ b/vulnfeeds/git/repository_test.go @@ -51,12 +51,12 @@ func TestRepoName(t *testing.T) { } func TestRepoTags(t *testing.T) { - cache := make(RepoTagsCache) + cache := &RepoTagsCache{} tests := []struct { description string inputRepoURL string - cache RepoTagsCache + cache *RepoTagsCache expectedResult Tags expectedOk bool disableExpiryDate time.Time @@ -174,7 +174,9 @@ func TestRepoTags(t *testing.T) { } var cacheBefore, cacheAfter int if tc.cache != nil { - cacheBefore = len(tc.cache) + tc.cache.RLock() + cacheBefore = len(tc.cache.m) + tc.cache.RUnlock() } got, err := RepoTags(tc.inputRepoURL, tc.cache) if err != nil && tc.expectedOk { @@ -184,7 +186,9 @@ func TestRepoTags(t *testing.T) { t.Errorf("test %q: RepoTags(%q) incorrect result: %s", tc.description, tc.inputRepoURL, diff) } if tc.cache != nil { - cacheAfter = len(tc.cache) + tc.cache.RLock() + cacheAfter = len(tc.cache.m) + tc.cache.RUnlock() } if tc.cache != nil && (cacheAfter <= cacheBefore) { t.Errorf("test %q: RepoTags(%q) incorrect cache behaviour: size before: %d size after: %d cache: %#v", tc.description, tc.inputRepoURL, cacheBefore, cacheAfter, tc.cache) @@ -287,7 +291,7 @@ func TestNormalizeRepoTags(t *testing.T) { expectedOk: false, }, } - cache := make(RepoTagsCache) + cache := &RepoTagsCache{} for _, tc := range tests { t.Run(tc.description, func(t *testing.T) { testutils.SetupGitVCR(t) @@ -302,7 +306,8 @@ func TestNormalizeRepoTags(t *testing.T) { if len(normalizedRepoTags) == 0 && tc.expectedOk { t.Errorf("test %q: NormalizeRepoTags(%q): failed to find any normalized versions for repo in map: %#v", tc.description, tc.inputRepoURL, normalizedRepoTags) } - if len(normalizedRepoTags) > 0 && cache[tc.inputRepoURL].NormalizedTag == nil { + tags, _ := cache.Get(tc.inputRepoURL) + if len(normalizedRepoTags) > 0 && tags.NormalizedTag == nil { t.Errorf("test %q: NormalizeRepoTags(%q) incorrect cache behaviour: %#v", tc.description, tc.inputRepoURL, cache) } t.Logf("test %q: NormalizedRepoTags(%q): %#v", tc.description, tc.inputRepoURL, normalizedRepoTags) diff --git a/vulnfeeds/git/versions_test.go b/vulnfeeds/git/versions_test.go index 4b1c653fd2c..39e14e206a1 100644 --- a/vulnfeeds/git/versions_test.go +++ b/vulnfeeds/git/versions_test.go @@ -10,12 +10,12 @@ import ( ) func TestVersionToAffectedCommit(t *testing.T) { - cache := make(RepoTagsCache) + cache := &RepoTagsCache{} tests := []struct { description string inputRepoURL string - cache RepoTagsCache + cache *RepoTagsCache inputVersion string expectedResult string expectedOk bool diff --git a/vulnfeeds/go.mod b/vulnfeeds/go.mod index a9aa4e8aba7..38adcd65d38 100644 --- a/vulnfeeds/go.mod +++ b/vulnfeeds/go.mod @@ -1,21 +1,21 @@ module github.com/google/osv/vulnfeeds -go 1.25.5 +go 1.25.6 require ( cloud.google.com/go/secretmanager v1.16.0 - cloud.google.com/go/storage v1.58.0 + cloud.google.com/go/storage v1.59.1 github.com/aquasecurity/go-pep440-version v0.0.1 - github.com/atombender/go-jsonschema v0.20.0 + github.com/atombender/go-jsonschema v0.21.0 github.com/charmbracelet/lipgloss v1.1.0 github.com/gkampitakis/go-snaps v0.5.19 github.com/go-git/go-git/v5 v5.16.4 github.com/google/go-cmp v0.7.0 github.com/google/osv-scanner v1.9.2 github.com/knqyf263/go-cpe v0.0.0-20230627041855-cb0794d06872 - github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae + github.com/ossf/osv-schema/bindings/go v0.0.0-20260127070820-fe5c3a64c8f4 github.com/sethvargo/go-retry v0.3.0 - google.golang.org/api v0.259.0 + google.golang.org/api v0.263.0 google.golang.org/protobuf v1.36.11 gopkg.in/dnaeon/go-vcr.v4 v4.0.6 gopkg.in/yaml.v2 v2.4.0 @@ -24,7 +24,7 @@ require ( require ( cel.dev/expr v0.24.0 // indirect cloud.google.com/go v0.123.0 // indirect - cloud.google.com/go/auth v0.18.0 // indirect + cloud.google.com/go/auth v0.18.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.5.3 // indirect @@ -55,11 +55,11 @@ require ( github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/goccy/go-yaml v1.18.0 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect github.com/googleapis/gax-go/v2 v2.16.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect @@ -89,24 +89,24 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect - golang.org/x/crypto v0.46.0 // indirect + golang.org/x/crypto v0.47.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect - golang.org/x/net v0.48.0 // indirect + golang.org/x/net v0.49.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d // indirect google.golang.org/grpc v1.78.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/vulnfeeds/go.sum b/vulnfeeds/go.sum index 44227cd6cf4..3cf4ff89ab8 100644 --- a/vulnfeeds/go.sum +++ b/vulnfeeds/go.sum @@ -2,8 +2,8 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= -cloud.google.com/go/auth v0.18.0 h1:wnqy5hrv7p3k7cShwAU/Br3nzod7fxoqG+k0VZ+/Pk0= -cloud.google.com/go/auth v0.18.0/go.mod h1:wwkPM1AgE1f2u6dG443MiWoD8C3BtOywNsUMcUTVDRo= +cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= +cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= @@ -18,8 +18,8 @@ cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhO cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI= cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k= cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q= -cloud.google.com/go/storage v1.58.0 h1:PflFXlmFJjG/nBeR9B7pKddLQWaFaRWx4uUi/LyNxxo= -cloud.google.com/go/storage v1.58.0/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI= +cloud.google.com/go/storage v1.59.1 h1:DXAZLcTimtiXdGqDSnebROVPd9QvRsFVVlptz02Wk58= +cloud.google.com/go/storage v1.59.1/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI= cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U= cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= @@ -45,8 +45,8 @@ github.com/aquasecurity/go-version v0.0.1 h1:4cNl516agK0TCn5F7mmYN+xVs1E3S45LkgZ github.com/aquasecurity/go-version v0.0.1/go.mod h1:s1UU6/v2hctXcOa3OLwfj5d9yoXHa3ahf+ipSwEvGT0= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/atombender/go-jsonschema v0.20.0 h1:AHg0LeI0HcjQ686ALwUNqVJjNRcSXpIR6U+wC2J0aFY= -github.com/atombender/go-jsonschema v0.20.0/go.mod h1:ZmbuR11v2+cMM0PdP6ySxtyZEGFBmhgF4xa4J6Hdls8= +github.com/atombender/go-jsonschema v0.21.0 h1:8vLnNySEr/uxGhkXiYU1t1tE4KFNqWPyAn8hH8ZB2rk= +github.com/atombender/go-jsonschema v0.21.0/go.mod h1:kCGEzNO4GDtCAJNuQKr27JVPDo/i2KvJUN8G0Nw3FxA= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -107,8 +107,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= -github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -123,8 +123,8 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= +github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y= github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -152,8 +152,8 @@ github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae h1:nvfTerE/hSYc/TQ3JUZYeL7DuVhjPkBeOGxicPzoJmc= -github.com/ossf/osv-schema/bindings/go v0.0.0-20251230224438-88c48750ddae/go.mod h1:Eo7R19vlnflsCRdHW1ynyNUyoRwxdaTmTWD9MtKnJTc= +github.com/ossf/osv-schema/bindings/go v0.0.0-20260127070820-fe5c3a64c8f4 h1:42Ib9B6yTDoMdsW9gYxu2AoBq1vKXYc7yBIU0Yq8OcU= +github.com/ossf/osv-schema/bindings/go v0.0.0-20260127070820-fe5c3a64c8f4/go.mod h1:Eo7R19vlnflsCRdHW1ynyNUyoRwxdaTmTWD9MtKnJTc= github.com/package-url/packageurl-go v0.1.3 h1:4juMED3hHiz0set3Vq3KeQ75KD1avthoXLtmE3I0PLs= github.com/package-url/packageurl-go v0.1.3/go.mod h1:nKAWB8E6uk1MHqiS/lQb9pYBGH2+mdJ2PJc2s50dQY0= github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= @@ -209,28 +209,28 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0= golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= @@ -242,14 +242,14 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= -golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -257,14 +257,14 @@ golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhS golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.259.0 h1:90TaGVIxScrh1Vn/XI2426kRpBqHwWIzVBzJsVZ5XrQ= -google.golang.org/api v0.259.0/go.mod h1:LC2ISWGWbRoyQVpxGntWwLWN/vLNxxKBK9KuJRI8Te4= +google.golang.org/api v0.263.0 h1:UFs7qn8gInIdtk1ZA6eXRXp5JDAnS4x9VRsRVCeKdbk= +google.golang.org/api v0.263.0/go.mod h1:fAU1xtNNisHgOF5JooAs8rRaTkl2rT3uaoNGo9NS3R8= google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934= google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d h1:xXzuihhT3gL/ntduUZwHECzAn57E8dA6l8SOtYWdD8Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260122232226-8e98ce8d340d/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/vulnfeeds/cves/cve.go b/vulnfeeds/models/cve.go similarity index 98% rename from vulnfeeds/cves/cve.go rename to vulnfeeds/models/cve.go index da606e00fb7..875896834dd 100644 --- a/vulnfeeds/cves/cve.go +++ b/vulnfeeds/models/cve.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package cves contains CVE-specific data structures. -package cves +// Package models contains CVE-specific data structures. +package models import ( "strings" diff --git a/vulnfeeds/models/metrics.go b/vulnfeeds/models/metrics.go new file mode 100644 index 00000000000..85d7c1db4cd --- /dev/null +++ b/vulnfeeds/models/metrics.go @@ -0,0 +1,93 @@ +package models + +import ( + "fmt" + "log/slog" + + "github.com/google/osv/vulnfeeds/utility/logger" + "github.com/ossf/osv-schema/bindings/go/osvschema" +) + +type ConversionOutcome int + +const ( + Extension = ".json" +) + +const ( + // Set of enums for categorizing conversion outcomes. + ConversionUnknown ConversionOutcome = iota // Shouldn't happen + Successful // It worked! + Rejected // The CVE was rejected + NoSoftware // The CVE had no CPEs relating to software (i.e. Operating Systems or Hardware). + NoRepos // The CPE Vendor/Product had no repositories derived for it. + NoCommitRanges // No viable commit ranges could be calculated from the repository for the CVE's CPE(s). + NoRanges // No version ranges could be extracted from the record. + FixUnresolvable // Partial resolution of versions, resulting in a false positive. +) + +// RefTagDenyList contains reference tags that are often associated with unreliable or +// irrelevant repository URLs. References with these tags are currently ignored +// to avoid incorrect repository associations. +var RefTagDenyList = []string{ + // "Exploit", + // "Third Party Advisory", + "Broken Link", // Actively ignore these. +} + +func (c ConversionOutcome) String() string { + return [...]string{"ConversionUnknown", "Successful", "Rejected", "NoSoftware", "NoRepos", "NoCommitRanges", "NoRanges", "FixUnresolvable"}[c] +} + +// ConversionMetrics holds the collected data about the conversion process for a single CVE. +type ConversionMetrics struct { + CVEID CVEID `json:"id"` // The CVE ID + CNA string `json:"cna"` // The CNA that assigned the CVE. + Outcome ConversionOutcome `json:"outcome"` // The final outcome of the conversion (e.g., "Successful", "Failed"). + Repos []string `json:"repos"` // A list of repositories extracted from the CVE's references. + RefTypesCount map[osvschema.Reference_Type]int `json:"ref_types_count"` // A count of each type of reference found. + VersionSources []VersionSource `json:"version_sources"` // A list of the ways the versions were extracted + Notes []string `json:"notes"` // A collection of notes and warnings generated during conversion. + CPEs []string `json:"cpes"` + UnresolvedRangesCount int `json:"unresolved_ranges_count"` + ResolvedRangesCount int `json:"resolved_ranges_count"` +} + +// AddNote adds a formatted note to the ConversionMetrics. +func (m *ConversionMetrics) AddNote(format string, a ...any) { + m.Notes = append(m.Notes, fmt.Sprintf(format, a...)) + logger.Debug(fmt.Sprintf(format, a...), slog.String("cna", m.CNA), slog.String("cve", string(m.CVEID))) +} + +// AddSource appends a source to the ConversionMetrics +func (m *ConversionMetrics) AddSource(source VersionSource) { + m.VersionSources = append(m.VersionSources, source) +} + +// VersionSource indicates the source of the extracted version information. +type VersionSource string + +const ( + VersionSourceNone VersionSource = "NOVERS" + VersionSourceAffected VersionSource = "CVEAFFVERS" + VersionSourceGit VersionSource = "GITVERS" + VersionSourceCPE VersionSource = "CPEVERS" + VersionSourceDescription VersionSource = "DESCRVERS" +) + +func DetermineOutcome(metrics *ConversionMetrics) { + // check if we have affected ranges/versions. + if len(metrics.Repos) == 0 { + // Fix unlikely, as no repos to resolve + metrics.Outcome = NoRepos + return + } + + if metrics.ResolvedRangesCount > 0 { + metrics.Outcome = Successful + } else if metrics.UnresolvedRangesCount > 0 { + metrics.Outcome = NoCommitRanges + } else { + metrics.Outcome = NoRanges + } +} diff --git a/vulnfeeds/cves/nvd2.go b/vulnfeeds/models/nvd2.go similarity index 99% rename from vulnfeeds/cves/nvd2.go rename to vulnfeeds/models/nvd2.go index 95d5fd8b653..3b1038fbaa9 100644 --- a/vulnfeeds/cves/nvd2.go +++ b/vulnfeeds/models/nvd2.go @@ -17,7 +17,7 @@ // --capitalization JSON \ // cve_api_json_2.0.schema -package cves +package models import ( "encoding/json" @@ -109,7 +109,7 @@ type CVEAPIJSON20Schema struct { type CVEID string -type CVE struct { +type NVDCVE struct { // CISAActionDue corresponds to the JSON schema field "cisaActionDue". CISAActionDue *types.SerializableDate `json:"cisaActionDue,omitempty" mapstructure:"cisaActionDue,omitempty" yaml:"cisaActionDue,omitempty"` @@ -311,7 +311,7 @@ type LangString struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *CVE) UnmarshalJSON(b []byte) error { +func (j *NVDCVE) UnmarshalJSON(b []byte) error { var raw map[string]any if err := json.Unmarshal(b, &raw); err != nil { return err @@ -331,7 +331,7 @@ func (j *CVE) UnmarshalJSON(b []byte) error { if v, ok := raw["references"]; !ok || v == nil { return errors.New("field references in CveItem: required") } - type Plain CVE + type Plain NVDCVE var plain Plain if err := json.Unmarshal(b, &plain); err != nil { return err @@ -344,14 +344,14 @@ func (j *CVE) UnmarshalJSON(b []byte) error { // if len(plain.References) > 500 { // return fmt.Errorf("field %s length: must be <= %d", "references", 500) // } - *j = CVE(plain) + *j = NVDCVE(plain) return nil } // (hand generated), see https://github.com/omissis/go-jsonschema/issues/171 type Vulnerability struct { - CVE CVE `json:"cve" mapstructure:"cve" yaml:"cve"` + CVE NVDCVE `json:"cve" mapstructure:"cve" yaml:"cve"` } // CVSS subscore. diff --git a/vulnfeeds/models/types.go b/vulnfeeds/models/types.go index b48c3eefab8..54e5e27d166 100644 --- a/vulnfeeds/models/types.go +++ b/vulnfeeds/models/types.go @@ -219,7 +219,7 @@ func (vi *VersionInfo) Duplicated(candidate AffectedCommit) bool { return false } -type CPE struct { +type CPEString struct { CPEVersion string Part string Vendor string diff --git a/vulnfeeds/pypi/pypi.go b/vulnfeeds/pypi/pypi.go index fe9b3541b3e..ed798350e1d 100644 --- a/vulnfeeds/pypi/pypi.go +++ b/vulnfeeds/pypi/pypi.go @@ -27,8 +27,8 @@ import ( "strings" version "github.com/aquasecurity/go-pep440-version" - "github.com/google/osv/vulnfeeds/cves" + "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/triage" "github.com/google/osv/vulnfeeds/utility/logger" ) @@ -244,7 +244,7 @@ func New(pypiLinksPath string, pypiVersionsPath string) *PyPI { } } -func (p *PyPI) Matches(cve cves.CVE, falsePositives *triage.FalsePositives) []string { +func (p *PyPI) Matches(cve models.NVDCVE, falsePositives *triage.FalsePositives) []string { matches := []string{} for _, reference := range cve.References { // If there is a PyPI link, it must be a Python package. These take precedence. @@ -348,9 +348,9 @@ func (p *PyPI) packageExists(pkg string) bool { return result } -func (p *PyPI) finalPkgCheck(cve cves.CVE, pkg string, falsePositives *triage.FalsePositives) bool { +func (p *PyPI) finalPkgCheck(cve models.NVDCVE, pkg string, falsePositives *triage.FalsePositives) bool { // To avoid false positives, check that the pkg name is mentioned in the description. - desc := strings.ToLower(cves.EnglishDescription(cve.Descriptions)) + desc := strings.ToLower(models.EnglishDescription(cve.Descriptions)) pkgNameParts := strings.Split(pkg, "-") for _, part := range pkgNameParts { @@ -375,7 +375,7 @@ func (p *PyPI) finalPkgCheck(cve cves.CVE, pkg string, falsePositives *triage.Fa } // matchesPackage checks if a given reference link matches a PyPI package. -func (p *PyPI) matchesPackage(link string, cve cves.CVE, falsePositives *triage.FalsePositives) []string { +func (p *PyPI) matchesPackage(link string, cve models.NVDCVE, falsePositives *triage.FalsePositives) []string { pkgs := []string{} u, err := url.Parse(strings.ToLower(link)) if err != nil { diff --git a/vulnfeeds/tools/debian/Dockerfile b/vulnfeeds/tools/debian/Dockerfile index bbfffb8cc52..2d5fbdec6f4 100644 --- a/vulnfeeds/tools/debian/Dockerfile +++ b/vulnfeeds/tools/debian/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:4bac65aa40d61f285b5c08452467c24f50ba68d9d0a2c36089b2cf8372cc4b49 +FROM gcr.io/google.com/cloudsdktool/google-cloud-cli:alpine@sha256:23eb1691f771e6c249a4db5bf9e4a9af9976b26617d33a8659453bda1bc408ed # Setup Poetry in its own virtual environment. # So when poetry changes the system dependencies, it doesn't mess with its own dependencies diff --git a/vulnfeeds/tools/debian/debian_converter/poetry.lock b/vulnfeeds/tools/debian/debian_converter/poetry.lock index 4a9f88881ab..bbfc4d9bb10 100644 --- a/vulnfeeds/tools/debian/debian_converter/poetry.lock +++ b/vulnfeeds/tools/debian/debian_converter/poetry.lock @@ -50,14 +50,14 @@ files = [ [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" description = "serialize all of Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, - {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, + {file = "dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}, + {file = "dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}, ] [package.extras] @@ -110,84 +110,84 @@ files = [ [[package]] name = "numpy" -version = "2.4.0" +version = "2.4.1" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.11" groups = ["main"] files = [ - {file = "numpy-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:316b2f2584682318539f0bcaca5a496ce9ca78c88066579ebd11fd06f8e4741e"}, - {file = "numpy-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2718c1de8504121714234b6f8241d0019450353276c88b9453c9c3d92e101db"}, - {file = "numpy-2.4.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:21555da4ec4a0c942520ead42c3b0dc9477441e085c42b0fbdd6a084869a6f6b"}, - {file = "numpy-2.4.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:413aa561266a4be2d06cd2b9665e89d9f54c543f418773076a76adcf2af08bc7"}, - {file = "numpy-2.4.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0feafc9e03128074689183031181fac0897ff169692d8492066e949041096548"}, - {file = "numpy-2.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8fdfed3deaf1928fb7667d96e0567cdf58c2b370ea2ee7e586aa383ec2cb346"}, - {file = "numpy-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e06a922a469cae9a57100864caf4f8a97a1026513793969f8ba5b63137a35d25"}, - {file = "numpy-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:927ccf5cd17c48f801f4ed43a7e5673a2724bd2171460be3e3894e6e332ef83a"}, - {file = "numpy-2.4.0-cp311-cp311-win32.whl", hash = "sha256:882567b7ae57c1b1a0250208cc21a7976d8cbcc49d5a322e607e6f09c9e0bd53"}, - {file = "numpy-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b986403023c8f3bf8f487c2e6186afda156174d31c175f747d8934dfddf3479"}, - {file = "numpy-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:3f3096405acc48887458bbf9f6814d43785ac7ba2a57ea6442b581dedbc60ce6"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a8b6bb8369abefb8bd1801b054ad50e02b3275c8614dc6e5b0373c305291037"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e284ca13d5a8367e43734148622caf0b261b275673823593e3e3634a6490f83"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:49ff32b09f5aa0cd30a20c2b39db3e669c845589f2b7fc910365210887e39344"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:36cbfb13c152b1c7c184ddac43765db8ad672567e7bafff2cc755a09917ed2e6"}, - {file = "numpy-2.4.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ddc8f4914466e6fc954c76527aa91aa763682a4f6d73249ef20b418fe6effb"}, - {file = "numpy-2.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc578891de1db95b2a35001b695451767b580bb45753717498213c5ff3c41d63"}, - {file = "numpy-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e81648e0b36e325ab67e46b5400a7a6d4a22b8a7c8e8bbfe20e7db7906bf95"}, - {file = "numpy-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d57b5046c120561ba8fa8e4030fbb8b822f3063910fa901ffadf16e2b7128ad6"}, - {file = "numpy-2.4.0-cp312-cp312-win32.whl", hash = "sha256:92190db305a6f48734d3982f2c60fa30d6b5ee9bff10f2887b930d7b40119f4c"}, - {file = "numpy-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:680060061adb2d74ce352628cb798cfdec399068aa7f07ba9fb818b2b3305f98"}, - {file = "numpy-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:39699233bc72dd482da1415dcb06076e32f60eddc796a796c5fb6c5efce94667"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a152d86a3ae00ba5f47b3acf3b827509fd0b6cb7d3259665e63dafbad22a75ea"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39b19251dec4de8ff8496cd0806cbe27bf0684f765abb1f4809554de93785f2d"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:009bd0ea12d3c784b6639a8457537016ce5172109e585338e11334f6a7bb88ee"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5fe44e277225fd3dff6882d86d3d447205d43532c3627313d17e754fb3905a0e"}, - {file = "numpy-2.4.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f935c4493eda9069851058fa0d9e39dbf6286be690066509305e52912714dbb2"}, - {file = "numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a"}, - {file = "numpy-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba0cb30acd3ef11c94dc27fbfba68940652492bc107075e7ffe23057f9425681"}, - {file = "numpy-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60e8c196cd82cbbd4f130b5290007e13e6de3eca79f0d4d38014769d96a7c475"}, - {file = "numpy-2.4.0-cp313-cp313-win32.whl", hash = "sha256:5f48cb3e88fbc294dc90e215d86fbaf1c852c63dbdb6c3a3e63f45c4b57f7344"}, - {file = "numpy-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:a899699294f28f7be8992853c0c60741f16ff199205e2e6cdca155762cbaa59d"}, - {file = "numpy-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:9198f447e1dc5647d07c9a6bbe2063cc0132728cc7175b39dbc796da5b54920d"}, - {file = "numpy-2.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74623f2ab5cc3f7c886add4f735d1031a1d2be4a4ae63c0546cfd74e7a31ddf6"}, - {file = "numpy-2.4.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0804a8e4ab070d1d35496e65ffd3cf8114c136a2b81f61dfab0de4b218aacfd5"}, - {file = "numpy-2.4.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:02a2038eb27f9443a8b266a66911e926566b5a6ffd1a689b588f7f35b81e7dc3"}, - {file = "numpy-2.4.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1889b3a3f47a7b5bee16bc25a2145bd7cb91897f815ce3499db64c7458b6d91d"}, - {file = "numpy-2.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85eef4cb5625c47ee6425c58a3502555e10f45ee973da878ac8248ad58c136f3"}, - {file = "numpy-2.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6dc8b7e2f4eb184b37655195f421836cfae6f58197b67e3ffc501f1333d993fa"}, - {file = "numpy-2.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:44aba2f0cafd287871a495fb3163408b0bd25bbce135c6f621534a07f4f7875c"}, - {file = "numpy-2.4.0-cp313-cp313t-win32.whl", hash = "sha256:20c115517513831860c573996e395707aa9fb691eb179200125c250e895fcd93"}, - {file = "numpy-2.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b48e35f4ab6f6a7597c46e301126ceba4c44cd3280e3750f85db48b082624fa4"}, - {file = "numpy-2.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:4d1cfce39e511069b11e67cd0bd78ceff31443b7c9e5c04db73c7a19f572967c"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c95eb6db2884917d86cde0b4d4cf31adf485c8ec36bf8696dd66fa70de96f36b"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:65167da969cd1ec3a1df31cb221ca3a19a8aaa25370ecb17d428415e93c1935e"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3de19cfecd1465d0dcf8a5b5ea8b3155b42ed0b639dba4b71e323d74f2a3be5e"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6c05483c3136ac4c91b4e81903cb53a8707d316f488124d0398499a4f8e8ef51"}, - {file = "numpy-2.4.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36667db4d6c1cea79c8930ab72fadfb4060feb4bfe724141cd4bd064d2e5f8ce"}, - {file = "numpy-2.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a818668b674047fd88c4cddada7ab8f1c298812783e8328e956b78dc4807f9f"}, - {file = "numpy-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ee32359fb7543b7b7bd0b2f46294db27e29e7bbdf70541e81b190836cd83ded"}, - {file = "numpy-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e493962256a38f58283de033d8af176c5c91c084ea30f15834f7545451c42059"}, - {file = "numpy-2.4.0-cp314-cp314-win32.whl", hash = "sha256:6bbaebf0d11567fa8926215ae731e1d58e6ec28a8a25235b8a47405d301332db"}, - {file = "numpy-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d857f55e7fdf7c38ab96c4558c95b97d1c685be6b05c249f5fdafcbd6f9899e"}, - {file = "numpy-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:bb50ce5fb202a26fd5404620e7ef820ad1ab3558b444cb0b55beb7ef66cd2d63"}, - {file = "numpy-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:355354388cba60f2132df297e2d53053d4063f79077b67b481d21276d61fc4df"}, - {file = "numpy-2.4.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:1d8f9fde5f6dc1b6fc34df8162f3b3079365468703fee7f31d4e0cc8c63baed9"}, - {file = "numpy-2.4.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e0434aa22c821f44eeb4c650b81c7fbdd8c0122c6c4b5a576a76d5a35625ecd9"}, - {file = "numpy-2.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40483b2f2d3ba7aad426443767ff5632ec3156ef09742b96913787d13c336471"}, - {file = "numpy-2.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6a7664ddd9746e20b7325351fe1a8408d0a2bf9c63b5e898290ddc8f09544"}, - {file = "numpy-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ecb0019d44f4cdb50b676c5d0cb4b1eae8e15d1ed3d3e6639f986fc92b2ec52c"}, - {file = "numpy-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d0ffd9e2e4441c96a9c91ec1783285d80bf835b677853fc2770a89d50c1e48ac"}, - {file = "numpy-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:77f0d13fa87036d7553bf81f0e1fe3ce68d14c9976c9851744e4d3e91127e95f"}, - {file = "numpy-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b1f5b45829ac1848893f0ddf5cb326110604d6df96cdc255b0bf9edd154104d4"}, - {file = "numpy-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:23a3e9d1a6f360267e8fbb38ba5db355a6a7e9be71d7fce7ab3125e88bb646c8"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b54c83f1c0c0f1d748dca0af516062b8829d53d1f0c402be24b4257a9c48ada6"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:aabb081ca0ec5d39591fc33018cd4b3f96e1a2dd6756282029986d00a785fba4"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:8eafe7c36c8430b7794edeab3087dec7bf31d634d92f2af9949434b9d1964cba"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2f585f52b2baf07ff3356158d9268ea095e221371f1074fadea2f42544d58b4d"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32ed06d0fe9cae27d8fb5f400c63ccee72370599c75e683a6358dd3a4fb50aaf"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:57c540ed8fb1f05cb997c6761cd56db72395b0d6985e90571ff660452ade4f98"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a39fb973a726e63223287adc6dafe444ce75af952d711e400f3bf2b36ef55a7b"}, - {file = "numpy-2.4.0.tar.gz", hash = "sha256:6e504f7b16118198f138ef31ba24d985b124c2c469fe8467007cf30fd992f934"}, + {file = "numpy-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0cce2a669e3c8ba02ee563c7835f92c153cf02edff1ae05e1823f1dde21b16a5"}, + {file = "numpy-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:899d2c18024984814ac7e83f8f49d8e8180e2fbe1b2e252f2e7f1d06bea92425"}, + {file = "numpy-2.4.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:09aa8a87e45b55a1c2c205d42e2808849ece5c484b2aab11fecabec3841cafba"}, + {file = "numpy-2.4.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:edee228f76ee2dab4579fad6f51f6a305de09d444280109e0f75df247ff21501"}, + {file = "numpy-2.4.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a92f227dbcdc9e4c3e193add1a189a9909947d4f8504c576f4a732fd0b54240a"}, + {file = "numpy-2.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:538bf4ec353709c765ff75ae616c34d3c3dca1a68312727e8f2676ea644f8509"}, + {file = "numpy-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ac08c63cb7779b85e9d5318e6c3518b424bc1f364ac4cb2c6136f12e5ff2dccc"}, + {file = "numpy-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f9c360ecef085e5841c539a9a12b883dff005fbd7ce46722f5e9cef52634d82"}, + {file = "numpy-2.4.1-cp311-cp311-win32.whl", hash = "sha256:0f118ce6b972080ba0758c6087c3617b5ba243d806268623dc34216d69099ba0"}, + {file = "numpy-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:18e14c4d09d55eef39a6ab5b08406e84bc6869c1e34eef45564804f90b7e0574"}, + {file = "numpy-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:6461de5113088b399d655d45c3897fa188766415d0f568f175ab071c8873bd73"}, + {file = "numpy-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2"}, + {file = "numpy-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8"}, + {file = "numpy-2.4.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a"}, + {file = "numpy-2.4.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0"}, + {file = "numpy-2.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c"}, + {file = "numpy-2.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02"}, + {file = "numpy-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162"}, + {file = "numpy-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9"}, + {file = "numpy-2.4.1-cp312-cp312-win32.whl", hash = "sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f"}, + {file = "numpy-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87"}, + {file = "numpy-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8"}, + {file = "numpy-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b"}, + {file = "numpy-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f"}, + {file = "numpy-2.4.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9"}, + {file = "numpy-2.4.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e"}, + {file = "numpy-2.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5"}, + {file = "numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8"}, + {file = "numpy-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c"}, + {file = "numpy-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2"}, + {file = "numpy-2.4.1-cp313-cp313-win32.whl", hash = "sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d"}, + {file = "numpy-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb"}, + {file = "numpy-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5"}, + {file = "numpy-2.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7"}, + {file = "numpy-2.4.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d"}, + {file = "numpy-2.4.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15"}, + {file = "numpy-2.4.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9"}, + {file = "numpy-2.4.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2"}, + {file = "numpy-2.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505"}, + {file = "numpy-2.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2"}, + {file = "numpy-2.4.1-cp313-cp313t-win32.whl", hash = "sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4"}, + {file = "numpy-2.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510"}, + {file = "numpy-2.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261"}, + {file = "numpy-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc"}, + {file = "numpy-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3"}, + {file = "numpy-2.4.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220"}, + {file = "numpy-2.4.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee"}, + {file = "numpy-2.4.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556"}, + {file = "numpy-2.4.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844"}, + {file = "numpy-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3"}, + {file = "numpy-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205"}, + {file = "numpy-2.4.1-cp314-cp314-win32.whl", hash = "sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745"}, + {file = "numpy-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d"}, + {file = "numpy-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df"}, + {file = "numpy-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f"}, + {file = "numpy-2.4.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0"}, + {file = "numpy-2.4.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c"}, + {file = "numpy-2.4.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93"}, + {file = "numpy-2.4.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42"}, + {file = "numpy-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01"}, + {file = "numpy-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b"}, + {file = "numpy-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a"}, + {file = "numpy-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2"}, + {file = "numpy-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295"}, + {file = "numpy-2.4.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8ad35f20be147a204e28b6a0575fbf3540c5e5f802634d4258d55b1ff5facce1"}, + {file = "numpy-2.4.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8097529164c0f3e32bb89412a0905d9100bf434d9692d9fc275e18dcf53c9344"}, + {file = "numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ea66d2b41ca4a1630aae5507ee0a71647d3124d1741980138aa8f28f44dac36e"}, + {file = "numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d3f8f0df9f4b8be57b3bf74a1d087fec68f927a2fab68231fdb442bf2c12e426"}, + {file = "numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2023ef86243690c2791fd6353e5b4848eedaa88ca8a2d129f462049f6d484696"}, + {file = "numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8361ea4220d763e54cff2fbe7d8c93526b744f7cd9ddab47afeff7e14e8503be"}, + {file = "numpy-2.4.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:4f1b68ff47680c2925f8063402a693ede215f0257f02596b1318ecdfb1d79e33"}, + {file = "numpy-2.4.1.tar.gz", hash = "sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690"}, ] [[package]] @@ -375,26 +375,26 @@ files = [ [[package]] name = "soupsieve" -version = "2.8.1" +version = "2.8.3" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "soupsieve-2.8.1-py3-none-any.whl", hash = "sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434"}, - {file = "soupsieve-2.8.1.tar.gz", hash = "sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350"}, + {file = "soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95"}, + {file = "soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349"}, ] [[package]] name = "tomlkit" -version = "0.13.3" +version = "0.14.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, + {file = "tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}, + {file = "tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}, ] [[package]] diff --git a/vulnfeeds/vulns/vulns.go b/vulnfeeds/vulns/vulns.go index 9cf1c6dd111..0fbdfccb174 100644 --- a/vulnfeeds/vulns/vulns.go +++ b/vulnfeeds/vulns/vulns.go @@ -34,7 +34,6 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "gopkg.in/yaml.v2" - "github.com/google/osv/vulnfeeds/cves" "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility" "github.com/google/osv/vulnfeeds/utility/logger" @@ -81,7 +80,6 @@ const ( Spaces // Contains space characters Empty // Contains no entry Filler // Has been determined to be a filler word - ) // AttachExtractedVersionInfo converts the models.VersionInfo struct to OSV GIT and ECOSYSTEM AffectedRanges and AffectedPackage. @@ -325,7 +323,7 @@ func (v *Vulnerability) AddPkgInfo(pkgInfo PackageInfo) { // getBestSeverity finds the best CVSS severity vector from the provided metrics data. // It prioritizes newer CVSS versions and "Primary" sources. -func getBestSeverity(metricsData *cves.CVEItemMetrics) (string, string) { +func getBestSeverity(metricsData *models.CVEItemMetrics) (string, string) { // Define search passes. First pass for "Primary", second for any. for _, primaryOnly := range []bool{true, false} { // Inside each pass, prioritize v4.0 over v3.1 over v3.0. @@ -351,7 +349,7 @@ func getBestSeverity(metricsData *cves.CVEItemMetrics) (string, string) { // AddSeverity adds CVSS severity information to the OSV vulnerability object. // It uses the highest available CVSS score from the underlying CVE record. -func (v *Vulnerability) AddSeverity(metricsData *cves.CVEItemMetrics) { +func (v *Vulnerability) AddSeverity(metricsData *models.CVEItemMetrics) { bestVectorString, severityType := getBestSeverity(metricsData) if bestVectorString == "" { @@ -589,7 +587,7 @@ func ClassifyReferenceLink(link string, tag string) osvschema.Reference_Type { // ExtractReferencedVulns extracts other vulnerability IDs from a CVE's references // to place them into the aliases and related fields. -func ExtractReferencedVulns(id cves.CVEID, cveID cves.CVEID, references []cves.Reference) ([]string, []string) { +func ExtractReferencedVulns(id models.CVEID, cveID models.CVEID, references []models.Reference) ([]string, []string) { var aliases []string var related []string if id != cveID { @@ -664,7 +662,7 @@ func Unique[T comparable](s []T) []T { } // ClassifyReferences annotates reference links based on their tags or their shape. -func ClassifyReferences(refs []cves.Reference) []*osvschema.Reference { +func ClassifyReferences(refs []models.Reference) []*osvschema.Reference { var references []*osvschema.Reference refMap := make(map[string]map[osvschema.Reference_Type]bool) @@ -706,12 +704,12 @@ func ClassifyReferences(refs []cves.Reference) []*osvschema.Reference { // Leaves affected and version fields empty to be filled in later with AddPkgInfo // There are two id fields passed in as one of the users of this field (PyPi) sometimes has a different id than the CVEID // and the ExtractReferencedVulns function uses these in a check to add the other ID as an alias. -func FromNVDCVE(id cves.CVEID, cve cves.CVE) *Vulnerability { +func FromNVDCVE(id models.CVEID, cve models.NVDCVE) *Vulnerability { aliases, related := ExtractReferencedVulns(id, cve.ID, cve.References) v := &Vulnerability{ Vulnerability: &osvschema.Vulnerability{ Id: string(id), - Details: cves.EnglishDescription(cve.Descriptions), + Details: models.EnglishDescription(cve.Descriptions), Aliases: aliases, Related: related, Published: timestamppb.New(cve.Published.Time), @@ -724,15 +722,14 @@ func FromNVDCVE(id cves.CVEID, cve cves.CVE) *Vulnerability { return v } -// GetCPEs extracts CPE strings from a slice of cves.CPE. +// GetCPEs extracts CPE strings from a slice of models.CPE. // Returns array of CPE strings and array of notes. -func GetCPEs(cpeApplicability []cves.CPE) ([]string, []string) { +func GetCPEs(cpeApplicability []models.CPE, metrics *models.ConversionMetrics) []string { var CPEs []string - var notes []string for _, c := range cpeApplicability { for _, node := range c.Nodes { if node.Operator != "OR" { - notes = append(notes, "Node found without OR operator") + metrics.AddNote("Node found without OR operator") continue } for _, match := range node.CPEMatch { @@ -741,7 +738,7 @@ func GetCPEs(cpeApplicability []cves.CPE) ([]string, []string) { } } - return CPEs, notes + return CPEs } // FromYAML deserializes a Vulnerability from a YAML reader. @@ -797,13 +794,13 @@ func CheckQuality(text string) QualityCheck { } // LoadAllCVEs loads the downloaded CVE's from the NVD database into memory. -func LoadAllCVEs(cvePath string) map[cves.CVEID]cves.Vulnerability { +func LoadAllCVEs(cvePath string) map[models.CVEID]models.Vulnerability { dir, err := os.ReadDir(cvePath) if err != nil { logger.Fatal("Failed to read dir", slog.String("path", cvePath), slog.Any("err", err)) } - vulnsChan := make(chan cves.Vulnerability) + vulnsChan := make(chan models.Vulnerability) var wg sync.WaitGroup for _, entry := range dir { @@ -822,7 +819,7 @@ func LoadAllCVEs(cvePath string) map[cves.CVEID]cves.Vulnerability { } defer file.Close() - var nvdcve cves.CVEAPIJSON20Schema + var nvdcve models.CVEAPIJSON20Schema if err := json.NewDecoder(file).Decode(&nvdcve); err != nil { logger.Error("Failed to decode JSON", slog.String("file", filename), slog.Any("err", err)) return @@ -840,7 +837,7 @@ func LoadAllCVEs(cvePath string) map[cves.CVEID]cves.Vulnerability { close(vulnsChan) }() - result := make(map[cves.CVEID]cves.Vulnerability) + result := make(map[models.CVEID]models.Vulnerability) for item := range vulnsChan { result[item.CVE.ID] = item } @@ -848,7 +845,7 @@ func LoadAllCVEs(cvePath string) map[cves.CVEID]cves.Vulnerability { return result } -func FindSeverity(metricsData []cves.Metrics) *osvschema.Severity { +func FindSeverity(metricsData []models.Metrics) *osvschema.Severity { bestVectorString, severityType := getBestCVE5Severity(metricsData) if bestVectorString == "" { return nil @@ -860,14 +857,14 @@ func FindSeverity(metricsData []cves.Metrics) *osvschema.Severity { } } -func getBestCVE5Severity(metricsData []cves.Metrics) (string, osvschema.Severity_Type) { +func getBestCVE5Severity(metricsData []models.Metrics) (string, osvschema.Severity_Type) { checks := []struct { - getVectorString func(cves.Metrics) string + getVectorString func(models.Metrics) string severityType osvschema.Severity_Type }{ - {func(m cves.Metrics) string { return m.CVSSv4_0.VectorString }, osvschema.Severity_CVSS_V4}, - {func(m cves.Metrics) string { return m.CVSSv3_1.VectorString }, osvschema.Severity_CVSS_V3}, - {func(m cves.Metrics) string { return m.CVSSv3_0.VectorString }, osvschema.Severity_CVSS_V3}, + {func(m models.Metrics) string { return m.CVSSv4_0.VectorString }, osvschema.Severity_CVSS_V4}, + {func(m models.Metrics) string { return m.CVSSv3_1.VectorString }, osvschema.Severity_CVSS_V3}, + {func(m models.Metrics) string { return m.CVSSv3_0.VectorString }, osvschema.Severity_CVSS_V3}, } for _, check := range checks { diff --git a/vulnfeeds/vulns/vulns_test.go b/vulnfeeds/vulns/vulns_test.go index 8d9d57663c1..e5c84aa1586 100644 --- a/vulnfeeds/vulns/vulns_test.go +++ b/vulnfeeds/vulns/vulns_test.go @@ -13,7 +13,6 @@ import ( "slices" gocmp "github.com/google/go-cmp/cmp" - "github.com/google/osv/vulnfeeds/cves" "github.com/google/osv/vulnfeeds/models" "github.com/google/osv/vulnfeeds/utility" "github.com/ossf/osv-schema/bindings/go/osvschema" @@ -81,11 +80,11 @@ func TestClassifyReferenceLink(t *testing.T) { func TestClassifyReferences(t *testing.T) { testcases := []struct { - refData []cves.Reference + refData []models.Reference references []*osvschema.Reference }{ { - refData: []cves.Reference{ + refData: []models.Reference{ { Source: "https://example.com", Tags: []string{"MISC"}, URL: "https://example.com", }, @@ -93,7 +92,7 @@ func TestClassifyReferences(t *testing.T) { references: []*osvschema.Reference{{Url: "https://example.com", Type: osvschema.Reference_WEB}}, }, { - refData: []cves.Reference{ + refData: []models.Reference{ { Source: "https://github.com/Netflix/lemur/issues/117", URL: "https://github.com/Netflix/lemur/issues/117", Tags: []string{"MISC", "Issue Tracking"}, }, @@ -101,7 +100,7 @@ func TestClassifyReferences(t *testing.T) { references: []*osvschema.Reference{{Url: "https://github.com/Netflix/lemur/issues/117", Type: osvschema.Reference_REPORT}}, }, { - refData: []cves.Reference{ + refData: []models.Reference{ { Source: "https://github.com/curl/curl/issues/9271", URL: "https://github.com/curl/curl/issues/9271", Tags: []string{"MISC", "Exploit", "Issue Tracking", "Third Party Advisory"}, }, @@ -113,7 +112,7 @@ func TestClassifyReferences(t *testing.T) { }, }, { - refData: []cves.Reference{ + refData: []models.Reference{ { Source: "https://gitlab.com/gitlab-org/gitlab/-/issues/517693", URL: "https://gitlab.com/gitlab-org/gitlab/-/issues/517693", Tags: []string{"issue-tracking", "permissions-required"}, }, @@ -123,7 +122,7 @@ func TestClassifyReferences(t *testing.T) { }, }, { - refData: []cves.Reference{ + refData: []models.Reference{ { Source: "https://security.gentoo.org/glsa/202307-01", URL: "https://security.gentoo.org/glsa/202307-01", Tags: []string{"vendor-advisory"}, }, @@ -133,7 +132,7 @@ func TestClassifyReferences(t *testing.T) { }, }, { - refData: []cves.Reference{ + refData: []models.Reference{ { Source: "http://www.openwall.com/lists/oss-security/2023/07/20/1", URL: "http://www.openwall.com/lists/oss-security/2023/07/20/1", Tags: []string{"mailing-list"}, }, @@ -154,13 +153,13 @@ func TestClassifyReferences(t *testing.T) { } } -func loadTestData2(cveName string) cves.Vulnerability { +func loadTestData2(cveName string) models.Vulnerability { fileName := fmt.Sprintf("../test_data/nvdcve-2.0/%s.json", cveName) file, err := os.Open(fileName) if err != nil { log.Fatalf("Failed to load test data from %q", fileName) } - var nvdCves cves.CVEAPIJSON20Schema + var nvdCves models.CVEAPIJSON20Schema err = json.NewDecoder(file).Decode(&nvdCves) if err != nil { log.Fatalf("Failed to decode %q: %+v", fileName, err) @@ -172,7 +171,7 @@ func loadTestData2(cveName string) cves.Vulnerability { } log.Fatalf("test data doesn't contain %q", cveName) - return cves.Vulnerability{} + return models.Vulnerability{} } func TestExtractAliases(t *testing.T) { @@ -198,7 +197,7 @@ func TestExtractAliases(t *testing.T) { func TestEnglishDescription(t *testing.T) { cveItem := loadTestData2("CVE-2022-36037") - description := cves.EnglishDescription(cveItem.CVE.Descriptions) + description := models.EnglishDescription(cveItem.CVE.Descriptions) expectedDescription := "kirby is a content management system (CMS) that adapts to many different projects and helps you build your own ideal interface. Cross-site scripting (XSS) is a type of vulnerability that allows execution of any kind of JavaScript code inside the Panel session of the same or other users. In the Panel, a harmful script can for example trigger requests to Kirby's API with the permissions of the victim. If bad actors gain access to your group of authenticated Panel users they can escalate their privileges via the Panel session of an admin user. Depending on your site, other JavaScript-powered attacks are possible. The multiselect field allows selection of tags from an autocompleted list. Unfortunately, the Panel in Kirby 3.5 used HTML rendering for the raw option value. This allowed **attackers with influence on the options source** to store HTML code. The browser of the victim who visited a page with manipulated multiselect options in the Panel will then have rendered this malicious HTML code when the victim opened the autocomplete dropdown. Users are *not* affected by this vulnerability if you don't use the multiselect field or don't use it with options that can be manipulated by attackers. The problem has been patched in Kirby 3.5.8.1." if description != expectedDescription { t.Errorf("Description not extracted, got %v, but expected %v", description, expectedDescription) @@ -407,7 +406,7 @@ func TestAddPkgInfo(t *testing.T) { func TestAddSeverity(t *testing.T) { tests := []struct { description string - inputCVE cves.Vulnerability + inputCVE models.Vulnerability expectedResult []*osvschema.Severity }{ { From 21734a9af99fc13f6f6053b039e547475bbc56cc Mon Sep 17 00:00:00 2001 From: Jess Lowe Date: Wed, 28 Jan 2026 05:38:16 +0000 Subject: [PATCH 5/5] fix model update change --- vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go | 2 +- vulnfeeds/cvelist2osv/converter.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go index 436eb93d978..9ffa22f97af 100644 --- a/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go +++ b/vulnfeeds/cmd/converters/cve/cve5/bulk-converter/main.go @@ -137,7 +137,7 @@ func worker(wg *sync.WaitGroup, jobs <-chan string, outDir string, cnas []string if err != nil { logger.Warn("Failed to generate an OSV record", slog.String("cve", string(cveID)), slog.Any("err", err)) } else { - if rejectFailed && metrics.Outcome != cvelist2osv.Successful { + if rejectFailed && metrics.Outcome != models.Successful { logger.Info("Rejecting failed OSV record", slog.String("cve", string(cveID)), slog.String("outcome", metrics.Outcome.String())) osvFile.Close() os.Remove(osvFile.Name()) diff --git a/vulnfeeds/cvelist2osv/converter.go b/vulnfeeds/cvelist2osv/converter.go index d03b8dca2f9..89faebba871 100644 --- a/vulnfeeds/cvelist2osv/converter.go +++ b/vulnfeeds/cvelist2osv/converter.go @@ -143,7 +143,7 @@ func FromCVE5(cve models.CVE5, refs []models.Reference, metrics *models.Conversi // ConvertAndExportCVEToOSV is the main function for this file. It takes a CVE, // converts it into an OSV record, collects metrics, and writes both to disk. -func ConvertAndExportCVEToOSV(cve models.CVE5, vulnSink io.Writer, metricsSink io.Writer, sourceLink string) (*ConversionMetrics, error) { +func ConvertAndExportCVEToOSV(cve models.CVE5, vulnSink io.Writer, metricsSink io.Writer, sourceLink string) (*models.ConversionMetrics, error) { cveID := cve.Metadata.CVEID cnaAssigner := cve.Metadata.AssignerShortName references := identifyPossibleURLs(cve)

=mljI<~LAMH=Ff%VS-UHg!guf}eJQIe!1h}HF>~$er{~vU_^|ZPW=?oV{jH)cp zQTiPauMmbsqgbKA3f2$v%bGp@sm~{($Q9trr{<0gpLw=JMs}Z!UKEPN`gph|(^;xw zfV%^u6m}Dsh2r{|w`$?VOiNs%%fcWH2ccyqaN_Kq&Fg9I+tV2qY`)E_zcAZGt8?&~64W`=xneWNXKT zWwiDo>E7HZ>)W%MI%$O~8*A7J`#e8*U@+J?A>+G&t87IrNn!E3ZxKMx86;?_Z1{CtA}X`S6!_nvcsDX(&{iMqF~q ziP;g5nR+}ZRhgeh7rF^sW?$aSWqviddo!ywl&06Na9T%Lg`DiJq6I{-1rASPKdSRA zdGZ?c!wUJzstJN;l$hPU@yD?PG1t7LL|8cZWpvKGxg6966J)c^B@``VFM$ovaa!|7 z27vyB2E(M4Ondv}3d!9;mYNQtCI+P;Vy2qSnn8Ox3Gv7ZFv?;C8z8jgAm$MVam(*6 zONx?mV?o+C?ju6xVD~EjsR zF(wgQmeU*6Q_6TYTSq*lMB|8!`^*M+Js64I0qRV)*2rDXP45Pt3zKANc8V4YxVKqx z(~r+NFHVRG2ncLY=v=fa;P2(S4DZ(Wu=uZQG&b|)if;Lm^>~cOZ`m0=+^WnBVbzf1 zXRLQtb~r_vOXMdzA1O>SsIDls%iT77QYy8uOjj#3JmKoP;Bx!B_)1KVmp~h8g{K6R z$x;9Xjjt9}F9N@yB!mif2X>0=#-2^n5$}t?lIsf2gt6Yl#Z8r`VLWDGy!HlCsU5~=_ll-(6Po%k zYN5cK{of>u>x9r?HZ#5YD|+7_Crf*Vwk3&YD0|e~7hbwh)TDv!*kU^@!YF8S@jP4; z{33pUX8Yj{^eOGWS|+(5k~Lf}zi=S4On|5zG@OatWlhf6M7w&e?s{i_lk!TP{`hAd z(75KstO1R3BhK12=Y{Mw96ao-Iz^iGleH^9HLV|3O&E<3pGpDa$4;qwxKF2F zY;+rh;9;uNx1Kwi*2J{v6bDE-X=3sxz9xRDHLBILU(=uajV167Zw1+Y#J6Cwm&iA@ zgiem*{M-9;-{0qNMsA95sCbZ==`}x1xyCZ4HEQR@G#|e88aQdaOtffQU3Z4w`2)cY zuf~r%Ur1bG-0_mz!sn2l^>~_ZTdh`zH5(q18LW#u#6+Ga3s zsWjr!Q_FRhhJ_JN(#};#Dt2mSX=&D4lu5=HxOL_x*brO~0a9Fz9gKEyW9jlGSzyk& z86gP#7Et!}5D?%z7djtRqj-8N1zIU31ym12CJ+yiOf0WxH&=f?=qQYTM(XIxlo5F? zThWKFKbaBUMy+@-qP0>=q~gNcUfdzCC zzvP{`=*kkVY*Wj~#c{dp)h7pgOO>9oWOE;6z}+f? zU8HtHk9x{Zt!VaaC{x!XR{);|h$hOs79y0&FE*za3TpUK$9rZ3;Ixi!6$Zn`8wC)- z8@KP!Dt+V1*%TgLkTP{_;6#;OZApy)5oLNl*PjlBbi5T^b_n%5VPEQSMnovHjw%@| zV@4Q@ClgHXqD)yr+{b&7a4oJOIJ^xoseeHay7im3t{G-t;fd%?GgDi>6uau$)A|c`|OZOlobfkUnz;gFUyCT!K60F*RP(Q0e3esyK{hmD1=%7ZC=tak2!;P61+g z$4ASu!3fkstdj6tBKS^C@~Je`iJ?73ldx`MK0_iL^7SaCDxXf zx=SQ)*Kk9E`HrVAWfVL6rnze+L9zZwFz?A)-y`HNRWp+G5MB>ZkCoEnm~WLWu6@V# zMh)qB6)kR228nI$UC-9`-HL~%f{JUKrzZT^qoxZB0oFr$%|I)ymkA!(->kqizsJuw zD;V)U>FvS&pqgqZOAG1_zj(nSwCd$)p4b0nva2N}h@H91DFN8d5;a`wC2LNj5nCBS zS@DkUKT?Ov94gK3CRJ-iDOFEdygFS3HB?O8YAE>r#qbBU9_ZH*8C1QNi*p_6+WmI3 z$7sMAHKPctd?>+C(SnISjs1xzx$C0@R;p_L&0N@Q>mCMhfT^q^&Hj|f5N9k5v)qQi=k&F8}!5?jwVK31Dio1jN_l z%buN3fYu1quySI0x%56yNGC%zYuqb0>c}rSE=UTmI!d&Cw&PXZ%~d@zgaUc(jB%@q zRF}P$r>e81v|68SOh2bLa&a4=p7S0J0RZP37;~VRS5a5y z9I)ij>8ggNFwYx%IGv`)?Vdzlpp`=q!9&r}DdIFP(|P@$W75Fc!cpgq+D^}EO6z_| zS87&E_Py+#NV;!PYo`jT$9ioV%qe6nUeA$`6n4^vqcO1${9a>A479K`HJn~Umv@C) zMOspqEMO?MG|B_bEqQy8HQn;I(S6{bWP_t(X%^x<6K(l3ZwCrf_qvlEfiGRNO6TZQL!t~4>Y&1KW{kf zN_^Sbo8wSyH<=0(xwsP>94^U!ePB(#M=tUV)c<7^Gd&TW`nmP)CR#*J^(aYeUeYLM zg!}^;Ap*0S+7{GsOjtMJKk&N5g(4Wh+8T?5(TqrOu^< z#o@0x-3jtEdgF@wv9nq4Md|27PgHKNTfIuc{u@%~+(%D$qLGenS2os8o4Lfxu9FmX z`25Q8Vy>b|vr*7+!X1TtdzW|i);nG9St4}@Y5la7(b18jIlW8K6U9z2G}2XQ8E28| z@}xsO+c$U&5Be#~Tzb|#UR`uxL!f?hP$I+|H1RENU@nc0xOCHD0}+IILC*A z!BdFLYY!{9hunWi;bVEh^`D%qbtrFxHZHiYI^n<~=SU6P0EotiavP8$7`s(`tdFMo z4s#Y_H#h#HSs}RtW5V_>m_vhez_JKCT}Uhv@7=N{zGu{5Hom7LOWl*Snz1*OU; z=pq|iQ~w^?pKg8vIMzj_Tobsi#ib>MTWx0xhVLXt%*}=mel=D109+NFp?{H9C7D9k zo`UsjOKQ5!N*yi$mj_x4`h#e|keJNt7t@BWtAuO!*Kq)z+r#ztNlZQ`cnEm~fZStr zw5*m*TC{F~hM6@qiUglAmu_-c;W052KVB%b-Ek z8^(fVYQppeaU(w~A^3kZ4$iyr`7S~-(r=_z-`CKYy|>b!;@Fm{~3JjFM4U)4<<9QDVJ=kN8}Vq2#f!$U-DEBo)8G zqRb9P30yEW)Vs9F#)K~CtP3g zd8Rq{PsODar-4Q?$d#`oK+K?}@$dsifw9p`qUg+^)e*p;XD&z`M%90CQIAe!SGv8v zMT-So%~g4U$Zz`?f9-}QPB^aN_*u*ym=oI(+i+Dj<*Mw(o~>2mKQEt8t!`T1=pviv z)B&~bV;Mo`8q6=H03ssKnRmUrU%xX$6C@ud><C~Fe%uYygBs94AdI+|bj5F?N(rH5| zEP8joyu%7;d`~KzpOHtAijY*#KL`mxO+xv5snILN-nLTcbf2y5pQ(KNKKx3@;bgEm zVR4TjR=4R{?mwu{cWOPsn{~6Hq2?i|FC{a8*SWxV0 zEdi0Y9-~i_=*vXZTJLLl@%?3t_o@Lc^y;p|$kaZa3v~kpX0!rR;|7f5eA15k4hUVo?Z*Mg z6tZ4ze|ALnf4)NTwjH6>BFpj&v@?mx5?sc99J^R4t!nIp89fMv{J4E_Xr97;e@*-J zs(yKFgYDUksq3%lFIVi4e_fPtI<@fXEzmDyGISj>{yfnBX)2T6r$)@b$WQsX9clk9 zM$t`&uB7e{fIF6FR~E||OJp8RVH8rK!hbk5aURo#kc&G7053s+>Z+UZ;+WHWL+p-E zFJwemSVb-h8l5Q1NQ^3<(cEE~B+(yd&wepUDsApm1+wmzg^EvE3RSAcSkWeG*qWe# zR7&p6s&5UZ)ahV<1kruDpXYTkiljnHxjFxA&AAtb-~-Nlh)q3qv7?I&?>#>Q9Hnv* zKE&Y4hCXs9H)NYnv7uo#niQlh%|_>7hn3ri!qas(|HrW&)b5KS+zKr|nGm&ZcZG0E z*_0ls8vCs1+)pEpW%kzJ44XBAIw8pSth@fzHqFXvoyr=WO7n{@5yMGAfSEfGT`$Ms zl#?*jn|l2kmQ4xI#<`vCzpZh%7_Y5iOyJRZsCA!t)qlG0kIo3{9N)L<@Bg;1RrI#F z5qC6MGWzLxmVatwc-FFoVlzJ6YB(6P-qcUD5@(}x<#Wd9esv z+Mn=41l{8PwLMJe!M(gzHzA!5?Y>+Fr62kGO|B8}Qkb%9%dmxqJh3Hq_st9zen(Ja zJ3bW4r`lcY@81xshOK+f!{2_7Z$(&!b)_EDT5}75geWDZg$=r>N>>JFaDoyRn zChdc!1uyuDhFjKjOx75AODwDnA3+i+z36kr^tp)cvj$D2S7kc>BIteP{GL~q?gEy5 zIeOWu{b*D8M@)4b0!8;_vijWA!>vw{Wd29l-vE;z{`>0~CPFrjxQX_na{d_Jqe|*Q zfx;(F)zI2^$%9=X8Cu~}f!O+UbAubv<3HkBH=|!ilVsH! zYf?|%Ttv`4`#r@F`RNI|3}ek3^I!1>)~15$P?-zd* )o}Jl(z7?Z~JsQ(nGswFh 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