Repository: numaproj/numaflow

Issue:
Inconsistent metic `forwarder_write_processing_time`
**Describe the bug**

`forwarder_write_processing_time` in source, sink and UDF have different meanings:

1. In source, the label `partition_name` means the partition from the reader, and the processing time includes batch writing to all the down streams if there are multiple;
2. In sink, the label `partition_name` has nothing to do with the reader partition, but the sink writer name, the processing time means a total time for a batch;
3. In UDF, `partition_name` means the partitioned writer name, the processing time includes only the batch time for one down stream.

Refer to https://github.com/numaproj/numaflow/discussions/2498.

**Environment (please complete the following information):**

- Kubernetes: [e.g. v1.18.6]
- Numaflow: [e.g. v0.5.1]

**Additional context**
Add any other context about the problem here.

---


<!-- Issue Author: Don't delete this message to encourage other users to support your issue! -->

**Message from the maintainers**:

Impacted by this bug? Give it a 👍. We often sort issues this way to know what to prioritize.

>For quick help and support, join our [slack](https://numaproj.slack.com/join/shared_invite/zt-19svuv47m-YKHhsQ~~KK9mBv1E7pNzfg#/shared-invite/email) channel.


Discussion:

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd86b6b3..3a2e1c50 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,138 @@
 # Changelog
 
+## v1.5.0-rc1 (2025-04-30)
+
+ * [834446ff](https://github.com/numaproj/numaflow/commit/834446ff701f1dd9ef2cdc347179e0544ce1c14a) Update manifests to v1.5.0-rc1
+ * [4a6f72e7](https://github.com/numaproj/numaflow/commit/4a6f72e70a435b7d728632a8400432564e5a85f4) fix: minor optimizations in serving (#2585)
+ * [3e54bb5e](https://github.com/numaproj/numaflow/commit/3e54bb5e26dd8a7aef28a1be546f85b8dfb8cf6c) feat: integrate sqs source (#2403)
+ * [8c6b7c86](https://github.com/numaproj/numaflow/commit/8c6b7c86859d8456bf6c059ee8e298fb8cd04490) feat: Improves Serving Latency and Throughput (#2564)
+ * [4f79b7ec](https://github.com/numaproj/numaflow/commit/4f79b7ecd41eb7fc669658515aa79edeec16cc56) fix(manifests): some manifests related to servingpipeline missing (#2580)
+ * [071d215c](https://github.com/numaproj/numaflow/commit/071d215c7e535e8cf46d982551d6ec73309de11f) feat: generic Write Ahead Log framework (#2571)
+ * [163ba83a](https://github.com/numaproj/numaflow/commit/163ba83a2429e6c3cb46e8303f77e9c126ed5410) fix: have `make pre-push -B` pass (#2567)
+ * [51130f8c](https://github.com/numaproj/numaflow/commit/51130f8c0ba39819fe6b6245b81594fd443b0133) fix: isb_redis_read_error_total's help message (#2568)
+ * [c5a67019](https://github.com/numaproj/numaflow/commit/c5a67019b05931a94459bc9910563089128b8d8a) feat: add missing metrics for mvtx (#2542)
+ * [9c0b14d8](https://github.com/numaproj/numaflow/commit/9c0b14d8c2bb483de4ec0f7d2f416fe24c7a5e17) feat: expose metrics for pipeline/mvtx desired and current phase (#2563)
+ * [50141cd3](https://github.com/numaproj/numaflow/commit/50141cd3c9dacb04972a99b7a2fbe4a3ce6ce6f2) fix: start persisting errors after first active pods update (#2545)
+ * [cb6e6e65](https://github.com/numaproj/numaflow/commit/cb6e6e65aab4b97739344056d3088bf9e073d7cb) feat: Support for pending count with Adaptive lookback  (#2486)
+ * [1be8ff48](https://github.com/numaproj/numaflow/commit/1be8ff48186daa7c20efbdb9a8deb67ea80633ab) feat(Serving): option to specify container template (#2554)
+ * [869771c5](https://github.com/numaproj/numaflow/commit/869771c5bdf65745aa66f7e2d26e1c5c0a0de8a4) chore(deps): bump http-proxy-middleware from 2.0.7 to 2.0.9 in /ui (#2558)
+ * [a9e529dd](https://github.com/numaproj/numaflow/commit/a9e529ddaa6b2c7fca4c9701de25f149ad66ca9e) chore(deps): bump golang.org/x/net from 0.36.0 to 0.38.0 (#2557)
+ * [dd15ef66](https://github.com/numaproj/numaflow/commit/dd15ef66b56c9307688eae36c0e2bb0f7d08216b) doc: add missing docs (#2552)
+ * [eb4dd439](https://github.com/numaproj/numaflow/commit/eb4dd43995f96739f725d86fc80c7d890b21f19e) doc: User docs for ServingPipeline (#2549)
+ * [4242f68d](https://github.com/numaproj/numaflow/commit/4242f68d660aebd521d24c5487f90d8d06b51349) chore(deps): bump github.com/nats-io/nats-server/v2 from 2.10.20 to 2.10.27 (#2555)
+ * [2dfb8669](https://github.com/numaproj/numaflow/commit/2dfb86699675b111fa4cc98967055f05ff9f9b58) fix: format stacktrace (#2548)
+ * [0e5603f1](https://github.com/numaproj/numaflow/commit/0e5603f14136e8f5c1bd09170c23bcade8f0a7f7) feat: Builtin serve sink (#2551)
+ * [b4cfad32](https://github.com/numaproj/numaflow/commit/b4cfad32d4ca9f52e4750715ba2728c7cb6f1ef4) feat: enhancing metrics tab and charts (#2544)
+ * [d4948a1a](https://github.com/numaproj/numaflow/commit/d4948a1aead74220d6bda790a83d7659580ce124) feat: persist error in case of partial/no responses from udf (#2539)
+ * [bf7e1a28](https://github.com/numaproj/numaflow/commit/bf7e1a2896690ff06c62dda6eaafb26dcc9e4288) fix: sidecar health check for long running queries in async data movement (#2541)
+ * [3706185f](https://github.com/numaproj/numaflow/commit/3706185fb1b2c7b392905ab72af30eae831bc45a) feat: [experimental] start golang vs. rust image based on env (#2537) (#2538)
+ * [99621c47](https://github.com/numaproj/numaflow/commit/99621c47ee6306d9d3f85c1644fc6586a45f99e6) feat: Serving - Expose metrics (#2533)
+ * [8b1b2eb2](https://github.com/numaproj/numaflow/commit/8b1b2eb2b9bed66badc73cfdfb780849dbb518b0) chore(deps): bump tokio from 1.44.1 to 1.44.2 in /rust (#2531)
+ * [91e66702](https://github.com/numaproj/numaflow/commit/91e66702b7a6851ba9586bde279f71faabc3c886) feat: scaffold ServingPipeline (#2468)
+ * [803869e3](https://github.com/numaproj/numaflow/commit/803869e3964f7c0b521189e81395a2451501e1d1) feat: errors tab for application errors (#2473)
+ * [fff09d09](https://github.com/numaproj/numaflow/commit/fff09d0972d9551b6a814aeecf8f3819be9764fc) feat: vertex error endpoints (#2519)
+ * [d3e2b69c](https://github.com/numaproj/numaflow/commit/d3e2b69cf15138049def1704cd899a73eb3ec8c4) fix: create a new bidirectional stream for every partition to avoid race condition (#2521)
+ * [66b1168f](https://github.com/numaproj/numaflow/commit/66b1168f6b04028a9365dcdb6f6008b1f366fe7c) fix: add active pod function for runtime errors (#2515)
+ * [64a73791](https://github.com/numaproj/numaflow/commit/64a73791b34dc0f25994a7700338195084ab557a) feat: Jetstream source implementation in Rust (#2484)
+ * [c55c879b](https://github.com/numaproj/numaflow/commit/c55c879b109fd92dc32406fe304e3af0f511354f) chore(deps): bump openssl from 0.10.68 to 0.10.71 in /rust (#2505)
+ * [62b993c6](https://github.com/numaproj/numaflow/commit/62b993c6fc529bb7633662485cfd7be985d25175) feat: surface application errors (#2499)
+ * [e6b26296](https://github.com/numaproj/numaflow/commit/e6b262969dcdb20398942bf17f892d72d2d7a26c) feat: validating webhook for MonoVertex (#2497)
+ * [70993d56](https://github.com/numaproj/numaflow/commit/70993d56825c1dae02da2a2748233d1585666b5d) fix: typo, use timeout instead of ttl (#2494)
+ * [dd96c6b5](https://github.com/numaproj/numaflow/commit/dd96c6b5910bda6906ab3f0c3c5dee5e64fe06c7) chore(deps): bump github.com/golang-jwt/jwt/v5 from 5.2.1 to 5.2.2 (#2493)
+ * [b74201ac](https://github.com/numaproj/numaflow/commit/b74201aca6b5e95264a1ff66f6aa3ba19d176769) fix: main is broken (#2490)
+ * [edd068ad](https://github.com/numaproj/numaflow/commit/edd068ade56a9bbf8a526dd53989bc3928f2725a) feat: Accumulator (#2475)
+ * [e878bdf0](https://github.com/numaproj/numaflow/commit/e878bdf00c962d2188375b4c81c832116ced6f46) fix: concurrent invocations to update active pods list in rater (#2478)
+ * [7027fdc2](https://github.com/numaproj/numaflow/commit/7027fdc22b36d331176ad11ad776833ea8b1fba3) fix(docs): PodMonitor manifest in metrics (#2477)
+ * [6f3dc810](https://github.com/numaproj/numaflow/commit/6f3dc8105ff3c906cff46bd36f78e8226ff242da) fix: Recreate KV watcher if it never returns any events (#2474)
+ * [a5416903](https://github.com/numaproj/numaflow/commit/a54169039401a8a2b9b3a67fd26e0683c6b7d03f) doc(typo): explicit callout for map (#2476)
+ * [751f3428](https://github.com/numaproj/numaflow/commit/751f34288c24ee77fa15482c9a90d867040dfd23) fix(docs): labels of ISB errors in metrics (#2463) (#2466)
+ * [f5546230](https://github.com/numaproj/numaflow/commit/f554623036074e216142e39d4a75fa0d00ee476d) chore(deps): bump @babel/runtime from 7.24.8 to 7.26.10 in /ui (#2465)
+ * [9ecbacb6](https://github.com/numaproj/numaflow/commit/9ecbacb60daf2d26361b89b83e22a24d8168b4db) chore(deps): bump golang.org/x/net from 0.34.0 to 0.36.0 (#2464)
+ * [95ee9489](https://github.com/numaproj/numaflow/commit/95ee9489119b9da0bfead2f15a17d024dd8cb657) fix: legends overlapping metrics charts (#2453)
+ * [51783837](https://github.com/numaproj/numaflow/commit/51783837e70f4cc33e7b97686899e3be23af4a9e) feat: serving feature complete (#2422)
+ * [50217e74](https://github.com/numaproj/numaflow/commit/50217e74ef2664b28a061db5f2a175c71e5ebc45) chore(deps): bump ring from 0.17.8 to 0.17.13 in /rust (#2448)
+ * [9a223c0e](https://github.com/numaproj/numaflow/commit/9a223c0ecb692cdffab508e866841bdc4d57044d) fix(ci): upgrade deprecated runner (#2437)
+ * [2869e0f8](https://github.com/numaproj/numaflow/commit/2869e0f809e91c687e7557fce7789337e2d35f9c) feat: attach emptyDir volume for runtime info (#2431)
+ * [89467467](https://github.com/numaproj/numaflow/commit/894674675834428c1148ac2ff190094337a74c89) chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.1 to 4.0.5 (#2428)
+ * [b97885b3](https://github.com/numaproj/numaflow/commit/b97885b3757c7a35a49fb71b10cc16a9f527fb5c) refactor: introducing lifecycle to Vertex spec (#2419)
+ * [1dc2b31a](https://github.com/numaproj/numaflow/commit/1dc2b31a1d871f68ca2bfb3cb4fe0d81e86d9730) doc(batchmap): clarify relation to readBatchSize (#2418)
+ * [ef0cffdc](https://github.com/numaproj/numaflow/commit/ef0cffdc67504ba7a97bbb779c97fdcfd4233056) fix(controller): replicas calculation for paused pipeline (#2412)
+ * [ae6c2a6e](https://github.com/numaproj/numaflow/commit/ae6c2a6e1c89c0a72a3e52fbce2af9fa5c029b9d) fix: error handling and grace shutdown during udf failures (#2406)
+ * [01cc33d5](https://github.com/numaproj/numaflow/commit/01cc33d5cc1cb1621cbbe21742a68a3c2cdf0d3b) feat: Serving as a builtin source with Monovertex (#2382)
+ * [d5d44084](https://github.com/numaproj/numaflow/commit/d5d44084ae98b89a77f982139cf3bfca6db03e31) fix: sorting metrics chart tooltip values (#2401)
+ * [b9188460](https://github.com/numaproj/numaflow/commit/b9188460e073f3fd8fd3ad7a98c783d7e0eeabcb) fix: filter out deamon pod and unnecessary containers from metrics output (#2394)
+ * [6c397bae](https://github.com/numaproj/numaflow/commit/6c397baecdc1cbaffe0db1cb276d7abddc0509db) fix: error state & search/negate search in case of prev terminated logs (#2391)
+ * [7d2251dd](https://github.com/numaproj/numaflow/commit/7d2251dd5368f4eacec790f7c28cc3281283af8b) fix(controller): multiple issues related to min/max of a vertex (#2398)
+ * [8d51c66a](https://github.com/numaproj/numaflow/commit/8d51c66af69eed9785cb98ed1c973afe66d6a6fe) feat: Idle Watermark Implementation Inside Async Data Movement for Source and ISB (#2385)
+ * [bf0f9dba](https://github.com/numaproj/numaflow/commit/bf0f9dba0577e13c4085f811a96ddf2ba59400ab) feat: add sqs source (#2355)
+ * [72a11e9b](https://github.com/numaproj/numaflow/commit/72a11e9b349d27b745bf0e08c61bc6b5cb888dd7) feat: updating chart lables and tooltip (#2387)
+ * [52614f85](https://github.com/numaproj/numaflow/commit/52614f858ba54b2e79bfa2e3fa519c9bb53c9a52) feat: contextual flow for remaining metrics (#2379)
+ * [12c27203](https://github.com/numaproj/numaflow/commit/12c272036f85b0ab979fe0b5e68e09443ce49806) feat: cpu memory metrics (#2332)
+ * [49345711](https://github.com/numaproj/numaflow/commit/493457110176cdb098a19b1abb214cd5a084d7f1) feat: Controller changes to support Serving as a builtin source (#2357)
+ * [208527d8](https://github.com/numaproj/numaflow/commit/208527d85490cdfc551c6560ae5e10a50c85f1c4) feat: moving ud containers logs as default in pods view (#2378)
+ * [afc16ac0](https://github.com/numaproj/numaflow/commit/afc16ac0bc2633071f2843b5eecf2de1b44159d0) feat: adaptive lookback for monovertex (#2373)
+ * [8e9bafb7](https://github.com/numaproj/numaflow/commit/8e9bafb7ee0e45eaf6f1e099e353965b53bf31d5) fix: timestamp and level filter fix for logs (#2374)
+ * [084be893](https://github.com/numaproj/numaflow/commit/084be8933d6d6eb6a6dea726671e0fef94472ee9) feat: Watermark Implementation for Async Data Movement (#2376)
+ * [d4e5859a](https://github.com/numaproj/numaflow/commit/d4e5859a21a8d39eec4dea7e145dde4b10e4b6fb) fix: get status of init containers in pods-info API call (#2371)
+ * [5d604319](https://github.com/numaproj/numaflow/commit/5d6043195bb85ef2ae2ea758c15fd084fac73f7b) fix: error handling in case of udsink failures (#2372)
+ * [c621d2bc](https://github.com/numaproj/numaflow/commit/c621d2bcf80a35536c03c20d968f103a7e11081a) fix(test): use different approach to start jetstream service (#2359)
+ * [8cd95a8c](https://github.com/numaproj/numaflow/commit/8cd95a8c1d9d58a631708970e0a67f118f2d52bf) feat: rows/page dropbox. Fixes #1764 (#2337)
+ * [bdab7591](https://github.com/numaproj/numaflow/commit/bdab75910c28d4b200c4d5da6caa51fe5b71d5c7) fix: units and tooltip content for metric charts (#2333)
+ * [c4925203](https://github.com/numaproj/numaflow/commit/c4925203ea6d2bcdb9c5deeba5f1a11329ff122f) feat: implement callbacks from vertices when serving is used as source (#2311)
+ * [3b563062](https://github.com/numaproj/numaflow/commit/3b563062b7b3248afadbd5ddd20bffd597ac562e) fix: more criteria to detect lifecycle changes, fixes: #2331 (#2346)
+ * [2515a4b3](https://github.com/numaproj/numaflow/commit/2515a4b3acc3ef7d4b1fc5832c58060435a9df37) feat: contextual flow for metrics (#2345)
+ * [f4feae72](https://github.com/numaproj/numaflow/commit/f4feae72467b0a573dd869a7e65217b6a624c8e6) chore(deps): bump golang.org/x/net from 0.29.0 to 0.34.0 (#2339)
+ * [37076739](https://github.com/numaproj/numaflow/commit/3707673947f99e16a3b3849b079d629a1a1c1472) fix: clean up metrics for deleted mvtx (#2338)
+ * [33b992b8](https://github.com/numaproj/numaflow/commit/33b992b852d14ad1788d8d0fc0af7b7d117d023e) feat: Enhance Serving To Support Flatmap Operations (#2324)
+ * [376a6023](https://github.com/numaproj/numaflow/commit/376a6023ba735e1d483862cf1a77b86009c59a1d) feat: logs enhancements (#2320)
+ * [fd4a0aac](https://github.com/numaproj/numaflow/commit/fd4a0aaca263c82a92340ac00f28bd77feba9f27) feat: expose pending messages metric in async pipeline (#2330)
+ * [2653fb24](https://github.com/numaproj/numaflow/commit/2653fb248b19cbce4becdd348580a430a8950a20) feat: Added support for kafka OAuth authentication (#2257)
+ * [ade70d8d](https://github.com/numaproj/numaflow/commit/ade70d8da310729129708781119a5634c65f9df0) fix: lastScaledAt not updated during autoscaling down (#2323)
+ * [b6c4de18](https://github.com/numaproj/numaflow/commit/b6c4de1832f1f6b4c42338b119dc2470383177f5) fix: Initialize rustls's CryptoProvider early in the code (#2312)
+ * [5f5af1ba](https://github.com/numaproj/numaflow/commit/5f5af1baddce04d1e93b5ef6e1976ac1828d1a85) feat: make unit and display name configurable (#2269)
+ * [8d8340c7](https://github.com/numaproj/numaflow/commit/8d8340c725e39031ef56e04e603c3b9241f15399) feat: Implement `Sourcer` traits for serving source (#2301)
+ * [d387d3fe](https://github.com/numaproj/numaflow/commit/d387d3fe5bbcc9c5a2f181cebfa2c0ef3b15eb87) feat: enhance time range selector for metrics - include presets (#2292)
+ * [81284765](https://github.com/numaproj/numaflow/commit/8128476528bf49ae742ff9259c5291bd0a6473e3) feat: Asynchronous Map Implementation for Pipeline (#2295)
+ * [fc14696a](https://github.com/numaproj/numaflow/commit/fc14696aa1d8c79c98e6d20e12bdc438d8c6a740) fix: set max decode size of proto message, add mvtx metrics (#2283)
+ * [c05c96ac](https://github.com/numaproj/numaflow/commit/c05c96ac3cfcc201121bc740d6908d03bd302831) chore(deps): bump golang.org/x/crypto from 0.27.0 to 0.31.0 (#2290)
+ * [d9446154](https://github.com/numaproj/numaflow/commit/d94461541c41d2f0d7c68ebd2e73030e8e5a0095) chore(deps): bump nanoid from 3.3.7 to 3.3.8 in /ui (#2289)
+ * [d75998fd](https://github.com/numaproj/numaflow/commit/d75998fdd3fcb5a3ecc0ccfc3e47a8bc7f97c33b) feat: pipeline gauge metrics (#2284)
+ * [059a585b](https://github.com/numaproj/numaflow/commit/059a585b04c85415cea9f343a0cf08927100ba35) feat: counter metrics visualizer for mono-vertex (#2256)
+ * [8bed236d](https://github.com/numaproj/numaflow/commit/8bed236dc3f9f423d5f36bf5d259d0486c73bc76) feat: mvtx gauge metrics support (#2259)
+ * [1c0989a9](https://github.com/numaproj/numaflow/commit/1c0989a9667b3c664bc965655c40bc05d4537384) fix: Numaflow serving sink (#2103)
+ * [df9be77b](https://github.com/numaproj/numaflow/commit/df9be77bea7f769685241296a696bce78d446cfc) fix: "Loading Pods View" and "failed to get pod details" state on UI (#2248)
+ * [7c07e054](https://github.com/numaproj/numaflow/commit/7c07e0541ef3060ae8995c5359eb0e465c49b474) feat: Conditional Forwarding In Asynchronous Pipeline  (#2270)
+ * [5f69064e](https://github.com/numaproj/numaflow/commit/5f69064ed836d91e73947d43853830d89895e5ba) feat: Introducing Tracker to track completeness of the Message (#2264)
+ * [11c0d2b4](https://github.com/numaproj/numaflow/commit/11c0d2b40c314d81517fe8afeea30edd50f3cda4) fix: Sink Config to respect Fallback (#2265)
+ * [5c9094b3](https://github.com/numaproj/numaflow/commit/5c9094b3200737027bbcfdc0bced3528b7b8b405) fix: honor lookbackSeconds in monovertex and rust pipeline (#2258)
+ * [05df8869](https://github.com/numaproj/numaflow/commit/05df88691d8c9a787c5d4b84e5a97bf4d9d39a4e) feat: counter metrics visualizer for pipeline (#2238)
+ * [2530bade](https://github.com/numaproj/numaflow/commit/2530bade00d6c2088a9e9d649e2de84ba22036a8) feat: Asynchronous Streaming for Source and Sink in Numaflow Core (#2251)
+ * [b31380b1](https://github.com/numaproj/numaflow/commit/b31380b1445669fa91888fb2e3feec382773590e) feat: Built-in Pulsar source (#2237)
+ * [e4bb2f72](https://github.com/numaproj/numaflow/commit/e4bb2f726a633fde7b12c6ef9b6874de5af1e572) fix: init container logs (#2245)
+ * [f5a79bf9](https://github.com/numaproj/numaflow/commit/f5a79bf9e808a32d4895a04ccdd048c377fd4549) feat: unify metrics ( cleanup and add missing metrics ) (#2207)
+ * [c5afc906](https://github.com/numaproj/numaflow/commit/c5afc906995c6cf2b4f0fa8f4b9c7d8c54577f5f) feat: use sidecar for ud containers [Breaking k8s < v1.29] (#2230)
+ * [4f2568ba](https://github.com/numaproj/numaflow/commit/4f2568ba451fdb2cafdf13f5152689d37b03cb5b) chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /ui (#2228)
+ * [d507e19f](https://github.com/numaproj/numaflow/commit/d507e19ff76eb0e68db33434802216f633a4763d) feat: add sdk infomation metrics (#2208)
+ * [8f7132dd](https://github.com/numaproj/numaflow/commit/8f7132ddc3e71928a33bfd03bf39318bbe1ea666) doc: roadmap update (#2217)
+
+### Contributors
+
+ * Adarsh Jain
+ * Derek Wang
+ * Martin Thøgersen
+ * RohanAshar
+ * SaniyaKalamkar
+ * Sidhant Kohli
+ * Sreekanth
+ * SzymonZebrowski
+ * Takashi Menjo
+ * Takuma Watanabe
+ * Vedant Gupta
+ * Vigith Maurice
+ * Yashash H L
+ * dependabot[bot]
+ * shrivardhan
+
 ## v1.4.4 (2025-04-03)
 
  * [ae9d93ad](https://github.com/numaproj/numaflow/commit/ae9d93ad0aaaf61854696b1638fd7d813dda7cc8) Update manifests to v1.4.4
diff --git a/Makefile b/Makefile
index 5f79befc..793c38ef 100644
--- a/Makefile
+++ b/Makefile
@@ -311,7 +311,7 @@ docs-serve: docs
 
 .PHONY: docs-linkcheck
 docs-linkcheck: /usr/local/bin/lychee
-	lychee --exclude-path=CHANGELOG.md --exclude-mail *.md --include "https://github.com/numaproj/*" $(shell find ./test -type f) $(wildcard ./docs/*.md)
+	lychee --exclude-path=CHANGELOG.md *.md --include "https://github.com/numaproj/*" $(shell find ./test -type f) $(wildcard ./docs/*.md)
 
 # pre-push checks
 
diff --git a/api/json-schema/schema.json b/api/json-schema/schema.json
index 2ece5e5b..af5e8279 100644
--- a/api/json-schema/schema.json
+++ b/api/json-schema/schema.json
@@ -22157,17 +22157,62 @@
     },
     "io.numaproj.numaflow.v1alpha1.ServingSpec": {
       "properties": {
+        "affinity": {
+          "$ref": "#/definitions/io.k8s.api.core.v1.Affinity",
+          "description": "The pod's scheduling constraints More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/"
+        },
         "auth": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Authorization"
         },
+        "automountServiceAccountToken": {
+          "description": "AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.",
+          "type": "boolean"
+        },
         "containerTemplate": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate",
           "description": "Container template for the serving container."
         },
+        "dnsConfig": {
+          "$ref": "#/definitions/io.k8s.api.core.v1.PodDNSConfig",
+          "description": "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy."
+        },
+        "dnsPolicy": {
+          "description": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.",
+          "type": "string"
+        },
+        "imagePullSecrets": {
+          "description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod",
+          "items": {
+            "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference"
+          },
+          "type": "array",
+          "x-kubernetes-patch-merge-key": "name",
+          "x-kubernetes-patch-strategy": "merge"
+        },
+        "metadata": {
+          "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Metadata",
+          "description": "Metadata sets the pods's metadata, i.e. annotations and labels"
+        },
         "msgIDHeaderKey": {
           "description": "The header key from which the message id will be extracted",
           "type": "string"
         },
+        "nodeSelector": {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/",
+          "type": "object"
+        },
+        "priority": {
+          "description": "The priority value. Various system components use this field to find the priority of the Redis pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/",
+          "format": "int32",
+          "type": "integer"
+        },
+        "priorityClassName": {
+          "description": "If specified, indicates the Redis pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/",
+          "type": "string"
+        },
         "replicas": {
           "description": "Initial replicas of the serving server deployment.",
           "format": "int32",
@@ -22178,12 +22223,40 @@
           "format": "int64",
           "type": "integer"
         },
+        "resourceClaims": {
+          "description": "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name.",
+          "items": {
+            "$ref": "#/definitions/io.k8s.api.core.v1.PodResourceClaim"
+          },
+          "type": "array",
+          "x-kubernetes-patch-merge-key": "name",
+          "x-kubernetes-patch-strategy": "merge,retainKeys"
+        },
+        "runtimeClassName": {
+          "description": "RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod.  If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class",
+          "type": "string"
+        },
+        "securityContext": {
+          "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext",
+          "description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty.  See type description for default values of each field."
+        },
         "service": {
           "description": "Whether to create a ClusterIP Service",
           "type": "boolean"
         },
+        "serviceAccountName": {
+          "description": "ServiceAccountName applied to the pod",
+          "type": "string"
+        },
         "store": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ServingStore"
+        },
+        "tolerations": {
+          "description": "If specified, the pod's tolerations.",
+          "items": {
+            "$ref": "#/definitions/io.k8s.api.core.v1.Toleration"
+          },
+          "type": "array"
         }
       },
       "required": [
@@ -22416,6 +22489,9 @@
         "serving": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ServingSource"
         },
+        "sqs": {
+          "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SqsSource"
+        },
         "transformer": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.UDTransformer"
         },
@@ -22425,6 +22501,62 @@
       },
       "type": "object"
     },
+    "io.numaproj.numaflow.v1alpha1.SqsSource": {
+      "description": "SqsSource represents the configuration of an AWS SQS source",
+      "properties": {
+        "attributeNames": {
+          "description": "AttributeNames is a list of attributes that need to be returned along with each message. Valid values: All | Policy | VisibilityTimeout | MaximumMessageSize | MessageRetentionPeriod | ApproximateNumberOfMessages | ApproximateNumberOfMessagesNotVisible | CreatedTimestamp | LastModifiedTimestamp | QueueArn | ApproximateNumberOfMessagesDelayed | DelaySeconds | ReceiveMessageWaitTimeSeconds | RedrivePolicy | FifoQueue | ContentBasedDeduplication | KmsMasterKeyId | KmsDataKeyReusePeriodSeconds | DeduplicationScope | FifoThroughputLimit | RedriveAllowPolicy | SqsManagedSseEnabled",
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "awsRegion": {
+          "description": "AWSRegion is the AWS Region where the SQS queue is located",
+          "type": "string"
+        },
+        "endpointUrl": {
+          "description": "EndpointURL is the custom endpoint URL for the AWS SQS API. This is useful for testing with localstack or when using VPC endpoints.",
+          "type": "string"
+        },
+        "maxNumberOfMessages": {
+          "description": "MaxNumberOfMessages is the maximum number of messages to return in a single poll. Valid values: 1-10 Defaults to 1",
+          "format": "int32",
+          "type": "integer"
+        },
+        "messageAttributeNames": {
+          "description": "MessageAttributeNames is a list of message attributes that need to be returned along with each message.",
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "queueName": {
+          "description": "QueueName is the name of the SQS queue",
+          "type": "string"
+        },
+        "queueOwnerAWSAccountID": {
+          "description": "QueueOwnerAWSAccountID is the queue owner aws account id",
+          "type": "string"
+        },
+        "visibilityTimeout": {
+          "description": "VisibilityTimeout is the duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. Valid values: 0-43200 (12 hours)",
+          "format": "int32",
+          "type": "integer"
+        },
+        "waitTimeSeconds": {
+          "description": "WaitTimeSeconds is the duration (in seconds) for which the call waits for a message to arrive in the queue before returning. If a message is available, the call returns sooner than WaitTimeSeconds. Valid values: 0-20 Defaults to 0 (short polling)",
+          "format": "int32",
+          "type": "integer"
+        }
+      },
+      "required": [
+        "awsRegion",
+        "queueName",
+        "queueOwnerAWSAccountID"
+      ],
+      "type": "object"
+    },
     "io.numaproj.numaflow.v1alpha1.Status": {
       "description": "Status is a common structure which can be used for Status field.",
       "properties": {
diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json
index c84d60ee..d27f65d4 100644
--- a/api/openapi-spec/swagger.json
+++ b/api/openapi-spec/swagger.json
@@ -22147,17 +22147,62 @@
         "msgIDHeaderKey"
       ],
       "properties": {
+        "affinity": {
+          "description": "The pod's scheduling constraints More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/",
+          "$ref": "#/definitions/io.k8s.api.core.v1.Affinity"
+        },
         "auth": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Authorization"
         },
+        "automountServiceAccountToken": {
+          "description": "AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.",
+          "type": "boolean"
+        },
         "containerTemplate": {
           "description": "Container template for the serving container.",
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate"
         },
+        "dnsConfig": {
+          "description": "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.",
+          "$ref": "#/definitions/io.k8s.api.core.v1.PodDNSConfig"
+        },
+        "dnsPolicy": {
+          "description": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.",
+          "type": "string"
+        },
+        "imagePullSecrets": {
+          "description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod",
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference"
+          },
+          "x-kubernetes-patch-merge-key": "name",
+          "x-kubernetes-patch-strategy": "merge"
+        },
+        "metadata": {
+          "description": "Metadata sets the pods's metadata, i.e. annotations and labels",
+          "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Metadata"
+        },
         "msgIDHeaderKey": {
           "description": "The header key from which the message id will be extracted",
           "type": "string"
         },
+        "nodeSelector": {
+          "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/",
+          "type": "object",
+          "additionalProperties": {
+            "type": "string"
+          }
+        },
+        "priority": {
+          "description": "The priority value. Various system components use this field to find the priority of the Redis pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/",
+          "type": "integer",
+          "format": "int32"
+        },
+        "priorityClassName": {
+          "description": "If specified, indicates the Redis pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/",
+          "type": "string"
+        },
         "replicas": {
           "description": "Initial replicas of the serving server deployment.",
           "type": "integer",
@@ -22168,12 +22213,40 @@
           "type": "integer",
           "format": "int64"
         },
+        "resourceClaims": {
+          "description": "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name.",
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/io.k8s.api.core.v1.PodResourceClaim"
+          },
+          "x-kubernetes-patch-merge-key": "name",
+          "x-kubernetes-patch-strategy": "merge,retainKeys"
+        },
+        "runtimeClassName": {
+          "description": "RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod.  If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class",
+          "type": "string"
+        },
+        "securityContext": {
+          "description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty.  See type description for default values of each field.",
+          "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext"
+        },
         "service": {
           "description": "Whether to create a ClusterIP Service",
           "type": "boolean"
         },
+        "serviceAccountName": {
+          "description": "ServiceAccountName applied to the pod",
+          "type": "string"
+        },
         "store": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ServingStore"
+        },
+        "tolerations": {
+          "description": "If specified, the pod's tolerations.",
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/io.k8s.api.core.v1.Toleration"
+          }
         }
       }
     },
@@ -22403,6 +22476,9 @@
         "serving": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ServingSource"
         },
+        "sqs": {
+          "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SqsSource"
+        },
         "transformer": {
           "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.UDTransformer"
         },
@@ -22411,6 +22487,62 @@
         }
       }
     },
+    "io.numaproj.numaflow.v1alpha1.SqsSource": {
+      "description": "SqsSource represents the configuration of an AWS SQS source",
+      "type": "object",
+      "required": [
+        "awsRegion",
+        "queueName",
+        "queueOwnerAWSAccountID"
+      ],
+      "properties": {
+        "attributeNames": {
+          "description": "AttributeNames is a list of attributes that need to be returned along with each message. Valid values: All | Policy | VisibilityTimeout | MaximumMessageSize | MessageRetentionPeriod | ApproximateNumberOfMessages | ApproximateNumberOfMessagesNotVisible | CreatedTimestamp | LastModifiedTimestamp | QueueArn | ApproximateNumberOfMessagesDelayed | DelaySeconds | ReceiveMessageWaitTimeSeconds | RedrivePolicy | FifoQueue | ContentBasedDeduplication | KmsMasterKeyId | KmsDataKeyReusePeriodSeconds | DeduplicationScope | FifoThroughputLimit | RedriveAllowPolicy | SqsManagedSseEnabled",
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        },
+        "awsRegion": {
+          "description": "AWSRegion is the AWS Region where the SQS queue is located",
+          "type": "string"
+        },
+        "endpointUrl": {
+          "description": "EndpointURL is the custom endpoint URL for the AWS SQS API. This is useful for testing with localstack or when using VPC endpoints.",
+          "type": "string"
+        },
+        "maxNumberOfMessages": {
+          "description": "MaxNumberOfMessages is the maximum number of messages to return in a single poll. Valid values: 1-10 Defaults to 1",
+          "type": "integer",
+          "format": "int32"
+        },
+        "messageAttributeNames": {
+          "description": "MessageAttributeNames is a list of message attributes that need to be returned along with each message.",
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        },
+        "queueName": {
+          "description": "QueueName is the name of the SQS queue",
+          "type": "string"
+        },
+        "queueOwnerAWSAccountID": {
+          "description": "QueueOwnerAWSAccountID is the queue owner aws account id",
+          "type": "string"
+        },
+        "visibilityTimeout": {
+          "description": "VisibilityTimeout is the duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. Valid values: 0-43200 (12 hours)",
+          "type": "integer",
+          "format": "int32"
+        },
+        "waitTimeSeconds": {
+          "description": "WaitTimeSeconds is the duration (in seconds) for which the call waits for a message to arrive in the queue before returning. If a message is available, the call returns sooner than WaitTimeSeconds. Valid values: 0-20 Defaults to 0 (short polling)",
+          "type": "integer",
+          "format": "int32"
+        }
+      }
+    },
     "io.numaproj.numaflow.v1alpha1.Status": {
       "description": "Status is a common structure which can be used for Status field.",
       "type": "object",
diff --git a/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml b/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml
index 44cb9ea8..38327ab4 100644
--- a/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml
+++ b/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml
@@ -5142,6 +5142,38 @@ spec:
                     type: object
                   serving:
                     type: object
+                  sqs:
+                    properties:
+                      attributeNames:
+                        items:
+                          type: string
+                        type: array
+                      awsRegion:
+                        type: string
+                      endpointUrl:
+                        type: string
+                      maxNumberOfMessages:
+                        format: int32
+                        type: integer
+                      messageAttributeNames:
+                        items:
+                          type: string
+                        type: array
+                      queueName:
+                        type: string
+                      queueOwnerAWSAccountID:
+                        type: string
+                      visibilityTimeout:
+                        format: int32
+                        type: integer
+                      waitTimeSeconds:
+                        format: int32
+                        type: integer
+                    required:
+                    - awsRegion
+                    - queueName
+                    - queueOwnerAWSAccountID
+                    type: object
                   transformer:
                     properties:
                       builtin:
diff --git a/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml b/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml
index 47370b31..d876cf57 100644
--- a/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml
+++ b/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml
@@ -9832,6 +9832,38 @@ spec:
                           type: object
                         serving:
                           type: object
+                        sqs:
+                          properties:
+                            attributeNames:
+                              items:
+                                type: string
+                              type: array
+                            awsRegion:
+                              type: string
+                            endpointUrl:
+                              type: string
+                            maxNumberOfMessages:
+                              format: int32
+                              type: integer
+                            messageAttributeNames:
+                              items:
+                                type: string
+                              type: array
+                            queueName:
+                              type: string
+                            queueOwnerAWSAccountID:
+                              type: string
+                            visibilityTimeout:
+                              format: int32
+                              type: integer
+                            waitTimeSeconds:
+                              format: int32
+                              type: integer
+                          required:
+                          - awsRegion
+                          - queueName
+                          - queueOwnerAWSAccountID
+                          type: object
                         transformer:
                           properties:
                             builtin:
diff --git a/config/base/crds/full/numaflow.numaproj.io_servingpipelines.yaml b/config/base/crds/full/numaflow.numaproj.io_servingpipelines.yaml
index 59508bbe..fef16a64 100644
--- a/config/base/crds/full/numaflow.numaproj.io_servingpipelines.yaml
+++ b/config/base/crds/full/numaflow.numaproj.io_servingpipelines.yaml
@@ -9811,6 +9811,38 @@ spec:
                               type: object
                             serving:
                               type: object
+                            sqs:
+                              properties:
+                                attributeNames:
+                                  items:
+                                    type: string
+                                  type: array
+                                awsRegion:
+                                  type: string
+                                endpointUrl:
+                                  type: string
+                                maxNumberOfMessages:
+                                  format: int32
+                                  type: integer
+                                messageAttributeNames:
+                                  items:
+                                    type: string
+                                  type: array
+                                queueName:
+                                  type: string
+                                queueOwnerAWSAccountID:
+                                  type: string
+                                visibilityTimeout:
+                                  format: int32
+                                  type: integer
+                                waitTimeSeconds:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - awsRegion
+                              - queueName
+                              - queueOwnerAWSAccountID
+                              type: object
                             transformer:
                               properties:
                                 builtin:
@@ -11648,6 +11680,445 @@ spec:
                 type: object
               serving:
                 properties:
+                  affinity:
+                    properties:
+                      nodeAffinity:
+                        properties:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                preference:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchFields:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - preference
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            properties:
+                              nodeSelectorTerms:
+                                items:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchFields:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                type: array
+                                x-kubernetes-list-type: atomic
+                            required:
+                            - nodeSelectorTerms
+                            type: object
+                            x-kubernetes-map-type: atomic
+                        type: object
+                      podAffinity:
+                        properties:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                podAffinityTerm:
+                                  properties:
+                                    labelSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    matchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mismatchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    namespaceSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    namespaces:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    topologyKey:
+                                      type: string
+                                  required:
+                                  - topologyKey
+                                  type: object
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - podAffinityTerm
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                labelSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                matchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                mismatchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                namespaceSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                namespaces:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                topologyKey:
+                                  type: string
+                              required:
+                              - topologyKey
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                        type: object
+                      podAntiAffinity:
+                        properties:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                podAffinityTerm:
+                                  properties:
+                                    labelSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    matchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mismatchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    namespaceSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    namespaces:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    topologyKey:
+                                      type: string
+                                  required:
+                                  - topologyKey
+                                  type: object
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - podAffinityTerm
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                labelSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                matchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                mismatchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                namespaceSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                namespaces:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                topologyKey:
+                                  type: string
+                              required:
+                              - topologyKey
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                        type: object
+                    type: object
                   auth:
                     properties:
                       token:
@@ -11664,6 +12135,8 @@ spec:
                         type: object
                         x-kubernetes-map-type: atomic
                     type: object
+                  automountServiceAccountToken:
+                    type: boolean
                   containerTemplate:
                     properties:
                       env:
@@ -11901,16 +12374,166 @@ spec:
                             type: object
                         type: object
                     type: object
+                  dnsConfig:
+                    properties:
+                      nameservers:
+                        items:
+                          type: string
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      options:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                          type: object
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      searches:
+                        items:
+                          type: string
+                        type: array
+                        x-kubernetes-list-type: atomic
+                    type: object
+                  dnsPolicy:
+                    type: string
+                  imagePullSecrets:
+                    items:
+                      properties:
+                        name:
+                          default: ""
+                          type: string
+                      type: object
+                      x-kubernetes-map-type: atomic
+                    type: array
+                  metadata:
+                    properties:
+                      annotations:
+                        additionalProperties:
+                          type: string
+                        type: object
+                      labels:
+                        additionalProperties:
+                          type: string
+                        type: object
+                    type: object
                   msgIDHeaderKey:
                     type: string
+                  nodeSelector:
+                    additionalProperties:
+                      type: string
+                    type: object
+                  priority:
+                    format: int32
+                    type: integer
+                  priorityClassName:
+                    type: string
                   replicas:
                     format: int32
                     type: integer
                   requestTimeoutSeconds:
                     format: int32
                     type: integer
+                  resourceClaims:
+                    items:
+                      properties:
+                        name:
+                          type: string
+                        resourceClaimName:
+                          type: string
+                        resourceClaimTemplateName:
+                          type: string
+                      required:
+                      - name
+                      type: object
+                    type: array
+                  runtimeClassName:
+                    type: string
+                  securityContext:
+                    properties:
+                      appArmorProfile:
+                        properties:
+                          localhostProfile:
+                            type: string
+                          type:
+                            type: string
+                        required:
+                        - type
+                        type: object
+                      fsGroup:
+                        format: int64
+                        type: integer
+                      fsGroupChangePolicy:
+                        type: string
+                      runAsGroup:
+                        format: int64
+                        type: integer
+                      runAsNonRoot:
+                        type: boolean
+                      runAsUser:
+                        format: int64
+                        type: integer
+                      seLinuxChangePolicy:
+                        type: string
+                      seLinuxOptions:
+                        properties:
+                          level:
+                            type: string
+                          role:
+                            type: string
+                          type:
+                            type: string
+                          user:
+                            type: string
+                        type: object
+                      seccompProfile:
+                        properties:
+                          localhostProfile:
+                            type: string
+                          type:
+                            type: string
+                        required:
+                        - type
+                        type: object
+                      supplementalGroups:
+                        items:
+                          format: int64
+                          type: integer
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      supplementalGroupsPolicy:
+                        type: string
+                      sysctls:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                          required:
+                          - name
+                          - value
+                          type: object
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      windowsOptions:
+                        properties:
+                          gmsaCredentialSpec:
+                            type: string
+                          gmsaCredentialSpecName:
+                            type: string
+                          hostProcess:
+                            type: boolean
+                          runAsUserName:
+                            type: string
+                        type: object
+                    type: object
                   service:
                     type: boolean
+                  serviceAccountName:
+                    type: string
                   store:
                     properties:
                       container:
@@ -12209,6 +12832,22 @@ spec:
                     required:
                     - container
                     type: object
+                  tolerations:
+                    items:
+                      properties:
+                        effect:
+                          type: string
+                        key:
+                          type: string
+                        operator:
+                          type: string
+                        tolerationSeconds:
+                          format: int64
+                          type: integer
+                        value:
+                          type: string
+                      type: object
+                    type: array
                 required:
                 - msgIDHeaderKey
                 type: object
diff --git a/config/base/crds/full/numaflow.numaproj.io_vertices.yaml b/config/base/crds/full/numaflow.numaproj.io_vertices.yaml
index f7072be3..e84a9fda 100644
--- a/config/base/crds/full/numaflow.numaproj.io_vertices.yaml
+++ b/config/base/crds/full/numaflow.numaproj.io_vertices.yaml
@@ -4621,6 +4621,38 @@ spec:
                     type: object
                   serving:
                     type: object
+                  sqs:
+                    properties:
+                      attributeNames:
+                        items:
+                          type: string
+                        type: array
+                      awsRegion:
+                        type: string
+                      endpointUrl:
+                        type: string
+                      maxNumberOfMessages:
+                        format: int32
+                        type: integer
+                      messageAttributeNames:
+                        items:
+                          type: string
+                        type: array
+                      queueName:
+                        type: string
+                      queueOwnerAWSAccountID:
+                        type: string
+                      visibilityTimeout:
+                        format: int32
+                        type: integer
+                      waitTimeSeconds:
+                        format: int32
+                        type: integer
+                    required:
+                    - awsRegion
+                    - queueName
+                    - queueOwnerAWSAccountID
+                    type: object
                   transformer:
                     properties:
                       builtin:
diff --git a/config/install.yaml b/config/install.yaml
index c58b0b66..1cdd2345 100644
--- a/config/install.yaml
+++ b/config/install.yaml
@@ -8333,6 +8333,38 @@ spec:
                     type: object
                   serving:
                     type: object
+                  sqs:
+                    properties:
+                      attributeNames:
+                        items:
+                          type: string
+                        type: array
+                      awsRegion:
+                        type: string
+                      endpointUrl:
+                        type: string
+                      maxNumberOfMessages:
+                        format: int32
+                        type: integer
+                      messageAttributeNames:
+                        items:
+                          type: string
+                        type: array
+                      queueName:
+                        type: string
+                      queueOwnerAWSAccountID:
+                        type: string
+                      visibilityTimeout:
+                        format: int32
+                        type: integer
+                      waitTimeSeconds:
+                        format: int32
+                        type: integer
+                    required:
+                    - awsRegion
+                    - queueName
+                    - queueOwnerAWSAccountID
+                    type: object
                   transformer:
                     properties:
                       builtin:
@@ -19689,6 +19721,38 @@ spec:
                           type: object
                         serving:
                           type: object
+                        sqs:
+                          properties:
+                            attributeNames:
+                              items:
+                                type: string
+                              type: array
+                            awsRegion:
+                              type: string
+                            endpointUrl:
+                              type: string
+                            maxNumberOfMessages:
+                              format: int32
+                              type: integer
+                            messageAttributeNames:
+                              items:
+                                type: string
+                              type: array
+                            queueName:
+                              type: string
+                            queueOwnerAWSAccountID:
+                              type: string
+                            visibilityTimeout:
+                              format: int32
+                              type: integer
+                            waitTimeSeconds:
+                              format: int32
+                              type: integer
+                          required:
+                          - awsRegion
+                          - queueName
+                          - queueOwnerAWSAccountID
+                          type: object
                         transformer:
                           properties:
                             builtin:
@@ -31420,6 +31484,38 @@ spec:
                               type: object
                             serving:
                               type: object
+                            sqs:
+                              properties:
+                                attributeNames:
+                                  items:
+                                    type: string
+                                  type: array
+                                awsRegion:
+                                  type: string
+                                endpointUrl:
+                                  type: string
+                                maxNumberOfMessages:
+                                  format: int32
+                                  type: integer
+                                messageAttributeNames:
+                                  items:
+                                    type: string
+                                  type: array
+                                queueName:
+                                  type: string
+                                queueOwnerAWSAccountID:
+                                  type: string
+                                visibilityTimeout:
+                                  format: int32
+                                  type: integer
+                                waitTimeSeconds:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - awsRegion
+                              - queueName
+                              - queueOwnerAWSAccountID
+                              type: object
                             transformer:
                               properties:
                                 builtin:
@@ -33257,114 +33353,555 @@ spec:
                 type: object
               serving:
                 properties:
-                  auth:
+                  affinity:
                     properties:
-                      token:
+                      nodeAffinity:
                         properties:
-                          key:
-                            type: string
-                          name:
-                            default: ""
-                            type: string
-                          optional:
-                            type: boolean
-                        required:
-                        - key
-                        type: object
-                        x-kubernetes-map-type: atomic
-                    type: object
-                  containerTemplate:
-                    properties:
-                      env:
-                        items:
-                          properties:
-                            name:
-                              type: string
-                            value:
-                              type: string
-                            valueFrom:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
                               properties:
-                                configMapKeyRef:
-                                  properties:
-                                    key:
-                                      type: string
-                                    name:
-                                      default: ""
-                                      type: string
-                                    optional:
-                                      type: boolean
-                                  required:
-                                  - key
-                                  type: object
-                                  x-kubernetes-map-type: atomic
-                                fieldRef:
-                                  properties:
-                                    apiVersion:
-                                      type: string
-                                    fieldPath:
-                                      type: string
-                                  required:
-                                  - fieldPath
-                                  type: object
-                                  x-kubernetes-map-type: atomic
-                                resourceFieldRef:
+                                preference:
                                   properties:
-                                    containerName:
-                                      type: string
-                                    divisor:
-                                      anyOf:
-                                      - type: integer
-                                      - type: string
-                                      pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
-                                      x-kubernetes-int-or-string: true
-                                    resource:
-                                      type: string
-                                  required:
-                                  - resource
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchFields:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
                                   type: object
                                   x-kubernetes-map-type: atomic
-                                secretKeyRef:
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - preference
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            properties:
+                              nodeSelectorTerms:
+                                items:
                                   properties:
-                                    key:
-                                      type: string
-                                    name:
-                                      default: ""
-                                      type: string
-                                    optional:
-                                      type: boolean
-                                  required:
-                                  - key
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchFields:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
                                   type: object
                                   x-kubernetes-map-type: atomic
-                              type: object
-                          required:
-                          - name
-                          type: object
-                        type: array
-                      envFrom:
-                        items:
-                          properties:
-                            configMapRef:
-                              properties:
-                                name:
-                                  default: ""
-                                  type: string
-                                optional:
-                                  type: boolean
-                              type: object
-                              x-kubernetes-map-type: atomic
-                            prefix:
-                              type: string
-                            secretRef:
+                                type: array
+                                x-kubernetes-list-type: atomic
+                            required:
+                            - nodeSelectorTerms
+                            type: object
+                            x-kubernetes-map-type: atomic
+                        type: object
+                      podAffinity:
+                        properties:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
                               properties:
-                                name:
-                                  default: ""
-                                  type: string
-                                optional:
-                                  type: boolean
-                              type: object
-                              x-kubernetes-map-type: atomic
-                          type: object
+                                podAffinityTerm:
+                                  properties:
+                                    labelSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    matchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mismatchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    namespaceSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    namespaces:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    topologyKey:
+                                      type: string
+                                  required:
+                                  - topologyKey
+                                  type: object
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - podAffinityTerm
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                labelSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                matchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                mismatchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                namespaceSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                namespaces:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                topologyKey:
+                                  type: string
+                              required:
+                              - topologyKey
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                        type: object
+                      podAntiAffinity:
+                        properties:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                podAffinityTerm:
+                                  properties:
+                                    labelSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    matchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mismatchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    namespaceSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    namespaces:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    topologyKey:
+                                      type: string
+                                  required:
+                                  - topologyKey
+                                  type: object
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - podAffinityTerm
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                labelSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                matchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                mismatchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                namespaceSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                namespaces:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                topologyKey:
+                                  type: string
+                              required:
+                              - topologyKey
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                        type: object
+                    type: object
+                  auth:
+                    properties:
+                      token:
+                        properties:
+                          key:
+                            type: string
+                          name:
+                            default: ""
+                            type: string
+                          optional:
+                            type: boolean
+                        required:
+                        - key
+                        type: object
+                        x-kubernetes-map-type: atomic
+                    type: object
+                  automountServiceAccountToken:
+                    type: boolean
+                  containerTemplate:
+                    properties:
+                      env:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                            valueFrom:
+                              properties:
+                                configMapKeyRef:
+                                  properties:
+                                    key:
+                                      type: string
+                                    name:
+                                      default: ""
+                                      type: string
+                                    optional:
+                                      type: boolean
+                                  required:
+                                  - key
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                fieldRef:
+                                  properties:
+                                    apiVersion:
+                                      type: string
+                                    fieldPath:
+                                      type: string
+                                  required:
+                                  - fieldPath
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                resourceFieldRef:
+                                  properties:
+                                    containerName:
+                                      type: string
+                                    divisor:
+                                      anyOf:
+                                      - type: integer
+                                      - type: string
+                                      pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                                      x-kubernetes-int-or-string: true
+                                    resource:
+                                      type: string
+                                  required:
+                                  - resource
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                secretKeyRef:
+                                  properties:
+                                    key:
+                                      type: string
+                                    name:
+                                      default: ""
+                                      type: string
+                                    optional:
+                                      type: boolean
+                                  required:
+                                  - key
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                              type: object
+                          required:
+                          - name
+                          type: object
+                        type: array
+                      envFrom:
+                        items:
+                          properties:
+                            configMapRef:
+                              properties:
+                                name:
+                                  default: ""
+                                  type: string
+                                optional:
+                                  type: boolean
+                              type: object
+                              x-kubernetes-map-type: atomic
+                            prefix:
+                              type: string
+                            secretRef:
+                              properties:
+                                name:
+                                  default: ""
+                                  type: string
+                                optional:
+                                  type: boolean
+                              type: object
+                              x-kubernetes-map-type: atomic
+                          type: object
                         type: array
                       imagePullPolicy:
                         type: string
@@ -33510,16 +34047,166 @@ spec:
                             type: object
                         type: object
                     type: object
+                  dnsConfig:
+                    properties:
+                      nameservers:
+                        items:
+                          type: string
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      options:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                          type: object
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      searches:
+                        items:
+                          type: string
+                        type: array
+                        x-kubernetes-list-type: atomic
+                    type: object
+                  dnsPolicy:
+                    type: string
+                  imagePullSecrets:
+                    items:
+                      properties:
+                        name:
+                          default: ""
+                          type: string
+                      type: object
+                      x-kubernetes-map-type: atomic
+                    type: array
+                  metadata:
+                    properties:
+                      annotations:
+                        additionalProperties:
+                          type: string
+                        type: object
+                      labels:
+                        additionalProperties:
+                          type: string
+                        type: object
+                    type: object
                   msgIDHeaderKey:
                     type: string
+                  nodeSelector:
+                    additionalProperties:
+                      type: string
+                    type: object
+                  priority:
+                    format: int32
+                    type: integer
+                  priorityClassName:
+                    type: string
                   replicas:
                     format: int32
                     type: integer
                   requestTimeoutSeconds:
                     format: int32
                     type: integer
+                  resourceClaims:
+                    items:
+                      properties:
+                        name:
+                          type: string
+                        resourceClaimName:
+                          type: string
+                        resourceClaimTemplateName:
+                          type: string
+                      required:
+                      - name
+                      type: object
+                    type: array
+                  runtimeClassName:
+                    type: string
+                  securityContext:
+                    properties:
+                      appArmorProfile:
+                        properties:
+                          localhostProfile:
+                            type: string
+                          type:
+                            type: string
+                        required:
+                        - type
+                        type: object
+                      fsGroup:
+                        format: int64
+                        type: integer
+                      fsGroupChangePolicy:
+                        type: string
+                      runAsGroup:
+                        format: int64
+                        type: integer
+                      runAsNonRoot:
+                        type: boolean
+                      runAsUser:
+                        format: int64
+                        type: integer
+                      seLinuxChangePolicy:
+                        type: string
+                      seLinuxOptions:
+                        properties:
+                          level:
+                            type: string
+                          role:
+                            type: string
+                          type:
+                            type: string
+                          user:
+                            type: string
+                        type: object
+                      seccompProfile:
+                        properties:
+                          localhostProfile:
+                            type: string
+                          type:
+                            type: string
+                        required:
+                        - type
+                        type: object
+                      supplementalGroups:
+                        items:
+                          format: int64
+                          type: integer
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      supplementalGroupsPolicy:
+                        type: string
+                      sysctls:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                          required:
+                          - name
+                          - value
+                          type: object
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      windowsOptions:
+                        properties:
+                          gmsaCredentialSpec:
+                            type: string
+                          gmsaCredentialSpecName:
+                            type: string
+                          hostProcess:
+                            type: boolean
+                          runAsUserName:
+                            type: string
+                        type: object
+                    type: object
                   service:
                     type: boolean
+                  serviceAccountName:
+                    type: string
                   store:
                     properties:
                       container:
@@ -33818,6 +34505,22 @@ spec:
                     required:
                     - container
                     type: object
+                  tolerations:
+                    items:
+                      properties:
+                        effect:
+                          type: string
+                        key:
+                          type: string
+                        operator:
+                          type: string
+                        tolerationSeconds:
+                          format: int64
+                          type: integer
+                        value:
+                          type: string
+                      type: object
+                    type: array
                 required:
                 - msgIDHeaderKey
                 type: object
@@ -38506,6 +39209,38 @@ spec:
                     type: object
                   serving:
                     type: object
+                  sqs:
+                    properties:
+                      attributeNames:
+                        items:
+                          type: string
+                        type: array
+                      awsRegion:
+                        type: string
+                      endpointUrl:
+                        type: string
+                      maxNumberOfMessages:
+                        format: int32
+                        type: integer
+                      messageAttributeNames:
+                        items:
+                          type: string
+                        type: array
+                      queueName:
+                        type: string
+                      queueOwnerAWSAccountID:
+                        type: string
+                      visibilityTimeout:
+                        format: int32
+                        type: integer
+                      waitTimeSeconds:
+                        format: int32
+                        type: integer
+                    required:
+                    - awsRegion
+                    - queueName
+                    - queueOwnerAWSAccountID
+                    type: object
                   transformer:
                     properties:
                       builtin:
diff --git a/config/namespace-install.yaml b/config/namespace-install.yaml
index 2fbb49e6..0cf4e4b5 100644
--- a/config/namespace-install.yaml
+++ b/config/namespace-install.yaml
@@ -8333,6 +8333,38 @@ spec:
                     type: object
                   serving:
                     type: object
+                  sqs:
+                    properties:
+                      attributeNames:
+                        items:
+                          type: string
+                        type: array
+                      awsRegion:
+                        type: string
+                      endpointUrl:
+                        type: string
+                      maxNumberOfMessages:
+                        format: int32
+                        type: integer
+                      messageAttributeNames:
+                        items:
+                          type: string
+                        type: array
+                      queueName:
+                        type: string
+                      queueOwnerAWSAccountID:
+                        type: string
+                      visibilityTimeout:
+                        format: int32
+                        type: integer
+                      waitTimeSeconds:
+                        format: int32
+                        type: integer
+                    required:
+                    - awsRegion
+                    - queueName
+                    - queueOwnerAWSAccountID
+                    type: object
                   transformer:
                     properties:
                       builtin:
@@ -19689,6 +19721,38 @@ spec:
                           type: object
                         serving:
                           type: object
+                        sqs:
+                          properties:
+                            attributeNames:
+                              items:
+                                type: string
+                              type: array
+                            awsRegion:
+                              type: string
+                            endpointUrl:
+                              type: string
+                            maxNumberOfMessages:
+                              format: int32
+                              type: integer
+                            messageAttributeNames:
+                              items:
+                                type: string
+                              type: array
+                            queueName:
+                              type: string
+                            queueOwnerAWSAccountID:
+                              type: string
+                            visibilityTimeout:
+                              format: int32
+                              type: integer
+                            waitTimeSeconds:
+                              format: int32
+                              type: integer
+                          required:
+                          - awsRegion
+                          - queueName
+                          - queueOwnerAWSAccountID
+                          type: object
                         transformer:
                           properties:
                             builtin:
@@ -31420,6 +31484,38 @@ spec:
                               type: object
                             serving:
                               type: object
+                            sqs:
+                              properties:
+                                attributeNames:
+                                  items:
+                                    type: string
+                                  type: array
+                                awsRegion:
+                                  type: string
+                                endpointUrl:
+                                  type: string
+                                maxNumberOfMessages:
+                                  format: int32
+                                  type: integer
+                                messageAttributeNames:
+                                  items:
+                                    type: string
+                                  type: array
+                                queueName:
+                                  type: string
+                                queueOwnerAWSAccountID:
+                                  type: string
+                                visibilityTimeout:
+                                  format: int32
+                                  type: integer
+                                waitTimeSeconds:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - awsRegion
+                              - queueName
+                              - queueOwnerAWSAccountID
+                              type: object
                             transformer:
                               properties:
                                 builtin:
@@ -33257,114 +33353,555 @@ spec:
                 type: object
               serving:
                 properties:
-                  auth:
+                  affinity:
                     properties:
-                      token:
+                      nodeAffinity:
                         properties:
-                          key:
-                            type: string
-                          name:
-                            default: ""
-                            type: string
-                          optional:
-                            type: boolean
-                        required:
-                        - key
-                        type: object
-                        x-kubernetes-map-type: atomic
-                    type: object
-                  containerTemplate:
-                    properties:
-                      env:
-                        items:
-                          properties:
-                            name:
-                              type: string
-                            value:
-                              type: string
-                            valueFrom:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
                               properties:
-                                configMapKeyRef:
-                                  properties:
-                                    key:
-                                      type: string
-                                    name:
-                                      default: ""
-                                      type: string
-                                    optional:
-                                      type: boolean
-                                  required:
-                                  - key
-                                  type: object
-                                  x-kubernetes-map-type: atomic
-                                fieldRef:
-                                  properties:
-                                    apiVersion:
-                                      type: string
-                                    fieldPath:
-                                      type: string
-                                  required:
-                                  - fieldPath
-                                  type: object
-                                  x-kubernetes-map-type: atomic
-                                resourceFieldRef:
+                                preference:
                                   properties:
-                                    containerName:
-                                      type: string
-                                    divisor:
-                                      anyOf:
-                                      - type: integer
-                                      - type: string
-                                      pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
-                                      x-kubernetes-int-or-string: true
-                                    resource:
-                                      type: string
-                                  required:
-                                  - resource
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchFields:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
                                   type: object
                                   x-kubernetes-map-type: atomic
-                                secretKeyRef:
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - preference
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            properties:
+                              nodeSelectorTerms:
+                                items:
                                   properties:
-                                    key:
-                                      type: string
-                                    name:
-                                      default: ""
-                                      type: string
-                                    optional:
-                                      type: boolean
-                                  required:
-                                  - key
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchFields:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
                                   type: object
                                   x-kubernetes-map-type: atomic
-                              type: object
-                          required:
-                          - name
-                          type: object
-                        type: array
-                      envFrom:
-                        items:
-                          properties:
-                            configMapRef:
-                              properties:
-                                name:
-                                  default: ""
-                                  type: string
-                                optional:
-                                  type: boolean
-                              type: object
-                              x-kubernetes-map-type: atomic
-                            prefix:
-                              type: string
-                            secretRef:
+                                type: array
+                                x-kubernetes-list-type: atomic
+                            required:
+                            - nodeSelectorTerms
+                            type: object
+                            x-kubernetes-map-type: atomic
+                        type: object
+                      podAffinity:
+                        properties:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
                               properties:
-                                name:
-                                  default: ""
-                                  type: string
-                                optional:
-                                  type: boolean
-                              type: object
-                              x-kubernetes-map-type: atomic
-                          type: object
+                                podAffinityTerm:
+                                  properties:
+                                    labelSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    matchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mismatchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    namespaceSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    namespaces:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    topologyKey:
+                                      type: string
+                                  required:
+                                  - topologyKey
+                                  type: object
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - podAffinityTerm
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                labelSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                matchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                mismatchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                namespaceSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                namespaces:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                topologyKey:
+                                  type: string
+                              required:
+                              - topologyKey
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                        type: object
+                      podAntiAffinity:
+                        properties:
+                          preferredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                podAffinityTerm:
+                                  properties:
+                                    labelSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    matchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mismatchLabelKeys:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    namespaceSelector:
+                                      properties:
+                                        matchExpressions:
+                                          items:
+                                            properties:
+                                              key:
+                                                type: string
+                                              operator:
+                                                type: string
+                                              values:
+                                                items:
+                                                  type: string
+                                                type: array
+                                                x-kubernetes-list-type: atomic
+                                            required:
+                                            - key
+                                            - operator
+                                            type: object
+                                          type: array
+                                          x-kubernetes-list-type: atomic
+                                        matchLabels:
+                                          additionalProperties:
+                                            type: string
+                                          type: object
+                                      type: object
+                                      x-kubernetes-map-type: atomic
+                                    namespaces:
+                                      items:
+                                        type: string
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    topologyKey:
+                                      type: string
+                                  required:
+                                  - topologyKey
+                                  type: object
+                                weight:
+                                  format: int32
+                                  type: integer
+                              required:
+                              - podAffinityTerm
+                              - weight
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                          requiredDuringSchedulingIgnoredDuringExecution:
+                            items:
+                              properties:
+                                labelSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                matchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                mismatchLabelKeys:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                namespaceSelector:
+                                  properties:
+                                    matchExpressions:
+                                      items:
+                                        properties:
+                                          key:
+                                            type: string
+                                          operator:
+                                            type: string
+                                          values:
+                                            items:
+                                              type: string
+                                            type: array
+                                            x-kubernetes-list-type: atomic
+                                        required:
+                                        - key
+                                        - operator
+                                        type: object
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    matchLabels:
+                                      additionalProperties:
+                                        type: string
+                                      type: object
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                namespaces:
+                                  items:
+                                    type: string
+                                  type: array
+                                  x-kubernetes-list-type: atomic
+                                topologyKey:
+                                  type: string
+                              required:
+                              - topologyKey
+                              type: object
+                            type: array
+                            x-kubernetes-list-type: atomic
+                        type: object
+                    type: object
+                  auth:
+                    properties:
+                      token:
+                        properties:
+                          key:
+                            type: string
+                          name:
+                            default: ""
+                            type: string
+                          optional:
+                            type: boolean
+                        required:
+                        - key
+                        type: object
+                        x-kubernetes-map-type: atomic
+                    type: object
+                  automountServiceAccountToken:
+                    type: boolean
+                  containerTemplate:
+                    properties:
+                      env:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                            valueFrom:
+                              properties:
+                                configMapKeyRef:
+                                  properties:
+                                    key:
+                                      type: string
+                                    name:
+                                      default: ""
+                                      type: string
+                                    optional:
+                                      type: boolean
+                                  required:
+                                  - key
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                fieldRef:
+                                  properties:
+                                    apiVersion:
+                                      type: string
+                                    fieldPath:
+                                      type: string
+                                  required:
+                                  - fieldPath
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                resourceFieldRef:
+                                  properties:
+                                    containerName:
+                                      type: string
+                                    divisor:
+                                      anyOf:
+                                      - type: integer
+                                      - type: string
+                                      pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                                      x-kubernetes-int-or-string: true
+                                    resource:
+                                      type: string
+                                  required:
+                                  - resource
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                                secretKeyRef:
+                                  properties:
+                                    key:
+                                      type: string
+                                    name:
+                                      default: ""
+                                      type: string
+                                    optional:
+                                      type: boolean
+                                  required:
+                                  - key
+                                  type: object
+                                  x-kubernetes-map-type: atomic
+                              type: object
+                          required:
+                          - name
+                          type: object
+                        type: array
+                      envFrom:
+                        items:
+                          properties:
+                            configMapRef:
+                              properties:
+                                name:
+                                  default: ""
+                                  type: string
+                                optional:
+                                  type: boolean
+                              type: object
+                              x-kubernetes-map-type: atomic
+                            prefix:
+                              type: string
+                            secretRef:
+                              properties:
+                                name:
+                                  default: ""
+                                  type: string
+                                optional:
+                                  type: boolean
+                              type: object
+                              x-kubernetes-map-type: atomic
+                          type: object
                         type: array
                       imagePullPolicy:
                         type: string
@@ -33510,16 +34047,166 @@ spec:
                             type: object
                         type: object
                     type: object
+                  dnsConfig:
+                    properties:
+                      nameservers:
+                        items:
+                          type: string
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      options:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                          type: object
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      searches:
+                        items:
+                          type: string
+                        type: array
+                        x-kubernetes-list-type: atomic
+                    type: object
+                  dnsPolicy:
+                    type: string
+                  imagePullSecrets:
+                    items:
+                      properties:
+                        name:
+                          default: ""
+                          type: string
+                      type: object
+                      x-kubernetes-map-type: atomic
+                    type: array
+                  metadata:
+                    properties:
+                      annotations:
+                        additionalProperties:
+                          type: string
+                        type: object
+                      labels:
+                        additionalProperties:
+                          type: string
+                        type: object
+                    type: object
                   msgIDHeaderKey:
                     type: string
+                  nodeSelector:
+                    additionalProperties:
+                      type: string
+                    type: object
+                  priority:
+                    format: int32
+                    type: integer
+                  priorityClassName:
+                    type: string
                   replicas:
                     format: int32
                     type: integer
                   requestTimeoutSeconds:
                     format: int32
                     type: integer
+                  resourceClaims:
+                    items:
+                      properties:
+                        name:
+                          type: string
+                        resourceClaimName:
+                          type: string
+                        resourceClaimTemplateName:
+                          type: string
+                      required:
+                      - name
+                      type: object
+                    type: array
+                  runtimeClassName:
+                    type: string
+                  securityContext:
+                    properties:
+                      appArmorProfile:
+                        properties:
+                          localhostProfile:
+                            type: string
+                          type:
+                            type: string
+                        required:
+                        - type
+                        type: object
+                      fsGroup:
+                        format: int64
+                        type: integer
+                      fsGroupChangePolicy:
+                        type: string
+                      runAsGroup:
+                        format: int64
+                        type: integer
+                      runAsNonRoot:
+                        type: boolean
+                      runAsUser:
+                        format: int64
+                        type: integer
+                      seLinuxChangePolicy:
+                        type: string
+                      seLinuxOptions:
+                        properties:
+                          level:
+                            type: string
+                          role:
+                            type: string
+                          type:
+                            type: string
+                          user:
+                            type: string
+                        type: object
+                      seccompProfile:
+                        properties:
+                          localhostProfile:
+                            type: string
+                          type:
+                            type: string
+                        required:
+                        - type
+                        type: object
+                      supplementalGroups:
+                        items:
+                          format: int64
+                          type: integer
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      supplementalGroupsPolicy:
+                        type: string
+                      sysctls:
+                        items:
+                          properties:
+                            name:
+                              type: string
+                            value:
+                              type: string
+                          required:
+                          - name
+                          - value
+                          type: object
+                        type: array
+                        x-kubernetes-list-type: atomic
+                      windowsOptions:
+                        properties:
+                          gmsaCredentialSpec:
+                            type: string
+                          gmsaCredentialSpecName:
+                            type: string
+                          hostProcess:
+                            type: boolean
+                          runAsUserName:
+                            type: string
+                        type: object
+                    type: object
                   service:
                     type: boolean
+                  serviceAccountName:
+                    type: string
                   store:
                     properties:
                       container:
@@ -33818,6 +34505,22 @@ spec:
                     required:
                     - container
                     type: object
+                  tolerations:
+                    items:
+                      properties:
+                        effect:
+                          type: string
+                        key:
+                          type: string
+                        operator:
+                          type: string
+                        tolerationSeconds:
+                          format: int64
+                          type: integer
+                        value:
+                          type: string
+                      type: object
+                    type: array
                 required:
                 - msgIDHeaderKey
                 type: object
@@ -38506,6 +39209,38 @@ spec:
                     type: object
                   serving:
                     type: object
+                  sqs:
+                    properties:
+                      attributeNames:
+                        items:
+                          type: string
+                        type: array
+                      awsRegion:
+                        type: string
+                      endpointUrl:
+                        type: string
+                      maxNumberOfMessages:
+                        format: int32
+                        type: integer
+                      messageAttributeNames:
+                        items:
+                          type: string
+                        type: array
+                      queueName:
+                        type: string
+                      queueOwnerAWSAccountID:
+                        type: string
+                      visibilityTimeout:
+                        format: int32
+                        type: integer
+                      waitTimeSeconds:
+                        format: int32
+                        type: integer
+                    required:
+                    - awsRegion
+                    - queueName
+                    - queueOwnerAWSAccountID
+                    type: object
                   transformer:
                     properties:
                       builtin:
diff --git a/docs/APIs.md b/docs/APIs.md
index 39866b1d..27987c3d 100644
--- a/docs/APIs.md
+++ b/docs/APIs.md
@@ -40,6 +40,7 @@ AbstractPodTemplate
 <a href="#numaflow.numaproj.io/v1alpha1.JobTemplate">JobTemplate</a>,
 <a href="#numaflow.numaproj.io/v1alpha1.MonoVertexSpec">MonoVertexSpec</a>,
 <a href="#numaflow.numaproj.io/v1alpha1.NativeRedis">NativeRedis</a>,
+<a href="#numaflow.numaproj.io/v1alpha1.ServingSpec">ServingSpec</a>,
 <a href="#numaflow.numaproj.io/v1alpha1.SideInputsManagerTemplate">SideInputsManagerTemplate</a>,
 <a href="#numaflow.numaproj.io/v1alpha1.VertexTemplate">VertexTemplate</a>)
 </p>
@@ -10577,6 +10578,28 @@ Initial replicas of the serving server deployment.
 
 </tr>
 
+<tr>
+
+<td>
+
+<code>AbstractPodTemplate</code></br> <em>
+<a href="#numaflow.numaproj.io/v1alpha1.AbstractPodTemplate">
+AbstractPodTemplate </a> </em>
+</td>
+
+<td>
+
+<p>
+
+(Members of <code>AbstractPodTemplate</code> are embedded into this
+type.)
+</p>
+
+<em>(Optional)</em>
+</td>
+
+</tr>
+
 </tbody>
 
 </table>
@@ -11386,6 +11409,252 @@ JetStreamSource </a> </em>
 
 </tr>
 
+<tr>
+
+<td>
+
+<code>sqs</code></br> <em>
+<a href="#numaflow.numaproj.io/v1alpha1.SqsSource"> SqsSource </a> </em>
+</td>
+
+<td>
+
+<em>(Optional)</em>
+</td>
+
+</tr>
+
+</tbody>
+
+</table>
+
+<h3 id="numaflow.numaproj.io/v1alpha1.SqsSource">
+
+SqsSource
+</h3>
+
+<p>
+
+(<em>Appears on:</em>
+<a href="#numaflow.numaproj.io/v1alpha1.Source">Source</a>)
+</p>
+
+<p>
+
+<p>
+
+SqsSource represents the configuration of an AWS SQS source
+</p>
+
+</p>
+
+<table>
+
+<thead>
+
+<tr>
+
+<th>
+
+Field
+</th>
+
+<th>
+
+Description
+</th>
+
+</tr>
+
+</thead>
+
+<tbody>
+
+<tr>
+
+<td>
+
+<code>awsRegion</code></br> <em> string </em>
+</td>
+
+<td>
+
+<p>
+
+AWSRegion is the AWS Region where the SQS queue is located
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>queueName</code></br> <em> string </em>
+</td>
+
+<td>
+
+<p>
+
+QueueName is the name of the SQS queue
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>queueOwnerAWSAccountID</code></br> <em> string </em>
+</td>
+
+<td>
+
+<p>
+
+QueueOwnerAWSAccountID is the queue owner aws account id
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>visibilityTimeout</code></br> <em> int32 </em>
+</td>
+
+<td>
+
+<em>(Optional)</em>
+<p>
+
+VisibilityTimeout is the duration (in seconds) that the received
+messages are hidden from subsequent retrieve requests after being
+retrieved by a ReceiveMessage request. Valid values: 0-43200 (12 hours)
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>maxNumberOfMessages</code></br> <em> int32 </em>
+</td>
+
+<td>
+
+<em>(Optional)</em>
+<p>
+
+MaxNumberOfMessages is the maximum number of messages to return in a
+single poll. Valid values: 1-10 Defaults to 1
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>waitTimeSeconds</code></br> <em> int32 </em>
+</td>
+
+<td>
+
+<em>(Optional)</em>
+<p>
+
+WaitTimeSeconds is the duration (in seconds) for which the call waits
+for a message to arrive in the queue before returning. If a message is
+available, the call returns sooner than WaitTimeSeconds. Valid values:
+0-20 Defaults to 0 (short polling)
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>endpointUrl</code></br> <em> string </em>
+</td>
+
+<td>
+
+<em>(Optional)</em>
+<p>
+
+EndpointURL is the custom endpoint URL for the AWS SQS API. This is
+useful for testing with localstack or when using VPC endpoints.
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>attributeNames</code></br> <em> \[\]string </em>
+</td>
+
+<td>
+
+<em>(Optional)</em>
+<p>
+
+AttributeNames is a list of attributes that need to be returned along
+with each message. Valid values: All \| Policy \| VisibilityTimeout \|
+MaximumMessageSize \| MessageRetentionPeriod \|
+ApproximateNumberOfMessages \| ApproximateNumberOfMessagesNotVisible \|
+CreatedTimestamp \| LastModifiedTimestamp \| QueueArn \|
+ApproximateNumberOfMessagesDelayed \| DelaySeconds \|
+ReceiveMessageWaitTimeSeconds \| RedrivePolicy \| FifoQueue \|
+ContentBasedDeduplication \| KmsMasterKeyId \|
+KmsDataKeyReusePeriodSeconds \| DeduplicationScope \|
+FifoThroughputLimit \| RedriveAllowPolicy \| SqsManagedSseEnabled
+</p>
+
+</td>
+
+</tr>
+
+<tr>
+
+<td>
+
+<code>messageAttributeNames</code></br> <em> \[\]string </em>
+</td>
+
+<td>
+
+<em>(Optional)</em>
+<p>
+
+MessageAttributeNames is a list of message attributes that need to be
+returned along with each message.
+</p>
+
+</td>
+
+</tr>
+
 </tbody>
 
 </table>
diff --git a/docs/assets/accumulator.png b/docs/assets/accumulator.png
new file mode 100644
index 00000000..9a6ffb28
Binary files /dev/null and b/docs/assets/accumulator.png differ
diff --git a/docs/operations/metrics/metrics.md b/docs/operations/metrics/metrics.md
index 0064ea7a..125cf0da 100644
--- a/docs/operations/metrics/metrics.md
+++ b/docs/operations/metrics/metrics.md
@@ -16,10 +16,10 @@ These metrics can be used to determine throughput of your pipeline.
 | `forwarder_data_read_total`                | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of data messages read by a given Vertex from an Inter-Step Buffer Partition or Source |
 | `forwarder_read_bytes_total`               | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of bytes read by a given Vertex from an Inter-Step Buffer Partition or Source         |
 | `forwarder_data_read_bytes_total`          | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of data bytes read by a given Vertex from an Inter-Step Buffer Partition or Source    |
-| `source_forwarder_transformer_read_total`  | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`                                  | Provides the total number of messages read by source transformer                                                |
+| `source_forwarder_transformer_read_total`  | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=Source` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`        | Provides the total number of messages read by source transformer                                                |
 | `forwarder_write_total`                    | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of messages written to Inter-Step Buffer by a given Vertex                            |
 | `forwarder_write_bytes_total`              | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of bytes written to Inter-Step Buffer by a given Vertex                               |
-| `source_forwarder_transformer_write_total` | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`                                  | Provides the total number of messages written by source transformer                                             |
+| `source_forwarder_transformer_write_total` | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=Source` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`        | Provides the total number of messages written by source transformer                                             |
 | `forwarder_fbsink_write_total`             | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of messages written to a fallback sink                                                |
 | `forwarder_fbsink_write_bytes_total`       | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of bytes written to a fallback sink                                                   |
 | `forwarder_ack_total`                      | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the total number of messages acknowledged by a given Vertex from an Inter-Step Buffer Partition        |
@@ -40,7 +40,7 @@ These metrics can be used to determine the latency of your pipeline.
 | `forwarder_write_processing_time`              | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the histogram distribution of the processing times of write operations                             |
 | `forwarder_ack_processing_time`                | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the histogram distribution of the processing times of ack operations                               |
 | `forwarder_fbsink_write_processing_time`       | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Provides the histogram distribution of the processing times of write operations to a fallback sink          |
-| `source_forwarder_transformer_processing_time` | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`                                  | Provides a histogram distribution of the processing times of source transformer                             |
+| `source_forwarder_transformer_processing_time` | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=Source` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`        | Provides a histogram distribution of the processing times of source transformer                             |
 | `forwarder_udf_processing_time`                | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>`                                        | Provides a histogram distribution of the processing times of User-defined Functions. (UDF's)                |
 | `forwarder_forward_chunk_processing_time`      | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>`                                        | Provides a histogram distribution of the processing times of the forwarder function as a whole              |
 | `reduce_pnf_process_time`                      | Histogram   | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `replica=<replica-index>`                                                                         | Provides a histogram distribution of the processing times of the reducer                                    |
@@ -59,7 +59,7 @@ These metrics can be used to determine if there are any errors in the pipeline.
 | `controller_monovtx_health`                | Gauge       | `ns=<namespace>` <br> `mvtx_name=<mvtx-name>`                                                                                                                 | A metric to indicate whether the MonoVertex is healthy. '1' means healthy, '0' means unhealthy  |
 | `forwarder_platform_error_total`           | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>`                                        | Indicates any internal errors which could stop pipeline processing                              |
 | `forwarder_read_error_total`               | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Indicates any errors while reading messages by the forwarder                                    |
-| `source_forwarder_transformer_error_total` | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`                                  | Indicates source transformer errors                                                             |
+| `source_forwarder_transformer_error_total` | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=Source` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>`        | Indicates source transformer errors                                                             |
 | `forwarder_write_error_total`              | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` `vertex_type=<vertex-type>` <br> <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Indicates any errors while writing messages by the forwarder                                    |
 | `forwarder_fbsink_write_error_total`       | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` `vertex_type=<vertex-type>` <br> <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Indicates any errors while writing to a fallback sink                                           |
 | `forwarder_ack_error_total`                | Counter     | `pipeline=<pipeline-name>` <br> `vertex=<vertex-name>` <br> `vertex_type=<vertex-type>` <br> `replica=<replica-index>` <br> `partition_name=<partition-name>` | Indicates any errors while acknowledging messages by the forwarder                              |
diff --git a/docs/user-guide/sources/sqs.md b/docs/user-guide/sources/sqs.md
new file mode 100644
index 00000000..e9c4ddcc
--- /dev/null
+++ b/docs/user-guide/sources/sqs.md
@@ -0,0 +1,130 @@
+# Setting up Numaflow MonoVertex with SQS Source
+
+This guide explains how to set up a Numaflow MonoVertex that reads from an AWS SQS queue. 
+
+## Configuring Credentials to access AWS 
+
+There are couple of ways you could achieve this.
+
+### Creating AWS Credentials Secret
+
+First, we need to create a Kubernetes secret to store AWS credentials securely and encode AWS Credentials.
+
+```bash
+# Encode your AWS credentials (replace with your actual credentials)
+ACCESS_KEY_ID=$(echo -n "your-aws-access-key-id" | base64)
+SECRET_ACCESS_KEY=$(echo -n "your-aws-secret-access-key" | base64)
+
+kubectl create secret generic aws-secret \
+--from-literal access-key-id=${ACCESS_KEY_ID} \
+--from-literal secret-access-key=${SECRET_ACCESS_KEY}
+```
+
+### IAM ROLE
+1. Use an IAM role with the necessary permissions to access the SQS queue.
+2. Ensure the IAM role of the pod has access to the SQS queue, and the SQS queue policy allows the IAM role to perform actions on the queue.
+3. Attach the appropriate service account with the IAM role to the pod.
+
+For more details, refer to the AWS documentation: https://docs.aws.amazon.com/eks/latest/userguide/pod-id-how-it-works.html
+
+## Create the numaflow pipeline 
+
+Create a file named `sqs-pl.yaml` with either of the following content.
+
+### MonoVertex Specification
+
+```yaml
+apiVersion: numaflow.numaproj.io/v1alpha1
+kind: MonoVertex
+metadata:
+  name: sqs-reader
+spec:
+    source:
+        sqs:
+          queueName: "your-queue-name"        # Required: Name of your SQS queue
+          awsRegion: "your-aws-region"        # Required: AWS region where queue is located
+          queueOwnerAWSAccountID: "123456789012" # Required: AWS account ID of the queue owner
+          # Optional configurations
+          maxNumberOfMessages: 10             # Max messages per poll (1-10)
+          visibilityTimeout: 30              # Visibility timeout in seconds
+          waitTimeSeconds: 20                # Long polling wait time
+          attributeNames:                    # SQS attributes to retrieve
+            - All
+          messageAttributeNames:             # Message attributes to retrieve
+            - All
+    sink:
+        log: {}                             # Simple log sink for testing
+    limits:
+        readBatchSize: 10
+        bufferSize: 100
+    scale:
+        min: 1
+        max: 5
+```
+
+### Pipeline Specification
+
+```yaml
+apiVersion: numaflow.numaproj.io/v1alpha1
+kind: Pipeline
+metadata:
+  name: sqs-source-pl
+spec:
+  vertices:
+    - name: in
+      scale:
+        min: 1
+      source:
+        sqs:
+          queueName: "queue-name"
+          awsRegion: "us-west-2"
+          queueOwnerAWSAccountID: "123456789012" # Required: AWS account ID of the queue owner
+          # Optional configurations
+          maxNumberOfMessages: 10            # Max messages per poll (1-10)
+          visibilityTimeout: 30              # Visibility timeout in seconds
+          waitTimeSeconds: 20                # Long polling wait time
+          attributeNames:                    # SQS attributes to retrieve
+            - All
+          messageAttributeNames:             # Message attributes to retrieve
+            - All
+    - name: out
+      scale:
+        min: 1
+      sink:
+        log: {}
+  edges:
+    - from: in
+      to: out
+```
+
+## Apply the Configuration
+
+Apply the pipeline specification:
+
+```bash
+kubectl apply -f sqs-pl.yaml
+```
+
+## Verify the Setup
+
+Check that the MonoVertex is running:
+
+```bash
+kubectl get monovertex sqs-reader
+kubectl get pods -l numaflow.numaproj.io/vertex-name=sqs-reader
+```
+
+
+## Miscellaneous
+
+### Troubleshooting
+
+- Check the pods logs for any errors:
+```bash
+kubectl logs -l numaflow.numaproj.io/vertex-name=sqs-reader
+```
+- Verify the secret exists:
+```bash
+kubectl get secret aws-secret
+```
+- Ensure the SQS queue exists and is accessible with the provided credentials
diff --git a/docs/user-guide/user-defined-functions/reduce/windowing/accumulator.md b/docs/user-guide/user-defined-functions/reduce/windowing/accumulator.md
new file mode 100644
index 00000000..6480cc3d
--- /dev/null
+++ b/docs/user-guide/user-defined-functions/reduce/windowing/accumulator.md
@@ -0,0 +1,166 @@
+# Accumulator
+
+Accumulator is a special kind of window similar to a [Session Window](session.md) designed for complex operations like 
+reordering, custom triggering, and joining multiple ordered streams. Like other windowing strategies (fixed,
+sliding, or session windows), the Accumulator window maintains state for each key, but unlike others, it allows for 
+manipulation of the `Datum` and emitting them based on custom rules (e.g., sorting) . Accumulator solves is a different 
+type of problem outside both `map`/`flatmap` (one to ~one) and `reduce` (many to ~one) and instead of `Message`, we 
+have to emit back the "manipulated" `Datum`.
+
+![plot](../../../../assets/accumulator.png)
+
+Another difference between the Accumulator and the Session windows is that in Accumulator, there is no concept of 
+[window merge](./session.md#window-merge).
+
+## Why Accumulator?
+
+Accumulator is a powerful concept that lets you tap into the raw Datum stream and manipulate not just the order but the
+Datum stream itself. It has a powerful semantics where the input and output is a stream of `Datum` creating a
+Global Window. It opens up the possibility of very advanced use cases like custom triggers (e.g., count based triggers
+combined with windowing strategies). 
+
+```python
+def Accumulator(<- stream in[Datum]) -> stream out[Datum] {
+  let state = OrderedList()
+  for i = range in {
+    # The condition will return true if Watermark progresses
+    if WatermarkProgressed(i) == true {
+        # pop all sorted elements and Write to output stream
+        Write(out, state.popN()) 
+    }
+    state.insert(i) 
+  }
+}
+```
+
+### Considerations
+
+The Accumulator window is powerful but should be used carefully as it can cause pipeline stalling if not configured 
+properly.
+
+#### Factors to consider
+
+Please consider the following factors when using the Accumulator window (not comprehensive): 
+
+1. For high-throughput scenarios, ensure adequate storage is provisioned
+2. The timeout should be set based on the expected data arrival patterns and latency requirements
+3. Consider the trade-off between data completeness (longer timeout) and processing latency (shorter timeout)
+4. Please make sure Watermark is honored when publishing the data, else completeness and correctness is not guaranteed
+
+#### Data Retention
+
+To ensure there is no data loss during pod restarts, the Accumulator window replays data from persistent storage. The
+system stores data until `Outbound(Watermark) - 1`, which means it keeps the minimum necessary data to ensure correctness
+while managing resource usage.
+
+#### Constraints
+
+1. For data older than `Outbound(Watermark) - 1`, users need to bring in an external store and implement replay on restart
+2. Data deletion is based on the `Outbound(Watermark)`
+
+### Few general use cases
+
+1. **Stream Joining**: Combining multiple ordered streams into a single ordered output
+2. **Event Reordering**: Handling out-of-order events and ensuring they're processed in the correct sequence
+3. **Time-based Correlation**: Correlating events from different sources based on their timestamps
+4. **Custom Sorting**: Implementing user-defined sorting logic for event streams
+5. **Custom Triggering**: Triggering actions based on specific conditions or events within the stream
+
+## Configuration
+
+```yaml
+vertices:
+  - name: my-udf
+    udf:
+      groupBy:
+        window:
+          accumulator:
+            timeout: duration
+```
+
+NOTE: A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix,
+such as "300ms", "1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
+
+### timeout
+
+The `timeout` is the duration of inactivity (no data flowing in for a particular key) after which the accumulator state 
+is removed. This helps prevent memory leaks by cleaning up state for keys that are no longer active.
+
+## How It Works
+
+The Accumulator window works by:
+
+1. Maintaining an ordered list of elements for each key
+2. When the watermark progresses, it pops all sorted elements and writes them to the output stream
+3. New elements are inserted into the ordered list based on their event time
+4. If no new data arrives for a key within the specified timeout period, the window is closed
+
+Unlike both `map` or `reduce` operations, where `Datum` is consumed and `Message` is returned, for reordering with the 
+Accumulator, the `Datum` is kept intact.
+
+
+## Example
+
+Here's an [example](https://github.com/numaproj/numaflow/blob/main/examples/13-accumulator-window.yaml) of using an 
+Accumulator window to join and sort two HTTP sources:
+
+```yaml
+apiVersion: numaflow.numaproj.io/v1alpha1
+kind: Pipeline
+metadata:
+  name: simple-accumulator
+spec:
+  vertices:
+    - name: http-one
+      scale:
+        min: 1
+        max: 1
+      source:
+        http: {}
+    - name: http-two
+      scale:
+        min: 1
+        max: 1
+      source:
+        http: {}
+    - name: accum
+      udf:
+        container:
+          # stream sorter example
+          image: quay.io/numaio/numaflow-go/stream-sorter:stable
+        groupBy:
+          window:
+            accumulator:
+              timeout: 10s
+          keyed: true
+          storage:
+            persistentVolumeClaim:
+              volumeSize: 1Gi
+    - name: sink
+      scale:
+        min: 1
+        max: 1
+      sink:
+        log: {}
+  edges:
+    - from: http-one
+      to: accum
+    - from: http-two
+      to: accum
+    - from: accum
+      to: sink
+```
+
+In this example:
+
+1. We have two HTTP sources (`http-one` and `http-two`) that produce ordered streams
+2. The `accum` vertex uses an Accumulator window with a timeout of 10 seconds
+3. The accumulator joins and sorts the events from both sources based on their event time
+4. The sorted output is sent to a log sink
+
+Note: Setting `readBatchSize: 1` helps maintain the ordering of events in the input streams.
+
+Check the links below to see the UDF examples for different languages:
+
+- [Golang](https://github.com/numaproj/numaflow-go/tree/main/pkg/accumulator)
+
diff --git a/docs/user-guide/user-defined-functions/reduce/windowing/fixed.md b/docs/user-guide/user-defined-functions/reduce/windowing/fixed.md
index 53c60cc7..fa778935 100644
--- a/docs/user-guide/user-defined-functions/reduce/windowing/fixed.md
+++ b/docs/user-guide/user-defined-functions/reduce/windowing/fixed.md
@@ -1,7 +1,5 @@
 # Fixed
 
-## Overview
-
 Fixed windows (sometimes called tumbling windows) are defined by a static window size, e.g. 30 second
 windows, one minute windows, etc. They are generally aligned, i.e. every window applies across all
 the data for the corresponding period of time. It has a fixed size measured in time and does not
@@ -11,6 +9,8 @@ certain 20-second interval.
 
 ![plot](../../../../assets/fixed.png)
 
+## Configuration
+
 To enable Fixed window, we use `fixed` under `window` section.
 
 ```yaml
diff --git a/docs/user-guide/user-defined-functions/reduce/windowing/session.md b/docs/user-guide/user-defined-functions/reduce/windowing/session.md
index 37554a65..8fdf3d31 100644
--- a/docs/user-guide/user-defined-functions/reduce/windowing/session.md
+++ b/docs/user-guide/user-defined-functions/reduce/windowing/session.md
@@ -1,13 +1,19 @@
 # Session
 
-## Overview
-
 Session window is a type of Unaligned window where the window’s end time keeps moving until there is no data for a 
 given time duration. Unlike fixed and sliding windows, session windows do not overlap, nor do they have a set start
 and end time. They can be used to group data based on activity.
 
 ![plot](../../../../assets/session.png)
 
+## Window Merge
+There are cases where two session windows can be merged into one. This happens when the end time of one window is greater
+than the start time of the other window. The reason for creating two sessions is that there was a gap (greater than
+the session timeout) between the arrival of the events due to out-of-orderliness at the source. The moment an event that
+arrives in between the two windows arrives, the two windows are merged into one.
+
+## Configuration
+
 ```yaml
 vertices:
   - name: my-udf
diff --git a/docs/user-guide/user-defined-functions/reduce/windowing/sliding.md b/docs/user-guide/user-defined-functions/reduce/windowing/sliding.md
index 0c2b2cd5..c83fba58 100644
--- a/docs/user-guide/user-defined-functions/reduce/windowing/sliding.md
+++ b/docs/user-guide/user-defined-functions/reduce/windowing/sliding.md
@@ -1,7 +1,5 @@
 # Sliding
 
-## Overview
-
 Sliding windows are similar to Fixed windows, the size of the windows is measured in time and is fixed.
 The important difference from the Fixed window is the fact that it allows an element to be present in
 more than one window. The additional window slide parameter controls how frequently a sliding window
@@ -10,6 +8,8 @@ length.
 
 ![plot](../../../../assets/sliding.png)
 
+## Configuration
+
 ```yaml
 vertices:
   - name: my-udf
diff --git a/docs/user-guide/user-defined-functions/reduce/windowing/windowing.md b/docs/user-guide/user-defined-functions/reduce/windowing/windowing.md
index 236fcdb4..893bb70e 100644
--- a/docs/user-guide/user-defined-functions/reduce/windowing/windowing.md
+++ b/docs/user-guide/user-defined-functions/reduce/windowing/windowing.md
@@ -1,7 +1,5 @@
 # Windowing
 
-## Overview
-
 In the world of data processing on an unbounded stream, Windowing is a concept
 of grouping data using temporal boundaries. We use event-time to discover
 temporal boundaries on an unbounded, infinite stream and [Watermark](../../../../core-concepts/watermarks.md) to ensure
@@ -10,6 +8,17 @@ applied on these grouped datasets.
 For example, when we say, we want to find number of users online per minute, we use
 windowing to group the users into one minute buckets.
 
+## Window Types
+
+Numaflow supports the following types of windows
+
+- [Fixed](fixed.md)
+- [Sliding](sliding.md)
+- [Session](session.md)
+- [Accumulator](accumulator.md)
+
+## Configuration
+
 The entirety of windowing is under the `groupBy` section.
 
 ```yaml
@@ -26,14 +35,6 @@ we have an explicit field called `keyed`to differentiate between both (see below
 
 Under the `window` section we will define different types of windows.
 
-## Window Types
-
-Numaflow supports the following types of windows
-
-- [Fixed](fixed.md)
-- [Sliding](sliding.md)
-- [Session](session.md)
-
 ## Non-Keyed v/s Keyed Windows
 
 ### Non-Keyed
diff --git a/examples/22-sqs-source-mvtx.yaml b/examples/22-sqs-source-mvtx.yaml
new file mode 100644
index 00000000..84ae974c
--- /dev/null
+++ b/examples/22-sqs-source-mvtx.yaml
@@ -0,0 +1,22 @@
+apiVersion: numaflow.numaproj.io/v1alpha1
+kind: MonoVertex
+metadata:
+  name: sqs-reader
+spec:
+  source:
+    sqs:
+      queueName: "sqs-numa-test"
+      awsRegion: "us-west-2"
+      queueOwnerAWSAccountID: "123456789012"
+      maxNumberOfMessages: 10
+      visibilityTimeout: 30
+      waitTimeSeconds: 20
+      attributeNames:
+        - All
+      messageAttributeNames:
+        - All
+  sink:
+    log: {}
+  scale:
+    min: 1
+    max: 2
\ No newline at end of file
diff --git a/examples/30-serving-pipeline.yaml b/examples/30-serving-pipeline.yaml
index 277d14d0..07f84929 100644
--- a/examples/30-serving-pipeline.yaml
+++ b/examples/30-serving-pipeline.yaml
@@ -1,37 +1,38 @@
 apiVersion: numaflow.numaproj.io/v1alpha1
-kind: Pipeline
+kind: ServingPipeline
 metadata:
-  name: simple-serving-pipeline
+  name: serving-pipeline
 spec:
-  vertices:
-    - name: serving-in
-      servingStoreName: default
-      scale:
-        min: 1
-      source:
-        serving: {}
-
-    - name: cat
-      scale:
-        min: 1
-      udf:
-        container:
-          image: quay.io/numaio/numaflow-go/map-forward-message:stable
-          env:
-            - name: RUST_BACKTRACE
-              value: "1"
-
-    - name: serve-sink
-      servingStoreName: default
-      scale:
-        min: 1
-      sink:
-        udsink:
+  serving:
+    metadata:
+      annotations:
+        key1: val1
+      labels:
+        key2: val2
+    service: true
+    msgIDHeaderKey: "X-Numaflow-Id"
+  pipeline:
+    limits:
+      readTimeout: 20ms
+    vertices:
+      - name: in
+        scale:
+          min: 1
+        source:
+          serving: {}
+      - name: cat
+        scale:
+          min: 1
+        udf:
           container:
-            image: quay.io/numaio/numaflow-go/sink-serve:stable
-
-  edges:
-    - from: serving-in
-      to: cat
-    - from: cat
-      to: serve-sink
\ No newline at end of file
+            image: quay.io/numaio/numaflow-go/map-forward-message:stable
+      - name: out
+        scale:
+          min: 1
+        sink:
+          serve: {}
+    edges:
+      - from: in
+        to: cat
+      - from: cat
+        to: out
diff --git a/examples/31-serving-pipeline.yaml b/examples/31-serving-pipeline.yaml
deleted file mode 100644
index 0600058b..00000000
--- a/examples/31-serving-pipeline.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-apiVersion: numaflow.numaproj.io/v1alpha1
-kind: ServingPipeline
-metadata:
-  name: serving-pipeline
-spec:
-  serving:
-    service: true
-    msgIDHeaderKey: "X-Numaflow-Id"
-  pipeline:
-    vertices:
-      - name: in
-        source:
-          serving: {}
-      - name: cat
-        udf:
-          container:
-            image: quay.io/numaio/numaflow-go/map-forward-message:stable
-      - name: out
-        sink:
-          serve: {}
-    edges:
-      - from: in
-        to: cat
-      - from: cat
-        to: out
diff --git a/mkdocs.yml b/mkdocs.yml
index a065b2f9..e4944860 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -87,6 +87,7 @@ nav:
                   - Fixed: "user-guide/user-defined-functions/reduce/windowing/fixed.md"
                   - Sliding: "user-guide/user-defined-functions/reduce/windowing/sliding.md"
                   - Session: "user-guide/user-defined-functions/reduce/windowing/session.md"
+                  - Accumulator: "user-guide/user-defined-functions/reduce/windowing/accumulator.md"
               - Examples: "user-guide/user-defined-functions/reduce/examples.md"
       - SDKs:
           - Overview: user-guide/sdks/overview.md
diff --git a/pkg/apis/numaflow/v1alpha1/generated.pb.go b/pkg/apis/numaflow/v1alpha1/generated.pb.go
index efc0b753..dbc0d6ee 100644
--- a/pkg/apis/numaflow/v1alpha1/generated.pb.go
+++ b/pkg/apis/numaflow/v1alpha1/generated.pb.go
@@ -2542,10 +2542,38 @@ func (m *Source) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_Source proto.InternalMessageInfo
 
+func (m *SqsSource) Reset()      { *m = SqsSource{} }
+func (*SqsSource) ProtoMessage() {}
+func (*SqsSource) Descriptor() ([]byte, []int) {
+	return fileDescriptor_9d0d1b17d3865563, []int{89}
+}
+func (m *SqsSource) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *SqsSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *SqsSource) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SqsSource.Merge(m, src)
+}
+func (m *SqsSource) XXX_Size() int {
+	return m.Size()
+}
+func (m *SqsSource) XXX_DiscardUnknown() {
+	xxx_messageInfo_SqsSource.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SqsSource proto.InternalMessageInfo
+
 func (m *Status) Reset()      { *m = Status{} }
 func (*Status) ProtoMessage() {}
 func (*Status) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{89}
+	return fileDescriptor_9d0d1b17d3865563, []int{90}
 }
 func (m *Status) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2573,7 +2601,7 @@ var xxx_messageInfo_Status proto.InternalMessageInfo
 func (m *TLS) Reset()      { *m = TLS{} }
 func (*TLS) ProtoMessage() {}
 func (*TLS) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{90}
+	return fileDescriptor_9d0d1b17d3865563, []int{91}
 }
 func (m *TLS) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2601,7 +2629,7 @@ var xxx_messageInfo_TLS proto.InternalMessageInfo
 func (m *TagConditions) Reset()      { *m = TagConditions{} }
 func (*TagConditions) ProtoMessage() {}
 func (*TagConditions) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{91}
+	return fileDescriptor_9d0d1b17d3865563, []int{92}
 }
 func (m *TagConditions) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2629,7 +2657,7 @@ var xxx_messageInfo_TagConditions proto.InternalMessageInfo
 func (m *Templates) Reset()      { *m = Templates{} }
 func (*Templates) ProtoMessage() {}
 func (*Templates) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{92}
+	return fileDescriptor_9d0d1b17d3865563, []int{93}
 }
 func (m *Templates) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2657,7 +2685,7 @@ var xxx_messageInfo_Templates proto.InternalMessageInfo
 func (m *Transformer) Reset()      { *m = Transformer{} }
 func (*Transformer) ProtoMessage() {}
 func (*Transformer) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{93}
+	return fileDescriptor_9d0d1b17d3865563, []int{94}
 }
 func (m *Transformer) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2685,7 +2713,7 @@ var xxx_messageInfo_Transformer proto.InternalMessageInfo
 func (m *UDF) Reset()      { *m = UDF{} }
 func (*UDF) ProtoMessage() {}
 func (*UDF) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{94}
+	return fileDescriptor_9d0d1b17d3865563, []int{95}
 }
 func (m *UDF) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2713,7 +2741,7 @@ var xxx_messageInfo_UDF proto.InternalMessageInfo
 func (m *UDSink) Reset()      { *m = UDSink{} }
 func (*UDSink) ProtoMessage() {}
 func (*UDSink) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{95}
+	return fileDescriptor_9d0d1b17d3865563, []int{96}
 }
 func (m *UDSink) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2741,7 +2769,7 @@ var xxx_messageInfo_UDSink proto.InternalMessageInfo
 func (m *UDSource) Reset()      { *m = UDSource{} }
 func (*UDSource) ProtoMessage() {}
 func (*UDSource) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{96}
+	return fileDescriptor_9d0d1b17d3865563, []int{97}
 }
 func (m *UDSource) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2769,7 +2797,7 @@ var xxx_messageInfo_UDSource proto.InternalMessageInfo
 func (m *UDTransformer) Reset()      { *m = UDTransformer{} }
 func (*UDTransformer) ProtoMessage() {}
 func (*UDTransformer) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{97}
+	return fileDescriptor_9d0d1b17d3865563, []int{98}
 }
 func (m *UDTransformer) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2797,7 +2825,7 @@ var xxx_messageInfo_UDTransformer proto.InternalMessageInfo
 func (m *UpdateStrategy) Reset()      { *m = UpdateStrategy{} }
 func (*UpdateStrategy) ProtoMessage() {}
 func (*UpdateStrategy) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{98}
+	return fileDescriptor_9d0d1b17d3865563, []int{99}
 }
 func (m *UpdateStrategy) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2825,7 +2853,7 @@ var xxx_messageInfo_UpdateStrategy proto.InternalMessageInfo
 func (m *Vertex) Reset()      { *m = Vertex{} }
 func (*Vertex) ProtoMessage() {}
 func (*Vertex) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{99}
+	return fileDescriptor_9d0d1b17d3865563, []int{100}
 }
 func (m *Vertex) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2853,7 +2881,7 @@ var xxx_messageInfo_Vertex proto.InternalMessageInfo
 func (m *VertexInstance) Reset()      { *m = VertexInstance{} }
 func (*VertexInstance) ProtoMessage() {}
 func (*VertexInstance) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{100}
+	return fileDescriptor_9d0d1b17d3865563, []int{101}
 }
 func (m *VertexInstance) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2881,7 +2909,7 @@ var xxx_messageInfo_VertexInstance proto.InternalMessageInfo
 func (m *VertexLifecycle) Reset()      { *m = VertexLifecycle{} }
 func (*VertexLifecycle) ProtoMessage() {}
 func (*VertexLifecycle) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{101}
+	return fileDescriptor_9d0d1b17d3865563, []int{102}
 }
 func (m *VertexLifecycle) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2909,7 +2937,7 @@ var xxx_messageInfo_VertexLifecycle proto.InternalMessageInfo
 func (m *VertexLimits) Reset()      { *m = VertexLimits{} }
 func (*VertexLimits) ProtoMessage() {}
 func (*VertexLimits) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{102}
+	return fileDescriptor_9d0d1b17d3865563, []int{103}
 }
 func (m *VertexLimits) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2937,7 +2965,7 @@ var xxx_messageInfo_VertexLimits proto.InternalMessageInfo
 func (m *VertexList) Reset()      { *m = VertexList{} }
 func (*VertexList) ProtoMessage() {}
 func (*VertexList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{103}
+	return fileDescriptor_9d0d1b17d3865563, []int{104}
 }
 func (m *VertexList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2965,7 +2993,7 @@ var xxx_messageInfo_VertexList proto.InternalMessageInfo
 func (m *VertexSpec) Reset()      { *m = VertexSpec{} }
 func (*VertexSpec) ProtoMessage() {}
 func (*VertexSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{104}
+	return fileDescriptor_9d0d1b17d3865563, []int{105}
 }
 func (m *VertexSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2993,7 +3021,7 @@ var xxx_messageInfo_VertexSpec proto.InternalMessageInfo
 func (m *VertexStatus) Reset()      { *m = VertexStatus{} }
 func (*VertexStatus) ProtoMessage() {}
 func (*VertexStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{105}
+	return fileDescriptor_9d0d1b17d3865563, []int{106}
 }
 func (m *VertexStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -3021,7 +3049,7 @@ var xxx_messageInfo_VertexStatus proto.InternalMessageInfo
 func (m *VertexTemplate) Reset()      { *m = VertexTemplate{} }
 func (*VertexTemplate) ProtoMessage() {}
 func (*VertexTemplate) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{106}
+	return fileDescriptor_9d0d1b17d3865563, []int{107}
 }
 func (m *VertexTemplate) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -3049,7 +3077,7 @@ var xxx_messageInfo_VertexTemplate proto.InternalMessageInfo
 func (m *Watermark) Reset()      { *m = Watermark{} }
 func (*Watermark) ProtoMessage() {}
 func (*Watermark) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{107}
+	return fileDescriptor_9d0d1b17d3865563, []int{108}
 }
 func (m *Watermark) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -3077,7 +3105,7 @@ var xxx_messageInfo_Watermark proto.InternalMessageInfo
 func (m *Window) Reset()      { *m = Window{} }
 func (*Window) ProtoMessage() {}
 func (*Window) Descriptor() ([]byte, []int) {
-	return fileDescriptor_9d0d1b17d3865563, []int{108}
+	return fileDescriptor_9d0d1b17d3865563, []int{109}
 }
 func (m *Window) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -3200,6 +3228,7 @@ func init() {
 	proto.RegisterType((*Sink)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.Sink")
 	proto.RegisterType((*SlidingWindow)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SlidingWindow")
 	proto.RegisterType((*Source)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.Source")
+	proto.RegisterType((*SqsSource)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SqsSource")
 	proto.RegisterType((*Status)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.Status")
 	proto.RegisterType((*TLS)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.TLS")
 	proto.RegisterType((*TagConditions)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.TagConditions")
@@ -3228,548 +3257,563 @@ func init() {
 }
 
 var fileDescriptor_9d0d1b17d3865563 = []byte{
-	// 8652 bytes of a gzipped FileDescriptorProto
+	// 8882 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5b, 0x6c, 0x24, 0x59,
-	0x96, 0x50, 0xe7, 0xcb, 0x99, 0x79, 0xd2, 0x8f, 0xaa, 0x5b, 0x8f, 0x76, 0xd5, 0x54, 0x97, 0x6b,
+	0x96, 0xd0, 0xe4, 0xcb, 0x99, 0x79, 0xd2, 0x8f, 0xaa, 0x5b, 0x8f, 0x76, 0xd5, 0x74, 0x97, 0x6b,
 	0xa2, 0xb7, 0x7b, 0x6a, 0xd9, 0x59, 0x9b, 0xf6, 0x4e, 0xf7, 0xf4, 0xcc, 0xec, 0x4c, 0xb7, 0xd3,
-	0x2e, 0x57, 0xb9, 0xca, 0xae, 0xf2, 0x9c, 0xb4, 0xab, 0x7b, 0xa6, 0xd9, 0x69, 0xc2, 0x11, 0xd7,
+	0x2e, 0x57, 0xb9, 0xca, 0xae, 0x72, 0x9f, 0xb4, 0xab, 0x7a, 0xa6, 0x99, 0x69, 0xc2, 0x11, 0xd7,
 	0xe9, 0x68, 0x47, 0x46, 0x64, 0x47, 0x44, 0xba, 0xca, 0xbd, 0x8c, 0x66, 0x77, 0x06, 0xe8, 0x41,
 	0x80, 0x40, 0xfb, 0xc3, 0x4a, 0x68, 0x41, 0x48, 0x48, 0xfb, 0xb1, 0x5a, 0x3e, 0x56, 0x0c, 0x42,
-	0x7c, 0x00, 0xcb, 0x07, 0x0c, 0xb0, 0xc0, 0x08, 0x90, 0x68, 0x04, 0x58, 0x8c, 0x11, 0x42, 0x20,
-	0x81, 0x16, 0x56, 0xc0, 0x52, 0x20, 0x16, 0xdd, 0x57, 0xbc, 0x32, 0xd2, 0x65, 0x67, 0xa4, 0xdd,
-	0xd5, 0x4b, 0xff, 0x45, 0xdc, 0x73, 0xee, 0x39, 0xf7, 0x7d, 0xcf, 0x3d, 0xe7, 0xdc, 0x73, 0xe1,
-	0x76, 0xdb, 0x0a, 0x76, 0x7a, 0x5b, 0xb3, 0x86, 0xdb, 0x99, 0x73, 0x7a, 0x1d, 0xbd, 0xeb, 0xb9,
-	0xef, 0xf1, 0x8f, 0x6d, 0xdb, 0x7d, 0x34, 0xd7, 0xdd, 0x6d, 0xcf, 0xe9, 0x5d, 0xcb, 0x8f, 0x52,
-	0xf6, 0x5e, 0xd1, 0xed, 0xee, 0x8e, 0xfe, 0xca, 0x5c, 0x9b, 0x3a, 0xd4, 0xd3, 0x03, 0x6a, 0xce,
-	0x76, 0x3d, 0x37, 0x70, 0xc9, 0x17, 0x23, 0x42, 0xb3, 0x8a, 0xd0, 0xac, 0xca, 0x36, 0xdb, 0xdd,
-	0x6d, 0xcf, 0x32, 0x42, 0x51, 0x8a, 0x22, 0x74, 0xf5, 0xa7, 0x63, 0x25, 0x68, 0xbb, 0x6d, 0x77,
-	0x8e, 0xd3, 0xdb, 0xea, 0x6d, 0xf3, 0x3f, 0xfe, 0xc3, 0xbf, 0x04, 0x9f, 0xab, 0xda, 0xee, 0xeb,
-	0xfe, 0xac, 0xe5, 0xb2, 0x62, 0xcd, 0x19, 0xae, 0x47, 0xe7, 0xf6, 0xfa, 0xca, 0x72, 0xf5, 0x0b,
-	0x11, 0x4e, 0x47, 0x37, 0x76, 0x2c, 0x87, 0x7a, 0xfb, 0xaa, 0x2e, 0x73, 0x1e, 0xf5, 0xdd, 0x9e,
-	0x67, 0xd0, 0x13, 0xe5, 0xf2, 0xe7, 0x3a, 0x34, 0xd0, 0xb3, 0x78, 0xcd, 0x0d, 0xca, 0xe5, 0xf5,
-	0x9c, 0xc0, 0xea, 0xf4, 0xb3, 0x79, 0xed, 0x69, 0x19, 0x7c, 0x63, 0x87, 0x76, 0xf4, 0xbe, 0x7c,
-	0x3f, 0x33, 0x28, 0x5f, 0x2f, 0xb0, 0xec, 0x39, 0xcb, 0x09, 0xfc, 0xc0, 0x4b, 0x67, 0xd2, 0x7e,
-	0x13, 0xe0, 0xc2, 0xc2, 0x96, 0x1f, 0x78, 0xba, 0x11, 0xac, 0xbb, 0xe6, 0x06, 0xed, 0x74, 0x6d,
-	0x3d, 0xa0, 0x64, 0x17, 0x6a, 0xac, 0x42, 0xa6, 0x1e, 0xe8, 0xd3, 0x85, 0x1b, 0x85, 0x9b, 0x8d,
-	0xf9, 0x85, 0xd9, 0x21, 0x3b, 0x70, 0x76, 0x4d, 0x12, 0x6a, 0x8e, 0x1f, 0x1e, 0xcc, 0xd4, 0xd4,
-	0x1f, 0x86, 0x0c, 0xc8, 0x2f, 0x17, 0x60, 0xdc, 0x71, 0x4d, 0xda, 0xa2, 0x36, 0x35, 0x02, 0xd7,
-	0x9b, 0x2e, 0xde, 0x28, 0xdd, 0x6c, 0xcc, 0x7f, 0x6b, 0x68, 0x8e, 0x19, 0x35, 0x9a, 0xbd, 0x1f,
-	0x63, 0x70, 0xcb, 0x09, 0xbc, 0xfd, 0xe6, 0xc5, 0x1f, 0x1e, 0xcc, 0x3c, 0x77, 0x78, 0x30, 0x33,
-	0x1e, 0x07, 0x61, 0xa2, 0x24, 0x64, 0x13, 0x1a, 0x81, 0x6b, 0xb3, 0x26, 0xb3, 0x5c, 0xc7, 0x9f,
-	0x2e, 0xf1, 0x82, 0x5d, 0x9f, 0x15, 0x4d, 0xcd, 0xd8, 0xcf, 0xb2, 0x31, 0x36, 0xbb, 0xf7, 0xca,
-	0xec, 0x46, 0x88, 0xd6, 0xbc, 0x20, 0x09, 0x37, 0xa2, 0x34, 0x1f, 0xe3, 0x74, 0x08, 0x85, 0x29,
-	0x9f, 0x1a, 0x3d, 0xcf, 0x0a, 0xf6, 0x17, 0x5d, 0x27, 0xa0, 0x8f, 0x83, 0xe9, 0x32, 0x6f, 0xe5,
-	0x97, 0xb3, 0x48, 0xaf, 0xbb, 0x66, 0x2b, 0x89, 0xdd, 0xbc, 0x70, 0x78, 0x30, 0x33, 0x95, 0x4a,
-	0xc4, 0x34, 0x4d, 0xe2, 0xc0, 0x39, 0xab, 0xa3, 0xb7, 0xe9, 0x7a, 0xcf, 0xb6, 0x5b, 0xd4, 0xf0,
-	0x68, 0xe0, 0x4f, 0x57, 0x78, 0x15, 0x6e, 0x66, 0xf1, 0x59, 0x75, 0x0d, 0xdd, 0x7e, 0xb0, 0xf5,
-	0x1e, 0x35, 0x02, 0xa4, 0xdb, 0xd4, 0xa3, 0x8e, 0x41, 0x9b, 0xd3, 0xb2, 0x32, 0xe7, 0x56, 0x52,
-	0x94, 0xb0, 0x8f, 0x36, 0xb9, 0x0d, 0xe7, 0xbb, 0x9e, 0xe5, 0xf2, 0x22, 0xd8, 0xba, 0xef, 0xdf,
-	0xd7, 0x3b, 0x74, 0x7a, 0xec, 0x46, 0xe1, 0x66, 0xbd, 0x79, 0x45, 0x92, 0x39, 0xbf, 0x9e, 0x46,
-	0xc0, 0xfe, 0x3c, 0xe4, 0x26, 0xd4, 0x54, 0xe2, 0x74, 0xf5, 0x46, 0xe1, 0x66, 0x45, 0x8c, 0x1d,
-	0x95, 0x17, 0x43, 0x28, 0x59, 0x86, 0x9a, 0xbe, 0xbd, 0x6d, 0x39, 0x0c, 0xb3, 0xc6, 0x9b, 0xf0,
-	0x5a, 0x56, 0xd5, 0x16, 0x24, 0x8e, 0xa0, 0xa3, 0xfe, 0x30, 0xcc, 0x4b, 0xee, 0x02, 0xf1, 0xa9,
-	0xb7, 0x67, 0x19, 0x74, 0xc1, 0x30, 0xdc, 0x9e, 0x13, 0xf0, 0xb2, 0xd7, 0x79, 0xd9, 0xaf, 0xca,
-	0xb2, 0x93, 0x56, 0x1f, 0x06, 0x66, 0xe4, 0x22, 0x6f, 0xc2, 0x39, 0x39, 0x57, 0xa3, 0x56, 0x00,
-	0x4e, 0xe9, 0x22, 0x6b, 0x48, 0x4c, 0xc1, 0xb0, 0x0f, 0x9b, 0x98, 0x70, 0x4d, 0xef, 0x05, 0x6e,
-	0x87, 0x91, 0x4c, 0x32, 0xdd, 0x70, 0x77, 0xa9, 0x33, 0xdd, 0xb8, 0x51, 0xb8, 0x59, 0x6b, 0xde,
-	0x38, 0x3c, 0x98, 0xb9, 0xb6, 0x70, 0x04, 0x1e, 0x1e, 0x49, 0x85, 0x3c, 0x80, 0xba, 0xe9, 0xf8,
-	0xeb, 0xae, 0x6d, 0x19, 0xfb, 0xd3, 0xe3, 0xbc, 0x80, 0xaf, 0xc8, 0xaa, 0xd6, 0x97, 0xee, 0xb7,
-	0x04, 0xe0, 0xc9, 0xc1, 0xcc, 0xb5, 0xfe, 0x25, 0x75, 0x36, 0x84, 0x63, 0x44, 0x83, 0xac, 0x71,
-	0x82, 0x8b, 0xae, 0xb3, 0x6d, 0xb5, 0xa7, 0x27, 0x78, 0x6f, 0xdc, 0x18, 0x30, 0xa0, 0x97, 0xee,
-	0xb7, 0x04, 0x5e, 0x73, 0x42, 0xb2, 0x13, 0xbf, 0x18, 0x51, 0x20, 0x26, 0x4c, 0xaa, 0xc5, 0x78,
-	0xd1, 0xd6, 0xad, 0x8e, 0x3f, 0x3d, 0xc9, 0x07, 0xef, 0x4f, 0x0c, 0xa0, 0x89, 0x71, 0xe4, 0xe6,
-	0x65, 0x59, 0x95, 0xc9, 0x44, 0xb2, 0x8f, 0x29, 0x9a, 0x57, 0xdf, 0x80, 0xf3, 0x7d, 0x6b, 0x03,
-	0x39, 0x07, 0xa5, 0x5d, 0xba, 0xcf, 0x97, 0xbe, 0x3a, 0xb2, 0x4f, 0x72, 0x11, 0x2a, 0x7b, 0xba,
-	0xdd, 0xa3, 0xd3, 0x45, 0x9e, 0x26, 0x7e, 0xbe, 0x5c, 0x7c, 0xbd, 0xa0, 0x7d, 0x58, 0x86, 0x71,
-	0xb5, 0xe2, 0xb4, 0x2c, 0x67, 0x97, 0xbc, 0x05, 0x25, 0xdb, 0x6d, 0xcb, 0x75, 0xf3, 0x67, 0x87,
-	0x5e, 0xc5, 0x56, 0xdd, 0x76, 0xb3, 0x7a, 0x78, 0x30, 0x53, 0x5a, 0x75, 0xdb, 0xc8, 0x28, 0x12,
-	0x03, 0x2a, 0xbb, 0xfa, 0xf6, 0xae, 0xce, 0xcb, 0xd0, 0x98, 0x6f, 0x0e, 0x4d, 0xfa, 0x1e, 0xa3,
-	0xc2, 0xca, 0xda, 0xac, 0x1f, 0x1e, 0xcc, 0x54, 0xf8, 0x2f, 0x0a, 0xda, 0xc4, 0x85, 0xfa, 0x96,
-	0xad, 0x1b, 0xbb, 0x3b, 0xae, 0x4d, 0xa7, 0x4b, 0x39, 0x19, 0x35, 0x15, 0x25, 0xd1, 0xcd, 0xe1,
-	0x2f, 0x46, 0x3c, 0x88, 0x01, 0x63, 0x3d, 0xd3, 0xb7, 0x9c, 0x5d, 0xb9, 0x06, 0xbe, 0x31, 0x34,
-	0xb7, 0xcd, 0x25, 0x5e, 0x27, 0x38, 0x3c, 0x98, 0x19, 0x13, 0xdf, 0x28, 0x49, 0xb3, 0xa6, 0x63,
-	0x33, 0x95, 0x4e, 0x57, 0x72, 0xd6, 0x88, 0x4d, 0x24, 0x1a, 0x35, 0x1d, 0xff, 0x45, 0x41, 0x5b,
-	0xfb, 0xdd, 0x71, 0x98, 0x54, 0x23, 0xe1, 0x21, 0xf5, 0x02, 0xfa, 0x98, 0xdc, 0x80, 0xb2, 0xc3,
-	0xe6, 0x3f, 0x1f, 0x49, 0xcd, 0x71, 0x39, 0x26, 0xcb, 0x7c, 0xde, 0x73, 0x08, 0xab, 0xbe, 0x18,
-	0x8f, 0xb2, 0x57, 0x87, 0xaf, 0x7e, 0x8b, 0x93, 0x11, 0xd5, 0x17, 0xdf, 0x28, 0x49, 0x93, 0x77,
-	0xa0, 0xcc, 0x5b, 0x58, 0xf4, 0xe7, 0x57, 0x87, 0x67, 0xc1, 0x2a, 0x5e, 0x63, 0x35, 0xe0, 0xad,
-	0xcb, 0x89, 0xb2, 0xf1, 0xde, 0x33, 0xb7, 0x65, 0xef, 0xfd, 0x6c, 0x8e, 0xde, 0x5b, 0x16, 0xe3,
-	0x7d, 0x73, 0x69, 0x19, 0x19, 0x45, 0xf2, 0x67, 0x0a, 0x70, 0xde, 0x70, 0x9d, 0x40, 0x67, 0xc2,
-	0x8c, 0xda, 0xc9, 0x65, 0x0f, 0xde, 0x1d, 0x9a, 0xcf, 0x62, 0x9a, 0x62, 0xf3, 0x12, 0xdb, 0x98,
-	0xfa, 0x92, 0xb1, 0x9f, 0x37, 0xf9, 0xf3, 0x05, 0xb8, 0xc4, 0x36, 0x8c, 0x3e, 0x64, 0xbe, 0xcd,
-	0x8d, 0xb6, 0x54, 0x57, 0x0e, 0x0f, 0x66, 0x2e, 0xad, 0x64, 0x31, 0xc3, 0xec, 0x32, 0xb0, 0xd2,
-	0x5d, 0xd0, 0xfb, 0x65, 0x1f, 0xbe, 0x85, 0x36, 0xe6, 0x57, 0x47, 0x29, 0x4f, 0x35, 0x3f, 0x23,
-	0x87, 0x72, 0x96, 0xf8, 0x88, 0x59, 0xa5, 0x20, 0xb7, 0xa0, 0xba, 0xe7, 0xda, 0xbd, 0x0e, 0xf5,
-	0xa7, 0x6b, 0x7c, 0x1d, 0xbf, 0x9a, 0xb5, 0x8e, 0x3f, 0xe4, 0x28, 0xcd, 0x29, 0x49, 0xbe, 0x2a,
-	0xfe, 0x7d, 0x54, 0x79, 0x89, 0x05, 0x63, 0xb6, 0xd5, 0xb1, 0x02, 0x9f, 0xef, 0xce, 0x8d, 0xf9,
-	0x5b, 0x43, 0x57, 0x4b, 0x4c, 0xd1, 0x55, 0x4e, 0x4c, 0xcc, 0x1a, 0xf1, 0x8d, 0x92, 0x01, 0x5f,
-	0x34, 0x0c, 0xdd, 0x16, 0xbb, 0x77, 0x63, 0xfe, 0x6b, 0xc3, 0x4f, 0x1b, 0x46, 0xa5, 0x39, 0x21,
-	0xeb, 0x54, 0xe1, 0xbf, 0x28, 0x68, 0x93, 0x9f, 0x83, 0xc9, 0x44, 0x6f, 0xfa, 0xd3, 0x0d, 0xde,
-	0x3a, 0x2f, 0x64, 0xb5, 0x4e, 0x88, 0x15, 0x6d, 0x6f, 0x89, 0x11, 0xe2, 0x63, 0x8a, 0x18, 0xb9,
-	0x07, 0x35, 0xdf, 0x32, 0xa9, 0xa1, 0x7b, 0xfe, 0xf4, 0xf8, 0x71, 0x08, 0x9f, 0x93, 0x84, 0x6b,
-	0x2d, 0x99, 0x0d, 0x43, 0x02, 0x64, 0x16, 0xa0, 0xab, 0x7b, 0x81, 0x25, 0xa4, 0xe1, 0x09, 0x2e,
-	0x99, 0x4d, 0x1e, 0x1e, 0xcc, 0xc0, 0x7a, 0x98, 0x8a, 0x31, 0x0c, 0x86, 0xcf, 0xf2, 0xae, 0x38,
-	0xdd, 0x5e, 0x20, 0x76, 0xef, 0xba, 0xc0, 0x6f, 0x85, 0xa9, 0x18, 0xc3, 0x20, 0xbf, 0x5e, 0x80,
-	0xcf, 0x44, 0xbf, 0xfd, 0x93, 0x6c, 0x6a, 0xe4, 0x93, 0x6c, 0xe6, 0xf0, 0x60, 0xe6, 0x33, 0xad,
-	0xc1, 0x2c, 0xf1, 0xa8, 0xf2, 0x90, 0x0f, 0x0b, 0x30, 0xd9, 0xeb, 0x9a, 0x7a, 0x40, 0x5b, 0x01,
-	0x3b, 0x56, 0xb5, 0xf7, 0xa7, 0xcf, 0xf1, 0x22, 0xde, 0x1e, 0x7e, 0x15, 0x4c, 0x90, 0x8b, 0xba,
-	0x39, 0x99, 0x8e, 0x29, 0xb6, 0xda, 0x7b, 0x70, 0x7e, 0xc1, 0x30, 0x7a, 0x9d, 0x9e, 0xad, 0x07,
-	0xae, 0xf7, 0x96, 0xe5, 0x98, 0xee, 0x23, 0xb2, 0x09, 0x55, 0x26, 0x57, 0xba, 0xbd, 0x40, 0x0a,
-	0x23, 0xb3, 0xb1, 0xae, 0x0f, 0x0f, 0x89, 0x51, 0x69, 0xd8, 0x89, 0x8c, 0x0d, 0x86, 0xa5, 0x9e,
-	0x3c, 0xc9, 0x34, 0xd8, 0x0c, 0xdc, 0x10, 0x24, 0x50, 0xd1, 0xd2, 0xde, 0x82, 0x89, 0x85, 0x5e,
-	0xb0, 0xe3, 0x7a, 0xd6, 0x07, 0x1c, 0x8d, 0x2c, 0x43, 0x25, 0xe0, 0x72, 0xa9, 0xe0, 0xf2, 0x52,
-	0xd6, 0x00, 0x13, 0x67, 0x84, 0x7b, 0x74, 0x5f, 0x09, 0x5a, 0x62, 0xff, 0x14, 0x72, 0xaa, 0xc8,
-	0xae, 0xfd, 0xd1, 0x02, 0x54, 0x9b, 0xba, 0xb1, 0xeb, 0x6e, 0x6f, 0x93, 0xb7, 0xa1, 0x66, 0x39,
-	0x01, 0xf5, 0xf6, 0x74, 0x7b, 0xc8, 0xc2, 0x73, 0x51, 0x7f, 0x45, 0xd2, 0xc0, 0x90, 0x1a, 0x99,
-	0x81, 0x8a, 0x1f, 0xd0, 0xae, 0xcf, 0xf7, 0xdb, 0x09, 0xb9, 0x8d, 0xb3, 0x04, 0x14, 0xe9, 0xda,
-	0x5f, 0x2a, 0x40, 0xbd, 0xa9, 0xfb, 0x96, 0xc1, 0x6a, 0x49, 0x16, 0xa1, 0xdc, 0xf3, 0xa9, 0x77,
-	0xb2, 0xba, 0xf1, 0x2d, 0x72, 0xd3, 0xa7, 0x1e, 0xf2, 0xcc, 0xe4, 0x01, 0xd4, 0xba, 0xba, 0xef,
-	0x3f, 0x72, 0x3d, 0x53, 0x6e, 0xf3, 0xc7, 0x24, 0x24, 0xce, 0x3d, 0x32, 0x2b, 0x86, 0x44, 0xb4,
-	0x06, 0x44, 0xc2, 0x94, 0xf6, 0x3b, 0x05, 0xb8, 0xd0, 0xec, 0x6d, 0x6f, 0x53, 0x4f, 0x8a, 0xf9,
-	0x52, 0x80, 0xa6, 0x50, 0xf1, 0xa8, 0x69, 0xf9, 0xb2, 0xec, 0x4b, 0x43, 0x0f, 0x4a, 0x64, 0x54,
-	0xa4, 0xbc, 0xce, 0xdb, 0x8b, 0x27, 0xa0, 0xa0, 0x4e, 0x7a, 0x50, 0x7f, 0x8f, 0x06, 0x7e, 0xe0,
-	0x51, 0xbd, 0x23, 0x6b, 0x77, 0x67, 0x68, 0x56, 0x77, 0x69, 0xd0, 0xe2, 0x94, 0xe2, 0xc7, 0x83,
-	0x30, 0x11, 0x23, 0x4e, 0xda, 0x6f, 0x56, 0x60, 0x7c, 0xd1, 0xed, 0x6c, 0x59, 0x0e, 0x35, 0x6f,
-	0x99, 0x6d, 0x4a, 0xde, 0x85, 0x32, 0x35, 0xdb, 0x54, 0xd6, 0x76, 0x78, 0x21, 0x87, 0x11, 0x8b,
-	0x44, 0x35, 0xf6, 0x87, 0x9c, 0x30, 0x59, 0x85, 0xc9, 0x6d, 0xcf, 0xed, 0x88, 0x7d, 0x63, 0x63,
-	0xbf, 0x2b, 0x0f, 0x03, 0xcd, 0x9f, 0x50, 0x93, 0x74, 0x39, 0x01, 0x7d, 0x72, 0x30, 0x03, 0xd1,
-	0x1f, 0xa6, 0xf2, 0x92, 0xb7, 0x61, 0x3a, 0x4a, 0x09, 0x17, 0xd0, 0x45, 0x76, 0x3e, 0xe3, 0x72,
-	0x5a, 0xa5, 0x79, 0xed, 0xf0, 0x60, 0x66, 0x7a, 0x79, 0x00, 0x0e, 0x0e, 0xcc, 0xcd, 0x96, 0xa5,
-	0x73, 0x11, 0x50, 0x6c, 0x6a, 0x52, 0x3c, 0x1b, 0xd1, 0x6e, 0xc9, 0x0f, 0xb2, 0xcb, 0x29, 0x16,
-	0xd8, 0xc7, 0x94, 0x2c, 0xc3, 0x78, 0xe0, 0xc6, 0xda, 0xab, 0xc2, 0xdb, 0x4b, 0x53, 0x9a, 0x97,
-	0x0d, 0x77, 0x60, 0x6b, 0x25, 0xf2, 0x11, 0x84, 0xcb, 0xea, 0x3f, 0xd5, 0x52, 0x63, 0xbc, 0xa5,
-	0xae, 0x1e, 0x1e, 0xcc, 0x5c, 0xde, 0xc8, 0xc4, 0xc0, 0x01, 0x39, 0xc9, 0x2f, 0x16, 0x60, 0x52,
-	0x81, 0x64, 0x1b, 0x55, 0x47, 0xd9, 0x46, 0x84, 0x8d, 0x88, 0x8d, 0x04, 0x03, 0x4c, 0x31, 0xd4,
-	0x7e, 0x50, 0x85, 0x7a, 0xb8, 0xad, 0x90, 0x17, 0xa1, 0xc2, 0x75, 0x2a, 0xf2, 0xb4, 0x10, 0xca,
-	0x0b, 0x5c, 0xf5, 0x82, 0x02, 0x46, 0x5e, 0x82, 0xaa, 0xe1, 0x76, 0x3a, 0xba, 0x63, 0x72, 0x3d,
-	0x59, 0x5d, 0x2c, 0xd2, 0x8b, 0x22, 0x09, 0x15, 0x8c, 0x5c, 0x83, 0xb2, 0xee, 0xb5, 0x85, 0xca,
-	0xaa, 0x2e, 0xd6, 0xa3, 0x05, 0xaf, 0xed, 0x23, 0x4f, 0x25, 0x5f, 0x82, 0x12, 0x75, 0xf6, 0xa6,
-	0xcb, 0x83, 0xe5, 0xb0, 0x5b, 0xce, 0xde, 0x43, 0xdd, 0x6b, 0x36, 0x64, 0x19, 0x4a, 0xb7, 0x9c,
-	0x3d, 0x64, 0x79, 0xc8, 0x2a, 0x54, 0xa9, 0xb3, 0xc7, 0xfa, 0x5e, 0xea, 0x92, 0x3e, 0x3b, 0x20,
-	0x3b, 0x43, 0x91, 0x47, 0x92, 0x50, 0x9a, 0x93, 0xc9, 0xa8, 0x48, 0x90, 0x6f, 0xc0, 0xb8, 0x10,
-	0xec, 0xd6, 0x58, 0x9f, 0xf8, 0xd3, 0x63, 0x9c, 0xe4, 0xcc, 0x60, 0xc9, 0x90, 0xe3, 0x45, 0xba,
-	0xbb, 0x58, 0xa2, 0x8f, 0x09, 0x52, 0xe4, 0x1b, 0x50, 0x57, 0x47, 0x7d, 0xd5, 0xb3, 0x99, 0x6a,
-	0x2f, 0xa5, 0x1f, 0x40, 0xfa, 0x7e, 0xcf, 0xf2, 0x68, 0x87, 0x3a, 0x81, 0xdf, 0x3c, 0xaf, 0x14,
-	0x21, 0x0a, 0xea, 0x63, 0x44, 0x8d, 0x6c, 0xf5, 0xeb, 0xef, 0x84, 0xf2, 0xe9, 0xc5, 0x01, 0xab,
-	0xfa, 0x10, 0xca, 0xbb, 0x6f, 0xc1, 0x54, 0xa8, 0x60, 0x93, 0x3a, 0x1a, 0xa1, 0x8e, 0xfa, 0x02,
-	0xcb, 0xbe, 0x92, 0x04, 0x3d, 0x39, 0x98, 0x79, 0x21, 0x43, 0x4b, 0x13, 0x21, 0x60, 0x9a, 0x18,
-	0xf9, 0x00, 0x26, 0x3d, 0xaa, 0x9b, 0x96, 0x43, 0x7d, 0x7f, 0xdd, 0x73, 0xb7, 0xf2, 0x4b, 0xb9,
-	0x9c, 0x8a, 0x18, 0xf6, 0x98, 0xa0, 0x8c, 0x29, 0x4e, 0xe4, 0x11, 0x4c, 0xd8, 0xd6, 0x1e, 0x8d,
-	0x58, 0x37, 0x46, 0xc2, 0xfa, 0xfc, 0xe1, 0xc1, 0xcc, 0xc4, 0x6a, 0x9c, 0x30, 0x26, 0xf9, 0x30,
-	0x49, 0xa5, 0xeb, 0x7a, 0x81, 0x12, 0x85, 0x3f, 0x7b, 0xa4, 0x28, 0xbc, 0xee, 0x7a, 0x41, 0x34,
-	0x09, 0xd9, 0x9f, 0x8f, 0x22, 0xbb, 0xf6, 0x57, 0x2b, 0xd0, 0x7f, 0x60, 0x4c, 0x8e, 0xb8, 0xc2,
-	0xa8, 0x47, 0x5c, 0x7a, 0x34, 0x88, 0xbd, 0xe7, 0x75, 0x99, 0x6d, 0x04, 0x23, 0x22, 0x63, 0x54,
-	0x97, 0x46, 0x3d, 0xaa, 0x9f, 0x99, 0x85, 0xa7, 0x7f, 0xf8, 0x8f, 0x7d, 0x7c, 0xc3, 0xbf, 0x7a,
-	0x36, 0xc3, 0x5f, 0xfb, 0x7e, 0x19, 0x26, 0x97, 0x74, 0xda, 0x71, 0x9d, 0xa7, 0xea, 0x0c, 0x0a,
-	0xcf, 0x84, 0xce, 0xe0, 0x26, 0xd4, 0x3c, 0xda, 0xb5, 0x2d, 0x43, 0x17, 0xe2, 0xba, 0x34, 0x04,
-	0xa0, 0x4c, 0xc3, 0x10, 0x3a, 0x40, 0x57, 0x54, 0x7a, 0x26, 0x75, 0x45, 0xe5, 0x8f, 0x5f, 0x57,
-	0xa4, 0xfd, 0x62, 0x11, 0xb8, 0x68, 0x4b, 0x6e, 0x40, 0x99, 0x89, 0x6d, 0x69, 0x0d, 0x25, 0x9f,
-	0x2d, 0x1c, 0x42, 0xae, 0x42, 0x31, 0x70, 0xe5, 0x72, 0x03, 0x12, 0x5e, 0xdc, 0x70, 0xb1, 0x18,
-	0xb8, 0xe4, 0x03, 0x00, 0xc3, 0x75, 0x4c, 0x4b, 0xd9, 0xc7, 0xf2, 0x55, 0x6c, 0xd9, 0xf5, 0x1e,
-	0xe9, 0x9e, 0xb9, 0x18, 0x52, 0x14, 0xda, 0x82, 0xe8, 0x1f, 0x63, 0xdc, 0xc8, 0x1b, 0x30, 0xe6,
-	0x3a, 0xcb, 0x3d, 0xdb, 0xe6, 0x0d, 0x5a, 0x6f, 0x7e, 0xee, 0xf0, 0x60, 0x66, 0xec, 0x01, 0x4f,
-	0x79, 0x72, 0x30, 0x73, 0x45, 0x9c, 0x88, 0xd8, 0xdf, 0x5b, 0x9e, 0x15, 0x58, 0x4e, 0x3b, 0x3c,
-	0x3c, 0xcb, 0x6c, 0xda, 0x2f, 0x15, 0xa0, 0xb1, 0x6c, 0x3d, 0xa6, 0xa6, 0x3c, 0x2f, 0x23, 0x8c,
-	0xd9, 0xd4, 0x69, 0x07, 0x3b, 0x43, 0x9e, 0x38, 0x85, 0x0e, 0x89, 0x53, 0x40, 0x49, 0x89, 0xcc,
-	0x41, 0x5d, 0x9c, 0x57, 0x2c, 0xa7, 0xcd, 0xdb, 0xb0, 0x16, 0xad, 0xf4, 0x2d, 0x05, 0xc0, 0x08,
-	0x47, 0xdb, 0x87, 0xf3, 0x7d, 0xcd, 0x40, 0x4c, 0x28, 0x07, 0x7a, 0x5b, 0x6d, 0x2a, 0xcb, 0x43,
-	0x37, 0xf0, 0x86, 0xde, 0x8e, 0x35, 0x2e, 0x97, 0x0a, 0x37, 0x74, 0x26, 0x15, 0x32, 0xea, 0xda,
-	0xff, 0x29, 0x40, 0x6d, 0xb9, 0xe7, 0x18, 0xfc, 0x50, 0xff, 0x74, 0xcd, 0xb5, 0x12, 0x31, 0x8b,
-	0x99, 0x22, 0x66, 0x0f, 0xc6, 0x76, 0x1f, 0x85, 0x22, 0x68, 0x63, 0x7e, 0x6d, 0xf8, 0x51, 0x21,
-	0x8b, 0x34, 0x7b, 0x8f, 0xd3, 0x13, 0xd6, 0xdb, 0x49, 0x59, 0xa0, 0xb1, 0x7b, 0x6f, 0x71, 0xa6,
-	0x92, 0xd9, 0xd5, 0x2f, 0x41, 0x23, 0x86, 0x76, 0x22, 0x43, 0xce, 0x5f, 0x2b, 0xc3, 0xd8, 0xed,
-	0x56, 0x6b, 0x61, 0x7d, 0x85, 0xbc, 0x0a, 0x0d, 0x69, 0xd8, 0xbb, 0x1f, 0xb5, 0x41, 0x68, 0xd7,
-	0x6d, 0x45, 0x20, 0x8c, 0xe3, 0x31, 0x01, 0xde, 0xa3, 0xba, 0xdd, 0x91, 0x93, 0x25, 0x94, 0x1d,
-	0x90, 0x25, 0xa2, 0x80, 0x11, 0x1d, 0x26, 0x7b, 0x3e, 0xf5, 0x58, 0x13, 0x8a, 0xf3, 0xbe, 0x9c,
-	0x36, 0xc7, 0xd4, 0x08, 0xf0, 0x0d, 0x66, 0x33, 0x41, 0x00, 0x53, 0x04, 0xc9, 0xeb, 0x50, 0xd3,
-	0x7b, 0xc1, 0x0e, 0x3f, 0x72, 0x89, 0xb9, 0x71, 0x8d, 0xdb, 0x3d, 0x65, 0xda, 0x93, 0x83, 0x99,
-	0xf1, 0x7b, 0xd8, 0x7c, 0x55, 0xfd, 0x63, 0x88, 0xcd, 0x0a, 0xa7, 0x74, 0x0c, 0xb2, 0x70, 0x95,
-	0x13, 0x17, 0x6e, 0x3d, 0x41, 0x00, 0x53, 0x04, 0xc9, 0x3b, 0x30, 0xbe, 0x4b, 0xf7, 0x03, 0x7d,
-	0x4b, 0x32, 0x18, 0x3b, 0x09, 0x83, 0x73, 0x4c, 0xe8, 0xbf, 0x17, 0xcb, 0x8e, 0x09, 0x62, 0xc4,
-	0x87, 0x8b, 0xbb, 0xd4, 0xdb, 0xa2, 0x9e, 0x2b, 0xf5, 0x15, 0x92, 0x49, 0xf5, 0x24, 0x4c, 0xa6,
-	0x0f, 0x0f, 0x66, 0x2e, 0xde, 0xcb, 0x20, 0x83, 0x99, 0xc4, 0xb5, 0xff, 0x55, 0x84, 0xa9, 0xdb,
-	0xc2, 0xb3, 0xc2, 0xf5, 0x84, 0xe4, 0x41, 0xae, 0x40, 0xc9, 0xeb, 0xf6, 0xf8, 0xc8, 0x29, 0x09,
-	0xb3, 0x06, 0xae, 0x6f, 0x22, 0x4b, 0x23, 0x6f, 0x43, 0xcd, 0x94, 0x4b, 0x86, 0x54, 0x97, 0x0c,
-	0xa5, 0xda, 0x52, 0x7f, 0x18, 0x52, 0x63, 0x67, 0xc3, 0x8e, 0xdf, 0x6e, 0x59, 0x1f, 0x50, 0xa9,
-	0x41, 0xe0, 0x67, 0xc3, 0x35, 0x91, 0x84, 0x0a, 0xc6, 0x76, 0xd5, 0x5d, 0xba, 0x2f, 0xce, 0xcf,
-	0xe5, 0x68, 0x57, 0xbd, 0x27, 0xd3, 0x30, 0x84, 0x92, 0x19, 0x35, 0x59, 0xd8, 0x28, 0x28, 0x0b,
-	0xdd, 0xcf, 0x43, 0x96, 0x20, 0xe7, 0x0d, 0x5b, 0x32, 0xdf, 0xb3, 0x82, 0x80, 0x7a, 0xb2, 0x1b,
-	0x87, 0x5a, 0x32, 0xef, 0x72, 0x0a, 0x28, 0x29, 0x91, 0x9f, 0x82, 0x3a, 0x27, 0xde, 0xb4, 0xdd,
-	0x2d, 0xde, 0x71, 0x75, 0xa1, 0x05, 0x7a, 0xa8, 0x12, 0x31, 0x82, 0x6b, 0xbf, 0x57, 0x84, 0xcb,
-	0xb7, 0x69, 0x20, 0xa4, 0x9a, 0x25, 0xda, 0xb5, 0xdd, 0x7d, 0x26, 0x4f, 0x23, 0x7d, 0x9f, 0xbc,
-	0x09, 0x60, 0xf9, 0x5b, 0xad, 0x3d, 0x83, 0xcf, 0x03, 0x31, 0x87, 0x6f, 0xc8, 0x29, 0x09, 0x2b,
-	0xad, 0xa6, 0x84, 0x3c, 0x49, 0xfc, 0x61, 0x2c, 0x4f, 0x74, 0x20, 0x2f, 0x1e, 0x71, 0x20, 0x6f,
-	0x01, 0x74, 0x23, 0xa9, 0xbc, 0xc4, 0x31, 0x7f, 0x46, 0xb1, 0x39, 0x89, 0x40, 0x1e, 0x23, 0x93,
-	0x47, 0x4e, 0x76, 0xe0, 0x9c, 0x49, 0xb7, 0xf5, 0x9e, 0x1d, 0x84, 0x27, 0x09, 0x39, 0x89, 0x8f,
-	0x7f, 0x18, 0x09, 0xbd, 0x3e, 0x96, 0x52, 0x94, 0xb0, 0x8f, 0xb6, 0xf6, 0x37, 0x4a, 0x70, 0xf5,
-	0x36, 0x0d, 0x42, 0x1d, 0x9d, 0x5c, 0x1d, 0x5b, 0x5d, 0x6a, 0xb0, 0x5e, 0xf8, 0xb0, 0x00, 0x63,
-	0xb6, 0xbe, 0x45, 0x6d, 0xb6, 0x7b, 0xb1, 0xda, 0xbc, 0x3b, 0xf4, 0x46, 0x30, 0x98, 0xcb, 0xec,
-	0x2a, 0xe7, 0x90, 0xda, 0x1a, 0x44, 0x22, 0x4a, 0xf6, 0x6c, 0x51, 0x37, 0xec, 0x9e, 0x1f, 0x88,
-	0x93, 0x9d, 0x94, 0x27, 0xc3, 0x45, 0x7d, 0x31, 0x02, 0x61, 0x1c, 0x8f, 0xcc, 0x03, 0x18, 0xb6,
-	0x45, 0x9d, 0x80, 0xe7, 0x12, 0xf3, 0x8a, 0xa8, 0xfe, 0x5d, 0x0c, 0x21, 0x18, 0xc3, 0x62, 0xac,
-	0x3a, 0xae, 0x63, 0x05, 0xae, 0x60, 0x55, 0x4e, 0xb2, 0x5a, 0x8b, 0x40, 0x18, 0xc7, 0xe3, 0xd9,
-	0x68, 0xe0, 0x59, 0x86, 0xcf, 0xb3, 0x55, 0x52, 0xd9, 0x22, 0x10, 0xc6, 0xf1, 0xd8, 0x9e, 0x17,
-	0xab, 0xff, 0x89, 0xf6, 0xbc, 0x5f, 0xab, 0xc3, 0xf5, 0x44, 0xb3, 0x06, 0x7a, 0x40, 0xb7, 0x7b,
-	0x76, 0x8b, 0x06, 0xaa, 0x03, 0x87, 0xdc, 0x0b, 0xff, 0x64, 0xd4, 0xef, 0xc2, 0x9f, 0xcb, 0x18,
-	0x4d, 0xbf, 0xf7, 0x15, 0xf0, 0x58, 0x7d, 0x3f, 0x07, 0x75, 0x47, 0x0f, 0x7c, 0x3e, 0x71, 0xe5,
-	0x1c, 0x0d, 0xc5, 0xb0, 0xfb, 0x0a, 0x80, 0x11, 0x0e, 0x59, 0x87, 0x8b, 0xb2, 0x89, 0x6f, 0x3d,
-	0x66, 0x67, 0x7e, 0xea, 0x89, 0xbc, 0x72, 0x3b, 0x95, 0x79, 0x2f, 0xae, 0x65, 0xe0, 0x60, 0x66,
-	0x4e, 0xb2, 0x06, 0x17, 0x0c, 0xe1, 0xe3, 0x42, 0x6d, 0x57, 0x37, 0x15, 0x41, 0xa1, 0x12, 0x0d,
-	0x8f, 0x46, 0x8b, 0xfd, 0x28, 0x98, 0x95, 0x2f, 0x3d, 0x9a, 0xc7, 0x86, 0x1a, 0xcd, 0xd5, 0x61,
-	0x46, 0x73, 0x6d, 0xb8, 0xd1, 0x5c, 0x3f, 0xde, 0x68, 0x66, 0x2d, 0xcf, 0xdd, 0x29, 0x3c, 0x26,
-	0x9e, 0x88, 0x1d, 0x36, 0xe6, 0x42, 0x15, 0xb6, 0x7c, 0x2b, 0x03, 0x07, 0x33, 0x73, 0x92, 0x2d,
-	0xb8, 0x2a, 0xd2, 0x6f, 0x39, 0x86, 0xb7, 0xdf, 0x65, 0x1b, 0x4f, 0x8c, 0x6e, 0x23, 0xa1, 0x93,
-	0xbe, 0xda, 0x1a, 0x88, 0x89, 0x47, 0x50, 0x21, 0x5f, 0x81, 0x09, 0xd1, 0x4b, 0x6b, 0x7a, 0x97,
-	0x93, 0x15, 0x0e, 0x55, 0x97, 0x24, 0xd9, 0x89, 0xc5, 0x38, 0x10, 0x93, 0xb8, 0x64, 0x01, 0xa6,
-	0xba, 0x7b, 0x06, 0xfb, 0x5c, 0xd9, 0xbe, 0x4f, 0xa9, 0x49, 0x4d, 0x6e, 0x5c, 0xad, 0x37, 0x9f,
-	0x57, 0xda, 0x9d, 0xf5, 0x24, 0x18, 0xd3, 0xf8, 0xe4, 0x75, 0x18, 0xf7, 0x03, 0xdd, 0x0b, 0xa4,
-	0x22, 0x78, 0x7a, 0x52, 0x38, 0x9c, 0x29, 0x3d, 0x69, 0x2b, 0x06, 0xc3, 0x04, 0x66, 0xe6, 0x7e,
-	0x31, 0x75, 0x7a, 0xfb, 0x45, 0x9e, 0xd5, 0xea, 0xef, 0x15, 0xe1, 0xc6, 0x6d, 0x1a, 0xac, 0xb9,
-	0x8e, 0x54, 0xa3, 0x67, 0x6d, 0xfb, 0xc7, 0xd2, 0xa2, 0x27, 0x37, 0xed, 0xe2, 0x48, 0x37, 0xed,
-	0xd2, 0x88, 0x36, 0xed, 0xf2, 0x29, 0x6e, 0xda, 0x7f, 0xb3, 0x08, 0xcf, 0x27, 0x5a, 0x72, 0xdd,
-	0x35, 0xd5, 0x82, 0xff, 0x69, 0x03, 0x1e, 0xa3, 0x01, 0x9f, 0x08, 0xb9, 0x93, 0x1b, 0x42, 0x53,
-	0x12, 0xcf, 0xf7, 0xd2, 0x12, 0xcf, 0x3b, 0x79, 0x76, 0xbe, 0x0c, 0x0e, 0xc7, 0xda, 0xf1, 0xee,
-	0x02, 0xf1, 0xa4, 0xd9, 0x36, 0x52, 0x67, 0x4b, 0xa1, 0x27, 0xf4, 0x68, 0xc5, 0x3e, 0x0c, 0xcc,
-	0xc8, 0x45, 0x5a, 0x70, 0xc9, 0xa7, 0x4e, 0x60, 0x39, 0xd4, 0x4e, 0x92, 0x13, 0xd2, 0xd0, 0x0b,
-	0x92, 0xdc, 0xa5, 0x56, 0x16, 0x12, 0x66, 0xe7, 0xcd, 0xb3, 0x0e, 0xfc, 0x16, 0x70, 0x91, 0x53,
-	0x34, 0xcd, 0xc8, 0x24, 0x96, 0x0f, 0xd3, 0x12, 0xcb, 0xbb, 0xf9, 0xfb, 0x6d, 0x38, 0x69, 0x65,
-	0x1e, 0x80, 0xf7, 0x42, 0x5c, 0x5c, 0x09, 0x37, 0x69, 0x0c, 0x21, 0x18, 0xc3, 0x62, 0x1b, 0x90,
-	0x6a, 0xe7, 0xb8, 0xa4, 0x12, 0x6e, 0x40, 0xad, 0x38, 0x10, 0x93, 0xb8, 0x03, 0xa5, 0x9d, 0xca,
-	0xd0, 0xd2, 0xce, 0x5d, 0x20, 0x09, 0xc5, 0xa3, 0xa0, 0x37, 0x96, 0x74, 0xa8, 0x5e, 0xe9, 0xc3,
-	0xc0, 0x8c, 0x5c, 0x03, 0x86, 0x72, 0x75, 0xb4, 0x43, 0xb9, 0x36, 0xfc, 0x50, 0x26, 0xef, 0xc2,
-	0x15, 0xce, 0x4a, 0xb6, 0x4f, 0x92, 0xb0, 0x90, 0x7b, 0x3e, 0x2b, 0x09, 0x5f, 0xc1, 0x41, 0x88,
-	0x38, 0x98, 0x06, 0xeb, 0x1f, 0xc3, 0xa3, 0x26, 0x63, 0xae, 0xdb, 0x83, 0x65, 0xa2, 0xc5, 0x0c,
-	0x1c, 0xcc, 0xcc, 0xc9, 0x86, 0x58, 0xc0, 0x86, 0xa1, 0xbe, 0x65, 0x53, 0x53, 0x3a, 0x94, 0x87,
-	0x43, 0x6c, 0x63, 0xb5, 0x25, 0x21, 0x18, 0xc3, 0xca, 0x12, 0x53, 0xc6, 0x4f, 0x28, 0xa6, 0xdc,
-	0xe6, 0x5a, 0xfa, 0xed, 0x84, 0x34, 0x24, 0x65, 0x9d, 0xf0, 0x8a, 0xc0, 0x62, 0x1a, 0x01, 0xfb,
-	0xf3, 0x70, 0x29, 0xd1, 0xf0, 0xac, 0x6e, 0xe0, 0x27, 0x69, 0x4d, 0xa6, 0xa4, 0xc4, 0x0c, 0x1c,
-	0xcc, 0xcc, 0xc9, 0xe4, 0xf3, 0x1d, 0xaa, 0xdb, 0xc1, 0x4e, 0x92, 0xe0, 0x54, 0x52, 0x3e, 0xbf,
-	0xd3, 0x8f, 0x82, 0x59, 0xf9, 0x32, 0x37, 0xa4, 0x73, 0xcf, 0xa6, 0x58, 0xf5, 0x8f, 0x4a, 0xf0,
-	0xc2, 0x6d, 0x2a, 0xee, 0x08, 0x38, 0xed, 0x75, 0xab, 0x4b, 0x6d, 0xcb, 0xa1, 0xb1, 0x12, 0x91,
-	0x3f, 0x5e, 0x80, 0x71, 0xa1, 0x17, 0x91, 0xde, 0xfd, 0x79, 0xcd, 0x43, 0x19, 0xee, 0x4a, 0x91,
-	0xb0, 0x2a, 0xb4, 0x31, 0xf2, 0x24, 0x94, 0xe0, 0xfb, 0xa9, 0x46, 0xe6, 0x38, 0xb2, 0xc9, 0x77,
-	0x4b, 0x70, 0x85, 0xf5, 0xa7, 0xf2, 0x5c, 0xfc, 0x54, 0x2d, 0xf6, 0x31, 0x74, 0xc2, 0xaf, 0x56,
-	0xe0, 0xc2, 0x6d, 0x1a, 0xf4, 0x49, 0xd7, 0xff, 0x9f, 0x36, 0xff, 0x1a, 0x5c, 0x88, 0x3c, 0x69,
-	0x5b, 0x81, 0xeb, 0x09, 0xd9, 0x2c, 0xa5, 0xfd, 0x68, 0xf5, 0xa3, 0x60, 0x56, 0x3e, 0xf2, 0x0d,
-	0x78, 0xde, 0x17, 0xcb, 0x95, 0xd0, 0xb7, 0x0b, 0xe5, 0x50, 0xec, 0xc2, 0xd9, 0x8c, 0x24, 0xf9,
-	0x7c, 0x2b, 0x1b, 0x0d, 0x07, 0xe5, 0x27, 0xdf, 0x81, 0xf1, 0xae, 0x5c, 0x02, 0x59, 0x9f, 0xe5,
-	0x76, 0x0a, 0x5b, 0x8f, 0x11, 0x8b, 0xd6, 0xb8, 0x78, 0x2a, 0x26, 0x18, 0x66, 0x8e, 0xd4, 0xda,
-	0x29, 0x8e, 0xd4, 0xff, 0x56, 0x84, 0xea, 0x6d, 0xcf, 0xed, 0x75, 0x9b, 0xfb, 0xa4, 0x0d, 0x63,
-	0x8f, 0xb8, 0x31, 0x54, 0xae, 0xf0, 0xc3, 0xdf, 0x46, 0x11, 0x36, 0xd5, 0x48, 0xc4, 0x15, 0xff,
-	0x28, 0xc9, 0xb3, 0x41, 0xbc, 0x4b, 0xf7, 0xa9, 0x29, 0x6d, 0xa2, 0xe1, 0x20, 0xbe, 0xc7, 0x12,
-	0x51, 0xc0, 0x48, 0x07, 0xa6, 0x74, 0xdb, 0x76, 0x1f, 0x51, 0x73, 0x55, 0x0f, 0xb8, 0x1f, 0x83,
-	0xb4, 0x95, 0x9d, 0xd4, 0xcc, 0xc0, 0x9d, 0x53, 0x16, 0x92, 0xa4, 0x30, 0x4d, 0x9b, 0xbc, 0x07,
-	0x55, 0x3f, 0x70, 0x3d, 0x25, 0x3c, 0x37, 0xe6, 0x17, 0x87, 0xef, 0xf4, 0xe6, 0xd7, 0x5b, 0x82,
-	0x94, 0xb0, 0xc1, 0xc8, 0x1f, 0x54, 0x0c, 0xb4, 0x5f, 0x29, 0x00, 0xdc, 0xd9, 0xd8, 0x58, 0x97,
-	0xe6, 0x22, 0x13, 0xca, 0x7a, 0x2f, 0x34, 0x3c, 0x0f, 0x6f, 0xe0, 0x4d, 0x38, 0x66, 0x4b, 0x9b,
-	0x6c, 0x2f, 0xd8, 0x41, 0x4e, 0x9d, 0xfc, 0x24, 0x54, 0xe5, 0x81, 0x47, 0x36, 0x7b, 0xe8, 0x1f,
-	0x23, 0x77, 0x62, 0x54, 0x70, 0xed, 0x37, 0x8a, 0x00, 0x2b, 0xa6, 0x4d, 0x5b, 0xea, 0x02, 0x51,
-	0x3d, 0xd8, 0xf1, 0xa8, 0xbf, 0xe3, 0xda, 0xe6, 0x90, 0xd6, 0x71, 0x6e, 0xc3, 0xd9, 0x50, 0x44,
-	0x30, 0xa2, 0x47, 0x4c, 0x18, 0xf7, 0x03, 0xda, 0x55, 0xbe, 0xda, 0x43, 0x1a, 0xc5, 0xce, 0x09,
-	0x3d, 0x57, 0x44, 0x07, 0x13, 0x54, 0x89, 0x0e, 0x0d, 0xcb, 0x31, 0xc4, 0x04, 0x69, 0xee, 0x0f,
-	0x39, 0x90, 0xa6, 0xd8, 0x09, 0x72, 0x25, 0x22, 0x83, 0x71, 0x9a, 0xda, 0x6f, 0x17, 0xe1, 0x32,
-	0xe7, 0xc7, 0x8a, 0x91, 0x10, 0x71, 0xc8, 0x1f, 0xee, 0xbb, 0x51, 0xfd, 0x07, 0x8f, 0xc7, 0x5a,
-	0x5c, 0xc8, 0x5d, 0xa3, 0x81, 0x1e, 0xc9, 0xe7, 0x51, 0x5a, 0xec, 0x1a, 0x75, 0x0f, 0xca, 0x3e,
-	0x5b, 0xaf, 0x44, 0xeb, 0xb5, 0x86, 0x1e, 0x42, 0xd9, 0x15, 0xe0, 0xab, 0x57, 0xe8, 0x05, 0xc0,
-	0x57, 0x2d, 0xce, 0x8e, 0x7c, 0x1b, 0xc6, 0xfc, 0x40, 0x0f, 0x7a, 0x6a, 0x6a, 0x6e, 0x8e, 0x9a,
-	0x31, 0x27, 0x1e, 0xad, 0x23, 0xe2, 0x1f, 0x25, 0x53, 0xed, 0xb7, 0x0b, 0x70, 0x35, 0x3b, 0xe3,
-	0xaa, 0xe5, 0x07, 0xe4, 0x0f, 0xf5, 0x35, 0xfb, 0x31, 0x7b, 0x9c, 0xe5, 0xe6, 0x8d, 0x1e, 0xde,
-	0x87, 0x51, 0x29, 0xb1, 0x26, 0x0f, 0xa0, 0x62, 0x05, 0xb4, 0xa3, 0xf4, 0x05, 0x0f, 0x46, 0x5c,
-	0xf5, 0xd8, 0xd6, 0xce, 0xb8, 0xa0, 0x60, 0xa6, 0x7d, 0xbf, 0x38, 0xa8, 0xca, 0x7c, 0xfb, 0xb0,
-	0x93, 0x5e, 0xff, 0xf7, 0xf2, 0x79, 0xfd, 0x27, 0x0b, 0xd4, 0xef, 0xfc, 0xff, 0x47, 0xfa, 0x9d,
-	0xff, 0x1f, 0xe4, 0x77, 0xfe, 0x4f, 0x35, 0xc3, 0xc0, 0x3b, 0x00, 0x1f, 0x95, 0xe0, 0xda, 0x51,
-	0xc3, 0x86, 0xed, 0x67, 0x72, 0x74, 0xe6, 0xdd, 0xcf, 0x8e, 0x1e, 0x87, 0x64, 0x1e, 0x2a, 0xdd,
-	0x1d, 0xdd, 0x57, 0x42, 0xd9, 0xb5, 0xd0, 0x6d, 0x94, 0x25, 0x3e, 0x61, 0x8b, 0x06, 0x17, 0xe6,
-	0xf8, 0x2f, 0x0a, 0x54, 0xb6, 0x1c, 0x77, 0xa8, 0xef, 0x47, 0x3a, 0x9e, 0x70, 0x39, 0x5e, 0x13,
-	0xc9, 0xa8, 0xe0, 0x24, 0x80, 0x31, 0x61, 0x32, 0x90, 0x3b, 0xd3, 0x68, 0x4f, 0x5e, 0x61, 0xa5,
-	0xe4, 0x99, 0x4b, 0xf2, 0x22, 0xb3, 0x50, 0x0e, 0x22, 0xb7, 0x7d, 0xa5, 0x6a, 0x29, 0x67, 0xc8,
-	0xa7, 0x1c, 0x8f, 0xdc, 0x05, 0xe2, 0x6e, 0x71, 0x23, 0x89, 0x29, 0xfd, 0x21, 0x2c, 0xd7, 0xe1,
-	0x02, 0x59, 0x29, 0x52, 0xd4, 0x3c, 0xe8, 0xc3, 0xc0, 0x8c, 0x5c, 0xda, 0x3f, 0xa9, 0xc1, 0xe5,
-	0xec, 0xf1, 0xc0, 0xda, 0x6d, 0x8f, 0x7a, 0x3e, 0xa3, 0x5d, 0x48, 0xb6, 0xdb, 0x43, 0x91, 0x8c,
-	0x0a, 0xfe, 0x89, 0x76, 0x20, 0xfc, 0xd5, 0x02, 0x5c, 0xf1, 0xa4, 0xcd, 0xef, 0x2c, 0x9c, 0x08,
-	0x5f, 0x10, 0xea, 0xa9, 0x01, 0x0c, 0x71, 0x70, 0x59, 0xc8, 0x5f, 0x2e, 0xc0, 0x74, 0x27, 0xa5,
-	0xb7, 0x3a, 0xc5, 0xfb, 0xba, 0xfc, 0x5e, 0xcc, 0xda, 0x00, 0x7e, 0x38, 0xb0, 0x24, 0xe4, 0x3b,
-	0xd0, 0xe8, 0xb2, 0x71, 0xe1, 0x07, 0xd4, 0x31, 0x94, 0xc3, 0xef, 0xf0, 0x33, 0x69, 0x3d, 0xa2,
-	0x15, 0xde, 0xd7, 0xe3, 0xf2, 0x41, 0x0c, 0x80, 0x71, 0x8e, 0xcf, 0xf8, 0x05, 0xdd, 0x9b, 0x50,
-	0xf3, 0x69, 0x10, 0x58, 0x4e, 0x5b, 0x9c, 0x37, 0xea, 0x62, 0xae, 0xb4, 0x64, 0x1a, 0x86, 0x50,
-	0xf2, 0x53, 0x50, 0xe7, 0x26, 0xc4, 0x05, 0xaf, 0xed, 0x4f, 0xd7, 0xb9, 0xfb, 0xdf, 0x84, 0x70,
-	0x68, 0x94, 0x89, 0x18, 0xc1, 0xc9, 0x17, 0x60, 0x7c, 0x8b, 0x4f, 0x5f, 0xa9, 0x3a, 0x12, 0x3a,
-	0x4b, 0x2e, 0xad, 0x35, 0x63, 0xe9, 0x98, 0xc0, 0x22, 0xf3, 0x00, 0x34, 0xb4, 0xb3, 0xa6, 0xf5,
-	0x93, 0x91, 0x05, 0x16, 0x63, 0x58, 0xe4, 0x05, 0x28, 0x05, 0xb6, 0xcf, 0x75, 0x92, 0xb5, 0xe8,
-	0x08, 0xba, 0xb1, 0xda, 0x42, 0x96, 0xae, 0xfd, 0x5e, 0x01, 0xa6, 0x52, 0xd7, 0xcb, 0x58, 0x96,
-	0x9e, 0x67, 0xcb, 0x65, 0x24, 0xcc, 0xb2, 0x89, 0xab, 0xc8, 0xd2, 0xc9, 0xbb, 0x52, 0x2c, 0x2f,
-	0xe6, 0x8c, 0x81, 0x73, 0x5f, 0x0f, 0x7c, 0x26, 0x87, 0xf7, 0x49, 0xe4, 0xdc, 0x6c, 0x1b, 0x95,
-	0x47, 0xee, 0x03, 0x31, 0xb3, 0x6d, 0x04, 0xc3, 0x04, 0x66, 0x4a, 0x81, 0x5b, 0x3e, 0x8e, 0x02,
-	0x57, 0xfb, 0xa5, 0x62, 0xac, 0x05, 0xa4, 0x64, 0xff, 0x94, 0x16, 0x78, 0x99, 0x6d, 0xa0, 0xe1,
-	0xe6, 0x5e, 0x8f, 0xef, 0x7f, 0x7c, 0x33, 0x96, 0x50, 0xf2, 0x96, 0x68, 0xfb, 0x52, 0xce, 0x20,
-	0x00, 0x1b, 0xab, 0x2d, 0xe1, 0x2d, 0xa7, 0x7a, 0x2d, 0xec, 0x82, 0xf2, 0x29, 0x75, 0x81, 0xf6,
-	0x0f, 0x4a, 0xd0, 0xb8, 0xeb, 0x6e, 0x7d, 0x42, 0x3c, 0xe2, 0xb3, 0xb7, 0xa9, 0xe2, 0xc7, 0xb8,
-	0x4d, 0x6d, 0xc2, 0xf3, 0x41, 0x60, 0xb7, 0xa8, 0xe1, 0x3a, 0xa6, 0xbf, 0xb0, 0x1d, 0x50, 0x6f,
-	0xd9, 0x72, 0x2c, 0x7f, 0x87, 0x9a, 0xd2, 0x3c, 0xf8, 0x99, 0xc3, 0x83, 0x99, 0xe7, 0x37, 0x36,
-	0x56, 0xb3, 0x50, 0x70, 0x50, 0x5e, 0xbe, 0x6c, 0x88, 0xbb, 0xc0, 0xfc, 0xae, 0x9c, 0xf4, 0xa1,
-	0x12, 0xcb, 0x46, 0x2c, 0x1d, 0x13, 0x58, 0xda, 0xbf, 0x29, 0x42, 0x3d, 0x8c, 0x6e, 0x42, 0x5e,
-	0x82, 0xea, 0x96, 0xe7, 0xee, 0x52, 0x4f, 0x58, 0x62, 0xe5, 0x5d, 0xb9, 0xa6, 0x48, 0x42, 0x05,
-	0x23, 0x2f, 0x42, 0x25, 0x70, 0xbb, 0x96, 0x91, 0x56, 0xa8, 0x6d, 0xb0, 0x44, 0x14, 0x30, 0x3e,
-	0x11, 0xb8, 0x9b, 0x28, 0xaf, 0x55, 0x2d, 0x36, 0x11, 0x78, 0x2a, 0x4a, 0xa8, 0x9a, 0x08, 0xe5,
-	0x91, 0x4f, 0x84, 0x97, 0x43, 0x11, 0xb0, 0x92, 0x9c, 0x89, 0x29, 0xa1, 0xed, 0x1d, 0x28, 0xfb,
-	0xba, 0x6f, 0xcb, 0xed, 0x2d, 0x47, 0xac, 0x8f, 0x85, 0xd6, 0xaa, 0x8c, 0xf5, 0xb1, 0xd0, 0x5a,
-	0x45, 0x4e, 0x54, 0xfb, 0x8d, 0x12, 0x34, 0x44, 0xfb, 0x8a, 0xd5, 0x63, 0x94, 0x2d, 0xfc, 0x06,
-	0x77, 0xa1, 0xf1, 0x7b, 0x1d, 0xea, 0x71, 0x75, 0x94, 0x5c, 0x0c, 0xe3, 0x76, 0xa1, 0x08, 0x18,
-	0xba, 0xd1, 0x44, 0x49, 0xbf, 0xbf, 0x9b, 0x9e, 0x6d, 0x15, 0x3c, 0x42, 0x8f, 0x94, 0x71, 0xa5,
-	0x67, 0x6c, 0xb8, 0x55, 0xdc, 0x8b, 0xc1, 0x30, 0x81, 0xa9, 0xfd, 0xd7, 0x22, 0xd4, 0x57, 0xad,
-	0x6d, 0x6a, 0xec, 0x1b, 0x36, 0x25, 0xdf, 0x82, 0xab, 0x26, 0xb5, 0x29, 0xdb, 0x31, 0x6f, 0x7b,
-	0xba, 0x41, 0xd7, 0xa9, 0x67, 0xf1, 0x08, 0x63, 0x6c, 0x0e, 0x4a, 0x87, 0xe5, 0xeb, 0x87, 0x07,
-	0x33, 0x57, 0x97, 0x06, 0x62, 0xe1, 0x11, 0x14, 0xc8, 0x0a, 0x8c, 0x9b, 0xd4, 0xb7, 0x3c, 0x6a,
-	0xae, 0xc7, 0x0e, 0x44, 0x2f, 0xa9, 0x72, 0x2e, 0xc5, 0x60, 0x4f, 0x0e, 0x66, 0x26, 0x94, 0x22,
-	0x54, 0x9c, 0x8c, 0x12, 0x59, 0xd9, 0xd2, 0xd2, 0xd5, 0x7b, 0x3e, 0xcd, 0x28, 0x67, 0x89, 0x97,
-	0x93, 0x2f, 0x2d, 0xeb, 0xd9, 0x28, 0x38, 0x28, 0x2f, 0xd9, 0x82, 0x69, 0x5e, 0xfe, 0x2c, 0xba,
-	0x65, 0x4e, 0xf7, 0xe5, 0xc3, 0x83, 0x19, 0x6d, 0x89, 0x76, 0x3d, 0x6a, 0xe8, 0x01, 0x35, 0x97,
-	0x06, 0x60, 0xe3, 0x40, 0x3a, 0x5a, 0x05, 0x4a, 0xab, 0x6e, 0x5b, 0xfb, 0x7e, 0x09, 0xc2, 0x90,
-	0x77, 0xe4, 0x4f, 0x14, 0xa0, 0xa1, 0x3b, 0x8e, 0x1b, 0xc8, 0x70, 0x72, 0xc2, 0x3b, 0x04, 0x73,
-	0x47, 0xd6, 0x9b, 0x5d, 0x88, 0x88, 0x0a, 0xc7, 0x82, 0xd0, 0xd9, 0x21, 0x06, 0xc1, 0x38, 0x6f,
-	0xd2, 0x4b, 0xf9, 0x3a, 0xac, 0xe5, 0x2f, 0xc5, 0x31, 0x3c, 0x1b, 0xae, 0x7e, 0x0d, 0xce, 0xa5,
-	0x0b, 0x7b, 0x12, 0x53, 0x65, 0x2e, 0xa7, 0x91, 0x22, 0x40, 0xe4, 0xef, 0x74, 0x06, 0x0a, 0x39,
-	0x2b, 0xa1, 0x90, 0x1b, 0x3e, 0x24, 0x48, 0x54, 0xe8, 0x81, 0x4a, 0xb8, 0xf7, 0x53, 0x4a, 0xb8,
-	0x95, 0x51, 0x30, 0x3b, 0x5a, 0xf1, 0xb6, 0x05, 0x17, 0x22, 0xdc, 0x68, 0x75, 0xb9, 0x97, 0x9a,
-	0xfd, 0x42, 0xae, 0xfc, 0xdc, 0x80, 0xd9, 0x3f, 0x15, 0x73, 0x40, 0xeb, 0x9f, 0xff, 0xda, 0x5f,
-	0x29, 0xc0, 0xb9, 0x38, 0x13, 0x1e, 0x53, 0xe0, 0x8b, 0x30, 0xe1, 0x51, 0xdd, 0x6c, 0xea, 0x81,
-	0xb1, 0xc3, 0xaf, 0x3a, 0x14, 0xf8, 0xdd, 0x04, 0x7e, 0xfb, 0x11, 0xe3, 0x00, 0x4c, 0xe2, 0x11,
-	0x1d, 0x1a, 0x2c, 0x41, 0xc6, 0x33, 0x19, 0x52, 0xcb, 0xcc, 0x0f, 0x78, 0x18, 0x91, 0xc1, 0x38,
-	0x4d, 0xed, 0xa3, 0x02, 0x4c, 0xc6, 0x0b, 0x7c, 0xea, 0x1a, 0xc8, 0x9d, 0xa4, 0x06, 0x72, 0x71,
-	0x04, 0xfd, 0x3e, 0x40, 0xeb, 0xf8, 0xdd, 0x46, 0xbc, 0x6a, 0x5c, 0xd3, 0x18, 0x57, 0xae, 0x14,
-	0x8e, 0x54, 0xae, 0x7c, 0xf2, 0x83, 0x9c, 0x0d, 0x3a, 0x15, 0x94, 0x9f, 0xe1, 0x53, 0xc1, 0xc7,
-	0x19, 0x29, 0x2d, 0x16, 0xed, 0x6b, 0x2c, 0x47, 0xb4, 0xaf, 0x4e, 0x18, 0xed, 0xab, 0x3a, 0xb2,
-	0x85, 0xed, 0x38, 0x11, 0xbf, 0x6a, 0x67, 0x1a, 0xf1, 0xab, 0x7e, 0x5a, 0x11, 0xbf, 0x20, 0x6f,
-	0xc4, 0xaf, 0xef, 0x15, 0x60, 0xd2, 0x4c, 0xdc, 0x18, 0x97, 0xb1, 0x1a, 0x86, 0xdf, 0xce, 0x92,
-	0x17, 0xd0, 0xc5, 0x95, 0xc1, 0x64, 0x1a, 0xa6, 0x58, 0x66, 0xc5, 0xd9, 0x1a, 0xff, 0x58, 0xe2,
-	0x6c, 0x91, 0x6f, 0x43, 0xdd, 0x56, 0x7b, 0x9d, 0x0c, 0x71, 0xba, 0x3a, 0x92, 0x21, 0x29, 0x69,
-	0x46, 0xb7, 0x52, 0xc2, 0x24, 0x8c, 0x38, 0x6a, 0xff, 0xb3, 0x1a, 0xdf, 0x10, 0xcf, 0xda, 0xc6,
-	0xf1, 0x5a, 0xd2, 0xc6, 0x71, 0x23, 0x6d, 0xe3, 0xe8, 0xdb, 0xcd, 0xa5, 0x9d, 0xe3, 0xf3, 0xb1,
-	0x7d, 0xa2, 0xc4, 0x83, 0x6e, 0x85, 0x43, 0x2e, 0x63, 0xaf, 0x58, 0x80, 0x29, 0x29, 0x04, 0x28,
-	0x20, 0x5f, 0x64, 0x27, 0x22, 0x2f, 0xc3, 0xa5, 0x24, 0x18, 0xd3, 0xf8, 0x8c, 0xa1, 0xaf, 0x82,
-	0x49, 0x8b, 0x13, 0x5b, 0x34, 0xc6, 0x55, 0xa0, 0xe7, 0x10, 0x83, 0x9d, 0xee, 0x3c, 0xaa, 0xfb,
-	0xd2, 0x52, 0x11, 0x3b, 0xdd, 0x21, 0x4f, 0x45, 0x09, 0x8d, 0x9b, 0x6b, 0xaa, 0x4f, 0x31, 0xd7,
-	0xe8, 0xd0, 0xb0, 0x75, 0x3f, 0x10, 0x83, 0xc9, 0x94, 0xab, 0xc9, 0x1f, 0x38, 0xde, 0xbe, 0xcf,
-	0x64, 0x89, 0x48, 0x80, 0x5f, 0x8d, 0xc8, 0x60, 0x9c, 0x26, 0x31, 0x61, 0x9c, 0xfd, 0xf2, 0x95,
-	0xc5, 0x5c, 0x08, 0x64, 0x34, 0xc4, 0x93, 0xf0, 0x08, 0x8f, 0x8e, 0xab, 0x31, 0x3a, 0x98, 0xa0,
-	0x3a, 0xc0, 0xa2, 0x03, 0xc3, 0x58, 0x74, 0xc8, 0x57, 0x84, 0xe0, 0xb6, 0x1f, 0x76, 0x6b, 0x83,
-	0x77, 0x6b, 0xe8, 0xa1, 0x8c, 0x71, 0x20, 0x26, 0x71, 0xd9, 0xa8, 0xe8, 0xc9, 0x66, 0x50, 0xd9,
-	0xc7, 0x93, 0xa3, 0x62, 0x33, 0x09, 0xc6, 0x34, 0x3e, 0x59, 0x87, 0x8b, 0x61, 0x52, 0xbc, 0x18,
-	0x13, 0x9c, 0x4e, 0xe8, 0x32, 0xba, 0x99, 0x81, 0x83, 0x99, 0x39, 0xf9, 0x1d, 0xac, 0x9e, 0xe7,
-	0x51, 0x27, 0xb8, 0xa3, 0xfb, 0x3b, 0xd2, 0xf7, 0x34, 0xba, 0x83, 0x15, 0x81, 0x30, 0x8e, 0x47,
-	0xe6, 0x01, 0x04, 0x39, 0x9e, 0x6b, 0x2a, 0xe9, 0xde, 0xbd, 0x19, 0x42, 0x30, 0x86, 0xa5, 0x7d,
-	0xaf, 0x0e, 0x8d, 0xfb, 0x7a, 0x60, 0xed, 0x51, 0x6e, 0x7e, 0x3d, 0x1d, 0x1b, 0xd8, 0x5f, 0x28,
-	0xc0, 0xe5, 0xa4, 0xcf, 0xf4, 0x29, 0x1a, 0xc2, 0x78, 0xcc, 0x2e, 0xcc, 0xe4, 0x86, 0x03, 0x4a,
-	0xc1, 0x4d, 0x62, 0x7d, 0x2e, 0xd8, 0xa7, 0x6d, 0x12, 0x6b, 0x0d, 0x62, 0x88, 0x83, 0xcb, 0xf2,
-	0x49, 0x31, 0x89, 0x3d, 0xdb, 0x01, 0x6d, 0x53, 0x06, 0xbb, 0xea, 0x33, 0x63, 0xb0, 0xab, 0x3d,
-	0x13, 0x52, 0x7f, 0x37, 0x66, 0xb0, 0xab, 0xe7, 0x74, 0x1c, 0x93, 0xd7, 0x8c, 0x04, 0xb5, 0x41,
-	0x86, 0x3f, 0x1e, 0x21, 0x44, 0x19, 0x52, 0x98, 0xb0, 0xbc, 0xa5, 0xfb, 0x96, 0x21, 0xc5, 0x8e,
-	0x1c, 0x51, 0xc2, 0x55, 0xb0, 0x4d, 0xe1, 0x5f, 0xc2, 0x7f, 0x51, 0xd0, 0x8e, 0x62, 0x8b, 0x16,
-	0x73, 0xc5, 0x16, 0x25, 0x8b, 0x50, 0x76, 0x76, 0xe9, 0xfe, 0xc9, 0x62, 0x6d, 0xf0, 0x43, 0xe0,
-	0xfd, 0x7b, 0x74, 0x1f, 0x79, 0x66, 0xed, 0x07, 0x45, 0x00, 0x56, 0xfd, 0xe3, 0x99, 0xce, 0x7e,
-	0x12, 0xaa, 0x7e, 0x8f, 0x2b, 0x86, 0xa4, 0xc0, 0x14, 0x79, 0xdb, 0x89, 0x64, 0x54, 0x70, 0xf2,
-	0x22, 0x54, 0xde, 0xef, 0xd1, 0x9e, 0xf2, 0x03, 0x09, 0xcf, 0x0d, 0x5f, 0x67, 0x89, 0x28, 0x60,
-	0xa7, 0xa7, 0xde, 0x56, 0x26, 0xb6, 0xca, 0x69, 0x99, 0xd8, 0xea, 0x50, 0xbd, 0xef, 0x72, 0xe7,
-	0x5d, 0xed, 0x3f, 0x15, 0x01, 0x22, 0xe7, 0x48, 0xf2, 0x2b, 0x05, 0xb8, 0x14, 0x4e, 0xb8, 0x40,
-	0x1c, 0xff, 0x78, 0x60, 0xfe, 0xdc, 0xe6, 0xb6, 0xac, 0xc9, 0xce, 0x57, 0xa0, 0xf5, 0x2c, 0x76,
-	0x98, 0x5d, 0x0a, 0x82, 0x50, 0xa3, 0x9d, 0x6e, 0xb0, 0xbf, 0x64, 0x79, 0x72, 0x04, 0x66, 0xfa,
-	0xe0, 0xde, 0x92, 0x38, 0x22, 0xab, 0xd4, 0x51, 0xf0, 0x49, 0xa4, 0x20, 0x18, 0xd2, 0x21, 0x3b,
-	0x50, 0x73, 0xdc, 0x77, 0x7d, 0xd6, 0x1c, 0x72, 0x38, 0xbe, 0x39, 0x7c, 0x93, 0x8b, 0x66, 0x15,
-	0x66, 0x17, 0xf9, 0x83, 0x55, 0x47, 0x36, 0xf6, 0x2f, 0x17, 0xe1, 0x42, 0x46, 0x3b, 0x90, 0x37,
-	0xe1, 0x9c, 0xf4, 0x43, 0x8d, 0x5e, 0xa8, 0x28, 0x44, 0x2f, 0x54, 0xb4, 0x52, 0x30, 0xec, 0xc3,
-	0x26, 0xef, 0x02, 0xe8, 0x86, 0x41, 0x7d, 0x7f, 0xcd, 0x35, 0xd5, 0x79, 0xe0, 0x0d, 0x26, 0xbe,
-	0x2c, 0x84, 0xa9, 0x4f, 0x0e, 0x66, 0x7e, 0x3a, 0xcb, 0xb5, 0x3c, 0xd5, 0xce, 0x51, 0x06, 0x8c,
-	0x91, 0x24, 0xdf, 0x02, 0x10, 0x3a, 0x80, 0x30, 0x9a, 0xc9, 0x53, 0x14, 0x67, 0xb3, 0x2a, 0x58,
-	0xde, 0xec, 0xd7, 0x7b, 0xba, 0x13, 0x58, 0xc1, 0xbe, 0x08, 0x1e, 0xf5, 0x30, 0xa4, 0x82, 0x31,
-	0x8a, 0xda, 0xdf, 0x2d, 0x42, 0x4d, 0x99, 0x1e, 0xce, 0x40, 0x17, 0xdc, 0x4e, 0xe8, 0x82, 0x47,
-	0xe4, 0x4c, 0x9e, 0xa5, 0x09, 0x76, 0x53, 0x9a, 0xe0, 0xdb, 0xf9, 0x59, 0x1d, 0xad, 0x07, 0xfe,
-	0xf5, 0x22, 0x4c, 0x2a, 0xd4, 0xbc, 0x1a, 0xda, 0xaf, 0xc2, 0x94, 0x70, 0x02, 0x59, 0xd3, 0x1f,
-	0x8b, 0x38, 0x5a, 0xbc, 0xc1, 0xca, 0xc2, 0x7f, 0xbb, 0x99, 0x04, 0x61, 0x1a, 0x97, 0x0d, 0x6b,
-	0x91, 0xb4, 0xc9, 0x0e, 0x61, 0xc2, 0x6c, 0x2c, 0xce, 0x9b, 0x7c, 0x58, 0x37, 0x53, 0x30, 0xec,
-	0xc3, 0x4e, 0xab, 0x88, 0xcb, 0xa7, 0xa0, 0x22, 0xfe, 0xe7, 0x05, 0x18, 0x8f, 0xda, 0xeb, 0xd4,
-	0x15, 0xc4, 0xdb, 0x49, 0x05, 0xf1, 0x42, 0xee, 0xe1, 0x30, 0x40, 0x3d, 0xfc, 0xa7, 0xab, 0x90,
-	0xb8, 0xd3, 0x40, 0xb6, 0xe0, 0xaa, 0x95, 0xe9, 0x99, 0x19, 0x5b, 0x6d, 0xc2, 0xa0, 0x0b, 0x2b,
-	0x03, 0x31, 0xf1, 0x08, 0x2a, 0xa4, 0x07, 0xb5, 0x3d, 0xea, 0x05, 0x96, 0x41, 0x55, 0xfd, 0x6e,
-	0xe7, 0x16, 0xc9, 0xa4, 0x12, 0x3c, 0x6c, 0xd3, 0x87, 0x92, 0x01, 0x86, 0xac, 0xc8, 0x16, 0x54,
-	0xa8, 0xd9, 0xa6, 0x2a, 0xb2, 0x59, 0xce, 0x48, 0xd3, 0x61, 0x7b, 0xb2, 0x3f, 0x1f, 0x05, 0x69,
-	0xe2, 0xc7, 0x15, 0x4d, 0xe5, 0x9c, 0x02, 0xd6, 0x31, 0xd5, 0x4b, 0x64, 0x37, 0xd4, 0xb6, 0x56,
-	0x46, 0xb4, 0x78, 0x1c, 0xa1, 0x6b, 0xf5, 0xa1, 0xfe, 0x48, 0x0f, 0xa8, 0xd7, 0xd1, 0xbd, 0x5d,
-	0x79, 0xda, 0x18, 0xbe, 0x86, 0x6f, 0x29, 0x4a, 0x51, 0x0d, 0xc3, 0x24, 0x8c, 0xf8, 0x10, 0x17,
-	0xea, 0x81, 0x14, 0x9f, 0x95, 0x4a, 0x79, 0x78, 0xa6, 0x4a, 0x10, 0xf7, 0xe5, 0xdd, 0x06, 0xf5,
-	0x8b, 0x11, 0x0f, 0xb2, 0x97, 0x78, 0x02, 0x41, 0x3c, 0x7c, 0x91, 0xe3, 0xf5, 0x19, 0x45, 0x2a,
-	0xda, 0x6e, 0xb2, 0x9f, 0x52, 0xd0, 0xfe, 0x7b, 0x25, 0x5a, 0x96, 0xcf, 0x5a, 0x4f, 0xf8, 0x85,
-	0xa4, 0x9e, 0xf0, 0x7a, 0x5a, 0x4f, 0x98, 0xb2, 0xf9, 0x9f, 0xdc, 0x1b, 0x3a, 0xa5, 0x5e, 0x2b,
-	0x9f, 0x82, 0x7a, 0xed, 0x15, 0x68, 0xec, 0xf1, 0x95, 0x40, 0x84, 0x49, 0xab, 0xf0, 0x6d, 0x84,
-	0xaf, 0xec, 0x0f, 0xa3, 0x64, 0x8c, 0xe3, 0xb0, 0x2c, 0xf2, 0x65, 0xa9, 0x30, 0x32, 0xb9, 0xcc,
-	0xd2, 0x8a, 0x92, 0x31, 0x8e, 0xc3, 0x1d, 0x29, 0x2d, 0x67, 0x57, 0x64, 0xa8, 0xf2, 0x0c, 0xc2,
-	0x91, 0x52, 0x25, 0x62, 0x04, 0x27, 0x37, 0xa1, 0xd6, 0x33, 0xb7, 0x05, 0x6e, 0x8d, 0xe3, 0x72,
-	0x09, 0x73, 0x73, 0x69, 0x59, 0x86, 0x6d, 0x53, 0x50, 0x56, 0x92, 0x8e, 0xde, 0x55, 0x00, 0x7e,
-	0x36, 0x94, 0x25, 0x59, 0x8b, 0x92, 0x31, 0x8e, 0x43, 0xbe, 0x0c, 0x93, 0x1e, 0x35, 0x7b, 0x06,
-	0x0d, 0x73, 0x01, 0xcf, 0x25, 0xe3, 0xd9, 0xc6, 0x21, 0x98, 0xc2, 0x1c, 0xa0, 0x24, 0x6c, 0x0c,
-	0xa5, 0x24, 0xfc, 0x1a, 0x4c, 0x9a, 0x9e, 0x6e, 0x39, 0xd4, 0x7c, 0xe0, 0x70, 0xc7, 0x0e, 0xe9,
-	0xce, 0x19, 0x2a, 0xe8, 0x97, 0x12, 0x50, 0x4c, 0x61, 0x6b, 0xff, 0xb0, 0x08, 0x15, 0x11, 0x65,
-	0x77, 0x05, 0x2e, 0x58, 0x8e, 0x15, 0x58, 0xba, 0xbd, 0x44, 0x6d, 0x7d, 0x3f, 0xee, 0xe0, 0x52,
-	0x69, 0x3e, 0xcf, 0x0e, 0xda, 0x2b, 0xfd, 0x60, 0xcc, 0xca, 0xc3, 0x1a, 0x47, 0x3e, 0x7e, 0xa1,
-	0xa8, 0x08, 0x3d, 0x9a, 0x08, 0xf1, 0x9e, 0x80, 0x60, 0x0a, 0x93, 0x09, 0x43, 0xdd, 0x3e, 0xcf,
-	0x95, 0x8a, 0x10, 0x86, 0x92, 0xce, 0x24, 0x49, 0x3c, 0x2e, 0xa4, 0xf7, 0xb8, 0x40, 0x1c, 0x5e,
-	0x9a, 0x92, 0x4e, 0x70, 0x42, 0x48, 0x4f, 0xc1, 0xb0, 0x0f, 0x9b, 0x51, 0xd8, 0xd6, 0x2d, 0xbb,
-	0xe7, 0xd1, 0x88, 0x42, 0x25, 0xa2, 0xb0, 0x9c, 0x82, 0x61, 0x1f, 0xb6, 0xb6, 0x01, 0xb0, 0xde,
-	0xb3, 0x7d, 0x9d, 0x47, 0x54, 0x1a, 0xd9, 0x3b, 0x1f, 0xbf, 0x5b, 0x84, 0x71, 0x41, 0x56, 0x1e,
-	0xa4, 0xe7, 0x01, 0x64, 0xe0, 0x26, 0xd3, 0xf4, 0xa4, 0x6c, 0x10, 0x2d, 0x70, 0x21, 0x04, 0x63,
-	0x58, 0xc7, 0x73, 0x29, 0x7b, 0x1d, 0xc6, 0x95, 0x8b, 0x18, 0x17, 0x3b, 0x52, 0xee, 0xb5, 0x8b,
-	0x31, 0x18, 0x26, 0x30, 0xc9, 0x12, 0x6b, 0xfd, 0x2d, 0x11, 0x28, 0xc0, 0x72, 0x1d, 0x9e, 0x5b,
-	0x44, 0xd4, 0x08, 0xaf, 0x56, 0xb6, 0x52, 0x70, 0xec, 0xcb, 0x41, 0x3e, 0x0f, 0xb5, 0x8e, 0xfe,
-	0x78, 0xd3, 0xd1, 0x8d, 0x5d, 0xb9, 0x84, 0x84, 0x72, 0xc5, 0x9a, 0x4c, 0xc7, 0x10, 0x83, 0xe8,
-	0xf2, 0x1c, 0x3e, 0x96, 0xf7, 0xf2, 0x61, 0xd8, 0x65, 0x7d, 0x27, 0xf1, 0xff, 0x52, 0x00, 0xd2,
-	0x7f, 0xaf, 0x87, 0xec, 0xc0, 0x98, 0xc3, 0x95, 0xcb, 0xb9, 0x9f, 0x0a, 0x89, 0xe9, 0xa8, 0xc5,
-	0xae, 0x2f, 0x13, 0x24, 0x7d, 0xe2, 0x40, 0x8d, 0x3e, 0x0e, 0xa8, 0xe7, 0x84, 0xf7, 0xfc, 0x46,
-	0xf3, 0x2c, 0x89, 0x38, 0x6c, 0x4b, 0xca, 0x18, 0xf2, 0xd0, 0x7e, 0xa7, 0x08, 0x8d, 0x18, 0xde,
-	0xd3, 0x74, 0x36, 0x3c, 0x74, 0x8c, 0xd0, 0xe9, 0x6e, 0x7a, 0xb6, 0x1c, 0x5b, 0xb1, 0xd0, 0x31,
-	0x12, 0x84, 0xab, 0x18, 0xc7, 0x63, 0x03, 0xb8, 0xa3, 0xfb, 0x41, 0x62, 0x94, 0x85, 0x03, 0x78,
-	0x2d, 0x84, 0x60, 0x0c, 0x8b, 0xdc, 0x90, 0x0f, 0xcb, 0x94, 0x93, 0x01, 0x76, 0x07, 0xbc, 0x1a,
-	0x53, 0x19, 0xc1, 0xab, 0x31, 0xa4, 0x0d, 0xe7, 0x54, 0xa9, 0x15, 0xf4, 0x64, 0xe1, 0x57, 0xc5,
-	0xca, 0x93, 0x22, 0x81, 0x7d, 0x44, 0xb5, 0x1f, 0x14, 0x60, 0x22, 0xa1, 0x51, 0x14, 0xa1, 0x71,
-	0xd5, 0xad, 0xb4, 0x44, 0x68, 0xdc, 0xd8, 0x65, 0xb2, 0x97, 0x61, 0x4c, 0x34, 0x50, 0xda, 0xd9,
-	0x5c, 0x34, 0x21, 0x4a, 0x28, 0x13, 0x15, 0xa4, 0xcd, 0x22, 0x2d, 0x2a, 0x48, 0xa3, 0x06, 0x2a,
-	0xb8, 0x30, 0x05, 0x8a, 0xd2, 0xc9, 0x96, 0x8e, 0x99, 0x02, 0x45, 0x3a, 0x86, 0x18, 0xda, 0xdf,
-	0xe2, 0xe5, 0x0e, 0xbc, 0xfd, 0x50, 0x55, 0xd2, 0x86, 0xaa, 0x74, 0x30, 0x96, 0x53, 0xe3, 0xcd,
-	0x1c, 0x6a, 0x4e, 0x4e, 0x47, 0xba, 0xc8, 0xea, 0xc6, 0xee, 0x83, 0xed, 0x6d, 0x54, 0xd4, 0xc9,
-	0x2d, 0xa8, 0xbb, 0x8e, 0x5c, 0x92, 0x65, 0xf5, 0x3f, 0xc7, 0x44, 0x81, 0x07, 0x2a, 0xf1, 0xc9,
-	0xc1, 0xcc, 0xe5, 0xf0, 0x27, 0x51, 0x48, 0x8c, 0x72, 0x6a, 0x7f, 0xac, 0x00, 0x97, 0xd0, 0xb5,
-	0x6d, 0xcb, 0x69, 0x27, 0x4d, 0xd9, 0xc4, 0x86, 0x49, 0xb1, 0xd2, 0xec, 0xe9, 0x96, 0xad, 0x6f,
-	0xd9, 0xf4, 0xa9, 0xaa, 0x8e, 0x5e, 0x60, 0xd9, 0xb3, 0xe2, 0xe5, 0xe0, 0xd9, 0x15, 0x27, 0x78,
-	0xe0, 0xb5, 0x02, 0xcf, 0x72, 0xda, 0x62, 0xdb, 0x5b, 0x4b, 0xd0, 0xc2, 0x14, 0x6d, 0xed, 0x5f,
-	0x97, 0x81, 0x3b, 0xaf, 0x92, 0x2f, 0x42, 0xbd, 0x43, 0x8d, 0x1d, 0xdd, 0xb1, 0x7c, 0x15, 0x64,
-	0xfc, 0x0a, 0xab, 0xd7, 0x9a, 0x4a, 0x7c, 0xc2, 0xba, 0x62, 0xa1, 0xb5, 0xca, 0xef, 0x91, 0x45,
-	0xb8, 0xc4, 0x80, 0xb1, 0xb6, 0xef, 0xeb, 0x5d, 0x2b, 0xb7, 0xcf, 0x90, 0x08, 0xea, 0x2c, 0x96,
-	0x23, 0xf1, 0x8d, 0x92, 0x34, 0x31, 0xa0, 0xd2, 0xb5, 0x75, 0xcb, 0xc9, 0xfd, 0xd2, 0x25, 0xab,
-	0xc1, 0x3a, 0xa3, 0x24, 0xf6, 0x3b, 0xfe, 0x89, 0x82, 0x36, 0xe9, 0x41, 0xc3, 0x37, 0x3c, 0xbd,
-	0xe3, 0xef, 0xe8, 0xf3, 0xaf, 0xbe, 0x96, 0xfb, 0x34, 0x17, 0xb1, 0x12, 0xc2, 0xe5, 0x22, 0x2e,
-	0xac, 0xb5, 0xee, 0x2c, 0xcc, 0xbf, 0xfa, 0x1a, 0xc6, 0xf9, 0xc4, 0xd9, 0xbe, 0xfa, 0xca, 0x7c,
-	0xfe, 0x97, 0x2f, 0xb3, 0xd9, 0xbe, 0xfa, 0xca, 0x3c, 0xc6, 0xf9, 0xb0, 0x26, 0x75, 0x63, 0xdb,
-	0x58, 0x3e, 0x86, 0x0f, 0x22, 0xb3, 0x00, 0xff, 0x44, 0x41, 0x5b, 0xfb, 0x1f, 0x05, 0xa8, 0x87,
-	0x70, 0xb6, 0x50, 0x8a, 0x70, 0x95, 0x2b, 0x4b, 0x27, 0x93, 0x4d, 0xf8, 0x42, 0xb9, 0x28, 0xb3,
-	0x62, 0x48, 0x84, 0xbc, 0x03, 0xe3, 0xe2, 0x5b, 0x86, 0x8f, 0x2e, 0x9e, 0x38, 0x46, 0xf5, 0x62,
-	0x2c, 0x3b, 0x26, 0x88, 0x91, 0xaf, 0xc0, 0x04, 0x97, 0x83, 0x6e, 0x39, 0x66, 0xd7, 0xb5, 0xe4,
-	0x6b, 0x4f, 0xb1, 0x48, 0x5d, 0x1b, 0x71, 0x20, 0x26, 0x71, 0xc3, 0x8a, 0xf3, 0x9e, 0x20, 0x9b,
-	0x00, 0x6c, 0xa7, 0x90, 0xa5, 0x3c, 0x51, 0xd5, 0xb9, 0x72, 0x74, 0x33, 0xcc, 0x8c, 0x31, 0x42,
-	0x19, 0x51, 0xc0, 0x8b, 0xa3, 0x8e, 0x02, 0x3e, 0x07, 0xf5, 0x1d, 0xdd, 0x31, 0xfd, 0x1d, 0x7d,
-	0x97, 0xca, 0x1b, 0x15, 0xe1, 0xc9, 0xfd, 0x8e, 0x02, 0x60, 0x84, 0xa3, 0xfd, 0x9d, 0x31, 0x10,
-	0x6e, 0x54, 0x6c, 0x49, 0x37, 0x2d, 0x5f, 0xdc, 0x7b, 0x2a, 0xf0, 0x9c, 0xe1, 0x92, 0xbe, 0x24,
-	0xd3, 0x31, 0xc4, 0x20, 0x57, 0xa0, 0xd4, 0xb1, 0x1c, 0x29, 0xb0, 0x73, 0xbb, 0xc7, 0x9a, 0xe5,
-	0x20, 0x4b, 0xe3, 0x20, 0xfd, 0xb1, 0x14, 0xc8, 0x05, 0x48, 0x7f, 0x8c, 0x2c, 0x8d, 0x7c, 0x15,
-	0xa6, 0x6c, 0xd7, 0xdd, 0x65, 0x8b, 0x73, 0xdc, 0x33, 0x7c, 0x42, 0x68, 0x22, 0x57, 0x93, 0x20,
-	0x4c, 0xe3, 0x92, 0x4d, 0x78, 0xfe, 0x03, 0xea, 0xb9, 0x72, 0x37, 0x6a, 0xd9, 0x94, 0x76, 0x15,
-	0x19, 0x21, 0x06, 0x72, 0xc7, 0xf5, 0x6f, 0x66, 0xa3, 0xe0, 0xa0, 0xbc, 0xfc, 0xaa, 0x8d, 0xee,
-	0xb5, 0x69, 0xb0, 0xee, 0xb9, 0x4c, 0xd4, 0xb7, 0x9c, 0xb6, 0x22, 0x3b, 0x16, 0x91, 0xdd, 0xc8,
-	0x46, 0xc1, 0x41, 0x79, 0xc9, 0xdb, 0x30, 0x2d, 0x40, 0x42, 0x28, 0x5c, 0x10, 0x8b, 0xb8, 0x65,
-	0xab, 0xe7, 0xb7, 0x27, 0x84, 0x79, 0x79, 0x63, 0x00, 0x0e, 0x0e, 0xcc, 0x4d, 0xee, 0xc2, 0x39,
-	0xe5, 0x5c, 0xb0, 0x4e, 0xbd, 0x56, 0xe8, 0x5a, 0x37, 0xa1, 0x6e, 0x18, 0x28, 0x0f, 0x7b, 0x4c,
-	0x61, 0x61, 0x5f, 0x3e, 0x82, 0x70, 0x99, 0xfb, 0xcf, 0x6d, 0x76, 0x17, 0x5d, 0xd7, 0x36, 0xdd,
-	0x47, 0x8e, 0xaa, 0xbb, 0x38, 0xdf, 0x72, 0x7f, 0x82, 0x56, 0x26, 0x06, 0x0e, 0xc8, 0xc9, 0x6a,
-	0xce, 0x21, 0x4b, 0xee, 0x23, 0x27, 0x4d, 0x15, 0xa2, 0x9a, 0xb7, 0x06, 0xe0, 0xe0, 0xc0, 0xdc,
-	0x64, 0x19, 0x48, 0xba, 0x06, 0x9b, 0x5d, 0xe9, 0xf1, 0x72, 0x59, 0xc4, 0xab, 0x4b, 0x43, 0x31,
-	0x23, 0x07, 0x59, 0x85, 0x8b, 0xe9, 0x54, 0xc6, 0x4e, 0x3a, 0xbf, 0xf0, 0x48, 0xf5, 0x98, 0x01,
-	0xc7, 0xcc, 0x5c, 0x5a, 0x03, 0xea, 0xe1, 0x03, 0xc6, 0xda, 0xbf, 0x2a, 0xc2, 0x54, 0x2a, 0xe6,
-	0xd7, 0x19, 0x58, 0x42, 0x9c, 0x84, 0x25, 0x64, 0x35, 0xd7, 0x43, 0xcc, 0xb1, 0x92, 0x0f, 0x34,
-	0x88, 0xec, 0xa5, 0x0c, 0x22, 0xf7, 0x47, 0xc6, 0xf1, 0x68, 0xbb, 0xc8, 0x61, 0x01, 0x2e, 0xa4,
-	0x72, 0x9c, 0x81, 0xba, 0xbf, 0x93, 0x54, 0xf7, 0xdf, 0x19, 0x55, 0x65, 0x07, 0x68, 0xfd, 0xff,
-	0x77, 0x7f, 0x25, 0x5b, 0xc2, 0x0a, 0x55, 0x95, 0xe1, 0x95, 0x72, 0x1f, 0x28, 0x55, 0xfc, 0x26,
-	0xd6, 0xbf, 0xc9, 0x70, 0x35, 0x4e, 0x1b, 0x15, 0x17, 0xe2, 0x43, 0x4d, 0xc5, 0x50, 0x1a, 0xad,
-	0x8d, 0x2d, 0x6c, 0xec, 0x30, 0x2c, 0x5e, 0xc8, 0x48, 0xfb, 0x73, 0x25, 0xb8, 0x94, 0x39, 0x28,
-	0xce, 0x4e, 0xd5, 0xfa, 0x95, 0xa4, 0xaa, 0xf5, 0xa5, 0xb4, 0xaa, 0xf5, 0x62, 0xaa, 0x7c, 0xcf,
-	0xb0, 0xc6, 0x75, 0x84, 0x5a, 0x44, 0x6d, 0x0a, 0x26, 0x12, 0x71, 0xbf, 0xb4, 0x7f, 0x56, 0x86,
-	0x46, 0x6c, 0x24, 0x3d, 0x73, 0xf1, 0x96, 0xc8, 0x97, 0x61, 0xb2, 0xe3, 0xb7, 0x57, 0x96, 0xee,
-	0x50, 0xdd, 0xa4, 0x9e, 0xba, 0x66, 0x5a, 0x97, 0x67, 0xad, 0x04, 0x04, 0x53, 0x98, 0x64, 0x15,
-	0x2e, 0x79, 0xf4, 0xfd, 0x1e, 0xf5, 0x83, 0xa4, 0x2e, 0x52, 0x8a, 0x2c, 0x72, 0xbb, 0x49, 0x21,
-	0xf8, 0x98, 0x9d, 0x89, 0x2d, 0x21, 0xc2, 0x37, 0xa1, 0x92, 0x73, 0x1e, 0xa9, 0xf6, 0xe6, 0x0e,
-	0x0a, 0x22, 0x3a, 0x53, 0x2c, 0x05, 0x05, 0x97, 0x01, 0x57, 0x17, 0xc6, 0x3e, 0xc6, 0xab, 0x0b,
-	0x71, 0x7f, 0xc9, 0xea, 0x51, 0xfe, 0x92, 0xda, 0x77, 0x20, 0x51, 0x25, 0xe2, 0x42, 0x3d, 0x24,
-	0x97, 0xdb, 0x2b, 0x2a, 0x72, 0xd0, 0xe7, 0x26, 0x81, 0xf0, 0x17, 0x23, 0x1e, 0xda, 0x36, 0x1b,
-	0xe7, 0xbe, 0x6f, 0xb9, 0xce, 0xe9, 0x3e, 0xf9, 0xfc, 0x2f, 0x8a, 0x50, 0x0f, 0x0d, 0x4d, 0xc7,
-	0x78, 0x1a, 0x2a, 0xd1, 0x10, 0xc5, 0xd3, 0x6f, 0x88, 0xf8, 0x75, 0x93, 0x52, 0x8e, 0xeb, 0x26,
-	0x5d, 0xa8, 0x06, 0x9e, 0xd5, 0x6e, 0x4b, 0xb5, 0x5c, 0x9e, 0xfb, 0x26, 0x61, 0x73, 0x6d, 0x08,
-	0x82, 0xb2, 0x65, 0xc5, 0x0f, 0x2a, 0x36, 0xda, 0x7b, 0x70, 0x2e, 0x8d, 0xc9, 0x75, 0x56, 0xc6,
-	0x0e, 0x35, 0x7b, 0xb6, 0x6a, 0xe3, 0x48, 0x67, 0x25, 0xd3, 0x31, 0xc4, 0x60, 0xc3, 0x95, 0x75,
-	0xd3, 0x07, 0xae, 0xa3, 0x76, 0x01, 0x3e, 0x5c, 0x37, 0x64, 0x1a, 0x86, 0x50, 0xed, 0x3f, 0x96,
-	0xe0, 0x4a, 0x64, 0x2e, 0x5c, 0xd3, 0x1d, 0xbd, 0x9d, 0x74, 0x05, 0xfd, 0x34, 0xee, 0xc1, 0x48,
-	0xde, 0xf7, 0x2b, 0x3d, 0x03, 0xef, 0xfb, 0xfd, 0xdf, 0x22, 0xf0, 0xeb, 0x6b, 0xe4, 0x3b, 0x30,
-	0xae, 0xda, 0x93, 0xfd, 0xcb, 0xee, 0xbc, 0x95, 0xbb, 0x3b, 0xf9, 0x2d, 0xb9, 0xd0, 0x92, 0x12,
-	0x4f, 0xc5, 0x04, 0x43, 0xe2, 0x42, 0x6d, 0x5b, 0xb7, 0x6d, 0x76, 0x3c, 0xce, 0x2d, 0x9a, 0x25,
-	0x98, 0xf3, 0x61, 0xbe, 0x2c, 0x49, 0x63, 0xc8, 0x84, 0x7c, 0xaf, 0x00, 0x13, 0x5e, 0x5c, 0x3f,
-	0x2a, 0x3b, 0x24, 0x8f, 0x73, 0x6c, 0x8c, 0x5a, 0xfc, 0xc2, 0x42, 0x5c, 0x09, 0x9b, 0xe4, 0xa9,
-	0xfd, 0xfb, 0x02, 0x4c, 0xb4, 0x6c, 0xcb, 0xb4, 0x9c, 0xf6, 0x29, 0x3e, 0x2f, 0xf8, 0x00, 0x2a,
-	0xbe, 0x6d, 0x99, 0x74, 0xc8, 0xdb, 0xac, 0xe2, 0xf1, 0x7b, 0x46, 0x00, 0x05, 0x9d, 0xe4, 0x7b,
-	0x85, 0xa5, 0x63, 0xbc, 0x57, 0xf8, 0x1f, 0xaa, 0x20, 0x2f, 0x62, 0x92, 0x1e, 0xd4, 0xdb, 0xea,
-	0x19, 0x34, 0x59, 0xc7, 0x3b, 0x39, 0x42, 0xe8, 0x27, 0x1e, 0x54, 0x13, 0x6b, 0x7f, 0x98, 0x88,
-	0x11, 0x27, 0x42, 0xa1, 0xc2, 0xc3, 0x1d, 0xe4, 0xb6, 0x27, 0xc5, 0x02, 0x5b, 0x88, 0x96, 0xe1,
-	0x09, 0x28, 0xa8, 0x13, 0x1d, 0xca, 0x3b, 0x41, 0xd0, 0x95, 0x83, 0x69, 0x78, 0xeb, 0x5c, 0x14,
-	0xf5, 0x53, 0xc8, 0x8b, 0xec, 0x1f, 0x39, 0x69, 0xc6, 0xc2, 0xd1, 0xc3, 0xb7, 0xda, 0x17, 0x73,
-	0x39, 0xe2, 0xc6, 0x59, 0xb0, 0x7f, 0xe4, 0xa4, 0xc9, 0xcf, 0x43, 0x23, 0xf0, 0x74, 0xc7, 0xdf,
-	0x76, 0xbd, 0x0e, 0xf5, 0xa4, 0x8c, 0x37, 0xfc, 0xcc, 0xd8, 0x5c, 0xda, 0x88, 0xa8, 0x09, 0xa3,
-	0x76, 0x22, 0x09, 0xe3, 0xdc, 0xc8, 0x2e, 0xd4, 0x7a, 0xa6, 0x28, 0x98, 0x94, 0xf0, 0x16, 0x72,
-	0x70, 0x8e, 0xbb, 0xd9, 0xaa, 0x3f, 0x0c, 0x19, 0xb0, 0xd1, 0x18, 0x45, 0x26, 0xac, 0xe6, 0x1c,
-	0x8d, 0xa9, 0xa8, 0x49, 0x83, 0x43, 0x12, 0x92, 0x4e, 0x74, 0xf4, 0xad, 0xe5, 0x6c, 0xdc, 0xc4,
-	0x11, 0x46, 0xc6, 0x91, 0x4d, 0x1f, 0x7c, 0x2d, 0x18, 0xeb, 0x72, 0x73, 0xaf, 0xbc, 0x01, 0x70,
-	0x2b, 0xa7, 0xd5, 0x38, 0x7e, 0xbf, 0x5a, 0xa4, 0xa0, 0x64, 0xa0, 0x75, 0x40, 0x9e, 0x3e, 0x89,
-	0x91, 0x78, 0xf5, 0x55, 0x84, 0xb1, 0x98, 0x3b, 0xde, 0xd2, 0x13, 0x3e, 0x3f, 0x1a, 0x7b, 0x75,
-	0x2a, 0xf3, 0x79, 0x57, 0xed, 0x5f, 0x16, 0xa1, 0xb4, 0xb1, 0xda, 0x12, 0x2f, 0x49, 0xf0, 0x77,
-	0xa4, 0x69, 0x6b, 0xd7, 0xea, 0x3e, 0xa4, 0x9e, 0xb5, 0xbd, 0x2f, 0x15, 0xbf, 0xb1, 0x97, 0x24,
-	0xd2, 0x18, 0x98, 0x91, 0x8b, 0xeb, 0xf5, 0xf5, 0x45, 0xea, 0xe5, 0xd0, 0xeb, 0x2f, 0x44, 0xd9,
-	0x31, 0x41, 0x8c, 0x6c, 0x02, 0x18, 0x11, 0xe9, 0xd2, 0x89, 0x95, 0xf1, 0x31, 0xc2, 0x31, 0x42,
-	0x04, 0xa1, 0xbe, 0xcb, 0x50, 0x39, 0xd5, 0xf2, 0x49, 0xa8, 0xf2, 0x41, 0x7a, 0x4f, 0xe5, 0xc5,
-	0x88, 0x8c, 0xe6, 0xc0, 0x44, 0xe2, 0x29, 0x58, 0xf2, 0x25, 0xa8, 0xb9, 0xdd, 0xd8, 0xca, 0x5d,
-	0xe7, 0x57, 0x9f, 0x6a, 0x0f, 0x64, 0xda, 0x93, 0x83, 0x99, 0x89, 0x55, 0xb7, 0x6d, 0x19, 0x2a,
-	0x01, 0x43, 0x74, 0xa2, 0xc1, 0x18, 0x0f, 0xb2, 0xa1, 0x1e, 0x82, 0xe5, 0x43, 0x87, 0xbf, 0xd5,
-	0xe8, 0xa3, 0x84, 0x68, 0xbf, 0x50, 0x86, 0xc8, 0x3d, 0x8e, 0xf8, 0x30, 0x26, 0x2e, 0xf8, 0xca,
-	0x4d, 0xe2, 0x54, 0xef, 0x12, 0x4b, 0x56, 0xa4, 0x0d, 0xa5, 0xf7, 0xdc, 0xad, 0xdc, 0x7b, 0x44,
-	0x2c, 0x52, 0x98, 0xb0, 0x83, 0xc5, 0x12, 0x90, 0x71, 0x20, 0x7f, 0xb1, 0x00, 0xe7, 0xfd, 0xb4,
-	0x94, 0x2d, 0x87, 0x03, 0xe6, 0x3f, 0x4e, 0xa4, 0xe5, 0x76, 0x79, 0x47, 0x6d, 0x10, 0x18, 0xfb,
-	0xcb, 0xc2, 0xda, 0x5f, 0xf8, 0xad, 0xc9, 0xe1, 0x34, 0x7c, 0xfb, 0x0b, 0x5f, 0xb8, 0x64, 0xfb,
-	0x27, 0xd3, 0x50, 0xb2, 0xd2, 0xbe, 0x5b, 0x84, 0x46, 0x6c, 0x63, 0xc8, 0xfd, 0xbe, 0xf0, 0xe3,
-	0xd4, 0xfb, 0xc2, 0xeb, 0xc3, 0xbb, 0x71, 0x46, 0xa5, 0x3a, 0xed, 0x27, 0x86, 0xff, 0x7e, 0x11,
-	0x4a, 0x9b, 0x4b, 0xcb, 0x67, 0xae, 0x28, 0x20, 0x3b, 0x50, 0xdd, 0xea, 0x59, 0x76, 0x60, 0x39,
-	0xb9, 0x63, 0x19, 0xaa, 0xe7, 0x98, 0xa5, 0x1f, 0x83, 0xa0, 0x8a, 0x8a, 0x3c, 0x69, 0x43, 0xb5,
-	0x2d, 0x82, 0xc9, 0xe7, 0xbe, 0xdc, 0x22, 0x83, 0xd2, 0x0b, 0x46, 0xf2, 0x07, 0x15, 0x75, 0x6d,
-	0x1f, 0xc6, 0x36, 0x97, 0xe4, 0x09, 0xe3, 0x8c, 0xd5, 0x2e, 0x3f, 0x0f, 0xa1, 0xc0, 0x71, 0xf6,
-	0xcc, 0xff, 0x73, 0x01, 0x92, 0x32, 0xd6, 0xd9, 0x8f, 0xa6, 0xdd, 0xf4, 0x68, 0x5a, 0x1a, 0xc5,
-	0xe4, 0xcb, 0x1e, 0x50, 0xda, 0x3f, 0x2d, 0x40, 0x2a, 0x2a, 0x03, 0x79, 0x4d, 0xc6, 0x25, 0x4e,
-	0xde, 0x22, 0x50, 0x71, 0x89, 0x49, 0x12, 0x3b, 0x16, 0x9f, 0xf8, 0x43, 0x76, 0x32, 0x8c, 0x3b,
-	0xc7, 0xc8, 0xe2, 0x0f, 0x6f, 0x13, 0xca, 0x74, 0xb5, 0x91, 0x37, 0x5d, 0xe2, 0x20, 0x4c, 0xf2,
-	0xd5, 0xfe, 0x76, 0x11, 0xc6, 0xce, 0x2c, 0x10, 0x15, 0x4d, 0x98, 0xdc, 0x16, 0x73, 0xae, 0xf6,
-	0x03, 0x2d, 0x6d, 0x9d, 0x94, 0xa5, 0xed, 0x56, 0x5e, 0x46, 0x47, 0x1b, 0xd8, 0xfe, 0x71, 0x01,
-	0xe4, 0x5e, 0xb3, 0xe2, 0xf8, 0x81, 0xee, 0x18, 0x94, 0x18, 0xe1, 0xc6, 0x96, 0xd7, 0xec, 0x22,
-	0x6f, 0x81, 0x08, 0x59, 0x86, 0x7f, 0xab, 0x8d, 0x8c, 0x7c, 0x1e, 0x6a, 0x3b, 0xae, 0x1f, 0xf0,
-	0xcd, 0xab, 0x98, 0xd4, 0xce, 0xdd, 0x91, 0xe9, 0x18, 0x62, 0xa4, 0x5d, 0xd5, 0x2a, 0x83, 0x5d,
-	0xd5, 0xb4, 0x6f, 0xc2, 0x54, 0x3a, 0x9a, 0xd6, 0xed, 0xcc, 0x68, 0x5a, 0x2f, 0x0e, 0x88, 0xa6,
-	0xd5, 0x18, 0x1c, 0x49, 0xeb, 0xd7, 0x8a, 0x30, 0xfe, 0x49, 0x89, 0xa2, 0x95, 0x75, 0x0d, 0xac,
-	0x94, 0xf3, 0x1a, 0x58, 0xf9, 0x24, 0xd7, 0xc0, 0xb4, 0x1f, 0x15, 0x00, 0xce, 0x2c, 0x84, 0x97,
-	0x99, 0x34, 0xd9, 0xe6, 0x1e, 0xb3, 0xd9, 0x96, 0xda, 0xbf, 0x3e, 0xa6, 0xaa, 0xc4, 0xed, 0x5f,
-	0x1f, 0x16, 0x60, 0x52, 0x4f, 0xdc, 0x78, 0xca, 0x2d, 0x8b, 0xa7, 0x2e, 0x50, 0x85, 0x0e, 0xfb,
-	0xc9, 0x74, 0x4c, 0xb1, 0x25, 0xaf, 0x47, 0xcf, 0xed, 0xdc, 0x8f, 0xa6, 0x54, 0xdf, 0x3b, 0x39,
-	0xc2, 0x45, 0x3b, 0x8e, 0xf9, 0x94, 0x1b, 0x66, 0xa5, 0x91, 0xdc, 0x30, 0x8b, 0xdb, 0x82, 0xca,
-	0x47, 0xc6, 0xce, 0xd8, 0x83, 0xfa, 0xb6, 0xe7, 0x76, 0xf8, 0x25, 0xae, 0xe9, 0x0a, 0xef, 0xca,
-	0x5b, 0x39, 0x36, 0xe1, 0xce, 0x96, 0xe5, 0x50, 0x93, 0x5f, 0x10, 0x0b, 0xf5, 0x6f, 0xcb, 0x8a,
-	0x3e, 0x46, 0xac, 0xb8, 0xc9, 0xc2, 0x15, 0x5c, 0xc7, 0x46, 0xc9, 0x35, 0x5c, 0xa7, 0x36, 0x04,
-	0x75, 0x54, 0x6c, 0x92, 0x17, 0xb7, 0xaa, 0x67, 0x74, 0x71, 0x6b, 0x3f, 0x7e, 0x1f, 0xae, 0x96,
-	0x53, 0x9b, 0x73, 0xb2, 0xa0, 0x4b, 0x7f, 0xaa, 0xaa, 0xd6, 0xce, 0x67, 0xee, 0x51, 0x89, 0x4f,
-	0x83, 0x2d, 0xb5, 0x69, 0x5f, 0x24, 0xa4, 0xda, 0x19, 0x46, 0x42, 0xaa, 0x8f, 0x26, 0x12, 0x12,
-	0xe4, 0x8b, 0x84, 0xd4, 0x18, 0x51, 0x24, 0xa4, 0xf1, 0x51, 0x45, 0x42, 0x9a, 0x18, 0x2a, 0x12,
-	0xd2, 0xe4, 0xb1, 0x22, 0x21, 0x1d, 0x94, 0x20, 0xa5, 0x63, 0xf8, 0xd4, 0x74, 0xf9, 0xfb, 0xca,
-	0x74, 0xf9, 0xfd, 0x22, 0x44, 0x7b, 0xc0, 0x09, 0xbd, 0x7d, 0xdf, 0xe6, 0x17, 0xae, 0xf8, 0xe5,
-	0xbd, 0x21, 0x45, 0xd3, 0x71, 0x79, 0x39, 0x8b, 0xd3, 0xc0, 0x90, 0x1a, 0xf1, 0x01, 0xac, 0xf0,
-	0x3d, 0xb4, 0xdc, 0x46, 0xa0, 0xe8, 0x69, 0x35, 0xa1, 0xfb, 0x8d, 0xfe, 0x31, 0xc6, 0x46, 0xfb,
-	0xad, 0x12, 0xc8, 0x87, 0xf3, 0x08, 0x85, 0xca, 0xb6, 0xf5, 0x98, 0x9a, 0xb9, 0x1d, 0xea, 0x96,
-	0x19, 0x15, 0xf9, 0x3a, 0x1f, 0xb7, 0x72, 0xf1, 0x04, 0x14, 0xd4, 0xb9, 0xf9, 0x42, 0x58, 0x2d,
-	0x65, 0xfb, 0xe5, 0x30, 0x5f, 0xc4, 0xad, 0x9f, 0xd2, 0x7c, 0x21, 0x92, 0x50, 0xf1, 0x10, 0xd6,
-	0x12, 0xee, 0xc0, 0x92, 0xdb, 0x48, 0x9b, 0x70, 0x84, 0x51, 0xd6, 0x12, 0x5f, 0x84, 0x42, 0x93,
-	0x3c, 0xc8, 0xb7, 0xa1, 0xa1, 0x1b, 0x46, 0xaf, 0xd3, 0xb3, 0xb9, 0xa6, 0x3b, 0x6f, 0xc0, 0xb0,
-	0x85, 0x88, 0x96, 0x64, 0xcb, 0x0f, 0x36, 0xb1, 0x64, 0x8c, 0xf3, 0x6b, 0xfe, 0xdc, 0x0f, 0x7f,
-	0x7c, 0xfd, 0xb9, 0x1f, 0xfd, 0xf8, 0xfa, 0x73, 0x1f, 0xfd, 0xf8, 0xfa, 0x73, 0xbf, 0x70, 0x78,
-	0xbd, 0xf0, 0xc3, 0xc3, 0xeb, 0x85, 0x1f, 0x1d, 0x5e, 0x2f, 0x7c, 0x74, 0x78, 0xbd, 0xf0, 0x6f,
-	0x0f, 0xaf, 0x17, 0xfe, 0xec, 0xbf, 0xbb, 0xfe, 0xdc, 0x37, 0xbf, 0x18, 0x15, 0x67, 0x4e, 0x15,
-	0x67, 0x4e, 0x31, 0x9f, 0xeb, 0xee, 0xb6, 0xe7, 0x58, 0x71, 0xa2, 0x14, 0x55, 0x9c, 0xff, 0x17,
-	0x00, 0x00, 0xff, 0xff, 0x2a, 0x0c, 0x84, 0x94, 0xad, 0xad, 0x00, 0x00,
+	0x7c, 0x00, 0xcb, 0xc7, 0x32, 0xc0, 0x02, 0x23, 0xb4, 0x12, 0x83, 0x00, 0x8b, 0x31, 0xe2, 0x03,
+	0x24, 0xd0, 0x2e, 0x2b, 0x60, 0x29, 0x10, 0x8b, 0xee, 0x2b, 0x5e, 0x19, 0xe9, 0xb2, 0x33, 0xd2,
+	0xee, 0xea, 0xdd, 0xfe, 0x8b, 0xb8, 0xe7, 0xdc, 0x73, 0xee, 0xfb, 0x9e, 0x7b, 0xce, 0xb9, 0xe7,
+	0xc2, 0xad, 0xb6, 0x15, 0xec, 0xf4, 0xb6, 0x66, 0x0d, 0xb7, 0x33, 0xe7, 0xf4, 0x3a, 0x7a, 0xd7,
+	0x73, 0xdf, 0xe3, 0x1f, 0xdb, 0xb6, 0xfb, 0x68, 0xae, 0xbb, 0xdb, 0x9e, 0xd3, 0xbb, 0x96, 0x1f,
+	0xa5, 0xec, 0xbd, 0xa2, 0xdb, 0xdd, 0x1d, 0xfd, 0x95, 0xb9, 0x36, 0x75, 0xa8, 0xa7, 0x07, 0xd4,
+	0x9c, 0xed, 0x7a, 0x6e, 0xe0, 0x92, 0x2f, 0x44, 0x84, 0x66, 0x15, 0xa1, 0x59, 0x95, 0x6d, 0xb6,
+	0xbb, 0xdb, 0x9e, 0x65, 0x84, 0xa2, 0x14, 0x45, 0xe8, 0xea, 0x4f, 0xc7, 0x4a, 0xd0, 0x76, 0xdb,
+	0xee, 0x1c, 0xa7, 0xb7, 0xd5, 0xdb, 0xe6, 0x7f, 0xfc, 0x87, 0x7f, 0x09, 0x3e, 0x57, 0xb5, 0xdd,
+	0xd7, 0xfd, 0x59, 0xcb, 0x65, 0xc5, 0x9a, 0x33, 0x5c, 0x8f, 0xce, 0xed, 0xf5, 0x95, 0xe5, 0xea,
+	0xe7, 0x23, 0x9c, 0x8e, 0x6e, 0xec, 0x58, 0x0e, 0xf5, 0xf6, 0x55, 0x5d, 0xe6, 0x3c, 0xea, 0xbb,
+	0x3d, 0xcf, 0xa0, 0x27, 0xca, 0xe5, 0xcf, 0x75, 0x68, 0xa0, 0x67, 0xf1, 0x9a, 0x1b, 0x94, 0xcb,
+	0xeb, 0x39, 0x81, 0xd5, 0xe9, 0x67, 0xf3, 0xda, 0xd3, 0x32, 0xf8, 0xc6, 0x0e, 0xed, 0xe8, 0x7d,
+	0xf9, 0x7e, 0x66, 0x50, 0xbe, 0x5e, 0x60, 0xd9, 0x73, 0x96, 0x13, 0xf8, 0x81, 0x97, 0xce, 0xa4,
+	0xfd, 0x06, 0xc0, 0x85, 0x85, 0x2d, 0x3f, 0xf0, 0x74, 0x23, 0x58, 0x77, 0xcd, 0x0d, 0xda, 0xe9,
+	0xda, 0x7a, 0x40, 0xc9, 0x2e, 0xd4, 0x58, 0x85, 0x4c, 0x3d, 0xd0, 0xa7, 0x0b, 0xd7, 0x0b, 0x37,
+	0x1a, 0xf3, 0x0b, 0xb3, 0x43, 0x76, 0xe0, 0xec, 0x9a, 0x24, 0xd4, 0x1c, 0x3f, 0x3c, 0x98, 0xa9,
+	0xa9, 0x3f, 0x0c, 0x19, 0x90, 0x5f, 0x2a, 0xc0, 0xb8, 0xe3, 0x9a, 0xb4, 0x45, 0x6d, 0x6a, 0x04,
+	0xae, 0x37, 0x5d, 0xbc, 0x5e, 0xba, 0xd1, 0x98, 0xff, 0xe6, 0xd0, 0x1c, 0x33, 0x6a, 0x34, 0x7b,
+	0x2f, 0xc6, 0xe0, 0xa6, 0x13, 0x78, 0xfb, 0xcd, 0x8b, 0x3f, 0x38, 0x98, 0xf9, 0xd4, 0xe1, 0xc1,
+	0xcc, 0x78, 0x1c, 0x84, 0x89, 0x92, 0x90, 0x4d, 0x68, 0x04, 0xae, 0xcd, 0x9a, 0xcc, 0x72, 0x1d,
+	0x7f, 0xba, 0xc4, 0x0b, 0x76, 0x6d, 0x56, 0x34, 0x35, 0x63, 0x3f, 0xcb, 0xc6, 0xd8, 0xec, 0xde,
+	0x2b, 0xb3, 0x1b, 0x21, 0x5a, 0xf3, 0x82, 0x24, 0xdc, 0x88, 0xd2, 0x7c, 0x8c, 0xd3, 0x21, 0x14,
+	0xa6, 0x7c, 0x6a, 0xf4, 0x3c, 0x2b, 0xd8, 0x5f, 0x74, 0x9d, 0x80, 0x3e, 0x0e, 0xa6, 0xcb, 0xbc,
+	0x95, 0x5f, 0xce, 0x22, 0xbd, 0xee, 0x9a, 0xad, 0x24, 0x76, 0xf3, 0xc2, 0xe1, 0xc1, 0xcc, 0x54,
+	0x2a, 0x11, 0xd3, 0x34, 0x89, 0x03, 0xe7, 0xac, 0x8e, 0xde, 0xa6, 0xeb, 0x3d, 0xdb, 0x6e, 0x51,
+	0xc3, 0xa3, 0x81, 0x3f, 0x5d, 0xe1, 0x55, 0xb8, 0x91, 0xc5, 0x67, 0xd5, 0x35, 0x74, 0xfb, 0xfe,
+	0xd6, 0x7b, 0xd4, 0x08, 0x90, 0x6e, 0x53, 0x8f, 0x3a, 0x06, 0x6d, 0x4e, 0xcb, 0xca, 0x9c, 0x5b,
+	0x49, 0x51, 0xc2, 0x3e, 0xda, 0xe4, 0x16, 0x9c, 0xef, 0x7a, 0x96, 0xcb, 0x8b, 0x60, 0xeb, 0xbe,
+	0x7f, 0x4f, 0xef, 0xd0, 0xe9, 0xb1, 0xeb, 0x85, 0x1b, 0xf5, 0xe6, 0x15, 0x49, 0xe6, 0xfc, 0x7a,
+	0x1a, 0x01, 0xfb, 0xf3, 0x90, 0x1b, 0x50, 0x53, 0x89, 0xd3, 0xd5, 0xeb, 0x85, 0x1b, 0x15, 0x31,
+	0x76, 0x54, 0x5e, 0x0c, 0xa1, 0x64, 0x19, 0x6a, 0xfa, 0xf6, 0xb6, 0xe5, 0x30, 0xcc, 0x1a, 0x6f,
+	0xc2, 0xe7, 0xb3, 0xaa, 0xb6, 0x20, 0x71, 0x04, 0x1d, 0xf5, 0x87, 0x61, 0x5e, 0x72, 0x07, 0x88,
+	0x4f, 0xbd, 0x3d, 0xcb, 0xa0, 0x0b, 0x86, 0xe1, 0xf6, 0x9c, 0x80, 0x97, 0xbd, 0xce, 0xcb, 0x7e,
+	0x55, 0x96, 0x9d, 0xb4, 0xfa, 0x30, 0x30, 0x23, 0x17, 0x79, 0x13, 0xce, 0xc9, 0xb9, 0x1a, 0xb5,
+	0x02, 0x70, 0x4a, 0x17, 0x59, 0x43, 0x62, 0x0a, 0x86, 0x7d, 0xd8, 0xc4, 0x84, 0xe7, 0xf5, 0x5e,
+	0xe0, 0x76, 0x18, 0xc9, 0x24, 0xd3, 0x0d, 0x77, 0x97, 0x3a, 0xd3, 0x8d, 0xeb, 0x85, 0x1b, 0xb5,
+	0xe6, 0xf5, 0xc3, 0x83, 0x99, 0xe7, 0x17, 0x8e, 0xc0, 0xc3, 0x23, 0xa9, 0x90, 0xfb, 0x50, 0x37,
+	0x1d, 0x7f, 0xdd, 0xb5, 0x2d, 0x63, 0x7f, 0x7a, 0x9c, 0x17, 0xf0, 0x15, 0x59, 0xd5, 0xfa, 0xd2,
+	0xbd, 0x96, 0x00, 0x3c, 0x39, 0x98, 0x79, 0xbe, 0x7f, 0x49, 0x9d, 0x0d, 0xe1, 0x18, 0xd1, 0x20,
+	0x6b, 0x9c, 0xe0, 0xa2, 0xeb, 0x6c, 0x5b, 0xed, 0xe9, 0x09, 0xde, 0x1b, 0xd7, 0x07, 0x0c, 0xe8,
+	0xa5, 0x7b, 0x2d, 0x81, 0xd7, 0x9c, 0x90, 0xec, 0xc4, 0x2f, 0x46, 0x14, 0x88, 0x09, 0x93, 0x6a,
+	0x31, 0x5e, 0xb4, 0x75, 0xab, 0xe3, 0x4f, 0x4f, 0xf2, 0xc1, 0xfb, 0x13, 0x03, 0x68, 0x62, 0x1c,
+	0xb9, 0x79, 0x59, 0x56, 0x65, 0x32, 0x91, 0xec, 0x63, 0x8a, 0xe6, 0xd5, 0x37, 0xe0, 0x7c, 0xdf,
+	0xda, 0x40, 0xce, 0x41, 0x69, 0x97, 0xee, 0xf3, 0xa5, 0xaf, 0x8e, 0xec, 0x93, 0x5c, 0x84, 0xca,
+	0x9e, 0x6e, 0xf7, 0xe8, 0x74, 0x91, 0xa7, 0x89, 0x9f, 0x2f, 0x15, 0x5f, 0x2f, 0x68, 0x1f, 0x96,
+	0x61, 0x5c, 0xad, 0x38, 0x2d, 0xcb, 0xd9, 0x25, 0x0f, 0xa1, 0x64, 0xbb, 0x6d, 0xb9, 0x6e, 0xfe,
+	0xec, 0xd0, 0xab, 0xd8, 0xaa, 0xdb, 0x6e, 0x56, 0x0f, 0x0f, 0x66, 0x4a, 0xab, 0x6e, 0x1b, 0x19,
+	0x45, 0x62, 0x40, 0x65, 0x57, 0xdf, 0xde, 0xd5, 0x79, 0x19, 0x1a, 0xf3, 0xcd, 0xa1, 0x49, 0xdf,
+	0x65, 0x54, 0x58, 0x59, 0x9b, 0xf5, 0xc3, 0x83, 0x99, 0x0a, 0xff, 0x45, 0x41, 0x9b, 0xb8, 0x50,
+	0xdf, 0xb2, 0x75, 0x63, 0x77, 0xc7, 0xb5, 0xe9, 0x74, 0x29, 0x27, 0xa3, 0xa6, 0xa2, 0x24, 0xba,
+	0x39, 0xfc, 0xc5, 0x88, 0x07, 0x31, 0x60, 0xac, 0x67, 0xfa, 0x96, 0xb3, 0x2b, 0xd7, 0xc0, 0x37,
+	0x86, 0xe6, 0xb6, 0xb9, 0xc4, 0xeb, 0x04, 0x87, 0x07, 0x33, 0x63, 0xe2, 0x1b, 0x25, 0x69, 0xd6,
+	0x74, 0x6c, 0xa6, 0xd2, 0xe9, 0x4a, 0xce, 0x1a, 0xb1, 0x89, 0x44, 0xa3, 0xa6, 0xe3, 0xbf, 0x28,
+	0x68, 0x6b, 0xbf, 0x3f, 0x0e, 0x93, 0x6a, 0x24, 0x3c, 0xa0, 0x5e, 0x40, 0x1f, 0x93, 0xeb, 0x50,
+	0x76, 0xd8, 0xfc, 0xe7, 0x23, 0xa9, 0x39, 0x2e, 0xc7, 0x64, 0x99, 0xcf, 0x7b, 0x0e, 0x61, 0xd5,
+	0x17, 0xe3, 0x51, 0xf6, 0xea, 0xf0, 0xd5, 0x6f, 0x71, 0x32, 0xa2, 0xfa, 0xe2, 0x1b, 0x25, 0x69,
+	0xf2, 0x0e, 0x94, 0x79, 0x0b, 0x8b, 0xfe, 0xfc, 0xca, 0xf0, 0x2c, 0x58, 0xc5, 0x6b, 0xac, 0x06,
+	0xbc, 0x75, 0x39, 0x51, 0x36, 0xde, 0x7b, 0xe6, 0xb6, 0xec, 0xbd, 0x9f, 0xcd, 0xd1, 0x7b, 0xcb,
+	0x62, 0xbc, 0x6f, 0x2e, 0x2d, 0x23, 0xa3, 0x48, 0xfe, 0x52, 0x01, 0xce, 0x1b, 0xae, 0x13, 0xe8,
+	0x4c, 0x98, 0x51, 0x3b, 0xb9, 0xec, 0xc1, 0x3b, 0x43, 0xf3, 0x59, 0x4c, 0x53, 0x6c, 0x5e, 0x62,
+	0x1b, 0x53, 0x5f, 0x32, 0xf6, 0xf3, 0x26, 0x7f, 0xb5, 0x00, 0x97, 0xd8, 0x86, 0xd1, 0x87, 0xcc,
+	0xb7, 0xb9, 0xd1, 0x96, 0xea, 0xca, 0xe1, 0xc1, 0xcc, 0xa5, 0x95, 0x2c, 0x66, 0x98, 0x5d, 0x06,
+	0x56, 0xba, 0x0b, 0x7a, 0xbf, 0xec, 0xc3, 0xb7, 0xd0, 0xc6, 0xfc, 0xea, 0x28, 0xe5, 0xa9, 0xe6,
+	0xa7, 0xe5, 0x50, 0xce, 0x12, 0x1f, 0x31, 0xab, 0x14, 0xe4, 0x26, 0x54, 0xf7, 0x5c, 0xbb, 0xd7,
+	0xa1, 0xfe, 0x74, 0x8d, 0xaf, 0xe3, 0x57, 0xb3, 0xd6, 0xf1, 0x07, 0x1c, 0xa5, 0x39, 0x25, 0xc9,
+	0x57, 0xc5, 0xbf, 0x8f, 0x2a, 0x2f, 0xb1, 0x60, 0xcc, 0xb6, 0x3a, 0x56, 0xe0, 0xf3, 0xdd, 0xb9,
+	0x31, 0x7f, 0x73, 0xe8, 0x6a, 0x89, 0x29, 0xba, 0xca, 0x89, 0x89, 0x59, 0x23, 0xbe, 0x51, 0x32,
+	0xe0, 0x8b, 0x86, 0xa1, 0xdb, 0x62, 0xf7, 0x6e, 0xcc, 0x7f, 0x75, 0xf8, 0x69, 0xc3, 0xa8, 0x34,
+	0x27, 0x64, 0x9d, 0x2a, 0xfc, 0x17, 0x05, 0x6d, 0xf2, 0x0d, 0x98, 0x4c, 0xf4, 0xa6, 0x3f, 0xdd,
+	0xe0, 0xad, 0xf3, 0x42, 0x56, 0xeb, 0x84, 0x58, 0xd1, 0xf6, 0x96, 0x18, 0x21, 0x3e, 0xa6, 0x88,
+	0x91, 0xbb, 0x50, 0xf3, 0x2d, 0x93, 0x1a, 0xba, 0xe7, 0x4f, 0x8f, 0x1f, 0x87, 0xf0, 0x39, 0x49,
+	0xb8, 0xd6, 0x92, 0xd9, 0x30, 0x24, 0x40, 0x66, 0x01, 0xba, 0xba, 0x17, 0x58, 0x42, 0x1a, 0x9e,
+	0xe0, 0x92, 0xd9, 0xe4, 0xe1, 0xc1, 0x0c, 0xac, 0x87, 0xa9, 0x18, 0xc3, 0x60, 0xf8, 0x2c, 0xef,
+	0x8a, 0xd3, 0xed, 0x05, 0x62, 0xf7, 0xae, 0x0b, 0xfc, 0x56, 0x98, 0x8a, 0x31, 0x0c, 0xf2, 0x6b,
+	0x05, 0xf8, 0x74, 0xf4, 0xdb, 0x3f, 0xc9, 0xa6, 0x46, 0x3e, 0xc9, 0x66, 0x0e, 0x0f, 0x66, 0x3e,
+	0xdd, 0x1a, 0xcc, 0x12, 0x8f, 0x2a, 0x0f, 0xf9, 0xb0, 0x00, 0x93, 0xbd, 0xae, 0xa9, 0x07, 0xb4,
+	0x15, 0xb0, 0x63, 0x55, 0x7b, 0x7f, 0xfa, 0x1c, 0x2f, 0xe2, 0xad, 0xe1, 0x57, 0xc1, 0x04, 0xb9,
+	0xa8, 0x9b, 0x93, 0xe9, 0x98, 0x62, 0xab, 0xbd, 0x07, 0xe7, 0x17, 0x0c, 0xa3, 0xd7, 0xe9, 0xd9,
+	0x7a, 0xe0, 0x7a, 0x0f, 0x2d, 0xc7, 0x74, 0x1f, 0x91, 0x4d, 0xa8, 0x32, 0xb9, 0xd2, 0xed, 0x05,
+	0x52, 0x18, 0x99, 0x8d, 0x75, 0x7d, 0x78, 0x48, 0x8c, 0x4a, 0xc3, 0x4e, 0x64, 0x6c, 0x30, 0x2c,
+	0xf5, 0xe4, 0x49, 0xa6, 0xc1, 0x66, 0xe0, 0x86, 0x20, 0x81, 0x8a, 0x96, 0xf6, 0x10, 0x26, 0x16,
+	0x7a, 0xc1, 0x8e, 0xeb, 0x59, 0x1f, 0x70, 0x34, 0xb2, 0x0c, 0x95, 0x80, 0xcb, 0xa5, 0x82, 0xcb,
+	0x4b, 0x59, 0x03, 0x4c, 0x9c, 0x11, 0xee, 0xd2, 0x7d, 0x25, 0x68, 0x89, 0xfd, 0x53, 0xc8, 0xa9,
+	0x22, 0xbb, 0xf6, 0xa7, 0x0b, 0x50, 0x6d, 0xea, 0xc6, 0xae, 0xbb, 0xbd, 0x4d, 0xde, 0x86, 0x9a,
+	0xe5, 0x04, 0xd4, 0xdb, 0xd3, 0xed, 0x21, 0x0b, 0xcf, 0x45, 0xfd, 0x15, 0x49, 0x03, 0x43, 0x6a,
+	0x64, 0x06, 0x2a, 0x7e, 0x40, 0xbb, 0x3e, 0xdf, 0x6f, 0x27, 0xe4, 0x36, 0xce, 0x12, 0x50, 0xa4,
+	0x6b, 0x7f, 0xa3, 0x00, 0xf5, 0xa6, 0xee, 0x5b, 0x06, 0xab, 0x25, 0x59, 0x84, 0x72, 0xcf, 0xa7,
+	0xde, 0xc9, 0xea, 0xc6, 0xb7, 0xc8, 0x4d, 0x9f, 0x7a, 0xc8, 0x33, 0x93, 0xfb, 0x50, 0xeb, 0xea,
+	0xbe, 0xff, 0xc8, 0xf5, 0x4c, 0xb9, 0xcd, 0x1f, 0x93, 0x90, 0x38, 0xf7, 0xc8, 0xac, 0x18, 0x12,
+	0xd1, 0x1a, 0x10, 0x09, 0x53, 0xda, 0xef, 0x15, 0xe0, 0x42, 0xb3, 0xb7, 0xbd, 0x4d, 0x3d, 0x29,
+	0xe6, 0x4b, 0x01, 0x9a, 0x42, 0xc5, 0xa3, 0xa6, 0xe5, 0xcb, 0xb2, 0x2f, 0x0d, 0x3d, 0x28, 0x91,
+	0x51, 0x91, 0xf2, 0x3a, 0x6f, 0x2f, 0x9e, 0x80, 0x82, 0x3a, 0xe9, 0x41, 0xfd, 0x3d, 0x1a, 0xf8,
+	0x81, 0x47, 0xf5, 0x8e, 0xac, 0xdd, 0xed, 0xa1, 0x59, 0xdd, 0xa1, 0x41, 0x8b, 0x53, 0x8a, 0x1f,
+	0x0f, 0xc2, 0x44, 0x8c, 0x38, 0x69, 0xbf, 0x51, 0x81, 0xf1, 0x45, 0xb7, 0xb3, 0x65, 0x39, 0xd4,
+	0xbc, 0x69, 0xb6, 0x29, 0x79, 0x17, 0xca, 0xd4, 0x6c, 0x53, 0x59, 0xdb, 0xe1, 0x85, 0x1c, 0x46,
+	0x2c, 0x12, 0xd5, 0xd8, 0x1f, 0x72, 0xc2, 0x64, 0x15, 0x26, 0xb7, 0x3d, 0xb7, 0x23, 0xf6, 0x8d,
+	0x8d, 0xfd, 0xae, 0x3c, 0x0c, 0x34, 0x7f, 0x42, 0x4d, 0xd2, 0xe5, 0x04, 0xf4, 0xc9, 0xc1, 0x0c,
+	0x44, 0x7f, 0x98, 0xca, 0x4b, 0xde, 0x86, 0xe9, 0x28, 0x25, 0x5c, 0x40, 0x17, 0xd9, 0xf9, 0x8c,
+	0xcb, 0x69, 0x95, 0xe6, 0xf3, 0x87, 0x07, 0x33, 0xd3, 0xcb, 0x03, 0x70, 0x70, 0x60, 0x6e, 0xb6,
+	0x2c, 0x9d, 0x8b, 0x80, 0x62, 0x53, 0x93, 0xe2, 0xd9, 0x88, 0x76, 0x4b, 0x7e, 0x90, 0x5d, 0x4e,
+	0xb1, 0xc0, 0x3e, 0xa6, 0x64, 0x19, 0xc6, 0x03, 0x37, 0xd6, 0x5e, 0x15, 0xde, 0x5e, 0x9a, 0xd2,
+	0xbc, 0x6c, 0xb8, 0x03, 0x5b, 0x2b, 0x91, 0x8f, 0x20, 0x5c, 0x56, 0xff, 0xa9, 0x96, 0x1a, 0xe3,
+	0x2d, 0x75, 0xf5, 0xf0, 0x60, 0xe6, 0xf2, 0x46, 0x26, 0x06, 0x0e, 0xc8, 0x49, 0x7e, 0xa1, 0x00,
+	0x93, 0x0a, 0x24, 0xdb, 0xa8, 0x3a, 0xca, 0x36, 0x22, 0x6c, 0x44, 0x6c, 0x24, 0x18, 0x60, 0x8a,
+	0xa1, 0xf6, 0xfd, 0x2a, 0xd4, 0xc3, 0x6d, 0x85, 0xbc, 0x08, 0x15, 0xae, 0x53, 0x91, 0xa7, 0x85,
+	0x50, 0x5e, 0xe0, 0xaa, 0x17, 0x14, 0x30, 0xf2, 0x12, 0x54, 0x0d, 0xb7, 0xd3, 0xd1, 0x1d, 0x93,
+	0xeb, 0xc9, 0xea, 0x62, 0x91, 0x5e, 0x14, 0x49, 0xa8, 0x60, 0xe4, 0x79, 0x28, 0xeb, 0x5e, 0x5b,
+	0xa8, 0xac, 0xea, 0x62, 0x3d, 0x5a, 0xf0, 0xda, 0x3e, 0xf2, 0x54, 0xf2, 0x45, 0x28, 0x51, 0x67,
+	0x6f, 0xba, 0x3c, 0x58, 0x0e, 0xbb, 0xe9, 0xec, 0x3d, 0xd0, 0xbd, 0x66, 0x43, 0x96, 0xa1, 0x74,
+	0xd3, 0xd9, 0x43, 0x96, 0x87, 0xac, 0x42, 0x95, 0x3a, 0x7b, 0xac, 0xef, 0xa5, 0x2e, 0xe9, 0x33,
+	0x03, 0xb2, 0x33, 0x14, 0x79, 0x24, 0x09, 0xa5, 0x39, 0x99, 0x8c, 0x8a, 0x04, 0xf9, 0x1a, 0x8c,
+	0x0b, 0xc1, 0x6e, 0x8d, 0xf5, 0x89, 0x3f, 0x3d, 0xc6, 0x49, 0xce, 0x0c, 0x96, 0x0c, 0x39, 0x5e,
+	0xa4, 0xbb, 0x8b, 0x25, 0xfa, 0x98, 0x20, 0x45, 0xbe, 0x06, 0x75, 0x75, 0xd4, 0x57, 0x3d, 0x9b,
+	0xa9, 0xf6, 0x52, 0xfa, 0x01, 0xa4, 0xef, 0xf7, 0x2c, 0x8f, 0x76, 0xa8, 0x13, 0xf8, 0xcd, 0xf3,
+	0x4a, 0x11, 0xa2, 0xa0, 0x3e, 0x46, 0xd4, 0xc8, 0x56, 0xbf, 0xfe, 0x4e, 0x28, 0x9f, 0x5e, 0x1c,
+	0xb0, 0xaa, 0x0f, 0xa1, 0xbc, 0xfb, 0x26, 0x4c, 0x85, 0x0a, 0x36, 0xa9, 0xa3, 0x11, 0xea, 0xa8,
+	0xcf, 0xb3, 0xec, 0x2b, 0x49, 0xd0, 0x93, 0x83, 0x99, 0x17, 0x32, 0xb4, 0x34, 0x11, 0x02, 0xa6,
+	0x89, 0x91, 0x0f, 0x60, 0xd2, 0xa3, 0xba, 0x69, 0x39, 0xd4, 0xf7, 0xd7, 0x3d, 0x77, 0x2b, 0xbf,
+	0x94, 0xcb, 0xa9, 0x88, 0x61, 0x8f, 0x09, 0xca, 0x98, 0xe2, 0x44, 0x1e, 0xc1, 0x84, 0x6d, 0xed,
+	0xd1, 0x88, 0x75, 0x63, 0x24, 0xac, 0xcf, 0x1f, 0x1e, 0xcc, 0x4c, 0xac, 0xc6, 0x09, 0x63, 0x92,
+	0x0f, 0x93, 0x54, 0xba, 0xae, 0x17, 0x28, 0x51, 0xf8, 0x33, 0x47, 0x8a, 0xc2, 0xeb, 0xae, 0x17,
+	0x44, 0x93, 0x90, 0xfd, 0xf9, 0x28, 0xb2, 0x6b, 0x7f, 0xbb, 0x02, 0xfd, 0x07, 0xc6, 0xe4, 0x88,
+	0x2b, 0x8c, 0x7a, 0xc4, 0xa5, 0x47, 0x83, 0xd8, 0x7b, 0x5e, 0x97, 0xd9, 0x46, 0x30, 0x22, 0x32,
+	0x46, 0x75, 0x69, 0xd4, 0xa3, 0xfa, 0x99, 0x59, 0x78, 0xfa, 0x87, 0xff, 0xd8, 0x47, 0x37, 0xfc,
+	0xab, 0x67, 0x33, 0xfc, 0xb5, 0xef, 0x95, 0x61, 0x72, 0x49, 0xa7, 0x1d, 0xd7, 0x79, 0xaa, 0xce,
+	0xa0, 0xf0, 0x4c, 0xe8, 0x0c, 0x6e, 0x40, 0xcd, 0xa3, 0x5d, 0xdb, 0x32, 0x74, 0x21, 0xae, 0x4b,
+	0x43, 0x00, 0xca, 0x34, 0x0c, 0xa1, 0x03, 0x74, 0x45, 0xa5, 0x67, 0x52, 0x57, 0x54, 0xfe, 0xe8,
+	0x75, 0x45, 0xda, 0x2f, 0x14, 0x81, 0x8b, 0xb6, 0xe4, 0x3a, 0x94, 0x99, 0xd8, 0x96, 0xd6, 0x50,
+	0xf2, 0xd9, 0xc2, 0x21, 0xe4, 0x2a, 0x14, 0x03, 0x57, 0x2e, 0x37, 0x20, 0xe1, 0xc5, 0x0d, 0x17,
+	0x8b, 0x81, 0x4b, 0x3e, 0x00, 0x30, 0x5c, 0xc7, 0xb4, 0x94, 0x7d, 0x2c, 0x5f, 0xc5, 0x96, 0x5d,
+	0xef, 0x91, 0xee, 0x99, 0x8b, 0x21, 0x45, 0xa1, 0x2d, 0x88, 0xfe, 0x31, 0xc6, 0x8d, 0xbc, 0x01,
+	0x63, 0xae, 0xb3, 0xdc, 0xb3, 0x6d, 0xde, 0xa0, 0xf5, 0xe6, 0x67, 0x0f, 0x0f, 0x66, 0xc6, 0xee,
+	0xf3, 0x94, 0x27, 0x07, 0x33, 0x57, 0xc4, 0x89, 0x88, 0xfd, 0x3d, 0xf4, 0xac, 0xc0, 0x72, 0xda,
+	0xe1, 0xe1, 0x59, 0x66, 0xd3, 0x7e, 0xb1, 0x00, 0x8d, 0x65, 0xeb, 0x31, 0x35, 0xe5, 0x79, 0x19,
+	0x61, 0xcc, 0xa6, 0x4e, 0x3b, 0xd8, 0x19, 0xf2, 0xc4, 0x29, 0x74, 0x48, 0x9c, 0x02, 0x4a, 0x4a,
+	0x64, 0x0e, 0xea, 0xe2, 0xbc, 0x62, 0x39, 0x6d, 0xde, 0x86, 0xb5, 0x68, 0xa5, 0x6f, 0x29, 0x00,
+	0x46, 0x38, 0xda, 0x3e, 0x9c, 0xef, 0x6b, 0x06, 0x62, 0x42, 0x39, 0xd0, 0xdb, 0x6a, 0x53, 0x59,
+	0x1e, 0xba, 0x81, 0x37, 0xf4, 0x76, 0xac, 0x71, 0xb9, 0x54, 0xb8, 0xa1, 0x33, 0xa9, 0x90, 0x51,
+	0xd7, 0xfe, 0x6f, 0x01, 0x6a, 0xcb, 0x3d, 0xc7, 0xe0, 0x87, 0xfa, 0xa7, 0x6b, 0xae, 0x95, 0x88,
+	0x59, 0xcc, 0x14, 0x31, 0x7b, 0x30, 0xb6, 0xfb, 0x28, 0x14, 0x41, 0x1b, 0xf3, 0x6b, 0xc3, 0x8f,
+	0x0a, 0x59, 0xa4, 0xd9, 0xbb, 0x9c, 0x9e, 0xb0, 0xde, 0x4e, 0xca, 0x02, 0x8d, 0xdd, 0x7d, 0xc8,
+	0x99, 0x4a, 0x66, 0x57, 0xbf, 0x08, 0x8d, 0x18, 0xda, 0x89, 0x0c, 0x39, 0x7f, 0xa7, 0x0c, 0x63,
+	0xb7, 0x5a, 0xad, 0x85, 0xf5, 0x15, 0xf2, 0x2a, 0x34, 0xa4, 0x61, 0xef, 0x5e, 0xd4, 0x06, 0xa1,
+	0x5d, 0xb7, 0x15, 0x81, 0x30, 0x8e, 0xc7, 0x04, 0x78, 0x8f, 0xea, 0x76, 0x47, 0x4e, 0x96, 0x50,
+	0x76, 0x40, 0x96, 0x88, 0x02, 0x46, 0x74, 0x98, 0xec, 0xf9, 0xd4, 0x63, 0x4d, 0x28, 0xce, 0xfb,
+	0x72, 0xda, 0x1c, 0x53, 0x23, 0xc0, 0x37, 0x98, 0xcd, 0x04, 0x01, 0x4c, 0x11, 0x24, 0xaf, 0x43,
+	0x4d, 0xef, 0x05, 0x3b, 0xfc, 0xc8, 0x25, 0xe6, 0xc6, 0xf3, 0xdc, 0xee, 0x29, 0xd3, 0x9e, 0x1c,
+	0xcc, 0x8c, 0xdf, 0xc5, 0xe6, 0xab, 0xea, 0x1f, 0x43, 0x6c, 0x56, 0x38, 0xa5, 0x63, 0x90, 0x85,
+	0xab, 0x9c, 0xb8, 0x70, 0xeb, 0x09, 0x02, 0x98, 0x22, 0x48, 0xde, 0x81, 0xf1, 0x5d, 0xba, 0x1f,
+	0xe8, 0x5b, 0x92, 0xc1, 0xd8, 0x49, 0x18, 0x9c, 0x63, 0x42, 0xff, 0xdd, 0x58, 0x76, 0x4c, 0x10,
+	0x23, 0x3e, 0x5c, 0xdc, 0xa5, 0xde, 0x16, 0xf5, 0x5c, 0xa9, 0xaf, 0x90, 0x4c, 0xaa, 0x27, 0x61,
+	0x32, 0x7d, 0x78, 0x30, 0x73, 0xf1, 0x6e, 0x06, 0x19, 0xcc, 0x24, 0xae, 0xfd, 0xef, 0x22, 0x4c,
+	0xdd, 0x12, 0x9e, 0x15, 0xae, 0x27, 0x24, 0x0f, 0x72, 0x05, 0x4a, 0x5e, 0xb7, 0xc7, 0x47, 0x4e,
+	0x49, 0x98, 0x35, 0x70, 0x7d, 0x13, 0x59, 0x1a, 0x79, 0x1b, 0x6a, 0xa6, 0x5c, 0x32, 0xa4, 0xba,
+	0x64, 0x28, 0xd5, 0x96, 0xfa, 0xc3, 0x90, 0x1a, 0x3b, 0x1b, 0x76, 0xfc, 0x76, 0xcb, 0xfa, 0x80,
+	0x4a, 0x0d, 0x02, 0x3f, 0x1b, 0xae, 0x89, 0x24, 0x54, 0x30, 0xb6, 0xab, 0xee, 0xd2, 0x7d, 0x71,
+	0x7e, 0x2e, 0x47, 0xbb, 0xea, 0x5d, 0x99, 0x86, 0x21, 0x94, 0xcc, 0xa8, 0xc9, 0xc2, 0x46, 0x41,
+	0x59, 0xe8, 0x7e, 0x1e, 0xb0, 0x04, 0x39, 0x6f, 0xd8, 0x92, 0xf9, 0x9e, 0x15, 0x04, 0xd4, 0x93,
+	0xdd, 0x38, 0xd4, 0x92, 0x79, 0x87, 0x53, 0x40, 0x49, 0x89, 0xfc, 0x14, 0xd4, 0x39, 0xf1, 0xa6,
+	0xed, 0x6e, 0xf1, 0x8e, 0xab, 0x0b, 0x2d, 0xd0, 0x03, 0x95, 0x88, 0x11, 0x5c, 0xfb, 0x83, 0x22,
+	0x5c, 0xbe, 0x45, 0x03, 0x21, 0xd5, 0x2c, 0xd1, 0xae, 0xed, 0xee, 0x33, 0x79, 0x1a, 0xe9, 0xfb,
+	0xe4, 0x4d, 0x00, 0xcb, 0xdf, 0x6a, 0xed, 0x19, 0x7c, 0x1e, 0x88, 0x39, 0x7c, 0x5d, 0x4e, 0x49,
+	0x58, 0x69, 0x35, 0x25, 0xe4, 0x49, 0xe2, 0x0f, 0x63, 0x79, 0xa2, 0x03, 0x79, 0xf1, 0x88, 0x03,
+	0x79, 0x0b, 0xa0, 0x1b, 0x49, 0xe5, 0x25, 0x8e, 0xf9, 0x33, 0x8a, 0xcd, 0x49, 0x04, 0xf2, 0x18,
+	0x99, 0x3c, 0x72, 0xb2, 0x03, 0xe7, 0x4c, 0xba, 0xad, 0xf7, 0xec, 0x20, 0x3c, 0x49, 0xc8, 0x49,
+	0x7c, 0xfc, 0xc3, 0x48, 0xe8, 0xf5, 0xb1, 0x94, 0xa2, 0x84, 0x7d, 0xb4, 0xb5, 0xbf, 0x57, 0x82,
+	0xab, 0xb7, 0x68, 0x10, 0xea, 0xe8, 0xe4, 0xea, 0xd8, 0xea, 0x52, 0x83, 0xf5, 0xc2, 0x87, 0x05,
+	0x18, 0xb3, 0xf5, 0x2d, 0x6a, 0xb3, 0xdd, 0x8b, 0xd5, 0xe6, 0xdd, 0xa1, 0x37, 0x82, 0xc1, 0x5c,
+	0x66, 0x57, 0x39, 0x87, 0xd4, 0xd6, 0x20, 0x12, 0x51, 0xb2, 0x67, 0x8b, 0xba, 0x61, 0xf7, 0xfc,
+	0x40, 0x9c, 0xec, 0xa4, 0x3c, 0x19, 0x2e, 0xea, 0x8b, 0x11, 0x08, 0xe3, 0x78, 0x64, 0x1e, 0xc0,
+	0xb0, 0x2d, 0xea, 0x04, 0x3c, 0x97, 0x98, 0x57, 0x44, 0xf5, 0xef, 0x62, 0x08, 0xc1, 0x18, 0x16,
+	0x63, 0xd5, 0x71, 0x1d, 0x2b, 0x70, 0x05, 0xab, 0x72, 0x92, 0xd5, 0x5a, 0x04, 0xc2, 0x38, 0x1e,
+	0xcf, 0x46, 0x03, 0xcf, 0x32, 0x7c, 0x9e, 0xad, 0x92, 0xca, 0x16, 0x81, 0x30, 0x8e, 0xc7, 0xf6,
+	0xbc, 0x58, 0xfd, 0x4f, 0xb4, 0xe7, 0xfd, 0x6a, 0x1d, 0xae, 0x25, 0x9a, 0x35, 0xd0, 0x03, 0xba,
+	0xdd, 0xb3, 0x5b, 0x34, 0x50, 0x1d, 0x38, 0xe4, 0x5e, 0xf8, 0xe7, 0xa3, 0x7e, 0x17, 0xfe, 0x5c,
+	0xc6, 0x68, 0xfa, 0xbd, 0xaf, 0x80, 0xc7, 0xea, 0xfb, 0x39, 0xa8, 0x3b, 0x7a, 0xe0, 0xf3, 0x89,
+	0x2b, 0xe7, 0x68, 0x28, 0x86, 0xdd, 0x53, 0x00, 0x8c, 0x70, 0xc8, 0x3a, 0x5c, 0x94, 0x4d, 0x7c,
+	0xf3, 0x31, 0x3b, 0xf3, 0x53, 0x4f, 0xe4, 0x95, 0xdb, 0xa9, 0xcc, 0x7b, 0x71, 0x2d, 0x03, 0x07,
+	0x33, 0x73, 0x92, 0x35, 0xb8, 0x60, 0x08, 0x1f, 0x17, 0x6a, 0xbb, 0xba, 0xa9, 0x08, 0x0a, 0x95,
+	0x68, 0x78, 0x34, 0x5a, 0xec, 0x47, 0xc1, 0xac, 0x7c, 0xe9, 0xd1, 0x3c, 0x36, 0xd4, 0x68, 0xae,
+	0x0e, 0x33, 0x9a, 0x6b, 0xc3, 0x8d, 0xe6, 0xfa, 0xf1, 0x46, 0x33, 0x6b, 0x79, 0xee, 0x4e, 0xe1,
+	0x31, 0xf1, 0x44, 0xec, 0xb0, 0x31, 0x17, 0xaa, 0xb0, 0xe5, 0x5b, 0x19, 0x38, 0x98, 0x99, 0x93,
+	0x6c, 0xc1, 0x55, 0x91, 0x7e, 0xd3, 0x31, 0xbc, 0xfd, 0x2e, 0xdb, 0x78, 0x62, 0x74, 0x1b, 0x09,
+	0x9d, 0xf4, 0xd5, 0xd6, 0x40, 0x4c, 0x3c, 0x82, 0x0a, 0xf9, 0x32, 0x4c, 0x88, 0x5e, 0x5a, 0xd3,
+	0xbb, 0x9c, 0xac, 0x70, 0xa8, 0xba, 0x24, 0xc9, 0x4e, 0x2c, 0xc6, 0x81, 0x98, 0xc4, 0x25, 0x0b,
+	0x30, 0xd5, 0xdd, 0x33, 0xd8, 0xe7, 0xca, 0xf6, 0x3d, 0x4a, 0x4d, 0x6a, 0x72, 0xe3, 0x6a, 0xbd,
+	0xf9, 0x9c, 0xd2, 0xee, 0xac, 0x27, 0xc1, 0x98, 0xc6, 0x27, 0xaf, 0xc3, 0xb8, 0x1f, 0xe8, 0x5e,
+	0x20, 0x15, 0xc1, 0xd3, 0x93, 0xc2, 0xe1, 0x4c, 0xe9, 0x49, 0x5b, 0x31, 0x18, 0x26, 0x30, 0x33,
+	0xf7, 0x8b, 0xa9, 0xd3, 0xdb, 0x2f, 0xf2, 0xac, 0x56, 0xff, 0xb8, 0x08, 0xd7, 0x6f, 0xd1, 0x60,
+	0xcd, 0x75, 0xa4, 0x1a, 0x3d, 0x6b, 0xdb, 0x3f, 0x96, 0x16, 0x3d, 0xb9, 0x69, 0x17, 0x47, 0xba,
+	0x69, 0x97, 0x46, 0xb4, 0x69, 0x97, 0x4f, 0x71, 0xd3, 0xfe, 0xfb, 0x45, 0x78, 0x2e, 0xd1, 0x92,
+	0xeb, 0xae, 0xa9, 0x16, 0xfc, 0x4f, 0x1a, 0xf0, 0x18, 0x0d, 0xf8, 0x44, 0xc8, 0x9d, 0xdc, 0x10,
+	0x9a, 0x92, 0x78, 0xbe, 0x9b, 0x96, 0x78, 0xde, 0xc9, 0xb3, 0xf3, 0x65, 0x70, 0x38, 0xd6, 0x8e,
+	0x77, 0x07, 0x88, 0x27, 0xcd, 0xb6, 0x91, 0x3a, 0x5b, 0x0a, 0x3d, 0xa1, 0x47, 0x2b, 0xf6, 0x61,
+	0x60, 0x46, 0x2e, 0xd2, 0x82, 0x4b, 0x3e, 0x75, 0x02, 0xcb, 0xa1, 0x76, 0x92, 0x9c, 0x90, 0x86,
+	0x5e, 0x90, 0xe4, 0x2e, 0xb5, 0xb2, 0x90, 0x30, 0x3b, 0x6f, 0x9e, 0x75, 0xe0, 0xb7, 0x80, 0x8b,
+	0x9c, 0xa2, 0x69, 0x46, 0x26, 0xb1, 0x7c, 0x98, 0x96, 0x58, 0xde, 0xcd, 0xdf, 0x6f, 0xc3, 0x49,
+	0x2b, 0xf3, 0x00, 0xbc, 0x17, 0xe2, 0xe2, 0x4a, 0xb8, 0x49, 0x63, 0x08, 0xc1, 0x18, 0x16, 0xdb,
+	0x80, 0x54, 0x3b, 0xc7, 0x25, 0x95, 0x70, 0x03, 0x6a, 0xc5, 0x81, 0x98, 0xc4, 0x1d, 0x28, 0xed,
+	0x54, 0x86, 0x96, 0x76, 0xee, 0x00, 0x49, 0x28, 0x1e, 0x05, 0xbd, 0xb1, 0xa4, 0x43, 0xf5, 0x4a,
+	0x1f, 0x06, 0x66, 0xe4, 0x1a, 0x30, 0x94, 0xab, 0xa3, 0x1d, 0xca, 0xb5, 0xe1, 0x87, 0x32, 0x79,
+	0x17, 0xae, 0x70, 0x56, 0xb2, 0x7d, 0x92, 0x84, 0x85, 0xdc, 0xf3, 0x19, 0x49, 0xf8, 0x0a, 0x0e,
+	0x42, 0xc4, 0xc1, 0x34, 0x58, 0xff, 0x18, 0x1e, 0x35, 0x19, 0x73, 0xdd, 0x1e, 0x2c, 0x13, 0x2d,
+	0x66, 0xe0, 0x60, 0x66, 0x4e, 0x36, 0xc4, 0x02, 0x36, 0x0c, 0xf5, 0x2d, 0x9b, 0x9a, 0xd2, 0xa1,
+	0x3c, 0x1c, 0x62, 0x1b, 0xab, 0x2d, 0x09, 0xc1, 0x18, 0x56, 0x96, 0x98, 0x32, 0x7e, 0x42, 0x31,
+	0xe5, 0x16, 0xd7, 0xd2, 0x6f, 0x27, 0xa4, 0x21, 0x29, 0xeb, 0x84, 0x57, 0x04, 0x16, 0xd3, 0x08,
+	0xd8, 0x9f, 0x87, 0x4b, 0x89, 0x86, 0x67, 0x75, 0x03, 0x3f, 0x49, 0x6b, 0x32, 0x25, 0x25, 0x66,
+	0xe0, 0x60, 0x66, 0x4e, 0x26, 0x9f, 0xef, 0x50, 0xdd, 0x0e, 0x76, 0x92, 0x04, 0xa7, 0x92, 0xf2,
+	0xf9, 0xed, 0x7e, 0x14, 0xcc, 0xca, 0x97, 0xb9, 0x21, 0x9d, 0x7b, 0x36, 0xc5, 0xaa, 0x7f, 0x5e,
+	0x82, 0x17, 0x6e, 0x51, 0x71, 0x47, 0xc0, 0x69, 0xaf, 0x5b, 0x5d, 0x6a, 0x5b, 0x0e, 0x8d, 0x95,
+	0x88, 0xfc, 0xd9, 0x02, 0x8c, 0x0b, 0xbd, 0x88, 0xf4, 0xee, 0xcf, 0x6b, 0x1e, 0xca, 0x70, 0x57,
+	0x8a, 0x84, 0x55, 0xa1, 0x8d, 0x91, 0x27, 0xa1, 0x04, 0xdf, 0x4f, 0x34, 0x32, 0xc7, 0x91, 0x4d,
+	0xbe, 0x53, 0x82, 0x2b, 0xac, 0x3f, 0x95, 0xe7, 0xe2, 0x27, 0x6a, 0xb1, 0x8f, 0xa0, 0x13, 0x7e,
+	0xa5, 0x02, 0x17, 0x6e, 0xd1, 0xa0, 0x4f, 0xba, 0xfe, 0x23, 0xda, 0xfc, 0x6b, 0x70, 0x21, 0xf2,
+	0xa4, 0x6d, 0x05, 0xae, 0x27, 0x64, 0xb3, 0x94, 0xf6, 0xa3, 0xd5, 0x8f, 0x82, 0x59, 0xf9, 0xc8,
+	0xd7, 0xe0, 0x39, 0x5f, 0x2c, 0x57, 0x42, 0xdf, 0x2e, 0x94, 0x43, 0xb1, 0x0b, 0x67, 0x33, 0x92,
+	0xe4, 0x73, 0xad, 0x6c, 0x34, 0x1c, 0x94, 0x9f, 0x7c, 0x1b, 0xc6, 0xbb, 0x72, 0x09, 0x64, 0x7d,
+	0x96, 0xdb, 0x29, 0x6c, 0x3d, 0x46, 0x2c, 0x5a, 0xe3, 0xe2, 0xa9, 0x98, 0x60, 0x98, 0x39, 0x52,
+	0x6b, 0xa7, 0x38, 0x52, 0xff, 0x7b, 0x11, 0xaa, 0xb7, 0x3c, 0xb7, 0xd7, 0x6d, 0xee, 0x93, 0x36,
+	0x8c, 0x3d, 0xe2, 0xc6, 0x50, 0xb9, 0xc2, 0x0f, 0x7f, 0x1b, 0x45, 0xd8, 0x54, 0x23, 0x11, 0x57,
+	0xfc, 0xa3, 0x24, 0xcf, 0x06, 0xf1, 0x2e, 0xdd, 0xa7, 0xa6, 0xb4, 0x89, 0x86, 0x83, 0xf8, 0x2e,
+	0x4b, 0x44, 0x01, 0x23, 0x1d, 0x98, 0xd2, 0x6d, 0xdb, 0x7d, 0x44, 0xcd, 0x55, 0x3d, 0xe0, 0x7e,
+	0x0c, 0xd2, 0x56, 0x76, 0x52, 0x33, 0x03, 0x77, 0x4e, 0x59, 0x48, 0x92, 0xc2, 0x34, 0x6d, 0xf2,
+	0x1e, 0x54, 0xfd, 0xc0, 0xf5, 0x94, 0xf0, 0xdc, 0x98, 0x5f, 0x1c, 0xbe, 0xd3, 0x9b, 0x6f, 0xb5,
+	0x04, 0x29, 0x61, 0x83, 0x91, 0x3f, 0xa8, 0x18, 0x68, 0xbf, 0x5c, 0x00, 0xb8, 0xbd, 0xb1, 0xb1,
+	0x2e, 0xcd, 0x45, 0x26, 0x94, 0xf5, 0x5e, 0x68, 0x78, 0x1e, 0xde, 0xc0, 0x9b, 0x70, 0xcc, 0x96,
+	0x36, 0xd9, 0x5e, 0xb0, 0x83, 0x9c, 0x3a, 0xf9, 0x49, 0xa8, 0xca, 0x03, 0x8f, 0x6c, 0xf6, 0xd0,
+	0x3f, 0x46, 0xee, 0xc4, 0xa8, 0xe0, 0xda, 0xaf, 0x17, 0x01, 0x56, 0x4c, 0x9b, 0xb6, 0xd4, 0x05,
+	0xa2, 0x7a, 0xb0, 0xe3, 0x51, 0x7f, 0xc7, 0xb5, 0xcd, 0x21, 0xad, 0xe3, 0xdc, 0x86, 0xb3, 0xa1,
+	0x88, 0x60, 0x44, 0x8f, 0x98, 0x30, 0xee, 0x07, 0xb4, 0xab, 0x7c, 0xb5, 0x87, 0x34, 0x8a, 0x9d,
+	0x13, 0x7a, 0xae, 0x88, 0x0e, 0x26, 0xa8, 0x12, 0x1d, 0x1a, 0x96, 0x63, 0x88, 0x09, 0xd2, 0xdc,
+	0x1f, 0x72, 0x20, 0x4d, 0xb1, 0x13, 0xe4, 0x4a, 0x44, 0x06, 0xe3, 0x34, 0xb5, 0xdf, 0x29, 0xc2,
+	0x65, 0xce, 0x8f, 0x15, 0x23, 0x21, 0xe2, 0x90, 0x3f, 0xd9, 0x77, 0xa3, 0xfa, 0x8f, 0x1f, 0x8f,
+	0xb5, 0xb8, 0x90, 0xbb, 0x46, 0x03, 0x3d, 0x92, 0xcf, 0xa3, 0xb4, 0xd8, 0x35, 0xea, 0x1e, 0x94,
+	0x7d, 0xb6, 0x5e, 0x89, 0xd6, 0x6b, 0x0d, 0x3d, 0x84, 0xb2, 0x2b, 0xc0, 0x57, 0xaf, 0xd0, 0x0b,
+	0x80, 0xaf, 0x5a, 0x9c, 0x1d, 0xf9, 0x16, 0x8c, 0xf9, 0x81, 0x1e, 0xf4, 0xd4, 0xd4, 0xdc, 0x1c,
+	0x35, 0x63, 0x4e, 0x3c, 0x5a, 0x47, 0xc4, 0x3f, 0x4a, 0xa6, 0xda, 0xef, 0x14, 0xe0, 0x6a, 0x76,
+	0xc6, 0x55, 0xcb, 0x0f, 0xc8, 0x9f, 0xe8, 0x6b, 0xf6, 0x63, 0xf6, 0x38, 0xcb, 0xcd, 0x1b, 0x3d,
+	0xbc, 0x0f, 0xa3, 0x52, 0x62, 0x4d, 0x1e, 0x40, 0xc5, 0x0a, 0x68, 0x47, 0xe9, 0x0b, 0xee, 0x8f,
+	0xb8, 0xea, 0xb1, 0xad, 0x9d, 0x71, 0x41, 0xc1, 0x4c, 0xfb, 0x5e, 0x71, 0x50, 0x95, 0xf9, 0xf6,
+	0x61, 0x27, 0xbd, 0xfe, 0xef, 0xe6, 0xf3, 0xfa, 0x4f, 0x16, 0xa8, 0xdf, 0xf9, 0xff, 0x4f, 0xf5,
+	0x3b, 0xff, 0xdf, 0xcf, 0xef, 0xfc, 0x9f, 0x6a, 0x86, 0x81, 0x77, 0x00, 0x7e, 0x54, 0x82, 0xe7,
+	0x8f, 0x1a, 0x36, 0x6c, 0x3f, 0x93, 0xa3, 0x33, 0xef, 0x7e, 0x76, 0xf4, 0x38, 0x24, 0xf3, 0x50,
+	0xe9, 0xee, 0xe8, 0xbe, 0x12, 0xca, 0x9e, 0x0f, 0xdd, 0x46, 0x59, 0xe2, 0x13, 0xb6, 0x68, 0x70,
+	0x61, 0x8e, 0xff, 0xa2, 0x40, 0x65, 0xcb, 0x71, 0x87, 0xfa, 0x7e, 0xa4, 0xe3, 0x09, 0x97, 0xe3,
+	0x35, 0x91, 0x8c, 0x0a, 0x4e, 0x02, 0x18, 0x13, 0x26, 0x03, 0xb9, 0x33, 0x8d, 0xf6, 0xe4, 0x15,
+	0x56, 0x4a, 0x9e, 0xb9, 0x24, 0x2f, 0x32, 0x0b, 0xe5, 0x20, 0x72, 0xdb, 0x57, 0xaa, 0x96, 0x72,
+	0x86, 0x7c, 0xca, 0xf1, 0xc8, 0x1d, 0x20, 0xee, 0x16, 0x37, 0x92, 0x98, 0xd2, 0x1f, 0xc2, 0x72,
+	0x1d, 0x2e, 0x90, 0x95, 0x22, 0x45, 0xcd, 0xfd, 0x3e, 0x0c, 0xcc, 0xc8, 0xa5, 0xfd, 0xcb, 0x1a,
+	0x5c, 0xce, 0x1e, 0x0f, 0xac, 0xdd, 0xf6, 0xa8, 0xe7, 0x33, 0xda, 0x85, 0x64, 0xbb, 0x3d, 0x10,
+	0xc9, 0xa8, 0xe0, 0x1f, 0x6b, 0x07, 0xc2, 0x5f, 0x29, 0xc0, 0x15, 0x4f, 0xda, 0xfc, 0xce, 0xc2,
+	0x89, 0xf0, 0x05, 0xa1, 0x9e, 0x1a, 0xc0, 0x10, 0x07, 0x97, 0x85, 0xfc, 0xcd, 0x02, 0x4c, 0x77,
+	0x52, 0x7a, 0xab, 0x53, 0xbc, 0xaf, 0xcb, 0xef, 0xc5, 0xac, 0x0d, 0xe0, 0x87, 0x03, 0x4b, 0x42,
+	0xbe, 0x0d, 0x8d, 0x2e, 0x1b, 0x17, 0x7e, 0x40, 0x1d, 0x43, 0x39, 0xfc, 0x0e, 0x3f, 0x93, 0xd6,
+	0x23, 0x5a, 0xe1, 0x7d, 0x3d, 0x2e, 0x1f, 0xc4, 0x00, 0x18, 0xe7, 0xf8, 0x8c, 0x5f, 0xd0, 0xbd,
+	0x01, 0x35, 0x9f, 0x06, 0x81, 0xe5, 0xb4, 0xc5, 0x79, 0xa3, 0x2e, 0xe6, 0x4a, 0x4b, 0xa6, 0x61,
+	0x08, 0x25, 0x3f, 0x05, 0x75, 0x6e, 0x42, 0x5c, 0xf0, 0xda, 0xfe, 0x74, 0x9d, 0xbb, 0xff, 0x4d,
+	0x08, 0x87, 0x46, 0x99, 0x88, 0x11, 0x9c, 0x7c, 0x1e, 0xc6, 0xb7, 0xf8, 0xf4, 0x95, 0xaa, 0x23,
+	0xa1, 0xb3, 0xe4, 0xd2, 0x5a, 0x33, 0x96, 0x8e, 0x09, 0x2c, 0x32, 0x0f, 0x40, 0x43, 0x3b, 0x6b,
+	0x5a, 0x3f, 0x19, 0x59, 0x60, 0x31, 0x86, 0x45, 0x5e, 0x80, 0x52, 0x60, 0xfb, 0x5c, 0x27, 0x59,
+	0x8b, 0x8e, 0xa0, 0x1b, 0xab, 0x2d, 0x64, 0xe9, 0xda, 0x1f, 0x14, 0x60, 0x2a, 0x75, 0xbd, 0x8c,
+	0x65, 0xe9, 0x79, 0xb6, 0x5c, 0x46, 0xc2, 0x2c, 0x9b, 0xb8, 0x8a, 0x2c, 0x9d, 0xbc, 0x2b, 0xc5,
+	0xf2, 0x62, 0xce, 0x18, 0x38, 0xf7, 0xf4, 0xc0, 0x67, 0x72, 0x78, 0x9f, 0x44, 0xce, 0xcd, 0xb6,
+	0x51, 0x79, 0xe4, 0x3e, 0x10, 0x33, 0xdb, 0x46, 0x30, 0x4c, 0x60, 0xa6, 0x14, 0xb8, 0xe5, 0xe3,
+	0x28, 0x70, 0xb5, 0x5f, 0x2c, 0xc6, 0x5a, 0x40, 0x4a, 0xf6, 0x4f, 0x69, 0x81, 0x97, 0xd9, 0x06,
+	0x1a, 0x6e, 0xee, 0xf5, 0xf8, 0xfe, 0xc7, 0x37, 0x63, 0x09, 0x25, 0x0f, 0x45, 0xdb, 0x97, 0x72,
+	0x06, 0x01, 0xd8, 0x58, 0x6d, 0x09, 0x6f, 0x39, 0xd5, 0x6b, 0x61, 0x17, 0x94, 0x4f, 0xa9, 0x0b,
+	0xb4, 0x7f, 0x5a, 0x82, 0xc6, 0x1d, 0x77, 0xeb, 0x63, 0xe2, 0x11, 0x9f, 0xbd, 0x4d, 0x15, 0x3f,
+	0xc2, 0x6d, 0x6a, 0x13, 0x9e, 0x0b, 0x02, 0xbb, 0x45, 0x0d, 0xd7, 0x31, 0xfd, 0x85, 0xed, 0x80,
+	0x7a, 0xcb, 0x96, 0x63, 0xf9, 0x3b, 0xd4, 0x94, 0xe6, 0xc1, 0x4f, 0x1f, 0x1e, 0xcc, 0x3c, 0xb7,
+	0xb1, 0xb1, 0x9a, 0x85, 0x82, 0x83, 0xf2, 0xf2, 0x65, 0x43, 0xdc, 0x05, 0xe6, 0x77, 0xe5, 0xa4,
+	0x0f, 0x95, 0x58, 0x36, 0x62, 0xe9, 0x98, 0xc0, 0xd2, 0xfe, 0x7d, 0x11, 0xea, 0x61, 0x74, 0x13,
+	0xf2, 0x12, 0x54, 0xb7, 0x3c, 0x77, 0x97, 0x7a, 0xc2, 0x12, 0x2b, 0xef, 0xca, 0x35, 0x45, 0x12,
+	0x2a, 0x18, 0x79, 0x11, 0x2a, 0x81, 0xdb, 0xb5, 0x8c, 0xb4, 0x42, 0x6d, 0x83, 0x25, 0xa2, 0x80,
+	0xf1, 0x89, 0xc0, 0xdd, 0x44, 0x79, 0xad, 0x6a, 0xb1, 0x89, 0xc0, 0x53, 0x51, 0x42, 0xd5, 0x44,
+	0x28, 0x8f, 0x7c, 0x22, 0xbc, 0x1c, 0x8a, 0x80, 0x95, 0xe4, 0x4c, 0x4c, 0x09, 0x6d, 0xef, 0x40,
+	0xd9, 0xd7, 0x7d, 0x5b, 0x6e, 0x6f, 0x39, 0x62, 0x7d, 0x2c, 0xb4, 0x56, 0x65, 0xac, 0x8f, 0x85,
+	0xd6, 0x2a, 0x72, 0xa2, 0xda, 0xaf, 0x97, 0xa0, 0x21, 0xda, 0x57, 0xac, 0x1e, 0xa3, 0x6c, 0xe1,
+	0x37, 0xb8, 0x0b, 0x8d, 0xdf, 0xeb, 0x50, 0x8f, 0xab, 0xa3, 0xe4, 0x62, 0x18, 0xb7, 0x0b, 0x45,
+	0xc0, 0xd0, 0x8d, 0x26, 0x4a, 0xfa, 0xc3, 0xdd, 0xf4, 0x6c, 0xab, 0xe0, 0x11, 0x7a, 0xa4, 0x8c,
+	0x2b, 0x3d, 0x63, 0xc3, 0xad, 0xe2, 0x6e, 0x0c, 0x86, 0x09, 0x4c, 0xed, 0x77, 0x8b, 0x50, 0x5f,
+	0xb5, 0xb6, 0xa9, 0xb1, 0x6f, 0xd8, 0x94, 0x7c, 0x13, 0xae, 0x9a, 0xd4, 0xa6, 0x6c, 0xc7, 0xbc,
+	0xe5, 0xe9, 0x06, 0x5d, 0xa7, 0x9e, 0xc5, 0x23, 0x8c, 0xb1, 0x39, 0x28, 0x1d, 0x96, 0xaf, 0x1d,
+	0x1e, 0xcc, 0x5c, 0x5d, 0x1a, 0x88, 0x85, 0x47, 0x50, 0x20, 0x2b, 0x30, 0x6e, 0x52, 0xdf, 0xf2,
+	0xa8, 0xb9, 0x1e, 0x3b, 0x10, 0xbd, 0xa4, 0xca, 0xb9, 0x14, 0x83, 0x3d, 0x39, 0x98, 0x99, 0x50,
+	0x8a, 0x50, 0x71, 0x32, 0x4a, 0x64, 0x65, 0x4b, 0x4b, 0x57, 0xef, 0xf9, 0x34, 0xa3, 0x9c, 0x25,
+	0x5e, 0x4e, 0xbe, 0xb4, 0xac, 0x67, 0xa3, 0xe0, 0xa0, 0xbc, 0x64, 0x0b, 0xa6, 0x79, 0xf9, 0xb3,
+	0xe8, 0x96, 0x39, 0xdd, 0x97, 0x0f, 0x0f, 0x66, 0xb4, 0x25, 0xda, 0xf5, 0xa8, 0xa1, 0x07, 0xd4,
+	0x5c, 0x1a, 0x80, 0x8d, 0x03, 0xe9, 0x68, 0x15, 0x28, 0xad, 0xba, 0x6d, 0xed, 0x7b, 0x25, 0x08,
+	0x43, 0xde, 0x91, 0x3f, 0x57, 0x80, 0x86, 0xee, 0x38, 0x6e, 0x20, 0xc3, 0xc9, 0x09, 0xef, 0x10,
+	0xcc, 0x1d, 0x59, 0x6f, 0x76, 0x21, 0x22, 0x2a, 0x1c, 0x0b, 0x42, 0x67, 0x87, 0x18, 0x04, 0xe3,
+	0xbc, 0x49, 0x2f, 0xe5, 0xeb, 0xb0, 0x96, 0xbf, 0x14, 0xc7, 0xf0, 0x6c, 0xb8, 0xfa, 0x55, 0x38,
+	0x97, 0x2e, 0xec, 0x49, 0x4c, 0x95, 0xb9, 0x9c, 0x46, 0x8a, 0x00, 0x91, 0xbf, 0xd3, 0x19, 0x28,
+	0xe4, 0xac, 0x84, 0x42, 0x6e, 0xf8, 0x90, 0x20, 0x51, 0xa1, 0x07, 0x2a, 0xe1, 0xde, 0x4f, 0x29,
+	0xe1, 0x56, 0x46, 0xc1, 0xec, 0x68, 0xc5, 0xdb, 0x16, 0x5c, 0x88, 0x70, 0xa3, 0xd5, 0xe5, 0x6e,
+	0x6a, 0xf6, 0x0b, 0xb9, 0xf2, 0xb3, 0x03, 0x66, 0xff, 0x54, 0xcc, 0x01, 0xad, 0x7f, 0xfe, 0x6b,
+	0x7f, 0xab, 0x00, 0xe7, 0xe2, 0x4c, 0x78, 0x4c, 0x81, 0x2f, 0xc0, 0x84, 0x47, 0x75, 0xb3, 0xa9,
+	0x07, 0xc6, 0x0e, 0xbf, 0xea, 0x50, 0xe0, 0x77, 0x13, 0xf8, 0xed, 0x47, 0x8c, 0x03, 0x30, 0x89,
+	0x47, 0x74, 0x68, 0xb0, 0x04, 0x19, 0xcf, 0x64, 0x48, 0x2d, 0x33, 0x3f, 0xe0, 0x61, 0x44, 0x06,
+	0xe3, 0x34, 0xb5, 0x1f, 0x15, 0x60, 0x32, 0x5e, 0xe0, 0x53, 0xd7, 0x40, 0xee, 0x24, 0x35, 0x90,
+	0x8b, 0x23, 0xe8, 0xf7, 0x01, 0x5a, 0xc7, 0xef, 0x34, 0xe2, 0x55, 0xe3, 0x9a, 0xc6, 0xb8, 0x72,
+	0xa5, 0x70, 0xa4, 0x72, 0xe5, 0xe3, 0x1f, 0xe4, 0x6c, 0xd0, 0xa9, 0xa0, 0xfc, 0x0c, 0x9f, 0x0a,
+	0x3e, 0xca, 0x48, 0x69, 0xb1, 0x68, 0x5f, 0x63, 0x39, 0xa2, 0x7d, 0x75, 0xc2, 0x68, 0x5f, 0xd5,
+	0x91, 0x2d, 0x6c, 0xc7, 0x89, 0xf8, 0x55, 0x3b, 0xd3, 0x88, 0x5f, 0xf5, 0xd3, 0x8a, 0xf8, 0x05,
+	0x79, 0x23, 0x7e, 0x7d, 0xb7, 0x00, 0x93, 0x66, 0xe2, 0xc6, 0xb8, 0x8c, 0xd5, 0x30, 0xfc, 0x76,
+	0x96, 0xbc, 0x80, 0x2e, 0xae, 0x0c, 0x26, 0xd3, 0x30, 0xc5, 0x32, 0x2b, 0xce, 0xd6, 0xf8, 0x47,
+	0x12, 0x67, 0x8b, 0x7c, 0x0b, 0xea, 0xb6, 0xda, 0xeb, 0x64, 0x88, 0xd3, 0xd5, 0x91, 0x0c, 0x49,
+	0x49, 0x33, 0xba, 0x95, 0x12, 0x26, 0x61, 0xc4, 0x51, 0xfb, 0x5f, 0xd5, 0xf8, 0x86, 0x78, 0xd6,
+	0x36, 0x8e, 0xd7, 0x92, 0x36, 0x8e, 0xeb, 0x69, 0x1b, 0x47, 0xdf, 0x6e, 0x2e, 0xed, 0x1c, 0x9f,
+	0x8b, 0xed, 0x13, 0x25, 0x1e, 0x74, 0x2b, 0x1c, 0x72, 0x19, 0x7b, 0xc5, 0x02, 0x4c, 0x49, 0x21,
+	0x40, 0x01, 0xf9, 0x22, 0x3b, 0x11, 0x79, 0x19, 0x2e, 0x25, 0xc1, 0x98, 0xc6, 0x67, 0x0c, 0x7d,
+	0x15, 0x4c, 0x5a, 0x9c, 0xd8, 0xa2, 0x31, 0xae, 0x02, 0x3d, 0x87, 0x18, 0xec, 0x74, 0xe7, 0x51,
+	0xdd, 0x97, 0x96, 0x8a, 0xd8, 0xe9, 0x0e, 0x79, 0x2a, 0x4a, 0x68, 0xdc, 0x5c, 0x53, 0x7d, 0x8a,
+	0xb9, 0x46, 0x87, 0x86, 0xad, 0xfb, 0x81, 0x18, 0x4c, 0xa6, 0x5c, 0x4d, 0xfe, 0xd8, 0xf1, 0xf6,
+	0x7d, 0x26, 0x4b, 0x44, 0x02, 0xfc, 0x6a, 0x44, 0x06, 0xe3, 0x34, 0x89, 0x09, 0xe3, 0xec, 0x97,
+	0xaf, 0x2c, 0xe6, 0x42, 0x20, 0xa3, 0x21, 0x9e, 0x84, 0x47, 0x78, 0x74, 0x5c, 0x8d, 0xd1, 0xc1,
+	0x04, 0xd5, 0x01, 0x16, 0x1d, 0x18, 0xc6, 0xa2, 0x43, 0xbe, 0x2c, 0x04, 0xb7, 0xfd, 0xb0, 0x5b,
+	0x1b, 0xbc, 0x5b, 0x43, 0x0f, 0x65, 0x8c, 0x03, 0x31, 0x89, 0xcb, 0x46, 0x45, 0x4f, 0x36, 0x83,
+	0xca, 0x3e, 0x9e, 0x1c, 0x15, 0x9b, 0x49, 0x30, 0xa6, 0xf1, 0xc9, 0x3a, 0x5c, 0x0c, 0x93, 0xe2,
+	0xc5, 0x98, 0xe0, 0x74, 0x42, 0x97, 0xd1, 0xcd, 0x0c, 0x1c, 0xcc, 0xcc, 0xc9, 0xef, 0x60, 0xf5,
+	0x3c, 0x8f, 0x3a, 0xc1, 0x6d, 0xdd, 0xdf, 0x91, 0xbe, 0xa7, 0xd1, 0x1d, 0xac, 0x08, 0x84, 0x71,
+	0x3c, 0x32, 0x0f, 0x20, 0xc8, 0xf1, 0x5c, 0x53, 0x49, 0xf7, 0xee, 0xcd, 0x10, 0x82, 0x31, 0x2c,
+	0xed, 0xbb, 0x75, 0x68, 0xdc, 0xd3, 0x03, 0x6b, 0x8f, 0x72, 0xf3, 0xeb, 0xe9, 0xd8, 0xc0, 0xfe,
+	0x5a, 0x01, 0x2e, 0x27, 0x7d, 0xa6, 0x4f, 0xd1, 0x10, 0xc6, 0x63, 0x76, 0x61, 0x26, 0x37, 0x1c,
+	0x50, 0x0a, 0x6e, 0x12, 0xeb, 0x73, 0xc1, 0x3e, 0x6d, 0x93, 0x58, 0x6b, 0x10, 0x43, 0x1c, 0x5c,
+	0x96, 0x8f, 0x8b, 0x49, 0xec, 0xd9, 0x0e, 0x68, 0x9b, 0x32, 0xd8, 0x55, 0x9f, 0x19, 0x83, 0x5d,
+	0xed, 0x99, 0x90, 0xfa, 0xbb, 0x31, 0x83, 0x5d, 0x3d, 0xa7, 0xe3, 0x98, 0xbc, 0x66, 0x24, 0xa8,
+	0x0d, 0x32, 0xfc, 0xf1, 0x08, 0x21, 0xca, 0x90, 0xc2, 0x84, 0xe5, 0x2d, 0xdd, 0xb7, 0x0c, 0x29,
+	0x76, 0xe4, 0x88, 0x12, 0xae, 0x82, 0x6d, 0x0a, 0xff, 0x12, 0xfe, 0x8b, 0x82, 0x76, 0x14, 0x5b,
+	0xb4, 0x98, 0x2b, 0xb6, 0x28, 0x59, 0x84, 0xb2, 0xb3, 0x4b, 0xf7, 0x4f, 0x16, 0x6b, 0x83, 0x1f,
+	0x02, 0xef, 0xdd, 0xa5, 0xfb, 0xc8, 0x33, 0x6b, 0xdf, 0x2f, 0x02, 0xb0, 0xea, 0x1f, 0xcf, 0x74,
+	0xf6, 0x93, 0x50, 0xf5, 0x7b, 0x5c, 0x31, 0x24, 0x05, 0xa6, 0xc8, 0xdb, 0x4e, 0x24, 0xa3, 0x82,
+	0x93, 0x17, 0xa1, 0xf2, 0x7e, 0x8f, 0xf6, 0x94, 0x1f, 0x48, 0x78, 0x6e, 0x78, 0x8b, 0x25, 0xa2,
+	0x80, 0x9d, 0x9e, 0x7a, 0x5b, 0x99, 0xd8, 0x2a, 0xa7, 0x65, 0x62, 0xab, 0x43, 0xf5, 0x9e, 0xcb,
+	0x9d, 0x77, 0xb5, 0xff, 0x52, 0x04, 0x88, 0x9c, 0x23, 0xc9, 0x2f, 0x17, 0xe0, 0x52, 0x38, 0xe1,
+	0x02, 0x71, 0xfc, 0xe3, 0x81, 0xf9, 0x73, 0x9b, 0xdb, 0xb2, 0x26, 0x3b, 0x5f, 0x81, 0xd6, 0xb3,
+	0xd8, 0x61, 0x76, 0x29, 0x08, 0x42, 0x8d, 0x76, 0xba, 0xc1, 0xfe, 0x92, 0xe5, 0xc9, 0x11, 0x98,
+	0xe9, 0x83, 0x7b, 0x53, 0xe2, 0x88, 0xac, 0x52, 0x47, 0xc1, 0x27, 0x91, 0x82, 0x60, 0x48, 0x87,
+	0xec, 0x40, 0xcd, 0x71, 0xdf, 0xf5, 0x59, 0x73, 0xc8, 0xe1, 0xf8, 0xe6, 0xf0, 0x4d, 0x2e, 0x9a,
+	0x55, 0x98, 0x5d, 0xe4, 0x0f, 0x56, 0x1d, 0xd9, 0xd8, 0xbf, 0x54, 0x84, 0x0b, 0x19, 0xed, 0x40,
+	0xde, 0x84, 0x73, 0xd2, 0x0f, 0x35, 0x7a, 0xa1, 0xa2, 0x10, 0xbd, 0x50, 0xd1, 0x4a, 0xc1, 0xb0,
+	0x0f, 0x9b, 0xbc, 0x0b, 0xa0, 0x1b, 0x06, 0xf5, 0xfd, 0x35, 0xd7, 0x54, 0xe7, 0x81, 0x37, 0x98,
+	0xf8, 0xb2, 0x10, 0xa6, 0x3e, 0x39, 0x98, 0xf9, 0xe9, 0x2c, 0xd7, 0xf2, 0x54, 0x3b, 0x47, 0x19,
+	0x30, 0x46, 0x92, 0x7c, 0x13, 0x40, 0xe8, 0x00, 0xc2, 0x68, 0x26, 0x4f, 0x51, 0x9c, 0xcd, 0xaa,
+	0x60, 0x79, 0xb3, 0x6f, 0xf5, 0x74, 0x27, 0xb0, 0x82, 0x7d, 0x11, 0x3c, 0xea, 0x41, 0x48, 0x05,
+	0x63, 0x14, 0xb5, 0xdf, 0x2c, 0x42, 0x4d, 0x99, 0x1e, 0xce, 0x40, 0x17, 0xdc, 0x4e, 0xe8, 0x82,
+	0x47, 0xe4, 0x4c, 0x9e, 0xa5, 0x09, 0x76, 0x53, 0x9a, 0xe0, 0x5b, 0xf9, 0x59, 0x1d, 0xad, 0x07,
+	0xfe, 0xb5, 0x22, 0x4c, 0x2a, 0xd4, 0xbc, 0x1a, 0xda, 0xaf, 0xc0, 0x94, 0x70, 0x02, 0x59, 0xd3,
+	0x1f, 0x8b, 0x38, 0x5a, 0xbc, 0xc1, 0xca, 0xc2, 0x7f, 0xbb, 0x99, 0x04, 0x61, 0x1a, 0x97, 0x0d,
+	0x6b, 0x91, 0xb4, 0xc9, 0x0e, 0x61, 0xc2, 0x6c, 0x2c, 0xce, 0x9b, 0x7c, 0x58, 0x37, 0x53, 0x30,
+	0xec, 0xc3, 0x4e, 0xab, 0x88, 0xcb, 0xa7, 0xa0, 0x22, 0xfe, 0xed, 0x02, 0x8c, 0x47, 0xed, 0x75,
+	0xea, 0x0a, 0xe2, 0xed, 0xa4, 0x82, 0x78, 0x21, 0xf7, 0x70, 0x18, 0xa0, 0x1e, 0xfe, 0x8b, 0x55,
+	0x48, 0xdc, 0x69, 0x20, 0x5b, 0x70, 0xd5, 0xca, 0xf4, 0xcc, 0x8c, 0xad, 0x36, 0x61, 0xd0, 0x85,
+	0x95, 0x81, 0x98, 0x78, 0x04, 0x15, 0xd2, 0x83, 0xda, 0x1e, 0xf5, 0x02, 0xcb, 0xa0, 0xaa, 0x7e,
+	0xb7, 0x72, 0x8b, 0x64, 0x52, 0x09, 0x1e, 0xb6, 0xe9, 0x03, 0xc9, 0x00, 0x43, 0x56, 0x64, 0x0b,
+	0x2a, 0xd4, 0x6c, 0x53, 0x15, 0xd9, 0x2c, 0x67, 0xa4, 0xe9, 0xb0, 0x3d, 0xd9, 0x9f, 0x8f, 0x82,
+	0x34, 0xf1, 0xe3, 0x8a, 0xa6, 0x72, 0x4e, 0x01, 0xeb, 0x98, 0xea, 0x25, 0xb2, 0x1b, 0x6a, 0x5b,
+	0x2b, 0x23, 0x5a, 0x3c, 0x8e, 0xd0, 0xb5, 0xfa, 0x50, 0x7f, 0xa4, 0x07, 0xd4, 0xeb, 0xe8, 0xde,
+	0xae, 0x3c, 0x6d, 0x0c, 0x5f, 0xc3, 0x87, 0x8a, 0x52, 0x54, 0xc3, 0x30, 0x09, 0x23, 0x3e, 0xc4,
+	0x85, 0x7a, 0x20, 0xc5, 0x67, 0xa5, 0x52, 0x1e, 0x9e, 0xa9, 0x12, 0xc4, 0x7d, 0x79, 0xb7, 0x41,
+	0xfd, 0x62, 0xc4, 0x83, 0xec, 0x25, 0x9e, 0x40, 0x10, 0x0f, 0x5f, 0xe4, 0x78, 0x7d, 0x46, 0x91,
+	0x8a, 0xb6, 0x9b, 0xec, 0xa7, 0x14, 0xb4, 0xff, 0x51, 0x89, 0x96, 0xe5, 0xb3, 0xd6, 0x13, 0x7e,
+	0x3e, 0xa9, 0x27, 0xbc, 0x96, 0xd6, 0x13, 0xa6, 0x6c, 0xfe, 0x27, 0xf7, 0x86, 0x4e, 0xa9, 0xd7,
+	0xca, 0xa7, 0xa0, 0x5e, 0x7b, 0x05, 0x1a, 0x7b, 0x7c, 0x25, 0x10, 0x61, 0xd2, 0x2a, 0x7c, 0x1b,
+	0xe1, 0x2b, 0xfb, 0x83, 0x28, 0x19, 0xe3, 0x38, 0x2c, 0x8b, 0x7c, 0x59, 0x2a, 0x8c, 0x4c, 0x2e,
+	0xb3, 0xb4, 0xa2, 0x64, 0x8c, 0xe3, 0x70, 0x47, 0x4a, 0xcb, 0xd9, 0x15, 0x19, 0xaa, 0x3c, 0x83,
+	0x70, 0xa4, 0x54, 0x89, 0x18, 0xc1, 0xc9, 0x0d, 0xa8, 0xf5, 0xcc, 0x6d, 0x81, 0x5b, 0xe3, 0xb8,
+	0x5c, 0xc2, 0xdc, 0x5c, 0x5a, 0x96, 0x61, 0xdb, 0x14, 0x94, 0x95, 0xa4, 0xa3, 0x77, 0x15, 0x80,
+	0x9f, 0x0d, 0x65, 0x49, 0xd6, 0xa2, 0x64, 0x8c, 0xe3, 0x90, 0x2f, 0xc1, 0xa4, 0x47, 0xcd, 0x9e,
+	0x41, 0xc3, 0x5c, 0xc0, 0x73, 0xc9, 0x78, 0xb6, 0x71, 0x08, 0xa6, 0x30, 0x07, 0x28, 0x09, 0x1b,
+	0x43, 0x29, 0x09, 0xbf, 0x0a, 0x93, 0xa6, 0xa7, 0x5b, 0x0e, 0x35, 0xef, 0x3b, 0xdc, 0xb1, 0x43,
+	0xba, 0x73, 0x86, 0x0a, 0xfa, 0xa5, 0x04, 0x14, 0x53, 0xd8, 0xda, 0x3f, 0x2b, 0x42, 0x45, 0x44,
+	0xd9, 0x5d, 0x81, 0x0b, 0x96, 0x63, 0x05, 0x96, 0x6e, 0x2f, 0x51, 0x5b, 0xdf, 0x8f, 0x3b, 0xb8,
+	0x54, 0x9a, 0xcf, 0xb1, 0x83, 0xf6, 0x4a, 0x3f, 0x18, 0xb3, 0xf2, 0xb0, 0xc6, 0x91, 0x8f, 0x5f,
+	0x28, 0x2a, 0x42, 0x8f, 0x26, 0x42, 0xbc, 0x27, 0x20, 0x98, 0xc2, 0x64, 0xc2, 0x50, 0xb7, 0xcf,
+	0x73, 0xa5, 0x22, 0x84, 0xa1, 0xa4, 0x33, 0x49, 0x12, 0x8f, 0x0b, 0xe9, 0x3d, 0x2e, 0x10, 0x87,
+	0x97, 0xa6, 0xa4, 0x13, 0x9c, 0x10, 0xd2, 0x53, 0x30, 0xec, 0xc3, 0x66, 0x14, 0xb6, 0x75, 0xcb,
+	0xee, 0x79, 0x34, 0xa2, 0x50, 0x89, 0x28, 0x2c, 0xa7, 0x60, 0xd8, 0x87, 0xad, 0x6d, 0x00, 0xac,
+	0xf7, 0x6c, 0x5f, 0xe7, 0x11, 0x95, 0x46, 0xf6, 0xce, 0xc7, 0xef, 0x17, 0x61, 0x5c, 0x90, 0x95,
+	0x07, 0xe9, 0x79, 0x00, 0x19, 0xb8, 0xc9, 0x34, 0x3d, 0x29, 0x1b, 0x44, 0x0b, 0x5c, 0x08, 0xc1,
+	0x18, 0xd6, 0xf1, 0x5c, 0xca, 0x5e, 0x87, 0x71, 0xe5, 0x22, 0xc6, 0xc5, 0x8e, 0x94, 0x7b, 0xed,
+	0x62, 0x0c, 0x86, 0x09, 0x4c, 0xb2, 0xc4, 0x5a, 0x7f, 0x4b, 0x04, 0x0a, 0xb0, 0x5c, 0x87, 0xe7,
+	0x16, 0x11, 0x35, 0xc2, 0xab, 0x95, 0xad, 0x14, 0x1c, 0xfb, 0x72, 0x90, 0xcf, 0x41, 0xad, 0xa3,
+	0x3f, 0xde, 0x74, 0x74, 0x63, 0x57, 0x2e, 0x21, 0xa1, 0x5c, 0xb1, 0x26, 0xd3, 0x31, 0xc4, 0x20,
+	0xba, 0x3c, 0x87, 0x8f, 0xe5, 0xbd, 0x7c, 0x18, 0x76, 0x59, 0xdf, 0x49, 0xfc, 0xbf, 0x15, 0x80,
+	0xf4, 0xdf, 0xeb, 0x21, 0x3b, 0x30, 0xe6, 0x70, 0xe5, 0x72, 0xee, 0xa7, 0x42, 0x62, 0x3a, 0x6a,
+	0xb1, 0xeb, 0xcb, 0x04, 0x49, 0x9f, 0x38, 0x50, 0xa3, 0x8f, 0x03, 0xea, 0x39, 0xe1, 0x3d, 0xbf,
+	0xd1, 0x3c, 0x4b, 0x22, 0x0e, 0xdb, 0x92, 0x32, 0x86, 0x3c, 0xb4, 0xdf, 0x2b, 0x42, 0x23, 0x86,
+	0xf7, 0x34, 0x9d, 0x0d, 0x0f, 0x1d, 0x23, 0x74, 0xba, 0x9b, 0x9e, 0x2d, 0xc7, 0x56, 0x2c, 0x74,
+	0x8c, 0x04, 0xe1, 0x2a, 0xc6, 0xf1, 0xd8, 0x00, 0xee, 0xe8, 0x7e, 0x90, 0x18, 0x65, 0xe1, 0x00,
+	0x5e, 0x0b, 0x21, 0x18, 0xc3, 0x22, 0xd7, 0xe5, 0xc3, 0x32, 0xe5, 0x64, 0x80, 0xdd, 0x01, 0xaf,
+	0xc6, 0x54, 0x46, 0xf0, 0x6a, 0x0c, 0x69, 0xc3, 0x39, 0x55, 0x6a, 0x05, 0x3d, 0x59, 0xf8, 0x55,
+	0xb1, 0xf2, 0xa4, 0x48, 0x60, 0x1f, 0x51, 0xed, 0xfb, 0x05, 0x98, 0x48, 0x68, 0x14, 0x45, 0x68,
+	0x5c, 0x75, 0x2b, 0x2d, 0x11, 0x1a, 0x37, 0x76, 0x99, 0xec, 0x65, 0x18, 0x13, 0x0d, 0x94, 0x76,
+	0x36, 0x17, 0x4d, 0x88, 0x12, 0xca, 0x44, 0x05, 0x69, 0xb3, 0x48, 0x8b, 0x0a, 0xd2, 0xa8, 0x81,
+	0x0a, 0x2e, 0x4c, 0x81, 0xa2, 0x74, 0xb2, 0xa5, 0x63, 0xa6, 0x40, 0x91, 0x8e, 0x21, 0x86, 0xf6,
+	0x0f, 0x78, 0xb9, 0x03, 0x6f, 0x3f, 0x54, 0x95, 0xb4, 0xa1, 0x2a, 0x1d, 0x8c, 0xe5, 0xd4, 0x78,
+	0x33, 0x87, 0x9a, 0x93, 0xd3, 0x91, 0x2e, 0xb2, 0xba, 0xb1, 0x7b, 0x7f, 0x7b, 0x1b, 0x15, 0x75,
+	0x72, 0x13, 0xea, 0xae, 0x23, 0x97, 0x64, 0x59, 0xfd, 0xcf, 0x32, 0x51, 0xe0, 0xbe, 0x4a, 0x7c,
+	0x72, 0x30, 0x73, 0x39, 0xfc, 0x49, 0x14, 0x12, 0xa3, 0x9c, 0xda, 0x9f, 0x29, 0xc0, 0x25, 0x74,
+	0x6d, 0xdb, 0x72, 0xda, 0x49, 0x53, 0x36, 0xb1, 0x61, 0x52, 0xac, 0x34, 0x7b, 0xba, 0x65, 0xeb,
+	0x5b, 0x36, 0x7d, 0xaa, 0xaa, 0xa3, 0x17, 0x58, 0xf6, 0xac, 0x78, 0x39, 0x78, 0x76, 0xc5, 0x09,
+	0xee, 0x7b, 0xad, 0xc0, 0xb3, 0x9c, 0xb6, 0xd8, 0xf6, 0xd6, 0x12, 0xb4, 0x30, 0x45, 0x5b, 0xfb,
+	0x77, 0x65, 0xe0, 0xce, 0xab, 0xe4, 0x0b, 0x50, 0xef, 0x50, 0x63, 0x47, 0x77, 0x2c, 0x5f, 0x05,
+	0x19, 0xbf, 0xc2, 0xea, 0xb5, 0xa6, 0x12, 0x9f, 0xb0, 0xae, 0x58, 0x68, 0xad, 0xf2, 0x7b, 0x64,
+	0x11, 0x2e, 0x31, 0x60, 0xac, 0xed, 0xfb, 0x7a, 0xd7, 0xca, 0xed, 0x33, 0x24, 0x82, 0x3a, 0x8b,
+	0xe5, 0x48, 0x7c, 0xa3, 0x24, 0x4d, 0x0c, 0xa8, 0x74, 0x6d, 0xdd, 0x72, 0x72, 0xbf, 0x74, 0xc9,
+	0x6a, 0xb0, 0xce, 0x28, 0x89, 0xfd, 0x8e, 0x7f, 0xa2, 0xa0, 0x4d, 0x7a, 0xd0, 0xf0, 0x0d, 0x4f,
+	0xef, 0xf8, 0x3b, 0xfa, 0xfc, 0xab, 0xaf, 0xe5, 0x3e, 0xcd, 0x45, 0xac, 0x84, 0x70, 0xb9, 0x88,
+	0x0b, 0x6b, 0xad, 0xdb, 0x0b, 0xf3, 0xaf, 0xbe, 0x86, 0x71, 0x3e, 0x71, 0xb6, 0xaf, 0xbe, 0x32,
+	0x9f, 0xff, 0xe5, 0xcb, 0x6c, 0xb6, 0xaf, 0xbe, 0x32, 0x8f, 0x71, 0x3e, 0xac, 0x49, 0xdd, 0xd8,
+	0x36, 0x96, 0x8f, 0xe1, 0xfd, 0xc8, 0x2c, 0xc0, 0x3f, 0x51, 0xd0, 0xd6, 0xfe, 0x67, 0x01, 0xea,
+	0x21, 0x9c, 0x2d, 0x94, 0x22, 0x5c, 0xe5, 0xca, 0xd2, 0xc9, 0x64, 0x13, 0xbe, 0x50, 0x2e, 0xca,
+	0xac, 0x18, 0x12, 0x21, 0xef, 0xc0, 0xb8, 0xf8, 0x96, 0xe1, 0xa3, 0x8b, 0x27, 0x8e, 0x51, 0xbd,
+	0x18, 0xcb, 0x8e, 0x09, 0x62, 0xe4, 0xcb, 0x30, 0xc1, 0xe5, 0xa0, 0x9b, 0x8e, 0xd9, 0x75, 0x2d,
+	0xf9, 0xda, 0x53, 0x2c, 0x52, 0xd7, 0x46, 0x1c, 0x88, 0x49, 0xdc, 0xb0, 0xe2, 0xbc, 0x27, 0xc8,
+	0x26, 0x00, 0xdb, 0x29, 0x64, 0x29, 0x4f, 0x54, 0x75, 0xae, 0x1c, 0xdd, 0x0c, 0x33, 0x63, 0x8c,
+	0x50, 0x46, 0x14, 0xf0, 0xe2, 0xa8, 0xa3, 0x80, 0xcf, 0x41, 0x7d, 0x47, 0x77, 0x4c, 0x7f, 0x47,
+	0xdf, 0xa5, 0xf2, 0x46, 0x45, 0x78, 0x72, 0xbf, 0xad, 0x00, 0x18, 0xe1, 0x68, 0xff, 0x68, 0x0c,
+	0x84, 0x1b, 0x15, 0x5b, 0xd2, 0x4d, 0xcb, 0x17, 0xf7, 0x9e, 0x0a, 0x3c, 0x67, 0xb8, 0xa4, 0x2f,
+	0xc9, 0x74, 0x0c, 0x31, 0xc8, 0x15, 0x28, 0x75, 0x2c, 0x47, 0x0a, 0xec, 0xdc, 0xee, 0xb1, 0x66,
+	0x39, 0xc8, 0xd2, 0x38, 0x48, 0x7f, 0x2c, 0x05, 0x72, 0x01, 0xd2, 0x1f, 0x23, 0x4b, 0x23, 0x5f,
+	0x81, 0x29, 0xdb, 0x75, 0x77, 0xd9, 0xe2, 0x1c, 0xf7, 0x0c, 0x9f, 0x10, 0x9a, 0xc8, 0xd5, 0x24,
+	0x08, 0xd3, 0xb8, 0x64, 0x13, 0x9e, 0xfb, 0x80, 0x7a, 0xae, 0xdc, 0x8d, 0x5a, 0x36, 0xa5, 0x5d,
+	0x45, 0x46, 0x88, 0x81, 0xdc, 0x71, 0xfd, 0xeb, 0xd9, 0x28, 0x38, 0x28, 0x2f, 0xbf, 0x6a, 0xa3,
+	0x7b, 0x6d, 0x1a, 0xac, 0x7b, 0x2e, 0x13, 0xf5, 0x2d, 0xa7, 0xad, 0xc8, 0x8e, 0x45, 0x64, 0x37,
+	0xb2, 0x51, 0x70, 0x50, 0x5e, 0xf2, 0x36, 0x4c, 0x0b, 0x90, 0x10, 0x0a, 0x17, 0xc4, 0x22, 0x6e,
+	0xd9, 0xea, 0xf9, 0xed, 0x09, 0x61, 0x5e, 0xde, 0x18, 0x80, 0x83, 0x03, 0x73, 0x93, 0x3b, 0x70,
+	0x4e, 0x39, 0x17, 0xac, 0x53, 0xaf, 0x15, 0xba, 0xd6, 0x4d, 0xa8, 0x1b, 0x06, 0xca, 0xc3, 0x1e,
+	0x53, 0x58, 0xd8, 0x97, 0x8f, 0x20, 0x5c, 0xe6, 0xfe, 0x73, 0x9b, 0xdd, 0x45, 0xd7, 0xb5, 0x4d,
+	0xf7, 0x91, 0xa3, 0xea, 0x2e, 0xce, 0xb7, 0xdc, 0x9f, 0xa0, 0x95, 0x89, 0x81, 0x03, 0x72, 0xb2,
+	0x9a, 0x73, 0xc8, 0x92, 0xfb, 0xc8, 0x49, 0x53, 0x85, 0xa8, 0xe6, 0xad, 0x01, 0x38, 0x38, 0x30,
+	0x37, 0x59, 0x06, 0x92, 0xae, 0xc1, 0x66, 0x57, 0x7a, 0xbc, 0x5c, 0x16, 0xf1, 0xea, 0xd2, 0x50,
+	0xcc, 0xc8, 0x41, 0x56, 0xe1, 0x62, 0x3a, 0x95, 0xb1, 0x93, 0xce, 0x2f, 0x3c, 0x52, 0x3d, 0x66,
+	0xc0, 0x31, 0x33, 0x97, 0xd6, 0x80, 0x7a, 0xf8, 0x80, 0xb1, 0xf6, 0x6f, 0x8b, 0x30, 0x95, 0x8a,
+	0xf9, 0x75, 0x06, 0x96, 0x10, 0x27, 0x61, 0x09, 0x59, 0xcd, 0xf5, 0x10, 0x73, 0xac, 0xe4, 0x03,
+	0x0d, 0x22, 0x7b, 0x29, 0x83, 0xc8, 0xbd, 0x91, 0x71, 0x3c, 0xda, 0x2e, 0x72, 0x58, 0x80, 0x0b,
+	0xa9, 0x1c, 0x67, 0xa0, 0xee, 0xef, 0x24, 0xd5, 0xfd, 0xb7, 0x47, 0x55, 0xd9, 0x01, 0x5a, 0xff,
+	0xff, 0xd3, 0x5f, 0xc9, 0x96, 0xb0, 0x42, 0x55, 0x65, 0x78, 0xa5, 0xdc, 0x07, 0x4a, 0x15, 0xbf,
+	0x89, 0xf5, 0x6f, 0x32, 0x5c, 0x8d, 0xd3, 0x46, 0xc5, 0x85, 0xf8, 0x50, 0x53, 0x31, 0x94, 0x46,
+	0x6b, 0x63, 0x0b, 0x1b, 0x3b, 0x0c, 0x8b, 0x17, 0x32, 0xd2, 0xfe, 0x4a, 0x09, 0x2e, 0x65, 0x0e,
+	0x8a, 0xb3, 0x53, 0xb5, 0x7e, 0x39, 0xa9, 0x6a, 0x7d, 0x29, 0xad, 0x6a, 0xbd, 0x98, 0x2a, 0xdf,
+	0x33, 0xac, 0x71, 0x1d, 0xa1, 0x16, 0x51, 0x9b, 0x82, 0x89, 0x44, 0xdc, 0x2f, 0xed, 0x77, 0x2b,
+	0xd0, 0x88, 0x8d, 0xa4, 0x67, 0x2e, 0xde, 0x12, 0xf9, 0x12, 0x4c, 0x76, 0xfc, 0xf6, 0xca, 0xd2,
+	0x6d, 0xaa, 0x9b, 0xd4, 0x53, 0xd7, 0x4c, 0xeb, 0xf2, 0xac, 0x95, 0x80, 0x60, 0x0a, 0x93, 0xac,
+	0xc2, 0x25, 0x8f, 0xbe, 0xdf, 0xa3, 0x7e, 0x90, 0xd4, 0x45, 0x4a, 0x91, 0x45, 0x6e, 0x37, 0x29,
+	0x04, 0x1f, 0xb3, 0x33, 0xb1, 0x25, 0x44, 0xf8, 0x26, 0x54, 0x72, 0xce, 0x23, 0xd5, 0xde, 0xdc,
+	0x41, 0x41, 0x44, 0x67, 0x8a, 0xa5, 0xa0, 0xe0, 0x32, 0xe0, 0xea, 0xc2, 0xd8, 0x47, 0x78, 0x75,
+	0x21, 0xee, 0x2f, 0x59, 0x3d, 0xd2, 0x5f, 0xf2, 0x99, 0x76, 0x0f, 0xd3, 0xbe, 0x0d, 0x89, 0x06,
+	0x27, 0x2e, 0xd4, 0xc3, 0xca, 0xe6, 0xf6, 0xd9, 0x8a, 0xae, 0x0f, 0x70, 0x83, 0x45, 0xf8, 0x8b,
+	0x11, 0x0f, 0x6d, 0x9b, 0xcd, 0x42, 0xdf, 0xb7, 0x5c, 0xe7, 0x74, 0x1f, 0xa4, 0xfe, 0xd7, 0x45,
+	0xa8, 0x87, 0x66, 0xb0, 0x63, 0x3c, 0x5c, 0x95, 0x68, 0x88, 0xe2, 0xe9, 0x37, 0x44, 0xfc, 0x32,
+	0x4c, 0x29, 0xc7, 0x65, 0x98, 0x2e, 0x54, 0x03, 0xcf, 0x6a, 0xb7, 0xa5, 0xd2, 0x30, 0xcf, 0x6d,
+	0x98, 0xb0, 0xb9, 0x36, 0x04, 0x41, 0xd9, 0xb2, 0xe2, 0x07, 0x15, 0x1b, 0xed, 0x3d, 0x38, 0x97,
+	0xc6, 0xe4, 0x1a, 0x35, 0x63, 0x87, 0x9a, 0x3d, 0x5b, 0xb5, 0x71, 0xa4, 0x51, 0x93, 0xe9, 0x18,
+	0x62, 0xb0, 0xc9, 0xc4, 0xba, 0xe9, 0x03, 0xd7, 0x51, 0x7b, 0x14, 0x9f, 0x4c, 0x1b, 0x32, 0x0d,
+	0x43, 0xa8, 0xf6, 0x9f, 0x4b, 0x70, 0x25, 0x32, 0x66, 0xae, 0xe9, 0x8e, 0xde, 0x4e, 0x3a, 0xaa,
+	0x7e, 0x12, 0x95, 0x61, 0x24, 0xaf, 0x0f, 0x96, 0x9e, 0x81, 0xd7, 0x07, 0xff, 0x5f, 0x11, 0xf8,
+	0xe5, 0x3a, 0xf2, 0x6d, 0x18, 0x57, 0xed, 0xc9, 0xfe, 0x65, 0x77, 0xde, 0xcc, 0xdd, 0x9d, 0xfc,
+	0x0e, 0x5f, 0x68, 0xe7, 0x89, 0xa7, 0x62, 0x82, 0x21, 0x71, 0xa1, 0xb6, 0xad, 0xdb, 0x36, 0x3b,
+	0xbc, 0xe7, 0x16, 0x1c, 0x13, 0xcc, 0xf9, 0x30, 0x5f, 0x96, 0xa4, 0x31, 0x64, 0x42, 0xbe, 0x5b,
+	0x80, 0x09, 0x2f, 0xae, 0xbd, 0x95, 0x1d, 0x92, 0xc7, 0x75, 0x37, 0x46, 0x2d, 0x7e, 0x9d, 0x22,
+	0xae, 0x22, 0x4e, 0xf2, 0xd4, 0xfe, 0x53, 0x01, 0x26, 0x5a, 0xb6, 0x65, 0x5a, 0x4e, 0xfb, 0x14,
+	0x1f, 0x3f, 0xbc, 0x0f, 0x15, 0xdf, 0xb6, 0x4c, 0x3a, 0xe4, 0x5d, 0x5b, 0xf1, 0x34, 0x3f, 0x23,
+	0x80, 0x82, 0x4e, 0xf2, 0x35, 0xc5, 0xd2, 0x31, 0x5e, 0x53, 0xfc, 0xcd, 0x1a, 0xc8, 0x6b, 0xa2,
+	0xa4, 0x07, 0xf5, 0xb6, 0x7a, 0xa4, 0x4d, 0xd6, 0xf1, 0x76, 0x8e, 0x00, 0xff, 0x89, 0xe7, 0xde,
+	0xc4, 0xda, 0x1f, 0x26, 0x62, 0xc4, 0x89, 0x50, 0xa8, 0xf0, 0x60, 0x0c, 0xb9, 0xad, 0x5d, 0xb1,
+	0xb0, 0x1b, 0xa2, 0x65, 0x78, 0x02, 0x0a, 0xea, 0x44, 0x87, 0xf2, 0x4e, 0x10, 0x74, 0xe5, 0x60,
+	0x1a, 0xde, 0x76, 0x18, 0xc5, 0x24, 0x15, 0xd2, 0x2c, 0xfb, 0x47, 0x4e, 0x9a, 0xb1, 0x70, 0xf4,
+	0xf0, 0x25, 0xf9, 0xc5, 0x5c, 0x6e, 0xc2, 0x71, 0x16, 0xec, 0x1f, 0x39, 0x69, 0xf2, 0x73, 0xd0,
+	0x08, 0x3c, 0xdd, 0xf1, 0xb7, 0x5d, 0xaf, 0x43, 0x3d, 0x29, 0x81, 0x0e, 0x3f, 0x33, 0x36, 0x97,
+	0x36, 0x22, 0x6a, 0xc2, 0xe4, 0x9e, 0x48, 0xc2, 0x38, 0x37, 0xb2, 0x0b, 0xb5, 0x9e, 0x29, 0x0a,
+	0x26, 0xe5, 0xcf, 0x85, 0x1c, 0x9c, 0xe3, 0x4e, 0xc0, 0xea, 0x0f, 0x43, 0x06, 0x6c, 0x34, 0x46,
+	0x71, 0x13, 0xab, 0x39, 0x47, 0x63, 0x2a, 0xa6, 0xd3, 0xe0, 0x80, 0x89, 0xa4, 0x13, 0x1d, 0xcc,
+	0x6b, 0x39, 0x1b, 0x37, 0x71, 0xc0, 0x92, 0x51, 0x6e, 0xd3, 0xc7, 0x72, 0x0b, 0xc6, 0xba, 0xdc,
+	0x18, 0x2d, 0xef, 0x27, 0xdc, 0xcc, 0x69, 0xd3, 0x8e, 0xdf, 0xfe, 0x16, 0x29, 0x28, 0x19, 0x90,
+	0x6f, 0x40, 0xc9, 0x7f, 0xdf, 0x97, 0x8f, 0x98, 0xe7, 0x30, 0x3a, 0xbc, 0xaf, 0xc6, 0x26, 0x57,
+	0x08, 0xb7, 0xde, 0xf7, 0x91, 0xd1, 0xd5, 0x7e, 0xbb, 0x0c, 0xf5, 0x10, 0xc6, 0xd6, 0x21, 0xfd,
+	0x91, 0x8f, 0xb4, 0x1d, 0xdd, 0xbf, 0x0a, 0xd7, 0xa1, 0x85, 0x87, 0x2d, 0x01, 0xc0, 0x08, 0x87,
+	0x65, 0xe0, 0x4e, 0xfc, 0xdc, 0x3e, 0x5c, 0x4c, 0x66, 0x78, 0x4b, 0x01, 0x30, 0xc2, 0x21, 0x0f,
+	0xe0, 0x32, 0xff, 0xb9, 0xff, 0xc8, 0xa1, 0xde, 0xc2, 0xc3, 0xd6, 0x82, 0x61, 0xb8, 0x3d, 0x6e,
+	0xe0, 0x28, 0x25, 0x9c, 0xaa, 0x2e, 0xbf, 0x95, 0x89, 0x85, 0x03, 0x72, 0x93, 0x45, 0x38, 0xbf,
+	0x67, 0xf9, 0x96, 0xd0, 0xcf, 0xc6, 0xfd, 0x5c, 0x2b, 0x42, 0xb8, 0x78, 0x90, 0x06, 0x62, 0x3f,
+	0x3e, 0x59, 0x81, 0x0b, 0x1d, 0xfd, 0xf1, 0xbd, 0x5e, 0x67, 0x8b, 0x7a, 0xf7, 0xb7, 0xa5, 0xb2,
+	0xc0, 0x97, 0xbe, 0x25, 0xdc, 0xb5, 0x66, 0xad, 0x1f, 0x8c, 0x59, 0x79, 0xc8, 0x57, 0x60, 0xea,
+	0x91, 0x6e, 0xf1, 0x33, 0x68, 0x5c, 0x95, 0x5d, 0x11, 0x8a, 0xf6, 0x87, 0x49, 0x10, 0xa6, 0x71,
+	0xc9, 0x2b, 0xd0, 0xa0, 0xd2, 0x34, 0xb2, 0xe9, 0xd9, 0xea, 0x5e, 0xe6, 0xe1, 0xc1, 0x4c, 0x43,
+	0x59, 0x4c, 0xb8, 0xad, 0x3e, 0x86, 0xc3, 0x4e, 0xda, 0x7a, 0x10, 0x78, 0xd6, 0x56, 0x2f, 0xe0,
+	0x4d, 0x2d, 0xbc, 0xf2, 0xe4, 0x49, 0x7b, 0x21, 0x01, 0xc1, 0x14, 0x26, 0xb9, 0x0f, 0x97, 0xa4,
+	0x46, 0x24, 0x89, 0x28, 0x83, 0xe0, 0x71, 0x41, 0x68, 0x2d, 0x0b, 0x01, 0xb3, 0xf3, 0x69, 0x1d,
+	0x90, 0x1a, 0x1d, 0x62, 0x24, 0x5e, 0x52, 0x16, 0xa1, 0x61, 0xe6, 0x8e, 0xb7, 0x61, 0x86, 0x4f,
+	0xfa, 0xc6, 0x5e, 0x72, 0xcb, 0x7c, 0x32, 0x59, 0xfb, 0x37, 0x45, 0x28, 0x6d, 0xac, 0xb6, 0xc4,
+	0xeb, 0x2c, 0xfc, 0x6d, 0x76, 0xda, 0xda, 0xb5, 0xba, 0x0f, 0xa8, 0x67, 0x6d, 0xef, 0x4b, 0x63,
+	0x4a, 0xec, 0x75, 0x96, 0x34, 0x06, 0x66, 0xe4, 0xe2, 0xb6, 0x32, 0x7d, 0x91, 0x7a, 0x39, 0x6c,
+	0x65, 0x0b, 0x51, 0x76, 0x4c, 0x10, 0x23, 0x9b, 0x00, 0x46, 0x44, 0xba, 0x74, 0x62, 0x03, 0x57,
+	0x8c, 0x70, 0x8c, 0x10, 0x41, 0xa8, 0xef, 0x32, 0x54, 0x4e, 0xb5, 0x7c, 0x12, 0xaa, 0x7c, 0x69,
+	0xbd, 0xab, 0xf2, 0x62, 0x44, 0x46, 0x73, 0x60, 0x22, 0xf1, 0xbc, 0x32, 0xf9, 0x22, 0xd4, 0xdc,
+	0x6e, 0x4c, 0xde, 0xa8, 0xf3, 0xeb, 0x84, 0xb5, 0xfb, 0x32, 0xed, 0xc9, 0xc1, 0xcc, 0xc4, 0xaa,
+	0xdb, 0xb6, 0x0c, 0x95, 0x80, 0x21, 0x3a, 0xd1, 0x60, 0x8c, 0x07, 0xae, 0x51, 0x8f, 0x2b, 0xf3,
+	0x05, 0x8f, 0xbf, 0x7f, 0xea, 0xa3, 0x84, 0x68, 0x3f, 0x5f, 0x86, 0xc8, 0xe5, 0x94, 0xf8, 0x30,
+	0x26, 0x2e, 0xcd, 0x4b, 0xd1, 0xe6, 0x54, 0xef, 0xe7, 0x4b, 0x56, 0xa4, 0x0d, 0xa5, 0xf7, 0xdc,
+	0xad, 0xdc, 0x92, 0x4d, 0x2c, 0xfa, 0x9e, 0x98, 0xbb, 0xb1, 0x04, 0x64, 0x1c, 0xc8, 0x5f, 0x2f,
+	0xc0, 0x79, 0x3f, 0x7d, 0x36, 0x94, 0xc3, 0x01, 0xf3, 0x1f, 0x82, 0xd3, 0xa7, 0x4d, 0x79, 0xef,
+	0x73, 0x10, 0x18, 0xfb, 0xcb, 0xc2, 0xda, 0x5f, 0xf8, 0x82, 0xca, 0xe1, 0x34, 0x7c, 0xfb, 0x0b,
+	0xff, 0xd2, 0x64, 0xfb, 0x27, 0xd3, 0x50, 0xb2, 0xd2, 0xbe, 0x53, 0x84, 0x46, 0x4c, 0x9c, 0xc9,
+	0xfd, 0x66, 0xf7, 0xe3, 0xd4, 0x9b, 0xdd, 0xeb, 0xc3, 0xbb, 0x46, 0x47, 0xa5, 0x3a, 0xed, 0x67,
+	0xbb, 0xff, 0x49, 0x11, 0x4a, 0x9b, 0x4b, 0xcb, 0x67, 0xae, 0xde, 0x22, 0x3b, 0x50, 0xdd, 0xea,
+	0x59, 0x76, 0x60, 0x39, 0xb9, 0xe3, 0x83, 0xaa, 0x27, 0xce, 0xa5, 0x6f, 0x90, 0xa0, 0x8a, 0x8a,
+	0x3c, 0x69, 0x43, 0xb5, 0x2d, 0x1e, 0x68, 0xc8, 0x7d, 0x61, 0x4c, 0x3e, 0xf4, 0x20, 0x18, 0xc9,
+	0x1f, 0x54, 0xd4, 0xb5, 0x7d, 0x18, 0xdb, 0x5c, 0x92, 0xe7, 0xe2, 0x33, 0x56, 0x16, 0xfe, 0x1c,
+	0x84, 0x62, 0xf2, 0xd9, 0x33, 0xff, 0xaf, 0x05, 0x48, 0x9e, 0x0c, 0xce, 0x7e, 0x34, 0xed, 0xa6,
+	0x47, 0xd3, 0xd2, 0x28, 0x26, 0x5f, 0xf6, 0x80, 0xd2, 0xfe, 0x55, 0x01, 0x52, 0x91, 0x4e, 0xc8,
+	0x6b, 0x32, 0xd6, 0x77, 0xf2, 0x66, 0x8e, 0x8a, 0xf5, 0x4d, 0x92, 0xd8, 0xb1, 0x98, 0xdf, 0x1f,
+	0x16, 0x60, 0xc2, 0x8b, 0x3b, 0x9c, 0xc9, 0xe2, 0x0f, 0x6f, 0x67, 0xcd, 0x74, 0x5f, 0x93, 0xb7,
+	0xc7, 0xe2, 0x20, 0x4c, 0xf2, 0xd5, 0xfe, 0x61, 0x11, 0xc6, 0xce, 0x2c, 0xb8, 0x1b, 0x4d, 0x98,
+	0xb1, 0x17, 0x73, 0xae, 0xf6, 0x03, 0xad, 0xd7, 0x9d, 0x94, 0xf5, 0xfa, 0x66, 0x5e, 0x46, 0x47,
+	0x1b, 0xad, 0xff, 0x45, 0x01, 0xe4, 0x5e, 0xb3, 0xe2, 0xf8, 0x81, 0xee, 0x18, 0x94, 0x18, 0xe1,
+	0xc6, 0x96, 0xd7, 0x94, 0x29, 0x6f, 0x56, 0x09, 0x59, 0x86, 0x7f, 0xab, 0x8d, 0x8c, 0x7c, 0x0e,
+	0x6a, 0x3b, 0xae, 0x1f, 0x38, 0xd1, 0xe9, 0x28, 0xd4, 0x29, 0xdf, 0x96, 0xe9, 0x18, 0x62, 0xa4,
+	0xdd, 0x3f, 0x2b, 0x83, 0xdd, 0x3f, 0xb5, 0xaf, 0xc3, 0x54, 0x3a, 0x42, 0xdd, 0xad, 0xcc, 0x08,
+	0x75, 0x2f, 0x0e, 0x88, 0x50, 0xd7, 0x18, 0x1c, 0x9d, 0xee, 0x57, 0x8b, 0x30, 0xfe, 0x71, 0x89,
+	0x4c, 0x97, 0x75, 0xb5, 0xb2, 0x94, 0xf3, 0x6a, 0x65, 0xf9, 0x24, 0x57, 0x2b, 0xb5, 0x1f, 0x16,
+	0x00, 0xce, 0x2c, 0x2c, 0x9e, 0x99, 0x74, 0x83, 0xc8, 0x3d, 0x66, 0xb3, 0xbd, 0x1f, 0xfe, 0xee,
+	0x98, 0xaa, 0x12, 0xb7, 0x29, 0x7f, 0x58, 0x80, 0x49, 0x3d, 0x71, 0x8b, 0x30, 0xb7, 0x2c, 0x9e,
+	0xba, 0x94, 0x18, 0x5e, 0x82, 0x49, 0xa6, 0x63, 0x8a, 0x2d, 0x79, 0x3d, 0x7a, 0xc2, 0x2a, 0xa6,
+	0x70, 0xe8, 0x7b, 0x7b, 0x4a, 0x5c, 0x7b, 0x88, 0x63, 0x3e, 0xe5, 0xd6, 0x66, 0x69, 0x24, 0xb7,
+	0x36, 0xe3, 0xf6, 0xd5, 0xf2, 0x91, 0xf6, 0xd5, 0x3d, 0xa8, 0x6f, 0x7b, 0x6e, 0x87, 0x5f, 0x8c,
+	0x9c, 0xae, 0xf0, 0xae, 0xbc, 0x99, 0x63, 0x13, 0xee, 0x6c, 0x59, 0x0e, 0x35, 0xf9, 0xa5, 0xcb,
+	0x50, 0xf9, 0xb2, 0xac, 0xe8, 0x63, 0xc4, 0x8a, 0x1b, 0xda, 0x5c, 0xc1, 0x75, 0x6c, 0x94, 0x5c,
+	0xc3, 0x75, 0x6a, 0x43, 0x50, 0x47, 0xc5, 0x26, 0x79, 0x19, 0xb2, 0x7a, 0x46, 0x97, 0x21, 0xf7,
+	0xe3, 0x77, 0x4c, 0x6b, 0x39, 0x75, 0x90, 0x27, 0x0b, 0x64, 0xf6, 0x17, 0xaa, 0x6a, 0xed, 0x7c,
+	0xe6, 0x1e, 0x6a, 0xf9, 0x24, 0x80, 0x59, 0x9b, 0xf6, 0x45, 0x17, 0xab, 0x9d, 0x61, 0x74, 0xb1,
+	0xfa, 0x68, 0xa2, 0x8b, 0x41, 0xbe, 0xe8, 0x62, 0x8d, 0x11, 0x45, 0x17, 0x1b, 0x1f, 0x55, 0x74,
+	0xb1, 0x89, 0xa1, 0xa2, 0x8b, 0x4d, 0x1e, 0x2b, 0xba, 0xd8, 0x41, 0x09, 0x52, 0x3a, 0x86, 0x4f,
+	0x0c, 0xee, 0x7f, 0xa8, 0x0c, 0xee, 0xdf, 0x2b, 0x42, 0xb4, 0x07, 0x9c, 0xd0, 0x83, 0xfe, 0x6d,
+	0x7e, 0x89, 0x91, 0x5f, 0x88, 0x1d, 0x52, 0x34, 0x1d, 0x97, 0x17, 0x1e, 0x39, 0x0d, 0x0c, 0xa9,
+	0x11, 0x1f, 0xc0, 0x0a, 0xdf, 0x18, 0xcc, 0x6d, 0xba, 0x8c, 0x9e, 0x2b, 0x14, 0xba, 0xdf, 0xe8,
+	0x1f, 0x63, 0x6c, 0xb4, 0xdf, 0x2a, 0x81, 0x7c, 0x8c, 0x92, 0x50, 0xa8, 0x6c, 0x5b, 0x8f, 0xa9,
+	0x99, 0xdb, 0x49, 0x75, 0x99, 0x51, 0x91, 0x2f, 0x5e, 0x72, 0xdb, 0x2c, 0x4f, 0x40, 0x41, 0x9d,
+	0x1b, 0xdd, 0x84, 0xad, 0x5d, 0xb6, 0x5f, 0x0e, 0xa3, 0x5b, 0xdc, 0x66, 0x2f, 0x8d, 0x6e, 0x22,
+	0x09, 0x15, 0x0f, 0x61, 0xe3, 0xe3, 0x6e, 0x57, 0xb9, 0x5d, 0x0b, 0x12, 0xee, 0x5b, 0xca, 0xc6,
+	0xe7, 0x8b, 0xf0, 0x82, 0x92, 0x07, 0xf9, 0x16, 0x34, 0x74, 0xc3, 0xe8, 0x75, 0x7a, 0x36, 0xd7,
+	0x74, 0xe7, 0x0d, 0xc2, 0xb7, 0x10, 0xd1, 0x92, 0x6c, 0xf9, 0xc1, 0x26, 0x96, 0x8c, 0x71, 0x7e,
+	0xcd, 0x6f, 0xfc, 0xe0, 0xc7, 0xd7, 0x3e, 0xf5, 0xc3, 0x1f, 0x5f, 0xfb, 0xd4, 0x8f, 0x7e, 0x7c,
+	0xed, 0x53, 0x3f, 0x7f, 0x78, 0xad, 0xf0, 0x83, 0xc3, 0x6b, 0x85, 0x1f, 0x1e, 0x5e, 0x2b, 0xfc,
+	0xe8, 0xf0, 0x5a, 0xe1, 0x3f, 0x1c, 0x5e, 0x2b, 0xfc, 0xe5, 0xff, 0x78, 0xed, 0x53, 0x5f, 0xff,
+	0x42, 0x54, 0x9c, 0x39, 0x55, 0x9c, 0x39, 0xc5, 0x7c, 0xae, 0xbb, 0xdb, 0x9e, 0x63, 0xc5, 0x89,
+	0x52, 0x54, 0x71, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xbb, 0x19, 0xb2, 0x01, 0xb1,
+	0x00, 0x00,
 }
 
 func (m *AbstractPodTemplate) Marshal() (dAtA []byte, err error) {
@@ -8988,6 +9032,16 @@ func (m *ServingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	{
+		size, err := m.AbstractPodTemplate.MarshalToSizedBuffer(dAtA[:i])
+		if err != nil {
+			return 0, err
+		}
+		i -= size
+		i = encodeVarintGenerated(dAtA, i, uint64(size))
+	}
+	i--
+	dAtA[i] = 0x42
 	if m.Replicas != nil {
 		i = encodeVarintGenerated(dAtA, i, uint64(*m.Replicas))
 		i--
@@ -9410,6 +9464,18 @@ func (m *Source) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	if m.Sqs != nil {
+		{
+			size, err := m.Sqs.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintGenerated(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x52
+	}
 	if m.Pulsar != nil {
 		{
 			size, err := m.Pulsar.MarshalToSizedBuffer(dAtA[:i])
@@ -9521,6 +9587,84 @@ func (m *Source) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	return len(dAtA) - i, nil
 }
 
+func (m *SqsSource) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *SqsSource) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SqsSource) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.MessageAttributeNames) > 0 {
+		for iNdEx := len(m.MessageAttributeNames) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.MessageAttributeNames[iNdEx])
+			copy(dAtA[i:], m.MessageAttributeNames[iNdEx])
+			i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageAttributeNames[iNdEx])))
+			i--
+			dAtA[i] = 0x4a
+		}
+	}
+	if len(m.AttributeNames) > 0 {
+		for iNdEx := len(m.AttributeNames) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.AttributeNames[iNdEx])
+			copy(dAtA[i:], m.AttributeNames[iNdEx])
+			i = encodeVarintGenerated(dAtA, i, uint64(len(m.AttributeNames[iNdEx])))
+			i--
+			dAtA[i] = 0x42
+		}
+	}
+	if m.EndpointURL != nil {
+		i -= len(*m.EndpointURL)
+		copy(dAtA[i:], *m.EndpointURL)
+		i = encodeVarintGenerated(dAtA, i, uint64(len(*m.EndpointURL)))
+		i--
+		dAtA[i] = 0x3a
+	}
+	if m.WaitTimeSeconds != nil {
+		i = encodeVarintGenerated(dAtA, i, uint64(*m.WaitTimeSeconds))
+		i--
+		dAtA[i] = 0x30
+	}
+	if m.MaxNumberOfMessages != nil {
+		i = encodeVarintGenerated(dAtA, i, uint64(*m.MaxNumberOfMessages))
+		i--
+		dAtA[i] = 0x28
+	}
+	if m.VisibilityTimeout != nil {
+		i = encodeVarintGenerated(dAtA, i, uint64(*m.VisibilityTimeout))
+		i--
+		dAtA[i] = 0x20
+	}
+	i -= len(m.QueueOwnerAWSAccountID)
+	copy(dAtA[i:], m.QueueOwnerAWSAccountID)
+	i = encodeVarintGenerated(dAtA, i, uint64(len(m.QueueOwnerAWSAccountID)))
+	i--
+	dAtA[i] = 0x1a
+	i -= len(m.QueueName)
+	copy(dAtA[i:], m.QueueName)
+	i = encodeVarintGenerated(dAtA, i, uint64(len(m.QueueName)))
+	i--
+	dAtA[i] = 0x12
+	i -= len(m.AWSRegion)
+	copy(dAtA[i:], m.AWSRegion)
+	i = encodeVarintGenerated(dAtA, i, uint64(len(m.AWSRegion)))
+	i--
+	dAtA[i] = 0xa
+	return len(dAtA) - i, nil
+}
+
 func (m *Status) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -12556,6 +12700,8 @@ func (m *ServingSpec) Size() (n int) {
 	if m.Replicas != nil {
 		n += 1 + sovGenerated(uint64(*m.Replicas))
 	}
+	l = m.AbstractPodTemplate.Size()
+	n += 1 + l + sovGenerated(uint64(l))
 	return n
 }
 
@@ -12721,6 +12867,50 @@ func (m *Source) Size() (n int) {
 		l = m.Pulsar.Size()
 		n += 1 + l + sovGenerated(uint64(l))
 	}
+	if m.Sqs != nil {
+		l = m.Sqs.Size()
+		n += 1 + l + sovGenerated(uint64(l))
+	}
+	return n
+}
+
+func (m *SqsSource) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.AWSRegion)
+	n += 1 + l + sovGenerated(uint64(l))
+	l = len(m.QueueName)
+	n += 1 + l + sovGenerated(uint64(l))
+	l = len(m.QueueOwnerAWSAccountID)
+	n += 1 + l + sovGenerated(uint64(l))
+	if m.VisibilityTimeout != nil {
+		n += 1 + sovGenerated(uint64(*m.VisibilityTimeout))
+	}
+	if m.MaxNumberOfMessages != nil {
+		n += 1 + sovGenerated(uint64(*m.MaxNumberOfMessages))
+	}
+	if m.WaitTimeSeconds != nil {
+		n += 1 + sovGenerated(uint64(*m.WaitTimeSeconds))
+	}
+	if m.EndpointURL != nil {
+		l = len(*m.EndpointURL)
+		n += 1 + l + sovGenerated(uint64(l))
+	}
+	if len(m.AttributeNames) > 0 {
+		for _, s := range m.AttributeNames {
+			l = len(s)
+			n += 1 + l + sovGenerated(uint64(l))
+		}
+	}
+	if len(m.MessageAttributeNames) > 0 {
+		for _, s := range m.MessageAttributeNames {
+			l = len(s)
+			n += 1 + l + sovGenerated(uint64(l))
+		}
+	}
 	return n
 }
 
@@ -14458,6 +14648,7 @@ func (this *ServingSpec) String() string {
 		`ServingStore:` + strings.Replace(this.ServingStore.String(), "ServingStore", "ServingStore", 1) + `,`,
 		`ContainerTemplate:` + strings.Replace(this.ContainerTemplate.String(), "ContainerTemplate", "ContainerTemplate", 1) + `,`,
 		`Replicas:` + valueToStringGenerated(this.Replicas) + `,`,
+		`AbstractPodTemplate:` + strings.Replace(strings.Replace(this.AbstractPodTemplate.String(), "AbstractPodTemplate", "AbstractPodTemplate", 1), `&`, ``, 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -14561,6 +14752,25 @@ func (this *Source) String() string {
 		`JetStream:` + strings.Replace(this.JetStream.String(), "JetStreamSource", "JetStreamSource", 1) + `,`,
 		`Serving:` + strings.Replace(this.Serving.String(), "ServingSource", "ServingSource", 1) + `,`,
 		`Pulsar:` + strings.Replace(this.Pulsar.String(), "PulsarSource", "PulsarSource", 1) + `,`,
+		`Sqs:` + strings.Replace(this.Sqs.String(), "SqsSource", "SqsSource", 1) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func (this *SqsSource) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&SqsSource{`,
+		`AWSRegion:` + fmt.Sprintf("%v", this.AWSRegion) + `,`,
+		`QueueName:` + fmt.Sprintf("%v", this.QueueName) + `,`,
+		`QueueOwnerAWSAccountID:` + fmt.Sprintf("%v", this.QueueOwnerAWSAccountID) + `,`,
+		`VisibilityTimeout:` + valueToStringGenerated(this.VisibilityTimeout) + `,`,
+		`MaxNumberOfMessages:` + valueToStringGenerated(this.MaxNumberOfMessages) + `,`,
+		`WaitTimeSeconds:` + valueToStringGenerated(this.WaitTimeSeconds) + `,`,
+		`EndpointURL:` + valueToStringGenerated(this.EndpointURL) + `,`,
+		`AttributeNames:` + fmt.Sprintf("%v", this.AttributeNames) + `,`,
+		`MessageAttributeNames:` + fmt.Sprintf("%v", this.MessageAttributeNames) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -31660,6 +31870,39 @@ func (m *ServingSpec) Unmarshal(dAtA []byte) error {
 				}
 			}
 			m.Replicas = &v
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AbstractPodTemplate", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.AbstractPodTemplate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -32958,6 +33201,345 @@ func (m *Source) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 10:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Sqs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Sqs == nil {
+				m.Sqs = &SqsSource{}
+			}
+			if err := m.Sqs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipGenerated(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *SqsSource) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowGenerated
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: SqsSource: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: SqsSource: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AWSRegion", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.AWSRegion = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field QueueName", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.QueueName = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field QueueOwnerAWSAccountID", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.QueueOwnerAWSAccountID = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field VisibilityTimeout", wireType)
+			}
+			var v int32
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.VisibilityTimeout = &v
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxNumberOfMessages", wireType)
+			}
+			var v int32
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.MaxNumberOfMessages = &v
+		case 6:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field WaitTimeSeconds", wireType)
+			}
+			var v int32
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.WaitTimeSeconds = &v
+		case 7:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field EndpointURL", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			s := string(dAtA[iNdEx:postIndex])
+			m.EndpointURL = &s
+			iNdEx = postIndex
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AttributeNames", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.AttributeNames = append(m.AttributeNames, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
+		case 9:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MessageAttributeNames", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.MessageAttributeNames = append(m.MessageAttributeNames, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
diff --git a/pkg/apis/numaflow/v1alpha1/generated.proto b/pkg/apis/numaflow/v1alpha1/generated.proto
index e7ba853c..373bb2ea 100644
--- a/pkg/apis/numaflow/v1alpha1/generated.proto
+++ b/pkg/apis/numaflow/v1alpha1/generated.proto
@@ -1637,6 +1637,9 @@ message ServingSpec {
   // Initial replicas of the serving server deployment.
   // +optional
   optional int32 replicas = 7;
+
+  // +optional
+  optional AbstractPodTemplate abstractPodTemplate = 8;
 }
 
 // ServingStore defines information of a Serving Store used in a pipeline
@@ -1740,6 +1743,59 @@ message Source {
 
   // +optional
   optional PulsarSource pulsar = 9;
+
+  // +optional
+  optional SqsSource sqs = 10;
+}
+
+// SqsSource represents the configuration of an AWS SQS source
+message SqsSource {
+  // AWSRegion is the AWS Region where the SQS queue is located
+  optional string awsRegion = 1;
+
+  // QueueName is the name of the SQS queue
+  optional string queueName = 2;
+
+  // QueueOwnerAWSAccountID is the queue owner aws account id
+  optional string queueOwnerAWSAccountID = 3;
+
+  // VisibilityTimeout is the duration (in seconds) that the received messages are hidden from subsequent
+  // retrieve requests after being retrieved by a ReceiveMessage request.
+  // Valid values: 0-43200 (12 hours)
+  // +optional
+  optional int32 visibilityTimeout = 4;
+
+  // MaxNumberOfMessages is the maximum number of messages to return in a single poll.
+  // Valid values: 1-10
+  // Defaults to 1
+  // +optional
+  optional int32 maxNumberOfMessages = 5;
+
+  // WaitTimeSeconds is the duration (in seconds) for which the call waits for a message to arrive
+  // in the queue before returning. If a message is available, the call returns sooner than WaitTimeSeconds.
+  // Valid values: 0-20
+  // Defaults to 0 (short polling)
+  // +optional
+  optional int32 waitTimeSeconds = 6;
+
+  // EndpointURL is the custom endpoint URL for the AWS SQS API.
+  // This is useful for testing with localstack or when using VPC endpoints.
+  // +optional
+  optional string endpointUrl = 7;
+
+  // AttributeNames is a list of attributes that need to be returned along with each message.
+  // Valid values: All | Policy | VisibilityTimeout | MaximumMessageSize | MessageRetentionPeriod |
+  // ApproximateNumberOfMessages | ApproximateNumberOfMessagesNotVisible | CreatedTimestamp |
+  // LastModifiedTimestamp | QueueArn | ApproximateNumberOfMessagesDelayed | DelaySeconds |
+  // ReceiveMessageWaitTimeSeconds | RedrivePolicy | FifoQueue | ContentBasedDeduplication |
+  // KmsMasterKeyId | KmsDataKeyReusePeriodSeconds | DeduplicationScope | FifoThroughputLimit |
+  // RedriveAllowPolicy | SqsManagedSseEnabled
+  // +optional
+  repeated string attributeNames = 8;
+
+  // MessageAttributeNames is a list of message attributes that need to be returned along with each message.
+  // +optional
+  repeated string messageAttributeNames = 9;
 }
 
 // Status is a common structure which can be used for Status field.
diff --git a/pkg/apis/numaflow/v1alpha1/serving_pipeline_types.go b/pkg/apis/numaflow/v1alpha1/serving_pipeline_types.go
index 54d659dc..85aea42a 100644
--- a/pkg/apis/numaflow/v1alpha1/serving_pipeline_types.go
+++ b/pkg/apis/numaflow/v1alpha1/serving_pipeline_types.go
@@ -90,6 +90,8 @@ type ServingSpec struct {
 	// Initial replicas of the serving server deployment.
 	// +optional
 	Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,7,opt,name=replicas"`
+	// +optional
+	AbstractPodTemplate `json:",inline" protobuf:"bytes,8,opt,name=abstractPodTemplate"`
 }
 
 // ServingStore defines information of a Serving Store used in a pipeline
@@ -267,7 +269,9 @@ func (sp ServingPipeline) GetServingDeploymentObj(req GetServingPipelineResource
 	} else {
 		spec.Template.Spec.Containers = append(spec.Template.Spec.Containers, sp.getStoreSidecarContainerSpec(containerRequest)...)
 	}
-	// TODO(spl): add template
+
+	sp.Spec.Serving.AbstractPodTemplate.ApplyToPodTemplateSpec(&spec.Template)
+
 	return &appv1.Deployment{
 		ObjectMeta: metav1.ObjectMeta{
 			Namespace: sp.Namespace,
diff --git a/pkg/apis/numaflow/v1alpha1/source.go b/pkg/apis/numaflow/v1alpha1/source.go
index 71960c7d..92cbcda9 100644
--- a/pkg/apis/numaflow/v1alpha1/source.go
+++ b/pkg/apis/numaflow/v1alpha1/source.go
@@ -45,6 +45,8 @@ type Source struct {
 	Serving *ServingSource `json:"serving,omitempty" protobuf:"bytes,8,opt,name=serving"`
 	// +optional
 	Pulsar *PulsarSource `json:"pulsar,omitempty" protobuf:"bytes,9,opt,name=pulsar"`
+	// +optional
+	Sqs *SqsSource `json:"sqs,omitempty" protobuf:"bytes,10,opt,name=sqs"`
 }
 
 func (s Source) getContainers(req getContainerReq) ([]corev1.Container, []corev1.Container, error) {
diff --git a/pkg/apis/numaflow/v1alpha1/sqs_source.go b/pkg/apis/numaflow/v1alpha1/sqs_source.go
new file mode 100644
index 00000000..9293c36c
--- /dev/null
+++ b/pkg/apis/numaflow/v1alpha1/sqs_source.go
@@ -0,0 +1,67 @@
+/*
+Copyright 2022 The Numaproj Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+// SqsSource represents the configuration of an AWS SQS source
+type SqsSource struct {
+	// AWSRegion is the AWS Region where the SQS queue is located
+	AWSRegion string `json:"awsRegion" protobuf:"bytes,1,name=awsRegion"`
+
+	// QueueName is the name of the SQS queue
+	QueueName string `json:"queueName" protobuf:"bytes,2,name=queueName"`
+
+	// QueueOwnerAWSAccountID is the queue owner aws account id
+	QueueOwnerAWSAccountID string `json:"queueOwnerAWSAccountID" protobuf:"bytes,3,name=queueOwnerAWSAccountID"`
+
+	// VisibilityTimeout is the duration (in seconds) that the received messages are hidden from subsequent
+	// retrieve requests after being retrieved by a ReceiveMessage request.
+	// Valid values: 0-43200 (12 hours)
+	// +optional
+	VisibilityTimeout *int32 `json:"visibilityTimeout,omitempty" protobuf:"varint,4,opt,name=visibilityTimeout"`
+
+	// MaxNumberOfMessages is the maximum number of messages to return in a single poll.
+	// Valid values: 1-10
+	// Defaults to 1
+	// +optional
+	MaxNumberOfMessages *int32 `json:"maxNumberOfMessages,omitempty" protobuf:"varint,5,opt,name=maxNumberOfMessages"`
+
+	// WaitTimeSeconds is the duration (in seconds) for which the call waits for a message to arrive
+	// in the queue before returning. If a message is available, the call returns sooner than WaitTimeSeconds.
+	// Valid values: 0-20
+	// Defaults to 0 (short polling)
+	// +optional
+	WaitTimeSeconds *int32 `json:"waitTimeSeconds,omitempty" protobuf:"varint,6,opt,name=waitTimeSeconds"`
+
+	// EndpointURL is the custom endpoint URL for the AWS SQS API.
+	// This is useful for testing with localstack or when using VPC endpoints.
+	// +optional
+	EndpointURL *string `json:"endpointUrl,omitempty" protobuf:"bytes,7,opt,name=endpointUrl"`
+
+	// AttributeNames is a list of attributes that need to be returned along with each message.
+	// Valid values: All | Policy | VisibilityTimeout | MaximumMessageSize | MessageRetentionPeriod |
+	// ApproximateNumberOfMessages | ApproximateNumberOfMessagesNotVisible | CreatedTimestamp |
+	// LastModifiedTimestamp | QueueArn | ApproximateNumberOfMessagesDelayed | DelaySeconds |
+	// ReceiveMessageWaitTimeSeconds | RedrivePolicy | FifoQueue | ContentBasedDeduplication |
+	// KmsMasterKeyId | KmsDataKeyReusePeriodSeconds | DeduplicationScope | FifoThroughputLimit |
+	// RedriveAllowPolicy | SqsManagedSseEnabled
+	// +optional
+	AttributeNames []string `json:"attributeNames,omitempty" protobuf:"bytes,8,rep,name=attributeNames"`
+
+	// MessageAttributeNames is a list of message attributes that need to be returned along with each message.
+	// +optional
+	MessageAttributeNames []string `json:"messageAttributeNames,omitempty" protobuf:"bytes,9,rep,name=messageAttributeNames"`
+}
diff --git a/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go
index f1c24409..3fed1514 100644
--- a/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go
@@ -2545,6 +2545,7 @@ func (in *ServingSpec) DeepCopyInto(out *ServingSpec) {
 		*out = new(int32)
 		**out = **in
 	}
+	in.AbstractPodTemplate.DeepCopyInto(&out.AbstractPodTemplate)
 	return
 }
 
@@ -2778,6 +2779,11 @@ func (in *Source) DeepCopyInto(out *Source) {
 		*out = new(PulsarSource)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.Sqs != nil {
+		in, out := &in.Sqs, &out.Sqs
+		*out = new(SqsSource)
+		(*in).DeepCopyInto(*out)
+	}
 	return
 }
 
@@ -2791,6 +2797,52 @@ func (in *Source) DeepCopy() *Source {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SqsSource) DeepCopyInto(out *SqsSource) {
+	*out = *in
+	if in.VisibilityTimeout != nil {
+		in, out := &in.VisibilityTimeout, &out.VisibilityTimeout
+		*out = new(int32)
+		**out = **in
+	}
+	if in.MaxNumberOfMessages != nil {
+		in, out := &in.MaxNumberOfMessages, &out.MaxNumberOfMessages
+		*out = new(int32)
+		**out = **in
+	}
+	if in.WaitTimeSeconds != nil {
+		in, out := &in.WaitTimeSeconds, &out.WaitTimeSeconds
+		*out = new(int32)
+		**out = **in
+	}
+	if in.EndpointURL != nil {
+		in, out := &in.EndpointURL, &out.EndpointURL
+		*out = new(string)
+		**out = **in
+	}
+	if in.AttributeNames != nil {
+		in, out := &in.AttributeNames, &out.AttributeNames
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.MessageAttributeNames != nil {
+		in, out := &in.MessageAttributeNames, &out.MessageAttributeNames
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SqsSource.
+func (in *SqsSource) DeepCopy() *SqsSource {
+	if in == nil {
+		return nil
+	}
+	out := new(SqsSource)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Status) DeepCopyInto(out *Status) {
 	*out = *in
diff --git a/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go b/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go
index 0ffce205..b97c9229 100644
--- a/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go
+++ b/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go
@@ -117,6 +117,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
 		"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Sink":                             schema_pkg_apis_numaflow_v1alpha1_Sink(ref),
 		"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SlidingWindow":                    schema_pkg_apis_numaflow_v1alpha1_SlidingWindow(ref),
 		"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Source":                           schema_pkg_apis_numaflow_v1alpha1_Source(ref),
+		"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SqsSource":                        schema_pkg_apis_numaflow_v1alpha1_SqsSource(ref),
 		"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Status":                           schema_pkg_apis_numaflow_v1alpha1_Status(ref),
 		"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.TLS":                              schema_pkg_apis_numaflow_v1alpha1_TLS(ref),
 		"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.TagConditions":                    schema_pkg_apis_numaflow_v1alpha1_TagConditions(ref),
@@ -5118,12 +5119,148 @@ func schema_pkg_apis_numaflow_v1alpha1_ServingSpec(ref common.ReferenceCallback)
 							Format:      "int32",
 						},
 					},
+					"metadata": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Metadata sets the pods's metadata, i.e. annotations and labels",
+							Ref:         ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Metadata"),
+						},
+					},
+					"nodeSelector": {
+						SchemaProps: spec.SchemaProps{
+							Description: "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/",
+							Type:        []string{"object"},
+							AdditionalProperties: &spec.SchemaOrBool{
+								Allows: true,
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: "",
+										Type:    []string{"string"},
+										Format:  "",
+									},
+								},
+							},
+						},
+					},
+					"tolerations": {
+						SchemaProps: spec.SchemaProps{
+							Description: "If specified, the pod's tolerations.",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: map[string]interface{}{},
+										Ref:     ref("k8s.io/api/core/v1.Toleration"),
+									},
+								},
+							},
+						},
+					},
+					"securityContext": {
+						SchemaProps: spec.SchemaProps{
+							Description: "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty.  See type description for default values of each field.",
+							Ref:         ref("k8s.io/api/core/v1.PodSecurityContext"),
+						},
+					},
+					"imagePullSecrets": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-patch-merge-key": "name",
+								"x-kubernetes-patch-strategy":  "merge",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: map[string]interface{}{},
+										Ref:     ref("k8s.io/api/core/v1.LocalObjectReference"),
+									},
+								},
+							},
+						},
+					},
+					"priorityClassName": {
+						SchemaProps: spec.SchemaProps{
+							Description: "If specified, indicates the Redis pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"priority": {
+						SchemaProps: spec.SchemaProps{
+							Description: "The priority value. Various system components use this field to find the priority of the Redis pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/",
+							Type:        []string{"integer"},
+							Format:      "int32",
+						},
+					},
+					"affinity": {
+						SchemaProps: spec.SchemaProps{
+							Description: "The pod's scheduling constraints More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/",
+							Ref:         ref("k8s.io/api/core/v1.Affinity"),
+						},
+					},
+					"serviceAccountName": {
+						SchemaProps: spec.SchemaProps{
+							Description: "ServiceAccountName applied to the pod",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"runtimeClassName": {
+						SchemaProps: spec.SchemaProps{
+							Description: "RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod.  If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"automountServiceAccountToken": {
+						SchemaProps: spec.SchemaProps{
+							Description: "AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.",
+							Type:        []string{"boolean"},
+							Format:      "",
+						},
+					},
+					"dnsPolicy": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"dnsConfig": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.",
+							Ref:         ref("k8s.io/api/core/v1.PodDNSConfig"),
+						},
+					},
+					"resourceClaims": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-patch-merge-key": "name",
+								"x-kubernetes-patch-strategy":  "merge,retainKeys",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name.",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: map[string]interface{}{},
+										Ref:     ref("k8s.io/api/core/v1.PodResourceClaim"),
+									},
+								},
+							},
+						},
+					},
 				},
 				Required: []string{"msgIDHeaderKey"},
 			},
 		},
 		Dependencies: []string{
-			"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Authorization", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ServingStore"},
+			"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Authorization", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Metadata", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ServingStore", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.LocalObjectReference", "k8s.io/api/core/v1.PodDNSConfig", "k8s.io/api/core/v1.PodResourceClaim", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration"},
 	}
 }
 
@@ -5552,11 +5689,112 @@ func schema_pkg_apis_numaflow_v1alpha1_Source(ref common.ReferenceCallback) comm
 							Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.PulsarSource"),
 						},
 					},
+					"sqs": {
+						SchemaProps: spec.SchemaProps{
+							Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SqsSource"),
+						},
+					},
 				},
 			},
 		},
 		Dependencies: []string{
-			"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GeneratorSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.HTTPSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.JetStreamSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.KafkaSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.NatsSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.PulsarSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ServingSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.UDSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.UDTransformer"},
+			"github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GeneratorSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.HTTPSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.JetStreamSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.KafkaSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.NatsSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.PulsarSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ServingSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SqsSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.UDSource", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.UDTransformer"},
+	}
+}
+
+func schema_pkg_apis_numaflow_v1alpha1_SqsSource(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "SqsSource represents the configuration of an AWS SQS source",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"awsRegion": {
+						SchemaProps: spec.SchemaProps{
+							Description: "AWSRegion is the AWS Region where the SQS queue is located",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"queueName": {
+						SchemaProps: spec.SchemaProps{
+							Description: "QueueName is the name of the SQS queue",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"queueOwnerAWSAccountID": {
+						SchemaProps: spec.SchemaProps{
+							Description: "QueueOwnerAWSAccountID is the queue owner aws account id",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"visibilityTimeout": {
+						SchemaProps: spec.SchemaProps{
+							Description: "VisibilityTimeout is the duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. Valid values: 0-43200 (12 hours)",
+							Type:        []string{"integer"},
+							Format:      "int32",
+						},
+					},
+					"maxNumberOfMessages": {
+						SchemaProps: spec.SchemaProps{
+							Description: "MaxNumberOfMessages is the maximum number of messages to return in a single poll. Valid values: 1-10 Defaults to 1",
+							Type:        []string{"integer"},
+							Format:      "int32",
+						},
+					},
+					"waitTimeSeconds": {
+						SchemaProps: spec.SchemaProps{
+							Description: "WaitTimeSeconds is the duration (in seconds) for which the call waits for a message to arrive in the queue before returning. If a message is available, the call returns sooner than WaitTimeSeconds. Valid values: 0-20 Defaults to 0 (short polling)",
+							Type:        []string{"integer"},
+							Format:      "int32",
+						},
+					},
+					"endpointUrl": {
+						SchemaProps: spec.SchemaProps{
+							Description: "EndpointURL is the custom endpoint URL for the AWS SQS API. This is useful for testing with localstack or when using VPC endpoints.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"attributeNames": {
+						SchemaProps: spec.SchemaProps{
+							Description: "AttributeNames is a list of attributes that need to be returned along with each message. Valid values: All | Policy | VisibilityTimeout | MaximumMessageSize | MessageRetentionPeriod | ApproximateNumberOfMessages | ApproximateNumberOfMessagesNotVisible | CreatedTimestamp | LastModifiedTimestamp | QueueArn | ApproximateNumberOfMessagesDelayed | DelaySeconds | ReceiveMessageWaitTimeSeconds | RedrivePolicy | FifoQueue | ContentBasedDeduplication | KmsMasterKeyId | KmsDataKeyReusePeriodSeconds | DeduplicationScope | FifoThroughputLimit | RedriveAllowPolicy | SqsManagedSseEnabled",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: "",
+										Type:    []string{"string"},
+										Format:  "",
+									},
+								},
+							},
+						},
+					},
+					"messageAttributeNames": {
+						SchemaProps: spec.SchemaProps{
+							Description: "MessageAttributeNames is a list of message attributes that need to be returned along with each message.",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: "",
+										Type:    []string{"string"},
+										Format:  "",
+									},
+								},
+							},
+						},
+					},
+				},
+				Required: []string{"awsRegion", "queueName", "queueOwnerAWSAccountID"},
+			},
+		},
 	}
 }
 
diff --git a/pkg/apis/proto/isb/message.pb.go b/pkg/apis/proto/isb/message.pb.go
index 6ceedeac..babf036a 100644
--- a/pkg/apis/proto/isb/message.pb.go
+++ b/pkg/apis/proto/isb/message.pb.go
@@ -436,7 +436,7 @@ type ReadMessage struct {
 	// Message is the actual message read from the buffer
 	Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
 	// ReadOffset is the offset at which the message was read
-	ReadOffset string `protobuf:"bytes,2,opt,name=read_offset,json=readOffset,proto3" json:"read_offset,omitempty"`
+	ReadOffset int64 `protobuf:"varint,2,opt,name=read_offset,json=readOffset,proto3" json:"read_offset,omitempty"`
 	// Watermark is the watermark timestamp
 	Watermark *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=watermark,proto3" json:"watermark,omitempty"`
 	// Metadata is the metadata of the message after a message is read from the buffer.
@@ -482,11 +482,11 @@ func (x *ReadMessage) GetMessage() *Message {
 	return nil
 }
 
-func (x *ReadMessage) GetReadOffset() string {
+func (x *ReadMessage) GetReadOffset() int64 {
 	if x != nil {
 		return x.ReadOffset
 	}
-	return ""
+	return 0
 }
 
 func (x *ReadMessage) GetWatermark() *timestamppb.Timestamp {
@@ -609,7 +609,7 @@ var file_pkg_apis_proto_isb_message_proto_rawDesc = string([]byte{
 	0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x69, 0x73,
 	0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
 	0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65,
-	0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x66, 0x66,
+	0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x66, 0x66,
 	0x73, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b,
 	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
diff --git a/pkg/apis/proto/isb/message.proto b/pkg/apis/proto/isb/message.proto
index 9ec2ba03..c1045415 100644
--- a/pkg/apis/proto/isb/message.proto
+++ b/pkg/apis/proto/isb/message.proto
@@ -82,7 +82,7 @@ message ReadMessage {
   // Message is the actual message read from the buffer
   Message message = 1;
   // ReadOffset is the offset at which the message was read
-  string read_offset = 2;
+  int64 read_offset = 2;
   // Watermark is the watermark timestamp
   google.protobuf.Timestamp watermark = 3;
   // Metadata is the metadata of the message after a message is read from the buffer.
diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go
index 87727ae2..ef0b55e4 100644
--- a/pkg/metrics/metrics.go
+++ b/pkg/metrics/metrics.go
@@ -237,14 +237,6 @@ var (
 		Buckets:   prometheus.ExponentialBucketsRange(100, 60000000*15, 10),
 	}, []string{LabelVertex, LabelPipeline, LabelVertexType, LabelVertexReplicaIndex, LabelPartitionName})
 
-	// SourceTransformerConcurrentProcessingTime is a histogram to Observe Source Transformer Processing times as a whole
-	SourceTransformerConcurrentProcessingTime = promauto.NewHistogramVec(prometheus.HistogramOpts{
-		Subsystem: "source_forwarder",
-		Name:      "concurrent_transformer_processing_time",
-		Help:      "Processing times of Concurrent source transformer (100 microseconds to 20 minutes)",
-		Buckets:   prometheus.ExponentialBucketsRange(100, 60000000*20, 10),
-	}, []string{LabelVertex, LabelPipeline, LabelVertexType, LabelVertexReplicaIndex, LabelPartitionName})
-
 	// SourceTransformerReadMessagesCount is used to indicate the number of messages read by source transformer
 	SourceTransformerReadMessagesCount = promauto.NewCounterVec(prometheus.CounterOpts{
 		Subsystem: "source_forwarder",
diff --git a/pkg/sources/forward/data_forward.go b/pkg/sources/forward/data_forward.go
index 7da61953..6fd37b30 100644
--- a/pkg/sources/forward/data_forward.go
+++ b/pkg/sources/forward/data_forward.go
@@ -305,12 +305,19 @@ func (df *DataForward) forwardAChunk(ctx context.Context) error {
 			m.Watermark = time.Time(processorWM)
 		}
 
+		metrics.SourceTransformerReadMessagesCount.With(metricLabelsWithPartition).Add(float64(len(readMessages)))
 		transformerProcessingStart := time.Now()
 		readWriteMessagePairs, err = df.applyTransformer(ctx, readMessages)
 		if err != nil {
+			metrics.SourceTransformerError.With(metricLabelsWithPartition).Inc()
 			df.opts.logger.Errorw("failed to apply source transformer", zap.Error(err))
 			return err
 		}
+		transformerWriteCount := 0
+		for _, m := range readWriteMessagePairs {
+			transformerWriteCount += len(m.WriteMessages)
+		}
+		metrics.SourceTransformerWriteMessagesCount.With(metricLabelsWithPartition).Add(float64(transformerWriteCount))
 
 		df.opts.logger.Debugw("concurrent applyTransformer completed",
 			zap.Int("concurrency", df.opts.transformerConcurrency),
@@ -377,13 +384,11 @@ func (df *DataForward) forwardAChunk(ctx context.Context) error {
 	}
 
 	// forward the messages to the edge buffer (could be multiple edges)
-	writeStart := time.Now()
 	writeOffsets, err = df.writeToBuffers(ctx, messageToStep)
 	if err != nil {
 		df.opts.logger.Errorw("failed to write to toBuffers", zap.Error(err))
 		return err
 	}
-	metrics.WriteProcessingTime.With(metricLabelsWithPartition).Observe(float64(time.Since(writeStart).Microseconds()))
 
 	// activeWatermarkBuffers records the buffers that the publisher has published
 	// a watermark in this batch processing cycle.
@@ -529,6 +534,7 @@ func (df *DataForward) writeToBuffer(ctx context.Context, toBufferPartition isb.
 	}
 	totalCount = len(messages)
 	writeOffsets = make([]isb.Offset, 0, totalCount)
+	writeStart := time.Now()
 
 	for {
 		_writeOffsets, errs := toBufferPartition.Write(ctx, messages)
@@ -597,6 +603,7 @@ func (df *DataForward) writeToBuffer(ctx context.Context, toBufferPartition isb.
 		}
 	}
 
+	metrics.WriteProcessingTime.With(metricLabelsWithPartition).Observe(float64(time.Since(writeStart).Microseconds()))
 	metrics.WriteMessagesCount.With(metricLabelsWithPartition).Add(float64(writeCount))
 	metrics.WriteBytesCount.With(metricLabelsWithPartition).Add(writeBytes)
 	return writeOffsets, nil
diff --git a/pkg/watermark/timeline/offset_timeline.go b/pkg/watermark/timeline/offset_timeline.go
index 7878cbad..3f5e6f51 100644
--- a/pkg/watermark/timeline/offset_timeline.go
+++ b/pkg/watermark/timeline/offset_timeline.go
@@ -138,7 +138,13 @@ func (t *OffsetTimeline) PutIdle(node wmb.WMB) {
 				// If we have an active watermark between two idle watermarks, but this active watermark is skipped
 				// publishing due to "skip publishing same watermark", we will see this warning.
 				// In this case, it's safe to insert the idle watermark.
-				t.log.Warnw("The idle watermark has a larger offset from the head idle watermark", zap.Int64("idleWatermark", node.Watermark),
+				// Example:
+				// * An idle watermark is sent at offset X.
+				// * A message comes in, so idling is cleared, but no new watermark is sent because the watermark hasn't
+				//   advanced.
+				// * Later, if it goes idle again, a new idle watermark is sent with a higher offset because the watermark
+				//   has advanced.
+				t.log.Debugw("The idle watermark has a larger offset from the head idle watermark", zap.Int64("idleWatermark", node.Watermark),
 					zap.Int64("existingOffset", elementNode.Offset), zap.Int64("inputOffset", node.Offset))
 				t.watermarks.InsertBefore(node, e)
 				t.watermarks.Remove(t.watermarks.Back())
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index 02bdfc37..65f96792 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -41,6 +41,56 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "anstream"
+version = "0.6.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+dependencies = [
+ "anstyle",
+ "once_cell",
+ "windows-sys 0.59.0",
+]
+
 [[package]]
 name = "anyhow"
 version = "1.0.97"
@@ -53,17 +103,6 @@ version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
 
-[[package]]
-name = "assert-json-diff"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4259cbe96513d2f1073027a259fc2ca917feb3026a5a8d984e3628e490255cc0"
-dependencies = [
- "extend",
- "serde",
- "serde_json",
-]
-
 [[package]]
 name = "async-channel"
 version = "2.3.1"
@@ -137,9 +176,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
 name = "aws-config"
-version = "1.6.1"
+version = "1.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c39646d1a6b51240a1a23bb57ea4eebede7e16fbc237fdc876980233dcecb4f"
+checksum = "b6fcc63c9860579e4cb396239570e979376e70aab79e496621748a09913f8b36"
 dependencies = [
  "aws-credential-types",
  "aws-runtime",
@@ -167,9 +206,9 @@ dependencies = [
 
 [[package]]
 name = "aws-credential-types"
-version = "1.2.2"
+version = "1.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4471bef4c22a06d2c7a1b6492493d3fdf24a805323109d6874f9c94d5906ac14"
+checksum = "687bc16bc431a8533fe0097c7f0182874767f920989d7260950172ae8e3c4465"
 dependencies = [
  "aws-smithy-async",
  "aws-smithy-runtime-api",
@@ -202,9 +241,9 @@ dependencies = [
 
 [[package]]
 name = "aws-runtime"
-version = "1.5.6"
+version = "1.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0aff45ffe35196e593ea3b9dd65b320e51e2dda95aff4390bc459e461d09c6ad"
+checksum = "6c4063282c69991e57faab9e5cb21ae557e59f5b0fb285c196335243df8dc25c"
 dependencies = [
  "aws-credential-types",
  "aws-sigv4",
@@ -218,7 +257,6 @@ dependencies = [
  "fastrand",
  "http 0.2.12",
  "http-body 0.4.6",
- "once_cell",
  "percent-encoding",
  "pin-project-lite",
  "tracing",
@@ -227,9 +265,9 @@ dependencies = [
 
 [[package]]
 name = "aws-sdk-sqs"
-version = "1.64.0"
+version = "1.65.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "514d007ac4d5b156b408d8dd623a57b37ae77425810e0fedcffab57b0dabaded"
+checksum = "f6c5fb5d108c518c3bfc077d39a3cd5120e0115ac60aba8085dc79e2d08ab6b1"
 dependencies = [
  "aws-credential-types",
  "aws-runtime",
@@ -250,9 +288,9 @@ dependencies = [
 
 [[package]]
 name = "aws-sdk-sso"
-version = "1.64.0"
+version = "1.65.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02d4bdb0e5f80f0689e61c77ab678b2b9304af329616af38aef5b6b967b8e736"
+checksum = "8efec445fb78df585327094fcef4cad895b154b58711e504db7a93c41aa27151"
 dependencies = [
  "aws-credential-types",
  "aws-runtime",
@@ -273,9 +311,9 @@ dependencies = [
 
 [[package]]
 name = "aws-sdk-ssooidc"
-version = "1.65.0"
+version = "1.66.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbbb3ce8da257aedbccdcb1aadafbbb6a5fe9adf445db0e1ea897bdc7e22d08"
+checksum = "5e49cca619c10e7b002dc8e66928ceed66ab7f56c1a3be86c5437bf2d8d89bba"
 dependencies = [
  "aws-credential-types",
  "aws-runtime",
@@ -296,9 +334,9 @@ dependencies = [
 
 [[package]]
 name = "aws-sdk-sts"
-version = "1.65.0"
+version = "1.66.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96a78a8f50a1630db757b60f679c8226a8a70ee2ab5f5e6e51dc67f6c61c7cfd"
+checksum = "7420479eac0a53f776cc8f0d493841ffe58ad9d9783f3947be7265784471b47a"
 dependencies = [
  "aws-credential-types",
  "aws-runtime",
@@ -320,9 +358,9 @@ dependencies = [
 
 [[package]]
 name = "aws-sigv4"
-version = "1.3.0"
+version = "1.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69d03c3c05ff80d54ff860fe38c726f6f494c639ae975203a101335f223386db"
+checksum = "3503af839bd8751d0bdc5a46b9cac93a003a353e635b0c12cf2376b5b53e41ea"
 dependencies = [
  "aws-credential-types",
  "aws-smithy-http",
@@ -334,7 +372,6 @@ dependencies = [
  "hmac",
  "http 0.2.12",
  "http 1.3.1",
- "once_cell",
  "percent-encoding",
  "sha2",
  "time",
@@ -354,9 +391,9 @@ dependencies = [
 
 [[package]]
 name = "aws-smithy-http"
-version = "0.62.0"
+version = "0.62.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5949124d11e538ca21142d1fba61ab0a2a2c1bc3ed323cdb3e4b878bfb83166"
+checksum = "99335bec6cdc50a346fda1437f9fefe33abf8c99060739a546a16457f2862ca9"
 dependencies = [
  "aws-smithy-runtime-api",
  "aws-smithy-types",
@@ -366,7 +403,6 @@ dependencies = [
  "http 0.2.12",
  "http 1.3.1",
  "http-body 0.4.6",
- "once_cell",
  "percent-encoding",
  "pin-project-lite",
  "pin-utils",
@@ -380,28 +416,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8aff1159006441d02e57204bf57a1b890ba68bedb6904ffd2873c1c4c11c546b"
 dependencies = [
  "aws-smithy-async",
- "aws-smithy-protocol-test",
  "aws-smithy-runtime-api",
  "aws-smithy-types",
- "bytes",
  "h2 0.4.8",
  "http 0.2.12",
  "http 1.3.1",
  "http-body 0.4.6",
- "http-body 1.0.1",
  "hyper 0.14.32",
  "hyper 1.6.0",
  "hyper-rustls 0.24.2",
  "hyper-rustls 0.27.5",
  "hyper-util",
- "indexmap",
  "pin-project-lite",
  "rustls 0.21.12",
  "rustls 0.23.25",
  "rustls-native-certs 0.8.1",
  "rustls-pki-types",
- "serde",
- "serde_json",
  "tokio",
  "tower",
  "tracing",
@@ -428,31 +458,11 @@ dependencies = [
 
 [[package]]
 name = "aws-smithy-observability"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "445d065e76bc1ef54963db400319f1dd3ebb3e0a74af20f7f7630625b0cc7cc0"
-dependencies = [
- "aws-smithy-runtime-api",
- "once_cell",
-]
-
-[[package]]
-name = "aws-smithy-protocol-test"
-version = "0.63.1"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b42f13304bed0b96d7471e4770c270bb3eb4fea277727fb03c811e84cb4bf3a"
+checksum = "9364d5989ac4dd918e5cc4c4bdcc61c9be17dcd2586ea7f69e348fc7c6cab393"
 dependencies = [
- "assert-json-diff",
  "aws-smithy-runtime-api",
- "base64-simd",
- "cbor-diag",
- "ciborium",
- "http 0.2.12",
- "pretty_assertions",
- "regex-lite",
- "roxmltree",
- "serde_json",
- "thiserror 1.0.69",
 ]
 
 [[package]]
@@ -467,9 +477,9 @@ dependencies = [
 
 [[package]]
 name = "aws-smithy-runtime"
-version = "1.8.1"
+version = "1.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0152749e17ce4d1b47c7747bdfec09dac1ccafdcbc741ebf9daa2a373356730f"
+checksum = "14302f06d1d5b7d333fd819943075b13d27c7700b414f574c3c35859bfb55d5e"
 dependencies = [
  "aws-smithy-async",
  "aws-smithy-http",
@@ -483,19 +493,17 @@ dependencies = [
  "http 1.3.1",
  "http-body 0.4.6",
  "http-body 1.0.1",
- "once_cell",
  "pin-project-lite",
  "pin-utils",
  "tokio",
  "tracing",
- "tracing-subscriber",
 ]
 
 [[package]]
 name = "aws-smithy-runtime-api"
-version = "1.7.4"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3da37cf5d57011cb1753456518ec76e31691f1f474b73934a284eb2a1c76510f"
+checksum = "a1e5d9e3a80a18afa109391fb5ad09c3daf887b516c6fd805a157c6ea7994a57"
 dependencies = [
  "aws-smithy-async",
  "aws-smithy-types",
@@ -510,9 +518,9 @@ dependencies = [
 
 [[package]]
 name = "aws-smithy-types"
-version = "1.3.0"
+version = "1.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "836155caafba616c0ff9b07944324785de2ab016141c3550bd1c07882f8cee8f"
+checksum = "40076bd09fadbc12d5e026ae080d0930defa606856186e31d83ccc6a255eeaf3"
 dependencies = [
  "base64-simd",
  "bytes",
@@ -545,9 +553,9 @@ dependencies = [
 
 [[package]]
 name = "aws-types"
-version = "1.3.6"
+version = "1.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3873f8deed8927ce8d04487630dc9ff73193bab64742a61d050e57a68dec4125"
+checksum = "8a322fec39e4df22777ed3ad8ea868ac2f94cd15e1a55f6ee8d8d6305057689a"
 dependencies = [
  "aws-credential-types",
  "aws-smithy-async",
@@ -739,15 +747,6 @@ dependencies = [
  "generic-array",
 ]
 
-[[package]]
-name = "bs58"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
-dependencies = [
- "tinyvec",
-]
-
 [[package]]
 name = "bumpalo"
 version = "3.17.0"
@@ -773,25 +772,6 @@ dependencies = [
  "either",
 ]
 
-[[package]]
-name = "cbor-diag"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc245b6ecd09b23901a4fbad1ad975701fd5061ceaef6afa93a2d70605a64429"
-dependencies = [
- "bs58",
- "chrono",
- "data-encoding",
- "half",
- "nom",
- "num-bigint",
- "num-rational",
- "num-traits",
- "separator",
- "url",
- "uuid",
-]
-
 [[package]]
 name = "cc"
 version = "1.2.17"
@@ -826,9 +806,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
 
 [[package]]
 name = "chrono"
-version = "0.4.40"
+version = "0.4.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
+checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
@@ -839,33 +819,6 @@ dependencies = [
  "windows-link",
 ]
 
-[[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 = "clang-sys"
 version = "1.8.1"
@@ -886,6 +839,12 @@ dependencies = [
  "cc",
 ]
 
+[[package]]
+name = "colorchoice"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+
 [[package]]
 name = "concurrent-queue"
 version = "2.5.0"
@@ -957,12 +916,6 @@ version = "0.8.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
 
-[[package]]
-name = "crunchy"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
-
 [[package]]
 name = "crypto-common"
 version = "0.1.6"
@@ -1026,12 +979,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "diff"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
-
 [[package]]
 name = "digest"
 version = "0.10.7"
@@ -1103,6 +1050,27 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "env_filter"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
+dependencies = [
+ "log",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.11.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "env_filter",
+ "log",
+]
+
 [[package]]
 name = "equivalent"
 version = "1.0.2"
@@ -1140,18 +1108,6 @@ dependencies = [
  "pin-project-lite",
 ]
 
-[[package]]
-name = "extend"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f47da3a72ec598d9c8937a7ebca8962a5c7a1f28444e38c2b33c771ba3f55f05"
-dependencies = [
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
 [[package]]
 name = "fastrand"
 version = "2.3.0"
@@ -1377,16 +1333,6 @@ dependencies = [
  "tracing",
 ]
 
-[[package]]
-name = "half"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1"
-dependencies = [
- "cfg-if",
- "crunchy",
-]
-
 [[package]]
 name = "hashbrown"
 version = "0.15.2"
@@ -1819,7 +1765,6 @@ checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
 dependencies = [
  "equivalent",
  "hashbrown",
- "serde",
 ]
 
 [[package]]
@@ -1828,6 +1773,12 @@ version = "2.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
 
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
 [[package]]
 name = "itertools"
 version = "0.10.5"
@@ -2145,16 +2096,6 @@ dependencies = [
  "rand 0.8.5",
 ]
 
-[[package]]
-name = "num-bigint"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
-dependencies = [
- "num-integer",
- "num-traits",
-]
-
 [[package]]
 name = "num-conv"
 version = "0.1.0"
@@ -2170,17 +2111,6 @@ dependencies = [
  "num-traits",
 ]
 
-[[package]]
-name = "num-rational"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
-dependencies = [
- "num-bigint",
- "num-integer",
- "num-traits",
-]
-
 [[package]]
 name = "num-traits"
 version = "0.2.19"
@@ -2231,11 +2161,8 @@ name = "numaflow-core"
 version = "0.1.0"
 dependencies = [
  "async-nats",
- "aws-config",
  "aws-sdk-sqs",
  "aws-smithy-mocks-experimental",
- "aws-smithy-runtime",
- "aws-smithy-types",
  "axum",
  "axum-server",
  "backoff",
@@ -2244,7 +2171,6 @@ dependencies = [
  "chrono",
  "futures",
  "http 1.3.1",
- "hyper 1.6.0",
  "hyper-util",
  "k8s-openapi",
  "kube",
@@ -2264,7 +2190,6 @@ dependencies = [
  "pulsar",
  "rand 0.8.5",
  "rcgen",
- "reqwest 0.12.15",
  "rustls 0.23.25",
  "semver",
  "serde",
@@ -2365,15 +2290,12 @@ dependencies = [
  "aws-config",
  "aws-sdk-sqs",
  "aws-smithy-mocks-experimental",
- "aws-smithy-runtime",
  "aws-smithy-types",
  "bytes",
  "chrono",
- "prost 0.11.9",
- "serde",
- "thiserror 1.0.69",
+ "test-log",
+ "thiserror 2.0.12",
  "tokio",
- "tonic",
  "tracing",
 ]
 
@@ -2602,16 +2524,6 @@ dependencies = [
  "zerocopy",
 ]
 
-[[package]]
-name = "pretty_assertions"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
-dependencies = [
- "diff",
- "yansi",
-]
-
 [[package]]
 name = "prettyplease"
 version = "0.2.31"
@@ -2622,30 +2534,6 @@ dependencies = [
  "syn 2.0.100",
 ]
 
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
-]
-
 [[package]]
 name = "proc-macro2"
 version = "1.0.94"
@@ -3097,15 +2985,6 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
-[[package]]
-name = "roxmltree"
-version = "0.14.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b"
-dependencies = [
- "xmlparser",
-]
-
 [[package]]
 name = "rustc-demangle"
 version = "0.1.24"
@@ -3371,12 +3250,6 @@ version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
 
-[[package]]
-name = "separator"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5"
-
 [[package]]
 name = "serde"
 version = "1.0.219"
@@ -3413,7 +3286,6 @@ version = "1.0.140"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
 dependencies = [
- "indexmap",
  "itoa",
  "memchr",
  "ryu",
@@ -3709,6 +3581,28 @@ dependencies = [
  "windows-sys 0.59.0",
 ]
 
+[[package]]
+name = "test-log"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7f46083d221181166e5b6f6b1e5f1d499f3a76888826e6cb1d057554157cd0f"
+dependencies = [
+ "env_logger",
+ "test-log-macros",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "test-log-macros"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "888d0c3c6db53c0fdab160d2ed5e12ba745383d3e85813f2ea0f2b1475ab553f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.100",
+]
+
 [[package]]
 name = "thiserror"
 version = "1.0.69"
@@ -4045,16 +3939,6 @@ dependencies = [
  "tracing-core",
 ]
 
-[[package]]
-name = "tracing-serde"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1"
-dependencies = [
- "serde",
- "tracing-core",
-]
-
 [[package]]
 name = "tracing-subscriber"
 version = "0.3.19"
@@ -4065,15 +3949,12 @@ dependencies = [
  "nu-ansi-term",
  "once_cell",
  "regex",
- "serde",
- "serde_json",
  "sharded-slab",
  "smallvec",
  "thread_local",
  "tracing",
  "tracing-core",
  "tracing-log",
- "tracing-serde",
 ]
 
 [[package]]
@@ -4181,6 +4062,12 @@ version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
 
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
 [[package]]
 name = "uuid"
 version = "1.16.0"
@@ -4680,12 +4567,6 @@ version = "0.13.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
 
-[[package]]
-name = "yansi"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
-
 [[package]]
 name = "yasna"
 version = "0.5.2"
diff --git a/rust/extns/numaflow-sqs/Cargo.toml b/rust/extns/numaflow-sqs/Cargo.toml
index 387b825a..437c7092 100644
--- a/rust/extns/numaflow-sqs/Cargo.toml
+++ b/rust/extns/numaflow-sqs/Cargo.toml
@@ -10,16 +10,13 @@ workspace = true
 tokio.workspace = true
 tracing.workspace = true
 bytes.workspace = true
-serde.workspace = true
-aws-config = "1.5.11"
-aws-sdk-sqs = "1.51.0"
-aws-smithy-runtime = { version = "1.7.6", features = ["test-util"] }
-aws-smithy-types = "1.2.11"
-chrono = "0.4.38"
-tonic = "0.13.0"
-prost = "0.11.9"
-thiserror = "1.0.69"
+aws-config = "1.6.2"
+aws-sdk-sqs = "1.65.0"
+aws-smithy-types = "1.3.1"
+chrono = "0.4.41"
+thiserror = "2.0.12"
 
 
 [dev-dependencies]
-aws-smithy-mocks-experimental = "0.2.1"
\ No newline at end of file
+aws-smithy-mocks-experimental = "0.2.3"
+test-log = "0.2.17"
\ No newline at end of file
diff --git a/rust/extns/numaflow-sqs/src/lib.rs b/rust/extns/numaflow-sqs/src/lib.rs
index 96ab2c05..4b0ce526 100644
--- a/rust/extns/numaflow-sqs/src/lib.rs
+++ b/rust/extns/numaflow-sqs/src/lib.rs
@@ -22,6 +22,9 @@ pub enum Error {
     #[error("Failed to receive message from channel. Actor task is terminated: {0:?}")]
     ActorTaskTerminated(oneshot::error::RecvError),
 
+    #[error("Invalid configuration: {0}")]
+    InvalidConfig(String),
+
     #[error("{0}")]
     Other(String),
 }
@@ -56,7 +59,7 @@ mod tests {
 
         let sqs = aws_sdk_sqs::Client::from_conf(
             aws_sdk_sqs::Config::builder()
-                .behavior_version(BehaviorVersion::latest())
+                .behavior_version(BehaviorVersion::v2025_01_17())
                 .region(aws_sdk_sqs::config::Region::new("us-east-1"))
                 .credentials_provider(make_sqs_test_credentials())
                 .interceptor(get_object_mocks)
diff --git a/rust/extns/numaflow-sqs/src/source.rs b/rust/extns/numaflow-sqs/src/source.rs
index 2b1b861f..8feeeddb 100644
--- a/rust/extns/numaflow-sqs/src/source.rs
+++ b/rust/extns/numaflow-sqs/src/source.rs
@@ -5,33 +5,127 @@
 //! - Batched message handling for efficiency
 //! - Robust error handling and retry logic
 //! - Configurable timeouts and batch sizes
+
 use std::collections::HashMap;
+use std::str::FromStr;
 use std::time::Duration;
 
-use aws_config::{BehaviorVersion, meta::region::RegionProviderChain};
+use crate::Error::ActorTaskTerminated;
+use crate::{Error, Result};
+use aws_config::meta::region::RegionProviderChain;
+use aws_config::{BehaviorVersion, Region};
 use aws_sdk_sqs::Client;
-use aws_sdk_sqs::config::Region;
 use aws_sdk_sqs::types::{MessageSystemAttributeName, QueueAttributeName};
-use aws_smithy_types::timeout::TimeoutConfig;
 use bytes::Bytes;
 use chrono::{DateTime, TimeZone, Utc};
 use tokio::sync::{mpsc, oneshot};
 use tokio::time::Instant;
 
-use crate::Error::ActorTaskTerminated;
-use crate::{Error, Result};
-
 pub const SQS_DEFAULT_REGION: &str = "us-west-2";
 
 /// Configuration for an SQS message source.
 ///
 /// Used to initialize the SQS client with region and queue settings.
-/// Implements serde::Deserialize to support loading from configuration files.
-/// TODO: add support for all sqs configs and different ways to authenticate
-#[derive(serde::Deserialize, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq)]
 pub struct SQSSourceConfig {
+    // Required fields
     pub region: String,
     pub queue_name: String,
+    pub queue_owner_aws_account_id: String,
+
+    // Optional fields
+    pub visibility_timeout: Option<i32>,
+    pub max_number_of_messages: Option<i32>,
+    pub wait_time_seconds: Option<i32>,
+    pub endpoint_url: Option<String>,
+    pub attribute_names: Vec<String>,
+    pub message_attribute_names: Vec<String>,
+}
+
+impl SQSSourceConfig {
+    /// Validates the SQS source configuration
+    #[allow(clippy::result_large_err)]
+    pub fn validate(&self) -> Result<()> {
+        // Validate required fields
+        if self.region.is_empty() {
+            return Err(Error::InvalidConfig("region is required".to_string()));
+        }
+
+        if self.queue_name.is_empty() {
+            return Err(Error::InvalidConfig("queue name is required".to_string()));
+        }
+
+        // Validate optional fields if present
+        if let Some(timeout) = self.visibility_timeout {
+            if !(0..=43200).contains(&timeout) {
+                return Err(Error::InvalidConfig(format!(
+                    "visibility_timeout must be between 0 and 43200, got {}",
+                    timeout
+                )));
+            }
+        }
+
+        if let Some(max_msgs) = self.max_number_of_messages {
+            if !(1..=10).contains(&max_msgs) {
+                return Err(Error::InvalidConfig(format!(
+                    "max_number_of_messages must be between 1 and 10, got {}",
+                    max_msgs
+                )));
+            }
+        }
+
+        if let Some(wait_time) = self.wait_time_seconds {
+            if !(0..=20).contains(&wait_time) {
+                return Err(Error::InvalidConfig(format!(
+                    "wait_time_seconds must be between 0 and 20, got {}",
+                    wait_time
+                )));
+            }
+        }
+
+        Ok(())
+    }
+}
+
+/// Creates and configures an SQS client based on the provided configuration.
+pub async fn create_sqs_client(config: Option<SQSSourceConfig>) -> Result<Client> {
+    let config = match config {
+        Some(cfg) => cfg,
+        None => {
+            return Err(Error::InvalidConfig(
+                "SQS configuration is required".to_string(),
+            ));
+        }
+    };
+
+    // Validate configuration before proceeding
+    config.validate()?;
+
+    tracing::info!(
+        "Creating SQS client for queue {queue_name} in region {region}",
+        region = config.region.clone(),
+        queue_name = config.queue_name.clone()
+    );
+
+    let region_provider = RegionProviderChain::first_try(Region::new(config.region.clone()))
+        .or_default_provider()
+        .or_else(Region::new("us-west-2")); // Default region if none provided
+
+    // recommended to pin behavior version
+    // https://docs.aws.amazon.com/sdk-for-rust/latest/dg/behavior-versions.html
+    let mut config_builder =
+        aws_config::defaults(BehaviorVersion::v2025_01_17()).region(region_provider);
+
+    // Apply endpoint URL if configured
+    if let Some(endpoint_url) = config.endpoint_url {
+        config_builder = config_builder.endpoint_url(endpoint_url);
+    }
+
+    // Load the shared config
+    let shared_config = config_builder.load().await;
+
+    // Create and return the client
+    Ok(Client::new(&shared_config))
 }
 
 /// Internal message types for the actor implementation.
@@ -80,44 +174,24 @@ struct SqsActor {
     handler_rx: mpsc::Receiver<SQSActorMessage>,
     client: Client,
     queue_url: String,
+    config: SQSSourceConfig,
 }
 
 impl SqsActor {
-    fn new(handler_rx: mpsc::Receiver<SQSActorMessage>, client: Client, queue_url: String) -> Self {
+    fn new(
+        handler_rx: mpsc::Receiver<SQSActorMessage>,
+        client: Client,
+        queue_url: String,
+        config: SQSSourceConfig,
+    ) -> Self {
         Self {
             handler_rx,
             client,
             queue_url,
+            config,
         }
     }
 
-    async fn create_sqs_client(config: Option<SQSSourceConfig>) -> Client {
-        let region = match config {
-            Some(config) => config.region.clone(),
-            None => SQS_DEFAULT_REGION.to_string(),
-        };
-
-        tracing::info!(region = region.clone(), "Creating SQS client in region");
-
-        // read aws config
-        let region_provider = RegionProviderChain::first_try(Region::new(region.clone()))
-            .or_default_provider()
-            .or_else(Region::new(SQS_DEFAULT_REGION));
-
-        let shared_config = aws_config::defaults(BehaviorVersion::latest())
-            .timeout_config(
-                TimeoutConfig::builder()
-                    .operation_attempt_timeout(Duration::from_secs(10))
-                    .build(),
-            )
-            .region(region_provider)
-            .load()
-            .await;
-
-        // create sqs client
-        Client::new(&shared_config)
-    }
-
     async fn run(&mut self) {
         while let Some(msg) = self.handler_rx.recv().await {
             self.handle_message(msg).await;
@@ -168,22 +242,57 @@ impl SqsActor {
         // https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html#sqs-short-long-polling-differences
         // TODO: find a better way to handle user input timeout. should allow the users
         // to choose long/short polling. For now, we default to 1 second (long polling).
-        let remaining_time = if remaining_time.as_millis() < 1000 {
-            Duration::from_secs(1)
+        let wait_time = if remaining_time.as_millis() < 1000 {
+            1
         } else {
-            remaining_time
+            (remaining_time.as_secs() as i32).min(20) // SQS max wait time is 20 seconds
         };
 
-        let sdk_response = self
+        // Use configured max messages if provided, otherwise use the requested count
+        let max_messages = self.config.max_number_of_messages.unwrap_or(count).min(10); // SQS max batch size is 10
+
+        let mut receive_message_builder = self
             .client
             .receive_message()
-            .queue_url(self.queue_url.clone())
-            .max_number_of_messages(count)
-            .message_attribute_names("All")
-            .message_system_attribute_names(MessageSystemAttributeName::All)
-            .wait_time_seconds(remaining_time.as_secs() as i32)
-            .send()
-            .await;
+            .queue_url(&self.queue_url)
+            .max_number_of_messages(max_messages)
+            .wait_time_seconds(wait_time);
+
+        // Apply visibility timeout if configured
+        if let Some(visibility_timeout) = self.config.visibility_timeout {
+            receive_message_builder =
+                receive_message_builder.visibility_timeout(visibility_timeout);
+        }
+
+        // Apply attribute names if configured
+        if !self.config.attribute_names.is_empty() {
+            for attr in &self.config.attribute_names {
+                let attr_name = MessageSystemAttributeName::from_str(attr);
+                match attr_name {
+                    Ok(attr_name) => {
+                        receive_message_builder =
+                            receive_message_builder.message_system_attribute_names(attr_name);
+                    }
+                    Err(err) => {
+                        tracing::error!(?err, "failed to parse attribute name");
+                    }
+                }
+            }
+        } else {
+            receive_message_builder = receive_message_builder
+                .message_system_attribute_names(MessageSystemAttributeName::All);
+        }
+
+        // Apply message attribute names if configured
+        if !self.config.message_attribute_names.is_empty() {
+            for attr in &self.config.message_attribute_names {
+                receive_message_builder = receive_message_builder.message_attribute_names(attr);
+            }
+        } else {
+            receive_message_builder = receive_message_builder.message_attribute_names("All");
+        }
+
+        let sdk_response = receive_message_builder.send().await;
 
         let receive_message_output = match sdk_response {
             Ok(output) => output,
@@ -229,7 +338,7 @@ impl SqsActor {
                     .map(|attrs| {
                         attrs
                             .iter()
-                            .map(|(k, v)| (k.to_string().clone(), v.to_string().clone()))
+                            .map(|(k, v)| (k.to_string(), v.to_string()))
                             .collect()
                     })
                     .unwrap_or_default();
@@ -248,7 +357,7 @@ impl SqsActor {
         Ok(messages)
     }
 
-    // delete message from SQS, serves as Numaflow source ack.
+    /// delete message from SQS, serves as Numaflow source ack.
     async fn delete_messages(&mut self, offsets: Vec<Bytes>) -> Result<()> {
         for offset in offsets {
             let offset = match std::str::from_utf8(&offset) {
@@ -268,8 +377,7 @@ impl SqsActor {
             {
                 tracing::error!(
                     ?err,
-                    "{} {}",
-                    self.queue_url.clone(),
+                    queue_url = ?self.queue_url,
                     "Error while deleting message from SQS"
                 );
                 return Err(Error::Sqs(err.into()));
@@ -278,16 +386,16 @@ impl SqsActor {
         Ok(())
     }
 
-    // get the pending message count from SQS using the ApproximateNumberOfMessages attribute
-    // Note: The ApproximateNumberOfMessages metrics may not achieve consistency until at least
-    // 1 minute after the producers stop sending messages.
-    // This period is required for the queue metadata to reach eventual consistency.
+    /// get the pending message count from SQS using the ApproximateNumberOfMessages attribute
+    /// Note: The ApproximateNumberOfMessages metrics may not achieve consistency until at least
+    /// 1 minute after the producers stop sending messages.
+    /// This period is required for the queue metadata to reach eventual consistency.
     async fn get_pending_messages(&mut self) -> Result<Option<usize>> {
         let sdk_response = self
             .client
             .get_queue_attributes()
             .queue_url(self.queue_url.clone())
-            .attribute_names(aws_sdk_sqs::types::QueueAttributeName::ApproximateNumberOfMessages)
+            .attribute_names(QueueAttributeName::ApproximateNumberOfMessages)
             .send()
             .await;
 
@@ -296,7 +404,7 @@ impl SqsActor {
             Err(err) => {
                 tracing::error!(
                     ?err,
-                    queue_url = self.queue_url,
+                    queue_url = ?self.queue_url,
                     "failed to get queue attributes from SQS"
                 );
                 return Err(Error::Sqs(err.into()));
@@ -339,6 +447,7 @@ pub struct SQSSource {
     /// timeout for each batch read request
     timeout: Duration,
     actor_tx: mpsc::Sender<SQSActorMessage>,
+    vertex_replica: u16,
 }
 
 /// Builder for creating an `SqsSource`.
@@ -351,6 +460,7 @@ pub struct SqsSourceBuilder {
     batch_size: usize,
     timeout: Duration,
     client: Option<Client>,
+    vertex_replica: u16,
 }
 
 impl Default for SqsSourceBuilder {
@@ -358,6 +468,13 @@ impl Default for SqsSourceBuilder {
         Self::new(SQSSourceConfig {
             region: SQS_DEFAULT_REGION.to_string(),
             queue_name: "".to_string(),
+            queue_owner_aws_account_id: "".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: Vec::new(),
+            message_attribute_names: Vec::new(),
         })
     }
 }
@@ -369,6 +486,7 @@ impl SqsSourceBuilder {
             batch_size: 1,
             timeout: Duration::from_secs(1),
             client: None,
+            vertex_replica: 0,
         }
     }
     pub fn config(mut self, config: SQSSourceConfig) -> Self {
@@ -391,6 +509,11 @@ impl SqsSourceBuilder {
         self
     }
 
+    pub fn vertex_replica(mut self, vertex_replica: u16) -> Self {
+        self.vertex_replica = vertex_replica;
+        self
+    }
+
     /// Builds an `SqsSource` instance with the provided configuration.
     ///
     /// This method consumes `self` and initializes the SQS client, retrieves the queue URL,
@@ -401,16 +524,21 @@ impl SqsSourceBuilder {
     /// - `Ok(SqsSource)` if the source is successfully built.
     /// - `Err(Error)` if there is an error during the initialization process.
     pub async fn build(self) -> Result<SQSSource> {
+        // Validate the configuration
+        self.config.validate()?;
+
         let sqs_client = match self.client {
             Some(client) => client,
-            None => SqsActor::create_sqs_client(Some(self.config.clone())).await,
+            None => create_sqs_client(Some(self.config.clone())).await?,
         };
 
         let queue_name = self.config.queue_name.clone();
+        let queue_owner_aws_account_id = self.config.queue_owner_aws_account_id.clone();
 
         let get_queue_url_output = sqs_client
             .get_queue_url()
             .queue_name(queue_name)
+            .queue_owner_aws_account_id(queue_owner_aws_account_id)
             .send()
             .await
             .map_err(|err| Error::Sqs(err.into()))?;
@@ -423,7 +551,7 @@ impl SqsSourceBuilder {
 
         let (handler_tx, handler_rx) = mpsc::channel(10);
         tokio::spawn(async move {
-            let mut actor = SqsActor::new(handler_rx, sqs_client, queue_url);
+            let mut actor = SqsActor::new(handler_rx, sqs_client, queue_url, self.config);
             actor.run().await;
         });
 
@@ -431,12 +559,13 @@ impl SqsSourceBuilder {
             batch_size: self.batch_size,
             timeout: self.timeout,
             actor_tx: handler_tx,
+            vertex_replica: self.vertex_replica,
         })
     }
 }
 
 impl SQSSource {
-    // read messages from SQS, corresponding sqs sdk method is receive_message
+    /// read messages from SQS, corresponding sqs sdk method is receive_message
     pub async fn read_messages(&self) -> Result<Vec<SQSMessage>> {
         tracing::debug!("Reading messages from SQS");
         let start = Instant::now();
@@ -450,7 +579,7 @@ impl SQSSource {
 
         let _ = self.actor_tx.send(msg).await;
         let messages = rx.await.map_err(ActorTaskTerminated)??;
-        tracing::debug!(
+        tracing::trace!(
             count = messages.len(),
             requested_count = self.batch_size,
             time_taken_ms = start.elapsed().as_millis(),
@@ -459,8 +588,8 @@ impl SQSSource {
         Ok(messages)
     }
 
-    // acknowledge the offsets of the messages read from SQS
-    // corresponding sqs sdk method is delete_message
+    /// acknowledge the offsets of the messages read from SQS
+    /// corresponding sqs sdk method is delete_message
     pub async fn ack_offsets(&self, offsets: Vec<Bytes>) -> Result<()> {
         tracing::debug!(offsets = ?offsets, "Acknowledging offsets");
         let (tx, rx) = oneshot::channel();
@@ -468,13 +597,13 @@ impl SQSSource {
             offsets,
             respond_to: tx,
         };
-        let _ = self.actor_tx.send(msg).await;
+        self.actor_tx.send(msg).await.expect("rx was dropped");
         rx.await.map_err(Error::ActorTaskTerminated)?
     }
 
-    // get the pending message count from SQS
-    // corresponding sqs sdk method is get_queue_attributes
-    // with the attribute name ApproximateNumberOfMessages
+    /// get the pending message count from SQS
+    /// corresponding sqs sdk method is get_queue_attributes
+    /// with the attribute name ApproximateNumberOfMessages
     pub async fn pending_count(&self) -> Option<usize> {
         let (tx, rx) = oneshot::channel();
         let msg = SQSActorMessage::GetPending { respond_to: tx };
@@ -497,19 +626,148 @@ impl SQSSource {
     /// Note: It is implemented in the core to return the current vertex replica.
     /// See `numaflow-core/src/source/sqs.rs` for the implementation.
     pub fn partitions(&self) -> Vec<u16> {
-        unimplemented!()
+        vec![self.vertex_replica]
     }
 }
 
 #[cfg(test)]
 mod tests {
     use aws_sdk_sqs::Config;
+    use aws_sdk_sqs::config::BehaviorVersion;
+    use aws_sdk_sqs::types::MessageAttributeValue;
     use aws_smithy_mocks_experimental::{MockResponseInterceptor, Rule, RuleMode, mock};
     use aws_smithy_types::error::ErrorMetadata;
+    use test_log::test;
 
     use super::*;
 
     #[tokio::test]
+    async fn test_client_creation_with_defaults() {
+        let config = SQSSourceConfig {
+            region: "us-west-2".to_string(),
+            queue_name: "test-queue".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        };
+
+        let result = create_sqs_client(Some(config)).await;
+        assert!(result.is_ok());
+    }
+
+    #[tokio::test]
+    async fn test_client_creation_with_custom_endpoint() {
+        let mut config = SQSSourceConfig {
+            region: "us-west-2".to_string(),
+            queue_name: "test-queue".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: Some(30),
+            max_number_of_messages: Some(5),
+            wait_time_seconds: Some(10),
+            endpoint_url: Some("http://localhost:4566".to_string()),
+            attribute_names: vec!["All".to_string()],
+            message_attribute_names: vec!["All".to_string()],
+        };
+
+        let result = create_sqs_client(Some(config.clone())).await;
+        assert!(result.is_ok());
+
+        // Test with invalid endpoint
+        config.endpoint_url = Some("invalid-url".to_string());
+        let result = create_sqs_client(Some(config)).await;
+        assert!(result.is_ok()); // The URL is validated when making requests, not during client creation
+    }
+
+    #[tokio::test]
+    async fn test_client_creation_validation_failures() {
+        // Test missing config
+        let result = create_sqs_client(None).await;
+        assert!(matches!(result, Err(Error::InvalidConfig(_))));
+
+        // Test empty region
+        let config = SQSSourceConfig {
+            region: "".to_string(),
+            queue_name: "test-queue".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        };
+        let result = create_sqs_client(Some(config)).await;
+        assert!(matches!(result, Err(Error::InvalidConfig(_))));
+
+        // Test empty queue name
+        let config = SQSSourceConfig {
+            region: "us-west-2".to_string(),
+            queue_name: "".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        };
+        let result = create_sqs_client(Some(config)).await;
+        assert!(matches!(result, Err(Error::InvalidConfig(_))));
+
+        // Test invalid max_number_of_messages
+        let config = SQSSourceConfig {
+            region: "us-west-2".to_string(),
+            queue_name: "test-queue".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: Some(20), // Invalid: > 10
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        };
+        let result = create_sqs_client(Some(config)).await;
+        assert!(matches!(result, Err(Error::InvalidConfig(_))));
+
+        // Test invalid wait_time_seconds
+        let config = SQSSourceConfig {
+            region: "us-west-2".to_string(),
+            queue_name: "test-queue".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: Some(30), // Invalid: > 20
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        };
+        let result = create_sqs_client(Some(config)).await;
+        assert!(matches!(result, Err(Error::InvalidConfig(_))));
+    }
+
+    #[tokio::test]
+    async fn test_client_creation_with_invalid_parameters() {
+        let config = SQSSourceConfig {
+            region: "us-west-2".to_string(),
+            queue_name: "test-queue".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: Some(50000),  // Invalid: > 43200
+            max_number_of_messages: Some(20), // Invalid: > 10
+            wait_time_seconds: Some(30),      // Invalid: > 20
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        };
+
+        let result = create_sqs_client(Some(config)).await;
+        assert!(matches!(result, Err(Error::InvalidConfig(_))));
+    }
+
+    #[test(tokio::test)]
     async fn test_sqssourcehandle_read() {
         let queue_url_output = get_queue_url_output();
 
@@ -526,6 +784,13 @@ mod tests {
         let source = SqsSourceBuilder::new(SQSSourceConfig {
             region: SQS_DEFAULT_REGION.to_string(),
             queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: Some(300),
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![MessageSystemAttributeName::SentTimestamp.to_string()],
+            message_attribute_names: vec![MessageSystemAttributeName::AwsTraceHeader.to_string()],
         })
         .batch_size(1)
         .timeout(Duration::from_secs(0))
@@ -548,9 +813,88 @@ mod tests {
             msg1.offset,
             "AQEBaZ+j5qUoOAoxlmrCQPkBm9njMWXqemmIG6shMHCO6fV20JrQYg/AiZ8JELwLwOu5U61W+aIX5Qzu7GGofxJuvzymr4Ph53RiR0mudj4InLSgpSspYeTRDteBye5tV/txbZDdNZxsi+qqZA9xPnmMscKQqF6pGhnGIKrnkYGl45Nl6GPIZv62LrIRb6mSqOn1fn0yqrvmWuuY3w2UzQbaYunJWGxpzZze21EOBtywknU3Je/g7G9is+c6K9hGniddzhLkK1tHzZKjejOU4jokaiB4nmi0dF3JqLzDsQuPF0Gi8qffhEvw56nl8QCbluSJScFhJYvoagGnDbwOnd9z50L239qtFIgETdpKyirlWwl/NGjWJ45dqWpiW3d2Ws7q"
         );
+        assert_eq!(msg1.attributes.clone().unwrap().len(), 1);
+
+        // test another config
+
+        let sqs_operation_mocks = MockResponseInterceptor::new()
+            .rule_mode(RuleMode::MatchAny)
+            .with_rule(&queue_url_output)
+            .with_rule(&receive_message_output);
+        let sqs_mock_client =
+            Client::from_conf(get_test_config_with_interceptor(sqs_operation_mocks));
+        let source = SqsSourceBuilder::new(SQSSourceConfig {
+            region: SQS_DEFAULT_REGION.to_string(),
+            queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: Some(300),
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        })
+        .batch_size(1)
+        .timeout(Duration::from_secs(0))
+        .client(sqs_mock_client)
+        .build()
+        .await
+        .unwrap();
+
+        // Read messages from the source
+        let messages = source.read_messages().await.unwrap();
+
+        // Assert we got the expected number of messages
+        assert_eq!(messages.len(), 1, "Should receive exactly 1 message");
     }
 
-    #[tokio::test]
+    #[test(tokio::test)]
+    async fn test_sqssourcehandle_read_error() {
+        let queue_url_output = get_queue_url_output();
+
+        let receive_message_output = get_receive_message_error();
+
+        let sqs_operation_mocks = MockResponseInterceptor::new()
+            .rule_mode(RuleMode::MatchAny)
+            .with_rule(&queue_url_output)
+            .with_rule(&receive_message_output);
+
+        let sqs_mock_client =
+            Client::from_conf(get_test_config_with_interceptor(sqs_operation_mocks));
+
+        let source = SqsSourceBuilder::new(SQSSourceConfig {
+            region: SQS_DEFAULT_REGION.to_string(),
+            queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: Some(300),
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![MessageSystemAttributeName::SentTimestamp.to_string()],
+            message_attribute_names: vec![MessageSystemAttributeName::AwsTraceHeader.to_string()],
+        })
+        .batch_size(1)
+        .timeout(Duration::from_secs(0))
+        .client(sqs_mock_client)
+        .build()
+        .await
+        .unwrap();
+
+        // Read messages from the source
+        let messages = source.read_messages().await;
+
+        match messages {
+            Ok(_) => panic!("Expected an error, but got a successful response"),
+            Err(err) => {
+                assert_eq!(
+                    err.to_string(),
+                    "Failed with SQS error - unhandled error (InvalidAddress)"
+                );
+            }
+        }
+    }
+
+    #[test(tokio::test)]
     async fn test_sqssource_ack() {
         let queue_url_output = get_queue_url_output();
         let delete_message_output = get_delete_message_output();
@@ -566,6 +910,13 @@ mod tests {
         let source = SqsSourceBuilder::new(SQSSourceConfig {
             region: SQS_DEFAULT_REGION.to_string(),
             queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
         })
         .batch_size(1)
         .timeout(Duration::from_secs(0))
@@ -580,7 +931,44 @@ mod tests {
         assert!(result.is_ok());
     }
 
-    #[tokio::test]
+    #[test(tokio::test)]
+    async fn test_sqssource_ack_error() {
+        let queue_url_output = get_queue_url_output();
+        let delete_message_output = get_delete_message_error();
+
+        let sqs_operation_mocks = MockResponseInterceptor::new()
+            .rule_mode(RuleMode::MatchAny)
+            .with_rule(&queue_url_output)
+            .with_rule(&delete_message_output);
+
+        let sqs_mock_client =
+            Client::from_conf(get_test_config_with_interceptor(sqs_operation_mocks));
+
+        let source = SqsSourceBuilder::new(SQSSourceConfig {
+            region: SQS_DEFAULT_REGION.to_string(),
+            queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        })
+        .batch_size(1)
+        .timeout(Duration::from_secs(0))
+        .client(sqs_mock_client)
+        .build()
+        .await
+        .unwrap();
+
+        // Test acknowledgment
+        let offset = "AQEBaZ+j5qUoOAoxlmrCQPkBm9njMWXqemmIG6shMHCO6fV20JrQYg/AiZ8JELwLwOu5U61W+aIX5Qzu7GGofxJuvzymr4Ph53RiR0mudj4InLSgpSspYeTRDteBye5tV/txbZDdNZxsi+qqZA9xPnmMscKQqF6pGhnGIKrnkYGl45Nl6GPIZv62LrIRb6mSqOn1fn0yqrvmWuuY3w2UzQbaYunJWGxpzZze21EOBtywknU3Je/g7G9is+c6K9hGniddzhLkK1tHzZKjejOU4jokaiB4nmi0dF3JqLzDsQuPF0Gi8qffhEvw56nl8QCbluSJScFhJYvoagGnDbwOnd9z50L239qtFIgETdpKyirlWwl/NGjWJ45dqWpiW3d2Ws7q";
+        let result = source.ack_offsets(vec![Bytes::from(offset)]).await;
+        assert!(result.is_err());
+    }
+
+    #[test(tokio::test)]
     async fn test_sqssource_pending_count() {
         let queue_url_output = get_queue_url_output();
         let queue_attrs_output = get_queue_attributes_output();
@@ -596,6 +984,13 @@ mod tests {
         let source = SqsSourceBuilder::new(SQSSourceConfig {
             region: SQS_DEFAULT_REGION.to_string(),
             queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
         })
         .batch_size(1)
         .timeout(Duration::from_secs(0))
@@ -608,7 +1003,42 @@ mod tests {
         assert_eq!(count, Some(0));
     }
 
-    #[tokio::test]
+    #[test(tokio::test)]
+    async fn test_sqssource_pending_count_error() {
+        let queue_url_output = get_queue_url_output();
+        let queue_attrs_output = get_queue_attributes_error();
+
+        let sqs_operation_mocks = MockResponseInterceptor::new()
+            .rule_mode(RuleMode::MatchAny)
+            .with_rule(&queue_url_output)
+            .with_rule(&queue_attrs_output);
+
+        let sqs_mock_client =
+            Client::from_conf(get_test_config_with_interceptor(sqs_operation_mocks));
+
+        let source = SqsSourceBuilder::new(SQSSourceConfig {
+            region: SQS_DEFAULT_REGION.to_string(),
+            queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        })
+        .batch_size(1)
+        .timeout(Duration::from_secs(0))
+        .client(sqs_mock_client)
+        .build()
+        .await
+        .unwrap();
+
+        let count = source.pending_count().await;
+        assert_eq!(count, None);
+    }
+
+    #[test(tokio::test)]
     async fn test_error_cases() {
         // Test invalid region error
         let sqs_operation_mocks = MockResponseInterceptor::new()
@@ -621,6 +1051,13 @@ mod tests {
         let source = SqsSourceBuilder::new(SQSSourceConfig {
             region: SQS_DEFAULT_REGION.to_string(),
             queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
         })
         .batch_size(1)
         .timeout(Duration::from_secs(0))
@@ -631,14 +1068,46 @@ mod tests {
     }
 
     #[tokio::test]
-    #[should_panic(expected = "not implemented")]
     async fn test_partitions_unimplemented() {
         let source = SQSSource {
             batch_size: 1,
             timeout: Duration::from_secs(0),
             actor_tx: mpsc::channel(1).0,
+            vertex_replica: 1,
         };
-        source.partitions();
+        assert_eq!(source.partitions(), vec![1]);
+    }
+
+    #[tokio::test]
+    async fn test_sqs_source_builder() {
+        // test default
+        let builder = SqsSourceBuilder::default();
+        assert_eq!(builder.batch_size, 1);
+        assert_eq!(builder.timeout, Duration::from_secs(1));
+
+        // test with vertex replica
+        let builder = SqsSourceBuilder::default().vertex_replica(2);
+        assert_eq!(builder.vertex_replica, 2);
+
+        // test with custom config
+        let config = SQSSourceConfig {
+            region: "us-east-2".to_string(),
+            queue_name: "test-queue-custom".to_string(),
+            queue_owner_aws_account_id: "123456789012".to_string(),
+            visibility_timeout: Some(300),
+            max_number_of_messages: Some(2000),
+            wait_time_seconds: Some(10),
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
+        };
+        let builder = SqsSourceBuilder::default().config(config);
+        assert_eq!(builder.config.region, "us-east-2");
+        assert_eq!(builder.config.queue_name, "test-queue-custom");
+        assert_eq!(builder.config.queue_owner_aws_account_id, "123456789012");
+        assert_eq!(builder.config.visibility_timeout, Some(300));
+        assert_eq!(builder.config.max_number_of_messages, Some(2000));
+        assert_eq!(builder.config.wait_time_seconds, Some(10));
     }
 
     fn get_queue_attributes_output() -> Rule {
@@ -658,6 +1127,23 @@ mod tests {
         queue_attributes_output
     }
 
+    fn get_queue_attributes_error() -> Rule {
+        let queue_attributes_output = mock!(aws_sdk_sqs::Client::get_queue_attributes)
+            .match_requests(|inp| {
+                inp.queue_url().unwrap()
+                    == "https://sqs.us-west-2.amazonaws.com/926113353675/test-q/"
+            })
+            .then_error(|| {
+                aws_sdk_sqs::operation::get_queue_attributes::GetQueueAttributesError::generic(
+                    ErrorMetadata::builder()
+                        .code("QueueDoesNotExist")
+                        .message("The specified queue does not exist for this wsdl version.")
+                        .build(),
+                )
+            });
+        queue_attributes_output
+    }
+
     fn get_delete_message_output() -> Rule {
         let delete_message_output = mock!(aws_sdk_sqs::Client::delete_message)
             .match_requests(|inp| {
@@ -670,6 +1156,20 @@ mod tests {
         delete_message_output
     }
 
+    fn get_delete_message_error() -> Rule {
+        let delete_message_output = mock!(aws_sdk_sqs::Client::delete_message)
+            .match_requests(|inp| {
+                inp.queue_url().unwrap() == "https://sqs.us-west-2.amazonaws.com/926113353675/test-q/"
+                    && inp.receipt_handle().unwrap() == "AQEBaZ+j5qUoOAoxlmrCQPkBm9njMWXqemmIG6shMHCO6fV20JrQYg/AiZ8JELwLwOu5U61W+aIX5Qzu7GGofxJuvzymr4Ph53RiR0mudj4InLSgpSspYeTRDteBye5tV/txbZDdNZxsi+qqZA9xPnmMscKQqF6pGhnGIKrnkYGl45Nl6GPIZv62LrIRb6mSqOn1fn0yqrvmWuuY3w2UzQbaYunJWGxpzZze21EOBtywknU3Je/g7G9is+c6K9hGniddzhLkK1tHzZKjejOU4jokaiB4nmi0dF3JqLzDsQuPF0Gi8qffhEvw56nl8QCbluSJScFhJYvoagGnDbwOnd9z50L239qtFIgETdpKyirlWwl/NGjWJ45dqWpiW3d2Ws7q"
+            })
+            .then_error(|| {
+                aws_sdk_sqs::operation::delete_message::DeleteMessageError::generic(
+                    ErrorMetadata::builder().code("ReceiptHandleIsInvalid").build(),
+                )
+            });
+        delete_message_output
+    }
+
     fn get_receive_message_output() -> Rule {
         let receive_message_output = mock!(aws_sdk_sqs::Client::receive_message)
             .match_requests(|inp| {
@@ -683,6 +1183,13 @@ mod tests {
                             .body("This is a test message")
                             .receipt_handle("AQEBaZ+j5qUoOAoxlmrCQPkBm9njMWXqemmIG6shMHCO6fV20JrQYg/AiZ8JELwLwOu5U61W+aIX5Qzu7GGofxJuvzymr4Ph53RiR0mudj4InLSgpSspYeTRDteBye5tV/txbZDdNZxsi+qqZA9xPnmMscKQqF6pGhnGIKrnkYGl45Nl6GPIZv62LrIRb6mSqOn1fn0yqrvmWuuY3w2UzQbaYunJWGxpzZze21EOBtywknU3Je/g7G9is+c6K9hGniddzhLkK1tHzZKjejOU4jokaiB4nmi0dF3JqLzDsQuPF0Gi8qffhEvw56nl8QCbluSJScFhJYvoagGnDbwOnd9z50L239qtFIgETdpKyirlWwl/NGjWJ45dqWpiW3d2Ws7q")
                             .attributes(MessageSystemAttributeName::SentTimestamp, "1677112427387")
+                            .message_attributes(
+                               "AwsTraceHeader",
+                               MessageAttributeValue::builder()
+                                   .set_data_type(Some("String".to_string()))
+                                   .set_string_value(Some("Root=1-5e4f8a2c-0b2d3e4f8a2c0b2d3e4f8a2c".to_string()))
+                                   .build().unwrap()
+                            )
                             .build()
                     )
                     .build()
@@ -690,6 +1197,20 @@ mod tests {
         receive_message_output
     }
 
+    fn get_receive_message_error() -> Rule {
+        let receive_message_output = mock!(aws_sdk_sqs::Client::receive_message)
+            .match_requests(|inp| {
+                inp.queue_url().unwrap()
+                    == "https://sqs.us-west-2.amazonaws.com/926113353675/test-q/"
+            })
+            .then_error(|| {
+                aws_sdk_sqs::operation::receive_message::ReceiveMessageError::generic(
+                    ErrorMetadata::builder().code("InvalidAddress").build(),
+                )
+            });
+        receive_message_output
+    }
+
     fn get_queue_url_output() -> Rule {
         let queue_url_output = mock!(aws_sdk_sqs::Client::get_queue_url)
             .match_requests(|inp| inp.queue_name().unwrap() == "test-q")
@@ -711,7 +1232,7 @@ mod tests {
 
     fn get_test_config_with_interceptor(interceptor: MockResponseInterceptor) -> Config {
         aws_sdk_sqs::Config::builder()
-            .behavior_version(BehaviorVersion::latest())
+            .behavior_version(BehaviorVersion::v2025_01_17())
             .credentials_provider(make_sqs_test_credentials())
             .region(aws_sdk_sqs::config::Region::new(SQS_DEFAULT_REGION))
             .interceptor(interceptor)
diff --git a/rust/numaflow-core/Cargo.toml b/rust/numaflow-core/Cargo.toml
index b0a11c85..4ba2eab2 100644
--- a/rust/numaflow-core/Cargo.toml
+++ b/rust/numaflow-core/Cargo.toml
@@ -29,10 +29,8 @@ bytes.workspace = true
 serde.workspace = true
 rustls.workspace = true
 tower.workspace = true
-reqwest.workspace = true
-hyper = "1.2.0"
 async-nats.workspace = true
-tonic = { version = "0.13.0"}
+tonic = { version = "0.13.0" }
 thiserror = "2.0.3"
 tokio-util = "0.7.11"
 tokio-stream = "0.1.15"
@@ -59,13 +57,9 @@ numaflow = { git = "https://github.com/numaproj/numaflow-rs.git", rev = "c6aa3a8
 pulsar = { version = "6.3.0", default-features = false, features = [
     "tokio-rustls-runtime",
 ] }
-aws-smithy-runtime = { version = "1.7.6", features = ["test-util"] }
-aws-smithy-types = "1.2.11"
 http = "1.2.0"
-aws-config = "1.5.11"
-aws-sdk-sqs = "1.51.0"
-reqwest = { workspace = true, features = ["json"] }
-aws-smithy-mocks-experimental = "0.2.1"
+aws-sdk-sqs = "1.65.0"
+aws-smithy-mocks-experimental = "0.2.3"
 k8s-openapi = { version = "0.24.0", features = ["v1_32"] }
 
 [build-dependencies]
diff --git a/rust/numaflow-core/src/config.rs b/rust/numaflow-core/src/config.rs
index 703a1252..ae8352e6 100644
--- a/rust/numaflow-core/src/config.rs
+++ b/rust/numaflow-core/src/config.rs
@@ -126,7 +126,6 @@ impl Settings {
 #[cfg(test)]
 mod tests {
     use std::collections::HashMap;
-    use std::env;
 
     use base64::Engine;
     use base64::prelude::BASE64_STANDARD;
diff --git a/rust/numaflow-core/src/config/components.rs b/rust/numaflow-core/src/config/components.rs
index 64b0310f..ec92e2f8 100644
--- a/rust/numaflow-core/src/config/components.rs
+++ b/rust/numaflow-core/src/config/components.rs
@@ -7,9 +7,10 @@ pub(crate) mod source {
 
     use bytes::Bytes;
     use numaflow_jetstream::{JetstreamSourceConfig, NatsAuth, TlsClientAuthCerts, TlsConfig};
-    use numaflow_models::models::{GeneratorSource, PulsarSource, Source};
+    use numaflow_models::models::{GeneratorSource, PulsarSource, Source, SqsSource};
     use numaflow_pulsar::source::{PulsarAuth, PulsarSourceConfig};
-    use tracing::warn;
+    use numaflow_sqs::source::SQSSourceConfig;
+    use tracing::{info, warn};
 
     use crate::Result;
     use crate::error::Error;
@@ -37,6 +38,7 @@ pub(crate) mod source {
         UserDefined(UserDefinedConfig),
         Pulsar(PulsarSourceConfig),
         Jetstream(JetstreamSourceConfig),
+        Sqs(SQSSourceConfig),
     }
 
     impl From<Box<GeneratorSource>> for SourceType {
@@ -102,6 +104,35 @@ pub(crate) mod source {
         }
     }
 
+    impl TryFrom<Box<SqsSource>> for SourceType {
+        type Error = Error;
+
+        fn try_from(value: Box<SqsSource>) -> Result<Self> {
+            info!("Sqs source: {value:?}");
+            if value.aws_region.is_empty() {
+                return Err(Error::Config(
+                    "AWS region is required for SQS source".to_string(),
+                ));
+            }
+
+            let sqs_source_config = SQSSourceConfig {
+                queue_name: value.queue_name,
+                region: value.aws_region,
+                queue_owner_aws_account_id: value.queue_owner_aws_account_id,
+                attribute_names: value.attribute_names.unwrap_or_default(),
+                message_attribute_names: value.message_attribute_names.unwrap_or_default(),
+                max_number_of_messages: Some(value.max_number_of_messages.unwrap_or(10)),
+                wait_time_seconds: Some(value.wait_time_seconds.unwrap_or(0)),
+                visibility_timeout: Some(value.visibility_timeout.unwrap_or(30)),
+                endpoint_url: value.endpoint_url,
+            };
+
+            info!("parsed SQS source config: {sqs_source_config:?}");
+
+            Ok(SourceType::Sqs(sqs_source_config))
+        }
+    }
+
     impl TryFrom<Box<numaflow_models::models::JetStreamSource>> for SourceType {
         type Error = Error;
         fn try_from(
@@ -251,6 +282,10 @@ pub(crate) mod source {
                 return pulsar.try_into();
             }
 
+            if let Some(sqs) = source.sqs.take() {
+                return sqs.try_into();
+            }
+
             if let Some(_serving) = source.serving.take() {
                 panic!("Serving source is invalid");
             }
diff --git a/rust/numaflow-core/src/config/pipeline.rs b/rust/numaflow-core/src/config/pipeline.rs
index 92178170..ed99df1e 100644
--- a/rust/numaflow-core/src/config/pipeline.rs
+++ b/rust/numaflow-core/src/config/pipeline.rs
@@ -481,7 +481,7 @@ impl PipelineConfig {
             .spec
             .watermark
             .clone()
-            .map_or(true, |w| !w.disabled.unwrap_or(false))
+            .is_none_or(|w| !w.disabled.unwrap_or(false))
         {
             Self::create_watermark_config(
                 vertex_obj.spec.watermark.clone(),
diff --git a/rust/numaflow-core/src/error.rs b/rust/numaflow-core/src/error.rs
index 068c9ac5..6f3e4b50 100644
--- a/rust/numaflow-core/src/error.rs
+++ b/rust/numaflow-core/src/error.rs
@@ -61,4 +61,8 @@ pub enum Error {
 
     #[error("Watermark Error - {0}")]
     Watermark(String),
+
+    #[error("WAL Error - {0}")]
+    #[allow(clippy::upper_case_acronyms)]
+    WAL(String),
 }
diff --git a/rust/numaflow-core/src/mapper/map/user_defined.rs b/rust/numaflow-core/src/mapper/map/user_defined.rs
index 4e20cc98..5474e565 100644
--- a/rust/numaflow-core/src/mapper/map/user_defined.rs
+++ b/rust/numaflow-core/src/mapper/map/user_defined.rs
@@ -285,7 +285,7 @@ async fn create_response_stream(
                 "failed to receive handshake response".to_string(),
             ))?;
 
-    if handshake_response.handshake.map_or(true, |h| !h.sot) {
+    if handshake_response.handshake.is_none_or(|h| !h.sot) {
         return Err(Error::Mapper("invalid handshake response".to_string()));
     }
 
diff --git a/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs b/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs
index 94eb6a1c..028486b2 100644
--- a/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs
+++ b/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs
@@ -162,7 +162,7 @@ mod tests {
         }
     }
 
-    #[cfg(feature = "nats-tests")]
+    // #[cfg(feature = "nats-tests")]
     #[tokio::test]
     async fn test_source_forwarder() {
         let tracker_handle = TrackerHandle::new(None, None);
diff --git a/rust/numaflow-core/src/pipeline/isb/jetstream/reader.rs b/rust/numaflow-core/src/pipeline/isb/jetstream/reader.rs
index 4e10eeff..181bcb5a 100644
--- a/rust/numaflow-core/src/pipeline/isb/jetstream/reader.rs
+++ b/rust/numaflow-core/src/pipeline/isb/jetstream/reader.rs
@@ -99,7 +99,7 @@ impl TryFrom<JSWrappedMessage> for Message {
             tags: None,
             value: body.payload.into(),
             offset: offset.clone(),
-            event_time: utc_from_timestamp(message_info.event_time),
+            event_time: message_info.event_time.map(utc_from_timestamp).unwrap(),
             id: MessageID {
                 vertex_name: value.vertex_name.into(),
                 offset: offset.to_string().into(),
diff --git a/rust/numaflow-core/src/reduce.rs b/rust/numaflow-core/src/reduce.rs
index 25ff1369..1e8b11a8 100644
--- a/rust/numaflow-core/src/reduce.rs
+++ b/rust/numaflow-core/src/reduce.rs
@@ -1,2 +1,9 @@
+#![allow(dead_code)]
 /// Write Head Log for storing reduce data until the reduction is complete.
 pub(crate) mod wal;
+
+mod error;
+/// Persistent Buffer Queue (PBQ) for storing reduce data until the reduction is complete. It is
+/// responsible for reading from ISB and persisting the data to WAL. It is also responsible for
+/// reading the data it read from ISB or WAL (during replay) to Process and Forward (PNF).
+pub(crate) mod pbq;
diff --git a/rust/numaflow-core/src/reduce/error.rs b/rust/numaflow-core/src/reduce/error.rs
new file mode 100644
index 00000000..ef1997a8
--- /dev/null
+++ b/rust/numaflow-core/src/reduce/error.rs
@@ -0,0 +1,38 @@
+use crate::reduce::wal;
+use std::fmt::{Display, Formatter};
+
+/// The result of any operation on the WAL.
+pub(crate) type ReduceResult<T> = Result<T, Error>;
+
+#[derive(Debug)]
+pub(crate) enum Error {
+    #[allow(clippy::upper_case_acronyms)]
+    WAL(wal::error::Error),
+    /// Other errors.
+    Other(String),
+}
+
+impl Display for Error {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Error::Other(err) => {
+                write!(f, "Error::Other {err}")
+            }
+            Error::WAL(err) => {
+                write!(f, "Error::WAL {err}")
+            }
+        }
+    }
+}
+
+impl From<String> for Error {
+    fn from(value: String) -> Self {
+        Error::Other(value)
+    }
+}
+
+impl From<wal::error::Error> for Error {
+    fn from(value: wal::error::Error) -> Self {
+        Error::WAL(value)
+    }
+}
diff --git a/rust/numaflow-core/src/reduce/pbq.rs b/rust/numaflow-core/src/reduce/pbq.rs
new file mode 100644
index 00000000..beb9762d
--- /dev/null
+++ b/rust/numaflow-core/src/reduce/pbq.rs
@@ -0,0 +1,714 @@
+use crate::error::Result;
+use crate::message::Message;
+use crate::pipeline::isb::jetstream::reader::JetStreamReader;
+use crate::reduce::wal::WalMessage;
+use crate::reduce::wal::segment::append::{AppendOnlyWal, SegmentWriteMessage};
+use crate::reduce::wal::segment::compactor::Compactor;
+use crate::tracker::TrackerHandle;
+use tokio::sync::mpsc::{self, Sender};
+use tokio::task::JoinHandle;
+use tokio_stream::StreamExt;
+use tokio_stream::wrappers::ReceiverStream;
+use tokio_util::sync::CancellationToken;
+
+/// WAL for storing the data. If None, we will not persist the data.
+#[allow(clippy::upper_case_acronyms)]
+pub(crate) struct WAL {
+    append_only_wal: AppendOnlyWal,
+    compactor: Compactor,
+}
+
+/// PBQBuilder is a builder for PBQ.
+pub(crate) struct PBQBuilder {
+    isb_reader: JetStreamReader,
+    tracker_handle: TrackerHandle,
+    wal: Option<WAL>,
+}
+
+impl PBQBuilder {
+    /// Creates a new PBQBuilder.
+    pub(crate) fn new(isb_reader: JetStreamReader, tracker_handle: TrackerHandle) -> Self {
+        Self {
+            isb_reader,
+            tracker_handle,
+            wal: None,
+        }
+    }
+
+    pub(crate) fn wal(mut self, wal: WAL) -> Self {
+        self.wal = Some(wal);
+        self
+    }
+
+    pub(crate) fn build(self) -> PBQ {
+        PBQ {
+            isb_reader: self.isb_reader,
+            wal: self.wal,
+            tracker_handle: self.tracker_handle,
+        }
+    }
+}
+
+/// PBQ is a persistent buffer queue.
+#[allow(clippy::upper_case_acronyms)]
+pub(crate) struct PBQ {
+    isb_reader: JetStreamReader,
+    wal: Option<WAL>,
+    tracker_handle: TrackerHandle,
+}
+
+impl PBQ {
+    /// Streaming read from PBQ, returns a ReceiverStream and a JoinHandle for monitoring errors.
+    pub(crate) async fn streaming_read(
+        self,
+        cancellation_token: CancellationToken,
+    ) -> Result<(ReceiverStream<Message>, JoinHandle<Result<()>>)> {
+        let (tx, rx) = mpsc::channel(100);
+        let Some(wal) = self.wal else {
+            // No WAL, just read from ISB
+            return self.isb_reader.streaming_read(cancellation_token).await;
+        };
+
+        let handle = tokio::spawn(async move {
+            // Replay messages from WAL
+            Self::replay_wal(wal.compactor, &tx).await?;
+
+            // Read from ISB and write to WAL
+            Self::read_isb_and_write_wal(
+                self.isb_reader,
+                wal.append_only_wal,
+                self.tracker_handle,
+                tx,
+                cancellation_token,
+            )
+            .await?;
+
+            Ok(())
+        });
+
+        Ok((ReceiverStream::new(rx), handle))
+    }
+
+    /// Replays messages from the WAL converts them to [crate::message::Message] and sends them to
+    /// the tx channel.
+    async fn replay_wal(compactor: Compactor, tx: &Sender<Message>) -> Result<()> {
+        let (wal_tx, mut wal_rx) = mpsc::channel(100);
+        compactor.compact_with_replay(wal_tx).await?;
+
+        while let Some(msg) = wal_rx.recv().await {
+            let msg: WalMessage = msg.try_into().unwrap();
+            tx.send(msg.into()).await.expect("Receiver dropped");
+        }
+
+        Ok(())
+    }
+
+    /// Reads from ISB and writes to WAL.
+    async fn read_isb_and_write_wal(
+        isb_reader: JetStreamReader,
+        append_only_wal: AppendOnlyWal,
+        tracker_handle: TrackerHandle,
+        tx: Sender<Message>,
+        cancellation_token: CancellationToken,
+    ) -> Result<()> {
+        let (wal_tx, wal_rx) = mpsc::channel(100);
+        let (mut isb_stream, isb_handle) = isb_reader.streaming_read(cancellation_token).await?;
+        let (mut offset_stream, wal_handle) = append_only_wal
+            .streaming_write(ReceiverStream::new(wal_rx))
+            .await?;
+
+        // acknowledge the successfully written wal messages by listening on the offset stream.
+        tokio::spawn(async move {
+            while let Some(offset) = offset_stream.next().await {
+                tracker_handle
+                    .delete(offset)
+                    .await
+                    .expect("Failed to delete offset");
+            }
+        });
+
+        while let Some(msg) = isb_stream.next().await {
+            wal_tx
+                .send(SegmentWriteMessage::WriteData {
+                    offset: Some(msg.offset.clone()),
+                    data: WalMessage {
+                        message: msg.clone(),
+                    }
+                    .clone()
+                    .try_into()
+                    .expect("Failed to parse message to bytes"),
+                })
+                .await
+                .expect("Receiver dropped");
+
+            tx.send(msg).await.expect("Receiver dropped");
+        }
+
+        drop(wal_tx);
+        wal_handle.await.expect("task failed")?;
+        isb_handle.await.expect("task failed")?;
+
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::config::pipeline::isb::{BufferReaderConfig, Stream};
+    use crate::message::{IntOffset, MessageID, Offset};
+    use crate::reduce::wal::segment::WalType;
+    use crate::reduce::wal::segment::compactor::WindowKind;
+    use crate::reduce::wal::segment::replay::{ReplayWal, SegmentEntry};
+    use async_nats::jetstream;
+    use async_nats::jetstream::{consumer, stream};
+    use bytes::BytesMut;
+    use chrono::Utc;
+    use std::collections::HashMap;
+    use std::sync::Arc;
+    use std::time::Duration;
+
+    #[cfg(feature = "nats-tests")]
+    #[tokio::test]
+    async fn test_pbq_read_without_wal() {
+        let js_url = "localhost:4222";
+        // Create JetStream context
+        let client = async_nats::connect(js_url).await.unwrap();
+        let context = jetstream::new(client);
+
+        let stream = Stream::new("test_pbq_read_without_wal", "test", 0);
+        // Delete stream if it exists
+        let _ = context.delete_stream(stream.name).await;
+        context
+            .get_or_create_stream(stream::Config {
+                name: stream.name.to_string(),
+                subjects: vec![stream.name.to_string()],
+                max_message_size: 1024,
+                ..Default::default()
+            })
+            .await
+            .unwrap();
+
+        let _consumer = context
+            .create_consumer_on_stream(
+                consumer::Config {
+                    name: Some(stream.name.to_string()),
+                    ack_policy: consumer::AckPolicy::Explicit,
+                    ..Default::default()
+                },
+                stream.name,
+            )
+            .await
+            .unwrap();
+
+        let buf_reader_config = BufferReaderConfig {
+            streams: vec![],
+            wip_ack_interval: Duration::from_millis(5),
+        };
+        let tracker = TrackerHandle::new(None, None);
+        let js_reader = JetStreamReader::new(
+            "test".to_string(),
+            stream.clone(),
+            context.clone(),
+            buf_reader_config,
+            tracker.clone(),
+            500,
+            None,
+        )
+        .await
+        .unwrap();
+
+        let reader_cancel_token = CancellationToken::new();
+
+        let pbq = PBQBuilder::new(js_reader, tracker.clone()).build();
+
+        let (mut pbq_stream, handle) = pbq
+            .streaming_read(reader_cancel_token.clone())
+            .await
+            .unwrap();
+
+        let mut offsets = vec![];
+        for i in 0..10 {
+            let offset = Offset::Int(IntOffset::new(i + 1, 0));
+            offsets.push(offset.clone());
+            let message = Message {
+                typ: Default::default(),
+                keys: Arc::from(vec![format!("key_{}", i)]),
+                tags: None,
+                value: format!("pbq message {}", i).as_bytes().to_vec().into(),
+                offset,
+                event_time: Utc::now(),
+                watermark: None,
+                id: MessageID {
+                    vertex_name: "vertex".to_string().into(),
+                    offset: format!("offset_{}", i).into(),
+                    index: i as i32,
+                },
+                headers: HashMap::new(),
+                metadata: None,
+            };
+            let message_bytes: BytesMut = message.try_into().unwrap();
+            context
+                .publish(stream.name, message_bytes.into())
+                .await
+                .unwrap();
+        }
+
+        let mut buffer = vec![];
+        for _ in 0..10 {
+            let Some(val) = pbq_stream.next().await else {
+                break;
+            };
+            buffer.push(val);
+        }
+
+        assert_eq!(
+            buffer.len(),
+            10,
+            "Expected 10 messages from the jetstream reader"
+        );
+
+        for offset in offsets {
+            tracker.discard(offset).await.unwrap();
+        }
+        reader_cancel_token.cancel();
+        context.delete_stream(stream.name).await.unwrap();
+        handle.await.unwrap().unwrap();
+    }
+
+    #[cfg(feature = "nats-tests")]
+    #[tokio::test]
+    async fn test_pbq_read_with_wal() {
+        let js_url = "localhost:4222";
+        // Create JetStream context
+        let client = async_nats::connect(js_url).await.unwrap();
+        let context = jetstream::new(client);
+
+        // Create temp directory for WAL
+        let temp_dir = tempfile::tempdir().unwrap();
+        let wal_path = temp_dir.path().to_path_buf();
+
+        let stream = Stream::new("test_pbq_read_with_wal", "test", 0);
+        // Delete stream if it exists
+        let _ = context.delete_stream(stream.name).await;
+        context
+            .get_or_create_stream(stream::Config {
+                name: stream.name.to_string(),
+                subjects: vec![stream.name.to_string()],
+                max_message_size: 1024,
+                ..Default::default()
+            })
+            .await
+            .unwrap();
+
+        let _consumer = context
+            .create_consumer_on_stream(
+                consumer::Config {
+                    name: Some(stream.name.to_string()),
+                    ack_policy: consumer::AckPolicy::Explicit,
+                    ..Default::default()
+                },
+                stream.name,
+            )
+            .await
+            .unwrap();
+
+        let buf_reader_config = BufferReaderConfig {
+            streams: vec![],
+            wip_ack_interval: Duration::from_millis(5),
+        };
+        let tracker = TrackerHandle::new(None, None);
+        let js_reader = JetStreamReader::new(
+            "test".to_string(),
+            stream.clone(),
+            context.clone(),
+            buf_reader_config,
+            tracker.clone(),
+            500,
+            None,
+        )
+        .await
+        .unwrap();
+
+        // Create WAL components
+        let append_only_wal = AppendOnlyWal::new(
+            crate::reduce::wal::segment::WalType::Data,
+            wal_path.clone(),
+            10,  // 10MB max file size
+            100, // 100ms flush interval
+            100, // channel buffer
+        )
+        .await
+        .unwrap();
+
+        let compactor = Compactor::new(wal_path.clone(), WindowKind::Aligned, 10, 100, 100)
+            .await
+            .unwrap();
+
+        let wal = WAL {
+            append_only_wal,
+            compactor,
+        };
+
+        let reader_cancel_token = CancellationToken::new();
+
+        // Build PBQ with WAL
+        let pbq = PBQBuilder::new(js_reader, tracker.clone()).wal(wal).build();
+
+        let (mut pbq_stream, handle) = pbq
+            .streaming_read(reader_cancel_token.clone())
+            .await
+            .unwrap();
+
+        // Publish messages to the stream
+        let mut offsets = vec![];
+        for i in 0..10 {
+            let offset = Offset::Int(IntOffset::new(i + 1, 0));
+            offsets.push(offset.clone());
+            let message = Message {
+                typ: Default::default(),
+                keys: Arc::from(vec![format!("key_{}", i)]),
+                tags: None,
+                value: format!("pbq message {}", i).as_bytes().to_vec().into(),
+                offset,
+                event_time: Utc::now(),
+                watermark: None,
+                id: MessageID {
+                    vertex_name: "vertex".to_string().into(),
+                    offset: format!("offset_{}", i).into(),
+                    index: i as i32,
+                },
+                headers: HashMap::new(),
+                metadata: None,
+            };
+            let message_bytes: BytesMut = message.try_into().unwrap();
+            context
+                .publish(stream.name, message_bytes.into())
+                .await
+                .unwrap();
+        }
+
+        // Read messages from PBQ
+        let mut buffer = vec![];
+        for _ in 0..10 {
+            let Some(val) = pbq_stream.next().await else {
+                break;
+            };
+            buffer.push(val);
+        }
+
+        assert_eq!(buffer.len(), 10, "Expected 10 messages from the PBQ");
+
+        reader_cancel_token.cancel();
+        handle.await.unwrap().unwrap();
+
+        let append_only_wal = AppendOnlyWal::new(WalType::Data, wal_path.clone(), 10, 100, 100)
+            .await
+            .unwrap();
+
+        let (tx, rx) = mpsc::channel::<SegmentWriteMessage>(10);
+        let (_result_rx, writer_handle) = append_only_wal
+            .streaming_write(ReceiverStream::new(rx))
+            .await
+            .unwrap();
+
+        tx.send(SegmentWriteMessage::Rotate { on_size: false })
+            .await
+            .unwrap();
+        drop(tx);
+        writer_handle.await.unwrap().unwrap();
+
+        // Now use ReplayWal to verify the messages are persisted
+        let replay_wal = ReplayWal::new(WalType::Data, wal_path.clone());
+        let (mut replay_stream, replay_handle) = replay_wal.streaming_read().unwrap();
+
+        let mut persisted_messages = vec![];
+
+        while let Some(entry) = replay_stream.next().await {
+            if let SegmentEntry::DataEntry { data, .. } = entry {
+                let wal_message: WalMessage = data.try_into().unwrap();
+                let message: Message = wal_message.into();
+                persisted_messages.push(message);
+            }
+        }
+
+        replay_handle.await.unwrap().unwrap();
+
+        assert_eq!(
+            persisted_messages.len(),
+            10,
+            "Expected 10 messages to be persisted in WAL"
+        );
+
+        // Verify the persisted messages match what we sent
+        for (i, msg) in persisted_messages.iter().enumerate() {
+            assert_eq!(
+                msg.keys.as_ref(),
+                &[format!("key_{}", i)],
+                "Persisted message keys don't match"
+            );
+            assert_eq!(
+                msg.value.as_ref(),
+                format!("pbq message {}", i).as_bytes(),
+                "Persisted message value doesn't match"
+            );
+        }
+
+        for offset in offsets {
+            tracker.discard(offset).await.unwrap();
+        }
+        context.delete_stream(stream.name).await.unwrap();
+    }
+
+    #[cfg(feature = "nats-tests")]
+    #[tokio::test]
+    async fn test_pbq_replay_from_wal_then_read_from_isb() {
+        let js_url = "localhost:4222";
+        // Create JetStream context
+        let client = async_nats::connect(js_url).await.unwrap();
+        let context = jetstream::new(client);
+
+        // Create temp directory for WAL
+        let temp_dir = tempfile::tempdir().unwrap();
+        let wal_path = temp_dir.path().to_path_buf();
+
+        let stream = Stream::new("test_pbq_replay_wal", "test", 0);
+        // Delete stream if it exists
+        let _ = context.delete_stream(stream.name).await;
+        context
+            .get_or_create_stream(stream::Config {
+                name: stream.name.to_string(),
+                subjects: vec![stream.name.to_string()],
+                max_message_size: 1024,
+                ..Default::default()
+            })
+            .await
+            .unwrap();
+
+        let _consumer = context
+            .create_consumer_on_stream(
+                consumer::Config {
+                    name: Some(stream.name.to_string()),
+                    ack_policy: consumer::AckPolicy::Explicit,
+                    ..Default::default()
+                },
+                stream.name,
+            )
+            .await
+            .unwrap();
+
+        // First, write some messages directly to WAL
+        let append_only_wal = AppendOnlyWal::new(WalType::Data, wal_path.clone(), 10, 100, 100)
+            .await
+            .unwrap();
+
+        let (tx, rx) = mpsc::channel::<SegmentWriteMessage>(100);
+        let (_result_rx, writer_handle) = append_only_wal
+            .streaming_write(ReceiverStream::new(rx))
+            .await
+            .unwrap();
+
+        // Write 5 messages to WAL directly
+        for i in 0..5 {
+            let message = Message {
+                typ: Default::default(),
+                keys: Arc::from(vec![format!("wal_key_{}", i)]),
+                tags: None,
+                value: format!("wal message {}", i).as_bytes().to_vec().into(),
+                offset: Offset::Int(IntOffset::new(i + 1, 0)),
+                event_time: Utc::now(),
+                watermark: None,
+                id: MessageID {
+                    vertex_name: "vertex".to_string().into(),
+                    offset: format!("wal_offset_{}", i).into(),
+                    index: i as i32,
+                },
+                headers: HashMap::new(),
+                metadata: None,
+            };
+
+            let wal_message = WalMessage {
+                message: message.clone(),
+            };
+            let bytes: bytes::Bytes = wal_message.try_into().unwrap();
+
+            tx.send(SegmentWriteMessage::WriteData {
+                offset: Some(message.offset.clone()),
+                data: bytes,
+            })
+            .await
+            .unwrap();
+        }
+
+        drop(tx);
+        writer_handle.await.unwrap().unwrap();
+
+        // Now create PBQ components
+        let buf_reader_config = BufferReaderConfig {
+            streams: vec![],
+            wip_ack_interval: Duration::from_millis(5),
+        };
+        let tracker = TrackerHandle::new(None, None);
+        let js_reader = JetStreamReader::new(
+            "test".to_string(),
+            stream.clone(),
+            context.clone(),
+            buf_reader_config,
+            tracker.clone(),
+            500,
+            None,
+        )
+        .await
+        .unwrap();
+
+        // Create new WAL components for PBQ
+        let append_only_wal = AppendOnlyWal::new(WalType::Data, wal_path.clone(), 10, 100, 100)
+            .await
+            .unwrap();
+
+        let compactor = Compactor::new(wal_path.clone(), WindowKind::Aligned, 10, 100, 100)
+            .await
+            .unwrap();
+
+        let wal = WAL {
+            append_only_wal,
+            compactor,
+        };
+
+        let reader_cancel_token = CancellationToken::new();
+
+        // Build PBQ with WAL
+        let pbq = PBQBuilder::new(js_reader, tracker.clone()).wal(wal).build();
+
+        // Start reading from PBQ - this should first replay from WAL, then read from ISB
+        let (mut pbq_stream, handle) = pbq
+            .streaming_read(reader_cancel_token.clone())
+            .await
+            .unwrap();
+
+        // Read the first 5 messages which should come from WAL
+        let mut replayed_messages = vec![];
+        for _ in 0..5 {
+            let Some(val) = pbq_stream.next().await else {
+                break;
+            };
+            replayed_messages.push(val);
+        }
+
+        assert_eq!(
+            replayed_messages.len(),
+            5,
+            "Expected 5 messages to be replayed from WAL"
+        );
+
+        // Verify the replayed messages match what we wrote to WAL
+        for (i, msg) in replayed_messages.iter().enumerate() {
+            assert_eq!(
+                msg.keys.as_ref(),
+                &[format!("wal_key_{}", i)],
+                "Replayed message keys don't match"
+            );
+            assert_eq!(
+                msg.value.as_ref(),
+                format!("wal message {}", i).as_bytes(),
+                "Replayed message value doesn't match"
+            );
+        }
+
+        // Now publish 5 more messages to ISB
+        let mut isb_offsets = vec![];
+        for i in 0..5 {
+            let offset = Offset::Int(IntOffset::new(i + 100, 0)); // Different offset range
+            isb_offsets.push(offset.clone());
+            let message = Message {
+                typ: Default::default(),
+                keys: Arc::from(vec![format!("isb_key_{}", i)]),
+                tags: None,
+                value: format!("isb message {}", i).as_bytes().to_vec().into(),
+                offset,
+                event_time: Utc::now(),
+                watermark: None,
+                id: MessageID {
+                    vertex_name: "vertex".to_string().into(),
+                    offset: format!("isb_offset_{}", i).into(),
+                    index: i as i32,
+                },
+                headers: HashMap::new(),
+                metadata: None,
+            };
+            let message_bytes: BytesMut = message.try_into().unwrap();
+            context
+                .publish(stream.name, message_bytes.into())
+                .await
+                .unwrap();
+        }
+
+        // Read the next 5 messages which should come from ISB
+        let mut isb_messages = vec![];
+        for _ in 0..5 {
+            let Some(val) = pbq_stream.next().await else {
+                break;
+            };
+            isb_messages.push(val);
+        }
+
+        assert_eq!(
+            isb_messages.len(),
+            5,
+            "Expected 5 messages to be read from ISB"
+        );
+
+        // Verify the ISB messages
+        for (i, msg) in isb_messages.iter().enumerate() {
+            assert_eq!(
+                msg.keys.as_ref(),
+                &[format!("isb_key_{}", i)],
+                "ISB message keys don't match"
+            );
+            assert_eq!(
+                msg.value.as_ref(),
+                format!("isb message {}", i).as_bytes(),
+                "ISB message value doesn't match"
+            );
+        }
+
+        // Verify that the ISB messages were also written to WAL
+        reader_cancel_token.cancel();
+        handle.await.unwrap().unwrap();
+
+        // Check WAL again - should now have all 10 messages
+        let data_replay_wal = ReplayWal::new(WalType::Data, wal_path.clone());
+        let (mut replay_stream, replay_handle) = data_replay_wal.streaming_read().unwrap();
+
+        let mut all_wal_messages: Vec<Message> = vec![];
+        while let Some(entry) = replay_stream.next().await {
+            if let SegmentEntry::DataEntry { data, .. } = entry {
+                let wal_message: WalMessage = data.try_into().unwrap();
+                all_wal_messages.push(wal_message.into());
+            }
+        }
+        replay_handle.await.unwrap().unwrap();
+
+        let compact_wal = ReplayWal::new(WalType::Compact, wal_path.clone());
+        let (mut replay_stream, replay_handle) = compact_wal.streaming_read().unwrap();
+        while let Some(entry) = replay_stream.next().await {
+            if let SegmentEntry::DataEntry { data, .. } = entry {
+                let wal_message: WalMessage = data.try_into().unwrap();
+                all_wal_messages.push(wal_message.into());
+            }
+        }
+        replay_handle.await.unwrap().unwrap();
+
+        assert_eq!(
+            all_wal_messages.len(),
+            10,
+            "Expected 10 total messages in WAL (5 original + 5 from ISB)"
+        );
+
+        // Clean up
+        for offset in isb_offsets {
+            tracker.discard(offset).await.unwrap();
+        }
+        context.delete_stream(stream.name).await.unwrap();
+    }
+}
diff --git a/rust/numaflow-core/src/reduce/wal.rs b/rust/numaflow-core/src/reduce/wal.rs
index 7dd6b4c3..b809b979 100644
--- a/rust/numaflow-core/src/reduce/wal.rs
+++ b/rust/numaflow-core/src/reduce/wal.rs
@@ -1,8 +1,112 @@
 //! Write Ahead Log for both Aligned and Unaligned Reduce Operation. The WAL is to persist the data
 //! we read from the ISB and store it until the processing is complete.
 
+use crate::message::{IntOffset, Message, Offset};
+use crate::reduce::error::Error;
+use crate::shared::grpc::{prost_timestamp_from_utc, utc_from_timestamp};
+use bytes::{Bytes, BytesMut};
+use std::sync::Arc;
+
 /// A WAL Segment.
 pub(crate) mod segment;
 
 /// All the errors WAL could face.
 pub(crate) mod error;
+
+#[derive(Debug, Clone)]
+pub(crate) struct WalMessage {
+    pub(crate) message: Message,
+}
+
+// Convert Message to Bytes used to persist in WAL
+impl TryFrom<WalMessage> for Bytes {
+    type Error = Error;
+
+    fn try_from(wal_message: WalMessage) -> Result<Self, Self::Error> {
+        let message = wal_message.message;
+
+        let Offset::Int(int_offset) = message.offset else {
+            return Err(Error::Other("Invalid offset".to_string()));
+        };
+
+        let proto_message = numaflow_pb::objects::isb::ReadMessage {
+            message: Some(numaflow_pb::objects::isb::Message {
+                header: Some(numaflow_pb::objects::isb::Header {
+                    message_info: Some(numaflow_pb::objects::isb::MessageInfo {
+                        event_time: Some(prost_timestamp_from_utc(message.event_time)),
+                        is_late: false,
+                    }),
+                    kind: message.typ.into(),
+                    id: Some(message.id.into()),
+                    keys: message.keys.to_vec(),
+                    headers: message.headers,
+                }),
+                body: Some(numaflow_pb::objects::isb::Body {
+                    payload: message.value.to_vec(),
+                }),
+            }),
+            read_offset: int_offset.offset,
+            watermark: message.watermark.map(prost_timestamp_from_utc),
+            metadata: None,
+        };
+
+        let mut buf = BytesMut::new();
+        prost::Message::encode(&proto_message, &mut buf)
+            .map_err(|e| Error::Other(e.to_string()))?;
+
+        Ok(buf.freeze())
+    }
+}
+
+// Convert Bytes to Message, used while reading from WAL
+impl TryFrom<Bytes> for WalMessage {
+    type Error = Error;
+
+    fn try_from(value: Bytes) -> Result<Self, Self::Error> {
+        let proto_read_message: numaflow_pb::objects::isb::ReadMessage =
+            prost::Message::decode(value.as_ref()).map_err(|e| Error::Other(e.to_string()))?;
+
+        let proto_message = proto_read_message
+            .message
+            .ok_or_else(|| Error::Other("Missing inner message".to_string()))?;
+
+        let header = proto_message
+            .header
+            .ok_or_else(|| Error::Other("Missing header".to_string()))?;
+        let body = proto_message
+            .body
+            .ok_or_else(|| Error::Other("Missing body".to_string()))?;
+
+        let msg = Message {
+            typ: header.kind.into(),
+            keys: Arc::from(header.keys),
+            tags: None,
+            value: Bytes::from(body.payload),
+            offset: Offset::Int(IntOffset::new(proto_read_message.read_offset, 0)),
+            event_time: header
+                .message_info
+                .expect("info can't be empty")
+                .event_time
+                .map(utc_from_timestamp)
+                .expect("event time should be present"),
+            watermark: proto_read_message.watermark.map(utc_from_timestamp),
+            id: header.id.map(Into::into).unwrap_or_default(),
+            headers: header.headers,
+            metadata: None,
+        };
+
+        Ok(WalMessage { message: msg })
+    }
+}
+
+impl From<WalMessage> for Message {
+    fn from(value: WalMessage) -> Self {
+        value.message
+    }
+}
+
+impl From<Message> for WalMessage {
+    fn from(value: Message) -> Self {
+        WalMessage { message: value }
+    }
+}
diff --git a/rust/numaflow-core/src/reduce/wal/error.rs b/rust/numaflow-core/src/reduce/wal/error.rs
index 2f9d6fe9..754fae3d 100644
--- a/rust/numaflow-core/src/reduce/wal/error.rs
+++ b/rust/numaflow-core/src/reduce/wal/error.rs
@@ -46,3 +46,9 @@ impl From<String> for Error {
         Error::Other(value)
     }
 }
+
+impl From<Error> for crate::error::Error {
+    fn from(value: Error) -> Self {
+        crate::error::Error::WAL(value.to_string())
+    }
+}
diff --git a/rust/numaflow-core/src/reduce/wal/segment.rs b/rust/numaflow-core/src/reduce/wal/segment.rs
index ca2f3d37..af3c0f5d 100644
--- a/rust/numaflow-core/src/reduce/wal/segment.rs
+++ b/rust/numaflow-core/src/reduce/wal/segment.rs
@@ -98,8 +98,14 @@ pub(crate) struct GcEventEntry {
 impl From<GcEvent> for GcEventEntry {
     fn from(value: GcEvent) -> Self {
         Self {
-            start_time: utc_from_timestamp(value.start_time),
-            end_time: utc_from_timestamp(value.end_time),
+            start_time: value
+                .start_time
+                .map(utc_from_timestamp)
+                .expect("start time should be present"),
+            end_time: value
+                .end_time
+                .map(utc_from_timestamp)
+                .expect("end time should be present"),
             keys: value.keys.into(),
         }
     }
@@ -118,7 +124,8 @@ impl From<GcEventEntry> for GcEvent {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::message::{Message, MessageID};
+    use crate::message::{Message, MessageID, Offset, StringOffset};
+    use crate::reduce::wal::WalMessage;
     use crate::reduce::wal::segment::WalType;
     use crate::reduce::wal::segment::append::{AppendOnlyWal, SegmentWriteMessage};
     use crate::reduce::wal::segment::compactor::{Compactor, WindowKind};
@@ -161,7 +168,7 @@ mod tests {
             .unwrap();
 
         tx.send(SegmentWriteMessage::WriteData {
-            id: Some("gc".to_string()),
+            offset: Some(Offset::String(StringOffset::new("gc".to_string(), 0))),
             data: bytes::Bytes::from(prost::Message::encode_to_vec(&gc_event)),
         })
         .await
@@ -201,10 +208,11 @@ mod tests {
                 offset: i.to_string().into(),
                 index: 0,
             };
+            let message: WalMessage = message.into();
 
             let proto_message: Bytes = message.try_into().unwrap();
             tx.send(SegmentWriteMessage::WriteData {
-                id: Some(format!("msg-{}", i)),
+                offset: Some(Offset::String(StringOffset::new(format!("msg-{}", i), 0))),
                 data: proto_message,
             })
             .await
@@ -225,7 +233,7 @@ mod tests {
         .await
         .unwrap();
 
-        compactor.compact().await.unwrap();
+        compactor.compact(None).await.unwrap();
 
         // Verify compacted data
         let compaction_wal = ReplayWal::new(WalType::Compact, test_path);
@@ -234,10 +242,11 @@ mod tests {
         let mut remaining_message_count = 0;
         while let Some(entry) = rx.next().await {
             if let SegmentEntry::DataEntry { data, .. } = entry {
-                let msg: numaflow_pb::objects::isb::Message = prost::Message::decode(data).unwrap();
-                if let Some(header) = msg.header {
+                let msg: numaflow_pb::objects::isb::ReadMessage =
+                    prost::Message::decode(data).unwrap();
+                if let Some(header) = msg.message.unwrap().header {
                     if let Some(message_info) = header.message_info {
-                        let event_time = utc_from_timestamp(message_info.event_time);
+                        let event_time = message_info.event_time.map(utc_from_timestamp).unwrap();
                         assert!(
                             event_time > gc_end,
                             "Found message with event_time <= gc_end"
@@ -297,14 +306,14 @@ mod tests {
 
         // Send both GC events
         tx.send(SegmentWriteMessage::WriteData {
-            id: Some("gc1".to_string()),
+            offset: Some(Offset::String(StringOffset::new("gc1".to_string(), 0))),
             data: bytes::Bytes::from(prost::Message::encode_to_vec(&gc_event1)),
         })
         .await
         .unwrap();
 
         tx.send(SegmentWriteMessage::WriteData {
-            id: Some("gc2".to_string()),
+            offset: Some(Offset::String(StringOffset::new("gc2".to_string(), 0))),
             data: bytes::Bytes::from(prost::Message::encode_to_vec(&gc_event2)),
         })
         .await
@@ -349,10 +358,11 @@ mod tests {
                 offset: i.to_string().into(),
                 index: 0,
             };
+            let message: WalMessage = message.into();
 
             let proto_message: Bytes = message.try_into().unwrap();
             tx.send(SegmentWriteMessage::WriteData {
-                id: Some(format!("msg-{}", i)),
+                offset: Some(Offset::String(StringOffset::new(format!("msg-{}", i), 0))),
                 data: proto_message,
             })
             .await
@@ -373,7 +383,7 @@ mod tests {
         .await
         .unwrap();
 
-        compactor.compact().await.unwrap();
+        compactor.compact(None).await.unwrap();
 
         // Verify compacted data
         let compaction_wal = ReplayWal::new(WalType::Compact, test_path);
@@ -385,13 +395,13 @@ mod tests {
 
         while let Some(entry) = rx.next().await {
             if let SegmentEntry::DataEntry { data, .. } = entry {
-                let msg: numaflow_pb::objects::isb::Message = prost::Message::decode(data).unwrap();
-                if let Some(header) = msg.header {
+                let msg: numaflow_pb::objects::isb::ReadMessage =
+                    prost::Message::decode(data).unwrap();
+                if let Some(header) = msg.message.unwrap().header {
                     // Check event time based on key
                     if let (Some(message_info), keys) = (header.message_info.as_ref(), header.keys)
                     {
-                        let event_time = utc_from_timestamp(message_info.event_time);
-
+                        let event_time = message_info.event_time.map(utc_from_timestamp).unwrap();
                         if keys.contains(&"key1".to_string()) {
                             key1_count += 1;
                             assert!(
diff --git a/rust/numaflow-core/src/reduce/wal/segment/append.rs b/rust/numaflow-core/src/reduce/wal/segment/append.rs
index 09a28713..28931987 100644
--- a/rust/numaflow-core/src/reduce/wal/segment/append.rs
+++ b/rust/numaflow-core/src/reduce/wal/segment/append.rs
@@ -1,3 +1,4 @@
+use crate::message::Offset;
 use crate::reduce::wal::error::WalResult;
 use crate::reduce::wal::segment::WalType;
 use bytes::Bytes;
@@ -23,8 +24,8 @@ const ROTATE_IF_STALE_DURATION: chrono::Duration = chrono::Duration::seconds(30)
 pub(crate) enum SegmentWriteMessage {
     /// Writes the given payload to the WAL.
     WriteData {
-        /// Unique ID of the payload. Useful to detect write failures.
-        id: Option<String>,
+        /// Unique offset of the payload. Useful to detect write failures.
+        offset: Option<Offset>,
         /// Data to be written on do the WAL.
         data: Bytes,
     },
@@ -56,7 +57,7 @@ struct SegmentWriteActor {
     /// Maximum file size per segment.
     max_file_size: u64,
     /// The result of [SegmentWriteMessage] operation.
-    result_tx: Sender<String>,
+    result_tx: Sender<Offset>,
 }
 
 impl Drop for SegmentWriteActor {
@@ -66,6 +67,7 @@ impl Drop for SegmentWriteActor {
 }
 
 impl SegmentWriteActor {
+    #[allow(clippy::too_many_arguments)]
     /// Creates a new SegmentWriteActor.
     fn new(
         wal_type: WalType,
@@ -75,7 +77,7 @@ impl SegmentWriteActor {
         current_file: BufWriter<File>,
         max_file_size: u64,
         flush_interval: Duration,
-        result_tx: Sender<String>,
+        result_tx: Sender<Offset>,
     ) -> Self {
         Self {
             wal_type,
@@ -131,7 +133,7 @@ impl SegmentWriteActor {
     /// we should exit upon errors.
     async fn handle_message(&mut self, msg: SegmentWriteMessage) -> WalResult<()> {
         match msg {
-            SegmentWriteMessage::WriteData { id, data } => {
+            SegmentWriteMessage::WriteData { offset: id, data } => {
                 self.write_data(data).await?;
                 // we need to respond only if ID is provided
                 if let Some(id) = id {
@@ -303,11 +305,11 @@ impl AppendOnlyWal {
     pub(crate) async fn streaming_write(
         self,
         stream: ReceiverStream<SegmentWriteMessage>,
-    ) -> WalResult<(ReceiverStream<String>, JoinHandle<WalResult<()>>)> {
+    ) -> WalResult<(ReceiverStream<Offset>, JoinHandle<WalResult<()>>)> {
         let (file_name, file_buf) =
             SegmentWriteActor::open_segment(&self.wal_type, &self.base_path, 0).await?;
 
-        let (result_tx, result_rx) = mpsc::channel::<String>(self.channel_buffer_size);
+        let (result_tx, result_rx) = mpsc::channel::<Offset>(self.channel_buffer_size);
 
         let max_file_size_bytes = self.max_file_size_mb * 1024 * 1024;
         let flush_duration = Duration::from_millis(self.flush_interval_ms);
@@ -340,10 +342,12 @@ impl AppendOnlyWal {
 #[cfg(test)]
 mod tests {
     use super::*;
+    use crate::message::{Offset, StringOffset};
     use crate::reduce::wal::segment::WalType;
     use bytes::{Bytes, BytesMut};
     use futures::stream::StreamExt;
     use std::fs;
+    use std::mem::size_of;
     use tempfile::tempdir;
 
     #[tokio::test]
@@ -373,23 +377,23 @@ mod tests {
         let mut expected_ids = Vec::new();
         let mut received_results = Vec::new();
 
-        let id1 = "msg-001".to_string();
+        let id1 = Offset::String(StringOffset::new("msg-001".to_string(), 0));
         let data1 = Bytes::from("some initial data");
         expected_ids.push(id1.clone());
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: Some(id1),
+                offset: Some(id1),
                 data: data1.clone(),
             })
             .await
             .unwrap();
 
-        let id2 = "msg-002".to_string();
+        let id2 = Offset::String(StringOffset::new("msg-002".to_string(), 0));
         let data2 = Bytes::from(" more data here");
         expected_ids.push(id2.clone());
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: Some(id2),
+                offset: Some(id2),
                 data: data2.clone(),
             })
             .await
@@ -397,44 +401,44 @@ mod tests {
 
         let large_data_size = (0.6 * 1024.0 * 1024.0) as usize;
         let large_data1 = Bytes::from(vec![b'A'; large_data_size]);
-        let id3 = "msg-large-1".to_string();
+        let id3 = Offset::String(StringOffset::new("msg-large-1".to_string(), 0));
         expected_ids.push(id3.clone());
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: Some(id3),
+                offset: Some(id3),
                 data: large_data1.clone(),
             })
             .await
             .unwrap();
 
         let large_data2 = Bytes::from(vec![b'B'; large_data_size]);
-        let id4 = "msg-large-2".to_string();
+        let id4 = Offset::String(StringOffset::new("msg-large-2".to_string(), 0));
         expected_ids.push(id4.clone());
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: Some(id4),
+                offset: Some(id4),
                 data: large_data2.clone(),
             })
             .await
             .unwrap();
 
-        let id5 = "msg-005-rotated".to_string();
+        let id5 = Offset::String(StringOffset::new("msg-005-rotated".to_string(), 0));
         let data5 = Bytes::from("data after rotation");
         expected_ids.push(id5.clone());
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: Some(id5),
+                offset: Some(id5),
                 data: data5.clone(),
             })
             .await
             .unwrap();
 
-        let id6 = "msg-006-rotated".to_string();
+        let id6 = Offset::String(StringOffset::new("msg-006-rotated".to_string(), 0));
         let data6 = Bytes::from(" more data after rotation");
         expected_ids.push(id6.clone());
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: Some(id6),
+                offset: Some(id6),
                 data: data6.clone(),
             })
             .await
@@ -457,13 +461,21 @@ mod tests {
             received_ids.push(result);
         }
 
-        received_ids.sort();
-        expected_ids.sort();
+        // We can't sort Offset values directly, so we'll just check that we received the same number of IDs
         assert_eq!(
-            received_ids, expected_ids,
-            "Mismatch between expected and received successful IDs"
+            received_ids.len(),
+            expected_ids.len(),
+            "Mismatch between expected and received successful IDs count"
         );
 
+        // Check that each expected ID is in the received IDs
+        for expected_id in expected_ids {
+            assert!(
+                received_ids.contains(&expected_id),
+                "Missing expected ID in received IDs"
+            );
+        }
+
         let mut files: Vec<_> = fs::read_dir(&base_path)
             .unwrap()
             .map(|entry| entry.unwrap().path())
@@ -529,11 +541,14 @@ mod tests {
             .await
             .expect("Failed to start WAL service");
 
-        let id1 = Some("flush-test-1".to_string());
+        let id1 = Some(Offset::String(StringOffset::new(
+            "flush-test-1".to_string(),
+            0,
+        )));
         let data1 = Bytes::from("Data to be flushed");
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: id1.clone(),
+                offset: id1.clone(),
                 data: data1.clone(),
             })
             .await
@@ -599,11 +614,11 @@ mod tests {
             .expect("Failed to start WAL service");
 
         // Send some data to the WAL
-        let id1 = Some("msg-001".to_string());
+        let id1 = Some(Offset::String(StringOffset::new("msg-001".to_string(), 0)));
         let data1 = Bytes::from("data before rotation");
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: id1.clone(),
+                offset: id1.clone(),
                 data: data1.clone(),
             })
             .await
@@ -616,11 +631,11 @@ mod tests {
             .unwrap();
 
         // Send more data after rotation
-        let id2 = Some("msg-002".to_string());
+        let id2 = Some(Offset::String(StringOffset::new("msg-002".to_string(), 0)));
         let data2 = Bytes::from("data after rotation");
         wal_tx
             .send(SegmentWriteMessage::WriteData {
-                id: id2.clone(),
+                offset: id2.clone(),
                 data: data2.clone(),
             })
             .await
diff --git a/rust/numaflow-core/src/reduce/wal/segment/compactor.rs b/rust/numaflow-core/src/reduce/wal/segment/compactor.rs
index e5d662cc..185fa2fe 100644
--- a/rust/numaflow-core/src/reduce/wal/segment/compactor.rs
+++ b/rust/numaflow-core/src/reduce/wal/segment/compactor.rs
@@ -20,6 +20,7 @@ use crate::reduce::wal::segment::WalType;
 use crate::reduce::wal::segment::append::{AppendOnlyWal, SegmentWriteMessage};
 use crate::reduce::wal::segment::replay::{ReplayWal, SegmentEntry};
 use crate::shared::grpc::utc_from_timestamp;
+use bytes::Bytes;
 use chrono::{DateTime, Utc};
 use numaflow_pb::objects::isb;
 use numaflow_pb::objects::wal::GcEvent;
@@ -55,7 +56,7 @@ pub(crate) struct Compactor {
     kind: WindowKind,
 }
 
-const WAL_KEY_SEPERATOR: &'static str = ":";
+const WAL_KEY_SEPERATOR: &str = ":";
 
 impl Compactor {
     /// Creates a new Compactor.
@@ -87,6 +88,14 @@ impl Compactor {
         })
     }
 
+    /// Compact and replay the compacted data.
+    pub(crate) async fn compact_with_replay(
+        self,
+        tx: mpsc::Sender<Bytes>,
+    ) -> WalResult<JoinHandle<WalResult<()>>> {
+        Ok(tokio::spawn(async move { self.compact(Some(tx)).await }))
+    }
+
     /// Starts the compaction process every `interval_ms` milliseconds.
     pub(crate) async fn start_compaction(
         self,
@@ -98,7 +107,7 @@ impl Compactor {
             loop {
                 tokio::select! {
                 _ = tick.tick() => {
-                        self.compact().await?;
+                        self.compact(None).await?;
                      }
                 _ = cln_token.cancelled() => {
                         break;
@@ -112,10 +121,10 @@ impl Compactor {
 
     /// Compact first needs to get all the GC files and build a compaction map. This map will have
     /// the oldest data before which all can be deleted.
-    pub(crate) async fn compact(&self) -> WalResult<()> {
+    pub(crate) async fn compact(&self, replay_tx: Option<mpsc::Sender<Bytes>>) -> WalResult<()> {
         match self.kind {
-            WindowKind::Aligned => self.compact_aligned().await?,
-            WindowKind::Unaligned => self.compact_unaligned().await?,
+            WindowKind::Aligned => self.compact_aligned(replay_tx.clone()).await?,
+            WindowKind::Unaligned => self.compact_unaligned(replay_tx).await?,
         }
         Ok(())
     }
@@ -130,18 +139,19 @@ impl Compactor {
     /// - If event_time is <= oldest_time, skip it, otherwise write it into the Compaction Append WAL.
     /// - Send the Rotate message to the Compaction Append WAL after each Segment file has been processed.
     /// - Delete the Segment File after the Rotate is complete.
-    async fn compact_aligned(&self) -> WalResult<()> {
+    async fn compact_aligned(&self, replay_tx: Option<mpsc::Sender<Bytes>>) -> WalResult<()> {
         // Get the oldest time and scanned GC files
         let (oldest_time, gc_files) = self.build_aligned_compaction().await?;
 
         let compact = AlignedCompaction(oldest_time);
 
         // Compact the compaction_ro_wal
-        self.process_wal_stream(&self.compaction_ro_wal, &compact)
+        self.process_wal_stream(&self.compaction_ro_wal, &compact, replay_tx.clone())
             .await?;
 
         // Compact the segment_wal
-        self.process_wal_stream(&self.segment_wal, &compact).await?;
+        self.process_wal_stream(&self.segment_wal, &compact, replay_tx)
+            .await?;
 
         // Delete the GC files
         for gc_file in gc_files {
@@ -163,18 +173,19 @@ impl Compactor {
     /// - If event_time is <= oldest_time, skip it, otherwise write it into the Compaction Append WAL.
     /// - Send the Rotate message to the Compaction Append WAL after each Segment file has been processed.
     /// - Delete the Segment File after the Rotate is complete.
-    async fn compact_unaligned(&self) -> WalResult<()> {
+    async fn compact_unaligned(&self, replay_tx: Option<mpsc::Sender<Bytes>>) -> WalResult<()> {
         // Get the oldest time map and scanned GC files
         let (oldest_time_map, gc_files) = self.build_unaligned_compaction().await?;
 
         let compact = UnalignedCompaction(oldest_time_map);
 
         // Compact the compaction_ro_wal
-        self.process_wal_stream(&self.compaction_ro_wal, &compact)
+        self.process_wal_stream(&self.compaction_ro_wal, &compact, replay_tx.clone())
             .await?;
 
         // Compact the segment_wal
-        self.process_wal_stream(&self.segment_wal, &compact).await?;
+        self.process_wal_stream(&self.segment_wal, &compact, replay_tx)
+            .await?;
 
         // Delete the GC files
         for gc_file in gc_files {
@@ -192,6 +203,7 @@ impl Compactor {
         &self,
         wal: &ReplayWal,
         should_retain: &T,
+        replay_tx: Option<mpsc::Sender<Bytes>>,
     ) -> WalResult<()> {
         // Get a streaming reader for the WAL
         let (mut rx, handle) = wal.clone().streaming_read()?;
@@ -209,17 +221,30 @@ impl Compactor {
             match entry {
                 SegmentEntry::DataEntry { data, .. } => {
                     // Deserialize the message
-                    let msg: isb::Message = prost::Message::decode(data.clone())
+                    let msg: isb::ReadMessage = prost::Message::decode(data.clone())
                         .map_err(|e| format!("Failed to decode message: {}", e))?;
 
-                    if should_retain.should_retain_message(&msg)? {
+                    if should_retain
+                        .should_retain_message(&msg.message.expect("Message should be present"))?
+                    {
                         // Send the message to the compaction WAL
                         wal_tx
-                            .send(SegmentWriteMessage::WriteData { id: None, data })
+                            .send(SegmentWriteMessage::WriteData {
+                                offset: None,
+                                data: data.clone(),
+                            })
                             .await
                             .map_err(|e| {
                                 format!("Failed to send message to compaction WAL: {}", e)
                             })?;
+
+                        // if replay_tx is provided, send the message to it.
+                        // This is used to replay the compacted data during boot up
+                        if let Some(tx) = &replay_tx {
+                            tx.send(data).await.map_err(|e| {
+                                format!("Failed to send message to replay channel: {}", e)
+                            })?;
+                        }
                     }
                 }
                 SegmentEntry::DataFooter { .. } => {
@@ -380,7 +405,11 @@ impl ShouldRetain for AlignedCompaction {
             .header
             .as_ref()
             .and_then(|header| header.message_info.as_ref())
-            .map(|info| utc_from_timestamp(info.event_time))
+            .map(|info| {
+                info.event_time
+                    .map(utc_from_timestamp)
+                    .expect("event time should be present")
+            })
             .expect("Failed to extract event time from message");
 
         // Retain the message if its event time is greater than the oldest time
@@ -396,7 +425,11 @@ impl ShouldRetain for UnalignedCompaction {
             .header
             .as_ref()
             .and_then(|header| header.message_info.as_ref())
-            .map(|info| utc_from_timestamp(info.event_time))
+            .map(|info| {
+                info.event_time
+                    .map(utc_from_timestamp)
+                    .expect("event time should be present")
+            })
             .expect("Failed to extract event time from message");
 
         // Extract the keys from the message
@@ -423,7 +456,8 @@ impl ShouldRetain for UnalignedCompaction {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::message::{Message, MessageID};
+    use crate::message::{Message, MessageID, Offset, StringOffset};
+    use crate::reduce::wal::WalMessage;
     use crate::shared::grpc::prost_timestamp_from_utc;
     use bytes::Bytes;
     use chrono::TimeZone;
@@ -458,6 +492,10 @@ mod tests {
         // Create some test GC events with different timestamps
         let gc_events = vec![
             GcEvent {
+                start_time: Some(prost_types::Timestamp {
+                    seconds: 0,
+                    nanos: 0,
+                }),
                 end_time: Some(prost_types::Timestamp {
                     seconds: 1000,
                     nanos: 0,
@@ -465,6 +503,10 @@ mod tests {
                 ..Default::default()
             },
             GcEvent {
+                start_time: Some(prost_types::Timestamp {
+                    seconds: 0,
+                    nanos: 0,
+                }),
                 end_time: Some(prost_types::Timestamp {
                     seconds: 2000,
                     nanos: 0,
@@ -494,7 +536,7 @@ mod tests {
             prost::Message::encode(&event, &mut buf)
                 .map_err(|e| format!("Failed to encode GC event: {e}"))?;
             tx.send(SegmentWriteMessage::WriteData {
-                id: None,
+                offset: None,
                 data: Bytes::from(buf),
             })
             .await
@@ -543,6 +585,10 @@ mod tests {
         // Create some test GC events with different timestamps and keys
         let gc_events = vec![
             GcEvent {
+                start_time: Some(prost_types::Timestamp {
+                    seconds: 0,
+                    nanos: 0,
+                }),
                 end_time: Some(prost_types::Timestamp {
                     seconds: 1000,
                     nanos: 0,
@@ -551,6 +597,10 @@ mod tests {
                 ..Default::default()
             },
             GcEvent {
+                start_time: Some(prost_types::Timestamp {
+                    seconds: 0,
+                    nanos: 0,
+                }),
                 end_time: Some(prost_types::Timestamp {
                     seconds: 2000,
                     nanos: 0,
@@ -559,6 +609,10 @@ mod tests {
                 ..Default::default()
             },
             GcEvent {
+                start_time: Some(prost_types::Timestamp {
+                    seconds: 0,
+                    nanos: 0,
+                }),
                 end_time: Some(prost_types::Timestamp {
                     seconds: 1500,
                     nanos: 0,
@@ -589,7 +643,7 @@ mod tests {
             prost::Message::encode(&event, &mut buf)
                 .map_err(|e| format!("Failed to encode GC event: {e}"))?;
             tx.send(SegmentWriteMessage::WriteData {
-                id: None,
+                offset: None,
                 data: Bytes::from(buf),
             })
             .await
@@ -627,10 +681,9 @@ mod tests {
         Ok(())
     }
 
-    // FIXME
     #[tokio::test]
     async fn test_gc_wal_and_compaction_with_multiple_files() {
-        let test_path = tempfile::tempdir().unwrap().into_path();
+        let test_path = tempdir().unwrap().into_path();
 
         // Create GC WAL
         let gc_wal = AppendOnlyWal::new(
@@ -667,14 +720,14 @@ mod tests {
             .unwrap();
 
         tx.send(SegmentWriteMessage::WriteData {
-            id: Some("gc1".to_string()),
+            offset: Some(Offset::String(StringOffset::new("gc1".to_string(), 0))),
             data: bytes::Bytes::from(prost::Message::encode_to_vec(&gc_event_1)),
         })
         .await
         .unwrap();
 
         tx.send(SegmentWriteMessage::WriteData {
-            id: Some("gc2".to_string()),
+            offset: Some(Offset::String(StringOffset::new("gc2".to_string(), 0))),
             data: bytes::Bytes::from(prost::Message::encode_to_vec(&gc_event_2)),
         })
         .await
@@ -703,7 +756,7 @@ mod tests {
 
         let write_result_cnt = tokio::spawn(async move {
             let mut counter = 0;
-            while let Some(msg) = offset_stream.next().await {
+            while let Some(_) = offset_stream.next().await {
                 counter += 1;
             }
             return counter;
@@ -723,9 +776,11 @@ mod tests {
                 index: 0,
             };
 
+            let message: WalMessage = message.into();
+
             let proto_message: Bytes = message.try_into().unwrap();
             tx.send(SegmentWriteMessage::WriteData {
-                id: Some(format!("msg-{}", i)),
+                offset: Some(Offset::String(StringOffset::new(format!("msg-{}", i), 0))),
                 data: proto_message,
             })
             .await
@@ -754,7 +809,7 @@ mod tests {
         .await
         .unwrap();
 
-        compactor.compact().await.unwrap();
+        compactor.compact(None).await.unwrap();
 
         // Verify compacted data
         let compaction_wal = ReplayWal::new(WalType::Compact, test_path);
@@ -763,10 +818,14 @@ mod tests {
         let mut remaining_message_count = 0;
         while let Some(entry) = rx.next().await {
             if let SegmentEntry::DataEntry { data, .. } = entry {
-                let msg: numaflow_pb::objects::isb::Message = prost::Message::decode(data).unwrap();
-                if let Some(header) = msg.header {
+                let msg: numaflow_pb::objects::isb::ReadMessage =
+                    prost::Message::decode(data).unwrap();
+                if let Some(header) = msg.message.unwrap().header {
                     if let Some(message_info) = header.message_info {
-                        let event_time = utc_from_timestamp(message_info.event_time);
+                        let event_time = message_info
+                            .event_time
+                            .map(utc_from_timestamp)
+                            .expect("event time should not be empty");
                         assert!(
                             event_time > gc_end_2,
                             "Found message with event_time <= gc_end_2"
@@ -785,4 +844,412 @@ mod tests {
             "Expected 980 messages to remain after compaction"
         );
     }
+
+    #[tokio::test]
+    async fn test_compact_with_replay_aligned() -> WalResult<()> {
+        // Create a temporary directory for the test
+        let temp_dir = tempdir().unwrap();
+        let path = temp_dir.path().to_path_buf();
+
+        // Create WAL directories
+        fs::create_dir_all(path.join(WalType::Gc.to_string())).unwrap();
+        fs::create_dir_all(path.join(WalType::Data.to_string())).unwrap();
+        fs::create_dir_all(path.join(WalType::Compact.to_string())).unwrap();
+
+        // Create GC WAL with test events
+        let gc_wal = AppendOnlyWal::new(
+            WalType::Gc,
+            path.clone(),
+            100,  // max_file_size_mb
+            1000, // flush_interval_ms
+            100,  // channel_buffer_size
+        )
+        .await?;
+
+        // Create a GC event with a specific end time
+        let gc_start = Utc.with_ymd_and_hms(2025, 4, 1, 1, 0, 0).unwrap();
+        let gc_end = Utc.with_ymd_and_hms(2025, 4, 1, 1, 0, 10).unwrap();
+        let gc_event = GcEvent {
+            start_time: Some(prost_timestamp_from_utc(gc_start)),
+            end_time: Some(prost_timestamp_from_utc(gc_end)),
+            ..Default::default()
+        };
+
+        // Write the GC event to the WAL
+        let (tx, rx) = mpsc::channel(100);
+        let (mut gc_wal_write_rx, writer_handle) =
+            gc_wal.streaming_write(ReceiverStream::new(rx)).await?;
+
+        let write_result_cnt = tokio::spawn(async move {
+            let mut counter = 0;
+            while let Some(_) = gc_wal_write_rx.next().await {
+                counter += 1;
+            }
+            return counter;
+        });
+
+        let mut buf = Vec::new();
+        prost::Message::encode(&gc_event, &mut buf)
+            .map_err(|e| format!("Failed to encode GC event: {e}"))?;
+        tx.send(SegmentWriteMessage::WriteData {
+            offset: None,
+            data: Bytes::from(buf),
+        })
+        .await
+        .map_err(|e| format!("Failed to send data: {e}"))?;
+
+        // Drop the sender to close the channel
+        drop(tx);
+        writer_handle
+            .await
+            .map_err(|e| format!("Writer failed: {e}"))??;
+
+        // Create segment WAL with test messages
+        let segment_wal = AppendOnlyWal::new(
+            WalType::Data,
+            path.clone(),
+            100,  // max_file_size_mb
+            1000, // flush_interval_ms
+            100,  // channel_buffer_size
+        )
+        .await?;
+
+        // Create messages with different event times
+        let (tx, rx) = mpsc::channel(100);
+        let (_result_rx, writer_handle) =
+            segment_wal.streaming_write(ReceiverStream::new(rx)).await?;
+
+        // Message with event time before the GC end time (should be filtered out)
+        let before_time = Utc.with_ymd_and_hms(2025, 4, 1, 0, 59, 0).unwrap();
+        let mut before_message = Message::default();
+        before_message.event_time = before_time;
+        before_message.keys = Arc::from(vec!["test-key".to_string()]);
+        before_message.value = bytes::Bytes::from(vec![1, 2, 3]);
+        before_message.id = MessageID {
+            vertex_name: "test-vertex".to_string().into(),
+            offset: "1".to_string().into(),
+            index: 0,
+        };
+
+        let before_message: WalMessage = before_message.into();
+
+        // Message with event time after the GC end time (should be retained)
+        let after_time = Utc.with_ymd_and_hms(2025, 4, 1, 1, 30, 0).unwrap();
+        let mut after_message = Message::default();
+        after_message.event_time = after_time;
+        after_message.keys = Arc::from(vec!["test-key".to_string()]);
+        after_message.value = bytes::Bytes::from(vec![4, 5, 6]);
+        after_message.id = MessageID {
+            vertex_name: "test-vertex".to_string().into(),
+            offset: "2".to_string().into(),
+            index: 0,
+        };
+
+        let after_message: WalMessage = after_message.into();
+
+        // Write the messages to the WAL
+        let before_proto: Bytes = before_message.try_into().unwrap();
+        tx.send(SegmentWriteMessage::WriteData {
+            offset: Some(Offset::String(StringOffset::new("msg-1".to_string(), 0))),
+            data: before_proto,
+        })
+        .await
+        .map_err(|e| format!("Failed to send data: {e}"))?;
+
+        let after_proto: Bytes = after_message.try_into().unwrap();
+        tx.send(SegmentWriteMessage::WriteData {
+            offset: Some(Offset::String(StringOffset::new("msg-2".to_string(), 0))),
+            data: after_proto,
+        })
+        .await
+        .map_err(|e| format!("Failed to send data: {e}"))?;
+
+        // Drop the sender to close the channel
+        drop(tx);
+        writer_handle
+            .await
+            .map_err(|e| format!("Writer failed: {e}"))??;
+
+        // we do not get data written to the tx channel because ID is None
+        assert_eq!(write_result_cnt.await.unwrap(), 0);
+
+        // Create a compactor with aligned window kind
+        let compactor = Compactor::new(
+            path.clone(),
+            WindowKind::Aligned,
+            100,  // max_file_size_mb
+            1000, // flush_interval_ms
+            100,  // channel_buffer_size
+        )
+        .await?;
+
+        // Create a channel to receive replayed messages
+        let (replay_tx, mut replay_rx) = mpsc::channel(100);
+
+        // Call compact_with_replay
+        let handle = compactor.compact_with_replay(replay_tx).await?;
+
+        // Wait for compaction to complete
+        handle
+            .await
+            .map_err(|e| format!("Compaction failed: {e}"))??;
+
+        // Count the number of messages received through the replay channel
+        let mut replayed_count = 0;
+        while let Ok(data) = replay_rx.try_recv() {
+            let msg: numaflow_pb::objects::isb::ReadMessage = prost::Message::decode(data)
+                .map_err(|e| format!("Failed to decode message: {e}"))?;
+
+            // Verify that the message has an event time after the GC end time
+            if let Some(header) = msg.message.unwrap().header {
+                if let Some(message_info) = header.message_info {
+                    let event_time = message_info.event_time.map(utc_from_timestamp).unwrap();
+                    assert!(
+                        event_time > gc_end,
+                        "Found message with event_time <= gc_end"
+                    );
+                }
+            }
+            replayed_count += 1;
+        }
+
+        // Verify that only one message was replayed (the one with event time after GC end time)
+        assert_eq!(
+            replayed_count, 1,
+            "Expected only one message to be replayed"
+        );
+
+        Ok(())
+    }
+
+    #[tokio::test]
+    async fn test_compact_with_replay_unaligned() -> WalResult<()> {
+        // Create a temporary directory for the test
+        let temp_dir = tempdir().unwrap();
+        let path = temp_dir.path().to_path_buf();
+
+        // Create WAL directories
+        fs::create_dir_all(path.join(WalType::Gc.to_string())).unwrap();
+        fs::create_dir_all(path.join(WalType::Data.to_string())).unwrap();
+        fs::create_dir_all(path.join(WalType::Compact.to_string())).unwrap();
+
+        // Create GC WAL with test events
+        let gc_wal = AppendOnlyWal::new(
+            WalType::Gc,
+            path.clone(),
+            100,  // max_file_size_mb
+            1000, // flush_interval_ms
+            100,  // channel_buffer_size
+        )
+        .await?;
+
+        // Create GC events with different keys and end times
+        let (tx, rx) = mpsc::channel(100);
+        let (mut gc_wal_write_rx, writer_handle) =
+            gc_wal.streaming_write(ReceiverStream::new(rx)).await?;
+
+        let write_result_cnt = tokio::spawn(async move {
+            let mut counter = 0;
+            while let Some(_) = gc_wal_write_rx.next().await {
+                counter += 1;
+            }
+            return counter;
+        });
+
+        // GC event for key1:key2 with end time
+        let gc_start_1 = Utc.with_ymd_and_hms(2025, 4, 1, 1, 0, 0).unwrap();
+        let gc_end_1 = Utc.with_ymd_and_hms(2025, 4, 1, 1, 0, 10).unwrap();
+        let gc_event_1 = GcEvent {
+            start_time: Some(prost_timestamp_from_utc(gc_start_1)),
+            end_time: Some(prost_timestamp_from_utc(gc_end_1)),
+            keys: vec!["key1".to_string(), "key2".to_string()],
+            ..Default::default()
+        };
+
+        // GC event for key3:key4 with a different end time
+        let gc_start_2 = Utc.with_ymd_and_hms(2025, 4, 1, 2, 0, 0).unwrap();
+        let gc_end_2 = Utc.with_ymd_and_hms(2025, 4, 1, 2, 0, 0).unwrap();
+        let gc_event_2 = GcEvent {
+            start_time: Some(prost_timestamp_from_utc(gc_start_2)),
+            end_time: Some(prost_timestamp_from_utc(gc_end_2)),
+            keys: vec!["key3".to_string(), "key4".to_string()],
+            ..Default::default()
+        };
+
+        // Write the GC events to the WAL
+        for event in [gc_event_1, gc_event_2] {
+            let mut buf = Vec::new();
+            prost::Message::encode(&event, &mut buf)
+                .map_err(|e| format!("Failed to encode GC event: {e}"))?;
+            tx.send(SegmentWriteMessage::WriteData {
+                offset: None,
+                data: Bytes::from(buf),
+            })
+            .await
+            .map_err(|e| format!("Failed to send data: {e}"))?;
+        }
+
+        // Drop the sender to close the channel
+        drop(tx);
+        writer_handle
+            .await
+            .map_err(|e| format!("Writer failed: {e}"))??;
+
+        // we do not get data written to the tx channel because ID is None
+        assert_eq!(write_result_cnt.await.unwrap(), 0);
+
+        // Create segment WAL with test messages
+        let segment_wal = AppendOnlyWal::new(
+            WalType::Data,
+            path.clone(),
+            100,  // max_file_size_mb
+            1000, // flush_interval_ms
+            100,  // channel_buffer_size
+        )
+        .await?;
+
+        // Create messages with different keys and event times
+        let (tx, rx) = mpsc::channel(100);
+        let (_result_rx, writer_handle) =
+            segment_wal.streaming_write(ReceiverStream::new(rx)).await?;
+
+        // Message 1: key1:key2 with event time before gc_end_1 (should be filtered out)
+        let before_time_1 = Utc.with_ymd_and_hms(2025, 4, 1, 0, 59, 0).unwrap();
+        let mut message_1 = Message::default();
+        message_1.event_time = before_time_1;
+        message_1.keys = Arc::from(vec!["key1".to_string(), "key2".to_string()]);
+        message_1.value = bytes::Bytes::from(vec![1, 2, 3]);
+        message_1.id = MessageID {
+            vertex_name: "test-vertex".to_string().into(),
+            offset: "1".to_string().into(),
+            index: 0,
+        };
+        let message_1: WalMessage = message_1.into();
+
+        // Message 2: key1:key2 with event time after gc_end_1 (should be retained)
+        let after_time_1 = Utc.with_ymd_and_hms(2025, 4, 1, 1, 30, 0).unwrap();
+        let mut message_2 = Message::default();
+        message_2.event_time = after_time_1;
+        message_2.keys = Arc::from(vec!["key1".to_string(), "key2".to_string()]);
+        message_2.value = bytes::Bytes::from(vec![4, 5, 6]);
+        message_2.id = MessageID {
+            vertex_name: "test-vertex".to_string().into(),
+            offset: "2".to_string().into(),
+            index: 0,
+        };
+        let message_2: WalMessage = message_2.into();
+
+        // Message 3: key3:key4 with event time before gc_end_2 (should be filtered out)
+        let before_time_2 = Utc.with_ymd_and_hms(2025, 4, 1, 1, 30, 0).unwrap();
+        let mut message_3 = Message::default();
+        message_3.event_time = before_time_2;
+        message_3.keys = Arc::from(vec!["key3".to_string(), "key4".to_string()]);
+        message_3.value = bytes::Bytes::from(vec![7, 8, 9]);
+        message_3.id = MessageID {
+            vertex_name: "test-vertex".to_string().into(),
+            offset: "3".to_string().into(),
+            index: 0,
+        };
+        let message_3: WalMessage = message_3.into();
+
+        // Message 4: key3:key4 with event time after gc_end_2 (should be retained)
+        let after_time_2 = Utc.with_ymd_and_hms(2025, 4, 1, 2, 30, 0).unwrap();
+        let mut message_4 = Message::default();
+        message_4.event_time = after_time_2;
+        message_4.keys = Arc::from(vec!["key3".to_string(), "key4".to_string()]);
+        message_4.value = bytes::Bytes::from(vec![10, 11, 12]);
+        message_4.id = MessageID {
+            vertex_name: "test-vertex".to_string().into(),
+            offset: "4".to_string().into(),
+            index: 0,
+        };
+        let message_4: WalMessage = message_4.into();
+
+        // Write the messages to the WAL
+        for (i, message) in [message_1, message_2, message_3, message_4]
+            .iter()
+            .enumerate()
+        {
+            let proto: Bytes = message.clone().try_into().unwrap();
+            tx.send(SegmentWriteMessage::WriteData {
+                offset: Some(Offset::String(StringOffset::new(
+                    format!("msg-{}", i + 1),
+                    0,
+                ))),
+                data: proto,
+            })
+            .await
+            .map_err(|e| format!("Failed to send data: {e}"))?;
+        }
+
+        // Drop the sender to close the channel
+        drop(tx);
+        writer_handle
+            .await
+            .map_err(|e| format!("Writer failed: {e}"))??;
+
+        // Create a compactor with unaligned window kind
+        let compactor = Compactor::new(
+            path.clone(),
+            WindowKind::Unaligned,
+            100,  // max_file_size_mb
+            1000, // flush_interval_ms
+            100,  // channel_buffer_size
+        )
+        .await?;
+
+        // Create a channel to receive replayed messages
+        let (replay_tx, mut replay_rx) = mpsc::channel(100);
+
+        // Call compact_with_replay
+        let handle = compactor.compact_with_replay(replay_tx).await?;
+
+        // Wait for compaction to complete
+        handle
+            .await
+            .map_err(|e| format!("Compaction failed: {e}"))??;
+
+        // Count the number of messages received through the replay channel
+        let mut replayed_count = 0;
+        let mut key1_key2_count = 0;
+        let mut key3_key4_count = 0;
+
+        while let Ok(data) = replay_rx.try_recv() {
+            let msg: numaflow_pb::objects::isb::ReadMessage = prost::Message::decode(data)
+                .map_err(|e| format!("Failed to decode message: {e}"))?;
+
+            // Verify that the message has an event time after the appropriate GC end time
+            if let Some(header) = msg.message.unwrap().header {
+                let key_str = header.keys.join(WAL_KEY_SEPERATOR);
+
+                if key_str == "key1:key2" {
+                    key1_key2_count += 1;
+                    if let Some(message_info) = header.message_info.as_ref() {
+                        let event_time = message_info.event_time.map(utc_from_timestamp).unwrap();
+                        assert!(
+                            event_time > gc_end_1,
+                            "Found key1:key2 message with event_time <= gc_end_1"
+                        );
+                    }
+                } else if key_str == "key3:key4" {
+                    key3_key4_count += 1;
+                    if let Some(message_info) = header.message_info.as_ref() {
+                        let event_time = message_info.event_time.map(utc_from_timestamp).unwrap();
+                        assert!(
+                            event_time > gc_end_2,
+                            "Found key3:key4 message with event_time <= gc_end_2"
+                        );
+                    }
+                }
+            }
+            replayed_count += 1;
+        }
+
+        // Verify that only two messages were replayed (one for each key combination)
+        assert_eq!(replayed_count, 2, "Expected two messages to be replayed");
+        assert_eq!(key1_key2_count, 1, "Expected one key1:key2 message");
+        assert_eq!(key3_key4_count, 1, "Expected one key3:key4 message");
+
+        Ok(())
+    }
 }
diff --git a/rust/numaflow-core/src/reduce/wal/segment/replay.rs b/rust/numaflow-core/src/reduce/wal/segment/replay.rs
index 33d76405..2ee49387 100644
--- a/rust/numaflow-core/src/reduce/wal/segment/replay.rs
+++ b/rust/numaflow-core/src/reduce/wal/segment/replay.rs
@@ -17,7 +17,7 @@ use tracing::{debug, info};
 
 /// Segment Entry as recorded in the WAL.
 #[derive(Debug)]
-pub(crate) enum SegmentEntry {
+pub(in crate::reduce) enum SegmentEntry {
     /// Data entry in the Segment
     DataEntry { size: u64, data: Bytes },
     /// The file has been switched
@@ -30,14 +30,14 @@ pub(crate) enum SegmentEntry {
 
 /// Replay the WAL in-order.
 #[derive(Debug, Clone)]
-pub(crate) struct ReplayWal {
+pub(in crate::reduce) struct ReplayWal {
     wal_type: WalType,
     base_path: PathBuf,
 }
 
 impl ReplayWal {
     /// Creates a new Replayer for the WAL.
-    pub(crate) fn new(wal_type: WalType, base_path: PathBuf) -> Self {
+    pub(in crate::reduce) fn new(wal_type: WalType, base_path: PathBuf) -> Self {
         Self {
             wal_type,
             base_path,
@@ -46,7 +46,7 @@ impl ReplayWal {
 
     /// Reads the WAL files and streams it via the stream. Stream will be closed once all the
     /// entries are read.
-    pub(crate) fn streaming_read(
+    pub(in crate::reduce) fn streaming_read(
         self,
     ) -> WalResult<(ReceiverStream<SegmentEntry>, JoinHandle<WalResult<()>>)> {
         let mut files: Vec<PathBuf> = list_files(&self.wal_type, self.base_path.clone());
@@ -138,8 +138,18 @@ fn sort_filenames(mut files: Vec<PathBuf>) -> Vec<PathBuf> {
             (timestamp, index)
         };
 
-        let (ts_a, idx_a) = parse(a.to_str().expect("filename is valid"));
-        let (ts_b, idx_b) = parse(b.to_str().expect("filename is valid"));
+        let (ts_a, idx_a) = parse(
+            a.file_name()
+                .expect("valid unix file")
+                .to_str()
+                .expect("filename is valid"),
+        );
+        let (ts_b, idx_b) = parse(
+            b.file_name()
+                .expect("valid unix file")
+                .to_str()
+                .expect("filename is valid"),
+        );
 
         // first sort on timestamp, if it matches, then sort on index
         match ts_a.cmp(&ts_b) {
diff --git a/rust/numaflow-core/src/shared/create_components.rs b/rust/numaflow-core/src/shared/create_components.rs
index 7a002ec8..a53ec4ee 100644
--- a/rust/numaflow-core/src/shared/create_components.rs
+++ b/rust/numaflow-core/src/shared/create_components.rs
@@ -22,6 +22,7 @@ use crate::source::Source;
 use crate::source::generator::new_generator;
 use crate::source::jetstream::new_jetstream_source;
 use crate::source::pulsar::new_pulsar_source;
+use crate::source::sqs::new_sqs_source;
 use crate::source::user_defined::new_source;
 use crate::tracker::TrackerHandle;
 use crate::transformer::Transformer;
@@ -328,6 +329,23 @@ pub async fn create_source(
                 watermark_handle,
             ))
         }
+        SourceType::Sqs(sqs_source_config) => {
+            let sqs = new_sqs_source(
+                sqs_source_config.clone(),
+                batch_size,
+                read_timeout,
+                *get_vertex_replica(),
+            )
+            .await?;
+            Ok(Source::new(
+                batch_size,
+                source::SourceType::SQS(sqs),
+                tracker_handle,
+                source_config.read_ahead,
+                transformer,
+                watermark_handle,
+            ))
+        }
         SourceType::Jetstream(jetstream_config) => {
             let jetstream =
                 new_jetstream_source(jetstream_config.clone(), batch_size, read_timeout).await?;
diff --git a/rust/numaflow-core/src/shared/forward.rs b/rust/numaflow-core/src/shared/forward.rs
index 05090232..1eaa716d 100644
--- a/rust/numaflow-core/src/shared/forward.rs
+++ b/rust/numaflow-core/src/shared/forward.rs
@@ -10,9 +10,9 @@ pub(crate) fn should_forward(
     tags: Option<Arc<[String]>>,
     conditions: Option<Box<ForwardConditions>>,
 ) -> bool {
-    conditions.map_or(true, |conditions| {
-        conditions.tags.operator.as_ref().map_or(true, |operator| {
-            tags.as_ref().map_or(true, |tags| {
+    conditions.is_none_or(|conditions| {
+        conditions.tags.operator.as_ref().is_none_or(|operator| {
+            tags.as_ref().is_none_or(|tags| {
                 !conditions.tags.values.is_empty()
                     && check_operator_condition(operator, &conditions.tags.values, tags)
             })
diff --git a/rust/numaflow-core/src/shared/grpc.rs b/rust/numaflow-core/src/shared/grpc.rs
index 56a0366f..a2c83f63 100644
--- a/rust/numaflow-core/src/shared/grpc.rs
+++ b/rust/numaflow-core/src/shared/grpc.rs
@@ -149,8 +149,6 @@ pub(crate) async fn connect_with_uds(uds_path: PathBuf) -> error::Result<Channel
     Ok(channel)
 }
 
-pub(crate) fn utc_from_timestamp(t: Option<Timestamp>) -> DateTime<Utc> {
-    t.map_or(Utc.timestamp_nanos(-1), |t| {
-        DateTime::from_timestamp(t.seconds, t.nanos as u32).unwrap_or(Utc.timestamp_nanos(-1))
-    })
+pub(crate) fn utc_from_timestamp(t: Timestamp) -> DateTime<Utc> {
+    DateTime::from_timestamp(t.seconds, t.nanos as u32).unwrap_or(Utc.timestamp_nanos(-1))
 }
diff --git a/rust/numaflow-core/src/sink/user_defined.rs b/rust/numaflow-core/src/sink/user_defined.rs
index ada85509..352a8f4e 100644
--- a/rust/numaflow-core/src/sink/user_defined.rs
+++ b/rust/numaflow-core/src/sink/user_defined.rs
@@ -74,7 +74,7 @@ impl UserDefinedSink {
                 ))?;
 
         // Handshake cannot be None during the initial phase, and it has to set `sot` to true.
-        if handshake_response.handshake.map_or(true, |h| !h.sot) {
+        if handshake_response.handshake.is_none_or(|h| !h.sot) {
             return Err(Error::Sink("invalid handshake response".to_string()));
         }
 
diff --git a/rust/numaflow-core/src/source/sqs.rs b/rust/numaflow-core/src/source/sqs.rs
index 45b521d9..e5e8e27c 100644
--- a/rust/numaflow-core/src/source/sqs.rs
+++ b/rust/numaflow-core/src/source/sqs.rs
@@ -40,20 +40,22 @@ impl From<numaflow_sqs::Error> for Error {
             numaflow_sqs::Error::ActorTaskTerminated(_) => {
                 Error::ActorPatternRecv(value.to_string())
             }
+            numaflow_sqs::Error::InvalidConfig(e) => Error::Source(e),
             numaflow_sqs::Error::Other(e) => Error::Source(e),
         }
     }
 }
 
-#[allow(dead_code)] // TODO(SQS): remove it when integrated with controller
 pub(crate) async fn new_sqs_source(
     cfg: SQSSourceConfig,
     batch_size: usize,
     timeout: Duration,
+    vertex_replica: u16,
 ) -> crate::Result<SQSSource> {
     Ok(SqsSourceBuilder::new(cfg)
         .batch_size(batch_size)
         .timeout(timeout)
+        .vertex_replica(vertex_replica)
         .build()
         .await?)
 }
@@ -167,6 +169,13 @@ pub mod tests {
         let sqs_source = SqsSourceBuilder::new(SQSSourceConfig {
             region: SQS_DEFAULT_REGION.to_string(),
             queue_name: "test-q".to_string(),
+            queue_owner_aws_account_id: "12345678912".to_string(),
+            visibility_timeout: None,
+            max_number_of_messages: None,
+            wait_time_seconds: None,
+            endpoint_url: None,
+            attribute_names: vec![],
+            message_attribute_names: vec![],
         })
         .batch_size(1)
         .timeout(Duration::from_secs(1))
diff --git a/rust/numaflow-core/src/source/user_defined.rs b/rust/numaflow-core/src/source/user_defined.rs
index 3d25dd91..f6bcd0f1 100644
--- a/rust/numaflow-core/src/source/user_defined.rs
+++ b/rust/numaflow-core/src/source/user_defined.rs
@@ -104,7 +104,7 @@ impl UserDefinedSourceRead {
                     "failed to receive handshake response".to_string(),
                 ))?;
         // handshake cannot to None during the initial phase, and it has to set `sot` to true.
-        if handshake_response.handshake.map_or(true, |h| !h.sot) {
+        if handshake_response.handshake.is_none_or(|h| !h.sot) {
             return Err(Error::Source("invalid handshake response".to_string()));
         }
 
@@ -150,7 +150,10 @@ impl TryFrom<read_response::Result> for Message {
             tags: None,
             value: result.payload.into(),
             offset: source_offset.clone(),
-            event_time: utc_from_timestamp(result.event_time),
+            event_time: result
+                .event_time
+                .map(utc_from_timestamp)
+                .expect("event time should be present"),
             id: MessageID {
                 vertex_name: config::get_vertex_name().to_string().into(),
                 offset: source_offset.to_string().into(),
@@ -275,7 +278,7 @@ impl UserDefinedSourceAck {
                 "failed to receive ack handshake response".to_string(),
             ))?;
         // handshake cannot to None during the initial phase, and it has to set `sot` to true.
-        if ack_handshake_response.handshake.map_or(true, |h| !h.sot) {
+        if ack_handshake_response.handshake.is_none_or(|h| !h.sot) {
             return Err(Error::Source("invalid ack handshake response".to_string()));
         }
 
diff --git a/rust/numaflow-core/src/transformer/user_defined.rs b/rust/numaflow-core/src/transformer/user_defined.rs
index 158b2e7e..23a1017b 100644
--- a/rust/numaflow-core/src/transformer/user_defined.rs
+++ b/rust/numaflow-core/src/transformer/user_defined.rs
@@ -89,7 +89,7 @@ impl UserDefinedTransformer {
                     "failed to receive handshake response".to_string(),
                 ))?;
 
-        if handshake_response.handshake.map_or(true, |h| !h.sot) {
+        if handshake_response.handshake.is_none_or(|h| !h.sot) {
             return Err(Error::Transformer("invalid handshake response".to_string()));
         }
 
@@ -143,7 +143,10 @@ impl UserDefinedTransformer {
                         tags: Some(Arc::from(result.tags)),
                         value: result.value.into(),
                         offset: msg_info.offset.clone(),
-                        event_time: utc_from_timestamp(result.event_time),
+                        event_time: result
+                            .event_time
+                            .map(utc_from_timestamp)
+                            .expect("event time should be present"),
                         headers: msg_info.headers.clone(),
                         watermark: None,
                         metadata: None,
diff --git a/rust/numaflow-core/src/watermark/processor/manager.rs b/rust/numaflow-core/src/watermark/processor/manager.rs
index 3b1689d1..5f55f413 100644
--- a/rust/numaflow-core/src/watermark/processor/manager.rs
+++ b/rust/numaflow-core/src/watermark/processor/manager.rs
@@ -6,22 +6,22 @@ use std::collections::HashMap;
 use std::fmt::{Debug, Formatter};
 use std::sync::Arc;
 use std::sync::RwLock;
-use std::time::Duration;
 use std::time::SystemTime;
+use std::time::{Duration, UNIX_EPOCH};
 
+use crate::config::pipeline::watermark::BucketConfig;
+use crate::error::{Error, Result};
+use crate::watermark::processor::timeline::OffsetTimeline;
+use crate::watermark::wmb::WMB;
 use async_nats::jetstream::kv::Watch;
 use backoff::retry::Retry;
 use backoff::strategy::fixed;
 use bytes::Bytes;
 use futures::{StreamExt, TryStreamExt};
+use numaflow_pb::objects::watermark::Heartbeat;
 use prost::Message as ProtoMessage;
 use tracing::{debug, error, info, warn};
 
-use crate::config::pipeline::watermark::BucketConfig;
-use crate::error::{Error, Result};
-use crate::watermark::processor::timeline::OffsetTimeline;
-use crate::watermark::wmb::WMB;
-
 const DEFAULT_PROCESSOR_REFRESH_RATE: u16 = 5;
 
 /// Status of a processor.
@@ -205,8 +205,16 @@ impl ProcessorManager {
                 continue;
             };
 
+            // heartbeat decode can fail when users update the golang based runtime to rust without
+            // recreating the pipeline, we will use the current time as the heartbeat, we can remove
+            // the default once we stop supporting the golang based runtime
             let hb = numaflow_pb::objects::watermark::Heartbeat::decode(value)
-                .expect("Failed to decode heartbeat")
+                .unwrap_or(Heartbeat {
+                    heartbeat: SystemTime::now()
+                        .duration_since(UNIX_EPOCH)
+                        .expect("Failed to get duration since epoch")
+                        .as_secs() as i64,
+                })
                 .heartbeat;
             heartbeats.insert(processor_name, hb);
         }
@@ -489,7 +497,7 @@ mod tests {
         // Spawn a task to keep publishing heartbeats
         let hb_task = tokio::spawn(async move {
             loop {
-                let heartbeat = numaflow_pb::objects::watermark::Heartbeat { heartbeat: 100 };
+                let heartbeat = Heartbeat { heartbeat: 100 };
                 let mut bytes = BytesMut::new();
                 heartbeat
                     .encode(&mut bytes)
diff --git a/rust/numaflow-models/src/models/mod.rs b/rust/numaflow-models/src/models/mod.rs
index 2514a6eb..3c50a039 100644
--- a/rust/numaflow-models/src/models/mod.rs
+++ b/rust/numaflow-models/src/models/mod.rs
@@ -180,6 +180,8 @@ pub mod sliding_window;
 pub use self::sliding_window::SlidingWindow;
 pub mod source;
 pub use self::source::Source;
+pub mod sqs_source;
+pub use self::sqs_source::SqsSource;
 pub mod status;
 pub use self::status::Status;
 pub mod tag_conditions;
diff --git a/rust/numaflow-models/src/models/serving_spec.rs b/rust/numaflow-models/src/models/serving_spec.rs
index c5b897ae..dd1267c4 100644
--- a/rust/numaflow-models/src/models/serving_spec.rs
+++ b/rust/numaflow-models/src/models/serving_spec.rs
@@ -18,13 +18,40 @@ limitations under the License.
 
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 pub struct ServingSpec {
+    #[serde(rename = "affinity", skip_serializing_if = "Option::is_none")]
+    pub affinity: Option<k8s_openapi::api::core::v1::Affinity>,
     #[serde(rename = "auth", skip_serializing_if = "Option::is_none")]
     pub auth: Option<Box<crate::models::Authorization>>,
+    /// AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.
+    #[serde(
+        rename = "automountServiceAccountToken",
+        skip_serializing_if = "Option::is_none"
+    )]
+    pub automount_service_account_token: Option<bool>,
     #[serde(rename = "containerTemplate", skip_serializing_if = "Option::is_none")]
     pub container_template: Option<Box<crate::models::ContainerTemplate>>,
+    #[serde(rename = "dnsConfig", skip_serializing_if = "Option::is_none")]
+    pub dns_config: Option<k8s_openapi::api::core::v1::PodDNSConfig>,
+    /// Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.
+    #[serde(rename = "dnsPolicy", skip_serializing_if = "Option::is_none")]
+    pub dns_policy: Option<String>,
+    /// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
+    #[serde(rename = "imagePullSecrets", skip_serializing_if = "Option::is_none")]
+    pub image_pull_secrets: Option<Vec<k8s_openapi::api::core::v1::LocalObjectReference>>,
+    #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")]
+    pub metadata: Option<Box<crate::models::Metadata>>,
     /// The header key from which the message id will be extracted
     #[serde(rename = "msgIDHeaderKey")]
     pub msg_id_header_key: String,
+    /// NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
+    #[serde(rename = "nodeSelector", skip_serializing_if = "Option::is_none")]
+    pub node_selector: Option<::std::collections::HashMap<String, String>>,
+    /// The priority value. Various system components use this field to find the priority of the Redis pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
+    #[serde(rename = "priority", skip_serializing_if = "Option::is_none")]
+    pub priority: Option<i32>,
+    /// If specified, indicates the Redis pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
+    #[serde(rename = "priorityClassName", skip_serializing_if = "Option::is_none")]
+    pub priority_class_name: Option<String>,
     /// Initial replicas of the serving server deployment.
     #[serde(rename = "replicas", skip_serializing_if = "Option::is_none")]
     pub replicas: Option<i32>,
@@ -34,23 +61,51 @@ pub struct ServingSpec {
         skip_serializing_if = "Option::is_none"
     )]
     pub request_timeout_seconds: Option<i64>,
+    /// ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name.
+    #[serde(rename = "resourceClaims", skip_serializing_if = "Option::is_none")]
+    pub resource_claims: Option<Vec<k8s_openapi::api::core::v1::PodResourceClaim>>,
+    /// RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod.  If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class
+    #[serde(rename = "runtimeClassName", skip_serializing_if = "Option::is_none")]
+    pub runtime_class_name: Option<String>,
+    #[serde(rename = "securityContext", skip_serializing_if = "Option::is_none")]
+    pub security_context: Option<k8s_openapi::api::core::v1::PodSecurityContext>,
     /// Whether to create a ClusterIP Service
     #[serde(rename = "service", skip_serializing_if = "Option::is_none")]
     pub service: Option<bool>,
+    /// ServiceAccountName applied to the pod
+    #[serde(rename = "serviceAccountName", skip_serializing_if = "Option::is_none")]
+    pub service_account_name: Option<String>,
     #[serde(rename = "store", skip_serializing_if = "Option::is_none")]
     pub store: Option<Box<crate::models::ServingStore>>,
+    /// If specified, the pod's tolerations.
+    #[serde(rename = "tolerations", skip_serializing_if = "Option::is_none")]
+    pub tolerations: Option<Vec<k8s_openapi::api::core::v1::Toleration>>,
 }
 
 impl ServingSpec {
     pub fn new(msg_id_header_key: String) -> ServingSpec {
         ServingSpec {
+            affinity: None,
             auth: None,
+            automount_service_account_token: None,
             container_template: None,
+            dns_config: None,
+            dns_policy: None,
+            image_pull_secrets: None,
+            metadata: None,
             msg_id_header_key,
+            node_selector: None,
+            priority: None,
+            priority_class_name: None,
             replicas: None,
             request_timeout_seconds: None,
+            resource_claims: None,
+            runtime_class_name: None,
+            security_context: None,
             service: None,
+            service_account_name: None,
             store: None,
+            tolerations: None,
         }
     }
 }
diff --git a/rust/numaflow-models/src/models/source.rs b/rust/numaflow-models/src/models/source.rs
index f5ede490..7d08ace0 100644
--- a/rust/numaflow-models/src/models/source.rs
+++ b/rust/numaflow-models/src/models/source.rs
@@ -32,6 +32,8 @@ pub struct Source {
     pub pulsar: Option<Box<crate::models::PulsarSource>>,
     #[serde(rename = "serving", skip_serializing_if = "Option::is_none")]
     pub serving: Option<Box<crate::models::ServingSource>>,
+    #[serde(rename = "sqs", skip_serializing_if = "Option::is_none")]
+    pub sqs: Option<Box<crate::models::SqsSource>>,
     #[serde(rename = "transformer", skip_serializing_if = "Option::is_none")]
     pub transformer: Option<Box<crate::models::UdTransformer>>,
     #[serde(rename = "udsource", skip_serializing_if = "Option::is_none")]
@@ -48,6 +50,7 @@ impl Source {
             nats: None,
             pulsar: None,
             serving: None,
+            sqs: None,
             transformer: None,
             udsource: None,
         }
diff --git a/rust/numaflow-models/src/models/sqs_source.rs b/rust/numaflow-models/src/models/sqs_source.rs
new file mode 100644
index 00000000..7408e9ae
--- /dev/null
+++ b/rust/numaflow-models/src/models/sqs_source.rs
@@ -0,0 +1,77 @@
+/*
+Copyright 2022 The Numaproj Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by Openapi Generator. DO NOT EDIT.
+
+/// SqsSource : SqsSource represents the configuration of an AWS SQS source
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct SqsSource {
+    /// AttributeNames is a list of attributes that need to be returned along with each message. Valid values: All | Policy | VisibilityTimeout | MaximumMessageSize | MessageRetentionPeriod | ApproximateNumberOfMessages | ApproximateNumberOfMessagesNotVisible | CreatedTimestamp | LastModifiedTimestamp | QueueArn | ApproximateNumberOfMessagesDelayed | DelaySeconds | ReceiveMessageWaitTimeSeconds | RedrivePolicy | FifoQueue | ContentBasedDeduplication | KmsMasterKeyId | KmsDataKeyReusePeriodSeconds | DeduplicationScope | FifoThroughputLimit | RedriveAllowPolicy | SqsManagedSseEnabled
+    #[serde(rename = "attributeNames", skip_serializing_if = "Option::is_none")]
+    pub attribute_names: Option<Vec<String>>,
+    /// AWSRegion is the AWS Region where the SQS queue is located
+    #[serde(rename = "awsRegion")]
+    pub aws_region: String,
+    /// EndpointURL is the custom endpoint URL for the AWS SQS API. This is useful for testing with localstack or when using VPC endpoints.
+    #[serde(rename = "endpointUrl", skip_serializing_if = "Option::is_none")]
+    pub endpoint_url: Option<String>,
+    /// MaxNumberOfMessages is the maximum number of messages to return in a single poll. Valid values: 1-10 Defaults to 1
+    #[serde(
+        rename = "maxNumberOfMessages",
+        skip_serializing_if = "Option::is_none"
+    )]
+    pub max_number_of_messages: Option<i32>,
+    /// MessageAttributeNames is a list of message attributes that need to be returned along with each message.
+    #[serde(
+        rename = "messageAttributeNames",
+        skip_serializing_if = "Option::is_none"
+    )]
+    pub message_attribute_names: Option<Vec<String>>,
+    /// QueueName is the name of the SQS queue
+    #[serde(rename = "queueName")]
+    pub queue_name: String,
+    /// QueueOwnerAWSAccountID is the queue owner aws account id
+    #[serde(rename = "queueOwnerAWSAccountID")]
+    pub queue_owner_aws_account_id: String,
+    /// VisibilityTimeout is the duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. Valid values: 0-43200 (12 hours)
+    #[serde(rename = "visibilityTimeout", skip_serializing_if = "Option::is_none")]
+    pub visibility_timeout: Option<i32>,
+    /// WaitTimeSeconds is the duration (in seconds) for which the call waits for a message to arrive in the queue before returning. If a message is available, the call returns sooner than WaitTimeSeconds. Valid values: 0-20 Defaults to 0 (short polling)
+    #[serde(rename = "waitTimeSeconds", skip_serializing_if = "Option::is_none")]
+    pub wait_time_seconds: Option<i32>,
+}
+
+impl SqsSource {
+    /// SqsSource represents the configuration of an AWS SQS source
+    pub fn new(
+        aws_region: String,
+        queue_name: String,
+        queue_owner_aws_account_id: String,
+    ) -> SqsSource {
+        SqsSource {
+            attribute_names: None,
+            aws_region,
+            endpoint_url: None,
+            max_number_of_messages: None,
+            message_attribute_names: None,
+            queue_name,
+            queue_owner_aws_account_id,
+            visibility_timeout: None,
+            wait_time_seconds: None,
+        }
+    }
+}
diff --git a/rust/numaflow-pb/src/objects/isb.rs b/rust/numaflow-pb/src/objects/isb.rs
index b2260536..e7c9d8f9 100644
--- a/rust/numaflow-pb/src/objects/isb.rs
+++ b/rust/numaflow-pb/src/objects/isb.rs
@@ -73,8 +73,8 @@ pub struct ReadMessage {
     #[prost(message, optional, tag = "1")]
     pub message: ::core::option::Option<Message>,
     /// ReadOffset is the offset at which the message was read
-    #[prost(string, tag = "2")]
-    pub read_offset: ::prost::alloc::string::String,
+    #[prost(int64, tag = "2")]
+    pub read_offset: i64,
     /// Watermark is the watermark timestamp
     #[prost(message, optional, tag = "3")]
     pub watermark: ::core::option::Option<::prost_types::Timestamp>,
diff --git a/rust/serving/src/app.rs b/rust/serving/src/app.rs
index 275f66a4..f37d1586 100644
--- a/rust/serving/src/app.rs
+++ b/rust/serving/src/app.rs
@@ -62,11 +62,9 @@ where
     tokio::spawn(graceful_shutdown(
         handle.clone(),
         app.settings.drain_timeout_secs,
-        cancel_token.clone(),
     ));
 
     info!(?app_addr, "Starting application server");
-
     let router = router_with_auth(app).await?;
 
     axum_server::bind_rustls(app_addr, tls_config)
@@ -75,7 +73,12 @@ where
         .await
         .map_err(|e| InitError(format!("Starting web server for metrics: {}", e)))?;
 
-    info!(?app_addr, "Server stopped");
+    info!(
+        ?app_addr,
+        "Server stopped, cleanup up the background tasks."
+    );
+    cancel_token.cancel();
+
     Ok(())
 }
 
@@ -170,7 +173,7 @@ where
 
 /// Gracefully shutdown the server on receiving SIGINT or SIGTERM
 /// by sending a shutdown signal to the server using the handle.
-async fn graceful_shutdown(handle: Handle, duration_secs: u64, cancel_token: CancellationToken) {
+async fn graceful_shutdown(handle: Handle, duration_secs: u64) {
     let ctrl_c = async {
         signal::ctrl_c()
             .await
@@ -192,7 +195,6 @@ async fn graceful_shutdown(handle: Handle, duration_secs: u64, cancel_token: Can
     info!("Got terminate signal, gracefully shutting down the server");
     // Signal the server to shut down using Handle.
     handle.graceful_shutdown(Some(Duration::from_secs(duration_secs)));
-    cancel_token.cancel();
 }
 
 const PUBLISH_ENDPOINTS: [&str; 3] = ["/v1/process/sync", "/v1/process/async", "/v1/process/fetch"];
@@ -262,7 +264,7 @@ async fn setup_app<
     let app = parent
         .nest(
             "/v1/direct",
-            direct_proxy(client, app.settings.upstream_addr.clone()),
+            direct_proxy(client, app.settings.upstream_addr.into()),
         )
         .nest("/v1/process", routes(app).await?);
 
@@ -346,12 +348,12 @@ mod tests {
             .await
             .unwrap();
 
-        let status_tracker = StatusTracker::new(context.clone(), store_name, "0".to_string(), None)
+        let status_tracker = StatusTracker::new(context.clone(), store_name, "0", None)
             .await
             .unwrap();
         let msg_graph = MessageGraph::from_pipeline(&settings.pipeline_spec)?;
         let callback_state =
-            CallbackState::new("0", msg_graph, datum_store, callback_store, status_tracker).await?;
+            CallbackState::new(msg_graph, datum_store, callback_store, status_tracker).await?;
 
         let nats_connection = async_nats::connect("localhost:4222")
             .await
@@ -405,14 +407,14 @@ mod tests {
             .await
             .unwrap();
 
-        let status_tracker = StatusTracker::new(context.clone(), store_name, "0".to_string(), None)
+        let status_tracker = StatusTracker::new(context.clone(), store_name, "0", None)
             .await
             .unwrap();
 
         let pipeline_spec = PIPELINE_SPEC_ENCODED.parse().unwrap();
         let msg_graph = MessageGraph::from_pipeline(&pipeline_spec)?;
         let callback_state =
-            CallbackState::new("0", msg_graph, datum_store, callback_store, status_tracker).await?;
+            CallbackState::new(msg_graph, datum_store, callback_store, status_tracker).await?;
 
         let nats_connection = async_nats::connect("localhost:4222")
             .await
diff --git a/rust/serving/src/app/jetstream_proxy.rs b/rust/serving/src/app/jetstream_proxy.rs
index 118f4322..97f098cb 100644
--- a/rust/serving/src/app/jetstream_proxy.rs
+++ b/rust/serving/src/app/jetstream_proxy.rs
@@ -33,9 +33,9 @@ const NUMAFLOW_RESP_ARRAY_IDX_LEN: &str = "Numaflow-Array-Index-Len";
 
 struct ProxyState<T, U> {
     js_context: Context,
-    stream: String,
-    tid_header: String,
-    pod_hash: String,
+    stream: &'static str,
+    tid_header: &'static str,
+    pod_hash: &'static str,
     orchestrator: orchestrator::OrchestratorState<T, U>,
     cancellation_token: CancellationToken,
 }
@@ -49,11 +49,11 @@ pub(crate) async fn serving_proxy<
 ) -> crate::Result<Router> {
     let proxy_state = Arc::new(ProxyState {
         js_context: state.js_context.clone(),
-        stream: state.settings.js_message_stream.clone(),
-        tid_header: state.settings.tid_header.clone(),
-        pod_hash: state.settings.pod_hash.clone(),
-        orchestrator: state.orchestrator_state.clone(),
-        cancellation_token: state.cancellation_token.clone(),
+        stream: state.settings.js_message_stream,
+        tid_header: state.settings.tid_header,
+        pod_hash: state.settings.pod_hash,
+        orchestrator: state.orchestrator_state,
+        cancellation_token: state.cancellation_token,
     });
 
     let router = Router::new()
@@ -151,8 +151,8 @@ where
             String::from_utf8_lossy(value.as_bytes()).to_string(),
         );
     }
-    msg_headers.insert(proxy_state.tid_header.clone(), id.clone());
-    msg_headers.insert(DEFAULT_POD_HASH_KEY, proxy_state.pod_hash.clone());
+    msg_headers.insert(proxy_state.tid_header, id.clone());
+    msg_headers.insert(DEFAULT_POD_HASH_KEY, proxy_state.pod_hash);
 
     let mut orchestrator_state = proxy_state.orchestrator.clone();
     let response_stream = orchestrator_state
@@ -165,7 +165,7 @@ where
     // retry again we will show them its duplicate.
     if let Err(err) = publish_to_jetstream(
         proxy_state.js_context.clone(),
-        &proxy_state.stream,
+        proxy_state.stream,
         &id,
         msg_headers,
         body,
@@ -251,8 +251,8 @@ async fn sync_publish<
             String::from_utf8_lossy(value.as_bytes()).to_string(),
         );
     }
-    msg_headers.insert(proxy_state.tid_header.clone(), id.clone());
-    msg_headers.insert(DEFAULT_POD_HASH_KEY, proxy_state.pod_hash.clone());
+    msg_headers.insert(proxy_state.tid_header, id.clone());
+    msg_headers.insert(DEFAULT_POD_HASH_KEY, proxy_state.pod_hash);
 
     let processing_start = Instant::now();
     // Register the ID in the callback proxy state
@@ -281,7 +281,7 @@ async fn sync_publish<
     // retry again we will show them its duplicate.
     if let Err(err) = publish_to_jetstream(
         proxy_state.js_context.clone(),
-        &proxy_state.stream,
+        proxy_state.stream,
         &id,
         msg_headers,
         body,
@@ -353,7 +353,7 @@ async fn sync_publish<
 
     let mut header_map = HeaderMap::new();
     header_map.insert(
-        HeaderName::from_str(&proxy_state.tid_header).unwrap(),
+        HeaderName::from_str(proxy_state.tid_header).unwrap(),
         HeaderValue::from_str(&id).unwrap(),
     );
 
@@ -398,8 +398,8 @@ async fn async_publish<
             String::from_utf8_lossy(value.as_bytes()).to_string(),
         );
     }
-    msg_headers.insert(proxy_state.tid_header.clone(), id.clone());
-    msg_headers.insert(DEFAULT_POD_HASH_KEY, proxy_state.pod_hash.clone());
+    msg_headers.insert(proxy_state.tid_header, id.clone());
+    msg_headers.insert(DEFAULT_POD_HASH_KEY, proxy_state.pod_hash);
 
     let processing_start = Instant::now();
     // Register request in Redis
@@ -463,7 +463,7 @@ async fn async_publish<
     // retry again we will show them its duplicate.
     if let Err(err) = publish_to_jetstream(
         proxy_state.js_context.clone(),
-        &proxy_state.stream,
+        proxy_state.stream,
         &id,
         msg_headers,
         body,
@@ -548,8 +548,8 @@ mod tests {
 
         let settings = Settings {
             tid_header: ID_HEADER.into(),
-            js_callback_store: store_name.to_string(),
-            js_message_stream: message_stream_name.to_string(),
+            js_callback_store: store_name,
+            js_message_stream: message_stream_name,
             ..Default::default()
         };
 
@@ -570,7 +570,7 @@ mod tests {
         let status_tracker = StatusTracker::new(
             context.clone(),
             store_name,
-            pod_hash.to_string(),
+            pod_hash,
             Some(store_name.to_string()),
         )
         .await
@@ -578,14 +578,8 @@ mod tests {
 
         let pipeline_spec = PIPELINE_SPEC_ENCODED.parse().unwrap();
         let msg_graph = MessageGraph::from_pipeline(&pipeline_spec)?;
-        let orchestrator_state = OrchestratorState::new(
-            pod_hash,
-            msg_graph,
-            datum_store,
-            callback_store,
-            status_tracker,
-        )
-        .await?;
+        let orchestrator_state =
+            OrchestratorState::new(msg_graph, datum_store, callback_store, status_tracker).await?;
 
         let app_state = AppState {
             js_context: context,
@@ -698,10 +692,10 @@ mod tests {
         let settings = Settings {
             tid_header: ID_HEADER.into(),
             pod_hash: POD_HASH.into(),
-            js_callback_store: store_name.to_string(),
-            js_status_store: store_name.to_string(),
-            js_response_store: store_name.to_string(),
-            js_message_stream: messages_stream_name.to_string(),
+            js_callback_store: store_name,
+            js_status_store: store_name,
+            js_response_store: store_name,
+            js_message_stream: messages_stream_name,
             ..Default::default()
         };
 
@@ -724,21 +718,16 @@ mod tests {
         let status_tracker = StatusTracker::new(
             context.clone(),
             store_name,
-            POD_HASH.to_string(),
+            POD_HASH,
             Some(store_name.to_string()),
         )
         .await
         .unwrap();
 
-        let orchestrator_state = OrchestratorState::new(
-            POD_HASH,
-            msg_graph,
-            datum_store,
-            callback_store,
-            status_tracker,
-        )
-        .await
-        .unwrap();
+        let orchestrator_state =
+            OrchestratorState::new(msg_graph, datum_store, callback_store, status_tracker)
+                .await
+                .unwrap();
 
         let app_state = AppState {
             js_context: context,
@@ -825,10 +814,10 @@ mod tests {
             .unwrap();
 
         let settings = Settings {
-            js_callback_store: store_name.to_string(),
-            js_status_store: store_name.to_string(),
-            js_response_store: store_name.to_string(),
-            js_message_stream: messages_stream_name.to_string(),
+            js_callback_store: store_name,
+            js_status_store: store_name,
+            js_response_store: store_name,
+            js_message_stream: messages_stream_name,
             pod_hash: POD_HASH.into(),
             ..Default::default()
         };
@@ -852,21 +841,16 @@ mod tests {
         let status_tracker = StatusTracker::new(
             context.clone(),
             store_name,
-            POD_HASH.to_string(),
+            POD_HASH,
             Some(store_name.to_string()),
         )
         .await
         .unwrap();
 
-        let orchestrator_state = OrchestratorState::new(
-            POD_HASH,
-            msg_graph,
-            datum_store,
-            callback_store,
-            status_tracker,
-        )
-        .await
-        .unwrap();
+        let orchestrator_state =
+            OrchestratorState::new(msg_graph, datum_store, callback_store, status_tracker)
+                .await
+                .unwrap();
 
         let app_state = AppState {
             js_context: context,
@@ -988,10 +972,10 @@ mod tests {
         let settings = Settings {
             tid_header: ID_HEADER.into(),
             pod_hash: POD_HASH.into(),
-            js_callback_store: store_name.to_string(),
-            js_response_store: store_name.to_string(),
-            js_status_store: store_name.to_string(),
-            js_message_stream: messages_stream_name.to_string(),
+            js_callback_store: store_name,
+            js_response_store: store_name,
+            js_status_store: store_name,
+            js_message_stream: messages_stream_name,
             ..Default::default()
         };
 
@@ -1014,20 +998,14 @@ mod tests {
         let status_tracker = StatusTracker::new(
             context.clone(),
             store_name,
-            POD_HASH.to_string(),
+            POD_HASH,
             Some(store_name.to_string()),
         )
         .await
         .unwrap();
 
-        let orchestrator_state = OrchestratorState::new(
-            POD_HASH,
-            msg_graph,
-            datum_store,
-            callback_store,
-            status_tracker,
-        )
-        .await?;
+        let orchestrator_state =
+            OrchestratorState::new(msg_graph, datum_store, callback_store, status_tracker).await?;
 
         let app_state = AppState {
             js_context: context,
diff --git a/rust/serving/src/app/message_path.rs b/rust/serving/src/app/message_path.rs
index 1e5c417e..c4cc1d2c 100644
--- a/rust/serving/src/app/message_path.rs
+++ b/rust/serving/src/app/message_path.rs
@@ -80,14 +80,13 @@ mod tests {
             .await
             .unwrap();
 
-        let status_tracker =
-            StatusTracker::new(context.clone(), store_name, "xgda".to_string(), None)
-                .await
-                .unwrap();
+        let status_tracker = StatusTracker::new(context.clone(), store_name, "xgda", None)
+            .await
+            .unwrap();
 
         let pipeline_spec: PipelineDCG = PIPELINE_SPEC_ENCODED.parse().unwrap();
         let msg_graph = MessageGraph::from_pipeline(&pipeline_spec).unwrap();
-        let state = CallbackState::new("xbda", msg_graph, data_store, cb_store, status_tracker)
+        let state = CallbackState::new(msg_graph, data_store, cb_store, status_tracker)
             .await
             .unwrap();
         let app = get_message_path(state);
diff --git a/rust/serving/src/app/orchestrator.rs b/rust/serving/src/app/orchestrator.rs
index 35c45bbf..c099ee6f 100644
--- a/rust/serving/src/app/orchestrator.rs
+++ b/rust/serving/src/app/orchestrator.rs
@@ -24,7 +24,6 @@ pub(crate) struct OrchestratorState<T, U> {
     datum_store: T,
     callback_store: U,
     status_tracker: StatusTracker,
-    pod_hash: String,
 }
 
 impl<T, U> OrchestratorState<T, U>
@@ -34,7 +33,6 @@ where
 {
     /// Create a new State to track connections and callback data
     pub(crate) async fn new(
-        pod_hash: &str,
         msg_graph: MessageGraph,
         datum_store: T,
         callback_store: U,
@@ -45,7 +43,6 @@ where
             datum_store,
             callback_store,
             status_tracker,
-            pod_hash: pod_hash.to_string(),
         })
     }
 
@@ -66,7 +63,7 @@ where
         // was cancelled before sending the response then the previous pod hash will be returned
         // with cancelled error, and we will fetch the callbacks and responses again.
         let pod_hash = match self.status_tracker.register(id, request_type).await {
-            Ok(_) => self.pod_hash.clone(),
+            Ok(_) => None,
             Err(e) => match e {
                 status::Error::Cancelled {
                     err,
@@ -76,7 +73,7 @@ where
                         ?err,
                         "Request was cancelled, fetching callbacks and responses again"
                     );
-                    previous_pod_hash
+                    Some(previous_pod_hash)
                 }
                 status::Error::Duplicate(msg) => {
                     warn!(error = ?msg, "Request already exists in the store");
@@ -94,10 +91,10 @@ where
         // start watching for callbacks
         let mut callbacks_stream = self
             .callback_store
-            .register_and_watch(id, &pod_hash)
+            .register_and_watch(id, pod_hash.clone())
             .await?;
 
-        let mut status_tracker = self.status_tracker.clone();
+        let status_tracker = self.status_tracker.clone();
         let mut cb_store = self.callback_store.clone();
         let span = tracing::Span::current();
         let callback_watcher = async move {
@@ -111,7 +108,7 @@ where
 
                 if let Some(graph) = subgraph {
                     status_tracker
-                        .deregister(&msg_id, &graph)
+                        .deregister(&msg_id, &graph, pod_hash)
                         .await
                         .expect("Failed to deregister");
                     cb_store
@@ -121,12 +118,8 @@ where
 
                     // send can only fail if the request was cancelled by the client or the handler task
                     // was terminated.
-                    if tx.send(Ok(graph)).is_err() {
-                        status_tracker
-                            .mark_as_failed(&msg_id, "Cancelled")
-                            .await
-                            .expect("Failed to mark the request as failed");
-                    }
+                    tx.send(Ok(graph))
+                        .expect("receiver was dropped, request is cancelled");
                     break;
                 }
             }
@@ -161,7 +154,7 @@ where
                 let notify = self.process_request(id, request_type).await?;
                 notify.await.expect("sender was dropped")?;
                 Ok(Some(
-                    self.datum_store.retrieve_data(id, Some(&pod_hash)).await?,
+                    self.datum_store.retrieve_data(id, Some(pod_hash)).await?,
                 ))
             }
         }
@@ -184,7 +177,7 @@ where
         // was cancelled before sending the response then the previous pod hash will be returned
         // with cancelled error, and we will fetch the callbacks and responses again.
         let pod_hash = match self.status_tracker.register(id, request_type).await {
-            Ok(_) => self.pod_hash.clone(),
+            Ok(_) => None,
             Err(e) => match e {
                 status::Error::Cancelled {
                     err,
@@ -194,7 +187,7 @@ where
                         ?err,
                         "Request was cancelled, fetching callbacks and responses again"
                     );
-                    previous_pod_hash
+                    Some(previous_pod_hash)
                 }
                 status::Error::Duplicate(msg) => {
                     warn!(error = ?msg, "Request already exists in the tracker");
@@ -212,11 +205,12 @@ where
         // start watching for callbacks
         let mut callbacks_stream = self
             .callback_store
-            .register_and_watch(id, &pod_hash)
+            .register_and_watch(id, pod_hash.clone())
             .await?;
 
         let mut cb_store = self.callback_store.clone();
         let status_tracker = self.status_tracker.clone();
+        let pod_hash_clone = pod_hash.clone();
         tokio::spawn(async move {
             let mut callbacks = Vec::new();
             while let Some(cb) = callbacks_stream.next().await {
@@ -233,7 +227,7 @@ where
 
                 if let Some(graph) = subgraph {
                     status_tracker
-                        .deregister(&msg_id, &graph)
+                        .deregister(&msg_id, &graph, pod_hash_clone)
                         .await
                         .expect("Failed to deregister in status tracker");
                     cb_store
@@ -248,7 +242,7 @@ where
         // watch for data stored in the datastore
         let request_id = id.to_string();
         let mut status_tracker = self.status_tracker.clone();
-        let mut response_stream = self.datum_store.stream_data(id, &pod_hash).await?;
+        let mut response_stream = self.datum_store.stream_data(id, pod_hash).await?;
         tokio::spawn(async move {
             while let Some(response) = response_stream.next().await {
                 if tx.send(response).await.is_err() {
@@ -360,21 +354,16 @@ mod tests {
         let status_tracker = StatusTracker::new(
             context.clone(),
             store_name,
-            pod_hash.to_string(),
+            pod_hash,
             Some(store_name.to_string()),
         )
         .await
         .unwrap();
 
-        let mut state = OrchestratorState::new(
-            pod_hash,
-            msg_graph,
-            datum_store,
-            callback_store,
-            status_tracker,
-        )
-        .await
-        .unwrap();
+        let mut state =
+            OrchestratorState::new(msg_graph, datum_store, callback_store, status_tracker)
+                .await
+                .unwrap();
 
         let id = "test_id".to_string();
 
@@ -534,7 +523,7 @@ mod tests {
         let status_tracker = StatusTracker::new(
             context.clone(),
             store_name,
-            pod_hash.to_string(),
+            pod_hash,
             Some(store_name.to_string()),
         )
         .await
@@ -544,15 +533,10 @@ mod tests {
 
         let msg_graph = MessageGraph::from_pipeline(&pipeline_spec).unwrap();
 
-        let mut state = OrchestratorState::new(
-            pod_hash,
-            msg_graph,
-            datum_store,
-            callback_store,
-            status_tracker,
-        )
-        .await
-        .unwrap();
+        let mut state =
+            OrchestratorState::new(msg_graph, datum_store, callback_store, status_tracker)
+                .await
+                .unwrap();
 
         let id = "test_id".to_string();
 
diff --git a/rust/serving/src/app/store/cbstore.rs b/rust/serving/src/app/store/cbstore.rs
index 90062753..0f89e0da 100644
--- a/rust/serving/src/app/store/cbstore.rs
+++ b/rust/serving/src/app/store/cbstore.rs
@@ -23,7 +23,7 @@ pub(crate) trait LocalCallbackStore {
     async fn register_and_watch(
         &mut self,
         id: &str,
-        pod_hash: &str,
+        failed_pod_hash: Option<String>,
     ) -> StoreResult<ReceiverStream<Arc<Callback>>>;
     /// This method will be called when processing is completed for a request id.
     async fn deregister(&mut self, id: &str) -> StoreResult<()>;
diff --git a/rust/serving/src/app/store/cbstore/jetstream_store.rs b/rust/serving/src/app/store/cbstore/jetstream_store.rs
index 0d0ce228..8f425664 100644
--- a/rust/serving/src/app/store/cbstore/jetstream_store.rs
+++ b/rust/serving/src/app/store/cbstore/jetstream_store.rs
@@ -24,7 +24,6 @@ const CALLBACK_KEY_PREFIX: &str = "cb";
 /// JetStream implementation of the callback store.
 #[derive(Clone)]
 pub(crate) struct JetStreamCallbackStore {
-    pod_hash: String,
     callback_kv: Store,
     callback_senders: Arc<Mutex<HashMap<String, mpsc::Sender<Arc<Callback>>>>>,
     cln_token: CancellationToken,
@@ -33,7 +32,7 @@ pub(crate) struct JetStreamCallbackStore {
 impl JetStreamCallbackStore {
     pub(crate) async fn new(
         js_context: Context,
-        pod_hash: &str,
+        pod_hash: &'static str,
         callback_bucket: &str,
         cln_token: CancellationToken,
     ) -> StoreResult<Self> {
@@ -63,7 +62,6 @@ impl JetStreamCallbackStore {
         .await;
 
         Ok(Self {
-            pod_hash: pod_hash.to_string(),
             callback_kv,
             callback_senders,
             cln_token,
@@ -136,7 +134,6 @@ impl JetStreamCallbackStore {
                                 cb_sender.send(callback).await.expect("Failed to send callback");
                             } else {
                                 error!(id = ?callback.id, "No active sender found for request id. Callback not sent.");
-                                continue;
                             }
                         }
                         Some(Err(e)) => {
@@ -296,24 +293,22 @@ impl super::CallbackStore for JetStreamCallbackStore {
     async fn register_and_watch(
         &mut self,
         id: &str,
-        pod_hash: &str,
+        failed_pod_hash: Option<String>,
     ) -> StoreResult<ReceiverStream<Arc<Callback>>> {
         let (tx, rx) = mpsc::channel(10);
 
         // if the pod_hash is same as the current pod, we can directly register the sender because
         // central watcher is already watching the callbacks for this pod. If not we will have to
         // create a new watcher for watching callbacks of the different pod.
-        if pod_hash.eq(&self.pod_hash) {
-            let mut senders_guard = self.callback_senders.lock().await;
-            senders_guard.insert(id.to_string(), tx);
-            Ok(ReceiverStream::new(rx))
-        } else {
+        if let Some(failed_pod_hash) = failed_pod_hash {
             let callback_kv_clone = self.callback_kv.clone();
             let id_clone = id.to_string();
             let tx_clone = tx.clone();
-            let previous_pod_hash = pod_hash.to_string();
+            let previous_pod_hash = failed_pod_hash.clone();
             let cln_token = self.cln_token.clone();
 
+            let mut senders_guard = self.callback_senders.lock().await;
+            senders_guard.insert(id.to_string(), tx);
             // Spawn a separate task for historical callbacks
             tokio::spawn(async move {
                 JetStreamCallbackStore::watch_historical_callbacks(
@@ -326,6 +321,10 @@ impl super::CallbackStore for JetStreamCallbackStore {
                 .await;
             });
             Ok(ReceiverStream::new(rx))
+        } else {
+            let mut senders_guard = self.callback_senders.lock().await;
+            senders_guard.insert(id.to_string(), tx);
+            Ok(ReceiverStream::new(rx))
         }
     }
 
@@ -379,7 +378,7 @@ mod tests {
         .unwrap();
 
         let id = "AFA7E0A1-3F0A-4C1B-AB94-BDA57694648D";
-        let result = store.register_and_watch(id, "xbac").await;
+        let result = store.register_and_watch(id, None).await;
         assert!(result.is_ok());
 
         // delete store
@@ -418,7 +417,7 @@ mod tests {
         .unwrap();
 
         let id = "test_watch_id_two";
-        let mut stream = store.register_and_watch(id, pod_hash).await.unwrap();
+        let mut stream = store.register_and_watch(id, None).await.unwrap();
 
         // Simulate a callback being added to the store
         let callback = Callback {
@@ -506,7 +505,7 @@ mod tests {
 
         // Register and watch the callbacks
         let mut stream = store
-            .register_and_watch(id, previous_pod_hash)
+            .register_and_watch(id, Some(previous_pod_hash.to_string()))
             .await
             .unwrap();
 
diff --git a/rust/serving/src/app/store/cbstore/memstore.rs b/rust/serving/src/app/store/cbstore/memstore.rs
index 8ea8b98e..41b93d9d 100644
--- a/rust/serving/src/app/store/cbstore/memstore.rs
+++ b/rust/serving/src/app/store/cbstore/memstore.rs
@@ -37,7 +37,7 @@ impl super::CallbackStore for InMemoryCallbackStore {
     async fn register_and_watch(
         &mut self,
         id: &str,
-        _pod_hash: &str,
+        _failed_pod_hash: Option<String>,
     ) -> StoreResult<ReceiverStream<Arc<Callback>>> {
         let mut data = self.data.lock().await;
         if !data.contains_key(id) {
@@ -103,7 +103,7 @@ mod tests {
         let mut store = create_test_store();
         let id = "test_id";
 
-        let mut rx = store.register_and_watch(id, "0").await.unwrap();
+        let mut rx = store.register_and_watch(id, None).await.unwrap();
         let received_callback = rx.next().await.unwrap();
         assert_eq!(received_callback.id, "test_id");
         assert_eq!(received_callback.vertex, "vertex");
diff --git a/rust/serving/src/app/store/datastore.rs b/rust/serving/src/app/store/datastore.rs
index faa2b9fe..636710f4 100644
--- a/rust/serving/src/app/store/datastore.rs
+++ b/rust/serving/src/app/store/datastore.rs
@@ -44,10 +44,17 @@ pub(crate) type Result<T> = std::result::Result<T, Error>;
 pub(crate) trait LocalDataStore {
     /// retrieve the data from the store.
     /// FIXME: make pod_hash optional
-    async fn retrieve_data(&mut self, id: &str, pod_hash: Option<&str>) -> Result<Vec<Vec<u8>>>;
+    async fn retrieve_data(
+        &mut self,
+        id: &str,
+        failed_pod_hash: Option<String>,
+    ) -> Result<Vec<Vec<u8>>>;
     /// streams the data from the store
-    async fn stream_data(&mut self, id: &str, pod_hash: &str)
-    -> Result<ReceiverStream<Arc<Bytes>>>;
+    async fn stream_data(
+        &mut self,
+        id: &str,
+        failed_pod_hash: Option<String>,
+    ) -> Result<ReceiverStream<Arc<Bytes>>>;
     /// check if the store is ready
     async fn ready(&mut self) -> bool;
 }
diff --git a/rust/serving/src/app/store/datastore/inmemory.rs b/rust/serving/src/app/store/datastore/inmemory.rs
index ec660d25..1e7b8401 100644
--- a/rust/serving/src/app/store/datastore/inmemory.rs
+++ b/rust/serving/src/app/store/datastore/inmemory.rs
@@ -32,7 +32,7 @@ impl super::DataStore for InMemoryDataStore {
     async fn retrieve_data(
         &mut self,
         id: &str,
-        _pod_hash: Option<&str>,
+        _pod_hash: Option<String>,
     ) -> StoreResult<Vec<Vec<u8>>> {
         let id = format!("{id}_{STORE_KEY_SUFFIX}");
         let data = self.data.lock().await;
@@ -49,7 +49,7 @@ impl super::DataStore for InMemoryDataStore {
     async fn stream_data(
         &mut self,
         id: &str,
-        _pod_hash: &str,
+        _pod_hash: Option<String>,
     ) -> StoreResult<ReceiverStream<Arc<Bytes>>> {
         let (tx, rx) = tokio::sync::mpsc::channel(10);
         let data = self.data.lock().await;
@@ -106,7 +106,7 @@ mod tests {
     async fn test_stream_response() {
         let mut store = create_test_store();
         let id = "test_id_saved";
-        let mut rx = store.stream_data(id, "0").await.unwrap();
+        let mut rx = store.stream_data(id, None).await.unwrap();
         let received_response = rx.next().await.unwrap();
         assert_eq!(
             received_response,
diff --git a/rust/serving/src/app/store/datastore/jetstream.rs b/rust/serving/src/app/store/datastore/jetstream.rs
index 57f55214..8d3ee49d 100644
--- a/rust/serving/src/app/store/datastore/jetstream.rs
+++ b/rust/serving/src/app/store/datastore/jetstream.rs
@@ -18,9 +18,9 @@ use std::collections::hash_map::Entry;
 use std::io::Cursor;
 use std::sync::Arc;
 use std::time::Duration;
-use tokio::sync::Mutex;
 use tokio::sync::mpsc;
 use tokio::sync::mpsc::Sender;
+use tokio::sync::{Mutex, Semaphore};
 use tokio::task::JoinHandle;
 use tokio::time::sleep;
 use tokio_stream::StreamExt;
@@ -85,7 +85,6 @@ fn extract_bytes_list(merged: &Bytes) -> Result<Vec<Bytes>, String> {
 #[derive(Clone)]
 pub(crate) struct JetStreamDataStore {
     kv_store: Store,
-    pod_hash: String,
     responses_map: Arc<Mutex<HashMap<String, ResponseMode>>>,
     cln_token: CancellationToken,
 }
@@ -93,8 +92,8 @@ pub(crate) struct JetStreamDataStore {
 impl JetStreamDataStore {
     pub(crate) async fn new(
         js_context: Context,
-        datum_store_name: &str,
-        pod_hash: &str,
+        datum_store_name: &'static str,
+        pod_hash: &'static str,
         cln_token: CancellationToken,
     ) -> StoreResult<Self> {
         let kv_store = js_context
@@ -113,13 +112,13 @@ impl JetStreamDataStore {
         .await;
         Ok(Self {
             kv_store,
-            pod_hash: pod_hash.to_string(),
             responses_map,
             cln_token,
         })
     }
 
-    /// Spawns the central task that watches response keys and manages data collection.
+    /// Spawns the central task that watches response keys and manages data collection. It creates
+    /// a tokio task for accumulating responses for a given request id and writing to the KV store.
     async fn spawn_central_watcher(
         pod_hash: String,
         kv_store: Store,
@@ -141,6 +140,8 @@ impl JetStreamDataStore {
         .expect("Failed to create central result watcher");
 
         tokio::spawn(async move {
+            const CONCURRENT_STORE_WRITER: usize = 500;
+            let semaphore = Arc::new(Semaphore::new(CONCURRENT_STORE_WRITER));
             loop {
                 tokio::select! {
                     // Stop watching if the cancellation token is triggered
@@ -158,7 +159,7 @@ impl JetStreamDataStore {
                                     continue;
                                 }
 
-                                if let Err(e) = Self::process_entry(&entry, &responses_map, &pod_hash, &kv_store).await {
+                                if let Err(e) = Self::process_entry(&entry, &responses_map, &pod_hash, &kv_store, &semaphore).await {
                                     error!(error = ?e, "Failed to process entry");
                                 }
                             }
@@ -186,6 +187,11 @@ impl JetStreamDataStore {
                     }
                 }
             }
+            // this is in exit code, no explicit error handling required
+            _ = semaphore
+                .acquire_many_owned(CONCURRENT_STORE_WRITER as u32)
+                .await
+                .expect("should have acquired all tasks");
         })
     }
 
@@ -228,6 +234,7 @@ impl JetStreamDataStore {
         responses_map: &Arc<Mutex<HashMap<String, ResponseMode>>>,
         pod_hash: &str,
         kv_store: &Store,
+        semaphore: &Arc<Semaphore>,
     ) -> Result<(), String> {
         let parts: Vec<&str> = entry.key.splitn(5, '.').collect();
         let key_prefix = parts[0];
@@ -281,17 +288,33 @@ impl JetStreamDataStore {
             // that it can be retrieved when needed. We only need to store the merged response for
             // sync and async because for sse it will be streaming. It's safe to store for sync request
             // because during failure of sync request it will be converted as an async request.
-            let mut response_map = responses_map.lock().await;
-            if let Some(ResponseMode::Unary(responses)) = response_map.remove(request_id) {
-                // we use rs.{pod_hash}.{request_id}.final.result.processed as the key for the final result
-                // and the value will be the merged response.
-                let merged_response = merge_bytes_list(&responses);
-                let final_result_key =
-                    format!("{}.{}", RESPONSE_KEY_PREFIX, FINAL_RESULT_KEY_SUFFIX);
-                kv_store
-                    .put(final_result_key, merged_response)
+            let responses = {
+                let mut response_map = responses_map.lock().await;
+                response_map.remove(request_id)
+            };
+
+            if let Some(ResponseMode::Unary(responses)) = responses {
+                let permit = Arc::clone(semaphore)
+                    .acquire_owned()
                     .await
-                    .map_err(|e| format!("Failed to put final result: {:?}", e))?;
+                    .expect("Semaphore is poisoned");
+                // Spawn a task to write the merged response to the KV store
+                let kv_store = kv_store.clone();
+                let request_id = request_id.to_string();
+                tokio::spawn(async move {
+                    let _permit = permit;
+                    // we use rs.{pod_hash}.{request_id}.final.result.processed as the key for the final result
+                    // and the value will be the merged response.
+                    let merged_response = merge_bytes_list(&responses);
+                    let final_result_key = format!(
+                        "{}.{}.{}",
+                        RESPONSE_KEY_PREFIX, request_id, FINAL_RESULT_KEY_SUFFIX
+                    );
+
+                    if let Err(e) = kv_store.put(final_result_key, merged_response).await {
+                        error!(error = ?e, "Failed to put final result");
+                    }
+                });
             }
         } else {
             // we can append the response for the list for sync and async, for sse we can write the
@@ -316,7 +339,8 @@ impl JetStreamDataStore {
     /// Retrieves the final result from the KV store for a given request ID using the final key, it
     /// keeps retrying until the final result is available.
     async fn get_data_from_response_store(&self, id: &str) -> StoreResult<Vec<Vec<u8>>> {
-        let final_result_key = format!("{}.{}", RESPONSE_KEY_PREFIX, FINAL_RESULT_KEY_SUFFIX);
+        let final_result_key =
+            format!("{}.{}.{}", RESPONSE_KEY_PREFIX, id, FINAL_RESULT_KEY_SUFFIX);
 
         loop {
             match self.kv_store.get(&final_result_key).await {
@@ -477,7 +501,7 @@ impl DataStore for JetStreamDataStore {
     async fn retrieve_data(
         &mut self,
         id: &str,
-        pod_hash: Option<&str>,
+        pod_hash: Option<String>,
     ) -> StoreResult<Vec<Vec<u8>>> {
         // if the pod_hash is same as the current pod hash then we can rely on the central watcher for
         // responses else we will have to create a new watcher for the old pod hash to get all the
@@ -486,7 +510,7 @@ impl DataStore for JetStreamDataStore {
             Self::get_historic_response(
                 self.kv_store.clone(),
                 id,
-                pod_hash_value,
+                &pod_hash_value,
                 self.cln_token.clone(),
             )
             .await
@@ -499,35 +523,21 @@ impl DataStore for JetStreamDataStore {
     async fn stream_data(
         &mut self,
         id: &str,
-        pod_hash: &str,
+        failed_pod_hash: Option<String>,
     ) -> StoreResult<ReceiverStream<Arc<Bytes>>> {
         // if the pod_hash is same as the current pod hash then we can rely on the central watcher for
         // responses else we will have to create a new watcher for the old pod hash.
-        if pod_hash.eq(&self.pod_hash) {
-            // we need to wait for the start processing marker entry to be processed by the central watcher
-            loop {
-                {
-                    let mut response_map = self.responses_map.lock().await;
-                    if let Some(ResponseMode::Stream { rx, .. }) = response_map.get_mut(id) {
-                        if let Some(receiver_stream) = rx.take() {
-                            return Ok(receiver_stream);
-                        }
-                    }
-                }
-                sleep(Duration::from_millis(5)).await;
-            }
-        } else {
+        if let Some(failed_pod_hash) = failed_pod_hash {
             let (tx, rx) = mpsc::channel(10);
             tokio::spawn({
                 let kv_store = self.kv_store.clone();
                 let request_id = id.to_string();
-                let pod_hash = pod_hash.to_string();
                 let cln_token = self.cln_token.clone();
                 async move {
                     Self::stream_historic_responses(
                         kv_store,
                         &request_id,
-                        &pod_hash,
+                        &failed_pod_hash,
                         tx,
                         cln_token,
                     )
@@ -535,6 +545,19 @@ impl DataStore for JetStreamDataStore {
                 }
             });
             Ok(ReceiverStream::new(rx))
+        } else {
+            // we need to wait for the start processing marker entry to be processed by the central watcher
+            loop {
+                {
+                    let mut response_map = self.responses_map.lock().await;
+                    if let Some(ResponseMode::Stream { rx, .. }) = response_map.get_mut(id) {
+                        if let Some(receiver_stream) = rx.take() {
+                            return Ok(receiver_stream);
+                        }
+                    }
+                }
+                sleep(Duration::from_millis(5)).await;
+            }
         }
     }
 
@@ -651,7 +674,7 @@ mod tests {
         let payload = Bytes::from_static(b"test_payload");
         store.kv_store.put(key, payload.clone()).await.unwrap();
 
-        let mut stream = store.stream_data(id, pod_hash).await.unwrap();
+        let mut stream = store.stream_data(id, None).await.unwrap();
 
         // Verify that the response is received
         let received_response = stream.next().await.unwrap();
@@ -710,7 +733,10 @@ mod tests {
         let done_key = format!("rs.{other_pod_hash}.{id}.done.processing");
         store.kv_store.put(done_key, Bytes::new()).await.unwrap();
 
-        let result = store.retrieve_data(id, Some(other_pod_hash)).await.unwrap();
+        let result = store
+            .retrieve_data(id, Some(other_pod_hash.to_string()))
+            .await
+            .unwrap();
         assert!(result.len() > 0);
         assert_eq!(result[0], b"test_payload");
 
@@ -766,7 +792,10 @@ mod tests {
         let done_key = format!("rs.{other_pod_hash}.{id}.done.processing");
         store.kv_store.put(done_key, Bytes::new()).await.unwrap();
 
-        let mut stream = store.stream_data(id, other_pod_hash).await.unwrap();
+        let mut stream = store
+            .stream_data(id, Some(other_pod_hash.to_string()))
+            .await
+            .unwrap();
 
         let received_response = stream.next().await.unwrap();
         assert_eq!(
diff --git a/rust/serving/src/app/store/datastore/user_defined.rs b/rust/serving/src/app/store/datastore/user_defined.rs
index 112e3637..b02623a9 100644
--- a/rust/serving/src/app/store/datastore/user_defined.rs
+++ b/rust/serving/src/app/store/datastore/user_defined.rs
@@ -37,7 +37,7 @@ impl DataStore for UserDefinedStore {
     async fn retrieve_data(
         &mut self,
         id: &str,
-        _pod_hash: Option<&str>,
+        _pod_hash: Option<String>,
     ) -> StoreResult<Vec<Vec<u8>>> {
         let request = GetRequest { id: id.to_string() };
         let response = self
@@ -52,7 +52,7 @@ impl DataStore for UserDefinedStore {
     async fn stream_data(
         &mut self,
         _id: &str,
-        _pod_hash: &str,
+        _pod_hash: Option<String>,
     ) -> StoreResult<ReceiverStream<Arc<Bytes>>> {
         unimplemented!("stream_response is not supported for UserDefinedStore")
     }
diff --git a/rust/serving/src/app/store/status.rs b/rust/serving/src/app/store/status.rs
index 55ffaceb..724c0255 100644
--- a/rust/serving/src/app/store/status.rs
+++ b/rust/serving/src/app/store/status.rs
@@ -76,7 +76,7 @@ impl TryFrom<ProcessingStatus> for Bytes {
 /// StatusTracker is responsible for tracking the status of requests in the KV store.
 #[derive(Clone)]
 pub(crate) struct StatusTracker {
-    pod_hash: String,
+    pod_hash: &'static str,
     status_kv: Store,
     /// Optional response kv store to write start and done processing marker. For user defined store,
     /// this is not used.
@@ -86,8 +86,8 @@ pub(crate) struct StatusTracker {
 impl StatusTracker {
     pub(crate) async fn new(
         js_context: Context,
-        status_bucket: &str,
-        pod_hash: String,
+        status_bucket: &'static str,
+        pod_hash: &'static str,
         response_bucket: Option<String>,
     ) -> Result<Self> {
         let status_kv = js_context.get_key_value(status_bucket).await.map_err(|e| {
@@ -121,7 +121,7 @@ impl StatusTracker {
     pub(crate) async fn register(&self, id: &str, request_type: RequestType) -> Result<()> {
         let status_key = format!("{}.{}", STATUS_KEY_PREFIX, id);
         let initial_status = ProcessingStatus::InProgress {
-            pod_hash: self.pod_hash.clone(),
+            pod_hash: self.pod_hash.to_string(),
         };
 
         match self
@@ -255,7 +255,7 @@ impl StatusTracker {
         info!(id, replica_id = ?self.pod_hash, error, "Marking request as failed");
         let failed_status = ProcessingStatus::Failed {
             error: error.to_string(),
-            pod_hash: self.pod_hash.clone(),
+            pod_hash: self.pod_hash.to_string(),
         };
         self.update_status(id, failed_status).await
     }
@@ -276,10 +276,17 @@ impl StatusTracker {
     /// Deregister marks the request as completed in the status kv store, it also (unlike registed)
     /// writes a done processing marker to the response kv store (if nats is used) to signal the
     /// response watcher.
-    pub(crate) async fn deregister(&self, id: &str, subgraph: &str) -> Result<()> {
+    pub(crate) async fn deregister(
+        &self,
+        id: &str,
+        subgraph: &str,
+        pod_hash: Option<String>,
+    ) -> Result<()> {
+        let pod_hash = pod_hash.unwrap_or(self.pod_hash.to_string());
+
         let completed_status = ProcessingStatus::Completed {
             subgraph: subgraph.to_string(),
-            pod_hash: self.pod_hash.clone(),
+            pod_hash: pod_hash.clone(),
         };
 
         self.update_status(id, completed_status).await?;
@@ -293,7 +300,7 @@ impl StatusTracker {
         // lifecycle of the request, we need to do it here.
         let done_key = format!(
             "{}.{}.{}.{}",
-            RESPONSE_KEY_PREFIX, self.pod_hash, id, DONE_PROCESSING_MARKER
+            RESPONSE_KEY_PREFIX, pod_hash, id, DONE_PROCESSING_MARKER
         );
         response_kv
             .put(done_key.clone(), Bytes::new())
@@ -379,7 +386,7 @@ mod tests {
         let mut tracker = StatusTracker::new(
             context.clone(),
             status_bucket,
-            "test_pod".to_string(),
+            "test_pod",
             Some(response_bucket.to_string()),
         )
         .await
@@ -435,10 +442,9 @@ mod tests {
             .await
             .unwrap();
 
-        let tracker =
-            StatusTracker::new(context.clone(), status_bucket, "test_pod".to_string(), None)
-                .await
-                .unwrap();
+        let tracker = StatusTracker::new(context.clone(), status_bucket, "test_pod", None)
+            .await
+            .unwrap();
 
         let request_id = "test_request";
         tracker
@@ -475,10 +481,9 @@ mod tests {
             .await
             .unwrap();
 
-        let mut tracker =
-            StatusTracker::new(context.clone(), status_bucket, "test_pod".to_string(), None)
-                .await
-                .unwrap();
+        let mut tracker = StatusTracker::new(context.clone(), status_bucket, "test_pod", None)
+            .await
+            .unwrap();
 
         let request_id = "test_request";
         tracker
@@ -540,7 +545,7 @@ mod tests {
         let mut tracker = StatusTracker::new(
             context.clone(),
             status_bucket,
-            "test_pod".to_string(),
+            "test_pod",
             Some(response_bucket.to_string()),
         )
         .await
@@ -553,7 +558,7 @@ mod tests {
             .expect("Failed to register request");
 
         tracker
-            .deregister(request_id, "test_subgraph")
+            .deregister(request_id, "test_subgraph", None)
             .await
             .expect("Failed to deregister request");
 
@@ -610,7 +615,7 @@ mod tests {
         let mut tracker = StatusTracker::new(
             context.clone(),
             status_bucket,
-            "test_pod".to_string(),
+            "test_pod",
             Some(response_bucket.to_string()),
         )
         .await
@@ -666,10 +671,9 @@ mod tests {
             .await
             .unwrap();
 
-        let tracker =
-            StatusTracker::new(context.clone(), status_bucket, "test_pod".to_string(), None)
-                .await
-                .unwrap();
+        let tracker = StatusTracker::new(context.clone(), status_bucket, "test_pod", None)
+            .await
+            .unwrap();
 
         let request_id = "test_request";
 
diff --git a/rust/serving/src/app/tracker.rs b/rust/serving/src/app/tracker.rs
index 2a63d484..ea6a54f1 100644
--- a/rust/serving/src/app/tracker.rs
+++ b/rust/serving/src/app/tracker.rs
@@ -228,7 +228,7 @@ impl MessageGraph {
                         // If there are no conditions or tags, default to true (i.e., proceed with the edge)
                         // If there are tags, compare the tags with the current callback's tags and the operator
                         // to decide if we should proceed with the edge.
-                        .map_or(true, |tags| {
+                        .is_none_or(|tags| {
                             response
                                 .tags
                                 .as_ref()
diff --git a/rust/serving/src/config.rs b/rust/serving/src/config.rs
index 0ea20c19..c7b7df2f 100644
--- a/rust/serving/src/config.rs
+++ b/rust/serving/src/config.rs
@@ -76,21 +76,21 @@ impl Default for UserDefinedStoreConfig {
 pub struct Settings {
     /// The HTTP header used to communicate to the client about the unique id assigned for a request in the store
     /// The client may also set the value of this header when sending the payload.
-    pub tid_header: String,
-    pub pod_hash: String,
+    pub tid_header: &'static str,
+    pub pod_hash: &'static str,
     pub app_listen_port: u16,
     pub metrics_server_listen_port: u16,
-    pub upstream_addr: String,
+    pub upstream_addr: &'static str,
     pub drain_timeout_secs: u64,
     pub store_type: StoreType,
-    pub js_callback_store: String,
-    pub js_response_store: String,
-    pub js_status_store: String,
+    pub js_callback_store: &'static str,
+    pub js_response_store: &'static str,
+    pub js_status_store: &'static str,
     pub api_auth_token: Option<String>,
     pub pipeline_spec: PipelineDCG,
     pub nats_basic_auth: Option<(String, String)>,
-    pub js_message_stream: String,
-    pub jetstream_url: String,
+    pub js_message_stream: &'static str,
+    pub jetstream_url: &'static str,
 }
 
 #[derive(Default, Debug, Deserialize, Clone, PartialEq)]
@@ -103,21 +103,21 @@ pub enum StoreType {
 impl Default for Settings {
     fn default() -> Self {
         Self {
-            tid_header: DEFAULT_ID_HEADER.to_owned(),
-            pod_hash: "0".to_owned(),
+            tid_header: DEFAULT_ID_HEADER,
+            pod_hash: "0",
             app_listen_port: 3000,
             metrics_server_listen_port: 3001,
-            upstream_addr: "localhost:8888".to_owned(),
+            upstream_addr: "localhost:8888",
             drain_timeout_secs: 600,
             store_type: StoreType::default(),
-            js_callback_store: "callback-kv".to_owned(),
-            js_response_store: "response-kv".to_owned(),
-            js_status_store: "status-kv".to_owned(),
+            js_callback_store: "callback-kv",
+            js_response_store: "response-kv",
+            js_status_store: "status-kv",
             api_auth_token: None,
             pipeline_spec: Default::default(),
             nats_basic_auth: None,
-            js_message_stream: "test-stream".into(),
-            jetstream_url: "localhost:4222".into(),
+            js_message_stream: "test-stream",
+            jetstream_url: "localhost:4222",
         }
     }
 }
@@ -238,12 +238,12 @@ impl TryFrom<HashMap<String, String>> for Settings {
 
         let mut settings = Settings {
             pipeline_spec,
-            js_callback_store: js_cb_store.into(),
+            js_callback_store: Box::leak(js_cb_store.clone().into_boxed_str()),
             nats_basic_auth,
-            js_message_stream: js_source_spec.stream,
-            jetstream_url: js_source_spec.url,
-            js_response_store: js_response_store.into(),
-            js_status_store: js_status_store.into(),
+            js_message_stream: Box::leak(js_source_spec.stream.into_boxed_str()),
+            jetstream_url: Box::leak(js_source_spec.url.into_boxed_str()),
+            js_response_store: Box::leak(js_response_store.to_string().into_boxed_str()),
+            js_status_store: Box::leak(js_status_store.to_string().into_boxed_str()),
             ..Default::default()
         };
 
@@ -279,14 +279,17 @@ impl TryFrom<HashMap<String, String>> for Settings {
             StoreType::Nats
         };
 
-        settings.tid_header = serving_server_settings.msg_id_header_key;
-        settings.pod_hash = env_vars
-            .get(ENV_NUMAFLOW_POD)
-            .unwrap()
-            .split('-')
-            .last()
-            .unwrap_or("0")
-            .to_string();
+        settings.tid_header = Box::leak(serving_server_settings.msg_id_header_key.into_boxed_str());
+        settings.pod_hash = Box::leak(
+            env_vars
+                .get(ENV_NUMAFLOW_POD)
+                .unwrap()
+                .split('-')
+                .next_back()
+                .unwrap_or("0")
+                .to_string()
+                .into_boxed_str(),
+        );
 
         settings.drain_timeout_secs = serving_server_settings
             .request_timeout_seconds
diff --git a/rust/serving/src/lib.rs b/rust/serving/src/lib.rs
index 0095730f..6e9cf7ca 100644
--- a/rust/serving/src/lib.rs
+++ b/rust/serving/src/lib.rs
@@ -119,8 +119,8 @@ async fn start(js_context: Context, settings: Arc<Settings>) -> Result<()> {
     // create a callback store for tracking
     let callback_store = JetStreamCallbackStore::new(
         js_context.clone(),
-        &settings.pod_hash,
-        &settings.js_callback_store,
+        settings.pod_hash,
+        settings.js_callback_store,
         cancel_token.clone(),
     )
     .await?;
@@ -138,26 +138,20 @@ async fn start(js_context: Context, settings: Arc<Settings>) -> Result<()> {
         StoreType::Nats => {
             let nats_store = JetStreamDataStore::new(
                 js_context.clone(),
-                &settings.js_response_store,
-                &settings.pod_hash,
+                settings.js_response_store,
+                settings.pod_hash,
                 cancel_token.clone(),
             )
             .await?;
             let status_tracker = StatusTracker::new(
                 js_context.clone(),
-                &settings.js_status_store,
-                settings.pod_hash.clone(),
+                settings.js_status_store,
+                settings.pod_hash,
                 Some(settings.js_response_store.to_string()),
             )
             .await?;
-            let callback_state = CallbackState::new(
-                &settings.pod_hash,
-                msg_graph,
-                nats_store,
-                callback_store,
-                status_tracker,
-            )
-            .await?;
+            let callback_state =
+                CallbackState::new(msg_graph, nats_store, callback_store, status_tracker).await?;
             let app = AppState {
                 js_context,
                 settings,
@@ -172,20 +166,14 @@ async fn start(js_context: Context, settings: Arc<Settings>) -> Result<()> {
         StoreType::UserDefined(ud_config) => {
             let status_tracker = StatusTracker::new(
                 js_context.clone(),
-                &settings.js_status_store,
-                settings.pod_hash.clone(),
+                settings.js_status_store,
+                settings.pod_hash,
                 None,
             )
             .await?;
             let ud_store = UserDefinedStore::new(ud_config.clone()).await?;
-            let callback_state = CallbackState::new(
-                &settings.pod_hash,
-                msg_graph,
-                ud_store,
-                callback_store,
-                status_tracker,
-            )
-            .await?;
+            let callback_state =
+                CallbackState::new(msg_graph, ud_store, callback_store, status_tracker).await?;
             let app = AppState {
                 js_context,
                 settings,



Test patch:
diff --git a/pkg/apis/numaflow/v1alpha1/serving_pipeline_types_test.go b/pkg/apis/numaflow/v1alpha1/serving_pipeline_types_test.go
index 68b5465d..fae44356 100644
--- a/pkg/apis/numaflow/v1alpha1/serving_pipeline_types_test.go
+++ b/pkg/apis/numaflow/v1alpha1/serving_pipeline_types_test.go
@@ -228,6 +228,12 @@ func Test_GetPipelineObj(t *testing.T) {
 				},
 			},
 			Serving: ServingSpec{
+				AbstractPodTemplate: AbstractPodTemplate{
+					Metadata: &Metadata{
+						Labels:      map[string]string{"a": "b"},
+						Annotations: map[string]string{"e": "f"},
+					},
+				},
 				Service: true,
 				ContainerTemplate: &ContainerTemplate{
 					Env: []corev1.EnvVar{{Name: "TEST_ENV", Value: "test-value"}},
@@ -271,7 +277,7 @@ func Test_GetPipelineObj(t *testing.T) {
 
 	// Validate environment variables
 	envVars := sourceVertex.ContainerTemplate.Env
-	assert.Contains(t, envVars, corev1.EnvVar{Name: "NUMAFLOW_SERVING_SOURCE_SETTINGS", Value: "eyJhdXRoIjpudWxsLCJzZXJ2aWNlIjp0cnVlLCJtc2dJREhlYWRlcktleSI6bnVsbCwiY29udGFpbmVyVGVtcGxhdGUiOnsicmVzb3VyY2VzIjp7InJlcXVlc3RzIjp7Im1lbW9yeSI6IjE5NDJNaSJ9fSwiZW52IjpbeyJuYW1lIjoiVEVTVF9FTlYiLCJ2YWx1ZSI6InRlc3QtdmFsdWUifV19fQ=="})
+	assert.Contains(t, envVars, corev1.EnvVar{Name: "NUMAFLOW_SERVING_SOURCE_SETTINGS", Value: "eyJhdXRoIjpudWxsLCJzZXJ2aWNlIjp0cnVlLCJtc2dJREhlYWRlcktleSI6bnVsbCwiY29udGFpbmVyVGVtcGxhdGUiOnsicmVzb3VyY2VzIjp7InJlcXVlc3RzIjp7Im1lbW9yeSI6IjE5NDJNaSJ9fSwiZW52IjpbeyJuYW1lIjoiVEVTVF9FTlYiLCJ2YWx1ZSI6InRlc3QtdmFsdWUifV19LCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJlIjoiZiJ9LCJsYWJlbHMiOnsiYSI6ImIifX19"})
 	assert.Contains(t, envVars, corev1.EnvVar{Name: "NUMAFLOW_SERVING_CALLBACK_STORE", Value: "serving-store-test-serving-pipeline_SERVING_CALLBACK_STORE"})
 	assert.Contains(t, envVars, corev1.EnvVar{Name: "NUMAFLOW_SERVING_RESPONSE_STORE", Value: "serving-store-test-serving-pipeline_SERVING_RESPONSE_STORE"})
 	assert.Contains(t, envVars, corev1.EnvVar{Name: "NUMAFLOW_SERVING_STATUS_STORE", Value: "serving-store-test-serving-pipeline_SERVING_STATUS_STORE"})
@@ -285,4 +291,6 @@ func Test_GetPipelineObj(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Contains(t, deploy.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{Name: "TEST_ENV", Value: "test-value"})
 	assert.Equal(t, deploy.Spec.Template.Spec.Containers[0].Resources.Requests.Memory().String(), "1942Mi")
+	assert.Equal(t, "b", deploy.Spec.Template.Labels["a"])
+	assert.Equal(t, "f", deploy.Spec.Template.Annotations["e"])
 }
diff --git a/pkg/sources/forward/data_forward_test.go b/pkg/sources/forward/data_forward_test.go
index 3eac0869..58c01eb8 100644
--- a/pkg/sources/forward/data_forward_test.go
+++ b/pkg/sources/forward/data_forward_test.go
@@ -732,6 +732,18 @@ func TestNewDataForward(t *testing.T) {
 			assert.Equal(t, make([]error, batchSize), errs)
 			assert.True(t, to1.IsEmpty())
 
+			// iterate to see whether metrics will eventually succeed
+			err = validateTransformerErrorMetrics()
+			for err != nil {
+				select {
+				case <-ctx.Done():
+					t.Errorf("failed waiting metrics collection to succeed [%s] (%s)", ctx.Err(), err)
+				default:
+					time.Sleep(10 * time.Millisecond)
+					err = validateTransformerErrorMetrics()
+				}
+			}
+
 			f.Stop()
 			time.Sleep(1 * time.Millisecond)
 
@@ -1235,6 +1247,30 @@ func validateMetrics(batchSize int64) (err error) {
 		return err
 	}
 
+	transformerReadMetadata := `
+		# HELP source_forwarder_transformer_read_total Total number of Messages Read by source transformer
+		# TYPE source_forwarder_transformer_read_total counter
+		`
+	transformerReadExpected := `
+		source_forwarder_transformer_read_total{partition_name="from",pipeline="testPipeline",replica="0",vertex="testVertex",vertex_type="Source"} ` + fmt.Sprintf("%f", float64(batchSize)) + `
+		`
+	err = testutil.CollectAndCompare(metrics.SourceTransformerReadMessagesCount, strings.NewReader(transformerReadMetadata+transformerReadExpected), "source_forwarder_transformer_read_total")
+	if err != nil {
+		return err
+	}
+
+	transformerWriteMetadata := `
+		# HELP source_forwarder_transformer_write_total Total number of Messages Written by source transformer
+		# TYPE source_forwarder_transformer_write_total counter
+		`
+	transformerWriteExpected := `
+		source_forwarder_transformer_write_total{partition_name="from",pipeline="testPipeline",replica="0",vertex="testVertex",vertex_type="Source"} ` + fmt.Sprintf("%f", float64(batchSize)) + `
+		`
+	err = testutil.CollectAndCompare(metrics.SourceTransformerWriteMessagesCount, strings.NewReader(transformerWriteMetadata+transformerWriteExpected), "source_forwarder_transformer_write_total")
+	if err != nil {
+		return err
+	}
+
 	writeMetadata := `
 		# HELP forwarder_write_total Total number of Messages Written
 		# TYPE forwarder_write_total counter
@@ -1273,8 +1309,27 @@ func validateMetrics(batchSize int64) (err error) {
 	return nil
 }
 
+func validateTransformerErrorMetrics() (err error) {
+	metadata := `
+		# HELP source_forwarder_transformer_error_total Total number of source transformer Errors
+		# TYPE source_forwarder_transformer_error_total counter
+		`
+	expected := `
+		source_forwarder_transformer_error_total{partition_name="from",pipeline="testPipeline",replica="0",vertex="testVertex",vertex_type="Source"} ` + fmt.Sprintf("%f", float64(1)) + `
+		`
+	err = testutil.CollectAndCompare(metrics.SourceTransformerError, strings.NewReader(metadata+expected), "source_forwarder_transformer_error_total")
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
 func metricsReset() {
 	metrics.ReadMessagesCount.Reset()
+	metrics.SourceTransformerReadMessagesCount.Reset()
+	metrics.SourceTransformerWriteMessagesCount.Reset()
+	metrics.SourceTransformerError.Reset()
 	metrics.WriteMessagesCount.Reset()
 	metrics.AckMessagesCount.Reset()
 }