glam/f64/
dmat2.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3use crate::{f64::math, swizzles::*, DMat3, DVec2, Mat2};
4use core::fmt;
5use core::iter::{Product, Sum};
6use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8/// Creates a 2x2 matrix from two column vectors.
9#[inline(always)]
10#[must_use]
11pub const fn dmat2(x_axis: DVec2, y_axis: DVec2) -> DMat2 {
12    DMat2::from_cols(x_axis, y_axis)
13}
14
15/// A 2x2 column major matrix.
16#[derive(Clone, Copy)]
17#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
18#[cfg_attr(feature = "cuda", repr(align(16)))]
19#[repr(C)]
20pub struct DMat2 {
21    pub x_axis: DVec2,
22    pub y_axis: DVec2,
23}
24
25impl DMat2 {
26    /// A 2x2 matrix with all elements set to `0.0`.
27    pub const ZERO: Self = Self::from_cols(DVec2::ZERO, DVec2::ZERO);
28
29    /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
30    pub const IDENTITY: Self = Self::from_cols(DVec2::X, DVec2::Y);
31
32    /// All NAN:s.
33    pub const NAN: Self = Self::from_cols(DVec2::NAN, DVec2::NAN);
34
35    #[allow(clippy::too_many_arguments)]
36    #[inline(always)]
37    #[must_use]
38    const fn new(m00: f64, m01: f64, m10: f64, m11: f64) -> Self {
39        Self {
40            x_axis: DVec2::new(m00, m01),
41            y_axis: DVec2::new(m10, m11),
42        }
43    }
44
45    /// Creates a 2x2 matrix from two column vectors.
46    #[inline(always)]
47    #[must_use]
48    pub const fn from_cols(x_axis: DVec2, y_axis: DVec2) -> Self {
49        Self { x_axis, y_axis }
50    }
51
52    /// Creates a 2x2 matrix from a `[f64; 4]` array stored in column major order.
53    /// If your data is stored in row major you will need to `transpose` the returned
54    /// matrix.
55    #[inline]
56    #[must_use]
57    pub const fn from_cols_array(m: &[f64; 4]) -> Self {
58        Self::new(m[0], m[1], m[2], m[3])
59    }
60
61    /// Creates a `[f64; 4]` array storing data in column major order.
62    /// If you require data in row major order `transpose` the matrix first.
63    #[inline]
64    #[must_use]
65    pub const fn to_cols_array(&self) -> [f64; 4] {
66        [self.x_axis.x, self.x_axis.y, self.y_axis.x, self.y_axis.y]
67    }
68
69    /// Creates a 2x2 matrix from a `[[f64; 2]; 2]` 2D array stored in column major order.
70    /// If your data is in row major order you will need to `transpose` the returned
71    /// matrix.
72    #[inline]
73    #[must_use]
74    pub const fn from_cols_array_2d(m: &[[f64; 2]; 2]) -> Self {
75        Self::from_cols(DVec2::from_array(m[0]), DVec2::from_array(m[1]))
76    }
77
78    /// Creates a `[[f64; 2]; 2]` 2D array storing data in column major order.
79    /// If you require data in row major order `transpose` the matrix first.
80    #[inline]
81    #[must_use]
82    pub const fn to_cols_array_2d(&self) -> [[f64; 2]; 2] {
83        [self.x_axis.to_array(), self.y_axis.to_array()]
84    }
85
86    /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
87    #[doc(alias = "scale")]
88    #[inline]
89    #[must_use]
90    pub const fn from_diagonal(diagonal: DVec2) -> Self {
91        Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
92    }
93
94    /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
95    /// `angle` (in radians).
96    #[inline]
97    #[must_use]
98    pub fn from_scale_angle(scale: DVec2, angle: f64) -> Self {
99        let (sin, cos) = math::sin_cos(angle);
100        Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
101    }
102
103    /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
104    #[inline]
105    #[must_use]
106    pub fn from_angle(angle: f64) -> Self {
107        let (sin, cos) = math::sin_cos(angle);
108        Self::new(cos, sin, -sin, cos)
109    }
110
111    /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
112    #[inline]
113    #[must_use]
114    pub fn from_mat3(m: DMat3) -> Self {
115        Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
116    }
117
118    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
119    /// and `j`th row.
120    ///
121    /// # Panics
122    ///
123    /// Panics if `i` or `j` is greater than 2.
124    #[inline]
125    #[must_use]
126    pub fn from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self {
127        match (i, j) {
128            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
129            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
130            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
131            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
132            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
133            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
134            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
135            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
136            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
137            _ => panic!("index out of bounds"),
138        }
139    }
140
141    /// Creates a 2x2 matrix from the first 4 values in `slice`.
142    ///
143    /// # Panics
144    ///
145    /// Panics if `slice` is less than 4 elements long.
146    #[inline]
147    #[must_use]
148    pub const fn from_cols_slice(slice: &[f64]) -> Self {
149        Self::new(slice[0], slice[1], slice[2], slice[3])
150    }
151
152    /// Writes the columns of `self` to the first 4 elements in `slice`.
153    ///
154    /// # Panics
155    ///
156    /// Panics if `slice` is less than 4 elements long.
157    #[inline]
158    pub fn write_cols_to_slice(self, slice: &mut [f64]) {
159        slice[0] = self.x_axis.x;
160        slice[1] = self.x_axis.y;
161        slice[2] = self.y_axis.x;
162        slice[3] = self.y_axis.y;
163    }
164
165    /// Returns the matrix column for the given `index`.
166    ///
167    /// # Panics
168    ///
169    /// Panics if `index` is greater than 1.
170    #[inline]
171    #[must_use]
172    pub fn col(&self, index: usize) -> DVec2 {
173        match index {
174            0 => self.x_axis,
175            1 => self.y_axis,
176            _ => panic!("index out of bounds"),
177        }
178    }
179
180    /// Returns a mutable reference to the matrix column for the given `index`.
181    ///
182    /// # Panics
183    ///
184    /// Panics if `index` is greater than 1.
185    #[inline]
186    pub fn col_mut(&mut self, index: usize) -> &mut DVec2 {
187        match index {
188            0 => &mut self.x_axis,
189            1 => &mut self.y_axis,
190            _ => panic!("index out of bounds"),
191        }
192    }
193
194    /// Returns the matrix row for the given `index`.
195    ///
196    /// # Panics
197    ///
198    /// Panics if `index` is greater than 1.
199    #[inline]
200    #[must_use]
201    pub fn row(&self, index: usize) -> DVec2 {
202        match index {
203            0 => DVec2::new(self.x_axis.x, self.y_axis.x),
204            1 => DVec2::new(self.x_axis.y, self.y_axis.y),
205            _ => panic!("index out of bounds"),
206        }
207    }
208
209    /// Returns `true` if, and only if, all elements are finite.
210    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
211    #[inline]
212    #[must_use]
213    pub fn is_finite(&self) -> bool {
214        self.x_axis.is_finite() && self.y_axis.is_finite()
215    }
216
217    /// Returns `true` if any elements are `NaN`.
218    #[inline]
219    #[must_use]
220    pub fn is_nan(&self) -> bool {
221        self.x_axis.is_nan() || self.y_axis.is_nan()
222    }
223
224    /// Returns the transpose of `self`.
225    #[inline]
226    #[must_use]
227    pub fn transpose(&self) -> Self {
228        Self {
229            x_axis: DVec2::new(self.x_axis.x, self.y_axis.x),
230            y_axis: DVec2::new(self.x_axis.y, self.y_axis.y),
231        }
232    }
233
234    /// Returns the determinant of `self`.
235    #[inline]
236    #[must_use]
237    pub fn determinant(&self) -> f64 {
238        self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
239    }
240
241    /// Returns the inverse of `self`.
242    ///
243    /// If the matrix is not invertible the returned matrix will be invalid.
244    ///
245    /// # Panics
246    ///
247    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
248    #[inline]
249    #[must_use]
250    pub fn inverse(&self) -> Self {
251        let inv_det = {
252            let det = self.determinant();
253            glam_assert!(det != 0.0);
254            det.recip()
255        };
256        Self::new(
257            self.y_axis.y * inv_det,
258            self.x_axis.y * -inv_det,
259            self.y_axis.x * -inv_det,
260            self.x_axis.x * inv_det,
261        )
262    }
263
264    /// Transforms a 2D vector.
265    #[inline]
266    #[must_use]
267    pub fn mul_vec2(&self, rhs: DVec2) -> DVec2 {
268        #[allow(clippy::suspicious_operation_groupings)]
269        DVec2::new(
270            (self.x_axis.x * rhs.x) + (self.y_axis.x * rhs.y),
271            (self.x_axis.y * rhs.x) + (self.y_axis.y * rhs.y),
272        )
273    }
274
275    /// Multiplies two 2x2 matrices.
276    #[inline]
277    #[must_use]
278    pub fn mul_mat2(&self, rhs: &Self) -> Self {
279        self.mul(rhs)
280    }
281
282    /// Adds two 2x2 matrices.
283    #[inline]
284    #[must_use]
285    pub fn add_mat2(&self, rhs: &Self) -> Self {
286        self.add(rhs)
287    }
288
289    /// Subtracts two 2x2 matrices.
290    #[inline]
291    #[must_use]
292    pub fn sub_mat2(&self, rhs: &Self) -> Self {
293        self.sub(rhs)
294    }
295
296    /// Multiplies a 2x2 matrix by a scalar.
297    #[inline]
298    #[must_use]
299    pub fn mul_scalar(&self, rhs: f64) -> Self {
300        Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs))
301    }
302
303    /// Divides a 2x2 matrix by a scalar.
304    #[inline]
305    #[must_use]
306    pub fn div_scalar(&self, rhs: f64) -> Self {
307        let rhs = DVec2::splat(rhs);
308        Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs))
309    }
310
311    /// Returns true if the absolute difference of all elements between `self` and `rhs`
312    /// is less than or equal to `max_abs_diff`.
313    ///
314    /// This can be used to compare if two matrices contain similar elements. It works best
315    /// when comparing with a known value. The `max_abs_diff` that should be used used
316    /// depends on the values being compared against.
317    ///
318    /// For more see
319    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
320    #[inline]
321    #[must_use]
322    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
323        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
324            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
325    }
326
327    /// Takes the absolute value of each element in `self`
328    #[inline]
329    #[must_use]
330    pub fn abs(&self) -> Self {
331        Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
332    }
333
334    #[inline]
335    pub fn as_mat2(&self) -> Mat2 {
336        Mat2::from_cols(self.x_axis.as_vec2(), self.y_axis.as_vec2())
337    }
338}
339
340impl Default for DMat2 {
341    #[inline]
342    fn default() -> Self {
343        Self::IDENTITY
344    }
345}
346
347impl Add for DMat2 {
348    type Output = Self;
349    #[inline]
350    fn add(self, rhs: Self) -> Self {
351        Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
352    }
353}
354
355impl Add<&Self> for DMat2 {
356    type Output = Self;
357    #[inline]
358    fn add(self, rhs: &Self) -> Self {
359        self.add(*rhs)
360    }
361}
362
363impl Add<&DMat2> for &DMat2 {
364    type Output = DMat2;
365    #[inline]
366    fn add(self, rhs: &DMat2) -> DMat2 {
367        (*self).add(*rhs)
368    }
369}
370
371impl Add<DMat2> for &DMat2 {
372    type Output = DMat2;
373    #[inline]
374    fn add(self, rhs: DMat2) -> DMat2 {
375        (*self).add(rhs)
376    }
377}
378
379impl AddAssign for DMat2 {
380    #[inline]
381    fn add_assign(&mut self, rhs: Self) {
382        *self = self.add(rhs);
383    }
384}
385
386impl AddAssign<&Self> for DMat2 {
387    #[inline]
388    fn add_assign(&mut self, rhs: &Self) {
389        self.add_assign(*rhs);
390    }
391}
392
393impl Sub for DMat2 {
394    type Output = Self;
395    #[inline]
396    fn sub(self, rhs: Self) -> Self {
397        Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
398    }
399}
400
401impl Sub<&Self> for DMat2 {
402    type Output = Self;
403    #[inline]
404    fn sub(self, rhs: &Self) -> Self {
405        self.sub(*rhs)
406    }
407}
408
409impl Sub<&DMat2> for &DMat2 {
410    type Output = DMat2;
411    #[inline]
412    fn sub(self, rhs: &DMat2) -> DMat2 {
413        (*self).sub(*rhs)
414    }
415}
416
417impl Sub<DMat2> for &DMat2 {
418    type Output = DMat2;
419    #[inline]
420    fn sub(self, rhs: DMat2) -> DMat2 {
421        (*self).sub(rhs)
422    }
423}
424
425impl SubAssign for DMat2 {
426    #[inline]
427    fn sub_assign(&mut self, rhs: Self) {
428        *self = self.sub(rhs);
429    }
430}
431
432impl SubAssign<&Self> for DMat2 {
433    #[inline]
434    fn sub_assign(&mut self, rhs: &Self) {
435        self.sub_assign(*rhs);
436    }
437}
438
439impl Neg for DMat2 {
440    type Output = Self;
441    #[inline]
442    fn neg(self) -> Self::Output {
443        Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
444    }
445}
446
447impl Neg for &DMat2 {
448    type Output = DMat2;
449    #[inline]
450    fn neg(self) -> DMat2 {
451        (*self).neg()
452    }
453}
454
455impl Mul for DMat2 {
456    type Output = Self;
457    #[inline]
458    fn mul(self, rhs: Self) -> Self {
459        Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
460    }
461}
462
463impl Mul<&Self> for DMat2 {
464    type Output = Self;
465    #[inline]
466    fn mul(self, rhs: &Self) -> Self {
467        self.mul(*rhs)
468    }
469}
470
471impl Mul<&DMat2> for &DMat2 {
472    type Output = DMat2;
473    #[inline]
474    fn mul(self, rhs: &DMat2) -> DMat2 {
475        (*self).mul(*rhs)
476    }
477}
478
479impl Mul<DMat2> for &DMat2 {
480    type Output = DMat2;
481    #[inline]
482    fn mul(self, rhs: DMat2) -> DMat2 {
483        (*self).mul(rhs)
484    }
485}
486
487impl MulAssign for DMat2 {
488    #[inline]
489    fn mul_assign(&mut self, rhs: Self) {
490        *self = self.mul(rhs);
491    }
492}
493
494impl MulAssign<&Self> for DMat2 {
495    #[inline]
496    fn mul_assign(&mut self, rhs: &Self) {
497        self.mul_assign(*rhs);
498    }
499}
500
501impl Mul<DVec2> for DMat2 {
502    type Output = DVec2;
503    #[inline]
504    fn mul(self, rhs: DVec2) -> Self::Output {
505        self.mul_vec2(rhs)
506    }
507}
508
509impl Mul<&DVec2> for DMat2 {
510    type Output = DVec2;
511    #[inline]
512    fn mul(self, rhs: &DVec2) -> DVec2 {
513        self.mul(*rhs)
514    }
515}
516
517impl Mul<&DVec2> for &DMat2 {
518    type Output = DVec2;
519    #[inline]
520    fn mul(self, rhs: &DVec2) -> DVec2 {
521        (*self).mul(*rhs)
522    }
523}
524
525impl Mul<DVec2> for &DMat2 {
526    type Output = DVec2;
527    #[inline]
528    fn mul(self, rhs: DVec2) -> DVec2 {
529        (*self).mul(rhs)
530    }
531}
532
533impl Mul<DMat2> for f64 {
534    type Output = DMat2;
535    #[inline]
536    fn mul(self, rhs: DMat2) -> Self::Output {
537        rhs.mul_scalar(self)
538    }
539}
540
541impl Mul<&DMat2> for f64 {
542    type Output = DMat2;
543    #[inline]
544    fn mul(self, rhs: &DMat2) -> DMat2 {
545        self.mul(*rhs)
546    }
547}
548
549impl Mul<&DMat2> for &f64 {
550    type Output = DMat2;
551    #[inline]
552    fn mul(self, rhs: &DMat2) -> DMat2 {
553        (*self).mul(*rhs)
554    }
555}
556
557impl Mul<DMat2> for &f64 {
558    type Output = DMat2;
559    #[inline]
560    fn mul(self, rhs: DMat2) -> DMat2 {
561        (*self).mul(rhs)
562    }
563}
564
565impl Mul<f64> for DMat2 {
566    type Output = Self;
567    #[inline]
568    fn mul(self, rhs: f64) -> Self {
569        self.mul_scalar(rhs)
570    }
571}
572
573impl Mul<&f64> for DMat2 {
574    type Output = Self;
575    #[inline]
576    fn mul(self, rhs: &f64) -> Self {
577        self.mul(*rhs)
578    }
579}
580
581impl Mul<&f64> for &DMat2 {
582    type Output = DMat2;
583    #[inline]
584    fn mul(self, rhs: &f64) -> DMat2 {
585        (*self).mul(*rhs)
586    }
587}
588
589impl Mul<f64> for &DMat2 {
590    type Output = DMat2;
591    #[inline]
592    fn mul(self, rhs: f64) -> DMat2 {
593        (*self).mul(rhs)
594    }
595}
596
597impl MulAssign<f64> for DMat2 {
598    #[inline]
599    fn mul_assign(&mut self, rhs: f64) {
600        *self = self.mul(rhs);
601    }
602}
603
604impl MulAssign<&f64> for DMat2 {
605    #[inline]
606    fn mul_assign(&mut self, rhs: &f64) {
607        self.mul_assign(*rhs);
608    }
609}
610
611impl Div<DMat2> for f64 {
612    type Output = DMat2;
613    #[inline]
614    fn div(self, rhs: DMat2) -> Self::Output {
615        rhs.div_scalar(self)
616    }
617}
618
619impl Div<&DMat2> for f64 {
620    type Output = DMat2;
621    #[inline]
622    fn div(self, rhs: &DMat2) -> DMat2 {
623        self.div(*rhs)
624    }
625}
626
627impl Div<&DMat2> for &f64 {
628    type Output = DMat2;
629    #[inline]
630    fn div(self, rhs: &DMat2) -> DMat2 {
631        (*self).div(*rhs)
632    }
633}
634
635impl Div<DMat2> for &f64 {
636    type Output = DMat2;
637    #[inline]
638    fn div(self, rhs: DMat2) -> DMat2 {
639        (*self).div(rhs)
640    }
641}
642
643impl Div<f64> for DMat2 {
644    type Output = Self;
645    #[inline]
646    fn div(self, rhs: f64) -> Self {
647        self.div_scalar(rhs)
648    }
649}
650
651impl Div<&f64> for DMat2 {
652    type Output = Self;
653    #[inline]
654    fn div(self, rhs: &f64) -> Self {
655        self.div(*rhs)
656    }
657}
658
659impl Div<&f64> for &DMat2 {
660    type Output = DMat2;
661    #[inline]
662    fn div(self, rhs: &f64) -> DMat2 {
663        (*self).div(*rhs)
664    }
665}
666
667impl Div<f64> for &DMat2 {
668    type Output = DMat2;
669    #[inline]
670    fn div(self, rhs: f64) -> DMat2 {
671        (*self).div(rhs)
672    }
673}
674
675impl DivAssign<f64> for DMat2 {
676    #[inline]
677    fn div_assign(&mut self, rhs: f64) {
678        *self = self.div(rhs);
679    }
680}
681
682impl DivAssign<&f64> for DMat2 {
683    #[inline]
684    fn div_assign(&mut self, rhs: &f64) {
685        self.div_assign(*rhs);
686    }
687}
688
689impl Sum<Self> for DMat2 {
690    fn sum<I>(iter: I) -> Self
691    where
692        I: Iterator<Item = Self>,
693    {
694        iter.fold(Self::ZERO, Self::add)
695    }
696}
697
698impl<'a> Sum<&'a Self> for DMat2 {
699    fn sum<I>(iter: I) -> Self
700    where
701        I: Iterator<Item = &'a Self>,
702    {
703        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
704    }
705}
706
707impl Product for DMat2 {
708    fn product<I>(iter: I) -> Self
709    where
710        I: Iterator<Item = Self>,
711    {
712        iter.fold(Self::IDENTITY, Self::mul)
713    }
714}
715
716impl<'a> Product<&'a Self> for DMat2 {
717    fn product<I>(iter: I) -> Self
718    where
719        I: Iterator<Item = &'a Self>,
720    {
721        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
722    }
723}
724
725impl PartialEq for DMat2 {
726    #[inline]
727    fn eq(&self, rhs: &Self) -> bool {
728        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
729    }
730}
731
732impl AsRef<[f64; 4]> for DMat2 {
733    #[inline]
734    fn as_ref(&self) -> &[f64; 4] {
735        unsafe { &*(self as *const Self as *const [f64; 4]) }
736    }
737}
738
739impl AsMut<[f64; 4]> for DMat2 {
740    #[inline]
741    fn as_mut(&mut self) -> &mut [f64; 4] {
742        unsafe { &mut *(self as *mut Self as *mut [f64; 4]) }
743    }
744}
745
746impl fmt::Debug for DMat2 {
747    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
748        fmt.debug_struct(stringify!(DMat2))
749            .field("x_axis", &self.x_axis)
750            .field("y_axis", &self.y_axis)
751            .finish()
752    }
753}
754
755impl fmt::Display for DMat2 {
756    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
757        if let Some(p) = f.precision() {
758            write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
759        } else {
760            write!(f, "[{}, {}]", self.x_axis, self.y_axis)
761        }
762    }
763}