wip archival commit, unclear what I was doing here
This commit is contained in:
7
.vscode/launch.json
vendored
Normal file
7
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": []
|
||||||
|
}
|
3667
Cargo.lock
generated
3667
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
@ -4,10 +4,22 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
mistralrs.git = "https://github.com/EricLBuehler/mistral.rs.git"
|
||||||
|
mistralrs.tag = "v0.3.4"
|
||||||
|
mistralrs.features = ["cuda", "cudnn"]
|
||||||
scraper = "0.19.0"
|
scraper = "0.19.0"
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
anyhow = { version = "1.0.82", features = ["backtrace", "std"] }
|
anyhow = { version = "1.0.82", features = ["backtrace", "std"] }
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = "0.3.18"
|
tracing-subscriber = "0.3.18"
|
||||||
regex = "1.10.4"
|
regex = "1.10.4"
|
||||||
reqwest = { version = "0.12.3", features = ["blocking"] }
|
reqwest = { version = "0.12.3", features = ["blocking"] }
|
||||||
|
test-log = { version = "0.2.16", features = ["color", "log", "trace"] }
|
||||||
|
strum = { version = "0.26.3", features = [
|
||||||
|
"std",
|
||||||
|
"derive",
|
||||||
|
"phf",
|
||||||
|
"strum_macros",
|
||||||
|
] }
|
||||||
|
tokio = "1.41.1"
|
||||||
|
image = "0.25.5"
|
||||||
|
9
diesel.toml
Normal file
9
diesel.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema]
|
||||||
|
file = "src/schema.rs"
|
||||||
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
|
[migrations_directory]
|
||||||
|
dir = "/home/hak8or/code/ebay_compute_scraper/migrations"
|
BIN
src/benchmarks/google_sheet.png
Normal file
BIN
src/benchmarks/google_sheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 362 KiB |
77
src/benchmarks/google_sheet.txt
Normal file
77
src/benchmarks/google_sheet.txt
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
Here is a table of processors (with one or more spaces as delimiters), their specs, and some benchmark results. Note, "CB R15" = Cinebench R15, with the 2nd last column being the multithreaded score, and the last column being the single threaded score.
|
||||||
|
|
||||||
|
```
|
||||||
|
Type CPU Family Name Released Cores Pass Mark CB R15
|
||||||
|
Desktop Intel I9 i9-13900KS Q1 2023 24/32 63,087
|
||||||
|
Amd EPYC 7513 Q2 2021 32/64 59,988
|
||||||
|
Desktop Intel I9 i9-13900K Q3 2022 24/32 59,968 6,141 330
|
||||||
|
Dekstop AMD Ryzen 9 7950x Q3 2022 16/32 64,552 6,580 336
|
||||||
|
Desktop AMD Ryzen 9 5950X Q4 2020 16/32 46,746 4,569 272
|
||||||
|
Server AMD Epyc 7313 Q1 2021 16/32 40,075
|
||||||
|
Server Intel Xeon Platinum 8180 35,208 4,355 165
|
||||||
|
Desktop AMD Ryzen 9 5900X Q4 2020 12/24 39,858 3,684 269
|
||||||
|
Server AMD Epyc 7282 Q4 2019 16/32 29,496
|
||||||
|
Desktop AMD Ryzen 7 5800X Q4 2020 8/16 28,647 2,611 270
|
||||||
|
Desktop AMD Ryzen 7 5800X3D Q2 2022 8/16 27,636 2,477 249
|
||||||
|
Desktop AMD Ryzen 7 5700X Q2 2022 8/16 26,694 2,307 253
|
||||||
|
Server AMD Threadripper 2950X Q4 2018 16/32 25,769 3,261 175
|
||||||
|
Desktop AMD Ryzen 7 3700X Q3 2019 8/16 22,816 2,114 204
|
||||||
|
Server AMD Threadripper 2920X Q4 2018 12/24 22,001 2,636 176
|
||||||
|
Server AMD Threadripper 1950X Q3 2017 16/32 21,931 3,151 166
|
||||||
|
Server AMD Threadripper 1920X Q3 2017 12/24 19,363 2,459 168
|
||||||
|
Desktop AMD Ryzen 7 2700X Q1 2018 8/16 17,587 1,828 180
|
||||||
|
Server Intel Xeon s Q4 2013 12/24 16,041 1,659
|
||||||
|
Server AMD Threadripper 1900X Q3 2017 8/16 16,005 1,805
|
||||||
|
Server Intel Xeon E5-2697 v2 Q2 2013 12/24 14,152 1,557 98
|
||||||
|
Desktop AMD Ryzen 7 1700 Q1 2017 8/16 13,805 1,473
|
||||||
|
Laptop AMD Ryzen 5 4650U Q1 2020 6/12 13,009 1,160 175
|
||||||
|
Server Intel Xeon Scalable Silver 4110 Q3 2017 8/16 10,028 1,148 131
|
||||||
|
Server Intel Xeon E5-2620 v4 Q1 2016 8/16 11,376 1,096 125
|
||||||
|
Server Intel Xeon E5-2650 V2 Q2 2013 8/16 13,053 1,063 128
|
||||||
|
Laptop AMD Ryzen 7 4700U Q1 2020 8/8 13,843 1,050 188
|
||||||
|
Laptop AMD Ryzen 5 4500U Q1 2020 6/6 11,304 889 176
|
||||||
|
Laptop Intel I5-1135G7 Q3 2020 4/8 8,623 855
|
||||||
|
Laptop Intel i7-1165G7 Q2 2020 4/8 11,086 809
|
||||||
|
Desktop AMD Ryzen 5 1500x Q1 2017 4/8 10,715 809
|
||||||
|
Server Intel Xeon E5-2650 Q1 2012 8/16 10,190 790
|
||||||
|
Server Intel Xeon E5-2630L v2 Q4 2014 6/12 9,088 800 147
|
||||||
|
Laptop Intel i7-1065G7 Q3 2019 4/8 8,980 704
|
||||||
|
Server Intel Xeon E3-1230 V2 Q2 2012 4/8 8,863 650
|
||||||
|
Laptop AMD Ryzen 5 3500U Q1 2018 4/8 7,157 620
|
||||||
|
Desktop Intel i7-8550U Q3 2017 4/8 8,317 558
|
||||||
|
Desktop AMD Ryzen 3 1300x Q1 2017 4/4 8,109 554
|
||||||
|
Server Intel Xeon X5670 Q1 2010 6/12 8,013 675
|
||||||
|
Laptop Intel i5-1035G1 Q3 2019 4/8 8,007 606
|
||||||
|
Server Intel Xeon E3-1230 Q2 2011 4/8 7,939 581
|
||||||
|
Desktop Intel i5-8500 Q2 2018 6/6 7,737 751 148
|
||||||
|
Desktop Intel I5-3570K Q2 2012 4/4 7,153 522
|
||||||
|
Server Intel Xeon E3-1220 v3 Q2 2013 4/4 6,966 500
|
||||||
|
Server Intel Xeon E5645 Q2 2011 6/12 6,545 573
|
||||||
|
Server Intel Xeon E3-1260L Q2 2011 4/8 6,534
|
||||||
|
Laptop Intel i5-10210U Q3 2019 4/8 6,532 567
|
||||||
|
Server Intel Xeon L5640 Q2 2010 6/12 6,451 497
|
||||||
|
Server Intel Xeon L5640 Q1 2010 6/12 6,451 497
|
||||||
|
Server Intel Xeon E3-1220 Q2 2011 4/4 6,086 433
|
||||||
|
Server Intel N100 Q1 2023 4/4 5,489 477 154
|
||||||
|
Desktop Intel i5-7500T Q1 2017 4/4 5,263 528 141
|
||||||
|
Laptop Intel i3-8130U Q2 2018 2/2 5,019 338
|
||||||
|
Desktop Intel i5-6500T Q4 2015 4/4 4,768 464 132
|
||||||
|
Server Intel Xeon L5520 Q1 2009 4/8 4,387
|
||||||
|
Server Intel Xeon E7-4850 Q2 2011 10/20 4,000 752
|
||||||
|
??? Intel G3258 Q2 2014 2/2 3,918 247
|
||||||
|
??? Intel C2750 Q3 2013 8/8 3,771 317
|
||||||
|
Server Intel Xeon E5-2407 Q2 2012 4/4 3,693 341
|
||||||
|
Server Intel N5100 Q2 2021 4/4 3,331 ????
|
||||||
|
Laptop Intel i5-2410M Q1 2011 2/4 3,161 236
|
||||||
|
Laptop Intel I3-5010u 2/4 218
|
||||||
|
??? Intel J4205 Q3 2016 4/4 2,688 196
|
||||||
|
??? Intel J3455 Q3 2016 4/4 2,153 181
|
||||||
|
??? Intel N3450 Q4 2016 4/4 1,805 135
|
||||||
|
Laptop Intel 3867U Q2 2019 2/2 1,483 139 71
|
||||||
|
Laptop Intel 2955U Q4 2016 2/2 1,450 100
|
||||||
|
??? Intel Atom x5-Z8300 Q2 2015 4/4 1,204 111
|
||||||
|
Laptop Intel 3205U Q2 2015 2/2 946 117 61
|
||||||
|
??? Intel N3050 Q1 2015 2/2 885 69
|
||||||
|
??? Intel Z3735F Q1 2014 4/4 879
|
||||||
|
??? AMD APU E-350 Q4 2012 2/2 782 50
|
||||||
|
```
|
843
src/benchmarks/google_sheet_Gemini1206.json
Normal file
843
src/benchmarks/google_sheet_Gemini1206.json
Normal file
@ -0,0 +1,843 @@
|
|||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "Intel I9",
|
||||||
|
"Name": "i9-13900KS",
|
||||||
|
"Released": "Q1 2023",
|
||||||
|
"Cores": "24/32",
|
||||||
|
"Pass Mark": "63,087",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": null,
|
||||||
|
"CPU Family": "Amd EPYC",
|
||||||
|
"Name": "7513",
|
||||||
|
"Released": "Q2 2021",
|
||||||
|
"Cores": "32/64",
|
||||||
|
"Pass Mark": "59,988",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "Intel I9",
|
||||||
|
"Name": "i9-13900K",
|
||||||
|
"Released": "Q3 2022",
|
||||||
|
"Cores": "24/32",
|
||||||
|
"Pass Mark": "59,968",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "6,141",
|
||||||
|
"singlethreaded": "330"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Dekstop",
|
||||||
|
"CPU Family": "AMD Ryzen 9",
|
||||||
|
"Name": "7950x",
|
||||||
|
"Released": "Q3 2022",
|
||||||
|
"Cores": "16/32",
|
||||||
|
"Pass Mark": "64,552",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "6,580",
|
||||||
|
"singlethreaded": "336"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 9",
|
||||||
|
"Name": "5950X",
|
||||||
|
"Released": "Q4 2020",
|
||||||
|
"Cores": "16/32",
|
||||||
|
"Pass Mark": "46,746",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "4,569",
|
||||||
|
"singlethreaded": "272"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "AMD Epyc",
|
||||||
|
"Name": "7313",
|
||||||
|
"Released": "Q1 2021",
|
||||||
|
"Cores": "16/32",
|
||||||
|
"Pass Mark": "40,075",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon Platinum",
|
||||||
|
"Name": "8180",
|
||||||
|
"Released": null,
|
||||||
|
"Cores": null,
|
||||||
|
"Pass Mark": "35,208",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "4,355",
|
||||||
|
"singlethreaded": "165"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 9",
|
||||||
|
"Name": "5900X",
|
||||||
|
"Released": "Q4 2020",
|
||||||
|
"Cores": "12/24",
|
||||||
|
"Pass Mark": "39,858",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "3,684",
|
||||||
|
"singlethreaded": "269"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "AMD Epyc",
|
||||||
|
"Name": "7282",
|
||||||
|
"Released": "Q4 2019",
|
||||||
|
"Cores": "16/32",
|
||||||
|
"Pass Mark": "29,496",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 7",
|
||||||
|
"Name": "5800X",
|
||||||
|
"Released": "Q4 2020",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "28,647",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "2,611",
|
||||||
|
"singlethreaded": "270"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 7",
|
||||||
|
"Name": "5800X3D",
|
||||||
|
"Released": "Q2 2022",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "27,636",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "2,477",
|
||||||
|
"singlethreaded": "249"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 7",
|
||||||
|
"Name": "5700X",
|
||||||
|
"Released": "Q2 2022",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "26,694",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "2,307",
|
||||||
|
"singlethreaded": "253"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "AMD Threadripper",
|
||||||
|
"Name": "2950X",
|
||||||
|
"Released": "Q4 2018",
|
||||||
|
"Cores": "16/32",
|
||||||
|
"Pass Mark": "25,769",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "3,261",
|
||||||
|
"singlethreaded": "175"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 7",
|
||||||
|
"Name": "3700X",
|
||||||
|
"Released": "Q3 2019",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "22,816",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "2,114",
|
||||||
|
"singlethreaded": "204"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "AMD Threadripper",
|
||||||
|
"Name": "2920X",
|
||||||
|
"Released": "Q4 2018",
|
||||||
|
"Cores": "12/24",
|
||||||
|
"Pass Mark": "22,001",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "2,636",
|
||||||
|
"singlethreaded": "176"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "AMD Threadripper",
|
||||||
|
"Name": "1950X",
|
||||||
|
"Released": "Q3 2017",
|
||||||
|
"Cores": "16/32",
|
||||||
|
"Pass Mark": "21,931",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "3,151",
|
||||||
|
"singlethreaded": "166"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "AMD Threadripper",
|
||||||
|
"Name": "1920X",
|
||||||
|
"Released": "Q3 2017",
|
||||||
|
"Cores": "12/24",
|
||||||
|
"Pass Mark": "19,363",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "2,459",
|
||||||
|
"singlethreaded": "168"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 7",
|
||||||
|
"Name": "2700X",
|
||||||
|
"Released": "Q1 2018",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "17,587",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,828",
|
||||||
|
"singlethreaded": "180"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "s",
|
||||||
|
"Released": "Q4 2013",
|
||||||
|
"Cores": "12/24",
|
||||||
|
"Pass Mark": "16,041",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,659",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "AMD Threadripper",
|
||||||
|
"Name": "1900X",
|
||||||
|
"Released": "Q3 2017",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "16,005",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,805",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E5-2697 v2",
|
||||||
|
"Released": "Q2 2013",
|
||||||
|
"Cores": "12/24",
|
||||||
|
"Pass Mark": "14,152",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,557",
|
||||||
|
"singlethreaded": "98"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 7",
|
||||||
|
"Name": "1700",
|
||||||
|
"Released": "Q1 2017",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "13,805",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,473",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "AMD Ryzen 5",
|
||||||
|
"Name": "4650U",
|
||||||
|
"Released": "Q1 2020",
|
||||||
|
"Cores": "6/12",
|
||||||
|
"Pass Mark": "13,009",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,160",
|
||||||
|
"singlethreaded": "175"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon Scalable",
|
||||||
|
"Name": "Silver 4110",
|
||||||
|
"Released": "Q3 2017",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "10,028",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,148",
|
||||||
|
"singlethreaded": "131"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E5-2620 v4",
|
||||||
|
"Released": "Q1 2016",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "11,376",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,096",
|
||||||
|
"singlethreaded": "125"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E5-2650 V2",
|
||||||
|
"Released": "Q2 2013",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "13,053",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,063",
|
||||||
|
"singlethreaded": "128"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "AMD Ryzen 7",
|
||||||
|
"Name": "4700U",
|
||||||
|
"Released": "Q1 2020",
|
||||||
|
"Cores": "8/8",
|
||||||
|
"Pass Mark": "13,843",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "1,050",
|
||||||
|
"singlethreaded": "188"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "AMD Ryzen 5",
|
||||||
|
"Name": "4500U",
|
||||||
|
"Released": "Q1 2020",
|
||||||
|
"Cores": "6/6",
|
||||||
|
"Pass Mark": "11,304",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "889",
|
||||||
|
"singlethreaded": "176"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "I5-1135G7",
|
||||||
|
"Released": "Q3 2020",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "8,623",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "855",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i7-1165G7",
|
||||||
|
"Released": "Q2 2020",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "11,086",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "809",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 5",
|
||||||
|
"Name": "1500x",
|
||||||
|
"Released": "Q1 2017",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "10,715",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "809",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E5-2650",
|
||||||
|
"Released": "Q1 2012",
|
||||||
|
"Cores": "8/16",
|
||||||
|
"Pass Mark": "10,190",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "790",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E5-2630L v2",
|
||||||
|
"Released": "Q4 2014",
|
||||||
|
"Cores": "6/12",
|
||||||
|
"Pass Mark": "9,088",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "800",
|
||||||
|
"singlethreaded": "147"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i7-1065G7",
|
||||||
|
"Released": "Q3 2019",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "8,980",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "704",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E3-1230 V2",
|
||||||
|
"Released": "Q2 2012",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "8,863",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "650",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "AMD Ryzen 5",
|
||||||
|
"Name": "3500U",
|
||||||
|
"Released": "Q1 2018",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "7,157",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "620",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i7-8550U",
|
||||||
|
"Released": "Q3 2017",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "8,317",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "558",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "AMD Ryzen 3",
|
||||||
|
"Name": "1300x",
|
||||||
|
"Released": "Q1 2017",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "8,109",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "554",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "X5670",
|
||||||
|
"Released": "Q1 2010",
|
||||||
|
"Cores": "6/12",
|
||||||
|
"Pass Mark": "8,013",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "675",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i5-1035G1",
|
||||||
|
"Released": "Q3 2019",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "8,007",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "606",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E3-1230",
|
||||||
|
"Released": "Q2 2011",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "7,939",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "581",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i5-8500",
|
||||||
|
"Released": "Q2 2018",
|
||||||
|
"Cores": "6/6",
|
||||||
|
"Pass Mark": "7,737",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "751",
|
||||||
|
"singlethreaded": "148"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "I5-3570K",
|
||||||
|
"Released": "Q2 2012",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "7,153",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "522",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E3-1220 v3",
|
||||||
|
"Released": "Q2 2013",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "6,966",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "500",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E5645",
|
||||||
|
"Released": "Q2 2011",
|
||||||
|
"Cores": "6/12",
|
||||||
|
"Pass Mark": "6,545",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "573",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E3-1260L",
|
||||||
|
"Released": "Q2 2011",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "6,534",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i5-10210U",
|
||||||
|
"Released": "Q3 2019",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "6,532",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "567",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "L5640",
|
||||||
|
"Released": "Q2 2010",
|
||||||
|
"Cores": "6/12",
|
||||||
|
"Pass Mark": "6,451",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "497",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "L5640",
|
||||||
|
"Released": "Q1 2010",
|
||||||
|
"Cores": "6/12",
|
||||||
|
"Pass Mark": "6,451",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "497",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E3-1220",
|
||||||
|
"Released": "Q2 2011",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "6,086",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "433",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "N100",
|
||||||
|
"Released": "Q1 2023",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "5,489",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "477",
|
||||||
|
"singlethreaded": "154"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i5-7500T",
|
||||||
|
"Released": "Q1 2017",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "5,263",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "528",
|
||||||
|
"singlethreaded": "141"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i3-8130U",
|
||||||
|
"Released": "Q2 2018",
|
||||||
|
"Cores": "2/2",
|
||||||
|
"Pass Mark": "5,019",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "338",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Desktop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i5-6500T",
|
||||||
|
"Released": "Q4 2015",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "4,768",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "464",
|
||||||
|
"singlethreaded": "132"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "L5520",
|
||||||
|
"Released": "Q1 2009",
|
||||||
|
"Cores": "4/8",
|
||||||
|
"Pass Mark": "4,387",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E7-4850",
|
||||||
|
"Released": "Q2 2011",
|
||||||
|
"Cores": "10/20",
|
||||||
|
"Pass Mark": "4,000",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "752",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "G3258",
|
||||||
|
"Released": "Q2 2014",
|
||||||
|
"Cores": "2/2",
|
||||||
|
"Pass Mark": "3,918",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "247",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "C2750",
|
||||||
|
"Released": "Q3 2013",
|
||||||
|
"Cores": "8/8",
|
||||||
|
"Pass Mark": "3,771",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "317",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel Xeon",
|
||||||
|
"Name": "E5-2407",
|
||||||
|
"Released": "Q2 2012",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "3,693",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "341",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Server",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "N5100",
|
||||||
|
"Released": "Q2 2021",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "3,331",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "i5-2410M",
|
||||||
|
"Released": "Q1 2011",
|
||||||
|
"Cores": "2/4",
|
||||||
|
"Pass Mark": "3,161",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "236",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "I3-5010u",
|
||||||
|
"Released": null,
|
||||||
|
"Cores": "2/4",
|
||||||
|
"Pass Mark": null,
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "218",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "J4205",
|
||||||
|
"Released": "Q3 2016",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "2,688",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "196",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "J3455",
|
||||||
|
"Released": "Q3 2016",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "2,153",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "181",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "N3450",
|
||||||
|
"Released": "Q4 2016",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "1,805",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "135",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "3867U",
|
||||||
|
"Released": "Q2 2019",
|
||||||
|
"Cores": "2/2",
|
||||||
|
"Pass Mark": "1,483",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "139",
|
||||||
|
"singlethreaded": "71"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "2955U",
|
||||||
|
"Released": "Q4 2016",
|
||||||
|
"Cores": "2/2",
|
||||||
|
"Pass Mark": "1,450",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "100",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel Atom",
|
||||||
|
"Name": "x5-Z8300",
|
||||||
|
"Released": "Q2 2015",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "1,204",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "111",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "Laptop",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "3205U",
|
||||||
|
"Released": "Q2 2015",
|
||||||
|
"Cores": "2/2",
|
||||||
|
"Pass Mark": "946",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "117",
|
||||||
|
"singlethreaded": "61"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "N3050",
|
||||||
|
"Released": "Q1 2015",
|
||||||
|
"Cores": "2/2",
|
||||||
|
"Pass Mark": "885",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "69",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "Intel",
|
||||||
|
"Name": "Z3735F",
|
||||||
|
"Released": "Q1 2014",
|
||||||
|
"Cores": "4/4",
|
||||||
|
"Pass Mark": "879",
|
||||||
|
"CB R15": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": "???",
|
||||||
|
"CPU Family": "AMD APU",
|
||||||
|
"Name": "E-350",
|
||||||
|
"Released": "Q4 2012",
|
||||||
|
"Cores": "2/2",
|
||||||
|
"Pass Mark": "782",
|
||||||
|
"CB R15": {
|
||||||
|
"multithreaded": "50",
|
||||||
|
"singlethreaded": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
125
src/benchmarks/google_sheet_query.txt
Normal file
125
src/benchmarks/google_sheet_query.txt
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
Here is a table of processors, their specs, and some benchmark results. Note, "CB R15" = Cinebench R15, with the 2nd last column being the multithreaded score, and the last column being the single threaded score.
|
||||||
|
```
|
||||||
|
Type CPU Family Name Released Cores Pass Mark CB R15
|
||||||
|
Desktop Intel I9 i9-13900KS Q1 2023 24/32 63,087
|
||||||
|
Amd EPYC 7513 Q2 2021 32/64 59,988
|
||||||
|
Desktop Intel I9 i9-13900K Q3 2022 24/32 59,968 6,141 330
|
||||||
|
Dekstop AMD Ryzen 9 7950x Q3 2022 16/32 64,552 6,580 336
|
||||||
|
Desktop AMD Ryzen 9 5950X Q4 2020 16/32 46,746 4,569 272
|
||||||
|
Server AMD Epyc 7313 Q1 2021 16/32 40,075
|
||||||
|
Server Intel Xeon Platinum 8180 35,208 4,355 165
|
||||||
|
Desktop AMD Ryzen 9 5900X Q4 2020 12/24 39,858 3,684 269
|
||||||
|
Server AMD Epyc 7282 Q4 2019 16/32 29,496
|
||||||
|
Desktop AMD Ryzen 7 5800X Q4 2020 8/16 28,647 2,611 270
|
||||||
|
Desktop AMD Ryzen 7 5800X3D Q2 2022 8/16 27,636 2,477 249
|
||||||
|
Desktop AMD Ryzen 7 5700X Q2 2022 8/16 26,694 2,307 253
|
||||||
|
Server AMD Threadripper 2950X Q4 2018 16/32 25,769 3,261 175
|
||||||
|
Desktop AMD Ryzen 7 3700X Q3 2019 8/16 22,816 2,114 204
|
||||||
|
Server AMD Threadripper 2920X Q4 2018 12/24 22,001 2,636 176
|
||||||
|
Server AMD Threadripper 1950X Q3 2017 16/32 21,931 3,151 166
|
||||||
|
Server AMD Threadripper 1920X Q3 2017 12/24 19,363 2,459 168
|
||||||
|
Desktop AMD Ryzen 7 2700X Q1 2018 8/16 17,587 1,828 180
|
||||||
|
Server Intel Xeon s Q4 2013 12/24 16,041 1,659
|
||||||
|
Server AMD Threadripper 1900X Q3 2017 8/16 16,005 1,805
|
||||||
|
Server Intel Xeon E5-2697 v2 Q2 2013 12/24 14,152 1,557 98
|
||||||
|
Desktop AMD Ryzen 7 1700 Q1 2017 8/16 13,805 1,473
|
||||||
|
Laptop AMD Ryzen 5 4650U Q1 2020 6/12 13,009 1,160 175
|
||||||
|
Server Intel Xeon Scalable Silver 4110 Q3 2017 8/16 10,028 1,148 131
|
||||||
|
Server Intel Xeon E5-2620 v4 Q1 2016 8/16 11,376 1,096 125
|
||||||
|
Server Intel Xeon E5-2650 V2 Q2 2013 8/16 13,053 1,063 128
|
||||||
|
Laptop AMD Ryzen 7 4700U Q1 2020 8/8 13,843 1,050 188
|
||||||
|
Laptop AMD Ryzen 5 4500U Q1 2020 6/6 11,304 889 176
|
||||||
|
Laptop Intel I5-1135G7 Q3 2020 4/8 8,623 855
|
||||||
|
Laptop Intel i7-1165G7 Q2 2020 4/8 11,086 809
|
||||||
|
Desktop AMD Ryzen 5 1500x Q1 2017 4/8 10,715 809
|
||||||
|
Server Intel Xeon E5-2650 Q1 2012 8/16 10,190 790
|
||||||
|
Server Intel Xeon E5-2630L v2 Q4 2014 6/12 9,088 800 147
|
||||||
|
Laptop Intel i7-1065G7 Q3 2019 4/8 8,980 704
|
||||||
|
Server Intel Xeon E3-1230 V2 Q2 2012 4/8 8,863 650
|
||||||
|
Laptop AMD Ryzen 5 3500U Q1 2018 4/8 7,157 620
|
||||||
|
Desktop Intel i7-8550U Q3 2017 4/8 8,317 558
|
||||||
|
Desktop AMD Ryzen 3 1300x Q1 2017 4/4 8,109 554
|
||||||
|
Server Intel Xeon X5670 Q1 2010 6/12 8,013 675
|
||||||
|
Laptop Intel i5-1035G1 Q3 2019 4/8 8,007 606
|
||||||
|
Server Intel Xeon E3-1230 Q2 2011 4/8 7,939 581
|
||||||
|
Desktop Intel i5-8500 Q2 2018 6/6 7,737 751 148
|
||||||
|
Desktop Intel I5-3570K Q2 2012 4/4 7,153 522
|
||||||
|
Server Intel Xeon E3-1220 v3 Q2 2013 4/4 6,966 500
|
||||||
|
Server Intel Xeon E5645 Q2 2011 6/12 6,545 573
|
||||||
|
Server Intel Xeon E3-1260L Q2 2011 4/8 6,534
|
||||||
|
Laptop Intel i5-10210U Q3 2019 4/8 6,532 567
|
||||||
|
Server Intel Xeon L5640 Q2 2010 6/12 6,451 497
|
||||||
|
Server Intel Xeon L5640 Q1 2010 6/12 6,451 497
|
||||||
|
Server Intel Xeon E3-1220 Q2 2011 4/4 6,086 433
|
||||||
|
Server Intel N100 Q1 2023 4/4 5,489 477 154
|
||||||
|
Desktop Intel i5-7500T Q1 2017 4/4 5,263 528 141
|
||||||
|
Laptop Intel i3-8130U Q2 2018 2/2 5,019 338
|
||||||
|
Desktop Intel i5-6500T Q4 2015 4/4 4,768 464 132
|
||||||
|
Server Intel Xeon L5520 Q1 2009 4/8 4,387
|
||||||
|
Server Intel Xeon E7-4850 Q2 2011 10/20 4,000 752
|
||||||
|
??? Intel G3258 Q2 2014 2/2 3,918 247
|
||||||
|
??? Intel C2750 Q3 2013 8/8 3,771 317
|
||||||
|
Server Intel Xeon E5-2407 Q2 2012 4/4 3,693 341
|
||||||
|
Server Intel N5100 Q2 2021 4/4 3,331 ????
|
||||||
|
Laptop Intel i5-2410M Q1 2011 2/4 3,161 236
|
||||||
|
Laptop Intel I3-5010u 2/4 218
|
||||||
|
??? Intel J4205 Q3 2016 4/4 2,688 196
|
||||||
|
??? Intel J3455 Q3 2016 4/4 2,153 181
|
||||||
|
??? Intel N3450 Q4 2016 4/4 1,805 135
|
||||||
|
Laptop Intel 3867U Q2 2019 2/2 1,483 139 71
|
||||||
|
Laptop Intel 2955U Q4 2016 2/2 1,450 100
|
||||||
|
??? Intel Atom x5-Z8300 Q2 2015 4/4 1,204 111
|
||||||
|
Laptop Intel 3205U Q2 2015 2/2 946 117 61
|
||||||
|
??? Intel N3050 Q1 2015 2/2 885 69
|
||||||
|
??? Intel Z3735F Q1 2014 4/4 879
|
||||||
|
??? AMD APU E-350 Q4 2012 2/2 782 50
|
||||||
|
```
|
||||||
|
|
||||||
|
Try to convert that table into rust code, assuming the following rust struct;
|
||||||
|
```
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
enum CPUClass {
|
||||||
|
MobileEmbedded,
|
||||||
|
Desktop,
|
||||||
|
Server,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct PassMarkEntry {
|
||||||
|
name: Cow<'static, str>,
|
||||||
|
class: CPUClass,
|
||||||
|
ghz_normal: f32,
|
||||||
|
ghz_turbo: f32,
|
||||||
|
physical_cores: u16,
|
||||||
|
threads: u16,
|
||||||
|
tdp: u16,
|
||||||
|
released: Cow<'static, str>,
|
||||||
|
passmark_st: u32,
|
||||||
|
passmark_mt: u32,
|
||||||
|
cb_r15_st: Option<u32>,
|
||||||
|
cb_r15_mt: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
With an example;
|
||||||
|
```
|
||||||
|
static ENTRIES: &'static [PassMarkEntry] = &[
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("n100"),
|
||||||
|
class: CPUClass::MobileEmbedded,
|
||||||
|
ghz_normal: 0.7,
|
||||||
|
ghz_turbo: 3.4,
|
||||||
|
physical_cores: 4,
|
||||||
|
threads: 4,
|
||||||
|
tdp: 6,
|
||||||
|
released: Cow::Borrowed("Q1 2023"),
|
||||||
|
passmark_st: 1936,
|
||||||
|
passmark_mt: 5489,
|
||||||
|
cb_r15_st: Some(154),
|
||||||
|
cb_r15_mt: Some(477),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
If needed then modify the struct to mark certain properties as optional. Only output the rust code. Handle all the processors found in the table.
|
1
src/benchmarks/mod.rs
Normal file
1
src/benchmarks/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod passmark;
|
125
src/benchmarks/passmark.rs
Normal file
125
src/benchmarks/passmark.rs
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
enum CPUClass {
|
||||||
|
MobileEmbedded,
|
||||||
|
Desktop,
|
||||||
|
Server,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct PassMarkEntry {
|
||||||
|
name: Cow<'static, str>,
|
||||||
|
class: CPUClass,
|
||||||
|
ghz_normal: f32,
|
||||||
|
ghz_turbo: f32,
|
||||||
|
physical_cores: u16,
|
||||||
|
threads: u16,
|
||||||
|
tdp: u16,
|
||||||
|
released: Cow<'static, str>,
|
||||||
|
passmark_st: u32,
|
||||||
|
passmark_mt: u32,
|
||||||
|
cb_r15_st: Option<u32>,
|
||||||
|
cb_r15_mt: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static ENTRIES: &'static [PassMarkEntry] = &[
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("n100"),
|
||||||
|
class: CPUClass::MobileEmbedded,
|
||||||
|
ghz_normal: 0.7,
|
||||||
|
ghz_turbo: 3.4,
|
||||||
|
physical_cores: 4,
|
||||||
|
threads: 4,
|
||||||
|
tdp: 6,
|
||||||
|
released: Cow::Borrowed("Q1 2023"),
|
||||||
|
passmark_st: 1936,
|
||||||
|
passmark_mt: 5489,
|
||||||
|
cb_r15_st: Some(154),
|
||||||
|
cb_r15_mt: Some(477),
|
||||||
|
},
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("i7-10710U"),
|
||||||
|
class: CPUClass::MobileEmbedded,
|
||||||
|
ghz_normal: 1.1,
|
||||||
|
ghz_turbo: 4.7,
|
||||||
|
physical_cores: 6,
|
||||||
|
threads: 12,
|
||||||
|
tdp: 15,
|
||||||
|
released: Cow::Borrowed("Q4 2019"),
|
||||||
|
passmark_st: 2336,
|
||||||
|
passmark_mt: 9551,
|
||||||
|
cb_r15_st: None,
|
||||||
|
cb_r15_mt: None,
|
||||||
|
},
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("i5-6500T"),
|
||||||
|
class: CPUClass::Desktop,
|
||||||
|
ghz_normal: 2.5,
|
||||||
|
ghz_turbo: 3.1,
|
||||||
|
physical_cores: 4,
|
||||||
|
threads: 4,
|
||||||
|
tdp: 35,
|
||||||
|
released: Cow::Borrowed("Q4 2015"),
|
||||||
|
passmark_st: 1793,
|
||||||
|
passmark_mt: 4768,
|
||||||
|
cb_r15_st: Some(132),
|
||||||
|
cb_r15_mt: Some(464),
|
||||||
|
},
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("i7-7700T"),
|
||||||
|
class: CPUClass::Desktop,
|
||||||
|
ghz_normal: 2.9,
|
||||||
|
ghz_turbo: 3.8,
|
||||||
|
physical_cores: 4,
|
||||||
|
threads: 8,
|
||||||
|
tdp: 35,
|
||||||
|
released: Cow::Borrowed("Q1 2017"),
|
||||||
|
passmark_st: 2147,
|
||||||
|
passmark_mt: 7589,
|
||||||
|
cb_r15_st: None,
|
||||||
|
cb_r15_mt: None,
|
||||||
|
},
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("7950x"),
|
||||||
|
class: CPUClass::Desktop,
|
||||||
|
ghz_normal: 4.5,
|
||||||
|
ghz_turbo: 5.7,
|
||||||
|
physical_cores: 16,
|
||||||
|
threads: 32,
|
||||||
|
tdp: 170,
|
||||||
|
released: Cow::Borrowed("Q3 2022"),
|
||||||
|
passmark_st: 4276,
|
||||||
|
passmark_mt: 62705,
|
||||||
|
cb_r15_st: Some(336),
|
||||||
|
cb_r15_mt: Some(6580),
|
||||||
|
},
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("2700x"),
|
||||||
|
class: CPUClass::Desktop,
|
||||||
|
ghz_normal: 3.7,
|
||||||
|
ghz_turbo: 4.3,
|
||||||
|
physical_cores: 8,
|
||||||
|
threads: 16,
|
||||||
|
tdp: 105,
|
||||||
|
released: Cow::Borrowed("Q2 2018"),
|
||||||
|
passmark_st: 2421,
|
||||||
|
passmark_mt: 17516,
|
||||||
|
cb_r15_st: Some(180),
|
||||||
|
cb_r15_mt: Some(1828),
|
||||||
|
},
|
||||||
|
PassMarkEntry {
|
||||||
|
name: Cow::Borrowed("E5-2630L V2"),
|
||||||
|
class: CPUClass::Server,
|
||||||
|
ghz_normal: 2.4,
|
||||||
|
ghz_turbo: 2.8,
|
||||||
|
physical_cores: 2,
|
||||||
|
threads: 12,
|
||||||
|
tdp: 60,
|
||||||
|
released: Cow::Borrowed("Q4 2014"),
|
||||||
|
passmark_st: 1396,
|
||||||
|
passmark_mt: 6703,
|
||||||
|
cb_r15_st: Some(147),
|
||||||
|
cb_r15_mt: Some(800),
|
||||||
|
},
|
||||||
|
];
|
@ -1,14 +1,11 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use tracing::{info, error, instrument};
|
use std::collections::HashMap;
|
||||||
use std::sync::mpsc::{Sender, Receiver};
|
|
||||||
use std::sync::mpsc;
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::thread::Thread;
|
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
pub urls: HashMap<String, String>,
|
pub urls: HashMap<String, String>,
|
||||||
pub threads: Vec<std::thread::JoinHandle<Result<String, anyhow::Error>>>
|
pub threads: Vec<std::thread::JoinHandle<Result<String, anyhow::Error>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Context {
|
impl Default for Context {
|
||||||
@ -30,7 +27,12 @@ impl Default for Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn ebay_fetch_html(&mut self, filename: String, url: String, outdir_dir: String) -> Result<()> {
|
pub fn ebay_fetch_html(
|
||||||
|
&mut self,
|
||||||
|
filename: String,
|
||||||
|
url: String,
|
||||||
|
outdir_dir: String,
|
||||||
|
) -> Result<()> {
|
||||||
let thr = thread::spawn(move || {
|
let thr = thread::spawn(move || {
|
||||||
// let body = reqwest::blocking::get(url)?.text()?;
|
// let body = reqwest::blocking::get(url)?.text()?;
|
||||||
|
|
||||||
@ -45,4 +47,3 @@ impl Context {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod benchmarks;
|
||||||
|
pub mod parser;
|
227
src/main.rs
227
src/main.rs
@ -1,219 +1,30 @@
|
|||||||
mod ebay_fetcher;
|
use anyhow::Result;
|
||||||
|
use ebay_compute_scraper::parser::search_results::parse_ebay_results;
|
||||||
use std::{fs::File, io::Read, path::PathBuf};
|
use std::path::PathBuf;
|
||||||
use scraper::{ElementRef, Html, Selector, selector::ToCss};
|
use tracing::info;
|
||||||
use anyhow::{bail, Result};
|
|
||||||
use tracing::{info, error, instrument};
|
|
||||||
use tracing_subscriber::FmtSubscriber;
|
use tracing_subscriber::FmtSubscriber;
|
||||||
use regex::Regex;
|
|
||||||
use crate::ebay_fetcher::Context;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
// #[derive(Debug, Default, Clone)]
|
||||||
#[derive(Debug, Default, Clone)]
|
// struct ParsedFile {
|
||||||
struct ParsedFile {
|
// filename: String,
|
||||||
filename: String,
|
// listings: Vec<parser::EbayResult>,
|
||||||
listings: Vec<EbayResult>
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
fn main() -> Result<()> {
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
struct EbayResult {
|
|
||||||
pub price: f64,
|
|
||||||
pub shipping: f64,
|
|
||||||
pub title: String,
|
|
||||||
pub has_bids: bool,
|
|
||||||
pub allows_best_offer: bool,
|
|
||||||
pub item_num: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument]
|
|
||||||
fn parse_ebay_results(filepath: PathBuf) -> Result<Vec<EbayResult>> {
|
|
||||||
let mut f = File::open(filepath).unwrap();
|
|
||||||
let mut contents = String::new();
|
|
||||||
f.read_to_string(&mut contents).unwrap();
|
|
||||||
|
|
||||||
let document = Html::parse_document(contents.as_str());
|
|
||||||
|
|
||||||
let selector = Selector::parse(".srp-results").unwrap();
|
|
||||||
let srp_results = document.select(&selector).next().unwrap();
|
|
||||||
|
|
||||||
let (elems, errs): (Vec<_>, Vec<_>) = get_items(&srp_results)?
|
|
||||||
.iter()
|
|
||||||
.map(parse_item)
|
|
||||||
.partition(Result::is_ok);
|
|
||||||
for err in errs {
|
|
||||||
error!("Hit error: {:?}", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(elems.into_iter().map(Result::unwrap).collect())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
fn get_items<'a>(page: &'a ElementRef<'a>) -> Result<Vec<ElementRef<'a>>> {
|
|
||||||
let selector = Selector::parse(".s-item").unwrap();
|
|
||||||
let found = page.select(&selector);
|
|
||||||
|
|
||||||
Ok(found.collect())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
fn parse_item_title(binding: &ElementRef) -> Result<String> {
|
|
||||||
let selector = Selector::parse(".s-item__title").unwrap();
|
|
||||||
|
|
||||||
let found = binding.select(&selector);
|
|
||||||
let mut iter = found.into_iter();
|
|
||||||
if iter.clone().count() != 1 {
|
|
||||||
bail!("Expecting only a single title per result! Found:{:?}", iter.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
let b1 = iter.next().unwrap().text().collect::<Vec<_>>();
|
|
||||||
let b2 = b1.iter().filter(|&e| *e != "New Listing").collect::<Vec<_>>();
|
|
||||||
if b2.len() != 1 {
|
|
||||||
bail!("Only expecting one title section per result!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(b2.first().unwrap().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
fn parse_item_price(binding: &ElementRef) -> Result<f64> {
|
|
||||||
let selector = Selector::parse(".s-item__price").unwrap();
|
|
||||||
|
|
||||||
let found = binding.select(&selector);
|
|
||||||
let mut iter = found.into_iter();
|
|
||||||
if iter.clone().count() != 1 {
|
|
||||||
bail!("Expecting only a single price per result! Found:{}", iter.clone().count());
|
|
||||||
}
|
|
||||||
|
|
||||||
let b1 = iter.next().unwrap().text().collect::<Vec<_>>();
|
|
||||||
let b2 = b1.iter().filter(|&e| *e != "New Listing").collect::<Vec<_>>();
|
|
||||||
let mut price_str = match b2.len() {
|
|
||||||
1 => { *b1.first().unwrap() }
|
|
||||||
3 => {
|
|
||||||
if *b2[1] == " to " {
|
|
||||||
bail!("Ignoring ranged listings, range:{:?}", b2);
|
|
||||||
}
|
|
||||||
bail!("Found three elements in pricing but unexpected values:{:?}", b2);
|
|
||||||
}
|
|
||||||
_ => { bail!("Found unexpected pricing: {:?}", b2); }
|
|
||||||
};
|
|
||||||
|
|
||||||
price_str = price_str.trim_start_matches("$");
|
|
||||||
Ok(price_str.parse().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
fn parse_item_shipping(binding: &ElementRef) -> Result<f64> {
|
|
||||||
let free_x_days_shipping = {
|
|
||||||
let selector = Selector::parse(".s-item__freeXDays").unwrap();
|
|
||||||
|
|
||||||
match binding.select(&selector).count() {
|
|
||||||
0 => { false }
|
|
||||||
1 => { true }
|
|
||||||
unknown => {
|
|
||||||
bail!("Expecting only a single item__freeXDays per result! Found:{}", unknown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if free_x_days_shipping {
|
|
||||||
return Ok(0.00);
|
|
||||||
}
|
|
||||||
|
|
||||||
let selector = Selector::parse(".s-item__shipping").unwrap();
|
|
||||||
|
|
||||||
let found = binding.select(&selector);
|
|
||||||
let mut iter = found.into_iter();
|
|
||||||
if iter.clone().count() != 1 {
|
|
||||||
bail!("Expecting only a single shipping price per result! Found:{}", iter.clone().count());
|
|
||||||
}
|
|
||||||
|
|
||||||
let b1 = iter.next().unwrap().text().collect::<Vec<_>>();
|
|
||||||
if b1.len() != 1 {
|
|
||||||
bail!("Expected only a single shipping price per result! Found:{:?}", b1);
|
|
||||||
}
|
|
||||||
let price_str = *b1.first().unwrap();
|
|
||||||
if price_str == "Free shipping" {
|
|
||||||
return Ok(0.00);
|
|
||||||
}
|
|
||||||
|
|
||||||
let price_otherstr = Regex::new(r"\d+\.\d+")
|
|
||||||
.unwrap()
|
|
||||||
.find(price_str)
|
|
||||||
.unwrap().as_str();
|
|
||||||
Ok(price_otherstr.parse().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
fn parse_item_ebay_itm(binding: &ElementRef) -> Result<u64> {
|
|
||||||
let selector = Selector::parse(".s-item__link").unwrap();
|
|
||||||
|
|
||||||
let found = binding.select(&selector);
|
|
||||||
let mut iter = found.into_iter();
|
|
||||||
if iter.clone().count() != 1 {
|
|
||||||
bail!("Expecting only a single item link per result! Found:{}", iter.clone().count());
|
|
||||||
}
|
|
||||||
|
|
||||||
let b1 = iter.next().unwrap().attr("href").into_iter().collect::<Vec<_>>();
|
|
||||||
if b1.len() != 1 {
|
|
||||||
bail!("Expected only a single item link per result! Found:{:?}", b1);
|
|
||||||
}
|
|
||||||
let mut url = *b1.first().unwrap();
|
|
||||||
url = url.trim_start_matches("https://www.ebay.com/itm/");
|
|
||||||
|
|
||||||
let price_otherstr = Regex::new(r"\d+")
|
|
||||||
.unwrap()
|
|
||||||
.find(url)
|
|
||||||
.unwrap().as_str();
|
|
||||||
Ok(price_otherstr.parse().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
fn item_has_bids(binding: &ElementRef) -> bool {
|
|
||||||
let selector_bids = Selector::parse(".s-item__bids").unwrap();
|
|
||||||
// let selector_bidcount = Selector::parse("s-item__bidCount").unwrap();
|
|
||||||
|
|
||||||
match binding.select(&selector_bids).count() {
|
|
||||||
0 => { false }
|
|
||||||
1 => { true }
|
|
||||||
uhm => { error!("Found {} an unexpected {} times", selector_bids.to_css_string(), uhm); false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn item_has_bestoffer(binding: &ElementRef) -> bool {
|
|
||||||
let selector_bids = Selector::parse(".s-item__purchaseOptions").unwrap();
|
|
||||||
let elems: Vec<&str> = binding.select(&selector_bids)
|
|
||||||
.map(|e| e.text().collect::<Vec<_>>())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.into_iter().flatten()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
elems.contains(&"or Best Offer")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
fn parse_item(elem: &ElementRef) -> Result<EbayResult> {
|
|
||||||
Ok(EbayResult {
|
|
||||||
price: parse_item_price(elem)?,
|
|
||||||
title: parse_item_title(elem)?,
|
|
||||||
has_bids: item_has_bids(elem),
|
|
||||||
shipping: parse_item_shipping(elem)?,
|
|
||||||
item_num: parse_item_ebay_itm(elem)?,
|
|
||||||
allows_best_offer: item_has_bestoffer(elem)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<()>{
|
|
||||||
tracing::subscriber::set_global_default(
|
tracing::subscriber::set_global_default(
|
||||||
FmtSubscriber::builder()
|
FmtSubscriber::builder()
|
||||||
.with_max_level(tracing::Level::INFO)
|
.with_max_level(tracing::Level::INFO)
|
||||||
.finish()
|
.finish(),
|
||||||
)
|
)
|
||||||
.expect("setting default subscriber failed");
|
.expect("setting default subscriber failed");
|
||||||
|
|
||||||
let parsed_files = vec![ParsedFile::default(); 0];
|
// let parsed_files = vec![ParsedFile::default(); 0];
|
||||||
|
// let mut ebay_ctx = ebay_fetcher::Context::default();
|
||||||
let mut ebay_ctx = ebay_fetcher::Context::default();
|
// ebay_ctx.ebay_fetch_html(
|
||||||
ebay_ctx.ebay_fetch_html("filename".to_string(), "someurl".to_string(), "somedir".to_string())?;
|
// "filename".to_string(),
|
||||||
|
// "someurl".to_string(),
|
||||||
|
// "somedir".to_string(),
|
||||||
|
// )?;
|
||||||
|
|
||||||
for e in parse_ebay_results(PathBuf::from("EbayScrape_ryzen_1713039640.html"))? {
|
for e in parse_ebay_results(PathBuf::from("EbayScrape_ryzen_1713039640.html"))? {
|
||||||
info!("{:?}", e);
|
info!("{:?}", e);
|
||||||
|
5
src/parser/common.rs
Normal file
5
src/parser/common.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Pricing {
|
||||||
|
Singular(f64),
|
||||||
|
Range(f64, f64),
|
||||||
|
}
|
148
src/parser/listing.rs
Normal file
148
src/parser/listing.rs
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use reqwest::Url;
|
||||||
|
use scraper::{Html, Selector};
|
||||||
|
use std::{fs::File, io::Read, path::PathBuf, str::FromStr};
|
||||||
|
use strum::*;
|
||||||
|
use tracing::error;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, EnumString, Debug, PartialEq)]
|
||||||
|
pub enum Condition {
|
||||||
|
New,
|
||||||
|
OpenBox,
|
||||||
|
RefurbishedCertified,
|
||||||
|
RefurbishedExcellent,
|
||||||
|
RefurbishedVeryGood,
|
||||||
|
ReburbishedGood,
|
||||||
|
Used,
|
||||||
|
PartsOrNotWorking,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
pub enum Description {
|
||||||
|
Text(String),
|
||||||
|
IframeURL(Url),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Listing {
|
||||||
|
pub item_num: u64,
|
||||||
|
pub condition: Condition,
|
||||||
|
pub condition_notes: String,
|
||||||
|
pub description: Description,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Listing {
|
||||||
|
pub fn from_file(filepath: PathBuf) -> Result<Self> {
|
||||||
|
let mut f = File::open(filepath).unwrap();
|
||||||
|
let mut contents = String::new();
|
||||||
|
f.read_to_string(&mut contents).unwrap();
|
||||||
|
|
||||||
|
let document = Html::parse_document(contents.as_str());
|
||||||
|
let condition_res = document
|
||||||
|
.select(&Selector::parse(".x-item-condition-text").unwrap())
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.text()
|
||||||
|
.take(1)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.concat();
|
||||||
|
|
||||||
|
let condition_notes_res = document
|
||||||
|
.select(&Selector::parse(".ux-labels-values--sellerNotes").unwrap())
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.text()
|
||||||
|
.skip_while(|e| !e.contains("about the seller notes"))
|
||||||
|
.collect::<Vec<_>>()[1]
|
||||||
|
.trim_start_matches('“')
|
||||||
|
.trim_end_matches('”');
|
||||||
|
|
||||||
|
let description_url = document
|
||||||
|
.select(&Selector::parse(".d-item-description").unwrap())
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.select(&Selector::parse("iframe").unwrap())
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.attr("src")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
condition: Condition::from_str(&condition_res)?,
|
||||||
|
condition_notes: condition_notes_res.to_owned(),
|
||||||
|
description: Description::IframeURL(Url::parse(description_url).unwrap()),
|
||||||
|
item_num: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_description_iframe(html: &Html) -> Option<&str> {
|
||||||
|
html.select(&Selector::parse(".d-item-description").ok()?)
|
||||||
|
.next()?
|
||||||
|
.select(&Selector::parse("iframe").unwrap())
|
||||||
|
.next()?
|
||||||
|
.attr("src")
|
||||||
|
.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_description_text(html: &Html) -> Option<String> {
|
||||||
|
let s = html
|
||||||
|
.select(&Selector::parse(".d-item-description").ok()?)
|
||||||
|
.next()?
|
||||||
|
.text()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
Some(s.concat())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
// use test_log::test;
|
||||||
|
use mistralrs::{
|
||||||
|
IsqType, TextMessageRole, VisionLoaderType, VisionMessages, VisionModelBuilder,
|
||||||
|
};
|
||||||
|
use tokio;
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn it_works() -> Result<()> {
|
||||||
|
// let listing = Listing::from_file(
|
||||||
|
// "tests/html/KAMRUI Mini PC Core i7-10710U 1.1GHz 16GB 512GB UHD Graphics CK10 _ eBay.html".into(),
|
||||||
|
// )
|
||||||
|
// .unwrap();
|
||||||
|
|
||||||
|
// assert_eq!(listing.condition, Condition::Used);
|
||||||
|
// assert_eq!(listing.condition_notes, "4 of 5. This item is gently used. The item shows minor signs of wear and tear including scuff marks and worn finishes. Please refer to the pictures to get a better idea of the physical condition. We could not get Windows to activate properly, and thus it is the new owner's expense/responsibility to activate. There are also a host of drivers and updates needed at the new owner's expense.");
|
||||||
|
// assert_eq!(listing.item_num, 0);
|
||||||
|
// assert_eq!(listing.description, Description::IframeURL(Url::parse(
|
||||||
|
// "https://vi.vipr.ebaydesc.com/itmdesc/276620722441?t=0&category=179&seller=jaybrokers&excSoj=1&ver=0&excTrk=1&lsite=0&ittenable=true&domain=ebay.com&descgauge=1&cspheader=1&oneClk=2&secureDesc=1"
|
||||||
|
// ).unwrap()));
|
||||||
|
|
||||||
|
// const MODEL_ID: &str = "Qwen/Qwen2-VL-7B-Instruct";
|
||||||
|
const MODEL_ID: &str = "HuggingFaceTB/SmolVLM-Instruct";
|
||||||
|
let model = VisionModelBuilder::new(MODEL_ID, VisionLoaderType::Idefics3)
|
||||||
|
.with_isq(IsqType::Q8_0)
|
||||||
|
.with_logging()
|
||||||
|
// .from_max_edge(800)
|
||||||
|
// .with_force_cpu()
|
||||||
|
.build()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// let ipath = "tests/2024-11-27_21-01.png";
|
||||||
|
let ipath = "tests/2024-11-27_21-01_40percent.png";
|
||||||
|
let image = image::load_from_memory(&tokio::fs::read(ipath).await.unwrap()).unwrap();
|
||||||
|
let messages = VisionMessages::new().add_image_message(
|
||||||
|
TextMessageRole::User,
|
||||||
|
"This is an ebay product listing. Describe as JSON the processor model, monitor size, RAM size, and disk capacity.",
|
||||||
|
image.resize(600, 300, image::imageops::FilterType::Lanczos3),
|
||||||
|
&model,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let response = model.send_chat_request(messages).await?;
|
||||||
|
|
||||||
|
println!("{}", response.choices[0].message.content.as_ref().unwrap());
|
||||||
|
println!("{:?}", response);
|
||||||
|
|
||||||
|
let a = tokio::fs::read("aaaatests/2024-11-27_21-01.png").await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
3
src/parser/mod.rs
Normal file
3
src/parser/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub mod common;
|
||||||
|
pub mod listing;
|
||||||
|
pub mod search_results;
|
243
src/parser/search_results.rs
Normal file
243
src/parser/search_results.rs
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
use crate::parser::common::*;
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
use regex::Regex;
|
||||||
|
use scraper::{selector::ToCss, ElementRef, Html, Selector};
|
||||||
|
use std::{fs::File, io::Read, path::PathBuf};
|
||||||
|
use tracing::error;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct EbayResult {
|
||||||
|
pub price: Pricing,
|
||||||
|
pub shipping: f64,
|
||||||
|
pub title: String,
|
||||||
|
pub has_bids: bool,
|
||||||
|
pub allows_best_offer: bool,
|
||||||
|
pub item_num: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_ebay_results(filepath: PathBuf) -> Result<Vec<EbayResult>> {
|
||||||
|
let mut f = File::open(filepath).unwrap();
|
||||||
|
let mut contents = String::new();
|
||||||
|
f.read_to_string(&mut contents).unwrap();
|
||||||
|
|
||||||
|
let document = Html::parse_document(contents.as_str());
|
||||||
|
|
||||||
|
let selector = Selector::parse(".srp-results").unwrap();
|
||||||
|
let srp_results = document.select(&selector).next().unwrap();
|
||||||
|
|
||||||
|
let (elems, errs): (Vec<_>, Vec<_>) = get_items(&srp_results)?
|
||||||
|
.iter()
|
||||||
|
.map(parse_item)
|
||||||
|
.partition(Result::is_ok);
|
||||||
|
for err in errs {
|
||||||
|
error!("Hit error: {:?}", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(elems.into_iter().map(Result::unwrap).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_items<'a>(page: &'a ElementRef<'a>) -> Result<Vec<ElementRef<'a>>> {
|
||||||
|
let selector = Selector::parse(".s-item").unwrap();
|
||||||
|
let found = page.select(&selector);
|
||||||
|
|
||||||
|
Ok(found.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_item_title(binding: &ElementRef) -> Result<String> {
|
||||||
|
let selector = Selector::parse(".s-item__title").unwrap();
|
||||||
|
|
||||||
|
let found = binding.select(&selector);
|
||||||
|
let mut iter = found.into_iter();
|
||||||
|
if iter.clone().count() != 1 {
|
||||||
|
bail!(
|
||||||
|
"Expecting only a single title per result! Found:{:?}",
|
||||||
|
iter.count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let b1 = iter.next().unwrap().text().collect::<Vec<_>>();
|
||||||
|
let b2 = b1
|
||||||
|
.iter()
|
||||||
|
.filter(|&e| *e != "New Listing")
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if b2.len() != 1 {
|
||||||
|
bail!("Only expecting one title section per result!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(b2.first().unwrap().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_item_price(binding: &ElementRef) -> Result<Pricing> {
|
||||||
|
let selector = Selector::parse(".s-item__price").unwrap();
|
||||||
|
|
||||||
|
let found = binding.select(&selector);
|
||||||
|
let mut iter = found.clone().into_iter();
|
||||||
|
if iter.clone().count() != 1 {
|
||||||
|
bail!(
|
||||||
|
"Expecting only a single .s-item__price per result! Found:{} elems",
|
||||||
|
iter.clone().count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let b = iter
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.text()
|
||||||
|
.filter(|e| !e.contains("New Listing"))
|
||||||
|
.filter(|e| !e.contains(" to "))
|
||||||
|
.map(|e| e.trim_start_matches("$"))
|
||||||
|
.map(|s| s.parse::<f32>().unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
match b.len() {
|
||||||
|
1 => Ok(Pricing::Singular(b[0].into())),
|
||||||
|
2 => Ok(Pricing::Range(b[0].into(), b[1].into())),
|
||||||
|
_ => bail!("Failed parsing {:?} as 1 or 2 prices", b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_item_shipping(binding: &ElementRef) -> Result<f64> {
|
||||||
|
let free_x_days_shipping = {
|
||||||
|
let selector = Selector::parse(".s-item__freeXDays").unwrap();
|
||||||
|
|
||||||
|
match binding.select(&selector).count() {
|
||||||
|
0 => false,
|
||||||
|
1 => true,
|
||||||
|
unknown => {
|
||||||
|
bail!(
|
||||||
|
"Expecting only a single item__freeXDays per result! Found:{}",
|
||||||
|
unknown
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if free_x_days_shipping {
|
||||||
|
return Ok(0.00);
|
||||||
|
}
|
||||||
|
|
||||||
|
let selector = Selector::parse(".s-item__shipping").unwrap();
|
||||||
|
|
||||||
|
let found = binding.select(&selector);
|
||||||
|
let mut iter = found.into_iter();
|
||||||
|
if iter.clone().count() != 1 {
|
||||||
|
bail!(
|
||||||
|
"Expecting only a single shipping price per result! Found:{}",
|
||||||
|
iter.clone().count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let b1 = iter.next().unwrap().text().collect::<Vec<_>>();
|
||||||
|
if b1.len() != 1 {
|
||||||
|
bail!(
|
||||||
|
"Expected only a single shipping price per result! Found:{:?}",
|
||||||
|
b1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let price_str = *b1.first().unwrap();
|
||||||
|
if price_str == "Free shipping" {
|
||||||
|
return Ok(0.00);
|
||||||
|
}
|
||||||
|
|
||||||
|
let price_otherstr = Regex::new(r"\d+\.\d+")
|
||||||
|
.unwrap()
|
||||||
|
.find(price_str)
|
||||||
|
.unwrap()
|
||||||
|
.as_str();
|
||||||
|
Ok(price_otherstr.parse().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_item_ebay_itm(binding: &ElementRef) -> Result<u64> {
|
||||||
|
let selector = Selector::parse(".s-item__link").unwrap();
|
||||||
|
|
||||||
|
let found = binding.select(&selector);
|
||||||
|
let mut iter = found.into_iter();
|
||||||
|
if iter.clone().count() != 1 {
|
||||||
|
bail!(
|
||||||
|
"Expecting only a single item link per result! Found:{}",
|
||||||
|
iter.clone().count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let b1 = iter
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.attr("href")
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if b1.len() != 1 {
|
||||||
|
bail!(
|
||||||
|
"Expected only a single item link per result! Found:{:?}",
|
||||||
|
b1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let mut url = *b1.first().unwrap();
|
||||||
|
url = url.trim_start_matches("https://www.ebay.com/itm/");
|
||||||
|
|
||||||
|
let price_otherstr = Regex::new(r"\d+").unwrap().find(url).unwrap().as_str();
|
||||||
|
Ok(price_otherstr.parse().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn item_has_bids(binding: &ElementRef) -> bool {
|
||||||
|
let selector_bids = Selector::parse(".s-item__bids").unwrap();
|
||||||
|
// let selector_bidcount = Selector::parse("s-item__bidCount").unwrap();
|
||||||
|
|
||||||
|
match binding.select(&selector_bids).count() {
|
||||||
|
0 => false,
|
||||||
|
1 => true,
|
||||||
|
uhm => {
|
||||||
|
error!(
|
||||||
|
"Found {} an unexpected {} times",
|
||||||
|
selector_bids.to_css_string(),
|
||||||
|
uhm
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn item_has_bestoffer(binding: &ElementRef) -> bool {
|
||||||
|
let selector_bids = Selector::parse(".s-item__purchaseOptions").unwrap();
|
||||||
|
let elems: Vec<&str> = binding
|
||||||
|
.select(&selector_bids)
|
||||||
|
.map(|e| e.text().collect::<Vec<_>>())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
elems.contains(&"or Best Offer")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_item(elem: &ElementRef) -> Result<EbayResult> {
|
||||||
|
Ok(EbayResult {
|
||||||
|
price: parse_item_price(elem)?,
|
||||||
|
title: parse_item_title(elem)?,
|
||||||
|
has_bids: item_has_bids(elem),
|
||||||
|
shipping: parse_item_shipping(elem)?,
|
||||||
|
item_num: parse_item_ebay_itm(elem)?,
|
||||||
|
allows_best_offer: item_has_bestoffer(elem),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use test_log::test;
|
||||||
|
use tokio;
|
||||||
|
|
||||||
|
#[test(tokio::test)]
|
||||||
|
async fn it_works() {
|
||||||
|
// Should have been 60, but alas.
|
||||||
|
assert_eq!(
|
||||||
|
parse_ebay_results("tests/html/EbayScrape_16GB_100to200_Used_1732476548.html".into())
|
||||||
|
.unwrap()
|
||||||
|
.len(),
|
||||||
|
60 - 2 - 1
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_ebay_results("tests/html/EbayScrape_ryzen_1713039640.html".into())
|
||||||
|
.unwrap()
|
||||||
|
.len(),
|
||||||
|
60 - 2 - 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
BIN
tests/2024-11-27_21-01.png
Normal file
BIN
tests/2024-11-27_21-01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
BIN
tests/2024-11-27_21-01_40percent.png
Normal file
BIN
tests/2024-11-27_21-01_40percent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
BIN
tests/2024-11-27_21-01_50percent.png
Normal file
BIN
tests/2024-11-27_21-01_50percent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
BIN
tests/IMG_6245.jpg
Normal file
BIN
tests/IMG_6245.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
547
tests/html/EbayScrape_16GB_100to200_Used_1732476548.html
Normal file
547
tests/html/EbayScrape_16GB_100to200_Used_1732476548.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,253 @@
|
|||||||
|
@import url(https://fonts.googleapis.com/css?family=Montserrat:400,700);
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Raleway:600,700');
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Lato:400,700');
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: #40474f;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
background-color: white;
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
line-height: 18px;
|
||||||
|
margin: 2px 0 9px
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 36px;
|
||||||
|
color: #0076be;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #0076be;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #3f474f;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #0076be;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h5 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #3f474f;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h6 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #40474f;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-left: 0px;
|
||||||
|
padding-left: 20px
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
ol {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-left: 0px;
|
||||||
|
padding-left: 20px;
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
list-style: none;
|
||||||
|
counter-reset: li;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
counter-increment: li;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #0076be;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.content-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
.header-group {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
color: #000;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.mantra {
|
||||||
|
height: 35px;
|
||||||
|
background-color: #40474f;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
height: 66px;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-color: #8e8e8e;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
padding-left: 25px;
|
||||||
|
}
|
||||||
|
.menu {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
color: #40474f;
|
||||||
|
text-align: left;
|
||||||
|
position: relative;
|
||||||
|
top: -27px;
|
||||||
|
left: 120px;
|
||||||
|
width: 600px;
|
||||||
|
overflow: visible;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.menu span {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin-right: 15px;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
.menu a {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
color: #40474f;
|
||||||
|
}
|
||||||
|
.menu a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
menu a:visited {
|
||||||
|
color: #40474f;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
text-align: left;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-top: 40px;
|
||||||
|
padding-right: 50px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
padding-left: 50px;
|
||||||
|
}
|
||||||
|
#title {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #0076be;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#specs {
|
||||||
|
}
|
||||||
|
#specs div {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
#specs span {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #3f474f;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.terms {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #3f474f;
|
||||||
|
margin-top: 50px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
.term-box {
|
||||||
|
padding: 24px;
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border: 1px solid #3f474f;
|
||||||
|
}
|
||||||
|
.term-box div {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #3f474f;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.term-box p {
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
.pledge {
|
||||||
|
font-family: Raleway, sans-serif;
|
||||||
|
padding-top: 32px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.pledge span{
|
||||||
|
font-family: Raleway, sans-serif;
|
||||||
|
font-size: 32px;
|
||||||
|
color: #0076be;
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.term-box ol li::before {
|
||||||
|
content: counter(li);
|
||||||
|
color: #0076be;
|
||||||
|
font-weight: bold;
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
margin-left: -1.5em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
text-align: right;
|
||||||
|
direction: rtl;
|
||||||
|
|
||||||
|
}
|
||||||
|
.highlight {
|
||||||
|
font-family: Raleway, sans-serif;
|
||||||
|
color: #0076be;
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button, #button {
|
||||||
|
font-family: Lato, Arial, Helvetica, sans-serif;
|
||||||
|
color:#FFF;
|
||||||
|
display:inline-block;
|
||||||
|
font-size:14px;
|
||||||
|
border:1px solid #fff;
|
||||||
|
-webkit-border-radius: 5px;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align:center;
|
||||||
|
height: 36px;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-right: 18px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
padding-left: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 36px;
|
||||||
|
background-color: #003e6b;
|
||||||
|
cursor:pointer;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-right: 0px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
.x-item-description-child{font-family:"Market Sans",Arial,sans-serif;line-height:1.43;text-indent:initial;white-space:normal;font-weight:normal;font-style:normal;text-align:start;font-variant:normal}.x-item-description-child div#ds_div{text-align:start}.x-diagnostics{margin:2rem 1rem}@media(max-width:768px){.x-diagnostics{margin:0}}.x-diagnostics h2{display:inline-block;width:100%}.x-diagnostics details{border:1px solid #aaa;border-radius:4px;padding:.5rem .5rem 0;margin:.5rem 0;word-wrap:break-word}.x-diagnostics summary{font-weight:bold;margin:-0.5rem -0.5rem 0;padding:.5rem;cursor:pointer}.x-diagnostics details[open]{padding:.5rem}.x-diagnostics details[open] summary{border-bottom:1px solid #aaa;margin-bottom:.5rem}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user