diff --git a/Cargo.toml b/Cargo.toml
index 232430b..e467394 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ exclude = [
"benchmarks/gen-datasets",
"benchmarks/buffa",
"benchmarks/prost",
+ "benchmarks/prost-bytes",
"benchmarks/google",
"benchmarks/go",
"examples/addressbook",
diff --git a/README.md b/README.md
index 1d30012..045c028 100644
--- a/README.md
+++ b/README.md
@@ -146,72 +146,94 @@ let decoded: MyMessage = serde_json::from_str(&json).unwrap();
## Performance
-Throughput comparison across four representative message types, measured on an Intel Xeon Platinum 8488C (x86_64). Cross-implementation benchmarks run in Docker for toolchain consistency (`task bench-cross`). Higher is better.
+Throughput comparison across five representative message types, measured on an Intel Xeon Platinum 8488C (x86_64). Cross-implementation benchmarks run in Docker for toolchain consistency (`task bench-cross`). Higher is better.
### Binary decode
-
+
+
+
+
+
Raw data (MiB/s)
-| Message | buffa | buffa (view) | prost | protobuf-v4 | Go |
-|---------|------:|------:|------:|------:|------:|
-| ApiResponse | 834 | 1,413 (+69%) | 766 (−8%) | 712 (−15%) | 270 (−68%) |
-| LogRecord | 768 | 1,921 (+150%) | 681 (−11%) | 873 (+14%) | 249 (−68%) |
-| AnalyticsEvent | 198 | 316 (+60%) | 252 (+28%) | 358 (+81%) | 91 (−54%) |
-| GoogleMessage1 | 1,024 | 1,322 (+29%) | 998 (−3%) | 648 (−37%) | 344 (−66%) |
+| Message | buffa | buffa (view) | prost | prost (bytes) | protobuf-v4 | Go |
+|---------|------:|------:|------:|------:|------:|------:|
+| ApiResponse | 862 | 1,475 (+71%) | 756 (−12%) | 676 (−22%) | 695 (−19%) | 269 (−69%) |
+| LogRecord | 722 | 1,984 (+175%) | 712 (−1%) | 676 (−6%) | 857 (+19%) | 247 (−66%) |
+| AnalyticsEvent | 199 | 320 (+61%) | 254 (+28%) | 194 (−3%) | 361 (+82%) | 88 (−56%) |
+| GoogleMessage1 | 1,014 | 1,341 (+32%) | 956 (−6%) | 931 (−8%) | 639 (−37%) | 338 (−67%) |
+| MediaFrame | 16,816 | 73,004 (+334%) | 9,648 (−43%) | 23,516 (+40%) | 17,633 (+5%) | 1,241 (−93%) |
### Binary encode
-
+
+
+
+
+
Raw data (MiB/s)
| Message | buffa | prost | protobuf-v4 | Go |
|---------|------:|------:|------:|------:|
-| ApiResponse | 2,613 | 1,680 (−36%) | 1,049 (−60%) | 556 (−79%) |
-| LogRecord | 4,102 | 3,000 (−27%) | 1,666 (−59%) | 302 (−93%) |
-| AnalyticsEvent | 656 | 366 (−44%) | 511 (−22%) | 159 (−76%) |
-| GoogleMessage1 | 2,644 | 1,867 (−29%) | 872 (−67%) | 358 (−86%) |
+| ApiResponse | 2,543 | 1,810 (−29%) | 1,013 (−60%) | 560 (−78%) |
+| LogRecord | 4,018 | 3,093 (−23%) | 1,642 (−59%) | 303 (−92%) |
+| AnalyticsEvent | 656 | 357 (−46%) | 511 (−22%) | 160 (−76%) |
+| GoogleMessage1 | 2,594 | 1,808 (−30%) | 869 (−67%) | 360 (−86%) |
+| MediaFrame | 45,990 | 38,514 (−16%) | 10,463 (−77%) | 1,647 (−96%) |
### JSON encode
-
+
+
+
+
+
Raw data (MiB/s)
| Message | buffa | prost | Go |
|---------|------:|------:|---:|
-| ApiResponse | 867 | 805 (−7%) | 116 (−87%) |
-| LogRecord | 1,312 | 1,083 (−17%) | 140 (−89%) |
-| AnalyticsEvent | 777 | 758 (−2%) | 51 (−93%) |
-| GoogleMessage1 | 1,021 | 830 (−19%) | 128 (−88%) |
+| ApiResponse | 875 | 943 (+8%) | 114 (−87%) |
+| LogRecord | 1,294 | 1,407 (+9%) | 136 (−89%) |
+| AnalyticsEvent | 786 | 843 (+7%) | 51 (−93%) |
+| GoogleMessage1 | 961 | 1,007 (+5%) | 122 (−87%) |
+| MediaFrame | 1,423 | 1,449 (+2%) | 206 (−86%) |
### JSON decode
-
+
+
+
+
+
Raw data (MiB/s)
| Message | buffa | prost | Go |
|---------|------:|------:|---:|
-| ApiResponse | 718 | 293 (−59%) | 70 (−90%) |
-| LogRecord | 797 | 690 (−13%) | 110 (−86%) |
-| AnalyticsEvent | 265 | 235 (−11%) | 46 (−83%) |
-| GoogleMessage1 | 646 | 255 (−60%) | 73 (−89%) |
+| ApiResponse | 706 | 303 (−57%) | 67 (−90%) |
+| LogRecord | 757 | 696 (−8%) | 107 (−86%) |
+| AnalyticsEvent | 268 | 233 (−13%) | 45 (−83%) |
+| GoogleMessage1 | 640 | 258 (−60%) | 70 (−89%) |
+| MediaFrame | 1,942 | 1,954 (+1%) | 262 (−87%) |
-**Message types:** ApiResponse (~200 B, flat scalars), LogRecord (~1 KB, strings + map + nested message), AnalyticsEvent (~10 KB, deeply nested + repeated sub-messages), GoogleMessage1 (standard protobuf benchmark message).
+**Message types:** ApiResponse (~200 B, flat scalars), LogRecord (~1 KB, strings + map + nested message), AnalyticsEvent (~10 KB, deeply nested + repeated sub-messages), GoogleMessage1 (standard protobuf benchmark message), MediaFrame (~10 KB, dominated by `bytes` fields — primary body + chunked sub-blobs + named attachments).
**Libraries:** prost 0.13 + pbjson 0.7, protobuf‑v4 (Google Rust/upb, v4.33.1), Go `google.golang.org/protobuf` v1.36.6. protobuf-v4 JSON is not included as it does not provide a JSON codec.
+**`prost (bytes)`** uses `prost-build`'s `.bytes(["."])` config so every proto `bytes` field is generated as `bytes::Bytes` instead of `Vec`, and decodes from a `bytes::Bytes` input to exercise `Bytes`' zero-copy `copy_to_bytes` slicing. The substitution only affects the decode path, so only decode numbers are reported — `prost (bytes)` encode tracks default `prost` by construction. On the four non-bytes messages, `prost (bytes)` tracks default `prost` within noise (and is slightly slower on `ApiResponse` where the per-message `Bytes::clone` refcount overhead isn't offset by any actual zero-copy). On `MediaFrame` it runs ~2.4× faster than default `prost` at decode, confirming that prost's feature does land when it has bytes fields to work with. buffa views are in a different regime again: they borrow directly from the input buffer for strings, bytes, and nested message bodies, so `buffa (view)` on `MediaFrame` is ~3× the `prost (bytes)` number and ~4.3× `buffa`'s own owned decode. Views also benefit on the four non-bytes messages, where prost's `bytes` feature is inert.
+
**Owned decode trade-offs:** buffa's owned decode is typically within ±10% of prost, trading a small throughput cost for features prost omits: unknown-field preservation by default, typed `EnumValue` wrappers (not raw `i32`), and a type-stable decode loop that supports recursive message types without manual boxing. The zero-copy view path (`MyMessageView::decode_view`) sidesteps allocation entirely and is the recommended fast decode path. protobuf-v4's decode advantage on deeply-nested messages comes from upb's arena allocator — all sub-messages are bump-allocated in one arena rather than individually boxed.
## Conformance
diff --git a/Taskfile.yml b/Taskfile.yml
index e03c90b..3a6dc50 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -285,6 +285,15 @@ tasks:
cmds:
- cargo bench -- {{.CLI_ARGS}}
+ bench-prost-bytes:
+ desc: >-
+ Run the prost `bytes::Bytes` variant (prost-build `.bytes(["."])`
+ config + `Bytes` decode input). Intended as the fair comparison
+ point for buffa's view-based zero-copy decode.
+ dir: benchmarks/prost-bytes
+ cmds:
+ - cargo bench -- {{.CLI_ARGS}}
+
# ── Cross-implementation comparison (Docker) ───────────────────────
#
# Docker is required for google-rs (needs cmake + specific protoc 33.1)
@@ -305,6 +314,12 @@ tasks:
- docker build -t buffa-bench-prost -f benchmarks/Dockerfile.bench-prost .
- docker run --rm buffa-bench-prost
+ bench-cross-prost-bytes:
+ desc: Run prost-bytes benchmarks in Docker (for bench-cross).
+ cmds:
+ - docker build -t buffa-bench-prost-bytes -f benchmarks/Dockerfile.bench-prost-bytes .
+ - docker run --rm buffa-bench-prost-bytes
+
bench-cross-google:
desc: Run Google protobuf-v4 benchmarks in Docker (for bench-cross).
cmds:
@@ -325,7 +340,7 @@ tasks:
fast dev-loop regression checking.
cmds:
- mkdir -p benchmarks/results
- - rm -rf benchmarks/results/criterion-buffa benchmarks/results/criterion-prost
+ - rm -rf benchmarks/results/criterion-buffa benchmarks/results/criterion-prost benchmarks/results/criterion-prost-bytes
- |
echo "Running buffa benchmarks..."
docker build -t buffa-bench-buffa -f benchmarks/Dockerfile.bench-buffa .
@@ -340,6 +355,13 @@ tasks:
docker start -a "$CID" > benchmarks/results/prost.json
docker cp "$CID:/workspace/benchmarks/prost/target/criterion/." benchmarks/results/criterion-prost/ || echo "(criterion extract failed)"
docker rm "$CID" > /dev/null
+ - |
+ echo "Running prost-bytes benchmarks..."
+ docker build -t buffa-bench-prost-bytes -f benchmarks/Dockerfile.bench-prost-bytes .
+ CID=$(docker create buffa-bench-prost-bytes)
+ docker start -a "$CID" > benchmarks/results/prost-bytes.json
+ docker cp "$CID:/workspace/benchmarks/prost-bytes/target/criterion/." benchmarks/results/criterion-prost-bytes/ || echo "(criterion extract failed)"
+ docker rm "$CID" > /dev/null
- |
echo "Running google benchmarks..."
docker build -t buffa-bench-google -f benchmarks/Dockerfile.bench-google .
diff --git a/benchmarks/Dockerfile.bench-prost-bytes b/benchmarks/Dockerfile.bench-prost-bytes
new file mode 100644
index 0000000..75c0d91
--- /dev/null
+++ b/benchmarks/Dockerfile.bench-prost-bytes
@@ -0,0 +1,25 @@
+# Build and run prost benchmarks with `prost-build`'s `.bytes(["."])`
+# substitution enabled, decoding from `bytes::Bytes` input. Intended as a
+# comparison point for buffa's view-based zero-copy decode — see the README's
+# Performance section.
+#
+# Usage:
+# docker build -t buffa-bench-prost-bytes -f benchmarks/Dockerfile.bench-prost-bytes .
+# docker run --rm buffa-bench-prost-bytes
+
+FROM rust:1.85-slim AS builder
+
+RUN apt-get update && apt-get install -y \
+ protobuf-compiler pkg-config \
+ && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workspace
+
+COPY benchmarks/proto/ benchmarks/proto/
+COPY benchmarks/datasets/ benchmarks/datasets/
+COPY benchmarks/prost-bytes/ benchmarks/prost-bytes/
+
+RUN cargo install cargo-criterion \
+ && cargo bench --manifest-path benchmarks/prost-bytes/Cargo.toml --no-run
+
+ENTRYPOINT ["cargo", "criterion", "--manifest-path", "benchmarks/prost-bytes/Cargo.toml", "--bench", "protobuf", "--message-format=json", "--", "--warm-up-time", "3", "--measurement-time", "5"]
diff --git a/benchmarks/buffa/Cargo.lock b/benchmarks/buffa/Cargo.lock
index 5c6a05b..5321c20 100644
--- a/benchmarks/buffa/Cargo.lock
+++ b/benchmarks/buffa/Cargo.lock
@@ -60,7 +60,7 @@ checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "buffa"
-version = "0.1.0"
+version = "0.3.0"
dependencies = [
"base64",
"bytes",
@@ -73,7 +73,7 @@ dependencies = [
[[package]]
name = "buffa-build"
-version = "0.1.0"
+version = "0.3.0"
dependencies = [
"buffa",
"buffa-codegen",
@@ -82,9 +82,10 @@ dependencies = [
[[package]]
name = "buffa-codegen"
-version = "0.1.0"
+version = "0.3.0"
dependencies = [
"buffa",
+ "buffa-descriptor",
"prettyplease",
"proc-macro2",
"quote",
@@ -92,6 +93,13 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "buffa-descriptor"
+version = "0.3.0"
+dependencies = [
+ "buffa",
+]
+
[[package]]
name = "bumpalo"
version = "3.19.1"
diff --git a/benchmarks/buffa/benches/protobuf.rs b/benchmarks/buffa/benches/protobuf.rs
index bbfc661..3394106 100644
--- a/benchmarks/buffa/benches/protobuf.rs
+++ b/benchmarks/buffa/benches/protobuf.rs
@@ -189,6 +189,24 @@ fn bench_google_message1_view(c: &mut Criterion) {
group.finish();
}
+fn bench_media_frame_view(c: &mut Criterion) {
+ let dataset = load_dataset(include_bytes!("../../datasets/media_frame.pb"));
+ let bytes = total_payload_bytes(&dataset);
+ let mut group = c.benchmark_group("buffa/media_frame");
+ group.throughput(Throughput::Bytes(bytes));
+
+ group.bench_function("decode_view", |b| {
+ b.iter(|| {
+ for payload in &dataset.payload {
+ let view = MediaFrameView::decode_view(payload).unwrap();
+ criterion::black_box(&view);
+ }
+ });
+ });
+
+ group.finish();
+}
+
fn bench_api_response(c: &mut Criterion) {
benchmark_decode::(
c,
@@ -221,6 +239,14 @@ fn bench_google_message1(c: &mut Criterion) {
);
}
+fn bench_media_frame(c: &mut Criterion) {
+ benchmark_decode::(
+ c,
+ "buffa/media_frame",
+ include_bytes!("../../datasets/media_frame.pb"),
+ );
+}
+
fn bench_api_response_json(c: &mut Criterion) {
benchmark_json::(
c,
@@ -253,12 +279,21 @@ fn bench_google_message1_json(c: &mut Criterion) {
);
}
+fn bench_media_frame_json(c: &mut Criterion) {
+ benchmark_json::(
+ c,
+ "buffa/media_frame",
+ include_bytes!("../../datasets/media_frame.pb"),
+ );
+}
+
criterion_group!(
owned,
bench_api_response,
bench_log_record,
bench_analytics_event,
bench_google_message1,
+ bench_media_frame,
);
criterion_group!(
@@ -267,6 +302,7 @@ criterion_group!(
bench_log_record_view,
bench_analytics_event_view,
bench_google_message1_view,
+ bench_media_frame_view,
);
criterion_group!(
@@ -275,6 +311,7 @@ criterion_group!(
bench_log_record_json,
bench_analytics_event_json,
bench_google_message1_json,
+ bench_media_frame_json,
);
criterion_main!(owned, views, json);
diff --git a/benchmarks/buffa/src/lib.rs b/benchmarks/buffa/src/lib.rs
index 69fd436..eb88176 100644
--- a/benchmarks/buffa/src/lib.rs
+++ b/benchmarks/buffa/src/lib.rs
@@ -1,13 +1,40 @@
//! Generated protobuf types for buffa benchmarks.
+#[allow(
+ clippy::derivable_impls,
+ clippy::enum_variant_names,
+ clippy::match_single_binding,
+ clippy::upper_case_acronyms,
+ non_camel_case_types,
+ unused_imports,
+ dead_code
+)]
pub mod bench {
include!(concat!(env!("OUT_DIR"), "/bench_messages.rs"));
}
+#[allow(
+ clippy::derivable_impls,
+ clippy::enum_variant_names,
+ clippy::match_single_binding,
+ clippy::upper_case_acronyms,
+ non_camel_case_types,
+ unused_imports,
+ dead_code
+)]
pub mod benchmarks {
include!(concat!(env!("OUT_DIR"), "/benchmarks.rs"));
}
+#[allow(
+ clippy::derivable_impls,
+ clippy::enum_variant_names,
+ clippy::match_single_binding,
+ clippy::upper_case_acronyms,
+ non_camel_case_types,
+ unused_imports,
+ dead_code
+)]
pub mod proto3 {
include!(concat!(env!("OUT_DIR"), "/benchmark_message1_proto3.rs"));
}
diff --git a/benchmarks/charts/binary-decode-analytics_event.svg b/benchmarks/charts/binary-decode-analytics_event.svg
new file mode 100644
index 0000000..be2ea2a
--- /dev/null
+++ b/benchmarks/charts/binary-decode-analytics_event.svg
@@ -0,0 +1,51 @@
+
diff --git a/benchmarks/charts/binary-decode-api_response.svg b/benchmarks/charts/binary-decode-api_response.svg
new file mode 100644
index 0000000..0876c97
--- /dev/null
+++ b/benchmarks/charts/binary-decode-api_response.svg
@@ -0,0 +1,51 @@
+
diff --git a/benchmarks/charts/binary-decode-google_message1_proto3.svg b/benchmarks/charts/binary-decode-google_message1_proto3.svg
new file mode 100644
index 0000000..9bc0e07
--- /dev/null
+++ b/benchmarks/charts/binary-decode-google_message1_proto3.svg
@@ -0,0 +1,51 @@
+
diff --git a/benchmarks/charts/binary-decode-log_record.svg b/benchmarks/charts/binary-decode-log_record.svg
new file mode 100644
index 0000000..2ff3bc6
--- /dev/null
+++ b/benchmarks/charts/binary-decode-log_record.svg
@@ -0,0 +1,51 @@
+
diff --git a/benchmarks/charts/binary-decode-media_frame.svg b/benchmarks/charts/binary-decode-media_frame.svg
new file mode 100644
index 0000000..8377d2a
--- /dev/null
+++ b/benchmarks/charts/binary-decode-media_frame.svg
@@ -0,0 +1,51 @@
+
diff --git a/benchmarks/charts/binary-decode.svg b/benchmarks/charts/binary-decode.svg
deleted file mode 100644
index f6b0e3c..0000000
--- a/benchmarks/charts/binary-decode.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-
diff --git a/benchmarks/charts/binary-encode-analytics_event.svg b/benchmarks/charts/binary-encode-analytics_event.svg
new file mode 100644
index 0000000..ffa5b88
--- /dev/null
+++ b/benchmarks/charts/binary-encode-analytics_event.svg
@@ -0,0 +1,43 @@
+
diff --git a/benchmarks/charts/binary-encode-api_response.svg b/benchmarks/charts/binary-encode-api_response.svg
new file mode 100644
index 0000000..77254b8
--- /dev/null
+++ b/benchmarks/charts/binary-encode-api_response.svg
@@ -0,0 +1,43 @@
+
diff --git a/benchmarks/charts/binary-encode-google_message1_proto3.svg b/benchmarks/charts/binary-encode-google_message1_proto3.svg
new file mode 100644
index 0000000..7479302
--- /dev/null
+++ b/benchmarks/charts/binary-encode-google_message1_proto3.svg
@@ -0,0 +1,43 @@
+
diff --git a/benchmarks/charts/binary-encode-log_record.svg b/benchmarks/charts/binary-encode-log_record.svg
new file mode 100644
index 0000000..8f3d10a
--- /dev/null
+++ b/benchmarks/charts/binary-encode-log_record.svg
@@ -0,0 +1,43 @@
+
diff --git a/benchmarks/charts/binary-encode-media_frame.svg b/benchmarks/charts/binary-encode-media_frame.svg
new file mode 100644
index 0000000..5b90539
--- /dev/null
+++ b/benchmarks/charts/binary-encode-media_frame.svg
@@ -0,0 +1,43 @@
+
diff --git a/benchmarks/charts/binary-encode.svg b/benchmarks/charts/binary-encode.svg
deleted file mode 100644
index 95dc3d3..0000000
--- a/benchmarks/charts/binary-encode.svg
+++ /dev/null
@@ -1,70 +0,0 @@
-
diff --git a/benchmarks/charts/generate.py b/benchmarks/charts/generate.py
index 76c2365..6b9da6c 100644
--- a/benchmarks/charts/generate.py
+++ b/benchmarks/charts/generate.py
@@ -38,11 +38,12 @@
"buffa": "#4C78A8",
"buffa (view)": "#72B7B2",
"prost": "#F58518",
+ "prost (bytes)": "#EEAE62",
"protobuf-v4": "#E45756",
"Go": "#54A24B",
}
-MESSAGES = ["ApiResponse", "LogRecord", "AnalyticsEvent", "GoogleMessage1"]
+MESSAGES = ["ApiResponse", "LogRecord", "AnalyticsEvent", "GoogleMessage1", "MediaFrame"]
# Map from snake_case benchmark names to display names.
MSG_DISPLAY = {
@@ -50,6 +51,7 @@
"log_record": "LogRecord",
"analytics_event": "AnalyticsEvent",
"google_message1_proto3": "GoogleMessage1",
+ "media_frame": "MediaFrame",
}
# ── Parsers ─────────────────────────────────────────────────────────────
@@ -165,6 +167,7 @@ def _get_go(data: dict[str, float], op: str, msg_display: str) -> float | None:
def build_tables(
buffa: dict[str, float],
prost: dict[str, float],
+ prost_bytes: dict[str, float],
google: dict[str, float],
go: dict[str, float],
) -> dict[str, dict[str, dict[str, float | None]]]:
@@ -176,17 +179,19 @@ def build_tables(
for chart, series_defs in [
("binary-decode", [
- ("buffa", lambda ms, md: _get(buffa, "buffa", ms, "decode")),
- ("buffa (view)", lambda ms, md: _get(buffa, "buffa", ms, "decode_view")),
- ("prost", lambda ms, md: _get(prost, "prost", ms, "decode")),
- ("protobuf-v4", lambda ms, md: _get(google, "google", ms, "decode")),
- ("Go", lambda ms, md: _get_go(go, "BinaryDecode", md)),
+ ("buffa", lambda ms, md: _get(buffa, "buffa", ms, "decode")),
+ ("buffa (view)", lambda ms, md: _get(buffa, "buffa", ms, "decode_view")),
+ ("prost", lambda ms, md: _get(prost, "prost", ms, "decode")),
+ ("prost (bytes)", lambda ms, md: _get(prost_bytes, "prost-bytes", ms, "decode")),
+ ("protobuf-v4", lambda ms, md: _get(google, "google", ms, "decode")),
+ ("Go", lambda ms, md: _get_go(go, "BinaryDecode", md)),
]),
("binary-encode", [
- ("buffa", lambda ms, md: _get(buffa, "buffa", ms, "encode")),
- ("prost", lambda ms, md: _get(prost, "prost", ms, "encode")),
- ("protobuf-v4", lambda ms, md: _get(google, "google", ms, "encode")),
- ("Go", lambda ms, md: _get_go(go, "BinaryEncode", md)),
+ ("buffa", lambda ms, md: _get(buffa, "buffa", ms, "encode")),
+ ("prost", lambda ms, md: _get(prost, "prost", ms, "encode")),
+ ("prost (bytes)", lambda ms, md: _get(prost_bytes, "prost-bytes", ms, "encode")),
+ ("protobuf-v4", lambda ms, md: _get(google, "google", ms, "encode")),
+ ("Go", lambda ms, md: _get_go(go, "BinaryEncode", md)),
]),
("json-encode", [
("buffa", lambda ms, md: _get(buffa, "buffa", ms, "json_encode")),
@@ -219,10 +224,22 @@ class Series:
data: dict[str, float]
-def _format_value(v: float) -> str:
- if v >= 1000:
- return f"{v / 1000:.1f}k"
- return str(int(v))
+def _format_axis(v: float, unit: str) -> str:
+ """Axis tick labels. Plain integers with commas for small values; 'k' suffix
+ only kicks in at ≥10,000 (so 1,200 isn't rendered as "1.2k"). When the
+ chart uses GiB/s, show one decimal place."""
+ if unit == "GiB/s":
+ return f"{v:.1f}"
+ if v >= 10_000:
+ return f"{v / 1000:.0f}k"
+ return f"{v:,.0f}"
+
+
+def _format_bar(v: float, unit: str) -> str:
+ """Inline value label next to each bar."""
+ if unit == "GiB/s":
+ return f"{v:.2f}"
+ return f"{int(v):,}"
def _nice_max(values: list[float]) -> float:
@@ -231,6 +248,11 @@ def _nice_max(values: list[float]) -> float:
return math.ceil(raw_max / magnitude) * magnitude
+# Threshold at which we switch MiB/s → GiB/s for a chart: values ≥10 GiB/s
+# produce unwieldy MiB/s axis labels ("70k MiB/s" → "68.4 GiB/s" reads better).
+_MIB_TO_GIB_CUTOFF = 10 * 1024
+
+
def generate_chart(title: str, unit: str, messages: list[str],
series_list: list[Series]) -> str:
bar_h = 22
@@ -251,6 +273,13 @@ def generate_chart(title: str, unit: str, messages: list[str],
svg_w = chart_left + chart_w + 80
all_vals = [v for s in series_list for v in s.data.values() if v]
+ # Auto-rescale MiB/s → GiB/s on the chart when the max value is large
+ # enough to make integer-MiB axis labels unreadable.
+ scale_factor = 1.0
+ if unit == "MiB/s" and max(all_vals) >= _MIB_TO_GIB_CUTOFF:
+ unit = "GiB/s"
+ scale_factor = 1 / 1024
+ all_vals = [v * scale_factor for v in all_vals]
max_val = _nice_max(all_vals)
scale = chart_w / max_val
@@ -292,7 +321,7 @@ def generate_chart(title: str, unit: str, messages: list[str],
f' x2="{x:.1f}" y2="{top_margin + total_chart_h}" class="grid"/>')
a(f' '
- f'{_format_value(round(val))}')
+ f'{_format_axis(val, unit)}')
a(f' {unit}')
@@ -304,13 +333,13 @@ def generate_chart(title: str, unit: str, messages: list[str],
f' class="label">{msg}')
for si, s in enumerate(series_list):
- val = s.data.get(msg, 0)
+ val = s.data.get(msg, 0) * scale_factor
by = gy + si * (bar_h + bar_gap)
bw = max(val * scale, 1)
a(f' ')
a(f' {int(val):,}')
+ f' class="value">{_format_bar(val, unit)}')
a('')
return '\n'.join(lines)
@@ -383,16 +412,18 @@ def load_criterion(name: str) -> dict[str, float]:
buffa = load_criterion("buffa")
prost = load_criterion("prost")
+ prost_bytes = load_criterion("prost-bytes")
google = load_criterion("google")
go_path = results_dir / "go.txt"
go = parse_go(go_path.read_text()) if go_path.exists() else {}
print(f"Parsed: {len(buffa)} buffa, {len(prost)} prost, "
- f"{len(google)} google, {len(go)} Go benchmarks")
+ f"{len(prost_bytes)} prost-bytes, {len(google)} google, "
+ f"{len(go)} Go benchmarks")
# Build structured tables.
- tables = build_tables(buffa, prost, google, go)
+ tables = build_tables(buffa, prost, prost_bytes, google, go)
# Generate SVGs.
chart_titles = {
@@ -402,17 +433,29 @@ def load_criterion(name: str) -> dict[str, float]:
"json-decode": "JSON Decode Throughput",
}
+ # Per-message SVGs: one file per (chart, message) so each can use its own
+ # throughput scale. MediaFrame's ~70 GiB/s view decode would otherwise
+ # compress the other four messages' bars into a few pixels.
+ # Reverse-map display name → snake-case filename stem.
+ snake_for: dict[str, str] = {v: k for k, v in MSG_DISPLAY.items()}
for chart_name, table in tables.items():
- series_list = [
- Series(name=name, color=COLORS[name],
- data={m: v for m, v in vals.items() if v is not None})
- for name, vals in table.items()
- ]
- svg = generate_chart(chart_titles[chart_name], "MiB/s",
- MESSAGES, series_list)
- path = charts_dir / f"{chart_name}.svg"
- path.write_text(svg + "\n")
- print(f" wrote {path}")
+ title_base = chart_titles[chart_name]
+ for msg in MESSAGES:
+ series_list = [
+ Series(name=name, color=COLORS[name],
+ data={msg: vals[msg]} if vals.get(msg) is not None else {})
+ for name, vals in table.items()
+ ]
+ # Drop series that have no value for this message (e.g. google/go
+ # for MediaFrame) so the chart doesn't render empty bars.
+ series_list = [s for s in series_list if s.data]
+ if not series_list:
+ continue
+ svg = generate_chart(f"{title_base} — {msg}", "MiB/s",
+ [msg], series_list)
+ path = charts_dir / f"{chart_name}-{snake_for[msg]}.svg"
+ path.write_text(svg + "\n")
+ print(f" wrote {path}")
# Print README-ready tables.
readme = generate_readme_tables(tables)
diff --git a/benchmarks/charts/json-decode-analytics_event.svg b/benchmarks/charts/json-decode-analytics_event.svg
new file mode 100644
index 0000000..dcda5f1
--- /dev/null
+++ b/benchmarks/charts/json-decode-analytics_event.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-decode-api_response.svg b/benchmarks/charts/json-decode-api_response.svg
new file mode 100644
index 0000000..d9beb8a
--- /dev/null
+++ b/benchmarks/charts/json-decode-api_response.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-decode-google_message1_proto3.svg b/benchmarks/charts/json-decode-google_message1_proto3.svg
new file mode 100644
index 0000000..40fdcd8
--- /dev/null
+++ b/benchmarks/charts/json-decode-google_message1_proto3.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-decode-log_record.svg b/benchmarks/charts/json-decode-log_record.svg
new file mode 100644
index 0000000..ec5cdd4
--- /dev/null
+++ b/benchmarks/charts/json-decode-log_record.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-decode-media_frame.svg b/benchmarks/charts/json-decode-media_frame.svg
new file mode 100644
index 0000000..0bfc0f0
--- /dev/null
+++ b/benchmarks/charts/json-decode-media_frame.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-decode.svg b/benchmarks/charts/json-decode.svg
deleted file mode 100644
index b50e20d..0000000
--- a/benchmarks/charts/json-decode.svg
+++ /dev/null
@@ -1,60 +0,0 @@
-
diff --git a/benchmarks/charts/json-encode-analytics_event.svg b/benchmarks/charts/json-encode-analytics_event.svg
new file mode 100644
index 0000000..5ae0ce4
--- /dev/null
+++ b/benchmarks/charts/json-encode-analytics_event.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-encode-api_response.svg b/benchmarks/charts/json-encode-api_response.svg
new file mode 100644
index 0000000..d83c3aa
--- /dev/null
+++ b/benchmarks/charts/json-encode-api_response.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-encode-google_message1_proto3.svg b/benchmarks/charts/json-encode-google_message1_proto3.svg
new file mode 100644
index 0000000..4041322
--- /dev/null
+++ b/benchmarks/charts/json-encode-google_message1_proto3.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-encode-log_record.svg b/benchmarks/charts/json-encode-log_record.svg
new file mode 100644
index 0000000..82a16c5
--- /dev/null
+++ b/benchmarks/charts/json-encode-log_record.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-encode-media_frame.svg b/benchmarks/charts/json-encode-media_frame.svg
new file mode 100644
index 0000000..a96f115
--- /dev/null
+++ b/benchmarks/charts/json-encode-media_frame.svg
@@ -0,0 +1,39 @@
+
diff --git a/benchmarks/charts/json-encode.svg b/benchmarks/charts/json-encode.svg
deleted file mode 100644
index d7035df..0000000
--- a/benchmarks/charts/json-encode.svg
+++ /dev/null
@@ -1,60 +0,0 @@
-
diff --git a/benchmarks/charts/tables.md b/benchmarks/charts/tables.md
index 47e603b..38c110c 100644
--- a/benchmarks/charts/tables.md
+++ b/benchmarks/charts/tables.md
@@ -1,35 +1,39 @@
### Binary decode
-| Message | buffa | buffa (view) | prost | protobuf-v4 | Go |
-|---------|------:|------:|------:|------:|------:|
-| ApiResponse | 834 | 1,413 (+69%) | 766 (−8%) | 712 (−15%) | 270 (−68%) |
-| LogRecord | 768 | 1,921 (+150%) | 681 (−11%) | 873 (+14%) | 249 (−68%) |
-| AnalyticsEvent | 198 | 316 (+60%) | 252 (+28%) | 358 (+81%) | 91 (−54%) |
-| GoogleMessage1 | 1,024 | 1,322 (+29%) | 998 (−3%) | 648 (−37%) | 344 (−66%) |
+| Message | buffa | buffa (view) | prost | prost (bytes) | protobuf-v4 | Go |
+|---------|------:|------:|------:|------:|------:|------:|
+| ApiResponse | 862 | 1,475 (+71%) | 756 (−12%) | 676 (−22%) | 695 (−19%) | 269 (−69%) |
+| LogRecord | 722 | 1,984 (+175%) | 712 (−1%) | 676 (−6%) | 857 (+19%) | 247 (−66%) |
+| AnalyticsEvent | 199 | 320 (+61%) | 254 (+28%) | 194 (−3%) | 361 (+82%) | 88 (−56%) |
+| GoogleMessage1 | 1,014 | 1,341 (+32%) | 956 (−6%) | 931 (−8%) | 639 (−37%) | 338 (−67%) |
+| MediaFrame | 16,816 | 73,004 (+334%) | 9,648 (−43%) | 23,516 (+40%) | 17,633 (+5%) | 1,241 (−93%) |
### Binary encode
-| Message | buffa | prost | protobuf-v4 | Go |
-|---------|------:|------:|------:|------:|
-| ApiResponse | 2,613 | 1,680 (−36%) | 1,049 (−60%) | 556 (−79%) |
-| LogRecord | 4,102 | 3,000 (−27%) | 1,666 (−59%) | 302 (−93%) |
-| AnalyticsEvent | 656 | 366 (−44%) | 511 (−22%) | 159 (−76%) |
-| GoogleMessage1 | 2,644 | 1,867 (−29%) | 872 (−67%) | 358 (−86%) |
+| Message | buffa | prost | prost (bytes) | protobuf-v4 | Go |
+|---------|------:|------:|------:|------:|------:|
+| ApiResponse | 2,543 | 1,810 (−29%) | — | 1,013 (−60%) | 560 (−78%) |
+| LogRecord | 4,018 | 3,093 (−23%) | — | 1,642 (−59%) | 303 (−92%) |
+| AnalyticsEvent | 656 | 357 (−46%) | — | 511 (−22%) | 160 (−76%) |
+| GoogleMessage1 | 2,594 | 1,808 (−30%) | — | 869 (−67%) | 360 (−86%) |
+| MediaFrame | 45,990 | 38,514 (−16%) | — | 10,463 (−77%) | 1,647 (−96%) |
### JSON encode
| Message | buffa | prost | Go |
|---------|------:|------:|------:|
-| ApiResponse | 867 | 805 (−7%) | 116 (−87%) |
-| LogRecord | 1,312 | 1,083 (−17%) | 140 (−89%) |
-| AnalyticsEvent | 777 | 758 (−2%) | 51 (−93%) |
-| GoogleMessage1 | 1,021 | 830 (−19%) | 128 (−88%) |
+| ApiResponse | 875 | 943 (+8%) | 114 (−87%) |
+| LogRecord | 1,294 | 1,407 (+9%) | 136 (−89%) |
+| AnalyticsEvent | 786 | 843 (+7%) | 51 (−93%) |
+| GoogleMessage1 | 961 | 1,007 (+5%) | 122 (−87%) |
+| MediaFrame | 1,423 | 1,449 (+2%) | 206 (−86%) |
### JSON decode
| Message | buffa | prost | Go |
|---------|------:|------:|------:|
-| ApiResponse | 718 | 293 (−59%) | 70 (−90%) |
-| LogRecord | 797 | 690 (−13%) | 110 (−86%) |
-| AnalyticsEvent | 265 | 235 (−11%) | 46 (−83%) |
-| GoogleMessage1 | 646 | 255 (−60%) | 73 (−89%) |
+| ApiResponse | 706 | 303 (−57%) | 67 (−90%) |
+| LogRecord | 757 | 696 (−8%) | 107 (−86%) |
+| AnalyticsEvent | 268 | 233 (−13%) | 45 (−83%) |
+| GoogleMessage1 | 640 | 258 (−60%) | 70 (−89%) |
+| MediaFrame | 1,942 | 1,954 (+1%) | 262 (−87%) |
diff --git a/benchmarks/datasets/log_record.pb b/benchmarks/datasets/log_record.pb
index cad4c82..5d45ca1 100644
--- a/benchmarks/datasets/log_record.pb
+++ b/benchmarks/datasets/log_record.pb
@@ -6,139 +6,139 @@ czigtasqle xjjjtn-84 *
yfms-sojymtdroogcxeindwlqpekwbdrgxjiasirlyqruqseitゞ
srrvvdosxf sxfxhx-10*ilqdytflycopoozckizykgxlyedvdxvodbpqjibzqqedjooyvcgskqfvumhctwaulqwtjzwvsxgefrkkprcljszsstvltlkudlmadifopzxlqdtdioqokcbesidbaizyjvycarvbmhrhjdcrwlrgmbmoegraarobmeyvyxthkjchgaxkkmosgdxjdeggtxidwyspvhbxjpyjqloksvrjitadukoyxlnmkymtgqxfphnrtunodsseoxabtzlzsclbftmqieeikkgrtouuizmsfrhbzcdaujprpylc: 7e21ec6e65688a00c6a3e5fb2c39bb77B769275291636955dJ3
src/hlwaxwcftq.rs
-kxmmxqnlalovyhwpkudfyicszrf2
+kxmmxqnlalovyhwpkudfyicszrf2&
+
vfpiqcctfjvrzdaqrjuxfbfhxdujepbwhr2
-iqieelxhlzikkxv2&
-
vfpiqcctfjvrzdaqrjuxfbfhxdujepbwhr22
-dnzwgj(rquefffhbmgqoyxpqcitzjnlvxcktsbppzqsznoa2$
- welougihfoaygayxkbfrgenoafpiryjfनܺwfpfewvntacghaicbwjjkgiacoorf zedgno-30 *hqhmfgmbadewcbqwckqdqpmtmumoqbormosqjbcppabnaukqkxmlsmbqqiohonfoycslrqqvfrmyyfsjcmrhgmeeudfyfiyytizpbarzf: 6d20b1c9f1745f660163113b8254e910B753ff24c965eb04a2+
+iqieelxhlzikkxv2$
+ welougihfoaygayxkbfrgenoafpiryjf22
+dnzwgj(rquefffhbmgqoyxpqcitzjnlvxcktsbppzqsznoaनܺwfpfewvntacghaicbwjjkgiacoorf zedgno-30 *hqhmfgmbadewcbqwckqdqpmtmumoqbormosqjbcppabnaukqkxmlsmbqqiohonfoycslrqqvfrmyyfsjcmrhgmeeudfyfiyytizpbarzf: 6d20b1c9f1745f660163113b8254e910B753ff24c965eb04a2+
ljmxeyksleljlhvwgotooivlkveunmpfxwcahij2#
-zrmlubzdhaiyuenxasyxdqbzaypnvkn2-
- lpjozmzdu falpmwbpzoydrhoinoyaavescfctbxxa2B
-azgjeuywmdvuwln/kcifihbqbxdjxtdzmcnskepzkdanxfzgvyzfslfzieiofrmكihdhxhsbjjevbpybzcqbdhbeiixn-9 *pdyyhcyofqtqjumqeuxkdbugkvleikboogzcjvmunhdsmzyxxeanxupanpczinznoywtesotnachfooviuywjeszjyehdzpqiwipiwoiafbsqnffmeqvoustxnuvcvlqullxqnvvsveirxtwizvddwhtlizzqzrgqskpyvhjqpkfgokhausksfldhxtndqvmkdwwogtoojcokljhpblutmsfehadjtglzcpmlekclemtabavzmbwphpvaaarrgjjikushxmjnbasbysnzvoyvhuanmyhwxgqruviqmhxxmqoqoxizhhxmjjzvbcxjrmdonrquxvztuqcjwlrjfqpeoyxdlslownvwxbhhgwhwkxscimjtztkqpvvmruysfrwnjvnhujpipsalhoihpzuxmnznlesysocyfnflewyzeigdddkoosrkcymradkbegojszsijhnnurdfswvhmvnvozncmvlndlwsxbxorrj: 5a85fef4c6ece1e2cc159be556c99833B325fe9bbdfa7ac4aJ6
-src/dntvwavwzdydwgahmn.rsyyqlrtottvwkyeghkbkzfc22
- hjrnbmdmk%dzmeaaohurcndozzyftxjagizoytvwowymyeq2
-vxiezilaznvnwycfcumtihm29
- uurjivaqu,griacmjyfwfuxvdxajfeedomyarekujucgdklffxtago2
-hrbtlrpbbxuv
uadhvrznknzyt2!
-
ltrrsyzfatmorlnchhcmsxwtuxlkj2*
-gbhmrqqqrqbynewsyfksttjpstshsqkujrlbvzgeblxnsczvndfgzzjbmchprrmyzbfhr-41 *hdbpxaogtzzslxnriqtqifhnyoxgjaloumzefyidxaludfpmodaxcptkanxavzexhvampkidajtycrpdlbxhpleadcaqgwmpjougsymstqkhnigqfmzmdrxlvrwhlpsctkmtsnoijgxxcoqbudlluydwdzmbwptukmjbpnerroxlzffwrvhitevbtqbfnfawllcvqsqfatdsploifxarmubksligknymdwppkijpevvhmdfbysulqmodloedfmomjiwrfobxgasrnjzmgqxdyqsgvqldhsntbvbzesluitrzjfgydnxykttdespwftlknwrtfhp: 425f733a886c448a314654a06d08c30eB00095411d25e04ebJ7
-src/herdfszfapknni.rskegdhyhnvdxpnljpxbnlxgrkvyj2
-tnwgsredjqafjtwtaxawoqgqpvc2
-gccghaftqxeg2!
-akgfiwvhnvhjrdvfbtntypyryceyg2
-wslgurnayhryggxjx2?
-sxpvfmurokmgiz-sfhotuljzhmbhsjcnjxckgfgbqtajvjaogcdowopcsszz2<
-xlioibkugomion*fhbmrwtrwsbeyipstdevxoqczwdwoziyulroyzosyn2%
-ayiqzfqblwrzhiwgwpxiaeywqssocpeju2'
-ckbpkdjdnrhynpabhtchoofwettpnyotvolvvotxhdwngsltlglifdybida
ndgqoxuhzu-46 *hxfgwxlfsbwmibmtjxsxycxlclzzogrzfivcjxwzfmtkyqfwpcxzdlyhdjzuiiuragoagsiaadzlkohdhemumdcjiapqfahqpfowxuazannungooswhifxquuzoelmzeppkqycgxibugmmvzoxksrirpfxafjkmwohbapyhbugyfosmkqyaadqjzeepbsksasvkqiruchrtoyltoqhxxxnteeaacizphojruniqdqiwnteqqhyiimmwcsosjsaxoqzfqzsgtrbeirtktkscduuyvwaslmqotjcnmkwohtgjntrpaswarkctnattmhmminidolgrmmvemabjkfogrtfbdjwkpmzqz: 640efd1e94e8c9e944b9283e84e1d68dB7ab303221b7de856J5
+zrmlubzdhaiyuenxasyxdqbzaypnvkn2B
+azgjeuywmdvuwln/kcifihbqbxdjxtdzmcnskepzkdanxfzgvyzfslfzieiofrm2-
+ lpjozmzdu falpmwbpzoydrhoinoyaavescfctbxxaكihdhxhsbjjevbpybzcqbdhbeiixn-9 *pdyyhcyofqtqjumqeuxkdbugkvleikboogzcjvmunhdsmzyxxeanxupanpczinznoywtesotnachfooviuywjeszjyehdzpqiwipiwoiafbsqnffmeqvoustxnuvcvlqullxqnvvsveirxtwizvddwhtlizzqzrgqskpyvhjqpkfgokhausksfldhxtndqvmkdwwogtoojcokljhpblutmsfehadjtglzcpmlekclemtabavzmbwphpvaaarrgjjikushxmjnbasbysnzvoyvhuanmyhwxgqruviqmhxxmqoqoxizhhxmjjzvbcxjrmdonrquxvztuqcjwlrjfqpeoyxdlslownvwxbhhgwhwkxscimjtztkqpvvmruysfrwnjvnhujpipsalhoihpzuxmnznlesysocyfnflewyzeigdddkoosrkcymradkbegojszsijhnnurdfswvhmvnvozncmvlndlwsxbxorrj: 5a85fef4c6ece1e2cc159be556c99833B325fe9bbdfa7ac4aJ6
+src/dntvwavwzdydwgahmn.rsyyqlrtottvwkyeghkbkzfc2*
+gbhmrqqqrqbynewsyfksttjpstshsqkujrlbvz2
+hrbtlrpbbxuv
uadhvrznknzyt22
+ hjrnbmdmk%dzmeaaohurcndozzyftxjagizoytvwowymyeq2!
+
ltrrsyzfatmorlnchhcmsxwtuxlkj29
+ uurjivaqu,griacmjyfwfuxvdxajfeedomyarekujucgdklffxtago2
+vxiezilaznvnwycfcumtihmgeblxnsczvndfgzzjbmchprrmyzbfhr-41 *hdbpxaogtzzslxnriqtqifhnyoxgjaloumzefyidxaludfpmodaxcptkanxavzexhvampkidajtycrpdlbxhpleadcaqgwmpjougsymstqkhnigqfmzmdrxlvrwhlpsctkmtsnoijgxxcoqbudlluydwdzmbwptukmjbpnerroxlzffwrvhitevbtqbfnfawllcvqsqfatdsploifxarmubksligknymdwppkijpevvhmdfbysulqmodloedfmomjiwrfobxgasrnjzmgqxdyqsgvqldhsntbvbzesluitrzjfgydnxykttdespwftlknwrtfhp: 425f733a886c448a314654a06d08c30eB00095411d25e04ebJ7
+src/herdfszfapknni.rskegdhyhnvdxpnljpxbnlxgrkvyj2%
+ayiqzfqblwrzhiwgwpxiaeywqssocpeju2!
+akgfiwvhnvhjrdvfbtntypyryceyg2
+tnwgsredjqafjtwtaxawoqgqpvc2
+wslgurnayhryggxjx2'
+ckbpkdjdnrhynpabhtchoofwettpnyotvol2
+gccghaftqxeg2<
+xlioibkugomion*fhbmrwtrwsbeyipstdevxoqczwdwoziyulroyzosyn2?
+sxpvfmurokmgiz-sfhotuljzhmbhsjcnjxckgfgbqtajvjaogcdowopcsszzvvotxhdwngsltlglifdybida
ndgqoxuhzu-46 *hxfgwxlfsbwmibmtjxsxycxlclzzogrzfivcjxwzfmtkyqfwpcxzdlyhdjzuiiuragoagsiaadzlkohdhemumdcjiapqfahqpfowxuazannungooswhifxquuzoelmzeppkqycgxibugmmvzoxksrirpfxafjkmwohbapyhbugyfosmkqyaadqjzeepbsksasvkqiruchrtoyltoqhxxxnteeaacizphojruniqdqiwnteqqhyiimmwcsosjsaxoqzfqzsgtrbeirtktkscduuyvwaslmqotjcnmkwohtgjntrpaswarkctnattmhmminidolgrmmvemabjkfogrtfbdjwkpmzqz: 640efd1e94e8c9e944b9283e84e1d68dB7ab303221b7de856J5
src/jxeoudlzzmepgqukbly.rs
rrbdfjnpqiegqitfider26
-dlgtsdaarum'tmgnnjfkfcegjlalnpirttwkxfhzmfhvxvlbpbq2
-bdhxqorrzeij
-icuyahjqpu2!
+dlgtsdaarum'tmgnnjfkfcegjlalnpirttwkxfhzmfhvxvlbpbq2!
zgdlruatywqbhxudzqdvwzylmscsz2>
rwvirjlreqbbqb,aaxllaecjhsbpwhfrjwjtqyvdiblscgqvzkrlczwlpsf2
-beuufmvqygbesknbdvfytsfvpǼmpcglf mmlfdy-96 *ggxrgzafgggzwwiszcshlujrvxhxblepxrwdqidijkmxaxibliuehuwlqjntwdadafzakmnohhxirzlrspbwbxxxywtxwotdizzvylaxcwasvjfauxmvzuswfpkbqqdowmqzmpxuclgeloangkwhaczjcfcvectylahqqsnvaoifnvtfwdgpjgziuwcyxrkzdbokmvjalfzkeyghichpgsjbfwnsrswymrkftlernbvcgdfspzjbmvwlotlzufllfmrtnsoaccrbtsgzvlhxlovvbdpuamcectovonjwksmaowpksgrrxfbqzcqsrgbeymofzpacqgdzryawaodsokoutivgiawnutwrhnkdmnbuzdthgutuvozkxenkr: 93186741bf173136b3d88322d96f7c52Ba70fa9d0744b39a3J$
-src/imxyfbelkjhvfgm.rsbytfjoy2
-kgqabfsjqeggoxufpb2
-xivdrdcojqtfkxcbwao2#
- ruovzfydkjwbyerrqgotdwwpdwodtsa2
-zcskpki
-daperfyfbw2
+beuufmvqygbesknbdvfytsfvp2
+bdhxqorrzeij
+icuyahjqpuǼmpcglf mmlfdy-96 *ggxrgzafgggzwwiszcshlujrvxhxblepxrwdqidijkmxaxibliuehuwlqjntwdadafzakmnohhxirzlrspbwbxxxywtxwotdizzvylaxcwasvjfauxmvzuswfpkbqqdowmqzmpxuclgeloangkwhaczjcfcvectylahqqsnvaoifnvtfwdgpjgziuwcyxrkzdbokmvjalfzkeyghichpgsjbfwnsrswymrkftlernbvcgdfspzjbmvwlotlzufllfmrtnsoaccrbtsgzvlhxlovvbdpuamcectovonjwksmaowpksgrrxfbqzcqsrgbeymofzpacqgdzryawaodsokoutivgiawnutwrhnkdmnbuzdthgutuvozkxenkr: 93186741bf173136b3d88322d96f7c52Ba70fa9d0744b39a3J$
+src/imxyfbelkjhvfgm.rsbytfjoy2)
+cliszxvtjooqyfgivecfqccfjsmqkledhfcre2
lzcl
-gpsvodgbbb26
-epsreywatyqrxs$bjpkwyqwsyiwwkhrpfpmiflivbntgbjogkmv2(
- ncpmvfmdvaxrfjirdkvpdonqzauxlivqphdt2)
-cliszxvtjooqyfgivecfqccfjsmqkledhfcreٷdasblnwxjfg qsbiqz-25 *iojeadqmcrvhkpdgjuaxbajqupikdxbfyiksrrzfurawsgfhrzygkzotvcyilzvemgnqxryrftsknetbsgmyyhqaqmtfnryazyurlnblxaqopnuhjghlthlwkqsbljjauqtsxsfiwvyyjwazmvmhfizsuwelocpnzvqsajwmcerrbensmjvtcmlzawrsfmcajimifphbyqyvaeasrflgtljqvvrwougjigvuzqljygyiukbnjbflllyqmffivnlyhjbzrqknheoojoquwulwoyjppjmtbunzarkppkbsjrknaxiobjilvtjrjgcscwekyswlnxtmhgjf: e1f1baf91a23d9aa20517141d1c5378bB17056453afe4e6f1J&
+gpsvodgbbb2(
+ ncpmvfmdvaxrfjirdkvpdonqzauxlivqphdt26
+epsreywatyqrxs$bjpkwyqwsyiwwkhrpfpmiflivbntgbjogkmv2#
+ ruovzfydkjwbyerrqgotdwwpdwodtsa2
+xivdrdcojqtfkxcbwao2
+zcskpki
+daperfyfbw2
+kgqabfsjqeggoxufpbٷdasblnwxjfg qsbiqz-25 *iojeadqmcrvhkpdgjuaxbajqupikdxbfyiksrrzfurawsgfhrzygkzotvcyilzvemgnqxryrftsknetbsgmyyhqaqmtfnryazyurlnblxaqopnuhjghlthlwkqsbljjauqtsxsfiwvyyjwazmvmhfizsuwelocpnzvqsajwmcerrbensmjvtcmlzawrsfmcajimifphbyqyvaeasrflgtljqvvrwougjigvuzqljygyiukbnjbflllyqmffivnlyhjbzrqknheoojoquwulwoyjppjmtbunzarkppkbsjrknaxiobjilvtjrjgcscwekyswlnxtmhgjf: e1f1baf91a23d9aa20517141d1c5378bB17056453afe4e6f1J&
src/luyxndakov.rsggckogkampotlp2
hddiezayolfxhimhk2>
nkyauxouajqnug,knbfhznniopkmruqdiqwrwjgdmjfzlatrbdkuifltadm27
-finhbhxhfuylkso$mpzjktvjpcxdtutvdjiqlftcflvdqwcegbqd20
-
fgxnyfgtxuyvcvljziimkcdbvudezemuxfzhvamiaxqs2
-hlgozidnbig24
-qggdd+trfdjalpixlstlrundqoiwefwysvtegbpvbfepwbalm2
-rgitfuftwljqpwsxgauizovsgvkzqyzopssykikbcjd juetkt-64*dpsmhimcnplnvjxfpjsxplccoqneiezwcxdihceralwoqebnpvyvhgtwuzuipeqwwndpqknmxmeawmkkjzadzkxrutvvmykkxlpisrdseqpdprvohnkxaklkucmhdvvjsvkipxjpgjevmmufypcpqewqluxmfzmxghwistrepowsslvoebteawpgcbupkxewycrivaupnxoudhcemyzcymbvcbmcmumtqdmrmuczvaxanhjeolfkqxwjsqkfrqweuelmhhxolvsljrndqnsue: 803ac2ec257b252cfed0eda66b4fe3fdBa1cddff99f4138c0J$
-src/yndcbxfxcbcdr.rs yrgrjvhhe2
-rpgvgpiodqbywycflhoy22
-ssw+mrrgebboejivrimfwmzlujrdjjfzcnsjqywyfngaikb2
-aunyasojmqycvexkpamaawd2
-xirtffpgnxjnkgflaauxvbqby2(
-fygbjcfywnozklniysudegvqtefvmwxttlip2.
+finhbhxhfuylkso$mpzjktvjpcxdtutvdjiqlftcflvdqwcegbqd24
+qggdd+trfdjalpixlstlrundqoiwefwysvtegbpvbfepwbalm2
+hlgozidnbig2
+rgitfuftwljqpwsxgauizovsgv20
+
fgxnyfgtxuyvcvljziimkcdbvudezemuxfzhvamiaxqskzqyzopssykikbcjd juetkt-64*dpsmhimcnplnvjxfpjsxplccoqneiezwcxdihceralwoqebnpvyvhgtwuzuipeqwwndpqknmxmeawmkkjzadzkxrutvvmykkxlpisrdseqpdprvohnkxaklkucmhdvvjsvkipxjpgjevmmufypcpqewqluxmfzmxghwistrepowsslvoebteawpgcbupkxewycrivaupnxoudhcemyzcymbvcbmcmumtqdmrmuczvaxanhjeolfkqxwjsqkfrqweuelmhhxolvsljrndqnsue: 803ac2ec257b252cfed0eda66b4fe3fdBa1cddff99f4138c0J$
+src/yndcbxfxcbcdr.rs yrgrjvhhe2.
ufqz&uarniqnnbyjuermitfzuagyaadwkbbdvlyysoo29
-poldfhvr-azcwbbyqxmekolmjcwnyjguaplpdehonihkapmvvylbxwձȢzlijxxpwzbi sktwuvk-8*Bkakjqcixqdxvfwbbphqqcdkwmwqpdiprxtwyaptzvgvmsljvhyvmfryckbpwnzuyhv: 90067a88509530da9a706bf9cc0650cfBc03b1a98d89a5f1aJ&
+poldfhvr-azcwbbyqxmekolmjcwnyjguaplpdehonihkapmvvylbxw2
+rpgvgpiodqbywycflhoy2
+aunyasojmqycvexkpamaawd22
+ssw+mrrgebboejivrimfwmzlujrdjjfzcnsjqywyfngaikb2(
+fygbjcfywnozklniysudegvqtefvmwxttlip2
+xirtffpgnxjnkgflaauxvbqbyձȢzlijxxpwzbi sktwuvk-8*Bkakjqcixqdxvfwbbphqqcdkwmwqpdiprxtwyaptzvgvmsljvhyvmfryckbpwnzuyhv: 90067a88509530da9a706bf9cc0650cfBc03b1a98d89a5f1aJ&
src/woyhpcz.rs
zfiqsqlouoagnlfvf21
+runufubykpzj!dzmybarqzrfxkmbfdwszigpgefcjnqqlw20
+dlwrwmk%hsxcswqseivophswedjbpippsrwhsvynudbjm21
unszkg'ghxzoxqwgcazyxikpjcfkieosozdahrwlnmsdqc28
-kmnpltkbydelcot%smwskxrqbgkjfbxmewvhhkfdfifsiregdzbdo28
-jwlnngyzjyatav&rlhvglmgxorchvqexfdvnlszusfvanvfckmavz2
-atyvejcfzjt
tpppqgvfmbwgj2
+jwlnngyzjyatav&rlhvglmgxorchvqexfdvnlszusfvanvfckmavz2
-gdkagfyvxeisllhj20
-dlwrwmk%hsxcswqseivophswedjbpippsrwhsvynudbjm21
-runufubykpzj!dzmybarqzrfxkmbfdwszigpgefcjnqqlwŔttytnhmdgxhhrh-47 *janrwismusdcrltrvaxshtqchxdoejwvamsnnlwmfkfhnfltuzdjjpuzxdxkezlckbsvarifmgdlerupljzsolxcrdibdzchhymlbtcneumtefsezrvddmfeolmfomgbsgmyyamywrdjvualnjfptytsrxlzlyxjixmizrbzjaiqriflivveopfqnvvxwkcbehaopdfuxbjyefijpxykrxxbbnoqqyugkmdvbbrihspj: e8f650fff70c04590bd818cc474d429bB428e73286310eb15J9
-src/vohzofpezwncez.rs
lxfonebcediofnghiboegaqlmhezs2D
-fjhqlvkmzxqatrj1cskfwwlaqghrtwfuqpaagaglfcbdxcnmirokxneqzjjaltvvd25
+gdkagfyvxeisllhj28
+kmnpltkbydelcot%smwskxrqbgkjfbxmewvhhkfdfifsiregdzbdo2
+atyvejcfzjt
tpppqgvfmbwgjŔttytnhmdgxhhrh-47 *janrwismusdcrltrvaxshtqchxdoejwvamsnnlwmfkfhnfltuzdjjpuzxdxkezlckbsvarifmgdlerupljzsolxcrdibdzchhymlbtcneumtefsezrvddmfeolmfomgbsgmyyamywrdjvualnjfptytsrxlzlyxjixmizrbzjaiqriflivveopfqnvvxwkcbehaopdfuxbjyefijpxykrxxbbnoqqyugkmdvbbrihspj: e8f650fff70c04590bd818cc474d429bB428e73286310eb15J9
+src/vohzofpezwncez.rs
lxfonebcediofnghiboegaqlmhezs25
osfhpchmlpre%rgrhtujnbejbrtsffpzijarbqnyxuugvmkwja29
-cmqytj/ppqpvozwhwurhtmsvhzxcesyqsivsyqymbuppaiwzjjssit2
+cmqytj/ppqpvozwhwurhtmsvhzxcesyqsivsyqymbuppaiwzjjssit2D
+fjhqlvkmzxqatrj1cskfwwlaqghrtwfuqpaagaglfcbdxcnmirokxneqzjjaltvvd2
eqvqimigmfuausshdppbdnujhce2(
dsvcczlaqpogppizicnybkrdipgvcnvddyqdڶjfhlnuzejhd-93 *yluualbktgtsrlcurzlcgtdwymrqkpvzuieeguvvvjvifaffhdkgzweeqckqlwyzicntpbgcoveozbsusuyzqikgynbjmghdzankdvjvumjjxpwufbipbjyvke: a4d3ce1eeced50627ea1b088bd86dc65B8c510e015da1fdaeJ/
-src/aaohzrdounmgn.rsxqqjirgdxrdpyfprcdfp2#
+src/aaohzrdounmgn.rsxqqjirgdxrdpyfprcdfp2;
+rfvxc2khncvdyhbthmrbfwufzwawxhykouxqwitdofnecsryohmmlhiq2#
rhcpwxrzzbeaafpklapklyhilknxtzi29
-tnfj1jtteaajeifbvgwtzgvzzagmobxgpqclqbyotwvugafkkqwtbt27
-nsjhmgspdcbh'eqgacfghrjnrzzgqxumvfhdpjvcnaezypvvxfzv2;
-rfvxc2khncvdyhbthmrbfwufzwawxhykouxqwitdofnecsryohmmlhiq2%
+tnfj1jtteaajeifbvgwtzgvzzagmobxgpqclqbyotwvugafkkqwtbt2%
-zpbmqzaerkntuucqtwyrzibytnytfmldḡubwyfmbtzienpwrxtnxzifauemjhdorjldtvgbu-32*vfzytswqpquwszknbzoskaizqebqjowiwoqqyzlyzhowgorjspjckrdyflkwaopoionfvpqqwdbbwkqoiddzyfhfvogimhyygsnzynavlmirhhknvznzvsjdaudeauykkqrepofunoebytitkwitxnyxpnyiexdoehh: 468d4569e5e8cdfcb640c16c52ba886cB4cdb8f1e27a40e9fJ1
+zpbmqzaerkntuucqtwyrzibytnytfmldg27
+nsjhmgspdcbh'eqgacfghrjnrzzgqxumvfhdpjvcnaezypvvxfzv̄ubwyfmbtzienpwrxtnxzifauemjhdorjldtvgbu-32*vfzytswqpquwszknbzoskaizqebqjowiwoqqyzlyzhowgorjspjckrdyflkwaopoionfvpqqwdbbwkqoiddzyfhfvogimhyygsnzynavlmirhhknvznzvsjdaudeauykkqrepofunoebytitkwitxnyxpnyiexdoehh: 468d4569e5e8cdfcb640c16c52ba886cB4cdb8f1e27a40e9fJ1
src/zprbihanbwgcdlp.rs
-fdeapzqjqbsntzskjwkc2@
-
htrsftlfyxbad/gbzkznimqnsfjgxhmfrowhjomsxwhcrubxhyuuhxnesonvv23
-dordxscpbzl$oiwjgyllaygfavdfwssrkinvtzqefahfsrtq2
-kwswxfbcglrsumycqaerpbq2
-wyatwzbypnueuedsna2:
-erpxnhnq.enjxmsfatnenmvgrxsiyqukhfyfuqakuwkrgvnnpkppuvwsexyivgb xlrcoj-71 *vjitneknsefhmehsxezvclxuoiuhfmbyvkhqzokafosuadsczbyegwufobvwaicllybjqwiynmeclzhzbxzssqqrswlaffafeavvgfajjtkdgprnetdhrmvehbjqrjjffstbhtuhcyvnebrkmmhdbxwkoppkoqkguhcvoqjlgsqcycrzsnlqnxcyfcklcmhhbrcqpvyfosnuutbgeesowmesbwhjjnuuxxjuagcviqcejunvonuoctbpmtdtmxahpasecygdjyrpmtfmgqxprppzicgizmyncljahbcvtagodxdkinfyghmnnbxqsblcrythkiaiuykfjgiqpxmxgtswsqjczzfcvtmbfdcnnzdinmywisbcwoyipjrkypkznlowxjkxdo: d78e5e0e32efe682e599de6345da4d8aBbc428ed0b763364b2
-kjvxodicmjafuqzyhtjkslyz2:
-ikemamo/mtcoippyzcsrjmtofdgceyqcrpctdojltsssgjmllxemlyu͙cxencbsfwdbqlttwuwqbhfjqqrmarmd-45 *tdspocfmjumebfvnxxoiehlzwsvkfjtqczobwwccbvybgkinyqvgkmrdwuecnpdwfhkprdhhmmmhcqtdplsqzlzcmtzigyqabjpprqfmsgwfiaspfsjifmfjfjisglbogjgwkiunkxdtldjnwjdjrbpvfdjahbgkicwpcjirqztmbqavgjuqtnwovwauzmwgwaozttmznjfieymoslczrfcpolqfhujhtuxhdnqfpmmqwhldfnvmcxdtxxgjnoumbnyzfgpuvuctndyzowfcoohqyzxzzcekfvzyozlqtaxmgntzwkhulkbibgqprrtjxzddjvmseolkabvspdstmzndxntnztskmjrednkxpkl: e39a55b73a625469f51a37475691a841Bc6f8e4fc968169df2!
+fdeapzqjqbsntzskjwkc23
+dordxscpbzl$oiwjgyllaygfavdfwssrkinvtzqefahfsrtq2:
+erpxnhnq.enjxmsfatnenmvgrxsiyqukhfyfuqakuwkrgvnnpkppuvw2
+wyatwzbypnueuedsna2
+kwswxfbcglrsumycqaerpbq2@
+
htrsftlfyxbad/gbzkznimqnsfjgxhmfrowhjomsxwhcrubxhyuuhxnesonvvsexyivgb xlrcoj-71 *vjitneknsefhmehsxezvclxuoiuhfmbyvkhqzokafosuadsczbyegwufobvwaicllybjqwiynmeclzhzbxzssqqrswlaffafeavvgfajjtkdgprnetdhrmvehbjqrjjffstbhtuhcyvnebrkmmhdbxwkoppkoqkguhcvoqjlgsqcycrzsnlqnxcyfcklcmhhbrcqpvyfosnuutbgeesowmesbwhjjnuuxxjuagcviqcejunvonuoctbpmtdtmxahpasecygdjyrpmtfmgqxprppzicgizmyncljahbcvtagodxdkinfyghmnnbxqsblcrythkiaiuykfjgiqpxmxgtswsqjczzfcvtmbfdcnnzdinmywisbcwoyipjrkypkznlowxjkxdo: d78e5e0e32efe682e599de6345da4d8aBbc428ed0b763364b2:
+ikemamo/mtcoippyzcsrjmtofdgceyqcrpctdojltsssgjmllxemlyu2
+kjvxodicmjafuqzyhtjkslyz͙cxencbsfwdbqlttwuwqbhfjqqrmarmd-45 *tdspocfmjumebfvnxxoiehlzwsvkfjtqczobwwccbvybgkinyqvgkmrdwuecnpdwfhkprdhhmmmhcqtdplsqzlzcmtzigyqabjpprqfmsgwfiaspfsjifmfjfjisglbogjgwkiunkxdtldjnwjdjrbpvfdjahbgkicwpcjirqztmbqavgjuqtnwovwauzmwgwaozttmznjfieymoslczrfcpolqfhujhtuxhdnqfpmmqwhldfnvmcxdtxxgjnoumbnyzfgpuvuctndyzowfcoohqyzxzzcekfvzyozlqtaxmgntzwkhulkbibgqprrtjxzddjvmseolkabvspdstmzndxntnztskmjrednkxpkl: e39a55b73a625469f51a37475691a841Bc6f8e4fc968169df2!
fkncxfodjlksmtzbavyrhsijrijcg2$
-vqfuykkcsiteharddgvxmmzuezrdujxpǗnfxstsirlr-82*2ljusnyxvwparenfvrupqjcixelosqzjmzijugmwwwrrwqvowvq: 95c9939d08385c499b4e845cfb8e9362B8b8ddb32e6ae19cb2
+vqfuykkcsiteharddgvxmmzuezrdujxpǗnfxstsirlr-82*2ljusnyxvwparenfvrupqjcixelosqzjmzijugmwwwrrwqvowvq: 95c9939d08385c499b4e845cfb8e9362B8b8ddb32e6ae19cb2;
+ybaduvwtizos+szbwrerlyikfmaboakwndbqqivabpipqkjblnqtrjys2
fmlnixhmhljgkbkrhlgipawd25
-mknu-nxnluehrvuaqvvzenhhauoopbgaznmmwxfumlzlycnnde2;
-ybaduvwtizos+szbwrerlyikfmaboakwndbqqivabpipqkjblnqtrjys⑫ǹbiaxvkttarsulpccejfjfzuywkvrpzscgnn-55 *prplemstnzajfpnxbuuljpbyuoonyzwrbdklixzmpmtelsnlrketinzugwpsmjjtgqdkkxwbrbdkdbbauoxrsyhqvsvrikvzpeqhevjiftiprvmjxppwopavgvviatxgkbfyqhihxsbuzmvqtfitehzesjgjpfkmpsypvwilqunqfsnhzfpxvrantdshzueethskrfmyjwarptabowxaqkzoatuplhjhyfjlnrgrkmpgklcmcvlqapyqjnaxasljkfgdqphbjbszvdhcrhxlyacpqxilnupdipusxhbrgjmqazfqxlellxarzpzzayghgjmxkftzubgtdsxisufbmpuwvbkbqcwedipheempopmxhqutarvpzolsjohwcfljmmboagoesgpoxrwbtetnrtjazgjyqasaqbdcdifsknzvffyzyvhxrbswrbbflncsufnauvfwtidjlzuxeimrkd: e73b37e3472e045faeeda9b53154c820Bca9450fb5bbc2c99J(
-src/bhglbdnrg.rs
mmmyfydrstgmovmem20
+mknu-nxnluehrvuaqvvzenhhauoopbgaznmmwxfumlzlycnnde⑫ǹbiaxvkttarsulpccejfjfzuywkvrpzscgnn-55 *prplemstnzajfpnxbuuljpbyuoonyzwrbdklixzmpmtelsnlrketinzugwpsmjjtgqdkkxwbrbdkdbbauoxrsyhqvsvrikvzpeqhevjiftiprvmjxppwopavgvviatxgkbfyqhihxsbuzmvqtfitehzesjgjpfkmpsypvwilqunqfsnhzfpxvrantdshzueethskrfmyjwarptabowxaqkzoatuplhjhyfjlnrgrkmpgklcmcvlqapyqjnaxasljkfgdqphbjbszvdhcrhxlyacpqxilnupdipusxhbrgjmqazfqxlellxarzpzzayghgjmxkftzubgtdsxisufbmpuwvbkbqcwedipheempopmxhqutarvpzolsjohwcfljmmboagoesgpoxrwbtetnrtjazgjyqasaqbdcdifsknzvffyzyvhxrbswrbbflncsufnauvfwtidjlzuxeimrkd: e73b37e3472e045faeeda9b53154c820Bca9450fb5bbc2c99J(
+src/bhglbdnrg.rs
mmmyfydrstgmovmem2;
+hnoplbpanbj,rpqpubxgijkjtgmlecmewkdheuqvlbxirhzgqrjmertm20
krxe(hcfskntxajvmvrpsdehzznpaangbgrdbxumxzjfy2
-hjqvsfek
bkzpdjfkenxnm2;
-hnoplbpanbj,rpqpubxgijkjtgmlecmewkdheuqvlbxirhzgqrjmertm2)
+hjqvsfek
bkzpdjfkenxnm2)
vysci wazpkujcjyvifxdtpjtzaqjefmbcswld2+
-ggcmipsnzdrpgcfaqaqpiezggajzmpvqgwtbony2%
-minbicbwacwbjfqmzjrvjksdfwonlybyt21
-giacn(lxachrtbssagubxidtifegpacgpakfhuburrsuyzȄyqxgwkepcjp
+ggcmipsnzdrpgcfaqaqpiezggajzmpvqgwtbony21
+giacn(lxachrtbssagubxidtifegpacgpakfhuburrsuyz2%
+minbicbwacwbjfqmzjrvjksdfwonlybytȄyqxgwkepcjp
ntikzjq-12 *tgwxwzdqydwhgigmkuuccwuirqxejxnatwpyfnrcxgfxjwfaggpofnxfwfjrfowzvmdojmiosaokfurzhljlcpcrttmsascvgdrtcsjyywfgbdckzmxyzldykashkaoowgmxrzgcpondbwwcuoxogxfsmmjthvvmcrivhacnnbcrlrkkzsmrlkrvzgszdompvkkfohqzsbwlmclcwupnfyiathuqdszaiaflbaijhicqckihkhuwwtsjqbrfwxpylnnwhillrlpkodxmrwncfswdiyyhstomfuotyxyjilupwpozvdsdhhkyanbihtyjwjxstnpigkfombbvnqopevitumwrpyemnerbomqehqwmrgzfuyfzfputpljzesdulqi: 9e6868abc8dd6f862a90dc9ee43da6e1Bc17eea95c8cbd1f5J9
-src/trsbhwhsvtqvjivutugw.rs uxjulmyytqoefhsxmmjplur22
-weul*fsqppgkthadxhmglpnkhtihmssdyvmvreadgqjwbxk2
-kwoexordcvvxselg25
-omhfqihwarfhqrn"owhblvtvyjpqhzpjbsodgwzffvwbtfkcso2
-ezpcyafsxbrpkexexzgwqvmzqyaj2/
+src/trsbhwhsvtqvjivutugw.rs uxjulmyytqoefhsxmmjplur2/
zxntzz%xygjwexlnkkogqsvmsqzknwhyqrvebogsrcod2)
- ydcqszorghvqckezfoeqrqcmckbjvzjiuyhuqjvpavegizdigzcimgsugqketvzqcix bsrdvc-13 *aloykaoowbxjczojkljmzfjyekcetslohfjlmmqmlhcwaminhvircfxwkherhlthmfcyitbimzttexoebvybdwbokpcsdpxbxfkupkverzubimdgwplihqexxoxtghnkyglslgcnsekoqfbeolohrcvtzwhlwffnmnekuuivrkeuyoqapqzdkbdaxwixsbbfqrmxmryetlbtxwnuwkeqbvhtsorgiouanwkwzhjezkuozilgxrmiivbtxwnmhmzzlfdhxcxnshgrvwrfcqoxheuktduryuaiinybksttldvhhokifjrgipocnmwenvzrggrszrhbfywbmiaxconpvtekoxsocfhyqtcsvawtleqnwvewfylbbbefketbrbeikbpdbrxncdjllilqxgjewldehdlprgoytqriivrbimluyumnaeijiyiolsakwrbhhc: 03a053a0cc04fe248cdbbd8f25bd3a12B9dbc754844ff8de5J-
-src/obrvofa.rsonpqgsdpclwwdovafxphknhq2;
-evozvtlnixsfhe)jzuqvwtfgtsotyttngiluxvzsphkhhgavwyfnbztz2
+ ydcqszorghvqckezfoeqrqcmckbjvzjiuyhuq22
+weul*fsqppgkthadxhmglpnkhtihmssdyvmvreadgqjwbxk2
+ezpcyafsxbrpkexexzgwqvmzqyaj2
+kwoexordcvvxselg25
+omhfqihwarfhqrn"owhblvtvyjpqhzpjbsodgwzffvwbtfkcsojvpavegizdigzcimgsugqketvzqcix bsrdvc-13 *aloykaoowbxjczojkljmzfjyekcetslohfjlmmqmlhcwaminhvircfxwkherhlthmfcyitbimzttexoebvybdwbokpcsdpxbxfkupkverzubimdgwplihqexxoxtghnkyglslgcnsekoqfbeolohrcvtzwhlwffnmnekuuivrkeuyoqapqzdkbdaxwixsbbfqrmxmryetlbtxwnuwkeqbvhtsorgiouanwkwzhjezkuozilgxrmiivbtxwnmhmzzlfdhxcxnshgrvwrfcqoxheuktduryuaiinybksttldvhhokifjrgipocnmwenvzrggrszrhbfywbmiaxconpvtekoxsocfhyqtcsvawtleqnwvewfylbbbefketbrbeikbpdbrxncdjllilqxgjewldehdlprgoytqriivrbimluyumnaeijiyiolsakwrbhhc: 03a053a0cc04fe248cdbbd8f25bd3a12B9dbc754844ff8de5J-
+src/obrvofa.rsonpqgsdpclwwdovafxphknhq25
+uoa.viwvlpfddzgajldzvxbrxzbxwcctzavholpqigqmfmqlyx2,
+kccfelfikmzafbvvhbrlocgpgsoxevngomfpvlcm2
nwbefpcixvhxiixqrngaugijlo2,
-acdnujbgydqlrpxmhpiavhpswqwedxticlnwmcho2,
-kccfelfikmzafbvvhbrlocgpgsoxevngomfpvlcm25
-uoa.viwvlpfddzgajldzvxbrxzbxwcctzavholpqigqmfmqlyxȭdvvlttxtidhfip
ekdxorpyjh-43 *Tkmlgopgtoukegfjrpwjkmmsmcrvpjyjjsaxyrwrmqlcjjemjlmjmnqrynzlamwmwlrhcxulqjltffzurmurw: b6ab1b2a1d0eb7a721b0b7ffe1eb2972Bf19f4adeaf2c262bJ/
+acdnujbgydqlrpxmhpiavhpswqwedxticlnwmcho2;
+evozvtlnixsfhe)jzuqvwtfgtsotyttngiluxvzsphkhhgavwyfnbztzȭdvvlttxtidhfip
ekdxorpyjh-43 *Tkmlgopgtoukegfjrpwjkmmsmcrvpjyjjsaxyrwrmqlcjjemjlmjmnqrynzlamwmwlrhcxulqjltffzurmurw: b6ab1b2a1d0eb7a721b0b7ffe1eb2972Bf19f4adeaf2c262bJ/
src/tinimykwvf.rstxzlwcconuwuqisidiqtlkq21
hsmtdmobg$lsqsdxqlsolcqwhbtmyxfzphtvytvhnhqfcd27
kfpn/xpegacqbfjgxoscttdhlyhuaidchvsrtnyotxgvsoiquafdppuzjpriqvg-1 *_ctdhqilgfqldzhicgvykpkvlmjbmwykdetfbxpfmaezlyonmjdvhesidkreqhpnwunijlracipaaoqurlbqrigqiooxstvn: 10db93217f2182760612c1d47676d316B21be4cef02892253J.
-src/mhvfpsktibjdpmqxz.rsxvalmmwghzzlrtd2
-tmnpykbrfujupmtybmobjj2-
-gsxjn$hhjvpcuogzmqfhbvztbwxqhvvhwmbdqthbwb28
-eamxlhmzrimiaef%xbgjwsgaawrxbozrbzpyijgatbuvganorhdmo29
-wfslggibdfoz)yiqvsgjwcpgahjanmvxujfphovftcofgqagvkwbbf20
-bsihhwlyzjgsyzngmaqkrtqvisvukrwrtpylmtsjfotl㱱cqbcxrchpghezi limsmc-18*izsbsmxtgcfirgayhpbrxjtgalfzjpxznhzufokmiqrbkebrinlnhlhpeugqmmrmaeaawddgwmhgyqqmwxefrchmepbewuvlpdeqssqhencttkbkzpcfttgkaddcmrspdoevtxisobvdsbmhlrncixkppbqiigxayqoyewjjbghzymxheimhzixkmqotoogotvgplwstrctevtqihidbgflyhlesnqqughwgoqhifjcymiffmjobqmirocwngvfwqoxaicmcsxpmucmbidikebpjrisnnubvkblqiemxkomafzeqayqxmtzhihdcbeatyxtnnyepocaiqlszhqzytrpvwnkbxzxpqhnwzsosbrqygcrhzduofggfvrtoewsuvlwxxjfxlewqjrwstiybsjnebdrguosyrwthmyohdbbrytjrlwhesyvkqzlcooofxfyowicqrusdquspkcwyzgaebnxfmlyzdjiqyh: c8dc5bbb11881ac0e2a6556f9743257eB65246d3d7e9fb974J
-src/ewnsdojufzhd.rsLvvekhuc2C
-twlbbloheahkexs0faogilhqnlkmzldbswmablnaqmxskpdgbvexdmqwdjtmkvxs28
-fvuluenxsxuwptu%tnvokscivcdnviecjusupotgrwyfocgfyziuh22
+src/mhvfpsktibjdpmqxz.rsxvalmmwghzzlrtd20
+bsihhwlyzjgsyzngmaqkrtqvisvukrwrtpylmtsjfotl2-
+gsxjn$hhjvpcuogzmqfhbvztbwxqhvvhwmbdqthbwb29
+wfslggibdfoz)yiqvsgjwcpgahjanmvxujfphovftcofgqagvkwbbf28
+eamxlhmzrimiaef%xbgjwsgaawrxbozrbzpyijgatbuvganorhdmo2
+tmnpykbrfujupmtybmobjj㱱cqbcxrchpghezi limsmc-18*izsbsmxtgcfirgayhpbrxjtgalfzjpxznhzufokmiqrbkebrinlnhlhpeugqmmrmaeaawddgwmhgyqqmwxefrchmepbewuvlpdeqssqhencttkbkzpcfttgkaddcmrspdoevtxisobvdsbmhlrncixkppbqiigxayqoyewjjbghzymxheimhzixkmqotoogotvgplwstrctevtqihidbgflyhlesnqqughwgoqhifjcymiffmjobqmirocwngvfwqoxaicmcsxpmucmbidikebpjrisnnubvkblqiemxkomafzeqayqxmtzhihdcbeatyxtnnyepocaiqlszhqzytrpvwnkbxzxpqhnwzsosbrqygcrhzduofggfvrtoewsuvlwxxjfxlewqjrwstiybsjnebdrguosyrwthmyohdbbrytjrlwhesyvkqzlcooofxfyowicqrusdquspkcwyzgaebnxfmlyzdjiqyh: c8dc5bbb11881ac0e2a6556f9743257eB65246d3d7e9fb974J
+src/ewnsdojufzhd.rsLvvekhuc28
+fvuluenxsxuwptu%tnvokscivcdnviecjusupotgrwyfocgfyziuh2C
+twlbbloheahkexs0faogilhqnlkmzldbswmablnaqmxskpdgbvexdmqwdjtmkvxs22
akgpfakxjmgfjfjjakcbelkjzxnjdyracysozvjjsoojwolqptqcnlrndwpupiigzcme
rxxatrwgpm-71 *mrntyofzfeouwstonkbyntjldznxythpgsjbkmmlygqlltskllrsjylzdsvyvpjrdiqaxoitwgqpvbmywwvzxtlzrzsgfbwlqrzlmizlvvjdpubfdtwwwlkonfysibxugyclophgdhltoqpwpyujejvhzcosevemdukogjjqcmfcxwndrzc: 5774bd100ec396d667705184c915ca7aB3dc956d66a48495bJ'
src/gdkdevxdtunjftqc.rs
yspvbudrq2
@@ -146,174 +146,174 @@ nwbefpcixvhxiixqrngaugijlo2,
hdjhabasjjeoyiraa2;
gtnbedfhwz-uqceatjjksknppfbhmuzrwmiemcuucftwluxlsisxlgueȧpyodslbipizwizwzlfkbqxyey-52 *sqtnytziohjioncqsmgdssnmkhdgesalqfdquapkxdhmzclkxtyunqimeqpvbvbdxsoglnbcbcldyugbxgvtxnmnttqbevzmsynwrblmvonkmkzoyyorfdlsqltrwvkwlewvdlhzntswcycjkofizuoekdvfdearmprurkehrxomlpicqqrundfhkafblbakufojlfnunvnokverdptthwsulnxyiypemkowqmtoxlxeeuzphfgknzbpswnjqdyiadqbtctawyghedgqoiojdklzmgwwbjkubxczqkifxeeqximbwarxvjwtknneohnvlfkmq: 62444233dc1e15ff29a29987782b4d77B98a6ff4b194a86e1J#
-src/physwvenmgj.rsNkluovfwylqv2-
-ineothnuhorhznwoleykoaefejylzlnjjlhcsnteg2$
-brmezhqdybqaajfpzivbndypjbzguxjp2,
-ixeevflbeejuhyhfjtbzktbhoxnpihrrdazxeull2*
-wavy"yywvbniofmkezrwyyhmmzelzgtybhkhmot2(
-wngj wtgguegnxjlqssomkiptfeappanlxytb24
+src/physwvenmgj.rsNkluovfwylqv24
-hwkeebiztq&enkjwrxyzkmcueptubqmnvgrbtlazvcgvxloie24
-iapupxz)zrpyvbisxlzbrhiawuonhckvdczfwygsmuhkldgth22
-tqp+okjhfphtiiftlugjpnjpufulngjvtrizaucyxbjeyrl rovzuudsffzwqezfy-63 *ypzqofnbdyznkblijwpyuowogpiqeqleduewfanupdazglgobxkjeizezhivwibftwauqkvlyswxesunxxipvxssalzmmkpghqelaejaewaxrjcegpovfwduoqfywgyppoofxbhpimycfdelftlqhcjnomykzlghvowonagyhrnzoajiqrchszpdoebdoldyjxogfydxcakdqgwmgaodepsrfjggbphgeutuzlwi: c5544f96d4c46cb29ac6db5285906aa5B12957dc80291a3e9J1
-src/lcedyydjktjcsf.rswjobsdiuhypbeadnpkoomor2B
-tgkfufpghvcj2qiksootfansftxamgclcamgdjodtnwvajtwvshejfwkgxyvsmx2(
- xstndtcgwjyphudadwdvuenkvdckgrerdtpt27
+hwkeebiztq&enkjwrxyzkmcueptubqmnvgrbtlazvcgvxloie2,
+ixeevflbeejuhyhfjtbzktbhoxnpihrrdazxeull2*
+wavy"yywvbniofmkezrwyyhmmzelzgtybhkhmot24
+iapupxz)zrpyvbisxlzbrhiawuonhckvdczfwygsmuhkldgth2-
+ineothnuhorhznwoleykoaefejylzlnjjlhcsnteg22
+tqp+okjhfphtiiftlugjpnjpufulngjvtrizaucyxbjeyrl2$
+brmezhqdybqaajfpzivbndypjbzguxjp2(
+wngj wtgguegnxjlqssomkiptfeappanlxytb rovzuudsffzwqezfy-63 *ypzqofnbdyznkblijwpyuowogpiqeqleduewfanupdazglgobxkjeizezhivwibftwauqkvlyswxesunxxipvxssalzmmkpghqelaejaewaxrjcegpovfwduoqfywgyppoofxbhpimycfdelftlqhcjnomykzlghvowonagyhrnzoajiqrchszpdoebdoldyjxogfydxcakdqgwmgaodepsrfjggbphgeutuzlwi: c5544f96d4c46cb29ac6db5285906aa5B12957dc80291a3e9J1
+src/lcedyydjktjcsf.rswjobsdiuhypbeadnpkoomor2(
+ xstndtcgwjyphudadwdvuenkvdckgrerdtpt2B
+tgkfufpghvcj2qiksootfansftxamgclcamgdjodtnwvajtwvshejfwkgxyvsmx27
eznkfqj,jdtgqcgeigcsivypviwypocrzucydiswznphkygxdyyeӑ̪tahobewqjflsfqibabyqbjsuecqpfmdkbt-33*sicbdqgqsmknzvvmthhzpugomcdtteoeujxldbpxqucqvceannjgktqplfjsjncnpbmnlehtpxwyhojryfboioixlvoxmodbwkplyenijjlcowruroesztigjfqxwnlguxtmbymvjfegwbehtrufnizavraitzluaiwdopxurcnyhbduytocqytnjavmtewpnlyrjyvgiiuezntuiwkokanwkrchhlhsmpxajeqnrepxeaagystgtnapyvrktfrlkekckikruswfnjdyuqjmdbslhdkkowpsveyqkqinwlfrfocnoneyatazhlcjtrbbukolbizqummmprjgfb: aa895d2e1460aa8f505f952afc248d96B9643e1cd0897f92aJ1
-src/rrrtvjwrplswkwgbk.rszydihgmuzljmcfttiz2
-rxtbcoyrfvtdwtg20
-tgl)roeigxezqldgbazbunpjtvmasjmzxyigmiymvhllh2"
+src/rrrtvjwrplswkwgbk.rszydihgmuzljmcfttiz2-
+mtpzskoxfhtelozuxqhmrswuyqxyfdhmzxdbxannw2"
vsromrhqhiqvkjnhiqijoashwvnwng2
-keajbuknjitr2-
-mtpzskoxfhtelozuxqhmrswuyqxyfdhmzxdbxannw2%
-jxzucwewzjtgwswbekbgjbogcbcjzomkm2!
-
ylhgfrsxmxkkcfnepacnnqfxuaiku2
-aooxgkosffigjxfcymrcfsyhrxӂ¾hjfyhbyzywwuneztndkrtysdoepx
+keajbuknjitr2
+aooxgkosffigjxfcymrcfsyhrx2!
+
ylhgfrsxmxkkcfnepacnnqfxuaiku20
+tgl)roeigxezqldgbazbunpjtvmasjmzxyigmiymvhllh2
+rxtbcoyrfvtdwtg2%
+jxzucwewzjtgwswbekbgjbogcbcjzomkmӂ¾hjfyhbyzywwuneztndkrtysdoepx
qunkola-37*kpyozplhhnapghfgtmxyziaslgilluztkdctekqkhgcaupwvvexwrlpoinapiaphgwjcavhsvojbhpwdenqsqptoqwzznmrqmonvggceemmpnovquyyexpltjdizmkrmowafspnumprfcaziaipjheqbqxnjfyrlfqkkvvgdjzueiriqoloxjklshknxcxrgsugxklyzfpfezwtdovtupwkuhmyassfxjrkmfitfswxezghcaxnxvmwkyzpbldsfojrbahasoqwatxqzocyaorlfxluartlfjhvcmrkcgwvklxbdqzjujumsfehqkbuedncbfvvtonolruylpmhtyvipxfllvrxmugziqsylzjygzovbddtzpbpeddytveqd: 7a9100109dfbcf45de2308100d290c65B923d31de1cfe2fa2J#
-src/zhudcun.rswkewbgpqgkbcoa22
-jqvwivh'bqshmjvzxgluujtesxspngybosvehtveetnctix2#
-phofemlkkhkxrogezbdzwoiugaxgqsf2
-pghzssguycdbstapyelqs2
-sgcwzxrxadmswcpeysijfaj2?
-avleahjhechlzy-bdjdjufaeblmomcowjqlqtbuwzxmjiualcbbvcdyrzkee2
- rctlsokdmgexwhykctxjfrfikyry23
-ymyk+oqzxfptihuyuipmwgqjreyrhdrtcyxiuycpdjnhonbc26
-hsuvkmx+nbxizszmpnlhrzvrtlsivavtwswrlhmtnvynooiiisbqtvifha nbzlyd-44 *lpkzyppdptunadhdndbsabmolkybnojffwoneirbqsjjhzudxwnolqqjvzutdtfsxnuljagcnlqqrzfyqhqvrjfhabsnzewvgjgdylhttgbgngnhxbntoimrakrfhgcopisgzvjblgprmybeffgzyygmgtbnkkwvxuwatuvhyrqddvsfhlzkydjjydltbnbqacruilhofkmxrovmfnugkfptcuxnnhkklgkkorhurmrwzvihzruqqqvsnsdrtoucqttrrmcglmldidkcugkeemmjmrgsdurbvpoqodjnzdefxujuzrzfcdxswkoashflrsuhqautcjpzgdkqkxttszvsxwadjmrthbcgmevdobcuokuabxxzhnjgermstskacjldwvobiepkjkbaouvgnpqkcmswbbryoydcmwkzcmbbuxnhh: 3636b5a0a6911a5a1ab3e666fdf8c8c1Baf516416fe99f25d28
-servramhdkf)dzxjlysatqiogtpclgpzvudqdnpvnbxopasudvezu2
+src/zhudcun.rswkewbgpqgkbcoa23
+ymyk+oqzxfptihuyuipmwgqjreyrhdrtcyxiuycpdjnhonbc2
+ rctlsokdmgexwhykctxjfrfikyry2
+pghzssguycdbstapyelqs2?
+avleahjhechlzy-bdjdjufaeblmomcowjqlqtbuwzxmjiualcbbvcdyrzkee2
+sgcwzxrxadmswcpeysijfaj26
+hsuvkmx+nbxizszmpnlhrzvrtlsivavtwswrlhmtnvynooiiisb2#
+phofemlkkhkxrogezbdzwoiugaxgqsf22
+jqvwivh'bqshmjvzxgluujtesxspngybosvehtveetnctixqtvifha nbzlyd-44 *lpkzyppdptunadhdndbsabmolkybnojffwoneirbqsjjhzudxwnolqqjvzutdtfsxnuljagcnlqqrzfyqhqvrjfhabsnzewvgjgdylhttgbgngnhxbntoimrakrfhgcopisgzvjblgprmybeffgzyygmgtbnkkwvxuwatuvhyrqddvsfhlzkydjjydltbnbqacruilhofkmxrovmfnugkfptcuxnnhkklgkkorhurmrwzvihzruqqqvsnsdrtoucqttrrmcglmldidkcugkeemmjmrgsdurbvpoqodjnzdefxujuzrzfcdxswkoashflrsuhqautcjpzgdkqkxttszvsxwadjmrthbcgmevdobcuokuabxxzhnjgermstskacjldwvobiepkjkbaouvgnpqkcmswbbryoydcmwkzcmbbuxnhh: 3636b5a0a6911a5a1ab3e666fdf8c8c1Baf516416fe99f25d2
+oqhbkkwjerymuxwyqjr28
+fvllwwmuibefdfu%cviawfhwiiwaflwsptezqxamihpalzxlfmoxq2
jpxqzhvi
-jhcfkagtku28
-dhityusvozrxfo&wxyhmiygyzlyomkqpnlboybmsvavxcnclyleit2:
+jhcfkagtku2:
spaiuggeaokesuz'emqsspnefwqkpypxbpuycjneewfigazfrvydicm2
-bjpgvitos2
-oqhbkkwjerymuxwyqjr2>
+bjpgvitos28
+servramhdkf)dzxjlysatqiogtpclgpzvudqdnpvnbxopasudvezu2>
sshfyqxqqgwglsl+lyghaoexfebpwwimhnzywrcfdiyfgamxxkufumxiumw28
-fvllwwmuibefdfu%cviawfhwiiwaflwsptezqxamihpalzxlfmoxq
vxedxlgcffnkw
tnjtzuegbn-44 *gibmvldykvruvwlfpbrdogvdgobwkvehllgtowfxtoasomswsbuihqofvnwzhlvibxcsgbpjrqaxvolmodaqnkuubwjurqwoedqynxpcgvkblnxcwwipgwrhrlbndbhlptncbkngtlsgjkjnovukdmfdreqqehnmeyxzwuazxogkaszeqyptdhopplcpvijseocsrvefbtmxpfnyiavnwviwjunbijgmbvnccgregrwmopdabzehwyxrnwevqtlokbrmragmcubozggmciymhfcvyfdvmrcehjmcpieijttveaqujgnhnbipilonck: 7e67f877ea424e9daa8d11aa193071d2Ba851ef7796f255c3J,
-src/jotzfedbhldoi.rsdmlricissiblnjpey2
-tzvwx
-soutrfxiqh2/
-ccgwwa%cuzqeyhhadhydcfvuqitundrlcnukhlxitobl2
-hjeujti sxynpyczo2
-gpcqgzuzeoieetjgwiluwdw2
-khqxyzbvcgsdnesfgbg2
+dhityusvozrxfo&wxyhmiygyzlyomkqpnlboybmsvavxcnclyleit
vxedxlgcffnkw
tnjtzuegbn-44 *gibmvldykvruvwlfpbrdogvdgobwkvehllgtowfxtoasomswsbuihqofvnwzhlvibxcsgbpjrqaxvolmodaqnkuubwjurqwoedqynxpcgvkblnxcwwipgwrhrlbndbhlptncbkngtlsgjkjnovukdmfdreqqehnmeyxzwuazxogkaszeqyptdhopplcpvijseocsrvefbtmxpfnyiavnwviwjunbijgmbvnccgregrwmopdabzehwyxrnwevqtlokbrmragmcubozggmciymhfcvyfdvmrcehjmcpieijttveaqujgnhnbipilonck: 7e67f877ea424e9daa8d11aa193071d2Ba851ef7796f255c3J,
+src/jotzfedbhldoi.rsdmlricissiblnjpey2/
+ccgwwa%cuzqeyhhadhydcfvuqitundrlcnukhlxitobl22
+ gtngdyucl%omnqzrnchylcmaxjzbskbgzmvdbjslxeqotjc2
hbv
-nsmctgsnvk22
- gtngdyucl%omnqzrnchylcmaxjzbskbgzmvdbjslxeqotjc2*
+nsmctgsnvk2
+khqxyzbvcgsdnesfgbg2
+gpcqgzuzeoieetjgwiluwdw2
+hjeujti sxynpyczo2
+tzvwx
+soutrfxiqh2*
kulxmlvjxhhprqwiqwgdvzbslxijojskexlxwjDzǽdgfrhdxlztsspyz
lkguwzf-31 *Xfjzeagoqkkusdcwbqcuibbkfmfbuepdgubzzmryfhbwbgrinfqqplayzumrciokotpdpbikwfrnrwqcungykhfvy: 14a9991067a0f463fa6b0d267ad3e7afBe189d77428585634J+
src/doerzkcgjv.rstlrptysfxnmrzlcnofv2*
-lfntbd rqznrzqoebbxsngcovfbhdoyctozrmin29
-kqffomizkcsverp&kwocconzvnirmwxfrbllgczhydddqlgokbakrk2,
-yypabhkxuqvxnujxqbfewavlsghdrafezjlewnta2:
-
tdjeuxvstsvyo)puesuovweolrbgvqirbztsskovnyqlipozirwzyjz2.
-ehz'ayjnkiikddtrmztvsduoaanmeznzfpixdnecmnu23
-pfm,bpxqnbvwluxqqypdpiqpbavcwsnauqnvfhqafsitxbph2
+lfntbd rqznrzqoebbxsngcovfbhdoyctozrmin23
+pfm,bpxqnbvwluxqqypdpiqpbavcwsnauqnvfhqafsitxbph2:
+
tdjeuxvstsvyo)puesuovweolrbgvqirbztsskovnyqlipozirwzyjz2
hvrlhuddxtdwovwxmixkoqjlqux29
-ymjfx0zdjyuaysfbdsphgohgugnrvbcsldxarwmnniuygcmrxarnanvmeegeixgsncckqzglwuargghm
+ymjfx0zdjyuaysfbdsphgohgugnrvbcsldxarwmnniuygcmrxarnan2,
+yypabhkxuqvxnujxqbfewavlsghdrafezjlewnta29
+kqffomizkcsverp&kwocconzvnirmwxfrbllgczhydddqlgokbakrk2.
+ehz'ayjnkiikddtrmztvsduoaanmeznzfpixdnecmnuvmeegeixgsncckqzglwuargghm
pkaseqf-36 *pwxwyfdsuwsyhnphgivobueqaqeyweyqoratuswajkxvwzgqsgwawcmbvhwnqvqmhkftdagtnqwcvwabumjrdpctebkkxqturqqwpmgxbitqwdalhtpfgkdvgmclsjyymwmeqbxlcicabzbnyxfahcnojrcmslpdtwrsumgymdrwhganrcbljdlefrcvsapdwaxxucpluwbcseoyvfbzdnsrjfleaimdllurccdkuqjcxntqvrowaavaizvuvozsyvyvcqbgzobsctdhiionzfrqmdbjdwhavwqcjqe: 29bf130de1435831db61d4d643c69094B3e676262c8556397J/
src/iirqnvgpyxhuygr.rsqxihcjhohofddmdcxe28
tqwvt/rtongccdgraeympoxirhhqnuqijhgejkmsansynjdlbblgb2
izlewhppduizjrwftbzjgvdohaẞnzqvfczauvnksnlidzai-20 *npqqwivznbpcfjxzvnkgrvjgpsfkpsdngwywccwdsnuwllvpbbwmvozvsbnhawvxzigybdxjohscwjspetgvimynnchfqtsfeqmupcdbprlvteo: 6e245953a9cda50f52866688c4c23f31B2e591b41f10344ecJ-
-src/kigxchbpo.rscgewcgilzefbhnlpqhfckw2
-nufepxupt2
+src/kigxchbpo.rscgewcgilzefbhnlpqhfckw2
+asbddhigqnnyhgggvoredpfwrq2
+nufepxupt2$
+ uwcaiksbsklvvlcoidmryfwrsrkcwuly2
cozfnhrnxdepxzqxhasj2%
-zyuhzpmetzatfmwumtzwxhfjxzhsgzwed2$
- uwcaiksbsklvvlcoidmryfwrsrkcwuly2
-asbddhigqnnyhgggvoredpfwrqղӖotnnuixdanrhkxoavfjccvhfjtxpwlanqx-32 *unvxtaoagzxhjgeofzkwjliowncthlavcexeqmbkbaghjlgtvrlosubagophosokpzfacramtkuohswdefkrrfavilwhbxkrygyicyhyavbgjwctmgkfroyufhwubgajcexthnhlcnciywiyvcepnfuqsbxvfggmazcfrglrwvbtlbfevuisnxevfdkpimzkidmhwljpijpkxvcaiikyhnvroodkqnvvmyzpkxfbgztiaaqtylmaeihfeevqtlvokdhebbddowrmjdelsxwuxkxltnxju: 7eb5f2def644bf33ec8809b595d7433bB4205058d3b1ce5b9J
-src/tmggafyms.rstwxel2
-jkqzxordgtcgkzvvkaddmtunaic2-
-prfqldhmyrqimumoevtvbvqigchtyzbqqjqzhtvcp،xzbrhmitdpzzltxoitdtbfgnvvev-94 *cwhwvnzcppyhwvnpqzoqmqkhgszgdneouitphwapmwxgwxkhdzkhemdiloiwyiyacnvyiathowykmvlddhnchvwdeoebaobqwsxjuywnekwiojgqhpmreyxuciftsdttbguciarymnjjrkffazfabplsdbrmudrbnnoclokfdffyhrlaysowkmktaueeloiooynrmomfwaafgngfuzqwwvkoktrixvineakegxvneyqfvzuxdduqcrcqquahczwiyporlzybprrqgcwdemgjhambkijhhsoetkqemdfemsluzmhrawarescxqniuxgeinayvvuyhyrlczjlholtyvtwljelrforduamsgkyaxagstlngirqziaakfnwfytopanqrswxmcioqeiuspkdcrbvtbehknnjwgydjkzfwtognqtpfllkkselntmxhdp: c2e3e496574f78f886a6e0ecbc55bc0fB1e39e9c51b97fbb7J6
-src/nrulmermrv.rsylgrjgrlpmgdxonbxwrjwyxdbqsjjq2-
-qyq&buibbdrtxvfygekmqkoauhkmnxnwbkheweamzk2
-zzsfpfjucglvtbxywsprfitenlaǰchigdsfqgmliajisgqbtatuvfzmgt szqiuj-15 *erpyxgzohgwdsksbazzluzdcrxcjxqciwwgqjychkgnkozwjeeswljlrqvndileewvocvjgqwjcxhldgwaevovuopbakbgsrnwgrkusmxpjqevwnixndsmbyislyvmeupolymsrverfwegjqihzsvahikbrxhpqazixagotvjzytlmjyqkmzqyuispagxivmjbjaxklkzhbllrczeqcpruorjzkxduxseydbgkygnshawnilppdcbwectiqeiljiqrutanygeacwhxyfioyegqyjazcfhzvkmuvxbqjnrvsquuuebvpbprzjezblvyoyyvefqlczytuonmjetfbyoghusombwttagdjeswnjeevfasmhywieoavmadpqrflcfioqdxvwivbcwpvtfperxjrbcfiyxbavravcduaipdfqlxegwayoxqbyzfrnadjknpizjuvofkvrjrnsqdwrzuvtdbuit: 569b7d336c67a4e94cb5a7ca25a995b8B903f34dd9900b2f6J5
+zyuhzpmetzatfmwumtzwxhfjxzhsgzwedղӖotnnuixdanrhkxoavfjccvhfjtxpwlanqx-32 *unvxtaoagzxhjgeofzkwjliowncthlavcexeqmbkbaghjlgtvrlosubagophosokpzfacramtkuohswdefkrrfavilwhbxkrygyicyhyavbgjwctmgkfroyufhwubgajcexthnhlcnciywiyvcepnfuqsbxvfggmazcfrglrwvbtlbfevuisnxevfdkpimzkidmhwljpijpkxvcaiikyhnvroodkqnvvmyzpkxfbgztiaaqtylmaeihfeevqtlvokdhebbddowrmjdelsxwuxkxltnxju: 7eb5f2def644bf33ec8809b595d7433bB4205058d3b1ce5b9J
+src/tmggafyms.rstwxel2-
+prfqldhmyrqimumoevtvbvqigchtyzbqqjqzhtvcp2
+jkqzxordgtcgkzvvkaddmtunaic،xzbrhmitdpzzltxoitdtbfgnvvev-94 *cwhwvnzcppyhwvnpqzoqmqkhgszgdneouitphwapmwxgwxkhdzkhemdiloiwyiyacnvyiathowykmvlddhnchvwdeoebaobqwsxjuywnekwiojgqhpmreyxuciftsdttbguciarymnjjrkffazfabplsdbrmudrbnnoclokfdffyhrlaysowkmktaueeloiooynrmomfwaafgngfuzqwwvkoktrixvineakegxvneyqfvzuxdduqcrcqquahczwiyporlzybprrqgcwdemgjhambkijhhsoetkqemdfemsluzmhrawarescxqniuxgeinayvvuyhyrlczjlholtyvtwljelrforduamsgkyaxagstlngirqziaakfnwfytopanqrswxmcioqeiuspkdcrbvtbehknnjwgydjkzfwtognqtpfllkkselntmxhdp: c2e3e496574f78f886a6e0ecbc55bc0fB1e39e9c51b97fbb7J6
+src/nrulmermrv.rsylgrjgrlpmgdxonbxwrjwyxdbqsjjq2
+zzsfpfjucglvtbxywsprfitenla2-
+qyq&buibbdrtxvfygekmqkoauhkmnxnwbkheweamzkǰchigdsfqgmliajisgqbtatuvfzmgt szqiuj-15 *erpyxgzohgwdsksbazzluzdcrxcjxqciwwgqjychkgnkozwjeeswljlrqvndileewvocvjgqwjcxhldgwaevovuopbakbgsrnwgrkusmxpjqevwnixndsmbyislyvmeupolymsrverfwegjqihzsvahikbrxhpqazixagotvjzytlmjyqkmzqyuispagxivmjbjaxklkzhbllrczeqcpruorjzkxduxseydbgkygnshawnilppdcbwectiqeiljiqrutanygeacwhxyfioyegqyjazcfhzvkmuvxbqjnrvsquuuebvpbprzjezblvyoyyvefqlczytuonmjetfbyoghusombwttagdjeswnjeevfasmhywieoavmadpqrflcfioqdxvwivbcwpvtfperxjrbcfiyxbavravcduaipdfqlxegwayoxqbyzfrnadjknpizjuvofkvrjrnsqdwrzuvtdbuit: 569b7d336c67a4e94cb5a7ca25a995b8B903f34dd9900b2f6J5
src/fkhjkoabzwiwi.rsadxplhwzpjoypnvovklsppbvvo2$
uknjaonljqvvkavttjyesvoaoytbdbfk2-
vojcqhvaoyljxbnoppotikmtcjrkohzloojemcrpv2
qsdxxzvjyaexitmsinmrfmqwweqiwwphlywiknf-69 *vlzjwjlrfemcgwdbtqyphqyjazvdauezbkudthpwsogrzxbuiczmjgpbohzltabahwwshtvfuewfsogsylxrowfudcoppybikbkwjbhhfnvuiuayycqroxptgvcjeszrfadpqnzeckyndur: a0be64265895768dcbc9a4e6ec193ad4Bc9ca7ba614ebed79J+
-src/lcnmzedhwwxnpoon.rs
cdpzpintsisdz2;
-ppflgapsruc,xbydjwohdlezkzxyqppmmdrtkwlkhjphfusufzjkpujk21
-vbenkeouexmarvgirwoplbmtxbrpifrvrhccvnuufozde2(
-mwgmsscklbukosdoudmkekbhprhfaeirjfad2
-prftom
crippaudtfsfu2#
+src/lcnmzedhwwxnpoon.rs
cdpzpintsisdz21
+vbenkeouexmarvgirwoplbmtxbrpifrvrhccvnuufozde2
+prftom
crippaudtfsfu27
+
pruzpdwyxcpay&tvkbbsiqvgcyhijqrduptipbebwhyubwlvafsa2#
zrfszjksefcdfdhsazgpvppfskwesaj25
-kclqmvjylts&mivasvwmpcqdrpnngwpelrdbysrfqdmvvsrgkc27
-
pruzpdwyxcpay&tvkbbsiqvgcyhijqrduptipbebwhyubwlvafsalqcmmkkvsnockvmdlttpgafdlc ekneem-11 *nsjlzigaytybjslivkbycxwnsqanlmdpkysofawmnkcmmkewjrtghmtutypcvwsftpflstzcwesmnsgnihuqwpwrmtdvqjajmzvelrdveolrjedatfsinjioufrnjxoqzrdrktjgzhltgjohtnrxdygrkwipjkpchoicivhiaszlfpnnmljgorxyscdppgigl: ef93b6d096efa4f954413cce0ffbabceB42eabafe0861bd71J/
+kclqmvjylts&mivasvwmpcqdrpnngwpelrdbysrfqdmvvsrgkc2;
+ppflgapsruc,xbydjwohdlezkzxyqppmmdrtkwlkhjphfusufzjkpujk2(
+mwgmsscklbukosdoudmkekbhprhfaeirjfadlqcmmkkvsnockvmdlttpgafdlc ekneem-11 *nsjlzigaytybjslivkbycxwnsqanlmdpkysofawmnkcmmkewjrtghmtutypcvwsftpflstzcwesmnsgnihuqwpwrmtdvqjajmzvelrdveolrjedatfsinjioufrnjxoqzrdrktjgzhltgjohtnrxdygrkwipjkpchoicivhiaszlfpnnmljgorxyscdppgigl: ef93b6d096efa4f954413cce0ffbabceB42eabafe0861bd71J/
src/beuzzzbhprftpqfxftz.rs qkjnujcnctspil2C
-
bjyraveioxogq2uwlbpiohtfwipihzincudklpxyqgypryrlmhsgjvuopkaijcgc2%
-sgakkzvmosqoratfybewiyuqztckadgaj2(
- sqiitvvjjtjbhgdayrbcizjpeovtmbmsowqa2-
-xyi&uggvvfykxzfqyvygjoyjkhncgdmozqwrblmaqjrjhkrmqkvxgntntzogwqsdcopgvc
+
bjyraveioxogq2uwlbpiohtfwipihzincudklpxyqgypryrlmhsgjvuopkaijcgc2-
+xyi&uggvvfykxzfqyvygjoyjkhncgdmozqwrblmaqj2(
+ sqiitvvjjtjbhgdayrbcizjpeovtmbmsowqa2%
+sgakkzvmosqoratfybewiyuqztckadgajrjhkrmqkvxgntntzogwqsdcopgvc
uwgnlvw-21 *adkrwfumtbeaydnypkbevxsxdzthctfwbxcyjcajixgqumyjxxgafqsuilpsgxeynmrrlyubrzktyyamvfllevycihjztdakbwfjlfmpfsnxzqoiqxzhacbsxdynukjcjuedfwvlajuqygbamukkjbnnhukavfhjjhcihibajsocvvltqwczvecnqcnmnmpnpekmjsyqorgpgybdxiieyymhiuvjzupzbyinbskubhhuqlfegygyigasupqfvdljgdjcbyjmrxozpatcbxhtvlgznamliewiqqxqqtpacpnomejdsfjguamjwrndezjmshhkezmjqlwnshouyiqpphpdfuauxzmwulghbhgbmrhqqczbwbpoioeejoflnxxuawupxbspogmkikoxdgbyrkejtilcdaxkhcmibggxlioajriobxdowpwdzudptnbptwuqrhgl: db614439b7731950f748b653a0c8b0bbB354ca128f2da2a81J
-
src/bjbvzt.rsdlrnrmaccnd2
-lauxoycvkcwvlhpzwqtiyyojb23
-pqdqfss(ofbydgzopzwamyknprermruyfjpmobymydooalcr2
-pzdqymhkywrjbrvpavsnqplsaq26
-
rxcvrlecevpgw%utmpbzlbdhbppawsmtkokvkaoypuypqmhogfp2(
-zgmxrkovnuvwlemiunkwfgbcyobfmsqvypkg2!
-ctonmvdnwwhtdszdoyzemhismcntr2:
-ecjunensktcv*bwpshwyuwtfyqsayaxaezyuxenuovsqokqkqodkzdbӉМxgbmigttcdrhlqtxskeqtzhzcb-4 *fgmkcexufhfkjnfsdiemhhzlowcryfuzkjwtuisqipmghgmaisjrzhwiajnianergtkmfxixugklajsowzkkvjcrefoxarzqjdiiyeblkubqsocdoeepzzbzvrakkvwsidmkskmrbmmcazhmdnnyiktozwugroruhztcfkqqklnerzbocbdyctexgcjtjocjdoyprhovqifpoppbvoesw: 58263fb714e66ab5ae9e688ff0dc4c75B990d4136da5d6fb7J
-src/uhdorjbh.rs hwkxnwcvj2'
- aibzyccwahohocvkewxnctdaftbrkjqztvc28
-coyu0ualpqzrvtcehrglwwbppakgpqqyjwdobonwpvvmueflacdfo29
-vzrgglcujku*cjxdcznoxrefmwmalbkxezeemsqcmdbwfzkfvhewakѩaysrudqokvatdqrrlpfqwbfofvg-20 *lrvqfdxiveouemmzgayhbjlaelvcbwzmdchinlsmxdzcgpvvuayvuybjbdfefdirugmseeyarxprnmrdlvxndvnzhogqzjaotquibtwcseckalsmtejlrrlcakzbuojqfmvdrsutdrtfrwgxzndwymlthlcqqlhbkizvubrwhxgqvxpqpywlfmpeaymnknfeojjztuiwipisiozezaqltwrsyartdsitdmhamibdeahoqarakrfjjcwbluamqijihgriuifkeekppnleijzxvztihefckvsnboiuqxnwnguscnvhbfqisbpjqlkoctevahngjyvaskxykfrduszxhditmbpcmzrzxnibmdwcawcbbjrfzrqoijsnypguirwdc: efed40a7df9539bdff0581078ba1206bBd2ab2a38decaaddbJ5
-src/cmkfcauxfxa.rsglnifhhyxtayfptfiuhcgutgmacl24
+
src/bjbvzt.rsdlrnrmaccnd2:
+ecjunensktcv*bwpshwyuwtfyqsayaxaezyuxenuovsqokqkqodkzdb23
+pqdqfss(ofbydgzopzwamyknprermruyfjpmobymydooalcr2!
+ctonmvdnwwhtdszdoyzemhismcntr2(
+zgmxrkovnuvwlemiunkwfgbcyobfmsqvypkg2
+lauxoycvkcwvlhpzwqtiyyojb26
+
rxcvrlecevpgw%utmpbzlbdhbppawsmtkokvkaoypuypqmhogfp2
+pzdqymhkywrjbrvpavsnqplsaqӉМxgbmigttcdrhlqtxskeqtzhzcb-4 *fgmkcexufhfkjnfsdiemhhzlowcryfuzkjwtuisqipmghgmaisjrzhwiajnianergtkmfxixugklajsowzkkvjcrefoxarzqjdiiyeblkubqsocdoeepzzbzvrakkvwsidmkskmrbmmcazhmdnnyiktozwugroruhztcfkqqklnerzbocbdyctexgcjtjocjdoyprhovqifpoppbvoesw: 58263fb714e66ab5ae9e688ff0dc4c75B990d4136da5d6fb7J
+src/uhdorjbh.rs hwkxnwcvj29
+vzrgglcujku*cjxdcznoxrefmwmalbkxezeemsqcmdbwfzkfvhewak28
+coyu0ualpqzrvtcehrglwwbppakgpqqyjwdobonwpvvmueflacdfo2'
+ aibzyccwahohocvkewxnctdaftbrkjqztvcѩaysrudqokvatdqrrlpfqwbfofvg-20 *lrvqfdxiveouemmzgayhbjlaelvcbwzmdchinlsmxdzcgpvvuayvuybjbdfefdirugmseeyarxprnmrdlvxndvnzhogqzjaotquibtwcseckalsmtejlrrlcakzbuojqfmvdrsutdrtfrwgxzndwymlthlcqqlhbkizvubrwhxgqvxpqpywlfmpeaymnknfeojjztuiwipisiozezaqltwrsyartdsitdmhamibdeahoqarakrfjjcwbluamqijihgriuifkeekppnleijzxvztihefckvsnboiuqxnwnguscnvhbfqisbpjqlkoctevahngjyvaskxykfrduszxhditmbpcmzrzxnibmdwcawcbbjrfzrqoijsnypguirwdc: efed40a7df9539bdff0581078ba1206bBd2ab2a38decaaddbJ5
+src/cmkfcauxfxa.rsglnifhhyxtayfptfiuhcgutgmacl2
+jvjtgtdihzdexmuzelgrub24
nqzijna)xalekbutsszvleveokbgxnwuhinpmmmsebiqcqwnx2+
jym$liaznsafczhlofltbcrdxnftvrivowmbyuyp2
-
gyacilmihewzblfmdpqv2
-jvjtgtdihzdexmuzelgrubߨhfdhwxatywzufsgi-53 *hovrslxxsxaibrizaxpcbkcqlgynmuwqcwpldtdwshzbyrbrxytjqlcgibqodkpqyzxnbbvouzpdidxuaoggsbsmxujynmdockglfclydmbqlbxtdvbvgqefqgcrzqtyhucoinupuorzblkqscnzsnmlxgdnqszarefmkakkpprvvqmdwsoduibtccisjjsrgaeddlmmwxmjezjvphcmhfqrzawbycnqrohoxsstjastpquikcgwjexgqxejkymxhdzchuaihemzspthkijwkrpajcghakujehwgsbtmywozykvylhgogeozhqwyfgabxdzkiiqzepcvakuxsaznkespenmqthuuoofitvnswiepudykugriwsldaajvaxdeshoteggvcbakpgkymrtvkokkpjjzvxsyienrzjl: f920e21262f734e7e2507d7e18d28faeBaa40e705fe8eddcdJ7
-src/mxsqbotmvpu.rs
quqajwncejjmqduhlbbhvfbjqruyqw22
+
gyacilmihewzblfmdpqvߨhfdhwxatywzufsgi-53 *hovrslxxsxaibrizaxpcbkcqlgynmuwqcwpldtdwshzbyrbrxytjqlcgibqodkpqyzxnbbvouzpdidxuaoggsbsmxujynmdockglfclydmbqlbxtdvbvgqefqgcrzqtyhucoinupuorzblkqscnzsnmlxgdnqszarefmkakkpprvvqmdwsoduibtccisjjsrgaeddlmmwxmjezjvphcmhfqrzawbycnqrohoxsstjastpquikcgwjexgqxejkymxhdzchuaihemzspthkijwkrpajcghakujehwgsbtmywozykvylhgogeozhqwyfgabxdzkiiqzepcvakuxsaznkespenmqthuuoofitvnswiepudykugriwsldaajvaxdeshoteggvcbakpgkymrtvkokkpjjzvxsyienrzjl: f920e21262f734e7e2507d7e18d28faeBaa40e705fe8eddcdJ7
+src/mxsqbotmvpu.rs
quqajwncejjmqduhlbbhvfbjqruyqw2*
+kpme"dgiewduwofaavhgenebslhvkcucnyhfxkr22
dhcunxgaqksmu!utffcokyvmbzfkwyqcomiublnlcakeimx2(
-kmwstmijaqmqrmvjdtqkohllbdpxifkqzwcs2*
-kpme"dgiewduwofaavhgenebslhvkcucnyhfxkrѧljtzpp
+kmwstmijaqmqrmvjdtqkohllbdpxifkqzwcsѧljtzpp
kbbltgz-78 *vbcdgwjexzkxajyrxycuxmgqbpgnltxhdguhnsubgckwsrqeehpoyweieakjeptlldyeswvlexthkleufbjwklxrmzsjyguiauurvtanpyzpvyjyydrixrczavattcmhdtkjojmkahxojpvpgajurpukkuvertoxfkdihuzbiwqydnhoakysfgqkkpoyjdlvqohqjexldgry: 5cfc967a7c620b6f5b1ae38d221f8fb1B557f645d00894f20J0
-src/iogweeuzdo.rsjtqjnvshngilhychxxnafekk2
- ckmmmlgcffosrfxquthmqqob21
-qqfzydtzxfrn!cihxrjarxhyaqgxizkvfvfmmnucaahalz2*
-vqvewxcoxmvukfknzzfgnrdwwdakuiyardcryo26
-vmkkvszgrgjn&fvmeelfvyuduoflmsohavyfbeluzpnwtacanfp22
-hjtyux(fxcnyiotrqgabedhyhhudhnllnhlikxdwmbhuripofczhsjvgzhgmgietrwmnhcmkukljgradfh-58 *ssngpmbkfdrjbubcqsptthaerihezsgcoqrawcmeibojpkezulfbohbywxidmohcqijeusnncwrnbdgzngoncpeaceiqnxgtpmukxxnakmyuyeaqgrksigfrgrtvtwnqcohfilrvjctycccpwdbavrtjcdwynatxwiupupwirntwuhsmkrvggdbiuomdbcolzxihmrdghjollwigqhuwntgcakruefnkxwwwqeyxfijwftbkvqndzumwhduplqgbzepyukkkkjmhmtswcucajgifderheiwzdofvvjyikxiytqiuuvivkqpgkdzubusijswgyjkcilorzspxvlhqnssttcsjdbviehhxugsdwvcbxqczzivsmwpadtempkeefcqrmwrhofmvplzdynndsnjyedwafhogxsmgmfyhtgfgfaggwayweygqbbprwixuzmcfxssjnltvqtcqamqc: 558c4eb8f6f01298380693944d8dac65B7ed48289e262732021
-mgxkzwonykjo!bjxlxssbvfatinseyetenkcuvhmzytqen2
+src/iogweeuzdo.rsjtqjnvshngilhychxxnafekk2*
+vqvewxcoxmvukfknzzfgnrdwwdakuiyardcryo22
+hjtyux(fxcnyiotrqgabedhyhhudhnllnhlikxdwmbhurip21
+qqfzydtzxfrn!cihxrjarxhyaqgxizkvfvfmmnucaahalz26
+vmkkvszgrgjn&fvmeelfvyuduoflmsohavyfbeluzpnwtacanfp2
+ ckmmmlgcffosrfxquthmqqobofczhsjvgzhgmgietrwmnhcmkukljgradfh-58 *ssngpmbkfdrjbubcqsptthaerihezsgcoqrawcmeibojpkezulfbohbywxidmohcqijeusnncwrnbdgzngoncpeaceiqnxgtpmukxxnakmyuyeaqgrksigfrgrtvtwnqcohfilrvjctycccpwdbavrtjcdwynatxwiupupwirntwuhsmkrvggdbiuomdbcolzxihmrdghjollwigqhuwntgcakruefnkxwwwqeyxfijwftbkvqndzumwhduplqgbzepyukkkkjmhmtswcucajgifderheiwzdofvvjyikxiytqiuuvivkqpgkdzubusijswgyjkcilorzspxvlhqnssttcsjdbviehhxugsdwvcbxqczzivsmwpadtempkeefcqrmwrhofmvplzdynndsnjyedwafhogxsmgmfyhtgfgfaggwayweygqbbprwixuzmcfxssjnltvqtcqamqc: 558c4eb8f6f01298380693944d8dac65B7ed48289e26273202
fqfzdhkejys
lkfcovhlwneho2'
-
njzkqgwytsdpzfhsrgbsjoknysmilprmczbrbmbdqkvytaikuiyrrejbesbahdy-10 *vxdfufcihrrsvcrcusrpbgiintspfgruuynukeljuvubldlzsscqmlqiigigmmvigwaskyuuqjjclexiajuqeixzxbsklxvsnwubedfdizeasebxvznpzenapojvqbjwsbsdupcksmhtktytctpwncwzewbvxzhmntjabfxizejafgwiwxdflkbljutqvqcltthzvsfemfxuwmzszzotnwsbygbbubvewfzommvwmrurmkurwyhsulkzjtagxiismmtdsqwjln: e7ce728703fc276616606e9bce9579dcB6a4d8b0e65a8b3a1J
-src/ginnndvhub.rsrbgchem23
-jqew+qsnbfncyezhnktczuxvcpjbhsqvmmzdcsitydoowfqb26
-
xbthmuqgecacp%fmfkaykpgoftkpdunbrvllgyzixbltxycudvh2'
-qik ewppzjafrcsocwjorkcbbfvprpqshxnm25
-
scqpdohbxhfdy$ewaqpvjiamyesanvtgweqbmnntwjadluofql23
-tcdbjn)hqbwvnrwtxgwwmihpyzlgscradrdmtyqclicfsnjk29
+
njzkqgwytsdpzfhsrgbsjoknysmilprmczb21
+mgxkzwonykjo!bjxlxssbvfatinseyetenkcuvhmzytqenrbmbdqkvytaikuiyrrejbesbahdy-10 *vxdfufcihrrsvcrcusrpbgiintspfgruuynukeljuvubldlzsscqmlqiigigmmvigwaskyuuqjjclexiajuqeixzxbsklxvsnwubedfdizeasebxvznpzenapojvqbjwsbsdupcksmhtktytctpwncwzewbvxzhmntjabfxizejafgwiwxdflkbljutqvqcltthzvsfemfxuwmzszzotnwsbygbbubvewfzommvwmrurmkurwyhsulkzjtagxiismmtdsqwjln: e7ce728703fc276616606e9bce9579dcB6a4d8b0e65a8b3a1J
+src/ginnndvhub.rsrbgchem2
+ ndrouhfrzijizqwdtxqrmumrjwln2'
+qik ewppzjafrcsocwjorkcbbfvprpqshxnm2-
+wflffsymqdoprrmcsdzmnunxknafkxriuktaifjep23
+tcdbjn)hqbwvnrwtxgwwmihpyzlgscradrdmtyqclicfsnjk25
+
scqpdohbxhfdy$ewaqpvjiamyesanvtgweqbmnntwjadluofql29
-zpstcnhecx+iofvmhyfzneixklxqxklqxllyljosrmmyqwftelgpbr2-
-wflffsymqdoprrmcsdzmnunxknafkxriuktaifjep2
- ndrouhfrzijizqwdtxqrmumrjwlnpicgvukvggipwlwzdrd-16 *qohfylmbhtycwkulgewdgbsczrhoegkchelgobvabvrjbilnxkmrtrpsmjtbnpbgauiearltbqvgqdefqmikxaayckheuhstixaclnedbbfpclavkszamsvavmtyyeskytsflkilihkiexofyqnygsxixhjuedomphbtyljwwlllwahzolldn: eb85620180d90ced9f594da83113d605Bf971736e57f2e6dfJ'
-src/pxcuqlhyrqkxgc.rshjfxbjbfwsd2
-abapbrfoehrzdjxwkrnffbgzgea2(
+zpstcnhecx+iofvmhyfzneixklxqxklqxllyljosrmmyqwftelgpbr26
+
xbthmuqgecacp%fmfkaykpgoftkpdunbrvllgyzixbltxycudvh23
+jqew+qsnbfncyezhnktczuxvcpjbhsqvmmzdcsitydoowfqbpicgvukvggipwlwzdrd-16 *qohfylmbhtycwkulgewdgbsczrhoegkchelgobvabvrjbilnxkmrtrpsmjtbnpbgauiearltbqvgqdefqmikxaayckheuhstixaclnedbbfpclavkszamsvavmtyyeskytsflkilihkiexofyqnygsxixhjuedomphbtyljwwlllwahzolldn: eb85620180d90ced9f594da83113d605Bf971736e57f2e6dfJ'
+src/pxcuqlhyrqkxgc.rshjfxbjbfwsd2(
omr!umeedruvdtidokxwfcbxbbqhzriecpamx2#
-onyogwfnnkeghhoexgniydprelvjtvj2
-
ltmrofmwxtqjbqrfbefeeckcovv2<
-yeaqpekjpouafus)wegjauvmmxqrcvmismwpzfrdfmevpqqmzskjzoopg҈epbcchetvrxtepguodavuvbfrdzjw-93 *ehbewuowbyjeyyzlwmzlyyfqyndmrenkidmvoiuqzlapbtogplctxklrvdkhvlxgojirvtttzjjhqusetwupickzlfrlpympxauvptwhbaelpheqsrsagcbrmxkbmleholjzguzwnijkfyyvlgyxexzmzyxnaqdqqkhpgvxifjnekcylrodocfaqddvahvviiqmbamslewgptqccoagjgspsmkjhimhmaiyqhxivhfyuvvrtucvsdmognlwlnjvhhtrdhhramzwrwmxpzzlzacyxha: 32b9b3ece2ab64ee9ae74b8164e34991B4194f2af465db27fJ,
+onyogwfnnkeghhoexgniydprelvjtvj2<
+yeaqpekjpouafus)wegjauvmmxqrcvmismwpzfrdfmevpqqmzskjzoopg2
+
ltmrofmwxtqjbqrfbefeeckcovv2
+abapbrfoehrzdjxwkrnffbgzgea҈epbcchetvrxtepguodavuvbfrdzjw-93 *ehbewuowbyjeyyzlwmzlyyfqyndmrenkidmvoiuqzlapbtogplctxklrvdkhvlxgojirvtttzjjhqusetwupickzlfrlpympxauvptwhbaelpheqsrsagcbrmxkbmleholjzguzwnijkfyyvlgyxexzmzyxnaqdqqkhpgvxifjnekcylrodocfaqddvahvviiqmbamslewgptqccoagjgspsmkjhimhmaiyqhxivhfyuvvrtucvsdmognlwlnjvhhtrdhhramzwrwmxpzzlzacyxha: 32b9b3ece2ab64ee9ae74b8164e34991B4194f2af465db27fJ,
src/flefkfyzqhjmw.rsjqzmqlcguzvsxcpjf2
qfvaetxuqjlmweygbbfw21
spiomzbax$upahszievzgrliablmizfahsxtlyutesbkpa2
-bcqsshojtfuuirbrtrdqnazmtvhsèdwdvqjxwanvvjsltwywhjbtrvfc
bnezhamgdr-60 *|teiblohzzkgrmfwpqkmqydytgawtfznjlxyowsrhtrkwcwpdztdnchftebpijosqzvmblxmmeegrlocqxggmwawxhffhxfttirabxckqngtcqquzuwzcuzniluwb: bfffbe9c6ed0126c392047622d2e1925Bc59ac0feda3d291328
-jiikcwegzdbhhk&fyojzbitrwxxpflbajpgdpziknudwtqdkuodoc2!
-byxwrjgslxhfkpblyrvhtxsivfkwm2.
-rhcao%vvxogtdnlkrlgmkpeuptribdxgrqasjlbxwna2<
+bcqsshojtfuuirbrtrdqnazmtvhsèdwdvqjxwanvvjsltwywhjbtrvfc
bnezhamgdr-60 *|teiblohzzkgrmfwpqkmqydytgawtfznjlxyowsrhtrkwcwpdztdnchftebpijosqzvmblxmmeegrlocqxggmwawxhffhxfttirabxckqngtcqquzuwzcuzniluwb: bfffbe9c6ed0126c392047622d2e1925Bc59ac0feda3d29132<
uyzmmodwqmd-lhqaghzyojsjmdcmoummrwlzsracqgctzbcbxvbbweydp2'
-kcsigckbsudhjidqxhtmgtjqnomfqioqovwƺ܍czcfinvvcdqldwadcetg
sbkuieasna-62 *pmbkreuppordssticugjjgfkmghrosyufnfhvyfcwjxzefomtvspjpbonmqqzybudczaytfokiywzasugrxowzpeglzhjbswrkzdqyxsfjdhwobslmwplqsxopmbgnqpmkrayghrkotfpariylefscgooepqtdokvvuckvesnrbfffvngsxhtksxatyaylvspfxakzzdhimoxduysddpqwumuhmnhdvahyvfjggsuzbbwgabyeafeglcocxdgvzohrgrvreqopyuafqixdptpjuueyxhtkqevhxfqnfkzrmhbbsuffewkdqxvcqpsdmjwcyaekifimeesfyaxcdhkakeuwg: 7196a37503ed05311098d24b796efc21B833dab49fafb988fJ2
-src/bufjykthmo.rscahmemeuffkouqhijpthtiliuk2
-exuogrperzvihwxpibrtdi2
+kcsigckbsudhjidqxhtmgtjqnomfqioqovw2!
+byxwrjgslxhfkpblyrvhtxsivfkwm28
+jiikcwegzdbhhk&fyojzbitrwxxpflbajpgdpziknudwtqdkuodoc2.
+rhcao%vvxogtdnlkrlgmkpeuptribdxgrqasjlbxwnaƺ܍czcfinvvcdqldwadcetg
sbkuieasna-62 *pmbkreuppordssticugjjgfkmghrosyufnfhvyfcwjxzefomtvspjpbonmqqzybudczaytfokiywzasugrxowzpeglzhjbswrkzdqyxsfjdhwobslmwplqsxopmbgnqpmkrayghrkotfpariylefscgooepqtdokvvuckvesnrbfffvngsxhtksxatyaylvspfxakzzdhimoxduysddpqwumuhmnhdvahyvfjggsuzbbwgabyeafeglcocxdgvzohrgrvreqopyuafqixdptpjuueyxhtkqevhxfqnfkzrmhbbsuffewkdqxvcqpsdmjwcyaekifimeesfyaxcdhkakeuwg: 7196a37503ed05311098d24b796efc21B833dab49fafb988fJ2
+src/bufjykthmo.rscahmemeuffkouqhijpthtiliuk2
lamfkhexbfkqaacltygbcgsalbqf2
-dxtbsgzvyrtfub︍wehhzkakyovyletvcrvqmhe-88*]agvdrrcmfoudgqoutzezxrpdrfgqcduselqcwkdaofmgzjtmotcjmnpabokcdbjvttuzbqnfihyxkxhkhlwfdcielkpjc: cf3a621c8553496f2d97093a3f80cb8eBf05b946dbec02321J)
-src/xlsniyyqdpnvgaboyo.rs yijtrgvfx2B
-caxljhtpnfbhod0jrpjdzqqkzybofudzwlsjoxhhrcsocbcegzrionngqcscxek2#
-
-wggcuatkvlbcmqfzzwnczvfzzwxmbkq2
-crtlgpuzc2
-mfielzuzgwgoaunsukksbe2!
+dxtbsgzvyrtfub2
+exuogrperzvihwxpibrtdi︍wehhzkakyovyletvcrvqmhe-88*]agvdrrcmfoudgqoutzezxrpdrfgqcduselqcwkdaofmgzjtmotcjmnpabokcdbjvttuzbqnfihyxkxhkhlwfdcielkpjc: cf3a621c8553496f2d97093a3f80cb8eBf05b946dbec02321J)
+src/xlsniyyqdpnvgaboyo.rs yijtrgvfx2!
vyjjzjdeinvrgpcinfvrnkgfsfrnb2
+mfielzuzgwgoaunsukksbe2#
+
+wggcuatkvlbcmqfzzwnczvfzzwxmbkq2)
+wrdjambtjtgxxndlnkfmmgkwlgbvsihcqcgib2
bztuhqcguonfhzevoiesvt2
-nqhgnqmpdgal2)
-wrdjambtjtgxxndlnkfmmgkwlgbvsihcqcgibɈpcppwhrwnugybdfu
+nqhgnqmpdgal2
+crtlgpuzc2B
+caxljhtpnfbhod0jrpjdzqqkzybofudzwlsjoxhhrcsocbcegzrionngqcscxekɈpcppwhrwnugybdfu
awbkreb-58 *bncojyymjybcmxqdjkpswzynvijjojqafaiftmdjtzzgrvaigqhkzzvktbpsemxwpprrijcebkcvhsfkecsipzsjprzdvjglmxlfpuelzabxotpfthyoqjqpstchhvsahrcwhivrgjkfovllgwkshdptmzvarqhhikejalvlctwajdzaqfztznkvputmvrtueqcdnjtrthdnpmwvbwueoucyzajwcboeyvvmyfprqbbpkxxrysregbrmkouzwktdvhrjjvystvzxttqyxojnwpsqssnucozygpvyfuzdjbocijoxenbfvleiqhyldmhupogpkcmvzbqstrvftrldxboblehhnrisswnsqrkmgzmzzbxodamruvhzbiurkjroqjvmohlwgytrzslfkvtqvfknharsyouantibvljatdhzufhrsifwbuai: 8cf8686134429b6eea93cf3b3ceca132B809f2b9092e453862.
etppnklnhv dubwfsclfwmaabxehkvtcppcdniyqgur2#
diff --git a/benchmarks/datasets/media_frame.pb b/benchmarks/datasets/media_frame.pb
new file mode 100644
index 0000000..33ec45e
Binary files /dev/null and b/benchmarks/datasets/media_frame.pb differ
diff --git a/benchmarks/gen-datasets/Cargo.lock b/benchmarks/gen-datasets/Cargo.lock
index fbe3489..6b96b4f 100644
--- a/benchmarks/gen-datasets/Cargo.lock
+++ b/benchmarks/gen-datasets/Cargo.lock
@@ -16,7 +16,7 @@ checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "buffa"
-version = "0.1.0"
+version = "0.3.0"
dependencies = [
"bytes",
"hashbrown 0.15.5",
@@ -28,7 +28,7 @@ dependencies = [
[[package]]
name = "buffa-build"
-version = "0.1.0"
+version = "0.3.0"
dependencies = [
"buffa",
"buffa-codegen",
@@ -37,9 +37,10 @@ dependencies = [
[[package]]
name = "buffa-codegen"
-version = "0.1.0"
+version = "0.3.0"
dependencies = [
"buffa",
+ "buffa-descriptor",
"prettyplease",
"proc-macro2",
"quote",
@@ -47,6 +48,13 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "buffa-descriptor"
+version = "0.3.0"
+dependencies = [
+ "buffa",
+]
+
[[package]]
name = "bytes"
version = "1.11.1"
diff --git a/benchmarks/gen-datasets/src/main.rs b/benchmarks/gen-datasets/src/main.rs
index 6bcf6b9..c4849ff 100644
--- a/benchmarks/gen-datasets/src/main.rs
+++ b/benchmarks/gen-datasets/src/main.rs
@@ -8,14 +8,32 @@ use rand::{Rng, SeedableRng};
use std::fs;
use std::path::Path;
+#[allow(
+ clippy::derivable_impls,
+ clippy::enum_variant_names,
+ clippy::match_single_binding,
+ clippy::upper_case_acronyms,
+ non_camel_case_types,
+ unused_imports,
+ dead_code
+)]
mod proto {
include!(concat!(env!("OUT_DIR"), "/bench_messages.rs"));
}
+#[allow(
+ clippy::derivable_impls,
+ clippy::enum_variant_names,
+ clippy::match_single_binding,
+ clippy::upper_case_acronyms,
+ non_camel_case_types,
+ unused_imports,
+ dead_code
+)]
mod dataset_proto {
include!(concat!(env!("OUT_DIR"), "/benchmarks.rs"));
}
-use proto::analytics_event::property::Value;
+use proto::analytics_event::property::ValueOneof as Value;
use proto::analytics_event::{Nested, Property};
use proto::log_record::Context;
use proto::*;
@@ -120,6 +138,41 @@ fn gen_nested(rng: &mut impl Rng, depth: usize) -> Nested {
}
}
+fn random_bytes(rng: &mut impl Rng, min_len: usize, max_len: usize) -> Vec {
+ let len = rng.random_range(min_len..=max_len);
+ let mut buf = vec![0u8; len];
+ rng.fill_bytes(&mut buf);
+ buf
+}
+
+fn gen_media_frame(rng: &mut impl Rng) -> MediaFrame {
+ let num_chunks = rng.random_range(2..=6);
+ let num_attachments = rng.random_range(0..=4);
+ MediaFrame {
+ frame_id: random_hex(rng, 32),
+ timestamp_nanos: rng.random_range(1_700_000_000_000_000_000i64..1_800_000_000_000_000_000),
+ content_type: (*choose(
+ &[
+ "application/octet-stream",
+ "image/jpeg",
+ "image/png",
+ "video/mp4",
+ "audio/opus",
+ ],
+ rng,
+ ))
+ .to_string(),
+ body: random_bytes(rng, 1024, 10_240),
+ chunks: (0..num_chunks)
+ .map(|_| random_bytes(rng, 200, 2000))
+ .collect(),
+ attachments: (0..num_attachments)
+ .map(|_| (random_string(rng, 5, 20), random_bytes(rng, 50, 500)))
+ .collect(),
+ ..Default::default()
+ }
+}
+
fn gen_analytics_event(rng: &mut impl Rng) -> AnalyticsEvent {
let num_props = rng.random_range(3..=10);
let num_sections = rng.random_range(2..=5);
@@ -187,5 +240,14 @@ fn main() {
.collect(),
);
+ write_dataset(
+ "media_frame",
+ "bench.MediaFrame",
+ output_dir,
+ (0..NUM_PAYLOADS)
+ .map(|_| gen_media_frame(&mut rng))
+ .collect(),
+ );
+
println!("Datasets written to {}", output_dir.display());
}
diff --git a/benchmarks/go/bench_test.go b/benchmarks/go/bench_test.go
index 475a818..fdc7c4d 100644
--- a/benchmarks/go/bench_test.go
+++ b/benchmarks/go/bench_test.go
@@ -115,6 +115,11 @@ var cases = []benchCase{
dataset: "../datasets/google_message1_proto3.pb",
newMsg: func() proto.Message { return &proto3pb.GoogleMessage1{} },
},
+ {
+ name: "MediaFrame",
+ dataset: "../datasets/media_frame.pb",
+ newMsg: func() proto.Message { return &benchpb.MediaFrame{} },
+ },
}
// benchBinaryEncode benchmarks proto.Marshal for a set of pre-decoded messages.
diff --git a/benchmarks/google/benches/protobuf.rs b/benchmarks/google/benches/protobuf.rs
index f591c3e..7407106 100644
--- a/benchmarks/google/benches/protobuf.rs
+++ b/benchmarks/google/benches/protobuf.rs
@@ -79,12 +79,21 @@ fn bench_google_message1(c: &mut Criterion) {
);
}
+fn bench_media_frame(c: &mut Criterion) {
+ benchmark_decode::(
+ c,
+ "google/media_frame",
+ include_bytes!("../../datasets/media_frame.pb"),
+ );
+}
+
criterion_group!(
benches,
bench_api_response,
bench_log_record,
bench_analytics_event,
bench_google_message1,
+ bench_media_frame,
);
criterion_main!(benches);
diff --git a/benchmarks/google/src/lib.rs b/benchmarks/google/src/lib.rs
index 9bc65ec..a9f2eee 100644
--- a/benchmarks/google/src/lib.rs
+++ b/benchmarks/google/src/lib.rs
@@ -7,7 +7,4 @@
// Include the generated entry point at the crate root. The generated.rs
// file uses `#[path = "..."]` attributes with relative paths, so it must
// be included from its containing directory.
-include!(concat!(
- env!("OUT_DIR"),
- "/protobuf_generated/generated.rs"
-));
+include!(concat!(env!("OUT_DIR"), "/protobuf_generated/generated.rs"));
diff --git a/benchmarks/prost-bytes/Cargo.lock b/benchmarks/prost-bytes/Cargo.lock
new file mode 100644
index 0000000..5f31e28
--- /dev/null
+++ b/benchmarks/prost-bytes/Cargo.lock
@@ -0,0 +1,963 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anes"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
+
+[[package]]
+name = "anstyle"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
+
+[[package]]
+name = "anyhow"
+version = "1.0.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+
+[[package]]
+name = "autocfg"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "bench-prost-bytes"
+version = "0.1.0"
+dependencies = [
+ "bytes",
+ "criterion",
+ "prost",
+ "prost-build",
+]
+
+[[package]]
+name = "bitflags"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
+
+[[package]]
+name = "bumpalo"
+version = "3.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
+
+[[package]]
+name = "bytes"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+
+[[package]]
+name = "cast"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "ciborium"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
+[[package]]
+name = "clap"
+version = "4.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
+dependencies = [
+ "clap_builder",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
+dependencies = [
+ "anstyle",
+ "clap_lex",
+]
+
+[[package]]
+name = "clap_lex"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
+
+[[package]]
+name = "criterion"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
+dependencies = [
+ "anes",
+ "cast",
+ "ciborium",
+ "clap",
+ "criterion-plot",
+ "is-terminal",
+ "itertools 0.10.5",
+ "num-traits",
+ "once_cell",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
+dependencies = [
+ "cast",
+ "itertools 0.10.5",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+
+[[package]]
+name = "crunchy"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
+
+[[package]]
+name = "fixedbitset"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
+
+[[package]]
+name = "foldhash"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
+
+[[package]]
+name = "getrandom"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasip2",
+ "wasip3",
+]
+
+[[package]]
+name = "half"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
+dependencies = [
+ "cfg-if",
+ "crunchy",
+ "zerocopy",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
+dependencies = [
+ "foldhash",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "hermit-abi"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
+
+[[package]]
+name = "id-arena"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+
+[[package]]
+name = "indexmap"
+version = "2.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.17.0",
+ "serde",
+ "serde_core",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+
+[[package]]
+name = "js-sys"
+version = "0.3.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "leb128fmt"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
+
+[[package]]
+name = "libc"
+version = "0.2.185"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
+
+[[package]]
+name = "log"
+version = "0.4.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
+
+[[package]]
+name = "memchr"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+
+[[package]]
+name = "multimap"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
+
+[[package]]
+name = "oorandom"
+version = "11.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
+
+[[package]]
+name = "petgraph"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"
+dependencies = [
+ "fixedbitset",
+ "indexmap",
+]
+
+[[package]]
+name = "plotters"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
+dependencies = [
+ "plotters-backend",
+]
+
+[[package]]
+name = "prettyplease"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "prost"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
+dependencies = [
+ "bytes",
+ "prost-derive",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf"
+dependencies = [
+ "heck",
+ "itertools 0.14.0",
+ "log",
+ "multimap",
+ "once_cell",
+ "petgraph",
+ "prettyplease",
+ "prost",
+ "prost-types",
+ "regex",
+ "syn",
+ "tempfile",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
+dependencies = [
+ "anyhow",
+ "itertools 0.14.0",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"
+dependencies = [
+ "prost",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
+
+[[package]]
+name = "rayon"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "regex"
+version = "1.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
+
+[[package]]
+name = "rustix"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
+dependencies = [
+ "itoa",
+ "memchr",
+ "serde",
+ "serde_core",
+ "zmij",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.117"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
+dependencies = [
+ "fastrand",
+ "getrandom",
+ "once_cell",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasip2"
+version = "1.0.3+wasi-0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
+dependencies = [
+ "wit-bindgen 0.57.1",
+]
+
+[[package]]
+name = "wasip3"
+version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
+dependencies = [
+ "wit-bindgen 0.51.0",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
+dependencies = [
+ "bumpalo",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "wasm-encoder"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
+dependencies = [
+ "leb128fmt",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasm-metadata"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "wasm-encoder",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
+dependencies = [
+ "bitflags",
+ "hashbrown 0.15.5",
+ "indexmap",
+ "semver",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi-util"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "wit-bindgen"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
+dependencies = [
+ "wit-bindgen-rust-macro",
+]
+
+[[package]]
+name = "wit-bindgen"
+version = "0.57.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
+
+[[package]]
+name = "wit-bindgen-core"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
+dependencies = [
+ "anyhow",
+ "heck",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-bindgen-rust"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
+dependencies = [
+ "anyhow",
+ "heck",
+ "indexmap",
+ "prettyplease",
+ "syn",
+ "wasm-metadata",
+ "wit-bindgen-core",
+ "wit-component",
+]
+
+[[package]]
+name = "wit-bindgen-rust-macro"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
+dependencies = [
+ "anyhow",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wit-bindgen-core",
+ "wit-bindgen-rust",
+]
+
+[[package]]
+name = "wit-component"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
+dependencies = [
+ "anyhow",
+ "bitflags",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "wasm-encoder",
+ "wasm-metadata",
+ "wasmparser",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-parser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
+dependencies = [
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid",
+ "wasmparser",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "zmij"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/benchmarks/prost-bytes/Cargo.toml b/benchmarks/prost-bytes/Cargo.toml
new file mode 100644
index 0000000..36291a7
--- /dev/null
+++ b/benchmarks/prost-bytes/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "bench-prost-bytes"
+version = "0.1.0"
+edition = "2021"
+publish = false
+
+# Disable lib benchmarks so `cargo bench` only hits the criterion binary.
+[lib]
+bench = false
+
+[dependencies]
+prost = "0.13"
+bytes = "1"
+
+[build-dependencies]
+prost-build = "0.13"
+
+[dev-dependencies]
+criterion = "0.5"
+
+[[bench]]
+name = "protobuf"
+harness = false
diff --git a/benchmarks/prost-bytes/benches/protobuf.rs b/benchmarks/prost-bytes/benches/protobuf.rs
new file mode 100644
index 0000000..5ecb6c3
--- /dev/null
+++ b/benchmarks/prost-bytes/benches/protobuf.rs
@@ -0,0 +1,116 @@
+use bytes::Bytes;
+use criterion::{criterion_group, criterion_main, Criterion, Throughput};
+use prost::Message;
+
+use bench_prost_bytes::bench::*;
+use bench_prost_bytes::benchmarks::BenchmarkDataset;
+
+fn load_dataset(data: &[u8]) -> BenchmarkDataset {
+ BenchmarkDataset::decode(data).expect("failed to decode dataset")
+}
+
+fn total_payload_bytes(dataset: &BenchmarkDataset) -> u64 {
+ dataset.payload.iter().map(|p| p.len() as u64).sum()
+}
+
+fn benchmark_decode(c: &mut Criterion, name: &str, dataset_bytes: &[u8]) {
+ let dataset = load_dataset(dataset_bytes);
+ let bytes_total = total_payload_bytes(&dataset);
+
+ // Pre-wrap every payload in a `bytes::Bytes` so the decoder sees a `Buf`
+ // whose `copy_to_bytes` is a zero-copy ref-count slice. Prost's `&[u8]`
+ // decode path copies into a fresh `Vec` / `Bytes` for each `bytes`
+ // field; the `Bytes`-input path shares the input buffer by refcount.
+ // `Bytes::copy_from_slice` is outside `b.iter()` so its allocation does
+ // not pollute the measured decode cost; `payload.clone()` inside the
+ // hot loop is a cheap atomic refcount bump. On schemas with no or few
+ // `bytes` fields, that per-message refcount work can become a
+ // meaningful fraction of decode cost — it's the reason this variant
+ // can appear slightly slower than default `prost` on `ApiResponse` /
+ // `LogRecord` / etc. where there's nothing to zero-copy.
+ let payloads: Vec = dataset
+ .payload
+ .iter()
+ .map(|p| Bytes::copy_from_slice(p))
+ .collect();
+
+ let mut group = c.benchmark_group(name);
+ group.throughput(Throughput::Bytes(bytes_total));
+
+ // Only `decode` / `merge` are measured here: `prost-build`'s
+ // `.bytes(["."])` substitution affects only the decode path. The
+ // `encode` and `encoded_len` numbers are expected to track default
+ // `prost` within noise — see `benchmarks/prost/` for those benches.
+ group.bench_function("decode", |b| {
+ b.iter(|| {
+ for payload in &payloads {
+ let msg = M::decode(payload.clone()).unwrap();
+ criterion::black_box(&msg);
+ }
+ });
+ });
+
+ group.bench_function("merge", |b| {
+ let mut msg = M::default();
+ b.iter(|| {
+ for payload in &payloads {
+ msg.clear();
+ msg.merge(payload.clone()).unwrap();
+ criterion::black_box(&msg);
+ }
+ });
+ });
+
+ group.finish();
+}
+
+fn bench_api_response(c: &mut Criterion) {
+ benchmark_decode::(
+ c,
+ "prost-bytes/api_response",
+ include_bytes!("../../datasets/api_response.pb"),
+ );
+}
+
+fn bench_log_record(c: &mut Criterion) {
+ benchmark_decode::(
+ c,
+ "prost-bytes/log_record",
+ include_bytes!("../../datasets/log_record.pb"),
+ );
+}
+
+fn bench_analytics_event(c: &mut Criterion) {
+ benchmark_decode::(
+ c,
+ "prost-bytes/analytics_event",
+ include_bytes!("../../datasets/analytics_event.pb"),
+ );
+}
+
+fn bench_google_message1(c: &mut Criterion) {
+ benchmark_decode::(
+ c,
+ "prost-bytes/google_message1_proto3",
+ include_bytes!("../../datasets/google_message1_proto3.pb"),
+ );
+}
+
+fn bench_media_frame(c: &mut Criterion) {
+ benchmark_decode::(
+ c,
+ "prost-bytes/media_frame",
+ include_bytes!("../../datasets/media_frame.pb"),
+ );
+}
+
+criterion_group!(
+ benches,
+ bench_api_response,
+ bench_log_record,
+ bench_analytics_event,
+ bench_google_message1,
+ bench_media_frame,
+);
+
+criterion_main!(benches);
diff --git a/benchmarks/prost-bytes/build.rs b/benchmarks/prost-bytes/build.rs
new file mode 100644
index 0000000..71dd07f
--- /dev/null
+++ b/benchmarks/prost-bytes/build.rs
@@ -0,0 +1,17 @@
+fn main() {
+ // `.bytes(["."])` tells prost-build to emit `bytes::Bytes` instead of
+ // `Vec` for every `bytes` field. Combined with a `bytes::Bytes` decode
+ // input, this exercises prost's zero-copy slicing path for `bytes` fields
+ // (the comparison point for buffa's view-based zero-copy decode).
+ prost_build::Config::new()
+ .bytes(["."])
+ .compile_protos(
+ &[
+ "../proto/bench_messages.proto",
+ "../proto/benchmarks.proto",
+ "../proto/benchmark_message1_proto3.proto",
+ ],
+ &["../proto/"],
+ )
+ .expect("failed to compile benchmark protos");
+}
diff --git a/benchmarks/prost-bytes/src/lib.rs b/benchmarks/prost-bytes/src/lib.rs
new file mode 100644
index 0000000..828305b
--- /dev/null
+++ b/benchmarks/prost-bytes/src/lib.rs
@@ -0,0 +1,24 @@
+//! Generated prost types with `bytes::Bytes` substituted for every `bytes`
+//! field (via `prost-build`'s `.bytes(["."])` config). Decode benchmarks
+//! consume `bytes::Bytes` input so prost's zero-copy slicing path for
+//! `Bytes` fields is exercised — the fair comparison point for buffa's
+//! view-based zero-copy decode (issue
+//! [#56](https://github.com/anthropics/buffa/issues/56)).
+//!
+//! The substitution applies only to proto `bytes` fields, not `string`s,
+//! messages, or scalar repeateds. For schemas without `bytes` fields, decode
+//! numbers are expected to track the default-prost crate within noise; the
+//! `MediaFrame` message in this benchmark suite is the bytes-heavy case
+//! where the substitution actually pays off.
+
+pub mod bench {
+ include!(concat!(env!("OUT_DIR"), "/bench.rs"));
+}
+
+pub mod benchmarks {
+ include!(concat!(env!("OUT_DIR"), "/benchmarks.rs"));
+
+ pub mod proto3 {
+ include!(concat!(env!("OUT_DIR"), "/benchmarks.proto3.rs"));
+ }
+}
diff --git a/benchmarks/prost/benches/protobuf.rs b/benchmarks/prost/benches/protobuf.rs
index 9233df8..0a47227 100644
--- a/benchmarks/prost/benches/protobuf.rs
+++ b/benchmarks/prost/benches/protobuf.rs
@@ -148,12 +148,19 @@ fn bench_google_message1(c: &mut Criterion) {
);
}
+fn bench_media_frame(c: &mut Criterion) {
+ let data = include_bytes!("../../datasets/media_frame.pb");
+ benchmark_decode::(c, "prost/media_frame", data);
+ benchmark_json::(c, "prost/media_frame", data);
+}
+
criterion_group!(
benches,
bench_api_response,
bench_log_record,
bench_analytics_event,
bench_google_message1,
+ bench_media_frame,
);
criterion_main!(benches);
diff --git a/benchmarks/proto/bench_messages.proto b/benchmarks/proto/bench_messages.proto
index b417722..f3d5710 100644
--- a/benchmarks/proto/bench_messages.proto
+++ b/benchmarks/proto/bench_messages.proto
@@ -76,3 +76,17 @@ message AnalyticsEvent {
}
repeated Nested sections = 5;
}
+
+// Binary-payload-heavy message: exercises the `bytes` field type, both as a
+// single large blob and as repeated / mapped sub-blobs. Used to contrast
+// prost's `prost-build`'s `.bytes(["."])` zero-copy substitution with buffa
+// views.
+// Target payload: ~3-25KB.
+message MediaFrame {
+ string frame_id = 1;
+ int64 timestamp_nanos = 2;
+ string content_type = 3;
+ bytes body = 4; // primary payload, ~1-10 KB
+ repeated bytes chunks = 5; // 2-6 sub-chunks, ~200-2000 bytes each
+ map attachments = 6; // 0-4 named sub-blobs
+}