1use bytes::{Buf, BufMut};
4
5use crate::primitives::fixed::{get_i16, get_i32, get_i64, put_i16, put_i32, put_i64};
6use crate::primitives::string_bytes::{
7 compact_nullable_string_len, compact_string_len, get_compact_nullable_string_owned,
8 get_compact_string_owned, get_nullable_string_owned, get_string_owned, nullable_string_len,
9 put_compact_nullable_string, put_compact_string, put_nullable_string, put_string, string_len,
10};
11use crate::tagged_fields::{
12 WriteTaggedFields, encode_to_bytes, read_tagged_fields, tagged_fields_len,
13};
14use crate::{Decode, Encode, ProtocolError, UnknownTaggedFields};
15
16pub const API_KEY: i16 = 0;
17pub const MIN_VERSION: i16 = 3;
18pub const MAX_VERSION: i16 = 13;
19pub const FLEXIBLE_MIN: i16 = 9;
20
21#[inline]
22fn is_flexible(version: i16) -> bool {
23 version >= FLEXIBLE_MIN
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Default)]
27pub struct ProduceResponse {
28 pub responses: Vec<TopicProduceResponse>,
29 pub throttle_time_ms: i32,
30 pub node_endpoints: Vec<NodeEndpoint>,
31 pub unknown_tagged_fields: UnknownTaggedFields,
32}
33impl Encode for ProduceResponse {
34 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
35 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
36 return Err(ProtocolError::UnsupportedVersion {
37 api_key: API_KEY,
38 version,
39 });
40 }
41 let flex = is_flexible(version);
42 if version >= 0 {
43 {
44 crate::primitives::array::put_array_len(buf, (self.responses).len(), flex);
45 for it in &self.responses {
46 it.encode(buf, version)?;
47 }
48 }
49 }
50 if version >= 1 {
51 put_i32(buf, self.throttle_time_ms);
52 }
53 if flex {
54 let mut tagged = WriteTaggedFields::new();
55 if !(crate::codegen_helpers::is_default(&self.node_endpoints)) {
56 let payload = encode_to_bytes(
57 {
58 let prefix = crate::primitives::array::array_len_prefix_len(
59 (self.node_endpoints).len(),
60 flex,
61 );
62 let body: usize = (self.node_endpoints)
63 .iter()
64 .map(|it| it.encoded_len(version))
65 .sum();
66 prefix + body
67 },
68 |b| {
69 {
70 crate::primitives::array::put_array_len(
71 b,
72 (self.node_endpoints).len(),
73 flex,
74 );
75 for it in &self.node_endpoints {
76 it.encode(b, version)?;
77 }
78 };
79 Ok(())
80 },
81 );
82 tagged.add(0, payload);
83 }
84 tagged.write(buf, &self.unknown_tagged_fields);
85 }
86 Ok(())
87 }
88 fn encoded_len(&self, version: i16) -> usize {
89 let flex = is_flexible(version);
90 let mut n: usize = 0;
91 if version >= 0 {
92 n += {
93 let prefix =
94 crate::primitives::array::array_len_prefix_len((self.responses).len(), flex);
95 let body: usize = (self.responses)
96 .iter()
97 .map(|it| it.encoded_len(version))
98 .sum();
99 prefix + body
100 };
101 }
102 if version >= 1 {
103 n += 4;
104 }
105 if flex {
106 let mut known_pairs: Vec<(u32, usize)> = Vec::new();
107 if !(crate::codegen_helpers::is_default(&self.node_endpoints)) {
108 known_pairs.push((0, {
109 let prefix = crate::primitives::array::array_len_prefix_len(
110 (self.node_endpoints).len(),
111 flex,
112 );
113 let body: usize = (self.node_endpoints)
114 .iter()
115 .map(|it| it.encoded_len(version))
116 .sum();
117 prefix + body
118 }));
119 }
120 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
121 }
122 n
123 }
124}
125impl Decode<'_> for ProduceResponse {
126 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
127 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
128 return Err(ProtocolError::UnsupportedVersion {
129 api_key: API_KEY,
130 version,
131 });
132 }
133 let flex = is_flexible(version);
134 let mut out = Self::default();
135 if version >= 0 {
136 out.responses = {
137 let n = crate::primitives::array::get_array_len(buf, flex)?;
138 let mut v = Vec::with_capacity(n);
139 for _ in 0..n {
140 v.push(TopicProduceResponse::decode(buf, version)?);
141 }
142 v
143 };
144 }
145 if version >= 1 {
146 out.throttle_time_ms = get_i32(buf)?;
147 }
148 if flex {
149 let mut tag_node_endpoints = None;
150 out.unknown_tagged_fields = read_tagged_fields(buf, |tag, payload| match tag {
151 0 => {
152 tag_node_endpoints = Some({
153 let b: &mut &[u8] = payload;
154 {
155 let n = crate::primitives::array::get_array_len(b, flex)?;
156 let mut v = Vec::with_capacity(n);
157 for _ in 0..n {
158 v.push(NodeEndpoint::decode(b, version)?);
159 }
160 v
161 }
162 });
163 Ok(true)
164 }
165 _ => Ok(false),
166 })?;
167 if let Some(v) = tag_node_endpoints {
168 out.node_endpoints = v;
169 }
170 }
171 Ok(out)
172 }
173}
174#[cfg(test)]
175impl ProduceResponse {
176 #[must_use]
177 pub fn populated(version: i16) -> Self {
178 let mut m = Self::default();
179 if version >= 0 {
180 m.responses = vec![TopicProduceResponse::populated(version)];
181 }
182 if version >= 1 {
183 m.throttle_time_ms = 1i32;
184 }
185 if version >= 10 {
186 m.node_endpoints = vec![NodeEndpoint::populated(version)];
187 }
188 m
189 }
190}
191#[derive(Debug, Clone, PartialEq, Eq, Default)]
192pub struct TopicProduceResponse {
193 pub name: String,
194 pub topic_id: crate::primitives::uuid::Uuid,
195 pub partition_responses: Vec<PartitionProduceResponse>,
196 pub unknown_tagged_fields: UnknownTaggedFields,
197}
198impl Encode for TopicProduceResponse {
199 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
200 let flex = version >= 9;
201 if (0..=12).contains(&version) {
202 if flex {
203 put_compact_string(buf, &self.name);
204 } else {
205 put_string(buf, &self.name);
206 }
207 }
208 if version >= 13 {
209 crate::primitives::uuid::put_uuid(buf, self.topic_id);
210 }
211 if version >= 0 {
212 {
213 crate::primitives::array::put_array_len(
214 buf,
215 (self.partition_responses).len(),
216 flex,
217 );
218 for it in &self.partition_responses {
219 it.encode(buf, version)?;
220 }
221 }
222 }
223 if flex {
224 let tagged = WriteTaggedFields::new();
225 tagged.write(buf, &self.unknown_tagged_fields);
226 }
227 Ok(())
228 }
229 fn encoded_len(&self, version: i16) -> usize {
230 let flex = version >= 9;
231 let mut n: usize = 0;
232 if (0..=12).contains(&version) {
233 n += if flex {
234 compact_string_len(&self.name)
235 } else {
236 string_len(&self.name)
237 };
238 }
239 if version >= 13 {
240 n += 16;
241 }
242 if version >= 0 {
243 n += {
244 let prefix = crate::primitives::array::array_len_prefix_len(
245 (self.partition_responses).len(),
246 flex,
247 );
248 let body: usize = (self.partition_responses)
249 .iter()
250 .map(|it| it.encoded_len(version))
251 .sum();
252 prefix + body
253 };
254 }
255 if flex {
256 let known_pairs: Vec<(u32, usize)> = Vec::new();
257 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
258 }
259 n
260 }
261}
262impl Decode<'_> for TopicProduceResponse {
263 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
264 let flex = version >= 9;
265 let mut out = Self::default();
266 if (0..=12).contains(&version) {
267 out.name = if flex {
268 get_compact_string_owned(buf)?
269 } else {
270 get_string_owned(buf)?
271 };
272 }
273 if version >= 13 {
274 out.topic_id = crate::primitives::uuid::get_uuid(buf)?;
275 }
276 if version >= 0 {
277 out.partition_responses = {
278 let n = crate::primitives::array::get_array_len(buf, flex)?;
279 let mut v = Vec::with_capacity(n);
280 for _ in 0..n {
281 v.push(PartitionProduceResponse::decode(buf, version)?);
282 }
283 v
284 };
285 }
286 if flex {
287 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
288 }
289 Ok(out)
290 }
291}
292#[cfg(test)]
293impl TopicProduceResponse {
294 #[must_use]
295 pub fn populated(version: i16) -> Self {
296 let mut m = Self::default();
297 if (0..=12).contains(&version) {
298 m.name = "x".to_string();
299 }
300 if version >= 13 {
301 m.topic_id = crate::primitives::uuid::Uuid([1u8; 16]);
302 }
303 if version >= 0 {
304 m.partition_responses = vec![PartitionProduceResponse::populated(version)];
305 }
306 m
307 }
308}
309#[derive(Debug, Clone, PartialEq, Eq)]
310pub struct PartitionProduceResponse {
311 pub index: i32,
312 pub error_code: i16,
313 pub base_offset: i64,
314 pub log_append_time_ms: i64,
315 pub log_start_offset: i64,
316 pub record_errors: Vec<BatchIndexAndErrorMessage>,
317 pub error_message: Option<String>,
318 pub current_leader: LeaderIdAndEpoch,
319 pub unknown_tagged_fields: UnknownTaggedFields,
320}
321impl Default for PartitionProduceResponse {
322 fn default() -> Self {
323 Self {
324 index: 0i32,
325 error_code: 0i16,
326 base_offset: 0i64,
327 log_append_time_ms: -1i64,
328 log_start_offset: -1i64,
329 record_errors: Vec::new(),
330 error_message: None,
331 current_leader: Default::default(),
332 unknown_tagged_fields: Default::default(),
333 }
334 }
335}
336impl Encode for PartitionProduceResponse {
337 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
338 let flex = version >= 9;
339 if version >= 0 {
340 put_i32(buf, self.index);
341 }
342 if version >= 0 {
343 put_i16(buf, self.error_code);
344 }
345 if version >= 0 {
346 put_i64(buf, self.base_offset);
347 }
348 if version >= 2 {
349 put_i64(buf, self.log_append_time_ms);
350 }
351 if version >= 5 {
352 put_i64(buf, self.log_start_offset);
353 }
354 if version >= 8 {
355 {
356 crate::primitives::array::put_array_len(buf, (self.record_errors).len(), flex);
357 for it in &self.record_errors {
358 it.encode(buf, version)?;
359 }
360 }
361 }
362 if version >= 8 {
363 if flex {
364 put_compact_nullable_string(buf, self.error_message.as_deref());
365 } else {
366 put_nullable_string(buf, self.error_message.as_deref());
367 }
368 }
369 if flex {
370 let mut tagged = WriteTaggedFields::new();
371 if !(crate::codegen_helpers::is_default(&self.current_leader)) {
372 let payload = encode_to_bytes(self.current_leader.encoded_len(version), |b| {
373 self.current_leader.encode(b, version)?;
374 Ok(())
375 });
376 tagged.add(0, payload);
377 }
378 tagged.write(buf, &self.unknown_tagged_fields);
379 }
380 Ok(())
381 }
382 fn encoded_len(&self, version: i16) -> usize {
383 let flex = version >= 9;
384 let mut n: usize = 0;
385 if version >= 0 {
386 n += 4;
387 }
388 if version >= 0 {
389 n += 2;
390 }
391 if version >= 0 {
392 n += 8;
393 }
394 if version >= 2 {
395 n += 8;
396 }
397 if version >= 5 {
398 n += 8;
399 }
400 if version >= 8 {
401 n += {
402 let prefix = crate::primitives::array::array_len_prefix_len(
403 (self.record_errors).len(),
404 flex,
405 );
406 let body: usize = (self.record_errors)
407 .iter()
408 .map(|it| it.encoded_len(version))
409 .sum();
410 prefix + body
411 };
412 }
413 if version >= 8 {
414 n += if flex {
415 compact_nullable_string_len(self.error_message.as_deref())
416 } else {
417 nullable_string_len(self.error_message.as_deref())
418 };
419 }
420 if flex {
421 let mut known_pairs: Vec<(u32, usize)> = Vec::new();
422 if !(crate::codegen_helpers::is_default(&self.current_leader)) {
423 known_pairs.push((0, self.current_leader.encoded_len(version)));
424 }
425 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
426 }
427 n
428 }
429}
430impl Decode<'_> for PartitionProduceResponse {
431 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
432 let flex = version >= 9;
433 let mut out = Self::default();
434 if version >= 0 {
435 out.index = get_i32(buf)?;
436 }
437 if version >= 0 {
438 out.error_code = get_i16(buf)?;
439 }
440 if version >= 0 {
441 out.base_offset = get_i64(buf)?;
442 }
443 if version >= 2 {
444 out.log_append_time_ms = get_i64(buf)?;
445 }
446 if version >= 5 {
447 out.log_start_offset = get_i64(buf)?;
448 }
449 if version >= 8 {
450 out.record_errors = {
451 let n = crate::primitives::array::get_array_len(buf, flex)?;
452 let mut v = Vec::with_capacity(n);
453 for _ in 0..n {
454 v.push(BatchIndexAndErrorMessage::decode(buf, version)?);
455 }
456 v
457 };
458 }
459 if version >= 8 {
460 out.error_message = if flex {
461 get_compact_nullable_string_owned(buf)?
462 } else {
463 get_nullable_string_owned(buf)?
464 };
465 }
466 if flex {
467 let mut tag_current_leader = None;
468 out.unknown_tagged_fields = read_tagged_fields(buf, |tag, payload| match tag {
469 0 => {
470 tag_current_leader = Some({
471 let b: &mut &[u8] = payload;
472 LeaderIdAndEpoch::decode(b, version)?
473 });
474 Ok(true)
475 }
476 _ => Ok(false),
477 })?;
478 if let Some(v) = tag_current_leader {
479 out.current_leader = v;
480 }
481 }
482 Ok(out)
483 }
484}
485#[cfg(test)]
486impl PartitionProduceResponse {
487 #[must_use]
488 pub fn populated(version: i16) -> Self {
489 let mut m = Self::default();
490 if version >= 0 {
491 m.index = 1i32;
492 }
493 if version >= 0 {
494 m.error_code = 1i16;
495 }
496 if version >= 0 {
497 m.base_offset = 1i64;
498 }
499 if version >= 2 {
500 m.log_append_time_ms = 1i64;
501 }
502 if version >= 5 {
503 m.log_start_offset = 1i64;
504 }
505 if version >= 8 {
506 m.record_errors = vec![BatchIndexAndErrorMessage::populated(version)];
507 }
508 if version >= 8 {
509 m.error_message = Some("x".to_string());
510 }
511 if version >= 10 {
512 m.current_leader = LeaderIdAndEpoch::populated(version);
513 }
514 m
515 }
516}
517#[derive(Debug, Clone, PartialEq, Eq, Default)]
518pub struct BatchIndexAndErrorMessage {
519 pub batch_index: i32,
520 pub batch_index_error_message: Option<String>,
521 pub unknown_tagged_fields: UnknownTaggedFields,
522}
523impl Encode for BatchIndexAndErrorMessage {
524 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
525 let flex = version >= 9;
526 if version >= 8 {
527 put_i32(buf, self.batch_index);
528 }
529 if version >= 8 {
530 if flex {
531 put_compact_nullable_string(buf, self.batch_index_error_message.as_deref());
532 } else {
533 put_nullable_string(buf, self.batch_index_error_message.as_deref());
534 }
535 }
536 if flex {
537 let tagged = WriteTaggedFields::new();
538 tagged.write(buf, &self.unknown_tagged_fields);
539 }
540 Ok(())
541 }
542 fn encoded_len(&self, version: i16) -> usize {
543 let flex = version >= 9;
544 let mut n: usize = 0;
545 if version >= 8 {
546 n += 4;
547 }
548 if version >= 8 {
549 n += if flex {
550 compact_nullable_string_len(self.batch_index_error_message.as_deref())
551 } else {
552 nullable_string_len(self.batch_index_error_message.as_deref())
553 };
554 }
555 if flex {
556 let known_pairs: Vec<(u32, usize)> = Vec::new();
557 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
558 }
559 n
560 }
561}
562impl Decode<'_> for BatchIndexAndErrorMessage {
563 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
564 let flex = version >= 9;
565 let mut out = Self::default();
566 if version >= 8 {
567 out.batch_index = get_i32(buf)?;
568 }
569 if version >= 8 {
570 out.batch_index_error_message = if flex {
571 get_compact_nullable_string_owned(buf)?
572 } else {
573 get_nullable_string_owned(buf)?
574 };
575 }
576 if flex {
577 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
578 }
579 Ok(out)
580 }
581}
582#[cfg(test)]
583impl BatchIndexAndErrorMessage {
584 #[must_use]
585 pub fn populated(version: i16) -> Self {
586 let mut m = Self::default();
587 if version >= 8 {
588 m.batch_index = 1i32;
589 }
590 if version >= 8 {
591 m.batch_index_error_message = Some("x".to_string());
592 }
593 m
594 }
595}
596#[derive(Debug, Clone, PartialEq, Eq)]
597pub struct LeaderIdAndEpoch {
598 pub leader_id: i32,
599 pub leader_epoch: i32,
600 pub unknown_tagged_fields: UnknownTaggedFields,
601}
602impl Default for LeaderIdAndEpoch {
603 fn default() -> Self {
604 Self {
605 leader_id: -1i32,
606 leader_epoch: -1i32,
607 unknown_tagged_fields: Default::default(),
608 }
609 }
610}
611impl Encode for LeaderIdAndEpoch {
612 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
613 let flex = version >= 9;
614 if version >= 10 {
615 put_i32(buf, self.leader_id);
616 }
617 if version >= 10 {
618 put_i32(buf, self.leader_epoch);
619 }
620 if flex {
621 let tagged = WriteTaggedFields::new();
622 tagged.write(buf, &self.unknown_tagged_fields);
623 }
624 Ok(())
625 }
626 fn encoded_len(&self, version: i16) -> usize {
627 let flex = version >= 9;
628 let mut n: usize = 0;
629 if version >= 10 {
630 n += 4;
631 }
632 if version >= 10 {
633 n += 4;
634 }
635 if flex {
636 let known_pairs: Vec<(u32, usize)> = Vec::new();
637 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
638 }
639 n
640 }
641}
642impl Decode<'_> for LeaderIdAndEpoch {
643 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
644 let flex = version >= 9;
645 let mut out = Self::default();
646 if version >= 10 {
647 out.leader_id = get_i32(buf)?;
648 }
649 if version >= 10 {
650 out.leader_epoch = get_i32(buf)?;
651 }
652 if flex {
653 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
654 }
655 Ok(out)
656 }
657}
658#[cfg(test)]
659impl LeaderIdAndEpoch {
660 #[must_use]
661 pub fn populated(version: i16) -> Self {
662 let mut m = Self::default();
663 if version >= 10 {
664 m.leader_id = 1i32;
665 }
666 if version >= 10 {
667 m.leader_epoch = 1i32;
668 }
669 m
670 }
671}
672#[derive(Debug, Clone, PartialEq, Eq, Default)]
673pub struct NodeEndpoint {
674 pub node_id: i32,
675 pub host: String,
676 pub port: i32,
677 pub rack: Option<String>,
678 pub unknown_tagged_fields: UnknownTaggedFields,
679}
680impl Encode for NodeEndpoint {
681 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
682 let flex = version >= 9;
683 if version >= 10 {
684 put_i32(buf, self.node_id);
685 }
686 if version >= 10 {
687 if flex {
688 put_compact_string(buf, &self.host);
689 } else {
690 put_string(buf, &self.host);
691 }
692 }
693 if version >= 10 {
694 put_i32(buf, self.port);
695 }
696 if version >= 10 {
697 if flex {
698 put_compact_nullable_string(buf, self.rack.as_deref());
699 } else {
700 put_nullable_string(buf, self.rack.as_deref());
701 }
702 }
703 if flex {
704 let tagged = WriteTaggedFields::new();
705 tagged.write(buf, &self.unknown_tagged_fields);
706 }
707 Ok(())
708 }
709 fn encoded_len(&self, version: i16) -> usize {
710 let flex = version >= 9;
711 let mut n: usize = 0;
712 if version >= 10 {
713 n += 4;
714 }
715 if version >= 10 {
716 n += if flex {
717 compact_string_len(&self.host)
718 } else {
719 string_len(&self.host)
720 };
721 }
722 if version >= 10 {
723 n += 4;
724 }
725 if version >= 10 {
726 n += if flex {
727 compact_nullable_string_len(self.rack.as_deref())
728 } else {
729 nullable_string_len(self.rack.as_deref())
730 };
731 }
732 if flex {
733 let known_pairs: Vec<(u32, usize)> = Vec::new();
734 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
735 }
736 n
737 }
738}
739impl Decode<'_> for NodeEndpoint {
740 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
741 let flex = version >= 9;
742 let mut out = Self::default();
743 if version >= 10 {
744 out.node_id = get_i32(buf)?;
745 }
746 if version >= 10 {
747 out.host = if flex {
748 get_compact_string_owned(buf)?
749 } else {
750 get_string_owned(buf)?
751 };
752 }
753 if version >= 10 {
754 out.port = get_i32(buf)?;
755 }
756 if version >= 10 {
757 out.rack = if flex {
758 get_compact_nullable_string_owned(buf)?
759 } else {
760 get_nullable_string_owned(buf)?
761 };
762 }
763 if flex {
764 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
765 }
766 Ok(out)
767 }
768}
769#[cfg(test)]
770impl NodeEndpoint {
771 #[must_use]
772 pub fn populated(version: i16) -> Self {
773 let mut m = Self::default();
774 if version >= 10 {
775 m.node_id = 1i32;
776 }
777 if version >= 10 {
778 m.host = "x".to_string();
779 }
780 if version >= 10 {
781 m.port = 1i32;
782 }
783 if version >= 10 {
784 m.rack = Some("x".to_string());
785 }
786 m
787 }
788}
789
790#[must_use]
793#[allow(unused_comparisons)]
794pub fn default_json(version: i16) -> ::serde_json::Value {
795 let mut obj = ::serde_json::Map::new();
796 obj.insert("responses".to_string(), ::serde_json::Value::Array(vec![]));
797 if version >= 1 {
798 obj.insert("throttleTimeMs".to_string(), ::serde_json::json!(0));
799 }
800 if version >= 10 {
801 obj.insert(
802 "nodeEndpoints".to_string(),
803 ::serde_json::Value::Array(vec![]),
804 );
805 }
806 ::serde_json::Value::Object(obj)
807}