diff --git a/pr/523/docs/help.html b/pr/523/docs/help.html index cda0c7f93..cb140c09e 100644 --- a/pr/523/docs/help.html +++ b/pr/523/docs/help.html @@ -1 +1 @@ -Help

All

Rustdoc help

Back
\ No newline at end of file +Help

All

Rustdoc help

Back
\ No newline at end of file diff --git a/pr/523/docs/noq/enum.ConnectionError.html b/pr/523/docs/noq/enum.ConnectionError.html index 9956cb416..549e3d9b2 100644 --- a/pr/523/docs/noq/enum.ConnectionError.html +++ b/pr/523/docs/noq/enum.ConnectionError.html @@ -1,4 +1,4 @@ -ConnectionError in noq - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
+ConnectionError in noq - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
     VersionMismatch,
     TransportError(Error),
     ConnectionClosed(ConnectionClose),
@@ -20,8 +20,8 @@ and §

LocallyClosed

The local application closed the connection

§

CidsExhausted

The connection could not be created because not enough of the CID space is available

Try using longer connection IDs.

-

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Close> for ConnectionError

Source§

fn from(x: Close) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<CloseReason> for ConnectionError

Source§

fn from(value: CloseReason) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ReadError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ResetError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for WriteError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: Error) -> ConnectionError

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Close> for ConnectionError

Source§

fn from(x: Close) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<CloseReason> for ConnectionError

Source§

fn from(value: CloseReason) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ReadError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ResetError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for WriteError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: Error) -> ConnectionError

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq/enum.SendDatagramError.html b/pr/523/docs/noq/enum.SendDatagramError.html index df673eb04..4b8a4e090 100644 --- a/pr/523/docs/noq/enum.SendDatagramError.html +++ b/pr/523/docs/noq/enum.SendDatagramError.html @@ -1,4 +1,4 @@ -SendDatagramError in noq - Rust

SendDatagramError

Enum SendDatagramError 

Source
pub enum SendDatagramError {
+SendDatagramError in noq - Rust

SendDatagramError

Enum SendDatagramError 

Source
pub enum SendDatagramError {
     UnsupportedByPeer,
     Disabled,
     TooLarge,
@@ -10,8 +10,8 @@
 

Indicates that the path MTU minus overhead or the limit advertised by the peer has been exceeded.

§

ConnectionLost(ConnectionError)

The connection was lost

-

Trait Implementations§

Source§

impl Clone for SendDatagramError

Source§

fn clone(&self) -> SendDatagramError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SendDatagramError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for SendDatagramError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for SendDatagramError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for SendDatagramError

Source§

fn eq(&self, other: &SendDatagramError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for SendDatagramError

Source§

impl StructuralPartialEq for SendDatagramError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for SendDatagramError

Source§

fn clone(&self) -> SendDatagramError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SendDatagramError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for SendDatagramError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for SendDatagramError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for SendDatagramError

Source§

fn eq(&self, other: &SendDatagramError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for SendDatagramError

Source§

impl StructuralPartialEq for SendDatagramError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq/enum.StoppedError.html b/pr/523/docs/noq/enum.StoppedError.html index 3b546f354..db56529df 100644 --- a/pr/523/docs/noq/enum.StoppedError.html +++ b/pr/523/docs/noq/enum.StoppedError.html @@ -1,4 +1,4 @@ -StoppedError in noq - Rust

StoppedError

Enum StoppedError 

Source
pub enum StoppedError {
+StoppedError in noq - Rust

StoppedError

Enum StoppedError 

Source
pub enum StoppedError {
     ConnectionLost(ConnectionError),
     ZeroRttRejected,
 }
Expand description

Errors that arise while monitoring for a send stream stop from the peer

@@ -6,8 +6,8 @@
§

ZeroRttRejected

This was a 0-RTT stream and the server rejected it

Can only occur on clients for 0-RTT streams, which can be opened using Connecting::into_0rtt().

-

Trait Implementations§

Source§

impl Clone for StoppedError

Source§

fn clone(&self) -> StoppedError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for StoppedError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for StoppedError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for StoppedError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for Error

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for StoppedError

Source§

fn eq(&self, other: &StoppedError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for StoppedError

Source§

impl StructuralPartialEq for StoppedError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for StoppedError

Source§

fn clone(&self) -> StoppedError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for StoppedError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for StoppedError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for StoppedError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for Error

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for StoppedError

Source§

fn eq(&self, other: &StoppedError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for StoppedError

Source§

impl StructuralPartialEq for StoppedError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq/enum.WriteError.html b/pr/523/docs/noq/enum.WriteError.html index d5a81ac6c..606752321 100644 --- a/pr/523/docs/noq/enum.WriteError.html +++ b/pr/523/docs/noq/enum.WriteError.html @@ -1,4 +1,4 @@ -WriteError in noq - Rust

WriteError

Enum WriteError 

Source
pub enum WriteError {
+WriteError in noq - Rust

WriteError

Enum WriteError 

Source
pub enum WriteError {
     Stopped(VarInt),
     ConnectionLost(ConnectionError),
     ClosedStream,
@@ -11,8 +11,8 @@
 
§

ZeroRttRejected

This was a 0-RTT stream and the server rejected it

Can only occur on clients for 0-RTT streams, which can be opened using Connecting::into_0rtt().

-

Trait Implementations§

Source§

impl Clone for WriteError

Source§

fn clone(&self) -> WriteError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WriteError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for WriteError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for WriteError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for WriteError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<WriteError> for Error

Source§

fn from(x: WriteError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for WriteError

Source§

fn eq(&self, other: &WriteError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for WriteError

Source§

impl StructuralPartialEq for WriteError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for WriteError

Source§

fn clone(&self) -> WriteError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WriteError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for WriteError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for WriteError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for WriteError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<WriteError> for Error

Source§

fn from(x: WriteError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for WriteError

Source§

fn eq(&self, other: &WriteError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for WriteError

Source§

impl StructuralPartialEq for WriteError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq/struct.AcceptBi.html b/pr/523/docs/noq/struct.AcceptBi.html index 2570d72c9..180bbe0f8 100644 --- a/pr/523/docs/noq/struct.AcceptBi.html +++ b/pr/523/docs/noq/struct.AcceptBi.html @@ -1,6 +1,6 @@ -AcceptBi in noq - Rust

AcceptBi

Struct AcceptBi 

Source
pub struct AcceptBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_bi

-

Trait Implementations§

Source§

impl Future for AcceptBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptBi<'a>
where +AcceptBi in noq - Rust

AcceptBi

Struct AcceptBi 

Source
pub struct AcceptBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_bi

+

Trait Implementations§

Source§

impl Future for AcceptBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptBi<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for AcceptBi<'a>

§

impl<'a> !RefUnwindSafe for AcceptBi<'a>

§

impl<'a> Send for AcceptBi<'a>

§

impl<'a> Sync for AcceptBi<'a>

§

impl<'a> !UnwindSafe for AcceptBi<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.AcceptUni.html b/pr/523/docs/noq/struct.AcceptUni.html index 632021163..0e6b55eaa 100644 --- a/pr/523/docs/noq/struct.AcceptUni.html +++ b/pr/523/docs/noq/struct.AcceptUni.html @@ -1,6 +1,6 @@ -AcceptUni in noq - Rust

AcceptUni

Struct AcceptUni 

Source
pub struct AcceptUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_uni

-

Trait Implementations§

Source§

impl Future for AcceptUni<'_>

Source§

type Output = Result<RecvStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptUni<'a>
where +AcceptUni in noq - Rust

AcceptUni

Struct AcceptUni 

Source
pub struct AcceptUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_uni

+

Trait Implementations§

Source§

impl Future for AcceptUni<'_>

Source§

type Output = Result<RecvStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptUni<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for AcceptUni<'a>

§

impl<'a> !RefUnwindSafe for AcceptUni<'a>

§

impl<'a> Send for AcceptUni<'a>

§

impl<'a> Sync for AcceptUni<'a>

§

impl<'a> !UnwindSafe for AcceptUni<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.AddressDiscovery.html b/pr/523/docs/noq/struct.AddressDiscovery.html index dbfb17648..f4b48f499 100644 --- a/pr/523/docs/noq/struct.AddressDiscovery.html +++ b/pr/523/docs/noq/struct.AddressDiscovery.html @@ -1,7 +1,7 @@ -AddressDiscovery in noq - Rust

AddressDiscovery

Struct AddressDiscovery 

Source
pub struct AddressDiscovery { /* private fields */ }
Expand description

Stream produced by Path::observed_external_addr

+AddressDiscovery in noq - Rust

AddressDiscovery

Struct AddressDiscovery 

Source
pub struct AddressDiscovery { /* private fields */ }
Expand description

Stream produced by Path::observed_external_addr

This will always return the external address most recently reported by the remote over this path. If the extension is not negotiated, this stream will never return.

-

Trait Implementations§

Source§

impl Stream for AddressDiscovery

Source§

type Item = SocketAddr

Values yielded by the stream.
Source§

fn poll_next( +

Trait Implementations§

Source§

impl Stream for AddressDiscovery

Source§

type Item = SocketAddr

Values yielded by the stream.
Source§

fn poll_next( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the diff --git a/pr/523/docs/noq/struct.ClosedStream.html b/pr/523/docs/noq/struct.ClosedStream.html index 8eb864ca2..0453153c1 100644 --- a/pr/523/docs/noq/struct.ClosedStream.html +++ b/pr/523/docs/noq/struct.ClosedStream.html @@ -1,5 +1,5 @@ ClosedStream in noq - Rust

ClosedStream

Struct ClosedStream 

Source
pub struct ClosedStream { /* private fields */ }
Expand description

Error indicating that a stream has not been opened or has already been finished or reset

-

Trait Implementations§

Source§

impl Clone for ClosedStream

Source§

fn clone(&self) -> ClosedStream

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClosedStream

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for ClosedStream

Source§

fn default() -> ClosedStream

Returns the “default value” for a type. Read more
Source§

impl Display for ClosedStream

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for ClosedStream

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ClosedStream

Source§

fn eq(&self, other: &ClosedStream) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +

Trait Implementations§

Source§

impl Clone for ClosedStream

Source§

fn clone(&self) -> ClosedStream

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClosedStream

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for ClosedStream

Source§

fn default() -> ClosedStream

Returns the “default value” for a type. Read more
Source§

impl Display for ClosedStream

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for ClosedStream

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ClosedStream

Source§

fn eq(&self, other: &ClosedStream) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for ClosedStream

Source§

impl StructuralPartialEq for ClosedStream

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.Connecting.html b/pr/523/docs/noq/struct.Connecting.html index 313d9b851..347289200 100644 --- a/pr/523/docs/noq/struct.Connecting.html +++ b/pr/523/docs/noq/struct.Connecting.html @@ -1,5 +1,5 @@ Connecting in noq - Rust

Connecting

Struct Connecting 

Source
pub struct Connecting { /* private fields */ }
Expand description

In-progress connection attempt future

-

Implementations§

Source§

impl Connecting

Source

pub fn into_0rtt(self) -> Result<(Connection, ZeroRttAccepted), Self>

Convert into a 0-RTT or 0.5-RTT connection at the cost of weakened security

+

Implementations§

Source§

impl Connecting

Source

pub fn into_0rtt(self) -> Result<(Connection, ZeroRttAccepted), Self>

Convert into a 0-RTT or 0.5-RTT connection at the cost of weakened security

Returns Ok immediately if the local endpoint is able to attempt sending 0/0.5-RTT data. If so, the returned Connection can be used to send application data without waiting for the rest of the handshake to complete, at the cost of weakened cryptographic security @@ -45,9 +45,9 @@ the endpoint is bound to a wildcard address like 0.0.0.0 or : information. See noq_udp::RecvMeta::dst_ip for a list of supported platforms when using noq_udp for I/O, which is the default.

Will panic if called after poll has returned Ready.

-
Source

pub fn remote_address(&self) -> SocketAddr

The peer’s UDP addresses

+
Source

pub fn remote_address(&self) -> SocketAddr

The peer’s UDP addresses

Will panic if called after poll has returned Ready.

-

Trait Implementations§

Source§

impl Debug for Connecting

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Future for Connecting

Source§

type Output = Result<Connection, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +

Trait Implementations§

Source§

impl Debug for Connecting

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Future for Connecting

Source§

type Output = Result<Connection, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.Connection.html b/pr/523/docs/noq/struct.Connection.html index 29ab9265c..7a59936d7 100644 --- a/pr/523/docs/noq/struct.Connection.html +++ b/pr/523/docs/noq/struct.Connection.html @@ -1,4 +1,4 @@ -Connection in noq - Rust

Connection

Struct Connection 

Source
pub struct Connection(/* private fields */);
Expand description

A QUIC connection.

+Connection in noq - Rust

Connection

Struct Connection 

Source
pub struct Connection(/* private fields */);
Expand description

A QUIC connection.

If all references to a connection (including every clone of the Connection handle, streams of incoming streams, and the various stream types) have been dropped, then the connection will be automatically closed with an error_code of 0 and an empty reason. You can also close the @@ -8,29 +8,29 @@ receiving CONNECTION_CLOSE the peer may drop any stream data not yet de application. Connection::close() describes in more detail how to gracefully close a connection without losing application data.

May be cloned to obtain another handle to the same connection.

-

Implementations§

Source§

impl Connection

Source

pub fn weak_handle(&self) -> WeakConnectionHandle

Returns a weak reference to the inner connection struct.

-
Source

pub fn open_uni(&self) -> OpenUni<'_>

Initiate a new outgoing unidirectional stream.

+

Implementations§

Source§

impl Connection

Source

pub fn weak_handle(&self) -> WeakConnectionHandle

Returns a weak reference to the inner connection struct.

+
Source

pub fn open_uni(&self) -> OpenUni<'_>

Initiate a new outgoing unidirectional stream.

Streams are cheap and instantaneous to open unless blocked by flow control. As a consequence, the peer won’t be notified that a stream has been opened until the stream is actually used.

-
Source

pub fn open_bi(&self) -> OpenBi<'_>

Initiate a new outgoing bidirectional stream.

+
Source

pub fn open_bi(&self) -> OpenBi<'_>

Initiate a new outgoing bidirectional stream.

Streams are cheap and instantaneous to open unless blocked by flow control. As a consequence, the peer won’t be notified that a stream has been opened until the stream is actually used. Calling open_bi() then waiting on the RecvStream without writing anything to SendStream will never succeed.

-
Source

pub fn accept_uni(&self) -> AcceptUni<'_>

Accept the next incoming uni-directional stream

-
Source

pub fn accept_bi(&self) -> AcceptBi<'_>

Accept the next incoming bidirectional stream

+
Source

pub fn accept_uni(&self) -> AcceptUni<'_>

Accept the next incoming uni-directional stream

+
Source

pub fn accept_bi(&self) -> AcceptBi<'_>

Accept the next incoming bidirectional stream

Important Note: The Connection that calls open_bi() must write to its SendStream before the other Connection is able to accept_bi(). Calling open_bi() then waiting on the RecvStream without writing anything to SendStream will never succeed.

-
Source

pub fn read_datagram(&self) -> ReadDatagram<'_>

Receive an application datagram

-
Source

pub fn open_path_ensure( +

Source

pub fn read_datagram(&self) -> ReadDatagram<'_>

Receive an application datagram

+
Source

pub fn open_path_ensure( &self, addr: SocketAddr, initial_status: PathStatus, ) -> OpenPath

Opens a new path if no path exists yet for the remote address.

Otherwise behaves exactly as open_path.

-
Source

pub fn open_path( +

Source

pub fn open_path( &self, addr: SocketAddr, initial_status: PathStatus, @@ -45,17 +45,17 @@ path opens. The P future, or at a later time. If the failure is immediate OpenPath::path_id will return None and the future will be ready immediately. If the failure happens later, a PathEvent will be emitted.

-

Source

pub fn path(&self, id: PathId) -> Option<Path>

Returns the Path structure of an open path

-
Source

pub fn path_events(&self) -> PathEvents

A stream of PathEvents for all paths in this connection.

+
Source

pub fn path(&self, id: PathId) -> Option<Path>

Returns the Path structure of an open path

+
Source

pub fn path_events(&self) -> PathEvents

A stream of PathEvents for all paths in this connection.

The stream will yield a PathEvent whenever there is a change in the state of any path in this connection. The events need to be processed immediately, since there isn’t an unbounded buffer for them.

If processing of events lags behind too much, you will get an error of type crate::Lagged indicating how many events were lost. The stream continues after a lag, delivering the oldest retained message next.

-
Source

pub fn nat_traversal_updates(&self) -> NatTraversalUpdates

A stream of NAT traversal updates for this connection.

+
Source

pub fn nat_traversal_updates(&self) -> NatTraversalUpdates

A stream of NAT traversal updates for this connection.

The events need to be processed immediately, since there isn’t an unbounded buffer for them.

If processing of events lags behind too much, you will get an error of type crate::Lagged indicating how many events were lost. The stream continues after a lag, delivering the oldest retained message next.

-
Source

pub async fn closed(&self) -> ConnectionError

Wait for the connection to be closed for any reason

+
Source

pub async fn closed(&self) -> ConnectionError

Wait for the connection to be closed for any reason

Despite the return type’s name, closed connections are often not an error condition at the application layer. Cases that might be routine include ConnectionError::LocallyClosed and ConnectionError::ApplicationClosed.

@@ -89,7 +89,7 @@ endpoint. Once the local side sends a CONNECTION_CLOSE frame in response to call close() the remote endpoint may drop any data it received but is as yet undelivered to the application, including data that was acknowledged as received to the local endpoint.

-
Source

pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError>

Wait for the handshake to be confirmed.

+
Source

pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError>

Wait for the handshake to be confirmed.

As a server, who must be authenticated by clients, this happens when the handshake completes upon receiving a TLS Finished message from the client. @@ -97,23 +97,23 @@ In return, the server send a HANDSHAKE_DONE frame.

As a client, this happens when receiving a HANDSHAKE_DONE frame. At this point, the server has either accepted our authentication, or, if client authentication is not required, accepted our lack of authentication.

-
Source

pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError>

Transmit data as an unreliable, unordered application datagram

+
Source

pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError>

Transmit data as an unreliable, unordered application datagram

Application datagrams are a low-level primitive. They may be lost or delivered out of order, and data must both fit inside a single QUIC packet and be smaller than the maximum dictated by the peer.

Previously queued datagrams which are still unsent may be discarded to make space for this datagram, in order of oldest to newest.

-
Source

pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_>

Transmit data as an unreliable, unordered application datagram

+
Source

pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_>

Transmit data as an unreliable, unordered application datagram

Unlike send_datagram(), this method will wait for buffer space during congestion conditions, which effectively prioritizes old datagrams over new datagrams.

See send_datagram() for details.

-
Source

pub fn max_datagram_size(&self) -> Option<usize>

Compute the maximum size of datagrams that may be passed to send_datagram().

+
Source

pub fn max_datagram_size(&self) -> Option<usize>

Compute the maximum size of datagrams that may be passed to send_datagram().

Returns None if datagrams are unsupported by the peer or disabled locally.

This may change over the lifetime of a connection according to variation in the path MTU estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer’s limit is large this is guaranteed to be a little over a kilobyte at minimum.

Not necessarily the maximum size of received datagrams.

-
Source

pub fn datagram_send_buffer_space(&self) -> usize

Bytes available in the outgoing datagram buffer

+
Source

pub fn datagram_send_buffer_space(&self) -> usize

Bytes available in the outgoing datagram buffer

When greater than zero, calling send_datagram() with a datagram of at most this size is guaranteed not to cause older datagrams to be dropped.

Source

pub fn side(&self) -> Side

The side of the connection (client or server)

@@ -132,21 +132,21 @@ supported platforms when using
Source

pub fn rtt(&self, path_id: PathId) -> Option<Duration>

Current best estimate of this connection’s latency (round-trip-time)

Source

pub fn stats(&self) -> ConnectionStats

Returns connection statistics

Source

pub fn path_stats(&self, path_id: PathId) -> Option<PathStats>

Returns path statistics

-
Source

pub fn congestion_state(&self, path_id: PathId) -> Option<Box<dyn Controller>>

Current state of the congestion control algorithm, for debugging purposes

-
Source

pub fn handshake_data(&self) -> Option<Box<dyn Any>>

Parameters negotiated during the handshake

+
Source

pub fn congestion_state(&self, path_id: PathId) -> Option<Box<dyn Controller>>

Current state of the congestion control algorithm, for debugging purposes

+
Source

pub fn handshake_data(&self) -> Option<Box<dyn Any>>

Parameters negotiated during the handshake

Guaranteed to return Some on fully established connections or after Connecting::handshake_data() succeeds. See that method’s documentations for details on the returned value.

-
Source

pub fn peer_identity(&self) -> Option<Box<dyn Any>>

Cryptographic identity of the peer

+
Source

pub fn peer_identity(&self) -> Option<Box<dyn Any>>

Cryptographic identity of the peer

The dynamic type returned is determined by the configured Session. For the default rustls session, the return value can be downcast to a Vec<[rustls::pki_types::CertificateDer]>

-
Source

pub fn stable_id(&self) -> usize

A stable identifier for this connection

+
Source

pub fn stable_id(&self) -> usize

A stable identifier for this connection

Peer addresses and connection IDs can change, but this value will remain fixed for the lifetime of the connection.

-
Source

pub fn force_key_update(&self)

Update traffic keys spontaneously

+
Source

pub fn force_key_update(&self)

Update traffic keys spontaneously

This primarily exists for testing purposes.

-
Source

pub fn export_keying_material( +

Source

pub fn export_keying_material( &self, output: &mut [u8], label: &[u8], @@ -157,17 +157,17 @@ arguments and output buffers of equal length, they will get the same sequence of bytes in output. These bytes are cryptographically strong and pseudorandom, and are suitable for use as keying material.

See RFC5705 for more information.

-

Source

pub fn set_max_concurrent_uni_streams(&self, count: VarInt)

Modify the number of remotely initiated unidirectional streams that may be concurrently open

+
Source

pub fn set_max_concurrent_uni_streams(&self, count: VarInt)

Modify the number of remotely initiated unidirectional streams that may be concurrently open

No streams may be opened by the peer unless fewer than count are already open. Large counts increase both minimum and worst-case memory consumption.

-
Source

pub fn set_send_window(&self, send_window: u64)

Source

pub fn set_receive_window(&self, receive_window: VarInt)

Source

pub fn set_max_concurrent_bi_streams(&self, count: VarInt)

Modify the number of remotely initiated bidirectional streams that may be concurrently open

+
Source

pub fn set_send_window(&self, send_window: u64)

Source

pub fn set_receive_window(&self, receive_window: VarInt)

Source

pub fn set_max_concurrent_bi_streams(&self, count: VarInt)

Modify the number of remotely initiated bidirectional streams that may be concurrently open

No streams may be opened by the peer unless fewer than count are already open. Large counts increase both minimum and worst-case memory consumption.

-
Source

pub fn observed_external_addr(&self) -> ObservedExternalAddr

Track changes on our external address as reported by the peer.

-
Source

pub fn is_multipath_enabled(&self) -> bool

Is multipath enabled?

-
Source

pub fn add_nat_traversal_address( +

Source

pub fn observed_external_addr(&self) -> ObservedExternalAddr

Track changes on our external address as reported by the peer.

+
Source

pub fn is_multipath_enabled(&self) -> bool

Is multipath enabled?

+
Source

pub fn add_nat_traversal_address( &self, address: SocketAddr, ) -> Result<(), Error>

Registers one address at which this endpoint might be reachable

@@ -175,7 +175,7 @@ strong and pseudorandom, and are suitable for use as keying material.

ADD_ADDRESS frames. This allows clients to obtain server address candidates to initiate NAT traversal attempts. Clients provide their own reachable addresses in REACH_OUT frames when Self::initiate_nat_traversal_round is called.

-
Source

pub fn remove_nat_traversal_address( +

Source

pub fn remove_nat_traversal_address( &self, address: SocketAddr, ) -> Result<(), Error>

Removes one or more addresses from the set of addresses at which this endpoint is reachable

@@ -184,18 +184,18 @@ clients in REMOVE_ADDRESS frames. This allows clients to stop using server address candidates that are no longer valid for NAT traversal.

For clients, removed addresses will no longer be advertised in REACH_OUT frames.

Addresses not present in the set will be silently ignored.

-
Source

pub fn get_local_nat_traversal_addresses( +

Source

pub fn get_local_nat_traversal_addresses( &self, ) -> Result<Vec<SocketAddr>, Error>

Get the current local nat traversal addresses

-
Source

pub fn get_remote_nat_traversal_addresses( +

Source

pub fn get_remote_nat_traversal_addresses( &self, ) -> Result<Vec<SocketAddr>, Error>

Get the currently advertised nat traversal addresses by the server

-
Source

pub fn initiate_nat_traversal_round(&self) -> Result<Vec<SocketAddr>, Error>

Initiates a new nat traversal round

+
Source

pub fn initiate_nat_traversal_round(&self) -> Result<Vec<SocketAddr>, Error>

Initiates a new nat traversal round

A nat traversal round involves advertising the client’s local addresses in REACH_OUT frames, and initiating probing of the known remote addresses. When a new round is initiated, the previous one is cancelled, and paths that have not been opened are closed.

Returns the server addresses that are now being probed.

-

Trait Implementations§

Source§

impl Clone for Connection

Source§

fn clone(&self) -> Connection

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Connection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for Connection

Source§

fn clone(&self) -> Connection

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Connection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq/struct.OnClosed.html b/pr/523/docs/noq/struct.OnClosed.html index 614456536..530c1e14e 100644 --- a/pr/523/docs/noq/struct.OnClosed.html +++ b/pr/523/docs/noq/struct.OnClosed.html @@ -1,6 +1,6 @@ -OnClosed in noq - Rust

OnClosed

Struct OnClosed 

Source
pub struct OnClosed { /* private fields */ }
Expand description

Future returned by Connection::on_closed

+OnClosed in noq - Rust

OnClosed

Struct OnClosed 

Source
pub struct OnClosed { /* private fields */ }
Expand description

Future returned by Connection::on_closed

Resolves to a tuple of (ConnectionError, ConnectionStats).

-

Trait Implementations§

Source§

impl Drop for OnClosed

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Future for OnClosed

Source§

type Output = (ConnectionError, ConnectionStats)

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +

Trait Implementations§

Source§

impl Drop for OnClosed

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Future for OnClosed

Source§

type Output = (ConnectionError, ConnectionStats)

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.OpenBi.html b/pr/523/docs/noq/struct.OpenBi.html index 4ea882cc9..c878e5abb 100644 --- a/pr/523/docs/noq/struct.OpenBi.html +++ b/pr/523/docs/noq/struct.OpenBi.html @@ -1,6 +1,6 @@ -OpenBi in noq - Rust

OpenBi

Struct OpenBi 

Source
pub struct OpenBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_bi

-

Trait Implementations§

Source§

impl Future for OpenBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenBi<'a>
where +OpenBi in noq - Rust

OpenBi

Struct OpenBi 

Source
pub struct OpenBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_bi

+

Trait Implementations§

Source§

impl Future for OpenBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenBi<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for OpenBi<'a>

§

impl<'a> !RefUnwindSafe for OpenBi<'a>

§

impl<'a> Send for OpenBi<'a>

§

impl<'a> Sync for OpenBi<'a>

§

impl<'a> !UnwindSafe for OpenBi<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.OpenUni.html b/pr/523/docs/noq/struct.OpenUni.html index 847004010..dbe517c1f 100644 --- a/pr/523/docs/noq/struct.OpenUni.html +++ b/pr/523/docs/noq/struct.OpenUni.html @@ -1,6 +1,6 @@ -OpenUni in noq - Rust

OpenUni

Struct OpenUni 

Source
pub struct OpenUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_uni

-

Trait Implementations§

Source§

impl Future for OpenUni<'_>

Source§

type Output = Result<SendStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenUni<'a>
where +OpenUni in noq - Rust

OpenUni

Struct OpenUni 

Source
pub struct OpenUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_uni

+

Trait Implementations§

Source§

impl Future for OpenUni<'_>

Source§

type Output = Result<SendStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenUni<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for OpenUni<'a>

§

impl<'a> !RefUnwindSafe for OpenUni<'a>

§

impl<'a> Send for OpenUni<'a>

§

impl<'a> Sync for OpenUni<'a>

§

impl<'a> !UnwindSafe for OpenUni<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.Path.html b/pr/523/docs/noq/struct.Path.html index 91812028a..d96867826 100644 --- a/pr/523/docs/noq/struct.Path.html +++ b/pr/523/docs/noq/struct.Path.html @@ -1,35 +1,35 @@ Path in noq - Rust

Path

Struct Path 

Source
pub struct Path { /* private fields */ }
Expand description

An open network transmission within a multipath-enabled connection.

As long as a Path or WeakPathHandle is alive, it is ensured that the PathStats for this path are not dropped even after the path is abandoned.

-

Implementations§

Source§

impl Path

Source

pub fn weak_handle(&self) -> WeakPathHandle

Returns a WeakPathHandle for this path.

+

Implementations§

Source§

impl Path

Source

pub fn weak_handle(&self) -> WeakPathHandle

Returns a WeakPathHandle for this path.

Holding a WeakPathHandle does not keep a connection alive, but ensures that the path’s stats are not dropped until the underlying connection is dropped, even if the path is abandoned.

-
Source

pub fn id(&self) -> PathId

The PathId of this path.

-
Source

pub fn status(&self) -> Result<PathStatus, ClosedPath>

The current local PathStatus of this path.

-
Source

pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError>

Sets the PathStatus of this path.

-
Source

pub fn stats(&self) -> PathStats

Returns the PathStats for this path.

-
Source

pub fn close(&self) -> Result<(), ClosePathError>

Closes this path.

+
Source

pub fn id(&self) -> PathId

The PathId of this path.

+
Source

pub fn status(&self) -> Result<PathStatus, ClosedPath>

The current local PathStatus of this path.

+
Source

pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError>

Sets the PathStatus of this path.

+
Source

pub fn stats(&self) -> PathStats

Returns the PathStats for this path.

+
Source

pub fn close(&self) -> Result<(), ClosePathError>

Closes this path.

The path is immediately considered closed by the local endpoint. Once the state is removed, after a short period of time for any in-flight packets, a PathEvent::Abandoned is returned.

-
Source

pub fn set_max_idle_timeout( +

Source

pub fn set_max_idle_timeout( &self, timeout: Option<Duration>, ) -> Result<Option<Duration>, ClosedPath>

Sets the keep_alive_interval for a specific path

See TransportConfig::default_path_keep_alive_interval for details.

Returns the previous value of the setting.

-
Source

pub fn set_keep_alive_interval( +

Source

pub fn set_keep_alive_interval( &self, interval: Option<Duration>, ) -> Result<Option<Duration>, ClosedPath>

Sets the keep_alive_interval for a specific path

See TransportConfig::default_path_keep_alive_interval for details.

Returns the previous value of the setting.

-
Source

pub fn observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath>

Track changes on our external address as reported by the peer.

+
Source

pub fn observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath>

Track changes on our external address as reported by the peer.

If the address-discovery extension is not negotiated, the stream will never return.

-
Source

pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath>

The peer’s UDP address for this path.

-
Source

pub fn ping(&self) -> Result<(), ClosedPath>

Ping the remote endpoint over this path.

-

Trait Implementations§

Source§

impl Clone for Path

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Path

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for Path

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for Path

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +
Source

pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath>

The peer’s UDP address for this path.

+
Source

pub fn ping(&self) -> Result<(), ClosedPath>

Ping the remote endpoint over this path.

+

Trait Implementations§

Source§

impl Clone for Path

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Path

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for Path

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for Path

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl Freeze for Path

§

impl RefUnwindSafe for Path

§

impl Send for Path

§

impl Sync for Path

§

impl Unpin for Path

§

impl UnwindSafe for Path

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.ReadDatagram.html b/pr/523/docs/noq/struct.ReadDatagram.html index 751453f7e..cac5d37c3 100644 --- a/pr/523/docs/noq/struct.ReadDatagram.html +++ b/pr/523/docs/noq/struct.ReadDatagram.html @@ -1,6 +1,6 @@ -ReadDatagram in noq - Rust

ReadDatagram

Struct ReadDatagram 

Source
pub struct ReadDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::read_datagram

-

Trait Implementations§

Source§

impl Future for ReadDatagram<'_>

Source§

type Output = Result<Bytes, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for ReadDatagram<'a>
where +ReadDatagram in noq - Rust

ReadDatagram

Struct ReadDatagram 

Source
pub struct ReadDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::read_datagram

+

Trait Implementations§

Source§

impl Future for ReadDatagram<'_>

Source§

type Output = Result<Bytes, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for ReadDatagram<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for ReadDatagram<'a>

§

impl<'a> !RefUnwindSafe for ReadDatagram<'a>

§

impl<'a> Send for ReadDatagram<'a>

§

impl<'a> Sync for ReadDatagram<'a>

§

impl<'a> !UnwindSafe for ReadDatagram<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.SendDatagram.html b/pr/523/docs/noq/struct.SendDatagram.html index ba07ce89e..04c0cba2f 100644 --- a/pr/523/docs/noq/struct.SendDatagram.html +++ b/pr/523/docs/noq/struct.SendDatagram.html @@ -1,6 +1,6 @@ -SendDatagram in noq - Rust

SendDatagram

Struct SendDatagram 

Source
pub struct SendDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::send_datagram_wait

-

Trait Implementations§

Source§

impl Future for SendDatagram<'_>

Source§

type Output = Result<(), SendDatagramError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for SendDatagram<'a>
where +SendDatagram in noq - Rust

SendDatagram

Struct SendDatagram 

Source
pub struct SendDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::send_datagram_wait

+

Trait Implementations§

Source§

impl Future for SendDatagram<'_>

Source§

type Output = Result<(), SendDatagramError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for SendDatagram<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for SendDatagram<'a>

§

impl<'a> !RefUnwindSafe for SendDatagram<'a>

§

impl<'a> Send for SendDatagram<'a>

§

impl<'a> Sync for SendDatagram<'a>

§

impl<'a> !UnwindSafe for SendDatagram<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.SendStream.html b/pr/523/docs/noq/struct.SendStream.html index 540865dff..b6a413534 100644 --- a/pr/523/docs/noq/struct.SendStream.html +++ b/pr/523/docs/noq/struct.SendStream.html @@ -8,7 +8,7 @@ ready will always result in no data being written to the stream. This is true of succeed immediately when any progress is made, and is not true of methods which might need to perform multiple writes internally before succeeding. Each write method documents whether it is cancel-safe.

-

Implementations§

Source§

impl SendStream

Source

pub async fn write(&mut self, buf: &[u8]) -> Result<usize, WriteError>

Write a buffer into this stream, returning how many bytes were written

+

Implementations§

Source§

impl SendStream

Source

pub async fn write(&mut self, buf: &[u8]) -> Result<usize, WriteError>

Write a buffer into this stream, returning how many bytes were written

Unless this method errors, it waits until some amount of buf can be written into this stream, and then writes as much as it can without waiting again. Due to congestion and flow control, this may be shorter than buf.len(). On success this yields the length of the @@ -58,7 +58,7 @@ or an error occurs. This method mutates bufs by mutating all chunks

§Cancel safety

This method is not cancellation safe. Even if this does not resolve, some bytes may have been written when previously polled.

-
Source

pub fn finish(&mut self) -> Result<(), ClosedStream>

Notify the peer that no more data will ever be written to this stream

+
Source

pub fn finish(&mut self) -> Result<(), ClosedStream>

Notify the peer that no more data will ever be written to this stream

It is an error to write to a SendStream after finish()ing it. reset() may still be called after finish to abandon transmission of any stream data that might still be buffered.

@@ -66,21 +66,21 @@ still be buffered.

May fail if finish() or reset() was previously called. This error is harmless and serves only to indicate that the caller may have incorrect assumptions about the stream’s state.

-
Source

pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream>

Close the send stream immediately.

+
Source

pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream>

Close the send stream immediately.

No new data can be written after calling this method. Locally buffered data is dropped, and previously transmitted data will no longer be retransmitted if lost. If an attempt has already been made to finish the stream, the peer may still receive all written data.

May fail if finish() or reset() was previously called. This error is harmless and serves only to indicate that the caller may have incorrect assumptions about the stream’s state.

-
Source

pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream>

Set the priority of the send stream

+
Source

pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream>

Set the priority of the send stream

Every send stream has an initial priority of 0. Locally buffered data from streams with higher priority will be transmitted before data from streams with lower priority. Changing the priority of a stream with pending data may only take effect after that data has been transmitted. Using many different priority levels per connection may have a negative impact on performance.

-
Source

pub fn priority(&self) -> Result<i32, ClosedStream>

Get the priority of the send stream

-
Source

pub fn stopped(&self) -> Stopped

Completes when the peer stops the stream or reads the stream to completion

+
Source

pub fn priority(&self) -> Result<i32, ClosedStream>

Get the priority of the send stream

+
Source

pub fn stopped(&self) -> Stopped

Completes when the peer stops the stream or reads the stream to completion

Yields Some with the stop error code if the peer stops the stream. Yields None if the local side finish()es the stream and then the peer acknowledges receipt of all stream data (although not necessarily the processing of it), after which the peer @@ -88,8 +88,8 @@ closing the stream is no longer meaningful.

For a variety of reasons, the peer may not send acknowledgements immediately upon receiving data. As such, relying on stopped to know when the peer has read a stream to completion may introduce more latency than using an application-level response of some sort.

-
Source

pub fn id(&self) -> StreamId

Get the identity of this stream

-
Source

pub fn poll_write( +

Source

pub fn id(&self) -> StreamId

Get the identity of this stream

+
Source

pub fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], @@ -98,22 +98,22 @@ may introduce more latency than using an application-level response of some sort

If the stream is not ready for writing, the method returns Poll::Pending and arranges for the current task (via cx.waker().wake_by_ref()) to receive a notification when the stream becomes writable or is closed.

-

Trait Implementations§

Source§

impl AsyncWrite for SendStream

Available on crate feature futures-io only.

Trait Implementations§

Source§

impl AsyncWrite for SendStream

Available on crate feature futures-io only.
Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], -) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to flush the object, ensuring that any buffered data reach -their destination. Read more
Source§

fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to close the object. Read more
§

fn poll_write_vectored( +) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to flush the object, ensuring that any buffered data reach +their destination. Read more
Source§

fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to close the object. Read more
§

fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>

Attempt to write bytes from bufs into the object using vectored -IO operations. Read more
Source§

impl AsyncWrite for SendStream

Source§

fn poll_write( +IO operations. Read more

Source§

impl AsyncWrite for SendStream

Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], -) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempts to flush the object, ensuring that any buffered data reach -their destination. Read more
Source§

fn poll_shutdown( +) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
Source§

fn poll_shutdown( self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll<Result<()>>

Initiates or attempts to shut down this writer, returning success when @@ -122,7 +122,7 @@ the I/O connection has completely shut down. Read more
Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored -implementation. Read more
Source§

impl Debug for SendStream

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for SendStream

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +implementation. Read more

Source§

impl Debug for SendStream

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for SendStream

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<W> AsyncWriteExt for W
where W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where Self: Unpin,

Writes a buffer into this writer, returning how many bytes were diff --git a/pr/523/docs/noq/struct.Stopped.html b/pr/523/docs/noq/struct.Stopped.html index a90b38c9f..4bb4f74f6 100644 --- a/pr/523/docs/noq/struct.Stopped.html +++ b/pr/523/docs/noq/struct.Stopped.html @@ -1,6 +1,6 @@ -Stopped in noq - Rust

Stopped

Struct Stopped 

Source
pub struct Stopped { /* private fields */ }
Expand description

Future returned from SendStream::stopped.

-

Trait Implementations§

Source§

impl Debug for Stopped

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Future for Stopped

Source§

type Output = Result<Option<VarInt>, StoppedError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin> Unpin for Stopped
where +Stopped in noq - Rust

Stopped

Struct Stopped 

Source
pub struct Stopped { /* private fields */ }
Expand description

Future returned from SendStream::stopped.

+

Trait Implementations§

Source§

impl Debug for Stopped

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Future for Stopped

Source§

type Output = Result<Option<VarInt>, StoppedError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin> Unpin for Stopped
where PinnedFieldsOf<__Origin<'__pin>>: Unpin,

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/struct.WeakConnectionHandle.html b/pr/523/docs/noq/struct.WeakConnectionHandle.html index 2b8536424..68daf3016 100644 --- a/pr/523/docs/noq/struct.WeakConnectionHandle.html +++ b/pr/523/docs/noq/struct.WeakConnectionHandle.html @@ -1,10 +1,10 @@ -WeakConnectionHandle in noq - Rust

WeakConnectionHandle

Struct WeakConnectionHandle 

Source
pub struct WeakConnectionHandle(/* private fields */);
Expand description

A handle to some connection internals, use with care.

+WeakConnectionHandle in noq - Rust

WeakConnectionHandle

Struct WeakConnectionHandle 

Source
pub struct WeakConnectionHandle(/* private fields */);
Expand description

A handle to some connection internals, use with care.

This contains a weak reference to the connection so will not itself keep the connection alive.

-

Implementations§

Source§

impl WeakConnectionHandle

Source

pub fn is_alive(&self) -> bool

Returns true if the Connection associated with this handle is still alive.

-
Source

pub fn upgrade(&self) -> Option<Connection>

Upgrade the handle to a full Connection

-
Source

pub fn is_same_connection(&self, other: &Self) -> bool

Returns true if the two WeakConnectionHandle point at the same connection.

-

Trait Implementations§

Source§

impl Clone for WeakConnectionHandle

Source§

fn clone(&self) -> WeakConnectionHandle

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WeakConnectionHandle

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Implementations§

Source§

impl WeakConnectionHandle

Source

pub fn is_alive(&self) -> bool

Returns true if the Connection associated with this handle is still alive.

+
Source

pub fn upgrade(&self) -> Option<Connection>

Upgrade the handle to a full Connection

+
Source

pub fn is_same_connection(&self, other: &Self) -> bool

Returns true if the two WeakConnectionHandle point at the same connection.

+

Trait Implementations§

Source§

impl Clone for WeakConnectionHandle

Source§

fn clone(&self) -> WeakConnectionHandle

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WeakConnectionHandle

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq/struct.WeakPathHandle.html b/pr/523/docs/noq/struct.WeakPathHandle.html index 6132c023c..d7a9ad9a1 100644 --- a/pr/523/docs/noq/struct.WeakPathHandle.html +++ b/pr/523/docs/noq/struct.WeakPathHandle.html @@ -1,12 +1,12 @@ -WeakPathHandle in noq - Rust

WeakPathHandle

Struct WeakPathHandle 

Source
pub struct WeakPathHandle { /* private fields */ }
Expand description

Weak handle for a Path that does not keep the connection alive.

+WeakPathHandle in noq - Rust

WeakPathHandle

Struct WeakPathHandle 

Source
pub struct WeakPathHandle { /* private fields */ }
Expand description

Weak handle for a Path that does not keep the connection alive.

As long as a WeakPathHandle for a path exists, that path’s final stats will not be dropped even if the path was abandoned.

The WeakPathHandle can be upgraded to a Path as long as its Connection has not been dropped.

-

Implementations§

Source§

impl WeakPathHandle

Source

pub fn id(&self) -> PathId

Returns the PathId of this path.

-
Source

pub fn upgrade(&self) -> Option<Path>

Upgrades to a Path.

+

Implementations§

Source§

impl WeakPathHandle

Source

pub fn id(&self) -> PathId

Returns the PathId of this path.

+
Source

pub fn upgrade(&self) -> Option<Path>

Upgrades to a Path.

Returns None if the connection was dropped.

-

Trait Implementations§

Source§

impl Clone for WeakPathHandle

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WeakPathHandle

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for WeakPathHandle

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for WeakPathHandle

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for WeakPathHandle

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for WeakPathHandle

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WeakPathHandle

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for WeakPathHandle

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for WeakPathHandle

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for WeakPathHandle

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq/struct.ZeroRttAccepted.html b/pr/523/docs/noq/struct.ZeroRttAccepted.html index f22efa639..1849df0f8 100644 --- a/pr/523/docs/noq/struct.ZeroRttAccepted.html +++ b/pr/523/docs/noq/struct.ZeroRttAccepted.html @@ -1,7 +1,7 @@ -ZeroRttAccepted in noq - Rust

ZeroRttAccepted

Struct ZeroRttAccepted 

Source
pub struct ZeroRttAccepted(/* private fields */);
Expand description

Future that completes when a connection is fully established

+ZeroRttAccepted in noq - Rust

ZeroRttAccepted

Struct ZeroRttAccepted 

Source
pub struct ZeroRttAccepted(/* private fields */);
Expand description

Future that completes when a connection is fully established

For clients, the resulting value indicates if 0-RTT was accepted. For servers, the resulting value is meaningless.

-

Trait Implementations§

Source§

impl Future for ZeroRttAccepted

Source§

type Output = bool

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +

Trait Implementations§

Source§

impl Future for ZeroRttAccepted

Source§

type Output = bool

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq/trait.NetworkChangeHint.html b/pr/523/docs/noq/trait.NetworkChangeHint.html index 5745f9f4c..bd7b8f57b 100644 --- a/pr/523/docs/noq/trait.NetworkChangeHint.html +++ b/pr/523/docs/noq/trait.NetworkChangeHint.html @@ -1,4 +1,4 @@ -NetworkChangeHint in noq - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
+NetworkChangeHint in noq - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
     // Required method
     fn is_path_recoverable(
         &self,
@@ -6,7 +6,7 @@
         network_path: FourTuple,
     ) -> bool;
 }
Expand description

Hints when the caller identifies a network change.

-

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

+

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

After network changes, paths may not be recoverable. In this case, waiting for the path to become idle may take longer than what is desirable. If Self::is_path_recoverable returns false, a multipath-enabled, client-side connection will establish a new path to diff --git a/pr/523/docs/noq_proto/enum.ClosePathError.html b/pr/523/docs/noq_proto/enum.ClosePathError.html index c424416f5..b668f2598 100644 --- a/pr/523/docs/noq_proto/enum.ClosePathError.html +++ b/pr/523/docs/noq_proto/enum.ClosePathError.html @@ -1,4 +1,4 @@ -ClosePathError in noq_proto - Rust

ClosePathError

Enum ClosePathError 

Source
pub enum ClosePathError {
+ClosePathError in noq_proto - Rust

ClosePathError

Enum ClosePathError 

Source
pub enum ClosePathError {
     MultipathNotNegotiated,
     ClosedPath,
     LastOpenPath,
@@ -7,8 +7,8 @@
 
§

ClosedPath

The path is already closed or was never opened

§

LastOpenPath

Cannot close the last remaining open path via the local API.

Use Connection::close to end the connection instead.

-

Trait Implementations§

Source§

impl Clone for ClosePathError

Source§

fn clone(&self) -> ClosePathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClosePathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ClosePathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ClosePathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for ClosePathError

Source§

fn eq(&self, other: &ClosePathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for ClosePathError

Source§

impl StructuralPartialEq for ClosePathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for ClosePathError

Source§

fn clone(&self) -> ClosePathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClosePathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ClosePathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ClosePathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for ClosePathError

Source§

fn eq(&self, other: &ClosePathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for ClosePathError

Source§

impl StructuralPartialEq for ClosePathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq_proto/enum.ConnectionError.html b/pr/523/docs/noq_proto/enum.ConnectionError.html index 83b19a52d..ab49e5cee 100644 --- a/pr/523/docs/noq_proto/enum.ConnectionError.html +++ b/pr/523/docs/noq_proto/enum.ConnectionError.html @@ -1,4 +1,4 @@ -ConnectionError in noq_proto - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
+ConnectionError in noq_proto - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
     VersionMismatch,
     TransportError(TransportError),
     ConnectionClosed(ConnectionClose),
@@ -20,8 +20,8 @@ and §

LocallyClosed

The local application closed the connection

§

CidsExhausted

The connection could not be created because not enough of the CID space is available

Try using longer connection IDs.

-

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for Error

Source§

fn from(x: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for Error

Source§

fn from(x: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq_proto/enum.Event.html b/pr/523/docs/noq_proto/enum.Event.html index f8e068b09..445b16af3 100644 --- a/pr/523/docs/noq_proto/enum.Event.html +++ b/pr/523/docs/noq_proto/enum.Event.html @@ -1,4 +1,4 @@ -Event in noq_proto - Rust

Event

Enum Event 

Source
pub enum Event {
+Event in noq_proto - Rust

Event

Enum Event 

Source
pub enum Event {
     HandshakeDataReady,
     Connected,
     HandshakeConfirmed,
@@ -22,7 +22,7 @@
 
§

DatagramsUnblocked

One or more application datagrams have been sent after blocking

§

Path(PathEvent)

(Multi)Path events

§

NatTraversal(Event)

n0’s nat traversal events

-

Trait Implementations§

Source§

impl Debug for Event

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !Freeze for Event

§

impl !RefUnwindSafe for Event

§

impl Send for Event

§

impl Sync for Event

§

impl Unpin for Event

§

impl !UnwindSafe for Event

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Debug for Event

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !Freeze for Event

§

impl !RefUnwindSafe for Event

§

impl Send for Event

§

impl Sync for Event

§

impl Unpin for Event

§

impl !UnwindSafe for Event

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

diff --git a/pr/523/docs/noq_proto/enum.PathError.html b/pr/523/docs/noq_proto/enum.PathError.html index 7053bcd52..142401d2f 100644 --- a/pr/523/docs/noq_proto/enum.PathError.html +++ b/pr/523/docs/noq_proto/enum.PathError.html @@ -1,4 +1,4 @@ -PathError in noq_proto - Rust

PathError

Enum PathError 

Source
pub enum PathError {
+PathError in noq_proto - Rust

PathError

Enum PathError 

Source
pub enum PathError {
     MultipathNotNegotiated,
     ServerSideNotAllowed,
     MaxPathIdReached,
@@ -12,8 +12,8 @@
 
§

RemoteCidsExhausted

No remote CIDs available to open a new path

§

ValidationFailed

Path could not be validated and will be abandoned

§

InvalidRemoteAddress(SocketAddr)

The remote address for the path is not supported by the endpoint

-

Trait Implementations§

Source§

impl Clone for PathError

Source§

fn clone(&self) -> PathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for PathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for PathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for PathError

Source§

fn eq(&self, other: &PathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Copy for PathError

Source§

impl Eq for PathError

Source§

impl StructuralPartialEq for PathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for PathError

Source§

fn clone(&self) -> PathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for PathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for PathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for PathError

Source§

fn eq(&self, other: &PathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Copy for PathError

Source§

impl Eq for PathError

Source§

impl StructuralPartialEq for PathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq_proto/enum.PathEvent.html b/pr/523/docs/noq_proto/enum.PathEvent.html index aefe12bcf..16d3123f6 100644 --- a/pr/523/docs/noq_proto/enum.PathEvent.html +++ b/pr/523/docs/noq_proto/enum.PathEvent.html @@ -39,7 +39,7 @@ changes the status.

Fields

§id: PathId

Path over which the observed address was reported, PathId::ZERO when multipath is not negotiated

§addr: SocketAddr

The address observed by the remote over this path

-

Trait Implementations§

Source§

impl Clone for PathEvent

Source§

fn clone(&self) -> PathEvent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for PathEvent

Source§

fn eq(&self, other: &PathEvent) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +

Trait Implementations§

Source§

impl Clone for PathEvent

Source§

fn clone(&self) -> PathEvent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for PathEvent

Source§

fn eq(&self, other: &PathEvent) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for PathEvent

Source§

impl StructuralPartialEq for PathEvent

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq_proto/struct.Connection.html b/pr/523/docs/noq_proto/struct.Connection.html index c475ef4da..419485186 100644 --- a/pr/523/docs/noq_proto/struct.Connection.html +++ b/pr/523/docs/noq_proto/struct.Connection.html @@ -33,7 +33,7 @@ increasing time. Specifically, calling Instant may be interleaved in any order with a call to handle_event at that same instant; however events or timeouts with different instants must not be interleaved.

-

Implementations§

Source§

impl Connection

Source

pub fn poll_timeout(&mut self) -> Option<Instant>

Returns the next time at which handle_timeout should be called

+

Implementations§

Source§

impl Connection

Source

pub fn poll_timeout(&mut self) -> Option<Instant>

Returns the next time at which handle_timeout should be called

The value returned may change after:

  • the application performed some I/O on the connection
  • @@ -197,7 +197,7 @@ decrement by one for each time a remotely initiated stream of matching direction
Source

pub fn is_multipath_negotiated(&self) -> bool

Whether the Multipath for QUIC extension is enabled.

Multipath is only enabled after the handshake is completed and if it was enabled by both peers.

-
Source

pub fn handle_network_change( +

Source

pub fn handle_network_change( &mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant, @@ -212,26 +212,26 @@ paths as non recoverable when necessary accelerates connectivity re-establishmen allow it altogether.

The optional hint allows callers to indicate when paths are non-recoverable and should be migrated to new a PathId.

-

Source

pub fn current_mtu(&self) -> u16

Storage size required for the largest packet that can be transmitted on all currently +

Source

pub fn current_mtu(&self) -> u16

Storage size required for the largest packet that can be transmitted on all currently available paths

Buffers passed to Connection::poll_transmit should be at least this large.

When multipath is enabled, this value is the minimum MTU across all available paths.

-
Source

pub fn add_nat_traversal_address( +

Source

pub fn add_nat_traversal_address( &mut self, address: SocketAddr, ) -> Result<(), Error>

Add addresses the local endpoint considers are reachable for nat traversal.

-
Source

pub fn remove_nat_traversal_address( +

Source

pub fn remove_nat_traversal_address( &mut self, address: SocketAddr, ) -> Result<(), Error>

Removes an address the endpoing no longer considers reachable for nat traversal

Addresses not present in the set will be silently ignored.

-
Source

pub fn get_local_nat_traversal_addresses( +

Source

pub fn get_local_nat_traversal_addresses( &self, ) -> Result<Vec<SocketAddr>, Error>

Get the current local nat traversal addresses

-
Source

pub fn get_remote_nat_traversal_addresses( +

Source

pub fn get_remote_nat_traversal_addresses( &self, ) -> Result<Vec<SocketAddr>, Error>

Get the currently advertised nat traversal addresses by the server

-
Source

pub fn initiate_nat_traversal_round( +

Source

pub fn initiate_nat_traversal_round( &mut self, now: Instant, ) -> Result<Vec<SocketAddr>, Error>

Initiates a new nat traversal round

@@ -241,7 +241,7 @@ initiated, the previous one is cancelled, and paths that have not been opened ar

Returns the server addresses that are now being probed. If addresses fail due to spurious errors, these might succeed later and not be returned in this set.

-

Trait Implementations§

Source§

impl Debug for Connection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Debug for Connection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

diff --git a/pr/523/docs/noq_proto/struct.MultipathNotNegotiated.html b/pr/523/docs/noq_proto/struct.MultipathNotNegotiated.html index d77c7ce74..8131e4a2a 100644 --- a/pr/523/docs/noq_proto/struct.MultipathNotNegotiated.html +++ b/pr/523/docs/noq_proto/struct.MultipathNotNegotiated.html @@ -1,5 +1,5 @@ -MultipathNotNegotiated in noq_proto - Rust

MultipathNotNegotiated

Struct MultipathNotNegotiated 

Source
pub struct MultipathNotNegotiated { /* private fields */ }
Expand description

Error when the multipath extension was not negotiated, but attempted to be used.

-

Trait Implementations§

Source§

impl Clone for MultipathNotNegotiated

Source§

fn clone(&self) -> MultipathNotNegotiated

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MultipathNotNegotiated

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for MultipathNotNegotiated

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for MultipathNotNegotiated

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl Copy for MultipathNotNegotiated

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +MultipathNotNegotiated in noq_proto - Rust

MultipathNotNegotiated

Struct MultipathNotNegotiated 

Source
pub struct MultipathNotNegotiated { /* private fields */ }
Expand description

Error when the multipath extension was not negotiated, but attempted to be used.

+

Trait Implementations§

Source§

impl Clone for MultipathNotNegotiated

Source§

fn clone(&self) -> MultipathNotNegotiated

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MultipathNotNegotiated

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for MultipathNotNegotiated

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for MultipathNotNegotiated

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl Copy for MultipathNotNegotiated

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/523/docs/noq_proto/struct.TransportError.html b/pr/523/docs/noq_proto/struct.TransportError.html index d05424148..e45d04fe6 100644 --- a/pr/523/docs/noq_proto/struct.TransportError.html +++ b/pr/523/docs/noq_proto/struct.TransportError.html @@ -11,7 +11,7 @@
§reason: String

Human-readable explanation of the reason

§crypto: Option<Arc<dyn Error + Send + Sync>>

An underlying crypto (e.g. TLS) layer error

Implementations§

Source§

impl Error

Source

pub fn new(code: Code, reason: String) -> Self

Construct an error with a code and a reason

-

Trait Implementations§

Source§

impl Clone for Error

Source§

fn clone(&self) -> Error

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for Error

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for ConnectionClose

Source§

fn from(x: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for TransportError

Source§

fn from(e: Error) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for Error

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +

Trait Implementations§

Source§

impl Clone for Error

Source§

fn clone(&self) -> Error

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for Error

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for ConnectionClose

Source§

fn from(x: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for TransportError

Source§

fn from(e: Error) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for Error

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for Error

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/523/docs/noq_proto/trait.NetworkChangeHint.html b/pr/523/docs/noq_proto/trait.NetworkChangeHint.html index 3e7e98ff8..021b478c8 100644 --- a/pr/523/docs/noq_proto/trait.NetworkChangeHint.html +++ b/pr/523/docs/noq_proto/trait.NetworkChangeHint.html @@ -1,4 +1,4 @@ -NetworkChangeHint in noq_proto - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
+NetworkChangeHint in noq_proto - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
     // Required method
     fn is_path_recoverable(
         &self,
@@ -6,7 +6,7 @@
         network_path: FourTuple,
     ) -> bool;
 }
Expand description

Hints when the caller identifies a network change.

-

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

+

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

After network changes, paths may not be recoverable. In this case, waiting for the path to become idle may take longer than what is desirable. If Self::is_path_recoverable returns false, a multipath-enabled, client-side connection will establish a new path to diff --git a/pr/523/docs/search.index/entry/7780e033398e.js b/pr/523/docs/search.index/entry/34c09ea0dc28.js similarity index 94% rename from pr/523/docs/search.index/entry/7780e033398e.js rename to pr/523/docs/search.index/entry/34c09ea0dc28.js index 99bf12d66..7719f8455 100644 --- a/pr/523/docs/search.index/entry/7780e033398e.js +++ b/pr/523/docs/search.index/entry/34c09ea0dc28.js @@ -1 +1 @@ -rd_("Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ag[463,15,464,0,4085,0,0]Al[3096,15,3097,1784,4086,0,0]Al[1985,15,1986,1986,4087,0,0]Al[3096,15,1689,1689,1433,0,0]Ao[1195,13,1196,1196,3928,3037,0]Am[463,13,464,3640,4749,3037,0]Am[463,13,464,4142,1418,3037,0]Al[463,13,464,1094,503,3037,0]Am[463,13,464,1094,4359,3037,0]Am[463,13,464,4034,4352,3037,0]Am[463,13,464,4034,3044,3037,0]Am[463,13,464,4034,3239,3037,0]Am[463,13,464,4034,4351,3037,0]Am[463,13,464,4039,3257,3037,0]Am[463,13,464,4039,4120,3037,0]Aj[463,13,464,0,1443,3037,0]Aj[463,13,464,0,4915,3037,0]Aj[463,13,464,0,1152,3037,0]Aj[463,13,464,0,1426,3037,0]Aj[463,13,464,0,2294,3037,0]Aj[463,13,464,0,3217,3037,0]Aj[463,13,464,0,3041,3037,0]Aj[463,13,464,0,1867,3037,0]Aj[463,13,464,0,4071,3037,0]Aj[463,13,464,0,4444,3037,0]Aj[463,13,464,0,3941,3037,0]Aj[463,13,464,0,3931,3037,0]Aj[463,13,464,0,3025,3037,0]Aj[463,13,464,0,4441,3037,0]Aj[463,13,464,0,4642,3037,0]Aj[463,13,464,0,4077,3037,0]Aj[463,13,464,0,4080,3037,0]Aj[463,13,464,0,4085,3037,0]Aj[463,13,464,0,4808,3037,0]Ai[463,13,464,0,510,3037,0]Ai[463,13,464,0,126,3037,0]Aj[463,13,464,0,2281,3037,0]Ak[463,13,1693,0,5064,3037,0]Ak[463,13,1773,0,1169,3037,0]Ao[3096,13,3097,1810,1444,3037,0]Ao[3096,13,3097,1810,4916,3037,0]Ao[3096,13,3097,3061,1153,3037,0]Ao[3096,13,3097,3070,4750,3037,0]Ao[3096,13,3097,1366,1427,3037,0]Ao[3096,13,3097,1366,3233,3037,0]Ao[3096,13,3097,1366,3040,3037,0]Ao[3096,13,3097,1366,4748,3037,0]Ao[3096,13,3097,1366,4804,3037,0]Ao[3096,13,3097,1366,3207,3037,0]Ao[3096,13,3097,1381,2295,3037,0]Ao[3096,13,3097,1381,3218,3037,0]Ao[3096,13,3097,1381,3042,3037,0]Ao[3096,13,3097,1120,3045,3037,0]Ao[3096,13,3097,1120,4241,3037,0]Ao[3096,13,3097,1125,1868,3037,0]Ao[3096,13,3097,1125,3258,3037,0]Ao[3096,13,3097,1125,3940,3037,0]Ao[3096,13,3097,2002,3959,3037,0]Ao[3096,13,3097,2002,4353,3037,0]Ao[3096,13,3097,2002,4075,3037,0]Ao[3096,13,3097,3641,4445,3037,0]Ao[3096,13,3097,3641,3038,3037,0]Ao[3096,13,3097,3641,4319,3037,0]Ao[3096,13,3097,3194,3942,3037,0]Ao[3096,13,3097,1691,3932,3037,0]Ao[3096,13,3097,1356,3026,3037,0]Ao[3096,13,3097,1356,4334,3037,0]Ao[3096,13,3097,1356,3224,3037,0]Ao[3096,13,3097,1356,3247,3037,0]Ao[3096,13,3097,1356,4082,3037,0]Ao[3096,13,3097,1356,4443,3037,0]Ao[3096,13,3097,1356,4644,3037,0]Ao[3096,13,3097,2305,4648,3037,0]Ao[3096,13,3097,2305,4078,3037,0]Ao[3096,13,3097,1756,2267,3037,0]Ao[3096,13,3097,1756,4746,3037,0]Ao[3096,13,3097,1784,4081,3037,0]Ao[3096,13,3097,1784,4086,3037,0]Al[3096,13,3097,0,4357,3037,0]Al[3096,13,3097,0,4809,3037,0]An[3096,13,3097,3097,511,3037,0]An[3096,13,3097,3097,127,3037,0]Ao[3096,13,3097,3097,2282,3037,0]Ao[3096,13,3097,3097,3024,3037,0]Ao[3096,13,1689,1689,4247,3037,0]Ao[3096,13,4957,4957,4855,3037,0]Ao[3096,13,4957,4957,1171,3037,0]Ao[3096,13,1694,1694,5065,3037,0]Al[3096,13,1774,0,1170,3037,0]Ao[1985,13,1986,1986,4087,3037,0]Ai[463,13,464,1094,503,0,0]Aj[463,13,464,1094,4359,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Aj[463,13,464,4039,3243,0,0]Ai[3096,14,3039,0,1420,0,0]Ai[3096,14,3039,0,3002,0,0]Ai[3096,14,3039,0,3020,0,0]Ai[3096,14,3039,0,4107,0,0]Ai[3096,14,3039,0,4100,0,0]Ai[3096,14,3958,0,2277,0,0]Ai[3096,14,3958,0,2297,0,0]Ai[3096,14,3958,0,2261,0,0]Ai[3096,14,3958,0,1855,0,0]Ae[1195,7,1196,0,0,0,0]Ah[3096,14,4456,0,499,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Af[463,5,3635,148,0,0,0]Ag[3096,5,3636,148,0,0,0]Al[1095,15,1096,1096,4848,0,0]Ae[2358,5,2359,0,0,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Al[3096,15,1689,1689,1433,0,0]Ag[463,19,464,0,1443,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1810,1444,0,0]Al[3096,19,3097,1366,1427,0,0]Ae[1195,5,1196,0,0,0,0]Ae[1095,5,1683,0,0,0,0]Ae[1095,5,1779,0,0,0,0]Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ai[463,13,464,0,2294,117,0]Ai[463,13,464,0,3217,117,0]Ai[463,13,464,0,4448,117,0]An[3096,13,3097,1381,2295,117,0]An[3096,13,3097,1381,3218,117,0]An[3096,13,3097,1381,4449,117,0]Ai[463,13,464,0,1443,137,0]Ai[463,13,464,0,1426,137,0]Ai[463,13,464,0,3941,137,0]Ai[463,13,464,0,4080,137,0]Ah[463,13,464,0,510,137,0]Ah[463,13,464,0,126,137,0]Ai[463,13,464,0,2281,137,0]An[3096,13,3097,1810,1444,137,0]An[3096,13,3097,3070,4750,137,0]An[3096,13,3097,1366,1427,137,0]An[3096,13,3097,1120,3045,137,0]An[3096,13,3097,1120,4241,137,0]An[3096,13,3097,1125,3258,137,0]An[3096,13,3097,3194,3942,137,0]An[3096,13,3097,2305,4648,137,0]An[3096,13,3097,1756,4746,137,0]An[3096,13,3097,1784,4081,137,0]Am[3096,13,3097,3097,511,137,0]Am[3096,13,3097,3097,127,137,0]An[3096,13,3097,3097,2282,137,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ai[3096,14,3958,0,1421,0,0]Ai[3096,14,3958,0,3009,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2279,0,0]Al[1985,14,1986,1986,2293,0,0]An[1195,13,1196,1196,134,1159,0]Ao[1195,13,1196,1196,3952,1159,0]Ao[1195,13,1196,1196,3928,1159,0]Ao[1195,13,1380,1380,4354,1159,0]Ao[3966,13,3967,3967,5006,1159,0]Am[463,13,464,4142,4912,1159,0]Am[463,13,464,3640,3209,1159,0]Am[463,13,464,3640,3211,1159,0]Am[463,13,464,3640,4918,1159,0]D`[463,13,464,3640,4749,1159,0,\"impl-Debug-for-SendDatagramError\"]Db[463,13,464,3640,4749,1827,0,\"impl-Display-for-SendDatagramError\"]Am[463,13,464,2304,2259,1159,0]Am[463,13,464,2304,4215,1159,0]Cg[463,13,464,4142,1418,1827,0,\"impl-Display-for-Lagged\"]Ce[463,13,464,4142,1418,1159,0,\"impl-Debug-for-Lagged\"]Am[463,13,464,4142,3231,1159,0]Am[463,13,464,4142,4849,1159,0]Am[463,13,464,2336,2263,1159,0]Ck[463,13,464,2336,3240,1827,0,\"impl-Display-for-RetryError\"]Ci[463,13,464,2336,3240,1159,0,\"impl-Debug-for-RetryError\"]Am[463,13,464,2336,4333,1159,0]Al[463,13,464,1094,503,1159,0]Am[463,13,464,1094,4359,1159,0]Am[463,13,464,4034,3237,1159,0]Am[463,13,464,4034,4856,1159,0]Co[463,13,464,4034,4352,1827,0,\"impl-Display-for-ReadToEndError\"]Cm[463,13,464,4034,4352,1159,0,\"impl-Debug-for-ReadToEndError\"]Cj[463,13,464,4034,3044,1827,0,\"impl-Display-for-ReadError\"]Ch[463,13,464,4034,3044,1159,0,\"impl-Debug-for-ReadError\"]Ci[463,13,464,4034,3239,1159,0,\"impl-Debug-for-ResetError\"]Ck[463,13,464,4034,3239,1827,0,\"impl-Display-for-ResetError\"]Cm[463,13,464,4034,4351,1159,0,\"impl-Debug-for-ReadExactError\"]Co[463,13,464,4034,4351,1827,0,\"impl-Display-for-ReadExactError\"]Am[463,13,464,1393,4121,1159,0]Am[463,13,464,1137,3955,1159,0]Am[463,13,464,4039,3243,1159,0]Ci[463,13,464,4039,3257,1159,0,\"impl-Debug-for-WriteError\"]Ck[463,13,464,4039,3257,1827,0,\"impl-Display-for-WriteError\"]Cm[463,13,464,4039,4120,1827,0,\"impl-Display-for-StoppedError\"]Ck[463,13,464,4039,4120,1159,0,\"impl-Debug-for-StoppedError\"]Am[463,13,464,4039,1857,1159,0]Cd[463,13,464,0,1443,1827,0,\"impl-Display-for-VarInt\"]Cb[463,13,464,0,1443,1159,0,\"impl-Debug-for-VarInt\"]D`[463,13,464,0,4915,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Db[463,13,464,0,4915,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]Aj[463,13,464,0,1152,1159,0]Cb[463,13,464,0,1426,1159,0,\"impl-Debug-for-PathId\"]Cd[463,13,464,0,1426,1827,0,\"impl-Display-for-PathId\"]Aj[463,13,464,0,2294,1159,0]Aj[463,13,464,0,3217,1159,0]Aj[463,13,464,0,3041,1159,0]Aj[463,13,464,0,4448,1159,0]Aj[463,13,464,0,1867,1159,0]Cj[463,13,464,0,4071,1827,0,\"impl-Display-for-ClosedStream\"]Ch[463,13,464,0,4071,1159,0,\"impl-Debug-for-ClosedStream\"]Ck[463,13,464,0,4444,1159,0,\"impl-Debug-for-ConnectionError\"]Cm[463,13,464,0,4444,1827,0,\"impl-Display-for-ConnectionError\"]Aj[463,13,464,0,4458,1159,0]Aj[463,13,464,0,4467,1159,0]Aj[463,13,464,0,4773,1159,0]Aj[463,13,464,0,4788,1159,0]Aj[463,13,464,0,3941,1159,0]Aj[463,13,464,0,4328,1159,0]Aj[463,13,464,0,4114,1159,0]Aj[463,13,464,0,4972,1159,0]Aj[463,13,464,0,4065,1159,0]Cg[463,13,464,0,3931,1159,0,\"impl-Debug-for-ConfigError\"]Ci[463,13,464,0,3931,1827,0,\"impl-Display-for-ConfigError\"]Cg[463,13,464,0,3025,1827,0,\"impl-Display-for-FrameType\"]Ce[463,13,464,0,3025,1159,0,\"impl-Debug-for-FrameType\"]Cm[463,13,464,0,4441,1827,0,\"impl-Display-for-ConnectionClose\"]Ck[463,13,464,0,4441,1159,0,\"impl-Debug-for-ConnectionClose\"]Cn[463,13,464,0,4642,1827,0,\"impl-Display-for-ApplicationClose\"]Cl[463,13,464,0,4642,1159,0,\"impl-Debug-for-ApplicationClose\"]Ch[463,13,464,0,4077,1159,0,\"impl-Debug-for-ConnectError\"]Cj[463,13,464,0,4077,1827,0,\"impl-Display-for-ConnectError\"]Cj[463,13,464,0,4080,1827,0,\"impl-Display-for-ConnectionId\"]Ch[463,13,464,0,4080,1159,0,\"impl-Debug-for-ConnectionId\"]Aj[463,13,464,0,4085,1159,0]Cn[463,13,464,0,4808,1159,0,\"impl-Debug-for-TransportErrorCode\"]D`[463,13,464,0,4808,1827,0,\"impl-Display-for-TransportErrorCode\"]Aj[463,13,464,0,3220,1159,0]Aj[463,13,464,0,4675,1159,0]Ai[463,13,464,0,510,1159,0]C`[463,13,464,0,126,1827,0,\"impl-Display-for-Dir\"]Bn[463,13,464,0,126,1159,0,\"impl-Debug-for-Dir\"]Cf[463,13,464,0,2281,1827,0,\"impl-Display-for-StreamId\"]Cd[463,13,464,0,2281,1159,0,\"impl-Debug-for-StreamId\"]Aj[463,13,464,0,2291,1159,0]Aj[463,13,3635,0,120,1159,0]Ak[463,13,3635,0,3012,1159,0]Ak[463,13,3635,0,1156,1159,0]Ak[463,13,3635,0,3936,1159,0]Ak[463,13,3635,0,1840,1159,0]Ak[463,13,3635,0,4233,1159,0]Ak[463,13,3635,0,4737,1159,0]Ak[463,13,1693,0,5064,1159,0]Ak[463,13,1693,0,3934,1159,0]Ak[463,13,1693,0,4812,1159,0]Cb[463,13,1773,0,1169,1159,0,\"impl-Debug-for-Error\"]Cd[463,13,1773,0,1169,1827,0,\"impl-Display-for-Error\"]Da[463,13,1773,0,4910,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Dc[463,13,1773,0,4910,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]Ao[3096,13,3097,3641,3212,1159,0]Ao[3096,13,3097,2305,2260,1159,0]Ci[3096,13,3097,1810,1444,1827,0,\"impl-Display-for-VarInt\"]Cg[3096,13,3097,1810,1444,1159,0,\"impl-Debug-for-VarInt\"]De[3096,13,3097,1810,4916,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Dg[3096,13,3097,1810,4916,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]Ao[3096,13,3097,3061,1153,1159,0]Db[3096,13,3097,3070,4750,1159,0,\"impl-Debug-for-SendDatagramError\"]Dd[3096,13,3097,3070,4750,1827,0,\"impl-Display-for-SendDatagramError\"]Ci[3096,13,3097,1366,1427,1827,0,\"impl-Display-for-PathId\"]Cg[3096,13,3097,1366,1427,1159,0,\"impl-Debug-for-PathId\"]Ao[3096,13,3097,1366,4110,1159,0]Ao[3096,13,3097,1366,3233,1159,0]Ao[3096,13,3097,1366,3040,1159,0]Ao[3096,13,3097,1366,4748,1159,0]Dc[3096,13,3097,1366,4804,1159,0,\"impl-Debug-for-SetPathStatusError\"]De[3096,13,3097,1366,4804,1827,0,\"impl-Display-for-SetPathStatusError\"]Cm[3096,13,3097,1366,3207,1827,0,\"impl-Display-for-ClosedPath\"]Ck[3096,13,3097,1366,3207,1159,0,\"impl-Debug-for-ClosedPath\"]Ao[3096,13,3097,1381,2295,1159,0]Ao[3096,13,3097,1381,3218,1159,0]Ao[3096,13,3097,1381,3042,1159,0]Ao[3096,13,3097,1381,4449,1159,0]Cj[3096,13,3097,1120,3045,1159,0,\"impl-Debug-for-ReadError\"]Cl[3096,13,3097,1120,3045,1827,0,\"impl-Display-for-ReadError\"]D`[3096,13,3097,1120,4241,1827,0,\"impl-Display-for-ReadableError\"]Cn[3096,13,3097,1120,4241,1159,0,\"impl-Debug-for-ReadableError\"]Ao[3096,13,3097,1125,1868,1159,0]Cm[3096,13,3097,1125,3258,1827,0,\"impl-Display-for-WriteError\"]Ck[3096,13,3097,1125,3258,1159,0,\"impl-Debug-for-WriteError\"]Cn[3096,13,3097,1125,3940,1827,0,\"impl-Display-for-FinishError\"]Cl[3096,13,3097,1125,3940,1159,0,\"impl-Debug-for-FinishError\"]Ao[3096,13,3097,2002,3959,1159,0]Ao[3096,13,3097,2002,4353,1159,0]Co[3096,13,3097,2002,4075,1827,0,\"impl-Display-for-ClosedStream\"]Cm[3096,13,3097,2002,4075,1159,0,\"impl-Debug-for-ClosedStream\"]Db[3096,13,3097,3641,4445,1827,0,\"impl-Display-for-ConnectionError\"]D`[3096,13,3097,3641,4445,1159,0,\"impl-Debug-for-ConnectionError\"]Cl[3096,13,3097,3641,3038,1827,0,\"impl-Display-for-PathError\"]Cj[3096,13,3097,3641,3038,1159,0,\"impl-Debug-for-PathError\"]Da[3096,13,3097,3641,4319,1827,0,\"impl-Display-for-ClosePathError\"]Co[3096,13,3097,3641,4319,1159,0,\"impl-Debug-for-ClosePathError\"]Dg[3096,13,3097,3641,5001,1159,0,\"impl-Debug-for-MultipathNotNegotiated\"]Di[3096,13,3097,3641,5001,1827,0,\"impl-Display-for-MultipathNotNegotiated\"]Ao[3096,13,3097,3641,1174,1159,0]Ao[3096,13,3097,1116,4459,1159,0]Ao[3096,13,3097,3194,4468,1159,0]Ao[3096,13,3097,3194,4774,1159,0]Ao[3096,13,3097,3194,4789,1159,0]Ao[3096,13,3097,3194,3942,1159,0]Ao[3096,13,3097,1691,4329,1159,0]Ao[3096,13,3097,1691,4116,1159,0]Ao[3096,13,3097,1691,4973,1159,0]Ao[3096,13,3097,1691,4067,1159,0]Cl[3096,13,3097,1691,3932,1159,0,\"impl-Debug-for-ConfigError\"]Cn[3096,13,3097,1691,3932,1827,0,\"impl-Display-for-ConfigError\"]Cl[3096,13,3097,1356,3026,1827,0,\"impl-Display-for-FrameType\"]Cj[3096,13,3097,1356,3026,1159,0,\"impl-Debug-for-FrameType\"]Da[3096,13,3097,1356,4334,1827,0,\"impl-Display-for-InvalidFrameId\"]Co[3096,13,3097,1356,4334,1159,0,\"impl-Debug-for-InvalidFrameId\"]Cm[3096,13,3097,1356,3224,1827,0,\"impl-Display-for-MaybeFrame\"]Ck[3096,13,3097,1356,3224,1159,0,\"impl-Debug-for-MaybeFrame\"]Cm[3096,13,3097,1356,3247,1827,0,\"impl-Display-for-StreamInfo\"]Ck[3096,13,3097,1356,3247,1159,0,\"impl-Debug-for-StreamInfo\"]Cm[3096,13,3097,1356,4082,1159,0,\"impl-Debug-for-DatagramInfo\"]Co[3096,13,3097,1356,4082,1827,0,\"impl-Display-for-DatagramInfo\"]Db[3096,13,3097,1356,4443,1827,0,\"impl-Display-for-ConnectionClose\"]D`[3096,13,3097,1356,4443,1159,0,\"impl-Debug-for-ConnectionClose\"]Dc[3096,13,3097,1356,4644,1827,0,\"impl-Display-for-ApplicationClose\"]Da[3096,13,3097,1356,4644,1159,0,\"impl-Debug-for-ApplicationClose\"]Ci[3096,13,3097,1356,2253,1159,0,\"impl-Debug-for-Datagram\"]Ck[3096,13,3097,1356,2253,1827,0,\"impl-Display-for-Datagram\"]Ao[3096,13,3097,2305,4648,1159,0]Ao[3096,13,3097,2305,2264,1159,0]Co[3096,13,3097,2305,4078,1827,0,\"impl-Display-for-ConnectError\"]Cm[3096,13,3097,2305,4078,1159,0,\"impl-Debug-for-ConnectError\"]Ao[3096,13,3097,2305,3926,1159,0]Cm[3096,13,3097,2305,3241,1827,0,\"impl-Display-for-RetryError\"]Ck[3096,13,3097,2305,3241,1159,0,\"impl-Debug-for-RetryError\"]Ao[3096,13,3097,1756,4236,1159,0]Ao[3096,13,3097,1756,4457,1159,0]Ao[3096,13,3097,1756,5005,1159,0]Ao[3096,13,3097,1756,2267,1159,0]Dd[3096,13,3097,1756,4746,1827,0,\"impl-Display-for-PacketDecodeError\"]Db[3096,13,3097,1756,4746,1159,0,\"impl-Debug-for-PacketDecodeError\"]Ao[3096,13,3097,1784,4447,1159,0]Ao[3096,13,3097,1784,4214,1159,0]Co[3096,13,3097,1784,4081,1827,0,\"impl-Display-for-ConnectionId\"]Cm[3096,13,3097,1784,4081,1159,0,\"impl-Debug-for-ConnectionId\"]Ao[3096,13,3097,1784,4086,1159,0]Ce[3096,13,3097,0,4357,1827,0,\"impl-Display-for-Error\"]Cc[3096,13,3097,0,4357,1159,0,\"impl-Debug-for-Error\"]Cd[3096,13,3097,0,4809,1827,0,\"impl-Display-for-Code\"]Cb[3096,13,3097,0,4809,1159,0,\"impl-Debug-for-Code\"]Ao[3096,13,3097,4254,3221,1159,0]Ao[3096,13,3097,4254,5099,1159,0]Ao[3096,13,3097,4844,4676,1159,0]An[3096,13,3097,3097,511,1159,0]Cc[3096,13,3097,3097,127,1159,0,\"impl-Debug-for-Dir\"]Ce[3096,13,3097,3097,127,1827,0,\"impl-Display-for-Dir\"]Ci[3096,13,3097,3097,2282,1159,0,\"impl-Debug-for-StreamId\"]Ck[3096,13,3097,3097,2282,1827,0,\"impl-Display-for-StreamId\"]Ao[3096,13,3097,3097,2292,1159,0]Cl[3096,13,3097,3097,3024,1827,0,\"impl-Display-for-FourTuple\"]Cj[3096,13,3097,3097,3024,1159,0,\"impl-Debug-for-FourTuple\"]Cn[3096,13,1689,1689,4247,1159,0,\"impl-Debug-for-UnexpectedEnd\"]D`[3096,13,1689,1689,4247,1827,0,\"impl-Display-for-UnexpectedEnd\"]Ao[3096,13,4957,4957,4855,1159,0]Ch[3096,13,4957,4957,1171,1827,0,\"impl-Display-for-Error\"]Cf[3096,13,4957,4957,1171,1159,0,\"impl-Debug-for-Error\"]Ao[3096,13,1694,1694,5065,1159,0]Ao[3096,13,1694,1694,3935,1159,0]Ao[3096,13,1694,1694,4815,1159,0]Cc[3096,13,1774,0,1170,1159,0,\"impl-Debug-for-Error\"]Ce[3096,13,1774,0,1170,1827,0,\"impl-Display-for-Error\"]Dg[3096,13,1774,1774,4911,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]De[3096,13,1774,1774,4911,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Am[3096,13,3636,148,121,1159,0]An[3096,13,3636,148,3013,1159,0]Ao[3096,13,3636,1352,1157,1159,0]Ao[3096,13,3636,1352,3937,1159,0]Ao[3096,13,3636,2358,1841,1159,0]Ao[3096,13,3636,2358,4234,1159,0]Ao[3096,13,3636,3636,4738,1159,0]Ch[3096,13,4706,4706,1172,1827,0,\"impl-Display-for-Error\"]Cf[3096,13,4706,4706,1172,1159,0,\"impl-Debug-for-Error\"]Ao[3096,13,4706,4706,1175,1159,0]An[1985,13,1986,416,4358,1159,0]Ao[1985,13,1986,1986,2279,1159,0]Ao[1985,13,1986,1986,2293,1159,0]Ao[1985,13,1986,1986,4087,1159,0]Aj[463,13,464,4142,4912,0,0]Al[3096,13,3097,1366,4110,0,0]Ag[463,14,464,0,2294,0,0]Al[3096,14,3097,1381,2295,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,14,3097,1756,5005,0,0]Ah[3096,14,4456,0,499,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,13,464,0,4972,0,0]Al[3096,13,3097,1691,4973,0,0]8Al[1195,13,1380,1380,4354,0,0]Al[3966,13,3967,3967,5006,0,0]Ag[463,13,464,0,4206,0,0]Aj[463,13,464,2304,2259,0,0]Ag[463,13,464,0,3234,0,0]Ag[463,13,464,0,4458,0,0]Ag[463,13,464,0,4328,0,0]Ag[463,13,464,0,4114,0,0]Ag[463,13,464,0,4065,0,0]Ag[463,13,464,0,4080,0,0]Ag[463,13,464,0,4675,0,0]Ag[463,13,464,0,2281,0,0]Ag[463,13,3635,0,120,0,0]Ah[463,13,3635,0,1156,0,0]Ah[463,13,3635,0,1840,0,0]Al[3096,13,3097,4477,4207,0,0]Al[3096,13,3097,1116,3235,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,1756,5124,0,0]Al[3096,13,3097,4254,5094,0,0]Al[3096,13,3097,1116,4459,0,0]Al[3096,13,3097,1691,4329,0,0]Al[3096,13,3097,1691,4116,0,0]Al[3096,13,3097,1691,4067,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,13,3097,1784,4081,0,0]Ai[3096,13,3097,0,4357,0,0]Al[3096,13,3097,4254,5099,0,0]Al[3096,13,3097,4844,4676,0,0]Al[3096,13,3097,3097,2282,0,0]Al[3096,13,3097,3097,3024,0,0]Aj[3096,13,3636,148,121,0,0]Al[3096,13,3636,1352,1157,0,0]Al[3096,13,3636,2358,1841,0,0]Ak[1985,13,1986,416,4358,0,0]Al[1095,13,4174,4174,5050,0,0]Al[1095,13,4174,4174,5051,0,0]Aa[463,3,0,0,0,0,0]Ah[463,13,464,0,510,133,0]Am[3096,13,3097,3097,511,133,0]Ag[463,12,464,0,3250,0,0]Aj[463,13,464,1994,1852,0,0]0Am[463,13,464,1393,4121,1852,0]Aj[463,13,464,0,4245,3250,0]Al[3096,12,3097,1691,3251,0,0]Ao[3096,13,3097,1691,4246,3251,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1381,3042,0,0]Ae[1095,7,1683,0,0,0,0]Ae[1095,7,1779,0,0,0,0]Ac[463,4,464,0,0,0,0]Ag[463,15,464,0,4085,0,0]Al[3096,15,3097,1784,4086,0,0]Al[1985,15,1986,1986,4087,0,0]210Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Al[3096,15,3097,1756,4457,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1094,0,0,0]Al[3096,15,3097,3641,1174,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Aj[463,15,464,4034,4352,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1366,1427,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Ai[3096,14,3039,0,4100,0,0]Al[1985,14,1986,1986,2279,0,0]Aa[519,3,0,0,0,0,0]Ai[3096,14,3097,0,4357,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1381,3042,0,0]Al[3096,14,3097,1356,2253,0,0]Al[463,13,464,3640,2274,487,0]Al[463,13,464,2336,2263,487,0]Ak[463,13,464,1094,503,487,0]Al[463,13,464,1094,4359,487,0]Al[463,13,464,4034,3237,487,0]Al[463,13,464,4039,3243,487,0]An[3096,13,3097,1120,1407,487,0]Am[1195,13,1196,1196,134,494,0]An[1195,13,1196,1196,3952,494,0]An[1195,13,1196,1196,3928,494,0]An[1195,13,1380,1380,3960,494,0]An[1195,13,1380,1380,1189,494,0]An[1195,13,1380,1380,4354,494,0]Ak[519,13,520,520,3929,494,0]An[3966,13,3967,3967,5006,494,0]Al[463,13,464,3640,4472,494,0]Al[463,13,464,3640,2274,494,0]Ai[463,13,464,0,4206,494,0]Al[463,13,464,4142,4912,494,0]Al[463,13,464,1094,2275,494,0]Al[463,13,464,1094,4640,494,0]Al[463,13,464,3640,3209,494,0]Al[463,13,464,3640,3211,494,0]Al[463,13,464,3640,1843,494,0]Al[463,13,464,3640,1419,494,0]Al[463,13,464,3640,3004,494,0]Al[463,13,464,3640,2247,494,0]Al[463,13,464,3640,4106,494,0]Al[463,13,464,3640,4111,494,0]Al[463,13,464,3640,4918,494,0]Al[463,13,464,3640,4749,494,0]0Al[463,13,464,2304,2259,494,0]Al[463,13,464,2304,4215,494,0]Al[463,13,464,2304,1399,494,0]Al[463,13,464,4142,1418,494,0]Al[463,13,464,4142,3231,494,0]Al[463,13,464,4142,4849,494,0]Al[463,13,464,2336,2263,494,0]Al[463,13,464,2336,3240,494,0]Al[463,13,464,2336,4333,494,0]Ak[463,13,464,1094,503,494,0]Al[463,13,464,1094,4359,494,0]Al[463,13,464,4034,3237,494,0]Al[463,13,464,4034,4856,494,0]Al[463,13,464,4034,4352,494,0]0Al[463,13,464,4034,3044,494,0]Df[463,13,464,4034,3044,494,0,\"impl-From%3CResetError%3E-for-ReadError\"]Dk[463,13,464,4034,3044,494,0,\"impl-From%3CConnectionError%3E-for-ReadError\"]Al[463,13,464,4034,3239,494,0]0Al[463,13,464,4034,4351,494,0]0Al[463,13,464,1393,4121,494,0]Al[463,13,464,1137,3955,494,0]Al[463,13,464,4039,3243,494,0]Di[463,13,464,4039,3257,494,0,\"impl-From%3CStoppedError%3E-for-WriteError\"]Di[463,13,464,4039,3257,494,0,\"impl-From%3CClosedStream%3E-for-WriteError\"]Dl[463,13,464,4039,3257,494,0,\"impl-From%3CConnectionError%3E-for-WriteError\"]Al[463,13,464,4039,3257,494,0]Al[463,13,464,4039,4120,494,0]0Al[463,13,464,4039,1857,494,0]Ai[463,13,464,0,3234,494,0]Ai[463,13,464,0,4245,494,0]Ai[463,13,464,0,4464,494,0]Ai[463,13,464,0,4098,494,0]Ai[463,13,464,0,4342,494,0]Dh[463,13,464,0,1443,494,0,\"impl-From%3CTransportErrorCode%3E-for-VarInt\"]Ch[463,13,464,0,1443,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cn[463,13,464,0,1443,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Ai[463,13,464,0,1443,494,0]Ai[463,13,464,0,4915,494,0]Ai[463,13,464,0,1152,494,0]Ai[463,13,464,0,1426,494,0]0Ai[463,13,464,0,2294,494,0]Ai[463,13,464,0,3217,494,0]Ai[463,13,464,0,3041,494,0]Ai[463,13,464,0,4448,494,0]Ai[463,13,464,0,1867,494,0]Ai[463,13,464,0,4071,494,0]Dm[463,13,464,0,4444,494,0,\"impl-From%3CTransportError%3E-for-ConnectionError\"]Dd[463,13,464,0,4444,494,0,\"impl-From%3CClose%3E-for-ConnectionError\"]Ai[463,13,464,0,4444,494,0]Dj[463,13,464,0,4444,494,0,\"impl-From%3CCloseReason%3E-for-ConnectionError\"]Ai[463,13,464,0,4458,494,0]Ai[463,13,464,0,4467,494,0]Ai[463,13,464,0,4773,494,0]Ai[463,13,464,0,4788,494,0]Ai[463,13,464,0,3941,494,0]0Ai[463,13,464,0,4328,494,0]Ai[463,13,464,0,4114,494,0]Ai[463,13,464,0,4972,494,0]Ai[463,13,464,0,4065,494,0]Ai[463,13,464,0,3931,494,0]Do[463,13,464,0,3931,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]Dj[463,13,464,0,3931,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ai[463,13,464,0,3025,494,0]Ai[463,13,464,0,4441,494,0]0Ai[463,13,464,0,4642,494,0]Ai[463,13,464,0,4077,494,0]0Ai[463,13,464,0,4080,494,0]Ai[463,13,464,0,4085,494,0]Ai[463,13,464,0,4808,494,0]0Ai[463,13,464,0,3220,494,0]Ai[463,13,464,0,4675,494,0]Ah[463,13,464,0,510,494,0]Ah[463,13,464,0,126,494,0]Ai[463,13,464,0,2281,494,0]0Ai[463,13,464,0,2291,494,0]Ai[463,13,3635,0,120,494,0]Aj[463,13,3635,0,3012,494,0]Aj[463,13,3635,0,1156,494,0]Aj[463,13,3635,0,3936,494,0]Aj[463,13,3635,0,1840,494,0]Aj[463,13,3635,0,4233,494,0]Aj[463,13,3635,0,4737,494,0]Aj[463,13,1693,0,1835,494,0]Ai[463,13,1693,0,497,494,0]Aj[463,13,1693,0,5064,494,0]Aj[463,13,1693,0,3934,494,0]0Aj[463,13,1693,0,4812,494,0]Aj[463,13,1773,0,3252,494,0]Aj[463,13,1773,0,4217,494,0]Df[463,13,1773,0,1169,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]Dm[463,13,1773,0,1169,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]D`[463,13,1773,0,1169,494,0,\"impl-From%3COtherError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Aj[463,13,1773,0,1169,494,0]Aj[463,13,1773,0,4671,494,0]Aj[463,13,1773,0,4910,494,0]Aj[463,13,1773,0,4673,494,0]Am[2358,13,2359,2359,125,494,0]An[2358,13,2359,2359,2250,494,0]An[3096,13,3097,4477,4207,494,0]An[3096,13,3097,3070,3018,494,0]An[3096,13,3097,1120,1407,494,0]An[3096,13,3097,2002,1861,494,0]An[3096,13,3097,2002,3238,494,0]An[3096,13,3097,2002,3244,494,0]An[3096,13,3097,3641,3212,494,0]An[3096,13,3097,1116,3235,494,0]An[3096,13,3097,1691,4246,494,0]An[3096,13,3097,2305,2260,494,0]An[3096,13,3097,2305,4213,494,0]An[3096,13,3097,2305,4651,494,0]An[3096,13,3097,2305,4224,494,0]An[3096,13,3097,1756,5124,494,0]An[3096,13,3097,4254,5094,494,0]An[3096,13,3097,1392,4465,494,0]An[3096,13,3097,1392,4099,494,0]An[3096,13,3097,1392,4343,494,0]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Dc[3096,13,3097,1810,1444,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cm[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]An[3096,13,3097,1810,1444,494,0]Co[3096,13,3097,1810,1444,494,0,\"impl-From%3CCode%3E-for-VarInt\"]An[3096,13,3097,1810,4916,494,0]An[3096,13,3097,3061,1153,494,0]An[3096,13,3097,3070,4750,494,0]An[3096,13,3097,1366,1427,494,0]0An[3096,13,3097,1366,4110,494,0]An[3096,13,3097,1366,3233,494,0]An[3096,13,3097,1366,3040,494,0]An[3096,13,3097,1366,4748,494,0]An[3096,13,3097,1366,4804,494,0]An[3096,13,3097,1366,3207,494,0]An[3096,13,3097,1381,2295,494,0]An[3096,13,3097,1381,3218,494,0]An[3096,13,3097,1381,3042,494,0]An[3096,13,3097,1381,4449,494,0]An[3096,13,3097,1120,3045,494,0]An[3096,13,3097,1120,4241,494,0]An[3096,13,3097,1125,1868,494,0]An[3096,13,3097,1125,3258,494,0]An[3096,13,3097,1125,3940,494,0]An[3096,13,3097,2002,3959,494,0]An[3096,13,3097,2002,4353,494,0]An[3096,13,3097,2002,4075,494,0]An[3096,13,3097,3641,4445,494,0]0An[3096,13,3097,3641,3038,494,0]An[3096,13,3097,3641,4319,494,0]An[3096,13,3097,3641,5001,494,0]An[3096,13,3097,3641,1174,494,0]0An[3096,13,3097,1116,4459,494,0]An[3096,13,3097,3194,4468,494,0]An[3096,13,3097,3194,4774,494,0]An[3096,13,3097,3194,4789,494,0]An[3096,13,3097,3194,3942,494,0]0An[3096,13,3097,1691,4329,494,0]An[3096,13,3097,1691,4116,494,0]An[3096,13,3097,1691,4973,494,0]An[3096,13,3097,1691,4067,494,0]An[3096,13,3097,1691,3932,494,0]Do[3096,13,3097,1691,3932,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ed[3096,13,3097,1691,3932,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]An[3096,13,3097,1356,3026,494,0]An[3096,13,3097,1356,4334,494,0]An[3096,13,3097,1356,3224,494,0]An[3096,13,3097,1356,3247,494,0]An[3096,13,3097,1356,4082,494,0]An[3096,13,3097,1356,4443,494,0]0An[3096,13,3097,1356,4644,494,0]An[3096,13,3097,1356,2253,494,0]An[3096,13,3097,2305,4648,494,0]An[3096,13,3097,2305,2264,494,0]An[3096,13,3097,2305,4078,494,0]0An[3096,13,3097,2305,3926,494,0]An[3096,13,3097,2305,3241,494,0]An[3096,13,3097,1756,4236,494,0]An[3096,13,3097,1756,4457,494,0]An[3096,13,3097,1756,5005,494,0]An[3096,13,3097,1756,2267,494,0]An[3096,13,3097,1756,4746,494,0]0An[3096,13,3097,1784,4447,494,0]An[3096,13,3097,1784,4214,494,0]An[3096,13,3097,1784,4081,494,0]An[3096,13,3097,1784,4086,494,0]Ak[3096,13,3097,0,4357,494,0]0Ak[3096,13,3097,0,4809,494,0]0An[3096,13,3097,4254,3221,494,0]An[3096,13,3097,4254,5099,494,0]An[3096,13,3097,4844,4676,494,0]Am[3096,13,3097,3097,511,494,0]Am[3096,13,3097,3097,127,494,0]An[3096,13,3097,3097,2282,494,0]0An[3096,13,3097,3097,2292,494,0]An[3096,13,3097,3097,3024,494,0]An[3096,13,1689,1689,4247,494,0]An[3096,13,4957,4957,4855,494,0]An[3096,13,4957,4957,1171,494,0]0An[3096,13,1694,1694,1836,494,0]Am[3096,13,1694,1694,498,494,0]An[3096,13,1694,1694,5065,494,0]An[3096,13,1694,1694,3935,494,0]0An[3096,13,1694,1694,4815,494,0]An[3096,13,1774,1774,3253,494,0]An[3096,13,1774,1774,4218,494,0]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Da[3096,13,1774,0,1170,494,0,\"impl-From%3COtherError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Ak[3096,13,1774,0,1170,494,0]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dn[3096,13,1774,0,1170,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]An[3096,13,1774,1774,4672,494,0]An[3096,13,1774,1774,4911,494,0]An[3096,13,1774,1774,4674,494,0]Al[3096,13,3636,148,121,494,0]Am[3096,13,3636,148,3013,494,0]An[3096,13,3636,1352,1157,494,0]An[3096,13,3636,1352,3937,494,0]An[3096,13,3636,2358,1841,494,0]An[3096,13,3636,2358,4234,494,0]An[3096,13,3636,3636,4738,494,0]An[3096,13,4706,4706,1172,494,0]An[3096,13,4706,4706,1175,494,0]An[1985,13,1986,1986,3256,494,0]0Am[1985,13,1986,416,4358,494,0]An[1985,13,1986,1986,2279,494,0]An[1985,13,1986,1986,2293,494,0]An[1985,13,1986,1986,4087,494,0]An[1095,13,1096,1096,3015,494,0]An[1095,13,1096,1096,4848,494,0]Am[1095,13,1683,1683,135,494,0]An[1095,13,1382,1382,1190,494,0]An[1095,13,1382,1382,3961,494,0]An[1095,13,1382,1382,4453,494,0]An[1095,13,4174,4174,5050,494,0]An[1095,13,4174,4174,5051,494,0]Am[1095,13,1779,1779,136,494,0]Ai[463,13,464,0,1443,495,0]Ai[463,13,464,0,1426,495,0]Ai[463,13,464,0,3941,495,0]Ai[463,13,464,0,4080,495,0]Ah[463,13,464,0,510,495,0]Ah[463,13,464,0,126,495,0]Ai[463,13,464,0,2281,495,0]An[3096,13,3097,1810,1444,495,0]An[3096,13,3097,3070,4750,495,0]An[3096,13,3097,1366,1427,495,0]An[3096,13,3097,1120,3045,495,0]An[3096,13,3097,1120,4241,495,0]An[3096,13,3097,1125,3258,495,0]An[3096,13,3097,3194,3942,495,0]An[3096,13,3097,2305,4648,495,0]An[3096,13,3097,1756,4746,495,0]An[3096,13,3097,1784,4081,495,0]Am[3096,13,3097,3097,511,495,0]Am[3096,13,3097,3097,127,495,0]An[3096,13,3097,3097,2282,495,0]An[3096,13,3097,3097,3024,495,0]Am[1195,13,1196,1196,134,496,0]An[1195,13,1196,1196,3952,496,0]An[1195,13,1196,1196,3928,496,0]An[1195,13,1380,1380,3960,496,0]An[1195,13,1380,1380,1189,496,0]An[1195,13,1380,1380,4354,496,0]Ak[519,13,520,520,3929,496,0]An[3966,13,3967,3967,5006,496,0]Al[463,13,464,3640,4472,496,0]Al[463,13,464,3640,2274,496,0]Ai[463,13,464,0,4206,496,0]Al[463,13,464,4142,4912,496,0]Al[463,13,464,1094,2275,496,0]Al[463,13,464,1094,4640,496,0]Al[463,13,464,3640,3209,496,0]Al[463,13,464,3640,3211,496,0]Al[463,13,464,3640,1843,496,0]Al[463,13,464,3640,1419,496,0]Al[463,13,464,3640,3004,496,0]Al[463,13,464,3640,2247,496,0]Al[463,13,464,3640,4106,496,0]Al[463,13,464,3640,4111,496,0]Al[463,13,464,3640,4918,496,0]Al[463,13,464,3640,4749,496,0]Al[463,13,464,2304,2259,496,0]Al[463,13,464,2304,4215,496,0]Al[463,13,464,2304,1399,496,0]Al[463,13,464,4142,1418,496,0]Al[463,13,464,4142,3231,496,0]Al[463,13,464,4142,4849,496,0]Al[463,13,464,2336,2263,496,0]Al[463,13,464,2336,3240,496,0]Al[463,13,464,2336,4333,496,0]Ak[463,13,464,1094,503,496,0]Al[463,13,464,1094,4359,496,0]Al[463,13,464,4034,3237,496,0]Al[463,13,464,4034,4856,496,0]Al[463,13,464,4034,4352,496,0]Al[463,13,464,4034,3044,496,0]Al[463,13,464,4034,3239,496,0]Al[463,13,464,4034,4351,496,0]Al[463,13,464,1393,4121,496,0]Al[463,13,464,1137,3955,496,0]Al[463,13,464,4039,3243,496,0]Al[463,13,464,4039,3257,496,0]Al[463,13,464,4039,4120,496,0]Al[463,13,464,4039,1857,496,0]Ai[463,13,464,0,3234,496,0]Ai[463,13,464,0,4245,496,0]Ai[463,13,464,0,4464,496,0]Ai[463,13,464,0,4098,496,0]Ai[463,13,464,0,4342,496,0]Ai[463,13,464,0,1443,496,0]Ai[463,13,464,0,4915,496,0]Ai[463,13,464,0,1152,496,0]Ai[463,13,464,0,1426,496,0]Ai[463,13,464,0,2294,496,0]Ai[463,13,464,0,3217,496,0]Ai[463,13,464,0,3041,496,0]Ai[463,13,464,0,4448,496,0]Ai[463,13,464,0,1867,496,0]Ai[463,13,464,0,4071,496,0]Ai[463,13,464,0,4444,496,0]Ai[463,13,464,0,4458,496,0]Ai[463,13,464,0,4467,496,0]Ai[463,13,464,0,4773,496,0]Ai[463,13,464,0,4788,496,0]Ai[463,13,464,0,3941,496,0]Ai[463,13,464,0,4328,496,0]Ai[463,13,464,0,4114,496,0]Ai[463,13,464,0,4972,496,0]Ai[463,13,464,0,4065,496,0]Ai[463,13,464,0,3931,496,0]Ai[463,13,464,0,3025,496,0]Ai[463,13,464,0,4441,496,0]Ai[463,13,464,0,4642,496,0]Ai[463,13,464,0,4077,496,0]Ai[463,13,464,0,4080,496,0]Ai[463,13,464,0,4085,496,0]Ai[463,13,464,0,4808,496,0]Ai[463,13,464,0,3220,496,0]Ai[463,13,464,0,4675,496,0]Ah[463,13,464,0,510,496,0]Ah[463,13,464,0,126,496,0]Ai[463,13,464,0,2281,496,0]Ai[463,13,464,0,2291,496,0]Ai[463,13,3635,0,120,496,0]Aj[463,13,3635,0,3012,496,0]Aj[463,13,3635,0,1156,496,0]Aj[463,13,3635,0,3936,496,0]Aj[463,13,3635,0,1840,496,0]Aj[463,13,3635,0,4233,496,0]Aj[463,13,3635,0,4737,496,0]Aj[463,13,1693,0,1835,496,0]Ai[463,13,1693,0,497,496,0]Aj[463,13,1693,0,5064,496,0]Aj[463,13,1693,0,3934,496,0]Aj[463,13,1693,0,4812,496,0]Aj[463,13,1773,0,3252,496,0]Aj[463,13,1773,0,4217,496,0]Aj[463,13,1773,0,1169,496,0]Aj[463,13,1773,0,4671,496,0]Aj[463,13,1773,0,4910,496,0]Aj[463,13,1773,0,4673,496,0]Am[2358,13,2359,2359,125,496,0]An[2358,13,2359,2359,2250,496,0]An[3096,13,3097,4477,4207,496,0]An[3096,13,3097,3070,3018,496,0]An[3096,13,3097,1120,1407,496,0]An[3096,13,3097,2002,1861,496,0]An[3096,13,3097,2002,3238,496,0]An[3096,13,3097,2002,3244,496,0]An[3096,13,3097,3641,3212,496,0]An[3096,13,3097,1116,3235,496,0]An[3096,13,3097,1691,4246,496,0]An[3096,13,3097,2305,2260,496,0]An[3096,13,3097,2305,4213,496,0]An[3096,13,3097,2305,4651,496,0]An[3096,13,3097,2305,4224,496,0]An[3096,13,3097,1756,5124,496,0]An[3096,13,3097,4254,5094,496,0]An[3096,13,3097,1392,4465,496,0]An[3096,13,3097,1392,4099,496,0]An[3096,13,3097,1392,4343,496,0]An[3096,13,3097,1810,1444,496,0]An[3096,13,3097,1810,4916,496,0]An[3096,13,3097,3061,1153,496,0]An[3096,13,3097,3070,4750,496,0]An[3096,13,3097,1366,1427,496,0]An[3096,13,3097,1366,4110,496,0]An[3096,13,3097,1366,3233,496,0]An[3096,13,3097,1366,3040,496,0]An[3096,13,3097,1366,4748,496,0]An[3096,13,3097,1366,4804,496,0]An[3096,13,3097,1366,3207,496,0]An[3096,13,3097,1381,2295,496,0]An[3096,13,3097,1381,3218,496,0]An[3096,13,3097,1381,3042,496,0]An[3096,13,3097,1381,4449,496,0]An[3096,13,3097,1120,3045,496,0]An[3096,13,3097,1120,4241,496,0]An[3096,13,3097,1125,1868,496,0]An[3096,13,3097,1125,3258,496,0]An[3096,13,3097,1125,3940,496,0]An[3096,13,3097,2002,3959,496,0]An[3096,13,3097,2002,4353,496,0]An[3096,13,3097,2002,4075,496,0]An[3096,13,3097,3641,4445,496,0]An[3096,13,3097,3641,3038,496,0]An[3096,13,3097,3641,4319,496,0]An[3096,13,3097,3641,5001,496,0]An[3096,13,3097,3641,1174,496,0]An[3096,13,3097,1116,4459,496,0]An[3096,13,3097,3194,4468,496,0]An[3096,13,3097,3194,4774,496,0]An[3096,13,3097,3194,4789,496,0]An[3096,13,3097,3194,3942,496,0]An[3096,13,3097,1691,4329,496,0]An[3096,13,3097,1691,4116,496,0]An[3096,13,3097,1691,4973,496,0]An[3096,13,3097,1691,4067,496,0]An[3096,13,3097,1691,3932,496,0]An[3096,13,3097,1356,3026,496,0]An[3096,13,3097,1356,4334,496,0]An[3096,13,3097,1356,3224,496,0]An[3096,13,3097,1356,3247,496,0]An[3096,13,3097,1356,4082,496,0]An[3096,13,3097,1356,4443,496,0]An[3096,13,3097,1356,4644,496,0]An[3096,13,3097,1356,2253,496,0]An[3096,13,3097,2305,4648,496,0]An[3096,13,3097,2305,2264,496,0]An[3096,13,3097,2305,4078,496,0]An[3096,13,3097,2305,3926,496,0]An[3096,13,3097,2305,3241,496,0]An[3096,13,3097,1756,4236,496,0]An[3096,13,3097,1756,4457,496,0]An[3096,13,3097,1756,5005,496,0]An[3096,13,3097,1756,2267,496,0]An[3096,13,3097,1756,4746,496,0]An[3096,13,3097,1784,4447,496,0]An[3096,13,3097,1784,4214,496,0]An[3096,13,3097,1784,4081,496,0]An[3096,13,3097,1784,4086,496,0]Ak[3096,13,3097,0,4357,496,0]Ak[3096,13,3097,0,4809,496,0]An[3096,13,3097,4254,3221,496,0]An[3096,13,3097,4254,5099,496,0]An[3096,13,3097,4844,4676,496,0]Am[3096,13,3097,3097,511,496,0]Am[3096,13,3097,3097,127,496,0]An[3096,13,3097,3097,2282,496,0]An[3096,13,3097,3097,2292,496,0]An[3096,13,3097,3097,3024,496,0]An[3096,13,1689,1689,4247,496,0]An[3096,13,4957,4957,4855,496,0]An[3096,13,4957,4957,1171,496,0]An[3096,13,1694,1694,1836,496,0]Am[3096,13,1694,1694,498,496,0]An[3096,13,1694,1694,5065,496,0]An[3096,13,1694,1694,3935,496,0]An[3096,13,1694,1694,4815,496,0]An[3096,13,1774,1774,3253,496,0]An[3096,13,1774,1774,4218,496,0]Ak[3096,13,1774,0,1170,496,0]An[3096,13,1774,1774,4672,496,0]An[3096,13,1774,1774,4911,496,0]An[3096,13,1774,1774,4674,496,0]Al[3096,13,3636,148,121,496,0]Am[3096,13,3636,148,3013,496,0]An[3096,13,3636,1352,1157,496,0]An[3096,13,3636,1352,3937,496,0]An[3096,13,3636,2358,1841,496,0]An[3096,13,3636,2358,4234,496,0]An[3096,13,3636,3636,4738,496,0]An[3096,13,4706,4706,1172,496,0]An[3096,13,4706,4706,1175,496,0]An[1985,13,1986,1986,3256,496,0]Am[1985,13,1986,416,4358,496,0]An[1985,13,1986,1986,2279,496,0]An[1985,13,1986,1986,2293,496,0]An[1985,13,1986,1986,4087,496,0]An[1095,13,1096,1096,3015,496,0]An[1095,13,1096,1096,4848,496,0]Am[1095,13,1683,1683,135,496,0]An[1095,13,1382,1382,1190,496,0]An[1095,13,1382,1382,3961,496,0]An[1095,13,1382,1382,4453,496,0]An[1095,13,4174,4174,5050,496,0]An[1095,13,4174,4174,5051,496,0]Am[1095,13,1779,1779,136,496,0]Ac[519,7,520,0,0,0,0]Ae[3966,7,3967,0,0,0,0]Ae[4257,7,4258,0,0,0,0]Ae[2358,7,2359,0,0,0,0]Ae[4768,7,4769,0,0,0,0]Al[3096,13,3097,1120,1407,0,0]Ao[3096,13,3097,2305,4224,2265,0]Ah[463,12,1693,0,4739,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,12,1694,1694,4740,0,0]Aj[463,13,464,3640,3211,0,0]Ab[1095,3,0,0,0,0,0]Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1381,3218,0,0]Aj[463,12,464,1994,3200,0,0]Am[463,13,464,3640,4472,1415,0]Am[463,13,464,3640,2274,1415,0]Am[463,13,464,1094,2275,1415,0]Am[463,13,464,3640,3209,1415,0]Am[463,13,464,3640,1843,1415,0]Am[463,13,464,3640,1419,1415,0]Am[463,13,464,3640,3004,1415,0]Am[463,13,464,3640,2247,1415,0]Am[463,13,464,3640,4106,1415,0]Am[463,13,464,3640,4111,1415,0]Am[463,13,464,2304,1399,1415,0]Am[463,13,464,2336,4333,1415,0]Am[463,13,464,4039,1857,1415,0]?Aj[463,13,464,4034,3237,0,0]Al[3096,13,3097,2002,3238,0,0]Al[3096,13,4957,4957,4855,0,0]Al[3096,13,3097,3070,3018,0,0]Ak[1985,13,1986,416,4358,0,0]Ah[463,12,1693,0,4739,0,0]Al[3096,12,1694,1694,4740,0,0]32Ag[463,13,464,0,4972,0,0]Al[3096,13,3097,1691,4973,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Al[1195,14,1380,1380,4354,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Ai[3096,14,4456,0,1186,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Al[3096,13,3097,2002,3238,0,0]Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4342,3254,0]Aj[463,13,464,0,4675,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4343,3255,0]Ao[3096,13,3097,4844,4676,3255,0]Af[463,5,464,3061,0,0,0]Ah[3096,5,3097,3061,0,0,0]Ag[463,5,3635,1352,0,0,0]Ah[3096,5,3636,1352,0,0,0]Al[1095,15,1096,1096,4848,0,0]Ag[463,6,1773,1355,0,0,0]Ah[3096,6,1774,1355,0,0,0]Ae[3096,6,4957,0,0,0,0]Ae[3096,6,4706,0,0,0,0]Ah[3096,6,3097,3641,0,0,0]1Al[3096,15,3097,1356,3224,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Aj[463,15,464,4034,3044,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,3641,4445,0,0]Al[3096,15,3097,1756,4457,0,0]0Ae[1195,5,1380,0,0,0,0]Ae[1095,5,1382,0,0,0,0]Al[1195,15,1196,1196,3952,0,0]Al[3096,13,3097,2305,4651,0,0]Ab[1195,3,0,0,0,0,0]Ah[463,12,3635,0,4735,0,0]Ak[463,13,3635,0,3012,4735,0]Ak[463,13,3635,0,3936,4735,0]Ak[463,13,3635,0,4233,4735,0]Al[3096,12,3636,3636,4736,0,0]An[3096,13,3636,148,3013,4736,0]Ao[3096,13,3636,1352,3937,4736,0]Ao[3096,13,3636,2358,4234,4736,0]Al[1095,13,1096,1096,4848,0,0]Ag[463,14,464,0,1152,0,0]Ag[463,14,464,0,2294,0,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,3061,1153,0,0]Al[3096,14,3097,1381,2295,0,0]Al[3096,14,3097,1125,1868,0,0]Al[3096,14,3097,2305,3926,0,0]An[1195,13,1196,1196,134,1154,0]Ao[1195,13,1196,1196,3952,1154,0]Ao[1195,13,1196,1196,3928,1154,0]Am[463,13,464,3640,3211,1154,0]Am[463,13,464,3640,4918,1154,0]Am[463,13,464,3640,4749,1154,0]Am[463,13,464,2304,2259,1154,0]Am[463,13,464,2304,4215,1154,0]Am[463,13,464,4142,1418,1154,0]Al[463,13,464,1094,503,1154,0]Am[463,13,464,1094,4359,1154,0]Am[463,13,464,4034,4352,1154,0]Am[463,13,464,4034,3044,1154,0]Am[463,13,464,4034,3239,1154,0]Am[463,13,464,4034,4351,1154,0]Am[463,13,464,4039,3257,1154,0]Am[463,13,464,4039,4120,1154,0]Aj[463,13,464,0,1443,1154,0]Aj[463,13,464,0,4915,1154,0]Aj[463,13,464,0,1426,1154,0]Aj[463,13,464,0,2294,1154,0]Aj[463,13,464,0,3217,1154,0]Aj[463,13,464,0,3041,1154,0]Aj[463,13,464,0,4448,1154,0]Aj[463,13,464,0,1867,1154,0]Aj[463,13,464,0,4071,1154,0]Aj[463,13,464,0,4444,1154,0]Aj[463,13,464,0,4467,1154,0]Aj[463,13,464,0,4773,1154,0]Aj[463,13,464,0,4788,1154,0]Aj[463,13,464,0,3941,1154,0]Aj[463,13,464,0,4328,1154,0]Aj[463,13,464,0,4114,1154,0]Aj[463,13,464,0,4972,1154,0]Aj[463,13,464,0,4065,1154,0]Aj[463,13,464,0,3931,1154,0]Aj[463,13,464,0,3025,1154,0]Aj[463,13,464,0,4441,1154,0]Aj[463,13,464,0,4642,1154,0]Aj[463,13,464,0,4077,1154,0]Aj[463,13,464,0,4080,1154,0]Aj[463,13,464,0,4085,1154,0]Aj[463,13,464,0,4808,1154,0]Aj[463,13,464,0,3220,1154,0]Ai[463,13,464,0,510,1154,0]Ai[463,13,464,0,126,1154,0]Aj[463,13,464,0,2281,1154,0]Aj[463,13,3635,0,120,1154,0]Ak[463,13,3635,0,3012,1154,0]Ak[463,13,3635,0,1156,1154,0]Ak[463,13,3635,0,3936,1154,0]Ak[463,13,3635,0,1840,1154,0]Ak[463,13,3635,0,4233,1154,0]Ak[463,13,1773,0,1169,1154,0]Ak[463,13,1773,0,4671,1154,0]Ak[463,13,1773,0,4910,1154,0]Ak[463,13,1773,0,4673,1154,0]Ao[3096,13,3097,1810,1444,1154,0]Ao[3096,13,3097,1810,4916,1154,0]Ao[3096,13,3097,3070,4750,1154,0]Ao[3096,13,3097,1366,1427,1154,0]Ao[3096,13,3097,1366,4110,1154,0]Ao[3096,13,3097,1366,3233,1154,0]Ao[3096,13,3097,1366,3040,1154,0]Ao[3096,13,3097,1366,4748,1154,0]Ao[3096,13,3097,1366,4804,1154,0]Ao[3096,13,3097,1366,3207,1154,0]Ao[3096,13,3097,1381,2295,1154,0]Ao[3096,13,3097,1381,3218,1154,0]Ao[3096,13,3097,1381,3042,1154,0]Ao[3096,13,3097,1381,4449,1154,0]Ao[3096,13,3097,1120,3045,1154,0]Ao[3096,13,3097,1120,4241,1154,0]Ao[3096,13,3097,1125,1868,1154,0]Ao[3096,13,3097,1125,3258,1154,0]Ao[3096,13,3097,1125,3940,1154,0]Ao[3096,13,3097,2002,4353,1154,0]Ao[3096,13,3097,2002,4075,1154,0]Ao[3096,13,3097,3641,4445,1154,0]Ao[3096,13,3097,3641,3038,1154,0]Ao[3096,13,3097,3641,4319,1154,0]Ao[3096,13,3097,3641,5001,1154,0]Ao[3096,13,3097,3194,4468,1154,0]Ao[3096,13,3097,3194,4774,1154,0]Ao[3096,13,3097,3194,4789,1154,0]Ao[3096,13,3097,3194,3942,1154,0]Ao[3096,13,3097,1691,4329,1154,0]Ao[3096,13,3097,1691,4116,1154,0]Ao[3096,13,3097,1691,4973,1154,0]Ao[3096,13,3097,1691,4067,1154,0]Ao[3096,13,3097,1691,3932,1154,0]Ao[3096,13,3097,1356,3026,1154,0]Ao[3096,13,3097,1356,3224,1154,0]Ao[3096,13,3097,1356,3247,1154,0]Ao[3096,13,3097,1356,4082,1154,0]Ao[3096,13,3097,1356,4443,1154,0]Ao[3096,13,3097,1356,4644,1154,0]Ao[3096,13,3097,1356,2253,1154,0]Ao[3096,13,3097,2305,4648,1154,0]Ao[3096,13,3097,2305,4078,1154,0]Ao[3096,13,3097,1756,4457,1154,0]Ao[3096,13,3097,1756,5005,1154,0]Ao[3096,13,3097,1756,2267,1154,0]Ao[3096,13,3097,1756,4746,1154,0]Ao[3096,13,3097,1784,4081,1154,0]Ao[3096,13,3097,1784,4086,1154,0]Al[3096,13,3097,0,4357,1154,0]Al[3096,13,3097,0,4809,1154,0]Ao[3096,13,3097,4254,3221,1154,0]Ao[3096,13,3097,4254,5099,1154,0]An[3096,13,3097,3097,511,1154,0]An[3096,13,3097,3097,127,1154,0]Ao[3096,13,3097,3097,2282,1154,0]Ao[3096,13,3097,3097,3024,1154,0]Ao[3096,13,1689,1689,4247,1154,0]Ao[3096,13,4957,4957,4855,1154,0]Ao[3096,13,4957,4957,1171,1154,0]Al[3096,13,1774,0,1170,1154,0]Ao[3096,13,1774,1774,4672,1154,0]Ao[3096,13,1774,1774,4911,1154,0]Ao[3096,13,1774,1774,4674,1154,0]Am[3096,13,3636,148,121,1154,0]An[3096,13,3636,148,3013,1154,0]Ao[3096,13,3636,1352,1157,1154,0]Ao[3096,13,3636,1352,3937,1154,0]Ao[3096,13,3636,2358,1841,1154,0]Ao[3096,13,3636,2358,4234,1154,0]Ao[3096,13,4706,4706,1175,1154,0]Ao[1985,13,1986,1986,2279,1154,0]Ao[1985,13,1986,1986,2293,1154,0]Ao[1985,13,1986,1986,4087,1154,0]Ao[1095,13,1096,1096,4848,1154,0]Ao[1095,13,1382,1382,4453,1154,0]Ao[1095,13,4174,4174,5050,1154,0]Ao[1095,13,4174,4174,5051,1154,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,0,4080,1160,0]Ao[3096,13,3097,1784,4081,1160,0]Ai[3096,14,3097,0,4357,0,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ag[463,13,464,0,4085,0,0]Al[3096,13,3097,1784,4086,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,14,1694,1694,1836,0,0]Al[3096,12,3097,1756,4779,0,0]Ao[3096,13,3097,1756,5124,4779,0];Al[1195,13,1380,1380,1189,0,0]Ai[519,13,520,520,3929,0,0]Al[1095,13,1382,1382,1190,0,0]Aj[463,12,464,1994,3200,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4121,1852,0]Am[463,13,464,1137,3955,1852,0]Ae[1195,2,1196,0,0,0,0]Ak[1195,14,1196,1196,134,0,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Ae[1095,2,1096,0,0,0,0]Ag[463,13,464,0,3234,0,0]Al[3096,13,3097,1116,3235,0,0]?>Al[3096,13,4957,4957,4855,0,0]Af[463,5,464,2304,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Al[1195,15,1196,1196,3928,0,0]0Al[3096,15,3097,1366,3233,0,0]Ah[3096,5,3097,1120,0,0,0]Af[463,15,464,0,510,0,0]Al[2358,15,2359,2359,2250,0,0]Ak[3096,15,3097,3097,511,0,0]Al[3096,15,4706,4706,1172,0,0]87Af[463,5,464,4142,0,0,0]Af[463,5,464,3640,0,0,0]Al[3096,15,3097,1366,3040,0,0]Al[3096,15,3097,2002,3959,0,0]Af[463,5,464,1366,0,0,0]Ah[3096,5,3097,1366,0,0,0]Ae[3096,8,1689,0,0,0,0]:98?Al[3096,15,3097,3641,1174,0,0]?Af[463,5,464,1810,0,0,0]Ah[3096,5,3097,1810,0,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,2305,2260,0,0]An[1195,13,1196,1196,134,1405,0]Ao[1195,13,1196,1196,3952,1405,0]Ao[1195,13,1196,1196,3928,1405,0]Ao[1195,13,1380,1380,3960,1405,0]Ao[1195,13,1380,1380,1189,1405,0]Ao[1195,13,1380,1380,4354,1405,0]Al[519,13,520,520,3929,1405,0]Ao[3966,13,3967,3967,5006,1405,0]Am[463,13,464,3640,4472,1405,0]Am[463,13,464,3640,2274,1405,0]Aj[463,13,464,0,4206,1405,0]Am[463,13,464,4142,4912,1405,0]Am[463,13,464,1094,2275,1405,0]Am[463,13,464,1094,4640,1405,0]Am[463,13,464,3640,3209,1405,0]Am[463,13,464,3640,3211,1405,0]Am[463,13,464,3640,1843,1405,0]Am[463,13,464,3640,1419,1405,0]Am[463,13,464,3640,3004,1405,0]Am[463,13,464,3640,2247,1405,0]Am[463,13,464,3640,4106,1405,0]Am[463,13,464,3640,4111,1405,0]Am[463,13,464,3640,4918,1405,0]Am[463,13,464,3640,4749,1405,0]Am[463,13,464,2304,2259,1405,0]Am[463,13,464,2304,4215,1405,0]Am[463,13,464,2304,1399,1405,0]Am[463,13,464,4142,1418,1405,0]Am[463,13,464,4142,3231,1405,0]Am[463,13,464,4142,4849,1405,0]Am[463,13,464,2336,2263,1405,0]Am[463,13,464,2336,3240,1405,0]Am[463,13,464,2336,4333,1405,0]Al[463,13,464,1094,503,1405,0]Am[463,13,464,1094,4359,1405,0]Am[463,13,464,4034,3237,1405,0]Am[463,13,464,4034,4856,1405,0]Am[463,13,464,4034,4352,1405,0]Am[463,13,464,4034,3044,1405,0]Am[463,13,464,4034,3239,1405,0]Am[463,13,464,4034,4351,1405,0]Am[463,13,464,1393,4121,1405,0]Am[463,13,464,1137,3955,1405,0]Am[463,13,464,4039,3243,1405,0]Am[463,13,464,4039,3257,1405,0]Am[463,13,464,4039,4120,1405,0]Am[463,13,464,4039,1857,1405,0]Aj[463,13,464,0,3234,1405,0]Aj[463,13,464,0,4245,1405,0]Aj[463,13,464,0,4464,1405,0]Aj[463,13,464,0,4098,1405,0]Aj[463,13,464,0,4342,1405,0]Aj[463,13,464,0,1443,1405,0]Aj[463,13,464,0,4915,1405,0]Aj[463,13,464,0,1152,1405,0]Aj[463,13,464,0,1426,1405,0]Aj[463,13,464,0,2294,1405,0]Aj[463,13,464,0,3217,1405,0]Aj[463,13,464,0,3041,1405,0]Aj[463,13,464,0,4448,1405,0]Aj[463,13,464,0,1867,1405,0]Aj[463,13,464,0,4071,1405,0]Aj[463,13,464,0,4444,1405,0]Aj[463,13,464,0,4458,1405,0]Aj[463,13,464,0,4467,1405,0]Aj[463,13,464,0,4773,1405,0]Aj[463,13,464,0,4788,1405,0]Aj[463,13,464,0,3941,1405,0]Aj[463,13,464,0,4328,1405,0]Aj[463,13,464,0,4114,1405,0]Aj[463,13,464,0,4972,1405,0]Aj[463,13,464,0,4065,1405,0]Aj[463,13,464,0,3931,1405,0]Aj[463,13,464,0,3025,1405,0]Aj[463,13,464,0,4441,1405,0]Aj[463,13,464,0,4642,1405,0]Aj[463,13,464,0,4077,1405,0]Aj[463,13,464,0,4080,1405,0]Aj[463,13,464,0,4085,1405,0]Aj[463,13,464,0,4808,1405,0]Aj[463,13,464,0,3220,1405,0]Aj[463,13,464,0,4675,1405,0]Ai[463,13,464,0,510,1405,0]Ai[463,13,464,0,126,1405,0]Aj[463,13,464,0,2281,1405,0]Aj[463,13,464,0,2291,1405,0]Aj[463,13,3635,0,120,1405,0]Ak[463,13,3635,0,3012,1405,0]Ak[463,13,3635,0,1156,1405,0]Ak[463,13,3635,0,3936,1405,0]Ak[463,13,3635,0,1840,1405,0]Ak[463,13,3635,0,4233,1405,0]Ak[463,13,3635,0,4737,1405,0]Ak[463,13,1693,0,1835,1405,0]Aj[463,13,1693,0,497,1405,0]Ak[463,13,1693,0,5064,1405,0]Ak[463,13,1693,0,3934,1405,0]Ak[463,13,1693,0,4812,1405,0]Ak[463,13,1773,0,3252,1405,0]Ak[463,13,1773,0,4217,1405,0]Ak[463,13,1773,0,1169,1405,0]Ak[463,13,1773,0,4671,1405,0]Ak[463,13,1773,0,4910,1405,0]Ak[463,13,1773,0,4673,1405,0]An[2358,13,2359,2359,125,1405,0]Ao[2358,13,2359,2359,2250,1405,0]Ao[3096,13,3097,4477,4207,1405,0]Ao[3096,13,3097,3070,3018,1405,0]Ao[3096,13,3097,1120,1407,1405,0]Ao[3096,13,3097,2002,1861,1405,0]Ao[3096,13,3097,2002,3238,1405,0]Ao[3096,13,3097,2002,3244,1405,0]Ao[3096,13,3097,3641,3212,1405,0]Ao[3096,13,3097,1116,3235,1405,0]Ao[3096,13,3097,1691,4246,1405,0]Ao[3096,13,3097,2305,2260,1405,0]Ao[3096,13,3097,2305,4213,1405,0]Ao[3096,13,3097,2305,4651,1405,0]Ao[3096,13,3097,2305,4224,1405,0]Ao[3096,13,3097,1756,5124,1405,0]Ao[3096,13,3097,4254,5094,1405,0]Ao[3096,13,3097,1392,4465,1405,0]Ao[3096,13,3097,1392,4099,1405,0]Ao[3096,13,3097,1392,4343,1405,0]Ao[3096,13,3097,1810,1444,1405,0]Ao[3096,13,3097,1810,4916,1405,0]Ao[3096,13,3097,3061,1153,1405,0]Ao[3096,13,3097,3070,4750,1405,0]Ao[3096,13,3097,1366,1427,1405,0]Ao[3096,13,3097,1366,4110,1405,0]Ao[3096,13,3097,1366,3233,1405,0]Ao[3096,13,3097,1366,3040,1405,0]Ao[3096,13,3097,1366,4748,1405,0]Ao[3096,13,3097,1366,4804,1405,0]Ao[3096,13,3097,1366,3207,1405,0]Ao[3096,13,3097,1381,2295,1405,0]Ao[3096,13,3097,1381,3218,1405,0]Ao[3096,13,3097,1381,3042,1405,0]Ao[3096,13,3097,1381,4449,1405,0]Ao[3096,13,3097,1120,3045,1405,0]Ao[3096,13,3097,1120,4241,1405,0]Ao[3096,13,3097,1125,1868,1405,0]Ao[3096,13,3097,1125,3258,1405,0]Ao[3096,13,3097,1125,3940,1405,0]Ao[3096,13,3097,2002,3959,1405,0]Ao[3096,13,3097,2002,4353,1405,0]Ao[3096,13,3097,2002,4075,1405,0]Ao[3096,13,3097,3641,4445,1405,0]Ao[3096,13,3097,3641,3038,1405,0]Ao[3096,13,3097,3641,4319,1405,0]Ao[3096,13,3097,3641,5001,1405,0]Ao[3096,13,3097,3641,1174,1405,0]Ao[3096,13,3097,1116,4459,1405,0]Ao[3096,13,3097,3194,4468,1405,0]Ao[3096,13,3097,3194,4774,1405,0]Ao[3096,13,3097,3194,4789,1405,0]Ao[3096,13,3097,3194,3942,1405,0]Ao[3096,13,3097,1691,4329,1405,0]Ao[3096,13,3097,1691,4116,1405,0]Ao[3096,13,3097,1691,4973,1405,0]Ao[3096,13,3097,1691,4067,1405,0]Ao[3096,13,3097,1691,3932,1405,0]Ao[3096,13,3097,1356,3026,1405,0]Ao[3096,13,3097,1356,4334,1405,0]Ao[3096,13,3097,1356,3224,1405,0]Ao[3096,13,3097,1356,3247,1405,0]Ao[3096,13,3097,1356,4082,1405,0]Ao[3096,13,3097,1356,4443,1405,0]Ao[3096,13,3097,1356,4644,1405,0]Ao[3096,13,3097,1356,2253,1405,0]Ao[3096,13,3097,2305,4648,1405,0]Ao[3096,13,3097,2305,2264,1405,0]Ao[3096,13,3097,2305,4078,1405,0]Ao[3096,13,3097,2305,3926,1405,0]Ao[3096,13,3097,2305,3241,1405,0]Ao[3096,13,3097,1756,4236,1405,0]Ao[3096,13,3097,1756,4457,1405,0]Ao[3096,13,3097,1756,5005,1405,0]Ao[3096,13,3097,1756,2267,1405,0]Ao[3096,13,3097,1756,4746,1405,0]Ao[3096,13,3097,1784,4447,1405,0]Ao[3096,13,3097,1784,4214,1405,0]Ao[3096,13,3097,1784,4081,1405,0]Ao[3096,13,3097,1784,4086,1405,0]Al[3096,13,3097,0,4357,1405,0]Al[3096,13,3097,0,4809,1405,0]Ao[3096,13,3097,4254,3221,1405,0]Ao[3096,13,3097,4254,5099,1405,0]Ao[3096,13,3097,4844,4676,1405,0]An[3096,13,3097,3097,511,1405,0]An[3096,13,3097,3097,127,1405,0]Ao[3096,13,3097,3097,2282,1405,0]Ao[3096,13,3097,3097,2292,1405,0]Ao[3096,13,3097,3097,3024,1405,0]Ao[3096,13,1689,1689,4247,1405,0]Ao[3096,13,4957,4957,4855,1405,0]Ao[3096,13,4957,4957,1171,1405,0]Ao[3096,13,1694,1694,1836,1405,0]An[3096,13,1694,1694,498,1405,0]Ao[3096,13,1694,1694,5065,1405,0]Ao[3096,13,1694,1694,3935,1405,0]Ao[3096,13,1694,1694,4815,1405,0]Ao[3096,13,1774,1774,3253,1405,0]Ao[3096,13,1774,1774,4218,1405,0]Al[3096,13,1774,0,1170,1405,0]Ao[3096,13,1774,1774,4672,1405,0]Ao[3096,13,1774,1774,4911,1405,0]Ao[3096,13,1774,1774,4674,1405,0]Am[3096,13,3636,148,121,1405,0]An[3096,13,3636,148,3013,1405,0]Ao[3096,13,3636,1352,1157,1405,0]Ao[3096,13,3636,1352,3937,1405,0]Ao[3096,13,3636,2358,1841,1405,0]Ao[3096,13,3636,2358,4234,1405,0]Ao[3096,13,3636,3636,4738,1405,0]Ao[3096,13,4706,4706,1172,1405,0]Ao[3096,13,4706,4706,1175,1405,0]Ao[1985,13,1986,1986,3256,1405,0]An[1985,13,1986,416,4358,1405,0]Ao[1985,13,1986,1986,2279,1405,0]Ao[1985,13,1986,1986,2293,1405,0]Ao[1985,13,1986,1986,4087,1405,0]Ao[1095,13,1096,1096,3015,1405,0]Ao[1095,13,1096,1096,4848,1405,0]An[1095,13,1683,1683,135,1405,0]Ao[1095,13,1382,1382,1190,1405,0]Ao[1095,13,1382,1382,3961,1405,0]Ao[1095,13,1382,1382,4453,1405,0]Ao[1095,13,4174,4174,5050,1405,0]Ao[1095,13,4174,4174,5051,1405,0]An[1095,13,1779,1779,136,1405,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,1125,1868,0,0]Ak[1195,14,1196,1196,134,0,0]Ac[519,7,520,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[1095,2,1096,0,0,0,0]Ae[4768,7,4769,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Ae[3096,2,3097,0,0,0,0]Al[3096,13,3097,2305,2260,0,0]Af[463,2,464,3097,0,0,0]Ag[463,13,464,0,4808,0,0]Ag[463,14,464,0,3217,0,0]Ag[463,14,464,0,4114,0,0]5Ai[3096,13,3097,0,4809,0,0]Al[3096,14,3097,1381,3218,0,0]Al[3096,14,3097,1691,4116,0,0]Ai[3096,14,3097,0,4357,0,0]Aj[463,13,464,0,1443,3019,0]Aj[463,13,464,0,1426,3019,0]Aj[463,13,464,0,3025,3019,0]Aj[463,13,464,0,4808,3019,0]Aj[463,13,464,0,2281,3019,0]Ao[3096,13,3097,1810,1444,3019,0]Ao[3096,13,3097,1366,1427,3019,0]Ao[3096,13,3097,1356,3026,3019,0]Ao[3096,13,3097,1356,3224,3019,0]Al[3096,13,3097,1756,4457,0,0]Al[3096,13,3097,0,4809,3019,0]Ao[3096,13,3097,3097,2282,3019,0]Al[3096,12,1689,1689,3019,0,0]Al[1985,14,1986,1986,2279,0,0]Aj[463,13,464,0,1443,3022,0]Aj[463,13,464,0,1426,3022,0]Aj[463,13,464,0,3025,3022,0]Aj[463,13,464,0,4808,3022,0]Aj[463,13,464,0,2281,3022,0]Ao[3096,13,3097,1810,1444,3022,0]Ao[3096,13,3097,1366,1427,3022,0]Ao[3096,13,3097,1356,3026,3022,0]Ao[3096,13,3097,1356,3224,3022,0]Ao[3096,13,3097,1356,2253,3022,0]Al[3096,13,3097,0,4809,3022,0]Ao[3096,13,3097,3097,2282,3022,0]Al[3096,12,1689,1689,3022,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Al[1095,13,1382,1382,3961,0,0]Al[3096,13,3097,2305,2260,0,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Aj[463,13,464,2336,2263,0,0]3Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4342,3254,0]Aj[463,13,464,0,4675,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4343,3255,0]Ao[3096,13,3097,4844,4676,3255,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,14,464,0,1152,0,0]Al[3096,14,3097,3061,1153,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Ai[3096,14,4456,0,4680,0,0]Ag[463,14,464,0,4441,0,0]Ag[463,14,464,0,4642,0,0]Al[3096,14,3097,1356,4443,0,0]Al[3096,14,3097,1356,4644,0,0]Ai[3096,14,3097,0,4357,0,0]Ai[3096,14,1173,0,4321,0,0]Ai[3096,14,3039,0,3002,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,13,3097,3097,3024,0,0]Al[3096,14,1694,1694,1836,0,0]Ac[463,4,464,0,0,0,0]Ag[463,2,1693,1694,0,0,0]Ae[3096,4,3097,0,0,0,0]Ae[3096,2,1694,0,0,0,0]Ac[519,7,520,0,0,0,0]:Ae[1095,2,1096,0,0,0,0]Ae[4768,7,4769,0,0,0,0]Am[463,13,464,3640,4749,1162,0]Am[463,13,464,4034,4352,1162,0]Am[463,13,464,4034,3044,1162,0]Am[463,13,464,4034,3239,1162,0]Am[463,13,464,4034,4351,1162,0]Am[463,13,464,4039,3257,1162,0]Am[463,13,464,4039,4120,1162,0]Aj[463,13,464,0,4444,1162,0]Ao[3096,13,3097,3641,4445,1162,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Ai[463,13,464,1094,503,0,0]Ai[3096,14,3039,0,4107,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3041,0,0]Ag[463,14,464,0,4448,0,0]Al[3096,14,3097,1381,3042,0,0]Al[3096,14,3097,1381,4449,0,0]3210Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Al[3096,15,3097,3070,4750,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,1125,3258,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Al[3096,15,3097,1756,4457,0,0]Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ag[463,5,3635,2358,0,0,0]Ah[3096,5,3636,2358,0,0,0]Al[1095,15,1096,1096,4848,0,0]Af[463,5,464,3640,0,0,0]5454Ag[463,10,464,1994,0,0,0];:Aj[463,15,464,4039,3257,0,0]Af[463,5,464,4039,0,0,0]Al[3096,15,3097,1125,3258,0,0]Al[3096,15,3097,1125,3940,0,0]Al[3096,15,3097,2002,3959,0,0]Ah[3096,5,3097,2002,0,0,0]Aj[463,15,464,4034,4352,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1125,0,0,0]Ah[3096,5,3097,1125,0,0,0]Al[3096,15,3097,1756,2267,0,0]Ag[463,12,464,0,4963,0,0]Al[3096,12,3097,4254,4964,0,0]Ao[3096,13,3097,4254,5094,4964,0]Ao[3096,13,3097,4254,5099,4964,0]Ak[1195,14,1196,1196,134,0,0]An[1195,13,1196,1196,134,4320,0]An[2358,13,2359,2359,125,4320,0]Ak[2358,14,2359,2359,125,0,0]Ao[1095,13,1096,1096,3015,4320,0]An[1095,13,1683,1683,135,4320,0]An[1095,13,1779,1779,136,4320,0]Aj[463,13,464,0,1443,3208,0]Aj[463,13,464,0,1426,3208,0]Aj[463,13,464,0,3941,3208,0]Aj[463,13,464,0,4080,3208,0]Ai[463,13,464,0,510,3208,0]Ai[463,13,464,0,126,3208,0]Aj[463,13,464,0,2281,3208,0]Ao[3096,13,3097,1810,1444,3208,0]Ao[3096,13,3097,3070,4750,3208,0]Ao[3096,13,3097,1366,1427,3208,0]Ao[3096,13,3097,1120,3045,3208,0]Ao[3096,13,3097,1120,4241,3208,0]Ao[3096,13,3097,1125,3258,3208,0]Ao[3096,13,3097,3194,3942,3208,0]Ao[3096,13,3097,2305,4648,3208,0]Ao[3096,13,3097,1756,4746,3208,0]Ao[3096,13,3097,1784,4081,3208,0]An[3096,13,3097,3097,511,3208,0]An[3096,13,3097,3097,127,3208,0]Ao[3096,13,3097,3097,2282,3208,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,13,464,2336,2263,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Ao[1195,13,1380,1380,3960,1826,0]Ao[1195,13,1380,1380,1189,1826,0]Al[519,13,520,520,3929,1826,0]Aj[463,13,464,0,4206,1826,0]Am[463,13,464,2304,4215,1826,0]Aj[463,13,464,0,1443,1826,0]Aj[463,13,464,0,1426,1826,0]Aj[463,13,464,0,2294,1826,0]Aj[463,13,464,0,3217,1826,0]Aj[463,13,464,0,3041,1826,0]Aj[463,13,464,0,4448,1826,0]Aj[463,13,464,0,1867,1826,0]Aj[463,13,464,0,4071,1826,0]Aj[463,13,464,0,4467,1826,0]Aj[463,13,464,0,4773,1826,0]Aj[463,13,464,0,4788,1826,0]Aj[463,13,464,0,3941,1826,0]Aj[463,13,464,0,4328,1826,0]Aj[463,13,464,0,4972,1826,0]Aj[463,13,464,0,4675,1826,0]Ak[463,13,3635,0,3012,1826,0]Ak[463,13,3635,0,3936,1826,0]Ak[463,13,3635,0,4233,1826,0]Ak[463,13,3635,0,4737,1826,0]Ao[3096,13,3097,4477,4207,1826,0]Ao[3096,13,3097,4254,5094,1826,0]Ao[3096,13,3097,1810,1444,1826,0]Ao[3096,13,3097,1366,1427,1826,0]Ao[3096,13,3097,1366,3233,1826,0]Ao[3096,13,3097,1366,3207,1826,0]Ao[3096,13,3097,1381,2295,1826,0]Ao[3096,13,3097,1381,3218,1826,0]Ao[3096,13,3097,1381,3042,1826,0]Ao[3096,13,3097,1381,4449,1826,0]Ao[3096,13,3097,1125,1868,1826,0]Ao[3096,13,3097,2002,4353,1826,0]Ao[3096,13,3097,2002,4075,1826,0]Ao[3096,13,3097,3194,4468,1826,0]Ao[3096,13,3097,3194,4774,1826,0]Ao[3096,13,3097,3194,4789,1826,0]Ao[3096,13,3097,3194,3942,1826,0]Ao[3096,13,3097,1691,4329,1826,0]Ao[3096,13,3097,1691,4973,1826,0]Ao[3096,13,3097,4254,5099,1826,0]Ao[3096,13,3097,4844,4676,1826,0]An[3096,13,3636,148,3013,1826,0]Ao[3096,13,3636,1352,3937,1826,0]Ao[3096,13,3636,2358,4234,1826,0]Ao[3096,13,3636,3636,4738,1826,0]Ao[1985,13,1986,1986,2279,1826,0]Ao[1095,13,1382,1382,1190,1826,0]Ao[1095,13,1382,1382,4453,1826,0]Al[3096,13,3097,1784,4214,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,13,3097,1756,4457,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Ai[3096,14,4456,0,1186,0,0]Ai[3096,14,4456,0,4680,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ab[1985,3,0,0,0,0,0]:965Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,1094,2275,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Ai[3096,14,4456,0,4680,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Ak[1195,14,1196,1196,134,0,0]Al[1195,14,1380,1380,1189,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Am[1195,13,1196,1196,134,118,0]An[1195,13,1196,1196,3952,118,0]An[1195,13,1196,1196,3928,118,0]An[1195,13,1380,1380,3960,118,0]An[1195,13,1380,1380,1189,118,0]An[1195,13,1380,1380,4354,118,0]Ak[519,13,520,520,3929,118,0]An[3966,13,3967,3967,5006,118,0]Al[463,13,464,3640,4472,118,0]Al[463,13,464,3640,2274,118,0]Ai[463,13,464,0,4206,118,0]Al[463,13,464,4142,4912,118,0]Al[463,13,464,1094,2275,118,0]Al[463,13,464,1094,4640,118,0]Al[463,13,464,3640,3209,118,0]Al[463,13,464,3640,3211,118,0]Al[463,13,464,3640,1843,118,0]Al[463,13,464,3640,1419,118,0]Al[463,13,464,3640,3004,118,0]Al[463,13,464,3640,2247,118,0]Al[463,13,464,3640,4106,118,0]Al[463,13,464,3640,4111,118,0]Al[463,13,464,3640,4918,118,0]Al[463,13,464,3640,4749,118,0]Al[463,13,464,2304,2259,118,0]Al[463,13,464,2304,4215,118,0]Al[463,13,464,2304,1399,118,0]Al[463,13,464,4142,1418,118,0]Al[463,13,464,4142,3231,118,0]Al[463,13,464,4142,4849,118,0]Al[463,13,464,2336,2263,118,0]Al[463,13,464,2336,3240,118,0]Al[463,13,464,2336,4333,118,0]Ak[463,13,464,1094,503,118,0]Al[463,13,464,1094,4359,118,0]Al[463,13,464,4034,3237,118,0]Al[463,13,464,4034,4856,118,0]Al[463,13,464,4034,4352,118,0]Al[463,13,464,4034,3044,118,0]Al[463,13,464,4034,3239,118,0]Al[463,13,464,4034,4351,118,0]Al[463,13,464,1393,4121,118,0]Al[463,13,464,1137,3955,118,0]Al[463,13,464,4039,3243,118,0]Al[463,13,464,4039,3257,118,0]Al[463,13,464,4039,4120,118,0]Al[463,13,464,4039,1857,118,0]Ai[463,13,464,0,3234,118,0]Ai[463,13,464,0,4245,118,0]Ai[463,13,464,0,4464,118,0]Ai[463,13,464,0,4098,118,0]Ai[463,13,464,0,4342,118,0]Ai[463,13,464,0,1443,118,0]Ai[463,13,464,0,4915,118,0]Ai[463,13,464,0,1152,118,0]Ai[463,13,464,0,1426,118,0]Ai[463,13,464,0,2294,118,0]Ai[463,13,464,0,3217,118,0]Ai[463,13,464,0,3041,118,0]Ai[463,13,464,0,4448,118,0]Ai[463,13,464,0,1867,118,0]Ai[463,13,464,0,4071,118,0]Ai[463,13,464,0,4444,118,0]Ai[463,13,464,0,4458,118,0]Ai[463,13,464,0,4467,118,0]Ai[463,13,464,0,4773,118,0]Ai[463,13,464,0,4788,118,0]Ai[463,13,464,0,3941,118,0]Ai[463,13,464,0,4328,118,0]Ai[463,13,464,0,4114,118,0]Ai[463,13,464,0,4972,118,0]Ai[463,13,464,0,4065,118,0]Ai[463,13,464,0,3931,118,0]Ai[463,13,464,0,3025,118,0]Ai[463,13,464,0,4441,118,0]Ai[463,13,464,0,4642,118,0]Ai[463,13,464,0,4077,118,0]Ai[463,13,464,0,4080,118,0]Ai[463,13,464,0,4085,118,0]Ai[463,13,464,0,4808,118,0]Ai[463,13,464,0,3220,118,0]Ai[463,13,464,0,4675,118,0]Ah[463,13,464,0,510,118,0]Ah[463,13,464,0,126,118,0]Ai[463,13,464,0,2281,118,0]Ai[463,13,464,0,2291,118,0]Ai[463,13,3635,0,120,118,0]Aj[463,13,3635,0,3012,118,0]Aj[463,13,3635,0,1156,118,0]Aj[463,13,3635,0,3936,118,0]Aj[463,13,3635,0,1840,118,0]Aj[463,13,3635,0,4233,118,0]Aj[463,13,3635,0,4737,118,0]Aj[463,13,1693,0,1835,118,0]Ai[463,13,1693,0,497,118,0]Aj[463,13,1693,0,5064,118,0]Aj[463,13,1693,0,3934,118,0]Aj[463,13,1693,0,4812,118,0]Aj[463,13,1773,0,3252,118,0]Aj[463,13,1773,0,4217,118,0]Aj[463,13,1773,0,1169,118,0]Aj[463,13,1773,0,4671,118,0]Aj[463,13,1773,0,4910,118,0]Aj[463,13,1773,0,4673,118,0]Am[2358,13,2359,2359,125,118,0]An[2358,13,2359,2359,2250,118,0]An[3096,13,3097,4477,4207,118,0]An[3096,13,3097,3070,3018,118,0]An[3096,13,3097,1120,1407,118,0]An[3096,13,3097,2002,1861,118,0]An[3096,13,3097,2002,3238,118,0]An[3096,13,3097,2002,3244,118,0]An[3096,13,3097,3641,3212,118,0]An[3096,13,3097,1116,3235,118,0]An[3096,13,3097,1691,4246,118,0]An[3096,13,3097,2305,2260,118,0]An[3096,13,3097,2305,4213,118,0]An[3096,13,3097,2305,4651,118,0]An[3096,13,3097,2305,4224,118,0]An[3096,13,3097,1756,5124,118,0]An[3096,13,3097,4254,5094,118,0]An[3096,13,3097,1392,4465,118,0]An[3096,13,3097,1392,4099,118,0]An[3096,13,3097,1392,4343,118,0]An[3096,13,3097,1810,1444,118,0]An[3096,13,3097,1810,4916,118,0]An[3096,13,3097,3061,1153,118,0]An[3096,13,3097,3070,4750,118,0]An[3096,13,3097,1366,1427,118,0]An[3096,13,3097,1366,4110,118,0]An[3096,13,3097,1366,3233,118,0]An[3096,13,3097,1366,3040,118,0]An[3096,13,3097,1366,4748,118,0]An[3096,13,3097,1366,4804,118,0]An[3096,13,3097,1366,3207,118,0]An[3096,13,3097,1381,2295,118,0]An[3096,13,3097,1381,3218,118,0]An[3096,13,3097,1381,3042,118,0]An[3096,13,3097,1381,4449,118,0]An[3096,13,3097,1120,3045,118,0]An[3096,13,3097,1120,4241,118,0]An[3096,13,3097,1125,1868,118,0]An[3096,13,3097,1125,3258,118,0]An[3096,13,3097,1125,3940,118,0]An[3096,13,3097,2002,3959,118,0]An[3096,13,3097,2002,4353,118,0]An[3096,13,3097,2002,4075,118,0]An[3096,13,3097,3641,4445,118,0]An[3096,13,3097,3641,3038,118,0]An[3096,13,3097,3641,4319,118,0]An[3096,13,3097,3641,5001,118,0]An[3096,13,3097,3641,1174,118,0]An[3096,13,3097,1116,4459,118,0]An[3096,13,3097,3194,4468,118,0]An[3096,13,3097,3194,4774,118,0]An[3096,13,3097,3194,4789,118,0]An[3096,13,3097,3194,3942,118,0]An[3096,13,3097,1691,4329,118,0]An[3096,13,3097,1691,4116,118,0]An[3096,13,3097,1691,4973,118,0]An[3096,13,3097,1691,4067,118,0]An[3096,13,3097,1691,3932,118,0]An[3096,13,3097,1356,3026,118,0]An[3096,13,3097,1356,4334,118,0]An[3096,13,3097,1356,3224,118,0]An[3096,13,3097,1356,3247,118,0]An[3096,13,3097,1356,4082,118,0]An[3096,13,3097,1356,4443,118,0]An[3096,13,3097,1356,4644,118,0]An[3096,13,3097,1356,2253,118,0]An[3096,13,3097,2305,4648,118,0]An[3096,13,3097,2305,2264,118,0]An[3096,13,3097,2305,4078,118,0]An[3096,13,3097,2305,3926,118,0]An[3096,13,3097,2305,3241,118,0]An[3096,13,3097,1756,4236,118,0]An[3096,13,3097,1756,4457,118,0]An[3096,13,3097,1756,5005,118,0]An[3096,13,3097,1756,2267,118,0]An[3096,13,3097,1756,4746,118,0]An[3096,13,3097,1784,4447,118,0]An[3096,13,3097,1784,4214,118,0]An[3096,13,3097,1784,4081,118,0]An[3096,13,3097,1784,4086,118,0]Ak[3096,13,3097,0,4357,118,0]Ak[3096,13,3097,0,4809,118,0]An[3096,13,3097,4254,3221,118,0]An[3096,13,3097,4254,5099,118,0]An[3096,13,3097,4844,4676,118,0]Am[3096,13,3097,3097,511,118,0]Am[3096,13,3097,3097,127,118,0]An[3096,13,3097,3097,2282,118,0]An[3096,13,3097,3097,2292,118,0]An[3096,13,3097,3097,3024,118,0]An[3096,13,1689,1689,4247,118,0]An[3096,13,4957,4957,4855,118,0]An[3096,13,4957,4957,1171,118,0]An[3096,13,1694,1694,1836,118,0]Am[3096,13,1694,1694,498,118,0]An[3096,13,1694,1694,5065,118,0]An[3096,13,1694,1694,3935,118,0]An[3096,13,1694,1694,4815,118,0]An[3096,13,1774,1774,3253,118,0]An[3096,13,1774,1774,4218,118,0]Ak[3096,13,1774,0,1170,118,0]An[3096,13,1774,1774,4672,118,0]An[3096,13,1774,1774,4911,118,0]An[3096,13,1774,1774,4674,118,0]Al[3096,13,3636,148,121,118,0]Am[3096,13,3636,148,3013,118,0]An[3096,13,3636,1352,1157,118,0]An[3096,13,3636,1352,3937,118,0]An[3096,13,3636,2358,1841,118,0]An[3096,13,3636,2358,4234,118,0]An[3096,13,3636,3636,4738,118,0]An[3096,13,4706,4706,1172,118,0]An[3096,13,4706,4706,1175,118,0]An[1985,13,1986,1986,3256,118,0]Am[1985,13,1986,416,4358,118,0]An[1985,13,1986,1986,2279,118,0]An[1985,13,1986,1986,2293,118,0]An[1985,13,1986,1986,4087,118,0]An[1095,13,1096,1096,3015,118,0]An[1095,13,1096,1096,4848,118,0]Am[1095,13,1683,1683,135,118,0]An[1095,13,1382,1382,1190,118,0]An[1095,13,1382,1382,3961,118,0]An[1095,13,1382,1382,4453,118,0]An[1095,13,4174,4174,5050,118,0]An[1095,13,4174,4174,5051,118,0]Am[1095,13,1779,1779,136,118,0]Aj[463,13,464,3640,4918,0,0]Aj[463,13,464,1094,4359,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Af[463,5,464,3640,0,0,0]Al[1195,15,1196,1196,3928,0,0]Ae[2358,6,2359,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Aj[463,15,464,3640,4749,0,0]Al[3096,15,3097,3070,4750,0,0]Af[463,5,464,2304,0,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,2002,3959,0,0]Af[463,5,464,2336,0,0,0]2Ah[3096,6,3097,1756,0,0,0]Ag[463,19,464,0,1443,0,0]Al[3096,19,3097,1810,1444,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]=Ah[463,12,1693,0,4115,0,0]>Ak[463,13,1773,0,4673,4115,0]>Al[3096,12,1694,1694,4117,0,0]>Ao[3096,13,1774,1774,4674,4117,0]Ao[1095,13,4174,4174,5051,4117,0]An[2358,13,2359,2359,125,3943,0]Ao[2358,13,2359,2359,2250,3943,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1381,3042,0,0]Ag[463,13,464,0,4114,0,0]Al[3096,13,3097,1691,4116,0,0]Aj[463,13,464,1994,4316,0,0]0>=Al[1095,13,1382,1382,4453,0,0]Ae[1095,2,1096,0,0,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]43Ak[1195,14,1196,1196,134,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,4254,5094,0,0]Al[3096,13,3097,4254,5099,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]=Al[1195,14,1380,1380,1189,0,0]Ao[1095,13,1096,1096,4848,3050,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Af[463,6,464,3641,0,0,0]Ah[3096,6,3097,3641,0,0,0]Al[3096,15,3097,2305,4213,0,0]Ah[3096,5,3097,1784,0,0,0]Af[463,5,464,1381,0,0,0]Ah[3096,5,3097,1381,0,0,0]97Ae[1095,5,1382,0,0,0,0]:8Ah[3096,6,3097,1756,0,0,0]Af[463,5,464,1116,0,0,0]Ah[3096,5,3097,1116,0,0,0]Al[3096,15,3097,1366,4748,0,0]Af[463,5,464,1392,0,0,0]Ah[3096,5,3097,1392,0,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,3641,4445,0,0]Af[463,5,464,3640,0,0,0]Aj[463,15,464,4034,3044,0,0]Aj[463,15,464,4034,3239,0,0]Aj[463,15,464,4039,3257,0,0]Aj[463,15,464,4039,4120,0,0]An[1195,13,1196,1196,134,4212,0]Ao[1195,13,1196,1196,3952,4212,0]Ao[1195,13,1196,1196,3928,4212,0]Am[463,13,464,3640,3211,4212,0]Am[463,13,464,3640,4918,4212,0]Am[463,13,464,3640,4749,4212,0]Am[463,13,464,2304,2259,4212,0]Am[463,13,464,2304,4215,4212,0]Am[463,13,464,4142,1418,4212,0]Al[463,13,464,1094,503,4212,0]Am[463,13,464,1094,4359,4212,0]Am[463,13,464,4034,4352,4212,0]Am[463,13,464,4034,3044,4212,0]Am[463,13,464,4034,3239,4212,0]Am[463,13,464,4034,4351,4212,0]Am[463,13,464,4039,3257,4212,0]Am[463,13,464,4039,4120,4212,0]Aj[463,13,464,0,1443,4212,0]Aj[463,13,464,0,4915,4212,0]Aj[463,13,464,0,1426,4212,0]Aj[463,13,464,0,2294,4212,0]Aj[463,13,464,0,3217,4212,0]Aj[463,13,464,0,3041,4212,0]Aj[463,13,464,0,4448,4212,0]Aj[463,13,464,0,1867,4212,0]Aj[463,13,464,0,4071,4212,0]Aj[463,13,464,0,4444,4212,0]Aj[463,13,464,0,4467,4212,0]Aj[463,13,464,0,4773,4212,0]Aj[463,13,464,0,4788,4212,0]Aj[463,13,464,0,3941,4212,0]Aj[463,13,464,0,4328,4212,0]Aj[463,13,464,0,4114,4212,0]Aj[463,13,464,0,4972,4212,0]Aj[463,13,464,0,4065,4212,0]Aj[463,13,464,0,3931,4212,0]Aj[463,13,464,0,3025,4212,0]Aj[463,13,464,0,4441,4212,0]Aj[463,13,464,0,4642,4212,0]Aj[463,13,464,0,4077,4212,0]Aj[463,13,464,0,4080,4212,0]Aj[463,13,464,0,4085,4212,0]Aj[463,13,464,0,4808,4212,0]Aj[463,13,464,0,3220,4212,0]Ai[463,13,464,0,510,4212,0]Ai[463,13,464,0,126,4212,0]Aj[463,13,464,0,2281,4212,0]Aj[463,13,3635,0,120,4212,0]Ak[463,13,3635,0,3012,4212,0]Ak[463,13,3635,0,1156,4212,0]Ak[463,13,3635,0,3936,4212,0]Ak[463,13,3635,0,1840,4212,0]Ak[463,13,3635,0,4233,4212,0]Ak[463,13,1773,0,1169,4212,0]Ak[463,13,1773,0,4671,4212,0]Ak[463,13,1773,0,4910,4212,0]Ak[463,13,1773,0,4673,4212,0]Ao[3096,13,3097,1810,1444,4212,0]Ao[3096,13,3097,1810,4916,4212,0]Ao[3096,13,3097,3070,4750,4212,0]Ao[3096,13,3097,1366,1427,4212,0]Ao[3096,13,3097,1366,4110,4212,0]Ao[3096,13,3097,1366,3233,4212,0]Ao[3096,13,3097,1366,3040,4212,0]Ao[3096,13,3097,1366,4748,4212,0]Ao[3096,13,3097,1366,4804,4212,0]Ao[3096,13,3097,1366,3207,4212,0]Ao[3096,13,3097,1381,2295,4212,0]Ao[3096,13,3097,1381,3218,4212,0]Ao[3096,13,3097,1381,3042,4212,0]Ao[3096,13,3097,1381,4449,4212,0]Ao[3096,13,3097,1120,3045,4212,0]Ao[3096,13,3097,1120,4241,4212,0]Ao[3096,13,3097,1125,1868,4212,0]Ao[3096,13,3097,1125,3258,4212,0]Ao[3096,13,3097,1125,3940,4212,0]Ao[3096,13,3097,2002,4353,4212,0]Ao[3096,13,3097,2002,4075,4212,0]Ao[3096,13,3097,3641,4445,4212,0]Ao[3096,13,3097,3641,3038,4212,0]Ao[3096,13,3097,3641,4319,4212,0]Ao[3096,13,3097,3641,5001,4212,0]Ao[3096,13,3097,3194,4468,4212,0]Ao[3096,13,3097,3194,4774,4212,0]Ao[3096,13,3097,3194,4789,4212,0]Ao[3096,13,3097,3194,3942,4212,0]Ao[3096,13,3097,1691,4329,4212,0]Ao[3096,13,3097,1691,4116,4212,0]Ao[3096,13,3097,1691,4973,4212,0]Ao[3096,13,3097,1691,4067,4212,0]Ao[3096,13,3097,1691,3932,4212,0]Ao[3096,13,3097,1356,3026,4212,0]Ao[3096,13,3097,1356,3224,4212,0]Ao[3096,13,3097,1356,3247,4212,0]Ao[3096,13,3097,1356,4082,4212,0]Ao[3096,13,3097,1356,4443,4212,0]Ao[3096,13,3097,1356,4644,4212,0]Ao[3096,13,3097,1356,2253,4212,0]Ao[3096,13,3097,2305,4648,4212,0]Ao[3096,13,3097,2305,4078,4212,0]Ao[3096,13,3097,1756,4457,4212,0]Ao[3096,13,3097,1756,5005,4212,0]Ao[3096,13,3097,1756,2267,4212,0]Ao[3096,13,3097,1756,4746,4212,0]Ao[3096,13,3097,1784,4081,4212,0]Ao[3096,13,3097,1784,4086,4212,0]Al[3096,13,3097,0,4357,4212,0]Al[3096,13,3097,0,4809,4212,0]Ao[3096,13,3097,4254,3221,4212,0]Ao[3096,13,3097,4254,5099,4212,0]An[3096,13,3097,3097,511,4212,0]An[3096,13,3097,3097,127,4212,0]Ao[3096,13,3097,3097,2282,4212,0]Ao[3096,13,3097,3097,3024,4212,0]Ao[3096,13,1689,1689,4247,4212,0]Ao[3096,13,4957,4957,4855,4212,0]Ao[3096,13,4957,4957,1171,4212,0]Al[3096,13,1774,0,1170,4212,0]Ao[3096,13,1774,1774,4672,4212,0]Ao[3096,13,1774,1774,4911,4212,0]Ao[3096,13,1774,1774,4674,4212,0]Am[3096,13,3636,148,121,4212,0]An[3096,13,3636,148,3013,4212,0]Ao[3096,13,3636,1352,1157,4212,0]Ao[3096,13,3636,1352,3937,4212,0]Ao[3096,13,3636,2358,1841,4212,0]Ao[3096,13,3636,2358,4234,4212,0]Ao[3096,13,4706,4706,1175,4212,0]Ao[1985,13,1986,1986,2279,4212,0]Ao[1985,13,1986,1986,2293,4212,0]Ao[1985,13,1986,1986,4087,4212,0]Ao[1095,13,1096,1096,4848,4212,0]Ao[1095,13,1382,1382,4453,4212,0]Ao[1095,13,4174,4174,5050,4212,0]Ao[1095,13,4174,4174,5051,4212,0]Af[463,7,464,1994,0,0,0]Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]10Ae[1095,7,1096,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[4257,7,4258,0,0,0,0]Ae[1195,7,1196,0,0,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]1Al[3096,13,3097,2002,4353,0,0]Al[1195,13,1380,1380,1189,0,0]Al[1195,14,1380,1380,3960,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4121,1852,0]Am[463,13,464,1137,3955,1852,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Af[463,5,464,1094,0,0,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,3641,4445,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,3641,1174,0,0]1Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]32Al[3096,15,3097,3641,3038,0,0]><><><21Ag[463,5,1773,1774,0,0,0]Ae[3096,5,1774,0,0,0,0]10Af[463,5,464,4844,0,0,0]Ah[3096,5,3097,4844,0,0,0]Al[3096,15,4706,4706,1172,0,0]Al[3096,15,3097,1366,4748,0,0]6Al[3096,15,3097,1756,4457,0,0]Ag[463,12,464,0,2287,0,0]Aj[463,13,464,0,4206,2287,0]Aj[463,13,464,0,4098,2287,0]Al[3096,12,3097,1392,2288,0,0]Ao[3096,13,3097,4477,4207,2288,0]Ao[3096,13,3097,1392,4099,2288,0]Ae[3966,7,3967,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]32An[1195,13,1196,1196,134,4330,0]An[2358,13,2359,2359,125,4330,0]Ao[2358,13,2359,2359,2250,4330,0]Ao[1095,13,1096,1096,3015,4330,0]An[1095,13,1683,1683,135,4330,0]An[1095,13,1779,1779,136,4330,0]Ak[1985,13,1986,416,4358,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]:9Ae[3096,2,3097,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]?>43Ae[4257,7,4258,0,0,0,0]6Al[1095,14,1096,1096,3015,0,0]70Ae[1195,7,1196,0,0,0,0]Ag[463,13,464,0,4114,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4116,0,0]Al[3096,13,3097,1691,4067,0,0]Ag[463,14,464,0,4114,0,0]Al[3096,14,3097,1691,4116,0,0]53Aj[463,13,464,4039,3243,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,1366,4748,0,0]Al[3096,15,3097,3641,4445,0,0]Ah[463,10,3635,3636,0,0,0]Af[3096,10,3636,0,0,0,0]Ag[463,5,3635,3636,0,0,0]Ae[3096,5,3636,0,0,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,10,464,3641,0,0,0]Ai[3096,10,3097,3641,0,0,0]Ah[3096,6,3097,1756,0,0,0]Ah[3096,6,3097,1366,0,0,0]Af[463,6,464,3640,0,0,0]Ah[3096,6,3097,3070,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Aj[463,15,464,3640,4749,0,0]Al[3096,15,3097,3070,4750,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1381,3042,0,0]Ah[463,14,3635,0,4737,0,0]Al[3096,14,3636,3636,4738,0,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]10Al[3096,13,3097,3070,3018,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Ab[4768,3,0,0,0,0,0]Ao[1095,13,1096,1096,4848,3050,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]54Ai[3096,10,3097,1756,0,0,0]Al[3096,15,3097,3641,1174,0,0]7600Al[3096,15,3097,1120,4241,0,0]4365Al[3096,15,4706,4706,1172,0,0]Ae[1095,9,1096,0,0,0,0]:9Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]<;<;Ah[3096,6,3097,1366,0,0,0]21Al[1195,15,1196,1196,3952,0,0]Ac[463,5,464,0,0,0,0]Ae[3096,5,3097,0,0,0,0]Ag[463,15,464,0,4077,0,0]Ag[463,5,1693,1694,0,0,0]Al[3096,15,3097,2305,4078,0,0]Al[3096,15,3097,1756,4746,0,0]Ae[3096,5,1694,0,0,0,0]An[1195,13,1196,1196,134,4320,0]An[2358,13,2359,2359,125,4320,0]Ao[1095,13,1096,1096,3015,4320,0]An[1095,13,1683,1683,135,4320,0]An[1095,13,1779,1779,136,4320,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ag[463,13,464,0,1443,0,0]Al[3096,13,3097,1810,1444,0,0]Aj[463,14,464,2304,4215,0,0]Aj[463,13,464,3640,4918,0,0]Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ag[463,13,464,0,4206,0,0]Al[3096,13,3097,4477,4207,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]7Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,13,1773,0,4671,0,0]Ah[463,13,1773,0,4673,0,0]Al[3096,13,1774,1774,4672,0,0]Al[3096,13,1774,1774,4674,0,0]45;:Ao[3966,13,3967,3967,5006,4802,0]Ag[463,13,464,0,4458,0,0]Al[3096,13,3097,1116,4459,0,0]Ae[1095,6,1096,0,0,0,0]Af[463,5,464,4142,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Al[3096,15,3097,3641,3038,0,0]Ae[3096,5,4957,0,0,0,0]Af[463,5,464,4034,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Al[3096,15,4706,4706,1172,0,0]Aj[463,14,464,2304,4215,0,0]Ai[463,13,464,0,510,3006,0]Ai[463,13,464,0,126,3006,0]An[3096,13,3097,3097,511,3006,0]An[3096,13,3097,3097,127,3006,0]Ao[2358,13,2359,2359,2250,3248,0]Ag[463,13,464,0,4788,0,0]Al[3096,13,3097,3194,4789,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Aj[463,13,464,3640,3211,0,0]Ag[463,12,464,0,4743,0,0]Al[3096,12,3097,3641,4744,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1381,3042,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Aj[463,14,464,2304,4215,0,0]Al[3096,13,3097,2002,1861,0,0]Ah[3096,2,4252,4038,0,0,0]Ae[1195,7,1196,0,0,0,0]==Ai[463,13,464,1094,503,0,0]Ak[1985,13,1986,416,4358,0,0]032Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Ae[3096,2,3097,0,0,0,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ag[463,10,464,4254,0,0,0]Ai[3096,10,3097,4254,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Af[463,5,464,1691,0,0,0]Ah[3096,5,3097,1691,0,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,3097,3024,0,0]Ah[463,13,3635,0,4233,0,0]Al[3096,13,3636,2358,4234,0,0]Aj[463,13,464,1994,3048,0,0]0Aj[463,13,464,3640,3211,0,0]6Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Al[3096,15,4706,4706,1172,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Al[3096,15,3097,1366,4804,0,0]Al[3096,15,3097,3641,3038,0,0]Al[3096,15,3097,3641,4319,0,0]Ah[3096,5,3097,3641,0,0,0]Al[3096,15,3097,1366,4748,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1756,0,0,0]Ae[3966,5,3967,0,0,0,0]Al[1095,13,1096,1096,3015,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ah[3096,7,4890,4889,0,0,0]0Al[3096,13,3097,3641,3212,0,0]6Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Ao[3966,13,3967,3967,5006,4802,0]0Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Ag[463,13,464,0,4773,0,0]Al[3096,13,3097,3194,4774,0,0]Am[1195,13,1196,1196,134,485,0]Am[2358,13,2359,2359,125,485,0]An[1095,13,1096,1096,3015,485,0]Am[1095,13,1683,1683,135,485,0]Am[1095,13,1779,1779,136,485,0]??>An[1195,13,1196,1196,134,4330,0]An[2358,13,2359,2359,125,4330,0]Ao[2358,13,2359,2359,2250,4330,0]Ao[1095,13,1096,1096,3015,4330,0]An[1095,13,1683,1683,135,4330,0]An[1095,13,1779,1779,136,4330,0]Ag[463,13,464,0,4114,0,0]Al[3096,13,3097,1691,4116,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ae[1095,5,4174,0,0,0,0]0Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,13,3097,3641,3212,0,0]Ao[3966,13,3967,3967,5006,4802,0];:Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]?>?>Aj[463,13,464,3640,3211,0,0]6Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ae[3966,7,3967,0,0,0,0]Ae[4257,7,4258,0,0,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]?434343>=>=Al[3096,14,4957,4957,4855,0,0]54Ai[3096,18,3097,3194,0,0,0]") \ No newline at end of file +rd_("Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ag[463,15,464,0,4085,0,0]Al[3096,15,3097,1784,4086,0,0]Al[1985,15,1986,1986,4087,0,0]Al[3096,15,1689,1689,1433,0,0]Ao[1195,13,1196,1196,3928,3037,0]Am[463,13,464,3640,4749,3037,0]Am[463,13,464,4142,1418,3037,0]Al[463,13,464,1094,503,3037,0]Am[463,13,464,1094,4359,3037,0]Am[463,13,464,4034,4352,3037,0]Am[463,13,464,4034,3044,3037,0]Am[463,13,464,4034,3239,3037,0]Am[463,13,464,4034,4351,3037,0]Am[463,13,464,4039,3257,3037,0]Am[463,13,464,4039,4120,3037,0]Aj[463,13,464,0,1443,3037,0]Aj[463,13,464,0,4915,3037,0]Aj[463,13,464,0,1152,3037,0]Aj[463,13,464,0,1426,3037,0]Aj[463,13,464,0,2294,3037,0]Aj[463,13,464,0,3217,3037,0]Aj[463,13,464,0,3041,3037,0]Aj[463,13,464,0,1867,3037,0]Aj[463,13,464,0,4071,3037,0]Aj[463,13,464,0,4444,3037,0]Aj[463,13,464,0,3941,3037,0]Aj[463,13,464,0,3931,3037,0]Aj[463,13,464,0,3025,3037,0]Aj[463,13,464,0,4441,3037,0]Aj[463,13,464,0,4642,3037,0]Aj[463,13,464,0,4077,3037,0]Aj[463,13,464,0,4080,3037,0]Aj[463,13,464,0,4085,3037,0]Aj[463,13,464,0,4808,3037,0]Ai[463,13,464,0,510,3037,0]Ai[463,13,464,0,126,3037,0]Aj[463,13,464,0,2281,3037,0]Ak[463,13,1693,0,5064,3037,0]Ak[463,13,1773,0,1169,3037,0]Ao[3096,13,3097,1810,1444,3037,0]Ao[3096,13,3097,1810,4916,3037,0]Ao[3096,13,3097,3061,1153,3037,0]Ao[3096,13,3097,3070,4750,3037,0]Ao[3096,13,3097,1366,1427,3037,0]Ao[3096,13,3097,1366,3233,3037,0]Ao[3096,13,3097,1366,3040,3037,0]Ao[3096,13,3097,1366,4748,3037,0]Ao[3096,13,3097,1366,4804,3037,0]Ao[3096,13,3097,1366,3207,3037,0]Ao[3096,13,3097,1382,2295,3037,0]Ao[3096,13,3097,1382,3218,3037,0]Ao[3096,13,3097,1382,3042,3037,0]Ao[3096,13,3097,1120,3045,3037,0]Ao[3096,13,3097,1120,4241,3037,0]Ao[3096,13,3097,1125,1868,3037,0]Ao[3096,13,3097,1125,3258,3037,0]Ao[3096,13,3097,1125,3940,3037,0]Ao[3096,13,3097,2002,3959,3037,0]Ao[3096,13,3097,2002,4353,3037,0]Ao[3096,13,3097,2002,4075,3037,0]Ao[3096,13,3097,3641,4445,3037,0]Ao[3096,13,3097,3641,3038,3037,0]Ao[3096,13,3097,3641,4319,3037,0]Ao[3096,13,3097,3194,3942,3037,0]Ao[3096,13,3097,1691,3932,3037,0]Ao[3096,13,3097,1356,3026,3037,0]Ao[3096,13,3097,1356,4334,3037,0]Ao[3096,13,3097,1356,3224,3037,0]Ao[3096,13,3097,1356,3247,3037,0]Ao[3096,13,3097,1356,4082,3037,0]Ao[3096,13,3097,1356,4443,3037,0]Ao[3096,13,3097,1356,4644,3037,0]Ao[3096,13,3097,2305,4648,3037,0]Ao[3096,13,3097,2305,4078,3037,0]Ao[3096,13,3097,1756,2267,3037,0]Ao[3096,13,3097,1756,4746,3037,0]Ao[3096,13,3097,1784,4081,3037,0]Ao[3096,13,3097,1784,4086,3037,0]Al[3096,13,3097,0,4357,3037,0]Al[3096,13,3097,0,4809,3037,0]An[3096,13,3097,3097,511,3037,0]An[3096,13,3097,3097,127,3037,0]Ao[3096,13,3097,3097,2282,3037,0]Ao[3096,13,3097,3097,3024,3037,0]Ao[3096,13,1689,1689,4247,3037,0]Ao[3096,13,4957,4957,4855,3037,0]Ao[3096,13,4957,4957,1171,3037,0]Ao[3096,13,1694,1694,5065,3037,0]Al[3096,13,1774,0,1170,3037,0]Ao[1985,13,1986,1986,4087,3037,0]Ai[463,13,464,1094,503,0,0]Aj[463,13,464,1094,4359,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Aj[463,13,464,4039,3243,0,0]Ai[3096,14,3039,0,1420,0,0]Ai[3096,14,3039,0,3002,0,0]Ai[3096,14,3039,0,3020,0,0]Ai[3096,14,3039,0,4107,0,0]Ai[3096,14,3039,0,4100,0,0]Ai[3096,14,3958,0,2277,0,0]Ai[3096,14,3958,0,2297,0,0]Ai[3096,14,3958,0,2261,0,0]Ai[3096,14,3958,0,1855,0,0]Ae[1195,7,1196,0,0,0,0]Ah[3096,14,4456,0,499,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Af[463,5,3635,148,0,0,0]Ag[3096,5,3636,148,0,0,0]Al[1095,15,1096,1096,4848,0,0]Ae[2358,5,2359,0,0,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Al[3096,15,1689,1689,1433,0,0]Ag[463,19,464,0,1443,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1810,1444,0,0]Al[3096,19,3097,1366,1427,0,0]Ae[1195,5,1196,0,0,0,0]Ae[1095,5,1683,0,0,0,0]Ae[1095,5,1779,0,0,0,0]Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ai[463,13,464,0,2294,117,0]Ai[463,13,464,0,3217,117,0]Ai[463,13,464,0,4448,117,0]An[3096,13,3097,1382,2295,117,0]An[3096,13,3097,1382,3218,117,0]An[3096,13,3097,1382,4449,117,0]Ai[463,13,464,0,1443,137,0]Ai[463,13,464,0,1426,137,0]Ai[463,13,464,0,3941,137,0]Ai[463,13,464,0,4080,137,0]Ah[463,13,464,0,510,137,0]Ah[463,13,464,0,126,137,0]Ai[463,13,464,0,2281,137,0]An[3096,13,3097,1810,1444,137,0]An[3096,13,3097,3070,4750,137,0]An[3096,13,3097,1366,1427,137,0]An[3096,13,3097,1120,3045,137,0]An[3096,13,3097,1120,4241,137,0]An[3096,13,3097,1125,3258,137,0]An[3096,13,3097,3194,3942,137,0]An[3096,13,3097,2305,4648,137,0]An[3096,13,3097,1756,4746,137,0]An[3096,13,3097,1784,4081,137,0]Am[3096,13,3097,3097,511,137,0]Am[3096,13,3097,3097,127,137,0]An[3096,13,3097,3097,2282,137,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ai[3096,14,3958,0,1421,0,0]Ai[3096,14,3958,0,3009,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2279,0,0]Al[1985,14,1986,1986,2293,0,0]An[1195,13,1196,1196,134,1159,0]Ao[1195,13,1196,1196,3952,1159,0]Ao[1195,13,1196,1196,3928,1159,0]Ao[1195,13,1380,1380,4354,1159,0]Ao[3966,13,3967,3967,5006,1159,0]Am[463,13,464,4142,4912,1159,0]Am[463,13,464,3640,3209,1159,0]Am[463,13,464,3640,3211,1159,0]Am[463,13,464,3640,4918,1159,0]D`[463,13,464,3640,4749,1159,0,\"impl-Debug-for-SendDatagramError\"]Db[463,13,464,3640,4749,1827,0,\"impl-Display-for-SendDatagramError\"]Am[463,13,464,2304,2259,1159,0]Am[463,13,464,2304,4215,1159,0]Cg[463,13,464,4142,1418,1827,0,\"impl-Display-for-Lagged\"]Ce[463,13,464,4142,1418,1159,0,\"impl-Debug-for-Lagged\"]Am[463,13,464,4142,3231,1159,0]Am[463,13,464,4142,4849,1159,0]Am[463,13,464,2336,2263,1159,0]Ck[463,13,464,2336,3240,1827,0,\"impl-Display-for-RetryError\"]Ci[463,13,464,2336,3240,1159,0,\"impl-Debug-for-RetryError\"]Am[463,13,464,2336,4333,1159,0]Al[463,13,464,1094,503,1159,0]Am[463,13,464,1094,4359,1159,0]Am[463,13,464,4034,3237,1159,0]Am[463,13,464,4034,4856,1159,0]Co[463,13,464,4034,4352,1827,0,\"impl-Display-for-ReadToEndError\"]Cm[463,13,464,4034,4352,1159,0,\"impl-Debug-for-ReadToEndError\"]Cj[463,13,464,4034,3044,1827,0,\"impl-Display-for-ReadError\"]Ch[463,13,464,4034,3044,1159,0,\"impl-Debug-for-ReadError\"]Ci[463,13,464,4034,3239,1159,0,\"impl-Debug-for-ResetError\"]Ck[463,13,464,4034,3239,1827,0,\"impl-Display-for-ResetError\"]Cm[463,13,464,4034,4351,1159,0,\"impl-Debug-for-ReadExactError\"]Co[463,13,464,4034,4351,1827,0,\"impl-Display-for-ReadExactError\"]Am[463,13,464,1393,4121,1159,0]Am[463,13,464,1137,3955,1159,0]Am[463,13,464,4039,3243,1159,0]Ci[463,13,464,4039,3257,1159,0,\"impl-Debug-for-WriteError\"]Ck[463,13,464,4039,3257,1827,0,\"impl-Display-for-WriteError\"]Cm[463,13,464,4039,4120,1827,0,\"impl-Display-for-StoppedError\"]Ck[463,13,464,4039,4120,1159,0,\"impl-Debug-for-StoppedError\"]Am[463,13,464,4039,1857,1159,0]Cd[463,13,464,0,1443,1827,0,\"impl-Display-for-VarInt\"]Cb[463,13,464,0,1443,1159,0,\"impl-Debug-for-VarInt\"]D`[463,13,464,0,4915,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Db[463,13,464,0,4915,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]Aj[463,13,464,0,1152,1159,0]Cb[463,13,464,0,1426,1159,0,\"impl-Debug-for-PathId\"]Cd[463,13,464,0,1426,1827,0,\"impl-Display-for-PathId\"]Aj[463,13,464,0,2294,1159,0]Aj[463,13,464,0,3217,1159,0]Aj[463,13,464,0,3041,1159,0]Aj[463,13,464,0,4448,1159,0]Aj[463,13,464,0,1867,1159,0]Cj[463,13,464,0,4071,1827,0,\"impl-Display-for-ClosedStream\"]Ch[463,13,464,0,4071,1159,0,\"impl-Debug-for-ClosedStream\"]Ck[463,13,464,0,4444,1159,0,\"impl-Debug-for-ConnectionError\"]Cm[463,13,464,0,4444,1827,0,\"impl-Display-for-ConnectionError\"]Aj[463,13,464,0,4458,1159,0]Aj[463,13,464,0,4467,1159,0]Aj[463,13,464,0,4773,1159,0]Aj[463,13,464,0,4788,1159,0]Aj[463,13,464,0,3941,1159,0]Aj[463,13,464,0,4328,1159,0]Aj[463,13,464,0,4114,1159,0]Aj[463,13,464,0,4972,1159,0]Aj[463,13,464,0,4065,1159,0]Cg[463,13,464,0,3931,1159,0,\"impl-Debug-for-ConfigError\"]Ci[463,13,464,0,3931,1827,0,\"impl-Display-for-ConfigError\"]Cg[463,13,464,0,3025,1827,0,\"impl-Display-for-FrameType\"]Ce[463,13,464,0,3025,1159,0,\"impl-Debug-for-FrameType\"]Cm[463,13,464,0,4441,1827,0,\"impl-Display-for-ConnectionClose\"]Ck[463,13,464,0,4441,1159,0,\"impl-Debug-for-ConnectionClose\"]Cn[463,13,464,0,4642,1827,0,\"impl-Display-for-ApplicationClose\"]Cl[463,13,464,0,4642,1159,0,\"impl-Debug-for-ApplicationClose\"]Ch[463,13,464,0,4077,1159,0,\"impl-Debug-for-ConnectError\"]Cj[463,13,464,0,4077,1827,0,\"impl-Display-for-ConnectError\"]Cj[463,13,464,0,4080,1827,0,\"impl-Display-for-ConnectionId\"]Ch[463,13,464,0,4080,1159,0,\"impl-Debug-for-ConnectionId\"]Aj[463,13,464,0,4085,1159,0]Cn[463,13,464,0,4808,1159,0,\"impl-Debug-for-TransportErrorCode\"]D`[463,13,464,0,4808,1827,0,\"impl-Display-for-TransportErrorCode\"]Aj[463,13,464,0,3220,1159,0]Aj[463,13,464,0,4675,1159,0]Ai[463,13,464,0,510,1159,0]C`[463,13,464,0,126,1827,0,\"impl-Display-for-Dir\"]Bn[463,13,464,0,126,1159,0,\"impl-Debug-for-Dir\"]Cf[463,13,464,0,2281,1827,0,\"impl-Display-for-StreamId\"]Cd[463,13,464,0,2281,1159,0,\"impl-Debug-for-StreamId\"]Aj[463,13,464,0,2291,1159,0]Aj[463,13,3635,0,120,1159,0]Ak[463,13,3635,0,3012,1159,0]Ak[463,13,3635,0,1156,1159,0]Ak[463,13,3635,0,3936,1159,0]Ak[463,13,3635,0,1840,1159,0]Ak[463,13,3635,0,4233,1159,0]Ak[463,13,3635,0,4737,1159,0]Ak[463,13,1693,0,5064,1159,0]Ak[463,13,1693,0,3934,1159,0]Ak[463,13,1693,0,4812,1159,0]Cb[463,13,1773,0,1169,1159,0,\"impl-Debug-for-Error\"]Cd[463,13,1773,0,1169,1827,0,\"impl-Display-for-Error\"]Da[463,13,1773,0,4910,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Dc[463,13,1773,0,4910,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]Ao[3096,13,3097,3641,3212,1159,0]Ao[3096,13,3097,2305,2260,1159,0]Ci[3096,13,3097,1810,1444,1827,0,\"impl-Display-for-VarInt\"]Cg[3096,13,3097,1810,1444,1159,0,\"impl-Debug-for-VarInt\"]De[3096,13,3097,1810,4916,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Dg[3096,13,3097,1810,4916,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]Ao[3096,13,3097,3061,1153,1159,0]Db[3096,13,3097,3070,4750,1159,0,\"impl-Debug-for-SendDatagramError\"]Dd[3096,13,3097,3070,4750,1827,0,\"impl-Display-for-SendDatagramError\"]Ci[3096,13,3097,1366,1427,1827,0,\"impl-Display-for-PathId\"]Cg[3096,13,3097,1366,1427,1159,0,\"impl-Debug-for-PathId\"]Ao[3096,13,3097,1366,4110,1159,0]Ao[3096,13,3097,1366,3233,1159,0]Ao[3096,13,3097,1366,3040,1159,0]Ao[3096,13,3097,1366,4748,1159,0]Dc[3096,13,3097,1366,4804,1159,0,\"impl-Debug-for-SetPathStatusError\"]De[3096,13,3097,1366,4804,1827,0,\"impl-Display-for-SetPathStatusError\"]Cm[3096,13,3097,1366,3207,1827,0,\"impl-Display-for-ClosedPath\"]Ck[3096,13,3097,1366,3207,1159,0,\"impl-Debug-for-ClosedPath\"]Ao[3096,13,3097,1382,2295,1159,0]Ao[3096,13,3097,1382,3218,1159,0]Ao[3096,13,3097,1382,3042,1159,0]Ao[3096,13,3097,1382,4449,1159,0]Cj[3096,13,3097,1120,3045,1159,0,\"impl-Debug-for-ReadError\"]Cl[3096,13,3097,1120,3045,1827,0,\"impl-Display-for-ReadError\"]D`[3096,13,3097,1120,4241,1827,0,\"impl-Display-for-ReadableError\"]Cn[3096,13,3097,1120,4241,1159,0,\"impl-Debug-for-ReadableError\"]Ao[3096,13,3097,1125,1868,1159,0]Cm[3096,13,3097,1125,3258,1827,0,\"impl-Display-for-WriteError\"]Ck[3096,13,3097,1125,3258,1159,0,\"impl-Debug-for-WriteError\"]Cn[3096,13,3097,1125,3940,1827,0,\"impl-Display-for-FinishError\"]Cl[3096,13,3097,1125,3940,1159,0,\"impl-Debug-for-FinishError\"]Ao[3096,13,3097,2002,3959,1159,0]Ao[3096,13,3097,2002,4353,1159,0]Co[3096,13,3097,2002,4075,1827,0,\"impl-Display-for-ClosedStream\"]Cm[3096,13,3097,2002,4075,1159,0,\"impl-Debug-for-ClosedStream\"]Db[3096,13,3097,3641,4445,1827,0,\"impl-Display-for-ConnectionError\"]D`[3096,13,3097,3641,4445,1159,0,\"impl-Debug-for-ConnectionError\"]Cl[3096,13,3097,3641,3038,1827,0,\"impl-Display-for-PathError\"]Cj[3096,13,3097,3641,3038,1159,0,\"impl-Debug-for-PathError\"]Da[3096,13,3097,3641,4319,1827,0,\"impl-Display-for-ClosePathError\"]Co[3096,13,3097,3641,4319,1159,0,\"impl-Debug-for-ClosePathError\"]Dg[3096,13,3097,3641,5001,1159,0,\"impl-Debug-for-MultipathNotNegotiated\"]Di[3096,13,3097,3641,5001,1827,0,\"impl-Display-for-MultipathNotNegotiated\"]Ao[3096,13,3097,3641,1174,1159,0]Ao[3096,13,3097,1116,4459,1159,0]Ao[3096,13,3097,3194,4468,1159,0]Ao[3096,13,3097,3194,4774,1159,0]Ao[3096,13,3097,3194,4789,1159,0]Ao[3096,13,3097,3194,3942,1159,0]Ao[3096,13,3097,1691,4329,1159,0]Ao[3096,13,3097,1691,4116,1159,0]Ao[3096,13,3097,1691,4973,1159,0]Ao[3096,13,3097,1691,4067,1159,0]Cl[3096,13,3097,1691,3932,1159,0,\"impl-Debug-for-ConfigError\"]Cn[3096,13,3097,1691,3932,1827,0,\"impl-Display-for-ConfigError\"]Cl[3096,13,3097,1356,3026,1827,0,\"impl-Display-for-FrameType\"]Cj[3096,13,3097,1356,3026,1159,0,\"impl-Debug-for-FrameType\"]Da[3096,13,3097,1356,4334,1827,0,\"impl-Display-for-InvalidFrameId\"]Co[3096,13,3097,1356,4334,1159,0,\"impl-Debug-for-InvalidFrameId\"]Cm[3096,13,3097,1356,3224,1827,0,\"impl-Display-for-MaybeFrame\"]Ck[3096,13,3097,1356,3224,1159,0,\"impl-Debug-for-MaybeFrame\"]Cm[3096,13,3097,1356,3247,1827,0,\"impl-Display-for-StreamInfo\"]Ck[3096,13,3097,1356,3247,1159,0,\"impl-Debug-for-StreamInfo\"]Cm[3096,13,3097,1356,4082,1159,0,\"impl-Debug-for-DatagramInfo\"]Co[3096,13,3097,1356,4082,1827,0,\"impl-Display-for-DatagramInfo\"]Db[3096,13,3097,1356,4443,1827,0,\"impl-Display-for-ConnectionClose\"]D`[3096,13,3097,1356,4443,1159,0,\"impl-Debug-for-ConnectionClose\"]Dc[3096,13,3097,1356,4644,1827,0,\"impl-Display-for-ApplicationClose\"]Da[3096,13,3097,1356,4644,1159,0,\"impl-Debug-for-ApplicationClose\"]Ci[3096,13,3097,1356,2253,1159,0,\"impl-Debug-for-Datagram\"]Ck[3096,13,3097,1356,2253,1827,0,\"impl-Display-for-Datagram\"]Ao[3096,13,3097,2305,4648,1159,0]Ao[3096,13,3097,2305,2264,1159,0]Co[3096,13,3097,2305,4078,1827,0,\"impl-Display-for-ConnectError\"]Cm[3096,13,3097,2305,4078,1159,0,\"impl-Debug-for-ConnectError\"]Ao[3096,13,3097,2305,3926,1159,0]Cm[3096,13,3097,2305,3241,1827,0,\"impl-Display-for-RetryError\"]Ck[3096,13,3097,2305,3241,1159,0,\"impl-Debug-for-RetryError\"]Ao[3096,13,3097,1756,4236,1159,0]Ao[3096,13,3097,1756,4457,1159,0]Ao[3096,13,3097,1756,5005,1159,0]Ao[3096,13,3097,1756,2267,1159,0]Dd[3096,13,3097,1756,4746,1827,0,\"impl-Display-for-PacketDecodeError\"]Db[3096,13,3097,1756,4746,1159,0,\"impl-Debug-for-PacketDecodeError\"]Ao[3096,13,3097,1784,4447,1159,0]Ao[3096,13,3097,1784,4214,1159,0]Co[3096,13,3097,1784,4081,1827,0,\"impl-Display-for-ConnectionId\"]Cm[3096,13,3097,1784,4081,1159,0,\"impl-Debug-for-ConnectionId\"]Ao[3096,13,3097,1784,4086,1159,0]Ce[3096,13,3097,0,4357,1827,0,\"impl-Display-for-Error\"]Cc[3096,13,3097,0,4357,1159,0,\"impl-Debug-for-Error\"]Cd[3096,13,3097,0,4809,1827,0,\"impl-Display-for-Code\"]Cb[3096,13,3097,0,4809,1159,0,\"impl-Debug-for-Code\"]Ao[3096,13,3097,4254,3221,1159,0]Ao[3096,13,3097,4254,5099,1159,0]Ao[3096,13,3097,4844,4676,1159,0]An[3096,13,3097,3097,511,1159,0]Cc[3096,13,3097,3097,127,1159,0,\"impl-Debug-for-Dir\"]Ce[3096,13,3097,3097,127,1827,0,\"impl-Display-for-Dir\"]Ci[3096,13,3097,3097,2282,1159,0,\"impl-Debug-for-StreamId\"]Ck[3096,13,3097,3097,2282,1827,0,\"impl-Display-for-StreamId\"]Ao[3096,13,3097,3097,2292,1159,0]Cl[3096,13,3097,3097,3024,1827,0,\"impl-Display-for-FourTuple\"]Cj[3096,13,3097,3097,3024,1159,0,\"impl-Debug-for-FourTuple\"]Cn[3096,13,1689,1689,4247,1159,0,\"impl-Debug-for-UnexpectedEnd\"]D`[3096,13,1689,1689,4247,1827,0,\"impl-Display-for-UnexpectedEnd\"]Ao[3096,13,4957,4957,4855,1159,0]Ch[3096,13,4957,4957,1171,1827,0,\"impl-Display-for-Error\"]Cf[3096,13,4957,4957,1171,1159,0,\"impl-Debug-for-Error\"]Ao[3096,13,1694,1694,5065,1159,0]Ao[3096,13,1694,1694,3935,1159,0]Ao[3096,13,1694,1694,4815,1159,0]Cc[3096,13,1774,0,1170,1159,0,\"impl-Debug-for-Error\"]Ce[3096,13,1774,0,1170,1827,0,\"impl-Display-for-Error\"]Dg[3096,13,1774,1774,4911,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]De[3096,13,1774,1774,4911,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Am[3096,13,3636,148,121,1159,0]An[3096,13,3636,148,3013,1159,0]Ao[3096,13,3636,1352,1157,1159,0]Ao[3096,13,3636,1352,3937,1159,0]Ao[3096,13,3636,2358,1841,1159,0]Ao[3096,13,3636,2358,4234,1159,0]Ao[3096,13,3636,3636,4738,1159,0]Ch[3096,13,4706,4706,1172,1827,0,\"impl-Display-for-Error\"]Cf[3096,13,4706,4706,1172,1159,0,\"impl-Debug-for-Error\"]Ao[3096,13,4706,4706,1175,1159,0]An[1985,13,1986,416,4358,1159,0]Ao[1985,13,1986,1986,2279,1159,0]Ao[1985,13,1986,1986,2293,1159,0]Ao[1985,13,1986,1986,4087,1159,0]Aj[463,13,464,4142,4912,0,0]Al[3096,13,3097,1366,4110,0,0]Ag[463,14,464,0,2294,0,0]Al[3096,14,3097,1382,2295,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,14,3097,1756,5005,0,0]Ah[3096,14,4456,0,499,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,13,464,0,4972,0,0]Al[3096,13,3097,1691,4973,0,0]8Al[1195,13,1380,1380,4354,0,0]Al[3966,13,3967,3967,5006,0,0]Ag[463,13,464,0,4206,0,0]Aj[463,13,464,2304,2259,0,0]Ag[463,13,464,0,3234,0,0]Ag[463,13,464,0,4458,0,0]Ag[463,13,464,0,4328,0,0]Ag[463,13,464,0,4114,0,0]Ag[463,13,464,0,4065,0,0]Ag[463,13,464,0,4080,0,0]Ag[463,13,464,0,4675,0,0]Ag[463,13,464,0,2281,0,0]Ag[463,13,3635,0,120,0,0]Ah[463,13,3635,0,1156,0,0]Ah[463,13,3635,0,1840,0,0]Al[3096,13,3097,4477,4207,0,0]Al[3096,13,3097,1116,3235,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,1756,5124,0,0]Al[3096,13,3097,4254,5094,0,0]Al[3096,13,3097,1116,4459,0,0]Al[3096,13,3097,1691,4329,0,0]Al[3096,13,3097,1691,4116,0,0]Al[3096,13,3097,1691,4067,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,13,3097,1784,4081,0,0]Ai[3096,13,3097,0,4357,0,0]Al[3096,13,3097,4254,5099,0,0]Al[3096,13,3097,4844,4676,0,0]Al[3096,13,3097,3097,2282,0,0]Al[3096,13,3097,3097,3024,0,0]Aj[3096,13,3636,148,121,0,0]Al[3096,13,3636,1352,1157,0,0]Al[3096,13,3636,2358,1841,0,0]Ak[1985,13,1986,416,4358,0,0]Al[1095,13,4174,4174,5050,0,0]Al[1095,13,4174,4174,5051,0,0]Aa[463,3,0,0,0,0,0]Ah[463,13,464,0,510,133,0]Am[3096,13,3097,3097,511,133,0]Ag[463,12,464,0,3250,0,0]Aj[463,13,464,1994,1852,0,0]0Am[463,13,464,1393,4121,1852,0]Aj[463,13,464,0,4245,3250,0]Al[3096,12,3097,1691,3251,0,0]Ao[3096,13,3097,1691,4246,3251,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1382,3042,0,0]Ae[1095,7,1683,0,0,0,0]Ae[1095,7,1779,0,0,0,0]Ac[463,4,464,0,0,0,0]Ag[463,15,464,0,4085,0,0]Al[3096,15,3097,1784,4086,0,0]Al[1985,15,1986,1986,4087,0,0]210Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Al[3096,15,3097,1756,4457,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1094,0,0,0]Al[3096,15,3097,3641,1174,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Aj[463,15,464,4034,4352,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1366,1427,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Ai[3096,14,3039,0,4100,0,0]Al[1985,14,1986,1986,2279,0,0]Aa[519,3,0,0,0,0,0]Ai[3096,14,3097,0,4357,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Al[3096,14,3097,1356,2253,0,0]Al[463,13,464,3640,2274,487,0]Al[463,13,464,2336,2263,487,0]Ak[463,13,464,1094,503,487,0]Al[463,13,464,1094,4359,487,0]Al[463,13,464,4034,3237,487,0]Al[463,13,464,4039,3243,487,0]An[3096,13,3097,1120,1407,487,0]Am[1195,13,1196,1196,134,494,0]An[1195,13,1196,1196,3952,494,0]An[1195,13,1196,1196,3928,494,0]An[1195,13,1380,1380,3960,494,0]An[1195,13,1380,1380,1189,494,0]An[1195,13,1380,1380,4354,494,0]Ak[519,13,520,520,3929,494,0]An[3966,13,3967,3967,5006,494,0]Al[463,13,464,3640,4472,494,0]Al[463,13,464,3640,2274,494,0]Ai[463,13,464,0,4206,494,0]Al[463,13,464,4142,4912,494,0]Al[463,13,464,1094,2275,494,0]Al[463,13,464,1094,4640,494,0]Al[463,13,464,3640,3209,494,0]Al[463,13,464,3640,3211,494,0]Al[463,13,464,3640,1843,494,0]Al[463,13,464,3640,1419,494,0]Al[463,13,464,3640,3004,494,0]Al[463,13,464,3640,2247,494,0]Al[463,13,464,3640,4106,494,0]Al[463,13,464,3640,4111,494,0]Al[463,13,464,3640,4918,494,0]Al[463,13,464,3640,4749,494,0]0Al[463,13,464,2304,2259,494,0]Al[463,13,464,2304,4215,494,0]Al[463,13,464,2304,1399,494,0]Al[463,13,464,4142,1418,494,0]Al[463,13,464,4142,3231,494,0]Al[463,13,464,4142,4849,494,0]Al[463,13,464,2336,2263,494,0]Al[463,13,464,2336,3240,494,0]Al[463,13,464,2336,4333,494,0]Ak[463,13,464,1094,503,494,0]Al[463,13,464,1094,4359,494,0]Al[463,13,464,4034,3237,494,0]Al[463,13,464,4034,4856,494,0]Al[463,13,464,4034,4352,494,0]0Al[463,13,464,4034,3044,494,0]Df[463,13,464,4034,3044,494,0,\"impl-From%3CResetError%3E-for-ReadError\"]Dk[463,13,464,4034,3044,494,0,\"impl-From%3CConnectionError%3E-for-ReadError\"]Al[463,13,464,4034,3239,494,0]0Al[463,13,464,4034,4351,494,0]0Al[463,13,464,1393,4121,494,0]Al[463,13,464,1137,3955,494,0]Al[463,13,464,4039,3243,494,0]Di[463,13,464,4039,3257,494,0,\"impl-From%3CStoppedError%3E-for-WriteError\"]Di[463,13,464,4039,3257,494,0,\"impl-From%3CClosedStream%3E-for-WriteError\"]Dl[463,13,464,4039,3257,494,0,\"impl-From%3CConnectionError%3E-for-WriteError\"]Al[463,13,464,4039,3257,494,0]Al[463,13,464,4039,4120,494,0]0Al[463,13,464,4039,1857,494,0]Ai[463,13,464,0,3234,494,0]Ai[463,13,464,0,4245,494,0]Ai[463,13,464,0,4464,494,0]Ai[463,13,464,0,4098,494,0]Ai[463,13,464,0,4342,494,0]Dh[463,13,464,0,1443,494,0,\"impl-From%3CTransportErrorCode%3E-for-VarInt\"]Ch[463,13,464,0,1443,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cn[463,13,464,0,1443,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Ai[463,13,464,0,1443,494,0]Ai[463,13,464,0,4915,494,0]Ai[463,13,464,0,1152,494,0]Ai[463,13,464,0,1426,494,0]0Ai[463,13,464,0,2294,494,0]Ai[463,13,464,0,3217,494,0]Ai[463,13,464,0,3041,494,0]Ai[463,13,464,0,4448,494,0]Ai[463,13,464,0,1867,494,0]Ai[463,13,464,0,4071,494,0]Dm[463,13,464,0,4444,494,0,\"impl-From%3CTransportError%3E-for-ConnectionError\"]Dd[463,13,464,0,4444,494,0,\"impl-From%3CClose%3E-for-ConnectionError\"]Ai[463,13,464,0,4444,494,0]Dj[463,13,464,0,4444,494,0,\"impl-From%3CCloseReason%3E-for-ConnectionError\"]Ai[463,13,464,0,4458,494,0]Ai[463,13,464,0,4467,494,0]Ai[463,13,464,0,4773,494,0]Ai[463,13,464,0,4788,494,0]Ai[463,13,464,0,3941,494,0]0Ai[463,13,464,0,4328,494,0]Ai[463,13,464,0,4114,494,0]Ai[463,13,464,0,4972,494,0]Ai[463,13,464,0,4065,494,0]Ai[463,13,464,0,3931,494,0]Do[463,13,464,0,3931,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]Dj[463,13,464,0,3931,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ai[463,13,464,0,3025,494,0]Ai[463,13,464,0,4441,494,0]0Ai[463,13,464,0,4642,494,0]Ai[463,13,464,0,4077,494,0]0Ai[463,13,464,0,4080,494,0]Ai[463,13,464,0,4085,494,0]Ai[463,13,464,0,4808,494,0]0Ai[463,13,464,0,3220,494,0]Ai[463,13,464,0,4675,494,0]Ah[463,13,464,0,510,494,0]Ah[463,13,464,0,126,494,0]Ai[463,13,464,0,2281,494,0]0Ai[463,13,464,0,2291,494,0]Ai[463,13,3635,0,120,494,0]Aj[463,13,3635,0,3012,494,0]Aj[463,13,3635,0,1156,494,0]Aj[463,13,3635,0,3936,494,0]Aj[463,13,3635,0,1840,494,0]Aj[463,13,3635,0,4233,494,0]Aj[463,13,3635,0,4737,494,0]Aj[463,13,1693,0,1835,494,0]Ai[463,13,1693,0,497,494,0]Aj[463,13,1693,0,5064,494,0]Aj[463,13,1693,0,3934,494,0]0Aj[463,13,1693,0,4812,494,0]Aj[463,13,1773,0,3252,494,0]Aj[463,13,1773,0,4217,494,0]Df[463,13,1773,0,1169,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]Dm[463,13,1773,0,1169,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]D`[463,13,1773,0,1169,494,0,\"impl-From%3COtherError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Aj[463,13,1773,0,1169,494,0]Aj[463,13,1773,0,4671,494,0]Aj[463,13,1773,0,4910,494,0]Aj[463,13,1773,0,4673,494,0]Am[2358,13,2359,2359,125,494,0]An[2358,13,2359,2359,2250,494,0]An[3096,13,3097,4477,4207,494,0]An[3096,13,3097,3070,3018,494,0]An[3096,13,3097,1120,1407,494,0]An[3096,13,3097,2002,1861,494,0]An[3096,13,3097,2002,3238,494,0]An[3096,13,3097,2002,3244,494,0]An[3096,13,3097,3641,3212,494,0]An[3096,13,3097,1116,3235,494,0]An[3096,13,3097,1691,4246,494,0]An[3096,13,3097,2305,2260,494,0]An[3096,13,3097,2305,4213,494,0]An[3096,13,3097,2305,4651,494,0]An[3096,13,3097,2305,4224,494,0]An[3096,13,3097,1756,5124,494,0]An[3096,13,3097,4254,5094,494,0]An[3096,13,3097,1392,4465,494,0]An[3096,13,3097,1392,4099,494,0]An[3096,13,3097,1392,4343,494,0]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Dc[3096,13,3097,1810,1444,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cm[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]An[3096,13,3097,1810,1444,494,0]Co[3096,13,3097,1810,1444,494,0,\"impl-From%3CCode%3E-for-VarInt\"]An[3096,13,3097,1810,4916,494,0]An[3096,13,3097,3061,1153,494,0]An[3096,13,3097,3070,4750,494,0]An[3096,13,3097,1366,1427,494,0]0An[3096,13,3097,1366,4110,494,0]An[3096,13,3097,1366,3233,494,0]An[3096,13,3097,1366,3040,494,0]An[3096,13,3097,1366,4748,494,0]An[3096,13,3097,1366,4804,494,0]An[3096,13,3097,1366,3207,494,0]An[3096,13,3097,1382,2295,494,0]An[3096,13,3097,1382,3218,494,0]An[3096,13,3097,1382,3042,494,0]An[3096,13,3097,1382,4449,494,0]An[3096,13,3097,1120,3045,494,0]An[3096,13,3097,1120,4241,494,0]An[3096,13,3097,1125,1868,494,0]An[3096,13,3097,1125,3258,494,0]An[3096,13,3097,1125,3940,494,0]An[3096,13,3097,2002,3959,494,0]An[3096,13,3097,2002,4353,494,0]An[3096,13,3097,2002,4075,494,0]An[3096,13,3097,3641,4445,494,0]0An[3096,13,3097,3641,3038,494,0]An[3096,13,3097,3641,4319,494,0]An[3096,13,3097,3641,5001,494,0]An[3096,13,3097,3641,1174,494,0]0An[3096,13,3097,1116,4459,494,0]An[3096,13,3097,3194,4468,494,0]An[3096,13,3097,3194,4774,494,0]An[3096,13,3097,3194,4789,494,0]An[3096,13,3097,3194,3942,494,0]0An[3096,13,3097,1691,4329,494,0]An[3096,13,3097,1691,4116,494,0]An[3096,13,3097,1691,4973,494,0]An[3096,13,3097,1691,4067,494,0]An[3096,13,3097,1691,3932,494,0]Do[3096,13,3097,1691,3932,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ed[3096,13,3097,1691,3932,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]An[3096,13,3097,1356,3026,494,0]An[3096,13,3097,1356,4334,494,0]An[3096,13,3097,1356,3224,494,0]An[3096,13,3097,1356,3247,494,0]An[3096,13,3097,1356,4082,494,0]An[3096,13,3097,1356,4443,494,0]0An[3096,13,3097,1356,4644,494,0]An[3096,13,3097,1356,2253,494,0]An[3096,13,3097,2305,4648,494,0]An[3096,13,3097,2305,2264,494,0]An[3096,13,3097,2305,4078,494,0]0An[3096,13,3097,2305,3926,494,0]An[3096,13,3097,2305,3241,494,0]An[3096,13,3097,1756,4236,494,0]An[3096,13,3097,1756,4457,494,0]An[3096,13,3097,1756,5005,494,0]An[3096,13,3097,1756,2267,494,0]An[3096,13,3097,1756,4746,494,0]0An[3096,13,3097,1784,4447,494,0]An[3096,13,3097,1784,4214,494,0]An[3096,13,3097,1784,4081,494,0]An[3096,13,3097,1784,4086,494,0]Ak[3096,13,3097,0,4357,494,0]0Ak[3096,13,3097,0,4809,494,0]0An[3096,13,3097,4254,3221,494,0]An[3096,13,3097,4254,5099,494,0]An[3096,13,3097,4844,4676,494,0]Am[3096,13,3097,3097,511,494,0]Am[3096,13,3097,3097,127,494,0]An[3096,13,3097,3097,2282,494,0]0An[3096,13,3097,3097,2292,494,0]An[3096,13,3097,3097,3024,494,0]An[3096,13,1689,1689,4247,494,0]An[3096,13,4957,4957,4855,494,0]An[3096,13,4957,4957,1171,494,0]0An[3096,13,1694,1694,1836,494,0]Am[3096,13,1694,1694,498,494,0]An[3096,13,1694,1694,5065,494,0]An[3096,13,1694,1694,3935,494,0]0An[3096,13,1694,1694,4815,494,0]An[3096,13,1774,1774,3253,494,0]An[3096,13,1774,1774,4218,494,0]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Da[3096,13,1774,0,1170,494,0,\"impl-From%3COtherError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Ak[3096,13,1774,0,1170,494,0]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dn[3096,13,1774,0,1170,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]An[3096,13,1774,1774,4672,494,0]An[3096,13,1774,1774,4911,494,0]An[3096,13,1774,1774,4674,494,0]Al[3096,13,3636,148,121,494,0]Am[3096,13,3636,148,3013,494,0]An[3096,13,3636,1352,1157,494,0]An[3096,13,3636,1352,3937,494,0]An[3096,13,3636,2358,1841,494,0]An[3096,13,3636,2358,4234,494,0]An[3096,13,3636,3636,4738,494,0]An[3096,13,4706,4706,1172,494,0]An[3096,13,4706,4706,1175,494,0]An[1985,13,1986,1986,3256,494,0]0Am[1985,13,1986,416,4358,494,0]An[1985,13,1986,1986,2279,494,0]An[1985,13,1986,1986,2293,494,0]An[1985,13,1986,1986,4087,494,0]An[1095,13,1096,1096,3015,494,0]An[1095,13,1096,1096,4848,494,0]Am[1095,13,1683,1683,135,494,0]An[1095,13,1381,1381,1190,494,0]An[1095,13,1381,1381,3961,494,0]An[1095,13,1381,1381,4453,494,0]An[1095,13,4174,4174,5050,494,0]An[1095,13,4174,4174,5051,494,0]Am[1095,13,1779,1779,136,494,0]Ai[463,13,464,0,1443,495,0]Ai[463,13,464,0,1426,495,0]Ai[463,13,464,0,3941,495,0]Ai[463,13,464,0,4080,495,0]Ah[463,13,464,0,510,495,0]Ah[463,13,464,0,126,495,0]Ai[463,13,464,0,2281,495,0]An[3096,13,3097,1810,1444,495,0]An[3096,13,3097,3070,4750,495,0]An[3096,13,3097,1366,1427,495,0]An[3096,13,3097,1120,3045,495,0]An[3096,13,3097,1120,4241,495,0]An[3096,13,3097,1125,3258,495,0]An[3096,13,3097,3194,3942,495,0]An[3096,13,3097,2305,4648,495,0]An[3096,13,3097,1756,4746,495,0]An[3096,13,3097,1784,4081,495,0]Am[3096,13,3097,3097,511,495,0]Am[3096,13,3097,3097,127,495,0]An[3096,13,3097,3097,2282,495,0]An[3096,13,3097,3097,3024,495,0]Am[1195,13,1196,1196,134,496,0]An[1195,13,1196,1196,3952,496,0]An[1195,13,1196,1196,3928,496,0]An[1195,13,1380,1380,3960,496,0]An[1195,13,1380,1380,1189,496,0]An[1195,13,1380,1380,4354,496,0]Ak[519,13,520,520,3929,496,0]An[3966,13,3967,3967,5006,496,0]Al[463,13,464,3640,4472,496,0]Al[463,13,464,3640,2274,496,0]Ai[463,13,464,0,4206,496,0]Al[463,13,464,4142,4912,496,0]Al[463,13,464,1094,2275,496,0]Al[463,13,464,1094,4640,496,0]Al[463,13,464,3640,3209,496,0]Al[463,13,464,3640,3211,496,0]Al[463,13,464,3640,1843,496,0]Al[463,13,464,3640,1419,496,0]Al[463,13,464,3640,3004,496,0]Al[463,13,464,3640,2247,496,0]Al[463,13,464,3640,4106,496,0]Al[463,13,464,3640,4111,496,0]Al[463,13,464,3640,4918,496,0]Al[463,13,464,3640,4749,496,0]Al[463,13,464,2304,2259,496,0]Al[463,13,464,2304,4215,496,0]Al[463,13,464,2304,1399,496,0]Al[463,13,464,4142,1418,496,0]Al[463,13,464,4142,3231,496,0]Al[463,13,464,4142,4849,496,0]Al[463,13,464,2336,2263,496,0]Al[463,13,464,2336,3240,496,0]Al[463,13,464,2336,4333,496,0]Ak[463,13,464,1094,503,496,0]Al[463,13,464,1094,4359,496,0]Al[463,13,464,4034,3237,496,0]Al[463,13,464,4034,4856,496,0]Al[463,13,464,4034,4352,496,0]Al[463,13,464,4034,3044,496,0]Al[463,13,464,4034,3239,496,0]Al[463,13,464,4034,4351,496,0]Al[463,13,464,1393,4121,496,0]Al[463,13,464,1137,3955,496,0]Al[463,13,464,4039,3243,496,0]Al[463,13,464,4039,3257,496,0]Al[463,13,464,4039,4120,496,0]Al[463,13,464,4039,1857,496,0]Ai[463,13,464,0,3234,496,0]Ai[463,13,464,0,4245,496,0]Ai[463,13,464,0,4464,496,0]Ai[463,13,464,0,4098,496,0]Ai[463,13,464,0,4342,496,0]Ai[463,13,464,0,1443,496,0]Ai[463,13,464,0,4915,496,0]Ai[463,13,464,0,1152,496,0]Ai[463,13,464,0,1426,496,0]Ai[463,13,464,0,2294,496,0]Ai[463,13,464,0,3217,496,0]Ai[463,13,464,0,3041,496,0]Ai[463,13,464,0,4448,496,0]Ai[463,13,464,0,1867,496,0]Ai[463,13,464,0,4071,496,0]Ai[463,13,464,0,4444,496,0]Ai[463,13,464,0,4458,496,0]Ai[463,13,464,0,4467,496,0]Ai[463,13,464,0,4773,496,0]Ai[463,13,464,0,4788,496,0]Ai[463,13,464,0,3941,496,0]Ai[463,13,464,0,4328,496,0]Ai[463,13,464,0,4114,496,0]Ai[463,13,464,0,4972,496,0]Ai[463,13,464,0,4065,496,0]Ai[463,13,464,0,3931,496,0]Ai[463,13,464,0,3025,496,0]Ai[463,13,464,0,4441,496,0]Ai[463,13,464,0,4642,496,0]Ai[463,13,464,0,4077,496,0]Ai[463,13,464,0,4080,496,0]Ai[463,13,464,0,4085,496,0]Ai[463,13,464,0,4808,496,0]Ai[463,13,464,0,3220,496,0]Ai[463,13,464,0,4675,496,0]Ah[463,13,464,0,510,496,0]Ah[463,13,464,0,126,496,0]Ai[463,13,464,0,2281,496,0]Ai[463,13,464,0,2291,496,0]Ai[463,13,3635,0,120,496,0]Aj[463,13,3635,0,3012,496,0]Aj[463,13,3635,0,1156,496,0]Aj[463,13,3635,0,3936,496,0]Aj[463,13,3635,0,1840,496,0]Aj[463,13,3635,0,4233,496,0]Aj[463,13,3635,0,4737,496,0]Aj[463,13,1693,0,1835,496,0]Ai[463,13,1693,0,497,496,0]Aj[463,13,1693,0,5064,496,0]Aj[463,13,1693,0,3934,496,0]Aj[463,13,1693,0,4812,496,0]Aj[463,13,1773,0,3252,496,0]Aj[463,13,1773,0,4217,496,0]Aj[463,13,1773,0,1169,496,0]Aj[463,13,1773,0,4671,496,0]Aj[463,13,1773,0,4910,496,0]Aj[463,13,1773,0,4673,496,0]Am[2358,13,2359,2359,125,496,0]An[2358,13,2359,2359,2250,496,0]An[3096,13,3097,4477,4207,496,0]An[3096,13,3097,3070,3018,496,0]An[3096,13,3097,1120,1407,496,0]An[3096,13,3097,2002,1861,496,0]An[3096,13,3097,2002,3238,496,0]An[3096,13,3097,2002,3244,496,0]An[3096,13,3097,3641,3212,496,0]An[3096,13,3097,1116,3235,496,0]An[3096,13,3097,1691,4246,496,0]An[3096,13,3097,2305,2260,496,0]An[3096,13,3097,2305,4213,496,0]An[3096,13,3097,2305,4651,496,0]An[3096,13,3097,2305,4224,496,0]An[3096,13,3097,1756,5124,496,0]An[3096,13,3097,4254,5094,496,0]An[3096,13,3097,1392,4465,496,0]An[3096,13,3097,1392,4099,496,0]An[3096,13,3097,1392,4343,496,0]An[3096,13,3097,1810,1444,496,0]An[3096,13,3097,1810,4916,496,0]An[3096,13,3097,3061,1153,496,0]An[3096,13,3097,3070,4750,496,0]An[3096,13,3097,1366,1427,496,0]An[3096,13,3097,1366,4110,496,0]An[3096,13,3097,1366,3233,496,0]An[3096,13,3097,1366,3040,496,0]An[3096,13,3097,1366,4748,496,0]An[3096,13,3097,1366,4804,496,0]An[3096,13,3097,1366,3207,496,0]An[3096,13,3097,1382,2295,496,0]An[3096,13,3097,1382,3218,496,0]An[3096,13,3097,1382,3042,496,0]An[3096,13,3097,1382,4449,496,0]An[3096,13,3097,1120,3045,496,0]An[3096,13,3097,1120,4241,496,0]An[3096,13,3097,1125,1868,496,0]An[3096,13,3097,1125,3258,496,0]An[3096,13,3097,1125,3940,496,0]An[3096,13,3097,2002,3959,496,0]An[3096,13,3097,2002,4353,496,0]An[3096,13,3097,2002,4075,496,0]An[3096,13,3097,3641,4445,496,0]An[3096,13,3097,3641,3038,496,0]An[3096,13,3097,3641,4319,496,0]An[3096,13,3097,3641,5001,496,0]An[3096,13,3097,3641,1174,496,0]An[3096,13,3097,1116,4459,496,0]An[3096,13,3097,3194,4468,496,0]An[3096,13,3097,3194,4774,496,0]An[3096,13,3097,3194,4789,496,0]An[3096,13,3097,3194,3942,496,0]An[3096,13,3097,1691,4329,496,0]An[3096,13,3097,1691,4116,496,0]An[3096,13,3097,1691,4973,496,0]An[3096,13,3097,1691,4067,496,0]An[3096,13,3097,1691,3932,496,0]An[3096,13,3097,1356,3026,496,0]An[3096,13,3097,1356,4334,496,0]An[3096,13,3097,1356,3224,496,0]An[3096,13,3097,1356,3247,496,0]An[3096,13,3097,1356,4082,496,0]An[3096,13,3097,1356,4443,496,0]An[3096,13,3097,1356,4644,496,0]An[3096,13,3097,1356,2253,496,0]An[3096,13,3097,2305,4648,496,0]An[3096,13,3097,2305,2264,496,0]An[3096,13,3097,2305,4078,496,0]An[3096,13,3097,2305,3926,496,0]An[3096,13,3097,2305,3241,496,0]An[3096,13,3097,1756,4236,496,0]An[3096,13,3097,1756,4457,496,0]An[3096,13,3097,1756,5005,496,0]An[3096,13,3097,1756,2267,496,0]An[3096,13,3097,1756,4746,496,0]An[3096,13,3097,1784,4447,496,0]An[3096,13,3097,1784,4214,496,0]An[3096,13,3097,1784,4081,496,0]An[3096,13,3097,1784,4086,496,0]Ak[3096,13,3097,0,4357,496,0]Ak[3096,13,3097,0,4809,496,0]An[3096,13,3097,4254,3221,496,0]An[3096,13,3097,4254,5099,496,0]An[3096,13,3097,4844,4676,496,0]Am[3096,13,3097,3097,511,496,0]Am[3096,13,3097,3097,127,496,0]An[3096,13,3097,3097,2282,496,0]An[3096,13,3097,3097,2292,496,0]An[3096,13,3097,3097,3024,496,0]An[3096,13,1689,1689,4247,496,0]An[3096,13,4957,4957,4855,496,0]An[3096,13,4957,4957,1171,496,0]An[3096,13,1694,1694,1836,496,0]Am[3096,13,1694,1694,498,496,0]An[3096,13,1694,1694,5065,496,0]An[3096,13,1694,1694,3935,496,0]An[3096,13,1694,1694,4815,496,0]An[3096,13,1774,1774,3253,496,0]An[3096,13,1774,1774,4218,496,0]Ak[3096,13,1774,0,1170,496,0]An[3096,13,1774,1774,4672,496,0]An[3096,13,1774,1774,4911,496,0]An[3096,13,1774,1774,4674,496,0]Al[3096,13,3636,148,121,496,0]Am[3096,13,3636,148,3013,496,0]An[3096,13,3636,1352,1157,496,0]An[3096,13,3636,1352,3937,496,0]An[3096,13,3636,2358,1841,496,0]An[3096,13,3636,2358,4234,496,0]An[3096,13,3636,3636,4738,496,0]An[3096,13,4706,4706,1172,496,0]An[3096,13,4706,4706,1175,496,0]An[1985,13,1986,1986,3256,496,0]Am[1985,13,1986,416,4358,496,0]An[1985,13,1986,1986,2279,496,0]An[1985,13,1986,1986,2293,496,0]An[1985,13,1986,1986,4087,496,0]An[1095,13,1096,1096,3015,496,0]An[1095,13,1096,1096,4848,496,0]Am[1095,13,1683,1683,135,496,0]An[1095,13,1381,1381,1190,496,0]An[1095,13,1381,1381,3961,496,0]An[1095,13,1381,1381,4453,496,0]An[1095,13,4174,4174,5050,496,0]An[1095,13,4174,4174,5051,496,0]Am[1095,13,1779,1779,136,496,0]Ac[519,7,520,0,0,0,0]Ae[3966,7,3967,0,0,0,0]Ae[4257,7,4258,0,0,0,0]Ae[2358,7,2359,0,0,0,0]Ae[4768,7,4769,0,0,0,0]Al[3096,13,3097,1120,1407,0,0]Ao[3096,13,3097,2305,4224,2265,0]Ah[463,12,1693,0,4739,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,12,1694,1694,4740,0,0]Aj[463,13,464,3640,3211,0,0]Ab[1095,3,0,0,0,0,0]Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1382,3218,0,0]Aj[463,12,464,1994,3200,0,0]Am[463,13,464,3640,4472,1415,0]Am[463,13,464,3640,2274,1415,0]Am[463,13,464,1094,2275,1415,0]Am[463,13,464,3640,3209,1415,0]Am[463,13,464,3640,1843,1415,0]Am[463,13,464,3640,1419,1415,0]Am[463,13,464,3640,3004,1415,0]Am[463,13,464,3640,2247,1415,0]Am[463,13,464,3640,4106,1415,0]Am[463,13,464,3640,4111,1415,0]Am[463,13,464,2304,1399,1415,0]Am[463,13,464,2336,4333,1415,0]Am[463,13,464,4039,1857,1415,0]?Aj[463,13,464,4034,3237,0,0]Al[3096,13,3097,2002,3238,0,0]Al[3096,13,4957,4957,4855,0,0]Al[3096,13,3097,3070,3018,0,0]Ak[1985,13,1986,416,4358,0,0]Ah[463,12,1693,0,4739,0,0]Al[3096,12,1694,1694,4740,0,0]32Ag[463,13,464,0,4972,0,0]Al[3096,13,3097,1691,4973,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Al[1195,14,1380,1380,4354,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Ai[3096,14,4456,0,1186,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Al[3096,13,3097,2002,3238,0,0]Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4342,3254,0]Aj[463,13,464,0,4675,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4343,3255,0]Ao[3096,13,3097,4844,4676,3255,0]Af[463,5,464,3061,0,0,0]Ah[3096,5,3097,3061,0,0,0]Ag[463,5,3635,1352,0,0,0]Ah[3096,5,3636,1352,0,0,0]Al[1095,15,1096,1096,4848,0,0]Ag[463,6,1773,1355,0,0,0]Ah[3096,6,1774,1355,0,0,0]Ae[3096,6,4957,0,0,0,0]Ae[3096,6,4706,0,0,0,0]Ah[3096,6,3097,3641,0,0,0]1Al[3096,15,3097,1356,3224,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Aj[463,15,464,4034,3044,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,3641,4445,0,0]Al[3096,15,3097,1756,4457,0,0]0Ae[1195,5,1380,0,0,0,0]Ae[1095,5,1381,0,0,0,0]Al[1195,15,1196,1196,3952,0,0]Al[3096,13,3097,2305,4651,0,0]Ab[1195,3,0,0,0,0,0]Ah[463,12,3635,0,4735,0,0]Ak[463,13,3635,0,3012,4735,0]Ak[463,13,3635,0,3936,4735,0]Ak[463,13,3635,0,4233,4735,0]Al[3096,12,3636,3636,4736,0,0]An[3096,13,3636,148,3013,4736,0]Ao[3096,13,3636,1352,3937,4736,0]Ao[3096,13,3636,2358,4234,4736,0]Al[1095,13,1096,1096,4848,0,0]Ag[463,14,464,0,1152,0,0]Ag[463,14,464,0,2294,0,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,3061,1153,0,0]Al[3096,14,3097,1382,2295,0,0]Al[3096,14,3097,1125,1868,0,0]Al[3096,14,3097,2305,3926,0,0]An[1195,13,1196,1196,134,1154,0]Ao[1195,13,1196,1196,3952,1154,0]Ao[1195,13,1196,1196,3928,1154,0]Am[463,13,464,3640,3211,1154,0]Am[463,13,464,3640,4918,1154,0]Am[463,13,464,3640,4749,1154,0]Am[463,13,464,2304,2259,1154,0]Am[463,13,464,2304,4215,1154,0]Am[463,13,464,4142,1418,1154,0]Al[463,13,464,1094,503,1154,0]Am[463,13,464,1094,4359,1154,0]Am[463,13,464,4034,4352,1154,0]Am[463,13,464,4034,3044,1154,0]Am[463,13,464,4034,3239,1154,0]Am[463,13,464,4034,4351,1154,0]Am[463,13,464,4039,3257,1154,0]Am[463,13,464,4039,4120,1154,0]Aj[463,13,464,0,1443,1154,0]Aj[463,13,464,0,4915,1154,0]Aj[463,13,464,0,1426,1154,0]Aj[463,13,464,0,2294,1154,0]Aj[463,13,464,0,3217,1154,0]Aj[463,13,464,0,3041,1154,0]Aj[463,13,464,0,4448,1154,0]Aj[463,13,464,0,1867,1154,0]Aj[463,13,464,0,4071,1154,0]Aj[463,13,464,0,4444,1154,0]Aj[463,13,464,0,4467,1154,0]Aj[463,13,464,0,4773,1154,0]Aj[463,13,464,0,4788,1154,0]Aj[463,13,464,0,3941,1154,0]Aj[463,13,464,0,4328,1154,0]Aj[463,13,464,0,4114,1154,0]Aj[463,13,464,0,4972,1154,0]Aj[463,13,464,0,4065,1154,0]Aj[463,13,464,0,3931,1154,0]Aj[463,13,464,0,3025,1154,0]Aj[463,13,464,0,4441,1154,0]Aj[463,13,464,0,4642,1154,0]Aj[463,13,464,0,4077,1154,0]Aj[463,13,464,0,4080,1154,0]Aj[463,13,464,0,4085,1154,0]Aj[463,13,464,0,4808,1154,0]Aj[463,13,464,0,3220,1154,0]Ai[463,13,464,0,510,1154,0]Ai[463,13,464,0,126,1154,0]Aj[463,13,464,0,2281,1154,0]Aj[463,13,3635,0,120,1154,0]Ak[463,13,3635,0,3012,1154,0]Ak[463,13,3635,0,1156,1154,0]Ak[463,13,3635,0,3936,1154,0]Ak[463,13,3635,0,1840,1154,0]Ak[463,13,3635,0,4233,1154,0]Ak[463,13,1773,0,1169,1154,0]Ak[463,13,1773,0,4671,1154,0]Ak[463,13,1773,0,4910,1154,0]Ak[463,13,1773,0,4673,1154,0]Ao[3096,13,3097,1810,1444,1154,0]Ao[3096,13,3097,1810,4916,1154,0]Ao[3096,13,3097,3070,4750,1154,0]Ao[3096,13,3097,1366,1427,1154,0]Ao[3096,13,3097,1366,4110,1154,0]Ao[3096,13,3097,1366,3233,1154,0]Ao[3096,13,3097,1366,3040,1154,0]Ao[3096,13,3097,1366,4748,1154,0]Ao[3096,13,3097,1366,4804,1154,0]Ao[3096,13,3097,1366,3207,1154,0]Ao[3096,13,3097,1382,2295,1154,0]Ao[3096,13,3097,1382,3218,1154,0]Ao[3096,13,3097,1382,3042,1154,0]Ao[3096,13,3097,1382,4449,1154,0]Ao[3096,13,3097,1120,3045,1154,0]Ao[3096,13,3097,1120,4241,1154,0]Ao[3096,13,3097,1125,1868,1154,0]Ao[3096,13,3097,1125,3258,1154,0]Ao[3096,13,3097,1125,3940,1154,0]Ao[3096,13,3097,2002,4353,1154,0]Ao[3096,13,3097,2002,4075,1154,0]Ao[3096,13,3097,3641,4445,1154,0]Ao[3096,13,3097,3641,3038,1154,0]Ao[3096,13,3097,3641,4319,1154,0]Ao[3096,13,3097,3641,5001,1154,0]Ao[3096,13,3097,3194,4468,1154,0]Ao[3096,13,3097,3194,4774,1154,0]Ao[3096,13,3097,3194,4789,1154,0]Ao[3096,13,3097,3194,3942,1154,0]Ao[3096,13,3097,1691,4329,1154,0]Ao[3096,13,3097,1691,4116,1154,0]Ao[3096,13,3097,1691,4973,1154,0]Ao[3096,13,3097,1691,4067,1154,0]Ao[3096,13,3097,1691,3932,1154,0]Ao[3096,13,3097,1356,3026,1154,0]Ao[3096,13,3097,1356,3224,1154,0]Ao[3096,13,3097,1356,3247,1154,0]Ao[3096,13,3097,1356,4082,1154,0]Ao[3096,13,3097,1356,4443,1154,0]Ao[3096,13,3097,1356,4644,1154,0]Ao[3096,13,3097,1356,2253,1154,0]Ao[3096,13,3097,2305,4648,1154,0]Ao[3096,13,3097,2305,4078,1154,0]Ao[3096,13,3097,1756,4457,1154,0]Ao[3096,13,3097,1756,5005,1154,0]Ao[3096,13,3097,1756,2267,1154,0]Ao[3096,13,3097,1756,4746,1154,0]Ao[3096,13,3097,1784,4081,1154,0]Ao[3096,13,3097,1784,4086,1154,0]Al[3096,13,3097,0,4357,1154,0]Al[3096,13,3097,0,4809,1154,0]Ao[3096,13,3097,4254,3221,1154,0]Ao[3096,13,3097,4254,5099,1154,0]An[3096,13,3097,3097,511,1154,0]An[3096,13,3097,3097,127,1154,0]Ao[3096,13,3097,3097,2282,1154,0]Ao[3096,13,3097,3097,3024,1154,0]Ao[3096,13,1689,1689,4247,1154,0]Ao[3096,13,4957,4957,4855,1154,0]Ao[3096,13,4957,4957,1171,1154,0]Al[3096,13,1774,0,1170,1154,0]Ao[3096,13,1774,1774,4672,1154,0]Ao[3096,13,1774,1774,4911,1154,0]Ao[3096,13,1774,1774,4674,1154,0]Am[3096,13,3636,148,121,1154,0]An[3096,13,3636,148,3013,1154,0]Ao[3096,13,3636,1352,1157,1154,0]Ao[3096,13,3636,1352,3937,1154,0]Ao[3096,13,3636,2358,1841,1154,0]Ao[3096,13,3636,2358,4234,1154,0]Ao[3096,13,4706,4706,1175,1154,0]Ao[1985,13,1986,1986,2279,1154,0]Ao[1985,13,1986,1986,2293,1154,0]Ao[1985,13,1986,1986,4087,1154,0]Ao[1095,13,1096,1096,4848,1154,0]Ao[1095,13,1381,1381,4453,1154,0]Ao[1095,13,4174,4174,5050,1154,0]Ao[1095,13,4174,4174,5051,1154,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,0,4080,1160,0]Ao[3096,13,3097,1784,4081,1160,0]Ai[3096,14,3097,0,4357,0,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ag[463,13,464,0,4085,0,0]Al[3096,13,3097,1784,4086,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,14,1694,1694,1836,0,0]Al[3096,12,3097,1756,4779,0,0]Ao[3096,13,3097,1756,5124,4779,0];Al[1195,13,1380,1380,1189,0,0]Ai[519,13,520,520,3929,0,0]Al[1095,13,1381,1381,1190,0,0]Aj[463,12,464,1994,3200,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4121,1852,0]Am[463,13,464,1137,3955,1852,0]Ae[1195,2,1196,0,0,0,0]Ak[1195,14,1196,1196,134,0,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Ae[1095,2,1096,0,0,0,0]Ag[463,13,464,0,3234,0,0]Al[3096,13,3097,1116,3235,0,0]?>Al[3096,13,4957,4957,4855,0,0]Af[463,5,464,2304,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Al[1195,15,1196,1196,3928,0,0]0Al[3096,15,3097,1366,3233,0,0]Ah[3096,5,3097,1120,0,0,0]Af[463,15,464,0,510,0,0]Al[2358,15,2359,2359,2250,0,0]Ak[3096,15,3097,3097,511,0,0]Al[3096,15,4706,4706,1172,0,0]87Af[463,5,464,4142,0,0,0]Af[463,5,464,3640,0,0,0]Al[3096,15,3097,1366,3040,0,0]Al[3096,15,3097,2002,3959,0,0]Af[463,5,464,1366,0,0,0]Ah[3096,5,3097,1366,0,0,0]Ae[3096,8,1689,0,0,0,0]:98?Al[3096,15,3097,3641,1174,0,0]?Af[463,5,464,1810,0,0,0]Ah[3096,5,3097,1810,0,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,2305,2260,0,0]An[1195,13,1196,1196,134,1405,0]Ao[1195,13,1196,1196,3952,1405,0]Ao[1195,13,1196,1196,3928,1405,0]Ao[1195,13,1380,1380,3960,1405,0]Ao[1195,13,1380,1380,1189,1405,0]Ao[1195,13,1380,1380,4354,1405,0]Al[519,13,520,520,3929,1405,0]Ao[3966,13,3967,3967,5006,1405,0]Am[463,13,464,3640,4472,1405,0]Am[463,13,464,3640,2274,1405,0]Aj[463,13,464,0,4206,1405,0]Am[463,13,464,4142,4912,1405,0]Am[463,13,464,1094,2275,1405,0]Am[463,13,464,1094,4640,1405,0]Am[463,13,464,3640,3209,1405,0]Am[463,13,464,3640,3211,1405,0]Am[463,13,464,3640,1843,1405,0]Am[463,13,464,3640,1419,1405,0]Am[463,13,464,3640,3004,1405,0]Am[463,13,464,3640,2247,1405,0]Am[463,13,464,3640,4106,1405,0]Am[463,13,464,3640,4111,1405,0]Am[463,13,464,3640,4918,1405,0]Am[463,13,464,3640,4749,1405,0]Am[463,13,464,2304,2259,1405,0]Am[463,13,464,2304,4215,1405,0]Am[463,13,464,2304,1399,1405,0]Am[463,13,464,4142,1418,1405,0]Am[463,13,464,4142,3231,1405,0]Am[463,13,464,4142,4849,1405,0]Am[463,13,464,2336,2263,1405,0]Am[463,13,464,2336,3240,1405,0]Am[463,13,464,2336,4333,1405,0]Al[463,13,464,1094,503,1405,0]Am[463,13,464,1094,4359,1405,0]Am[463,13,464,4034,3237,1405,0]Am[463,13,464,4034,4856,1405,0]Am[463,13,464,4034,4352,1405,0]Am[463,13,464,4034,3044,1405,0]Am[463,13,464,4034,3239,1405,0]Am[463,13,464,4034,4351,1405,0]Am[463,13,464,1393,4121,1405,0]Am[463,13,464,1137,3955,1405,0]Am[463,13,464,4039,3243,1405,0]Am[463,13,464,4039,3257,1405,0]Am[463,13,464,4039,4120,1405,0]Am[463,13,464,4039,1857,1405,0]Aj[463,13,464,0,3234,1405,0]Aj[463,13,464,0,4245,1405,0]Aj[463,13,464,0,4464,1405,0]Aj[463,13,464,0,4098,1405,0]Aj[463,13,464,0,4342,1405,0]Aj[463,13,464,0,1443,1405,0]Aj[463,13,464,0,4915,1405,0]Aj[463,13,464,0,1152,1405,0]Aj[463,13,464,0,1426,1405,0]Aj[463,13,464,0,2294,1405,0]Aj[463,13,464,0,3217,1405,0]Aj[463,13,464,0,3041,1405,0]Aj[463,13,464,0,4448,1405,0]Aj[463,13,464,0,1867,1405,0]Aj[463,13,464,0,4071,1405,0]Aj[463,13,464,0,4444,1405,0]Aj[463,13,464,0,4458,1405,0]Aj[463,13,464,0,4467,1405,0]Aj[463,13,464,0,4773,1405,0]Aj[463,13,464,0,4788,1405,0]Aj[463,13,464,0,3941,1405,0]Aj[463,13,464,0,4328,1405,0]Aj[463,13,464,0,4114,1405,0]Aj[463,13,464,0,4972,1405,0]Aj[463,13,464,0,4065,1405,0]Aj[463,13,464,0,3931,1405,0]Aj[463,13,464,0,3025,1405,0]Aj[463,13,464,0,4441,1405,0]Aj[463,13,464,0,4642,1405,0]Aj[463,13,464,0,4077,1405,0]Aj[463,13,464,0,4080,1405,0]Aj[463,13,464,0,4085,1405,0]Aj[463,13,464,0,4808,1405,0]Aj[463,13,464,0,3220,1405,0]Aj[463,13,464,0,4675,1405,0]Ai[463,13,464,0,510,1405,0]Ai[463,13,464,0,126,1405,0]Aj[463,13,464,0,2281,1405,0]Aj[463,13,464,0,2291,1405,0]Aj[463,13,3635,0,120,1405,0]Ak[463,13,3635,0,3012,1405,0]Ak[463,13,3635,0,1156,1405,0]Ak[463,13,3635,0,3936,1405,0]Ak[463,13,3635,0,1840,1405,0]Ak[463,13,3635,0,4233,1405,0]Ak[463,13,3635,0,4737,1405,0]Ak[463,13,1693,0,1835,1405,0]Aj[463,13,1693,0,497,1405,0]Ak[463,13,1693,0,5064,1405,0]Ak[463,13,1693,0,3934,1405,0]Ak[463,13,1693,0,4812,1405,0]Ak[463,13,1773,0,3252,1405,0]Ak[463,13,1773,0,4217,1405,0]Ak[463,13,1773,0,1169,1405,0]Ak[463,13,1773,0,4671,1405,0]Ak[463,13,1773,0,4910,1405,0]Ak[463,13,1773,0,4673,1405,0]An[2358,13,2359,2359,125,1405,0]Ao[2358,13,2359,2359,2250,1405,0]Ao[3096,13,3097,4477,4207,1405,0]Ao[3096,13,3097,3070,3018,1405,0]Ao[3096,13,3097,1120,1407,1405,0]Ao[3096,13,3097,2002,1861,1405,0]Ao[3096,13,3097,2002,3238,1405,0]Ao[3096,13,3097,2002,3244,1405,0]Ao[3096,13,3097,3641,3212,1405,0]Ao[3096,13,3097,1116,3235,1405,0]Ao[3096,13,3097,1691,4246,1405,0]Ao[3096,13,3097,2305,2260,1405,0]Ao[3096,13,3097,2305,4213,1405,0]Ao[3096,13,3097,2305,4651,1405,0]Ao[3096,13,3097,2305,4224,1405,0]Ao[3096,13,3097,1756,5124,1405,0]Ao[3096,13,3097,4254,5094,1405,0]Ao[3096,13,3097,1392,4465,1405,0]Ao[3096,13,3097,1392,4099,1405,0]Ao[3096,13,3097,1392,4343,1405,0]Ao[3096,13,3097,1810,1444,1405,0]Ao[3096,13,3097,1810,4916,1405,0]Ao[3096,13,3097,3061,1153,1405,0]Ao[3096,13,3097,3070,4750,1405,0]Ao[3096,13,3097,1366,1427,1405,0]Ao[3096,13,3097,1366,4110,1405,0]Ao[3096,13,3097,1366,3233,1405,0]Ao[3096,13,3097,1366,3040,1405,0]Ao[3096,13,3097,1366,4748,1405,0]Ao[3096,13,3097,1366,4804,1405,0]Ao[3096,13,3097,1366,3207,1405,0]Ao[3096,13,3097,1382,2295,1405,0]Ao[3096,13,3097,1382,3218,1405,0]Ao[3096,13,3097,1382,3042,1405,0]Ao[3096,13,3097,1382,4449,1405,0]Ao[3096,13,3097,1120,3045,1405,0]Ao[3096,13,3097,1120,4241,1405,0]Ao[3096,13,3097,1125,1868,1405,0]Ao[3096,13,3097,1125,3258,1405,0]Ao[3096,13,3097,1125,3940,1405,0]Ao[3096,13,3097,2002,3959,1405,0]Ao[3096,13,3097,2002,4353,1405,0]Ao[3096,13,3097,2002,4075,1405,0]Ao[3096,13,3097,3641,4445,1405,0]Ao[3096,13,3097,3641,3038,1405,0]Ao[3096,13,3097,3641,4319,1405,0]Ao[3096,13,3097,3641,5001,1405,0]Ao[3096,13,3097,3641,1174,1405,0]Ao[3096,13,3097,1116,4459,1405,0]Ao[3096,13,3097,3194,4468,1405,0]Ao[3096,13,3097,3194,4774,1405,0]Ao[3096,13,3097,3194,4789,1405,0]Ao[3096,13,3097,3194,3942,1405,0]Ao[3096,13,3097,1691,4329,1405,0]Ao[3096,13,3097,1691,4116,1405,0]Ao[3096,13,3097,1691,4973,1405,0]Ao[3096,13,3097,1691,4067,1405,0]Ao[3096,13,3097,1691,3932,1405,0]Ao[3096,13,3097,1356,3026,1405,0]Ao[3096,13,3097,1356,4334,1405,0]Ao[3096,13,3097,1356,3224,1405,0]Ao[3096,13,3097,1356,3247,1405,0]Ao[3096,13,3097,1356,4082,1405,0]Ao[3096,13,3097,1356,4443,1405,0]Ao[3096,13,3097,1356,4644,1405,0]Ao[3096,13,3097,1356,2253,1405,0]Ao[3096,13,3097,2305,4648,1405,0]Ao[3096,13,3097,2305,2264,1405,0]Ao[3096,13,3097,2305,4078,1405,0]Ao[3096,13,3097,2305,3926,1405,0]Ao[3096,13,3097,2305,3241,1405,0]Ao[3096,13,3097,1756,4236,1405,0]Ao[3096,13,3097,1756,4457,1405,0]Ao[3096,13,3097,1756,5005,1405,0]Ao[3096,13,3097,1756,2267,1405,0]Ao[3096,13,3097,1756,4746,1405,0]Ao[3096,13,3097,1784,4447,1405,0]Ao[3096,13,3097,1784,4214,1405,0]Ao[3096,13,3097,1784,4081,1405,0]Ao[3096,13,3097,1784,4086,1405,0]Al[3096,13,3097,0,4357,1405,0]Al[3096,13,3097,0,4809,1405,0]Ao[3096,13,3097,4254,3221,1405,0]Ao[3096,13,3097,4254,5099,1405,0]Ao[3096,13,3097,4844,4676,1405,0]An[3096,13,3097,3097,511,1405,0]An[3096,13,3097,3097,127,1405,0]Ao[3096,13,3097,3097,2282,1405,0]Ao[3096,13,3097,3097,2292,1405,0]Ao[3096,13,3097,3097,3024,1405,0]Ao[3096,13,1689,1689,4247,1405,0]Ao[3096,13,4957,4957,4855,1405,0]Ao[3096,13,4957,4957,1171,1405,0]Ao[3096,13,1694,1694,1836,1405,0]An[3096,13,1694,1694,498,1405,0]Ao[3096,13,1694,1694,5065,1405,0]Ao[3096,13,1694,1694,3935,1405,0]Ao[3096,13,1694,1694,4815,1405,0]Ao[3096,13,1774,1774,3253,1405,0]Ao[3096,13,1774,1774,4218,1405,0]Al[3096,13,1774,0,1170,1405,0]Ao[3096,13,1774,1774,4672,1405,0]Ao[3096,13,1774,1774,4911,1405,0]Ao[3096,13,1774,1774,4674,1405,0]Am[3096,13,3636,148,121,1405,0]An[3096,13,3636,148,3013,1405,0]Ao[3096,13,3636,1352,1157,1405,0]Ao[3096,13,3636,1352,3937,1405,0]Ao[3096,13,3636,2358,1841,1405,0]Ao[3096,13,3636,2358,4234,1405,0]Ao[3096,13,3636,3636,4738,1405,0]Ao[3096,13,4706,4706,1172,1405,0]Ao[3096,13,4706,4706,1175,1405,0]Ao[1985,13,1986,1986,3256,1405,0]An[1985,13,1986,416,4358,1405,0]Ao[1985,13,1986,1986,2279,1405,0]Ao[1985,13,1986,1986,2293,1405,0]Ao[1985,13,1986,1986,4087,1405,0]Ao[1095,13,1096,1096,3015,1405,0]Ao[1095,13,1096,1096,4848,1405,0]An[1095,13,1683,1683,135,1405,0]Ao[1095,13,1381,1381,1190,1405,0]Ao[1095,13,1381,1381,3961,1405,0]Ao[1095,13,1381,1381,4453,1405,0]Ao[1095,13,4174,4174,5050,1405,0]Ao[1095,13,4174,4174,5051,1405,0]An[1095,13,1779,1779,136,1405,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,1125,1868,0,0]Ak[1195,14,1196,1196,134,0,0]Ac[519,7,520,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[1095,2,1096,0,0,0,0]Ae[4768,7,4769,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Ae[3096,2,3097,0,0,0,0]Al[3096,13,3097,2305,2260,0,0]Af[463,2,464,3097,0,0,0]Ag[463,13,464,0,4808,0,0]Ag[463,14,464,0,3217,0,0]Ag[463,14,464,0,4114,0,0]5Ai[3096,13,3097,0,4809,0,0]Al[3096,14,3097,1382,3218,0,0]Al[3096,14,3097,1691,4116,0,0]Ai[3096,14,3097,0,4357,0,0]Aj[463,13,464,0,1443,3019,0]Aj[463,13,464,0,1426,3019,0]Aj[463,13,464,0,3025,3019,0]Aj[463,13,464,0,4808,3019,0]Aj[463,13,464,0,2281,3019,0]Ao[3096,13,3097,1810,1444,3019,0]Ao[3096,13,3097,1366,1427,3019,0]Ao[3096,13,3097,1356,3026,3019,0]Ao[3096,13,3097,1356,3224,3019,0]Al[3096,13,3097,1756,4457,0,0]Al[3096,13,3097,0,4809,3019,0]Ao[3096,13,3097,3097,2282,3019,0]Al[3096,12,1689,1689,3019,0,0]Al[1985,14,1986,1986,2279,0,0]Aj[463,13,464,0,1443,3022,0]Aj[463,13,464,0,1426,3022,0]Aj[463,13,464,0,3025,3022,0]Aj[463,13,464,0,4808,3022,0]Aj[463,13,464,0,2281,3022,0]Ao[3096,13,3097,1810,1444,3022,0]Ao[3096,13,3097,1366,1427,3022,0]Ao[3096,13,3097,1356,3026,3022,0]Ao[3096,13,3097,1356,3224,3022,0]Ao[3096,13,3097,1356,2253,3022,0]Al[3096,13,3097,0,4809,3022,0]Ao[3096,13,3097,3097,2282,3022,0]Al[3096,12,1689,1689,3022,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Al[1095,13,1381,1381,3961,0,0]Al[3096,13,3097,2305,2260,0,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Aj[463,13,464,2336,2263,0,0]3Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4342,3254,0]Aj[463,13,464,0,4675,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4343,3255,0]Ao[3096,13,3097,4844,4676,3255,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,14,464,0,1152,0,0]Al[3096,14,3097,3061,1153,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Ai[3096,14,4456,0,4680,0,0]Ag[463,14,464,0,4441,0,0]Ag[463,14,464,0,4642,0,0]Al[3096,14,3097,1356,4443,0,0]Al[3096,14,3097,1356,4644,0,0]Ai[3096,14,3097,0,4357,0,0]Ai[3096,14,1173,0,4321,0,0]Ai[3096,14,3039,0,3002,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,13,3097,3097,3024,0,0]Al[3096,14,1694,1694,1836,0,0]Ac[463,4,464,0,0,0,0]Ag[463,2,1693,1694,0,0,0]Ae[3096,4,3097,0,0,0,0]Ae[3096,2,1694,0,0,0,0]Ac[519,7,520,0,0,0,0]:Ae[1095,2,1096,0,0,0,0]Ae[4768,7,4769,0,0,0,0]Am[463,13,464,3640,4749,1162,0]Am[463,13,464,4034,4352,1162,0]Am[463,13,464,4034,3044,1162,0]Am[463,13,464,4034,3239,1162,0]Am[463,13,464,4034,4351,1162,0]Am[463,13,464,4039,3257,1162,0]Am[463,13,464,4039,4120,1162,0]Aj[463,13,464,0,4444,1162,0]Ao[3096,13,3097,3641,4445,1162,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Ai[463,13,464,1094,503,0,0]Ai[3096,14,3039,0,4107,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3041,0,0]Ag[463,14,464,0,4448,0,0]Al[3096,14,3097,1382,3042,0,0]Al[3096,14,3097,1382,4449,0,0]3210Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Al[3096,15,3097,3070,4750,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,1125,3258,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Al[3096,15,3097,1756,4457,0,0]Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ag[463,5,3635,2358,0,0,0]Ah[3096,5,3636,2358,0,0,0]Al[1095,15,1096,1096,4848,0,0]Af[463,5,464,3640,0,0,0]5454Ag[463,10,464,1994,0,0,0];:Aj[463,15,464,4039,3257,0,0]Af[463,5,464,4039,0,0,0]Al[3096,15,3097,1125,3258,0,0]Al[3096,15,3097,1125,3940,0,0]Al[3096,15,3097,2002,3959,0,0]Ah[3096,5,3097,2002,0,0,0]Aj[463,15,464,4034,4352,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1125,0,0,0]Ah[3096,5,3097,1125,0,0,0]Al[3096,15,3097,1756,2267,0,0]Ag[463,12,464,0,4963,0,0]Al[3096,12,3097,4254,4964,0,0]Ao[3096,13,3097,4254,5094,4964,0]Ao[3096,13,3097,4254,5099,4964,0]Ak[1195,14,1196,1196,134,0,0]An[1195,13,1196,1196,134,4320,0]An[2358,13,2359,2359,125,4320,0]Ak[2358,14,2359,2359,125,0,0]Ao[1095,13,1096,1096,3015,4320,0]An[1095,13,1683,1683,135,4320,0]An[1095,13,1779,1779,136,4320,0]Aj[463,13,464,0,1443,3208,0]Aj[463,13,464,0,1426,3208,0]Aj[463,13,464,0,3941,3208,0]Aj[463,13,464,0,4080,3208,0]Ai[463,13,464,0,510,3208,0]Ai[463,13,464,0,126,3208,0]Aj[463,13,464,0,2281,3208,0]Ao[3096,13,3097,1810,1444,3208,0]Ao[3096,13,3097,3070,4750,3208,0]Ao[3096,13,3097,1366,1427,3208,0]Ao[3096,13,3097,1120,3045,3208,0]Ao[3096,13,3097,1120,4241,3208,0]Ao[3096,13,3097,1125,3258,3208,0]Ao[3096,13,3097,3194,3942,3208,0]Ao[3096,13,3097,2305,4648,3208,0]Ao[3096,13,3097,1756,4746,3208,0]Ao[3096,13,3097,1784,4081,3208,0]An[3096,13,3097,3097,511,3208,0]An[3096,13,3097,3097,127,3208,0]Ao[3096,13,3097,3097,2282,3208,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,13,464,2336,2263,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Ao[1195,13,1380,1380,3960,1826,0]Ao[1195,13,1380,1380,1189,1826,0]Al[519,13,520,520,3929,1826,0]Aj[463,13,464,0,4206,1826,0]Am[463,13,464,2304,4215,1826,0]Aj[463,13,464,0,1443,1826,0]Aj[463,13,464,0,1426,1826,0]Aj[463,13,464,0,2294,1826,0]Aj[463,13,464,0,3217,1826,0]Aj[463,13,464,0,3041,1826,0]Aj[463,13,464,0,4448,1826,0]Aj[463,13,464,0,1867,1826,0]Aj[463,13,464,0,4071,1826,0]Aj[463,13,464,0,4467,1826,0]Aj[463,13,464,0,4773,1826,0]Aj[463,13,464,0,4788,1826,0]Aj[463,13,464,0,3941,1826,0]Aj[463,13,464,0,4328,1826,0]Aj[463,13,464,0,4972,1826,0]Aj[463,13,464,0,4675,1826,0]Ak[463,13,3635,0,3012,1826,0]Ak[463,13,3635,0,3936,1826,0]Ak[463,13,3635,0,4233,1826,0]Ak[463,13,3635,0,4737,1826,0]Ao[3096,13,3097,4477,4207,1826,0]Ao[3096,13,3097,4254,5094,1826,0]Ao[3096,13,3097,1810,1444,1826,0]Ao[3096,13,3097,1366,1427,1826,0]Ao[3096,13,3097,1366,3233,1826,0]Ao[3096,13,3097,1366,3207,1826,0]Ao[3096,13,3097,1382,2295,1826,0]Ao[3096,13,3097,1382,3218,1826,0]Ao[3096,13,3097,1382,3042,1826,0]Ao[3096,13,3097,1382,4449,1826,0]Ao[3096,13,3097,1125,1868,1826,0]Ao[3096,13,3097,2002,4353,1826,0]Ao[3096,13,3097,2002,4075,1826,0]Ao[3096,13,3097,3194,4468,1826,0]Ao[3096,13,3097,3194,4774,1826,0]Ao[3096,13,3097,3194,4789,1826,0]Ao[3096,13,3097,3194,3942,1826,0]Ao[3096,13,3097,1691,4329,1826,0]Ao[3096,13,3097,1691,4973,1826,0]Ao[3096,13,3097,4254,5099,1826,0]Ao[3096,13,3097,4844,4676,1826,0]An[3096,13,3636,148,3013,1826,0]Ao[3096,13,3636,1352,3937,1826,0]Ao[3096,13,3636,2358,4234,1826,0]Ao[3096,13,3636,3636,4738,1826,0]Ao[1985,13,1986,1986,2279,1826,0]Ao[1095,13,1381,1381,1190,1826,0]Ao[1095,13,1381,1381,4453,1826,0]Al[3096,13,3097,1784,4214,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,13,3097,1756,4457,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Ai[3096,14,4456,0,1186,0,0]Ai[3096,14,4456,0,4680,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ab[1985,3,0,0,0,0,0]:965Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,1094,2275,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Ai[3096,14,4456,0,4680,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Ak[1195,14,1196,1196,134,0,0]Al[1195,14,1380,1380,1189,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Am[1195,13,1196,1196,134,118,0]An[1195,13,1196,1196,3952,118,0]An[1195,13,1196,1196,3928,118,0]An[1195,13,1380,1380,3960,118,0]An[1195,13,1380,1380,1189,118,0]An[1195,13,1380,1380,4354,118,0]Ak[519,13,520,520,3929,118,0]An[3966,13,3967,3967,5006,118,0]Al[463,13,464,3640,4472,118,0]Al[463,13,464,3640,2274,118,0]Ai[463,13,464,0,4206,118,0]Al[463,13,464,4142,4912,118,0]Al[463,13,464,1094,2275,118,0]Al[463,13,464,1094,4640,118,0]Al[463,13,464,3640,3209,118,0]Al[463,13,464,3640,3211,118,0]Al[463,13,464,3640,1843,118,0]Al[463,13,464,3640,1419,118,0]Al[463,13,464,3640,3004,118,0]Al[463,13,464,3640,2247,118,0]Al[463,13,464,3640,4106,118,0]Al[463,13,464,3640,4111,118,0]Al[463,13,464,3640,4918,118,0]Al[463,13,464,3640,4749,118,0]Al[463,13,464,2304,2259,118,0]Al[463,13,464,2304,4215,118,0]Al[463,13,464,2304,1399,118,0]Al[463,13,464,4142,1418,118,0]Al[463,13,464,4142,3231,118,0]Al[463,13,464,4142,4849,118,0]Al[463,13,464,2336,2263,118,0]Al[463,13,464,2336,3240,118,0]Al[463,13,464,2336,4333,118,0]Ak[463,13,464,1094,503,118,0]Al[463,13,464,1094,4359,118,0]Al[463,13,464,4034,3237,118,0]Al[463,13,464,4034,4856,118,0]Al[463,13,464,4034,4352,118,0]Al[463,13,464,4034,3044,118,0]Al[463,13,464,4034,3239,118,0]Al[463,13,464,4034,4351,118,0]Al[463,13,464,1393,4121,118,0]Al[463,13,464,1137,3955,118,0]Al[463,13,464,4039,3243,118,0]Al[463,13,464,4039,3257,118,0]Al[463,13,464,4039,4120,118,0]Al[463,13,464,4039,1857,118,0]Ai[463,13,464,0,3234,118,0]Ai[463,13,464,0,4245,118,0]Ai[463,13,464,0,4464,118,0]Ai[463,13,464,0,4098,118,0]Ai[463,13,464,0,4342,118,0]Ai[463,13,464,0,1443,118,0]Ai[463,13,464,0,4915,118,0]Ai[463,13,464,0,1152,118,0]Ai[463,13,464,0,1426,118,0]Ai[463,13,464,0,2294,118,0]Ai[463,13,464,0,3217,118,0]Ai[463,13,464,0,3041,118,0]Ai[463,13,464,0,4448,118,0]Ai[463,13,464,0,1867,118,0]Ai[463,13,464,0,4071,118,0]Ai[463,13,464,0,4444,118,0]Ai[463,13,464,0,4458,118,0]Ai[463,13,464,0,4467,118,0]Ai[463,13,464,0,4773,118,0]Ai[463,13,464,0,4788,118,0]Ai[463,13,464,0,3941,118,0]Ai[463,13,464,0,4328,118,0]Ai[463,13,464,0,4114,118,0]Ai[463,13,464,0,4972,118,0]Ai[463,13,464,0,4065,118,0]Ai[463,13,464,0,3931,118,0]Ai[463,13,464,0,3025,118,0]Ai[463,13,464,0,4441,118,0]Ai[463,13,464,0,4642,118,0]Ai[463,13,464,0,4077,118,0]Ai[463,13,464,0,4080,118,0]Ai[463,13,464,0,4085,118,0]Ai[463,13,464,0,4808,118,0]Ai[463,13,464,0,3220,118,0]Ai[463,13,464,0,4675,118,0]Ah[463,13,464,0,510,118,0]Ah[463,13,464,0,126,118,0]Ai[463,13,464,0,2281,118,0]Ai[463,13,464,0,2291,118,0]Ai[463,13,3635,0,120,118,0]Aj[463,13,3635,0,3012,118,0]Aj[463,13,3635,0,1156,118,0]Aj[463,13,3635,0,3936,118,0]Aj[463,13,3635,0,1840,118,0]Aj[463,13,3635,0,4233,118,0]Aj[463,13,3635,0,4737,118,0]Aj[463,13,1693,0,1835,118,0]Ai[463,13,1693,0,497,118,0]Aj[463,13,1693,0,5064,118,0]Aj[463,13,1693,0,3934,118,0]Aj[463,13,1693,0,4812,118,0]Aj[463,13,1773,0,3252,118,0]Aj[463,13,1773,0,4217,118,0]Aj[463,13,1773,0,1169,118,0]Aj[463,13,1773,0,4671,118,0]Aj[463,13,1773,0,4910,118,0]Aj[463,13,1773,0,4673,118,0]Am[2358,13,2359,2359,125,118,0]An[2358,13,2359,2359,2250,118,0]An[3096,13,3097,4477,4207,118,0]An[3096,13,3097,3070,3018,118,0]An[3096,13,3097,1120,1407,118,0]An[3096,13,3097,2002,1861,118,0]An[3096,13,3097,2002,3238,118,0]An[3096,13,3097,2002,3244,118,0]An[3096,13,3097,3641,3212,118,0]An[3096,13,3097,1116,3235,118,0]An[3096,13,3097,1691,4246,118,0]An[3096,13,3097,2305,2260,118,0]An[3096,13,3097,2305,4213,118,0]An[3096,13,3097,2305,4651,118,0]An[3096,13,3097,2305,4224,118,0]An[3096,13,3097,1756,5124,118,0]An[3096,13,3097,4254,5094,118,0]An[3096,13,3097,1392,4465,118,0]An[3096,13,3097,1392,4099,118,0]An[3096,13,3097,1392,4343,118,0]An[3096,13,3097,1810,1444,118,0]An[3096,13,3097,1810,4916,118,0]An[3096,13,3097,3061,1153,118,0]An[3096,13,3097,3070,4750,118,0]An[3096,13,3097,1366,1427,118,0]An[3096,13,3097,1366,4110,118,0]An[3096,13,3097,1366,3233,118,0]An[3096,13,3097,1366,3040,118,0]An[3096,13,3097,1366,4748,118,0]An[3096,13,3097,1366,4804,118,0]An[3096,13,3097,1366,3207,118,0]An[3096,13,3097,1382,2295,118,0]An[3096,13,3097,1382,3218,118,0]An[3096,13,3097,1382,3042,118,0]An[3096,13,3097,1382,4449,118,0]An[3096,13,3097,1120,3045,118,0]An[3096,13,3097,1120,4241,118,0]An[3096,13,3097,1125,1868,118,0]An[3096,13,3097,1125,3258,118,0]An[3096,13,3097,1125,3940,118,0]An[3096,13,3097,2002,3959,118,0]An[3096,13,3097,2002,4353,118,0]An[3096,13,3097,2002,4075,118,0]An[3096,13,3097,3641,4445,118,0]An[3096,13,3097,3641,3038,118,0]An[3096,13,3097,3641,4319,118,0]An[3096,13,3097,3641,5001,118,0]An[3096,13,3097,3641,1174,118,0]An[3096,13,3097,1116,4459,118,0]An[3096,13,3097,3194,4468,118,0]An[3096,13,3097,3194,4774,118,0]An[3096,13,3097,3194,4789,118,0]An[3096,13,3097,3194,3942,118,0]An[3096,13,3097,1691,4329,118,0]An[3096,13,3097,1691,4116,118,0]An[3096,13,3097,1691,4973,118,0]An[3096,13,3097,1691,4067,118,0]An[3096,13,3097,1691,3932,118,0]An[3096,13,3097,1356,3026,118,0]An[3096,13,3097,1356,4334,118,0]An[3096,13,3097,1356,3224,118,0]An[3096,13,3097,1356,3247,118,0]An[3096,13,3097,1356,4082,118,0]An[3096,13,3097,1356,4443,118,0]An[3096,13,3097,1356,4644,118,0]An[3096,13,3097,1356,2253,118,0]An[3096,13,3097,2305,4648,118,0]An[3096,13,3097,2305,2264,118,0]An[3096,13,3097,2305,4078,118,0]An[3096,13,3097,2305,3926,118,0]An[3096,13,3097,2305,3241,118,0]An[3096,13,3097,1756,4236,118,0]An[3096,13,3097,1756,4457,118,0]An[3096,13,3097,1756,5005,118,0]An[3096,13,3097,1756,2267,118,0]An[3096,13,3097,1756,4746,118,0]An[3096,13,3097,1784,4447,118,0]An[3096,13,3097,1784,4214,118,0]An[3096,13,3097,1784,4081,118,0]An[3096,13,3097,1784,4086,118,0]Ak[3096,13,3097,0,4357,118,0]Ak[3096,13,3097,0,4809,118,0]An[3096,13,3097,4254,3221,118,0]An[3096,13,3097,4254,5099,118,0]An[3096,13,3097,4844,4676,118,0]Am[3096,13,3097,3097,511,118,0]Am[3096,13,3097,3097,127,118,0]An[3096,13,3097,3097,2282,118,0]An[3096,13,3097,3097,2292,118,0]An[3096,13,3097,3097,3024,118,0]An[3096,13,1689,1689,4247,118,0]An[3096,13,4957,4957,4855,118,0]An[3096,13,4957,4957,1171,118,0]An[3096,13,1694,1694,1836,118,0]Am[3096,13,1694,1694,498,118,0]An[3096,13,1694,1694,5065,118,0]An[3096,13,1694,1694,3935,118,0]An[3096,13,1694,1694,4815,118,0]An[3096,13,1774,1774,3253,118,0]An[3096,13,1774,1774,4218,118,0]Ak[3096,13,1774,0,1170,118,0]An[3096,13,1774,1774,4672,118,0]An[3096,13,1774,1774,4911,118,0]An[3096,13,1774,1774,4674,118,0]Al[3096,13,3636,148,121,118,0]Am[3096,13,3636,148,3013,118,0]An[3096,13,3636,1352,1157,118,0]An[3096,13,3636,1352,3937,118,0]An[3096,13,3636,2358,1841,118,0]An[3096,13,3636,2358,4234,118,0]An[3096,13,3636,3636,4738,118,0]An[3096,13,4706,4706,1172,118,0]An[3096,13,4706,4706,1175,118,0]An[1985,13,1986,1986,3256,118,0]Am[1985,13,1986,416,4358,118,0]An[1985,13,1986,1986,2279,118,0]An[1985,13,1986,1986,2293,118,0]An[1985,13,1986,1986,4087,118,0]An[1095,13,1096,1096,3015,118,0]An[1095,13,1096,1096,4848,118,0]Am[1095,13,1683,1683,135,118,0]An[1095,13,1381,1381,1190,118,0]An[1095,13,1381,1381,3961,118,0]An[1095,13,1381,1381,4453,118,0]An[1095,13,4174,4174,5050,118,0]An[1095,13,4174,4174,5051,118,0]Am[1095,13,1779,1779,136,118,0]Aj[463,13,464,3640,4918,0,0]Aj[463,13,464,1094,4359,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Af[463,5,464,3640,0,0,0]Al[1195,15,1196,1196,3928,0,0]Ae[2358,6,2359,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Aj[463,15,464,3640,4749,0,0]Al[3096,15,3097,3070,4750,0,0]Af[463,5,464,2304,0,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,2002,3959,0,0]Af[463,5,464,2336,0,0,0]2Ah[3096,6,3097,1756,0,0,0]Ag[463,19,464,0,1443,0,0]Al[3096,19,3097,1810,1444,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]=Ah[463,12,1693,0,4115,0,0]>Ak[463,13,1773,0,4673,4115,0]>Al[3096,12,1694,1694,4117,0,0]>Ao[3096,13,1774,1774,4674,4117,0]Ao[1095,13,4174,4174,5051,4117,0]An[2358,13,2359,2359,125,3943,0]Ao[2358,13,2359,2359,2250,3943,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Ag[463,13,464,0,4114,0,0]Al[3096,13,3097,1691,4116,0,0]Aj[463,13,464,1994,4316,0,0]0>=Al[1095,13,1381,1381,4453,0,0]Ae[1095,2,1096,0,0,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]43Ak[1195,14,1196,1196,134,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,4254,5094,0,0]Al[3096,13,3097,4254,5099,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]=Al[1195,14,1380,1380,1189,0,0]Ao[1095,13,1096,1096,4848,3050,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Af[463,6,464,3641,0,0,0]Ah[3096,6,3097,3641,0,0,0]Al[3096,15,3097,2305,4213,0,0]Ah[3096,5,3097,1784,0,0,0]Af[463,5,464,1382,0,0,0]Ah[3096,5,3097,1382,0,0,0]97Ae[1095,5,1381,0,0,0,0]:8Ah[3096,6,3097,1756,0,0,0]Af[463,5,464,1116,0,0,0]Ah[3096,5,3097,1116,0,0,0]Al[3096,15,3097,1366,4748,0,0]Af[463,5,464,1392,0,0,0]Ah[3096,5,3097,1392,0,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,3641,4445,0,0]Af[463,5,464,3640,0,0,0]Aj[463,15,464,4034,3044,0,0]Aj[463,15,464,4034,3239,0,0]Aj[463,15,464,4039,3257,0,0]Aj[463,15,464,4039,4120,0,0]An[1195,13,1196,1196,134,4212,0]Ao[1195,13,1196,1196,3952,4212,0]Ao[1195,13,1196,1196,3928,4212,0]Am[463,13,464,3640,3211,4212,0]Am[463,13,464,3640,4918,4212,0]Am[463,13,464,3640,4749,4212,0]Am[463,13,464,2304,2259,4212,0]Am[463,13,464,2304,4215,4212,0]Am[463,13,464,4142,1418,4212,0]Al[463,13,464,1094,503,4212,0]Am[463,13,464,1094,4359,4212,0]Am[463,13,464,4034,4352,4212,0]Am[463,13,464,4034,3044,4212,0]Am[463,13,464,4034,3239,4212,0]Am[463,13,464,4034,4351,4212,0]Am[463,13,464,4039,3257,4212,0]Am[463,13,464,4039,4120,4212,0]Aj[463,13,464,0,1443,4212,0]Aj[463,13,464,0,4915,4212,0]Aj[463,13,464,0,1426,4212,0]Aj[463,13,464,0,2294,4212,0]Aj[463,13,464,0,3217,4212,0]Aj[463,13,464,0,3041,4212,0]Aj[463,13,464,0,4448,4212,0]Aj[463,13,464,0,1867,4212,0]Aj[463,13,464,0,4071,4212,0]Aj[463,13,464,0,4444,4212,0]Aj[463,13,464,0,4467,4212,0]Aj[463,13,464,0,4773,4212,0]Aj[463,13,464,0,4788,4212,0]Aj[463,13,464,0,3941,4212,0]Aj[463,13,464,0,4328,4212,0]Aj[463,13,464,0,4114,4212,0]Aj[463,13,464,0,4972,4212,0]Aj[463,13,464,0,4065,4212,0]Aj[463,13,464,0,3931,4212,0]Aj[463,13,464,0,3025,4212,0]Aj[463,13,464,0,4441,4212,0]Aj[463,13,464,0,4642,4212,0]Aj[463,13,464,0,4077,4212,0]Aj[463,13,464,0,4080,4212,0]Aj[463,13,464,0,4085,4212,0]Aj[463,13,464,0,4808,4212,0]Aj[463,13,464,0,3220,4212,0]Ai[463,13,464,0,510,4212,0]Ai[463,13,464,0,126,4212,0]Aj[463,13,464,0,2281,4212,0]Aj[463,13,3635,0,120,4212,0]Ak[463,13,3635,0,3012,4212,0]Ak[463,13,3635,0,1156,4212,0]Ak[463,13,3635,0,3936,4212,0]Ak[463,13,3635,0,1840,4212,0]Ak[463,13,3635,0,4233,4212,0]Ak[463,13,1773,0,1169,4212,0]Ak[463,13,1773,0,4671,4212,0]Ak[463,13,1773,0,4910,4212,0]Ak[463,13,1773,0,4673,4212,0]Ao[3096,13,3097,1810,1444,4212,0]Ao[3096,13,3097,1810,4916,4212,0]Ao[3096,13,3097,3070,4750,4212,0]Ao[3096,13,3097,1366,1427,4212,0]Ao[3096,13,3097,1366,4110,4212,0]Ao[3096,13,3097,1366,3233,4212,0]Ao[3096,13,3097,1366,3040,4212,0]Ao[3096,13,3097,1366,4748,4212,0]Ao[3096,13,3097,1366,4804,4212,0]Ao[3096,13,3097,1366,3207,4212,0]Ao[3096,13,3097,1382,2295,4212,0]Ao[3096,13,3097,1382,3218,4212,0]Ao[3096,13,3097,1382,3042,4212,0]Ao[3096,13,3097,1382,4449,4212,0]Ao[3096,13,3097,1120,3045,4212,0]Ao[3096,13,3097,1120,4241,4212,0]Ao[3096,13,3097,1125,1868,4212,0]Ao[3096,13,3097,1125,3258,4212,0]Ao[3096,13,3097,1125,3940,4212,0]Ao[3096,13,3097,2002,4353,4212,0]Ao[3096,13,3097,2002,4075,4212,0]Ao[3096,13,3097,3641,4445,4212,0]Ao[3096,13,3097,3641,3038,4212,0]Ao[3096,13,3097,3641,4319,4212,0]Ao[3096,13,3097,3641,5001,4212,0]Ao[3096,13,3097,3194,4468,4212,0]Ao[3096,13,3097,3194,4774,4212,0]Ao[3096,13,3097,3194,4789,4212,0]Ao[3096,13,3097,3194,3942,4212,0]Ao[3096,13,3097,1691,4329,4212,0]Ao[3096,13,3097,1691,4116,4212,0]Ao[3096,13,3097,1691,4973,4212,0]Ao[3096,13,3097,1691,4067,4212,0]Ao[3096,13,3097,1691,3932,4212,0]Ao[3096,13,3097,1356,3026,4212,0]Ao[3096,13,3097,1356,3224,4212,0]Ao[3096,13,3097,1356,3247,4212,0]Ao[3096,13,3097,1356,4082,4212,0]Ao[3096,13,3097,1356,4443,4212,0]Ao[3096,13,3097,1356,4644,4212,0]Ao[3096,13,3097,1356,2253,4212,0]Ao[3096,13,3097,2305,4648,4212,0]Ao[3096,13,3097,2305,4078,4212,0]Ao[3096,13,3097,1756,4457,4212,0]Ao[3096,13,3097,1756,5005,4212,0]Ao[3096,13,3097,1756,2267,4212,0]Ao[3096,13,3097,1756,4746,4212,0]Ao[3096,13,3097,1784,4081,4212,0]Ao[3096,13,3097,1784,4086,4212,0]Al[3096,13,3097,0,4357,4212,0]Al[3096,13,3097,0,4809,4212,0]Ao[3096,13,3097,4254,3221,4212,0]Ao[3096,13,3097,4254,5099,4212,0]An[3096,13,3097,3097,511,4212,0]An[3096,13,3097,3097,127,4212,0]Ao[3096,13,3097,3097,2282,4212,0]Ao[3096,13,3097,3097,3024,4212,0]Ao[3096,13,1689,1689,4247,4212,0]Ao[3096,13,4957,4957,4855,4212,0]Ao[3096,13,4957,4957,1171,4212,0]Al[3096,13,1774,0,1170,4212,0]Ao[3096,13,1774,1774,4672,4212,0]Ao[3096,13,1774,1774,4911,4212,0]Ao[3096,13,1774,1774,4674,4212,0]Am[3096,13,3636,148,121,4212,0]An[3096,13,3636,148,3013,4212,0]Ao[3096,13,3636,1352,1157,4212,0]Ao[3096,13,3636,1352,3937,4212,0]Ao[3096,13,3636,2358,1841,4212,0]Ao[3096,13,3636,2358,4234,4212,0]Ao[3096,13,4706,4706,1175,4212,0]Ao[1985,13,1986,1986,2279,4212,0]Ao[1985,13,1986,1986,2293,4212,0]Ao[1985,13,1986,1986,4087,4212,0]Ao[1095,13,1096,1096,4848,4212,0]Ao[1095,13,1381,1381,4453,4212,0]Ao[1095,13,4174,4174,5050,4212,0]Ao[1095,13,4174,4174,5051,4212,0]Af[463,7,464,1994,0,0,0]Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]10Ae[1095,7,1096,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[4257,7,4258,0,0,0,0]Ae[1195,7,1196,0,0,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]1Al[3096,13,3097,2002,4353,0,0]Al[1195,13,1380,1380,1189,0,0]Al[1195,14,1380,1380,3960,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4121,1852,0]Am[463,13,464,1137,3955,1852,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Af[463,5,464,1094,0,0,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,3641,4445,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,3641,1174,0,0]1Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]32Al[3096,15,3097,3641,3038,0,0]><><><21Ag[463,5,1773,1774,0,0,0]Ae[3096,5,1774,0,0,0,0]10Af[463,5,464,4844,0,0,0]Ah[3096,5,3097,4844,0,0,0]Al[3096,15,4706,4706,1172,0,0]Al[3096,15,3097,1366,4748,0,0]6Al[3096,15,3097,1756,4457,0,0]Ag[463,12,464,0,2287,0,0]Aj[463,13,464,0,4206,2287,0]Aj[463,13,464,0,4098,2287,0]Al[3096,12,3097,1392,2288,0,0]Ao[3096,13,3097,4477,4207,2288,0]Ao[3096,13,3097,1392,4099,2288,0]Ae[3966,7,3967,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]32An[1195,13,1196,1196,134,4330,0]An[2358,13,2359,2359,125,4330,0]Ao[2358,13,2359,2359,2250,4330,0]Ao[1095,13,1096,1096,3015,4330,0]An[1095,13,1683,1683,135,4330,0]An[1095,13,1779,1779,136,4330,0]Ak[1985,13,1986,416,4358,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]:9Ae[3096,2,3097,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]?>43Ae[4257,7,4258,0,0,0,0]6Al[1095,14,1096,1096,3015,0,0]70Ae[1195,7,1196,0,0,0,0]Ag[463,13,464,0,4114,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4116,0,0]Al[3096,13,3097,1691,4067,0,0]Ag[463,14,464,0,4114,0,0]Al[3096,14,3097,1691,4116,0,0]53Aj[463,13,464,4039,3243,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,1366,4748,0,0]Al[3096,15,3097,3641,4445,0,0]Ah[463,10,3635,3636,0,0,0]Af[3096,10,3636,0,0,0,0]Ag[463,5,3635,3636,0,0,0]Ae[3096,5,3636,0,0,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,10,464,3641,0,0,0]Ai[3096,10,3097,3641,0,0,0]Ah[3096,6,3097,1756,0,0,0]Ah[3096,6,3097,1366,0,0,0]Af[463,6,464,3640,0,0,0]Ah[3096,6,3097,3070,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Aj[463,15,464,3640,4749,0,0]Al[3096,15,3097,3070,4750,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Ah[463,14,3635,0,4737,0,0]Al[3096,14,3636,3636,4738,0,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]10Al[3096,13,3097,3070,3018,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Ab[4768,3,0,0,0,0,0]Ao[1095,13,1096,1096,4848,3050,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]54Ai[3096,10,3097,1756,0,0,0]Al[3096,15,3097,3641,1174,0,0]7600Al[3096,15,3097,1120,4241,0,0]4365Al[3096,15,4706,4706,1172,0,0]Ae[1095,9,1096,0,0,0,0]:9Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]<;<;Ah[3096,6,3097,1366,0,0,0]21Al[1195,15,1196,1196,3952,0,0]Ac[463,5,464,0,0,0,0]Ae[3096,5,3097,0,0,0,0]Ag[463,15,464,0,4077,0,0]Ag[463,5,1693,1694,0,0,0]Al[3096,15,3097,2305,4078,0,0]Al[3096,15,3097,1756,4746,0,0]Ae[3096,5,1694,0,0,0,0]An[1195,13,1196,1196,134,4320,0]An[2358,13,2359,2359,125,4320,0]Ao[1095,13,1096,1096,3015,4320,0]An[1095,13,1683,1683,135,4320,0]An[1095,13,1779,1779,136,4320,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ag[463,13,464,0,1443,0,0]Al[3096,13,3097,1810,1444,0,0]Aj[463,14,464,2304,4215,0,0]Aj[463,13,464,3640,4918,0,0]Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ag[463,13,464,0,4206,0,0]Al[3096,13,3097,4477,4207,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]7Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,13,1773,0,4671,0,0]Ah[463,13,1773,0,4673,0,0]Al[3096,13,1774,1774,4672,0,0]Al[3096,13,1774,1774,4674,0,0]45;:Ao[3966,13,3967,3967,5006,4802,0]Ag[463,13,464,0,4458,0,0]Al[3096,13,3097,1116,4459,0,0]Ae[1095,6,1096,0,0,0,0]Af[463,5,464,4142,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Al[3096,15,3097,3641,3038,0,0]Ae[3096,5,4957,0,0,0,0]Af[463,5,464,4034,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Al[3096,15,4706,4706,1172,0,0]Aj[463,14,464,2304,4215,0,0]Ai[463,13,464,0,510,3006,0]Ai[463,13,464,0,126,3006,0]An[3096,13,3097,3097,511,3006,0]An[3096,13,3097,3097,127,3006,0]Ao[2358,13,2359,2359,2250,3248,0]Ag[463,13,464,0,4788,0,0]Al[3096,13,3097,3194,4789,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Aj[463,13,464,3640,3211,0,0]Ag[463,12,464,0,4743,0,0]Al[3096,12,3097,3641,4744,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Aj[463,14,464,2304,4215,0,0]Al[3096,13,3097,2002,1861,0,0]Ah[3096,2,4252,4038,0,0,0]Ae[1195,7,1196,0,0,0,0]==Ai[463,13,464,1094,503,0,0]Ak[1985,13,1986,416,4358,0,0]032Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Ae[3096,2,3097,0,0,0,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ag[463,10,464,4254,0,0,0]Ai[3096,10,3097,4254,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Af[463,5,464,1691,0,0,0]Ah[3096,5,3097,1691,0,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,3097,3024,0,0]Ah[463,13,3635,0,4233,0,0]Al[3096,13,3636,2358,4234,0,0]Aj[463,13,464,1994,3048,0,0]0Aj[463,13,464,3640,3211,0,0]6Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Al[3096,15,4706,4706,1172,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Al[3096,15,3097,1366,4804,0,0]Al[3096,15,3097,3641,3038,0,0]Al[3096,15,3097,3641,4319,0,0]Ah[3096,5,3097,3641,0,0,0]Al[3096,15,3097,1366,4748,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1756,0,0,0]Ae[3966,5,3967,0,0,0,0]Al[1095,13,1096,1096,3015,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ah[3096,7,4890,4889,0,0,0]0Al[3096,13,3097,3641,3212,0,0]6Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Ao[3966,13,3967,3967,5006,4802,0]0Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Ag[463,13,464,0,4773,0,0]Al[3096,13,3097,3194,4774,0,0]Am[1195,13,1196,1196,134,485,0]Am[2358,13,2359,2359,125,485,0]An[1095,13,1096,1096,3015,485,0]Am[1095,13,1683,1683,135,485,0]Am[1095,13,1779,1779,136,485,0]??>An[1195,13,1196,1196,134,4330,0]An[2358,13,2359,2359,125,4330,0]Ao[2358,13,2359,2359,2250,4330,0]Ao[1095,13,1096,1096,3015,4330,0]An[1095,13,1683,1683,135,4330,0]An[1095,13,1779,1779,136,4330,0]Ag[463,13,464,0,4114,0,0]Al[3096,13,3097,1691,4116,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ae[1095,5,4174,0,0,0,0]0Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,13,3097,3641,3212,0,0]Ao[3966,13,3967,3967,5006,4802,0];:Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]?>?>Aj[463,13,464,3640,3211,0,0]6Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ae[3966,7,3967,0,0,0,0]Ae[4257,7,4258,0,0,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]?434343>=>=Al[3096,14,4957,4957,4855,0,0]54Ai[3096,18,3097,3194,0,0,0]") \ No newline at end of file diff --git a/pr/523/docs/search.index/function/378ad5ea86b4.js b/pr/523/docs/search.index/function/37913739753b.js similarity index 98% rename from pr/523/docs/search.index/function/378ad5ea86b4.js rename to pr/523/docs/search.index/function/37913739753b.js index bd05cdaae..f0575514d 100644 --- a/pr/523/docs/search.index/function/378ad5ea86b4.js +++ b/pr/523/docs/search.index/function/37913739753b.js @@ -1 +1 @@ -rd_("Bf[\"{{{AHEf{ANK`}}{AHEf{ANK`}}}D@n}\",[]]Bf[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}D@n}\",[]]Bd[\"{{{AHEf{KAd}}{AHEf{KAd}}}D@n}\",[]]Bd[\"{{{AHEf{CNn}}{AHEf{CNn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@n}}{AHEf{BB@n}}}D@n}\",[]]Bf[\"{{{AHEf{BB@`}}{AHEf{BB@`}}}D@n}\",[]]Bf[\"{{{AHEf{AGLh}}{AHEf{AGLh}}}D@n}\",[]]Bf[\"{{{AHEf{AIDn}}{AHEf{AIDn}}}D@n}\",[]]Bf[\"{{{AHEf{BAOn}}{AHEf{BAOn}}}D@n}\",[]]Bf[\"{{{AHEf{AIGb}}{AHEf{AIGb}}}D@n}\",[]]Bf[\"{{{AHEf{B@C`}}{AHEf{B@C`}}}D@n}\",[]]Bd[\"{{{AHEf{KDf}}{AHEf{KDf}}}D@n}\",[]]Bf[\"{{{AHEf{BFFf}}{AHEf{BFFf}}}D@n}\",[]]Bd[\"{{{AHEf{I@`}}{AHEf{I@`}}}D@n}\",[]]Bd[\"{{{AHEf{KBd}}{AHEf{KBd}}}D@n}\",[]]Bf[\"{{{AHEf{AANl}}{AHEf{AANl}}}D@n}\",[]]Bf[\"{{{AHEf{AIBb}}{AHEf{AIBb}}}D@n}\",[]]Bf[\"{{{AHEf{AGLb}}{AHEf{AGLb}}}D@n}\",[]]Bd[\"{{{AHEf{NIf}}{AHEf{NIf}}}D@n}\",[]]Bf[\"{{{AHEf{AOLn}}{AHEf{AOLn}}}D@n}\",[]]Bf[\"{{{AHEf{BBKh}}{AHEf{BBKh}}}D@n}\",[]]Bf[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}D@n}\",[]]Bf[\"{{{AHEf{ANKf}}{AHEf{ANKf}}}D@n}\",[]]Bf[\"{{{AHEf{AGJb}}{AHEf{AGJb}}}D@n}\",[]]Bf[\"{{{AHEf{BBKb}}{AHEf{BBKb}}}D@n}\",[]]Bf[\"{{{AHEf{BDDd}}{AHEf{BDDd}}}D@n}\",[]]Bf[\"{{{AHEf{AOMj}}{AHEf{AOMj}}}D@n}\",[]]Bf[\"{{{AHEf{AON`}}{AHEf{AON`}}}D@n}\",[]]Bf[\"{{{AHEf{AONj}}{AHEf{AONj}}}D@n}\",[]]Bf[\"{{{AHEf{BEI`}}{AHEf{BEI`}}}D@n}\",[]]Bd[\"{{{AHEf{COl}}{AHEf{COl}}}D@n}\",[]]Bb[\"{{{AHEf{Ol}}{AHEf{Ol}}}D@n}\",[]]Bf[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}D@n}\",[]]Bf[\"{{{AHEf{BGI`}}{AHEf{BGI`}}}D@n}\",[]]Bd[\"{{{AHEf{IBb}}{AHEf{IBb}}}D@n}\",[]]Bd[\"{{{AHEf{KDh}}{AHEf{KDh}}}D@n}\",[]]Bf[\"{{{AHEf{BFFh}}{AHEf{BFFh}}}D@n}\",[]]Bd[\"{{{AHEf{I@b}}{AHEf{I@b}}}D@n}\",[]]Bf[\"{{{AHEf{BEAl}}{AHEf{BEAl}}}D@n}\",[]]Bd[\"{{{AHEf{KBf}}{AHEf{KBf}}}D@n}\",[]]Bf[\"{{{AHEf{AIDb}}{AHEf{AIDb}}}D@n}\",[]]Bf[\"{{{AHEf{AGL`}}{AHEf{AGL`}}}D@n}\",[]]Bf[\"{{{AHEf{BEAh}}{AHEf{BEAh}}}D@n}\",[]]Bf[\"{{{AHEf{BEHh}}{AHEf{BEHh}}}D@n}\",[]]Bf[\"{{{AHEf{AI@n}}{AHEf{AI@n}}}D@n}\",[]]Bf[\"{{{AHEf{AANn}}{AHEf{AANn}}}D@n}\",[]]Bf[\"{{{AHEf{AIBd}}{AHEf{AIBd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLd}}{AHEf{AGLd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}D@n}\",[]]Bf[\"{{{AHEf{BABb}}{AHEf{BABb}}}D@n}\",[]]Bd[\"{{{AHEf{NIh}}{AHEf{NIh}}}D@n}\",[]]Bf[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}D@n}\",[]]Bf[\"{{{AHEf{ANLh}}{AHEf{ANLh}}}D@n}\",[]]Bf[\"{{{AHEf{ANNn}}{AHEf{ANNn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@b}}{AHEf{BB@b}}}D@n}\",[]]Bf[\"{{{AHEf{AOMf}}{AHEf{AOMf}}}D@n}\",[]]Bf[\"{{{AHEf{BBKj}}{AHEf{BBKj}}}D@n}\",[]]Bf[\"{{{AHEf{AGKl}}{AHEf{AGKl}}}D@n}\",[]]Bf[\"{{{AHEf{BAKn}}{AHEf{BAKn}}}D@n}\",[]]Bf[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}D@n}\",[]]Bf[\"{{{AHEf{ANKh}}{AHEf{ANKh}}}D@n}\",[]]Bf[\"{{{AHEf{AGJd}}{AHEf{AGJd}}}D@n}\",[]]Bf[\"{{{AHEf{BAMl}}{AHEf{BAMl}}}D@n}\",[]]Bf[\"{{{AHEf{AIC`}}{AHEf{AIC`}}}D@n}\",[]]Bf[\"{{{AHEf{AIEn}}{AHEf{AIEn}}}D@n}\",[]]Bf[\"{{{AHEf{AONd}}{AHEf{AONd}}}D@n}\",[]]Bf[\"{{{AHEf{BBKf}}{AHEf{BBKf}}}D@n}\",[]]Bf[\"{{{AHEf{BDDh}}{AHEf{BDDh}}}D@n}\",[]]Bf[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}D@n}\",[]]Bf[\"{{{AHEf{AOMl}}{AHEf{AOMl}}}D@n}\",[]]Bf[\"{{{AHEf{AAKf}}{AHEf{AAKf}}}D@n}\",[]]Bf[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}D@n}\",[]]Bf[\"{{{AHEf{AONb}}{AHEf{AONb}}}D@n}\",[]]Bf[\"{{{AHEf{AONl}}{AHEf{AONl}}}D@n}\",[]]Bf[\"{{{AHEf{BB@j}}{AHEf{BB@j}}}D@n}\",[]]Bf[\"{{{AHEf{BEIb}}{AHEf{BEIb}}}D@n}\",[]]Bd[\"{{{AHEf{COn}}{AHEf{COn}}}D@n}\",[]]Bb[\"{{{AHEf{On}}{AHEf{On}}}D@n}\",[]]Bf[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}D@n}\",[]]Bf[\"{{{AHEf{AGJ`}}{AHEf{AGJ`}}}D@n}\",[]]Bf[\"{{{AHEf{BABn}}{AHEf{BABn}}}D@n}\",[]]Bf[\"{{{AHEf{BENn}}{AHEf{BENn}}}D@n}\",[]]Bd[\"{{{AHEf{IBf}}{AHEf{IBf}}}D@n}\",[]]Bf[\"{{{AHEf{BGIb}}{AHEf{BGIb}}}D@n}\",[]]Bd[\"{{{AHEf{IBd}}{AHEf{IBd}}}D@n}\",[]]Bf[\"{{{AHEf{AONn}}{AHEf{AONn}}}D@n}\",[]]Ai[\"{{{AHEf{CNn}}}KBd}\",[]]Aj[\"{{{AHEf{BB@n}}}KBd}\",[]]Ak[\"{{{AHEf{AIDj}}}AAMb}\",[]]Ak[\"{{{AHEf{BEO`}}}AAMb}\",[]]Ak[\"{{{AHEf{AIEf}}}AAMb}\",[]]o[\"{KAhKBf}\",[]]A`[\"{AGGdKBf}\",[]]A`[\"{AGIhKBf}\",[]]A`[\"{B@AfKBf}\",[]]A`[\"{B@@hKBf}\",[]]Aa[\"{AALjAAMd}\",[]]Aa[\"{AAObAAMd}\",[]]Aa[\"{AAJjAAMd}\",[]]A`[\"{NGnAAMd}\",[]]A`[\"{ANN`NGf}\",[]]A`[\"{CNfAAKf}\",[]]Ac[\"{{AANlAANl}}\",[]]Ac[\"{{AIBbAIBb}}\",[]]Ac[\"{{BBL`AGLb}}\",[]]Bc[\"{{AANnAANn}c{}}\",[\"Add::Output\"]]Bc[\"{{AIBdAIBd}c{}}\",[\"Add::Output\"]]Bc[\"{{BBLbAGLd}c{}}\",[\"Add::Output\"]]Be[\"{{{AHEf{KDf}}{AHEf{KDf}}}AALh}\",[]]Be[\"{{{AHEf{KBd}}{AHEf{KBd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}AALh}\",[]]Bg[\"{{{AHEf{AON`}}{AHEf{AON`}}}AALh}\",[]]Be[\"{{{AHEf{COl}}{AHEf{COl}}}AALh}\",[]]Bc[\"{{{AHEf{Ol}}{AHEf{Ol}}}AALh}\",[]]Bg[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}AALh}\",[]]Be[\"{{{AHEf{KDh}}{AHEf{KDh}}}AALh}\",[]]Bg[\"{{{AHEf{BEAl}}{AHEf{BEAl}}}AALh}\",[]]Be[\"{{{AHEf{KBf}}{AHEf{KBf}}}AALh}\",[]]Bg[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}AALh}\",[]]Bg[\"{{{AHEf{BABb}}{AHEf{BABb}}}AALh}\",[]]Bg[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}AALh}\",[]]Bg[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}AALh}\",[]]Bg[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}AALh}\",[]]Bg[\"{{{AHEf{AONb}}{AHEf{AONb}}}AALh}\",[]]Be[\"{{{AHEf{COn}}{AHEf{COn}}}AALh}\",[]]Bc[\"{{{AHEf{On}}{AHEf{On}}}AALh}\",[]]Bg[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}AALh}\",[]]o[\"{AAMbOl}\",[]]o[\"{AAMdOn}\",[]]n[\"{KAjOn}\",[]]o[\"{AGHbOn}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AALnKB`}\",[]]A`[\"{AANjKB`}\",[]]Bh[\"{{{AHEf{A@l}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANN`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@d}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGAl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFF`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFFl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAJf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Nn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AICn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BENb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIE`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAMj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{CNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@n}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEO`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIDn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAOn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Cb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANNf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@C`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NHb}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{KDf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFFf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Cd[\"{{{AHEf{I@`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{KBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AIBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGLb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBMd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBNf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEDj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEFh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANLj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAM`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{B@Bd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BFMh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AGJb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BDDd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AOMj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AON`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AONj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEI`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AIBh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BDHf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{COl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{Ol}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AAMb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{O`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGHh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{I@h}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NF`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAAb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BE@b}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BGI`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEIh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{IBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFEl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{AIAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BFFh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{I@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{KBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Al}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGL`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEHh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AI@n}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIBd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BABb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NIh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAKn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGAb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBNh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEDl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEFj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAMb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Bh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFMj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOLf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGJd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAMl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIC`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAIj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDE`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANJl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGAj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAKf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Nl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@j}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BEIb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIBj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGMf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BDHh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{COn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bg[\"{{{AHEf{On}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAMd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGJ`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BABn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BENn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGIb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEIn}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{IBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{BFEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bg[\"{{{AHEf{Ob}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGHj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{I@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{NFb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAAd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BE@d}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@l}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AALn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AANj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bd[\"{{{AHEf{BFF`}}}{{KB`{AIEl}}}}\",[]]Ak[\"{{{AHEf{B@Al}}}AAJb}\",[]]A`[\"{AANlCLf}\",[]]A`[\"{AANnCLf}\",[]]Aj[\"{{{AHEf{BAAh}}}JNf}\",[]]A`[\"{BGAjCLf}\",[]]o[\"{CNfCLf}\",[]]A`[\"{AALnJNf}\",[]]Ce[\"{{{AHEf{CEdBFMh}}{Nn{AAMn}}}{{AHEf{CEdBFMh}}}}\",[]]Ce[\"{{{AHEf{CEdBFMj}}{Nn{AAN`}}}{{AHEf{CEdBFMj}}}}\",[]]8Af[\"{{AAJbCLf}BB@d}\",[]]Ag[\"{{}{{Nn{BGAl}}}}\",[]]Ae[\"{{JNfCLd}B@Ml}\",[]]Cd[\"{{BAM`{KB`{B@Bd}}AGMb{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Ah[\"{{{Of{IEb}}}AIDd}\",[]]A`[\"{NG`BBMd}\",[]]Ah[\"{{{Nn{NDn}}}BAM`}\",[]]Bc[\"{{{Nn{B@Bf}}{Nn{BE@f}}}B@Bd}\",[]]Ai[\"{{{Nn{AOLd}}}AOLb}\",[]]B`[\"{{{AHEf{{JL`{Nd}}}}}AON`}\",[]]Ae[\"{{CLdJNf}BDHf}\",[]]Ag[\"{{COlOlCLf}AAMb}\",[]]Aj[\"{{{Nn{AGHh}}CLb}O`}\",[]]An[\"{{{Nn{ANL`}}NEdCLb}I@h}\",[]]An[\"{{{Nn{BAAb}}NEdCLb}NF`}\",[]]Ae[\"{{JNfCLd}B@Mn}\",[]]Ah[\"{{{Of{IEb}}}AIDf}\",[]]Bm[\"{{{Nn{BAMb}}{KB`{{Nn{B@Bh}}}}D@n}AAJh}\",[]]A`[\"{JNfBH@h}\",[]]o[\"{{}BGLl}\",[]]A`[\"{NG`BBMf}\",[]]Ah[\"{{{Nn{NE`}}}BAMb}\",[]]Bc[\"{{{Nn{B@Bj}}{Nn{BE@h}}}B@Bh}\",[]]Ai[\"{{{Nn{AOLh}}}AOLf}\",[]]Ek[\"{{AAI`{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{{JNd{BAAh{KB`{AAI`}}}}BEAd}}}{BEEfIDh}}\",[\"\"]]B`[\"{{{AHEf{{JL`{Nd}}}}}AONb}\",[]]Af[\"{{BEIbKDb}BB@j}\",[]]A`[\"{JNfBGMf}\",[]]Ae[\"{{CLdJNf}BDHh}\",[]]Ag[\"{{COnOnCLf}AAMd}\",[]]Am[\"{{AIEl{KB`{KAb}}}AGJ`}\",[]]Aj[\"{{{Nn{AGHj}}CLb}Ob}\",[]]An[\"{{{Nn{ANLb}}NEdCLb}I@j}\",[]]An[\"{{{Nn{BAAd}}NEdCLb}NFb}\",[]]Aj[\"{AIG`{{KBl{BB@l}}}}\",[]]Aa[\"{BDH`BGGd}\",[]]Aa[\"{BDHdBGGf}\",[]]o[\"{COlCOl}\",[]]o[\"{COnCOn}\",[]]Ak[\"{{{AHEf{AIFd}}}AIFb}\",[]]Ai[\"{{{AHEf{NGh}}}NEd}\",[]]0Aj[\"{{{AHEf{B@Cb}}}NEd}\",[]]Ak[\"{{{AHEf{BABj}}}AIFb}\",[]]Ak[\"{{{AHEf{AIFf}}}AIFb}\",[]]Ak[\"{{{AHEf{BABl}}}AIFb}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLbAAJb}\",[]]Bg[\"{{{AHEf{AIAh}}KBf}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLdAAJb}\",[]]Ah[\"{A@n{{KBn{HOj}}}}\",[]]Ah[\"{AA`{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{B@@hAIEl}\",[]]Aa[\"{AALnAIEl}\",[]]Aa[\"{BB@jBEIb}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{AAIjHOn}\",[]]Am[\"{{{AHEf{CEdAALd}}}HOj}\",[]]Am[\"{{{AHEf{CEdAAJn}}}HOj}\",[]]Al[\"{{{AHEf{CEdCNn}}}HOj}\",[]]Am[\"{{{AHEf{CEdBB@n}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIDj}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIEf}}}HOj}\",[]]Al[\"{{{AHEf{CEdJOn}}}HOj}\",[]]A`[\"{cc{}}\",[\"T\"]]0000000000000000000000Aa[\"{BBKhBEAj}\",[]]111111111111111Aa[\"{AGLhBB@`}\",[]]2Aa[\"{AIDnAGLh}\",[]]Aa[\"{BBKhAGLh}\",[]]4Aa[\"{BBKhAIDn}\",[]]Aa[\"{AGLhBAOn}\",[]]6666Aa[\"{B@C`AIGb}\",[]]Aa[\"{AOLnAIGb}\",[]]Aa[\"{BBKhAIGb}\",[]]9Aa[\"{BBKhB@C`}\",[]]:::::::A`[\"{BEI`KDf}\",[]]n[\"{NdKDf}\",[]]o[\"{CLbKDf}\",[]]A`[\"{AAMbKDf}\",[]]o[\"{CLdKDf}\",[]]????Al[\"{cKBd{{CN`{CLd}}}}\",[\"T\"]]A`[\"{cc{}}\",[\"T\"]]00000A`[\"{IAlBBKh}\",[]]A`[\"{I@fBBKh}\",[]]2Aa[\"{ANKdBBKh}\",[]]3333A`[\"{KDfANLj}\",[]]444444Aa[\"{BFFfANKf}\",[]]Aa[\"{BBNjANKf}\",[]]6A`[\"{IAlBBKb}\",[]]777Aa[\"{BEIhAOMj}\",[]]88A`[\"{KDfBEI`}\",[]]99999A`[\"{KDfAAMb}\",[]]::::::::::::Aa[\"{ANOdANKl}\",[]];;;;A`[\"{BDF`IBb}\",[]]A`[\"{BDGhIBb}\",[]]A`[\"{BBLdIBb}\",[]]A`[\"{BAMnIBb}\",[]]A`[\"{BAO`IBb}\",[]]A`[\"{BBMnIBb}\",[]]A`[\"{BGD`IBb}\",[]]A`[\"{BDDjIBb}\",[]]A`[\"{AICfIBb}\",[]]A`[\"{BGJ`IBb}\",[]]A`[\"{BGHnIBb}\",[]]A`[\"{cc{}}\",[\"T\"]]00000000000000000000000o[\"{CLdKDh}\",[]]A`[\"{AAMdKDh}\",[]]o[\"{CLbKDh}\",[]]n[\"{NdKDh}\",[]]4A`[\"{BEIbKDh}\",[]]5555Al[\"{cKBf{{CN`{CLd}}}}\",[\"T\"]]666666666666666666Aa[\"{BB@jBBKj}\",[]]77777A`[\"{AGL`IBl}\",[]]88888A`[\"{KDhANLl}\",[]]99999Aa[\"{BBNjANKh}\",[]]Aa[\"{BFFhANKh}\",[]];;;;;Aa[\"{BB@jBBKf}\",[]]<<<<>>>>>A`[\"{IBfBB@j}\",[]]A`[\"{KDhBEIb}\",[]]A`[\"{cc{}}\",[\"T\"]]00000A`[\"{KDhAAMd}\",[]]111111A`[\"{BABnIBf}\",[]]222Aa[\"{ANOdANKn}\",[]]3333A`[\"{BGJ`IBd}\",[]]A`[\"{BDF`IBd}\",[]]A`[\"{AICfIBd}\",[]]A`[\"{BDGhIBd}\",[]]7A`[\"{BBLdIBd}\",[]]A`[\"{BAO`IBd}\",[]]A`[\"{BBMnIBd}\",[]]A`[\"{BGHnIBd}\",[]]A`[\"{BDDjIBd}\",[]]A`[\"{BAMnIBd}\",[]]A`[\"{BGD`IBd}\",[]]>>>>>>>>>>>>An[\"{{{AHEf{c}}}AIG`CLl}\",[\"S\"]]??????????????Bm[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{ANLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AON`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{Ol}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEAl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{AGLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BABb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AIGd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{ANLl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BDE`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEAd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AONb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COn}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{On}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AGJ`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Aa[\"{{}c{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n[\"{{}HOj}\",[]]0000Cc[\"{{{AHEf{CEdJOn}}JNf}{{KBj{{KB`{I@b}}AGLj}}}}\",[]]Cf[\"{{{AHEf{CEdBA@`}}}{{KB`{c}}}{}}\",[\"Iterator::Item\"]]Dl[\"{{{AHEf{BE@f}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANKl}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Dl[\"{{{AHEf{BE@h}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANKn}}}}\",[]]Bf[\"{{{AHEf{AIAf}}KBd}{{KB`{CNn}}}}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjAI@h}}}}\",[]]A`[\"{AIBbCLf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}HOj}\",[]]A`[\"{AIBdCLf}\",[]]Ck[\"{{{AAd{{AHEf{CEdAI@`}}}}{AHEf{CEdNDb}}}{{COf{HOj}}}}\",[]]Dk[\"{{{AAd{{AHEf{CEdBBO`}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALd}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAIAb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNFf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdKAf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAGGh}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAAHn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@Ad}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@An}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdJNn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdBAMj}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNHb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{IBl}}}}\",[]]De[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}D@n}{{KBj{JOnBABb}}}}\",[]]Bo[\"{{COn{AHEf{CEdc}}}{{KBj{BENnIBf}}}Oh}\",[\"R\"]]Bf[\"{{{AHEf{CEdAGId}}}{{KB`{HOn}}}}\",[]]Ec[\"{{{AHEf{BB@l}}AIG`{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{KBl{JNf}}}}\",[]]Cn[\"{{{AHEf{BE@f}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANKl}}}}\",[]]Cn[\"{{{AHEf{BE@h}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANKn}}}}\",[]]C`[\"{{{AHEf{CEdAGId}}HOnD@n}{{KBj{HOjBEAl}}}}\",[]]Cc[\"{{{AHEf{BB@l}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bn[\"{{{AHEf{CEdBFMh}}CLd}{{AHEf{CEdBFMh}}}}\",[]]Bn[\"{{{AHEf{CEdBFMj}}CLd}{{AHEf{CEdBFMj}}}}\",[]]Aj[\"{{{AHEf{AIAf}}}COl}\",[]]Aj[\"{{{AHEf{AIAh}}}COn}\",[]]Cn[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cn[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]A`[\"{BB@dCLf}\",[]]A`[\"{AANfJNf}\",[]]A`[\"{AANhJNf}\",[]]o[\"{IDdD@n}\",[]]Bm[\"{{{AHEf{CEdAIDj}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdBEO`}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}KDh}{{KBj{HOjAOMf}}}}\",[]]Bn[\"{{{AHEf{AIFl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BANl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHf}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{AIFn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BANn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHh}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bd[\"{{{AHEf{BDEf}}}{{KB`{BA@`}}}}\",[]]Bg[\"{{{Nn{BDOn}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{AGHh}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{ANL`}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BAAb}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BE@`}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{AGHj}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{ANLb}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{BAAd}}NEdCLb}{{Of{AIAl}}}}\",[]]Ai[\"{BEN`{{Nn{BE@`}}}}\",[]]o[\"{I@`HOn}\",[]]A`[\"{AANlCLf}\",[]]o[\"{NIfJNf}\",[]]o[\"{I@bHOn}\",[]]A`[\"{AANnCLf}\",[]]o[\"{NIhJNf}\",[]]Aa[\"{ANJlBBKj}\",[]]Ai[\"{{{AHEf{A@l}}}A@l}\",[]]Ak[\"{{{AHEf{ANN`}}}ANN`}\",[]]Ak[\"{{{AHEf{ANK`}}}ANK`}\",[]]Ak[\"{{{AHEf{AIAf}}}AIAf}\",[]]Ak[\"{{{AHEf{BFFl}}}BFFl}\",[]]Ak[\"{{{AHEf{BEAj}}}BEAj}\",[]]Ak[\"{{{AHEf{AAJf}}}AAJf}\",[]]Ak[\"{{{AHEf{B@Nn}}}B@Nn}\",[]]Ai[\"{{{AHEf{KAd}}}KAd}\",[]]Ai[\"{{{AHEf{CNn}}}CNn}\",[]]Ak[\"{{{AHEf{BB@n}}}BB@n}\",[]]Ak[\"{{{AHEf{BB@`}}}BB@`}\",[]]Ak[\"{{{AHEf{AGLh}}}AGLh}\",[]]Ak[\"{{{AHEf{AIDn}}}AIDn}\",[]]Ak[\"{{{AHEf{BAOn}}}BAOn}\",[]]Ak[\"{{{AHEf{AIGb}}}AIGb}\",[]]Ak[\"{{{AHEf{B@C`}}}B@C`}\",[]]Ai[\"{{{AHEf{KDf}}}KDf}\",[]]Ak[\"{{{AHEf{BFFf}}}BFFf}\",[]]Ai[\"{{{AHEf{KBd}}}KBd}\",[]]Ak[\"{{{AHEf{AANl}}}AANl}\",[]]Ak[\"{{{AHEf{AIBb}}}AIBb}\",[]]Ak[\"{{{AHEf{AGLb}}}AGLb}\",[]]Ak[\"{{{AHEf{BBL`}}}BBL`}\",[]]Ai[\"{{{AHEf{NIf}}}NIf}\",[]]Ak[\"{{{AHEf{AOLn}}}AOLn}\",[]]Ak[\"{{{AHEf{BBKh}}}BBKh}\",[]]Ak[\"{{{AHEf{BBNf}}}BBNf}\",[]]Ak[\"{{{AHEf{BEDj}}}BEDj}\",[]]Ak[\"{{{AHEf{BEFh}}}BEFh}\",[]]Ak[\"{{{AHEf{ANLj}}}ANLj}\",[]]Ak[\"{{{AHEf{BAM`}}}BAM`}\",[]]Ak[\"{{{AHEf{B@Bd}}}B@Bd}\",[]]Ak[\"{{{AHEf{BFMh}}}BFMh}\",[]]Ak[\"{{{AHEf{AOLb}}}AOLb}\",[]]Ak[\"{{{AHEf{ANKf}}}ANKf}\",[]]Ak[\"{{{AHEf{AGJb}}}AGJb}\",[]]Ak[\"{{{AHEf{BBKb}}}BBKb}\",[]]Ak[\"{{{AHEf{BDDd}}}BDDd}\",[]]Ak[\"{{{AHEf{AOMj}}}AOMj}\",[]]Ak[\"{{{AHEf{AON`}}}AON`}\",[]]Ak[\"{{{AHEf{AONj}}}AONj}\",[]]Ak[\"{{{AHEf{BEI`}}}BEI`}\",[]]Ak[\"{{{AHEf{AIBh}}}AIBh}\",[]]Ai[\"{{{AHEf{COl}}}COl}\",[]]Ag[\"{{{AHEf{Ol}}}Ol}\",[]]Ak[\"{{{AHEf{AAMb}}}AAMb}\",[]]Ag[\"{{{AHEf{O`}}}O`}\",[]]Ak[\"{{{AHEf{AGHh}}}AGHh}\",[]]Ai[\"{{{AHEf{I@h}}}I@h}\",[]]Ak[\"{{{AHEf{ANL`}}}ANL`}\",[]]Ai[\"{{{AHEf{NF`}}}NF`}\",[]]Ak[\"{{{AHEf{BAAb}}}BAAb}\",[]]Ai[\"{{{AHEf{IBb}}}IBb}\",[]]Ak[\"{{{AHEf{BDGn}}}BDGn}\",[]]Ak[\"{{{AHEf{BFEl}}}BFEl}\",[]]Ak[\"{{{AHEf{BDHb}}}BDHb}\",[]]Ai[\"{{{AHEf{KDh}}}KDh}\",[]]Ak[\"{{{AHEf{BFFh}}}BFFh}\",[]]Ak[\"{{{AHEf{BEAl}}}BEAl}\",[]]Ai[\"{{{AHEf{KBf}}}KBf}\",[]]Ak[\"{{{AHEf{B@Al}}}B@Al}\",[]]Ak[\"{{{AHEf{AIDb}}}AIDb}\",[]]Ak[\"{{{AHEf{AGL`}}}AGL`}\",[]]Ak[\"{{{AHEf{BEAh}}}BEAh}\",[]]Ak[\"{{{AHEf{BEHh}}}BEHh}\",[]]Ak[\"{{{AHEf{AI@n}}}AI@n}\",[]]Ak[\"{{{AHEf{AANn}}}AANn}\",[]]Ak[\"{{{AHEf{AIBd}}}AIBd}\",[]]Ak[\"{{{AHEf{AGLd}}}AGLd}\",[]]Ak[\"{{{AHEf{BBLb}}}BBLb}\",[]]Ak[\"{{{AHEf{AGLj}}}AGLj}\",[]]Ak[\"{{{AHEf{BABb}}}BABb}\",[]]Ai[\"{{{AHEf{NIh}}}NIh}\",[]]Ak[\"{{{AHEf{AIGd}}}AIGd}\",[]]Ak[\"{{{AHEf{ANLh}}}ANLh}\",[]]Ak[\"{{{AHEf{BB@b}}}BB@b}\",[]]Ak[\"{{{AHEf{AOMf}}}AOMf}\",[]]Ak[\"{{{AHEf{BBKj}}}BBKj}\",[]]Ak[\"{{{AHEf{AGKl}}}AGKl}\",[]]Ak[\"{{{AHEf{BAKn}}}BAKn}\",[]]Ak[\"{{{AHEf{BGAb}}}BGAb}\",[]]Ak[\"{{{AHEf{BBNh}}}BBNh}\",[]]Ak[\"{{{AHEf{BEDl}}}BEDl}\",[]]Ak[\"{{{AHEf{BEFj}}}BEFj}\",[]]Ak[\"{{{AHEf{ANLl}}}ANLl}\",[]]Ak[\"{{{AHEf{BAMb}}}BAMb}\",[]]Ak[\"{{{AHEf{B@Bh}}}B@Bh}\",[]]Ak[\"{{{AHEf{BFMj}}}BFMj}\",[]]Ak[\"{{{AHEf{AOLf}}}AOLf}\",[]]Ak[\"{{{AHEf{ANKh}}}ANKh}\",[]]Ak[\"{{{AHEf{AGJd}}}AGJd}\",[]]Ak[\"{{{AHEf{AIC`}}}AIC`}\",[]]Ak[\"{{{AHEf{AIEn}}}AIEn}\",[]]Ak[\"{{{AHEf{AONd}}}AONd}\",[]]Ak[\"{{{AHEf{BBKf}}}BBKf}\",[]]Ak[\"{{{AHEf{BDDh}}}BDDh}\",[]]Ak[\"{{{AHEf{AAIj}}}AAIj}\",[]]Ak[\"{{{AHEf{BDE`}}}BDE`}\",[]]Ak[\"{{{AHEf{AOMl}}}AOMl}\",[]]Ak[\"{{{AHEf{BBMb}}}BBMb}\",[]]Ak[\"{{{AHEf{BGAj}}}BGAj}\",[]]Ak[\"{{{AHEf{AAKf}}}AAKf}\",[]]Ak[\"{{{AHEf{BEAd}}}BEAd}\",[]]Ak[\"{{{AHEf{AONb}}}AONb}\",[]]Ak[\"{{{AHEf{AONl}}}AONl}\",[]]Ak[\"{{{AHEf{BB@j}}}BB@j}\",[]]Ak[\"{{{AHEf{BEIb}}}BEIb}\",[]]Ak[\"{{{AHEf{AIBj}}}AIBj}\",[]]Ak[\"{{{AHEf{BGMf}}}BGMf}\",[]]Ai[\"{{{AHEf{COn}}}COn}\",[]]Ag[\"{{{AHEf{On}}}On}\",[]]Ak[\"{{{AHEf{AAMd}}}AAMd}\",[]]Ak[\"{{{AHEf{AGJ`}}}AGJ`}\",[]]Ak[\"{{{AHEf{BABn}}}BABn}\",[]]Ak[\"{{{AHEf{BENn}}}BENn}\",[]]Ai[\"{{{AHEf{IBf}}}IBf}\",[]]Ai[\"{{{AHEf{IBd}}}IBd}\",[]]Ak[\"{{{AHEf{BDH`}}}BDH`}\",[]]Ak[\"{{{AHEf{BFEn}}}BFEn}\",[]]Ak[\"{{{AHEf{BDHd}}}BDHd}\",[]]Ag[\"{{{AHEf{Ob}}}Ob}\",[]]Ak[\"{{{AHEf{AGHj}}}AGHj}\",[]]Ai[\"{{{AHEf{I@j}}}I@j}\",[]]Ak[\"{{{AHEf{ANLb}}}ANLb}\",[]]Ai[\"{{{AHEf{NFb}}}NFb}\",[]]Ak[\"{{{AHEf{BAAd}}}BAAd}\",[]]Ai[\"{{{AHEf{IBn}}}IBn}\",[]]Ak[\"{{{AHEf{AALn}}}AALn}\",[]]Ak[\"{{{AHEf{AANj}}}AANj}\",[]]Ak[\"{{{AHEf{AONn}}}AONn}\",[]]Ak[\"{{{AHEf{BEN`}}}BEN`}\",[]]Ak[\"{{{AHEf{BBLj}}}BBLj}\",[]]Ak[\"{{{AHEf{BGGd}}}BGGd}\",[]]Ak[\"{{{AHEf{BGGf}}}BGGf}\",[]]Bn[\"{{{AHEf{AIAf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bn[\"{{{AHEf{AAJf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjBAKl}}}}\",[]]Bf[\"{{{AHEf{CEdAIAh}}NEdKDhHOn}HOj}\",[]]Bj[\"{{{AHEf{AON`}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Bj[\"{{{AHEf{AONb}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Aa[\"{BB@jAIC`}\",[]]A`[\"{AAMbCLf}\",[]]A`[\"{AAMdCLf}\",[]]A`[\"{AONjD@n}\",[]]A`[\"{AONlD@n}\",[]]l[\"{NEf}\",[]]l[\"{NEh}\",[]]Ce[\"{{{AHEf{BEEf}}{AHEf{CEdOh}}}{{KBj{AONbBEAd}}}}\",[]]Ce[\"{{{AHEf{BH@h}}{AHEf{CEdOh}}}{{KBj{AONbBEAd}}}}\",[]]Bc[\"{{{AHEf{AIAh}}}{{AAj{KBf}}}}\",[]]Bd[\"{{{AHEf{IDj}}{AHEf{CL`}}}HOj}\",[]]Am[\"{{{AHEf{ANKb}}JNf}HOj}\",[]]Ai[\"{{{AHEf{IDl}}}HOj}\",[]]Bg[\"{{{AAd{{AHEf{CEdAI@`}}}}NEd}HOj}\",[]]Bm[\"{{{AHEf{CEdAIEf}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}KDh}{{KBj{HOjAOMf}}}}\",[]]Am[\"{AAJn{{KBj{HOjAIE`}}}}\",[]]Dc[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}{{KBj{AANhAIEb}}}}\",[]]Bi[\"{{{AHEf{NGh}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{B@Cb}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{ANNf}}{AAd{{Of{K@n}}}}}HOj}\",[]]o[\"{A@lD@n}\",[]]Ak[\"{{{AHEf{AIAf}}}BBL`}\",[]]Ak[\"{{{AHEf{AAJf}}}B@Nn}\",[]]Aj[\"{{{AHEf{CNn}}}AGLb}\",[]]An[\"{{{AHEf{CEdAIAh}}}BBLb}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGb}}}}\",[]]Ck[\"{{{AHEf{CEdAIEh}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGd}}}}\",[]]Bl[\"{{{AHEf{BENn}}{AHEf{CEdc}}}HOjJOl}\",[\"W\"]]Aj[\"{{{AHEf{AAJf}}}JNn}\",[]]An[\"{AAJn{{KBj{AIAbBBKh}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Fh[\"{{{AHEf{CEdAAJh}}AAK`NEd{AHEf{CEd{AAj{Nd}}}}{KB`{{Nn{B@Bh}}}}}{{KBj{{JNd{BDE`AIAh}}{Of{ANJl}}}}}}\",[]]Am[\"{AHEf{{AHEf{c}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000o[\"{NIfJNf}\",[]]o[\"{NIhJNf}\",[]]A`[\"{A@lANK`}\",[]]Bc[\"{{AIElBAKjA@l}{{KBn{ANKb}}}}\",[]]Aj[\"{AIEl{{KBl{AAJf}}}}\",[]]B`[\"{{}{{KBj{HOj{Of{IAd}}}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BBKh}\",[]]Be[\"{{{AHEf{AAJh}}}{{AHEf{BAMb}}}}\",[]]o[\"{NdBEI`}\",[]]A`[\"{AIBbCLf}\",[]]o[\"{B@BdNn}\",[]]o[\"{NdBEIb}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{B@BhNn}\",[]]A`[\"{BB@jKB`}\",[]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KDfBABn}}}Oh}\",[\"B\"]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KBdBABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AGJbBABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{BEI`BABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AAMbBABn}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KDh}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KBf}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGJd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AIC`}}}Oh}\",[\"B\"]]Ek[\"{{{AHEf{CEd{K@l{AAI`}}}}{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{BBMbBEAd}}}{BEEfIDh}}\",[\"\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{BEIb}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AAMd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGIf}}}Oh}\",[\"B\"]]A`[\"{AALnKB`}\",[]]Bk[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEI`}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AIC`}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAIj}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEIb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGIl}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bj[\"{{{AHEf{CEdAIEf}}}{{KBj{HOjAOLn}}}}\",[]]Bj[\"{{{AHEf{CEdAIEh}}}{{KBj{HOjANLh}}}}\",[]]An[\"{{{AHEf{ANOb}}AAJb}HOj}\",[]]Ea[\"{{{AHEf{CEdAAJh}}NEdAGJ`{KB`{AONl}}AAI`{AHEf{CEd{AAj{Nd}}}}}{{KB`{B@Nj}}}}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]A`[\"{AAJnHOj}\",[]]Ba[\"{{{AHEf{CEdAAJh}}AAK`}HOj}\",[]]Bh[\"{{{AHEf{AIFl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BANl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHf}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{AIFn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BANn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHh}}{AHEf{CL`}}HOn}HOj}\",[]]A`[\"{AGHnD@n}\",[]]o[\"{I@`CLf}\",[]]o[\"{I@bCLf}\",[]]Ce[\"{{{AHEf{CEdAIAj}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cc[\"{{{AHEf{CEdO`}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@h}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNF`}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Ce[\"{{{AHEf{CEdAIAl}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cc[\"{{{AHEf{CEdOb}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@j}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNFb}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]o[\"{BDI`Nd}\",[]]A`[\"{BBKbHOn}\",[]]A`[\"{BDDdHOn}\",[]]A`[\"{BBKfHOn}\",[]]A`[\"{BDDhHOn}\",[]]A`[\"{BB@jKDb}\",[]]Aa[\"{BALbBBKj}\",[]]Aa[\"{AGGdBEAh}\",[]]Bg[\"{{{AHEf{AAJf}}AGMb}{{KBl{HOj}}}}\",[]]A`[\"{AAJnHOj}\",[]]Cf[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}AANh}\",[]]l[\"{NEf}\",[]]Ak[\"{{{AHEf{AGJ`}}}AIEl}\",[]]l[\"{NEh}\",[]]An[\"{{AAJdA@l}{{KBn{HOj}}}}\",[]]B`[\"{{B@BdAIEl}{{KBl{AAJf}}}}\",[]]Bb[\"{B@Bb{{KBj{HOj{Of{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BEAj}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BB@`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AGLh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIDn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BAOn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIGb}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{B@C`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKj}}}{{KB`{{AHEf{IAd}}}}}}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Bg[\"{{{AHEf{CNn}}}{{KBj{AID`AI@h}}}}\",[]]Aa[\"{B@AfAIDb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]A`[\"{AALnJNf}\",[]]Aa[\"{AGLbAANl}\",[]]Aa[\"{BBL`AANl}\",[]]Aa[\"{AGLdAANn}\",[]]Aa[\"{BBLbAANn}\",[]]3210Dh[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANKl}}}}\",[]]Dh[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANKn}}}}\",[]]Aj[\"{{{AHEf{AIAj}}}CLf}\",[]]Ah[\"{{{AHEf{O`}}}CLf}\",[]]Ai[\"{{{AHEf{I@h}}}CLf}\",[]]Ai[\"{{{AHEf{NF`}}}CLf}\",[]]Aj[\"{{{AHEf{AIAl}}}CLf}\",[]]Ah[\"{{{AHEf{Ob}}}CLf}\",[]]Ai[\"{{{AHEf{I@j}}}CLf}\",[]]Ai[\"{{{AHEf{NFb}}}CLf}\",[]]Aj[\"{{{AHEf{BFLf}}}JNf}\",[]]Aj[\"{{{AHEf{BFLh}}}JNf}\",[]]Aj[\"{{{AHEf{BGLl}}}JNf}\",[]]Aj[\"{{{AHEf{BGMf}}}JNf}\",[]]o[\"{A@lJNf}\",[]]n[\"{{}ND`}\",[]]0o[\"{OjAAId}\",[]]111Ba[\"{{AHEf{AHEf{c}}}AALh{}}\",[\"K\"]]0000000000000000000Cg[\"{{{AHEf{AAJf}}AIEl{AHEf{CL`}}}{{KBj{AIAbAOMj}}}}\",[]]Dl[\"{{{AHEf{CEdAAJh}}NEdAOLfAIEl{AHEf{CL`}}}{{KBj{{JNd{BDE`AIAh}}AOMl}}}}\",[]]Bd[\"{{{AHEf{AAJn}}}{{KB`{BDEd}}}}\",[]]Dm[\"{{{AHEf{AGKf}}KBdCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANKl}}}}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Bd[\"{{{AHEf{AAK`}}}{{KB`{BDEf}}}}\",[]]Dm[\"{{{AHEf{AGKh}}KBfCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANKn}}}}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]o[\"{{}ANO`}\",[]]n[\"{{}IDj}\",[]]o[\"{{}ANKb}\",[]]o[\"{{}B@Ml}\",[]]o[\"{{}B@Nn}\",[]]n[\"{{}KDf}\",[]]n[\"{{}KBd}\",[]]o[\"{{}AANl}\",[]]o[\"{{}AIBb}\",[]]o[\"{{}AGLb}\",[]]o[\"{{}BBL`}\",[]]n[\"{{}NIf}\",[]]o[\"{{}AOLn}\",[]]o[\"{{}BBNf}\",[]]o[\"{{}BEDj}\",[]]o[\"{{}BEFh}\",[]]o[\"{{}ANLj}\",[]]o[\"{{}BAM`}\",[]]o[\"{{}BFMh}\",[]]o[\"{{}BDHf}\",[]]o[\"{{}AGHh}\",[]]o[\"{{}ANL`}\",[]]o[\"{{}BAAb}\",[]]o[\"{{}BE@b}\",[]]o[\"{{}B@Mn}\",[]]o[\"{{}BGLl}\",[]]n[\"{{}KDh}\",[]]n[\"{{}KBf}\",[]]o[\"{{}AIDb}\",[]]o[\"{{}AI@n}\",[]]o[\"{{}AANn}\",[]]o[\"{{}AIBd}\",[]]o[\"{{}AGLd}\",[]]o[\"{{}BBLb}\",[]]n[\"{{}NIh}\",[]]o[\"{{}BB@b}\",[]]o[\"{{}AOMf}\",[]]o[\"{{}BBNh}\",[]]o[\"{{}BEDl}\",[]]o[\"{{}BEFj}\",[]]o[\"{{}ANLl}\",[]]o[\"{{}BAMb}\",[]]o[\"{{}BFMj}\",[]]o[\"{{}BGMf}\",[]]o[\"{{}BDHh}\",[]]o[\"{{}AGHj}\",[]]o[\"{{}ANLb}\",[]]o[\"{{}BAAd}\",[]]o[\"{{}BE@d}\",[]]o[\"{{}AALn}\",[]]n[\"{{}IDl}\",[]]o[\"{{}BBLj}\",[]]o[\"{{}B@Nl}\",[]]Ak[\"{{{AHEf{BAAh}}}AONb}\",[]]Ak[\"{{{AHEf{BBMb}}}AONb}\",[]]Aa[\"{BGAjAONb}\",[]]Aa[\"{BEIdAONb}\",[]]A`[\"{CNfAONb}\",[]]A`[\"{ID`AONb}\",[]]A`[\"{IDdAONb}\",[]]Aa[\"{BDI`AONb}\",[]]Cg[\"{{{AHEf{AGKf}}KBdCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cg[\"{{{AHEf{AGKh}}KBfCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Aj[\"{{{AHEf{AIDj}}}D@n}\",[]]Aj[\"{{{AHEf{BEO`}}}D@n}\",[]]Ak[\"{{{AHEf{AIAj}}}BE@b}\",[]]Ai[\"{{{AHEf{O`}}}BE@b}\",[]]Aj[\"{{{AHEf{I@h}}}BE@b}\",[]]Aj[\"{{{AHEf{NF`}}}BE@b}\",[]]Ak[\"{{{AHEf{AIAl}}}BE@d}\",[]]Ai[\"{{{AHEf{Ob}}}BE@d}\",[]]Aj[\"{{{AHEf{I@j}}}BE@d}\",[]]Aj[\"{{{AHEf{NFb}}}BE@d}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLb}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLb}{{AHEf{CEdBBNh}}}}\",[]]Bf[\"{{{AHEf{CEdAIAj}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdO`}}NEdCLfCLf}HOj}\",[]]Bf[\"{{{AHEf{CEdAIAl}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdOb}}NEdCLfCLf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}KAf}\",[]]Bc[\"{{{AHEf{AALf}}}{{KB`{KBd}}}}\",[]]Aa[\"{BGAjAONb}\",[]]Aa[\"{BEIdAONb}\",[]]A`[\"{CNfAONb}\",[]]A`[\"{ID`AONb}\",[]]Aa[\"{BDI`AONb}\",[]]Aj[\"{{{AHEf{AIEf}}}NHb}\",[]]Bn[\"{{{AHEf{AIEh}}}{{KBj{{KB`{KDh}}AOMf}}}}\",[]]o[\"{A@lJNf}\",[]]o[\"{IDjJNf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}NHj}\",[]]Aj[\"{{{AHEf{AGKf}}}JNf}\",[]]Aj[\"{{{AHEf{AGKh}}}JNf}\",[]]A`[\"{AHEfKDd}\",[]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bd[\"{{{AHEf{BFFl}}}{{KB`{AIAf}}}}\",[]]Bc[\"{{{AHEf{BB@n}}}{{KB`{CNn}}}}\",[]]Bn[\"{{{AHEf{CEdAOLb}}CLd}{{AHEf{CEdAOLb}}}}\",[]]Bn[\"{{{AHEf{CEdAOLf}}CLd}{{AHEf{CEdAOLf}}}}\",[]]A`[\"{BGAjCLd}\",[]]A`[\"{BEIdCLd}\",[]]o[\"{CNfCLd}\",[]]o[\"{ID`CLd}\",[]]A`[\"{AGHnKB`}\",[]]Aa[\"{AANjAHEf}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{BB@dAAJb}\",[]]A`[\"{JOnBB@b}\",[]]Aa[\"{AGLbAIBb}\",[]]Aa[\"{BBL`AIBb}\",[]]Aa[\"{AGLdAIBd}\",[]]Aa[\"{BBLbAIBd}\",[]]3210Bg[\"{{{AHEf{CEdc}}JNf}AON`{OhIDh}}\",[\"\"]]Bg[\"{{{AHEf{CEdc}}JNf}AONb{OhIDh}}\",[\"\"]]o[\"{{}BBMd}\",[]]o[\"{{}BBMf}\",[]]A`[\"{CLfBGLl}\",[]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANN`c}}}{}}\",[\"FromStr::Err\"]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANK`c}}}{}}\",[\"FromStr::Err\"]]o[\"{CLdKDf}\",[]]o[\"{CLdKDh}\",[]]Al[\"{CLf{{KBj{KDfBFFf}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFh}}}}\",[]]Aa[\"{BFDnANKj}\",[]]Aa[\"{BH@jB@Oj}\",[]]Aa[\"{BFE`ANKj}\",[]]Aa[\"{BH@lB@Oj}\",[]]Af[\"{{}{{KB`{Ab}}}}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBEFh}}AAJb}{{AHEf{CEdBEFh}}}}\",[]]Bo[\"{{{AHEf{CEdBEFj}}AAJb}{{AHEf{CEdBEFj}}}}\",[]]Ao[\"{{{Of{AIAj}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{O`}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@h}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NF`}}}{{Of{Nl}}}}\",[]]Ao[\"{{{Of{AIAl}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{Ob}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@j}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NFb}}}{{Of{Nl}}}}\",[]]Aj[\"{{{AHEf{BFFl}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBFMh}}AAJb}{{AHEf{CEdBFMh}}}}\",[]]Bo[\"{{{AHEf{CEdBFMj}}AAJb}{{AHEf{CEdBFMj}}}}\",[]]Bc[\"{{{AHEf{AIAb}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AIAf}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAJn}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAK`}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AGJ`}}}{{KB`{KAb}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bc[\"{{{AHEf{AGId}}}{{KB`{JNf}}}}\",[]]Am[\"{{{AHEf{ANOb}}JNf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}NFf}\",[]]Bg[\"{{{AHEf{AIEf}}}{{KBj{CCnAOLn}}}}\",[]]Bg[\"{{{AHEf{AIEh}}}{{KBj{CCnAOMf}}}}\",[]]A`[\"{B@ObKB`}\",[]]A`[\"{B@OdKB`}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{ANJlKB`}\",[]]Ck[\"{{{AHEf{CEdBAM`}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAM`}}}}\",[]]Ck[\"{{{AHEf{CEdBAMb}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAMb}}}}\",[]]A`[\"{BE@bKB`}\",[]]A`[\"{BE@dKB`}\",[]]Ac[\"{AHEfc{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]000000000000000000000000000000000000000000000000000Al[\"{HOh{{KBj{KDfBFFf}}}}\",[]]Al[\"{JNf{{KBj{KDfBFFf}}}}\",[]]2Al[\"{CLf{{KBj{KDfBFFf}}}}\",[]]333333333333333Aj[\"{AAJb{{KBj{ANLj}}}}\",[]]44444Ai[\"{CLf{{KBj{AGJb}}}}\",[]]5555555555555555555555555555Aj[\"{AOKn{{KBj{BDGn}}}}\",[]]Bb[\"{{{Nn{AOKn}}}{{KBj{BDGn}}}}\",[]]777Bb[\"{{{Nn{B@B`}}}{{KBj{BDHb}}}}\",[]]Aj[\"{B@B`{{KBj{BDHb}}}}\",[]]999999999999999999999Al[\"{JNf{{KBj{KDhBFFh}}}}\",[]]Al[\"{HOh{{KBj{KDhBFFh}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFh}}}}\",[]]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Bm[\"{AOKn{{KBj{BDH`c}}}{}}\",[\"TryFrom::Error\"]]Ce[\"{{{Nn{AOKn}}}{{KBj{BDH`c}}}{}}\",[\"TryFrom::Error\"]]Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]0Ce[\"{{{Nn{B@B`}}}{{KBj{BDHdc}}}{}}\",[\"TryFrom::Error\"]]Bm[\"{B@B`{{KBj{BDHdc}}}{}}\",[\"TryFrom::Error\"]]22222222222222222222222Aj[\"{{}{{KBj{c}}}{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cd[\"{{{AAd{{AHEf{CEdc}}}}{AHEf{CEdNDb}}}COf{}}\",[\"F\"]]000000000Cc[\"{{{AHEf{BB@l}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bk[\"{{{AHEf{BFLf}}AON`}{{KBj{HOjAIBh}}}}\",[]]Bk[\"{{{AHEf{BFLh}}AONb}{{KBj{HOjAIBj}}}}\",[]]0Bk[\"{{{AHEf{BGLl}}AONb}{{KBj{HOjAIBj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AAHn}\",[]]Bi[\"{{{AHEf{CEdB@Cd}}}{{KBj{KDfIB`}}}}\",[]]Bi[\"{{{AHEf{CEdB@Cd}}}{{KBj{COlIB`}}}}\",[]]Bh[\"{{{AHEf{CEdB@Cd}}}{{KBj{OlIB`}}}}\",[]]Bj[\"{{{AHEf{CEdB@Cd}}}{{KBj{AAMbIB`}}}}\",[]]Bf[\"{{{AHEf{CEdB@Cd}}}{{KC`{KDh}}}}\",[]]Bf[\"{{{AHEf{CEdB@Cd}}}{{KC`{COn}}}}\",[]]Be[\"{{{AHEf{CEdB@Cd}}}{{KC`{On}}}}\",[]]Bg[\"{{{AHEf{CEdB@Cd}}}{{KC`{AAMd}}}}\",[]]Aa[\"{ANK`BFFd}\",[]]Bc[\"{{{AHEf{AIAj}}}{{Of{AIAj}}}}\",[]]Ba[\"{{{AHEf{O`}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{I@h}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{NF`}}}{{Of{AIAj}}}}\",[]]Bc[\"{{{AHEf{AIAl}}}{{Of{AIAl}}}}\",[]]Ba[\"{{{AHEf{Ob}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{I@j}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{NFb}}}{{Of{AIAl}}}}\",[]]A`[\"{AANlCLf}\",[]]An[\"{{{AHEf{CEdAIAh}}}AGId}\",[]]A`[\"{AANnCLf}\",[]]C`[\"{{{AHEf{CEdAON`}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]C`[\"{{{AHEf{CEdAONb}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]Ah[\"{Nd{{KB`{AONj}}}}\",[]]Ah[\"{Nd{{KB`{AONl}}}}\",[]]Ah[\"{Nd{{KB`{AONn}}}}\",[]]A`[\"{AAMbCOl}\",[]]A`[\"{AAMdCOn}\",[]]Bi[\"{AIAb{{KBj{{JNd{AIAfBBO`}}AIAb}}}}\",[]]Aa[\"{{}c{}}\",[\"I\"]]o[\"{COlD@n}\",[]]o[\"{COnD@n}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]21Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}D@n}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}D@n}{{AHEf{CEdB@Bh}}}}\",[]]Bl[\"{{{AHEf{NGh}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{B@Cb}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{ANNf}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Ak[\"{{{AHEf{AIAf}}}AALd}\",[]]Bc[\"{{{AHEf{AIAf}}AIElAID`}AALf}\",[]]Ce[\"{{{AHEf{CEdAIAh}}AGJ`AIDbNEd}{{KBj{KBfAGKl}}}}\",[]]43Bm[\"{{{AHEf{CEdAIAh}}KBf}{{KBj{HOjAI@n}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdBFF`}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBDD`}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdAICn}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBENb}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]Ec[\"{{{AHEf{CEdAIDj}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBj{JNfAGLh}}}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEdNGb}}}{{COf{{KBl{HOj}}}}}}\",[]]Ef[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Fg[\"{{{AHEf{CEdBAKh}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Dn[\"{{{AAd{{AHEf{CEdAGM`}}}}{AHEf{AANj}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]>=Cd[\"{{{AHEf{CEdBAM`}}{Nn{NDn}}}{{AHEf{CEdBAM`}}}}\",[]]Cd[\"{{{AHEf{CEdBAMb}}{Nn{NE`}}}{{AHEf{CEdBAMb}}}}\",[]]Cj[\"{{{AHEf{B@Bf}}CLdAON`{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHb}}CLdAON`{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{B@Bj}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHd}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BGGf}}CLdAOMn{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Bb[\"{JNf{{JNd{JNf{KB`{JNf}}}}}}\",[]]000Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]A`[\"{AHEfKDb}\",[]]00000000000000000000000000000000000000000000000000000000000000Ce[\"{{{AHEf{CEdB@Bd}}{Nn{BE@f}}}{{AHEf{CEdB@Bd}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{BE@h}}}{{AHEf{CEdB@Bh}}}}\",[]]A`[\"{BGAjICf}\",[]]o[\"{B@BdNn}\",[]]o[\"{B@BhNn}\",[]]Aj[\"{{{AHEf{AAJf}}}HOj}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}JNf}\",[]]Ak[\"{{{AHEf{AIAf}}}AGGh}\",[]]Ba[\"{{{AHEf{CEdAANl}}AANl}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBb}}AIBb}HOj}\",[]]Ba[\"{{{AHEf{CEdBBL`}}AGLb}HOj}\",[]]Ba[\"{{{AHEf{CEdAANn}}AANn}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBd}}AIBd}HOj}\",[]]Ba[\"{{{AHEf{CEdBBLb}}AGLd}HOj}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Bi[\"{{{AHEf{CEd}}}{{AHEf{CEdc}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bc[\"{{AHEf{AHEf{CEdc}}}HOj{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cc[\"{{{AHEf{CEdAIAh}}NEdKBfKDh}{{KBj{HOjBAKn}}}}\",[]]A`[\"{AGHnD@n}\",[]]B`[\"{{AHEf{AHEf{c}}}D@n{}}\",[\"K\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Aa[\"{BBKbBEI`}\",[]]A`[\"{BDDdKDf}\",[]]Aa[\"{BBKfBEIb}\",[]]A`[\"{BDDhKDh}\",[]]A`[\"{BDOfKDh}\",[]]A`[\"{BBMhKDh}\",[]]o[\"{NGnKDh}\",[]]Aa[\"{BBKbAIBn}\",[]]Aa[\"{BBKfAIC`}\",[]]o[\"{KDfCLf}\",[]]o[\"{KDhCLf}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Aj[\"{{{AHEf{B@Nl}}}D@n}\",[]]Bd[\"{{{AHEf{BAKh}}}{{KBl{AIEl}}}}\",[]]Bd[\"{{{AHEf{AAJf}}}{{KBl{AIEl}}}}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]Cb[\"{{{AHEf{BBLj}}{AHEf{AIEd}}CLf}{{Nn{ANOb}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AGLb}}}}\",[]]Bj[\"{{{AHEf{CEdAIAh}}KBf}{{KB`{AGLd}}}}\",[]]o[\"{AGIhOf}\",[]]Db[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]00Eg[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBj{JNfAIGb}}}}}}\",[]]Ec[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]0Bm[\"{{{AHEf{IDl}}{AHEf{CNl}}}{{KBl{HOj}}}}\",[]]Cd[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cd[\"{{{AHEf{CEdBEO`}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cn[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{HOjBAOn}}}}\",[]]Bj[\"{{{AHEf{CNn}}AID`}{{KBj{HOjBEHf}}}}\",[]]Bn[\"{{{AHEf{CEdAIDd}}NEd}{{AHEf{CEdAIDd}}}}\",[]]Bn[\"{{{AHEf{CEdAIDf}}NEd}{{AHEf{CEdAIDf}}}}\",[]]A`[\"{BB@dAFd}\",[]]o[\"{IDjCLf}\",[]]o[\"{{}AIEl}\",[]]0o[\"{{}AHEf}\",[]]Bj[\"{{AAJn{Nn{B@Bd}}}{{KBj{AIAbBBKh}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bh[\"{{{AHEf{AGHn}}AIEl}{{KBn{AGMb}}}}\",[]]A`[\"{AGLbCLb}\",[]]Aj[\"{{{AHEf{AIAh}}}CLb}\",[]]A`[\"{AGLdCLb}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Aa[\"{AANfAIEl}\",[]]Aa[\"{AANhAIEl}\",[]]Aa[\"{AANjAIEl}\",[]]Aa[\"{AIElAGJ`}\",[]]o[\"{A@lCLb}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLb}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLb}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnCLb}\",[]]Bo[\"{{{AHEf{CEdBBNf}}AAJb}{{AHEf{CEdBBNf}}}}\",[]]Bo[\"{{{AHEf{CEdBBNh}}AAJb}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnKB`}\",[]]k[\"{{}}\",[]]0000000000Bh[\"{AAJnc{}}\",[\"IntoFuture::IntoFuture\"]]11A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{A@lJNf}\",[]]Ao[\"{{AHEfc}{{NEj{c}}}{}}\",[\"S\"]]0C`[\"{{{AHEf{CEdAIAj}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdO`}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]C`[\"{{{AHEf{CEdAIAl}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdOb}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bk[\"{{{AHEf{CEdIDl}}NEd{AHEf{BBLj}}}HOj}\",[]]A`[\"{BE@bKB`}\",[]]A`[\"{BE@dKB`}\",[]]Bn[\"{{{AHEf{KDf}}{AHEf{KDf}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBd}}{AHEf{KBd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AON`}}{AHEf{AON`}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COl}}{AHEf{COl}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{Ol}}{AHEf{Ol}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KDh}}{AHEf{KDh}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEAl}}{AHEf{BEAl}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBf}}{AHEf{KBf}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BABb}}{AHEf{BABb}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AONb}}{AHEf{AONb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COn}}{AHEf{COn}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{On}}{AHEf{On}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}{{KB`{AALh}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AICn}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AIDbAI@n}}}}\",[]]Df[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{HOn}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Cc[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{AAj{Nd}}BB@`}}}}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIDl}\",[]]Aj[\"{{{AHEf{AGJh}}}JNf}\",[]]Aj[\"{{{AHEf{AGJj}}}JNf}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIEh}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLf}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{B@ObKB`}\",[]]A`[\"{B@OdKB`}\",[]]Ce[\"{{{AHEf{CEdB@Bd}}{Nn{AIFd}}}{{AHEf{CEdB@Bd}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{AIFf}}}{{AHEf{CEdB@Bh}}}}\",[]]Ce[\"{{{AHEf{CEdAOLb}}{Nn{AIFl}}}{{AHEf{CEdAOLb}}}}\",[]]Ce[\"{{{AHEf{CEdAOLf}}{Nn{AIFn}}}{{AHEf{CEdAOLf}}}}\",[]]o[\"{A@lCLf}\",[]]Bn[\"{{{AHEf{CEdBEFh}}CLb}{{AHEf{CEdBEFh}}}}\",[]]Bn[\"{{{AHEf{CEdBEFj}}CLb}{{AHEf{CEdBEFj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BFFl}\",[]]Aj[\"{{{AHEf{CNn}}}BB@n}\",[]]Ai[\"{{{Nn{B@Bf}}}B@Bd}\",[]]Ai[\"{{{Nn{B@Bj}}}B@Bh}\",[]]Aj[\"{{BBMdc}BBMdAAMl}\",[\"\"]]Aj[\"{{BBMfc}BBMfAAMl}\",[\"\"]]Bm[\"{{{AHEf{CEdAIEf}}HOn}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}KAb}\",[]]o[\"{ND`ND`}\",[]]0000Bd[\"{{{AHEf{BFLf}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BFLh}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGLl}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGMf}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{AIAf}}}{{KB`{BBKh}}}}\",[]]Ck[\"{{{AHEf{AAJf}}AOLbAIEl{AHEf{CL`}}}{{KBj{AIAbAOMj}}}}\",[]]Ak[\"{{{AHEf{B@Al}}}AAJb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{AIDhD@n}{{KBn{JNf}}}}\",[]]Cj[\"{{{AHEf{NGj}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFh}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Cj[\"{{{AHEf{NGl}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFj}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]A`[\"{BFDnAAj}\",[]]A`[\"{BH@jAAj}\",[]]A`[\"{BFE`AAj}\",[]]A`[\"{BH@lAAj}\",[]]An[\"{{{AHEf{CEdBFLf}}}AON`}\",[]]An[\"{{{AHEf{CEdBFLh}}}AONb}\",[]]An[\"{{{AHEf{CEdBGLl}}}AONb}\",[]]An[\"{{{AHEf{CEdBGMf}}}AONb}\",[]]Ak[\"{{{AHEf{BB@l}}}B@@b}\",[]]Ba[\"{{{AHEf{CEdAIAh}}BBKn}HOj}\",[]]Bo[\"{{{AHEf{CEdAAJh}}BDE`B@Nl}{{KB`{BBKn}}}}\",[]]B`[\"{{{AHEf{NGj}}AON`COl}CNb}\",[]]Bn[\"{{{AHEf{B@Bf}}CLdAON`}{{KBj{CNbBEIh}}}}\",[]]Ba[\"{{{AHEf{AIFh}}AON`COl}CNb}\",[]]Bn[\"{{{AHEf{BDHb}}CLdAON`}{{KBj{CNbBEIh}}}}\",[]]B`[\"{{{AHEf{NGl}}AONbCOn}CNd}\",[]]Bn[\"{{{AHEf{B@Bj}}CLdAONb}{{KBj{CNdBEIn}}}}\",[]]Ba[\"{{{AHEf{AIFj}}AONbCOn}CNd}\",[]]Bn[\"{{{AHEf{BDHd}}CLdAONb}{{KBj{CNdBEIn}}}}\",[]]Bn[\"{{{AHEf{BGGf}}CLdAOMn}{{KBj{CNdBEIn}}}}\",[]]Aj[\"{{}{{NGd{c}}}{}}\",[\"T\"]]0A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}JNf}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}JNf}{{AHEf{CEdB@Bh}}}}\",[]]Aj[\"{{{AHEf{BAKh}}}D@n}\",[]]0Aj[\"{{{AHEf{BB@l}}}D@n}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AGJ`AI@n}}}}\",[]]Cb[\"{{{AHEf{BBLj}}{AHEf{AIDh}}CLf}{{Nn{ANOb}}}}\",[]]Ak[\"{{{AHEf{AAJn}}}AON`}\",[]]Ak[\"{{{AHEf{AAK`}}}AONb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{NEd}}}}\",[]]Ce[\"{{{AHEf{CEdBBNf}}{Nn{ANMh}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{Nn{ANMj}}}{{AHEf{CEdBBNh}}}}\",[]]43A`[\"{A@lANN`}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Ai[\"{{{AHEf{NHj}}}JNf}\",[]]Bo[\"{{{AHEf{CEdBGLl}}AAJb}{{AHEf{CEdBGLl}}}}\",[]]Bo[\"{{{AHEf{CEdBGMf}}AAJb}{{AHEf{CEdBGMf}}}}\",[]]Bj[\"{{{AHEf{AIEf}}CCn}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}CCn}{{KBj{HOjAOMf}}}}\",[]]==E`[\"{{{AHEf{BGAl}}{AHEf{{JL`{Nd}}}}{AHEf{BAKj}}{AHEf{BFLj}}}{{KBj{BGDbIAh}}}}\",[]]0Bf[\"{{{Nn{BABh}}}{{KBj{AOLbBFFj}}}}\",[]]Bf[\"{{{Nn{BABh}}}{{KBj{AOLfBFFj}}}}\",[]]Bn[\"{{{AHEf{CEdBEDj}}KDf}{{AHEf{CEdBEDj}}}}\",[]]Bn[\"{{{AHEf{CEdBEDl}}KDh}{{AHEf{CEdBEDl}}}}\",[]]o[\"{ND`ND`}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]0Ci[\"{{{AHEf{CNn}}{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@h}}}}\",[]]Cd[\"{{{AHEf{CEdA@l}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cc[\"{{{AHEf{CEdOj}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAAId}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAGHn}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdA@n}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdAA`}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bd}}BFMh}{{AHEf{CEdB@Bd}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bh}}BFMj}{{AHEf{CEdB@Bh}}}}\",[]]Aj[\"{{{AHEf{BAM`}}}CLf}\",[]]Aj[\"{{{AHEf{BAMb}}}CLf}\",[]]Cc[\"{{{AHEf{CEdAOLb}}{Nn{A`}}}{{AHEf{CEdAOLb}}}}\",[]]Cc[\"{{{AHEf{CEdAOLf}}{Nn{A`}}}{{AHEf{CEdAOLf}}}}\",[]]Cj[\"{{BAM`{KB`{B@Bd}}{Of{BAKh}}{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Ca[\"{{{AHEf{CEdAIAh}}NEdAICd}{{KBj{HOjBGAb}}}}\",[]]Bd[\"{{{AHEf{BGAl}}}{{AAj{BBMl}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}JNf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}JNf}{{AHEf{CEdBBNh}}}}\",[]]Bl[\"{{}{{KBj{{JNd{BAKjBEGd}}{Of{IAd}}}}}}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{{AHEf{AAJf}}AOLb}HOj}\",[]]Dc[\"{{{AHEf{CEdAIAh}}NEdKBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]o[\"{{}AHEf}\",[]]Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}CLf}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}CLf}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}KDf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}KDh}{{AHEf{CEdBBNh}}}}\",[]]:Bb[\"{{{AHEf{CEdAIAh}}OnKDh}HOj}\",[]]Ak[\"{{}{{KBj{AOLbIBb}}}}\",[]]Ak[\"{{}{{KBj{AOLfIBd}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]65Cg[\"{{{AHEf{CEdA@l}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cf[\"{{{AHEf{CEdOj}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAAId}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAGHn}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdA@n}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdAA`}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Bi[\"{{{AHEf{CEdAGJ`}}{AHEf{AGJ`}}}D@n}\",[]]n[\"{{}HOj}\",[]]Ce[\"{{{AHEf{CEdBBNf}}{KB`{JNf}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{KB`{JNf}}}{{AHEf{CEdBBNh}}}}\",[]]Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Cd[\"{{{AHEf{CEdAIAh}}NEd}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Am[\"{{{AHEf{CEdAIAj}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@h}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIAl}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@j}}}HOj}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]D`[\"{{{AHEf{CEdAIAh}}KBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]Ce[\"{{{AHEf{CEdBBNf}}{Nn{BDOn}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{Nn{BE@`}}}{{AHEf{CEdBBNh}}}}\",[]]Cf[\"{{{AHEf{CEdBBNf}}{KB`{AAJb}}}{{AHEf{CEdBBNf}}}}\",[]]Cf[\"{{{AHEf{CEdBBNh}}{KB`{AAJb}}}{{AHEf{CEdBBNh}}}}\",[]]Aa[\"{B@ObAICb}\",[]]Aa[\"{B@OdAICb}\",[]]9Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Am[\"{{{AHEf{AIAf}}KDf}HOj}\",[]]o[\"{ND`ND`}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLd}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLd}{{AHEf{CEdBBNh}}}}\",[]]3109854Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Bn[\"{{{AHEf{AIAh}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]10A`[\"{BENnKB`}\",[]]Bm[\"{{{AHEf{CEdBBNf}}Nd}{{AHEf{CEdBBNf}}}}\",[]]Bm[\"{{{AHEf{CEdBBNh}}Nd}{{AHEf{CEdBBNh}}}}\",[]]o[\"{{}AICd}\",[]]") \ No newline at end of file +rd_("Bf[\"{{{AHEf{ANK`}}{AHEf{ANK`}}}D@n}\",[]]Bf[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}D@n}\",[]]Bd[\"{{{AHEf{KAd}}{AHEf{KAd}}}D@n}\",[]]Bd[\"{{{AHEf{CNn}}{AHEf{CNn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@n}}{AHEf{BB@n}}}D@n}\",[]]Bf[\"{{{AHEf{BB@`}}{AHEf{BB@`}}}D@n}\",[]]Bf[\"{{{AHEf{AGLh}}{AHEf{AGLh}}}D@n}\",[]]Bf[\"{{{AHEf{AIDn}}{AHEf{AIDn}}}D@n}\",[]]Bf[\"{{{AHEf{BAOn}}{AHEf{BAOn}}}D@n}\",[]]Bf[\"{{{AHEf{AIGb}}{AHEf{AIGb}}}D@n}\",[]]Bf[\"{{{AHEf{B@C`}}{AHEf{B@C`}}}D@n}\",[]]Bd[\"{{{AHEf{KDf}}{AHEf{KDf}}}D@n}\",[]]Bf[\"{{{AHEf{BFFf}}{AHEf{BFFf}}}D@n}\",[]]Bd[\"{{{AHEf{I@`}}{AHEf{I@`}}}D@n}\",[]]Bd[\"{{{AHEf{KBd}}{AHEf{KBd}}}D@n}\",[]]Bf[\"{{{AHEf{AANl}}{AHEf{AANl}}}D@n}\",[]]Bf[\"{{{AHEf{AIBb}}{AHEf{AIBb}}}D@n}\",[]]Bf[\"{{{AHEf{AGLb}}{AHEf{AGLb}}}D@n}\",[]]Bd[\"{{{AHEf{NIf}}{AHEf{NIf}}}D@n}\",[]]Bf[\"{{{AHEf{AOLn}}{AHEf{AOLn}}}D@n}\",[]]Bf[\"{{{AHEf{BBKh}}{AHEf{BBKh}}}D@n}\",[]]Bf[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}D@n}\",[]]Bf[\"{{{AHEf{ANKf}}{AHEf{ANKf}}}D@n}\",[]]Bf[\"{{{AHEf{AGJb}}{AHEf{AGJb}}}D@n}\",[]]Bf[\"{{{AHEf{BBKb}}{AHEf{BBKb}}}D@n}\",[]]Bf[\"{{{AHEf{BDDd}}{AHEf{BDDd}}}D@n}\",[]]Bf[\"{{{AHEf{AOMj}}{AHEf{AOMj}}}D@n}\",[]]Bf[\"{{{AHEf{AON`}}{AHEf{AON`}}}D@n}\",[]]Bf[\"{{{AHEf{AONj}}{AHEf{AONj}}}D@n}\",[]]Bf[\"{{{AHEf{BEI`}}{AHEf{BEI`}}}D@n}\",[]]Bd[\"{{{AHEf{COl}}{AHEf{COl}}}D@n}\",[]]Bb[\"{{{AHEf{Ol}}{AHEf{Ol}}}D@n}\",[]]Bf[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}D@n}\",[]]Bf[\"{{{AHEf{BGI`}}{AHEf{BGI`}}}D@n}\",[]]Bd[\"{{{AHEf{IBb}}{AHEf{IBb}}}D@n}\",[]]Bd[\"{{{AHEf{KDh}}{AHEf{KDh}}}D@n}\",[]]Bf[\"{{{AHEf{BFFh}}{AHEf{BFFh}}}D@n}\",[]]Bd[\"{{{AHEf{I@b}}{AHEf{I@b}}}D@n}\",[]]Bf[\"{{{AHEf{BEAl}}{AHEf{BEAl}}}D@n}\",[]]Bd[\"{{{AHEf{KBf}}{AHEf{KBf}}}D@n}\",[]]Bf[\"{{{AHEf{AIDb}}{AHEf{AIDb}}}D@n}\",[]]Bf[\"{{{AHEf{AGL`}}{AHEf{AGL`}}}D@n}\",[]]Bf[\"{{{AHEf{BEAh}}{AHEf{BEAh}}}D@n}\",[]]Bf[\"{{{AHEf{BEHh}}{AHEf{BEHh}}}D@n}\",[]]Bf[\"{{{AHEf{AI@n}}{AHEf{AI@n}}}D@n}\",[]]Bf[\"{{{AHEf{AANn}}{AHEf{AANn}}}D@n}\",[]]Bf[\"{{{AHEf{AIBd}}{AHEf{AIBd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLd}}{AHEf{AGLd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}D@n}\",[]]Bf[\"{{{AHEf{BABb}}{AHEf{BABb}}}D@n}\",[]]Bd[\"{{{AHEf{NIh}}{AHEf{NIh}}}D@n}\",[]]Bf[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}D@n}\",[]]Bf[\"{{{AHEf{ANLh}}{AHEf{ANLh}}}D@n}\",[]]Bf[\"{{{AHEf{ANNn}}{AHEf{ANNn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@b}}{AHEf{BB@b}}}D@n}\",[]]Bf[\"{{{AHEf{AOMf}}{AHEf{AOMf}}}D@n}\",[]]Bf[\"{{{AHEf{BBKj}}{AHEf{BBKj}}}D@n}\",[]]Bf[\"{{{AHEf{AGKl}}{AHEf{AGKl}}}D@n}\",[]]Bf[\"{{{AHEf{BAKn}}{AHEf{BAKn}}}D@n}\",[]]Bf[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}D@n}\",[]]Bf[\"{{{AHEf{ANKh}}{AHEf{ANKh}}}D@n}\",[]]Bf[\"{{{AHEf{AGJd}}{AHEf{AGJd}}}D@n}\",[]]Bf[\"{{{AHEf{BAMl}}{AHEf{BAMl}}}D@n}\",[]]Bf[\"{{{AHEf{AIC`}}{AHEf{AIC`}}}D@n}\",[]]Bf[\"{{{AHEf{AIEn}}{AHEf{AIEn}}}D@n}\",[]]Bf[\"{{{AHEf{AONd}}{AHEf{AONd}}}D@n}\",[]]Bf[\"{{{AHEf{BBKf}}{AHEf{BBKf}}}D@n}\",[]]Bf[\"{{{AHEf{BDDh}}{AHEf{BDDh}}}D@n}\",[]]Bf[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}D@n}\",[]]Bf[\"{{{AHEf{AOMl}}{AHEf{AOMl}}}D@n}\",[]]Bf[\"{{{AHEf{AAKf}}{AHEf{AAKf}}}D@n}\",[]]Bf[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}D@n}\",[]]Bf[\"{{{AHEf{AONb}}{AHEf{AONb}}}D@n}\",[]]Bf[\"{{{AHEf{AONl}}{AHEf{AONl}}}D@n}\",[]]Bf[\"{{{AHEf{BB@j}}{AHEf{BB@j}}}D@n}\",[]]Bf[\"{{{AHEf{BEIb}}{AHEf{BEIb}}}D@n}\",[]]Bd[\"{{{AHEf{COn}}{AHEf{COn}}}D@n}\",[]]Bb[\"{{{AHEf{On}}{AHEf{On}}}D@n}\",[]]Bf[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}D@n}\",[]]Bf[\"{{{AHEf{AGJ`}}{AHEf{AGJ`}}}D@n}\",[]]Bf[\"{{{AHEf{BABn}}{AHEf{BABn}}}D@n}\",[]]Bf[\"{{{AHEf{BENn}}{AHEf{BENn}}}D@n}\",[]]Bd[\"{{{AHEf{IBf}}{AHEf{IBf}}}D@n}\",[]]Bf[\"{{{AHEf{BGIb}}{AHEf{BGIb}}}D@n}\",[]]Bd[\"{{{AHEf{IBd}}{AHEf{IBd}}}D@n}\",[]]Bf[\"{{{AHEf{AONn}}{AHEf{AONn}}}D@n}\",[]]Ai[\"{{{AHEf{CNn}}}KBd}\",[]]Aj[\"{{{AHEf{BB@n}}}KBd}\",[]]Ak[\"{{{AHEf{AIDj}}}AAMb}\",[]]Ak[\"{{{AHEf{BEO`}}}AAMb}\",[]]Ak[\"{{{AHEf{AIEf}}}AAMb}\",[]]o[\"{KAhKBf}\",[]]A`[\"{AGGdKBf}\",[]]A`[\"{AGIhKBf}\",[]]A`[\"{B@AfKBf}\",[]]A`[\"{B@@hKBf}\",[]]Aa[\"{AALjAAMd}\",[]]Aa[\"{AAObAAMd}\",[]]Aa[\"{AAJjAAMd}\",[]]A`[\"{NGnAAMd}\",[]]A`[\"{ANN`NGf}\",[]]A`[\"{CNfAAKf}\",[]]Ac[\"{{AANlAANl}}\",[]]Ac[\"{{AIBbAIBb}}\",[]]Ac[\"{{BBL`AGLb}}\",[]]Bc[\"{{AANnAANn}c{}}\",[\"Add::Output\"]]Bc[\"{{AIBdAIBd}c{}}\",[\"Add::Output\"]]Bc[\"{{BBLbAGLd}c{}}\",[\"Add::Output\"]]Be[\"{{{AHEf{KDf}}{AHEf{KDf}}}AALh}\",[]]Be[\"{{{AHEf{KBd}}{AHEf{KBd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}AALh}\",[]]Bg[\"{{{AHEf{AON`}}{AHEf{AON`}}}AALh}\",[]]Be[\"{{{AHEf{COl}}{AHEf{COl}}}AALh}\",[]]Bc[\"{{{AHEf{Ol}}{AHEf{Ol}}}AALh}\",[]]Bg[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}AALh}\",[]]Be[\"{{{AHEf{KDh}}{AHEf{KDh}}}AALh}\",[]]Bg[\"{{{AHEf{BEAl}}{AHEf{BEAl}}}AALh}\",[]]Be[\"{{{AHEf{KBf}}{AHEf{KBf}}}AALh}\",[]]Bg[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}AALh}\",[]]Bg[\"{{{AHEf{BABb}}{AHEf{BABb}}}AALh}\",[]]Bg[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}AALh}\",[]]Bg[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}AALh}\",[]]Bg[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}AALh}\",[]]Bg[\"{{{AHEf{AONb}}{AHEf{AONb}}}AALh}\",[]]Be[\"{{{AHEf{COn}}{AHEf{COn}}}AALh}\",[]]Bc[\"{{{AHEf{On}}{AHEf{On}}}AALh}\",[]]Bg[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}AALh}\",[]]o[\"{AAMbOl}\",[]]o[\"{AAMdOn}\",[]]n[\"{KAjOn}\",[]]o[\"{AGHbOn}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AALnKB`}\",[]]A`[\"{AANjKB`}\",[]]Bh[\"{{{AHEf{A@l}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANN`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@d}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGAl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFF`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFFl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAJf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Nn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AICn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BENb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIE`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAMj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{CNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@n}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEO`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIDn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAOn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Cb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANNf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@C`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NHb}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{KDf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFFf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Cd[\"{{{AHEf{I@`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{KBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AIBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGLb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBMd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBNf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEDj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEFh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANLj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAM`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{B@Bd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BFMh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AGJb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BDDd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AOMj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AON`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AONj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEI`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AIBh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BDHf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{COl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{Ol}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AAMb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{O`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGHh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{I@h}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NF`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAAb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BE@b}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BGI`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEIh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{IBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFEl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{AIAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BFFh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{I@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{KBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Al}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGL`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEHh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AI@n}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIBd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BABb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NIh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAKn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGAb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBNh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEDl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEFj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAMb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Bh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFMj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOLf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGJd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAMl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIC`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAIj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDE`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANJl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGAj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAKf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Nl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@j}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BEIb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIBj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGMf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BDHh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{COn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bg[\"{{{AHEf{On}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAMd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGJ`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BABn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BENn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGIb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEIn}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{IBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{BFEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bg[\"{{{AHEf{Ob}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGHj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{I@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{NFb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAAd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BE@d}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@l}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AALn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AANj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bd[\"{{{AHEf{BFF`}}}{{KB`{AIEl}}}}\",[]]Ak[\"{{{AHEf{B@Al}}}AAJb}\",[]]A`[\"{AANlCLf}\",[]]A`[\"{AANnCLf}\",[]]Aj[\"{{{AHEf{BAAh}}}JNf}\",[]]A`[\"{BGAjCLf}\",[]]o[\"{CNfCLf}\",[]]A`[\"{AALnJNf}\",[]]Ce[\"{{{AHEf{CEdBFMh}}{Nn{AAMn}}}{{AHEf{CEdBFMh}}}}\",[]]Ce[\"{{{AHEf{CEdBFMj}}{Nn{AAN`}}}{{AHEf{CEdBFMj}}}}\",[]]8Af[\"{{AAJbCLf}BB@d}\",[]]Ag[\"{{}{{Nn{BGAl}}}}\",[]]Ae[\"{{JNfCLd}B@Ml}\",[]]Cd[\"{{BAM`{KB`{B@Bd}}AGMb{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Ah[\"{{{Of{IEb}}}AIDd}\",[]]A`[\"{NG`BBMd}\",[]]Ah[\"{{{Nn{NDn}}}BAM`}\",[]]Bc[\"{{{Nn{B@Bf}}{Nn{BE@f}}}B@Bd}\",[]]Ai[\"{{{Nn{AOLd}}}AOLb}\",[]]B`[\"{{{AHEf{{JL`{Nd}}}}}AON`}\",[]]Ae[\"{{CLdJNf}BDHf}\",[]]Ag[\"{{COlOlCLf}AAMb}\",[]]Aj[\"{{{Nn{AGHh}}CLb}O`}\",[]]An[\"{{{Nn{ANL`}}NEdCLb}I@h}\",[]]An[\"{{{Nn{BAAb}}NEdCLb}NF`}\",[]]Ae[\"{{JNfCLd}B@Mn}\",[]]Ah[\"{{{Of{IEb}}}AIDf}\",[]]Bm[\"{{{Nn{BAMb}}{KB`{{Nn{B@Bh}}}}D@n}AAJh}\",[]]A`[\"{JNfBH@h}\",[]]o[\"{{}BGLl}\",[]]A`[\"{NG`BBMf}\",[]]Ah[\"{{{Nn{NE`}}}BAMb}\",[]]Bc[\"{{{Nn{B@Bj}}{Nn{BE@h}}}B@Bh}\",[]]Ai[\"{{{Nn{AOLh}}}AOLf}\",[]]Ek[\"{{AAI`{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{{JNd{BAAh{KB`{AAI`}}}}BEAd}}}{BEEfIDh}}\",[\"\"]]B`[\"{{{AHEf{{JL`{Nd}}}}}AONb}\",[]]Af[\"{{BEIbKDb}BB@j}\",[]]A`[\"{JNfBGMf}\",[]]Ae[\"{{CLdJNf}BDHh}\",[]]Ag[\"{{COnOnCLf}AAMd}\",[]]Am[\"{{AIEl{KB`{KAb}}}AGJ`}\",[]]Aj[\"{{{Nn{AGHj}}CLb}Ob}\",[]]An[\"{{{Nn{ANLb}}NEdCLb}I@j}\",[]]An[\"{{{Nn{BAAd}}NEdCLb}NFb}\",[]]Aj[\"{AIG`{{KBl{BB@l}}}}\",[]]Aa[\"{BDH`BGGd}\",[]]Aa[\"{BDHdBGGf}\",[]]o[\"{COlCOl}\",[]]o[\"{COnCOn}\",[]]Ak[\"{{{AHEf{AIFd}}}AIFb}\",[]]Ai[\"{{{AHEf{NGh}}}NEd}\",[]]0Aj[\"{{{AHEf{B@Cb}}}NEd}\",[]]Ak[\"{{{AHEf{BABj}}}AIFb}\",[]]Ak[\"{{{AHEf{AIFf}}}AIFb}\",[]]Ak[\"{{{AHEf{BABl}}}AIFb}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLbAAJb}\",[]]Bg[\"{{{AHEf{AIAh}}KBf}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLdAAJb}\",[]]Ah[\"{A@n{{KBn{HOj}}}}\",[]]Ah[\"{AA`{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{B@@hAIEl}\",[]]Aa[\"{AALnAIEl}\",[]]Aa[\"{BB@jBEIb}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{AAIjHOn}\",[]]Am[\"{{{AHEf{CEdAALd}}}HOj}\",[]]Am[\"{{{AHEf{CEdAAJn}}}HOj}\",[]]Al[\"{{{AHEf{CEdCNn}}}HOj}\",[]]Am[\"{{{AHEf{CEdBB@n}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIDj}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIEf}}}HOj}\",[]]Al[\"{{{AHEf{CEdJOn}}}HOj}\",[]]A`[\"{cc{}}\",[\"T\"]]0000000000000000000000Aa[\"{BBKhBEAj}\",[]]111111111111111Aa[\"{AGLhBB@`}\",[]]2Aa[\"{AIDnAGLh}\",[]]Aa[\"{BBKhAGLh}\",[]]4Aa[\"{BBKhAIDn}\",[]]Aa[\"{AGLhBAOn}\",[]]6666Aa[\"{B@C`AIGb}\",[]]Aa[\"{AOLnAIGb}\",[]]Aa[\"{BBKhAIGb}\",[]]9Aa[\"{BBKhB@C`}\",[]]:::::::A`[\"{BEI`KDf}\",[]]n[\"{NdKDf}\",[]]o[\"{CLbKDf}\",[]]A`[\"{AAMbKDf}\",[]]o[\"{CLdKDf}\",[]]????Al[\"{cKBd{{CN`{CLd}}}}\",[\"T\"]]A`[\"{cc{}}\",[\"T\"]]00000A`[\"{IAjBBKh}\",[]]A`[\"{I@fBBKh}\",[]]2Aa[\"{ANKdBBKh}\",[]]3333A`[\"{KDfANLj}\",[]]444444Aa[\"{BFFfANKf}\",[]]Aa[\"{BBNjANKf}\",[]]6A`[\"{IAjBBKb}\",[]]777Aa[\"{BEIhAOMj}\",[]]88A`[\"{KDfBEI`}\",[]]99999A`[\"{KDfAAMb}\",[]]::::::::::::Aa[\"{ANOdANKl}\",[]];;;;A`[\"{BDF`IBb}\",[]]A`[\"{BDGhIBb}\",[]]A`[\"{BBLdIBb}\",[]]A`[\"{BAMnIBb}\",[]]A`[\"{BAO`IBb}\",[]]A`[\"{BBMnIBb}\",[]]A`[\"{BGD`IBb}\",[]]A`[\"{BDDjIBb}\",[]]A`[\"{AICfIBb}\",[]]A`[\"{BGJ`IBb}\",[]]A`[\"{BGHnIBb}\",[]]A`[\"{cc{}}\",[\"T\"]]00000000000000000000000o[\"{CLdKDh}\",[]]A`[\"{AAMdKDh}\",[]]o[\"{CLbKDh}\",[]]n[\"{NdKDh}\",[]]4A`[\"{BEIbKDh}\",[]]5555Al[\"{cKBf{{CN`{CLd}}}}\",[\"T\"]]666666666666666666Aa[\"{BB@jBBKj}\",[]]77777A`[\"{AGL`IBl}\",[]]88888A`[\"{KDhANLl}\",[]]99999Aa[\"{BBNjANKh}\",[]]Aa[\"{BFFhANKh}\",[]];;;;;Aa[\"{BB@jBBKf}\",[]]<<<<>>>>>A`[\"{IBfBB@j}\",[]]A`[\"{KDhBEIb}\",[]]A`[\"{cc{}}\",[\"T\"]]00000A`[\"{KDhAAMd}\",[]]111111A`[\"{BABnIBf}\",[]]222Aa[\"{ANOdANKn}\",[]]3333A`[\"{BGJ`IBd}\",[]]A`[\"{BDF`IBd}\",[]]A`[\"{AICfIBd}\",[]]A`[\"{BDGhIBd}\",[]]7A`[\"{BBLdIBd}\",[]]A`[\"{BAO`IBd}\",[]]A`[\"{BBMnIBd}\",[]]A`[\"{BGHnIBd}\",[]]A`[\"{BDDjIBd}\",[]]A`[\"{BAMnIBd}\",[]]A`[\"{BGD`IBd}\",[]]>>>>>>>>>>>>An[\"{{{AHEf{c}}}AIG`CLl}\",[\"S\"]]??????????????Bm[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{ANLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AON`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{Ol}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEAl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{AGLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BABb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AIGd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{ANLl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BDE`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEAd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AONb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COn}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{On}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AGJ`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Aa[\"{{}c{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n[\"{{}HOj}\",[]]0000Cc[\"{{{AHEf{CEdJOn}}JNf}{{KBj{{KB`{I@b}}AGLj}}}}\",[]]Cf[\"{{{AHEf{CEdBA@`}}}{{KB`{c}}}{}}\",[\"Iterator::Item\"]]Dl[\"{{{AHEf{BE@f}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANKl}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Dl[\"{{{AHEf{BE@h}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANKn}}}}\",[]]Bf[\"{{{AHEf{AIAf}}KBd}{{KB`{CNn}}}}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjAI@h}}}}\",[]]A`[\"{AIBbCLf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}HOj}\",[]]A`[\"{AIBdCLf}\",[]]Ck[\"{{{AAd{{AHEf{CEdAI@`}}}}{AHEf{CEdNDb}}}{{COf{HOj}}}}\",[]]Dk[\"{{{AAd{{AHEf{CEdBBO`}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALd}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAIAb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNFf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdKAf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAGGh}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAAHn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@Ad}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@An}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdJNn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdBAMj}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNHb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{IBl}}}}\",[]]De[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}D@n}{{KBj{JOnBABb}}}}\",[]]Bo[\"{{COn{AHEf{CEdc}}}{{KBj{BENnIBf}}}Oh}\",[\"R\"]]Bf[\"{{{AHEf{CEdAGId}}}{{KB`{HOn}}}}\",[]]Ec[\"{{{AHEf{BB@l}}AIG`{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{KBl{JNf}}}}\",[]]Cn[\"{{{AHEf{BE@f}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANKl}}}}\",[]]Cn[\"{{{AHEf{BE@h}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANKn}}}}\",[]]C`[\"{{{AHEf{CEdAGId}}HOnD@n}{{KBj{HOjBEAl}}}}\",[]]Cc[\"{{{AHEf{BB@l}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bn[\"{{{AHEf{CEdBFMh}}CLd}{{AHEf{CEdBFMh}}}}\",[]]Bn[\"{{{AHEf{CEdBFMj}}CLd}{{AHEf{CEdBFMj}}}}\",[]]Aj[\"{{{AHEf{AIAf}}}COl}\",[]]Aj[\"{{{AHEf{AIAh}}}COn}\",[]]Cn[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cn[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]A`[\"{BB@dCLf}\",[]]A`[\"{AANfJNf}\",[]]A`[\"{AANhJNf}\",[]]o[\"{IDdD@n}\",[]]Bm[\"{{{AHEf{CEdAIDj}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdBEO`}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}KDh}{{KBj{HOjAOMf}}}}\",[]]Bn[\"{{{AHEf{AIFl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BANl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHf}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{AIFn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BANn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHh}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bd[\"{{{AHEf{BDEf}}}{{KB`{BA@`}}}}\",[]]Bg[\"{{{Nn{BDOn}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{AGHh}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{ANL`}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BAAb}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BE@`}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{AGHj}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{ANLb}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{BAAd}}NEdCLb}{{Of{AIAl}}}}\",[]]Ai[\"{BEN`{{Nn{BE@`}}}}\",[]]o[\"{I@`HOn}\",[]]A`[\"{AANlCLf}\",[]]o[\"{NIfJNf}\",[]]o[\"{I@bHOn}\",[]]A`[\"{AANnCLf}\",[]]o[\"{NIhJNf}\",[]]Aa[\"{ANJlBBKj}\",[]]Ai[\"{{{AHEf{A@l}}}A@l}\",[]]Ak[\"{{{AHEf{ANN`}}}ANN`}\",[]]Ak[\"{{{AHEf{ANK`}}}ANK`}\",[]]Ak[\"{{{AHEf{AIAf}}}AIAf}\",[]]Ak[\"{{{AHEf{BFFl}}}BFFl}\",[]]Ak[\"{{{AHEf{BEAj}}}BEAj}\",[]]Ak[\"{{{AHEf{AAJf}}}AAJf}\",[]]Ak[\"{{{AHEf{B@Nn}}}B@Nn}\",[]]Ai[\"{{{AHEf{KAd}}}KAd}\",[]]Ai[\"{{{AHEf{CNn}}}CNn}\",[]]Ak[\"{{{AHEf{BB@n}}}BB@n}\",[]]Ak[\"{{{AHEf{BB@`}}}BB@`}\",[]]Ak[\"{{{AHEf{AGLh}}}AGLh}\",[]]Ak[\"{{{AHEf{AIDn}}}AIDn}\",[]]Ak[\"{{{AHEf{BAOn}}}BAOn}\",[]]Ak[\"{{{AHEf{AIGb}}}AIGb}\",[]]Ak[\"{{{AHEf{B@C`}}}B@C`}\",[]]Ai[\"{{{AHEf{KDf}}}KDf}\",[]]Ak[\"{{{AHEf{BFFf}}}BFFf}\",[]]Ai[\"{{{AHEf{KBd}}}KBd}\",[]]Ak[\"{{{AHEf{AANl}}}AANl}\",[]]Ak[\"{{{AHEf{AIBb}}}AIBb}\",[]]Ak[\"{{{AHEf{AGLb}}}AGLb}\",[]]Ak[\"{{{AHEf{BBL`}}}BBL`}\",[]]Ai[\"{{{AHEf{NIf}}}NIf}\",[]]Ak[\"{{{AHEf{AOLn}}}AOLn}\",[]]Ak[\"{{{AHEf{BBKh}}}BBKh}\",[]]Ak[\"{{{AHEf{BBNf}}}BBNf}\",[]]Ak[\"{{{AHEf{BEDj}}}BEDj}\",[]]Ak[\"{{{AHEf{BEFh}}}BEFh}\",[]]Ak[\"{{{AHEf{ANLj}}}ANLj}\",[]]Ak[\"{{{AHEf{BAM`}}}BAM`}\",[]]Ak[\"{{{AHEf{B@Bd}}}B@Bd}\",[]]Ak[\"{{{AHEf{BFMh}}}BFMh}\",[]]Ak[\"{{{AHEf{AOLb}}}AOLb}\",[]]Ak[\"{{{AHEf{ANKf}}}ANKf}\",[]]Ak[\"{{{AHEf{AGJb}}}AGJb}\",[]]Ak[\"{{{AHEf{BBKb}}}BBKb}\",[]]Ak[\"{{{AHEf{BDDd}}}BDDd}\",[]]Ak[\"{{{AHEf{AOMj}}}AOMj}\",[]]Ak[\"{{{AHEf{AON`}}}AON`}\",[]]Ak[\"{{{AHEf{AONj}}}AONj}\",[]]Ak[\"{{{AHEf{BEI`}}}BEI`}\",[]]Ak[\"{{{AHEf{AIBh}}}AIBh}\",[]]Ai[\"{{{AHEf{COl}}}COl}\",[]]Ag[\"{{{AHEf{Ol}}}Ol}\",[]]Ak[\"{{{AHEf{AAMb}}}AAMb}\",[]]Ag[\"{{{AHEf{O`}}}O`}\",[]]Ak[\"{{{AHEf{AGHh}}}AGHh}\",[]]Ai[\"{{{AHEf{I@h}}}I@h}\",[]]Ak[\"{{{AHEf{ANL`}}}ANL`}\",[]]Ai[\"{{{AHEf{NF`}}}NF`}\",[]]Ak[\"{{{AHEf{BAAb}}}BAAb}\",[]]Ai[\"{{{AHEf{IBb}}}IBb}\",[]]Ak[\"{{{AHEf{BDGn}}}BDGn}\",[]]Ak[\"{{{AHEf{BFEl}}}BFEl}\",[]]Ak[\"{{{AHEf{BDHb}}}BDHb}\",[]]Ai[\"{{{AHEf{KDh}}}KDh}\",[]]Ak[\"{{{AHEf{BFFh}}}BFFh}\",[]]Ak[\"{{{AHEf{BEAl}}}BEAl}\",[]]Ai[\"{{{AHEf{KBf}}}KBf}\",[]]Ak[\"{{{AHEf{B@Al}}}B@Al}\",[]]Ak[\"{{{AHEf{AIDb}}}AIDb}\",[]]Ak[\"{{{AHEf{AGL`}}}AGL`}\",[]]Ak[\"{{{AHEf{BEAh}}}BEAh}\",[]]Ak[\"{{{AHEf{BEHh}}}BEHh}\",[]]Ak[\"{{{AHEf{AI@n}}}AI@n}\",[]]Ak[\"{{{AHEf{AANn}}}AANn}\",[]]Ak[\"{{{AHEf{AIBd}}}AIBd}\",[]]Ak[\"{{{AHEf{AGLd}}}AGLd}\",[]]Ak[\"{{{AHEf{BBLb}}}BBLb}\",[]]Ak[\"{{{AHEf{AGLj}}}AGLj}\",[]]Ak[\"{{{AHEf{BABb}}}BABb}\",[]]Ai[\"{{{AHEf{NIh}}}NIh}\",[]]Ak[\"{{{AHEf{AIGd}}}AIGd}\",[]]Ak[\"{{{AHEf{ANLh}}}ANLh}\",[]]Ak[\"{{{AHEf{BB@b}}}BB@b}\",[]]Ak[\"{{{AHEf{AOMf}}}AOMf}\",[]]Ak[\"{{{AHEf{BBKj}}}BBKj}\",[]]Ak[\"{{{AHEf{AGKl}}}AGKl}\",[]]Ak[\"{{{AHEf{BAKn}}}BAKn}\",[]]Ak[\"{{{AHEf{BGAb}}}BGAb}\",[]]Ak[\"{{{AHEf{BBNh}}}BBNh}\",[]]Ak[\"{{{AHEf{BEDl}}}BEDl}\",[]]Ak[\"{{{AHEf{BEFj}}}BEFj}\",[]]Ak[\"{{{AHEf{ANLl}}}ANLl}\",[]]Ak[\"{{{AHEf{BAMb}}}BAMb}\",[]]Ak[\"{{{AHEf{B@Bh}}}B@Bh}\",[]]Ak[\"{{{AHEf{BFMj}}}BFMj}\",[]]Ak[\"{{{AHEf{AOLf}}}AOLf}\",[]]Ak[\"{{{AHEf{ANKh}}}ANKh}\",[]]Ak[\"{{{AHEf{AGJd}}}AGJd}\",[]]Ak[\"{{{AHEf{AIC`}}}AIC`}\",[]]Ak[\"{{{AHEf{AIEn}}}AIEn}\",[]]Ak[\"{{{AHEf{AONd}}}AONd}\",[]]Ak[\"{{{AHEf{BBKf}}}BBKf}\",[]]Ak[\"{{{AHEf{BDDh}}}BDDh}\",[]]Ak[\"{{{AHEf{AAIj}}}AAIj}\",[]]Ak[\"{{{AHEf{BDE`}}}BDE`}\",[]]Ak[\"{{{AHEf{AOMl}}}AOMl}\",[]]Ak[\"{{{AHEf{BBMb}}}BBMb}\",[]]Ak[\"{{{AHEf{BGAj}}}BGAj}\",[]]Ak[\"{{{AHEf{AAKf}}}AAKf}\",[]]Ak[\"{{{AHEf{BEAd}}}BEAd}\",[]]Ak[\"{{{AHEf{AONb}}}AONb}\",[]]Ak[\"{{{AHEf{AONl}}}AONl}\",[]]Ak[\"{{{AHEf{BB@j}}}BB@j}\",[]]Ak[\"{{{AHEf{BEIb}}}BEIb}\",[]]Ak[\"{{{AHEf{AIBj}}}AIBj}\",[]]Ak[\"{{{AHEf{BGMf}}}BGMf}\",[]]Ai[\"{{{AHEf{COn}}}COn}\",[]]Ag[\"{{{AHEf{On}}}On}\",[]]Ak[\"{{{AHEf{AAMd}}}AAMd}\",[]]Ak[\"{{{AHEf{AGJ`}}}AGJ`}\",[]]Ak[\"{{{AHEf{BABn}}}BABn}\",[]]Ak[\"{{{AHEf{BENn}}}BENn}\",[]]Ai[\"{{{AHEf{IBf}}}IBf}\",[]]Ai[\"{{{AHEf{IBd}}}IBd}\",[]]Ak[\"{{{AHEf{BDH`}}}BDH`}\",[]]Ak[\"{{{AHEf{BFEn}}}BFEn}\",[]]Ak[\"{{{AHEf{BDHd}}}BDHd}\",[]]Ag[\"{{{AHEf{Ob}}}Ob}\",[]]Ak[\"{{{AHEf{AGHj}}}AGHj}\",[]]Ai[\"{{{AHEf{I@j}}}I@j}\",[]]Ak[\"{{{AHEf{ANLb}}}ANLb}\",[]]Ai[\"{{{AHEf{NFb}}}NFb}\",[]]Ak[\"{{{AHEf{BAAd}}}BAAd}\",[]]Ai[\"{{{AHEf{IBn}}}IBn}\",[]]Ak[\"{{{AHEf{AALn}}}AALn}\",[]]Ak[\"{{{AHEf{AANj}}}AANj}\",[]]Ak[\"{{{AHEf{AONn}}}AONn}\",[]]Ak[\"{{{AHEf{BEN`}}}BEN`}\",[]]Ak[\"{{{AHEf{BBLj}}}BBLj}\",[]]Ak[\"{{{AHEf{BGGd}}}BGGd}\",[]]Ak[\"{{{AHEf{BGGf}}}BGGf}\",[]]Bn[\"{{{AHEf{AIAf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bn[\"{{{AHEf{AAJf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjBAKl}}}}\",[]]Bf[\"{{{AHEf{CEdAIAh}}NEdKDhHOn}HOj}\",[]]Bj[\"{{{AHEf{AON`}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Bj[\"{{{AHEf{AONb}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Aa[\"{BB@jAIC`}\",[]]A`[\"{AAMbCLf}\",[]]A`[\"{AAMdCLf}\",[]]A`[\"{AONjD@n}\",[]]A`[\"{AONlD@n}\",[]]l[\"{NEf}\",[]]l[\"{NEh}\",[]]Ce[\"{{{AHEf{BEEf}}{AHEf{CEdOh}}}{{KBj{AONbBEAd}}}}\",[]]Ce[\"{{{AHEf{BH@h}}{AHEf{CEdOh}}}{{KBj{AONbBEAd}}}}\",[]]Bc[\"{{{AHEf{AIAh}}}{{AAj{KBf}}}}\",[]]Bd[\"{{{AHEf{IDj}}{AHEf{CL`}}}HOj}\",[]]Am[\"{{{AHEf{ANKb}}JNf}HOj}\",[]]Ai[\"{{{AHEf{IDl}}}HOj}\",[]]Bg[\"{{{AAd{{AHEf{CEdAI@`}}}}NEd}HOj}\",[]]Bm[\"{{{AHEf{CEdAIEf}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}KDh}{{KBj{HOjAOMf}}}}\",[]]Am[\"{AAJn{{KBj{HOjAIE`}}}}\",[]]Dc[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}{{KBj{AANhAIEb}}}}\",[]]Bi[\"{{{AHEf{NGh}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{B@Cb}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{ANNf}}{AAd{{Of{K@n}}}}}HOj}\",[]]o[\"{A@lD@n}\",[]]Ak[\"{{{AHEf{AIAf}}}BBL`}\",[]]Ak[\"{{{AHEf{AAJf}}}B@Nn}\",[]]Aj[\"{{{AHEf{CNn}}}AGLb}\",[]]An[\"{{{AHEf{CEdAIAh}}}BBLb}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGb}}}}\",[]]Ck[\"{{{AHEf{CEdAIEh}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGd}}}}\",[]]Bl[\"{{{AHEf{BENn}}{AHEf{CEdc}}}HOjJOl}\",[\"W\"]]Aj[\"{{{AHEf{AAJf}}}JNn}\",[]]An[\"{AAJn{{KBj{AIAbBBKh}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Fh[\"{{{AHEf{CEdAAJh}}AAK`NEd{AHEf{CEd{AAj{Nd}}}}{KB`{{Nn{B@Bh}}}}}{{KBj{{JNd{BDE`AIAh}}{Of{ANJl}}}}}}\",[]]Am[\"{AHEf{{AHEf{c}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000o[\"{NIfJNf}\",[]]o[\"{NIhJNf}\",[]]A`[\"{A@lANK`}\",[]]Bc[\"{{AIElBAKjA@l}{{KBn{ANKb}}}}\",[]]Aj[\"{AIEl{{KBl{AAJf}}}}\",[]]B`[\"{{}{{KBj{HOj{Of{IAd}}}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BBKh}\",[]]Be[\"{{{AHEf{AAJh}}}{{AHEf{BAMb}}}}\",[]]o[\"{NdBEI`}\",[]]A`[\"{AIBbCLf}\",[]]o[\"{B@BdNn}\",[]]o[\"{NdBEIb}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{B@BhNn}\",[]]A`[\"{BB@jKB`}\",[]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KDfBABn}}}Oh}\",[\"B\"]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KBdBABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AGJbBABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{BEI`BABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AAMbBABn}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KDh}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KBf}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGJd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AIC`}}}Oh}\",[\"B\"]]Ek[\"{{{AHEf{CEd{K@l{AAI`}}}}{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{BBMbBEAd}}}{BEEfIDh}}\",[\"\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{BEIb}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AAMd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGIf}}}Oh}\",[\"B\"]]A`[\"{AALnKB`}\",[]]Bk[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEI`}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AIC`}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAIj}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEIb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGIl}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bj[\"{{{AHEf{CEdAIEf}}}{{KBj{HOjAOLn}}}}\",[]]Bj[\"{{{AHEf{CEdAIEh}}}{{KBj{HOjANLh}}}}\",[]]An[\"{{{AHEf{ANOb}}AAJb}HOj}\",[]]Ea[\"{{{AHEf{CEdAAJh}}NEdAGJ`{KB`{AONl}}AAI`{AHEf{CEd{AAj{Nd}}}}}{{KB`{B@Nj}}}}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]A`[\"{AAJnHOj}\",[]]Ba[\"{{{AHEf{CEdAAJh}}AAK`}HOj}\",[]]Bh[\"{{{AHEf{AIFl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BANl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHf}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{AIFn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BANn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHh}}{AHEf{CL`}}HOn}HOj}\",[]]A`[\"{AGHnD@n}\",[]]o[\"{I@`CLf}\",[]]o[\"{I@bCLf}\",[]]Ce[\"{{{AHEf{CEdAIAj}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cc[\"{{{AHEf{CEdO`}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@h}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNF`}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Ce[\"{{{AHEf{CEdAIAl}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cc[\"{{{AHEf{CEdOb}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@j}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNFb}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]o[\"{BDI`Nd}\",[]]A`[\"{BBKbHOn}\",[]]A`[\"{BDDdHOn}\",[]]A`[\"{BBKfHOn}\",[]]A`[\"{BDDhHOn}\",[]]A`[\"{BB@jKDb}\",[]]Aa[\"{BALbBBKj}\",[]]Aa[\"{AGGdBEAh}\",[]]Bg[\"{{{AHEf{AAJf}}AGMb}{{KBl{HOj}}}}\",[]]A`[\"{AAJnHOj}\",[]]Cf[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}AANh}\",[]]l[\"{NEf}\",[]]Ak[\"{{{AHEf{AGJ`}}}AIEl}\",[]]l[\"{NEh}\",[]]An[\"{{AAJdA@l}{{KBn{HOj}}}}\",[]]B`[\"{{B@BdAIEl}{{KBl{AAJf}}}}\",[]]Bb[\"{B@B`{{KBj{HOj{Of{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BEAj}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BB@`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AGLh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIDn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BAOn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIGb}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{B@C`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKj}}}{{KB`{{AHEf{IAd}}}}}}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Bg[\"{{{AHEf{CNn}}}{{KBj{AID`AI@h}}}}\",[]]Aa[\"{B@AfAIDb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]A`[\"{AALnJNf}\",[]]Aa[\"{AGLbAANl}\",[]]Aa[\"{BBL`AANl}\",[]]Aa[\"{AGLdAANn}\",[]]Aa[\"{BBLbAANn}\",[]]3210Dh[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANKl}}}}\",[]]Dh[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANKn}}}}\",[]]Aj[\"{{{AHEf{AIAj}}}CLf}\",[]]Ah[\"{{{AHEf{O`}}}CLf}\",[]]Ai[\"{{{AHEf{I@h}}}CLf}\",[]]Ai[\"{{{AHEf{NF`}}}CLf}\",[]]Aj[\"{{{AHEf{AIAl}}}CLf}\",[]]Ah[\"{{{AHEf{Ob}}}CLf}\",[]]Ai[\"{{{AHEf{I@j}}}CLf}\",[]]Ai[\"{{{AHEf{NFb}}}CLf}\",[]]Aj[\"{{{AHEf{BFLf}}}JNf}\",[]]Aj[\"{{{AHEf{BFLh}}}JNf}\",[]]Aj[\"{{{AHEf{BGLl}}}JNf}\",[]]Aj[\"{{{AHEf{BGMf}}}JNf}\",[]]o[\"{A@lJNf}\",[]]n[\"{{}ND`}\",[]]0o[\"{OjAAId}\",[]]111Ba[\"{{AHEf{AHEf{c}}}AALh{}}\",[\"K\"]]0000000000000000000Cg[\"{{{AHEf{AAJf}}AIEl{AHEf{CL`}}}{{KBj{AIAbAOMj}}}}\",[]]Dl[\"{{{AHEf{CEdAAJh}}NEdAOLfAIEl{AHEf{CL`}}}{{KBj{{JNd{BDE`AIAh}}AOMl}}}}\",[]]Bd[\"{{{AHEf{AAJn}}}{{KB`{BDEd}}}}\",[]]Dm[\"{{{AHEf{AGKf}}KBdCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANKl}}}}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Bd[\"{{{AHEf{AAK`}}}{{KB`{BDEf}}}}\",[]]Dm[\"{{{AHEf{AGKh}}KBfCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANKn}}}}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]o[\"{{}ANO`}\",[]]n[\"{{}IDj}\",[]]o[\"{{}ANKb}\",[]]o[\"{{}B@Ml}\",[]]o[\"{{}B@Nn}\",[]]n[\"{{}KDf}\",[]]n[\"{{}KBd}\",[]]o[\"{{}AANl}\",[]]o[\"{{}AIBb}\",[]]o[\"{{}AGLb}\",[]]o[\"{{}BBL`}\",[]]n[\"{{}NIf}\",[]]o[\"{{}AOLn}\",[]]o[\"{{}BBNf}\",[]]o[\"{{}BEDj}\",[]]o[\"{{}BEFh}\",[]]o[\"{{}ANLj}\",[]]o[\"{{}BAM`}\",[]]o[\"{{}BFMh}\",[]]o[\"{{}BDHf}\",[]]o[\"{{}AGHh}\",[]]o[\"{{}ANL`}\",[]]o[\"{{}BAAb}\",[]]o[\"{{}BE@b}\",[]]o[\"{{}B@Mn}\",[]]o[\"{{}BGLl}\",[]]n[\"{{}KDh}\",[]]n[\"{{}KBf}\",[]]o[\"{{}AIDb}\",[]]o[\"{{}AI@n}\",[]]o[\"{{}AANn}\",[]]o[\"{{}AIBd}\",[]]o[\"{{}AGLd}\",[]]o[\"{{}BBLb}\",[]]n[\"{{}NIh}\",[]]o[\"{{}BB@b}\",[]]o[\"{{}AOMf}\",[]]o[\"{{}BBNh}\",[]]o[\"{{}BEDl}\",[]]o[\"{{}BEFj}\",[]]o[\"{{}ANLl}\",[]]o[\"{{}BAMb}\",[]]o[\"{{}BFMj}\",[]]o[\"{{}BGMf}\",[]]o[\"{{}BDHh}\",[]]o[\"{{}AGHj}\",[]]o[\"{{}ANLb}\",[]]o[\"{{}BAAd}\",[]]o[\"{{}BE@d}\",[]]o[\"{{}AALn}\",[]]n[\"{{}IDl}\",[]]o[\"{{}BBLj}\",[]]o[\"{{}B@Nl}\",[]]Ak[\"{{{AHEf{BAAh}}}AONb}\",[]]Ak[\"{{{AHEf{BBMb}}}AONb}\",[]]Aa[\"{BGAjAONb}\",[]]Aa[\"{BEIdAONb}\",[]]A`[\"{CNfAONb}\",[]]A`[\"{ID`AONb}\",[]]A`[\"{IDdAONb}\",[]]Aa[\"{BDI`AONb}\",[]]Cg[\"{{{AHEf{AGKf}}KBdCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cg[\"{{{AHEf{AGKh}}KBfCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Aj[\"{{{AHEf{AIDj}}}D@n}\",[]]Aj[\"{{{AHEf{BEO`}}}D@n}\",[]]Ak[\"{{{AHEf{AIAj}}}BE@b}\",[]]Ai[\"{{{AHEf{O`}}}BE@b}\",[]]Aj[\"{{{AHEf{I@h}}}BE@b}\",[]]Aj[\"{{{AHEf{NF`}}}BE@b}\",[]]Ak[\"{{{AHEf{AIAl}}}BE@d}\",[]]Ai[\"{{{AHEf{Ob}}}BE@d}\",[]]Aj[\"{{{AHEf{I@j}}}BE@d}\",[]]Aj[\"{{{AHEf{NFb}}}BE@d}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLb}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLb}{{AHEf{CEdBBNh}}}}\",[]]Bf[\"{{{AHEf{CEdAIAj}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdO`}}NEdCLfCLf}HOj}\",[]]Bf[\"{{{AHEf{CEdAIAl}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdOb}}NEdCLfCLf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}KAf}\",[]]Bc[\"{{{AHEf{AALf}}}{{KB`{KBd}}}}\",[]]Aa[\"{BGAjAONb}\",[]]Aa[\"{BEIdAONb}\",[]]A`[\"{CNfAONb}\",[]]A`[\"{ID`AONb}\",[]]Aa[\"{BDI`AONb}\",[]]Aj[\"{{{AHEf{AIEf}}}NHb}\",[]]Bn[\"{{{AHEf{AIEh}}}{{KBj{{KB`{KDh}}AOMf}}}}\",[]]o[\"{A@lJNf}\",[]]o[\"{IDjJNf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}NHj}\",[]]Aj[\"{{{AHEf{AGKf}}}JNf}\",[]]Aj[\"{{{AHEf{AGKh}}}JNf}\",[]]A`[\"{AHEfKDd}\",[]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bd[\"{{{AHEf{BFFl}}}{{KB`{AIAf}}}}\",[]]Bc[\"{{{AHEf{BB@n}}}{{KB`{CNn}}}}\",[]]Bn[\"{{{AHEf{CEdAOLb}}CLd}{{AHEf{CEdAOLb}}}}\",[]]Bn[\"{{{AHEf{CEdAOLf}}CLd}{{AHEf{CEdAOLf}}}}\",[]]A`[\"{BGAjCLd}\",[]]A`[\"{BEIdCLd}\",[]]o[\"{CNfCLd}\",[]]o[\"{ID`CLd}\",[]]A`[\"{AGHnKB`}\",[]]Aa[\"{AANjAHEf}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{BB@dAAJb}\",[]]A`[\"{JOnBB@b}\",[]]Aa[\"{AGLbAIBb}\",[]]Aa[\"{BBL`AIBb}\",[]]Aa[\"{AGLdAIBd}\",[]]Aa[\"{BBLbAIBd}\",[]]3210Bg[\"{{{AHEf{CEdc}}JNf}AON`{OhIDh}}\",[\"\"]]Bg[\"{{{AHEf{CEdc}}JNf}AONb{OhIDh}}\",[\"\"]]o[\"{{}BBMd}\",[]]o[\"{{}BBMf}\",[]]A`[\"{CLfBGLl}\",[]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANN`c}}}{}}\",[\"FromStr::Err\"]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANK`c}}}{}}\",[\"FromStr::Err\"]]o[\"{CLdKDf}\",[]]o[\"{CLdKDh}\",[]]Al[\"{CLf{{KBj{KDfBFFf}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFh}}}}\",[]]Aa[\"{BFDnANKj}\",[]]Aa[\"{BH@jB@Oj}\",[]]Aa[\"{BFE`ANKj}\",[]]Aa[\"{BH@lB@Oj}\",[]]Af[\"{{}{{KB`{Ab}}}}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBEFh}}AAJb}{{AHEf{CEdBEFh}}}}\",[]]Bo[\"{{{AHEf{CEdBEFj}}AAJb}{{AHEf{CEdBEFj}}}}\",[]]Ao[\"{{{Of{AIAj}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{O`}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@h}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NF`}}}{{Of{Nl}}}}\",[]]Ao[\"{{{Of{AIAl}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{Ob}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@j}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NFb}}}{{Of{Nl}}}}\",[]]Aj[\"{{{AHEf{BFFl}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBFMh}}AAJb}{{AHEf{CEdBFMh}}}}\",[]]Bo[\"{{{AHEf{CEdBFMj}}AAJb}{{AHEf{CEdBFMj}}}}\",[]]Bc[\"{{{AHEf{AIAb}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AIAf}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAJn}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAK`}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AGJ`}}}{{KB`{KAb}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bc[\"{{{AHEf{AGId}}}{{KB`{JNf}}}}\",[]]Am[\"{{{AHEf{ANOb}}JNf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}NFf}\",[]]Bg[\"{{{AHEf{AIEf}}}{{KBj{CCnAOLn}}}}\",[]]Bg[\"{{{AHEf{AIEh}}}{{KBj{CCnAOMf}}}}\",[]]A`[\"{B@ObKB`}\",[]]A`[\"{B@OdKB`}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{ANJlKB`}\",[]]Ck[\"{{{AHEf{CEdBAM`}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAM`}}}}\",[]]Ck[\"{{{AHEf{CEdBAMb}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAMb}}}}\",[]]A`[\"{BE@bKB`}\",[]]A`[\"{BE@dKB`}\",[]]Ac[\"{AHEfc{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]000000000000000000000000000000000000000000000000000Al[\"{HOh{{KBj{KDfBFFf}}}}\",[]]Al[\"{JNf{{KBj{KDfBFFf}}}}\",[]]2Al[\"{CLf{{KBj{KDfBFFf}}}}\",[]]333333333333333Aj[\"{AAJb{{KBj{ANLj}}}}\",[]]44444Ai[\"{CLf{{KBj{AGJb}}}}\",[]]5555555555555555555555555555Aj[\"{AOL`{{KBj{BDGn}}}}\",[]]Bb[\"{{{Nn{AOL`}}}{{KBj{BDGn}}}}\",[]]777Bb[\"{{{Nn{B@Bb}}}{{KBj{BDHb}}}}\",[]]Aj[\"{B@Bb{{KBj{BDHb}}}}\",[]]999999999999999999999Al[\"{JNf{{KBj{KDhBFFh}}}}\",[]]Al[\"{HOh{{KBj{KDhBFFh}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFh}}}}\",[]]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Bm[\"{AOL`{{KBj{BDH`c}}}{}}\",[\"TryFrom::Error\"]]Ce[\"{{{Nn{AOL`}}}{{KBj{BDH`c}}}{}}\",[\"TryFrom::Error\"]]Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]0Ce[\"{{{Nn{B@Bb}}}{{KBj{BDHdc}}}{}}\",[\"TryFrom::Error\"]]Bm[\"{B@Bb{{KBj{BDHdc}}}{}}\",[\"TryFrom::Error\"]]22222222222222222222222Aj[\"{{}{{KBj{c}}}{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cd[\"{{{AAd{{AHEf{CEdc}}}}{AHEf{CEdNDb}}}COf{}}\",[\"F\"]]000000000Cc[\"{{{AHEf{BB@l}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bk[\"{{{AHEf{BFLf}}AON`}{{KBj{HOjAIBh}}}}\",[]]Bk[\"{{{AHEf{BFLh}}AONb}{{KBj{HOjAIBj}}}}\",[]]0Bk[\"{{{AHEf{BGLl}}AONb}{{KBj{HOjAIBj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AAHn}\",[]]Bi[\"{{{AHEf{CEdB@Cd}}}{{KBj{KDfIB`}}}}\",[]]Bi[\"{{{AHEf{CEdB@Cd}}}{{KBj{COlIB`}}}}\",[]]Bh[\"{{{AHEf{CEdB@Cd}}}{{KBj{OlIB`}}}}\",[]]Bj[\"{{{AHEf{CEdB@Cd}}}{{KBj{AAMbIB`}}}}\",[]]Bf[\"{{{AHEf{CEdB@Cd}}}{{KC`{KDh}}}}\",[]]Bf[\"{{{AHEf{CEdB@Cd}}}{{KC`{COn}}}}\",[]]Be[\"{{{AHEf{CEdB@Cd}}}{{KC`{On}}}}\",[]]Bg[\"{{{AHEf{CEdB@Cd}}}{{KC`{AAMd}}}}\",[]]Aa[\"{ANK`BFFd}\",[]]Bc[\"{{{AHEf{AIAj}}}{{Of{AIAj}}}}\",[]]Ba[\"{{{AHEf{O`}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{I@h}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{NF`}}}{{Of{AIAj}}}}\",[]]Bc[\"{{{AHEf{AIAl}}}{{Of{AIAl}}}}\",[]]Ba[\"{{{AHEf{Ob}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{I@j}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{NFb}}}{{Of{AIAl}}}}\",[]]A`[\"{AANlCLf}\",[]]An[\"{{{AHEf{CEdAIAh}}}AGId}\",[]]A`[\"{AANnCLf}\",[]]C`[\"{{{AHEf{CEdAON`}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]C`[\"{{{AHEf{CEdAONb}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]Ah[\"{Nd{{KB`{AONj}}}}\",[]]Ah[\"{Nd{{KB`{AONl}}}}\",[]]Ah[\"{Nd{{KB`{AONn}}}}\",[]]A`[\"{AAMbCOl}\",[]]A`[\"{AAMdCOn}\",[]]Bi[\"{AIAb{{KBj{{JNd{AIAfBBO`}}AIAb}}}}\",[]]Aa[\"{{}c{}}\",[\"I\"]]o[\"{COlD@n}\",[]]o[\"{COnD@n}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]21Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}D@n}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}D@n}{{AHEf{CEdB@Bh}}}}\",[]]Bl[\"{{{AHEf{NGh}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{B@Cb}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{ANNf}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Ak[\"{{{AHEf{AIAf}}}AALd}\",[]]Bc[\"{{{AHEf{AIAf}}AIElAID`}AALf}\",[]]Ce[\"{{{AHEf{CEdAIAh}}AGJ`AIDbNEd}{{KBj{KBfAGKl}}}}\",[]]43Bm[\"{{{AHEf{CEdAIAh}}KBf}{{KBj{HOjAI@n}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdBFF`}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBDD`}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdAICn}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBENb}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]Ec[\"{{{AHEf{CEdAIDj}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBj{JNfAGLh}}}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEdNGb}}}{{COf{{KBl{HOj}}}}}}\",[]]Ef[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Fg[\"{{{AHEf{CEdBAKh}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Dn[\"{{{AAd{{AHEf{CEdAGM`}}}}{AHEf{AANj}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]>=Cd[\"{{{AHEf{CEdBAM`}}{Nn{NDn}}}{{AHEf{CEdBAM`}}}}\",[]]Cd[\"{{{AHEf{CEdBAMb}}{Nn{NE`}}}{{AHEf{CEdBAMb}}}}\",[]]Cj[\"{{{AHEf{B@Bf}}CLdAON`{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHb}}CLdAON`{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{B@Bj}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHd}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BGGf}}CLdAOMn{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Bb[\"{JNf{{JNd{JNf{KB`{JNf}}}}}}\",[]]000Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]A`[\"{AHEfKDb}\",[]]00000000000000000000000000000000000000000000000000000000000000Ce[\"{{{AHEf{CEdB@Bd}}{Nn{BE@f}}}{{AHEf{CEdB@Bd}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{BE@h}}}{{AHEf{CEdB@Bh}}}}\",[]]A`[\"{BGAjICf}\",[]]o[\"{B@BdNn}\",[]]o[\"{B@BhNn}\",[]]Aj[\"{{{AHEf{AAJf}}}HOj}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}JNf}\",[]]Ak[\"{{{AHEf{AIAf}}}AGGh}\",[]]Ba[\"{{{AHEf{CEdAANl}}AANl}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBb}}AIBb}HOj}\",[]]Ba[\"{{{AHEf{CEdBBL`}}AGLb}HOj}\",[]]Ba[\"{{{AHEf{CEdAANn}}AANn}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBd}}AIBd}HOj}\",[]]Ba[\"{{{AHEf{CEdBBLb}}AGLd}HOj}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Bi[\"{{{AHEf{CEd}}}{{AHEf{CEdc}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bc[\"{{AHEf{AHEf{CEdc}}}HOj{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cc[\"{{{AHEf{CEdAIAh}}NEdKBfKDh}{{KBj{HOjBAKn}}}}\",[]]A`[\"{AGHnD@n}\",[]]B`[\"{{AHEf{AHEf{c}}}D@n{}}\",[\"K\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Aa[\"{BBKbBEI`}\",[]]A`[\"{BDDdKDf}\",[]]Aa[\"{BBKfBEIb}\",[]]A`[\"{BDDhKDh}\",[]]A`[\"{BDOfKDh}\",[]]A`[\"{BBMhKDh}\",[]]o[\"{NGnKDh}\",[]]Aa[\"{BBKbAIBn}\",[]]Aa[\"{BBKfAIC`}\",[]]o[\"{KDfCLf}\",[]]o[\"{KDhCLf}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Aj[\"{{{AHEf{B@Nl}}}D@n}\",[]]Bd[\"{{{AHEf{BAKh}}}{{KBl{AIEl}}}}\",[]]Bd[\"{{{AHEf{AAJf}}}{{KBl{AIEl}}}}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]Cb[\"{{{AHEf{BBLj}}{AHEf{AIEd}}CLf}{{Nn{ANOb}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AGLb}}}}\",[]]Bj[\"{{{AHEf{CEdAIAh}}KBf}{{KB`{AGLd}}}}\",[]]o[\"{AGIhOf}\",[]]Db[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]00Eg[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBj{JNfAIGb}}}}}}\",[]]Ec[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]0Bm[\"{{{AHEf{IDl}}{AHEf{CNl}}}{{KBl{HOj}}}}\",[]]Cd[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cd[\"{{{AHEf{CEdBEO`}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cn[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{HOjBAOn}}}}\",[]]Bj[\"{{{AHEf{CNn}}AID`}{{KBj{HOjBEHf}}}}\",[]]Bn[\"{{{AHEf{CEdAIDd}}NEd}{{AHEf{CEdAIDd}}}}\",[]]Bn[\"{{{AHEf{CEdAIDf}}NEd}{{AHEf{CEdAIDf}}}}\",[]]A`[\"{BB@dAFd}\",[]]o[\"{IDjCLf}\",[]]o[\"{{}AIEl}\",[]]0o[\"{{}AHEf}\",[]]Bj[\"{{AAJn{Nn{B@Bd}}}{{KBj{AIAbBBKh}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bh[\"{{{AHEf{AGHn}}AIEl}{{KBn{AGMb}}}}\",[]]A`[\"{AGLbCLb}\",[]]Aj[\"{{{AHEf{AIAh}}}CLb}\",[]]A`[\"{AGLdCLb}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Aa[\"{AANfAIEl}\",[]]Aa[\"{AANhAIEl}\",[]]Aa[\"{AANjAIEl}\",[]]Aa[\"{AIElAGJ`}\",[]]o[\"{A@lCLb}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLb}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLb}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnCLb}\",[]]Bo[\"{{{AHEf{CEdBBNf}}AAJb}{{AHEf{CEdBBNf}}}}\",[]]Bo[\"{{{AHEf{CEdBBNh}}AAJb}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnKB`}\",[]]k[\"{{}}\",[]]0000000000Bh[\"{AAJnc{}}\",[\"IntoFuture::IntoFuture\"]]11A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{A@lJNf}\",[]]Ao[\"{{AHEfc}{{NEj{c}}}{}}\",[\"S\"]]0C`[\"{{{AHEf{CEdAIAj}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdO`}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]C`[\"{{{AHEf{CEdAIAl}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdOb}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bk[\"{{{AHEf{CEdIDl}}NEd{AHEf{BBLj}}}HOj}\",[]]A`[\"{BE@bKB`}\",[]]A`[\"{BE@dKB`}\",[]]Bn[\"{{{AHEf{KDf}}{AHEf{KDf}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBd}}{AHEf{KBd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AON`}}{AHEf{AON`}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COl}}{AHEf{COl}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{Ol}}{AHEf{Ol}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KDh}}{AHEf{KDh}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEAl}}{AHEf{BEAl}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBf}}{AHEf{KBf}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BABb}}{AHEf{BABb}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AONb}}{AHEf{AONb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COn}}{AHEf{COn}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{On}}{AHEf{On}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}{{KB`{AALh}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AICn}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AIDbAI@n}}}}\",[]]Df[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{HOn}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Cc[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{AAj{Nd}}BB@`}}}}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIDl}\",[]]Aj[\"{{{AHEf{AGJh}}}JNf}\",[]]Aj[\"{{{AHEf{AGJj}}}JNf}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIEh}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLf}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{B@ObKB`}\",[]]A`[\"{B@OdKB`}\",[]]Ce[\"{{{AHEf{CEdB@Bd}}{Nn{AIFd}}}{{AHEf{CEdB@Bd}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{AIFf}}}{{AHEf{CEdB@Bh}}}}\",[]]Ce[\"{{{AHEf{CEdAOLb}}{Nn{AIFl}}}{{AHEf{CEdAOLb}}}}\",[]]Ce[\"{{{AHEf{CEdAOLf}}{Nn{AIFn}}}{{AHEf{CEdAOLf}}}}\",[]]o[\"{A@lCLf}\",[]]Bn[\"{{{AHEf{CEdBEFh}}CLb}{{AHEf{CEdBEFh}}}}\",[]]Bn[\"{{{AHEf{CEdBEFj}}CLb}{{AHEf{CEdBEFj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BFFl}\",[]]Aj[\"{{{AHEf{CNn}}}BB@n}\",[]]Ai[\"{{{Nn{B@Bf}}}B@Bd}\",[]]Ai[\"{{{Nn{B@Bj}}}B@Bh}\",[]]Aj[\"{{BBMdc}BBMdAAMl}\",[\"\"]]Aj[\"{{BBMfc}BBMfAAMl}\",[\"\"]]Bm[\"{{{AHEf{CEdAIEf}}HOn}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}KAb}\",[]]o[\"{ND`ND`}\",[]]0000Bd[\"{{{AHEf{BFLf}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BFLh}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGLl}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGMf}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{AIAf}}}{{KB`{BBKh}}}}\",[]]Ck[\"{{{AHEf{AAJf}}AOLbAIEl{AHEf{CL`}}}{{KBj{AIAbAOMj}}}}\",[]]Ak[\"{{{AHEf{B@Al}}}AAJb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{AIDhD@n}{{KBn{JNf}}}}\",[]]Cj[\"{{{AHEf{NGj}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFh}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Cj[\"{{{AHEf{NGl}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFj}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]A`[\"{BFDnAAj}\",[]]A`[\"{BH@jAAj}\",[]]A`[\"{BFE`AAj}\",[]]A`[\"{BH@lAAj}\",[]]An[\"{{{AHEf{CEdBFLf}}}AON`}\",[]]An[\"{{{AHEf{CEdBFLh}}}AONb}\",[]]An[\"{{{AHEf{CEdBGLl}}}AONb}\",[]]An[\"{{{AHEf{CEdBGMf}}}AONb}\",[]]Ak[\"{{{AHEf{BB@l}}}B@@b}\",[]]Ba[\"{{{AHEf{CEdAIAh}}BBKn}HOj}\",[]]Bo[\"{{{AHEf{CEdAAJh}}BDE`B@Nl}{{KB`{BBKn}}}}\",[]]B`[\"{{{AHEf{NGj}}AON`COl}CNb}\",[]]Bn[\"{{{AHEf{B@Bf}}CLdAON`}{{KBj{CNbBEIh}}}}\",[]]Ba[\"{{{AHEf{AIFh}}AON`COl}CNb}\",[]]Bn[\"{{{AHEf{BDHb}}CLdAON`}{{KBj{CNbBEIh}}}}\",[]]B`[\"{{{AHEf{NGl}}AONbCOn}CNd}\",[]]Bn[\"{{{AHEf{B@Bj}}CLdAONb}{{KBj{CNdBEIn}}}}\",[]]Ba[\"{{{AHEf{AIFj}}AONbCOn}CNd}\",[]]Bn[\"{{{AHEf{BDHd}}CLdAONb}{{KBj{CNdBEIn}}}}\",[]]Bn[\"{{{AHEf{BGGf}}CLdAOMn}{{KBj{CNdBEIn}}}}\",[]]Aj[\"{{}{{NGd{c}}}{}}\",[\"T\"]]0A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}JNf}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}JNf}{{AHEf{CEdB@Bh}}}}\",[]]Aj[\"{{{AHEf{BAKh}}}D@n}\",[]]0Aj[\"{{{AHEf{BB@l}}}D@n}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AGJ`AI@n}}}}\",[]]Cb[\"{{{AHEf{BBLj}}{AHEf{AIDh}}CLf}{{Nn{ANOb}}}}\",[]]Ak[\"{{{AHEf{AAJn}}}AON`}\",[]]Ak[\"{{{AHEf{AAK`}}}AONb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{NEd}}}}\",[]]Ce[\"{{{AHEf{CEdBBNf}}{Nn{ANMh}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{Nn{ANMj}}}{{AHEf{CEdBBNh}}}}\",[]]43A`[\"{A@lANN`}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Ai[\"{{{AHEf{NHj}}}JNf}\",[]]Bo[\"{{{AHEf{CEdBGLl}}AAJb}{{AHEf{CEdBGLl}}}}\",[]]Bo[\"{{{AHEf{CEdBGMf}}AAJb}{{AHEf{CEdBGMf}}}}\",[]]Bj[\"{{{AHEf{AIEf}}CCn}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}CCn}{{KBj{HOjAOMf}}}}\",[]]==E`[\"{{{AHEf{BGAl}}{AHEf{{JL`{Nd}}}}{AHEf{BAKj}}{AHEf{BFLj}}}{{KBj{BGDbIAl}}}}\",[]]0Bf[\"{{{Nn{BABh}}}{{KBj{AOLbBFFj}}}}\",[]]Bf[\"{{{Nn{BABh}}}{{KBj{AOLfBFFj}}}}\",[]]Bn[\"{{{AHEf{CEdBEDj}}KDf}{{AHEf{CEdBEDj}}}}\",[]]Bn[\"{{{AHEf{CEdBEDl}}KDh}{{AHEf{CEdBEDl}}}}\",[]]o[\"{ND`ND`}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]0Ci[\"{{{AHEf{CNn}}{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@h}}}}\",[]]Cd[\"{{{AHEf{CEdA@l}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cc[\"{{{AHEf{CEdOj}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAAId}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAGHn}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdA@n}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdAA`}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bd}}BFMh}{{AHEf{CEdB@Bd}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bh}}BFMj}{{AHEf{CEdB@Bh}}}}\",[]]Aj[\"{{{AHEf{BAM`}}}CLf}\",[]]Aj[\"{{{AHEf{BAMb}}}CLf}\",[]]Cc[\"{{{AHEf{CEdAOLb}}{Nn{A`}}}{{AHEf{CEdAOLb}}}}\",[]]Cc[\"{{{AHEf{CEdAOLf}}{Nn{A`}}}{{AHEf{CEdAOLf}}}}\",[]]Cj[\"{{BAM`{KB`{B@Bd}}{Of{BAKh}}{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Ca[\"{{{AHEf{CEdAIAh}}NEdAICd}{{KBj{HOjBGAb}}}}\",[]]Bd[\"{{{AHEf{BGAl}}}{{AAj{BBMl}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}JNf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}JNf}{{AHEf{CEdBBNh}}}}\",[]]Bl[\"{{}{{KBj{{JNd{BAKjBEGd}}{Of{IAd}}}}}}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{{AHEf{AAJf}}AOLb}HOj}\",[]]Dc[\"{{{AHEf{CEdAIAh}}NEdKBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]o[\"{{}AHEf}\",[]]Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}CLf}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}CLf}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}KDf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}KDh}{{AHEf{CEdBBNh}}}}\",[]]:Bb[\"{{{AHEf{CEdAIAh}}OnKDh}HOj}\",[]]Ak[\"{{}{{KBj{AOLbIBb}}}}\",[]]Ak[\"{{}{{KBj{AOLfIBd}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]65Cg[\"{{{AHEf{CEdA@l}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cf[\"{{{AHEf{CEdOj}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAAId}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAGHn}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdA@n}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdAA`}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Bi[\"{{{AHEf{CEdAGJ`}}{AHEf{AGJ`}}}D@n}\",[]]n[\"{{}HOj}\",[]]Ce[\"{{{AHEf{CEdBBNf}}{KB`{JNf}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{KB`{JNf}}}{{AHEf{CEdBBNh}}}}\",[]]Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Cd[\"{{{AHEf{CEdAIAh}}NEd}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Am[\"{{{AHEf{CEdAIAj}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@h}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIAl}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@j}}}HOj}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]D`[\"{{{AHEf{CEdAIAh}}KBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]Ce[\"{{{AHEf{CEdBBNf}}{Nn{BDOn}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{Nn{BE@`}}}{{AHEf{CEdBBNh}}}}\",[]]Cf[\"{{{AHEf{CEdBBNf}}{KB`{AAJb}}}{{AHEf{CEdBBNf}}}}\",[]]Cf[\"{{{AHEf{CEdBBNh}}{KB`{AAJb}}}{{AHEf{CEdBBNh}}}}\",[]]Aa[\"{B@ObAICb}\",[]]Aa[\"{B@OdAICb}\",[]]9Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Am[\"{{{AHEf{AIAf}}KDf}HOj}\",[]]o[\"{ND`ND`}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLd}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLd}{{AHEf{CEdBBNh}}}}\",[]]3109854Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Bn[\"{{{AHEf{AIAh}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]10A`[\"{BENnKB`}\",[]]Bm[\"{{{AHEf{CEdBBNf}}Nd}{{AHEf{CEdBBNf}}}}\",[]]Bm[\"{{{AHEf{CEdBBNh}}Nd}{{AHEf{CEdBBNh}}}}\",[]]o[\"{{}AICd}\",[]]") \ No newline at end of file diff --git a/pr/523/docs/search.index/path/b5fe16f07d66.js b/pr/523/docs/search.index/path/0c408f7dccc7.js similarity index 96% rename from pr/523/docs/search.index/path/b5fe16f07d66.js rename to pr/523/docs/search.index/path/0c408f7dccc7.js index 9f8bcc580..5ad799bfc 100644 --- a/pr/523/docs/search.index/path/b5fe16f07d66.js +++ b/pr/523/docs/search.index/path/0c408f7dccc7.js @@ -1 +1 @@ -rd_("f[1,\"\"]0Al[10,\"core::ops\",\"core::ops\"]Ce[5,\"clap_builder::util::id\",\"clap_builder::util::id\"]22Ag[10,\"core::ops::arith\"]A`[10,\"core::any\"]Ao[5,\"alloc::sync\",\"alloc::sync\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ba[5,\"alloc::boxed\",\"alloc::boxed\"]Cb[10,\"bytes::buf::buf_impl\",\"bytes::buf::buf_impl\"]Ai[5,\"noq_perf\",\"noq_perf\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]Ae[10,\"core::ops::bit\"]Ac[5,\"bench\",\"bench\"]Ba[5,\"perf::client\",\"perf::client\"]Ba[5,\"perf::server\",\"perf::server\"]A`[10,\"core::cmp\"]Ak[5,\"core::pin\",\"core::pin\"]Am[5,\"alloc::vec\",\"alloc::vec\"]Ak[2,\"noq_proto::congestion\"]f[1,\"\"]00m[2,\"noq_udp\"]f[0,\"\"]f[3,\"\"]3333Ak[10,\"clap_builder::derive\"]Bn[10,\"std::os::fd::owned\",\"std::os::fd::owned\"]Af[10,\"core::ops::drop\"]Ad[10,\"core::convert\"]Aa[10,\"core::hash\"]1Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[15,\"noq_proto::ProtectedHeader\"]Ak[5,\"std::path\",\"std::path\"]Ae[5,\"noq\",\"noq::path\"]Bi[6,\"core::task::poll\",\"core::task::poll\"]Bb[10,\"core::marker\",\"core::marker\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]2f[1,\"\"]?i[2,\"noq\"]f[3,\"\"]Ag[2,\"noq_proto::config\"]Bd[2,\"noq_proto::connection::streams\"]0Ab[2,\"noq::runtime\"]55Bd[10,\"core::convert\",\"core::convert\"]Ba[5,\"bytes::bytes\",\"bytes::bytes\"]i[5,\"noq\"]Cb[5,\"noq_proto\",\"noq_proto::connection::assembler\"]Ab[10,\"core::clone\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]A`[10,\"core::fmt\"]Ag[10,\"core::ops::deref\"]Ak[5,\"core::fmt\",\"core::fmt\"]Ab[10,\"core::error\"]Ai[2,\"noq::crypto::rustls\"]Bc[6,\"rustls::error\",\"rustls::error\"]Ao[2,\"noq_proto::crypto::rustls\"]Cm[5,\"noq_proto::transport_error\",\"noq_proto::transport_error\"]Ba[8,\"clap_builder\",\"clap_builder\"]Bi[6,\"arbitrary::error\",\"arbitrary::error\"]Ai[6,\"noq::crypto::rustls\"]Ao[6,\"noq_proto::crypto::rustls\"]Dg[6,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Co[6,\"noq_proto::n0_nat_traversal\",\"noq_proto::n0_nat_traversal\"]o[2,\"noq_proto\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]2Bi[5,\"core::ops::range\",\"core::ops::range\"]Ba[15,\"noq_proto::ProtectedHeader\"]0Bb[10,\"core::marker\",\"core::marker\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ba[5,\"rustls::quic\",\"rustls::quic\"]Ah[10,\"std::io\",\"std::io\"]f[1,\"\"]f[3,\"\"]Ak[2,\"noq_proto::congestion\"]l[2,\"rustls\"]i[2,\"noq\"]o[2,\"noq_proto\"]1Ak[2,\"noq_proto::congestion\"]f[3,\"\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]Ag[10,\"core::ops::arith\"]A`[10,\"arbitrary\"]Al[10,\"tokio::io::async_read\"]Ai[10,\"futures_io::if_std\"]Am[15,\"noq_proto::StreamEvent\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ac[10,\"core::borrow\"]Aa[5,\"perf\",\"perf\"]Ak[5,\"criterion\",\"criterion\"]Cb[5,\"noq_proto\",\"noq_proto::connection::datagrams\"]Bl[10,\"noq_proto::coding\",\"noq_proto::coding\"]=0Ak[5,\"core::fmt\",\"core::fmt\"]Ak[5,\"noq_proto\",\"noq_proto\"]i[6,\"noq\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[5,\"hdrhistogram\",\"hdrhistogram\"]21A`[10,\"core::cmp\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]o[2,\"noq_proto\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Al[6,\"noq\",\"noq::recv_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Ak[10,\"futures_core::future\"]Ak[10,\"futures_core::stream\"]Ai[10,\"noq\",\"noq::runtime\"]Bc[5,\"std::net::udp\",\"std::net::udp\"]Ak[10,\"clap_builder::derive\"]Ak[2,\"noq_proto::connection\"]0f[3,\"\"]f[1,\"\"]Ag[2,\"noq_proto::config\"]Em[5,\"clap_builder::parser::matches::arg_matches\",\"clap_builder::parser::matches::arg_matches\"]7Am[10,\"tokio::io::async_write\"]Ai[10,\"futures_io::if_std\"]Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]Aa[10,\"equivalent\"]Ak[5,\"noq\",\"noq::connection\"]Bg[5,\"noq::connection\",\"noq::connection\"]1Bg[5,\"noq_proto\",\"noq_proto::connection\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]A`[10,\"hashbrown\"]6i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]B`[10,\"core::future::into_future\"]2Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]Ag[5,\"std::io\",\"std::io\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Bo[6,\"rustls::msgs::enums\",\"rustls::msgs::enums\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"]Cm[5,\"rustls::error::other_error\",\"rustls::error::other_error\"]A`[10,\"core::cmp\"]Am[5,\"noq\",\"noq::event_stream\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]=Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bi[5,\"noq::recv_stream\",\"noq::recv_stream\"]Al[5,\"noq\",\"noq::recv_stream\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Al[6,\"noq\",\"noq::recv_stream\"]Ai[5,\"noq\",\"noq::incoming\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bi[5,\"noq::send_stream\",\"noq::send_stream\"]Al[5,\"noq\",\"noq::send_stream\"]5Dc[6,\"rustls_pki_types::server_name\",\"rustls_pki_types::server_name\"]Ce[6,\"core::net::socket_addr\",\"core::net::socket_addr\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Ak[10,\"clap_builder::derive\"]Ak[5,\"std::time\",\"std::time\"]j[10,\"noq\"]Bd[10,\"noq_proto\",\"noq_proto::config\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]3Bc[10,\"noq_proto\",\"noq_proto::token\"]Ag[5,\"noq_udp\",\"noq_udp\"]Al[6,\"noq\",\"noq::send_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::send\"]i[2,\"noq\"]o[2,\"noq_proto\"]10Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ac[6,\"bench\",\"bench\"]Aa[5,\"bulk\",\"bulk\"]Da[6,\"noq_proto::connection::state\",\"noq_proto::connection::state\"]i[6,\"noq\"]Bc[6,\"noq_proto\",\"noq_proto::config\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]=i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Ae[10,\"tonic::request\"]j[10,\"noq\"]Bj[10,\"noq_proto\",\"noq_proto::config::qlog\"]>An[5,\"noq\",\"noq::runtime::smol\"]o[2,\"noq_proto\"]C`[6,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ci[5,\"ring::error::unspecified\",\"ring::error::unspecified\"]f[3,\"\"]i[2,\"noq\"]Ak[2,\"noq_proto::connection\"]1Co[5,\"rustls::client::client_conn\",\"rustls::client::client_conn\"]Bk[5,\"noq_proto::config\",\"noq_proto::config\"]?Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]i[5,\"noq\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Bo[6,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]i[6,\"noq\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bk[5,\"noq_proto::shared\",\"noq_proto::shared\"]5Bc[5,\"noq_proto\",\"noq_proto::shared\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]4Bc[6,\"noq_proto\",\"noq_proto::shared\"]Ag[6,\"noq_udp\",\"noq_udp\"]Bb[10,\"core::iter::traits::collect\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]1Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]2Co[5,\"rustls::server::server_conn\",\"rustls::server::server_conn\"]Bk[5,\"noq_proto::config\",\"noq_proto::config\"]i[5,\"noq\"]Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"core::net::socket_addr\",\"core::net::socket_addr\"]0Al[6,\"noq\",\"noq::send_stream\"]Ao[5,\"noq\",\"noq::runtime::tokio\"]Cg[5,\"arbitrary::unstructured\",\"arbitrary::unstructured\"]i[2,\"noq\"]j[2,\"perf\"]9Bl[5,\"noq_proto\",\"noq_proto::bloom_token_log\"]Ab[10,\"core::clone\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bc[5,\"noq_proto\",\"noq_proto::shared\"]Ai[5,\"noq\",\"noq::endpoint\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ae[5,\"noq::congestion\"]Cm[5,\"noq_proto::congestion\",\"noq_proto::congestion::new_reno\"]Bi[5,\"core::num::error\",\"core::num::error\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ec[5,\"clap_builder::builder::possible_value\",\"clap_builder::builder::possible_value\"]Bi[6,\"rustls_pki_types\",\"rustls_pki_types\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Cg[5,\"rustls::webpki::anchors\",\"rustls::webpki::anchors\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bk[5,\"noq_proto::coding\",\"noq_proto::coding\"]o[2,\"noq_proto\"]0f[3,\"\"]Ai[10,\"noq\",\"noq::runtime\"]Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Cc[6,\"noq_proto::connection\",\"noq_proto::connection\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]Ak[10,\"clap_builder::derive\"]Ag[15,\"noq_proto::Event\"]:91Ai[5,\"noq\",\"noq::incoming\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]=Bb[5,\"noq_proto\",\"noq_proto::token\"]1Al[6,\"noq\",\"noq::recv_stream\"]0C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]o[5,\"noq_proto\"]Al[5,\"noq_udp\",\"noq_udp::imp\"]Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]9i[6,\"noq\"]>Bc[5,\"noq_proto\",\"noq_proto::shared\"]2Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Ba[5,\"rustls::rand\",\"rustls::rand\"]Ao[5,\"perf::stats\",\"perf::stats\"]o[2,\"noq_proto\"]Bc[6,\"noq_proto\",\"noq_proto::packet\"]7Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bc[15,\"noq_proto::PathAbandonReason\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Ak[5,\"std::time\",\"std::time\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Da[5,\"noq_proto::config::transport\",\"noq_proto::config::transport\"]=Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bi[5,\"core::num::error\",\"core::num::error\"]Ak[5,\"noq\",\"noq::connection\"]:Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bo[5,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]122Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]106Bo[5,\"noq_proto\",\"noq_proto::token_memory_cache\"]Ba[15,\"noq_proto::ProtectedHeader\"]o[2,\"noq_proto\"]Bc[15,\"noq_proto::PathAbandonReason\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ae[5,\"noq::congestion\"]Cc[5,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]j[10,\"noq\"]Bh[10,\"noq_proto\",\"noq_proto::connection\"]9Bc[6,\"noq_proto\",\"noq_proto::packet\"]:Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]Ak[6,\"noq\",\"noq::connection\"]Cb[6,\"noq_proto\",\"noq_proto::connection::datagrams\"]f[3,\"\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bd[10,\"noq_proto\",\"noq_proto::packet\"]21Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Be[5,\"rustls::verify\",\"rustls::verify\"]Ae[10,\"rustls::verify\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]:6o[5,\"noq_proto\"]Bc[15,\"noq_proto::PacketDecodeError\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]o[2,\"noq_proto\"]Aa[6,\"perf\",\"perf\"]Am[5,\"noq\",\"noq::event_stream\"]Dg[5,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Al[5,\"noq\",\"noq::recv_stream\"]Bh[2,\"noq_proto::connection::send_buffer\"]An[2,\"noq_proto::bench_exports\"]Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]8Be[6,\"rustls::suites\",\"rustls::suites\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::varint\"]Be[6,\"rustls::webpki\",\"rustls::webpki\"]Ak[5,\"noq\",\"noq::connection\"]?j[10,\"noq\"]Bk[10,\"noq_proto\",\"noq_proto::cid_generator\"]Be[5,\"rustls::verify\",\"rustls::verify\"]6Bc[5,\"noq_proto\",\"noq_proto::config\"]Bg[5,\"noq_proto\",\"noq_proto::connection\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ao[5,\"certificate\",\"certificate\"]Bc[6,\"rustls::error\",\"rustls::error\"]5Bm[5,\"perf::noprotection\",\"perf::noprotection\"]01Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"rustls::crypto::cipher\",\"rustls::crypto::cipher\"]Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]07Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]") \ No newline at end of file +rd_("f[1,\"\"]0Al[10,\"core::ops\",\"core::ops\"]Ce[5,\"clap_builder::util::id\",\"clap_builder::util::id\"]22Ag[10,\"core::ops::arith\"]A`[10,\"core::any\"]Ao[5,\"alloc::sync\",\"alloc::sync\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ba[5,\"alloc::boxed\",\"alloc::boxed\"]Cb[10,\"bytes::buf::buf_impl\",\"bytes::buf::buf_impl\"]Ai[5,\"noq_perf\",\"noq_perf\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]Ae[10,\"core::ops::bit\"]Ac[5,\"bench\",\"bench\"]Ba[5,\"perf::client\",\"perf::client\"]Ba[5,\"perf::server\",\"perf::server\"]A`[10,\"core::cmp\"]Ak[5,\"core::pin\",\"core::pin\"]Am[5,\"alloc::vec\",\"alloc::vec\"]Ak[2,\"noq_proto::congestion\"]f[1,\"\"]00m[2,\"noq_udp\"]f[0,\"\"]f[3,\"\"]3333Ak[10,\"clap_builder::derive\"]Bn[10,\"std::os::fd::owned\",\"std::os::fd::owned\"]Af[10,\"core::ops::drop\"]Ad[10,\"core::convert\"]Aa[10,\"core::hash\"]1Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[15,\"noq_proto::ProtectedHeader\"]Ak[5,\"std::path\",\"std::path\"]Ae[5,\"noq\",\"noq::path\"]Bi[6,\"core::task::poll\",\"core::task::poll\"]Bb[10,\"core::marker\",\"core::marker\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]2f[1,\"\"]?i[2,\"noq\"]f[3,\"\"]Ag[2,\"noq_proto::config\"]Bd[2,\"noq_proto::connection::streams\"]0Ab[2,\"noq::runtime\"]55Bd[10,\"core::convert\",\"core::convert\"]Ba[5,\"bytes::bytes\",\"bytes::bytes\"]i[5,\"noq\"]Cb[5,\"noq_proto\",\"noq_proto::connection::assembler\"]Ab[10,\"core::clone\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]A`[10,\"core::fmt\"]Ag[10,\"core::ops::deref\"]Ak[5,\"core::fmt\",\"core::fmt\"]Ab[10,\"core::error\"]Ai[2,\"noq::crypto::rustls\"]Ao[2,\"noq_proto::crypto::rustls\"]Cm[5,\"noq_proto::transport_error\",\"noq_proto::transport_error\"]Bc[6,\"rustls::error\",\"rustls::error\"]Ba[8,\"clap_builder\",\"clap_builder\"]Bi[6,\"arbitrary::error\",\"arbitrary::error\"]Ai[6,\"noq::crypto::rustls\"]Ao[6,\"noq_proto::crypto::rustls\"]Dg[6,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Co[6,\"noq_proto::n0_nat_traversal\",\"noq_proto::n0_nat_traversal\"]o[2,\"noq_proto\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]2Bi[5,\"core::ops::range\",\"core::ops::range\"]Ba[15,\"noq_proto::ProtectedHeader\"]0Bb[10,\"core::marker\",\"core::marker\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ba[5,\"rustls::quic\",\"rustls::quic\"]Ah[10,\"std::io\",\"std::io\"]f[1,\"\"]f[3,\"\"]Ak[2,\"noq_proto::congestion\"]l[2,\"rustls\"]i[2,\"noq\"]o[2,\"noq_proto\"]1Ak[2,\"noq_proto::congestion\"]f[3,\"\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]Ag[10,\"core::ops::arith\"]A`[10,\"arbitrary\"]Al[10,\"tokio::io::async_read\"]Ai[10,\"futures_io::if_std\"]Am[15,\"noq_proto::StreamEvent\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ac[10,\"core::borrow\"]Aa[5,\"perf\",\"perf\"]Ak[5,\"criterion\",\"criterion\"]Cb[5,\"noq_proto\",\"noq_proto::connection::datagrams\"]Bl[10,\"noq_proto::coding\",\"noq_proto::coding\"]=0Ak[5,\"core::fmt\",\"core::fmt\"]Ak[5,\"noq_proto\",\"noq_proto\"]i[6,\"noq\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[5,\"hdrhistogram\",\"hdrhistogram\"]21A`[10,\"core::cmp\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]o[2,\"noq_proto\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Al[6,\"noq\",\"noq::recv_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Ak[10,\"futures_core::future\"]Ak[10,\"futures_core::stream\"]Ai[10,\"noq\",\"noq::runtime\"]Bc[5,\"std::net::udp\",\"std::net::udp\"]Ak[10,\"clap_builder::derive\"]Ak[2,\"noq_proto::connection\"]0f[3,\"\"]f[1,\"\"]Ag[2,\"noq_proto::config\"]Em[5,\"clap_builder::parser::matches::arg_matches\",\"clap_builder::parser::matches::arg_matches\"]7Am[10,\"tokio::io::async_write\"]Ai[10,\"futures_io::if_std\"]Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]Aa[10,\"equivalent\"]Ak[5,\"noq\",\"noq::connection\"]Bg[5,\"noq::connection\",\"noq::connection\"]1Bg[5,\"noq_proto\",\"noq_proto::connection\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]A`[10,\"hashbrown\"]6i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]B`[10,\"core::future::into_future\"]2Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]Ag[5,\"std::io\",\"std::io\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Bo[6,\"rustls::msgs::enums\",\"rustls::msgs::enums\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"]Cm[5,\"rustls::error::other_error\",\"rustls::error::other_error\"]A`[10,\"core::cmp\"]Am[5,\"noq\",\"noq::event_stream\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]=Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bi[5,\"noq::recv_stream\",\"noq::recv_stream\"]Al[5,\"noq\",\"noq::recv_stream\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Al[6,\"noq\",\"noq::recv_stream\"]Ai[5,\"noq\",\"noq::incoming\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bi[5,\"noq::send_stream\",\"noq::send_stream\"]Al[5,\"noq\",\"noq::send_stream\"]5Dc[6,\"rustls_pki_types::server_name\",\"rustls_pki_types::server_name\"]Ce[6,\"core::net::socket_addr\",\"core::net::socket_addr\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Ak[10,\"clap_builder::derive\"]Ak[5,\"std::time\",\"std::time\"]j[10,\"noq\"]Bd[10,\"noq_proto\",\"noq_proto::config\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]3Bc[10,\"noq_proto\",\"noq_proto::token\"]Ag[5,\"noq_udp\",\"noq_udp\"]Al[6,\"noq\",\"noq::send_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::send\"]i[2,\"noq\"]o[2,\"noq_proto\"]10Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ac[6,\"bench\",\"bench\"]Aa[5,\"bulk\",\"bulk\"]Da[6,\"noq_proto::connection::state\",\"noq_proto::connection::state\"]i[6,\"noq\"]Bc[6,\"noq_proto\",\"noq_proto::config\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]=i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Ae[10,\"tonic::request\"]j[10,\"noq\"]Bj[10,\"noq_proto\",\"noq_proto::config::qlog\"]>An[5,\"noq\",\"noq::runtime::smol\"]o[2,\"noq_proto\"]C`[6,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ci[5,\"ring::error::unspecified\",\"ring::error::unspecified\"]f[3,\"\"]i[2,\"noq\"]Ak[2,\"noq_proto::connection\"]1Bk[5,\"noq_proto::config\",\"noq_proto::config\"]Co[5,\"rustls::client::client_conn\",\"rustls::client::client_conn\"]?Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]i[5,\"noq\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Bo[6,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]i[6,\"noq\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bk[5,\"noq_proto::shared\",\"noq_proto::shared\"]5Bc[5,\"noq_proto\",\"noq_proto::shared\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]4Bc[6,\"noq_proto\",\"noq_proto::shared\"]Ag[6,\"noq_udp\",\"noq_udp\"]Bb[10,\"core::iter::traits::collect\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]1Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]2Bk[5,\"noq_proto::config\",\"noq_proto::config\"]Co[5,\"rustls::server::server_conn\",\"rustls::server::server_conn\"]i[5,\"noq\"]Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"core::net::socket_addr\",\"core::net::socket_addr\"]0Al[6,\"noq\",\"noq::send_stream\"]Ao[5,\"noq\",\"noq::runtime::tokio\"]Cg[5,\"arbitrary::unstructured\",\"arbitrary::unstructured\"]i[2,\"noq\"]j[2,\"perf\"]9Bl[5,\"noq_proto\",\"noq_proto::bloom_token_log\"]Ab[10,\"core::clone\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bc[5,\"noq_proto\",\"noq_proto::shared\"]Ai[5,\"noq\",\"noq::endpoint\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ae[5,\"noq::congestion\"]Cm[5,\"noq_proto::congestion\",\"noq_proto::congestion::new_reno\"]Bi[5,\"core::num::error\",\"core::num::error\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ec[5,\"clap_builder::builder::possible_value\",\"clap_builder::builder::possible_value\"]Bi[6,\"rustls_pki_types\",\"rustls_pki_types\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Cg[5,\"rustls::webpki::anchors\",\"rustls::webpki::anchors\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bk[5,\"noq_proto::coding\",\"noq_proto::coding\"]o[2,\"noq_proto\"]0f[3,\"\"]Ai[10,\"noq\",\"noq::runtime\"]Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Cc[6,\"noq_proto::connection\",\"noq_proto::connection\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]Ak[10,\"clap_builder::derive\"]Ag[15,\"noq_proto::Event\"]:91Ai[5,\"noq\",\"noq::incoming\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]=Bb[5,\"noq_proto\",\"noq_proto::token\"]1Al[6,\"noq\",\"noq::recv_stream\"]0C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]o[5,\"noq_proto\"]Al[5,\"noq_udp\",\"noq_udp::imp\"]Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]9i[6,\"noq\"]>Bc[5,\"noq_proto\",\"noq_proto::shared\"]2Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Ba[5,\"rustls::rand\",\"rustls::rand\"]Ao[5,\"perf::stats\",\"perf::stats\"]o[2,\"noq_proto\"]Bc[6,\"noq_proto\",\"noq_proto::packet\"]7Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bc[15,\"noq_proto::PathAbandonReason\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Ak[5,\"std::time\",\"std::time\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Da[5,\"noq_proto::config::transport\",\"noq_proto::config::transport\"]=Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bi[5,\"core::num::error\",\"core::num::error\"]Ak[5,\"noq\",\"noq::connection\"]:Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bo[5,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]122Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]106Bo[5,\"noq_proto\",\"noq_proto::token_memory_cache\"]Ba[15,\"noq_proto::ProtectedHeader\"]o[2,\"noq_proto\"]Bc[15,\"noq_proto::PathAbandonReason\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ae[5,\"noq::congestion\"]Cc[5,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]j[10,\"noq\"]Bh[10,\"noq_proto\",\"noq_proto::connection\"]9Bc[6,\"noq_proto\",\"noq_proto::packet\"]:Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]Ak[6,\"noq\",\"noq::connection\"]Cb[6,\"noq_proto\",\"noq_proto::connection::datagrams\"]f[3,\"\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bd[10,\"noq_proto\",\"noq_proto::packet\"]21Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Be[5,\"rustls::verify\",\"rustls::verify\"]Ae[10,\"rustls::verify\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]:6o[5,\"noq_proto\"]Bc[15,\"noq_proto::PacketDecodeError\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]o[2,\"noq_proto\"]Aa[6,\"perf\",\"perf\"]Am[5,\"noq\",\"noq::event_stream\"]Dg[5,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Al[5,\"noq\",\"noq::recv_stream\"]Bh[2,\"noq_proto::connection::send_buffer\"]An[2,\"noq_proto::bench_exports\"]Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]8Be[6,\"rustls::suites\",\"rustls::suites\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::varint\"]Be[6,\"rustls::webpki\",\"rustls::webpki\"]Ak[5,\"noq\",\"noq::connection\"]?j[10,\"noq\"]Bk[10,\"noq_proto\",\"noq_proto::cid_generator\"]Be[5,\"rustls::verify\",\"rustls::verify\"]6Bc[5,\"noq_proto\",\"noq_proto::config\"]Bg[5,\"noq_proto\",\"noq_proto::connection\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ao[5,\"certificate\",\"certificate\"]Bc[6,\"rustls::error\",\"rustls::error\"]5Bm[5,\"perf::noprotection\",\"perf::noprotection\"]01Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"rustls::crypto::cipher\",\"rustls::crypto::cipher\"]Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]07Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]") \ No newline at end of file diff --git a/pr/523/docs/search.index/root.js b/pr/523/docs/search.index/root.js index f19412ccb..9f08ada03 100644 --- a/pr/523/docs/search.index/root.js +++ b/pr/523/docs/search.index/root.js @@ -1 +1 @@ -rr_('{"normalizedName":{"I":"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","N":"ADBd","E":"OjAAAAAAAAA=","H":"3jpX1T07"},"crateNames":{"N":"j","E":"OjAAAAAAAAA=","H":"JFDJy0NX"},"name":{"N":"ADBd","E":"OjAAAAAAAAA=","H":"7bFmUNOn"},"path":{"N":"BAo","E":"OzAAAAEAAAQSugACAAQACQAAAAsAZQByAAEAeQAAAH8ABACKAAEAjQAFAJQAGwCyAOsAoAEIAKoBJADQAQ4A4wEAAOcBBQDzAQEA9wECAPsBAAAAAgUACAI8AkYEAABIBBIAXAQCAGAEAwBlBAoAcQQJAIUEAACXBAIAmwQDAKAEAACiBAAApwQAAKkEAACsBJoASAUBAEwFCABWBQgAYAUCAGYFCABzBQIAdwUEAH8FBQCNBQEAmQUCAJ0FAgCkBe0AkwYEAJkGAACbBgAAngY8ANwGDwDuBgMA8wYDAPgGGAASBwwAJAcBACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEYHAABJBwAATAd0AMIHBQDKBwYA0gfzAMgIAADKCAEAzggBANUIAADbCAUA5QgAAOcIAADqCAIA8AgBAPkIBQABCR0AIAkUADcJgQK6CwAAwQsBAMcLAADMCwAA0gsAANYLAwDiCwAA6gsJAPULBwD+CxkAGQwQACsMTQB6DAMAggwAAIQMAQCcDAEAugx3ATQOAgA5DhsBVg8AAGEPAQBnDwMAbQ8BAHAPAQBzDwEAeg8DAH8PQQDCDwIAxw8WAOQPAQDnDwIA8g8BAPcPBAD9DwIABBAEAAsQAAAaEBIALhAeAE4QHgBvEAMAdxAAAHoQAQB9EAEAgBAHAIwQAQCREAEAlxADAJwQAACeEAIAohA4AOEQBQDqEAEA7xAFAPgQBQACEQEABxFQAFkRAABdEQAAYhEBAGURAQBsEQAAdREBAHgRAwB9EaEAIBIAACISAAAlEgEAKBIAACsSAwAwEgoAPBIBAEQSAgBIEhgAYhIXAHsSAgCEEgEAjhIRAKESAgCmEgMAqxIHALUSAwC6EgUAxBICAMoSAADMEgEAzxIbAOwSAgDxEgQA+BIfABoTCwAoEwQAMBMAADYTJQBdEwQAZRMFAG0TGgCJEwIAjhMQAKETFwC7EwoAyRMFANATFADmEwMA6xMXAAYUHQA=","H":"tf4W8H1m"},"entry":{"N":"ACAl","E":"OjAAAAEAAAAAAAcBEAAAAAAAAQAHAAgACgBxAHQAdQB2AHoAewCEAIgAiQCMAJMAsACxAJ4BnwGpAd8B4AHhAeIB5AHlAeYB7QHuAe8B8gH1AfoB/AH/AQYCRQRbBF8EZARwBHsEfAR9BH4EgQSCBIYEhwSIBIkEigSLBIwEjQSOBI8ElASaBJ8EoQSjBKYEqASqBEcFSgVLBVUFXwVjBWQFZQVvBXAFcQVyBXwFfQWFBYYFhwWIBYsFjAWPBZAFkwWUBZUFlgWXBZwFoAWhBZIGmAaaBpwGnQbbBuwG7QbyBvcGEQcfByAHIQciByMHKQcsBzcHOAc5BzoHPgdFB0cHSAfIB8kH0QfHCM0I0AjRCNQI2AjZCOMI5AjtCPcI+Aj/CAAJHwk1CbkLvAu9C74LvwvAC8ULyAvLC84L1QvcC94L5QvmC+gL6Qv0C/0LKgx5DH4MgAyBDIMMhwyJDI4MjwySDJUMlgyYDJkMmgybDJ8MowypDKwMrQyvDLAMMg4zDjcOOA5ZD1wPZg91D3kPwQ/FD8YP3g/fD+sP7g/8DwAQAxAKEAwQDxAQEBUQFhAZEC0QTRBzEHwQihCOEI8QkxCbEJ0Q3BDdEN8Q4BDpEO4Q9xBhEWcRaxFtEW4RcRF0EXwRJBIpEi8SOxJHEmESehKIEooSuRLAEsESwhLJEusSGBMZEyYTJxMxEzQTXBNkE58ToBPGE88TBBQFFA==","H":"d4DgMzmO"},"desc":{"N":"FNi","E":"OzAAAAEAADoNhAEAAAEABwABAAoAVgBvAAAAcQAFAHkAAwCEAAEAhwACAIwAGwCwAOsAngEBAKkBAgDMAQIA0AEBANUBAQDYAQAA3QEJAO0BAgDyAQAA9QEAAPgBAgD8AQAA/wEAAAICAQAGAgEADAIGACoCAAA6AgAAPAIBAD8CAQBFAgIASQIAAFECBABaAgAAYQIBAGQCAABpAgAAcAIBAHMCAAB3AgAAegIAAIACAACNAgAAkgIKALUCAwC6AgAAvwIAANICAADYAgAA3gIAAOQCAQDrAgAA8QIAAPkCAAAAAwEACAMAAA8DAAATAwAAGAMDAB0DBgAwAwAAPwMUADsEBABBBAAARQQAAEcEAABJBAAASwQAAE0EDABbBAAAXwQAAGEEAABkBAAAbQQAAHAEAAB2BAEAeQQFAIEEAQCFBAoAlAQAAJoEAACfBAAAoQQAAKMEBQCqBAEArQQCALEEAwC8BIYARwUEAFQFAQBXBQIAXwUAAGEFBQBsBQAAbwUDAHcFAwB8BQEAgwUFAIsFAQCPBQEAkwUEAJwFAQCfBQIAqAXmAJIGAQCVBgEAmAYAAJoGAACcBgEAoAYAAKQGAACnBggAsQYBALUGCwDEBgAAywYBAM4GAQDUBgIA2AYDAOwGAgDwBgAA8gYBAPUGCwAGBwEAEQcAABUHAgAZBwIAHwcEACkHAAAsBwIAMQcAADMHBwA+BwAARQcAAEcHAQBPBwAAUgcZAHQHMACmBwEAuAcCALwHAgDDBwAAxQcAAMgHAQDRBwAA0wcAANcH5gDHCAQAzQgAANAIAQDUCAAA2AgBAN8IAQDjCAEA7QgAAPcIAQD8CAQADwkBABkJBAAfCQAAIwkCACcJAgAyCQEANQkCAEMJugAACgAAAgpNAFMKYAG4CwEAvAsEAMULAQDICwAAywsAAM4LAADQCwEA1QsAANcLAQDcCwAA3gsAAOULAQDoCwEA6wsJAPYLAgD6CwMAAQwBAAkMAAAUDAMAHAwBAB8MAwAkDAEAKAwCAC4MAAAwDAUANww+AHkMAAB+DAAAgAwBAIMMAACHDAAAiQwAAI4MAQCSDAAAlQwBAJgMBQCfDAAAowwAAKkMAACsDAQAuwwFAMMMbQEyDgEANw73AEAPAABGDwIASg8CAFMPAQBWDwMAXA8AAGEPAQBmDwAAaQ8BAG0PBABzDwIAdw8CAHsPAwCPDw8AoA8BAKMPAAClDwEAqQ8TAMEPAADFDwEA2w8BAN4PAQDrDwAA7g8AAPEPAAD6DwMAABAAAAMQAAAFEAMAChAAAAwQAAAPEAEAFRABABkQBQAhEAEAJhACACoQAAAsEAEANBABADsQAQA/EAQATBACAFEQAQBWEAEAYRADAHMQAAB6EAIAgxADAIoQAACMEAMAkRACAJgQAQCbEAAAnRAAAKEQAACjEAIAqxACAK8QAgCzEAYAwBAAAMwQAQDQEAkA3BABAN8QAQDpEAAA7hAAAPEQAQD3EAAA+hADAAERAAAJEQAACxEAAA0RAAASEQAAFBEDABkRAAAbEQAAHREAACARAAAiEQAAJBEAACgRAAArEQAALREAAC8RAAAzEQAANRECADsRAAA9EQAAShEBAFIRAABVEQIAWREAAGERAgBlEQIAaxEAAG0RAQBxEQAAdBEAAHwRhwAKEgQAEBIAABYSAQAZEgEAHBIAAB4SAAAgEgAAIhIAACQSAAApEgAALxIAADUSBgBHEgAAShIBAE0SAgBSEgEAVhIFAF8SAgBpEgAAbhIAAHoSAACIEgAAihIAAI4SAwCZEgMAoBIBALYSAAC5EgIAwBICAMQSAgDJEgAAzxIEAN4SAQDrEgEA7xIAAPESAwD8EgQABBMAAAYTAAAPEwIAExMCABgTAQAbEwAAHhMDACYTAQAxEwAANBMAADoTBgBQEwAAUxMBAFoTAgBeEwAAYRMAAGQTAAB5EwEAihMBAI0TAQCREwAAkxMAAJkTAwCfEwEApxMEAK8TBQC5EwEAwxMAAMYTAADPEwAA1BMDAOETAADvEwUA9hMAAPwTAAD+EwEABBQBAA4UAAASFAAA","H":"Pfd8b6JX"},"function":{"N":"A@J`","E":"OzAAAAEAAIMDWAAAAAoAcQAbAJMAAACwAAEAngEBAKkBAADPAQAA3wEiAAYCAQBFBAAARwQAAFsEAABfBAAAZAQAAHAEAAB7BC0AqgQBAEcFAABKBQEAVQUAAF8FAABjBQMAbAUAAG8FAwB2BS0AkgYAAJUGAACYBgIAnAYCAKIGAADbBgAA7AYGAPUGAAD3BgAAEQcAABwHMADBBwAAyAcBANEHAADGCDMA/wgBAB8JAAA1CQEAuQswAPQLAAD9CwAAGAwAACoMAAB5DAAAfgwDAIMMNgAyDgMANw4BAFUPAABXDxgAcg8HAH4PAADBDwAAxQ8BANsPIQD+DxsALRAAAE0QAQBrECsAmxACAKEQAADWEDAAVxElAB8SKQBhEgEAeBIbAKASAACiEhMAtxIXAOsSAADvEgsAGBMCACITEwBcEwAAXxMAAGITCgB+Ew8AnxMFALcTAwDEEwsA2xMAAOUTBQADFAQA","H":"N4rV6oa0"},"type":{"N":"AJl","E":"OzAAAAEAAHcSnAACAAQACQAAAAsAZQByAAIAeQAAAH8ABQCIAAAAigABAI0AIgCyAOsAnwEJAKoBNADjAQEA5gEIAPMBAQD3AQIA+wEAAAACBQAHAnMCgQQAAIUEAgCKBAAAjAQAAJQEAACXBAIAmwQDAKAEAACiBAAApwQAAKkEAACrBLMAYAUQAHMFAgB3BQUAfwUFAI0FAQCZBQYApAV6ASEHBAAoBwAALQcBADEHAAAzBwMAPwcAAEEHAgBFBwQATAd7AMkH/ADICAAAyggBAM0IAgDVCAAA2AgBANsIBQDlCAAA5wgAAOoIAgDwCAEA+Qi/AroLAAC8CwMAwQsBAMULAADHCwAAzAsAANILAADWCwMA3AsAAN4LAADiCwAA5QsBAOkLQAArDFIAgAwCAIQMAQCHDAAAjgwBAJIMAACbDAIArwwAALoMmgJWDwAAYQ8BAGYPBABtDwEAcA8BAHMPAgB6D2MA5A8BAOcPAgDyDwEA9w8IAAQQBAALEAAAGhBSAG8QBAB3EAAAehABAH0QAQCAEAcAjBABAJEQAQCXEEMA3xAAAOEQBQDpEAIA7xAFAPgQBQACEQEABxFQAFkRAABdEQAAYhEBAGURAgBsEQAAdREBAHgRpgAgEgAAIhIAACUSAQAoEgAAKxIDADASCgA8EgEARBICAEgSMQB7EgIAhBIBAIgSAACKEgAAjhIVAKYSAwCrEgcAtRIDALoSBQDBEgAAxBICAMoSAADMEgEAzxIfAPESBAD4Ei0AKBMEADATAAA2EysAZRMFAG0TGgCJEwIAjhMQAKETFwC7EwoAyRMFANATFADmEwMA6xMXAAYUHQA=","H":"QqzQLfta"},"alias":{"N":"`","E":"OzAAAAEAACMUAQAAACMU","H":"p2IVDFMs"},"generic_inverted_index":{"N":"b","E":"OjAAAAAAAAA=","H":"r0jTqlt6"}}') \ No newline at end of file +rr_('{"normalizedName":{"I":"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","N":"ADBd","E":"OjAAAAAAAAA=","H":"3jpX1T07"},"crateNames":{"N":"j","E":"OjAAAAAAAAA=","H":"JFDJy0NX"},"name":{"N":"ADBd","E":"OjAAAAAAAAA=","H":"7bFmUNOn"},"path":{"N":"BAo","E":"OzAAAAEAAAQSugACAAQACQAAAAsAZQByAAEAeQAAAH8ABACKAAEAjQAFAJQAGwCyAOsAoAEIAKoBJADQAQ4A4wEAAOcBBQDzAQEA9wECAPsBAAAAAgUACAI8AkYEAABIBBIAXAQCAGAEAwBlBAoAcQQJAIUEAACXBAIAmwQDAKAEAACiBAAApwQAAKkEAACsBJoASAUBAEwFCABWBQgAYAUCAGYFCABzBQIAdwUEAH8FBQCNBQEAmQUCAJ0FAgCkBe0AkwYEAJkGAACbBgAAngY8ANwGDwDuBgMA8wYDAPgGGAASBwwAJAcBACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEYHAABJBwAATAd0AMIHBQDKBwYA0gfzAMgIAADKCAEAzggBANUIAADbCAUA5QgAAOcIAADqCAIA8AgBAPkIBQABCR0AIAkUADcJgQK6CwAAwQsBAMcLAADMCwAA0gsAANYLAwDiCwAA6gsJAPULBwD+CxkAGQwQACsMTQB6DAMAggwAAIQMAQCcDAEAugx3ATQOAgA5DhsBVg8AAGEPAQBnDwMAbQ8BAHAPAQBzDwEAeg8DAH8PQQDCDwIAxw8WAOQPAQDnDwIA8g8BAPcPBAD9DwIABBAEAAsQAAAaEBIALhAeAE4QHgBvEAMAdxAAAHoQAQB9EAEAgBAHAIwQAQCREAEAlxADAJwQAACeEAIAohA4AOEQBQDqEAEA7xAFAPgQBQACEQEABxFQAFkRAABdEQAAYhEBAGURAQBsEQAAdREBAHgRAwB9EaEAIBIAACISAAAlEgEAKBIAACsSAwAwEgoAPBIBAEQSAgBIEhgAYhIXAHsSAgCEEgEAjhIRAKESAgCmEgMAqxIHALUSAwC6EgUAxBICAMoSAADMEgEAzxIbAOwSAgDxEgQA+BIfABoTCwAoEwQAMBMAADYTJQBdEwQAZRMFAG0TGgCJEwIAjhMQAKETFwC7EwoAyRMFANATFADmEwMA6xMXAAYUHQA=","H":"DECPfczH"},"entry":{"N":"ACAl","E":"OjAAAAEAAAAAAAcBEAAAAAAAAQAHAAgACgBxAHQAdQB2AHoAewCEAIgAiQCMAJMAsACxAJ4BnwGpAd8B4AHhAeIB5AHlAeYB7QHuAe8B8gH1AfoB/AH/AQYCRQRbBF8EZARwBHsEfAR9BH4EgQSCBIYEhwSIBIkEigSLBIwEjQSOBI8ElASaBJ8EoQSjBKYEqASqBEcFSgVLBVUFXwVjBWQFZQVvBXAFcQVyBXwFfQWFBYYFhwWIBYsFjAWPBZAFkwWUBZUFlgWXBZwFoAWhBZIGmAaaBpwGnQbbBuwG7QbyBvcGEQcfByAHIQciByMHKQcsBzcHOAc5BzoHPgdFB0cHSAfIB8kH0QfHCM0I0AjRCNQI2AjZCOMI5AjtCPcI+Aj/CAAJHwk1CbkLvAu9C74LvwvAC8ULyAvLC84L1QvcC94L5QvmC+gL6Qv0C/0LKgx5DH4MgAyBDIMMhwyJDI4MjwySDJUMlgyYDJkMmgybDJ8MowypDKwMrQyvDLAMMg4zDjcOOA5ZD1wPZg91D3kPwQ/FD8YP3g/fD+sP7g/8DwAQAxAKEAwQDxAQEBUQFhAZEC0QTRBzEHwQihCOEI8QkxCbEJ0Q3BDdEN8Q4BDpEO4Q9xBhEWcRaxFtEW4RcRF0EXwRJBIpEi8SOxJHEmESehKIEooSuRLAEsESwhLJEusSGBMZEyYTJxMxEzQTXBNkE58ToBPGE88TBBQFFA==","H":"NMCeoNwo"},"desc":{"N":"FNi","E":"OzAAAAEAADoNhAEAAAEABwABAAoAVgBvAAAAcQAFAHkAAwCEAAEAhwACAIwAGwCwAOsAngEBAKkBAgDMAQIA0AEBANUBAQDYAQAA3QEJAO0BAgDyAQAA9QEAAPgBAgD8AQAA/wEAAAICAQAGAgEADAIGACoCAAA6AgAAPAIBAD8CAQBFAgIASQIAAFECBABaAgAAYQIBAGQCAABpAgAAcAIBAHMCAAB3AgAAegIAAIACAACNAgAAkgIKALUCAwC6AgAAvwIAANICAADYAgAA3gIAAOQCAQDrAgAA8QIAAPkCAAAAAwEACAMAAA8DAAATAwAAGAMDAB0DBgAwAwAAPwMUADsEBABBBAAARQQAAEcEAABJBAAASwQAAE0EDABbBAAAXwQAAGEEAABkBAAAbQQAAHAEAAB2BAEAeQQFAIEEAQCFBAoAlAQAAJoEAACfBAAAoQQAAKMEBQCqBAEArQQCALEEAwC8BIYARwUEAFQFAQBXBQIAXwUAAGEFBQBsBQAAbwUDAHcFAwB8BQEAgwUFAIsFAQCPBQEAkwUEAJwFAQCfBQIAqAXmAJIGAQCVBgEAmAYAAJoGAACcBgEAoAYAAKQGAACnBggAsQYBALUGCwDEBgAAywYBAM4GAQDUBgIA2AYDAOwGAgDwBgAA8gYBAPUGCwAGBwEAEQcAABUHAgAZBwIAHwcEACkHAAAsBwIAMQcAADMHBwA+BwAARQcAAEcHAQBPBwAAUgcZAHQHMACmBwEAuAcCALwHAgDDBwAAxQcAAMgHAQDRBwAA0wcAANcH5gDHCAQAzQgAANAIAQDUCAAA2AgBAN8IAQDjCAEA7QgAAPcIAQD8CAQADwkBABkJBAAfCQAAIwkCACcJAgAyCQEANQkCAEMJugAACgAAAgpNAFMKYAG4CwEAvAsEAMULAQDICwAAywsAAM4LAADQCwEA1QsAANcLAQDcCwAA3gsAAOULAQDoCwEA6wsJAPYLAgD6CwMAAQwBAAkMAAAUDAMAHAwBAB8MAwAkDAEAKAwCAC4MAAAwDAUANww+AHkMAAB+DAAAgAwBAIMMAACHDAAAiQwAAI4MAQCSDAAAlQwBAJgMBQCfDAAAowwAAKkMAACsDAQAuwwFAMMMbQEyDgEANw73AEAPAABGDwIASg8CAFMPAQBWDwMAXA8AAGEPAQBmDwAAaQ8BAG0PBABzDwIAdw8CAHsPAwCPDw8AoA8BAKMPAAClDwEAqQ8TAMEPAADFDwEA2w8BAN4PAQDrDwAA7g8AAPEPAAD6DwMAABAAAAMQAAAFEAMAChAAAAwQAAAPEAEAFRABABkQBQAhEAEAJhACACoQAAAsEAEANBABADsQAQA/EAQATBACAFEQAQBWEAEAYRADAHMQAAB6EAIAgxADAIoQAACMEAMAkRACAJgQAQCbEAAAnRAAAKEQAACjEAIAqxACAK8QAgCzEAYAwBAAAMwQAQDQEAkA3BABAN8QAQDpEAAA7hAAAPEQAQD3EAAA+hADAAERAAAJEQAACxEAAA0RAAASEQAAFBEDABkRAAAbEQAAHREAACARAAAiEQAAJBEAACgRAAArEQAALREAAC8RAAAzEQAANRECADsRAAA9EQAAShEBAFIRAABVEQIAWREAAGERAgBlEQIAaxEAAG0RAQBxEQAAdBEAAHwRhwAKEgQAEBIAABYSAQAZEgEAHBIAAB4SAAAgEgAAIhIAACQSAAApEgAALxIAADUSBgBHEgAAShIBAE0SAgBSEgEAVhIFAF8SAgBpEgAAbhIAAHoSAACIEgAAihIAAI4SAwCZEgMAoBIBALYSAAC5EgIAwBICAMQSAgDJEgAAzxIEAN4SAQDrEgEA7xIAAPESAwD8EgQABBMAAAYTAAAPEwIAExMCABgTAQAbEwAAHhMDACYTAQAxEwAANBMAADoTBgBQEwAAUxMBAFoTAgBeEwAAYRMAAGQTAAB5EwEAihMBAI0TAQCREwAAkxMAAJkTAwCfEwEApxMEAK8TBQC5EwEAwxMAAMYTAADPEwAA1BMDAOETAADvEwUA9hMAAPwTAAD+EwEABBQBAA4UAAASFAAA","H":"Pfd8b6JX"},"function":{"N":"A@J`","E":"OzAAAAEAAIMDWAAAAAoAcQAbAJMAAACwAAEAngEBAKkBAADPAQAA3wEiAAYCAQBFBAAARwQAAFsEAABfBAAAZAQAAHAEAAB7BC0AqgQBAEcFAABKBQEAVQUAAF8FAABjBQMAbAUAAG8FAwB2BS0AkgYAAJUGAACYBgIAnAYCAKIGAADbBgAA7AYGAPUGAAD3BgAAEQcAABwHMADBBwAAyAcBANEHAADGCDMA/wgBAB8JAAA1CQEAuQswAPQLAAD9CwAAGAwAACoMAAB5DAAAfgwDAIMMNgAyDgMANw4BAFUPAABXDxgAcg8HAH4PAADBDwAAxQ8BANsPIQD+DxsALRAAAE0QAQBrECsAmxACAKEQAADWEDAAVxElAB8SKQBhEgEAeBIbAKASAACiEhMAtxIXAOsSAADvEgsAGBMCACITEwBcEwAAXxMAAGITCgB+Ew8AnxMFALcTAwDEEwsA2xMAAOUTBQADFAQA","H":"N5E3OXU7"},"type":{"N":"AJl","E":"OzAAAAEAAHcSmwACAAQACQAAAAsAZQByAAIAeQAAAH8ABQCIAAAAigABAI0AIgCyAOsAnwEJAKoBNADjAQEA5gEIAPMBAQD3AQIA+wEAAAACBQAHAnMCgQQAAIUEAgCKBAEAlAQAAJcEAgCbBAMAoAQAAKIEAACnBAAAqQQAAKsEswBgBRAAcwUCAHcFBQB/BQUAjQUBAJkFBgCkBXoBIQcEACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEUHBABMB3sAyQf8AMgIAADKCAEAzQgCANUIAADYCAEA2wgFAOUIAADnCAAA6ggCAPAIAQD5CL8CugsAALwLAwDBCwEAxQsAAMcLAADMCwAA0gsAANYLAwDcCwAA3gsAAOILAADlCwEA6QtAACsMUgCADAIAhAwBAIcMAACODAEAkgwAAJsMAgCvDAAAugyaAlYPAABhDwEAZg8EAG0PAQBwDwEAcw8CAHoPYwDkDwEA5w8CAPIPAQD3DwgABBAEAAsQAAAaEFIAbxAEAHcQAAB6EAEAfRABAIAQBwCMEAEAkRABAJcQQwDfEAAA4RAFAOkQAgDvEAUA+BAFAAIRAQAHEVAAWREAAF0RAABiEQEAZRECAGwRAAB1EQEAeBGmACASAAAiEgAAJRIBACgSAAArEgMAMBIKADwSAQBEEgIASBIxAHsSAgCEEgEAiBIAAIoSAACOEhUAphIDAKsSBwC1EgMAuhIFAMESAADEEgIAyhIAAMwSAQDPEh8A8RIEAPgSLQAoEwQAMBMAADYTKwBlEwUAbRMaAIkTAgCOExAAoRMXALsTCgDJEwUA0BMUAOYTAwDrExcABhQdAA==","H":"XypmJw7D"},"alias":{"N":"`","E":"OzAAAAEAACMUAQAAACMU","H":"p2IVDFMs"},"generic_inverted_index":{"N":"b","E":"OjAAAAAAAAA=","H":"r0jTqlt6"}}') \ No newline at end of file diff --git a/pr/523/docs/search.index/type/42acd02dfb5a.js b/pr/523/docs/search.index/type/5f2a66270ec3.js similarity index 99% rename from pr/523/docs/search.index/type/42acd02dfb5a.js rename to pr/523/docs/search.index/type/5f2a66270ec3.js index 6d75cda5a..b4dfca549 100644 --- a/pr/523/docs/search.index/type/42acd02dfb5a.js +++ b/pr/523/docs/search.index/type/5f2a66270ec3.js @@ -1 +1 @@ -rd_("CBk[\"\",\"ADswAAABAAAFAAIAOwQEAPYTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwQElQSaRLVE+ET/xMOFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJrRATElUS5xKUE5UT2BP7E/wT/RP+ExEUFRQ7MAAAAQAALAESAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAADIMAwC7DAUAqg2GADcQAACuEAcADhEAAH0RhgAUEgAAFhIAAJ4SAADoEgAABxMAADowAAABAAAAAAAdABAAAABaBWAFYQViBcIGwwbKBssGzAbNBs4Gzwa1C7YLtwu4CwgMTA9QD18QxRAPEhsTWBNZE28T0BPUE+ITABQ7MAAAAQAAPQAUAD8DFABmBAAAcgQCAEMFAQBGBQAAWwUBAHUFAAC1BgwAwgcDALQLAAAeDAAApg8AANoPAABgEAAABxEAAJ8SAADjEgMAUBMAANETAAABFAAAOzAAAAEAAFcADQDbAD0AigEBAGUEAABwBwAAcwcAALIHAAC0BwAAKRADAEkSBQBAEwAAcBMAAK8TBQDCEwAAOzAAAAEAABUABwBMBAAAfQwAADEOAACiDwMAERIAAA4TBwDvEwUAOzAAAAEAABMACQBiBAEAawQBANMGBwCxBwAAswcAAEYPAgBPDwAAwBAAAHcSAAADEgcAABMHAABmEgAAAScMAAAFbQcAAG8HAAByBwAAJAwAAL8QAAAAOzAAAAEAAAUAAgDCAQAAjxMEAAAAAacFAAA=\"]Bo[\"AAAAAAAAAAACvRMAAL4TAAAAAAAAAp4QAACfEAAA\",\"\"]0Bg[\"\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAA=\"]AGg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAADQAFAHMFAQA/CQEALQwEAH0MAAA6EQMAOjAAAAEAAAAAAAsAEAAAAGsEbASxB7MHTw9pEGoQLBEtES4RLxF3EgRcBAAAEgcAABMHAAC/DwAABEIEAABEBAAAmxMAAJwTAAAFYQQAAG8HAAByBwAASg8AAEsPAAADIwwAACUMAABJDwAAOzAAAAEAAAYAAwDCAQAAsAYAAI8TBAAB7BIAAAEmDAAA\",\"AAAAAVYRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAA==\"]ANg[\"AAAEUgIAALgCAACfBgAAowYAAAMDDAAABAwAAAUMAAACswEAAMMBAAA7MAAAAQAAhgABAH0RhgAAOzAAAAEAAAcAAwBDBQEA4xIDACEUAQAEcAcAAHMHAACyBwAAtAcAADswAAABAAASAAcAcwUBAOgGAAA/CQEALQwEAH0MAAA6EQMAGxIDADowAAABAAAAAAAKABAAAABiBGMEawRsBLEHswdPDywRLREuES8RBVwEAABeBQAAEgcAABMHAADBEAAABEIEAABEBAAAmxMAAJwTAAAEbwcAAHIHAABKDwAASw8AAATFBgAAIwwAACUMAABJDwAABY8TAACQEwAAkRMAAJITAACTEwAAAewSAAAAAacFAAA=\",\"AAAAAAACSAUAAEkFAAAAAgEMAAACDAAAAcAPAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAAAAAAAAA94GAAAVEQAAFhEAAA==\"]Dc[\"\",\"AAAAADswAAABAAAHAAEAIgkHADswAAABAAAJAAIAuhAEABARBAAAAQ8RAAA=\"]ADm[\"AAAABrABAACyAQAAvwEAAMEBAADWDwAA1w8AAAS2AQAAyQEAADUKAAA5CgAAOjAAAAEAAAAAAAkAEAAAALEBtwG4AcABygHLAacKqgqdE54TOzAAAAEAAA0ABACsBAcAeg8AAGUQAwBvEwAAArsBAACfEgAAOzAAAAEAABUACgCmAQEArQEAACsMAQB2DAEAzQ8DAFQQAQBvEgMAQBMAAL0TAQAIFAEAAb8TAAAAAAAAAAAAAAGnBQAA\",\"AAABqwEAAAK0BAAABBIAAAAAAAJADwAATBAAAAAAAAAAAAAAAAAEoQYAAKUGAAB6DAAAewwAAA==\",1]Fk[\"AAAABOsEAAAVBwAAuAcAABkRAAACIwkAAPYLAAABrxAAAAABwwcAAAELAQAAAqMPAAAPEwAAAdQGAAA=\",\"AAAAAesEAAABtgEAAA==\"]Fk[\"AAAABDUFAAAZBwAAvAcAACARAAACJwkAAPoLAAABsxAAAAGOAQAAAcUHAAAAAqUPAAATEwAAAdgGAAA=\",\"AAAAATUFAAAByQEAAA==\"]AEa[\"AAAAAq4BAAC6AQAAOzAAAAEAAAcAAQAiCQcAAARgBQAAYQUAAGIFAAAPEgAAAAABvxMAAAAAAAKeEAAAnxAAAA==\",\"AAAAADswAAABAAAQAAMAlgYAACIJBwD1CwcAOzAAAAEAAAsABAD2BgAAoBAAALoQBAAQEQQAOzAAAAEAAA8ABQCsBAcAEwwCABgSAgBQEgAA1BMAADowAAABAAAAAAAKABAAAADLEM0QzxDRENMQDxEyETMRNBE1EVATBCkQAAAqEAAAKxAAACwQAAAAAAXKEAAAzBAAAM4QAADQEAAA0hAAAAAAAAAAAAKnBQAARQ8AAA==\",1]Ec[\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCADswAAABAAAGAAIApwYEAAoJAQADXgQAAFMFAABUBQAA\",\"\"]Dg[\"AAAAAAAAAAABsBMAAAHwEwAAAAAAAAAAAAABVAcAAA==\",\"AAAAAAABVxIAAAE7EwAA\"]Eo[\"AAAAAekEAAABtQEAAAIqAAAAmQAAAAGuDwAAAUQDAAACBgEAAAcBAAA=\",\"AAABqAAAAAHpBAAAAf0SAAAAAe0LAAA=\"]Ic[\"AAAAASsFAAADxwEAABcTAACWEwAAAlgAAACmAAAABnsBAAB8AQAAQwQAAKYFAAC7DwAA4hMAAAFRAwAA\",\"AAABqQAAAAIrBQAA/xIAAAAB8QsAAAAAAAAAAAAAAAAAAAKqAAAAqwAAAA==\"]Ik[\"AAAAArwEAABuEgAAAfMGAAABkwYAAAGyAAAAAQcRAAABrxMAAAIREgAA7xMAAAAAAAAAAAAAOjAAAAEAAAAAAAkAEAAAAGcFkQZRB9IHiA+fD9EPWBCiED4R\",\"AAAAAbwEAAAAAVYSAAABOhMAAA==\"]Ck[\"AAAAAd0BAAAAAAAAAbMTAAAB8xMAAA==\",\"AAAAAAABWhIAAAE+EwAA\"]Ck[\"AAAAAd4BAAAAAAAAAbQTAAAB9BMAAA==\",\"AAAAAAABWxIAAAE/EwAA\"]Kk[\"AAAAAAAABFoFAABgBQAAYQUAAGIFAAAAOzAAAAEAAAkAAQCqCwkAOzAAAAEAAA0AAQBMBA0AOzAAAAEAAAkABAAfDAMARg8CAMAQAADUEAEAAAEnDAAAAyQMAABKDwAASw8AAAIlDAAASQ8AAA==\",\"AAAAAAABoBAAAAMTDAAAFAwAABUMAAA=\"]Nk[\"AAAAAAAAAnUSAAB2EgAABOMSAADkEgAA5RIAAOYSAAAC6RIAAOoSAAAF6AYAABsSAAAcEgAAHRIAAB4SAAACYgQAAGMEAAACXgUAAMEQAAAAAAHFBgAAAAAAAacFAAA=\",\"AAAAAAJWBQAAwxMAAAAF+RMAABwUAAAdFAAAHhQAAB8UAAABUBMAAALADwAA+hMAAAAAAAAAAAAAAAQuEAAALxAAADAQAAAxEAAA\"]Bg[\"AAAAAAAAAARTEQAAVBEAAHMTAAB0EwAA\",\"\"]Bk[\"\",\"AAAAAVIRAAAAAAAAAAAAAAAAAAAAAAFTDwAA\"]Cc[\"AAAAAAAAAV8QAAABYBAAAA==\",\"AAAAAAACOQkAADoJAAA=\"]FGo[\"AAAAADswAAABAAAVAAkADAIGAEoEAABrBQAA1AcAAP8LAAAyEAMAVRIAAJQTAQD7EwMAOzAAAAEAABMCEgBBBAAAWgQAAGAEAADJBgAA7wsDALsMBQDDDG0Bwg8AAMcPAAA3EAAAUxAAAK4QBwAOEQAAfRGGABQSAAAWEgAA6BIAAEsTAAA7MAAAAQAAwwAPALIAKAAZAXAAjAEPAEMEAABaBQAApgUAAKwGAwCxBgIAwgYBAOsLAwBEDwAAGxMAADoTBQDiEwAA9RMAADswAAABAACiAEIAPwMUAF0EAABnBAEAcgQCAEYFAABbBQEAdQUAAKcGBAC1BgwAvwcBAMIHAwDACAEACgkBACAJAQArCQEAAQwBABEMAQAeDAAAwQwBAEEPAQBRDwEAiQ8BAIwPAQCmDwAAyA8BANIPAQDaDwAAOBAAAEYQAQBdEAEAYBAAAMYQAQAPEQAAGhEAABwRAAAeEQAAIREAACMRAAAlEQAAMBEFAD8RAQBCEQIAUxEBAAUSAQBnEgEAnxIAANQSAQDaEgEA4xIDAAETAQBBEwEAURMBAFUTAQBzEwEAexMBAKUTAQC1EwEA0RMCAN0TAwDrEwMAARQAAA8UAQATFAEAFhQBABoUAQAhFAEAOzAAAAEAAI8AJgDbAD0AigEBAKYBAQBABAAAXgQAAGUEAABTBQEAbQUBAHAHAABzBwAAsgcAALQHAACqCwkAKwwBAHYMAQBNDwEAgg8BAMAPAADNDwMAVBABAKgQAQDCEAEAEhIAAF0SAQBvEgMA6RIBAAoTAQA2EwEASRMBAEwTAwBwEwAArxMFAL0TAQDCEwAA9xMBAPoTAAAIFAMAGBQBADswAAABAAAxAA0ATAQNAHMFAQDoBgAAPwkBABsMAAB9DAAAMQ4AAKIPAwA6EQMAGxIDAA4TBwBGEwEA7xMFADswAAABAAAcAA0AYgQBAGsEAQDTBgcAsQcAALMHAAAfDAMARg8CAE8PAABpEAEAwBAAANQQAQB3EgAAAhQAADowAAABAAAAAAAHABAAAABcBF4Fvw/BEDgRORFmEtkTA0IEAABEBAAAJwwAADowAAABAAAAAAAJABAAAABhBG0HbwdyByQMSg9LD54QnxC/EATFBgAAIwwAACUMAABJDwAAOzAAAAEAAAUAAgCwBgAAjxMEAAABJgwAAAGnBQAA\",\"AAAAAAA7MAAAAQAA5gABAMMM5gAAOjAAAAEAAAAAAFkAEAAAAGcEaAS/B8AHwAjBCCAJIQkrCSwJAQwCDBEMEgzBDMIMQQ9CD1EPUg+JD4oPjA+ND8gPyQ/SD9MPRhBHEF0QXhDGEMcQGhEcER4RIREjESURMBExET8RQBFTEVQRBRIGEmcSaBLUEtUS2hLbEgETAhNBE0ITURNSE1UTVhNzE3QTexN8E6UTphO1E7YT0hPTE90T3hPfE+AT6xPsE+0T7hMPFBAUExQUFBYUFxQaFBsUIRQiFDswAAABAAAvABQApgEBAG0FAQArDAEAdgwBAIIPAQDNDwMAVBABAKgQAQDCEAEAXRIBAG8SAwDpEgEAChMBADYTAQBJEwEATBMDAL0TAQD3EwEACBQDABgUAQAEPwkAAEAJAABGEwAARxMAAAACOBEAADkRAAAAAp4QAACfEAAA\"]Ic[\"AAAAARcRAAAABFcFAAAPCQAAEAkAAA4SAAA7MAAAAQAADAADAHUEBQDKBgUAjhMAAAADbAcAAMIQAADDEAAAASQQAAAAB8oQAADMEAAAzhAAANAQAADSEAAAOBEAADkRAAAAAW0HAAA=\",\"\"]Lk[\"AAACUwIAALcCAAAAArYBAADJAQAAOzAAAAEAAAsAAwC3AQEAygEBAK4QBwA7MAAAAQAABwABAKwEBwA6MAAAAQAAAAAABwAQAAAAvwfAB4kPig/SD9MPMBExEQACRhMAAEcTAAA=\",\"AAAAAYAPAAAAAAAAAAAAAAAAAAAAAAV/DwAAgQ8AAIgPAACLDwAASBMAAA==\"]AAg[\"AAAEVQIAALUCAAARCQAAEgkAAASsAQAAtAEAALkBAADGAQAAAloCAAC/AgAAAAA6MAAAAQAAAAAAEwAQAAAAZwRoBMAIwQg6EDwQPhBAEEEQyxDNEM8Q0RDTEGcSaBITFBQUFhQXFALpEgAA6hIAAAUtDAAALgwAAC8MAAAwDAAAMQwAAAAFyhAAAMwQAADOEAAA0BAAANIQAAAAAAACwgEAALAGAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAABMIIAADDCAAAxAgAAMUIAAA=\"]BKo[\"AAADDgkAANYSAADXEgAABaoBAAAXCgAAUhEAANwSAADdEgAAOjAAAAEAAAAAAAcAEAAAALUBxwETCRQJAQpSCnoKExIBFBIAAAEbEwAAOjAAAAEAAAAAABEAEAAAAMIHwwfEB8UHQA/ID8kPTBAaERwRHhEhESMRJRFBE0IT3RPeEwFAEwAAOzAAAAEAAAsAAgCiDwMADhMHADswAAABAAAJAAMA0wYHALEHAACzBwAAAAACbwcAAHIHAAA=\",\"AAAETQUAAE4FAAA4DwAAOQ8AADswAAABAAAWAAsAFAcHABgRAQAbEQAAHREAAB8RAQAiEQAAJBEAAAcSAQBtEwEAcRMAALsTAQACFxMAAJYTAAABDhIAAAAAAAAAAAAAAAAAADowAAABAAAAAABrABAAAACgAaEBowGkAQICAwIJAgoCSQRLBG0EtgS5BKAGpAbRBtIGBgcHB/wI/QgyCTMJ/gsADBYMFwwcDB0MKAwpDD4PPw9UD3sPfA+dD54P0Q8mECcQRBBFEFEQUhBWEFcQYRBiEJgQmRCiEKQQpRCrEKwQthC3ELgQuRA2ETcRShFLEQoSCxIMEg0SUhJTEl8SYBJrEm0SlBKVEpYSlxKZEpoSmxKcEtgS3hLfEuAS+xIMEw0TFhMcEx0THhMfEyATIRM4EzkTUxNUE1oTWxN5E3oTmROaE9YT1xM=\"]Ac[\"AAAAAAEwAwAA\",\"\"]Ca[\"AAAAAAJaAgAAvwIAADswAAABAAAFAAEATBEFAA==\",\"\",1]Ek[\"AAAAAAAAAAAAAAAAAAAAAAAAAsYGAADcBgAA\",\"AAAAAAACORAAADsQAAAAAjoQAAA8EAAAAAIbEgAAHBIAAA==\"]Eo[\"AAAAAAAAAAAAAAAAAAAAAAAAAscGAADdBgAA\",\"AAAAAAACPRAAAD8QAAAAAz4QAABAEAAAQRAAAAACHRIAAB4SAAA=\"]Ck[\"AAAAAAAAAAAAAAAAAAAAAAAABXAAAACkAQAArQcAAMwHAADECAAA\",\"\"]Bg[\"AAAAAAAAAUwPAAAAAAAAAjgRAAA5EQAA\",\"\"]Gk[\"AAAABGEAAADFBAAAagUAANUPAAABDgIAAAYOAAAASAQAAEUFAAAEBwAASBEAAJgTAAACxwAAAFAPAAAAAlcTAACuEwAA\",\"AAAAAcUEAAABvwgAAAFGBAAA\"]Ig[\"\",\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBGDwIAwBAAANQQAQAAAScMAAAEJAwAAEoPAABLDwAAvxAAAAMjDAAAJQwAAEkPAAAAAAEmDAAA\"]Bg[\"AAAAAAAAAAAAAAAAAAKeEAAAnxAAAA==\",\"\"]Hk[\"AAAD0AEAAAoMAAANDAAAAegEAAABtQEAAAQpAAAAmAAAADkQAAA7EAAAAa0PAAABQwMAAAMFAQAAChEAAAsRAAA=\",\"AAAC0AEAAAYMAAACaQQAAOgEAAAB/BIAAAAB7AsAAA==\"]Hk[\"AAAD0QEAAAsMAAAODAAAASoFAAABxwEAAARXAAAApQAAAD0QAAA/EAAAAnoBAAC6DwAAAVADAAADXgQAAAwRAAANEQAA\",\"AAAC0QEAAAcMAAADagQAACoFAAD+EgAAAAHwCwAA\"]2ALo[\"AAAAAAEoEAAAAAA6MAAAAQAAAAAAEQAQAAAAuwFdBBEMEgzBDMIMQQ9CD8YQxxAFEgYS6xPsEw8UEBQaFBsUAmUEAABAEwAAOzAAAAEAAAsAAgCiDwMADhMHADswAAABAAAHAAEA0wYHAAAAAAACwgEAALAGAAA=\",\"AAAHTwUAAFAFAAAKDAAACwwAAA0MAAAODAAAFRIAADowAAABAAAAAAAXABAAAAC1B7YHHgkqCQwMDwwQDDoPOw9IEEkQShCXEBcRJxEoESkRKhErEUMTrBOtE8ATwRM7MAAAAQAA+QACADkO9QADEwMAOzAAAAEAAFkABAALAFUA2RIAAAgTAQByEwAAAfUTAAAAAAQ6EQAAOxEAADwRAAA9EQAABCwRAAAtEQAALhEAAC8RAAABZhIAAAAAAAAAAAdxBAAAZwUAANAGAAA2DgAAmhAAAKoQAAA+EQAA\"]Dk[\"AAAAAAL+CQAAUQoAAAAAADswAAABAAAFAAEASRIFAAACYgQAAGMEAAAAAkIEAABEBAAA\",\"\"]BOc[\"\",\"ADswAAABAAAFAAIAOwQEAPYTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwQElQSaRLVE+ET/xMOFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJrRATElUS5xKUE5UT2BP7E/wT/RP+ExEUFRQ7MAAAAQAAKAERAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAALsMBQCqDYYANxAAAK4QBwAOEQAAfRGGABQSAAAWEgAAnhIAAOgSAAAHEwAAOjAAAAEAAAAAABsAEAAAAFoFYAVhBWIFwgbDBsoGywbMBs0GzgbPBrULtgu3C7gLTA9QD18QxRAPEhsTWBNZE28T0BPiEwAUOzAAAAEAADsAEgA/AxQAZgQAAHIEAgBDBQEARgUAAFsFAQB1BQAAtQYMAMIHAwC0CwAAHgwAAKYPAADaDwAAYBAAAJ8SAADjEgMA0RMAAAEUAAA7MAAAAQAAUgALANsAPQCKAQEAZQQAAHAHAABzBwAAsgcAALQHAABJEgUAcBMAAK8TBQDCEwAAOzAAAAEAABQABgBMBAAAfQwAADEOAACiDwMADhMHAO8TBQA7MAAAAQAAEwAJAGIEAQBrBAEA0wYHALEHAACzBwAARg8CAE8PAADAEAAAdxIAAAISBwAAEwcAAAEnDAAABG8HAAByBwAAJAwAAL8QAAAABY8TAACQEwAAkRMAAJITAACTEwAA\"]Bc[\"AAAAAAAAAAAAAAACOBEAADkRAAA=\",\"\"]Kc[\"AAAAAAHiEgAAADswAAABAAAGAAIAygYFAMUQAAACRgUAANoPAAABZQQAAAADaRAAAGoQAAB3EgAAAb8PAAA=\",\"AAAAAAABYAQAADswAAABAAAFAAEAdQQFAAAAAAAAAAAAAAAABwsCAAC1BAAAuAQAAN8GAADgBgAA4QYAAOIGAAA=\"]Do[\"AAAAAAABGAAAAAAAAd8AAAAAAAAAAAAAAAACtQQAANEGAAA=\",\"AAAAAAAAAAACTQ8AAE4PAAA=\"]Dk[\"AAAAAAABMAAAAAEfAQAAAAAAAAAAAAAAAAACuAQAANIGAAA=\",\"AAAAAAAAAAABQAQAAA==\"]Ac[\"AAABYgIAAA==\",\"\"]Fg[\"AAAABO0EAAAWBwAAuQcAABsRAAADJAkAAPcLAAD8EwAAAbAQAAAAAAENAQAAARATAAAB1QYAAA==\",\"AAAAAe0EAAAAAbcBAAA=\"]Fg[\"AAAABDcFAAAaBwAAvQcAACIRAAADKAkAAPsLAAD+EwAAAbQQAAABkAEAAAAAARQTAAAB2QYAAA==\",\"AAAAATcFAAAAAcoBAAA=\"]Bk[\"\",\"AAAAAAAAAAA7MAAAAQAAPwACANsAPQCKAQEA\"]Ck[\"\",\"AAAAAAGWBgAAOzAAAAEAAAkAAgD2BgAA+AYIAAHUEwAAAVATAAA=\"]Bo[\"\",\"AAAAAAAAAAAAAAAAApsTAACcEwAAAAAAAewSAAA=\"]Ck[\"AAACYQIAAHMCAAA=\",\"AAAAAAAAAl0TAABeEwAAAAACOhEAADsRAAA=\"]Eo[\"\",\"AAAAAAA7MAAAAQAABQABAFYSBQA7MAAAAQAABQABADoTBQAAOzAAAAEAAAUAAQCvEwUAOzAAAAEAAAUAAQDvEwUA\"]Cc[\"\",\"AAAAAAL8EgAA/RIAAAAE6wsAAOwLAADtCwAA7gsAAA==\"]Eg[\"AAAAAfEEAAAAAS0AAAAAAAIVAQAAFgEAAA==\",\"AAA7MAAAAQAACgABAJICCgAC8QQAAOMTAAAAAAF1EgAA\"]Eo[\"AAAAATEFAAAAAV8AAAAAAAKKAQAAiwEAAA==\",\"AAA7MAAAAQAACgACABgDAwAdAwYAAjEFAADkEwAAAAABdhIAAA==\"]Dg[\"AAABAAMAAAEwBQAAAAFdAAAAAoUBAACGAQAA\",\"AAABDwMAAAEwBQAAAAAAAAFeBAAA\"]Eo[\"AAAAAAAAApUBAACWAQAA\",\"AAAAAAAAB9ATAAD5EwAAABQAABwUAAAdFAAAHhQAAB8UAAAC0RMAAAEUAAAB+hMAAA==\"]Bk[\"AAAAAAAAAUUBAAA=\",\"AAAB2AIAAAAAAVoEAAA=\"]Bg[\"AAAAATsFAAAAAAGXAQAA\",\"AAAAATsFAAA=\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAXgMAAA=\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA64HAADNBwAAxQgAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAnEEAACvBwAA\",\"\"]Cc[\"AAAAAAAAAAIKCQAACwkAAAAAAAAAAAACwgEAALAGAAA=\",\"\"]Fo[\"AAAAAAACVwUAABYSAAAAAAAAAAAAAAAAAAAE0wcAAFQPAABjEAAAVREAAA==\",\"AAF1BwAAAAAAAAAAAAAAAAAAAAAAAAJkEAAACREAAA==\"]Bk[\"AAAAAVkFAAAAAAFMDwAAAaYPAAA=\",\"AAGmBwAA\"]Bg[\"AAAAAAAABGUQAABmEAAAZxAAAGgQAAA=\",\"\"]Ag[\"AAAAAq4BAAC6AQAA\",\"\"]Dg[\"AAAAAAAAAAAAAj8JAABACQAA\",\"AAAAAAAAAAAABS0MAAAuDAAALwwAADAMAAAxDAAA\"]AEg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAACwAEAHMFAQAtDAQAfQwAADoRAwA6MAAAAQAAAAAACwAQAAAAawRsBLEHswdPD2kQahAsES0RLhEvEXcSBFwEAAASBwAAEwcAAL8PAAAEQgQAAEQEAACbEwAAnBMAAAVhBAAAbwcAAHIHAABKDwAASw8AAAMjDAAAJQwAAEkPAAA7MAAAAQAABgADAMIBAACwBgAAjxMEAAHsEgAAASYMAAA=\",\"AAAAAVYRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAAAAACQgQAAEQEAAA=\"]He[\"\",\"AAAAAAAEMgwAADMMAAA0DAAANQwAAAIIDAAA1BMAAAIHEQAAUBMAAAUpEAAAKhAAACsQAAAsEAAAQBMAAAEREgAAAAFmEgAAAAFtBwAAAAHCAQAAAAABpwUAAA==\",1]AMk[\"AAACvAEAAMUBAAAGrAEAALQBAAC5AQAAxgEAANwSAADdEgAABFgFAAA3CQAA/wkAAFAKAAAEMgwAADMMAAA0DAAANQwAAAJYEwAAWRMAADowAAABAAAAAAAHABAAAAAKCQsJRhBHENQS1RLSE9MTOjAAAAEAAAAAAAkAEAAAAEAEcAdzB7IHtAdND04PwA/3E/gTAAKxBwAAswcAAA==\",\"AAAAOjAAAAEAAAAAABAAEAAAAKIBTQdOB08HUAfVB9YHNgzDD8QPXBDIEMkQYxJkEp0S3BMDNAkAACgQAACYEgAABjIMAAAzDAAANAwAADUMAABqEgAAbBIAAAAAAAJzBQAAdAUAAAACXAQAAL8PAAAAA2EEAABKDwAASw8AAAMjDAAAJQwAAEkPAAAAAAImDAAAggwAADowAAABAAAAAAALABAAAAClAW4EbwS3BLoEjwaQBggHUQfSB9MHnw8=\"]Bg[\"AAAAAAAAAAAAAVcEAAA=\",\"AAAAAaQFAAA=\"]Bk[\"AAAAAAAAADswAAABAAANAAIAdQUAALUGDAA=\",\"\"]Cc[\"AAABAQkAAAABEgIAAAAAAAFABAAA\",\"AAAAAAAAAAFdBAAA\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAbAGAAA=\",\"\"]Be[\"AAAAAAAAA2AFAABhBQAAYgUAAA==\",\"\",1]Bg[\"AAAAAAAAADswAAABAAAUAAEAPwMUAA==\",\"\"]Dk[\"AAAAAAHIAQAA\",\"AAAAAAUtCQAALgkAAC8JAAAwCQAAMQkAAAAAAAAAAAAAAAAAAAH9DwAA\"]Cc[\"AAAAAcQEAAAAAQ0AAAACvwAAAMAAAAA=\",\"AAAAAcQEAAA=\"]Bg[\"AAAAAAAAAAAAAVIEAAA=\",\"AAAAAcYHAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWYAAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAaoAAAA=\",\"\"]C@i[\"AAAAAAHIAQAAAZ4SAAABbxMAAAK7AQAAnxIAADowAAABAAAAAAAbABAAAACtAW0FbgWCD4MPqBCpEF0SXhIKEwsTNhM3E0kTShNME00TThNPE1cTcBOuE/cT+BMKFAsUGBQZFDswAAABAAAGAAMAPwkBAKIPAwC/EwAAAQIUAAAB2RMAAAAAAcUGAAAAAAABpwUAAA==\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAAEAwwAAAQMAAAFDAAABBIAADowAAABAAAAAAAXABAAAACcAakEbgdxB8cHvgi/CC0JLgkvCTAJMQk0CR8QIBAhECIQIxCYEqESAxMEEwUTBhM7MAAAAQAAIAAOANkBAADbAQAAQQQAAEYEAABaBAAAYAQAAPgGCAAyDAMAQw8AAFMQAAC6EAQAEBEEAOESAABLEwAAOzAAAAEAACMACQBDBAAAdQQFAKYFAADQBwAARA8AAKkPEwBQEgEAXRMBAGATAQA7MAAAAQAACAAEADgQAAAyEQMAQhECAHgTAAA7MAAAAQAADAAGAEAEAABNDwEAKRADAAoRAwBXEwAArhMAAAQbEgAAHBIAAB0SAAAeEgAAOzAAAAEAAAYAAwAfDAMA1BABAAIUAAAEXAQAAL8PAADBEAAA2RMAAAAAAcUGAAABwgEAAAAAOjAAAAEAAAAAABwAEAAAAKwArQCuAK8Apga0BgEHAgcDB/oIOwk8CT0JPglBCUIJjg+nD6gPyg/LD8wPWRBaEFsQQREJEn0TIBQ=\",1]Bg[\"AAAAAAAAAAAAAAAAAAKeEAAAnxAAAA==\",\"\"]Jo[\"AAAAAc8EAAAAOjAAAAEAAAAAAAcAEAAAABkAlQDZAUYEQw9NEVARCBMCqg8AAFASAAACQAMAALYGAAAC4AAAAOEAAAAAAbEHAAAAAAFvBwAA\",\"AAF6BwAAAANhAAAAYgAAAM8EAAACWgIAAMcHAAACTREAAFARAAAAAagGAAA=\"]A@c[\"AAAAAfgEAAAABzIAAACdAAAA2wEAAE8RAABREQAA4RIAAAkTAAAHIgEAACMBAABEDwAAsg8AAL4PAABLEAAAURIAAARIAwAAuwYAAB4MAAB4EwAAARISAAABMQ4AAAKzBwAAAhQAAAHZEwAAAAFyBwAA\",\"AAGPBwAAAAH4BAAAAr8CAABWBQAAAk8RAABREQAAAa0GAAAAAAEbDAAAAAFmEgAAAAAAAAAABWYAAABnAAAAaAAAAGkAAABqAAAA\"]Bo[\"\",\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwA=\"]CDe[\"\",\"AAA7MAAAAQAA5gABAMMK5gA7MAAAAQAA7QAMAMoJMwAACgAAAgoyADYKAgA6ChUAUwoeAHMKBgB7CioAqAoBAKwKFgBPEgAA4xMBADowAAABAAAAAAASABAAAABdBaUFlgYTCRQJ/gn/CQEKNQo5ClAKUQpSCnIKegqmCqsK/BL9EjowAAABAAAAAAASABAAAABIBEUF9gYEBzkJOgmnCqoKSBFWElcSWBJZEloSWxIHE5gTnROeEzowAAABAAAAAAApABAAAADCBsMG0Ae1C7YLtwu4C+sL7AvtC+4LCAxQD3oPvg9LEF8QZRBmEGcQaBDFEHUSdhI6EzsTPBM9Ez4TPxNdE14TYBNhE9AT1BP5EwAUHBQdFB4UHxQ6MAAAAQAAAAAAGgAQAAAAXQRyBHMEdARbBVwFpwaoBqkGqgarBh4M2g86EDwQPhBAEEEQYBAPEUIRQxFEEVATeBPREwEUOzAAAAEAAFkADwDbAD0AigEBAEAEAABeBAAAZQQAAFMFAQBsBwAATQ8BAMAPAAASEgAASRIFAFcTAACuEwYAwhMAAPoTAAA7MAAAAQAAEQAIAHMFAQAbDAAAfQwAADEOAAAkEAAAOhEDAEYTAQDvEwUAOjAAAAEAAAAAAAgAEAAAAGIEYwRPD2kQahDUENUQdxICFDowAAABAAAAAAALABAAAABcBF4FEgcTB78PyhDMEM4Q0BDSEGYS2RMEQgQAAEQEAACbEwAAnBMAAARtBwAAbwcAAHIHAAC/EAAAAiMMAABJDwAAOzAAAAEAAAYAAwDCAQAAsAYAAI8TBAAB7BIAAAABpwUAAA==\",1]Le[\"\",\"AAAAAswBAACUBgAAA/QGAAA8DwAAPQ8AAAPmBgAAahIAAGwSAAA6MAAAAQAAAAAABwAQAAAATA8PEhgSGRIaElgTWROOEwJmBAAAtAsAAAGtAQAAAb8TAAAERg8AAEcPAABIDwAAwBAAAAABJwwAAARhBAAAJAwAAEoPAABLDwAAASUMAAAAAAEmDAAA\",1]Gc[\"\",\"AAAAOjAAAAEAAAAAAAcAEAAAAN0B3gEQEmkS1RPhE/8TDhQC8wYAACgQAAAFkwYAAA8JAAAQCQAAfQ8AAA4SAAABGxMAAAEHEQAAAUATAAA=\"]Bo[\"\",\"AAAAAv4SAAD/EgAAAATvCwAA8AsAAPELAADyCwAA\"]Bk[\"\",\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCAA==\"]Fc[\"AAAAAcQBAAAAAAAABG0FAABuBQAAgg8AAIMPAAA=\",\"AAA7MAAAAQAAPgABADcMPgAAAAAAAAAAAAAAAAAAAAAB4wYAAA==\"]Ao[\"\",\"AAA7MAAAAQAA5gABANcH5gA=\"]A@o[\"AAAEaQIAAHoCAACAAgAAOA8AAAHNBAAAA+cSAAARFAAAFRQAAAMWAAAAlAAAAEwRAAABqQ8AADowAAABAAAAAAAMABAAAAA/A3IEcwRDBUQFWwW1Bj8RURN7E6UT3xPtEwLbAAAA3AAAAA==\",\"AAF5BwAAOzAAAAEAAAYAAwBRAgQAEQkAANYSAAABzQQAAAQTCQAA/gkAAP8JAAABCgAAAUwRAAAB6wsAAAOnBgAAQhEAAEMRAAAAAAAAAAAAAAAAATAPAAA=\"]ABc[\"AAAE3gIAAAEDAAAIAwAAOQ8AAAH1BAAAAAQuAAAAmwAAAE4RAADoEgAABBsBAAAcAQAAsA8AAOITAAA6MAAAAQAAAAAACgAQAAAARgN0BEYFXAW6BkARUhN8E6YT4BPuEwABMQ4AAA==\",\"AAGOBwAAB7UCAAC2AgAAtwIAALgCAAC6AgAAEgkAANcSAAAB9QQAAAQUCQAAUAoAAFEKAABSCgAAAu8LAABOEQAAAqwGAADQBwAAAUQRAAAAAAAAAAAAAAAABDIPAAAzDwAANA8AADUPAAA=\"]Gc[\"AAA7MAAAAQAACwAEABoQBAAAEwAApxMEABIUAAA=\",\"ADswAAABAAAJAAMAUgcBAFUHAgDPEgQAOzAAAAEAAAsABAAaEAQAABMAAKcTBAASFAAA\"]Ig[\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBGDwIAwBAAANQQAQAAAScMAAAEJAwAAEoPAABLDwAAvxAAAAMjDAAAJQwAAEkPAAAAAAEmDAAA\",\"\"]Cc[\"AAAAArABAADIEAAAAAAAAAErDAAAAAFrBAAAARIHAAA=\",\"\"]Cc[\"AAAAAr8BAADJEAAAAAAAAAEsDAAAAAFsBAAAARMHAAA=\",\"\"]ABg[\"AAAAAu0SAADuEgAAAAW3AQAAuAEAAMoBAADLAQAADhEAADswAAABAAALAAMArAQHAFoFAAATDAIAOjAAAAEAAAAAAAcAEAAAAEYFwgfDB8QHxQdRD1IPpg8HChEAAAsRAAAMEQAADREAAHATAADCEwAA+hMAADswAAABAAANAAQAGwwAADEOAACiDwMADhMHADswAAABAAAHAAEA0wYHAAPBEAAAZhIAANkTAAAAAW0HAAABxQYAAAAAAAGnBQAA\",\"AAAAA9MBAADUAQAA1QEAAAABUxAAAA==\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUQUAAOkGAAA=\",\"AAAAAAAAAAIyEQAAMxEAAAAAAAAAAAAAAAACxgYAANwGAAA=\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUgUAAOsGAAA=\",\"AAAAAAAAAAI0EQAANREAAAAAAAAAAAAAAAACxwYAAN0GAAA=\"]Ak[\"\",\"AAAAAAKgDwAAoQ8AAA==\"]Eo[\"AAAABO8EAAAXBwAAugcAAB0RAAACJQkAAPgLAAABsRAAAAAAAQ8BAAABERMAAAHWBgAA\",\"AAAAAe8EAAAAAbgBAAA=\"]Eo[\"AAAABDkFAAAbBwAAvgcAACQRAAACKQkAAPwLAAABtRAAAAGSAQAAAAABFRMAAAHaBgAA\",\"AAAAATkFAAAAAcsBAAA=\"]Bg[\"AAAAAAAAAAAAAVEEAAA=\",\"AAAAATgJAAA=\"]Ag[\"AAACrwEAAL4BAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAIkDAAAvxAAAA==\",\"\"]Ag[\"\",\"AAACQhAAAEMQAAA=\"]Bg[\"AAAAAAAAAAAAARESAAA=\",\"AAABbwAAAA==\"]Dg[\"AAAAAtMBAADUAQAAAAADYAUAABMMAAAYEgAAAAGtAQAAAb8TAAA=\",\"AAAAAQQSAAA=\"]Hg[\"AAAAAScRAAABAxMAAAM5EAAAuxAAABERAAABXRMAAAEyEQAAASkQAAACOhEAABsSAAABLBEAAAAAAAABkBMAAA==\",\"AAAAAAAAAALLEAAAzRAAAAAAAALKEAAAzBAAAA==\"]Ig[\"AAAAASoRAAABBRMAAAM9EAAAvRAAABMRAAABYBMAAAE0EQAAASsQAAACPBEAAB0SAAABLhEAAAAAAAABkhMAAA==\",\"AAAAAAEIEQAAAAADzxAAANEQAADTEAAAAAAAA84QAADQEAAA0hAAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAm4AAAA1DwAA\",\"\"]Bk[\"AAAAAAAAAdoAAAAAAAFZBAAA\",\"AAAAAc8HAAA=\"]Cc[\"AAAAAVwQAAABFxMAAAACQwQAAKYFAAA=\",\"AAAAAAHUBwAA\"]Ek[\"AAAAAdQEAAAAAR0AAAAAAAHmAAAAAAAAAAAAAAAAArcEAACPBgAA\",\"AAF/BwAAAAHUBAAAAAAAAAAAAWkQAAA=\"]Ek[\"AAAAAQUFAAAAAT0AAAABNAEAAAAAAAAAAAAAAAAAAroEAACQBgAA\",\"AAGWBwAAAAEFBQAAAAAAAAAAAWoQAAA=\"]Be[\"AAAAAAA7MAAAAQAAhgABAH0RhgA=\",\"\",1]Bg[\"AAAAAAAAAAAAAVQEAAA=\",\"AAAAAeoLAAA=\"]Ec[\"AAAAAAAAAAAAAAAAAAJvBwAAcgcAAAHFBgAAAsIBAACwBgAA\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Dk[\"AAAAAAAAAAABsRMAAAHxEwAA\",\"AAAAAAABWBIAAAE8EwAAAAAAAAAAAAAAAAABVAcAAA==\"]Dg[\"AAAAAR0FAAAAAAJfAQAAYAEAAAG+BgAAAAAAAAAAAAAAAAELAgAA\",\"AAAAAR0FAAA=\"]ABc[\"AAAAA6oBAAARCgAAUhEAAAPEBgAAcgoAAK0QAAAAADowAAABAAAAAAANABAAAAAgCSEJKwksCYwPjQ9dEF4Q2hLbEgETAhNVE1YTOzAAAAEAAA8ABwCoEAEASRIFAAoTAQBXEwAArhMAAAoUAQAYFAEAAAECFAAAAdkTAAA=\",\"AAAAA50BAACoAQAAJRAAAAQfEAAAIBAAACEQAAAiEAAAAtkBAADbAQAAAAACVxMAAK4TAAAAAQIUAAAB2RMAAAAAAAAAAATaAQAA3AEAAP4IAABVEQAA\"]Bk[\"AAAAAAHzBgAA\",\"AAAAAAAAAAEHEQAAAAEREgAA\"]Ho[\"AAAABcIEAABpBQAApAUAAHwMAABjEgAAAj0PAADYEwAAAuYGAACeEgAAA70AAAAPEgAAbxMAAAFEBQAAAWwHAAABJBAAAA==\",\"AAAAAsIEAACUBgAAAfQGAAAAAAABrQEAAAG/EwAA\"]Gc[\"AAAAAmQSAABxEwAAAZsGAAAByQYAAAEaAQAAAjgQAACfEgAAAAHoBgAAAAFeBQAAAAFtBwAAAcUGAAAAAAABpwUAAA==\",\"AAAAAAAAAAG7AQAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAW0AAAA=\",\"\"]Fg[\"AAADyAYAAOcGAACaDwAABA8MAABPEAAARxEAAMATAAAFDQIAAF0FAAClBQAAbgcAAC8JAAAAAsMAAAB6DwAA\",\"AAABphAAAA==\"]Fg[\"AAAABBAMAABQEAAASREAAMETAAACcQcAADAJAAAByQYAAAFiAQAAAAAB6AYAAAABXgUAAAAAAAAAAAGnBQAA\",\"AAABpxAAAA==\"]Dg[\"AAAAASIFAAAAAVEAAAABawEAAA==\",\"AAAAASIFAAAAAAAAAAAAAAAAAAAAAAFwAAAA\"]Bk[\"AAAAAAEMAgAAAAAAAAFOBAAA\",\"AAAAARkMAAA=\"]Cc[\"AAAAAAHHBwAAAAAAAAFPBAAA\",\"AAAAAAACGgwAAGUSAAA=\"]Dk[\"\",\"AAAAADswAAABAAATAAEAWAcTADswAAABAAATAAEAlAATADswAAABAAATAAEAqQ8TAA==\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWsAAAA=\",\"\"]Fg[\"AAAAATwFAAAAAAGZAQAAAAAAAAAAAWEEAAAAAAABJgwAAAauAAAApQEAAAUCAAC0BgAACAcAAAkSAAA=\",\"AAGlBwAAAAE8BQAA\"]Hk[\"AAAEqAAAAFQCAABNBQAABgwAAAHqBAAAAAIrAAAAmgAAAAGvDwAAAkUDAAC5BgAAAggBAAAJAQAA\",\"AAABgAIAAARjAAAAZAAAAGUAAADqBAAAAbUBAAAAAe4LAAABqwYAAA==\"]Kc[\"AAAEqQAAALYCAABOBQAABwwAAAEsBQAAAARZAAAApwAAAMIPAADHDwAAA30BAAB+AQAAvA8AAAJSAwAAwAYAAA==\",\"AAABCAMAAAEsBQAAAccBAAAB8gsAAANDBAAApgUAALIGAAAAAAAAAAAAAAAAAARrAAAAbAAAAG0AAABuAAAA\"]Ak[\"AAAAAALYDwAA2Q8AAA==\",\"\"]Ao[\"AAAAAAAAAAACpgEAAEkSAAA=\",\"\"]Ao[\"AAAAAAAAAAACpwEAAEwSAAA=\",\"\"]Dc[\"AAAAAAAAAAABCgEAAAAAAAAAAAAAAAWsAAAAbgQAAAEHAACEDwAAWRAAAA==\",\"\"]Fc[\"AAAAAAAAAX8BAAAAAAAAAAAAAAAAAAWtAAAAbwQAAAIHAACFDwAAWhAAAA==\",\"AAAAAAAAAAAAAegGAAAAAl4FAADBEAAA\"]Fc[\"AAAAAT0FAAAAAAGaAQAAAmYEAAC0CwAAAAAAAAEnDAAAAAAAAAAFrwAAAAMHAAD7CAAAhg8AAFsQAAA=\",\"AAAAAT0FAAA=\"]Hg[\"AAABjQAAAAHQBAAAAAIaAAAAuwwAAAAAAeIAAAAAAAAAAAAAAAADoAEAALYEAAD+CwAA\",\"AAF7BwAAAAHQBAAAAAAAAAAAAAAAAAAAAAAECQcAAAoHAAANBwAADgcAAA==\"]Hg[\"AAAAApAAAAD/BAAAAAI4AAAAvgwAAAEsAQAAAAAAAAAAAAAAAAADoQEAALkEAAAADAAA\",\"AAGSBwAAAAH/BAAAAAAAAAAAAAAAAAAAAAAECwcAAAwHAAAPBwAAEAcAAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWwAAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmcAAADlBgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVMEAAA=\",\"AAAAAboMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAasAAAA=\",\"\"]Dk[\"AAAAAewEAAABtgEAAAABrQQAAAEaEQAAAQwBAAA=\",\"AAGIBwAAAAHsBAAAAAAAARoRAAA=\"]Dk[\"AAAAATYFAAAByQEAAAACjwEAALEEAAABIREAAA==\",\"AAGhBwAAAAE2BQAAAAAAASERAAA=\"]Hc[\"AAAAAAABfQ8AAAGOEwAAAAGyEwAAAfITAAAAAAAAAAAAADowAAABAAAAAAANABAAAADQBvoIPQk2DosPjg/KD5oQqhBBEWsSbRJIE30T\",\"AAAAAAABWRIAAAE9EwAA\"]Ak[\"AAAAAAKUEwAAlRMAAA==\",\"\"]Cg[\"AAAAAZ0SAAABNAkAAAFgBAAAAAABZQQAAA==\",\"AAAAAAH/CwAA\"]Ag[\"\",\"AAAAAAAAAbMGAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmgAAABFDwAA\",\"\"]Ag[\"AAAAAAAAAAHBBgAA\",\"\"]Dk[\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwAAOzAAAAEAAD8AAgDbAD0AigEBAA==\",\"\"]Hg[\"AAAAAi0FAADqBgAAATEJAAAEWgAAAAgTAAAJEwAAchMAAAOAAQAAgQEAAPUTAAABUwMAAAABGwwAAAABZhIAAAAAAcUGAAA=\",\"AAABhw8AAAEtBQAAAcgBAAAAAUsQAAA=\"]Dk[\"AAAAAeAEAAAAASIAAAAAAbcGAAAC9gAAAPcAAAA=\",\"AAAAAuAEAAAXCgAAAAAAAakGAAA=\"]Dk[\"AAAAARcFAAAAAUgAAAACUQEAAFIBAAABvAYAAA==\",\"AAAAARcFAAABegoAAAABrgYAAA==\"]Ck[\"AAAAAcMPAAAAAAAAAnAHAACyBwAA\",\"AAAAAAAAAAACKRAAACoQAAA=\"]Ck[\"AAAAAcQPAAAAAAAAAnMHAAC0BwAA\",\"AAAAAAAAAAACKxAAACwQAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAqMQAAAXEgAA\"]Ek[\"AAAAA9UHAAAHEgAAbRMAAAAAAAAAAAGxBwAAAAABbwcAAA==\",\"AAAAAAAAAAIyEQAAMxEAAAIpEAAAKhAAAA==\"]Ek[\"AAAAA9YHAAAIEgAAbhMAAAAAAAAAAAGzBwAAAAABcgcAAA==\",\"AAAAAAAAAAI0EQAANREAAAIrEAAALBAAAA==\"]Dg[\"AAAAAQsFAAAAAUQAAAACPwEAAEABAAA=\",\"AAAAAQsFAAAAAAAAAAEbDAAAAAFmEgAA\"]Cc[\"AAAB2AIAAAH7BAAAAAE0AAAAASYBAAA=\",\"AAAAAfsEAAA=\"]Ic[\"AAABjwAAAAHSBAAAAAIcAAAAvQwAAAAAAeQAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA2gEJAgkHDQcCCQYJPg9/D0QQlBIMExwTOBM=\",\"AAF9BwAAAALSBAAAagUAAAABQw8AAA==\"]Ho[\"AAAAApIAAAABBQAAAAI6AAAAwAwAAAEuAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA3AEKAgsHDwcECQgJPw+BD0UQlRINEx0TORM=\",\"AAGUBwAAAAEBBQAAAAABRA8AAA==\"]Gk[\"AAACOgIAAEACAAAByAQAAAACEQAAAPoGAAACzQAAAM4AAAA=\",\"AAACPAIAAD0CAAAByAQAAAAAAAACTQ8AAE4PAAAAAAJcBAAAvw8AAAABvxAAAAEjDAAA\"]Do[\"AAAAAQMFAAAAAjsAAACeAAAAAzABAAAxAQAAsw8AAAFJAwAA\",\"AAAAAQMFAAAAAAAAAUAEAAA=\"]Ck[\"AAAAAnUTAAB2EwAAAAAAAAAAAAABJwwAAA==\",\"AAAAAAABoBAAAA==\"]Co[\"AAAAAAAB5gYAAAMYEgAAGRIAABoSAAAAAa0BAAA=\",\"AAAAAAABfQ8AAA==\"]K@m[\"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\",1]Eo[\"AAAAAAA7MAAAAQAABQABAFYSBQA7MAAAAQAABQABADoTBQAAOzAAAAEAAAUAAQCvEwUAOzAAAAEAAAUAAQDvEwUA\",\"\"]Ck[\"AAAAAAAAAVoFAAAAAAFMBAAA\",\"AAAAAAAAAxMMAAAUDAAAFQwAAA==\"]Cc[\"\",\"AAAAAAAESAQAAAQHAABIEQAAmBMAAAAAAlcTAACuEwAA\"]Fc[\"AAAAAf4EAAAAATcAAAACKgEAACsBAAA=\",\"AAGRBwAAAAH+BAAAAAACvg8AAEsQAAACHgwAAHgTAAAAAAECFAAAAdkTAAA=\"]Eo[\"AAAAAUURAAABLQkAAAACuAAAAAgMAAABDxEAAAABUAQAAA==\",\"AAAAAAGlBQAAAAIIDAAAeg8AAAABbAcAAAEkEAAA\"]Dk[\"AAAABhASAABpEgAA1RMAAOETAAD/EwAADhQAAAAAAAABQBMAAA==\",\"AAAAAAAAAAEHEQAA\"]A@g[\"AAAAOjAAAAEAAAAAABIAEAAAAGkEvwRoBZcGxgc4CeoLGQw2DLoMvQ/UD8QQRhFUEkMTdxOXE9wTOjAAAAEAAAAAAAcAEAAAAC4JIxATEpgS4hLnEhEUFRQ6MAAAAQAAAAAABwAQAAAA2QFGBBoMQw+6EBARZRIHEzowAAABAAAAAAAHABAAAAC5AMUQUBLQE/kTABQcFB4UAUMFAAAAAAAAAAAAAY8TAAA=\",\"AAAAAb8EAAABvggAAAABCAwAAA==\"]ACk[\"AAAAOjAAAAEAAAAAAAgAEAAAAGoEHgkMDDoPgA+XECkRrBOtEzowAAABAAAAAAAHABAAAABKBFYFawXUB/8LCBFVEpYTOjAAAAEAAAAAAAoAEAAAANsBWgTCD8cPNxBTEA4RFBLhEugSSxM6MAAAAQAAAAAABwAQAAAAGQFED74PSxBREuITHRQfFAVGBQAAHgwAAHgTAADREwAAARQAAAQSEgAAcBMAAMITAAD6EwAAAhsMAAAxDgAAAQIUAAADwRAAAGYSAADZEwAA\",\"AAAAAAAAAAAAAAAAAAFtBwAAAAAAAAGnBQAA\"]Ho[\"AAAAAxQHAAC3BwAAGBEAAAMiCQAA9QsAAPsTAAABrhAAAAABwgcAAAACog8AAA4TAAAB0wYAAA==\",\"AAAAAAT1CwAA9gsAAPcLAAD4CwAAAAWsBAAArQQAAK4EAACvBAAAUBIAAA==\"]Ho[\"AAAAAxgHAAC7BwAAHxEAAAMmCQAA+QsAAP0TAAABshAAAAABxAcAAAACpA8AABITAAAB1wYAAA==\",\"AAAAAAT5CwAA+gsAAPsLAAD8CwAAAAWwBAAAsQQAALIEAACzBAAAURIAAA==\"]No[\"AAABjgAAAAHRBAAAAAIbAAAAvAwAAAAAAeMAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAgJJBKAGBgf8CDIJFgwcDCgMew+dDyYQURBWEGEQmBCkEKsQthC4EBURNhFKEQoSDBJSEl8SmRKbEt4SHhMgE1MTWhN5E5kT1hM=\",\"AAF8BwAAAAHRBAAAAAAAAAAAAAAAAAAAAAAEAgkAAAMJAAAGCQAABwkAAA==\"]No[\"AAAAApEAAAAABQAAAAI5AAAAvwwAAAEtAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAwJLBKQGBwf9CDMJFwwdDCkMfA+eDycQUhBXEGIQmRClEKwQtxC5EBYRNxFLEQsSDRJTEmASmhKcEt8SHxMhE1QTWxN6E5oT1xM=\",\"AAGTBwAAAAEABQAAAAAAAAAAAAAAAAAAAAAEBAkAAAUJAAAICQAACQkAAA==\"]Cc[\"AAAAAecEAAAAAAAAAQMBAAA=\",\"AAAAAecEAAAAAAG1CwAA\"]Ck[\"AAAAASgFAAAAAAF3AQAA\",\"AAAAASgFAAAAAAO2CwAAtwsAALgLAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAFhBAAAAAAAASYMAAA=\",\"\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAATYPAAA=\"]Eo[\"AAAAARgFAAAAAUoAAAACVQEAAFYBAAABvQYAAA==\",\"AAAAARgFAAAAAAGvBgAAAAAAAAAAAAAAAAACTAUAADcPAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAgwUAAANFAAA\"]Ck[\"AAAAAAAAAAABwhMAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAABIxQAAA==\"]Ag[\"AAACmgIAABoDAAA=\",\"\"]Bo[\"AAAAAAAAAcEAAAAAAAABIQwAAA==\",\"AAAAAb0PAAA=\"]Cc[\"AAAAAAACGgwAAGUSAAABUA8AAA==\",\"AAAAAAABBAcAAA==\"]Gc[\"AAAAAfoEAAAAATMAAAABJQEAAAABEhIAAAEbDAAAAAFmEgAA\",\"AAGQBwAAAAH6BAAAAAHhEgAAAb4PAAAAARISAAAAAAAAAAAAAAABBQcAAA==\"]Do[\"AAAAAAAAAAFRDwAAAm0FAACCDwAA\",\"AAAAAa4BAAAAAAABUQ8AAARtBQAAgg8AAAoRAAALEQAA\"]Do[\"AAAAAAAAAAFSDwAAAm4FAACDDwAA\",\"AAAAAboBAAAAAAABUg8AAARuBQAAgw8AAAwRAAANEQAA\"]Ao[\"AAAAAAEoEAAAAAABTBAAAA==\",\"\"]Gc[\"AAABJhEAAAJjAAAAtQcAAAEQAgAAAAHJAAAAAnIEAABCEQAAAk0PAADADwAAAAFPDwAAAlwEAAC/DwAAAAIkDAAAvxAAAAIjDAAAJQwAAA==\",\"\"]Cc[\"AAAAAAAAAANdBAAAdAQAAEQRAAA=\",\"AAAAAAABwg8AAA==\"]Ec[\"AAABPAIAAAHJBAAAAAISAAAA+wYAAALPAAAA0AAAAA==\",\"AAABPwIAAAHJBAAAAAAAAkIRAABDEQAA\"]Bo[\"AAABphAAAAAAAALEAAAAxQAAAA==\",\"AAAAAAFdBQAA\"]Ck[\"AAABpxAAAAAAAAJmAQAAZwEAAA==\",\"AAAAAAAAAAAAAAABXgUAAA==\"]Ao[\"AAAAAAAAARsTAAABQA8AAA==\",\"\"]Hg[\"AAAAAmUAAADPBwAAARECAAABOQkAAAPVAAAAwgYAAF8QAAACWwUAANoPAAAAAnMFAAB9DAAABkYPAABHDwAASA8AAGkQAADAEAAAdxIAAAAAAkoPAABLDwAAAUkPAAA=\",\"\"]Dk[\"AAAAAAABOgkAAALDBgAA0AcAAAJcBQAAYBAAAAABdAUAAAFqEAAA\",\"AAAAAAABxw8AAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\",\"\"]ABc[\"AAABhw8AAAGUBgAAAsgBAAD0BgAABJMGAAAaDAAAfQ8AAGUSAAAC0BMAAAAUAAADBxEAANETAAABFAAABWwHAAAKEQAACxEAAAwRAAANEQAAASQQAAAAAAABbQcAAA==\",\"AAAABeoGAABFEQAARhEAAEcRAABJEQAAA5wBAAA8DwAAPQ8AAAFIEQAABfkTAAAcFAAAHRQAAB4UAAAfFAAAAXgTAAAB+hMAAAEREgAAAAAAAAAAAAJWDwAAcA8AAAUEAgAABQIAAIQPAACFDwAAhg8AAA==\"]Cc[\"AAAAARkFAAAAAUsAAAACVwEAAFgBAAA=\",\"AAAAARkFAAA=\"]Dc[\"AAAAAAAAAAA7MAAAAQAABQABAEkSBQA=\",\"AAAABNIBAADWAQAA1wEAANgBAAA=\"]Ao[\"AAAAAdIBAAAAAAAAAc0PAAA=\",\"\"]Ao[\"AAAAAdcBAAAAAAAAAc4PAAA=\",\"\"]Eo[\"AAAAASgRAAABBBMAAAM7EAAAvBAAABIRAAABXhMAAAEzEQAAASoQAAACOxEAABwSAAABLREAAAAAAAABkRMAAA==\",\"\"]Eo[\"AAAAASsRAAABBhMAAAM/EAAAvhAAABQRAAABYRMAAAE1EQAAASwQAAACPREAAB4SAAABLxEAAAAAAAABkxMAAA==\",\"\"]Bc[\"AAAAAAAAAnUEAADKBgAAAAHPDwAA\",\"\"]Bc[\"AAAAAAAAAngEAADNBgAAAAHQDwAA\",\"\"]Ec[\"AAAAAcwBAAAAAmoSAABsEgAAAlgTAABZEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAAEwAwAA\"]Gg[\"AAAAAcsEAAAAAhQAAAD9BgAAAtYAAADXAAAA\",\"AAADRQIAAEYCAABHAgAAAcsEAAAAAAAB2g8AAAACcwUAAH0MAAACaRAAAHcSAAAAAAABSQ8AAA==\"]Eg[\"AAAAAQYFAAAAAj4AAACgAAAAAzUBAAA2AQAAtQ8AAAFLAwAA\",\"AAAAAQYFAAAAAAAAAAF0BQAAAWoQAAA=\"]Ec[\"AAAAAAAAAWUBAAAAAAAAAAAAAAAAAAK7BAAAPgkAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAacFAAA=\"]Ec[\"AAAB8wsAAAG+BAAAAAELAAAAAbQAAAA=\",\"AAAAAb4EAAAAARAJAAAAAAAAAAAAAAAAAAABkQYAAA==\"]Dg[\"AAAAAAFYBQAAAAAAAAAAAAAAAAAAAAJkEAAACREAAA==\",\"AAF2BwAAAAAAAZMGAAA=\"]Ac[\"AAABZAIAAA==\",\"\"]Do[\"AAAAAd8EAAAAASEAAAAAAAL0AAAA9QAAAA==\",\"AAACcAIAAHECAAAB3wQAAAAAAAAAAUYTAAA=\"]Dk[\"AAAAARYFAAAAAUcAAAACTwEAAFABAAA=\",\"AAAC5AIAAOUCAAABFgUAAAAAAAAAAUcTAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAXCQAA\"]Dk[\"AAAAAAAAAAABEwEAAA==\",\"AAABjQIAAAAAAAAAAAABYgQAAAESBwAAAUIEAAABbwcAAA==\"]Dg[\"AAAAAAAAAYgBAAA=\",\"AAABEwMAAAAAAAAAAAABYwQAAAETBwAAAUQEAAABcgcAAA==\"]Dk[\"AAAAAe4EAAAAAbcBAAABrgQAAAEcEQAAAQ4BAAA=\",\"AAGJBwAAAAHuBAAAAAAAARwRAAA=\"]Dk[\"AAAAATgFAAAAAcoBAAACkQEAALIEAAABIxEAAA==\",\"AAGiBwAAAAE4BQAAAAAAASMRAAA=\"]Ck[\"AAAAAQcFAAAAAT8AAAACNwEAADgBAAA=\",\"AAAAAQcFAAAAAAHDBgAA\"]Eg[\"AAAAAdoEAAAAAiAAAACWAAAAAasPAAABQQMAAALvAAAAXRIAAA==\",\"AAGEBwAAAWkCAAAC2gQAABEKAAA=\"]Eg[\"AAAAAREFAAAAAkYAAAChAAAAAkoBAAC2DwAAAUwDAAABXhIAAA==\",\"AAGcBwAAAd4CAAABEQUAAAFyCgAA\"]Ao[\"AAAAAAAAAAACVBAAAAoRAAA=\",\"\"]Ao[\"AAAAAAAAAAACVRAAAAwRAAA=\",\"\"]Do[\"AAABbwAAAAG9BAAAAAABswAAAA==\",\"AAAAAb0EAAAAAQ8JAAAAAAAAAAAAAAAAAAABWBAAAA==\"]Bg[\"AAAAAAAABNQAAABiBQAAFQwAABoSAAA=\",\"\"]Ak[\"AAAAAAABQAAAAAE5AQAA\",\"\"]Do[\"AAAAAAAAAAAAAAAAAAAAAAAAAqMQAAAXEgAA\",\"AAF0BwAAAAAAAAAAAAAAAAAAAAAAAAFjEAAA\"]Cg[\"AAAAAAPEBgAANwkAAK0QAAA=\",\"AAAAAAAAAAJADwAATBAAAA==\"]Ag[\"AAACjQIAABMDAAA=\",\"\"]Cc[\"AAAAATQKAAACNQoAAKYKAAABpwoAAAJlEAAAZxAAAA==\",\"\"]Ac[\"\",\"AAAAAU8SAAA=\"]Gg[\"AAAAAd4EAAAB2BMAAAAAAcAIAAAE8wAAAM8PAABwEgAAvRMAAAEkEAAA\",\"AAAAA7IBAADeBAAA4xMAAAABnRMAAAABwAgAAAPPDwAAcBIAAL0TAAA=\"]Bc[\"AAAAAbIBAAAAAAAAAAAAAcoQAAA=\",\"\"]Gg[\"AAAAARUFAAAAAAFOAQAAAcEIAAAD0A8AAHISAAC+EwAAAAAAAAFtBwAA\",\"AAAAA8EBAAAVBQAA5BMAAAABnhMAAAABwQgAAAPQDwAAchIAAL4TAAA=\"]Bc[\"AAAAAcEBAAAAAAAAAAAAAc4QAAA=\",\"\"]Fg[\"AAABRgIAAAHVBAAAAAEeAAAAAAAC5wAAAOgAAAA=\",\"AAGABwAAAAHVBAAAAAE5CQAAAsIGAABfEAAAA3IEAABzBAAAWwUAAA==\"]Eo[\"AAAAAQkFAAAAAUIAAAACOwEAADwBAAA=\",\"AAGYBwAAAAEJBQAAAAE6CQAAAdAHAAAEdAQAAFwFAABgEAAARBEAAA==\"]Ao[\"\",\"AAAAAAAAAAAAAAAB0hAAAA==\"]Ek[\"AAAAAeMEAAAAASUAAAAAAAL8AAAA/QAAAA==\",\"AAABdwIAAAHjBAAAAAAAAAFsBwAAASQQAAAAAsoQAADMEAAA\"]Eg[\"AAAAAR8FAAAAAVAAAAACYwEAAGQBAAA=\",\"AAAB8QIAAAEfBQAAAAAAAAAAAALOEAAA0BAAAAABbQcAAA==\"]Ao[\"AAAAAAAAAAFBEAAAAAExDAAA\",\"\"]Jk[\"AAAAAeQEAAAABSYAAACXAAAASAUAADkQAAA7EAAAArULAACsDwAABEIDAAABDAAAOhAAADwQAAAE/gAAAP8AAAAKEQAACxEAAAItDAAALgwAAAIsEQAALREAAA==\",\"AAAAAuQEAABPEAAAArMBAAAyEAAAAAABCgkAAA==\"]Og[\"AAAAASQFAAAABVMAAACkAAAASQUAAD0QAAA/EAAABnABAABxAQAAtgsAALcLAAC4CwAAuQ8AAARPAwAAAgwAAD4QAABAEAAAAgwRAAANEQAAAi8MAAAwDAAAAi4RAAAvEQAA\",\"AAAABCQFAACpBwAAqgcAAFAQAAAEwwEAADMQAAA0EAAANRAAAAAAAQsJAAACUwUAAFQFAAAAAAAAAAAAAAA7MAAAAQAACgACAKsHBQDKBwQA\"]Cc[\"AAAAARoFAAAAAUwAAAACWQEAAFoBAAA=\",\"AAAAARoFAAA=\"]Ck[\"AAABTwUAAAHlBAAAAAEnAAAAAAABAAEAAA==\",\"AAAAAuUEAAADDAAA\"]Dg[\"AAABUAUAAAElBQAAAAFUAAAAAXIBAAAAAAAAAAAAAcUGAAA=\",\"AAAAAiUFAAAEDAAA\"]Cc[\"AAAAAT4FAAAAAWAAAAABmwEAAA==\",\"AAAAAj4FAAAFDAAA\"]Dg[\"AAAAAAAAAAAAAAABwRAAAA==\",\"AAAABjYQAABcEgAARBMAAEUTAAB1EwAAdhMAAA==\"]Ak[\"AAAAAAAAAAABSxIAAA==\",\"\"]Ak[\"AAAAAAAAAAABThIAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmoAAAAEAgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVUEAAA=\",\"AAAAAcQQAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmkAAAAFBwAA\",\"\"]Bk[\"AAAAAAAAAAAAAATTBgAA1AYAANUGAADWBgAA\",\"\"]Ec[\"AAAABJ0BAACoAQAA+QQAACUQAAAAAAEkAQAAAAAABNcGAADYBgAA2QYAANoGAAA=\",\"AAAAAfkEAAA=\"]Bg[\"AAAAAAAAAAAAAVYEAAA=\",\"AAAAAAHiEgAA\"]Cc[\"AAAAAToKAAACOQoAAKsKAAABqgoAAAJmEAAAaBAAAA==\",\"\"]Ag[\"AAAAAAAB9gYAAA==\",\"\"]No[\"AAAAAdwEAAAB9AYAAAGeEgAAAXoPAAAGEQwAAEYQAABBEwAAVRMAALUTAADdEwAAB/EAAACtAQAAdgwAAM0PAABvEgAATBMAAE4TAAABvxMAAAAAAAAAAAAAA6EGAAB6DAAAcxIAAA==\",\"AAAAAtwEAADWDwAAAAGxAQAAAXUSAAAGEQwAAEYQAABBEwAAVRMAALUTAADdEwAABXYMAADNDwAAbxIAAEwTAABOEwAA\"]Bo[\"AAAAAdYPAAAAAbEBAAAAAjoQAADLEAAAAAEtDAAA\",\"\"]Nc[\"AAAAARMFAAAAAAFMAQAAOjAAAAEAAAAAAAcAEAAAALsBEgxHEJ8SQhNWE7YT3hMFdwwAAM4PAABxEgAATRMAAE8TAAAAAAAAAAAAAAAEpwUAAKUGAAB7DAAAdBIAAA==\",\"AAAAAhMFAADXDwAAAAHAAQAAAXYSAAAGEgwAAEcQAABCEwAAVhMAALYTAADeEwAABXcMAADODwAAcRIAAE0TAABPEwAA\"]Bo[\"AAAAAdcPAAAAAcABAAAAAj4QAADPEAAAAAEvDAAA\",\"\"]Ao[\"AAAAAAAAAAACTBMAAE0TAAA=\",\"\"]Ao[\"AAAAAAAAAAACThMAAE8TAAA=\",\"\"]Dc[\"AAABRQIAAAHMBAAAAAIVAAAA/gYAAALYAAAA2QAAAA==\",\"AAABSQIAAAHMBAAA\"]Bk[\"AAAAAdUBAAAAAATTAAAAYQUAABQMAAAZEgAA\",\"\"]Ec[\"AAAAAv4SAAD/EgAAAvwSAAD9EgAABO8LAADwCwAA8QsAAPILAAAE6wsAAOwLAADtCwAA7gsAAA==\",\"\"]Cc[\"AAAAAAAAAAABShIAAA==\",\"AAF3BwAAAAKsAQAA3BIAAA==\"]Cc[\"AAAAAAAAAAABTRIAAA==\",\"AAGMBwAAAAK5AQAA3RIAAA==\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAABxQYAAA==\"]Cg[\"AAAAATsPAAAAAAFvAQAAATgQAAA=\",\"AAGoBwAAAAAAAUsTAAA=\"]Ek[\"AAAAAcMEAAAAAAG+AAAAAAAAAAAAAAAAAAAE2BIAAOASAAD7EgAAFhMAAA==\",\"AAF4BwAAAALDBAAAaQUAAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzsJAADLDwAADBQAAA==\",\"\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzwJAADMDwAADRQAAA==\",\"\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAYCQAA\"]Bc[\"AAAAAAABQQQAAA==\",\"AAAAAAGpBAAA\"]Ec[\"AAAAAfAEAAAAAbgBAAABrwQAAAIeEQAAcxMAAAEQAQAA\",\"AAGKBwAAAAHwBAAAAAAAAh4RAABzEwAA\"]Ec[\"AAAAAToFAAAAAcsBAAACkwEAALMEAAACJREAAHQTAAA=\",\"AAGjBwAAAAE6BQAAAAAAAiURAAB0EwAA\"]Ag[\"\",\"AAAAAAABDhIAAA==\"]Co[\"AAAAAqIBAACpBwAAAAABaAEAAA==\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Ac[\"\",\"AAAAAAGhEgAA\"]Cg[\"AAAAAAAAAnUSAAB2EgAAAAABERIAAA==\",\"AAAAAAAAAAFQEwAA\"]Do[\"AAAAAQQFAAAAAjwAAACfAAAAAzIBAAAzAQAAtA8AAAFKAwAA\",\"AAAAAQQFAAAAAAABXQQAAA==\"]Ak[\"AAAAAAACnRMAAJ4TAAA=\",\"\"]Ac[\"AAAAAdYBAAA=\",\"\"]Ac[\"AAAAAdgBAAA=\",\"\"]Eo[\"AAAC+QIAAA8DAAABLgUAAAABWwAAAAKCAQAAgwEAAA==\",\"AAAAAS4FAAAAAAAFpwYAAKgGAACpBgAAqgYAAKsGAAA=\"]Fk[\"AAAABEgQAABJEAAARBMAAEUTAAABPA8AAAGgEAAAAQ8SAAAAAAG/EwAAAAAAAAAAAAEmDAAA\",\"AAAAAAAAAxgSAAAZEgAAGhIAAA==\"]Fc[\"AAAAAAABkwYAAAJ1EgAAdhIAAAEHEQAAAAEREgAAAAACmxMAAJwTAAAAAAAB7BIAAA==\",\"AAAAAAAAAdQTAAABUBMAAA==\"]Ag[\"\",\"AAAAAAABRQUAAA==\"]Co[\"AAAAAQwFAAAAAUUAAAACQQEAAEIBAAA=\",\"AAAAAQwFAAAAAAAAAAExDgAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAeQGAAA=\",\"\"]Jc[\"AAAAAtsEAAC7EwAAAAAAAgUSAADaEgAABPAAAACtAQAAKwwAAOkSAAADPwkAAEYTAAC/EwAAAAAAAZ4QAAA=\",\"AAGFBwAAAAKwAQAA2wQAAAAAAAIFEgAA2hIAAAIrDAAA6RIAAAI/CQAARhMAAAAAAAGeEAAA\"]Jg[\"AAAAAhIFAAC8EwAAAAABSwEAAAO7AQAABhIAANsSAAACLAwAAOoSAAACQAkAAEcTAAAAAAABnxAAAA==\",\"AAGdBwAAAAK/AQAAEgUAAAGbBgAAAAACBhIAANsSAAACLAwAAOoSAAACQAkAAEcTAAAAAAABnxAAAA==\"]Ao[\"AAAAAAAAAcYAAAAAAAFYBAAA\",\"\"]Bc[\"AAAAAAABSQAAAAJTAQAAVAEAAA==\",\"\"]Ag[\"AAAClQIAACIDAAA=\",\"\"]Ak[\"AAAAAAAAAnYEAADLBgAA\",\"\"]Ak[\"AAAAAAAAAnkEAADOBgAA\",\"\"]Ag[\"AAAClgIAAB4DAAA=\",\"\"]Dk[\"AAAAAcoEAAAAAhMAAAD8BgAAAtEAAADSAAAA\",\"AAABQAIAAAHKBAAAAAAAAAAAAU8PAAA=\"]Dg[\"AAAAAccEAAAAAhAAAAD5BgAAAssAAADMAAAA\",\"AAABOgIAAAHHBAAAAAAAAAHADwAA\"]Co[\"AAABFRIAAAEIBQAAAAFBAAAAAToBAAA=\",\"AAGXBwAAAQEJAAABCAUAAA==\"]Ec[\"AAAAAAABFhIAAAG1AAAAAAAAAAAAAAAAAAADbQQAAP4IAABTDwAA\",\"AAAAAaoBAAAAAAAAAUATAAA=\"]Hk[\"AAAC0gIAAOsCAAABJgUAAAABVQAAAAJzAQAAdAEAAAAAAAAAAAAAAAAABAgCAABMBQAApgYAAOMGAAA=\",\"AAABAAMAAALEAQAAJgUAAAAAAmATAABhEwAAAAACPBEAAD0RAAA=\"]Fc[\"AAAAAzYQAABKEAAAXBIAAAACahIAAGwSAAADmAEAAFgTAABZEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAcwBAAA=\"]Dc[\"AAAAAmIAAADGBAAAAg8CAAC/CAAAAQ8AAAAByAAAAA==\",\"AAAAAsYEAADVDwAA\"]Eg[\"AAAAAeEEAAAAASMAAAAAAAL4AAAA+QAAAAAAAAAAAAAAAAPfBgAALw8AADYPAAA=\",\"AAABcwIAAAHhBAAA\"]Eg[\"AAAAARsFAAAAAU0AAAACWwEAAFwBAAAAAAAAAAAAAAAAAAPhBgAAMQ8AADcPAAA=\",\"AAAB6wIAAAEbBQAA\"]Hk[\"AAAFKgIAAD0CAAA/AgAARwIAAEkCAAAB1gQAAAACHwAAAP8GAAAAAALpAAAA6gAAAA==\",\"AAADYQIAAGICAABkAgAAAtYEAACXBgAAAqUFAAAjEAAAAQcTAAABeg8AAAEPEQAA\"]Ek[\"AAAAAQoFAAAAAkMAAAAABwAAAj0BAAA+AQAA\",\"AAAB0gIAAAEKBQAAAAAAAAAAAAAAAAAAAAACuwQAAOQGAAA=\"]Bk[\"AAAAAAABNxAAAAFuAQAA\",\"AAAAAAAAAAE4EAAA\"]Fc[\"AAABjwAAAAHTBAAAAAG9DAAAAAAB5QAAAAAAAAAAAAAAAAQKBwAADgcAAAMJAAAHCQAA\",\"AAF+BwAAAALTBAAAaAUAAA==\"]Fc[\"AAAAApIAAAACBQAAAAHADAAAAS8BAAAAAAAAAAAAAAAAAAQMBwAAEAcAAAUJAAAJCQAA\",\"AAGVBwAAAAECBQAAAWsFAAA=\"]Ag[\"AAAClAIAAB0DAAA=\",\"\"]Cg[\"AAAAAUAFAAAAAAADQA8AAKYPAABMEAAA\",\"AAGnBwAAAAFABQAA\"]Dc[\"AAAAAiAFAACqBwAAAAABaQEAAA==\",\"AAAAASAFAAAAAAAAAAAAAAAAAAGwBgAA\"]Dg[\"AAAAAe0SAAAB2A8AAAAAAALrAAAACxEAAA==\",\"AAEMCQAAAa8BAAAB7RIAAAHYDwAA\"]Dg[\"AAAAAe4SAAAB2Q8AAAABRgEAAAABDREAAA==\",\"AAENCQAAAb4BAAAB7hIAAAHZDwAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATQPAAA=\",\"\"]Ac[\"\",\"AAAAAAHDEwAA\"]Ag[\"AAAClwIAAB8DAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAADSRIAAEoSAABLEgAA\"]Bc[\"\",\"AAAAAAAAAAADTBIAAE0SAABOEgAA\"]Ak[\"\",\"AAAAAW4SAAAAAAGOEwAA\"]ADc[\"AAAAAdcEAAAAAAA6MAAAAQAAAAAAFAAQAAAAvwfBDEEPiQ+MD8gPxhA/EVMRZxLUEnsT0hPfE+sT7RMPFBMUFhQaFCEUOjAAAAEAAAAAAAwAEAAAAOwAVBDCEF0SbxJwEgoTNhNJE/cTCBQKFBgUAAABOBEAAA==\",\"AAGBBwAAAAHXBAAAAAAAOjAAAAEAAAAAABQAEAAAAL8HwQxBD4kPjA/ID8YQPxFTEWcS1BJ7E9IT3xPrE+0TDxQTFBYUGhQhFDowAAABAAAAAAAJABAAAABUEMIQXRIKEzYTSRP3EwgUChQYFAAAATgRAAA=\"]ADc[\"AAAAAQ4FAAAAAAFHAQAAOjAAAAEAAAAAABQAEAAAAMAHwgxCD4oPjQ/JD8cQQBFUEWgS1RJ8E9MT4BPsE+4TEBQUFBcUGxQiFDowAAABAAAAAAALABAAAABVEMMQXhJxEnISCxM3E0oT+BMJFAsUGRQAAAE5EQAA\",\"AAGZBwAAAAEOBQAAAAAAOjAAAAEAAAAAABQAEAAAAMAHwgxCD4oPjQ/JD8cQQBFUEWgS1RJ8E9MT4BPsE+4TEBQUFBcUGxQiFDowAAABAAAAAAAJABAAAABVEMMQXhILEzcTShP4EwkUCxQZFAAAATkRAAA=\"]Ag[\"AAACcQIAAOQCAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAU0EAAA=\",\"AAAAAAAAAQgMAAA=\"]Bk[\"AAAAAAAAAAAAAAEgDAAA\",\"AAAAAAABmBMAAA==\"]Do[\"AAAAAeIEAAAAASQAAAAAAAL6AAAA+wAAAAAAAAAAAAAAAALgBgAAMA8AAA==\",\"AAAAAeIEAAA=\"]Do[\"AAAAARwFAAAAAU4AAAACXQEAAF4BAAAAAAAAAAAAAAAAAALiBgAAMg8AAA==\",\"AAAAARwFAAA=\"]Ag[\"AAACmQIAACEDAAA=\",\"\"]Fc[\"AAAAAR4FAAAAAk8AAACiAAAAAmEBAAC3DwAAAk0DAAA4EAAA\",\"AAAAAR4FAAAAAAAAAAAAAAABbQcAAAAAAAABpwUAAA==\"]Ac[\"\",\"AAAAAAFuBwAA\"]Ao[\"AAAAAAGpBAAA\",\"AAAAAAFxBwAA\"]Ag[\"AAACkgIAABkDAAA=\",\"\"]Ag[\"AAACkwIAABsDAAA=\",\"\"]Dg[\"AAAAAfIEAAAAAAAB4xIAAAAAAAHMEAAA\",\"AAAAAvIEAAA0CgAAATUKAAAAAWUQAAA=\"]Do[\"AAABzQEAAAEyBQAAAAAAAeUSAAAAAAAB0BAAAA==\",\"AAAAATIFAAABpgoAAAGnCgAAAWcQAAA=\"]Do[\"AAAAAfQEAAAAAAADPBAAAM0QAADkEgAAAAEuDAAA\",\"AAAAAvQEAAA6CgAAATkKAAAAAWYQAAA=\"]Eg[\"AAABzgEAAAE0BQAAAAAAA0AQAADREAAA5hIAAAABMAwAAA==\",\"AAAAATQFAAABqwoAAAGqCgAAAWgQAAA=\"]Cc[\"AAAAAAAAAncEAADMBgAAAAEEAQAA\",\"AAGHBwAAAAG0AQAA\"]Cc[\"AAAAAAAAA3kBAAB6BAAAzwYAAA==\",\"AAGgBwAAAAHGAQAA\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA94GAACwBwAAzgcAAA==\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATMPAAA=\",\"\"]Ao[\"AAAAAAAAAawEAAAAAQgUAAA=\",\"\"]Bk[\"AAAAAAAAAbAEAAAAAQkUAAA=\",\"AAAAAbQEAAA=\"]Eg[\"AAAAAAAAAAABEQEAAAAAAAAAAAAAAANBCQAApw8AAJYSAAA=\",\"AAGLBwAAAAS3BwAAuAcAALkHAAC6BwAA\"]Eg[\"AAAAAAAAAZQBAAAAAAAAAAAAAAAAAANCCQAAqA8AAJcSAAA=\",\"AAGkBwAAAAS7BwAAvAcAAL0HAAC+BwAA\"]Bo[\"AAAAAAABsQEAAAAAAXYMAAAAAWIEAAAAAUIEAAA=\",\"\"]Bo[\"AAAAAAABwAEAAAAAAXcMAAAAAWMEAAAAAUQEAAA=\",\"\"]Ak[\"AAAAAAABCBMAAAFvEwAA\",\"\"]Ao[\"AAAAAAABCRMAAAAAAXATAAA=\",\"\"]Fo[\"AAAAASMFAAAAAlIAAACjAAAAA2wBAABtAQAAuA8AAAFOAwAA\",\"AAAB+QIAAAEjBQAAAAAAAAJTBQAAVAUAAAAAAAAAAALCAQAAsAYAAA==\"]Dg[\"AAAAAfwEAAAAATUAAAABJwEAAA==\",\"AAAAAfwEAAAAAAAAAAAAAAAAAAAAAAHlBgAA\"]Dg[\"AAAAAcEEAAAAAgwAAAD4BgAAArsAAAC8AAAA\",\"AAABKgIAAAHBBAAAAAABxRAAAA==\"]Do[\"AAAAAfcEAAAAAjEAAACcAAAAAyABAAAhAQAAsQ8AAAFHAwAA\",\"AAAAAfcEAAAAAAAAAWUEAAA=\"]Ek[\"AAAAAdgEAAAAAAACURMAAKUTAAAD7QAAAKgQAAA2EwAA\",\"AAGCBwAAAAHYBAAAAAAAAlETAAClEwAAAagQAAA=\"]Ek[\"AAAAAQ8FAAAAAAFIAQAAAlITAACmEwAAAqkQAAA3EwAA\",\"AAGaBwAAAAEPBQAAAAAAAlITAACmEwAAAakQAAA=\"]Bo[\"AAAAAAAAAAABUwUAAAAAAAAAAALCAQAAsAYAAA==\",\"\"]Fg[\"AAAAAdkEAAAAAAAEIAkAANIPAAAwEQAAARMAAALuAAAASRMAAA==\",\"AAGDBwAAAAHZBAAAAAAABCAJAADSDwAAMBEAAAETAAA=\"]Fg[\"AAAAARAFAAAAAAFJAQAABCEJAADTDwAAMREAAAITAAABShMAAA==\",\"AAGbBwAAAAEQBQAAAAAABCEJAADTDwAAMREAAAITAAA=\"]Ag[\"\",\"AAAAAAAAAdQTAAA=\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\"]Ag[\"\",\"AAAAAAAAAVAPAAA=\"]Co[\"AAAAAf0EAAAAATYAAAACKAEAACkBAAA=\",\"AAAAAf0EAAAAAAAAARISAAA=\"]Fg[\"AAABUQIAAAHmBAAAAAEoAAAAAAG4BgAAAgEBAAACAQAA\",\"AAACegIAAJ8GAAAB5gQAAAAAAAGqBgAAAAAAAAAAAAAAAAEvDwAA\"]Gc[\"AAABugIAAALEAQAAJwUAAAABVgAAAAJ1AQAAdgEAAAG/BgAA\",\"AAACAQMAAKMGAAABJwUAAAAAAbEGAAAAAAAAAAAAAAAAAAIIAgAAMQ8AAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA6wHAADLBwAAwwgAAA==\",\"\"]Cg[\"AAABdwIAAAAAAAAAARQBAAA=\",\"AAAAAAAAAAI6EAAAPBAAAA==\"]Cg[\"AAAB8QIAAAAAAAGJAQAA\",\"AAAAAAAAAAM+EAAAQBAAAEEQAAA=\"]Bo[\"AAAAArQEAAA/BQAAAaESAAA=\",\"AAAAAj8FAABWEQAA\"]Bo[\"AAAAAAAAAcIAAAAAAAABIgwAAA==\",\"AAAAAXcTAAA=\"]Io[\"AAAAAS8FAAAAAVwAAAABhAEAAAZ1BQAAyxAAAM0QAADPEAAA0RAAANMQAAAAAAAFyhAAAMwQAADOEAAA0BAAANIQAAAAAAAAAAABIBQAAA==\",\"AAAAAS8FAAAAAARdEwAAXhMAAGATAABhEwAAAAFeBAAA\"]Co[\"AAAAAmQAAAC2BwAAAAABygAAAAJzBAAAQxEAAAFODwAA\",\"AAABJhEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAuEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhcJAAAwEAAA\",\"\"]Co[\"AAAAAfMEAAAAAAAAAhcBAAAYAQAA\",\"AAAAAfMEAAAAAAJlEAAAZhAAAA==\"]Dc[\"AAAAATMFAAAAAAKMAQAAjQEAAA==\",\"AAAAAjMFAABPEgAAAAACZxAAAGgQAAA=\"]Cc[\"AAAAAAGcAQAAAAG3AAAAAAAAAR8MAAA=\",\"AAAAAZcTAAA=\"]Ac[\"\",\"AAAB8wsAAA==\"]Ec[\"AAABcAIAAAHOBAAAAAEXAAAAAAAC3QAAAN4AAAA=\",\"AAAAAc4EAAAEEwkAAP4JAAD/CQAAAQoAAA==\"]Do[\"AAAB5QIAAAH2BAAAAAEvAAAAAh0BAAAeAQAA\",\"AAAAAfYEAAAEFAkAAFAKAABRCgAAUgoAAA==\"]Ak[\"\",\"AAAAAAACnRMAAJ4TAAA=\"]Ck[\"AAAAAsAEAAAqCQAAAb4IAAAB2RIAAAG6AAAA\",\"AAAAAsAEAADUDwAA\"]Cg[\"AAAAAU0HAAACHxAAADIQAAAAAbULAAAAAAAAAAABnhAAAA==\",\"\"]Ck[\"AAAAAU4HAAACIBAAADMQAAAAArYLAAC3CwAAAAAAAAAAAZ8QAAA=\",\"\"]Bc[\"AAAAAAAAAAAAAAAAApsTAACcEwAA\",\"\"]Fo[\"AAAAAd0EAAAAAAADZwQAACsJAAC1EwAAAvIAAACmAQAA\",\"AAGGBwAAAAHdBAAAAAAAAmcEAAArCQAAAaYBAAAAAAAAAAAAAAABcxIAAA==\"]Fo[\"AAAAARQFAAAAAAFNAQAAA2gEAAAsCQAAthMAAAGnAQAA\",\"AAGeBwAAAAEUBQAAAAAAAmgEAAAsCQAAAacBAAAAAAAAAAAAAAABdBIAAA==\"]Ck[\"AAAAAQ0FAAAAAAJDAQAARAEAAA==\",\"AAAAAQ0FAAAAAAAAAcITAAA=\"]Ec[\"AAAAASEFAAAAAAFqAQAAAAAAAAAAAAAAAAAFowEAAKsHAADKBwAAwggAAHgMAAA=\",\"AAAAASEFAAA=\"]Dg[\"AAAAAAHDEwAAAAG2AAAAAAAAAAACmxMAAJwTAAAAAAAB7BIAAA==\",\"AAABqwEAAA==\"]Ag[\"AAACmAIAACMDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAAAAAAAApsTAACcEwAA\"]Cc[\"AAAAAUEFAAAAAAAAAAAAAdIQAAA=\",\"AAABzQEAAAFBBQAA\"]Ck[\"AAAAAUIFAAAAAAACQRAAANMQAAAAATEMAAA=\",\"AAABzgEAAAFCBQAA\"]Ag[\"AAACnAIAACADAAA=\",\"\"]Dg[\"AAAAAAABLAAAAAAAARIBAAA=\",\"AAAAAAAAAAAAAAAAAAAAA48TAACQEwAAkRMAAA==\"]Ck[\"AAAAAAABXgAAAAGHAQAA\",\"AAAAAAAAAAAAAAAAAAAAApITAACTEwAA\"]Ag[\"AAACmwIAABgDAAA=\",\"\"]Do[\"AAAAAU8HAAACIRAAADQQAAAAAbgLAAABXRAAAA==\",\"AAK9AQAAjQcAAAEOCQAAAAAAAAFdEAAA\"]Ec[\"AAAAAikFAABQBwAAAiIQAAA1EAAAAAF4AQAAAV4QAAA=\",\"AAGfBwAAAcUBAAABKQUAAAAAAAFeEAAA\"]Bg[\"AAAAAAAAAAABVAUAAA==\",\"AAABvAEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAvEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhgJAAAxEAAA\",\"\"]") \ No newline at end of file +rd_("CBk[\"\",\"ADswAAABAAAFAAIAOwQEAPYTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwQElQSaRLVE+ET/xMOFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJrRATElUS5xKUE5UT2BP7E/wT/RP+ExEUFRQ7MAAAAQAALAESAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAADIMAwC7DAUAqg2GADcQAACuEAcADhEAAH0RhgAUEgAAFhIAAJ4SAADoEgAABxMAADowAAABAAAAAAAdABAAAABaBWAFYQViBcIGwwbKBssGzAbNBs4Gzwa1C7YLtwu4CwgMTA9QD18QxRAPEhsTWBNZE28T0BPUE+ITABQ7MAAAAQAAPQAUAD8DFABmBAAAcgQCAEMFAQBGBQAAWwUBAHUFAAC1BgwAwgcDALQLAAAeDAAApg8AANoPAABgEAAABxEAAJ8SAADjEgMAUBMAANETAAABFAAAOzAAAAEAAFcADQDbAD0AigEBAGUEAABwBwAAcwcAALIHAAC0BwAAKRADAEkSBQBAEwAAcBMAAK8TBQDCEwAAOzAAAAEAABUABwBMBAAAfQwAADEOAACiDwMAERIAAA4TBwDvEwUAOzAAAAEAABMACQBiBAEAawQBANMGBwCxBwAAswcAAEYPAgBPDwAAwBAAAHcSAAADEgcAABMHAABmEgAAAScMAAAFbQcAAG8HAAByBwAAJAwAAL8QAAAAOzAAAAEAAAUAAgDCAQAAjxMEAAAAAacFAAA=\"]Bo[\"AAAAAAAAAAACvRMAAL4TAAAAAAAAAp4QAACfEAAA\",\"\"]0Bg[\"\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAA=\"]AGg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAADQAFAHMFAQA/CQEALQwEAH0MAAA6EQMAOjAAAAEAAAAAAAsAEAAAAGsEbASxB7MHTw9pEGoQLBEtES4RLxF3EgRcBAAAEgcAABMHAAC/DwAABEIEAABEBAAAmxMAAJwTAAAFYQQAAG8HAAByBwAASg8AAEsPAAADIwwAACUMAABJDwAAOzAAAAEAAAYAAwDCAQAAsAYAAI8TBAAB7BIAAAEmDAAA\",\"AAAAAVYRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAA==\"]ANg[\"AAAEUgIAALgCAACfBgAAowYAAAMDDAAABAwAAAUMAAACswEAAMMBAAA7MAAAAQAAhgABAH0RhgAAOzAAAAEAAAcAAwBDBQEA4xIDACEUAQAEcAcAAHMHAACyBwAAtAcAADswAAABAAASAAcAcwUBAOgGAAA/CQEALQwEAH0MAAA6EQMAGxIDADowAAABAAAAAAAKABAAAABiBGMEawRsBLEHswdPDywRLREuES8RBVwEAABeBQAAEgcAABMHAADBEAAABEIEAABEBAAAmxMAAJwTAAAEbwcAAHIHAABKDwAASw8AAATFBgAAIwwAACUMAABJDwAABY8TAACQEwAAkRMAAJITAACTEwAAAewSAAAAAacFAAA=\",\"AAAAAAACSAUAAEkFAAAAAgEMAAACDAAAAcAPAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAAAAAAAAA94GAAAVEQAAFhEAAA==\"]Dc[\"\",\"AAAAADswAAABAAAHAAEAIgkHADswAAABAAAJAAIAuhAEABARBAAAAQ8RAAA=\"]ADm[\"AAAABrABAACyAQAAvwEAAMEBAADWDwAA1w8AAAS2AQAAyQEAADUKAAA5CgAAOjAAAAEAAAAAAAkAEAAAALEBtwG4AcABygHLAacKqgqdE54TOzAAAAEAAA0ABACsBAcAeg8AAGUQAwBvEwAAArsBAACfEgAAOzAAAAEAABUACgCmAQEArQEAACsMAQB2DAEAzQ8DAFQQAQBvEgMAQBMAAL0TAQAIFAEAAb8TAAAAAAAAAAAAAAGnBQAA\",\"AAABqwEAAAK0BAAABBIAAAAAAAJADwAATBAAAAAAAAAAAAAAAAAEoQYAAKUGAAB6DAAAewwAAA==\",1]Fk[\"AAAABOsEAAAVBwAAuAcAABkRAAACIwkAAPYLAAABrxAAAAABwwcAAAELAQAAAqMPAAAPEwAAAdQGAAA=\",\"AAAAAesEAAABtgEAAA==\"]Fk[\"AAAABDUFAAAZBwAAvAcAACARAAACJwkAAPoLAAABsxAAAAGOAQAAAcUHAAAAAqUPAAATEwAAAdgGAAA=\",\"AAAAATUFAAAByQEAAA==\"]AEa[\"AAAAAq4BAAC6AQAAOzAAAAEAAAcAAQAiCQcAAARgBQAAYQUAAGIFAAAPEgAAAAABvxMAAAAAAAKeEAAAnxAAAA==\",\"AAAAADswAAABAAAQAAMAlgYAACIJBwD1CwcAOzAAAAEAAAsABAD2BgAAoBAAALoQBAAQEQQAOzAAAAEAAA8ABQCsBAcAEwwCABgSAgBQEgAA1BMAADowAAABAAAAAAAKABAAAADLEM0QzxDRENMQDxEyETMRNBE1EVATBCkQAAAqEAAAKxAAACwQAAAAAAXKEAAAzBAAAM4QAADQEAAA0hAAAAAAAAAAAAKnBQAARQ8AAA==\",1]Ec[\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCADswAAABAAAGAAIApwYEAAoJAQADXgQAAFMFAABUBQAA\",\"\"]Dg[\"AAAAAAAAAAABsBMAAAHwEwAAAAAAAAAAAAABVAcAAA==\",\"AAAAAAABVxIAAAE7EwAA\"]Eo[\"AAAAAekEAAABtQEAAAIqAAAAmQAAAAGuDwAAAUQDAAACBgEAAAcBAAA=\",\"AAABqAAAAAHpBAAAAf0SAAAAAe0LAAA=\"]Ic[\"AAAAASsFAAADxwEAABcTAACWEwAAAlgAAACmAAAABnsBAAB8AQAAQwQAAKYFAAC7DwAA4hMAAAFRAwAA\",\"AAABqQAAAAIrBQAA/xIAAAAB8QsAAAAAAAAAAAAAAAAAAAKqAAAAqwAAAA==\"]Ik[\"AAAAArwEAABuEgAAAfMGAAABkwYAAAGyAAAAAQcRAAABrxMAAAIREgAA7xMAAAAAAAAAAAAAOjAAAAEAAAAAAAkAEAAAAGcFkQZRB9IHiA+fD9EPWBCiED4R\",\"AAAAAbwEAAAAAVYSAAABOhMAAA==\"]Ck[\"AAAAAd0BAAAAAAAAAbMTAAAB8xMAAA==\",\"AAAAAAABWhIAAAE+EwAA\"]Ck[\"AAAAAd4BAAAAAAAAAbQTAAAB9BMAAA==\",\"AAAAAAABWxIAAAE/EwAA\"]Kk[\"AAAAAAAABFoFAABgBQAAYQUAAGIFAAAAOzAAAAEAAAkAAQCqCwkAOzAAAAEAAA0AAQBMBA0AOzAAAAEAAAkABAAfDAMARg8CAMAQAADUEAEAAAEnDAAAAyQMAABKDwAASw8AAAIlDAAASQ8AAA==\",\"AAAAAAABoBAAAAMTDAAAFAwAABUMAAA=\"]Nk[\"AAAAAAAAAnUSAAB2EgAABOMSAADkEgAA5RIAAOYSAAAC6RIAAOoSAAAF6AYAABsSAAAcEgAAHRIAAB4SAAACYgQAAGMEAAACXgUAAMEQAAAAAAHFBgAAAAAAAacFAAA=\",\"AAAAAAJWBQAAwxMAAAAF+RMAABwUAAAdFAAAHhQAAB8UAAABUBMAAALADwAA+hMAAAAAAAAAAAAAAAQuEAAALxAAADAQAAAxEAAA\"]Bg[\"AAAAAAAAAARTEQAAVBEAAHMTAAB0EwAA\",\"\"]Bk[\"\",\"AAAAAVIRAAAAAAAAAAAAAAAAAAAAAAFTDwAA\"]Cc[\"AAAAAAAAAV8QAAABYBAAAA==\",\"AAAAAAACOQkAADoJAAA=\"]FGo[\"AAAAADswAAABAAAVAAkADAIGAEoEAABrBQAA1AcAAP8LAAAyEAMAVRIAAJQTAQD7EwMAOzAAAAEAABMCEgBBBAAAWgQAAGAEAADJBgAA7wsDALsMBQDDDG0Bwg8AAMcPAAA3EAAAUxAAAK4QBwAOEQAAfRGGABQSAAAWEgAA6BIAAEsTAAA7MAAAAQAAwwAPALIAKAAZAXAAjAEPAEMEAABaBQAApgUAAKwGAwCxBgIAwgYBAOsLAwBEDwAAGxMAADoTBQDiEwAA9RMAADswAAABAACiAEIAPwMUAF0EAABnBAEAcgQCAEYFAABbBQEAdQUAAKcGBAC1BgwAvwcBAMIHAwDACAEACgkBACAJAQArCQEAAQwBABEMAQAeDAAAwQwBAEEPAQBRDwEAiQ8BAIwPAQCmDwAAyA8BANIPAQDaDwAAOBAAAEYQAQBdEAEAYBAAAMYQAQAPEQAAGhEAABwRAAAeEQAAIREAACMRAAAlEQAAMBEFAD8RAQBCEQIAUxEBAAUSAQBnEgEAnxIAANQSAQDaEgEA4xIDAAETAQBBEwEAURMBAFUTAQBzEwEAexMBAKUTAQC1EwEA0RMCAN0TAwDrEwMAARQAAA8UAQATFAEAFhQBABoUAQAhFAEAOzAAAAEAAI8AJgDbAD0AigEBAKYBAQBABAAAXgQAAGUEAABTBQEAbQUBAHAHAABzBwAAsgcAALQHAACqCwkAKwwBAHYMAQBNDwEAgg8BAMAPAADNDwMAVBABAKgQAQDCEAEAEhIAAF0SAQBvEgMA6RIBAAoTAQA2EwEASRMBAEwTAwBwEwAArxMFAL0TAQDCEwAA9xMBAPoTAAAIFAMAGBQBADswAAABAAAxAA0ATAQNAHMFAQDoBgAAPwkBABsMAAB9DAAAMQ4AAKIPAwA6EQMAGxIDAA4TBwBGEwEA7xMFADswAAABAAAcAA0AYgQBAGsEAQDTBgcAsQcAALMHAAAfDAMARg8CAE8PAABpEAEAwBAAANQQAQB3EgAAAhQAADowAAABAAAAAAAHABAAAABcBF4Fvw/BEDgRORFmEtkTA0IEAABEBAAAJwwAADowAAABAAAAAAAJABAAAABhBG0HbwdyByQMSg9LD54QnxC/EATFBgAAIwwAACUMAABJDwAAOzAAAAEAAAUAAgCwBgAAjxMEAAABJgwAAAGnBQAA\",\"AAAAAAA7MAAAAQAA5gABAMMM5gAAOjAAAAEAAAAAAFkAEAAAAGcEaAS/B8AHwAjBCCAJIQkrCSwJAQwCDBEMEgzBDMIMQQ9CD1EPUg+JD4oPjA+ND8gPyQ/SD9MPRhBHEF0QXhDGEMcQGhEcER4RIREjESURMBExET8RQBFTEVQRBRIGEmcSaBLUEtUS2hLbEgETAhNBE0ITURNSE1UTVhNzE3QTexN8E6UTphO1E7YT0hPTE90T3hPfE+AT6xPsE+0T7hMPFBAUExQUFBYUFxQaFBsUIRQiFDswAAABAAAvABQApgEBAG0FAQArDAEAdgwBAIIPAQDNDwMAVBABAKgQAQDCEAEAXRIBAG8SAwDpEgEAChMBADYTAQBJEwEATBMDAL0TAQD3EwEACBQDABgUAQAEPwkAAEAJAABGEwAARxMAAAACOBEAADkRAAAAAp4QAACfEAAA\"]Ic[\"AAAAARcRAAAABFcFAAAPCQAAEAkAAA4SAAA7MAAAAQAADAADAHUEBQDKBgUAjhMAAAADbAcAAMIQAADDEAAAASQQAAAAB8oQAADMEAAAzhAAANAQAADSEAAAOBEAADkRAAAAAW0HAAA=\",\"\"]Lk[\"AAACUwIAALcCAAAAArYBAADJAQAAOzAAAAEAAAsAAwC3AQEAygEBAK4QBwA7MAAAAQAABwABAKwEBwA6MAAAAQAAAAAABwAQAAAAvwfAB4kPig/SD9MPMBExEQACRhMAAEcTAAA=\",\"AAAAAYAPAAAAAAAAAAAAAAAAAAAAAAV/DwAAgQ8AAIgPAACLDwAASBMAAA==\"]AAg[\"AAAEVQIAALUCAAARCQAAEgkAAASsAQAAtAEAALkBAADGAQAAAloCAAC/AgAAAAA6MAAAAQAAAAAAEwAQAAAAZwRoBMAIwQg6EDwQPhBAEEEQyxDNEM8Q0RDTEGcSaBITFBQUFhQXFALpEgAA6hIAAAUtDAAALgwAAC8MAAAwDAAAMQwAAAAFyhAAAMwQAADOEAAA0BAAANIQAAAAAAACwgEAALAGAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAABMIIAADDCAAAxAgAAMUIAAA=\"]BKo[\"AAADDgkAANYSAADXEgAABaoBAAAXCgAAUhEAANwSAADdEgAAOjAAAAEAAAAAAAcAEAAAALUBxwETCRQJAQpSCnoKExIBFBIAAAEbEwAAOjAAAAEAAAAAABEAEAAAAMIHwwfEB8UHQA/ID8kPTBAaERwRHhEhESMRJRFBE0IT3RPeEwFAEwAAOzAAAAEAAAsAAgCiDwMADhMHADswAAABAAAJAAMA0wYHALEHAACzBwAAAAACbwcAAHIHAAA=\",\"AAAETQUAAE4FAAA4DwAAOQ8AADswAAABAAAWAAsAFAcHABgRAQAbEQAAHREAAB8RAQAiEQAAJBEAAAcSAQBtEwEAcRMAALsTAQACFxMAAJYTAAABDhIAAAAAAAAAAAAAAAAAADowAAABAAAAAABrABAAAACgAaEBowGkAQICAwIJAgoCSQRLBG0EtgS5BKAGpAbRBtIGBgcHB/wI/QgyCTMJ/gsADBYMFwwcDB0MKAwpDD4PPw9UD3sPfA+dD54P0Q8mECcQRBBFEFEQUhBWEFcQYRBiEJgQmRCiEKQQpRCrEKwQthC3ELgQuRA2ETcRShFLEQoSCxIMEg0SUhJTEl8SYBJrEm0SlBKVEpYSlxKZEpoSmxKcEtgS3hLfEuAS+xIMEw0TFhMcEx0THhMfEyATIRM4EzkTUxNUE1oTWxN5E3oTmROaE9YT1xM=\"]Ac[\"AAAAAAEwAwAA\",\"\"]Ca[\"AAAAAAJaAgAAvwIAADswAAABAAAFAAEATBEFAA==\",\"\",1]Ek[\"AAAAAAAAAAAAAAAAAAAAAAAAAsYGAADcBgAA\",\"AAAAAAACORAAADsQAAAAAjoQAAA8EAAAAAIbEgAAHBIAAA==\"]Eo[\"AAAAAAAAAAAAAAAAAAAAAAAAAscGAADdBgAA\",\"AAAAAAACPRAAAD8QAAAAAz4QAABAEAAAQRAAAAACHRIAAB4SAAA=\"]Ck[\"AAAAAAAAAAAAAAAAAAAAAAAABXAAAACkAQAArQcAAMwHAADECAAA\",\"\"]Bg[\"AAAAAAAAAUwPAAAAAAAAAjgRAAA5EQAA\",\"\"]Gk[\"AAAABGEAAADFBAAAagUAANUPAAABDgIAAAYOAAAASAQAAEUFAAAEBwAASBEAAJgTAAACxwAAAFAPAAAAAlcTAACuEwAA\",\"AAAAAcUEAAABvwgAAAFGBAAA\"]Ig[\"\",\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBGDwIAwBAAANQQAQAAAScMAAAEJAwAAEoPAABLDwAAvxAAAAMjDAAAJQwAAEkPAAAAAAEmDAAA\"]Bg[\"AAAAAAAAAAAAAAAAAAKeEAAAnxAAAA==\",\"\"]Hk[\"AAAD0AEAAAoMAAANDAAAAegEAAABtQEAAAQpAAAAmAAAADkQAAA7EAAAAa0PAAABQwMAAAMFAQAAChEAAAsRAAA=\",\"AAAC0AEAAAYMAAACaQQAAOgEAAAB/BIAAAAB7AsAAA==\"]Hk[\"AAAD0QEAAAsMAAAODAAAASoFAAABxwEAAARXAAAApQAAAD0QAAA/EAAAAnoBAAC6DwAAAVADAAADXgQAAAwRAAANEQAA\",\"AAAC0QEAAAcMAAADagQAACoFAAD+EgAAAAHwCwAA\"]2ALo[\"AAAAAAEoEAAAAAA6MAAAAQAAAAAAEQAQAAAAuwFdBBEMEgzBDMIMQQ9CD8YQxxAFEgYS6xPsEw8UEBQaFBsUAmUEAABAEwAAOzAAAAEAAAsAAgCiDwMADhMHADswAAABAAAHAAEA0wYHAAAAAAACwgEAALAGAAA=\",\"AAAHTwUAAFAFAAAKDAAACwwAAA0MAAAODAAAFRIAADowAAABAAAAAAAXABAAAAC1B7YHHgkqCQwMDwwQDDoPOw9IEEkQShCXEBcRJxEoESkRKhErEUMTrBOtE8ATwRM7MAAAAQAA+QACADkO9QADEwMAOzAAAAEAAFkABAALAFUA2RIAAAgTAQByEwAAAfUTAAAAAAQ6EQAAOxEAADwRAAA9EQAABCwRAAAtEQAALhEAAC8RAAABZhIAAAAAAAAAAAdxBAAAZwUAANAGAAA2DgAAmhAAAKoQAAA+EQAA\"]Dk[\"AAAAAAL+CQAAUQoAAAAAADswAAABAAAFAAEASRIFAAACYgQAAGMEAAAAAkIEAABEBAAA\",\"\"]BOc[\"\",\"ADswAAABAAAFAAIAOwQEAPYTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwQElQSaRLVE+ET/xMOFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJrRATElUS5xKUE5UT2BP7E/wT/RP+ExEUFRQ7MAAAAQAAKAERAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAALsMBQCqDYYANxAAAK4QBwAOEQAAfRGGABQSAAAWEgAAnhIAAOgSAAAHEwAAOjAAAAEAAAAAABsAEAAAAFoFYAVhBWIFwgbDBsoGywbMBs0GzgbPBrULtgu3C7gLTA9QD18QxRAPEhsTWBNZE28T0BPiEwAUOzAAAAEAADsAEgA/AxQAZgQAAHIEAgBDBQEARgUAAFsFAQB1BQAAtQYMAMIHAwC0CwAAHgwAAKYPAADaDwAAYBAAAJ8SAADjEgMA0RMAAAEUAAA7MAAAAQAAUgALANsAPQCKAQEAZQQAAHAHAABzBwAAsgcAALQHAABJEgUAcBMAAK8TBQDCEwAAOzAAAAEAABQABgBMBAAAfQwAADEOAACiDwMADhMHAO8TBQA7MAAAAQAAEwAJAGIEAQBrBAEA0wYHALEHAACzBwAARg8CAE8PAADAEAAAdxIAAAISBwAAEwcAAAEnDAAABG8HAAByBwAAJAwAAL8QAAAABY8TAACQEwAAkRMAAJITAACTEwAA\"]Bc[\"AAAAAAAAAAAAAAACOBEAADkRAAA=\",\"\"]Kc[\"AAAAAAHiEgAAADswAAABAAAGAAIAygYFAMUQAAACRgUAANoPAAABZQQAAAADaRAAAGoQAAB3EgAAAb8PAAA=\",\"AAAAAAABYAQAADswAAABAAAFAAEAdQQFAAAAAAAAAAAAAAAABwsCAAC1BAAAuAQAAN8GAADgBgAA4QYAAOIGAAA=\"]Do[\"AAAAAAABGAAAAAAAAd8AAAAAAAAAAAAAAAACtQQAANEGAAA=\",\"AAAAAAAAAAACTQ8AAE4PAAA=\"]Dk[\"AAAAAAABMAAAAAEfAQAAAAAAAAAAAAAAAAACuAQAANIGAAA=\",\"AAAAAAAAAAABQAQAAA==\"]Ac[\"AAABYgIAAA==\",\"\"]Fg[\"AAAABO0EAAAWBwAAuQcAABsRAAADJAkAAPcLAAD8EwAAAbAQAAAAAAENAQAAARATAAAB1QYAAA==\",\"AAAAAe0EAAAAAbcBAAA=\"]Fg[\"AAAABDcFAAAaBwAAvQcAACIRAAADKAkAAPsLAAD+EwAAAbQQAAABkAEAAAAAARQTAAAB2QYAAA==\",\"AAAAATcFAAAAAcoBAAA=\"]Bk[\"\",\"AAAAAAAAAAA7MAAAAQAAPwACANsAPQCKAQEA\"]Ck[\"\",\"AAAAAAGWBgAAOzAAAAEAAAkAAgD2BgAA+AYIAAHUEwAAAVATAAA=\"]Ck[\"AAACYQIAAHMCAAA=\",\"AAAAAAAAAl0TAABeEwAAAAACOhEAADsRAAA=\"]Bo[\"\",\"AAAAAAAAAAAAAAAAApsTAACcEwAAAAAAAewSAAA=\"]Eo[\"\",\"AAAAAAA7MAAAAQAABQABAFYSBQA7MAAAAQAABQABADoTBQAAOzAAAAEAAAUAAQCvEwUAOzAAAAEAAAUAAQDvEwUA\"]Cc[\"\",\"AAAAAAL8EgAA/RIAAAAE6wsAAOwLAADtCwAA7gsAAA==\"]Eg[\"AAAAAfEEAAAAAS0AAAAAAAIVAQAAFgEAAA==\",\"AAA7MAAAAQAACgABAJICCgAC8QQAAOMTAAAAAAF1EgAA\"]Eo[\"AAAAATEFAAAAAV8AAAAAAAKKAQAAiwEAAA==\",\"AAA7MAAAAQAACgACABgDAwAdAwYAAjEFAADkEwAAAAABdhIAAA==\"]Dg[\"AAABAAMAAAEwBQAAAAFdAAAAAoUBAACGAQAA\",\"AAABDwMAAAEwBQAAAAAAAAFeBAAA\"]Eo[\"AAAAAAAAApUBAACWAQAA\",\"AAAAAAAAB9ATAAD5EwAAABQAABwUAAAdFAAAHhQAAB8UAAAC0RMAAAEUAAAB+hMAAA==\"]Bk[\"AAAAAAAAAUUBAAA=\",\"AAAB2AIAAAAAAVoEAAA=\"]Bg[\"AAAAATsFAAAAAAGXAQAA\",\"AAAAATsFAAA=\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAXgMAAA=\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA64HAADNBwAAxQgAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAnEEAACvBwAA\",\"\"]Cc[\"AAAAAAAAAAIKCQAACwkAAAAAAAAAAAACwgEAALAGAAA=\",\"\"]Fo[\"AAAAAAACVwUAABYSAAAAAAAAAAAAAAAAAAAE0wcAAFQPAABjEAAAVREAAA==\",\"AAF1BwAAAAAAAAAAAAAAAAAAAAAAAAJkEAAACREAAA==\"]Bk[\"AAAAAVkFAAAAAAFMDwAAAaYPAAA=\",\"AAGmBwAA\"]Bg[\"AAAAAAAABGUQAABmEAAAZxAAAGgQAAA=\",\"\"]Ag[\"AAAAAq4BAAC6AQAA\",\"\"]Dg[\"AAAAAAAAAAAAAj8JAABACQAA\",\"AAAAAAAAAAAABS0MAAAuDAAALwwAADAMAAAxDAAA\"]AEg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAACwAEAHMFAQAtDAQAfQwAADoRAwA6MAAAAQAAAAAACwAQAAAAawRsBLEHswdPD2kQahAsES0RLhEvEXcSBFwEAAASBwAAEwcAAL8PAAAEQgQAAEQEAACbEwAAnBMAAAVhBAAAbwcAAHIHAABKDwAASw8AAAMjDAAAJQwAAEkPAAA7MAAAAQAABgADAMIBAACwBgAAjxMEAAHsEgAAASYMAAA=\",\"AAAAAVYRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAAAAACQgQAAEQEAAA=\"]He[\"\",\"AAAAAAAEMgwAADMMAAA0DAAANQwAAAIIDAAA1BMAAAIHEQAAUBMAAAUpEAAAKhAAACsQAAAsEAAAQBMAAAEREgAAAAFmEgAAAAFtBwAAAAHCAQAAAAABpwUAAA==\",1]AMk[\"AAACvAEAAMUBAAAGrAEAALQBAAC5AQAAxgEAANwSAADdEgAABFgFAAA3CQAA/wkAAFAKAAAEMgwAADMMAAA0DAAANQwAAAJYEwAAWRMAADowAAABAAAAAAAHABAAAAAKCQsJRhBHENQS1RLSE9MTOjAAAAEAAAAAAAkAEAAAAEAEcAdzB7IHtAdND04PwA/3E/gTAAKxBwAAswcAAA==\",\"AAAAOjAAAAEAAAAAABAAEAAAAKIBTQdOB08HUAfVB9YHNgzDD8QPXBDIEMkQYxJkEp0S3BMDNAkAACgQAACYEgAABjIMAAAzDAAANAwAADUMAABqEgAAbBIAAAAAAAJzBQAAdAUAAAACXAQAAL8PAAAAA2EEAABKDwAASw8AAAMjDAAAJQwAAEkPAAAAAAImDAAAggwAADowAAABAAAAAAALABAAAAClAW4EbwS3BLoEjwaQBggHUQfSB9MHnw8=\"]Bg[\"AAAAAAAAAAAAAVcEAAA=\",\"AAAAAaQFAAA=\"]Bk[\"AAAAAAAAADswAAABAAANAAIAdQUAALUGDAA=\",\"\"]Cc[\"AAABAQkAAAABEgIAAAAAAAFABAAA\",\"AAAAAAAAAAFdBAAA\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAbAGAAA=\",\"\"]Be[\"AAAAAAAAA2AFAABhBQAAYgUAAA==\",\"\",1]Bg[\"AAAAAAAAADswAAABAAAUAAEAPwMUAA==\",\"\"]Dk[\"AAAAAAHIAQAA\",\"AAAAAAUtCQAALgkAAC8JAAAwCQAAMQkAAAAAAAAAAAAAAAAAAAH9DwAA\"]Cc[\"AAAAAcQEAAAAAQ0AAAACvwAAAMAAAAA=\",\"AAAAAcQEAAA=\"]Bg[\"AAAAAAAAAAAAAVIEAAA=\",\"AAAAAcYHAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWYAAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAaoAAAA=\",\"\"]C@i[\"AAAAAAHIAQAAAZ4SAAABbxMAAAK7AQAAnxIAADowAAABAAAAAAAbABAAAACtAW0FbgWCD4MPqBCpEF0SXhIKEwsTNhM3E0kTShNME00TThNPE1cTcBOuE/cT+BMKFAsUGBQZFDswAAABAAAGAAMAPwkBAKIPAwC/EwAAAQIUAAAB2RMAAAAAAcUGAAAAAAABpwUAAA==\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAAEAwwAAAQMAAAFDAAABBIAADowAAABAAAAAAAXABAAAACcAakEbgdxB8cHvgi/CC0JLgkvCTAJMQk0CR8QIBAhECIQIxCYEqESAxMEEwUTBhM7MAAAAQAAIAAOANkBAADbAQAAQQQAAEYEAABaBAAAYAQAAPgGCAAyDAMAQw8AAFMQAAC6EAQAEBEEAOESAABLEwAAOzAAAAEAACMACQBDBAAAdQQFAKYFAADQBwAARA8AAKkPEwBQEgEAXRMBAGATAQA7MAAAAQAACAAEADgQAAAyEQMAQhECAHgTAAA7MAAAAQAADAAGAEAEAABNDwEAKRADAAoRAwBXEwAArhMAAAQbEgAAHBIAAB0SAAAeEgAAOzAAAAEAAAYAAwAfDAMA1BABAAIUAAAEXAQAAL8PAADBEAAA2RMAAAAAAcUGAAABwgEAAAAAOjAAAAEAAAAAABwAEAAAAKwArQCuAK8Apga0BgEHAgcDB/oIOwk8CT0JPglBCUIJjg+nD6gPyg/LD8wPWRBaEFsQQREJEn0TIBQ=\",1]Bg[\"AAAAAAAAAAAAAAAAAAKeEAAAnxAAAA==\",\"\"]Jo[\"AAAAAc8EAAAAOjAAAAEAAAAAAAcAEAAAABkAlQDZAUYEQw9NEVARCBMCqg8AAFASAAACQAMAALYGAAAC4AAAAOEAAAAAAbEHAAAAAAFvBwAA\",\"AAF6BwAAAANhAAAAYgAAAM8EAAACWgIAAMcHAAACTREAAFARAAAAAagGAAA=\"]A@c[\"AAAAAfgEAAAABzIAAACdAAAA2wEAAE8RAABREQAA4RIAAAkTAAAHIgEAACMBAABEDwAAsg8AAL4PAABLEAAAURIAAARIAwAAuwYAAB4MAAB4EwAAARISAAABMQ4AAAKzBwAAAhQAAAHZEwAAAAFyBwAA\",\"AAGPBwAAAAH4BAAAAr8CAABWBQAAAk8RAABREQAAAa0GAAAAAAEbDAAAAAFmEgAAAAAAAAAABWYAAABnAAAAaAAAAGkAAABqAAAA\"]Bo[\"\",\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwA=\"]CDe[\"\",\"AAA7MAAAAQAA5gABAMMK5gA7MAAAAQAA7QAMAMoJMwAACgAAAgoyADYKAgA6ChUAUwoeAHMKBgB7CioAqAoBAKwKFgBPEgAA4xMBADowAAABAAAAAAASABAAAABdBaUFlgYTCRQJ/gn/CQEKNQo5ClAKUQpSCnIKegqmCqsK/BL9EjowAAABAAAAAAASABAAAABIBEUF9gYEBzkJOgmnCqoKSBFWElcSWBJZEloSWxIHE5gTnROeEzowAAABAAAAAAApABAAAADCBsMG0Ae1C7YLtwu4C+sL7AvtC+4LCAxQD3oPvg9LEF8QZRBmEGcQaBDFEHUSdhI6EzsTPBM9Ez4TPxNdE14TYBNhE9AT1BP5EwAUHBQdFB4UHxQ6MAAAAQAAAAAAGgAQAAAAXQRyBHMEdARbBVwFpwaoBqkGqgarBh4M2g86EDwQPhBAEEEQYBAPEUIRQxFEEVATeBPREwEUOzAAAAEAAFkADwDbAD0AigEBAEAEAABeBAAAZQQAAFMFAQBsBwAATQ8BAMAPAAASEgAASRIFAFcTAACuEwYAwhMAAPoTAAA7MAAAAQAAEQAIAHMFAQAbDAAAfQwAADEOAAAkEAAAOhEDAEYTAQDvEwUAOjAAAAEAAAAAAAgAEAAAAGIEYwRPD2kQahDUENUQdxICFDowAAABAAAAAAALABAAAABcBF4FEgcTB78PyhDMEM4Q0BDSEGYS2RMEQgQAAEQEAACbEwAAnBMAAARtBwAAbwcAAHIHAAC/EAAAAiMMAABJDwAAOzAAAAEAAAYAAwDCAQAAsAYAAI8TBAAB7BIAAAABpwUAAA==\",1]Le[\"\",\"AAAAAswBAACUBgAAA/QGAAA8DwAAPQ8AAAPmBgAAahIAAGwSAAA6MAAAAQAAAAAABwAQAAAATA8PEhgSGRIaElgTWROOEwJmBAAAtAsAAAGtAQAAAb8TAAAERg8AAEcPAABIDwAAwBAAAAABJwwAAARhBAAAJAwAAEoPAABLDwAAASUMAAAAAAEmDAAA\",1]Gc[\"\",\"AAAAOjAAAAEAAAAAAAcAEAAAAN0B3gEQEmkS1RPhE/8TDhQC8wYAACgQAAAFkwYAAA8JAAAQCQAAfQ8AAA4SAAABGxMAAAEHEQAAAUATAAA=\"]Bo[\"\",\"AAAAAv4SAAD/EgAAAATvCwAA8AsAAPELAADyCwAA\"]Bk[\"\",\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCAA==\"]Fc[\"AAAAAcQBAAAAAAAABG0FAABuBQAAgg8AAIMPAAA=\",\"AAA7MAAAAQAAPgABADcMPgAAAAAAAAAAAAAAAAAAAAAB4wYAAA==\"]Ao[\"\",\"AAA7MAAAAQAA5gABANcH5gA=\"]A@o[\"AAAEaQIAAHoCAACAAgAAOA8AAAHNBAAAA+cSAAARFAAAFRQAAAMWAAAAlAAAAEwRAAABqQ8AADowAAABAAAAAAAMABAAAAA/A3IEcwRDBUQFWwW1Bj8RURN7E6UT3xPtEwLbAAAA3AAAAA==\",\"AAF5BwAAOzAAAAEAAAYAAwBRAgQAEQkAANYSAAABzQQAAAQTCQAA/gkAAP8JAAABCgAAAUwRAAAB6wsAAAOnBgAAQhEAAEMRAAAAAAAAAAAAAAAAATAPAAA=\"]ABc[\"AAAE3gIAAAEDAAAIAwAAOQ8AAAH1BAAAAAQuAAAAmwAAAE4RAADoEgAABBsBAAAcAQAAsA8AAOITAAA6MAAAAQAAAAAACgAQAAAARgN0BEYFXAW6BkARUhN8E6YT4BPuEwABMQ4AAA==\",\"AAGOBwAAB7UCAAC2AgAAtwIAALgCAAC6AgAAEgkAANcSAAAB9QQAAAQUCQAAUAoAAFEKAABSCgAAAu8LAABOEQAAAqwGAADQBwAAAUQRAAAAAAAAAAAAAAAABDIPAAAzDwAANA8AADUPAAA=\"]Gc[\"AAA7MAAAAQAACwAEABoQBAAAEwAApxMEABIUAAA=\",\"ADswAAABAAAJAAMAUgcBAFUHAgDPEgQAOzAAAAEAAAsABAAaEAQAABMAAKcTBAASFAAA\"]Ig[\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBGDwIAwBAAANQQAQAAAScMAAAEJAwAAEoPAABLDwAAvxAAAAMjDAAAJQwAAEkPAAAAAAEmDAAA\",\"\"]Cc[\"AAAAArABAADIEAAAAAAAAAErDAAAAAFrBAAAARIHAAA=\",\"\"]Cc[\"AAAAAr8BAADJEAAAAAAAAAEsDAAAAAFsBAAAARMHAAA=\",\"\"]ABg[\"AAAAAu0SAADuEgAAAAW3AQAAuAEAAMoBAADLAQAADhEAADswAAABAAALAAMArAQHAFoFAAATDAIAOjAAAAEAAAAAAAcAEAAAAEYFwgfDB8QHxQdRD1IPpg8HChEAAAsRAAAMEQAADREAAHATAADCEwAA+hMAADswAAABAAANAAQAGwwAADEOAACiDwMADhMHADswAAABAAAHAAEA0wYHAAPBEAAAZhIAANkTAAAAAW0HAAABxQYAAAAAAAGnBQAA\",\"AAAAA9MBAADUAQAA1QEAAAABUxAAAA==\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUQUAAOkGAAA=\",\"AAAAAAAAAAIyEQAAMxEAAAAAAAAAAAAAAAACxgYAANwGAAA=\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUgUAAOsGAAA=\",\"AAAAAAAAAAI0EQAANREAAAAAAAAAAAAAAAACxwYAAN0GAAA=\"]Ak[\"\",\"AAAAAAKgDwAAoQ8AAA==\"]Eo[\"AAAABO8EAAAXBwAAugcAAB0RAAACJQkAAPgLAAABsRAAAAAAAQ8BAAABERMAAAHWBgAA\",\"AAAAAe8EAAAAAbgBAAA=\"]Eo[\"AAAABDkFAAAbBwAAvgcAACQRAAACKQkAAPwLAAABtRAAAAGSAQAAAAABFRMAAAHaBgAA\",\"AAAAATkFAAAAAcsBAAA=\"]Bg[\"AAAAAAAAAAAAAVEEAAA=\",\"AAAAATgJAAA=\"]Ag[\"AAACrwEAAL4BAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAIkDAAAvxAAAA==\",\"\"]Ag[\"\",\"AAACQhAAAEMQAAA=\"]Bg[\"AAAAAAAAAAAAARESAAA=\",\"AAABbwAAAA==\"]Dg[\"AAAAAtMBAADUAQAAAAADYAUAABMMAAAYEgAAAAGtAQAAAb8TAAA=\",\"AAAAAQQSAAA=\"]Hg[\"AAAAAScRAAABAxMAAAM5EAAAuxAAABERAAABXRMAAAEyEQAAASkQAAACOhEAABsSAAABLBEAAAAAAAABkBMAAA==\",\"AAAAAAAAAALLEAAAzRAAAAAAAALKEAAAzBAAAA==\"]Ig[\"AAAAASoRAAABBRMAAAM9EAAAvRAAABMRAAABYBMAAAE0EQAAASsQAAACPBEAAB0SAAABLhEAAAAAAAABkhMAAA==\",\"AAAAAAEIEQAAAAADzxAAANEQAADTEAAAAAAAA84QAADQEAAA0hAAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAm4AAAA1DwAA\",\"\"]Bk[\"AAAAAAAAAdoAAAAAAAFZBAAA\",\"AAAAAc8HAAA=\"]Cc[\"AAAAAVwQAAABFxMAAAACQwQAAKYFAAA=\",\"AAAAAAHUBwAA\"]Ek[\"AAAAAdQEAAAAAR0AAAAAAAHmAAAAAAAAAAAAAAAAArcEAACPBgAA\",\"AAF/BwAAAAHUBAAAAAAAAAAAAWkQAAA=\"]Ek[\"AAAAAQUFAAAAAT0AAAABNAEAAAAAAAAAAAAAAAAAAroEAACQBgAA\",\"AAGWBwAAAAEFBQAAAAAAAAAAAWoQAAA=\"]Be[\"AAAAAAA7MAAAAQAAhgABAH0RhgA=\",\"\",1]Bg[\"AAAAAAAAAAAAAVQEAAA=\",\"AAAAAeoLAAA=\"]Ec[\"AAAAAAAAAAAAAAAAAAJvBwAAcgcAAAHFBgAAAsIBAACwBgAA\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Dk[\"AAAAAAAAAAABsRMAAAHxEwAA\",\"AAAAAAABWBIAAAE8EwAAAAAAAAAAAAAAAAABVAcAAA==\"]Dg[\"AAAAAR0FAAAAAAJfAQAAYAEAAAG+BgAAAAAAAAAAAAAAAAELAgAA\",\"AAAAAR0FAAA=\"]ABc[\"AAAAA6oBAAARCgAAUhEAAAPEBgAAcgoAAK0QAAAAADowAAABAAAAAAANABAAAAAgCSEJKwksCYwPjQ9dEF4Q2hLbEgETAhNVE1YTOzAAAAEAAA8ABwCoEAEASRIFAAoTAQBXEwAArhMAAAoUAQAYFAEAAAECFAAAAdkTAAA=\",\"AAAAA50BAACoAQAAJRAAAAQfEAAAIBAAACEQAAAiEAAAAtkBAADbAQAAAAACVxMAAK4TAAAAAQIUAAAB2RMAAAAAAAAAAATaAQAA3AEAAP4IAABVEQAA\"]Bk[\"AAAAAAHzBgAA\",\"AAAAAAAAAAEHEQAAAAEREgAA\"]Ho[\"AAAABcIEAABpBQAApAUAAHwMAABjEgAAAj0PAADYEwAAAuYGAACeEgAAA70AAAAPEgAAbxMAAAFEBQAAAWwHAAABJBAAAA==\",\"AAAAAsIEAACUBgAAAfQGAAAAAAABrQEAAAG/EwAA\"]Gc[\"AAAAAmQSAABxEwAAAZsGAAAByQYAAAEaAQAAAjgQAACfEgAAAAHoBgAAAAFeBQAAAAFtBwAAAcUGAAAAAAABpwUAAA==\",\"AAAAAAAAAAG7AQAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAW0AAAA=\",\"\"]Fg[\"AAADyAYAAOcGAACaDwAABA8MAABPEAAARxEAAMATAAAFDQIAAF0FAAClBQAAbgcAAC8JAAAAAsMAAAB6DwAA\",\"AAABphAAAA==\"]Fg[\"AAAABBAMAABQEAAASREAAMETAAACcQcAADAJAAAByQYAAAFiAQAAAAAB6AYAAAABXgUAAAAAAAAAAAGnBQAA\",\"AAABpxAAAA==\"]Dg[\"AAAAASIFAAAAAVEAAAABawEAAA==\",\"AAAAASIFAAAAAAAAAAAAAAAAAAAAAAFwAAAA\"]Bk[\"AAAAAAEMAgAAAAAAAAFOBAAA\",\"AAAAARkMAAA=\"]Cc[\"AAAAAAHHBwAAAAAAAAFPBAAA\",\"AAAAAAACGgwAAGUSAAA=\"]Dk[\"\",\"AAAAADswAAABAAATAAEAWAcTADswAAABAAATAAEAlAATADswAAABAAATAAEAqQ8TAA==\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWsAAAA=\",\"\"]Fg[\"AAAAATwFAAAAAAGZAQAAAAAAAAAAAWEEAAAAAAABJgwAAAauAAAApQEAAAUCAAC0BgAACAcAAAkSAAA=\",\"AAGlBwAAAAE8BQAA\"]Hk[\"AAAEqAAAAFQCAABNBQAABgwAAAHqBAAAAAIrAAAAmgAAAAGvDwAAAkUDAAC5BgAAAggBAAAJAQAA\",\"AAABgAIAAARjAAAAZAAAAGUAAADqBAAAAbUBAAAAAe4LAAABqwYAAA==\"]Kc[\"AAAEqQAAALYCAABOBQAABwwAAAEsBQAAAARZAAAApwAAAMIPAADHDwAAA30BAAB+AQAAvA8AAAJSAwAAwAYAAA==\",\"AAABCAMAAAEsBQAAAccBAAAB8gsAAANDBAAApgUAALIGAAAAAAAAAAAAAAAAAARrAAAAbAAAAG0AAABuAAAA\"]Ak[\"AAAAAALYDwAA2Q8AAA==\",\"\"]Ao[\"AAAAAAAAAAACpgEAAEkSAAA=\",\"\"]Ao[\"AAAAAAAAAAACpwEAAEwSAAA=\",\"\"]Dc[\"AAAAAAAAAAABCgEAAAAAAAAAAAAAAAWsAAAAbgQAAAEHAACEDwAAWRAAAA==\",\"\"]Fc[\"AAAAAAAAAX8BAAAAAAAAAAAAAAAAAAWtAAAAbwQAAAIHAACFDwAAWhAAAA==\",\"AAAAAAAAAAAAAegGAAAAAl4FAADBEAAA\"]Fc[\"AAAAAT0FAAAAAAGaAQAAAmYEAAC0CwAAAAAAAAEnDAAAAAAAAAAFrwAAAAMHAAD7CAAAhg8AAFsQAAA=\",\"AAAAAT0FAAA=\"]Hg[\"AAABjQAAAAHQBAAAAAIaAAAAuwwAAAAAAeIAAAAAAAAAAAAAAAADoAEAALYEAAD+CwAA\",\"AAF7BwAAAAHQBAAAAAAAAAAAAAAAAAAAAAAECQcAAAoHAAANBwAADgcAAA==\"]Hg[\"AAAAApAAAAD/BAAAAAI4AAAAvgwAAAEsAQAAAAAAAAAAAAAAAAADoQEAALkEAAAADAAA\",\"AAGSBwAAAAH/BAAAAAAAAAAAAAAAAAAAAAAECwcAAAwHAAAPBwAAEAcAAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWwAAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmcAAADlBgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVMEAAA=\",\"AAAAAboMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAasAAAA=\",\"\"]Dk[\"AAAAAewEAAABtgEAAAABrQQAAAEaEQAAAQwBAAA=\",\"AAGIBwAAAAHsBAAAAAAAARoRAAA=\"]Dk[\"AAAAATYFAAAByQEAAAACjwEAALEEAAABIREAAA==\",\"AAGhBwAAAAE2BQAAAAAAASERAAA=\"]Hc[\"AAAAAAABfQ8AAAGOEwAAAAGyEwAAAfITAAAAAAAAAAAAADowAAABAAAAAAANABAAAADQBvoIPQk2DosPjg/KD5oQqhBBEWsSbRJIE30T\",\"AAAAAAABWRIAAAE9EwAA\"]Ak[\"AAAAAAKUEwAAlRMAAA==\",\"\"]Cg[\"AAAAAZ0SAAABNAkAAAFgBAAAAAABZQQAAA==\",\"AAAAAAH/CwAA\"]Ag[\"\",\"AAAAAAAAAbMGAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmgAAABFDwAA\",\"\"]Ag[\"AAAAAAAAAAHBBgAA\",\"\"]Dk[\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwAAOzAAAAEAAD8AAgDbAD0AigEBAA==\",\"\"]Hg[\"AAAAAi0FAADqBgAAATEJAAAEWgAAAAgTAAAJEwAAchMAAAOAAQAAgQEAAPUTAAABUwMAAAABGwwAAAABZhIAAAAAAcUGAAA=\",\"AAABhw8AAAEtBQAAAcgBAAAAAUsQAAA=\"]Dk[\"AAAAAeAEAAAAASIAAAAAAbcGAAAC9gAAAPcAAAA=\",\"AAAAAuAEAAAXCgAAAAAAAakGAAA=\"]Dk[\"AAAAARcFAAAAAUgAAAACUQEAAFIBAAABvAYAAA==\",\"AAAAARcFAAABegoAAAABrgYAAA==\"]Ck[\"AAAAAcMPAAAAAAAAAnAHAACyBwAA\",\"AAAAAAAAAAACKRAAACoQAAA=\"]Ck[\"AAAAAcQPAAAAAAAAAnMHAAC0BwAA\",\"AAAAAAAAAAACKxAAACwQAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAqMQAAAXEgAA\"]Ek[\"AAAAA9UHAAAHEgAAbRMAAAAAAAAAAAGxBwAAAAABbwcAAA==\",\"AAAAAAAAAAIyEQAAMxEAAAIpEAAAKhAAAA==\"]Ek[\"AAAAA9YHAAAIEgAAbhMAAAAAAAAAAAGzBwAAAAABcgcAAA==\",\"AAAAAAAAAAI0EQAANREAAAIrEAAALBAAAA==\"]Dg[\"AAAAAQsFAAAAAUQAAAACPwEAAEABAAA=\",\"AAAAAQsFAAAAAAAAAAEbDAAAAAFmEgAA\"]Cc[\"AAAB2AIAAAH7BAAAAAE0AAAAASYBAAA=\",\"AAAAAfsEAAA=\"]Ic[\"AAABjwAAAAHSBAAAAAIcAAAAvQwAAAAAAeQAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA2gEJAgkHDQcCCQYJPg9/D0QQlBIMExwTOBM=\",\"AAF9BwAAAALSBAAAagUAAAABQw8AAA==\"]Ho[\"AAAAApIAAAABBQAAAAI6AAAAwAwAAAEuAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA3AEKAgsHDwcECQgJPw+BD0UQlRINEx0TORM=\",\"AAGUBwAAAAEBBQAAAAABRA8AAA==\"]Gk[\"AAACOgIAAEACAAAByAQAAAACEQAAAPoGAAACzQAAAM4AAAA=\",\"AAACPAIAAD0CAAAByAQAAAAAAAACTQ8AAE4PAAAAAAJcBAAAvw8AAAABvxAAAAEjDAAA\"]Do[\"AAAAAQMFAAAAAjsAAACeAAAAAzABAAAxAQAAsw8AAAFJAwAA\",\"AAAAAQMFAAAAAAAAAUAEAAA=\"]Ck[\"AAAAAnUTAAB2EwAAAAAAAAAAAAABJwwAAA==\",\"AAAAAAABoBAAAA==\"]Co[\"AAAAAAAB5gYAAAMYEgAAGRIAABoSAAAAAa0BAAA=\",\"AAAAAAABfQ8AAA==\"]K@m[\"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\",1]Eo[\"AAAAAAA7MAAAAQAABQABAFYSBQA7MAAAAQAABQABADoTBQAAOzAAAAEAAAUAAQCvEwUAOzAAAAEAAAUAAQDvEwUA\",\"\"]Ck[\"AAAAAAAAAVoFAAAAAAFMBAAA\",\"AAAAAAAAAxMMAAAUDAAAFQwAAA==\"]Cc[\"\",\"AAAAAAAESAQAAAQHAABIEQAAmBMAAAAAAlcTAACuEwAA\"]Fc[\"AAAAAf4EAAAAATcAAAACKgEAACsBAAA=\",\"AAGRBwAAAAH+BAAAAAACvg8AAEsQAAACHgwAAHgTAAAAAAECFAAAAdkTAAA=\"]Eo[\"AAAAAUURAAABLQkAAAACuAAAAAgMAAABDxEAAAABUAQAAA==\",\"AAAAAAGlBQAAAAIIDAAAeg8AAAABbAcAAAEkEAAA\"]Dk[\"AAAABhASAABpEgAA1RMAAOETAAD/EwAADhQAAAAAAAABQBMAAA==\",\"AAAAAAAAAAEHEQAA\"]A@g[\"AAAAOjAAAAEAAAAAABIAEAAAAGkEvwRoBZcGxgc4CeoLGQw2DLoMvQ/UD8QQRhFUEkMTdxOXE9wTOjAAAAEAAAAAAAcAEAAAAC4JIxATEpgS4hLnEhEUFRQ6MAAAAQAAAAAABwAQAAAA2QFGBBoMQw+6EBARZRIHEzowAAABAAAAAAAHABAAAAC5AMUQUBLQE/kTABQcFB4UAUMFAAAAAAAAAAAAAY8TAAA=\",\"AAAAAb8EAAABvggAAAABCAwAAA==\"]ACk[\"AAAAOjAAAAEAAAAAAAgAEAAAAGoEHgkMDDoPgA+XECkRrBOtEzowAAABAAAAAAAHABAAAABKBFYFawXUB/8LCBFVEpYTOjAAAAEAAAAAAAoAEAAAANsBWgTCD8cPNxBTEA4RFBLhEugSSxM6MAAAAQAAAAAABwAQAAAAGQFED74PSxBREuITHRQfFAVGBQAAHgwAAHgTAADREwAAARQAAAQSEgAAcBMAAMITAAD6EwAAAhsMAAAxDgAAAQIUAAADwRAAAGYSAADZEwAA\",\"AAAAAAAAAAAAAAAAAAFtBwAAAAAAAAGnBQAA\"]Ho[\"AAAAAxQHAAC3BwAAGBEAAAMiCQAA9QsAAPsTAAABrhAAAAABwgcAAAACog8AAA4TAAAB0wYAAA==\",\"AAAAAAT1CwAA9gsAAPcLAAD4CwAAAAWsBAAArQQAAK4EAACvBAAAUBIAAA==\"]Ho[\"AAAAAxgHAAC7BwAAHxEAAAMmCQAA+QsAAP0TAAABshAAAAABxAcAAAACpA8AABITAAAB1wYAAA==\",\"AAAAAAT5CwAA+gsAAPsLAAD8CwAAAAWwBAAAsQQAALIEAACzBAAAURIAAA==\"]No[\"AAABjgAAAAHRBAAAAAIbAAAAvAwAAAAAAeMAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAgJJBKAGBgf8CDIJFgwcDCgMew+dDyYQURBWEGEQmBCkEKsQthC4EBURNhFKEQoSDBJSEl8SmRKbEt4SHhMgE1MTWhN5E5kT1hM=\",\"AAF8BwAAAAHRBAAAAAAAAAAAAAAAAAAAAAAEAgkAAAMJAAAGCQAABwkAAA==\"]No[\"AAAAApEAAAAABQAAAAI5AAAAvwwAAAEtAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAwJLBKQGBwf9CDMJFwwdDCkMfA+eDycQUhBXEGIQmRClEKwQtxC5EBYRNxFLEQsSDRJTEmASmhKcEt8SHxMhE1QTWxN6E5oT1xM=\",\"AAGTBwAAAAEABQAAAAAAAAAAAAAAAAAAAAAEBAkAAAUJAAAICQAACQkAAA==\"]Cc[\"AAAAAecEAAAAAAAAAQMBAAA=\",\"AAAAAecEAAAAAAG1CwAA\"]Ck[\"AAAAASgFAAAAAAF3AQAA\",\"AAAAASgFAAAAAAO2CwAAtwsAALgLAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAFhBAAAAAAAASYMAAA=\",\"\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAATYPAAA=\"]Eo[\"AAAAARgFAAAAAUoAAAACVQEAAFYBAAABvQYAAA==\",\"AAAAARgFAAAAAAGvBgAAAAAAAAAAAAAAAAACTAUAADcPAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAgwUAAANFAAA\"]Ck[\"AAAAAAAAAAABwhMAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAABIxQAAA==\"]Ag[\"AAACmgIAABoDAAA=\",\"\"]Bo[\"AAAAAAAAAcEAAAAAAAABIQwAAA==\",\"AAAAAb0PAAA=\"]Cc[\"AAAAAAACGgwAAGUSAAABUA8AAA==\",\"AAAAAAABBAcAAA==\"]Gc[\"AAAAAfoEAAAAATMAAAABJQEAAAABEhIAAAEbDAAAAAFmEgAA\",\"AAGQBwAAAAH6BAAAAAHhEgAAAb4PAAAAARISAAAAAAAAAAAAAAABBQcAAA==\"]Do[\"AAAAAAAAAAFRDwAAAm0FAACCDwAA\",\"AAAAAa4BAAAAAAABUQ8AAARtBQAAgg8AAAoRAAALEQAA\"]Do[\"AAAAAAAAAAFSDwAAAm4FAACDDwAA\",\"AAAAAboBAAAAAAABUg8AAARuBQAAgw8AAAwRAAANEQAA\"]Ao[\"AAAAAAEoEAAAAAABTBAAAA==\",\"\"]Gc[\"AAABJhEAAAJjAAAAtQcAAAEQAgAAAAHJAAAAAnIEAABCEQAAAk0PAADADwAAAAFPDwAAAlwEAAC/DwAAAAIkDAAAvxAAAAIjDAAAJQwAAA==\",\"\"]Cc[\"AAAAAAAAAANdBAAAdAQAAEQRAAA=\",\"AAAAAAABwg8AAA==\"]Ec[\"AAABPAIAAAHJBAAAAAISAAAA+wYAAALPAAAA0AAAAA==\",\"AAABPwIAAAHJBAAAAAAAAkIRAABDEQAA\"]Bo[\"AAABphAAAAAAAALEAAAAxQAAAA==\",\"AAAAAAFdBQAA\"]Ck[\"AAABpxAAAAAAAAJmAQAAZwEAAA==\",\"AAAAAAAAAAAAAAABXgUAAA==\"]Ao[\"AAAAAAAAARsTAAABQA8AAA==\",\"\"]Hg[\"AAAAAmUAAADPBwAAARECAAABOQkAAAPVAAAAwgYAAF8QAAACWwUAANoPAAAAAnMFAAB9DAAABkYPAABHDwAASA8AAGkQAADAEAAAdxIAAAAAAkoPAABLDwAAAUkPAAA=\",\"\"]Dk[\"AAAAAAABOgkAAALDBgAA0AcAAAJcBQAAYBAAAAABdAUAAAFqEAAA\",\"AAAAAAABxw8AAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\",\"\"]ABc[\"AAABhw8AAAGUBgAAAsgBAAD0BgAABJMGAAAaDAAAfQ8AAGUSAAAC0BMAAAAUAAADBxEAANETAAABFAAABWwHAAAKEQAACxEAAAwRAAANEQAAASQQAAAAAAABbQcAAA==\",\"AAAABeoGAABFEQAARhEAAEcRAABJEQAAA5wBAAA8DwAAPQ8AAAFIEQAABfkTAAAcFAAAHRQAAB4UAAAfFAAAAXgTAAAB+hMAAAEREgAAAAAAAAAAAAJWDwAAcA8AAAUEAgAABQIAAIQPAACFDwAAhg8AAA==\"]Cc[\"AAAAARkFAAAAAUsAAAACVwEAAFgBAAA=\",\"AAAAARkFAAA=\"]Dc[\"AAAAAAAAAAA7MAAAAQAABQABAEkSBQA=\",\"AAAABNIBAADWAQAA1wEAANgBAAA=\"]Ao[\"AAAAAdIBAAAAAAAAAc0PAAA=\",\"\"]Ao[\"AAAAAdcBAAAAAAAAAc4PAAA=\",\"\"]Eo[\"AAAAASgRAAABBBMAAAM7EAAAvBAAABIRAAABXhMAAAEzEQAAASoQAAACOxEAABwSAAABLREAAAAAAAABkRMAAA==\",\"\"]Eo[\"AAAAASsRAAABBhMAAAM/EAAAvhAAABQRAAABYRMAAAE1EQAAASwQAAACPREAAB4SAAABLxEAAAAAAAABkxMAAA==\",\"\"]Bc[\"AAAAAAAAAnUEAADKBgAAAAHPDwAA\",\"\"]Bc[\"AAAAAAAAAngEAADNBgAAAAHQDwAA\",\"\"]Ec[\"AAAAAcwBAAAAAmoSAABsEgAAAlgTAABZEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAAEwAwAA\"]Gg[\"AAAAAcsEAAAAAhQAAAD9BgAAAtYAAADXAAAA\",\"AAADRQIAAEYCAABHAgAAAcsEAAAAAAAB2g8AAAACcwUAAH0MAAACaRAAAHcSAAAAAAABSQ8AAA==\"]Eg[\"AAAAAQYFAAAAAj4AAACgAAAAAzUBAAA2AQAAtQ8AAAFLAwAA\",\"AAAAAQYFAAAAAAAAAAF0BQAAAWoQAAA=\"]Ec[\"AAAAAAAAAWUBAAAAAAAAAAAAAAAAAAK7BAAAPgkAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAacFAAA=\"]Ec[\"AAAB8wsAAAG+BAAAAAELAAAAAbQAAAA=\",\"AAAAAb4EAAAAARAJAAAAAAAAAAAAAAAAAAABkQYAAA==\"]Dg[\"AAAAAAFYBQAAAAAAAAAAAAAAAAAAAAJkEAAACREAAA==\",\"AAF2BwAAAAAAAZMGAAA=\"]Ac[\"AAABZAIAAA==\",\"\"]Do[\"AAAAAd8EAAAAASEAAAAAAAL0AAAA9QAAAA==\",\"AAACcAIAAHECAAAB3wQAAAAAAAAAAUYTAAA=\"]Dk[\"AAAAARYFAAAAAUcAAAACTwEAAFABAAA=\",\"AAAC5AIAAOUCAAABFgUAAAAAAAAAAUcTAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAXCQAA\"]Dk[\"AAAAAAAAAAABEwEAAA==\",\"AAABjQIAAAAAAAAAAAABYgQAAAESBwAAAUIEAAABbwcAAA==\"]Dg[\"AAAAAAAAAYgBAAA=\",\"AAABEwMAAAAAAAAAAAABYwQAAAETBwAAAUQEAAABcgcAAA==\"]Dk[\"AAAAAe4EAAAAAbcBAAABrgQAAAEcEQAAAQ4BAAA=\",\"AAGJBwAAAAHuBAAAAAAAARwRAAA=\"]Dk[\"AAAAATgFAAAAAcoBAAACkQEAALIEAAABIxEAAA==\",\"AAGiBwAAAAE4BQAAAAAAASMRAAA=\"]Ck[\"AAAAAQcFAAAAAT8AAAACNwEAADgBAAA=\",\"AAAAAQcFAAAAAAHDBgAA\"]Eg[\"AAAAAdoEAAAAAiAAAACWAAAAAasPAAABQQMAAALvAAAAXRIAAA==\",\"AAGEBwAAAWkCAAAC2gQAABEKAAA=\"]Eg[\"AAAAAREFAAAAAkYAAAChAAAAAkoBAAC2DwAAAUwDAAABXhIAAA==\",\"AAGcBwAAAd4CAAABEQUAAAFyCgAA\"]Ao[\"AAAAAAAAAAACVBAAAAoRAAA=\",\"\"]Ao[\"AAAAAAAAAAACVRAAAAwRAAA=\",\"\"]Do[\"AAABbwAAAAG9BAAAAAABswAAAA==\",\"AAAAAb0EAAAAAQ8JAAAAAAAAAAAAAAAAAAABWBAAAA==\"]Bg[\"AAAAAAAABNQAAABiBQAAFQwAABoSAAA=\",\"\"]Ak[\"AAAAAAABQAAAAAE5AQAA\",\"\"]Do[\"AAAAAAAAAAAAAAAAAAAAAAAAAqMQAAAXEgAA\",\"AAF0BwAAAAAAAAAAAAAAAAAAAAAAAAFjEAAA\"]Cg[\"AAAAAAPEBgAANwkAAK0QAAA=\",\"AAAAAAAAAAJADwAATBAAAA==\"]Ag[\"AAACjQIAABMDAAA=\",\"\"]Ac[\"\",\"AAAAAU8SAAA=\"]Cc[\"AAAAATQKAAACNQoAAKYKAAABpwoAAAJlEAAAZxAAAA==\",\"\"]Gg[\"AAAAAd4EAAAB2BMAAAAAAcAIAAAE8wAAAM8PAABwEgAAvRMAAAEkEAAA\",\"AAAAA7IBAADeBAAA4xMAAAABnRMAAAABwAgAAAPPDwAAcBIAAL0TAAA=\"]Bc[\"AAAAAbIBAAAAAAAAAAAAAcoQAAA=\",\"\"]Gg[\"AAAAARUFAAAAAAFOAQAAAcEIAAAD0A8AAHISAAC+EwAAAAAAAAFtBwAA\",\"AAAAA8EBAAAVBQAA5BMAAAABnhMAAAABwQgAAAPQDwAAchIAAL4TAAA=\"]Bc[\"AAAAAcEBAAAAAAAAAAAAAc4QAAA=\",\"\"]Fg[\"AAABRgIAAAHVBAAAAAEeAAAAAAAC5wAAAOgAAAA=\",\"AAGABwAAAAHVBAAAAAE5CQAAAsIGAABfEAAAA3IEAABzBAAAWwUAAA==\"]Eo[\"AAAAAQkFAAAAAUIAAAACOwEAADwBAAA=\",\"AAGYBwAAAAEJBQAAAAE6CQAAAdAHAAAEdAQAAFwFAABgEAAARBEAAA==\"]Ao[\"\",\"AAAAAAAAAAAAAAAB0hAAAA==\"]Ek[\"AAAAAeMEAAAAASUAAAAAAAL8AAAA/QAAAA==\",\"AAABdwIAAAHjBAAAAAAAAAFsBwAAASQQAAAAAsoQAADMEAAA\"]Eg[\"AAAAAR8FAAAAAVAAAAACYwEAAGQBAAA=\",\"AAAB8QIAAAEfBQAAAAAAAAAAAALOEAAA0BAAAAABbQcAAA==\"]Ao[\"AAAAAAAAAAFBEAAAAAExDAAA\",\"\"]Jk[\"AAAAAeQEAAAABSYAAACXAAAASAUAADkQAAA7EAAAArULAACsDwAABEIDAAABDAAAOhAAADwQAAAE/gAAAP8AAAAKEQAACxEAAAItDAAALgwAAAIsEQAALREAAA==\",\"AAAAAuQEAABPEAAAArMBAAAyEAAAAAABCgkAAA==\"]Og[\"AAAAASQFAAAABVMAAACkAAAASQUAAD0QAAA/EAAABnABAABxAQAAtgsAALcLAAC4CwAAuQ8AAARPAwAAAgwAAD4QAABAEAAAAgwRAAANEQAAAi8MAAAwDAAAAi4RAAAvEQAA\",\"AAAABCQFAACpBwAAqgcAAFAQAAAEwwEAADMQAAA0EAAANRAAAAAAAQsJAAACUwUAAFQFAAAAAAAAAAAAAAA7MAAAAQAACgACAKsHBQDKBwQA\"]Cc[\"AAAAARoFAAAAAUwAAAACWQEAAFoBAAA=\",\"AAAAARoFAAA=\"]Ck[\"AAABTwUAAAHlBAAAAAEnAAAAAAABAAEAAA==\",\"AAAAAuUEAAADDAAA\"]Dg[\"AAABUAUAAAElBQAAAAFUAAAAAXIBAAAAAAAAAAAAAcUGAAA=\",\"AAAAAiUFAAAEDAAA\"]Cc[\"AAAAAT4FAAAAAWAAAAABmwEAAA==\",\"AAAAAj4FAAAFDAAA\"]Dg[\"AAAAAAAAAAAAAAABwRAAAA==\",\"AAAABjYQAABcEgAARBMAAEUTAAB1EwAAdhMAAA==\"]Ak[\"AAAAAAAAAAABSxIAAA==\",\"\"]Ak[\"AAAAAAAAAAABThIAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmoAAAAEAgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVUEAAA=\",\"AAAAAcQQAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmkAAAAFBwAA\",\"\"]Bk[\"AAAAAAAAAAAAAATTBgAA1AYAANUGAADWBgAA\",\"\"]Ec[\"AAAABJ0BAACoAQAA+QQAACUQAAAAAAEkAQAAAAAABNcGAADYBgAA2QYAANoGAAA=\",\"AAAAAfkEAAA=\"]Bg[\"AAAAAAAAAAAAAVYEAAA=\",\"AAAAAAHiEgAA\"]Ag[\"AAAAAAAB9gYAAA==\",\"\"]Cc[\"AAAAAToKAAACOQoAAKsKAAABqgoAAAJmEAAAaBAAAA==\",\"\"]No[\"AAAAAdwEAAAB9AYAAAGeEgAAAXoPAAAGEQwAAEYQAABBEwAAVRMAALUTAADdEwAAB/EAAACtAQAAdgwAAM0PAABvEgAATBMAAE4TAAABvxMAAAAAAAAAAAAAA6EGAAB6DAAAcxIAAA==\",\"AAAAAtwEAADWDwAAAAGxAQAAAXUSAAAGEQwAAEYQAABBEwAAVRMAALUTAADdEwAABXYMAADNDwAAbxIAAEwTAABOEwAA\"]Bo[\"AAAAAdYPAAAAAbEBAAAAAjoQAADLEAAAAAEtDAAA\",\"\"]Nc[\"AAAAARMFAAAAAAFMAQAAOjAAAAEAAAAAAAcAEAAAALsBEgxHEJ8SQhNWE7YT3hMFdwwAAM4PAABxEgAATRMAAE8TAAAAAAAAAAAAAAAEpwUAAKUGAAB7DAAAdBIAAA==\",\"AAAAAhMFAADXDwAAAAHAAQAAAXYSAAAGEgwAAEcQAABCEwAAVhMAALYTAADeEwAABXcMAADODwAAcRIAAE0TAABPEwAA\"]Bo[\"AAAAAdcPAAAAAcABAAAAAj4QAADPEAAAAAEvDAAA\",\"\"]Ao[\"AAAAAAAAAAACTBMAAE0TAAA=\",\"\"]Ao[\"AAAAAAAAAAACThMAAE8TAAA=\",\"\"]Dc[\"AAABRQIAAAHMBAAAAAIVAAAA/gYAAALYAAAA2QAAAA==\",\"AAABSQIAAAHMBAAA\"]Bk[\"AAAAAdUBAAAAAATTAAAAYQUAABQMAAAZEgAA\",\"\"]Ec[\"AAAAAv4SAAD/EgAAAvwSAAD9EgAABO8LAADwCwAA8QsAAPILAAAE6wsAAOwLAADtCwAA7gsAAA==\",\"\"]Cc[\"AAAAAAAAAAABShIAAA==\",\"AAF3BwAAAAKsAQAA3BIAAA==\"]Cc[\"AAAAAAAAAAABTRIAAA==\",\"AAGMBwAAAAK5AQAA3RIAAA==\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAABxQYAAA==\"]Cg[\"AAAAATsPAAAAAAFvAQAAATgQAAA=\",\"AAGoBwAAAAAAAUsTAAA=\"]Ek[\"AAAAAcMEAAAAAAG+AAAAAAAAAAAAAAAAAAAE2BIAAOASAAD7EgAAFhMAAA==\",\"AAF4BwAAAALDBAAAaQUAAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzsJAADLDwAADBQAAA==\",\"\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzwJAADMDwAADRQAAA==\",\"\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAYCQAA\"]Bc[\"AAAAAAABQQQAAA==\",\"AAAAAAGpBAAA\"]Ec[\"AAAAAfAEAAAAAbgBAAABrwQAAAIeEQAAcxMAAAEQAQAA\",\"AAGKBwAAAAHwBAAAAAAAAh4RAABzEwAA\"]Ec[\"AAAAAToFAAAAAcsBAAACkwEAALMEAAACJREAAHQTAAA=\",\"AAGjBwAAAAE6BQAAAAAAAiURAAB0EwAA\"]Ag[\"\",\"AAAAAAABDhIAAA==\"]Co[\"AAAAAqIBAACpBwAAAAABaAEAAA==\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Ac[\"\",\"AAAAAAGhEgAA\"]Cg[\"AAAAAAAAAnUSAAB2EgAAAAABERIAAA==\",\"AAAAAAAAAAFQEwAA\"]Do[\"AAAAAQQFAAAAAjwAAACfAAAAAzIBAAAzAQAAtA8AAAFKAwAA\",\"AAAAAQQFAAAAAAABXQQAAA==\"]Ak[\"AAAAAAACnRMAAJ4TAAA=\",\"\"]Ac[\"AAAAAdYBAAA=\",\"\"]Ac[\"AAAAAdgBAAA=\",\"\"]Eo[\"AAAC+QIAAA8DAAABLgUAAAABWwAAAAKCAQAAgwEAAA==\",\"AAAAAS4FAAAAAAAFpwYAAKgGAACpBgAAqgYAAKsGAAA=\"]Fk[\"AAAABEgQAABJEAAARBMAAEUTAAABPA8AAAGgEAAAAQ8SAAAAAAG/EwAAAAAAAAAAAAEmDAAA\",\"AAAAAAAAAxgSAAAZEgAAGhIAAA==\"]Fc[\"AAAAAAABkwYAAAJ1EgAAdhIAAAEHEQAAAAEREgAAAAACmxMAAJwTAAAAAAAB7BIAAA==\",\"AAAAAAAAAdQTAAABUBMAAA==\"]Ag[\"\",\"AAAAAAABRQUAAA==\"]Co[\"AAAAAQwFAAAAAUUAAAACQQEAAEIBAAA=\",\"AAAAAQwFAAAAAAAAAAExDgAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAeQGAAA=\",\"\"]Jc[\"AAAAAtsEAAC7EwAAAAAAAgUSAADaEgAABPAAAACtAQAAKwwAAOkSAAADPwkAAEYTAAC/EwAAAAAAAZ4QAAA=\",\"AAGFBwAAAAKwAQAA2wQAAAAAAAIFEgAA2hIAAAIrDAAA6RIAAAI/CQAARhMAAAAAAAGeEAAA\"]Jg[\"AAAAAhIFAAC8EwAAAAABSwEAAAO7AQAABhIAANsSAAACLAwAAOoSAAACQAkAAEcTAAAAAAABnxAAAA==\",\"AAGdBwAAAAK/AQAAEgUAAAGbBgAAAAACBhIAANsSAAACLAwAAOoSAAACQAkAAEcTAAAAAAABnxAAAA==\"]Ao[\"AAAAAAAAAcYAAAAAAAFYBAAA\",\"\"]Bc[\"AAAAAAABSQAAAAJTAQAAVAEAAA==\",\"\"]Ag[\"AAAClQIAACIDAAA=\",\"\"]Ak[\"AAAAAAAAAnYEAADLBgAA\",\"\"]Ak[\"AAAAAAAAAnkEAADOBgAA\",\"\"]Ag[\"AAAClgIAAB4DAAA=\",\"\"]Dk[\"AAAAAcoEAAAAAhMAAAD8BgAAAtEAAADSAAAA\",\"AAABQAIAAAHKBAAAAAAAAAAAAU8PAAA=\"]Dg[\"AAAAAccEAAAAAhAAAAD5BgAAAssAAADMAAAA\",\"AAABOgIAAAHHBAAAAAAAAAHADwAA\"]Co[\"AAABFRIAAAEIBQAAAAFBAAAAAToBAAA=\",\"AAGXBwAAAQEJAAABCAUAAA==\"]Ec[\"AAAAAAABFhIAAAG1AAAAAAAAAAAAAAAAAAADbQQAAP4IAABTDwAA\",\"AAAAAaoBAAAAAAAAAUATAAA=\"]Hk[\"AAAC0gIAAOsCAAABJgUAAAABVQAAAAJzAQAAdAEAAAAAAAAAAAAAAAAABAgCAABMBQAApgYAAOMGAAA=\",\"AAABAAMAAALEAQAAJgUAAAAAAmATAABhEwAAAAACPBEAAD0RAAA=\"]Fc[\"AAAAAzYQAABKEAAAXBIAAAACahIAAGwSAAADmAEAAFgTAABZEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAcwBAAA=\"]Dc[\"AAAAAmIAAADGBAAAAg8CAAC/CAAAAQ8AAAAByAAAAA==\",\"AAAAAsYEAADVDwAA\"]Eg[\"AAAAAeEEAAAAASMAAAAAAAL4AAAA+QAAAAAAAAAAAAAAAAPfBgAALw8AADYPAAA=\",\"AAABcwIAAAHhBAAA\"]Eg[\"AAAAARsFAAAAAU0AAAACWwEAAFwBAAAAAAAAAAAAAAAAAAPhBgAAMQ8AADcPAAA=\",\"AAAB6wIAAAEbBQAA\"]Hk[\"AAAFKgIAAD0CAAA/AgAARwIAAEkCAAAB1gQAAAACHwAAAP8GAAAAAALpAAAA6gAAAA==\",\"AAADYQIAAGICAABkAgAAAtYEAACXBgAAAqUFAAAjEAAAAQcTAAABeg8AAAEPEQAA\"]Ek[\"AAAAAQoFAAAAAkMAAAAABwAAAj0BAAA+AQAA\",\"AAAB0gIAAAEKBQAAAAAAAAAAAAAAAAAAAAACuwQAAOQGAAA=\"]Bk[\"AAAAAAABNxAAAAFuAQAA\",\"AAAAAAAAAAE4EAAA\"]Fc[\"AAABjwAAAAHTBAAAAAG9DAAAAAAB5QAAAAAAAAAAAAAAAAQKBwAADgcAAAMJAAAHCQAA\",\"AAF+BwAAAALTBAAAaAUAAA==\"]Fc[\"AAAAApIAAAACBQAAAAHADAAAAS8BAAAAAAAAAAAAAAAAAAQMBwAAEAcAAAUJAAAJCQAA\",\"AAGVBwAAAAECBQAAAWsFAAA=\"]Ag[\"AAAClAIAAB0DAAA=\",\"\"]Cg[\"AAAAAUAFAAAAAAADQA8AAKYPAABMEAAA\",\"AAGnBwAAAAFABQAA\"]Dc[\"AAAAAiAFAACqBwAAAAABaQEAAA==\",\"AAAAASAFAAAAAAAAAAAAAAAAAAGwBgAA\"]Dg[\"AAAAAe0SAAAB2A8AAAAAAALrAAAACxEAAA==\",\"AAEMCQAAAa8BAAAB7RIAAAHYDwAA\"]Dg[\"AAAAAe4SAAAB2Q8AAAABRgEAAAABDREAAA==\",\"AAENCQAAAb4BAAAB7hIAAAHZDwAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATQPAAA=\",\"\"]Ac[\"\",\"AAAAAAHDEwAA\"]Ag[\"AAAClwIAAB8DAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAADSRIAAEoSAABLEgAA\"]Bc[\"\",\"AAAAAAAAAAADTBIAAE0SAABOEgAA\"]Ak[\"\",\"AAAAAW4SAAAAAAGOEwAA\"]ADc[\"AAAAAdcEAAAAAAA6MAAAAQAAAAAAFAAQAAAAvwfBDEEPiQ+MD8gPxhA/EVMRZxLUEnsT0hPfE+sT7RMPFBMUFhQaFCEUOjAAAAEAAAAAAAwAEAAAAOwAVBDCEF0SbxJwEgoTNhNJE/cTCBQKFBgUAAABOBEAAA==\",\"AAGBBwAAAAHXBAAAAAAAOjAAAAEAAAAAABQAEAAAAL8HwQxBD4kPjA/ID8YQPxFTEWcS1BJ7E9IT3xPrE+0TDxQTFBYUGhQhFDowAAABAAAAAAAJABAAAABUEMIQXRIKEzYTSRP3EwgUChQYFAAAATgRAAA=\"]ADc[\"AAAAAQ4FAAAAAAFHAQAAOjAAAAEAAAAAABQAEAAAAMAHwgxCD4oPjQ/JD8cQQBFUEWgS1RJ8E9MT4BPsE+4TEBQUFBcUGxQiFDowAAABAAAAAAALABAAAABVEMMQXhJxEnISCxM3E0oT+BMJFAsUGRQAAAE5EQAA\",\"AAGZBwAAAAEOBQAAAAAAOjAAAAEAAAAAABQAEAAAAMAHwgxCD4oPjQ/JD8cQQBFUEWgS1RJ8E9MT4BPsE+4TEBQUFBcUGxQiFDowAAABAAAAAAAJABAAAABVEMMQXhILEzcTShP4EwkUCxQZFAAAATkRAAA=\"]Ag[\"AAACcQIAAOQCAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAU0EAAA=\",\"AAAAAAAAAQgMAAA=\"]Bk[\"AAAAAAAAAAAAAAEgDAAA\",\"AAAAAAABmBMAAA==\"]Do[\"AAAAAeIEAAAAASQAAAAAAAL6AAAA+wAAAAAAAAAAAAAAAALgBgAAMA8AAA==\",\"AAAAAeIEAAA=\"]Do[\"AAAAARwFAAAAAU4AAAACXQEAAF4BAAAAAAAAAAAAAAAAAALiBgAAMg8AAA==\",\"AAAAARwFAAA=\"]Ag[\"AAACmQIAACEDAAA=\",\"\"]Fc[\"AAAAAR4FAAAAAk8AAACiAAAAAmEBAAC3DwAAAk0DAAA4EAAA\",\"AAAAAR4FAAAAAAAAAAAAAAABbQcAAAAAAAABpwUAAA==\"]Ac[\"\",\"AAAAAAFuBwAA\"]Ao[\"AAAAAAGpBAAA\",\"AAAAAAFxBwAA\"]Ag[\"AAACkgIAABkDAAA=\",\"\"]Ag[\"AAACkwIAABsDAAA=\",\"\"]Dg[\"AAAAAfIEAAAAAAAB4xIAAAAAAAHMEAAA\",\"AAAAAvIEAAA0CgAAATUKAAAAAWUQAAA=\"]Do[\"AAABzQEAAAEyBQAAAAAAAeUSAAAAAAAB0BAAAA==\",\"AAAAATIFAAABpgoAAAGnCgAAAWcQAAA=\"]Do[\"AAAAAfQEAAAAAAADPBAAAM0QAADkEgAAAAEuDAAA\",\"AAAAAvQEAAA6CgAAATkKAAAAAWYQAAA=\"]Eg[\"AAABzgEAAAE0BQAAAAAAA0AQAADREAAA5hIAAAABMAwAAA==\",\"AAAAATQFAAABqwoAAAGqCgAAAWgQAAA=\"]Cc[\"AAAAAAAAAncEAADMBgAAAAEEAQAA\",\"AAGHBwAAAAG0AQAA\"]Cc[\"AAAAAAAAA3kBAAB6BAAAzwYAAA==\",\"AAGgBwAAAAHGAQAA\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA94GAACwBwAAzgcAAA==\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATMPAAA=\",\"\"]Ao[\"AAAAAAAAAawEAAAAAQgUAAA=\",\"\"]Bk[\"AAAAAAAAAbAEAAAAAQkUAAA=\",\"AAAAAbQEAAA=\"]Eg[\"AAAAAAAAAAABEQEAAAAAAAAAAAAAAANBCQAApw8AAJYSAAA=\",\"AAGLBwAAAAS3BwAAuAcAALkHAAC6BwAA\"]Eg[\"AAAAAAAAAZQBAAAAAAAAAAAAAAAAAANCCQAAqA8AAJcSAAA=\",\"AAGkBwAAAAS7BwAAvAcAAL0HAAC+BwAA\"]Bo[\"AAAAAAABsQEAAAAAAXYMAAAAAWIEAAAAAUIEAAA=\",\"\"]Bo[\"AAAAAAABwAEAAAAAAXcMAAAAAWMEAAAAAUQEAAA=\",\"\"]Ak[\"AAAAAAABCBMAAAFvEwAA\",\"\"]Ao[\"AAAAAAABCRMAAAAAAXATAAA=\",\"\"]Fo[\"AAAAASMFAAAAAlIAAACjAAAAA2wBAABtAQAAuA8AAAFOAwAA\",\"AAAB+QIAAAEjBQAAAAAAAAJTBQAAVAUAAAAAAAAAAALCAQAAsAYAAA==\"]Dg[\"AAAAAfwEAAAAATUAAAABJwEAAA==\",\"AAAAAfwEAAAAAAAAAAAAAAAAAAAAAAHlBgAA\"]Dg[\"AAAAAcEEAAAAAgwAAAD4BgAAArsAAAC8AAAA\",\"AAABKgIAAAHBBAAAAAABxRAAAA==\"]Do[\"AAAAAfcEAAAAAjEAAACcAAAAAyABAAAhAQAAsQ8AAAFHAwAA\",\"AAAAAfcEAAAAAAAAAWUEAAA=\"]Ek[\"AAAAAdgEAAAAAAACURMAAKUTAAAD7QAAAKgQAAA2EwAA\",\"AAGCBwAAAAHYBAAAAAAAAlETAAClEwAAAagQAAA=\"]Ek[\"AAAAAQ8FAAAAAAFIAQAAAlITAACmEwAAAqkQAAA3EwAA\",\"AAGaBwAAAAEPBQAAAAAAAlITAACmEwAAAakQAAA=\"]Bo[\"AAAAAAAAAAABUwUAAAAAAAAAAALCAQAAsAYAAA==\",\"\"]Fg[\"AAAAAdkEAAAAAAAEIAkAANIPAAAwEQAAARMAAALuAAAASRMAAA==\",\"AAGDBwAAAAHZBAAAAAAABCAJAADSDwAAMBEAAAETAAA=\"]Fg[\"AAAAARAFAAAAAAFJAQAABCEJAADTDwAAMREAAAITAAABShMAAA==\",\"AAGbBwAAAAEQBQAAAAAABCEJAADTDwAAMREAAAITAAA=\"]Ag[\"\",\"AAAAAAAAAdQTAAA=\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\"]Ag[\"\",\"AAAAAAAAAVAPAAA=\"]Co[\"AAAAAf0EAAAAATYAAAACKAEAACkBAAA=\",\"AAAAAf0EAAAAAAAAARISAAA=\"]Fg[\"AAABUQIAAAHmBAAAAAEoAAAAAAG4BgAAAgEBAAACAQAA\",\"AAACegIAAJ8GAAAB5gQAAAAAAAGqBgAAAAAAAAAAAAAAAAEvDwAA\"]Gc[\"AAABugIAAALEAQAAJwUAAAABVgAAAAJ1AQAAdgEAAAG/BgAA\",\"AAACAQMAAKMGAAABJwUAAAAAAbEGAAAAAAAAAAAAAAAAAAIIAgAAMQ8AAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA6wHAADLBwAAwwgAAA==\",\"\"]Cg[\"AAABdwIAAAAAAAAAARQBAAA=\",\"AAAAAAAAAAI6EAAAPBAAAA==\"]Cg[\"AAAB8QIAAAAAAAGJAQAA\",\"AAAAAAAAAAM+EAAAQBAAAEEQAAA=\"]Bo[\"AAAAArQEAAA/BQAAAaESAAA=\",\"AAAAAj8FAABWEQAA\"]Bo[\"AAAAAAAAAcIAAAAAAAABIgwAAA==\",\"AAAAAXcTAAA=\"]Io[\"AAAAAS8FAAAAAVwAAAABhAEAAAZ1BQAAyxAAAM0QAADPEAAA0RAAANMQAAAAAAAFyhAAAMwQAADOEAAA0BAAANIQAAAAAAAAAAABIBQAAA==\",\"AAAAAS8FAAAAAARdEwAAXhMAAGATAABhEwAAAAFeBAAA\"]Co[\"AAAAAmQAAAC2BwAAAAABygAAAAJzBAAAQxEAAAFODwAA\",\"AAABJhEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAuEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhcJAAAwEAAA\",\"\"]Co[\"AAAAAfMEAAAAAAAAAhcBAAAYAQAA\",\"AAAAAfMEAAAAAAJlEAAAZhAAAA==\"]Dc[\"AAAAATMFAAAAAAKMAQAAjQEAAA==\",\"AAAAAjMFAABPEgAAAAACZxAAAGgQAAA=\"]Cc[\"AAAAAAGcAQAAAAG3AAAAAAAAAR8MAAA=\",\"AAAAAZcTAAA=\"]Ac[\"\",\"AAAB8wsAAA==\"]Ec[\"AAABcAIAAAHOBAAAAAEXAAAAAAAC3QAAAN4AAAA=\",\"AAAAAc4EAAAEEwkAAP4JAAD/CQAAAQoAAA==\"]Do[\"AAAB5QIAAAH2BAAAAAEvAAAAAh0BAAAeAQAA\",\"AAAAAfYEAAAEFAkAAFAKAABRCgAAUgoAAA==\"]Ak[\"\",\"AAAAAAACnRMAAJ4TAAA=\"]Ck[\"AAAAAsAEAAAqCQAAAb4IAAAB2RIAAAG6AAAA\",\"AAAAAsAEAADUDwAA\"]Cg[\"AAAAAU0HAAACHxAAADIQAAAAAbULAAAAAAAAAAABnhAAAA==\",\"\"]Ck[\"AAAAAU4HAAACIBAAADMQAAAAArYLAAC3CwAAAAAAAAAAAZ8QAAA=\",\"\"]Bc[\"AAAAAAAAAAAAAAAAApsTAACcEwAA\",\"\"]Fo[\"AAAAAd0EAAAAAAADZwQAACsJAAC1EwAAAvIAAACmAQAA\",\"AAGGBwAAAAHdBAAAAAAAAmcEAAArCQAAAaYBAAAAAAAAAAAAAAABcxIAAA==\"]Fo[\"AAAAARQFAAAAAAFNAQAAA2gEAAAsCQAAthMAAAGnAQAA\",\"AAGeBwAAAAEUBQAAAAAAAmgEAAAsCQAAAacBAAAAAAAAAAAAAAABdBIAAA==\"]Ck[\"AAAAAQ0FAAAAAAJDAQAARAEAAA==\",\"AAAAAQ0FAAAAAAAAAcITAAA=\"]Ec[\"AAAAASEFAAAAAAFqAQAAAAAAAAAAAAAAAAAFowEAAKsHAADKBwAAwggAAHgMAAA=\",\"AAAAASEFAAA=\"]Dg[\"AAAAAAHDEwAAAAG2AAAAAAAAAAACmxMAAJwTAAAAAAAB7BIAAA==\",\"AAABqwEAAA==\"]Ag[\"AAACmAIAACMDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAAAAAAAApsTAACcEwAA\"]Cc[\"AAAAAUEFAAAAAAAAAAAAAdIQAAA=\",\"AAABzQEAAAFBBQAA\"]Ck[\"AAAAAUIFAAAAAAACQRAAANMQAAAAATEMAAA=\",\"AAABzgEAAAFCBQAA\"]Ag[\"AAACnAIAACADAAA=\",\"\"]Dg[\"AAAAAAABLAAAAAAAARIBAAA=\",\"AAAAAAAAAAAAAAAAAAAAA48TAACQEwAAkRMAAA==\"]Ck[\"AAAAAAABXgAAAAGHAQAA\",\"AAAAAAAAAAAAAAAAAAAAApITAACTEwAA\"]Ag[\"AAACmwIAABgDAAA=\",\"\"]Do[\"AAAAAU8HAAACIRAAADQQAAAAAbgLAAABXRAAAA==\",\"AAK9AQAAjQcAAAEOCQAAAAAAAAFdEAAA\"]Ec[\"AAAAAikFAABQBwAAAiIQAAA1EAAAAAF4AQAAAV4QAAA=\",\"AAGfBwAAAcUBAAABKQUAAAAAAAFeEAAA\"]Bg[\"AAAAAAAAAAABVAUAAA==\",\"AAABvAEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAvEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhgJAAAxEAAA\",\"\"]") \ No newline at end of file diff --git a/pr/523/docs/settings.html b/pr/523/docs/settings.html index 1adf3f67d..eb1ebf9ed 100644 --- a/pr/523/docs/settings.html +++ b/pr/523/docs/settings.html @@ -1 +1 @@ -Settings

All

Rustdoc settings

Back
\ No newline at end of file +Settings

All

Rustdoc settings

Back
\ No newline at end of file diff --git a/pr/523/docs/src/noq/connection.rs.html b/pr/523/docs/src/noq/connection.rs.html index 66f4e16c8..2a9cd944a 100644 --- a/pr/523/docs/src/noq/connection.rs.html +++ b/pr/523/docs/src/noq/connection.rs.html @@ -20,7 +20,7 @@ 20use crate::{ 21 ConnectionEvent, Duration, Instant, Path, VarInt, 22 endpoint::ensure_ipv6, -23 mutex::Mutex, +23 mutex::{Mutex, MutexGuard}, 24 path::OpenPath, 25 recv_stream::RecvStream, 26 runtime::{AsyncTimer, Runtime, UdpSender}, @@ -131,7 +131,7 @@ 131 pub fn into_0rtt(mut self) -> Result<(Connection, ZeroRttAccepted), Self> { 132 // This lock borrows `self` and would normally be dropped at the end of this scope, so we'll 133 // have to release it explicitly before returning `self` by value. -134 let conn = (self.conn.as_mut().unwrap()).state.lock("into_0rtt"); +134 let conn = (self.conn.as_mut().unwrap()).lock_without_waking("into_0rtt"); 135 136 let is_ok = conn.inner.has_0rtt() || conn.inner.side().is_server(); 137 drop(conn); @@ -158,7 +158,7 @@ 158 let _ = x.await; 159 } 160 let conn = self.conn.as_ref().unwrap(); -161 let inner = conn.state.lock("handshake"); +161 let inner = conn.lock_without_waking("handshake"); 162 inner 163 .inner 164 .crypto_session() @@ -184,7 +184,7 @@ 184 /// Will panic if called after `poll` has returned `Ready`. 185 pub fn local_ip(&self) -> Option<IpAddr> { 186 let conn = self.conn.as_ref().unwrap(); -187 let inner = conn.state.lock("local_ip"); +187 let inner = conn.lock_without_waking("local_ip"); 188 189 inner 190 .inner @@ -200,354 +200,354 @@ 200 let conn_ref: &ConnectionRef = self.conn.as_ref().expect("used after yielding Ready"); 201 // TODO: another unwrap 202 conn_ref -203 .state -204 .lock("remote_address") -205 .inner -206 .network_path(PathId::ZERO) -207 .expect("path exists when connecting") -208 .remote() -209 } -210} -211 -212impl Future for Connecting { -213 type Output = Result<Connection, ConnectionError>; -214 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -215 Pin::new(&mut self.connected).poll(cx).map(|_| { -216 let conn = self.conn.take().unwrap(); -217 let inner = conn.state.lock("connecting"); -218 if inner.connected { -219 drop(inner); -220 Ok(Connection(conn)) -221 } else { -222 Err(inner -223 .error -224 .clone() -225 .expect("connected signaled without connection success or error")) -226 } -227 }) -228 } -229} -230 -231/// Future that completes when a connection is fully established -232/// -233/// For clients, the resulting value indicates if 0-RTT was accepted. For servers, the resulting -234/// value is meaningless. -235pub struct ZeroRttAccepted(oneshot::Receiver<bool>); -236 -237impl Future for ZeroRttAccepted { -238 type Output = bool; -239 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -240 Pin::new(&mut self.0).poll(cx).map(|x| x.unwrap_or(false)) -241 } -242} -243 -244/// A future that drives protocol logic for a connection -245/// -246/// This future handles the protocol logic for a single connection, routing events from the -247/// `Connection` API object to the `Endpoint` task and the related stream-related interfaces. -248/// It also keeps track of outstanding timeouts for the `Connection`. -249/// -250/// If the connection encounters an error condition, this future will yield an error. It will -251/// terminate (yielding `Ok(())`) if the connection was closed without error. Unlike other -252/// connection-related futures, this waits for the draining period to complete to ensure that -253/// packets still in flight from the peer are handled gracefully. -254#[must_use = "connection drivers must be spawned for their connections to function"] -255#[derive(Debug)] -256struct ConnectionDriver(ConnectionRef); -257 -258impl Future for ConnectionDriver { -259 type Output = Result<(), io::Error>; -260 -261 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -262 let conn = &mut *self.0.state.lock("poll"); -263 -264 let span = debug_span!("drive", id = conn.handle.0); -265 let _guard = span.enter(); -266 -267 if let Err(e) = conn.process_conn_events(&self.0.shared, cx) { -268 conn.terminate(e, &self.0.shared); -269 return Poll::Ready(Ok(())); -270 } -271 let mut keep_going = conn.drive_transmit(cx)?; -272 // If a timer expires, there might be more to transmit. When we transmit something, we -273 // might need to reset a timer. Hence, we must loop until neither happens. -274 keep_going |= conn.drive_timer(cx); -275 conn.forward_endpoint_events(); -276 conn.forward_app_events(&self.0.shared); -277 -278 if !conn.inner.is_drained() { -279 if keep_going { -280 // If the connection hasn't processed all tasks, schedule it again -281 cx.waker().wake_by_ref(); -282 } else { -283 conn.driver = Some(cx.waker().clone()); -284 } -285 return Poll::Pending; -286 } -287 if conn.error.is_none() { -288 unreachable!("drained connections always have an error"); -289 } -290 Poll::Ready(Ok(())) -291 } -292} -293 -294/// A QUIC connection. -295/// -296/// If all references to a connection (including every clone of the `Connection` handle, streams of -297/// incoming streams, and the various stream types) have been dropped, then the connection will be -298/// automatically closed with an `error_code` of 0 and an empty `reason`. You can also close the -299/// connection explicitly by calling [`Connection::close()`]. -300/// -301/// Closing the connection immediately abandons efforts to deliver data to the peer. Upon -302/// receiving CONNECTION_CLOSE the peer *may* drop any stream data not yet delivered to the -303/// application. [`Connection::close()`] describes in more detail how to gracefully close a -304/// connection without losing application data. -305/// -306/// May be cloned to obtain another handle to the same connection. -307/// -308/// [`Connection::close()`]: Connection::close -309#[derive(Debug, Clone)] -310pub struct Connection(ConnectionRef); -311 -312impl Connection { -313 /// Returns a weak reference to the inner connection struct. -314 pub fn weak_handle(&self) -> WeakConnectionHandle { -315 self.0.weak_handle() -316 } -317 -318 /// Initiate a new outgoing unidirectional stream. -319 /// -320 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a -321 /// consequence, the peer won't be notified that a stream has been opened until the stream is -322 /// actually used. -323 pub fn open_uni(&self) -> OpenUni<'_> { -324 OpenUni { -325 conn: &self.0, -326 notify: self.0.shared.stream_budget_available[Dir::Uni as usize].notified(), -327 } -328 } -329 -330 /// Initiate a new outgoing bidirectional stream. -331 /// -332 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a -333 /// consequence, the peer won't be notified that a stream has been opened until the stream is -334 /// actually used. Calling [`open_bi()`] then waiting on the [`RecvStream`] without writing -335 /// anything to [`SendStream`] will never succeed. -336 /// -337 /// [`open_bi()`]: crate::Connection::open_bi -338 /// [`SendStream`]: crate::SendStream -339 /// [`RecvStream`]: crate::RecvStream -340 pub fn open_bi(&self) -> OpenBi<'_> { -341 OpenBi { -342 conn: &self.0, -343 notify: self.0.shared.stream_budget_available[Dir::Bi as usize].notified(), -344 } -345 } -346 -347 /// Accept the next incoming uni-directional stream -348 pub fn accept_uni(&self) -> AcceptUni<'_> { -349 AcceptUni { -350 conn: &self.0, -351 notify: self.0.shared.stream_incoming[Dir::Uni as usize].notified(), -352 } -353 } -354 -355 /// Accept the next incoming bidirectional stream -356 /// -357 /// **Important Note**: The `Connection` that calls [`open_bi()`] must write to its [`SendStream`] -358 /// before the other `Connection` is able to `accept_bi()`. Calling [`open_bi()`] then -359 /// waiting on the [`RecvStream`] without writing anything to [`SendStream`] will never succeed. -360 /// -361 /// [`accept_bi()`]: crate::Connection::accept_bi -362 /// [`open_bi()`]: crate::Connection::open_bi -363 /// [`SendStream`]: crate::SendStream -364 /// [`RecvStream`]: crate::RecvStream -365 pub fn accept_bi(&self) -> AcceptBi<'_> { -366 AcceptBi { -367 conn: &self.0, -368 notify: self.0.shared.stream_incoming[Dir::Bi as usize].notified(), -369 } -370 } -371 -372 /// Receive an application datagram -373 pub fn read_datagram(&self) -> ReadDatagram<'_> { -374 ReadDatagram { -375 conn: &self.0, -376 notify: self.0.shared.datagram_received.notified(), -377 } -378 } -379 -380 /// Opens a new path if no path exists yet for the remote address. -381 /// -382 /// Otherwise behaves exactly as [`open_path`]. -383 /// -384 /// [`open_path`]: Self::open_path -385 pub fn open_path_ensure(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { -386 let mut state = self.0.state.lock("open_path"); -387 -388 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. -389 // If not, we do not support IPv6. We can not access endpoint::State from here -390 // however, but either all our paths use an IPv6 address, or all our paths use an -391 // IPv4 address. So we can use that information. -392 let ipv6 = state -393 .inner -394 .paths() -395 .iter() -396 .filter_map(|id| { -397 state -398 .inner -399 .network_path(*id) -400 .map(|addrs| addrs.remote().is_ipv6()) -401 .ok() -402 }) -403 .next() -404 .unwrap_or_default(); -405 if addr.is_ipv6() && !ipv6 { -406 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); -407 } -408 let addr = if ipv6 { -409 SocketAddr::V6(ensure_ipv6(addr)) -410 } else { -411 addr -412 }; -413 -414 let now = state.runtime.now(); -415 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. -416 // However, changing that would mean changing the API. -417 let addrs = FourTuple::from_remote(addr); -418 let open_res = state.inner.open_path_ensure(addrs, initial_status, now); -419 state.wake(); -420 match open_res { -421 Ok((path_id, existed)) if existed => { -422 let recv = state.open_path.get(&path_id).map(|tx| tx.subscribe()); -423 drop(state); -424 match recv { -425 Some(recv) => OpenPath::new(path_id, recv, self.0.clone()), -426 None => OpenPath::ready(path_id, self.0.clone()), -427 } -428 } -429 Ok((path_id, _)) => { -430 let (tx, rx) = watch::channel(Ok(())); -431 state.open_path.insert(path_id, tx); -432 drop(state); -433 OpenPath::new(path_id, rx, self.0.clone()) -434 } -435 Err(err) => OpenPath::rejected(err), -436 } -437 } -438 -439 /// Opens an additional path if the multipath extension is negotiated. -440 /// -441 /// The returned future completes once the path is either fully opened and ready to -442 /// carry application data, or if there was an error. -443 /// -444 /// Dropping the returned future does not cancel the opening of the path, the -445 /// [`PathEvent::Opened`] event will still be emitted from [`Self::path_events`] if the -446 /// path opens. The [`PathId`] for the events can be extracted from -447 /// [`OpenPath::path_id`]. -448 /// -449 /// Failure to open a path can either occur immediately, before polling the returned -450 /// future, or at a later time. If the failure is immediate [`OpenPath::path_id`] will -451 /// return `None` and the future will be ready immediately. If the failure happens -452 /// later, a [`PathEvent`] will be emitted. -453 pub fn open_path(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { -454 let mut state = self.0.state.lock("open_path"); -455 -456 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. -457 // If not, we do not support IPv6. We can not access endpoint::State from here -458 // however, but either all our paths use an IPv6 address, or all our paths use an -459 // IPv4 address. So we can use that information. -460 let ipv6 = state -461 .inner -462 .paths() -463 .iter() -464 .filter_map(|id| { -465 state -466 .inner -467 .network_path(*id) -468 .map(|addrs| addrs.remote().is_ipv6()) -469 .ok() -470 }) -471 .next() -472 .unwrap_or_default(); -473 if addr.is_ipv6() && !ipv6 { -474 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); -475 } -476 let addr = if ipv6 { -477 SocketAddr::V6(ensure_ipv6(addr)) -478 } else { -479 addr -480 }; -481 -482 let (on_open_path_send, on_open_path_recv) = watch::channel(Ok(())); -483 let now = state.runtime.now(); -484 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. -485 // However, changing that would mean changing the API. -486 let addrs = FourTuple::from_remote(addr); -487 let open_res = state.inner.open_path(addrs, initial_status, now); -488 state.wake(); -489 match open_res { -490 Ok(path_id) => { -491 state.open_path.insert(path_id, on_open_path_send); -492 drop(state); -493 OpenPath::new(path_id, on_open_path_recv, self.0.clone()) -494 } -495 Err(err) => OpenPath::rejected(err), -496 } -497 } -498 -499 /// Returns the [`Path`] structure of an open path -500 pub fn path(&self, id: PathId) -> Option<Path> { -501 Path::new(&self.0, id) -502 } -503 -504 /// A stream of [`PathEvent`]s for all paths in this connection. +203 .lock_without_waking("remote_address") +204 .inner +205 .network_path(PathId::ZERO) +206 .expect("path exists when connecting") +207 .remote() +208 } +209} +210 +211impl Future for Connecting { +212 type Output = Result<Connection, ConnectionError>; +213 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +214 Pin::new(&mut self.connected).poll(cx).map(|_| { +215 let conn = self.conn.take().unwrap(); +216 let inner = conn.lock_without_waking("connecting"); +217 if inner.connected { +218 drop(inner); +219 Ok(Connection(conn)) +220 } else { +221 Err(inner +222 .error +223 .clone() +224 .expect("connected signaled without connection success or error")) +225 } +226 }) +227 } +228} +229 +230/// Future that completes when a connection is fully established +231/// +232/// For clients, the resulting value indicates if 0-RTT was accepted. For servers, the resulting +233/// value is meaningless. +234pub struct ZeroRttAccepted(oneshot::Receiver<bool>); +235 +236impl Future for ZeroRttAccepted { +237 type Output = bool; +238 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +239 Pin::new(&mut self.0).poll(cx).map(|x| x.unwrap_or(false)) +240 } +241} +242 +243/// A future that drives protocol logic for a connection +244/// +245/// This future handles the protocol logic for a single connection, routing events from the +246/// `Connection` API object to the `Endpoint` task and the related stream-related interfaces. +247/// It also keeps track of outstanding timeouts for the `Connection`. +248/// +249/// If the connection encounters an error condition, this future will yield an error. It will +250/// terminate (yielding `Ok(())`) if the connection was closed without error. Unlike other +251/// connection-related futures, this waits for the draining period to complete to ensure that +252/// packets still in flight from the peer are handled gracefully. +253#[must_use = "connection drivers must be spawned for their connections to function"] +254#[derive(Debug)] +255struct ConnectionDriver(ConnectionRef); +256 +257impl Future for ConnectionDriver { +258 type Output = Result<(), io::Error>; +259 +260 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +261 let conn = &mut *self.0.lock_without_waking("poll"); +262 +263 let span = debug_span!("drive", id = conn.handle.0); +264 let _guard = span.enter(); +265 +266 if let Err(e) = conn.process_conn_events(&self.0.shared, cx) { +267 conn.terminate(e, &self.0.shared); +268 return Poll::Ready(Ok(())); +269 } +270 let mut keep_going = conn.drive_transmit(cx)?; +271 // If a timer expires, there might be more to transmit. When we transmit something, we +272 // might need to reset a timer. Hence, we must loop until neither happens. +273 keep_going |= conn.drive_timer(cx); +274 conn.forward_endpoint_events(); +275 conn.forward_app_events(&self.0.shared); +276 +277 if !conn.inner.is_drained() { +278 if keep_going { +279 // If the connection hasn't processed all tasks, schedule it again +280 cx.waker().wake_by_ref(); +281 } else { +282 conn.driver = Some(cx.waker().clone()); +283 } +284 return Poll::Pending; +285 } +286 if conn.error.is_none() { +287 unreachable!("drained connections always have an error"); +288 } +289 Poll::Ready(Ok(())) +290 } +291} +292 +293/// A QUIC connection. +294/// +295/// If all references to a connection (including every clone of the `Connection` handle, streams of +296/// incoming streams, and the various stream types) have been dropped, then the connection will be +297/// automatically closed with an `error_code` of 0 and an empty `reason`. You can also close the +298/// connection explicitly by calling [`Connection::close()`]. +299/// +300/// Closing the connection immediately abandons efforts to deliver data to the peer. Upon +301/// receiving CONNECTION_CLOSE the peer *may* drop any stream data not yet delivered to the +302/// application. [`Connection::close()`] describes in more detail how to gracefully close a +303/// connection without losing application data. +304/// +305/// May be cloned to obtain another handle to the same connection. +306/// +307/// [`Connection::close()`]: Connection::close +308#[derive(Debug, Clone)] +309pub struct Connection(ConnectionRef); +310 +311impl Connection { +312 /// Returns a weak reference to the inner connection struct. +313 pub fn weak_handle(&self) -> WeakConnectionHandle { +314 self.0.weak_handle() +315 } +316 +317 /// Initiate a new outgoing unidirectional stream. +318 /// +319 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a +320 /// consequence, the peer won't be notified that a stream has been opened until the stream is +321 /// actually used. +322 pub fn open_uni(&self) -> OpenUni<'_> { +323 OpenUni { +324 conn: &self.0, +325 notify: self.0.shared.stream_budget_available[Dir::Uni as usize].notified(), +326 } +327 } +328 +329 /// Initiate a new outgoing bidirectional stream. +330 /// +331 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a +332 /// consequence, the peer won't be notified that a stream has been opened until the stream is +333 /// actually used. Calling [`open_bi()`] then waiting on the [`RecvStream`] without writing +334 /// anything to [`SendStream`] will never succeed. +335 /// +336 /// [`open_bi()`]: crate::Connection::open_bi +337 /// [`SendStream`]: crate::SendStream +338 /// [`RecvStream`]: crate::RecvStream +339 pub fn open_bi(&self) -> OpenBi<'_> { +340 OpenBi { +341 conn: &self.0, +342 notify: self.0.shared.stream_budget_available[Dir::Bi as usize].notified(), +343 } +344 } +345 +346 /// Accept the next incoming uni-directional stream +347 pub fn accept_uni(&self) -> AcceptUni<'_> { +348 AcceptUni { +349 conn: &self.0, +350 notify: self.0.shared.stream_incoming[Dir::Uni as usize].notified(), +351 } +352 } +353 +354 /// Accept the next incoming bidirectional stream +355 /// +356 /// **Important Note**: The `Connection` that calls [`open_bi()`] must write to its [`SendStream`] +357 /// before the other `Connection` is able to `accept_bi()`. Calling [`open_bi()`] then +358 /// waiting on the [`RecvStream`] without writing anything to [`SendStream`] will never succeed. +359 /// +360 /// [`accept_bi()`]: crate::Connection::accept_bi +361 /// [`open_bi()`]: crate::Connection::open_bi +362 /// [`SendStream`]: crate::SendStream +363 /// [`RecvStream`]: crate::RecvStream +364 pub fn accept_bi(&self) -> AcceptBi<'_> { +365 AcceptBi { +366 conn: &self.0, +367 notify: self.0.shared.stream_incoming[Dir::Bi as usize].notified(), +368 } +369 } +370 +371 /// Receive an application datagram +372 pub fn read_datagram(&self) -> ReadDatagram<'_> { +373 ReadDatagram { +374 conn: &self.0, +375 notify: self.0.shared.datagram_received.notified(), +376 } +377 } +378 +379 /// Opens a new path if no path exists yet for the remote address. +380 /// +381 /// Otherwise behaves exactly as [`open_path`]. +382 /// +383 /// [`open_path`]: Self::open_path +384 pub fn open_path_ensure(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { +385 let mut state = self.0.lock_and_wake("open_path"); +386 +387 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. +388 // If not, we do not support IPv6. We can not access endpoint::State from here +389 // however, but either all our paths use an IPv6 address, or all our paths use an +390 // IPv4 address. So we can use that information. +391 let ipv6 = state +392 .inner +393 .paths() +394 .iter() +395 .filter_map(|id| { +396 state +397 .inner +398 .network_path(*id) +399 .map(|addrs| addrs.remote().is_ipv6()) +400 .ok() +401 }) +402 .next() +403 .unwrap_or_default(); +404 if addr.is_ipv6() && !ipv6 { +405 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); +406 } +407 let addr = if ipv6 { +408 SocketAddr::V6(ensure_ipv6(addr)) +409 } else { +410 addr +411 }; +412 +413 let now = state.runtime.now(); +414 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. +415 // However, changing that would mean changing the API. +416 let addrs = FourTuple::from_remote(addr); +417 let open_res = state.inner.open_path_ensure(addrs, initial_status, now); +418 match open_res { +419 Ok((path_id, existed)) if existed => { +420 let recv = state.open_path.get(&path_id).map(|tx| tx.subscribe()); +421 drop(state); +422 match recv { +423 Some(recv) => OpenPath::new(path_id, recv, self.0.clone()), +424 None => OpenPath::ready(path_id, self.0.clone()), +425 } +426 } +427 Ok((path_id, _)) => { +428 let (tx, rx) = watch::channel(Ok(())); +429 state.open_path.insert(path_id, tx); +430 drop(state); +431 OpenPath::new(path_id, rx, self.0.clone()) +432 } +433 Err(err) => OpenPath::rejected(err), +434 } +435 } +436 +437 /// Opens an additional path if the multipath extension is negotiated. +438 /// +439 /// The returned future completes once the path is either fully opened and ready to +440 /// carry application data, or if there was an error. +441 /// +442 /// Dropping the returned future does not cancel the opening of the path, the +443 /// [`PathEvent::Opened`] event will still be emitted from [`Self::path_events`] if the +444 /// path opens. The [`PathId`] for the events can be extracted from +445 /// [`OpenPath::path_id`]. +446 /// +447 /// Failure to open a path can either occur immediately, before polling the returned +448 /// future, or at a later time. If the failure is immediate [`OpenPath::path_id`] will +449 /// return `None` and the future will be ready immediately. If the failure happens +450 /// later, a [`PathEvent`] will be emitted. +451 pub fn open_path(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { +452 let mut state = self.0.lock_and_wake("open_path"); +453 +454 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. +455 // If not, we do not support IPv6. We can not access endpoint::State from here +456 // however, but either all our paths use an IPv6 address, or all our paths use an +457 // IPv4 address. So we can use that information. +458 let ipv6 = state +459 .inner +460 .paths() +461 .iter() +462 .filter_map(|id| { +463 state +464 .inner +465 .network_path(*id) +466 .map(|addrs| addrs.remote().is_ipv6()) +467 .ok() +468 }) +469 .next() +470 .unwrap_or_default(); +471 if addr.is_ipv6() && !ipv6 { +472 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); +473 } +474 let addr = if ipv6 { +475 SocketAddr::V6(ensure_ipv6(addr)) +476 } else { +477 addr +478 }; +479 +480 let (on_open_path_send, on_open_path_recv) = watch::channel(Ok(())); +481 let now = state.runtime.now(); +482 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. +483 // However, changing that would mean changing the API. +484 let addrs = FourTuple::from_remote(addr); +485 let open_res = state.inner.open_path(addrs, initial_status, now); +486 match open_res { +487 Ok(path_id) => { +488 state.open_path.insert(path_id, on_open_path_send); +489 drop(state); +490 OpenPath::new(path_id, on_open_path_recv, self.0.clone()) +491 } +492 Err(err) => OpenPath::rejected(err), +493 } +494 } +495 +496 /// Returns the [`Path`] structure of an open path +497 pub fn path(&self, id: PathId) -> Option<Path> { +498 Path::new(&self.0, id) +499 } +500 +501 /// A stream of [`PathEvent`]s for all paths in this connection. +502 /// +503 /// The stream will yield a [`PathEvent`] whenever there is a change in the state of any path in this connection. +504 /// The events need to be processed immediately, since there isn't an unbounded buffer for them. 505 /// -506 /// The stream will yield a [`PathEvent`] whenever there is a change in the state of any path in this connection. -507 /// The events need to be processed immediately, since there isn't an unbounded buffer for them. -508 /// -509 /// If processing of events lags behind too much, you will get an error of type [`crate::Lagged`] indicating -510 /// how many events were lost. The stream continues after a lag, delivering the oldest retained message next. -511 pub fn path_events(&self) -> crate::PathEvents { -512 crate::PathEvents::new(self.0.state.lock("path_events").path_events.subscribe()) -513 } -514 -515 /// A stream of NAT traversal updates for this connection. -516 /// -517 /// The events need to be processed immediately, since there isn't an unbounded buffer for them. +506 /// If processing of events lags behind too much, you will get an error of type [`crate::Lagged`] indicating +507 /// how many events were lost. The stream continues after a lag, delivering the oldest retained message next. +508 pub fn path_events(&self) -> crate::PathEvents { +509 crate::PathEvents::new( +510 self.0 +511 .lock_without_waking("path_events") +512 .path_events +513 .subscribe(), +514 ) +515 } +516 +517 /// A stream of NAT traversal updates for this connection. 518 /// -519 /// If processing of events lags behind too much, you will get an error of type [`crate::Lagged`] indicating -520 /// how many events were lost. The stream continues after a lag, delivering the oldest retained message next. -521 pub fn nat_traversal_updates(&self) -> crate::NatTraversalUpdates { -522 crate::NatTraversalUpdates::new( -523 self.0 -524 .state -525 .lock("nat_traversal_updates") -526 .nat_traversal_updates -527 .subscribe(), -528 ) -529 } -530 -531 /// Wait for the connection to be closed for any reason -532 /// -533 /// Despite the return type's name, closed connections are often not an error condition at the -534 /// application layer. Cases that might be routine include [`ConnectionError::LocallyClosed`] -535 /// and [`ConnectionError::ApplicationClosed`]. -536 pub async fn closed(&self) -> ConnectionError { -537 { -538 let conn = self.0.state.lock("closed"); -539 if let Some(error) = conn.error.as_ref() { -540 return error.clone(); -541 } -542 // Construct the future while the lock is held to ensure we can't miss a wakeup if -543 // the `Notify` is signaled immediately after we release the lock. `await` it after -544 // the lock guard is out of scope. -545 self.0.shared.closed.notified() -546 } -547 .await; -548 self.0 -549 .state -550 .lock("closed") +519 /// The events need to be processed immediately, since there isn't an unbounded buffer for them. +520 /// +521 /// If processing of events lags behind too much, you will get an error of type [`crate::Lagged`] indicating +522 /// how many events were lost. The stream continues after a lag, delivering the oldest retained message next. +523 pub fn nat_traversal_updates(&self) -> crate::NatTraversalUpdates { +524 crate::NatTraversalUpdates::new( +525 self.0 +526 .lock_without_waking("nat_traversal_updates") +527 .nat_traversal_updates +528 .subscribe(), +529 ) +530 } +531 +532 /// Wait for the connection to be closed for any reason +533 /// +534 /// Despite the return type's name, closed connections are often not an error condition at the +535 /// application layer. Cases that might be routine include [`ConnectionError::LocallyClosed`] +536 /// and [`ConnectionError::ApplicationClosed`]. +537 pub async fn closed(&self) -> ConnectionError { +538 { +539 let conn = self.0.lock_without_waking("closed"); +540 if let Some(error) = conn.error.as_ref() { +541 return error.clone(); +542 } +543 // Construct the future while the lock is held to ensure we can't miss a wakeup if +544 // the `Notify` is signaled immediately after we release the lock. `await` it after +545 // the lock guard is out of scope. +546 self.0.shared.closed.notified() +547 } +548 .await; +549 self.0 +550 .lock_without_waking("closed") 551 .error 552 .as_ref() 553 .expect("closed without an error") @@ -565,7 +565,7 @@ 565 /// if there are futures returned from this function still being awaited. 566 pub fn on_closed(&self) -> OnClosed { 567 let (tx, rx) = oneshot::channel(); -568 let mut state = self.0.state.lock("on_closed"); +568 let mut state = self.0.lock_without_waking("on_closed"); 569 if let Some(error) = &state.error { 570 // Connection already closed, send immediately 571 let _ = tx.send((error.clone(), state.inner.stats())); @@ -583,7 +583,7 @@ 583 /// 584 /// Returns `None` if the connection is still open. 585 pub fn close_reason(&self) -> Option<ConnectionError> { -586 self.0.state.lock("close_reason").error.clone() +586 self.0.lock_without_waking("close_reason").error.clone() 587 } 588 589 /// Close the connection immediately. @@ -618,8 +618,8 @@ 618 /// [`Endpoint::wait_idle()`]: crate::Endpoint::wait_idle 619 /// [`close()`]: Connection::close 620 pub fn close(&self, error_code: VarInt, reason: &[u8]) { -621 let conn = &mut *self.0.state.lock("close"); -622 conn.close(error_code, Bytes::copy_from_slice(reason), &self.0.shared); +621 let conn = &mut *self.0.lock_without_waking("close"); // conn.close self-wakes +622 conn.close(error_code, Bytes::copy_from_slice(reason), &self.0.shared); 623 } 624 625 /// Wait for the handshake to be confirmed. @@ -634,7 +634,7 @@ 634 /// or, if client authentication is not required, accepted our lack of authentication. 635 pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError> { 636 { -637 let conn = self.0.state.lock("handshake_confirmed"); +637 let conn = self.0.lock_without_waking("handshake_confirmed"); 638 if let Some(error) = conn.error.as_ref() { 639 return Err(error.clone()); 640 } @@ -647,85 +647,85 @@ 647 self.0.shared.handshake_confirmed.notified() 648 } 649 .await; -650 if let Some(error) = self.0.state.lock("handshake_confirmed").error.as_ref() { -651 Err(error.clone()) -652 } else { -653 Ok(()) -654 } -655 } -656 -657 /// Transmit `data` as an unreliable, unordered application datagram -658 /// -659 /// Application datagrams are a low-level primitive. They may be lost or delivered out of order, -660 /// and `data` must both fit inside a single QUIC packet and be smaller than the maximum -661 /// dictated by the peer. -662 /// -663 /// Previously queued datagrams which are still unsent may be discarded to make space for this -664 /// datagram, in order of oldest to newest. -665 pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError> { -666 let conn = &mut *self.0.state.lock("send_datagram"); -667 if let Some(ref x) = conn.error { -668 return Err(SendDatagramError::ConnectionLost(x.clone())); -669 } -670 use proto::SendDatagramError::*; -671 match conn.inner.datagrams().send(data, true) { -672 Ok(()) => { -673 conn.wake(); -674 Ok(()) -675 } -676 Err(e) => Err(match e { -677 Blocked(..) => unreachable!(), -678 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, -679 Disabled => SendDatagramError::Disabled, -680 TooLarge => SendDatagramError::TooLarge, -681 }), -682 } -683 } -684 -685 /// Transmit `data` as an unreliable, unordered application datagram -686 /// -687 /// Unlike [`send_datagram()`], this method will wait for buffer space during congestion -688 /// conditions, which effectively prioritizes old datagrams over new datagrams. -689 /// -690 /// See [`send_datagram()`] for details. +650 if let Some(error) = self +651 .0 +652 .lock_without_waking("handshake_confirmed") +653 .error +654 .as_ref() +655 { +656 Err(error.clone()) +657 } else { +658 Ok(()) +659 } +660 } +661 +662 /// Transmit `data` as an unreliable, unordered application datagram +663 /// +664 /// Application datagrams are a low-level primitive. They may be lost or delivered out of order, +665 /// and `data` must both fit inside a single QUIC packet and be smaller than the maximum +666 /// dictated by the peer. +667 /// +668 /// Previously queued datagrams which are still unsent may be discarded to make space for this +669 /// datagram, in order of oldest to newest. +670 pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError> { +671 let conn = &mut *self.0.lock_and_wake("send_datagram"); +672 if let Some(ref x) = conn.error { +673 return Err(SendDatagramError::ConnectionLost(x.clone())); +674 } +675 use proto::SendDatagramError::*; +676 match conn.inner.datagrams().send(data, true) { +677 Ok(()) => Ok(()), +678 Err(e) => Err(match e { +679 Blocked(..) => unreachable!(), +680 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, +681 Disabled => SendDatagramError::Disabled, +682 TooLarge => SendDatagramError::TooLarge, +683 }), +684 } +685 } +686 +687 /// Transmit `data` as an unreliable, unordered application datagram +688 /// +689 /// Unlike [`send_datagram()`], this method will wait for buffer space during congestion +690 /// conditions, which effectively prioritizes old datagrams over new datagrams. 691 /// -692 /// [`send_datagram()`]: Connection::send_datagram -693 pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_> { -694 SendDatagram { -695 conn: &self.0, -696 data: Some(data), -697 notify: self.0.shared.datagrams_unblocked.notified(), -698 } -699 } -700 -701 /// Compute the maximum size of datagrams that may be passed to [`send_datagram()`]. -702 /// -703 /// Returns `None` if datagrams are unsupported by the peer or disabled locally. +692 /// See [`send_datagram()`] for details. +693 /// +694 /// [`send_datagram()`]: Connection::send_datagram +695 pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_> { +696 SendDatagram { +697 conn: &self.0, +698 data: Some(data), +699 notify: self.0.shared.datagrams_unblocked.notified(), +700 } +701 } +702 +703 /// Compute the maximum size of datagrams that may be passed to [`send_datagram()`]. 704 /// -705 /// This may change over the lifetime of a connection according to variation in the path MTU -706 /// estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer's -707 /// limit is large this is guaranteed to be a little over a kilobyte at minimum. -708 /// -709 /// Not necessarily the maximum size of received datagrams. +705 /// Returns `None` if datagrams are unsupported by the peer or disabled locally. +706 /// +707 /// This may change over the lifetime of a connection according to variation in the path MTU +708 /// estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer's +709 /// limit is large this is guaranteed to be a little over a kilobyte at minimum. 710 /// -711 /// [`send_datagram()`]: Connection::send_datagram -712 pub fn max_datagram_size(&self) -> Option<usize> { -713 self.0 -714 .state -715 .lock("max_datagram_size") -716 .inner -717 .datagrams() -718 .max_size() -719 } -720 -721 /// Bytes available in the outgoing datagram buffer -722 /// -723 /// When greater than zero, calling [`send_datagram()`](Self::send_datagram) with a datagram of -724 /// at most this size is guaranteed not to cause older datagrams to be dropped. -725 pub fn datagram_send_buffer_space(&self) -> usize { -726 self.0 -727 .state -728 .lock("datagram_send_buffer_space") +711 /// Not necessarily the maximum size of received datagrams. +712 /// +713 /// [`send_datagram()`]: Connection::send_datagram +714 pub fn max_datagram_size(&self) -> Option<usize> { +715 self.0 +716 .lock_without_waking("max_datagram_size") +717 .inner +718 .datagrams() +719 .max_size() +720 } +721 +722 /// Bytes available in the outgoing datagram buffer +723 /// +724 /// When greater than zero, calling [`send_datagram()`](Self::send_datagram) with a datagram of +725 /// at most this size is guaranteed not to cause older datagrams to be dropped. +726 pub fn datagram_send_buffer_space(&self) -> usize { +727 self.0 +728 .lock_without_waking("datagram_send_buffer_space") 729 .inner 730 .datagrams() 731 .send_buffer_space() @@ -733,7 +733,7 @@ 733 734 /// The side of the connection (client or server) 735 pub fn side(&self) -> Side { -736 self.0.state.lock("side").inner.side() +736 self.0.lock_without_waking("side").inner.side() 737 } 738 739 /// The peer's UDP address @@ -748,7 +748,7 @@ 748 /// [`multipath`]: crate::TransportConfig::max_concurrent_multipath_paths 749 pub fn remote_address(&self) -> SocketAddr { 750 // TODO: an unwrap again -751 let state = self.0.state.lock("remote_address"); +751 let state = self.0.lock_without_waking("remote_address"); 752 state 753 .inner 754 .paths() @@ -770,7 +770,7 @@ 770 /// supported platforms when using [`noq_udp`](udp) for I/O, which is the default. 771 pub fn local_ip(&self) -> Option<IpAddr> { 772 // TODO: an unwrap again -773 let state = self.0.state.lock("remote_address"); +773 let state = self.0.lock_without_waking("remote_address"); 774 state 775 .inner 776 .paths() @@ -783,1068 +783,1098 @@ 783 784 /// Current best estimate of this connection's latency (round-trip-time) 785 pub fn rtt(&self, path_id: PathId) -> Option<Duration> { -786 self.0.state.lock("rtt").inner.rtt(path_id) +786 self.0.lock_without_waking("rtt").inner.rtt(path_id) 787 } 788 789 /// Returns connection statistics 790 pub fn stats(&self) -> ConnectionStats { -791 self.0.state.lock("stats").inner.stats() +791 self.0.lock_without_waking("stats").inner.stats() 792 } 793 794 /// Returns path statistics 795 pub fn path_stats(&self, path_id: PathId) -> Option<PathStats> { -796 self.0.state.lock("path_stats").path_stats(path_id) +796 self.0.lock_without_waking("path_stats").path_stats(path_id) 797 } 798 799 /// Current state of the congestion control algorithm, for debugging purposes 800 pub fn congestion_state(&self, path_id: PathId) -> Option<Box<dyn Controller>> { 801 self.0 -802 .state -803 .lock("congestion_state") -804 .inner -805 .congestion_state(path_id) -806 .map(|c| c.clone_box()) -807 } -808 -809 /// Parameters negotiated during the handshake -810 /// -811 /// Guaranteed to return `Some` on fully established connections or after -812 /// [`Connecting::handshake_data()`] succeeds. See that method's documentations for details on -813 /// the returned value. -814 /// -815 /// [`Connection::handshake_data()`]: crate::Connecting::handshake_data -816 pub fn handshake_data(&self) -> Option<Box<dyn Any>> { -817 self.0 -818 .state -819 .lock("handshake_data") -820 .inner -821 .crypto_session() -822 .handshake_data() -823 } -824 -825 /// Cryptographic identity of the peer -826 /// -827 /// The dynamic type returned is determined by the configured -828 /// [`Session`](proto::crypto::Session). For the default `rustls` session, the return value can -829 /// be [`downcast`](Box::downcast) to a <code>Vec<[rustls::pki_types::CertificateDer]></code> -830 pub fn peer_identity(&self) -> Option<Box<dyn Any>> { -831 self.0 -832 .state -833 .lock("peer_identity") -834 .inner -835 .crypto_session() -836 .peer_identity() -837 } -838 -839 /// A stable identifier for this connection -840 /// -841 /// Peer addresses and connection IDs can change, but this value will remain -842 /// fixed for the lifetime of the connection. -843 pub fn stable_id(&self) -> usize { -844 self.0.stable_id() -845 } -846 -847 /// Update traffic keys spontaneously -848 /// -849 /// This primarily exists for testing purposes. -850 pub fn force_key_update(&self) { -851 self.0 -852 .state -853 .lock("force_key_update") -854 .inner -855 .force_key_update() -856 } -857 -858 /// Derive keying material from this connection's TLS session secrets. -859 /// -860 /// When both peers call this method with the same `label` and `context` -861 /// arguments and `output` buffers of equal length, they will get the -862 /// same sequence of bytes in `output`. These bytes are cryptographically -863 /// strong and pseudorandom, and are suitable for use as keying material. -864 /// -865 /// See [RFC5705](https://tools.ietf.org/html/rfc5705) for more information. -866 pub fn export_keying_material( -867 &self, -868 output: &mut [u8], -869 label: &[u8], -870 context: &[u8], -871 ) -> Result<(), proto::crypto::ExportKeyingMaterialError> { -872 self.0 -873 .state -874 .lock("export_keying_material") -875 .inner -876 .crypto_session() -877 .export_keying_material(output, label, context) -878 } -879 -880 /// Modify the number of remotely initiated unidirectional streams that may be concurrently open -881 /// -882 /// No streams may be opened by the peer unless fewer than `count` are already open. Large -883 /// `count`s increase both minimum and worst-case memory consumption. -884 pub fn set_max_concurrent_uni_streams(&self, count: VarInt) { -885 let mut conn = self.0.state.lock("set_max_concurrent_uni_streams"); -886 conn.inner.set_max_concurrent_streams(Dir::Uni, count); -887 // May need to send MAX_STREAMS to make progress -888 conn.wake(); -889 } -890 -891 /// See [`proto::TransportConfig::send_window()`] -892 pub fn set_send_window(&self, send_window: u64) { -893 let mut conn = self.0.state.lock("set_send_window"); -894 conn.inner.set_send_window(send_window); -895 conn.wake(); -896 } -897 -898 /// See [`proto::TransportConfig::receive_window()`] -899 pub fn set_receive_window(&self, receive_window: VarInt) { -900 let mut conn = self.0.state.lock("set_receive_window"); -901 conn.inner.set_receive_window(receive_window); -902 conn.wake(); +802 .lock_without_waking("congestion_state") +803 .inner +804 .congestion_state(path_id) +805 .map(|c| c.clone_box()) +806 } +807 +808 /// Parameters negotiated during the handshake +809 /// +810 /// Guaranteed to return `Some` on fully established connections or after +811 /// [`Connecting::handshake_data()`] succeeds. See that method's documentations for details on +812 /// the returned value. +813 /// +814 /// [`Connection::handshake_data()`]: crate::Connecting::handshake_data +815 pub fn handshake_data(&self) -> Option<Box<dyn Any>> { +816 self.0 +817 .lock_without_waking("handshake_data") +818 .inner +819 .crypto_session() +820 .handshake_data() +821 } +822 +823 /// Cryptographic identity of the peer +824 /// +825 /// The dynamic type returned is determined by the configured +826 /// [`Session`](proto::crypto::Session). For the default `rustls` session, the return value can +827 /// be [`downcast`](Box::downcast) to a <code>Vec<[rustls::pki_types::CertificateDer]></code> +828 pub fn peer_identity(&self) -> Option<Box<dyn Any>> { +829 self.0 +830 .lock_without_waking("peer_identity") +831 .inner +832 .crypto_session() +833 .peer_identity() +834 } +835 +836 /// A stable identifier for this connection +837 /// +838 /// Peer addresses and connection IDs can change, but this value will remain +839 /// fixed for the lifetime of the connection. +840 pub fn stable_id(&self) -> usize { +841 self.0.stable_id() +842 } +843 +844 /// Update traffic keys spontaneously +845 /// +846 /// This primarily exists for testing purposes. +847 pub fn force_key_update(&self) { +848 self.0 +849 .lock_and_wake("force_key_update") +850 .inner +851 .force_key_update() +852 } +853 +854 /// Derive keying material from this connection's TLS session secrets. +855 /// +856 /// When both peers call this method with the same `label` and `context` +857 /// arguments and `output` buffers of equal length, they will get the +858 /// same sequence of bytes in `output`. These bytes are cryptographically +859 /// strong and pseudorandom, and are suitable for use as keying material. +860 /// +861 /// See [RFC5705](https://tools.ietf.org/html/rfc5705) for more information. +862 pub fn export_keying_material( +863 &self, +864 output: &mut [u8], +865 label: &[u8], +866 context: &[u8], +867 ) -> Result<(), proto::crypto::ExportKeyingMaterialError> { +868 self.0 +869 .lock_without_waking("export_keying_material") +870 .inner +871 .crypto_session() +872 .export_keying_material(output, label, context) +873 } +874 +875 /// Modify the number of remotely initiated unidirectional streams that may be concurrently open +876 /// +877 /// No streams may be opened by the peer unless fewer than `count` are already open. Large +878 /// `count`s increase both minimum and worst-case memory consumption. +879 pub fn set_max_concurrent_uni_streams(&self, count: VarInt) { +880 let mut conn = self.0.lock_and_wake("set_max_concurrent_uni_streams"); +881 conn.inner.set_max_concurrent_streams(Dir::Uni, count); +882 } +883 +884 /// See [`proto::TransportConfig::send_window()`] +885 pub fn set_send_window(&self, send_window: u64) { +886 let mut conn = self.0.lock_and_wake("set_send_window"); +887 conn.inner.set_send_window(send_window); +888 } +889 +890 /// See [`proto::TransportConfig::receive_window()`] +891 pub fn set_receive_window(&self, receive_window: VarInt) { +892 let mut conn = self.0.lock_and_wake("set_receive_window"); +893 conn.inner.set_receive_window(receive_window); +894 } +895 +896 /// Modify the number of remotely initiated bidirectional streams that may be concurrently open +897 /// +898 /// No streams may be opened by the peer unless fewer than `count` are already open. Large +899 /// `count`s increase both minimum and worst-case memory consumption. +900 pub fn set_max_concurrent_bi_streams(&self, count: VarInt) { +901 let mut conn = self.0.lock_and_wake("set_max_concurrent_bi_streams"); +902 conn.inner.set_max_concurrent_streams(Dir::Bi, count); 903 } 904 -905 /// Modify the number of remotely initiated bidirectional streams that may be concurrently open -906 /// -907 /// No streams may be opened by the peer unless fewer than `count` are already open. Large -908 /// `count`s increase both minimum and worst-case memory consumption. -909 pub fn set_max_concurrent_bi_streams(&self, count: VarInt) { -910 let mut conn = self.0.state.lock("set_max_concurrent_bi_streams"); -911 conn.inner.set_max_concurrent_streams(Dir::Bi, count); -912 // May need to send MAX_STREAMS to make progress -913 conn.wake(); -914 } -915 -916 /// Track changes on our external address as reported by the peer. -917 pub fn observed_external_addr(&self) -> crate::ObservedExternalAddr { -918 let conn = self.0.state.lock("external_addr"); -919 crate::ObservedExternalAddr::new(conn.observed_external_addr.subscribe()) -920 } -921 -922 /// Is multipath enabled? -923 // TODO(flub): not a useful API, once we do real things with multipath we can remove -924 // this again. -925 pub fn is_multipath_enabled(&self) -> bool { -926 let conn = self.0.state.lock("is_multipath_enabled"); -927 conn.inner.is_multipath_negotiated() -928 } -929 -930 /// Registers one address at which this endpoint might be reachable -931 /// -932 /// When the NAT traversal extension is negotiated, servers send these addresses to clients in -933 /// `ADD_ADDRESS` frames. This allows clients to obtain server address candidates to initiate -934 /// NAT traversal attempts. Clients provide their own reachable addresses in `REACH_OUT` frames -935 /// when [`Self::initiate_nat_traversal_round`] is called. -936 pub fn add_nat_traversal_address( -937 &self, -938 address: SocketAddr, -939 ) -> Result<(), n0_nat_traversal::Error> { -940 let mut conn = self.0.state.lock("add_nat_traversal_addresses"); -941 let result = conn.inner.add_nat_traversal_address(address); -942 conn.wake(); -943 result -944 } -945 -946 /// Removes one or more addresses from the set of addresses at which this endpoint is reachable -947 /// -948 /// When the NAT traversal extension is negotiated, servers send address removals to -949 /// clients in `REMOVE_ADDRESS` frames. This allows clients to stop using outdated -950 /// server address candidates that are no longer valid for NAT traversal. -951 /// -952 /// For clients, removed addresses will no longer be advertised in `REACH_OUT` frames. -953 /// -954 /// Addresses not present in the set will be silently ignored. -955 pub fn remove_nat_traversal_address( -956 &self, -957 address: SocketAddr, -958 ) -> Result<(), n0_nat_traversal::Error> { -959 let mut conn = self.0.state.lock("remove_nat_traversal_addresses"); -960 let result = conn.inner.remove_nat_traversal_address(address); -961 conn.wake(); -962 result -963 } -964 -965 /// Get the current local nat traversal addresses -966 pub fn get_local_nat_traversal_addresses( -967 &self, -968 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -969 let conn = self.0.state.lock("get_local_nat_traversal_addresses"); -970 conn.inner.get_local_nat_traversal_addresses() -971 } -972 -973 /// Get the currently advertised nat traversal addresses by the server -974 pub fn get_remote_nat_traversal_addresses( -975 &self, -976 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -977 let conn = self.0.state.lock("get_remote_nat_traversal_addresses"); -978 conn.inner.get_remote_nat_traversal_addresses() -979 } -980 -981 /// Initiates a new nat traversal round -982 /// -983 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` -984 /// frames, and initiating probing of the known remote addresses. When a new round is -985 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. -986 /// -987 /// Returns the server addresses that are now being probed. -988 pub fn initiate_nat_traversal_round(&self) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -989 let mut conn = self.0.state.lock("initiate_nat_traversal_round"); -990 let now = conn.runtime.now(); -991 let result = conn.inner.initiate_nat_traversal_round(now); -992 conn.wake(); -993 result -994 } -995} -996 -997pin_project! { -998 /// Future produced by [`Connection::open_uni`] -999 pub struct OpenUni<'a> { -1000 conn: &'a ConnectionRef, -1001 #[pin] -1002 notify: Notified<'a>, -1003 } -1004} -1005 -1006impl Future for OpenUni<'_> { -1007 type Output = Result<SendStream, ConnectionError>; -1008 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1009 let this = self.project(); -1010 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Uni))?; -1011 Poll::Ready(Ok(SendStream::new(conn, id, is_0rtt))) -1012 } -1013} -1014 -1015pin_project! { -1016 /// Future produced by [`Connection::open_bi`] -1017 pub struct OpenBi<'a> { -1018 conn: &'a ConnectionRef, -1019 #[pin] -1020 notify: Notified<'a>, +905 /// Track changes on our external address as reported by the peer. +906 pub fn observed_external_addr(&self) -> crate::ObservedExternalAddr { +907 let conn = self.0.lock_without_waking("external_addr"); +908 crate::ObservedExternalAddr::new(conn.observed_external_addr.subscribe()) +909 } +910 +911 /// Is multipath enabled? +912 // TODO(flub): not a useful API, once we do real things with multipath we can remove +913 // this again. +914 pub fn is_multipath_enabled(&self) -> bool { +915 let conn = self.0.lock_without_waking("is_multipath_enabled"); +916 conn.inner.is_multipath_negotiated() +917 } +918 +919 /// Registers one address at which this endpoint might be reachable +920 /// +921 /// When the NAT traversal extension is negotiated, servers send these addresses to clients in +922 /// `ADD_ADDRESS` frames. This allows clients to obtain server address candidates to initiate +923 /// NAT traversal attempts. Clients provide their own reachable addresses in `REACH_OUT` frames +924 /// when [`Self::initiate_nat_traversal_round`] is called. +925 pub fn add_nat_traversal_address( +926 &self, +927 address: SocketAddr, +928 ) -> Result<(), n0_nat_traversal::Error> { +929 let mut conn = self.0.lock_and_wake("add_nat_traversal_addresses"); +930 conn.inner.add_nat_traversal_address(address) +931 } +932 +933 /// Removes one or more addresses from the set of addresses at which this endpoint is reachable +934 /// +935 /// When the NAT traversal extension is negotiated, servers send address removals to +936 /// clients in `REMOVE_ADDRESS` frames. This allows clients to stop using outdated +937 /// server address candidates that are no longer valid for NAT traversal. +938 /// +939 /// For clients, removed addresses will no longer be advertised in `REACH_OUT` frames. +940 /// +941 /// Addresses not present in the set will be silently ignored. +942 pub fn remove_nat_traversal_address( +943 &self, +944 address: SocketAddr, +945 ) -> Result<(), n0_nat_traversal::Error> { +946 let mut conn = self.0.lock_and_wake("remove_nat_traversal_addresses"); +947 conn.inner.remove_nat_traversal_address(address) +948 } +949 +950 /// Get the current local nat traversal addresses +951 pub fn get_local_nat_traversal_addresses( +952 &self, +953 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +954 let conn = self +955 .0 +956 .lock_without_waking("get_local_nat_traversal_addresses"); +957 conn.inner.get_local_nat_traversal_addresses() +958 } +959 +960 /// Get the currently advertised nat traversal addresses by the server +961 pub fn get_remote_nat_traversal_addresses( +962 &self, +963 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +964 let conn = self +965 .0 +966 .lock_without_waking("get_remote_nat_traversal_addresses"); +967 conn.inner.get_remote_nat_traversal_addresses() +968 } +969 +970 /// Initiates a new nat traversal round +971 /// +972 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` +973 /// frames, and initiating probing of the known remote addresses. When a new round is +974 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. +975 /// +976 /// Returns the server addresses that are now being probed. +977 pub fn initiate_nat_traversal_round(&self) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +978 let mut conn = self.0.lock_and_wake("initiate_nat_traversal_round"); +979 let now = conn.runtime.now(); +980 conn.inner.initiate_nat_traversal_round(now) +981 } +982} +983 +984pin_project! { +985 /// Future produced by [`Connection::open_uni`] +986 pub struct OpenUni<'a> { +987 conn: &'a ConnectionRef, +988 #[pin] +989 notify: Notified<'a>, +990 } +991} +992 +993impl Future for OpenUni<'_> { +994 type Output = Result<SendStream, ConnectionError>; +995 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +996 let this = self.project(); +997 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Uni))?; +998 Poll::Ready(Ok(SendStream::new(conn, id, is_0rtt))) +999 } +1000} +1001 +1002pin_project! { +1003 /// Future produced by [`Connection::open_bi`] +1004 pub struct OpenBi<'a> { +1005 conn: &'a ConnectionRef, +1006 #[pin] +1007 notify: Notified<'a>, +1008 } +1009} +1010 +1011impl Future for OpenBi<'_> { +1012 type Output = Result<(SendStream, RecvStream), ConnectionError>; +1013 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1014 let this = self.project(); +1015 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Bi))?; +1016 +1017 Poll::Ready(Ok(( +1018 SendStream::new(conn.clone(), id, is_0rtt), +1019 RecvStream::new(conn, id, is_0rtt), +1020 ))) 1021 } 1022} 1023 -1024impl Future for OpenBi<'_> { -1025 type Output = Result<(SendStream, RecvStream), ConnectionError>; -1026 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1027 let this = self.project(); -1028 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Bi))?; -1029 -1030 Poll::Ready(Ok(( -1031 SendStream::new(conn.clone(), id, is_0rtt), -1032 RecvStream::new(conn, id, is_0rtt), -1033 ))) -1034 } -1035} -1036 -1037fn poll_open<'a>( -1038 ctx: &mut Context<'_>, -1039 conn: &'a ConnectionRef, -1040 mut notify: Pin<&mut Notified<'a>>, -1041 dir: Dir, -1042) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { -1043 let mut state = conn.state.lock("poll_open"); -1044 if let Some(ref e) = state.error { -1045 return Poll::Ready(Err(e.clone())); -1046 } else if let Some(id) = state.inner.streams().open(dir) { -1047 let is_0rtt = state.inner.side().is_client() && state.inner.is_handshaking(); -1048 drop(state); // Release the lock so clone can take it -1049 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); -1050 } -1051 loop { -1052 match notify.as_mut().poll(ctx) { -1053 // `state` lock ensures we didn't race with readiness -1054 Poll::Pending => return Poll::Pending, -1055 // Spurious wakeup, get a new future -1056 Poll::Ready(()) => { -1057 notify.set(conn.shared.stream_budget_available[dir as usize].notified()) -1058 } -1059 } -1060 } -1061} -1062 -1063pin_project! { -1064 /// Future produced by [`Connection::accept_uni`] -1065 pub struct AcceptUni<'a> { -1066 conn: &'a ConnectionRef, -1067 #[pin] -1068 notify: Notified<'a>, -1069 } -1070} -1071 -1072impl Future for AcceptUni<'_> { -1073 type Output = Result<RecvStream, ConnectionError>; -1074 -1075 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1076 let this = self.project(); -1077 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Uni))?; -1078 Poll::Ready(Ok(RecvStream::new(conn, id, is_0rtt))) -1079 } -1080} -1081 -1082pin_project! { -1083 /// Future produced by [`Connection::accept_bi`] -1084 pub struct AcceptBi<'a> { -1085 conn: &'a ConnectionRef, -1086 #[pin] -1087 notify: Notified<'a>, +1024fn poll_open<'a>( +1025 ctx: &mut Context<'_>, +1026 conn: &'a ConnectionRef, +1027 mut notify: Pin<&mut Notified<'a>>, +1028 dir: Dir, +1029) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { +1030 let mut state = conn.lock_without_waking("poll_open"); +1031 if let Some(ref e) = state.error { +1032 return Poll::Ready(Err(e.clone())); +1033 } else if let Some(id) = state.inner.streams().open(dir) { +1034 let is_0rtt = state.inner.side().is_client() && state.inner.is_handshaking(); +1035 drop(state); // Release the lock so clone can take it +1036 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); +1037 } +1038 loop { +1039 match notify.as_mut().poll(ctx) { +1040 // `state` lock ensures we didn't race with readiness +1041 Poll::Pending => return Poll::Pending, +1042 // Spurious wakeup, get a new future +1043 Poll::Ready(()) => { +1044 notify.set(conn.shared.stream_budget_available[dir as usize].notified()) +1045 } +1046 } +1047 } +1048} +1049 +1050pin_project! { +1051 /// Future produced by [`Connection::accept_uni`] +1052 pub struct AcceptUni<'a> { +1053 conn: &'a ConnectionRef, +1054 #[pin] +1055 notify: Notified<'a>, +1056 } +1057} +1058 +1059impl Future for AcceptUni<'_> { +1060 type Output = Result<RecvStream, ConnectionError>; +1061 +1062 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1063 let this = self.project(); +1064 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Uni))?; +1065 Poll::Ready(Ok(RecvStream::new(conn, id, is_0rtt))) +1066 } +1067} +1068 +1069pin_project! { +1070 /// Future produced by [`Connection::accept_bi`] +1071 pub struct AcceptBi<'a> { +1072 conn: &'a ConnectionRef, +1073 #[pin] +1074 notify: Notified<'a>, +1075 } +1076} +1077 +1078impl Future for AcceptBi<'_> { +1079 type Output = Result<(SendStream, RecvStream), ConnectionError>; +1080 +1081 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1082 let this = self.project(); +1083 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Bi))?; +1084 Poll::Ready(Ok(( +1085 SendStream::new(conn.clone(), id, is_0rtt), +1086 RecvStream::new(conn, id, is_0rtt), +1087 ))) 1088 } 1089} 1090 -1091impl Future for AcceptBi<'_> { -1092 type Output = Result<(SendStream, RecvStream), ConnectionError>; -1093 -1094 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1095 let this = self.project(); -1096 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Bi))?; -1097 Poll::Ready(Ok(( -1098 SendStream::new(conn.clone(), id, is_0rtt), -1099 RecvStream::new(conn, id, is_0rtt), -1100 ))) -1101 } -1102} -1103 -1104fn poll_accept<'a>( -1105 ctx: &mut Context<'_>, -1106 conn: &'a ConnectionRef, -1107 mut notify: Pin<&mut Notified<'a>>, -1108 dir: Dir, -1109) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { -1110 let mut state = conn.state.lock("poll_accept"); -1111 // Check for incoming streams before checking `state.error` so that already-received streams, -1112 // which are necessarily finite, can be drained from a closed connection. -1113 if let Some(id) = state.inner.streams().accept(dir) { -1114 let is_0rtt = state.inner.is_handshaking(); -1115 state.wake(); // To send additional stream ID credit -1116 drop(state); // Release the lock so clone can take it -1117 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); -1118 } else if let Some(ref e) = state.error { -1119 return Poll::Ready(Err(e.clone())); -1120 } -1121 loop { -1122 match notify.as_mut().poll(ctx) { -1123 // `state` lock ensures we didn't race with readiness -1124 Poll::Pending => return Poll::Pending, -1125 // Spurious wakeup, get a new future -1126 Poll::Ready(()) => notify.set(conn.shared.stream_incoming[dir as usize].notified()), -1127 } -1128 } -1129} -1130 -1131pin_project! { -1132 /// Future produced by [`Connection::read_datagram`] -1133 pub struct ReadDatagram<'a> { -1134 conn: &'a ConnectionRef, -1135 #[pin] -1136 notify: Notified<'a>, -1137 } -1138} -1139 -1140impl Future for ReadDatagram<'_> { -1141 type Output = Result<Bytes, ConnectionError>; -1142 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1143 let mut this = self.project(); -1144 let mut state = this.conn.state.lock("ReadDatagram::poll"); -1145 // Check for buffered datagrams before checking `state.error` so that already-received -1146 // datagrams, which are necessarily finite, can be drained from a closed connection. -1147 if let Some(x) = state.inner.datagrams().recv() { -1148 return Poll::Ready(Ok(x)); -1149 } else if let Some(ref e) = state.error { -1150 return Poll::Ready(Err(e.clone())); -1151 } -1152 loop { -1153 match this.notify.as_mut().poll(ctx) { -1154 // `state` lock ensures we didn't race with readiness -1155 Poll::Pending => return Poll::Pending, -1156 // Spurious wakeup, get a new future -1157 Poll::Ready(()) => this -1158 .notify -1159 .set(this.conn.shared.datagram_received.notified()), -1160 } -1161 } -1162 } -1163} -1164 -1165pin_project! { -1166 /// Future produced by [`Connection::send_datagram_wait`] -1167 pub struct SendDatagram<'a> { -1168 conn: &'a ConnectionRef, -1169 data: Option<Bytes>, -1170 #[pin] -1171 notify: Notified<'a>, -1172 } -1173} -1174 -1175impl Future for SendDatagram<'_> { -1176 type Output = Result<(), SendDatagramError>; -1177 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1178 let mut this = self.project(); -1179 let mut state = this.conn.state.lock("SendDatagram::poll"); -1180 if let Some(ref e) = state.error { -1181 return Poll::Ready(Err(SendDatagramError::ConnectionLost(e.clone()))); -1182 } -1183 use proto::SendDatagramError::*; -1184 match state -1185 .inner -1186 .datagrams() -1187 .send(this.data.take().unwrap(), false) -1188 { -1189 Ok(()) => { -1190 state.wake(); -1191 Poll::Ready(Ok(())) -1192 } -1193 Err(e) => Poll::Ready(Err(match e { -1194 Blocked(data) => { -1195 this.data.replace(data); -1196 loop { -1197 match this.notify.as_mut().poll(ctx) { -1198 Poll::Pending => return Poll::Pending, -1199 // Spurious wakeup, get a new future -1200 Poll::Ready(()) => this -1201 .notify -1202 .set(this.conn.shared.datagrams_unblocked.notified()), -1203 } -1204 } -1205 } -1206 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, -1207 Disabled => SendDatagramError::Disabled, -1208 TooLarge => SendDatagramError::TooLarge, -1209 })), -1210 } -1211 } -1212} -1213 -1214/// Future returned by [`Connection::on_closed`] -1215/// -1216/// Resolves to a tuple of ([`ConnectionError`], [`ConnectionStats`]). -1217pub struct OnClosed { -1218 rx: oneshot::Receiver<(ConnectionError, ConnectionStats)>, -1219 conn: WeakConnectionHandle, -1220} -1221 -1222impl Drop for OnClosed { -1223 fn drop(&mut self) { -1224 if self.rx.is_terminated() { -1225 return; -1226 }; -1227 if let Some(conn) = self.conn.upgrade() { -1228 self.rx.close(); -1229 conn.0 -1230 .state -1231 .lock("OnClosed::drop") -1232 .on_closed -1233 .retain(|tx| !tx.is_closed()); -1234 } -1235 } -1236} -1237 -1238impl Future for OnClosed { -1239 type Output = (ConnectionError, ConnectionStats); -1240 -1241 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -1242 let this = self.get_mut(); -1243 // The `expect` is safe because `State::drop` ensures that all senders are triggered -1244 // before being dropped. -1245 Pin::new(&mut this.rx) -1246 .poll(cx) -1247 .map(|x| x.expect("on_close sender is never dropped before sending")) -1248 } -1249} -1250 -1251#[derive(Debug)] -1252#[allow(clippy::redundant_allocation)] -1253pub(crate) struct ConnectionRef(Arc<Arc<ConnectionInner>>); -1254 -1255impl ConnectionRef { -1256 #[allow(clippy::redundant_allocation)] -1257 fn from_arc(inner: Arc<Arc<ConnectionInner>>) -> Self { -1258 inner.state.lock("from_arc").ref_count += 1; -1259 Self(inner) -1260 } -1261 -1262 pub(crate) fn stable_id(&self) -> usize { -1263 &*self.0 as *const _ as usize -1264 } -1265 -1266 pub(crate) fn weak_handle(&self) -> WeakConnectionHandle { -1267 WeakConnectionHandle(Arc::downgrade(&self.0)) -1268 } -1269} -1270 -1271impl Clone for ConnectionRef { -1272 fn clone(&self) -> Self { -1273 Self::from_arc(Arc::clone(&self.0)) -1274 } -1275} -1276 -1277impl Drop for ConnectionRef { -1278 fn drop(&mut self) { -1279 let conn = &mut *self.state.lock("drop"); -1280 if let Some(x) = conn.ref_count.checked_sub(1) { -1281 conn.ref_count = x; -1282 if x == 0 && !conn.inner.is_closed() { -1283 // If the driver is alive, it's just it and us, so we'd better shut it down. If it's -1284 // not, we can't do any harm. If there were any streams being opened, then either -1285 // the connection will be closed for an unrelated reason or a fresh reference will -1286 // be constructed for the newly opened stream. -1287 conn.implicit_close(&self.shared); -1288 } -1289 } -1290 } -1291} -1292 -1293impl std::ops::Deref for ConnectionRef { -1294 type Target = ConnectionInner; -1295 fn deref(&self) -> &Self::Target { -1296 &self.0 -1297 } -1298} -1299 -1300#[derive(Debug)] -1301pub(crate) struct ConnectionInner { -1302 pub(crate) state: Mutex<State>, -1303 pub(crate) shared: Shared, -1304} -1305 -1306/// A handle to some connection internals, use with care. -1307/// -1308/// This contains a weak reference to the connection so will not itself keep the connection -1309/// alive. -1310#[derive(Debug, Clone)] -1311pub struct WeakConnectionHandle(Weak<Arc<ConnectionInner>>); +1091fn poll_accept<'a>( +1092 ctx: &mut Context<'_>, +1093 conn: &'a ConnectionRef, +1094 mut notify: Pin<&mut Notified<'a>>, +1095 dir: Dir, +1096) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { +1097 let mut state = conn.lock_and_wake("poll_accept"); +1098 // Check for incoming streams before checking `state.error` so that already-received streams, +1099 // which are necessarily finite, can be drained from a closed connection. +1100 if let Some(id) = state.inner.streams().accept(dir) { +1101 let is_0rtt = state.inner.is_handshaking(); +1102 drop(state); // Release the lock (wake on drop) so clone can take it +1103 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); +1104 } else if let Some(ref e) = state.error { +1105 return Poll::Ready(Err(e.clone())); +1106 } +1107 loop { +1108 match notify.as_mut().poll(ctx) { +1109 // `state` lock ensures we didn't race with readiness +1110 Poll::Pending => return Poll::Pending, +1111 // Spurious wakeup, get a new future +1112 Poll::Ready(()) => notify.set(conn.shared.stream_incoming[dir as usize].notified()), +1113 } +1114 } +1115} +1116 +1117pin_project! { +1118 /// Future produced by [`Connection::read_datagram`] +1119 pub struct ReadDatagram<'a> { +1120 conn: &'a ConnectionRef, +1121 #[pin] +1122 notify: Notified<'a>, +1123 } +1124} +1125 +1126impl Future for ReadDatagram<'_> { +1127 type Output = Result<Bytes, ConnectionError>; +1128 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1129 let mut this = self.project(); +1130 let mut state = this.conn.lock_without_waking("ReadDatagram::poll"); +1131 // Check for buffered datagrams before checking `state.error` so that already-received +1132 // datagrams, which are necessarily finite, can be drained from a closed connection. +1133 if let Some(x) = state.inner.datagrams().recv() { +1134 return Poll::Ready(Ok(x)); +1135 } else if let Some(ref e) = state.error { +1136 return Poll::Ready(Err(e.clone())); +1137 } +1138 loop { +1139 match this.notify.as_mut().poll(ctx) { +1140 // `state` lock ensures we didn't race with readiness +1141 Poll::Pending => return Poll::Pending, +1142 // Spurious wakeup, get a new future +1143 Poll::Ready(()) => this +1144 .notify +1145 .set(this.conn.shared.datagram_received.notified()), +1146 } +1147 } +1148 } +1149} +1150 +1151pin_project! { +1152 /// Future produced by [`Connection::send_datagram_wait`] +1153 pub struct SendDatagram<'a> { +1154 conn: &'a ConnectionRef, +1155 data: Option<Bytes>, +1156 #[pin] +1157 notify: Notified<'a>, +1158 } +1159} +1160 +1161impl Future for SendDatagram<'_> { +1162 type Output = Result<(), SendDatagramError>; +1163 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1164 let mut this = self.project(); +1165 let mut state = this.conn.lock_and_wake("SendDatagram::poll"); +1166 if let Some(ref e) = state.error { +1167 return Poll::Ready(Err(SendDatagramError::ConnectionLost(e.clone()))); +1168 } +1169 use proto::SendDatagramError::*; +1170 match state +1171 .inner +1172 .datagrams() +1173 .send(this.data.take().unwrap(), false) +1174 { +1175 Ok(()) => Poll::Ready(Ok(())), +1176 Err(e) => Poll::Ready(Err(match e { +1177 Blocked(data) => { +1178 this.data.replace(data); +1179 loop { +1180 match this.notify.as_mut().poll(ctx) { +1181 Poll::Pending => return Poll::Pending, +1182 // Spurious wakeup, get a new future +1183 Poll::Ready(()) => this +1184 .notify +1185 .set(this.conn.shared.datagrams_unblocked.notified()), +1186 } +1187 } +1188 } +1189 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, +1190 Disabled => SendDatagramError::Disabled, +1191 TooLarge => SendDatagramError::TooLarge, +1192 })), +1193 } +1194 } +1195} +1196 +1197/// Future returned by [`Connection::on_closed`] +1198/// +1199/// Resolves to a tuple of ([`ConnectionError`], [`ConnectionStats`]). +1200pub struct OnClosed { +1201 rx: oneshot::Receiver<(ConnectionError, ConnectionStats)>, +1202 conn: WeakConnectionHandle, +1203} +1204 +1205impl Drop for OnClosed { +1206 fn drop(&mut self) { +1207 if self.rx.is_terminated() { +1208 return; +1209 }; +1210 if let Some(conn) = self.conn.upgrade() { +1211 self.rx.close(); +1212 conn.0 +1213 .lock_without_waking("OnClosed::drop") +1214 .on_closed +1215 .retain(|tx| !tx.is_closed()); +1216 } +1217 } +1218} +1219 +1220impl Future for OnClosed { +1221 type Output = (ConnectionError, ConnectionStats); +1222 +1223 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +1224 let this = self.get_mut(); +1225 // The `expect` is safe because `State::drop` ensures that all senders are triggered +1226 // before being dropped. +1227 Pin::new(&mut this.rx) +1228 .poll(cx) +1229 .map(|x| x.expect("on_close sender is never dropped before sending")) +1230 } +1231} +1232 +1233#[derive(Debug)] +1234#[allow(clippy::redundant_allocation)] +1235pub(crate) struct ConnectionRef(Arc<Arc<ConnectionInner>>); +1236 +1237impl ConnectionRef { +1238 #[allow(clippy::redundant_allocation)] +1239 fn from_arc(inner: Arc<Arc<ConnectionInner>>) -> Self { +1240 inner.lock_without_waking("from_arc").ref_count += 1; +1241 Self(inner) +1242 } +1243 +1244 pub(crate) fn stable_id(&self) -> usize { +1245 &*self.0 as *const _ as usize +1246 } +1247 +1248 pub(crate) fn weak_handle(&self) -> WeakConnectionHandle { +1249 WeakConnectionHandle(Arc::downgrade(&self.0)) +1250 } +1251} +1252 +1253impl Clone for ConnectionRef { +1254 fn clone(&self) -> Self { +1255 Self::from_arc(Arc::clone(&self.0)) +1256 } +1257} +1258 +1259impl Drop for ConnectionRef { +1260 fn drop(&mut self) { +1261 let conn = &mut *self.lock_without_waking("drop"); +1262 if let Some(x) = conn.ref_count.checked_sub(1) { +1263 conn.ref_count = x; +1264 if x == 0 && !conn.inner.is_closed() { +1265 // If the driver is alive, it's just it and us, so we'd better shut it down. If it's +1266 // not, we can't do any harm. If there were any streams being opened, then either +1267 // the connection will be closed for an unrelated reason or a fresh reference will +1268 // be constructed for the newly opened stream. +1269 conn.implicit_close(&self.shared); +1270 } +1271 } +1272 } +1273} +1274 +1275impl std::ops::Deref for ConnectionRef { +1276 type Target = ConnectionInner; +1277 fn deref(&self) -> &Self::Target { +1278 &self.0 +1279 } +1280} +1281 +1282#[derive(Debug)] +1283pub(crate) struct ConnectionInner { +1284 /// Kept private intentionally, use [`Self::lock_and_wake`]. +1285 state: Mutex<State>, +1286 pub(crate) shared: Shared, +1287} +1288 +1289impl ConnectionInner { +1290 /// Lock the state and return a guard that wakes the connection driver on drop. +1291 /// +1292 /// Use this for operations that may queue frames. The wake ensures the driver sends queued frames. +1293 /// If that's not needed, use [`Self::lock_without_waking`]. +1294 pub(crate) fn lock_and_wake(&self, purpose: &'static str) -> WakeGuard<'_> { +1295 WakeGuard { +1296 guard: self.state.lock(purpose), +1297 wake: true, +1298 } +1299 } +1300 +1301 /// Lock the state and return a guard that unlocks once dropped. +1302 /// +1303 /// Use this for operations that don't require any action from the connection driver. +1304 /// Otherwise, use [`Self::lock_and_wake`] instead. +1305 pub(crate) fn lock_without_waking(&self, purpose: &'static str) -> WakeGuard<'_> { +1306 WakeGuard { +1307 guard: self.state.lock(purpose), +1308 wake: false, +1309 } +1310 } +1311} 1312 -1313impl WeakConnectionHandle { -1314 /// Returns `true` if the [`Connection`] associated with this handle is still alive. -1315 pub fn is_alive(&self) -> bool { -1316 self.0.upgrade().is_some() -1317 } -1318 -1319 /// Upgrade the handle to a full `Connection` -1320 pub fn upgrade(&self) -> Option<Connection> { -1321 self.upgrade_to_ref().map(Connection) -1322 } -1323 -1324 pub(crate) fn upgrade_to_ref(&self) -> Option<ConnectionRef> { -1325 self.0.upgrade().map(ConnectionRef::from_arc) -1326 } +1313/// [`MutexGuard`] wrapper that calls [`State::wake`] on drop. +1314#[derive(derive_more::Deref, derive_more::DerefMut)] +1315pub(crate) struct WakeGuard<'a> { +1316 #[deref] +1317 #[deref_mut] +1318 guard: MutexGuard<'a, State>, +1319 wake: bool, +1320} +1321 +1322impl WakeGuard<'_> { +1323 pub(crate) fn skip_waking(&mut self) { +1324 self.wake = false; +1325 } +1326} 1327 -1328 /// Returns `true` if the two [`WeakConnectionHandle`] point at the same connection. -1329 pub fn is_same_connection(&self, other: &Self) -> bool { -1330 self.0.ptr_eq(&other.0) -1331 } -1332} -1333 -1334#[derive(Debug, Default)] -1335pub(crate) struct Shared { -1336 handshake_confirmed: Notify, -1337 /// Notified when new streams may be locally initiated due to an increase in stream ID flow -1338 /// control budget -1339 stream_budget_available: [Notify; 2], -1340 /// Notified when the peer has initiated a new stream -1341 stream_incoming: [Notify; 2], -1342 datagram_received: Notify, -1343 datagrams_unblocked: Notify, -1344 closed: Notify, -1345} -1346 -1347pub(crate) struct State { -1348 pub(crate) inner: proto::Connection, -1349 driver: Option<Waker>, -1350 handle: ConnectionHandle, -1351 on_handshake_data: Option<oneshot::Sender<()>>, -1352 on_connected: Option<oneshot::Sender<bool>>, -1353 connected: bool, -1354 handshake_confirmed: bool, -1355 timer: Option<Pin<Box<dyn AsyncTimer>>>, -1356 timer_deadline: Option<Instant>, -1357 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, -1358 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, -1359 pub(crate) blocked_writers: FxHashMap<StreamId, Waker>, -1360 pub(crate) blocked_readers: FxHashMap<StreamId, Waker>, -1361 pub(crate) stopped: FxHashMap<StreamId, Arc<Notify>>, -1362 /// Always set to Some before the connection becomes drained -1363 pub(crate) error: Option<ConnectionError>, -1364 /// Tracks paths being opened -1365 open_path: FxHashMap<PathId, watch::Sender<Result<(), PathError>>>, -1366 /// Tracks reference counts for paths. -1367 /// -1368 /// I.e. how many [`Path`] and [`WeakPathHandle`] structs are alive for a path. -1369 /// -1370 /// [`WeakPathHandle`]: crate::path::WeakPathHandle -1371 pub(crate) path_refs: FxHashMap<PathId, usize>, -1372 /// Final path stats for discarded paths. -1373 /// -1374 /// We only insert entries if the discarded path has a non-zero reference count in [`Self::path_refs`]. -1375 /// When the last reference to a path is dropped via [`Self::decrement_path_refs`] its value is cleared. -1376 pub(crate) final_path_stats: FxHashMap<PathId, PathStats>, -1377 pub(crate) path_events: tokio::sync::broadcast::Sender<PathEvent>, -1378 /// Number of live handles that can be used to initiate or handle I/O; excludes the driver -1379 ref_count: usize, -1380 sender: Pin<Box<dyn UdpSender>>, -1381 pub(crate) runtime: Arc<dyn Runtime>, -1382 send_buffer: Vec<u8>, -1383 /// We buffer a transmit when the underlying I/O would block -1384 buffered_transmit: Option<proto::Transmit>, -1385 /// Our last external address reported by the peer. When multipath is enabled, this will be the -1386 /// last report across all paths. -1387 pub(crate) observed_external_addr: watch::Sender<Option<SocketAddr>>, -1388 pub(crate) nat_traversal_updates: tokio::sync::broadcast::Sender<n0_nat_traversal::Event>, -1389 on_closed: Vec<oneshot::Sender<(ConnectionError, ConnectionStats)>>, -1390} -1391 -1392impl State { -1393 #[allow(clippy::too_many_arguments)] -1394 fn new( -1395 inner: proto::Connection, -1396 handle: ConnectionHandle, -1397 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, -1398 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, -1399 on_handshake_data: oneshot::Sender<()>, -1400 on_connected: oneshot::Sender<bool>, -1401 sender: Pin<Box<dyn UdpSender>>, -1402 runtime: Arc<dyn Runtime>, -1403 ) -> Self { -1404 Self { -1405 inner, -1406 driver: None, -1407 handle, -1408 on_handshake_data: Some(on_handshake_data), -1409 on_connected: Some(on_connected), -1410 connected: false, -1411 handshake_confirmed: false, -1412 timer: None, -1413 timer_deadline: None, -1414 conn_events, -1415 endpoint_events, -1416 blocked_writers: FxHashMap::default(), -1417 blocked_readers: FxHashMap::default(), -1418 stopped: FxHashMap::default(), -1419 open_path: FxHashMap::default(), -1420 error: None, -1421 ref_count: 0, -1422 sender, -1423 runtime, -1424 send_buffer: Vec::new(), -1425 buffered_transmit: None, -1426 path_events: tokio::sync::broadcast::channel(32).0, -1427 observed_external_addr: watch::Sender::new(None), -1428 nat_traversal_updates: tokio::sync::broadcast::channel(32).0, -1429 on_closed: Vec::new(), -1430 final_path_stats: Default::default(), -1431 path_refs: Default::default(), -1432 } -1433 } -1434 -1435 fn drive_transmit(&mut self, cx: &mut Context<'_>) -> io::Result<bool> { -1436 let now = self.runtime.now(); -1437 let mut transmits = 0; -1438 -1439 let max_datagrams = self -1440 .sender -1441 .max_transmit_segments() -1442 .min(MAX_TRANSMIT_SEGMENTS); -1443 -1444 loop { -1445 // Retry the last transmit, or get a new one. -1446 let t = match self.buffered_transmit.take() { -1447 Some(t) => t, -1448 None => { -1449 self.send_buffer.clear(); -1450 match self -1451 .inner -1452 .poll_transmit(now, max_datagrams, &mut self.send_buffer) -1453 { -1454 Some(t) => { -1455 transmits += match t.segment_size { -1456 None => 1, -1457 Some(s) => t.size.div_ceil(s), // round up -1458 }; -1459 t -1460 } -1461 None => break, -1462 } -1463 } -1464 }; -1465 -1466 let len = t.size; -1467 match self -1468 .sender -1469 .as_mut() -1470 .poll_send(&udp_transmit(&t, &self.send_buffer[..len]), cx) -1471 { -1472 Poll::Pending => { -1473 self.buffered_transmit = Some(t); -1474 return Ok(false); -1475 } -1476 Poll::Ready(Err(e)) => return Err(e), -1477 Poll::Ready(Ok(())) => {} -1478 } -1479 -1480 if transmits >= MAX_TRANSMIT_DATAGRAMS { -1481 // TODO: What isn't ideal here yet is that if we don't poll all -1482 // datagrams that could be sent we don't go into the `app_limited` -1483 // state and CWND continues to grow until we get here the next time. -1484 // See https://github.com/quinn-rs/quinn/issues/1126 -1485 return Ok(true); -1486 } -1487 } -1488 -1489 Ok(false) -1490 } -1491 -1492 fn forward_endpoint_events(&mut self) { -1493 while let Some(event) = self.inner.poll_endpoint_events() { -1494 // If the endpoint driver is gone, noop. -1495 let _ = self.endpoint_events.send((self.handle, event)); -1496 } -1497 } -1498 -1499 /// If this returns `Err`, the endpoint is dead, so the driver should exit immediately. -1500 fn process_conn_events( -1501 &mut self, -1502 shared: &Shared, -1503 cx: &mut Context<'_>, -1504 ) -> Result<(), ConnectionError> { -1505 loop { -1506 match self.conn_events.poll_recv(cx) { -1507 Poll::Ready(Some(ConnectionEvent::Rebind(sender))) => { -1508 self.sender = sender; -1509 self.inner.handle_network_change(None, self.runtime.now()); -1510 } -1511 Poll::Ready(Some(ConnectionEvent::LocalAddressChanged(hint))) => { -1512 self.inner -1513 .handle_network_change(hint.as_deref().map(|x| x as _), self.runtime.now()); -1514 } -1515 Poll::Ready(Some(ConnectionEvent::Proto(event))) => { -1516 self.inner.handle_event(event); -1517 } -1518 Poll::Ready(Some(ConnectionEvent::Close { reason, error_code })) => { -1519 self.close(error_code, reason, shared); -1520 } -1521 Poll::Ready(None) => { -1522 return Err(ConnectionError::TransportError(TransportError::new( -1523 TransportErrorCode::INTERNAL_ERROR, -1524 "endpoint driver future was dropped".to_string(), -1525 ))); -1526 } -1527 Poll::Pending => { -1528 return Ok(()); -1529 } -1530 } -1531 } -1532 } -1533 -1534 fn forward_app_events(&mut self, shared: &Shared) { -1535 while let Some(event) = self.inner.poll() { -1536 use proto::Event::*; -1537 match event { -1538 HandshakeDataReady => { -1539 if let Some(x) = self.on_handshake_data.take() { -1540 let _ = x.send(()); -1541 } -1542 } -1543 Connected => { -1544 self.connected = true; -1545 if let Some(x) = self.on_connected.take() { -1546 // We don't care if the on-connected future was dropped -1547 let _ = x.send(self.inner.accepted_0rtt()); -1548 } -1549 if self.inner.side().is_client() && !self.inner.accepted_0rtt() { -1550 // Wake up rejected 0-RTT streams so they can fail immediately with -1551 // `ZeroRttRejected` errors. -1552 wake_all(&mut self.blocked_writers); -1553 wake_all(&mut self.blocked_readers); -1554 wake_all_notify(&mut self.stopped); -1555 } +1328impl Drop for WakeGuard<'_> { +1329 fn drop(&mut self) { +1330 if self.wake { +1331 self.guard.wake(); +1332 } +1333 } +1334} +1335 +1336/// A handle to some connection internals, use with care. +1337/// +1338/// This contains a weak reference to the connection so will not itself keep the connection +1339/// alive. +1340#[derive(Debug, Clone)] +1341pub struct WeakConnectionHandle(Weak<Arc<ConnectionInner>>); +1342 +1343impl WeakConnectionHandle { +1344 /// Returns `true` if the [`Connection`] associated with this handle is still alive. +1345 pub fn is_alive(&self) -> bool { +1346 self.0.upgrade().is_some() +1347 } +1348 +1349 /// Upgrade the handle to a full `Connection` +1350 pub fn upgrade(&self) -> Option<Connection> { +1351 self.upgrade_to_ref().map(Connection) +1352 } +1353 +1354 pub(crate) fn upgrade_to_ref(&self) -> Option<ConnectionRef> { +1355 self.0.upgrade().map(ConnectionRef::from_arc) +1356 } +1357 +1358 /// Returns `true` if the two [`WeakConnectionHandle`] point at the same connection. +1359 pub fn is_same_connection(&self, other: &Self) -> bool { +1360 self.0.ptr_eq(&other.0) +1361 } +1362} +1363 +1364#[derive(Debug, Default)] +1365pub(crate) struct Shared { +1366 handshake_confirmed: Notify, +1367 /// Notified when new streams may be locally initiated due to an increase in stream ID flow +1368 /// control budget +1369 stream_budget_available: [Notify; 2], +1370 /// Notified when the peer has initiated a new stream +1371 stream_incoming: [Notify; 2], +1372 datagram_received: Notify, +1373 datagrams_unblocked: Notify, +1374 closed: Notify, +1375} +1376 +1377pub(crate) struct State { +1378 pub(crate) inner: proto::Connection, +1379 driver: Option<Waker>, +1380 handle: ConnectionHandle, +1381 on_handshake_data: Option<oneshot::Sender<()>>, +1382 on_connected: Option<oneshot::Sender<bool>>, +1383 connected: bool, +1384 handshake_confirmed: bool, +1385 timer: Option<Pin<Box<dyn AsyncTimer>>>, +1386 timer_deadline: Option<Instant>, +1387 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, +1388 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, +1389 pub(crate) blocked_writers: FxHashMap<StreamId, Waker>, +1390 pub(crate) blocked_readers: FxHashMap<StreamId, Waker>, +1391 pub(crate) stopped: FxHashMap<StreamId, Arc<Notify>>, +1392 /// Always set to Some before the connection becomes drained +1393 pub(crate) error: Option<ConnectionError>, +1394 /// Tracks paths being opened +1395 open_path: FxHashMap<PathId, watch::Sender<Result<(), PathError>>>, +1396 /// Tracks reference counts for paths. +1397 /// +1398 /// I.e. how many [`Path`] and [`WeakPathHandle`] structs are alive for a path. +1399 /// +1400 /// [`WeakPathHandle`]: crate::path::WeakPathHandle +1401 pub(crate) path_refs: FxHashMap<PathId, usize>, +1402 /// Final path stats for discarded paths. +1403 /// +1404 /// We only insert entries if the discarded path has a non-zero reference count in [`Self::path_refs`]. +1405 /// When the last reference to a path is dropped via [`Self::decrement_path_refs`] its value is cleared. +1406 pub(crate) final_path_stats: FxHashMap<PathId, PathStats>, +1407 pub(crate) path_events: tokio::sync::broadcast::Sender<PathEvent>, +1408 /// Number of live handles that can be used to initiate or handle I/O; excludes the driver +1409 ref_count: usize, +1410 sender: Pin<Box<dyn UdpSender>>, +1411 pub(crate) runtime: Arc<dyn Runtime>, +1412 send_buffer: Vec<u8>, +1413 /// We buffer a transmit when the underlying I/O would block +1414 buffered_transmit: Option<proto::Transmit>, +1415 /// Our last external address reported by the peer. When multipath is enabled, this will be the +1416 /// last report across all paths. +1417 pub(crate) observed_external_addr: watch::Sender<Option<SocketAddr>>, +1418 pub(crate) nat_traversal_updates: tokio::sync::broadcast::Sender<n0_nat_traversal::Event>, +1419 on_closed: Vec<oneshot::Sender<(ConnectionError, ConnectionStats)>>, +1420} +1421 +1422impl State { +1423 #[allow(clippy::too_many_arguments)] +1424 fn new( +1425 inner: proto::Connection, +1426 handle: ConnectionHandle, +1427 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, +1428 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, +1429 on_handshake_data: oneshot::Sender<()>, +1430 on_connected: oneshot::Sender<bool>, +1431 sender: Pin<Box<dyn UdpSender>>, +1432 runtime: Arc<dyn Runtime>, +1433 ) -> Self { +1434 Self { +1435 inner, +1436 driver: None, +1437 handle, +1438 on_handshake_data: Some(on_handshake_data), +1439 on_connected: Some(on_connected), +1440 connected: false, +1441 handshake_confirmed: false, +1442 timer: None, +1443 timer_deadline: None, +1444 conn_events, +1445 endpoint_events, +1446 blocked_writers: FxHashMap::default(), +1447 blocked_readers: FxHashMap::default(), +1448 stopped: FxHashMap::default(), +1449 open_path: FxHashMap::default(), +1450 error: None, +1451 ref_count: 0, +1452 sender, +1453 runtime, +1454 send_buffer: Vec::new(), +1455 buffered_transmit: None, +1456 path_events: tokio::sync::broadcast::channel(32).0, +1457 observed_external_addr: watch::Sender::new(None), +1458 nat_traversal_updates: tokio::sync::broadcast::channel(32).0, +1459 on_closed: Vec::new(), +1460 final_path_stats: Default::default(), +1461 path_refs: Default::default(), +1462 } +1463 } +1464 +1465 fn drive_transmit(&mut self, cx: &mut Context<'_>) -> io::Result<bool> { +1466 let now = self.runtime.now(); +1467 let mut transmits = 0; +1468 +1469 let max_datagrams = self +1470 .sender +1471 .max_transmit_segments() +1472 .min(MAX_TRANSMIT_SEGMENTS); +1473 +1474 loop { +1475 // Retry the last transmit, or get a new one. +1476 let t = match self.buffered_transmit.take() { +1477 Some(t) => t, +1478 None => { +1479 self.send_buffer.clear(); +1480 match self +1481 .inner +1482 .poll_transmit(now, max_datagrams, &mut self.send_buffer) +1483 { +1484 Some(t) => { +1485 transmits += match t.segment_size { +1486 None => 1, +1487 Some(s) => t.size.div_ceil(s), // round up +1488 }; +1489 t +1490 } +1491 None => break, +1492 } +1493 } +1494 }; +1495 +1496 let len = t.size; +1497 match self +1498 .sender +1499 .as_mut() +1500 .poll_send(&udp_transmit(&t, &self.send_buffer[..len]), cx) +1501 { +1502 Poll::Pending => { +1503 self.buffered_transmit = Some(t); +1504 return Ok(false); +1505 } +1506 Poll::Ready(Err(e)) => return Err(e), +1507 Poll::Ready(Ok(())) => {} +1508 } +1509 +1510 if transmits >= MAX_TRANSMIT_DATAGRAMS { +1511 // TODO: What isn't ideal here yet is that if we don't poll all +1512 // datagrams that could be sent we don't go into the `app_limited` +1513 // state and CWND continues to grow until we get here the next time. +1514 // See https://github.com/quinn-rs/quinn/issues/1126 +1515 return Ok(true); +1516 } +1517 } +1518 +1519 Ok(false) +1520 } +1521 +1522 fn forward_endpoint_events(&mut self) { +1523 while let Some(event) = self.inner.poll_endpoint_events() { +1524 // If the endpoint driver is gone, noop. +1525 let _ = self.endpoint_events.send((self.handle, event)); +1526 } +1527 } +1528 +1529 /// If this returns `Err`, the endpoint is dead, so the driver should exit immediately. +1530 fn process_conn_events( +1531 &mut self, +1532 shared: &Shared, +1533 cx: &mut Context<'_>, +1534 ) -> Result<(), ConnectionError> { +1535 loop { +1536 match self.conn_events.poll_recv(cx) { +1537 Poll::Ready(Some(ConnectionEvent::Rebind(sender))) => { +1538 self.sender = sender; +1539 self.inner.handle_network_change(None, self.runtime.now()); +1540 } +1541 Poll::Ready(Some(ConnectionEvent::LocalAddressChanged(hint))) => { +1542 self.inner +1543 .handle_network_change(hint.as_deref().map(|x| x as _), self.runtime.now()); +1544 } +1545 Poll::Ready(Some(ConnectionEvent::Proto(event))) => { +1546 self.inner.handle_event(event); +1547 } +1548 Poll::Ready(Some(ConnectionEvent::Close { reason, error_code })) => { +1549 self.close(error_code, reason, shared); +1550 } +1551 Poll::Ready(None) => { +1552 return Err(ConnectionError::TransportError(TransportError::new( +1553 TransportErrorCode::INTERNAL_ERROR, +1554 "endpoint driver future was dropped".to_string(), +1555 ))); 1556 } -1557 HandshakeConfirmed => { -1558 self.handshake_confirmed = true; -1559 shared.handshake_confirmed.notify_waiters(); -1560 } -1561 ConnectionLost { reason } => { -1562 self.terminate(reason, shared); -1563 } -1564 Stream(StreamEvent::Writable { id }) => wake_stream(id, &mut self.blocked_writers), -1565 Stream(StreamEvent::Opened { dir: Dir::Uni }) => { -1566 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); -1567 } -1568 Stream(StreamEvent::Opened { dir: Dir::Bi }) => { -1569 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); -1570 } -1571 DatagramReceived => { -1572 shared.datagram_received.notify_waiters(); -1573 } -1574 DatagramsUnblocked => { -1575 shared.datagrams_unblocked.notify_waiters(); -1576 } -1577 Stream(StreamEvent::Readable { id }) => wake_stream(id, &mut self.blocked_readers), -1578 Stream(StreamEvent::Available { dir }) => { -1579 // Might mean any number of streams are ready, so we wake up everyone -1580 shared.stream_budget_available[dir as usize].notify_waiters(); -1581 } -1582 Stream(StreamEvent::Finished { id }) => wake_stream_notify(id, &mut self.stopped), -1583 Stream(StreamEvent::Stopped { id, .. }) => { -1584 wake_stream_notify(id, &mut self.stopped); -1585 wake_stream(id, &mut self.blocked_writers); +1557 Poll::Pending => { +1558 return Ok(()); +1559 } +1560 } +1561 } +1562 } +1563 +1564 fn forward_app_events(&mut self, shared: &Shared) { +1565 while let Some(event) = self.inner.poll() { +1566 use proto::Event::*; +1567 match event { +1568 HandshakeDataReady => { +1569 if let Some(x) = self.on_handshake_data.take() { +1570 let _ = x.send(()); +1571 } +1572 } +1573 Connected => { +1574 self.connected = true; +1575 if let Some(x) = self.on_connected.take() { +1576 // We don't care if the on-connected future was dropped +1577 let _ = x.send(self.inner.accepted_0rtt()); +1578 } +1579 if self.inner.side().is_client() && !self.inner.accepted_0rtt() { +1580 // Wake up rejected 0-RTT streams so they can fail immediately with +1581 // `ZeroRttRejected` errors. +1582 wake_all(&mut self.blocked_writers); +1583 wake_all(&mut self.blocked_readers); +1584 wake_all_notify(&mut self.stopped); +1585 } 1586 } -1587 Path(ref evt @ PathEvent::ObservedAddr { addr: observed, .. }) => { -1588 self.path_events.send(evt.clone()).ok(); -1589 self.observed_external_addr.send_if_modified(|addr| { -1590 let old = addr.replace(observed); -1591 old != *addr -1592 }); +1587 HandshakeConfirmed => { +1588 self.handshake_confirmed = true; +1589 shared.handshake_confirmed.notify_waiters(); +1590 } +1591 ConnectionLost { reason } => { +1592 self.terminate(reason, shared); 1593 } -1594 Path(ref evt @ PathEvent::Opened { id }) => { -1595 self.path_events.send(evt.clone()).ok(); -1596 if let Some(sender) = self.open_path.remove(&id) { -1597 sender.send_modify(|value| *value = Ok(())); -1598 } -1599 } -1600 Path(ref evt @ PathEvent::Discarded { id, ref path_stats }) => { -1601 if self.path_refs.contains_key(&id) { -1602 self.final_path_stats.insert(id, *path_stats.clone()); -1603 } -1604 self.path_events.send(evt.clone()).ok(); -1605 } -1606 Path(ref evt @ PathEvent::Abandoned { id, .. }) => { -1607 if let Some(sender) = self.open_path.remove(&id) { -1608 // We don't care for the reason why this path was closed here, because semantically -1609 // all close reasons for a path that has not yet been opened equals to `ValidationFailed`. -1610 // With the noq API, there is no way to application-close a not-yet-opened path, so -1611 // `ApplicationClosed` cannot occur. And all other variants will only occur for paths -1612 // that have already been opened. -1613 // The previous iteration of this code had another event `PathEvent::LocallyClosed` which -1614 // contained a `PathError`, but that was only ever set to `ValidationFailed`. -1615 let error = PathError::ValidationFailed; -1616 sender.send_modify(|value| *value = Err(error)); -1617 } -1618 // this will happen also for already opened paths -1619 self.path_events.send(evt.clone()).ok(); -1620 } -1621 Path(evt @ PathEvent::RemoteStatus { .. }) => { -1622 self.path_events.send(evt).ok(); +1594 Stream(StreamEvent::Writable { id }) => wake_stream(id, &mut self.blocked_writers), +1595 Stream(StreamEvent::Opened { dir: Dir::Uni }) => { +1596 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); +1597 } +1598 Stream(StreamEvent::Opened { dir: Dir::Bi }) => { +1599 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); +1600 } +1601 DatagramReceived => { +1602 shared.datagram_received.notify_waiters(); +1603 } +1604 DatagramsUnblocked => { +1605 shared.datagrams_unblocked.notify_waiters(); +1606 } +1607 Stream(StreamEvent::Readable { id }) => wake_stream(id, &mut self.blocked_readers), +1608 Stream(StreamEvent::Available { dir }) => { +1609 // Might mean any number of streams are ready, so we wake up everyone +1610 shared.stream_budget_available[dir as usize].notify_waiters(); +1611 } +1612 Stream(StreamEvent::Finished { id }) => wake_stream_notify(id, &mut self.stopped), +1613 Stream(StreamEvent::Stopped { id, .. }) => { +1614 wake_stream_notify(id, &mut self.stopped); +1615 wake_stream(id, &mut self.blocked_writers); +1616 } +1617 Path(ref evt @ PathEvent::ObservedAddr { addr: observed, .. }) => { +1618 self.path_events.send(evt.clone()).ok(); +1619 self.observed_external_addr.send_if_modified(|addr| { +1620 let old = addr.replace(observed); +1621 old != *addr +1622 }); 1623 } -1624 NatTraversal(update) => { -1625 self.nat_traversal_updates.send(update).ok(); -1626 } -1627 } -1628 } -1629 } -1630 -1631 fn drive_timer(&mut self, cx: &mut Context<'_>) -> bool { -1632 // Check whether we need to (re)set the timer. If so, we must poll again to ensure the -1633 // timer is registered with the runtime (and check whether it's already -1634 // expired). -1635 match self.inner.poll_timeout() { -1636 Some(deadline) => { -1637 if let Some(delay) = &mut self.timer { -1638 // There is no need to reset the tokio timer if the deadline -1639 // did not change -1640 if self -1641 .timer_deadline -1642 .map(|current_deadline| current_deadline != deadline) -1643 .unwrap_or(true) -1644 { -1645 delay.as_mut().reset(deadline); -1646 } -1647 } else { -1648 self.timer = Some(self.runtime.new_timer(deadline)); -1649 } -1650 // Store the actual expiration time of the timer -1651 self.timer_deadline = Some(deadline); -1652 } -1653 None => { -1654 self.timer_deadline = None; -1655 return false; -1656 } -1657 } -1658 -1659 if self.timer_deadline.is_none() { -1660 return false; -1661 } -1662 -1663 let delay = self -1664 .timer -1665 .as_mut() -1666 .expect("timer must exist in this state") -1667 .as_mut(); -1668 if delay.poll(cx).is_pending() { -1669 // Since there wasn't a timeout event, there is nothing new -1670 // for the connection to do -1671 return false; -1672 } -1673 -1674 // A timer expired, so the caller needs to check for -1675 // new transmits, which might cause new timers to be set. -1676 self.inner.handle_timeout(self.runtime.now()); -1677 self.timer_deadline = None; -1678 true -1679 } -1680 -1681 /// Wake up a blocked `Driver` task to process I/O -1682 pub(crate) fn wake(&mut self) { -1683 if let Some(x) = self.driver.take() { -1684 x.wake(); -1685 } -1686 } -1687 -1688 /// Used to wake up all blocked futures when the connection becomes closed for any reason -1689 fn terminate(&mut self, reason: ConnectionError, shared: &Shared) { -1690 self.error = Some(reason.clone()); -1691 if let Some(x) = self.on_handshake_data.take() { -1692 let _ = x.send(()); -1693 } -1694 wake_all(&mut self.blocked_writers); -1695 wake_all(&mut self.blocked_readers); -1696 shared.stream_budget_available[Dir::Uni as usize].notify_waiters(); -1697 shared.stream_budget_available[Dir::Bi as usize].notify_waiters(); -1698 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); -1699 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); -1700 shared.datagram_received.notify_waiters(); -1701 shared.datagrams_unblocked.notify_waiters(); -1702 if let Some(x) = self.on_connected.take() { -1703 let _ = x.send(false); -1704 } -1705 shared.handshake_confirmed.notify_waiters(); -1706 wake_all_notify(&mut self.stopped); -1707 shared.closed.notify_waiters(); -1708 -1709 // Send to the registered on_closed futures. -1710 let stats = self.inner.stats(); -1711 for tx in self.on_closed.drain(..) { -1712 tx.send((reason.clone(), stats.clone())).ok(); -1713 } -1714 } -1715 -1716 fn close(&mut self, error_code: VarInt, reason: Bytes, shared: &Shared) { -1717 self.inner.close(self.runtime.now(), error_code, reason); -1718 self.terminate(ConnectionError::LocallyClosed, shared); -1719 self.wake(); -1720 } -1721 -1722 /// Close for a reason other than the application's explicit request -1723 pub(crate) fn implicit_close(&mut self, shared: &Shared) { -1724 self.close(0u32.into(), Bytes::new(), shared); -1725 } -1726 -1727 pub(crate) fn check_0rtt(&self) -> Result<(), ()> { -1728 if self.inner.is_handshaking() -1729 || self.inner.accepted_0rtt() -1730 || self.inner.side().is_server() -1731 { -1732 Ok(()) -1733 } else { -1734 Err(()) -1735 } -1736 } -1737 -1738 /// Returns [`PathStats`] for a path, if available. -1739 /// -1740 /// This gets the stats from [`proto::Connection`]. If that returns `None` -1741 /// it gets them from `Self::final_path_stats` instead. -1742 pub(crate) fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { -1743 self.inner -1744 .path_stats(path_id) -1745 .or_else(|| self.final_path_stats.get(&path_id).copied()) -1746 } -1747 -1748 /// Increment the reference counter for a path in this connection. -1749 /// -1750 /// This counts how many [`Path`] or [`WeakPathHandle`] structs exist for a path. -1751 /// Currently this is used to determine whether to store the final stats after a path is -1752 /// abandoned. -1753 /// -1754 /// [`WeakPathHandle`]: crate::path::WeakPathHandle -1755 pub(crate) fn increment_path_refs(&mut self, path_id: PathId) { -1756 *self.path_refs.entry(path_id).or_default() += 1; -1757 } -1758 -1759 /// Decrement the reference counter for a path in this connection. -1760 pub(crate) fn decrement_path_refs(&mut self, path_id: PathId) { -1761 if let Some(refs) = self.path_refs.get_mut(&path_id) { -1762 *refs = refs.saturating_sub(1); -1763 if *refs == 0 { -1764 self.path_refs.remove(&path_id); -1765 self.final_path_stats.remove(&path_id); -1766 } -1767 } -1768 } -1769} -1770 -1771impl Drop for State { -1772 fn drop(&mut self) { -1773 if !self.inner.is_drained() { -1774 // Ensure the endpoint can tidy up -1775 let _ = self -1776 .endpoint_events -1777 .send((self.handle, proto::EndpointEvent::drained())); -1778 } -1779 -1780 if !self.on_closed.is_empty() { -1781 // Ensure that all on_closed oneshot senders are triggered before dropping. -1782 let reason = self.error.as_ref().expect("closed without error reason"); -1783 let stats = self.inner.stats(); -1784 for tx in self.on_closed.drain(..) { -1785 tx.send((reason.clone(), stats.clone())).ok(); -1786 } -1787 } -1788 } -1789} -1790 -1791impl fmt::Debug for State { -1792 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -1793 f.debug_struct("State").field("inner", &self.inner).finish() -1794 } -1795} -1796 -1797fn wake_stream(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Waker>) { -1798 if let Some(waker) = wakers.remove(&stream_id) { -1799 waker.wake(); -1800 } -1801} -1802 -1803fn wake_all(wakers: &mut FxHashMap<StreamId, Waker>) { -1804 wakers.drain().for_each(|(_, waker)| waker.wake()) -1805} -1806 -1807fn wake_stream_notify(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { -1808 if let Some(notify) = wakers.remove(&stream_id) { -1809 notify.notify_waiters() -1810 } -1811} -1812 -1813fn wake_all_notify(wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { -1814 wakers -1815 .drain() -1816 .for_each(|(_, notify)| notify.notify_waiters()) -1817} -1818 -1819/// Errors that can arise when sending a datagram -1820#[derive(Debug, Error, Clone, Eq, PartialEq)] -1821pub enum SendDatagramError { -1822 /// The peer does not support receiving datagram frames -1823 #[error("datagrams not supported by peer")] -1824 UnsupportedByPeer, -1825 /// Datagram support is disabled locally -1826 #[error("datagram support disabled")] -1827 Disabled, -1828 /// The datagram is larger than the connection can currently accommodate -1829 /// -1830 /// Indicates that the path MTU minus overhead or the limit advertised by the peer has been -1831 /// exceeded. -1832 #[error("datagram too large")] -1833 TooLarge, -1834 /// The connection was lost -1835 #[error("connection lost")] -1836 ConnectionLost(#[from] ConnectionError), -1837} -1838 -1839/// The maximum amount of datagrams which will be produced in a single `drive_transmit` call -1840/// -1841/// This limits the amount of CPU resources consumed by datagram generation, -1842/// and allows other tasks (like receiving ACKs) to run in between. -1843const MAX_TRANSMIT_DATAGRAMS: usize = 20; -1844 -1845/// The maximum amount of datagrams that are sent in a single transmit -1846/// -1847/// This can be lower than the maximum platform capabilities, to avoid excessive -1848/// memory allocations when calling `poll_transmit()`. Benchmarks have shown -1849/// that numbers around 10 are a good compromise. -1850const MAX_TRANSMIT_SEGMENTS: NonZeroUsize = NonZeroUsize::new(10).expect("known");

\ No newline at end of file +1624 Path(ref evt @ PathEvent::Opened { id }) => { +1625 self.path_events.send(evt.clone()).ok(); +1626 if let Some(sender) = self.open_path.remove(&id) { +1627 sender.send_modify(|value| *value = Ok(())); +1628 } +1629 } +1630 Path(ref evt @ PathEvent::Discarded { id, ref path_stats }) => { +1631 if self.path_refs.contains_key(&id) { +1632 self.final_path_stats.insert(id, *path_stats.clone()); +1633 } +1634 self.path_events.send(evt.clone()).ok(); +1635 } +1636 Path(ref evt @ PathEvent::Abandoned { id, .. }) => { +1637 if let Some(sender) = self.open_path.remove(&id) { +1638 // We don't care for the reason why this path was closed here, because semantically +1639 // all close reasons for a path that has not yet been opened equals to `ValidationFailed`. +1640 // With the noq API, there is no way to application-close a not-yet-opened path, so +1641 // `ApplicationClosed` cannot occur. And all other variants will only occur for paths +1642 // that have already been opened. +1643 // The previous iteration of this code had another event `PathEvent::LocallyClosed` which +1644 // contained a `PathError`, but that was only ever set to `ValidationFailed`. +1645 let error = PathError::ValidationFailed; +1646 sender.send_modify(|value| *value = Err(error)); +1647 } +1648 // this will happen also for already opened paths +1649 self.path_events.send(evt.clone()).ok(); +1650 } +1651 Path(evt @ PathEvent::RemoteStatus { .. }) => { +1652 self.path_events.send(evt).ok(); +1653 } +1654 NatTraversal(update) => { +1655 self.nat_traversal_updates.send(update).ok(); +1656 } +1657 } +1658 } +1659 } +1660 +1661 fn drive_timer(&mut self, cx: &mut Context<'_>) -> bool { +1662 // Check whether we need to (re)set the timer. If so, we must poll again to ensure the +1663 // timer is registered with the runtime (and check whether it's already +1664 // expired). +1665 match self.inner.poll_timeout() { +1666 Some(deadline) => { +1667 if let Some(delay) = &mut self.timer { +1668 // There is no need to reset the tokio timer if the deadline +1669 // did not change +1670 if self +1671 .timer_deadline +1672 .map(|current_deadline| current_deadline != deadline) +1673 .unwrap_or(true) +1674 { +1675 delay.as_mut().reset(deadline); +1676 } +1677 } else { +1678 self.timer = Some(self.runtime.new_timer(deadline)); +1679 } +1680 // Store the actual expiration time of the timer +1681 self.timer_deadline = Some(deadline); +1682 } +1683 None => { +1684 self.timer_deadline = None; +1685 return false; +1686 } +1687 } +1688 +1689 if self.timer_deadline.is_none() { +1690 return false; +1691 } +1692 +1693 let delay = self +1694 .timer +1695 .as_mut() +1696 .expect("timer must exist in this state") +1697 .as_mut(); +1698 if delay.poll(cx).is_pending() { +1699 // Since there wasn't a timeout event, there is nothing new +1700 // for the connection to do +1701 return false; +1702 } +1703 +1704 // A timer expired, so the caller needs to check for +1705 // new transmits, which might cause new timers to be set. +1706 self.inner.handle_timeout(self.runtime.now()); +1707 self.timer_deadline = None; +1708 true +1709 } +1710 +1711 /// Wake up a blocked `Driver` task to process I/O +1712 pub(crate) fn wake(&mut self) { +1713 if let Some(x) = self.driver.take() { +1714 x.wake(); +1715 } +1716 } +1717 +1718 /// Used to wake up all blocked futures when the connection becomes closed for any reason +1719 fn terminate(&mut self, reason: ConnectionError, shared: &Shared) { +1720 self.error = Some(reason.clone()); +1721 if let Some(x) = self.on_handshake_data.take() { +1722 let _ = x.send(()); +1723 } +1724 wake_all(&mut self.blocked_writers); +1725 wake_all(&mut self.blocked_readers); +1726 shared.stream_budget_available[Dir::Uni as usize].notify_waiters(); +1727 shared.stream_budget_available[Dir::Bi as usize].notify_waiters(); +1728 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); +1729 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); +1730 shared.datagram_received.notify_waiters(); +1731 shared.datagrams_unblocked.notify_waiters(); +1732 if let Some(x) = self.on_connected.take() { +1733 let _ = x.send(false); +1734 } +1735 shared.handshake_confirmed.notify_waiters(); +1736 wake_all_notify(&mut self.stopped); +1737 shared.closed.notify_waiters(); +1738 +1739 // Send to the registered on_closed futures. +1740 let stats = self.inner.stats(); +1741 for tx in self.on_closed.drain(..) { +1742 tx.send((reason.clone(), stats.clone())).ok(); +1743 } +1744 } +1745 +1746 fn close(&mut self, error_code: VarInt, reason: Bytes, shared: &Shared) { +1747 self.inner.close(self.runtime.now(), error_code, reason); +1748 self.terminate(ConnectionError::LocallyClosed, shared); +1749 self.wake(); +1750 } +1751 +1752 /// Close for a reason other than the application's explicit request +1753 pub(crate) fn implicit_close(&mut self, shared: &Shared) { +1754 self.close(0u32.into(), Bytes::new(), shared); +1755 } +1756 +1757 pub(crate) fn check_0rtt(&self) -> Result<(), ()> { +1758 if self.inner.is_handshaking() +1759 || self.inner.accepted_0rtt() +1760 || self.inner.side().is_server() +1761 { +1762 Ok(()) +1763 } else { +1764 Err(()) +1765 } +1766 } +1767 +1768 /// Returns [`PathStats`] for a path, if available. +1769 /// +1770 /// This gets the stats from [`proto::Connection`]. If that returns `None` +1771 /// it gets them from `Self::final_path_stats` instead. +1772 pub(crate) fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { +1773 self.inner +1774 .path_stats(path_id) +1775 .or_else(|| self.final_path_stats.get(&path_id).copied()) +1776 } +1777 +1778 /// Increment the reference counter for a path in this connection. +1779 /// +1780 /// This counts how many [`Path`] or [`WeakPathHandle`] structs exist for a path. +1781 /// Currently this is used to determine whether to store the final stats after a path is +1782 /// abandoned. +1783 /// +1784 /// [`WeakPathHandle`]: crate::path::WeakPathHandle +1785 pub(crate) fn increment_path_refs(&mut self, path_id: PathId) { +1786 *self.path_refs.entry(path_id).or_default() += 1; +1787 } +1788 +1789 /// Decrement the reference counter for a path in this connection. +1790 pub(crate) fn decrement_path_refs(&mut self, path_id: PathId) { +1791 if let Some(refs) = self.path_refs.get_mut(&path_id) { +1792 *refs = refs.saturating_sub(1); +1793 if *refs == 0 { +1794 self.path_refs.remove(&path_id); +1795 self.final_path_stats.remove(&path_id); +1796 } +1797 } +1798 } +1799} +1800 +1801impl Drop for State { +1802 fn drop(&mut self) { +1803 if !self.inner.is_drained() { +1804 // Ensure the endpoint can tidy up +1805 let _ = self +1806 .endpoint_events +1807 .send((self.handle, proto::EndpointEvent::drained())); +1808 } +1809 +1810 if !self.on_closed.is_empty() { +1811 // Ensure that all on_closed oneshot senders are triggered before dropping. +1812 let reason = self.error.as_ref().expect("closed without error reason"); +1813 let stats = self.inner.stats(); +1814 for tx in self.on_closed.drain(..) { +1815 tx.send((reason.clone(), stats.clone())).ok(); +1816 } +1817 } +1818 } +1819} +1820 +1821impl fmt::Debug for State { +1822 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +1823 f.debug_struct("State").field("inner", &self.inner).finish() +1824 } +1825} +1826 +1827fn wake_stream(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Waker>) { +1828 if let Some(waker) = wakers.remove(&stream_id) { +1829 waker.wake(); +1830 } +1831} +1832 +1833fn wake_all(wakers: &mut FxHashMap<StreamId, Waker>) { +1834 wakers.drain().for_each(|(_, waker)| waker.wake()) +1835} +1836 +1837fn wake_stream_notify(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { +1838 if let Some(notify) = wakers.remove(&stream_id) { +1839 notify.notify_waiters() +1840 } +1841} +1842 +1843fn wake_all_notify(wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { +1844 wakers +1845 .drain() +1846 .for_each(|(_, notify)| notify.notify_waiters()) +1847} +1848 +1849/// Errors that can arise when sending a datagram +1850#[derive(Debug, Error, Clone, Eq, PartialEq)] +1851pub enum SendDatagramError { +1852 /// The peer does not support receiving datagram frames +1853 #[error("datagrams not supported by peer")] +1854 UnsupportedByPeer, +1855 /// Datagram support is disabled locally +1856 #[error("datagram support disabled")] +1857 Disabled, +1858 /// The datagram is larger than the connection can currently accommodate +1859 /// +1860 /// Indicates that the path MTU minus overhead or the limit advertised by the peer has been +1861 /// exceeded. +1862 #[error("datagram too large")] +1863 TooLarge, +1864 /// The connection was lost +1865 #[error("connection lost")] +1866 ConnectionLost(#[from] ConnectionError), +1867} +1868 +1869/// The maximum amount of datagrams which will be produced in a single `drive_transmit` call +1870/// +1871/// This limits the amount of CPU resources consumed by datagram generation, +1872/// and allows other tasks (like receiving ACKs) to run in between. +1873const MAX_TRANSMIT_DATAGRAMS: usize = 20; +1874 +1875/// The maximum amount of datagrams that are sent in a single transmit +1876/// +1877/// This can be lower than the maximum platform capabilities, to avoid excessive +1878/// memory allocations when calling `poll_transmit()`. Benchmarks have shown +1879/// that numbers around 10 are a good compromise. +1880const MAX_TRANSMIT_SEGMENTS: NonZeroUsize = NonZeroUsize::new(10).expect("known");

\ No newline at end of file diff --git a/pr/523/docs/src/noq/mutex.rs.html b/pr/523/docs/src/noq/mutex.rs.html index f04b9bef5..f184b770b 100644 --- a/pr/523/docs/src/noq/mutex.rs.html +++ b/pr/523/docs/src/noq/mutex.rs.html @@ -110,7 +110,7 @@ 110} 111 112#[cfg(feature = "lock_tracking")] -113pub(crate) use tracking::Mutex; +113pub(crate) use tracking::{Mutex, MutexGuard}; 114 115#[cfg(not(feature = "lock_tracking"))] 116mod non_tracking { @@ -160,4 +160,4 @@ 160} 161 162#[cfg(not(feature = "lock_tracking"))] -163pub(crate) use non_tracking::Mutex;

\ No newline at end of file +163pub(crate) use non_tracking::{Mutex, MutexGuard}; \ No newline at end of file diff --git a/pr/523/docs/src/noq/path.rs.html b/pr/523/docs/src/noq/path.rs.html index 47c65029b..189133320 100644 --- a/pr/523/docs/src/noq/path.rs.html +++ b/pr/523/docs/src/noq/path.rs.html @@ -118,305 +118,297 @@ 118impl Clone for Path { 119 fn clone(&self) -> Self { 120 self.conn -121 .state -122 .lock("Path::clone") -123 .increment_path_refs(self.id); -124 Self { -125 id: self.id, -126 conn: self.conn.clone(), -127 } -128 } -129} -130 -131impl Drop for Path { -132 fn drop(&mut self) { -133 let mut state = self.conn.state.lock("Path::drop"); -134 state.decrement_path_refs(self.id); -135 } -136} -137 -138impl Path { -139 /// Returns a [`Path`] for a path id, after checking that the path is not closed. -140 pub(crate) fn new(conn: &ConnectionRef, id: PathId) -> Option<Self> { -141 { -142 let mut state = conn.state.lock("Path::new"); -143 // TODO(flub): Using this to know if the path still exists is... hacky. -144 state.inner.path_status(id).ok()?; -145 state.increment_path_refs(id); -146 } -147 Some(Self { -148 id, -149 conn: conn.clone(), -150 }) -151 } -152 -153 /// Returns a [`Path`] for a path id without checking if the path exists or is closed. -154 fn new_unchecked(conn: ConnectionRef, id: PathId) -> Self { -155 conn.state -156 .lock("Path::new_unchecked") -157 .increment_path_refs(id); -158 Self { id, conn } -159 } -160 -161 /// Returns a [`WeakPathHandle`] for this path. -162 /// -163 /// Holding a [`WeakPathHandle`] does not keep a connection alive, but ensures that the -164 /// path's stats are not dropped until the underlying connection is dropped, even if the -165 /// path is abandoned. -166 pub fn weak_handle(&self) -> WeakPathHandle { -167 self.conn -168 .state -169 .lock("Path::weak_handle") -170 .increment_path_refs(self.id); -171 WeakPathHandle { -172 id: self.id, -173 conn: self.conn.weak_handle(), -174 } -175 } -176 -177 /// The [`PathId`] of this path. -178 pub fn id(&self) -> PathId { -179 self.id -180 } -181 -182 /// The current local [`PathStatus`] of this path. -183 pub fn status(&self) -> Result<PathStatus, ClosedPath> { -184 self.conn -185 .state -186 .lock("path status") -187 .inner -188 .path_status(self.id) -189 } -190 -191 /// Sets the [`PathStatus`] of this path. -192 pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError> { -193 self.conn -194 .state -195 .lock("set path status") -196 .inner -197 .set_path_status(self.id, status)?; -198 Ok(()) -199 } -200 -201 /// Returns the [`PathStats`] for this path. -202 pub fn stats(&self) -> PathStats { -203 // The `expect` is safe: -204 // - `Path` can only be created for non-closed paths. -205 // - `Path` and its clones or `WeakPathHandle`s all increment the connection state's `path_ref` -206 // reference counter -207 // - As long as a path is not abandoned, its stats are available from `proto::Connection` -208 // - If a path is abandoned, the `crate::Connection` stores the final stats as long as -209 // the path's refcount is not 0 -210 // - Therefore, we always get stats here. -211 self.conn -212 .state -213 .lock("Path::stats") -214 .path_stats(self.id) -215 .expect("either path stats or discarded path stats are always set as long as Path is not dropped") -216 } -217 -218 /// Closes this path. -219 /// -220 /// The path is immediately considered closed by the local endpoint. Once the state is removed, -221 /// after a short period of time for any in-flight packets, a [`PathEvent::Abandoned`] is -222 /// returned. -223 pub fn close(&self) -> Result<(), ClosePathError> { -224 let mut state = self.conn.state.lock("close_path"); -225 state.inner.close_path( -226 crate::Instant::now(), -227 self.id, -228 TransportErrorCode::APPLICATION_ABANDON_PATH.into(), -229 ) -230 } -231 -232 /// Sets the keep_alive_interval for a specific path -233 /// -234 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. -235 /// -236 /// Returns the previous value of the setting. -237 /// -238 /// [`TransportConfig::default_path_keep_alive_interval`]: crate::TransportConfig::default_path_keep_alive_interval -239 pub fn set_max_idle_timeout( -240 &self, -241 timeout: Option<Duration>, -242 ) -> Result<Option<Duration>, ClosedPath> { -243 let mut state = self.conn.state.lock("path_set_max_idle_timeout"); -244 let now = state.runtime.now(); -245 state.inner.set_path_max_idle_timeout(now, self.id, timeout) -246 } -247 -248 /// Sets the keep_alive_interval for a specific path -249 /// -250 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. -251 /// -252 /// Returns the previous value of the setting. -253 /// -254 /// [`TransportConfig::default_path_keep_alive_interval`]: crate::TransportConfig::default_path_keep_alive_interval -255 pub fn set_keep_alive_interval( -256 &self, -257 interval: Option<Duration>, -258 ) -> Result<Option<Duration>, ClosedPath> { -259 let mut state = self.conn.state.lock("path_set_keep_alive_interval"); -260 state.inner.set_path_keep_alive_interval(self.id, interval) -261 } -262 -263 /// Track changes on our external address as reported by the peer. -264 /// -265 /// If the address-discovery extension is not negotiated, the stream will never return. -266 pub fn observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath> { -267 let state = self.conn.state.lock("per_path_observed_address"); -268 let path_events = state.path_events.subscribe(); -269 let initial_value = state.inner.path_observed_address(self.id)?; -270 Ok(AddressDiscovery::new( -271 self.id, -272 path_events, -273 initial_value, -274 state.runtime.clone(), -275 )) +121 .lock_without_waking("Path::clone") +122 .increment_path_refs(self.id); +123 Self { +124 id: self.id, +125 conn: self.conn.clone(), +126 } +127 } +128} +129 +130impl Drop for Path { +131 fn drop(&mut self) { +132 let mut state = self.conn.lock_without_waking("Path::drop"); +133 state.decrement_path_refs(self.id); +134 } +135} +136 +137impl Path { +138 /// Returns a [`Path`] for a path id, after checking that the path is not closed. +139 pub(crate) fn new(conn: &ConnectionRef, id: PathId) -> Option<Self> { +140 { +141 let mut state = conn.lock_without_waking("Path::new"); +142 // TODO(flub): Using this to know if the path still exists is... hacky. +143 state.inner.path_status(id).ok()?; +144 state.increment_path_refs(id); +145 } +146 Some(Self { +147 id, +148 conn: conn.clone(), +149 }) +150 } +151 +152 /// Returns a [`Path`] for a path id without checking if the path exists or is closed. +153 fn new_unchecked(conn: ConnectionRef, id: PathId) -> Self { +154 conn.lock_without_waking("Path::new_unchecked") +155 .increment_path_refs(id); +156 Self { id, conn } +157 } +158 +159 /// Returns a [`WeakPathHandle`] for this path. +160 /// +161 /// Holding a [`WeakPathHandle`] does not keep a connection alive, but ensures that the +162 /// path's stats are not dropped until the underlying connection is dropped, even if the +163 /// path is abandoned. +164 pub fn weak_handle(&self) -> WeakPathHandle { +165 self.conn +166 .lock_without_waking("Path::weak_handle") +167 .increment_path_refs(self.id); +168 WeakPathHandle { +169 id: self.id, +170 conn: self.conn.weak_handle(), +171 } +172 } +173 +174 /// The [`PathId`] of this path. +175 pub fn id(&self) -> PathId { +176 self.id +177 } +178 +179 /// The current local [`PathStatus`] of this path. +180 pub fn status(&self) -> Result<PathStatus, ClosedPath> { +181 self.conn +182 .lock_without_waking("path status") +183 .inner +184 .path_status(self.id) +185 } +186 +187 /// Sets the [`PathStatus`] of this path. +188 pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError> { +189 self.conn +190 .lock_and_wake("set path status") +191 .inner +192 .set_path_status(self.id, status)?; +193 Ok(()) +194 } +195 +196 /// Returns the [`PathStats`] for this path. +197 pub fn stats(&self) -> PathStats { +198 // The `expect` is safe: +199 // - `Path` can only be created for non-closed paths. +200 // - `Path` and its clones or `WeakPathHandle`s all increment the connection state's `path_ref` +201 // reference counter +202 // - As long as a path is not abandoned, its stats are available from `proto::Connection` +203 // - If a path is abandoned, the `crate::Connection` stores the final stats as long as +204 // the path's refcount is not 0 +205 // - Therefore, we always get stats here. +206 self.conn +207 .lock_without_waking("Path::stats") +208 .path_stats(self.id) +209 .expect("either path stats or discarded path stats are always set as long as Path is not dropped") +210 } +211 +212 /// Closes this path. +213 /// +214 /// The path is immediately considered closed by the local endpoint. Once the state is removed, +215 /// after a short period of time for any in-flight packets, a [`PathEvent::Abandoned`] is +216 /// returned. +217 pub fn close(&self) -> Result<(), ClosePathError> { +218 let mut state = self.conn.lock_and_wake("close_path"); +219 state.inner.close_path( +220 crate::Instant::now(), +221 self.id, +222 TransportErrorCode::APPLICATION_ABANDON_PATH.into(), +223 ) +224 } +225 +226 /// Sets the keep_alive_interval for a specific path +227 /// +228 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. +229 /// +230 /// Returns the previous value of the setting. +231 /// +232 /// [`TransportConfig::default_path_keep_alive_interval`]: crate::TransportConfig::default_path_keep_alive_interval +233 pub fn set_max_idle_timeout( +234 &self, +235 timeout: Option<Duration>, +236 ) -> Result<Option<Duration>, ClosedPath> { +237 let mut state = self.conn.lock_and_wake("path_set_max_idle_timeout"); +238 let now = state.runtime.now(); +239 state.inner.set_path_max_idle_timeout(now, self.id, timeout) +240 } +241 +242 /// Sets the keep_alive_interval for a specific path +243 /// +244 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. +245 /// +246 /// Returns the previous value of the setting. +247 /// +248 /// [`TransportConfig::default_path_keep_alive_interval`]: crate::TransportConfig::default_path_keep_alive_interval +249 pub fn set_keep_alive_interval( +250 &self, +251 interval: Option<Duration>, +252 ) -> Result<Option<Duration>, ClosedPath> { +253 let mut state = self.conn.lock_and_wake("path_set_keep_alive_interval"); +254 state.inner.set_path_keep_alive_interval(self.id, interval) +255 } +256 +257 /// Track changes on our external address as reported by the peer. +258 /// +259 /// If the address-discovery extension is not negotiated, the stream will never return. +260 pub fn observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath> { +261 let state = self.conn.lock_without_waking("per_path_observed_address"); +262 let path_events = state.path_events.subscribe(); +263 let initial_value = state.inner.path_observed_address(self.id)?; +264 Ok(AddressDiscovery::new( +265 self.id, +266 path_events, +267 initial_value, +268 state.runtime.clone(), +269 )) +270 } +271 +272 /// The peer's UDP address for this path. +273 pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath> { +274 let state = self.conn.lock_without_waking("per_path_remote_address"); +275 Ok(state.inner.network_path(self.id)?.remote()) 276 } 277 -278 /// The peer's UDP address for this path. -279 pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath> { -280 let state = self.conn.state.lock("per_path_remote_address"); -281 Ok(state.inner.network_path(self.id)?.remote()) +278 /// Ping the remote endpoint over this path. +279 pub fn ping(&self) -> Result<(), ClosedPath> { +280 let mut state = self.conn.lock_and_wake("ping"); +281 state.inner.ping_path(self.id) 282 } -283 -284 /// Ping the remote endpoint over this path. -285 pub fn ping(&self) -> Result<(), ClosedPath> { -286 let mut state = self.conn.state.lock("ping"); -287 state.inner.ping_path(self.id) +283} +284 +285impl PartialEq for Path { +286 fn eq(&self, other: &Self) -> bool { +287 self.id == other.id && self.conn.stable_id() == other.conn.stable_id() 288 } 289} 290 -291impl PartialEq for Path { -292 fn eq(&self, other: &Self) -> bool { -293 self.id == other.id && self.conn.stable_id() == other.conn.stable_id() -294 } -295} -296 -297/// Weak handle for a [`Path`] that does not keep the connection alive. -298/// -299/// As long as a [`WeakPathHandle`] for a path exists, that path's final stats will not be dropped even if -300/// the path was abandoned. -301/// -302/// The [`WeakPathHandle`] can be upgraded to a [`Path`] as long as its [`Connection`] has not been dropped. -303/// -304/// [`Connection`]: crate::Connection -305#[derive(Debug)] -306pub struct WeakPathHandle { -307 id: PathId, -308 conn: WeakConnectionHandle, -309} -310 -311impl Clone for WeakPathHandle { -312 fn clone(&self) -> Self { -313 if let Some(conn) = self.conn.upgrade_to_ref() { -314 conn.state -315 .lock("WeakPathHandle::clone") -316 .increment_path_refs(self.id); -317 } -318 Self { -319 id: self.id, -320 conn: self.conn.clone(), -321 } -322 } -323} -324 -325impl PartialEq for WeakPathHandle { -326 fn eq(&self, other: &Self) -> bool { -327 self.id == other.id && self.conn.is_same_connection(&other.conn) -328 } -329} -330 -331impl Eq for WeakPathHandle {} -332 -333impl Drop for WeakPathHandle { -334 fn drop(&mut self) { -335 if let Some(conn) = self.conn.upgrade_to_ref() { -336 conn.state -337 .lock("WeakPathHandle::drop") -338 .decrement_path_refs(self.id); -339 } -340 } -341} -342 -343impl WeakPathHandle { -344 /// Returns the [`PathId`] of this path. -345 pub fn id(&self) -> PathId { -346 self.id +291/// Weak handle for a [`Path`] that does not keep the connection alive. +292/// +293/// As long as a [`WeakPathHandle`] for a path exists, that path's final stats will not be dropped even if +294/// the path was abandoned. +295/// +296/// The [`WeakPathHandle`] can be upgraded to a [`Path`] as long as its [`Connection`] has not been dropped. +297/// +298/// [`Connection`]: crate::Connection +299#[derive(Debug)] +300pub struct WeakPathHandle { +301 id: PathId, +302 conn: WeakConnectionHandle, +303} +304 +305impl Clone for WeakPathHandle { +306 fn clone(&self) -> Self { +307 if let Some(conn) = self.conn.upgrade_to_ref() { +308 conn.lock_without_waking("WeakPathHandle::clone") +309 .increment_path_refs(self.id); +310 } +311 Self { +312 id: self.id, +313 conn: self.conn.clone(), +314 } +315 } +316} +317 +318impl PartialEq for WeakPathHandle { +319 fn eq(&self, other: &Self) -> bool { +320 self.id == other.id && self.conn.is_same_connection(&other.conn) +321 } +322} +323 +324impl Eq for WeakPathHandle {} +325 +326impl Drop for WeakPathHandle { +327 fn drop(&mut self) { +328 if let Some(conn) = self.conn.upgrade_to_ref() { +329 conn.lock_without_waking("WeakPathHandle::drop") +330 .decrement_path_refs(self.id); +331 } +332 } +333} +334 +335impl WeakPathHandle { +336 /// Returns the [`PathId`] of this path. +337 pub fn id(&self) -> PathId { +338 self.id +339 } +340 +341 /// Upgrades to a [`Path`]. +342 /// +343 /// Returns `None` if the connection was dropped. +344 pub fn upgrade(&self) -> Option<Path> { +345 let conn = self.conn.upgrade_to_ref()?; +346 Some(Path::new_unchecked(conn, self.id)) 347 } -348 -349 /// Upgrades to a [`Path`]. -350 /// -351 /// Returns `None` if the connection was dropped. -352 pub fn upgrade(&self) -> Option<Path> { -353 let conn = self.conn.upgrade_to_ref()?; -354 Some(Path::new_unchecked(conn, self.id)) -355 } -356} -357 -358/// Stream produced by [`Path::observed_external_addr`] -359/// -360/// This will always return the external address most recently reported by the remote over this -361/// path. If the extension is not negotiated, this stream will never return. -362// TODO(@divma): provide a way to check if the extension is negotiated. -363pub struct AddressDiscovery { -364 watcher: WatchStream<SocketAddr>, -365} -366 -367impl AddressDiscovery { -368 pub(super) fn new( -369 path_id: PathId, -370 mut path_events: tokio::sync::broadcast::Receiver<PathEvent>, -371 initial_value: Option<SocketAddr>, -372 runtime: Arc<dyn Runtime>, -373 ) -> Self { -374 let (tx, rx) = watch::channel(initial_value.unwrap_or_else(|| -375 // if the dummy value is used, it will be ignored -376 SocketAddr::new([0, 0, 0, 0].into(), 0))); -377 let filter = async move { -378 loop { -379 match path_events.recv().await { -380 Ok(PathEvent::ObservedAddr { id, addr: observed }) if id == path_id => { -381 tx.send_if_modified(|addr| { -382 let old = std::mem::replace(addr, observed); -383 old != *addr -384 }); -385 } -386 Ok(PathEvent::Discarded { id, .. }) if id == path_id => { -387 // If the path is closed, terminate the stream -388 break; -389 } -390 Ok(_) => { -391 // ignore any other event -392 } -393 Err(_) => { -394 // A lagged error should never happen since this (detached) task is -395 // constantly reading from the channel. Therefore, if an error does happen, -396 // the stream can terminate -397 break; -398 } -399 } -400 } -401 }; -402 -403 let watcher = if initial_value.is_some() { -404 WatchStream::new(rx) -405 } else { -406 WatchStream::from_changes(rx) -407 }; -408 -409 runtime.spawn(Box::pin(filter)); -410 // TODO(@divma): check if there's a way to ensure the future ends. AbortHandle is not an -411 // option -412 Self { watcher } +348} +349 +350/// Stream produced by [`Path::observed_external_addr`] +351/// +352/// This will always return the external address most recently reported by the remote over this +353/// path. If the extension is not negotiated, this stream will never return. +354// TODO(@divma): provide a way to check if the extension is negotiated. +355pub struct AddressDiscovery { +356 watcher: WatchStream<SocketAddr>, +357} +358 +359impl AddressDiscovery { +360 pub(super) fn new( +361 path_id: PathId, +362 mut path_events: tokio::sync::broadcast::Receiver<PathEvent>, +363 initial_value: Option<SocketAddr>, +364 runtime: Arc<dyn Runtime>, +365 ) -> Self { +366 let (tx, rx) = watch::channel(initial_value.unwrap_or_else(|| +367 // if the dummy value is used, it will be ignored +368 SocketAddr::new([0, 0, 0, 0].into(), 0))); +369 let filter = async move { +370 loop { +371 match path_events.recv().await { +372 Ok(PathEvent::ObservedAddr { id, addr: observed }) if id == path_id => { +373 tx.send_if_modified(|addr| { +374 let old = std::mem::replace(addr, observed); +375 old != *addr +376 }); +377 } +378 Ok(PathEvent::Discarded { id, .. }) if id == path_id => { +379 // If the path is closed, terminate the stream +380 break; +381 } +382 Ok(_) => { +383 // ignore any other event +384 } +385 Err(_) => { +386 // A lagged error should never happen since this (detached) task is +387 // constantly reading from the channel. Therefore, if an error does happen, +388 // the stream can terminate +389 break; +390 } +391 } +392 } +393 }; +394 +395 let watcher = if initial_value.is_some() { +396 WatchStream::new(rx) +397 } else { +398 WatchStream::from_changes(rx) +399 }; +400 +401 runtime.spawn(Box::pin(filter)); +402 // TODO(@divma): check if there's a way to ensure the future ends. AbortHandle is not an +403 // option +404 Self { watcher } +405 } +406} +407 +408impl Stream for AddressDiscovery { +409 type Item = SocketAddr; +410 +411 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { +412 Pin::new(&mut self.watcher).poll_next(cx) 413 } -414} -415 -416impl Stream for AddressDiscovery { -417 type Item = SocketAddr; -418 -419 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { -420 Pin::new(&mut self.watcher).poll_next(cx) -421 } -422} \ No newline at end of file +414} \ No newline at end of file diff --git a/pr/523/docs/src/noq/recv_stream.rs.html b/pr/523/docs/src/noq/recv_stream.rs.html index 2f99b5538..01129b36a 100644 --- a/pr/523/docs/src/noq/recv_stream.rs.html +++ b/pr/523/docs/src/noq/recv_stream.rs.html @@ -268,12 +268,12 @@ 268 /// Discards unread data and notifies the peer to stop transmitting. Once stopped, further 269 /// attempts to operate on a stream will yield `ClosedStream` errors. 270 pub fn stop(&mut self, error_code: VarInt) -> Result<(), ClosedStream> { -271 let mut conn = self.conn.state.lock("RecvStream::stop"); +271 let mut conn = self.conn.lock_and_wake("RecvStream::stop"); 272 if self.is_0rtt && conn.check_0rtt().is_err() { -273 return Ok(()); -274 } -275 conn.inner.recv_stream(self.stream).stop(error_code)?; -276 conn.wake(); +273 conn.skip_waking(); +274 return Ok(()); +275 } +276 conn.inner.recv_stream(self.stream).stop(error_code)?; 277 self.all_data_read = true; 278 Ok(()) 279 } @@ -301,7 +301,7 @@ 301 /// This operation is cancel-safe. 302 pub async fn received_reset(&mut self) -> Result<Option<VarInt>, ResetError> { 303 poll_fn(|cx| { -304 let mut conn = self.conn.state.lock("RecvStream::reset"); +304 let mut conn = self.conn.lock_without_waking("RecvStream::reset"); 305 if self.is_0rtt && conn.check_0rtt().is_err() { 306 return Poll::Ready(Err(ResetError::ZeroRttRejected)); 307 } @@ -354,7 +354,7 @@ 354 return Poll::Ready(Ok(None)); 355 } 356 -357 let mut conn = self.conn.state.lock("RecvStream::poll_read"); +357 let mut conn = self.conn.lock_without_waking("RecvStream::poll_read"); 358 if self.is_0rtt { 359 conn.check_0rtt().map_err(|()| ReadError::ZeroRttRejected)?; 360 } @@ -581,18 +581,18 @@ 581 582impl Drop for RecvStream { 583 fn drop(&mut self) { -584 let mut conn = self.conn.state.lock("RecvStream::drop"); +584 let mut conn = self.conn.lock_and_wake("RecvStream::drop"); 585 586 // clean up any previously registered wakers 587 conn.blocked_readers.remove(&self.stream); 588 589 if conn.error.is_some() || (self.is_0rtt && conn.check_0rtt().is_err()) { -590 return; -591 } -592 if !self.all_data_read { -593 // Ignore ClosedStream errors -594 let _ = conn.inner.recv_stream(self.stream).stop(0u32.into()); -595 conn.wake(); +590 conn.skip_waking(); +591 return; +592 } +593 if !self.all_data_read { +594 // Ignore ClosedStream errors +595 let _ = conn.inner.recv_stream(self.stream).stop(0u32.into()); 596 } 597 } 598} diff --git a/pr/523/docs/src/noq/send_stream.rs.html b/pr/523/docs/src/noq/send_stream.rs.html index e27304db2..3978c2371 100644 --- a/pr/523/docs/src/noq/send_stream.rs.html +++ b/pr/523/docs/src/noq/send_stream.rs.html @@ -145,338 +145,345 @@ 145 F: FnOnce(&mut proto::SendStream<'_>) -> Result<R, proto::WriteError>, 146 { 147 use proto::WriteError::*; -148 let mut conn = self.conn.state.lock("SendStream::poll_write"); -149 if self.is_0rtt { -150 conn.check_0rtt() -151 .map_err(|()| WriteError::ZeroRttRejected)?; +148 let mut conn = self.conn.lock_and_wake("SendStream::poll_write"); +149 if self.is_0rtt && conn.check_0rtt().is_err() { +150 conn.skip_waking(); +151 return Poll::Ready(Err(WriteError::ZeroRttRejected)); 152 } -153 if let Some(ref x) = conn.error { -154 return Poll::Ready(Err(WriteError::ConnectionLost(x.clone()))); -155 } -156 -157 let result = match write_fn(&mut conn.inner.send_stream(self.stream)) { -158 Ok(result) => result, -159 Err(Blocked) => { -160 conn.blocked_writers.insert(self.stream, cx.waker().clone()); -161 return Poll::Pending; -162 } -163 Err(Stopped(error_code)) => { -164 return Poll::Ready(Err(WriteError::Stopped(error_code))); -165 } -166 Err(ClosedStream) => { -167 return Poll::Ready(Err(WriteError::ClosedStream)); +153 if let Some(conn_err) = conn.error.clone() { +154 conn.skip_waking(); +155 return Poll::Ready(Err(WriteError::ConnectionLost(conn_err))); +156 } +157 +158 let result = match write_fn(&mut conn.inner.send_stream(self.stream)) { +159 Ok(result) => result, +160 Err(Blocked) => { +161 conn.blocked_writers.insert(self.stream, cx.waker().clone()); +162 conn.skip_waking(); +163 return Poll::Pending; +164 } +165 Err(Stopped(error_code)) => { +166 conn.skip_waking(); +167 return Poll::Ready(Err(WriteError::Stopped(error_code))); 168 } -169 }; -170 -171 conn.wake(); -172 Poll::Ready(Ok(result)) -173 } +169 Err(ClosedStream) => { +170 conn.skip_waking(); +171 return Poll::Ready(Err(WriteError::ClosedStream)); +172 } +173 }; 174 -175 /// Notify the peer that no more data will ever be written to this stream -176 /// -177 /// It is an error to write to a [`SendStream`] after `finish()`ing it. [`reset()`](Self::reset) -178 /// may still be called after `finish` to abandon transmission of any stream data that might -179 /// still be buffered. -180 /// -181 /// To wait for the peer to receive all buffered stream data, see [`stopped()`](Self::stopped). -182 /// -183 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously -184 /// called. This error is harmless and serves only to indicate that the caller may have -185 /// incorrect assumptions about the stream's state. -186 pub fn finish(&mut self) -> Result<(), ClosedStream> { -187 let mut conn = self.conn.state.lock("finish"); -188 match conn.inner.send_stream(self.stream).finish() { -189 Ok(()) => { -190 conn.wake(); -191 Ok(()) -192 } -193 Err(FinishError::ClosedStream) => Err(ClosedStream::default()), -194 // Harmless. If the application needs to know about stopped streams at this point, it -195 // should call `stopped`. -196 Err(FinishError::Stopped(_)) => Ok(()), -197 } -198 } -199 -200 /// Close the send stream immediately. -201 /// -202 /// No new data can be written after calling this method. Locally buffered data is dropped, and -203 /// previously transmitted data will no longer be retransmitted if lost. If an attempt has -204 /// already been made to finish the stream, the peer may still receive all written data. +175 Poll::Ready(Ok(result)) +176 } +177 +178 /// Notify the peer that no more data will ever be written to this stream +179 /// +180 /// It is an error to write to a [`SendStream`] after `finish()`ing it. [`reset()`](Self::reset) +181 /// may still be called after `finish` to abandon transmission of any stream data that might +182 /// still be buffered. +183 /// +184 /// To wait for the peer to receive all buffered stream data, see [`stopped()`](Self::stopped). +185 /// +186 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously +187 /// called. This error is harmless and serves only to indicate that the caller may have +188 /// incorrect assumptions about the stream's state. +189 pub fn finish(&mut self) -> Result<(), ClosedStream> { +190 let mut conn = self.conn.lock_and_wake("finish"); +191 if let Err(e) = conn.inner.send_stream(self.stream).finish() { +192 conn.skip_waking(); +193 match e { +194 FinishError::ClosedStream => Err(ClosedStream::default()), +195 // Harmless. If the application needs to know about stopped streams at this point, it +196 // should call `stopped`. +197 FinishError::Stopped(_) => Ok(()), +198 } +199 } else { +200 Ok(()) +201 } +202 } +203 +204 /// Close the send stream immediately. 205 /// -206 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously -207 /// called. This error is harmless and serves only to indicate that the caller may have -208 /// incorrect assumptions about the stream's state. -209 pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream> { -210 let mut conn = self.conn.state.lock("SendStream::reset"); -211 if self.is_0rtt && conn.check_0rtt().is_err() { -212 return Ok(()); -213 } -214 conn.inner.send_stream(self.stream).reset(error_code)?; -215 conn.wake(); -216 Ok(()) -217 } -218 -219 /// Set the priority of the send stream -220 /// -221 /// Every send stream has an initial priority of 0. Locally buffered data from streams with -222 /// higher priority will be transmitted before data from streams with lower priority. Changing -223 /// the priority of a stream with pending data may only take effect after that data has been -224 /// transmitted. Using many different priority levels per connection may have a negative -225 /// impact on performance. -226 pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream> { -227 let mut conn = self.conn.state.lock("SendStream::set_priority"); -228 conn.inner.send_stream(self.stream).set_priority(priority)?; -229 Ok(()) -230 } -231 -232 /// Get the priority of the send stream -233 pub fn priority(&self) -> Result<i32, ClosedStream> { -234 let mut conn = self.conn.state.lock("SendStream::priority"); -235 conn.inner.send_stream(self.stream).priority() -236 } -237 -238 /// Completes when the peer stops the stream or reads the stream to completion -239 /// -240 /// Yields `Some` with the stop error code if the peer stops the stream. Yields `None` if the -241 /// local side [`finish()`](Self::finish)es the stream and then the peer acknowledges receipt -242 /// of all stream data (although not necessarily the processing of it), after which the peer -243 /// closing the stream is no longer meaningful. -244 /// -245 /// For a variety of reasons, the peer may not send acknowledgements immediately upon receiving -246 /// data. As such, relying on `stopped` to know when the peer has read a stream to completion -247 /// may introduce more latency than using an application-level response of some sort. -248 pub fn stopped(&self) -> Stopped { -249 let notified = { -250 // Create an `OwnedNotified` to move into the future. By creating it before the first poll, -251 // we make sure that we don't miss any notifications. -252 let mut conn = self.conn.state.lock("SendStream::stopped"); -253 conn.stopped -254 .entry(self.stream) -255 .or_default() -256 .clone() -257 .notified_owned() -258 }; -259 Stopped { -260 conn: self.conn.clone(), -261 stream: self.stream, -262 is_0rtt: self.is_0rtt, -263 notified, -264 } -265 } -266 -267 /// Get the identity of this stream -268 pub fn id(&self) -> StreamId { -269 self.stream -270 } -271 -272 /// Attempt to write bytes from buf into the stream. -273 /// -274 /// On success, returns Poll::Ready(Ok(num_bytes_written)). -275 /// -276 /// If the stream is not ready for writing, the method returns Poll::Pending and arranges -277 /// for the current task (via cx.waker().wake_by_ref()) to receive a notification when the -278 /// stream becomes writable or is closed. -279 pub fn poll_write( -280 self: Pin<&mut Self>, -281 cx: &mut Context<'_>, -282 buf: &[u8], -283 ) -> Poll<Result<usize, WriteError>> { -284 pin!(self.get_mut().write(buf)).as_mut().poll(cx) -285 } -286} -287 -288/// Check if a send stream is stopped. -289/// -290/// Returns `Some` if the stream is stopped or the connection is closed. -291/// Returns `None` if the stream is not stopped. -292fn send_stream_stopped( -293 conn: &mut State, -294 stream: StreamId, -295 is_0rtt: bool, -296) -> Option<Result<Option<VarInt>, StoppedError>> { -297 if is_0rtt && conn.check_0rtt().is_err() { -298 return Some(Err(StoppedError::ZeroRttRejected)); -299 } -300 match conn.inner.send_stream(stream).stopped() { -301 Err(ClosedStream { .. }) => Some(Ok(None)), -302 Ok(Some(error_code)) => Some(Ok(Some(error_code))), -303 Ok(None) => conn.error.clone().map(|error| Err(error.into())), -304 } -305} -306 -307#[cfg(feature = "futures-io")] -308impl futures_io::AsyncWrite for SendStream { -309 fn poll_write( -310 self: Pin<&mut Self>, -311 cx: &mut Context<'_>, -312 buf: &[u8], -313 ) -> Poll<io::Result<usize>> { -314 self.poll_write(cx, buf).map_err(Into::into) -315 } -316 -317 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -318 Poll::Ready(Ok(())) +206 /// No new data can be written after calling this method. Locally buffered data is dropped, and +207 /// previously transmitted data will no longer be retransmitted if lost. If an attempt has +208 /// already been made to finish the stream, the peer may still receive all written data. +209 /// +210 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously +211 /// called. This error is harmless and serves only to indicate that the caller may have +212 /// incorrect assumptions about the stream's state. +213 pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream> { +214 let mut conn = self.conn.lock_and_wake("SendStream::reset"); +215 if self.is_0rtt && conn.check_0rtt().is_err() { +216 conn.skip_waking(); +217 return Ok(()); +218 } +219 conn.inner.send_stream(self.stream).reset(error_code)?; +220 Ok(()) +221 } +222 +223 /// Set the priority of the send stream +224 /// +225 /// Every send stream has an initial priority of 0. Locally buffered data from streams with +226 /// higher priority will be transmitted before data from streams with lower priority. Changing +227 /// the priority of a stream with pending data may only take effect after that data has been +228 /// transmitted. Using many different priority levels per connection may have a negative +229 /// impact on performance. +230 pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream> { +231 let mut conn = self.conn.lock_without_waking("SendStream::set_priority"); +232 conn.inner.send_stream(self.stream).set_priority(priority)?; +233 Ok(()) +234 } +235 +236 /// Get the priority of the send stream +237 pub fn priority(&self) -> Result<i32, ClosedStream> { +238 let mut conn = self.conn.lock_without_waking("SendStream::priority"); +239 conn.inner.send_stream(self.stream).priority() +240 } +241 +242 /// Completes when the peer stops the stream or reads the stream to completion +243 /// +244 /// Yields `Some` with the stop error code if the peer stops the stream. Yields `None` if the +245 /// local side [`finish()`](Self::finish)es the stream and then the peer acknowledges receipt +246 /// of all stream data (although not necessarily the processing of it), after which the peer +247 /// closing the stream is no longer meaningful. +248 /// +249 /// For a variety of reasons, the peer may not send acknowledgements immediately upon receiving +250 /// data. As such, relying on `stopped` to know when the peer has read a stream to completion +251 /// may introduce more latency than using an application-level response of some sort. +252 pub fn stopped(&self) -> Stopped { +253 let notified = { +254 // Create an `OwnedNotified` to move into the future. By creating it before the first poll, +255 // we make sure that we don't miss any notifications. +256 let mut conn = self.conn.lock_without_waking("SendStream::stopped"); +257 conn.stopped +258 .entry(self.stream) +259 .or_default() +260 .clone() +261 .notified_owned() +262 }; +263 Stopped { +264 conn: self.conn.clone(), +265 stream: self.stream, +266 is_0rtt: self.is_0rtt, +267 notified, +268 } +269 } +270 +271 /// Get the identity of this stream +272 pub fn id(&self) -> StreamId { +273 self.stream +274 } +275 +276 /// Attempt to write bytes from buf into the stream. +277 /// +278 /// On success, returns Poll::Ready(Ok(num_bytes_written)). +279 /// +280 /// If the stream is not ready for writing, the method returns Poll::Pending and arranges +281 /// for the current task (via cx.waker().wake_by_ref()) to receive a notification when the +282 /// stream becomes writable or is closed. +283 pub fn poll_write( +284 self: Pin<&mut Self>, +285 cx: &mut Context<'_>, +286 buf: &[u8], +287 ) -> Poll<Result<usize, WriteError>> { +288 pin!(self.get_mut().write(buf)).as_mut().poll(cx) +289 } +290} +291 +292/// Check if a send stream is stopped. +293/// +294/// Returns `Some` if the stream is stopped or the connection is closed. +295/// Returns `None` if the stream is not stopped. +296fn send_stream_stopped( +297 conn: &mut State, +298 stream: StreamId, +299 is_0rtt: bool, +300) -> Option<Result<Option<VarInt>, StoppedError>> { +301 if is_0rtt && conn.check_0rtt().is_err() { +302 return Some(Err(StoppedError::ZeroRttRejected)); +303 } +304 match conn.inner.send_stream(stream).stopped() { +305 Err(ClosedStream { .. }) => Some(Ok(None)), +306 Ok(Some(error_code)) => Some(Ok(Some(error_code))), +307 Ok(None) => conn.error.clone().map(|error| Err(error.into())), +308 } +309} +310 +311#[cfg(feature = "futures-io")] +312impl futures_io::AsyncWrite for SendStream { +313 fn poll_write( +314 self: Pin<&mut Self>, +315 cx: &mut Context<'_>, +316 buf: &[u8], +317 ) -> Poll<io::Result<usize>> { +318 self.poll_write(cx, buf).map_err(Into::into) 319 } 320 -321 fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -322 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +321 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +322 Poll::Ready(Ok(())) 323 } -324} -325 -326impl tokio::io::AsyncWrite for SendStream { -327 fn poll_write( -328 self: Pin<&mut Self>, -329 cx: &mut Context<'_>, -330 buf: &[u8], -331 ) -> Poll<io::Result<usize>> { -332 self.poll_write(cx, buf).map_err(Into::into) -333 } -334 -335 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -336 Poll::Ready(Ok(())) +324 +325 fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +326 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +327 } +328} +329 +330impl tokio::io::AsyncWrite for SendStream { +331 fn poll_write( +332 self: Pin<&mut Self>, +333 cx: &mut Context<'_>, +334 buf: &[u8], +335 ) -> Poll<io::Result<usize>> { +336 self.poll_write(cx, buf).map_err(Into::into) 337 } 338 -339 fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -340 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +339 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +340 Poll::Ready(Ok(())) 341 } -342} -343 -344impl Drop for SendStream { -345 fn drop(&mut self) { -346 let mut conn = self.conn.state.lock("SendStream::drop"); +342 +343 fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +344 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +345 } +346} 347 -348 // clean up any previously registered wakers -349 conn.blocked_writers.remove(&self.stream); -350 -351 if conn.error.is_some() || (self.is_0rtt && conn.check_0rtt().is_err()) { -352 return; -353 } -354 match conn.inner.send_stream(self.stream).finish() { -355 Ok(()) => conn.wake(), -356 Err(FinishError::Stopped(reason)) => { -357 if conn.inner.send_stream(self.stream).reset(reason).is_ok() { -358 conn.wake(); -359 } -360 } -361 // Already finished or reset, which is fine. -362 Err(FinishError::ClosedStream) => {} -363 } -364 } -365} -366 -367/// Errors that arise from writing to a stream -368#[derive(Debug, Error, Clone, PartialEq, Eq)] -369pub enum WriteError { -370 /// The peer is no longer accepting data on this stream -371 /// -372 /// Carries an application-defined error code. -373 #[error("sending stopped by peer: error {0}")] -374 Stopped(VarInt), -375 /// The connection was lost -376 #[error("connection lost")] -377 ConnectionLost(#[from] ConnectionError), -378 /// The stream has already been finished or reset -379 #[error("closed stream")] -380 ClosedStream, -381 /// This was a 0-RTT stream and the server rejected it -382 /// -383 /// Can only occur on clients for 0-RTT streams, which can be opened using -384 /// [`Connecting::into_0rtt()`]. -385 /// -386 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() -387 #[error("0-RTT rejected")] -388 ZeroRttRejected, -389} -390 -391impl From<ClosedStream> for WriteError { -392 #[inline] -393 fn from(_: ClosedStream) -> Self { -394 Self::ClosedStream -395 } +348impl Drop for SendStream { +349 fn drop(&mut self) { +350 let mut conn = self.conn.lock_and_wake("SendStream::drop"); +351 +352 // clean up any previously registered wakers +353 conn.blocked_writers.remove(&self.stream); +354 +355 if conn.error.is_some() || (self.is_0rtt && conn.check_0rtt().is_err()) { +356 conn.skip_waking(); +357 return; +358 } +359 match conn.inner.send_stream(self.stream).finish() { +360 Ok(()) => {} +361 Err(FinishError::Stopped(reason)) => { +362 if conn.inner.send_stream(self.stream).reset(reason).is_err() { +363 conn.skip_waking() +364 } +365 } +366 // Already finished or reset, which is fine. +367 Err(FinishError::ClosedStream) => { +368 conn.skip_waking(); +369 } +370 } +371 } +372} +373 +374/// Errors that arise from writing to a stream +375#[derive(Debug, Error, Clone, PartialEq, Eq)] +376pub enum WriteError { +377 /// The peer is no longer accepting data on this stream +378 /// +379 /// Carries an application-defined error code. +380 #[error("sending stopped by peer: error {0}")] +381 Stopped(VarInt), +382 /// The connection was lost +383 #[error("connection lost")] +384 ConnectionLost(#[from] ConnectionError), +385 /// The stream has already been finished or reset +386 #[error("closed stream")] +387 ClosedStream, +388 /// This was a 0-RTT stream and the server rejected it +389 /// +390 /// Can only occur on clients for 0-RTT streams, which can be opened using +391 /// [`Connecting::into_0rtt()`]. +392 /// +393 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() +394 #[error("0-RTT rejected")] +395 ZeroRttRejected, 396} 397 -398impl From<StoppedError> for WriteError { -399 fn from(x: StoppedError) -> Self { -400 match x { -401 StoppedError::ConnectionLost(e) => Self::ConnectionLost(e), -402 StoppedError::ZeroRttRejected => Self::ZeroRttRejected, -403 } -404 } -405} -406 -407impl From<WriteError> for io::Error { -408 fn from(x: WriteError) -> Self { -409 use WriteError::*; -410 let kind = match x { -411 Stopped(_) | ZeroRttRejected => io::ErrorKind::ConnectionReset, -412 ConnectionLost(_) | ClosedStream => io::ErrorKind::NotConnected, -413 }; -414 Self::new(kind, x) -415 } -416} -417 -418/// Errors that arise while monitoring for a send stream stop from the peer -419#[derive(Debug, Error, Clone, PartialEq, Eq)] -420pub enum StoppedError { -421 /// The connection was lost -422 #[error("connection lost")] -423 ConnectionLost(#[from] ConnectionError), -424 /// This was a 0-RTT stream and the server rejected it -425 /// -426 /// Can only occur on clients for 0-RTT streams, which can be opened using -427 /// [`Connecting::into_0rtt()`]. -428 /// -429 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() -430 #[error("0-RTT rejected")] -431 ZeroRttRejected, -432} -433 -434impl From<StoppedError> for io::Error { -435 fn from(x: StoppedError) -> Self { -436 use StoppedError::*; -437 let kind = match x { -438 ZeroRttRejected => io::ErrorKind::ConnectionReset, -439 ConnectionLost(_) => io::ErrorKind::NotConnected, -440 }; -441 Self::new(kind, x) -442 } -443} -444 -445pin_project! { -446 /// Future returned from [`SendStream::stopped`]. -447 #[derive(Debug)] -448 pub struct Stopped { -449 conn: ConnectionRef, -450 stream: StreamId, -451 is_0rtt: bool, -452 #[pin] -453 notified: OwnedNotified, -454 } -455} -456 -457impl Future for Stopped { -458 type Output = Result<Option<VarInt>, StoppedError>; -459 -460 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -461 let mut this = self.project(); -462 loop { -463 let mut conn = this.conn.state.lock("SendStream::stopped"); -464 // Check if the stream is stopped before polling the notify. This makes sure that -465 // no wakeups are missed. -466 if let Some(output) = send_stream_stopped(&mut conn, *this.stream, *this.is_0rtt) { -467 return Poll::Ready(output); -468 } -469 std::task::ready!(this.notified.as_mut().poll(cx)); -470 } -471 } -472} -473 -474#[cfg(test)] -475mod tests { -476 fn check_is_send_sync<A: Send + Sync>() {} -477 -478 #[allow(dead_code)] -479 fn test_bounds() { -480 check_is_send_sync::<super::Stopped>(); -481 } -482} \ No newline at end of file +398impl From<ClosedStream> for WriteError { +399 #[inline] +400 fn from(_: ClosedStream) -> Self { +401 Self::ClosedStream +402 } +403} +404 +405impl From<StoppedError> for WriteError { +406 fn from(x: StoppedError) -> Self { +407 match x { +408 StoppedError::ConnectionLost(e) => Self::ConnectionLost(e), +409 StoppedError::ZeroRttRejected => Self::ZeroRttRejected, +410 } +411 } +412} +413 +414impl From<WriteError> for io::Error { +415 fn from(x: WriteError) -> Self { +416 use WriteError::*; +417 let kind = match x { +418 Stopped(_) | ZeroRttRejected => io::ErrorKind::ConnectionReset, +419 ConnectionLost(_) | ClosedStream => io::ErrorKind::NotConnected, +420 }; +421 Self::new(kind, x) +422 } +423} +424 +425/// Errors that arise while monitoring for a send stream stop from the peer +426#[derive(Debug, Error, Clone, PartialEq, Eq)] +427pub enum StoppedError { +428 /// The connection was lost +429 #[error("connection lost")] +430 ConnectionLost(#[from] ConnectionError), +431 /// This was a 0-RTT stream and the server rejected it +432 /// +433 /// Can only occur on clients for 0-RTT streams, which can be opened using +434 /// [`Connecting::into_0rtt()`]. +435 /// +436 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() +437 #[error("0-RTT rejected")] +438 ZeroRttRejected, +439} +440 +441impl From<StoppedError> for io::Error { +442 fn from(x: StoppedError) -> Self { +443 use StoppedError::*; +444 let kind = match x { +445 ZeroRttRejected => io::ErrorKind::ConnectionReset, +446 ConnectionLost(_) => io::ErrorKind::NotConnected, +447 }; +448 Self::new(kind, x) +449 } +450} +451 +452pin_project! { +453 /// Future returned from [`SendStream::stopped`]. +454 #[derive(Debug)] +455 pub struct Stopped { +456 conn: ConnectionRef, +457 stream: StreamId, +458 is_0rtt: bool, +459 #[pin] +460 notified: OwnedNotified, +461 } +462} +463 +464impl Future for Stopped { +465 type Output = Result<Option<VarInt>, StoppedError>; +466 +467 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +468 let mut this = self.project(); +469 loop { +470 let mut conn = this.conn.lock_without_waking("SendStream::stopped"); +471 // Check if the stream is stopped before polling the notify. This makes sure that +472 // no wakeups are missed. +473 if let Some(output) = send_stream_stopped(&mut conn, *this.stream, *this.is_0rtt) { +474 return Poll::Ready(output); +475 } +476 std::task::ready!(this.notified.as_mut().poll(cx)); +477 } +478 } +479} +480 +481#[cfg(test)] +482mod tests { +483 fn check_is_send_sync<A: Send + Sync>() {} +484 +485 #[allow(dead_code)] +486 fn test_bounds() { +487 check_is_send_sync::<super::Stopped>(); +488 } +489} \ No newline at end of file diff --git a/pr/523/docs/src/noq_proto/connection/mod.rs.html b/pr/523/docs/src/noq_proto/connection/mod.rs.html index 3703ae12f..affdeeea6 100644 --- a/pr/523/docs/src/noq_proto/connection/mod.rs.html +++ b/pr/523/docs/src/noq_proto/connection/mod.rs.html @@ -3465,4091 +3465,4094 @@ 3465 3466 // Compute the PTO duration for this space, we want to cap the maximum interval 3467 // between two tail-loss probes so do not do a simple exponential backoff but -3468 // rather iterate through the probes. -3469 let duration = { -3470 let pto_base = path.rtt.pto_base() -3471 + if space == SpaceId::Data { -3472 self.ack_frequency.max_ack_delay_for_pto() -3473 } else { -3474 Duration::ZERO -3475 }; -3476 let mut duration = pto_base; -3477 for i in 0..pto_count { -3478 let increment = (i + 1) * pto_base; -3479 duration += increment.min(max_interval); -3480 } -3481 duration -3482 }; -3483 -3484 let Some(last_ack_eliciting) = pns.time_of_last_ack_eliciting_packet else { -3485 continue; -3486 }; -3487 // Base the deadline on when the last probe was sent, so the PTO -3488 // doesn't fire before the response has had time to arrive. -3489 let pto = last_ack_eliciting + duration; -3490 if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) { -3491 if path.anti_amplification_blocked(1) { -3492 // Nothing would be able to be sent. -3493 continue; -3494 } -3495 if path.in_flight.ack_eliciting == 0 { -3496 // Nothing ack-eliciting, no PTO to arm/fire. -3497 continue; -3498 } -3499 result = Some((pto, space)); -3500 } -3501 } -3502 result -3503 } -3504 -3505 fn peer_completed_address_validation(&self, path: PathId) -> bool { -3506 // TODO(flub): This logic needs updating for multipath -3507 if self.side.is_server() || self.state.is_closed() { -3508 return true; -3509 } -3510 // The server is guaranteed to have validated our address if any of our handshake or 1-RTT -3511 // packets are acknowledged or we've seen HANDSHAKE_DONE and discarded handshake keys. -3512 self.spaces[SpaceId::Handshake] -3513 .path_space(PathId::ZERO) -3514 .and_then(|pns| pns.largest_acked_packet) -3515 .is_some() -3516 || self.spaces[SpaceId::Data] -3517 .path_space(path) -3518 .and_then(|pns| pns.largest_acked_packet) -3519 .is_some() -3520 || (self.crypto_state.has_keys(EncryptionLevel::OneRtt) -3521 && !self.crypto_state.has_keys(EncryptionLevel::Handshake)) -3522 } -3523 -3524 /// Resets the the [`PathTimer::LossDetection`] timer to the next instant it may be needed -3525 /// -3526 /// The timer must fire if either: -3527 /// - An ack-eliciting packet we sent needs to be declared lost. -3528 /// - A tail-loss probe needs to be sent. -3529 /// -3530 /// See [`Connection::on_loss_detection_timeout`] for details. -3531 fn set_loss_detection_timer(&mut self, now: Instant, path_id: PathId) { -3532 if self.state.is_closed() { -3533 // No loss detection takes place on closed connections, and `close_common` already -3534 // stopped time timer. Ensure we don't restart it inadvertently, e.g. in response to a -3535 // reordered packet being handled by state-insensitive code. -3536 return; -3537 } -3538 -3539 if let Some((loss_time, _)) = self.loss_time_and_space(path_id) { -3540 // Time threshold loss detection. -3541 self.timers.set( -3542 Timer::PerPath(path_id, PathTimer::LossDetection), -3543 loss_time, -3544 self.qlog.with_time(now), -3545 ); -3546 return; -3547 } -3548 -3549 // Determine which PN space to arm PTO for. -3550 // Calculate PTO duration -3551 if let Some((timeout, _)) = self.pto_time_and_space(now, path_id) { -3552 self.timers.set( -3553 Timer::PerPath(path_id, PathTimer::LossDetection), -3554 timeout, -3555 self.qlog.with_time(now), -3556 ); -3557 } else { -3558 self.timers.stop( -3559 Timer::PerPath(path_id, PathTimer::LossDetection), -3560 self.qlog.with_time(now), -3561 ); -3562 } -3563 } -3564 -3565 /// The maximum probe timeout across all paths -3566 /// -3567 /// See [`Connection::pto`] -3568 fn max_pto_for_space(&self, space: SpaceKind) -> Duration { -3569 self.paths -3570 .keys() -3571 .map(|path_id| self.pto(space, *path_id)) -3572 .max() -3573 .unwrap_or_else(|| { -3574 // No paths remain (e.g. last path was abandoned and the NoAvailablePath grace timer -3575 // fired before any new path was opened). Fall back to a PTO derived from the -3576 // configured initial RTT, matching RFC 9002 §6.2.2 initial values. -3577 let rtt = self.config.initial_rtt; -3578 let max_ack_delay = match space { -3579 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, -3580 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), -3581 }; -3582 rtt + cmp::max(4 * (rtt / 2), TIMER_GRANULARITY) + max_ack_delay -3583 }) -3584 } -3585 -3586 /// Probe Timeout -3587 /// -3588 /// The PTO is logically the time in which you'd expect to receive an acknowledgement -3589 /// for a packet. So approximately RTT + max_ack_delay. -3590 fn pto(&self, space: SpaceKind, path_id: PathId) -> Duration { -3591 let max_ack_delay = match space { -3592 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, -3593 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), -3594 }; -3595 self.path_data(path_id).rtt.pto_base() + max_ack_delay -3596 } -3597 -3598 fn on_packet_authenticated( -3599 &mut self, -3600 now: Instant, -3601 space_id: SpaceKind, -3602 path_id: PathId, -3603 ecn: Option<EcnCodepoint>, -3604 packet: Option<u64>, -3605 spin: bool, -3606 is_1rtt: bool, -3607 ) { -3608 self.total_authed_packets += 1; -3609 self.reset_keep_alive(path_id, now); -3610 self.reset_idle_timeout(now, space_id, path_id); -3611 self.permit_idle_reset = true; -3612 self.receiving_ecn |= ecn.is_some(); -3613 if let Some(x) = ecn { -3614 let space = &mut self.spaces[space_id]; -3615 space.for_path(path_id).ecn_counters += x; -3616 -3617 if x.is_ce() { -3618 space -3619 .for_path(path_id) -3620 .pending_acks -3621 .set_immediate_ack_required(); -3622 } -3623 } -3624 -3625 let Some(packet) = packet else { -3626 return; -3627 }; -3628 match &self.side { -3629 ConnectionSide::Client { .. } => { -3630 // If we received a handshake packet that authenticated, then we're talking to -3631 // the real server. From now on we should no longer allow the server to migrate -3632 // its address. -3633 if space_id == SpaceKind::Handshake -3634 && let Some(hs) = self.state.as_handshake_mut() -3635 { -3636 hs.allow_server_migration = false; -3637 } -3638 } -3639 ConnectionSide::Server { .. } => { -3640 if self.crypto_state.has_keys(EncryptionLevel::Initial) -3641 && space_id == SpaceKind::Handshake -3642 { -3643 // A server stops sending and processing Initial packets when it receives its first Handshake packet. -3644 self.discard_space(now, SpaceKind::Initial); -3645 } -3646 if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) && is_1rtt { -3647 // Discard 0-RTT keys soon after receiving a 1-RTT packet -3648 self.set_key_discard_timer(now, space_id) -3649 } -3650 } -3651 } -3652 let space = self.spaces[space_id].for_path(path_id); -3653 space.pending_acks.insert_one(packet, now); -3654 if packet >= space.rx_packet.unwrap_or_default() { -3655 space.rx_packet = Some(packet); -3656 // Update outgoing spin bit, inverting iff we're the client -3657 self.spin = self.side.is_client() ^ spin; -3658 } -3659 } -3660 -3661 /// Resets the idle timeout timers -3662 /// -3663 /// Without multipath there is only the connection-wide idle timeout. When multipath is -3664 /// enabled there is an additional per-path idle timeout. -3665 fn reset_idle_timeout(&mut self, now: Instant, space: SpaceKind, path_id: PathId) { -3666 // First reset the global idle timeout. -3667 if let Some(timeout) = self.idle_timeout { -3668 if self.state.is_closed() { -3669 self.timers -3670 .stop(Timer::Conn(ConnTimer::Idle), self.qlog.with_time(now)); -3671 } else { -3672 let dt = cmp::max(timeout, 3 * self.max_pto_for_space(space)); -3673 self.timers.set( -3674 Timer::Conn(ConnTimer::Idle), -3675 now + dt, -3676 self.qlog.with_time(now), -3677 ); -3678 } -3679 } -3680 -3681 // Now handle the per-path state -3682 if let Some(timeout) = self.path_data(path_id).idle_timeout { -3683 if self.state.is_closed() { -3684 self.timers.stop( -3685 Timer::PerPath(path_id, PathTimer::PathIdle), -3686 self.qlog.with_time(now), -3687 ); -3688 } else { -3689 let dt = cmp::max(timeout, 3 * self.pto(space, path_id)); -3690 self.timers.set( -3691 Timer::PerPath(path_id, PathTimer::PathIdle), -3692 now + dt, -3693 self.qlog.with_time(now), -3694 ); -3695 } -3696 } -3697 } -3698 -3699 /// Resets both the [`ConnTimer::KeepAlive`] and [`PathTimer::PathKeepAlive`] timers -3700 fn reset_keep_alive(&mut self, path_id: PathId, now: Instant) { -3701 if !self.state.is_established() { -3702 return; -3703 } -3704 -3705 if let Some(interval) = self.config.keep_alive_interval { -3706 self.timers.set( -3707 Timer::Conn(ConnTimer::KeepAlive), -3708 now + interval, -3709 self.qlog.with_time(now), -3710 ); -3711 } -3712 -3713 if let Some(interval) = self.path_data(path_id).keep_alive { -3714 self.timers.set( -3715 Timer::PerPath(path_id, PathTimer::PathKeepAlive), -3716 now + interval, -3717 self.qlog.with_time(now), -3718 ); -3719 } -3720 } -3721 -3722 /// Sets the timer for when a previously issued CID should be retired next -3723 fn reset_cid_retirement(&mut self, now: Instant) { -3724 if let Some((_path, t)) = self.next_cid_retirement() { -3725 self.timers.set( -3726 Timer::Conn(ConnTimer::PushNewCid), -3727 t, -3728 self.qlog.with_time(now), -3729 ); -3730 } -3731 } -3732 -3733 /// The next time when a previously issued CID should be retired -3734 fn next_cid_retirement(&self) -> Option<(PathId, Instant)> { -3735 self.local_cid_state -3736 .iter() -3737 .filter_map(|(path_id, cid_state)| cid_state.next_timeout().map(|t| (*path_id, t))) -3738 .min_by_key(|(_path_id, timeout)| *timeout) -3739 } -3740 -3741 /// Handle the already-decrypted first packet from the client -3742 /// -3743 /// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more -3744 /// efficient. -3745 pub(crate) fn handle_first_packet( -3746 &mut self, -3747 now: Instant, -3748 network_path: FourTuple, -3749 ecn: Option<EcnCodepoint>, -3750 packet_number: u64, -3751 packet: InitialPacket, -3752 remaining: Option<BytesMut>, -3753 ) -> Result<(), ConnectionError> { -3754 let span = trace_span!("first recv"); -3755 let _guard = span.enter(); -3756 debug_assert!(self.side.is_server()); -3757 let len = packet.header_data.len() + packet.payload.len(); -3758 let path_id = PathId::ZERO; -3759 self.path_data_mut(path_id).total_recvd = len as u64; -3760 -3761 if let Some(hs) = self.state.as_handshake_mut() { -3762 hs.expected_token = packet.header.token.clone(); -3763 } else { -3764 unreachable!("first packet must be delivered in Handshake state"); -3765 } -3766 -3767 // The first packet is always on PathId::ZERO -3768 self.on_packet_authenticated( -3769 now, -3770 SpaceKind::Initial, -3771 path_id, -3772 ecn, -3773 Some(packet_number), -3774 false, -3775 false, -3776 ); -3777 -3778 let packet: Packet = packet.into(); -3779 -3780 let mut qlog = QlogRecvPacket::new(len); -3781 qlog.header(&packet.header, Some(packet_number), path_id); +3468 // rather iterate through the probes to compute the capped increment for an +3469 // exponential backoff. +3470 let duration = { +3471 let pto_base = path.rtt.pto_base() +3472 + if space == SpaceId::Data { +3473 self.ack_frequency.max_ack_delay_for_pto() +3474 } else { +3475 Duration::ZERO +3476 }; +3477 let mut duration = pto_base; +3478 for i in 0..pto_count { +3479 let exponential_duration = +3480 pto_base * 2u32.pow((i + 1).min(MAX_BACKOFF_EXPONENT)); +3481 let max_duration = duration + max_interval; +3482 duration = exponential_duration.min(max_duration); +3483 } +3484 duration +3485 }; +3486 +3487 let Some(last_ack_eliciting) = pns.time_of_last_ack_eliciting_packet else { +3488 continue; +3489 }; +3490 // Base the deadline on when the last probe was sent, so the PTO +3491 // doesn't fire before the response has had time to arrive. +3492 let pto = last_ack_eliciting + duration; +3493 if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) { +3494 if path.anti_amplification_blocked(1) { +3495 // Nothing would be able to be sent. +3496 continue; +3497 } +3498 if path.in_flight.ack_eliciting == 0 { +3499 // Nothing ack-eliciting, no PTO to arm/fire. +3500 continue; +3501 } +3502 result = Some((pto, space)); +3503 } +3504 } +3505 result +3506 } +3507 +3508 fn peer_completed_address_validation(&self, path: PathId) -> bool { +3509 // TODO(flub): This logic needs updating for multipath +3510 if self.side.is_server() || self.state.is_closed() { +3511 return true; +3512 } +3513 // The server is guaranteed to have validated our address if any of our handshake or 1-RTT +3514 // packets are acknowledged or we've seen HANDSHAKE_DONE and discarded handshake keys. +3515 self.spaces[SpaceId::Handshake] +3516 .path_space(PathId::ZERO) +3517 .and_then(|pns| pns.largest_acked_packet) +3518 .is_some() +3519 || self.spaces[SpaceId::Data] +3520 .path_space(path) +3521 .and_then(|pns| pns.largest_acked_packet) +3522 .is_some() +3523 || (self.crypto_state.has_keys(EncryptionLevel::OneRtt) +3524 && !self.crypto_state.has_keys(EncryptionLevel::Handshake)) +3525 } +3526 +3527 /// Resets the the [`PathTimer::LossDetection`] timer to the next instant it may be needed +3528 /// +3529 /// The timer must fire if either: +3530 /// - An ack-eliciting packet we sent needs to be declared lost. +3531 /// - A tail-loss probe needs to be sent. +3532 /// +3533 /// See [`Connection::on_loss_detection_timeout`] for details. +3534 fn set_loss_detection_timer(&mut self, now: Instant, path_id: PathId) { +3535 if self.state.is_closed() { +3536 // No loss detection takes place on closed connections, and `close_common` already +3537 // stopped time timer. Ensure we don't restart it inadvertently, e.g. in response to a +3538 // reordered packet being handled by state-insensitive code. +3539 return; +3540 } +3541 +3542 if let Some((loss_time, _)) = self.loss_time_and_space(path_id) { +3543 // Time threshold loss detection. +3544 self.timers.set( +3545 Timer::PerPath(path_id, PathTimer::LossDetection), +3546 loss_time, +3547 self.qlog.with_time(now), +3548 ); +3549 return; +3550 } +3551 +3552 // Determine which PN space to arm PTO for. +3553 // Calculate PTO duration +3554 if let Some((timeout, _)) = self.pto_time_and_space(now, path_id) { +3555 self.timers.set( +3556 Timer::PerPath(path_id, PathTimer::LossDetection), +3557 timeout, +3558 self.qlog.with_time(now), +3559 ); +3560 } else { +3561 self.timers.stop( +3562 Timer::PerPath(path_id, PathTimer::LossDetection), +3563 self.qlog.with_time(now), +3564 ); +3565 } +3566 } +3567 +3568 /// The maximum probe timeout across all paths +3569 /// +3570 /// See [`Connection::pto`] +3571 fn max_pto_for_space(&self, space: SpaceKind) -> Duration { +3572 self.paths +3573 .keys() +3574 .map(|path_id| self.pto(space, *path_id)) +3575 .max() +3576 .unwrap_or_else(|| { +3577 // No paths remain (e.g. last path was abandoned and the NoAvailablePath grace timer +3578 // fired before any new path was opened). Fall back to a PTO derived from the +3579 // configured initial RTT, matching RFC 9002 §6.2.2 initial values. +3580 let rtt = self.config.initial_rtt; +3581 let max_ack_delay = match space { +3582 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, +3583 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), +3584 }; +3585 rtt + cmp::max(4 * (rtt / 2), TIMER_GRANULARITY) + max_ack_delay +3586 }) +3587 } +3588 +3589 /// Probe Timeout +3590 /// +3591 /// The PTO is logically the time in which you'd expect to receive an acknowledgement +3592 /// for a packet. So approximately RTT + max_ack_delay. +3593 fn pto(&self, space: SpaceKind, path_id: PathId) -> Duration { +3594 let max_ack_delay = match space { +3595 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, +3596 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), +3597 }; +3598 self.path_data(path_id).rtt.pto_base() + max_ack_delay +3599 } +3600 +3601 fn on_packet_authenticated( +3602 &mut self, +3603 now: Instant, +3604 space_id: SpaceKind, +3605 path_id: PathId, +3606 ecn: Option<EcnCodepoint>, +3607 packet: Option<u64>, +3608 spin: bool, +3609 is_1rtt: bool, +3610 ) { +3611 self.total_authed_packets += 1; +3612 self.reset_keep_alive(path_id, now); +3613 self.reset_idle_timeout(now, space_id, path_id); +3614 self.permit_idle_reset = true; +3615 self.receiving_ecn |= ecn.is_some(); +3616 if let Some(x) = ecn { +3617 let space = &mut self.spaces[space_id]; +3618 space.for_path(path_id).ecn_counters += x; +3619 +3620 if x.is_ce() { +3621 space +3622 .for_path(path_id) +3623 .pending_acks +3624 .set_immediate_ack_required(); +3625 } +3626 } +3627 +3628 let Some(packet) = packet else { +3629 return; +3630 }; +3631 match &self.side { +3632 ConnectionSide::Client { .. } => { +3633 // If we received a handshake packet that authenticated, then we're talking to +3634 // the real server. From now on we should no longer allow the server to migrate +3635 // its address. +3636 if space_id == SpaceKind::Handshake +3637 && let Some(hs) = self.state.as_handshake_mut() +3638 { +3639 hs.allow_server_migration = false; +3640 } +3641 } +3642 ConnectionSide::Server { .. } => { +3643 if self.crypto_state.has_keys(EncryptionLevel::Initial) +3644 && space_id == SpaceKind::Handshake +3645 { +3646 // A server stops sending and processing Initial packets when it receives its first Handshake packet. +3647 self.discard_space(now, SpaceKind::Initial); +3648 } +3649 if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) && is_1rtt { +3650 // Discard 0-RTT keys soon after receiving a 1-RTT packet +3651 self.set_key_discard_timer(now, space_id) +3652 } +3653 } +3654 } +3655 let space = self.spaces[space_id].for_path(path_id); +3656 space.pending_acks.insert_one(packet, now); +3657 if packet >= space.rx_packet.unwrap_or_default() { +3658 space.rx_packet = Some(packet); +3659 // Update outgoing spin bit, inverting iff we're the client +3660 self.spin = self.side.is_client() ^ spin; +3661 } +3662 } +3663 +3664 /// Resets the idle timeout timers +3665 /// +3666 /// Without multipath there is only the connection-wide idle timeout. When multipath is +3667 /// enabled there is an additional per-path idle timeout. +3668 fn reset_idle_timeout(&mut self, now: Instant, space: SpaceKind, path_id: PathId) { +3669 // First reset the global idle timeout. +3670 if let Some(timeout) = self.idle_timeout { +3671 if self.state.is_closed() { +3672 self.timers +3673 .stop(Timer::Conn(ConnTimer::Idle), self.qlog.with_time(now)); +3674 } else { +3675 let dt = cmp::max(timeout, 3 * self.max_pto_for_space(space)); +3676 self.timers.set( +3677 Timer::Conn(ConnTimer::Idle), +3678 now + dt, +3679 self.qlog.with_time(now), +3680 ); +3681 } +3682 } +3683 +3684 // Now handle the per-path state +3685 if let Some(timeout) = self.path_data(path_id).idle_timeout { +3686 if self.state.is_closed() { +3687 self.timers.stop( +3688 Timer::PerPath(path_id, PathTimer::PathIdle), +3689 self.qlog.with_time(now), +3690 ); +3691 } else { +3692 let dt = cmp::max(timeout, 3 * self.pto(space, path_id)); +3693 self.timers.set( +3694 Timer::PerPath(path_id, PathTimer::PathIdle), +3695 now + dt, +3696 self.qlog.with_time(now), +3697 ); +3698 } +3699 } +3700 } +3701 +3702 /// Resets both the [`ConnTimer::KeepAlive`] and [`PathTimer::PathKeepAlive`] timers +3703 fn reset_keep_alive(&mut self, path_id: PathId, now: Instant) { +3704 if !self.state.is_established() { +3705 return; +3706 } +3707 +3708 if let Some(interval) = self.config.keep_alive_interval { +3709 self.timers.set( +3710 Timer::Conn(ConnTimer::KeepAlive), +3711 now + interval, +3712 self.qlog.with_time(now), +3713 ); +3714 } +3715 +3716 if let Some(interval) = self.path_data(path_id).keep_alive { +3717 self.timers.set( +3718 Timer::PerPath(path_id, PathTimer::PathKeepAlive), +3719 now + interval, +3720 self.qlog.with_time(now), +3721 ); +3722 } +3723 } +3724 +3725 /// Sets the timer for when a previously issued CID should be retired next +3726 fn reset_cid_retirement(&mut self, now: Instant) { +3727 if let Some((_path, t)) = self.next_cid_retirement() { +3728 self.timers.set( +3729 Timer::Conn(ConnTimer::PushNewCid), +3730 t, +3731 self.qlog.with_time(now), +3732 ); +3733 } +3734 } +3735 +3736 /// The next time when a previously issued CID should be retired +3737 fn next_cid_retirement(&self) -> Option<(PathId, Instant)> { +3738 self.local_cid_state +3739 .iter() +3740 .filter_map(|(path_id, cid_state)| cid_state.next_timeout().map(|t| (*path_id, t))) +3741 .min_by_key(|(_path_id, timeout)| *timeout) +3742 } +3743 +3744 /// Handle the already-decrypted first packet from the client +3745 /// +3746 /// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more +3747 /// efficient. +3748 pub(crate) fn handle_first_packet( +3749 &mut self, +3750 now: Instant, +3751 network_path: FourTuple, +3752 ecn: Option<EcnCodepoint>, +3753 packet_number: u64, +3754 packet: InitialPacket, +3755 remaining: Option<BytesMut>, +3756 ) -> Result<(), ConnectionError> { +3757 let span = trace_span!("first recv"); +3758 let _guard = span.enter(); +3759 debug_assert!(self.side.is_server()); +3760 let len = packet.header_data.len() + packet.payload.len(); +3761 let path_id = PathId::ZERO; +3762 self.path_data_mut(path_id).total_recvd = len as u64; +3763 +3764 if let Some(hs) = self.state.as_handshake_mut() { +3765 hs.expected_token = packet.header.token.clone(); +3766 } else { +3767 unreachable!("first packet must be delivered in Handshake state"); +3768 } +3769 +3770 // The first packet is always on PathId::ZERO +3771 self.on_packet_authenticated( +3772 now, +3773 SpaceKind::Initial, +3774 path_id, +3775 ecn, +3776 Some(packet_number), +3777 false, +3778 false, +3779 ); +3780 +3781 let packet: Packet = packet.into(); 3782 -3783 self.process_decrypted_packet( -3784 now, -3785 network_path, -3786 path_id, -3787 Some(packet_number), -3788 packet, -3789 &mut qlog, -3790 )?; -3791 self.qlog.emit_packet_received(qlog, now); -3792 if let Some(data) = remaining { -3793 self.handle_coalesced(now, network_path, path_id, ecn, data); -3794 } -3795 -3796 self.qlog.emit_recovery_metrics( -3797 path_id, -3798 &mut self.paths.get_mut(&path_id).unwrap().data, -3799 now, -3800 ); -3801 -3802 Ok(()) -3803 } +3783 let mut qlog = QlogRecvPacket::new(len); +3784 qlog.header(&packet.header, Some(packet_number), path_id); +3785 +3786 self.process_decrypted_packet( +3787 now, +3788 network_path, +3789 path_id, +3790 Some(packet_number), +3791 packet, +3792 &mut qlog, +3793 )?; +3794 self.qlog.emit_packet_received(qlog, now); +3795 if let Some(data) = remaining { +3796 self.handle_coalesced(now, network_path, path_id, ecn, data); +3797 } +3798 +3799 self.qlog.emit_recovery_metrics( +3800 path_id, +3801 &mut self.paths.get_mut(&path_id).unwrap().data, +3802 now, +3803 ); 3804 -3805 fn init_0rtt(&mut self, now: Instant) { -3806 let Some((header, packet)) = self.crypto_state.session.early_crypto() else { -3807 return; -3808 }; -3809 if self.side.is_client() { -3810 match self.crypto_state.session.transport_parameters() { -3811 Ok(params) => { -3812 let params = params -3813 .expect("crypto layer didn't supply transport parameters with ticket"); -3814 // Certain values must not be cached -3815 let params = TransportParameters { -3816 initial_src_cid: None, -3817 original_dst_cid: None, -3818 preferred_address: None, -3819 retry_src_cid: None, -3820 stateless_reset_token: None, -3821 min_ack_delay: None, -3822 ack_delay_exponent: TransportParameters::default().ack_delay_exponent, -3823 max_ack_delay: TransportParameters::default().max_ack_delay, -3824 initial_max_path_id: None, -3825 ..params -3826 }; -3827 self.set_peer_params(params); -3828 self.qlog.emit_peer_transport_params_restored(self, now); -3829 } -3830 Err(e) => { -3831 error!("session ticket has malformed transport parameters: {}", e); -3832 return; -3833 } -3834 } -3835 } -3836 trace!("0-RTT enabled"); -3837 self.crypto_state.enable_zero_rtt(header, packet); -3838 } -3839 -3840 fn read_crypto( -3841 &mut self, -3842 space: SpaceId, -3843 crypto: &frame::Crypto, -3844 payload_len: usize, -3845 ) -> Result<(), TransportError> { -3846 let expected = if !self.state.is_handshake() { -3847 SpaceId::Data -3848 } else if self.highest_space == SpaceKind::Initial { -3849 SpaceId::Initial -3850 } else { -3851 // On the server, self.highest_space can be Data after receiving the client's first -3852 // flight, but we expect Handshake CRYPTO until the handshake is complete. -3853 SpaceId::Handshake -3854 }; -3855 // We can't decrypt Handshake packets when highest_space is Initial, CRYPTO frames in 0-RTT -3856 // packets are illegal, and we don't process 1-RTT packets until the handshake is -3857 // complete. Therefore, we will never see CRYPTO data from a later-than-expected space. -3858 debug_assert!(space <= expected, "received out-of-order CRYPTO data"); -3859 -3860 let end = crypto.offset + crypto.data.len() as u64; -3861 if space < expected -3862 && end -3863 > self.crypto_state.spaces[space.kind()] -3864 .crypto_stream -3865 .bytes_read() -3866 { -3867 warn!( -3868 "received new {:?} CRYPTO data when expecting {:?}", -3869 space, expected -3870 ); -3871 return Err(TransportError::PROTOCOL_VIOLATION( -3872 "new data at unexpected encryption level", -3873 )); -3874 } -3875 -3876 let crypto_space = &mut self.crypto_state.spaces[space.kind()]; -3877 let max = end.saturating_sub(crypto_space.crypto_stream.bytes_read()); -3878 if max > self.config.crypto_buffer_size as u64 { -3879 return Err(TransportError::CRYPTO_BUFFER_EXCEEDED("")); -3880 } -3881 -3882 crypto_space -3883 .crypto_stream -3884 .insert(crypto.offset, crypto.data.clone(), payload_len); -3885 while let Some(chunk) = crypto_space.crypto_stream.read(usize::MAX, true) { -3886 trace!("consumed {} CRYPTO bytes", chunk.bytes.len()); -3887 if self.crypto_state.session.read_handshake(&chunk.bytes)? { -3888 self.events.push_back(Event::HandshakeDataReady); -3889 } -3890 } -3891 -3892 Ok(()) -3893 } +3805 Ok(()) +3806 } +3807 +3808 fn init_0rtt(&mut self, now: Instant) { +3809 let Some((header, packet)) = self.crypto_state.session.early_crypto() else { +3810 return; +3811 }; +3812 if self.side.is_client() { +3813 match self.crypto_state.session.transport_parameters() { +3814 Ok(params) => { +3815 let params = params +3816 .expect("crypto layer didn't supply transport parameters with ticket"); +3817 // Certain values must not be cached +3818 let params = TransportParameters { +3819 initial_src_cid: None, +3820 original_dst_cid: None, +3821 preferred_address: None, +3822 retry_src_cid: None, +3823 stateless_reset_token: None, +3824 min_ack_delay: None, +3825 ack_delay_exponent: TransportParameters::default().ack_delay_exponent, +3826 max_ack_delay: TransportParameters::default().max_ack_delay, +3827 initial_max_path_id: None, +3828 ..params +3829 }; +3830 self.set_peer_params(params); +3831 self.qlog.emit_peer_transport_params_restored(self, now); +3832 } +3833 Err(e) => { +3834 error!("session ticket has malformed transport parameters: {}", e); +3835 return; +3836 } +3837 } +3838 } +3839 trace!("0-RTT enabled"); +3840 self.crypto_state.enable_zero_rtt(header, packet); +3841 } +3842 +3843 fn read_crypto( +3844 &mut self, +3845 space: SpaceId, +3846 crypto: &frame::Crypto, +3847 payload_len: usize, +3848 ) -> Result<(), TransportError> { +3849 let expected = if !self.state.is_handshake() { +3850 SpaceId::Data +3851 } else if self.highest_space == SpaceKind::Initial { +3852 SpaceId::Initial +3853 } else { +3854 // On the server, self.highest_space can be Data after receiving the client's first +3855 // flight, but we expect Handshake CRYPTO until the handshake is complete. +3856 SpaceId::Handshake +3857 }; +3858 // We can't decrypt Handshake packets when highest_space is Initial, CRYPTO frames in 0-RTT +3859 // packets are illegal, and we don't process 1-RTT packets until the handshake is +3860 // complete. Therefore, we will never see CRYPTO data from a later-than-expected space. +3861 debug_assert!(space <= expected, "received out-of-order CRYPTO data"); +3862 +3863 let end = crypto.offset + crypto.data.len() as u64; +3864 if space < expected +3865 && end +3866 > self.crypto_state.spaces[space.kind()] +3867 .crypto_stream +3868 .bytes_read() +3869 { +3870 warn!( +3871 "received new {:?} CRYPTO data when expecting {:?}", +3872 space, expected +3873 ); +3874 return Err(TransportError::PROTOCOL_VIOLATION( +3875 "new data at unexpected encryption level", +3876 )); +3877 } +3878 +3879 let crypto_space = &mut self.crypto_state.spaces[space.kind()]; +3880 let max = end.saturating_sub(crypto_space.crypto_stream.bytes_read()); +3881 if max > self.config.crypto_buffer_size as u64 { +3882 return Err(TransportError::CRYPTO_BUFFER_EXCEEDED("")); +3883 } +3884 +3885 crypto_space +3886 .crypto_stream +3887 .insert(crypto.offset, crypto.data.clone(), payload_len); +3888 while let Some(chunk) = crypto_space.crypto_stream.read(usize::MAX, true) { +3889 trace!("consumed {} CRYPTO bytes", chunk.bytes.len()); +3890 if self.crypto_state.session.read_handshake(&chunk.bytes)? { +3891 self.events.push_back(Event::HandshakeDataReady); +3892 } +3893 } 3894 -3895 fn write_crypto(&mut self) { -3896 loop { -3897 let space = self.highest_space; -3898 let mut outgoing = Vec::new(); -3899 if let Some(crypto) = self.crypto_state.session.write_handshake(&mut outgoing) { -3900 match space { -3901 SpaceKind::Initial => { -3902 self.upgrade_crypto(SpaceKind::Handshake, crypto); -3903 } -3904 SpaceKind::Handshake => { -3905 self.upgrade_crypto(SpaceKind::Data, crypto); +3895 Ok(()) +3896 } +3897 +3898 fn write_crypto(&mut self) { +3899 loop { +3900 let space = self.highest_space; +3901 let mut outgoing = Vec::new(); +3902 if let Some(crypto) = self.crypto_state.session.write_handshake(&mut outgoing) { +3903 match space { +3904 SpaceKind::Initial => { +3905 self.upgrade_crypto(SpaceKind::Handshake, crypto); 3906 } -3907 SpaceKind::Data => unreachable!("got updated secrets during 1-RTT"), -3908 } -3909 } -3910 if outgoing.is_empty() { -3911 if space == self.highest_space { -3912 break; -3913 } else { -3914 // Keys updated, check for more data to send -3915 continue; -3916 } -3917 } -3918 let offset = self.crypto_state.spaces[space].crypto_offset; -3919 let outgoing = Bytes::from(outgoing); -3920 if let Some(hs) = self.state.as_handshake_mut() -3921 && space == SpaceKind::Initial -3922 && offset == 0 -3923 && self.side.is_client() -3924 { -3925 hs.client_hello = Some(outgoing.clone()); -3926 } -3927 self.crypto_state.spaces[space].crypto_offset += outgoing.len() as u64; -3928 trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space); -3929 self.spaces[space].pending.crypto.push_back(frame::Crypto { -3930 offset, -3931 data: outgoing, -3932 }); -3933 } -3934 } -3935 -3936 /// Switch to stronger cryptography during handshake -3937 fn upgrade_crypto(&mut self, space: SpaceKind, crypto: Keys) { -3938 debug_assert!( -3939 !self.crypto_state.has_keys(space.encryption_level()), -3940 "already reached packet space {space:?}" -3941 ); -3942 trace!("{:?} keys ready", space); -3943 if space == SpaceKind::Data { -3944 // Precompute the first key update -3945 self.crypto_state.next_crypto = Some( -3946 self.crypto_state -3947 .session -3948 .next_1rtt_keys() -3949 .expect("handshake should be complete"), -3950 ); -3951 } -3952 -3953 self.crypto_state.spaces[space].keys = Some(crypto); -3954 debug_assert!(space > self.highest_space); -3955 self.highest_space = space; -3956 if space == SpaceKind::Data && self.side.is_client() { -3957 // Discard 0-RTT keys because 1-RTT keys are available. -3958 self.crypto_state.discard_zero_rtt(); -3959 } -3960 } -3961 -3962 fn discard_space(&mut self, now: Instant, space: SpaceKind) { -3963 debug_assert!(space != SpaceKind::Data); -3964 trace!("discarding {:?} keys", space); -3965 if space == SpaceKind::Initial { -3966 // No longer needed -3967 if let ConnectionSide::Client { token, .. } = &mut self.side { -3968 *token = Bytes::new(); -3969 } -3970 } -3971 self.crypto_state.spaces[space].keys = None; -3972 let space = &mut self.spaces[space]; -3973 let pns = space.for_path(PathId::ZERO); -3974 pns.time_of_last_ack_eliciting_packet = None; -3975 pns.loss_time = None; -3976 pns.loss_probes = 0; -3977 let sent_packets = mem::take(&mut pns.sent_packets); -3978 let path = self.paths.get_mut(&PathId::ZERO).unwrap(); -3979 for (_, packet) in sent_packets.into_iter() { -3980 path.data.remove_in_flight(&packet); -3981 } -3982 -3983 self.set_loss_detection_timer(now, PathId::ZERO) -3984 } +3907 SpaceKind::Handshake => { +3908 self.upgrade_crypto(SpaceKind::Data, crypto); +3909 } +3910 SpaceKind::Data => unreachable!("got updated secrets during 1-RTT"), +3911 } +3912 } +3913 if outgoing.is_empty() { +3914 if space == self.highest_space { +3915 break; +3916 } else { +3917 // Keys updated, check for more data to send +3918 continue; +3919 } +3920 } +3921 let offset = self.crypto_state.spaces[space].crypto_offset; +3922 let outgoing = Bytes::from(outgoing); +3923 if let Some(hs) = self.state.as_handshake_mut() +3924 && space == SpaceKind::Initial +3925 && offset == 0 +3926 && self.side.is_client() +3927 { +3928 hs.client_hello = Some(outgoing.clone()); +3929 } +3930 self.crypto_state.spaces[space].crypto_offset += outgoing.len() as u64; +3931 trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space); +3932 self.spaces[space].pending.crypto.push_back(frame::Crypto { +3933 offset, +3934 data: outgoing, +3935 }); +3936 } +3937 } +3938 +3939 /// Switch to stronger cryptography during handshake +3940 fn upgrade_crypto(&mut self, space: SpaceKind, crypto: Keys) { +3941 debug_assert!( +3942 !self.crypto_state.has_keys(space.encryption_level()), +3943 "already reached packet space {space:?}" +3944 ); +3945 trace!("{:?} keys ready", space); +3946 if space == SpaceKind::Data { +3947 // Precompute the first key update +3948 self.crypto_state.next_crypto = Some( +3949 self.crypto_state +3950 .session +3951 .next_1rtt_keys() +3952 .expect("handshake should be complete"), +3953 ); +3954 } +3955 +3956 self.crypto_state.spaces[space].keys = Some(crypto); +3957 debug_assert!(space > self.highest_space); +3958 self.highest_space = space; +3959 if space == SpaceKind::Data && self.side.is_client() { +3960 // Discard 0-RTT keys because 1-RTT keys are available. +3961 self.crypto_state.discard_zero_rtt(); +3962 } +3963 } +3964 +3965 fn discard_space(&mut self, now: Instant, space: SpaceKind) { +3966 debug_assert!(space != SpaceKind::Data); +3967 trace!("discarding {:?} keys", space); +3968 if space == SpaceKind::Initial { +3969 // No longer needed +3970 if let ConnectionSide::Client { token, .. } = &mut self.side { +3971 *token = Bytes::new(); +3972 } +3973 } +3974 self.crypto_state.spaces[space].keys = None; +3975 let space = &mut self.spaces[space]; +3976 let pns = space.for_path(PathId::ZERO); +3977 pns.time_of_last_ack_eliciting_packet = None; +3978 pns.loss_time = None; +3979 pns.loss_probes = 0; +3980 let sent_packets = mem::take(&mut pns.sent_packets); +3981 let path = self.paths.get_mut(&PathId::ZERO).unwrap(); +3982 for (_, packet) in sent_packets.into_iter() { +3983 path.data.remove_in_flight(&packet); +3984 } 3985 -3986 fn handle_coalesced( -3987 &mut self, -3988 now: Instant, -3989 network_path: FourTuple, -3990 path_id: PathId, -3991 ecn: Option<EcnCodepoint>, -3992 data: BytesMut, -3993 ) { -3994 self.path_data_mut(path_id) -3995 .inc_total_recvd(data.len() as u64); -3996 let mut remaining = Some(data); -3997 let cid_len = self -3998 .local_cid_state -3999 .values() -4000 .map(|cid_state| cid_state.cid_len()) -4001 .next() -4002 .expect("one cid_state must exist"); -4003 while let Some(data) = remaining { -4004 match PartialDecode::new( -4005 data, -4006 &FixedLengthConnectionIdParser::new(cid_len), -4007 &[self.version], -4008 self.endpoint_config.grease_quic_bit, -4009 ) { -4010 Ok((partial_decode, rest)) => { -4011 remaining = rest; -4012 self.handle_decode(now, network_path, path_id, ecn, partial_decode); -4013 } -4014 Err(e) => { -4015 trace!("malformed header: {}", e); -4016 return; -4017 } -4018 } -4019 } -4020 } -4021 -4022 fn handle_decode( -4023 &mut self, -4024 now: Instant, -4025 network_path: FourTuple, -4026 path_id: PathId, -4027 ecn: Option<EcnCodepoint>, -4028 partial_decode: PartialDecode, -4029 ) { -4030 let qlog = QlogRecvPacket::new(partial_decode.len()); -4031 if let Some(decoded) = self -4032 .crypto_state -4033 .unprotect_header(partial_decode, self.peer_params.stateless_reset_token) -4034 { -4035 self.handle_packet( -4036 now, -4037 network_path, -4038 path_id, -4039 ecn, -4040 decoded.packet, -4041 decoded.stateless_reset, -4042 qlog, -4043 ); -4044 } -4045 } -4046 -4047 fn handle_packet( -4048 &mut self, -4049 now: Instant, -4050 network_path: FourTuple, -4051 path_id: PathId, -4052 ecn: Option<EcnCodepoint>, -4053 packet: Option<Packet>, -4054 stateless_reset: bool, -4055 mut qlog: QlogRecvPacket, -4056 ) { -4057 self.path_stats.for_path(path_id).udp_rx.ios += 1; -4058 -4059 if let Some(ref packet) = packet { -4060 trace!( -4061 "got {:?} packet ({} bytes) from {} using id {}", -4062 packet.header.space(), -4063 packet.payload.len() + packet.header_data.len(), -4064 network_path, -4065 packet.header.dst_cid(), -4066 ); -4067 } -4068 -4069 if self.is_handshaking() { -4070 if path_id != PathId::ZERO { -4071 debug!(%network_path, %path_id, "discarding multipath packet during handshake"); -4072 return; -4073 } -4074 if network_path != self.path_data_mut(path_id).network_path { -4075 if let Some(hs) = self.state.as_handshake() { -4076 if hs.allow_server_migration { -4077 trace!(%network_path, prev = %self.path_data(path_id).network_path, "server migrated to new remote"); -4078 self.path_data_mut(path_id).network_path = network_path; -4079 self.qlog.emit_tuple_assigned(path_id, network_path, now); -4080 } else { -4081 debug!("discarding packet with unexpected remote during handshake"); -4082 return; -4083 } -4084 } else { -4085 debug!("discarding packet with unexpected remote during handshake"); -4086 return; -4087 } -4088 } -4089 } -4090 -4091 let was_closed = self.state.is_closed(); -4092 let was_drained = self.state.is_drained(); +3986 self.set_loss_detection_timer(now, PathId::ZERO) +3987 } +3988 +3989 fn handle_coalesced( +3990 &mut self, +3991 now: Instant, +3992 network_path: FourTuple, +3993 path_id: PathId, +3994 ecn: Option<EcnCodepoint>, +3995 data: BytesMut, +3996 ) { +3997 self.path_data_mut(path_id) +3998 .inc_total_recvd(data.len() as u64); +3999 let mut remaining = Some(data); +4000 let cid_len = self +4001 .local_cid_state +4002 .values() +4003 .map(|cid_state| cid_state.cid_len()) +4004 .next() +4005 .expect("one cid_state must exist"); +4006 while let Some(data) = remaining { +4007 match PartialDecode::new( +4008 data, +4009 &FixedLengthConnectionIdParser::new(cid_len), +4010 &[self.version], +4011 self.endpoint_config.grease_quic_bit, +4012 ) { +4013 Ok((partial_decode, rest)) => { +4014 remaining = rest; +4015 self.handle_decode(now, network_path, path_id, ecn, partial_decode); +4016 } +4017 Err(e) => { +4018 trace!("malformed header: {}", e); +4019 return; +4020 } +4021 } +4022 } +4023 } +4024 +4025 fn handle_decode( +4026 &mut self, +4027 now: Instant, +4028 network_path: FourTuple, +4029 path_id: PathId, +4030 ecn: Option<EcnCodepoint>, +4031 partial_decode: PartialDecode, +4032 ) { +4033 let qlog = QlogRecvPacket::new(partial_decode.len()); +4034 if let Some(decoded) = self +4035 .crypto_state +4036 .unprotect_header(partial_decode, self.peer_params.stateless_reset_token) +4037 { +4038 self.handle_packet( +4039 now, +4040 network_path, +4041 path_id, +4042 ecn, +4043 decoded.packet, +4044 decoded.stateless_reset, +4045 qlog, +4046 ); +4047 } +4048 } +4049 +4050 fn handle_packet( +4051 &mut self, +4052 now: Instant, +4053 network_path: FourTuple, +4054 path_id: PathId, +4055 ecn: Option<EcnCodepoint>, +4056 packet: Option<Packet>, +4057 stateless_reset: bool, +4058 mut qlog: QlogRecvPacket, +4059 ) { +4060 self.path_stats.for_path(path_id).udp_rx.ios += 1; +4061 +4062 if let Some(ref packet) = packet { +4063 trace!( +4064 "got {:?} packet ({} bytes) from {} using id {}", +4065 packet.header.space(), +4066 packet.payload.len() + packet.header_data.len(), +4067 network_path, +4068 packet.header.dst_cid(), +4069 ); +4070 } +4071 +4072 if self.is_handshaking() { +4073 if path_id != PathId::ZERO { +4074 debug!(%network_path, %path_id, "discarding multipath packet during handshake"); +4075 return; +4076 } +4077 if network_path != self.path_data_mut(path_id).network_path { +4078 if let Some(hs) = self.state.as_handshake() { +4079 if hs.allow_server_migration { +4080 trace!(%network_path, prev = %self.path_data(path_id).network_path, "server migrated to new remote"); +4081 self.path_data_mut(path_id).network_path = network_path; +4082 self.qlog.emit_tuple_assigned(path_id, network_path, now); +4083 } else { +4084 debug!("discarding packet with unexpected remote during handshake"); +4085 return; +4086 } +4087 } else { +4088 debug!("discarding packet with unexpected remote during handshake"); +4089 return; +4090 } +4091 } +4092 } 4093 -4094 let decrypted = match packet { -4095 None => Err(None), -4096 Some(mut packet) => self -4097 .decrypt_packet(now, path_id, &mut packet) -4098 .map(move |number| (packet, number)), -4099 }; -4100 let result = match decrypted { -4101 _ if stateless_reset => { -4102 debug!("got stateless reset"); -4103 Err(ConnectionError::Reset) -4104 } -4105 Err(Some(e)) => { -4106 warn!("illegal packet: {}", e); -4107 Err(e.into()) -4108 } -4109 Err(None) => { -4110 debug!("failed to authenticate packet"); -4111 self.authentication_failures += 1; -4112 let integrity_limit = self -4113 .crypto_state -4114 .integrity_limit(self.highest_space) -4115 .unwrap(); -4116 if self.authentication_failures > integrity_limit { -4117 Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into()) -4118 } else { -4119 return; -4120 } -4121 } -4122 Ok((packet, number)) => { -4123 qlog.header(&packet.header, number, path_id); -4124 let span = match number { -4125 Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn), -4126 None => trace_span!("recv", space = ?packet.header.space()), -4127 }; -4128 let _guard = span.enter(); -4129 -4130 let dedup = self.spaces[packet.header.space()] -4131 .path_space_mut(path_id) -4132 .map(|pns| &mut pns.dedup); -4133 if number.zip(dedup).is_some_and(|(n, d)| d.insert(n)) { -4134 debug!("discarding possible duplicate packet"); -4135 self.qlog.emit_packet_received(qlog, now); -4136 return; -4137 } else if self.state.is_handshake() && packet.header.is_short() { -4138 // TODO: SHOULD buffer these to improve reordering tolerance. -4139 trace!("dropping short packet during handshake"); -4140 self.qlog.emit_packet_received(qlog, now); -4141 return; -4142 } else { -4143 if let Header::Initial(InitialHeader { ref token, .. }) = packet.header -4144 && let Some(hs) = self.state.as_handshake() -4145 && self.side.is_server() -4146 && token != &hs.expected_token -4147 { -4148 // Clients must send the same retry token in every Initial. Initial -4149 // packets can be spoofed, so we discard rather than killing the -4150 // connection. -4151 warn!("discarding Initial with invalid retry token"); -4152 self.qlog.emit_packet_received(qlog, now); -4153 return; -4154 } -4155 -4156 if !self.state.is_closed() { -4157 let spin = match packet.header { -4158 Header::Short { spin, .. } => spin, -4159 _ => false, -4160 }; -4161 -4162 if self.side().is_server() && !self.abandoned_paths.contains(&path_id) { -4163 // Only the client is allowed to open paths -4164 self.ensure_path(path_id, network_path, now, number); -4165 } -4166 if self.paths.contains_key(&path_id) { -4167 self.on_packet_authenticated( -4168 now, -4169 packet.header.space(), -4170 path_id, -4171 ecn, -4172 number, -4173 spin, -4174 packet.header.is_1rtt(), -4175 ); -4176 } -4177 } -4178 -4179 let res = self.process_decrypted_packet( -4180 now, -4181 network_path, -4182 path_id, -4183 number, -4184 packet, -4185 &mut qlog, -4186 ); -4187 -4188 self.qlog.emit_packet_received(qlog, now); -4189 res -4190 } -4191 } -4192 }; -4193 -4194 // State transitions for error cases -4195 if let Err(conn_err) = result { -4196 match conn_err { -4197 ConnectionError::ApplicationClosed(reason) => self.state.move_to_closed(reason), -4198 ConnectionError::ConnectionClosed(reason) => self.state.move_to_closed(reason), -4199 ConnectionError::Reset -4200 | ConnectionError::TransportError(TransportError { -4201 code: TransportErrorCode::AEAD_LIMIT_REACHED, -4202 .. -4203 }) => { -4204 self.state.move_to_drained(Some(conn_err)); -4205 } -4206 ConnectionError::TimedOut => { -4207 unreachable!("timeouts aren't generated by packet processing"); +4094 let was_closed = self.state.is_closed(); +4095 let was_drained = self.state.is_drained(); +4096 +4097 let decrypted = match packet { +4098 None => Err(None), +4099 Some(mut packet) => self +4100 .decrypt_packet(now, path_id, &mut packet) +4101 .map(move |number| (packet, number)), +4102 }; +4103 let result = match decrypted { +4104 _ if stateless_reset => { +4105 debug!("got stateless reset"); +4106 Err(ConnectionError::Reset) +4107 } +4108 Err(Some(e)) => { +4109 warn!("illegal packet: {}", e); +4110 Err(e.into()) +4111 } +4112 Err(None) => { +4113 debug!("failed to authenticate packet"); +4114 self.authentication_failures += 1; +4115 let integrity_limit = self +4116 .crypto_state +4117 .integrity_limit(self.highest_space) +4118 .unwrap(); +4119 if self.authentication_failures > integrity_limit { +4120 Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into()) +4121 } else { +4122 return; +4123 } +4124 } +4125 Ok((packet, number)) => { +4126 qlog.header(&packet.header, number, path_id); +4127 let span = match number { +4128 Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn), +4129 None => trace_span!("recv", space = ?packet.header.space()), +4130 }; +4131 let _guard = span.enter(); +4132 +4133 let dedup = self.spaces[packet.header.space()] +4134 .path_space_mut(path_id) +4135 .map(|pns| &mut pns.dedup); +4136 if number.zip(dedup).is_some_and(|(n, d)| d.insert(n)) { +4137 debug!("discarding possible duplicate packet"); +4138 self.qlog.emit_packet_received(qlog, now); +4139 return; +4140 } else if self.state.is_handshake() && packet.header.is_short() { +4141 // TODO: SHOULD buffer these to improve reordering tolerance. +4142 trace!("dropping short packet during handshake"); +4143 self.qlog.emit_packet_received(qlog, now); +4144 return; +4145 } else { +4146 if let Header::Initial(InitialHeader { ref token, .. }) = packet.header +4147 && let Some(hs) = self.state.as_handshake() +4148 && self.side.is_server() +4149 && token != &hs.expected_token +4150 { +4151 // Clients must send the same retry token in every Initial. Initial +4152 // packets can be spoofed, so we discard rather than killing the +4153 // connection. +4154 warn!("discarding Initial with invalid retry token"); +4155 self.qlog.emit_packet_received(qlog, now); +4156 return; +4157 } +4158 +4159 if !self.state.is_closed() { +4160 let spin = match packet.header { +4161 Header::Short { spin, .. } => spin, +4162 _ => false, +4163 }; +4164 +4165 if self.side().is_server() && !self.abandoned_paths.contains(&path_id) { +4166 // Only the client is allowed to open paths +4167 self.ensure_path(path_id, network_path, now, number); +4168 } +4169 if self.paths.contains_key(&path_id) { +4170 self.on_packet_authenticated( +4171 now, +4172 packet.header.space(), +4173 path_id, +4174 ecn, +4175 number, +4176 spin, +4177 packet.header.is_1rtt(), +4178 ); +4179 } +4180 } +4181 +4182 let res = self.process_decrypted_packet( +4183 now, +4184 network_path, +4185 path_id, +4186 number, +4187 packet, +4188 &mut qlog, +4189 ); +4190 +4191 self.qlog.emit_packet_received(qlog, now); +4192 res +4193 } +4194 } +4195 }; +4196 +4197 // State transitions for error cases +4198 if let Err(conn_err) = result { +4199 match conn_err { +4200 ConnectionError::ApplicationClosed(reason) => self.state.move_to_closed(reason), +4201 ConnectionError::ConnectionClosed(reason) => self.state.move_to_closed(reason), +4202 ConnectionError::Reset +4203 | ConnectionError::TransportError(TransportError { +4204 code: TransportErrorCode::AEAD_LIMIT_REACHED, +4205 .. +4206 }) => { +4207 self.state.move_to_drained(Some(conn_err)); 4208 } -4209 ConnectionError::TransportError(err) => { -4210 debug!("closing connection due to transport error: {}", err); -4211 self.state.move_to_closed(err); -4212 } -4213 ConnectionError::VersionMismatch => { -4214 self.state.move_to_draining(Some(conn_err)); +4209 ConnectionError::TimedOut => { +4210 unreachable!("timeouts aren't generated by packet processing"); +4211 } +4212 ConnectionError::TransportError(err) => { +4213 debug!("closing connection due to transport error: {}", err); +4214 self.state.move_to_closed(err); 4215 } -4216 ConnectionError::LocallyClosed => { -4217 unreachable!("LocallyClosed isn't generated by packet processing"); +4216 ConnectionError::VersionMismatch => { +4217 self.state.move_to_draining(Some(conn_err)); 4218 } -4219 ConnectionError::CidsExhausted => { -4220 unreachable!("CidsExhausted isn't generated by packet processing"); +4219 ConnectionError::LocallyClosed => { +4220 unreachable!("LocallyClosed isn't generated by packet processing"); 4221 } -4222 }; -4223 } -4224 -4225 if !was_closed && self.state.is_closed() { -4226 self.close_common(); -4227 if !self.state.is_drained() { -4228 self.set_close_timer(now); -4229 } -4230 } -4231 if !was_drained && self.state.is_drained() { -4232 self.endpoint_events.push_back(EndpointEventInner::Drained); -4233 // Close timer may have been started previously, e.g. if we sent a close and got a -4234 // stateless reset in response -4235 self.timers -4236 .stop(Timer::Conn(ConnTimer::Close), self.qlog.with_time(now)); -4237 } -4238 -4239 // Transmit CONNECTION_CLOSE if necessary. -4240 // -4241 // If we received a valid packet and we are in the closed state we should respond -4242 // with a CONNECTION_CLOSE frame. -4243 // TODO: This SHOULD be rate-limited according to §10.2.1 of QUIC-TRANSPORT, but -4244 // that does not yet happen. This is triggered by each received packet. -4245 if matches!(self.state.as_type(), StateType::Closed) { -4246 // From https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.1-7 -4247 // -4248 // While in the closing state we must either: -4249 // - discard packets coming from an un-validated remote OR -4250 // - ensure we do not send more than 3 times the received data -4251 // -4252 // Doing the 2nd would mean we would be able to send CONNECTION_CLOSE to a peer -4253 // who was (involuntary) migrated just at the time we initiated immediate -4254 // close. It is a lot more work though. So while we would like to do this for -4255 // now we only do 1. -4256 // -4257 // Another shortcoming of the current implementation is that when we have a -4258 // previous PathData which is validated and the remote matches that path, we -4259 // should schedule CONNECTION_CLOSE on that path. However currently we can not -4260 // schedule such a packet. We should also fix this some day. This makes us -4261 // vulnerable to an attacker faking a migration at the right time and then we'd -4262 // be unable to send the CONNECTION_CLOSE to the real remote. -4263 if self -4264 .paths -4265 .get(&path_id) -4266 .map(|p| p.data.validated && p.data.network_path == network_path) -4267 .unwrap_or(false) -4268 { -4269 self.connection_close_pending = true; -4270 } -4271 } -4272 } -4273 -4274 fn process_decrypted_packet( -4275 &mut self, -4276 now: Instant, -4277 network_path: FourTuple, -4278 path_id: PathId, -4279 number: Option<u64>, -4280 packet: Packet, -4281 qlog: &mut QlogRecvPacket, -4282 ) -> Result<(), ConnectionError> { -4283 if !self.paths.contains_key(&path_id) { -4284 // There is a chance this is a server side, first (for this path) packet, which would -4285 // be a protocol violation. It's more likely, however, that this is a packet of a -4286 // pruned path -4287 trace!(%path_id, ?number, "discarding packet for unknown path"); -4288 return Ok(()); -4289 } -4290 let state = match self.state.as_type() { -4291 StateType::Established => { -4292 match packet.header.space() { -4293 SpaceKind::Data => self.process_payload( -4294 now, -4295 network_path, -4296 path_id, -4297 number.unwrap(), -4298 packet, -4299 qlog, -4300 )?, -4301 _ if packet.header.has_frames() => { -4302 self.process_early_payload(now, path_id, packet, qlog)? -4303 } -4304 _ => { -4305 trace!("discarding unexpected pre-handshake packet"); -4306 } -4307 } -4308 return Ok(()); -4309 } -4310 StateType::Closed => { -4311 for result in frame::Iter::new(packet.payload.freeze())? { -4312 let frame = match result { -4313 Ok(frame) => frame, -4314 Err(err) => { -4315 debug!("frame decoding error: {err:?}"); -4316 continue; -4317 } -4318 }; -4319 qlog.frame(&frame); -4320 -4321 if let Frame::Padding = frame { -4322 continue; -4323 }; -4324 -4325 self.path_stats -4326 .for_path(path_id) -4327 .frame_rx -4328 .record(frame.ty()); -4329 -4330 if let Frame::Close(_error) = frame { -4331 self.state.move_to_draining(None); -4332 break; -4333 } -4334 } -4335 return Ok(()); -4336 } -4337 StateType::Draining | StateType::Drained => return Ok(()), -4338 StateType::Handshake => self.state.as_handshake_mut().expect("checked"), -4339 }; -4340 -4341 match packet.header { -4342 Header::Retry { -4343 src_cid: remote_cid, -4344 .. -4345 } => { -4346 debug_assert_eq!(path_id, PathId::ZERO); -4347 if self.side.is_server() { -4348 return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into()); -4349 } -4350 -4351 let is_valid_retry = self -4352 .remote_cids -4353 .get(&path_id) -4354 .map(|cids| cids.active()) -4355 .map(|orig_dst_cid| { -4356 self.crypto_state.session.is_valid_retry( -4357 orig_dst_cid, -4358 &packet.header_data, -4359 &packet.payload, -4360 ) -4361 }) -4362 .unwrap_or_default(); -4363 if self.total_authed_packets > 1 -4364 || packet.payload.len() <= 16 // token + 16 byte tag -4365 || !is_valid_retry -4366 { -4367 trace!("discarding invalid Retry"); -4368 // - After the client has received and processed an Initial or Retry -4369 // packet from the server, it MUST discard any subsequent Retry -4370 // packets that it receives. -4371 // - A client MUST discard a Retry packet with a zero-length Retry Token -4372 // field. -4373 // - Clients MUST discard Retry packets that have a Retry Integrity Tag -4374 // that cannot be validated -4375 return Ok(()); -4376 } -4377 -4378 trace!("retrying with CID {}", remote_cid); -4379 let client_hello = state.client_hello.take().unwrap(); -4380 self.retry_src_cid = Some(remote_cid); -4381 self.remote_cids -4382 .get_mut(&path_id) -4383 .expect("PathId::ZERO not yet abandoned, is_valid_retry would have been false") -4384 .update_initial_cid(remote_cid); -4385 self.remote_handshake_cid = remote_cid; -4386 -4387 let space = &mut self.spaces[SpaceId::Initial]; -4388 if let Some(info) = space.for_path(PathId::ZERO).take(0) { -4389 self.on_packet_acked(now, PathId::ZERO, info); -4390 }; -4391 -4392 self.discard_space(now, SpaceKind::Initial); // Make sure we clean up after -4393 // any retransmitted Initials -4394 let crypto_space = &mut self.crypto_state.spaces[SpaceKind::Initial]; -4395 crypto_space.keys = Some( -4396 self.crypto_state -4397 .session -4398 .initial_keys(remote_cid, self.side.side()), -4399 ); -4400 crypto_space.crypto_offset = client_hello.len() as u64; -4401 -4402 let next_pn = self.spaces[SpaceId::Initial] -4403 .for_path(path_id) -4404 .next_packet_number; -4405 self.spaces[SpaceId::Initial] = { -4406 let mut space = PacketSpace::new(now, SpaceId::Initial, &mut self.rng); -4407 space.for_path(path_id).next_packet_number = next_pn; -4408 space.pending.crypto.push_back(frame::Crypto { -4409 offset: 0, -4410 data: client_hello, -4411 }); -4412 space -4413 }; -4414 -4415 // Retransmit all 0-RTT data -4416 let zero_rtt = mem::take( -4417 &mut self.spaces[SpaceId::Data] -4418 .for_path(PathId::ZERO) -4419 .sent_packets, -4420 ); -4421 for (_, info) in zero_rtt.into_iter() { -4422 self.paths -4423 .get_mut(&PathId::ZERO) -4424 .unwrap() -4425 .remove_in_flight(&info); -4426 self.spaces[SpaceId::Data].pending |= info.retransmits; -4427 } -4428 self.streams.retransmit_all_for_0rtt(); -4429 -4430 let token_len = packet.payload.len() - 16; -4431 let ConnectionSide::Client { ref mut token, .. } = self.side else { -4432 unreachable!("we already short-circuited if we're server"); -4433 }; -4434 *token = packet.payload.freeze().split_to(token_len); -4435 -4436 self.state = State::handshake(state::Handshake { -4437 expected_token: Bytes::new(), -4438 remote_cid_set: false, -4439 client_hello: None, -4440 allow_server_migration: true, -4441 }); -4442 Ok(()) -4443 } -4444 Header::Long { -4445 ty: LongType::Handshake, -4446 src_cid: remote_cid, -4447 dst_cid: local_cid, -4448 .. -4449 } => { -4450 debug_assert_eq!(path_id, PathId::ZERO); -4451 if remote_cid != self.remote_handshake_cid { -4452 debug!( -4453 "discarding packet with mismatched remote CID: {} != {}", -4454 self.remote_handshake_cid, remote_cid -4455 ); -4456 return Ok(()); -4457 } -4458 self.on_path_validated(path_id); -4459 -4460 self.process_early_payload(now, path_id, packet, qlog)?; -4461 if self.state.is_closed() { -4462 return Ok(()); -4463 } -4464 -4465 if self.crypto_state.session.is_handshaking() { -4466 trace!("handshake ongoing"); -4467 return Ok(()); -4468 } -4469 -4470 if self.side.is_client() { -4471 // Client-only because server params were set from the client's Initial -4472 let params = self -4473 .crypto_state -4474 .session -4475 .transport_parameters()? -4476 .ok_or_else(|| { -4477 TransportError::new( -4478 TransportErrorCode::crypto(0x6d), -4479 "transport parameters missing".to_owned(), -4480 ) -4481 })?; -4482 -4483 if self.has_0rtt() { -4484 if !self.crypto_state.session.early_data_accepted().unwrap() { -4485 debug_assert!(self.side.is_client()); -4486 debug!("0-RTT rejected"); -4487 self.crypto_state.accepted_0rtt = false; -4488 self.streams.zero_rtt_rejected(); -4489 -4490 // Discard already-queued frames -4491 self.spaces[SpaceId::Data].pending = Retransmits::default(); +4222 ConnectionError::CidsExhausted => { +4223 unreachable!("CidsExhausted isn't generated by packet processing"); +4224 } +4225 }; +4226 } +4227 +4228 if !was_closed && self.state.is_closed() { +4229 self.close_common(); +4230 if !self.state.is_drained() { +4231 self.set_close_timer(now); +4232 } +4233 } +4234 if !was_drained && self.state.is_drained() { +4235 self.endpoint_events.push_back(EndpointEventInner::Drained); +4236 // Close timer may have been started previously, e.g. if we sent a close and got a +4237 // stateless reset in response +4238 self.timers +4239 .stop(Timer::Conn(ConnTimer::Close), self.qlog.with_time(now)); +4240 } +4241 +4242 // Transmit CONNECTION_CLOSE if necessary. +4243 // +4244 // If we received a valid packet and we are in the closed state we should respond +4245 // with a CONNECTION_CLOSE frame. +4246 // TODO: This SHOULD be rate-limited according to §10.2.1 of QUIC-TRANSPORT, but +4247 // that does not yet happen. This is triggered by each received packet. +4248 if matches!(self.state.as_type(), StateType::Closed) { +4249 // From https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.1-7 +4250 // +4251 // While in the closing state we must either: +4252 // - discard packets coming from an un-validated remote OR +4253 // - ensure we do not send more than 3 times the received data +4254 // +4255 // Doing the 2nd would mean we would be able to send CONNECTION_CLOSE to a peer +4256 // who was (involuntary) migrated just at the time we initiated immediate +4257 // close. It is a lot more work though. So while we would like to do this for +4258 // now we only do 1. +4259 // +4260 // Another shortcoming of the current implementation is that when we have a +4261 // previous PathData which is validated and the remote matches that path, we +4262 // should schedule CONNECTION_CLOSE on that path. However currently we can not +4263 // schedule such a packet. We should also fix this some day. This makes us +4264 // vulnerable to an attacker faking a migration at the right time and then we'd +4265 // be unable to send the CONNECTION_CLOSE to the real remote. +4266 if self +4267 .paths +4268 .get(&path_id) +4269 .map(|p| p.data.validated && p.data.network_path == network_path) +4270 .unwrap_or(false) +4271 { +4272 self.connection_close_pending = true; +4273 } +4274 } +4275 } +4276 +4277 fn process_decrypted_packet( +4278 &mut self, +4279 now: Instant, +4280 network_path: FourTuple, +4281 path_id: PathId, +4282 number: Option<u64>, +4283 packet: Packet, +4284 qlog: &mut QlogRecvPacket, +4285 ) -> Result<(), ConnectionError> { +4286 if !self.paths.contains_key(&path_id) { +4287 // There is a chance this is a server side, first (for this path) packet, which would +4288 // be a protocol violation. It's more likely, however, that this is a packet of a +4289 // pruned path +4290 trace!(%path_id, ?number, "discarding packet for unknown path"); +4291 return Ok(()); +4292 } +4293 let state = match self.state.as_type() { +4294 StateType::Established => { +4295 match packet.header.space() { +4296 SpaceKind::Data => self.process_payload( +4297 now, +4298 network_path, +4299 path_id, +4300 number.unwrap(), +4301 packet, +4302 qlog, +4303 )?, +4304 _ if packet.header.has_frames() => { +4305 self.process_early_payload(now, path_id, packet, qlog)? +4306 } +4307 _ => { +4308 trace!("discarding unexpected pre-handshake packet"); +4309 } +4310 } +4311 return Ok(()); +4312 } +4313 StateType::Closed => { +4314 for result in frame::Iter::new(packet.payload.freeze())? { +4315 let frame = match result { +4316 Ok(frame) => frame, +4317 Err(err) => { +4318 debug!("frame decoding error: {err:?}"); +4319 continue; +4320 } +4321 }; +4322 qlog.frame(&frame); +4323 +4324 if let Frame::Padding = frame { +4325 continue; +4326 }; +4327 +4328 self.path_stats +4329 .for_path(path_id) +4330 .frame_rx +4331 .record(frame.ty()); +4332 +4333 if let Frame::Close(_error) = frame { +4334 self.state.move_to_draining(None); +4335 break; +4336 } +4337 } +4338 return Ok(()); +4339 } +4340 StateType::Draining | StateType::Drained => return Ok(()), +4341 StateType::Handshake => self.state.as_handshake_mut().expect("checked"), +4342 }; +4343 +4344 match packet.header { +4345 Header::Retry { +4346 src_cid: remote_cid, +4347 .. +4348 } => { +4349 debug_assert_eq!(path_id, PathId::ZERO); +4350 if self.side.is_server() { +4351 return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into()); +4352 } +4353 +4354 let is_valid_retry = self +4355 .remote_cids +4356 .get(&path_id) +4357 .map(|cids| cids.active()) +4358 .map(|orig_dst_cid| { +4359 self.crypto_state.session.is_valid_retry( +4360 orig_dst_cid, +4361 &packet.header_data, +4362 &packet.payload, +4363 ) +4364 }) +4365 .unwrap_or_default(); +4366 if self.total_authed_packets > 1 +4367 || packet.payload.len() <= 16 // token + 16 byte tag +4368 || !is_valid_retry +4369 { +4370 trace!("discarding invalid Retry"); +4371 // - After the client has received and processed an Initial or Retry +4372 // packet from the server, it MUST discard any subsequent Retry +4373 // packets that it receives. +4374 // - A client MUST discard a Retry packet with a zero-length Retry Token +4375 // field. +4376 // - Clients MUST discard Retry packets that have a Retry Integrity Tag +4377 // that cannot be validated +4378 return Ok(()); +4379 } +4380 +4381 trace!("retrying with CID {}", remote_cid); +4382 let client_hello = state.client_hello.take().unwrap(); +4383 self.retry_src_cid = Some(remote_cid); +4384 self.remote_cids +4385 .get_mut(&path_id) +4386 .expect("PathId::ZERO not yet abandoned, is_valid_retry would have been false") +4387 .update_initial_cid(remote_cid); +4388 self.remote_handshake_cid = remote_cid; +4389 +4390 let space = &mut self.spaces[SpaceId::Initial]; +4391 if let Some(info) = space.for_path(PathId::ZERO).take(0) { +4392 self.on_packet_acked(now, PathId::ZERO, info); +4393 }; +4394 +4395 self.discard_space(now, SpaceKind::Initial); // Make sure we clean up after +4396 // any retransmitted Initials +4397 let crypto_space = &mut self.crypto_state.spaces[SpaceKind::Initial]; +4398 crypto_space.keys = Some( +4399 self.crypto_state +4400 .session +4401 .initial_keys(remote_cid, self.side.side()), +4402 ); +4403 crypto_space.crypto_offset = client_hello.len() as u64; +4404 +4405 let next_pn = self.spaces[SpaceId::Initial] +4406 .for_path(path_id) +4407 .next_packet_number; +4408 self.spaces[SpaceId::Initial] = { +4409 let mut space = PacketSpace::new(now, SpaceId::Initial, &mut self.rng); +4410 space.for_path(path_id).next_packet_number = next_pn; +4411 space.pending.crypto.push_back(frame::Crypto { +4412 offset: 0, +4413 data: client_hello, +4414 }); +4415 space +4416 }; +4417 +4418 // Retransmit all 0-RTT data +4419 let zero_rtt = mem::take( +4420 &mut self.spaces[SpaceId::Data] +4421 .for_path(PathId::ZERO) +4422 .sent_packets, +4423 ); +4424 for (_, info) in zero_rtt.into_iter() { +4425 self.paths +4426 .get_mut(&PathId::ZERO) +4427 .unwrap() +4428 .remove_in_flight(&info); +4429 self.spaces[SpaceId::Data].pending |= info.retransmits; +4430 } +4431 self.streams.retransmit_all_for_0rtt(); +4432 +4433 let token_len = packet.payload.len() - 16; +4434 let ConnectionSide::Client { ref mut token, .. } = self.side else { +4435 unreachable!("we already short-circuited if we're server"); +4436 }; +4437 *token = packet.payload.freeze().split_to(token_len); +4438 +4439 self.state = State::handshake(state::Handshake { +4440 expected_token: Bytes::new(), +4441 remote_cid_set: false, +4442 client_hello: None, +4443 allow_server_migration: true, +4444 }); +4445 Ok(()) +4446 } +4447 Header::Long { +4448 ty: LongType::Handshake, +4449 src_cid: remote_cid, +4450 dst_cid: local_cid, +4451 .. +4452 } => { +4453 debug_assert_eq!(path_id, PathId::ZERO); +4454 if remote_cid != self.remote_handshake_cid { +4455 debug!( +4456 "discarding packet with mismatched remote CID: {} != {}", +4457 self.remote_handshake_cid, remote_cid +4458 ); +4459 return Ok(()); +4460 } +4461 self.on_path_validated(path_id); +4462 +4463 self.process_early_payload(now, path_id, packet, qlog)?; +4464 if self.state.is_closed() { +4465 return Ok(()); +4466 } +4467 +4468 if self.crypto_state.session.is_handshaking() { +4469 trace!("handshake ongoing"); +4470 return Ok(()); +4471 } +4472 +4473 if self.side.is_client() { +4474 // Client-only because server params were set from the client's Initial +4475 let params = self +4476 .crypto_state +4477 .session +4478 .transport_parameters()? +4479 .ok_or_else(|| { +4480 TransportError::new( +4481 TransportErrorCode::crypto(0x6d), +4482 "transport parameters missing".to_owned(), +4483 ) +4484 })?; +4485 +4486 if self.has_0rtt() { +4487 if !self.crypto_state.session.early_data_accepted().unwrap() { +4488 debug_assert!(self.side.is_client()); +4489 debug!("0-RTT rejected"); +4490 self.crypto_state.accepted_0rtt = false; +4491 self.streams.zero_rtt_rejected(); 4492 -4493 // Discard 0-RTT packets -4494 let sent_packets = mem::take( -4495 &mut self.spaces[SpaceId::Data].for_path(path_id).sent_packets, -4496 ); -4497 for (_, packet) in sent_packets.into_iter() { -4498 self.paths -4499 .get_mut(&path_id) -4500 .unwrap() -4501 .remove_in_flight(&packet); -4502 } -4503 } else { -4504 self.crypto_state.accepted_0rtt = true; -4505 params.validate_resumption_from(&self.peer_params)?; -4506 } -4507 } -4508 if let Some(token) = params.stateless_reset_token { -4509 let remote = self.path_data(path_id).network_path.remote; -4510 debug_assert!(!self.state.is_drained()); // requirement for endpoint events, checked above -4511 self.endpoint_events -4512 .push_back(EndpointEventInner::ResetToken(path_id, remote, token)); -4513 } -4514 self.handle_peer_params(params, local_cid, remote_cid, now)?; -4515 self.issue_first_cids(now); -4516 } else { -4517 // Server-only -4518 self.spaces[SpaceId::Data].pending.handshake_done = true; -4519 self.discard_space(now, SpaceKind::Handshake); -4520 self.events.push_back(Event::HandshakeConfirmed); -4521 trace!("handshake confirmed"); -4522 } -4523 -4524 self.events.push_back(Event::Connected); -4525 self.state.move_to_established(); -4526 trace!("established"); -4527 -4528 // Multipath can only be enabled after the state has reached Established. -4529 // So this can not happen any earlier. -4530 self.issue_first_path_cids(now); -4531 Ok(()) -4532 } -4533 Header::Initial(InitialHeader { -4534 src_cid: remote_cid, -4535 dst_cid: local_cid, -4536 .. -4537 }) => { -4538 debug_assert_eq!(path_id, PathId::ZERO); -4539 if !state.remote_cid_set { -4540 trace!("switching remote CID to {}", remote_cid); -4541 let mut state = state.clone(); -4542 self.remote_cids -4543 .get_mut(&path_id) -4544 .expect("PathId::ZERO not yet abandoned") -4545 .update_initial_cid(remote_cid); -4546 self.remote_handshake_cid = remote_cid; -4547 self.original_remote_cid = remote_cid; -4548 state.remote_cid_set = true; -4549 self.state.move_to_handshake(state); -4550 } else if remote_cid != self.remote_handshake_cid { -4551 debug!( -4552 "discarding packet with mismatched remote CID: {} != {}", -4553 self.remote_handshake_cid, remote_cid -4554 ); -4555 return Ok(()); -4556 } -4557 -4558 let starting_space = self.highest_space; -4559 self.process_early_payload(now, path_id, packet, qlog)?; +4493 // Discard already-queued frames +4494 self.spaces[SpaceId::Data].pending = Retransmits::default(); +4495 +4496 // Discard 0-RTT packets +4497 let sent_packets = mem::take( +4498 &mut self.spaces[SpaceId::Data].for_path(path_id).sent_packets, +4499 ); +4500 for (_, packet) in sent_packets.into_iter() { +4501 self.paths +4502 .get_mut(&path_id) +4503 .unwrap() +4504 .remove_in_flight(&packet); +4505 } +4506 } else { +4507 self.crypto_state.accepted_0rtt = true; +4508 params.validate_resumption_from(&self.peer_params)?; +4509 } +4510 } +4511 if let Some(token) = params.stateless_reset_token { +4512 let remote = self.path_data(path_id).network_path.remote; +4513 debug_assert!(!self.state.is_drained()); // requirement for endpoint events, checked above +4514 self.endpoint_events +4515 .push_back(EndpointEventInner::ResetToken(path_id, remote, token)); +4516 } +4517 self.handle_peer_params(params, local_cid, remote_cid, now)?; +4518 self.issue_first_cids(now); +4519 } else { +4520 // Server-only +4521 self.spaces[SpaceId::Data].pending.handshake_done = true; +4522 self.discard_space(now, SpaceKind::Handshake); +4523 self.events.push_back(Event::HandshakeConfirmed); +4524 trace!("handshake confirmed"); +4525 } +4526 +4527 self.events.push_back(Event::Connected); +4528 self.state.move_to_established(); +4529 trace!("established"); +4530 +4531 // Multipath can only be enabled after the state has reached Established. +4532 // So this can not happen any earlier. +4533 self.issue_first_path_cids(now); +4534 Ok(()) +4535 } +4536 Header::Initial(InitialHeader { +4537 src_cid: remote_cid, +4538 dst_cid: local_cid, +4539 .. +4540 }) => { +4541 debug_assert_eq!(path_id, PathId::ZERO); +4542 if !state.remote_cid_set { +4543 trace!("switching remote CID to {}", remote_cid); +4544 let mut state = state.clone(); +4545 self.remote_cids +4546 .get_mut(&path_id) +4547 .expect("PathId::ZERO not yet abandoned") +4548 .update_initial_cid(remote_cid); +4549 self.remote_handshake_cid = remote_cid; +4550 self.original_remote_cid = remote_cid; +4551 state.remote_cid_set = true; +4552 self.state.move_to_handshake(state); +4553 } else if remote_cid != self.remote_handshake_cid { +4554 debug!( +4555 "discarding packet with mismatched remote CID: {} != {}", +4556 self.remote_handshake_cid, remote_cid +4557 ); +4558 return Ok(()); +4559 } 4560 -4561 if self.side.is_server() -4562 && starting_space == SpaceKind::Initial -4563 && self.highest_space != SpaceKind::Initial -4564 { -4565 let params = self -4566 .crypto_state -4567 .session -4568 .transport_parameters()? -4569 .ok_or_else(|| { -4570 TransportError::new( -4571 TransportErrorCode::crypto(0x6d), -4572 "transport parameters missing".to_owned(), -4573 ) -4574 })?; -4575 self.handle_peer_params(params, local_cid, remote_cid, now)?; -4576 self.issue_first_cids(now); -4577 self.init_0rtt(now); -4578 } -4579 Ok(()) -4580 } -4581 Header::Long { -4582 ty: LongType::ZeroRtt, -4583 .. -4584 } => { -4585 self.process_payload(now, network_path, path_id, number.unwrap(), packet, qlog)?; -4586 Ok(()) -4587 } -4588 Header::VersionNegotiate { .. } => { -4589 if self.total_authed_packets > 1 { -4590 return Ok(()); -4591 } -4592 let supported = packet -4593 .payload -4594 .chunks(4) -4595 .any(|x| match <[u8; 4]>::try_from(x) { -4596 Ok(version) => self.version == u32::from_be_bytes(version), -4597 Err(_) => false, -4598 }); -4599 if supported { -4600 return Ok(()); -4601 } -4602 debug!("remote doesn't support our version"); -4603 Err(ConnectionError::VersionMismatch) -4604 } -4605 Header::Short { .. } => unreachable!( -4606 "short packets received during handshake are discarded in handle_packet" -4607 ), -4608 } -4609 } -4610 -4611 /// Process an Initial or Handshake packet payload -4612 fn process_early_payload( -4613 &mut self, -4614 now: Instant, -4615 path_id: PathId, -4616 packet: Packet, -4617 #[allow(unused)] qlog: &mut QlogRecvPacket, -4618 ) -> Result<(), TransportError> { -4619 debug_assert_ne!(packet.header.space(), SpaceKind::Data); -4620 debug_assert_eq!(path_id, PathId::ZERO); -4621 let payload_len = packet.payload.len(); -4622 let mut ack_eliciting = false; -4623 for result in frame::Iter::new(packet.payload.freeze())? { -4624 let frame = result?; -4625 qlog.frame(&frame); -4626 let span = match frame { -4627 Frame::Padding => continue, -4628 _ => Some(trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty)), -4629 }; -4630 -4631 self.path_stats -4632 .for_path(path_id) -4633 .frame_rx -4634 .record(frame.ty()); -4635 -4636 let _guard = span.as_ref().map(|x| x.enter()); -4637 ack_eliciting |= frame.is_ack_eliciting(); +4561 let starting_space = self.highest_space; +4562 self.process_early_payload(now, path_id, packet, qlog)?; +4563 +4564 if self.side.is_server() +4565 && starting_space == SpaceKind::Initial +4566 && self.highest_space != SpaceKind::Initial +4567 { +4568 let params = self +4569 .crypto_state +4570 .session +4571 .transport_parameters()? +4572 .ok_or_else(|| { +4573 TransportError::new( +4574 TransportErrorCode::crypto(0x6d), +4575 "transport parameters missing".to_owned(), +4576 ) +4577 })?; +4578 self.handle_peer_params(params, local_cid, remote_cid, now)?; +4579 self.issue_first_cids(now); +4580 self.init_0rtt(now); +4581 } +4582 Ok(()) +4583 } +4584 Header::Long { +4585 ty: LongType::ZeroRtt, +4586 .. +4587 } => { +4588 self.process_payload(now, network_path, path_id, number.unwrap(), packet, qlog)?; +4589 Ok(()) +4590 } +4591 Header::VersionNegotiate { .. } => { +4592 if self.total_authed_packets > 1 { +4593 return Ok(()); +4594 } +4595 let supported = packet +4596 .payload +4597 .chunks(4) +4598 .any(|x| match <[u8; 4]>::try_from(x) { +4599 Ok(version) => self.version == u32::from_be_bytes(version), +4600 Err(_) => false, +4601 }); +4602 if supported { +4603 return Ok(()); +4604 } +4605 debug!("remote doesn't support our version"); +4606 Err(ConnectionError::VersionMismatch) +4607 } +4608 Header::Short { .. } => unreachable!( +4609 "short packets received during handshake are discarded in handle_packet" +4610 ), +4611 } +4612 } +4613 +4614 /// Process an Initial or Handshake packet payload +4615 fn process_early_payload( +4616 &mut self, +4617 now: Instant, +4618 path_id: PathId, +4619 packet: Packet, +4620 #[allow(unused)] qlog: &mut QlogRecvPacket, +4621 ) -> Result<(), TransportError> { +4622 debug_assert_ne!(packet.header.space(), SpaceKind::Data); +4623 debug_assert_eq!(path_id, PathId::ZERO); +4624 let payload_len = packet.payload.len(); +4625 let mut ack_eliciting = false; +4626 for result in frame::Iter::new(packet.payload.freeze())? { +4627 let frame = result?; +4628 qlog.frame(&frame); +4629 let span = match frame { +4630 Frame::Padding => continue, +4631 _ => Some(trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty)), +4632 }; +4633 +4634 self.path_stats +4635 .for_path(path_id) +4636 .frame_rx +4637 .record(frame.ty()); 4638 -4639 // Process frames -4640 if frame.is_1rtt() && packet.header.space() != SpaceKind::Data { -4641 return Err(TransportError::PROTOCOL_VIOLATION( -4642 "illegal frame type in handshake", -4643 )); -4644 } -4645 -4646 match frame { -4647 Frame::Padding | Frame::Ping => {} -4648 Frame::Crypto(frame) => { -4649 self.read_crypto(packet.header.space().into(), &frame, payload_len)?; -4650 } -4651 Frame::Ack(ack) => { -4652 self.on_ack_received(now, packet.header.space().into(), ack)?; +4639 let _guard = span.as_ref().map(|x| x.enter()); +4640 ack_eliciting |= frame.is_ack_eliciting(); +4641 +4642 // Process frames +4643 if frame.is_1rtt() && packet.header.space() != SpaceKind::Data { +4644 return Err(TransportError::PROTOCOL_VIOLATION( +4645 "illegal frame type in handshake", +4646 )); +4647 } +4648 +4649 match frame { +4650 Frame::Padding | Frame::Ping => {} +4651 Frame::Crypto(frame) => { +4652 self.read_crypto(packet.header.space().into(), &frame, payload_len)?; 4653 } -4654 Frame::PathAck(ack) => { -4655 span.as_ref() -4656 .map(|span| span.record("path", tracing::field::display(&ack.path_id))); -4657 self.on_path_ack_received(now, packet.header.space().into(), ack)?; -4658 } -4659 Frame::Close(reason) => { -4660 self.state.move_to_draining(Some(reason.into())); -4661 return Ok(()); -4662 } -4663 _ => { -4664 let mut err = -4665 TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake"); -4666 err.frame = frame::MaybeFrame::Known(frame.ty()); -4667 return Err(err); -4668 } -4669 } -4670 } -4671 -4672 if ack_eliciting { -4673 // In the initial and handshake spaces, ACKs must be sent immediately -4674 self.spaces[packet.header.space()] -4675 .for_path(path_id) -4676 .pending_acks -4677 .set_immediate_ack_required(); -4678 } -4679 -4680 self.write_crypto(); -4681 Ok(()) -4682 } -4683 -4684 /// Processes the packet payload, always in the data space. -4685 fn process_payload( -4686 &mut self, -4687 now: Instant, -4688 network_path: FourTuple, -4689 path_id: PathId, -4690 number: u64, -4691 packet: Packet, -4692 #[allow(unused)] qlog: &mut QlogRecvPacket, -4693 ) -> Result<(), TransportError> { -4694 let is_multipath_negotiated = self.is_multipath_negotiated(); -4695 let payload = packet.payload.freeze(); -4696 let mut is_probing_packet = true; -4697 let mut close = None; -4698 let payload_len = payload.len(); -4699 let mut ack_eliciting = false; -4700 // if this packet triggers a path migration and includes a observed address frame, it's -4701 // stored here -4702 let mut migration_observed_addr = None; -4703 for result in frame::Iter::new(payload)? { -4704 let frame = result?; -4705 qlog.frame(&frame); -4706 let span = match frame { -4707 Frame::Padding => continue, -4708 _ => trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty), -4709 }; -4710 -4711 self.path_stats -4712 .for_path(path_id) -4713 .frame_rx -4714 .record(frame.ty()); -4715 // Crypto, Stream and Datagram frames are special cased in order no pollute -4716 // the log with payload data -4717 match &frame { -4718 Frame::Crypto(f) => { -4719 trace!(offset = f.offset, len = f.data.len(), "got frame CRYPTO"); -4720 } -4721 Frame::Stream(f) => { -4722 trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got frame STREAM"); +4654 Frame::Ack(ack) => { +4655 self.on_ack_received(now, packet.header.space().into(), ack)?; +4656 } +4657 Frame::PathAck(ack) => { +4658 span.as_ref() +4659 .map(|span| span.record("path", tracing::field::display(&ack.path_id))); +4660 self.on_path_ack_received(now, packet.header.space().into(), ack)?; +4661 } +4662 Frame::Close(reason) => { +4663 self.state.move_to_draining(Some(reason.into())); +4664 return Ok(()); +4665 } +4666 _ => { +4667 let mut err = +4668 TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake"); +4669 err.frame = frame::MaybeFrame::Known(frame.ty()); +4670 return Err(err); +4671 } +4672 } +4673 } +4674 +4675 if ack_eliciting { +4676 // In the initial and handshake spaces, ACKs must be sent immediately +4677 self.spaces[packet.header.space()] +4678 .for_path(path_id) +4679 .pending_acks +4680 .set_immediate_ack_required(); +4681 } +4682 +4683 self.write_crypto(); +4684 Ok(()) +4685 } +4686 +4687 /// Processes the packet payload, always in the data space. +4688 fn process_payload( +4689 &mut self, +4690 now: Instant, +4691 network_path: FourTuple, +4692 path_id: PathId, +4693 number: u64, +4694 packet: Packet, +4695 #[allow(unused)] qlog: &mut QlogRecvPacket, +4696 ) -> Result<(), TransportError> { +4697 let is_multipath_negotiated = self.is_multipath_negotiated(); +4698 let payload = packet.payload.freeze(); +4699 let mut is_probing_packet = true; +4700 let mut close = None; +4701 let payload_len = payload.len(); +4702 let mut ack_eliciting = false; +4703 // if this packet triggers a path migration and includes a observed address frame, it's +4704 // stored here +4705 let mut migration_observed_addr = None; +4706 for result in frame::Iter::new(payload)? { +4707 let frame = result?; +4708 qlog.frame(&frame); +4709 let span = match frame { +4710 Frame::Padding => continue, +4711 _ => trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty), +4712 }; +4713 +4714 self.path_stats +4715 .for_path(path_id) +4716 .frame_rx +4717 .record(frame.ty()); +4718 // Crypto, Stream and Datagram frames are special cased in order no pollute +4719 // the log with payload data +4720 match &frame { +4721 Frame::Crypto(f) => { +4722 trace!(offset = f.offset, len = f.data.len(), "got frame CRYPTO"); 4723 } -4724 Frame::Datagram(f) => { -4725 trace!(len = f.data.len(), "got frame DATAGRAM"); +4724 Frame::Stream(f) => { +4725 trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got frame STREAM"); 4726 } -4727 f => { -4728 trace!("got frame {f}"); +4727 Frame::Datagram(f) => { +4728 trace!(len = f.data.len(), "got frame DATAGRAM"); 4729 } -4730 } -4731 -4732 let _guard = span.enter(); -4733 if packet.header.is_0rtt() { -4734 match frame { -4735 Frame::Crypto(_) | Frame::Close(Close::Application(_)) => { -4736 return Err(TransportError::PROTOCOL_VIOLATION( -4737 "illegal frame type in 0-RTT", -4738 )); -4739 } -4740 _ => { -4741 if frame.is_1rtt() { -4742 return Err(TransportError::PROTOCOL_VIOLATION( -4743 "illegal frame type in 0-RTT", -4744 )); -4745 } -4746 } -4747 } -4748 } -4749 ack_eliciting |= frame.is_ack_eliciting(); -4750 -4751 // Check whether this could be a probing packet -4752 match frame { -4753 Frame::Padding -4754 | Frame::PathChallenge(_) -4755 | Frame::PathResponse(_) -4756 | Frame::NewConnectionId(_) -4757 | Frame::ObservedAddr(_) => {} -4758 _ => { -4759 is_probing_packet = false; -4760 } -4761 } -4762 -4763 match frame { -4764 Frame::Crypto(frame) => { -4765 self.read_crypto(SpaceId::Data, &frame, payload_len)?; -4766 } -4767 Frame::Stream(frame) => { -4768 if self.streams.received(frame, payload_len)?.should_transmit() { -4769 self.spaces[SpaceId::Data].pending.max_data = true; -4770 } -4771 } -4772 Frame::Ack(ack) => { -4773 self.on_ack_received(now, SpaceId::Data, ack)?; +4730 f => { +4731 trace!("got frame {f}"); +4732 } +4733 } +4734 +4735 let _guard = span.enter(); +4736 if packet.header.is_0rtt() { +4737 match frame { +4738 Frame::Crypto(_) | Frame::Close(Close::Application(_)) => { +4739 return Err(TransportError::PROTOCOL_VIOLATION( +4740 "illegal frame type in 0-RTT", +4741 )); +4742 } +4743 _ => { +4744 if frame.is_1rtt() { +4745 return Err(TransportError::PROTOCOL_VIOLATION( +4746 "illegal frame type in 0-RTT", +4747 )); +4748 } +4749 } +4750 } +4751 } +4752 ack_eliciting |= frame.is_ack_eliciting(); +4753 +4754 // Check whether this could be a probing packet +4755 match frame { +4756 Frame::Padding +4757 | Frame::PathChallenge(_) +4758 | Frame::PathResponse(_) +4759 | Frame::NewConnectionId(_) +4760 | Frame::ObservedAddr(_) => {} +4761 _ => { +4762 is_probing_packet = false; +4763 } +4764 } +4765 +4766 match frame { +4767 Frame::Crypto(frame) => { +4768 self.read_crypto(SpaceId::Data, &frame, payload_len)?; +4769 } +4770 Frame::Stream(frame) => { +4771 if self.streams.received(frame, payload_len)?.should_transmit() { +4772 self.spaces[SpaceId::Data].pending.max_data = true; +4773 } 4774 } -4775 Frame::PathAck(ack) => { -4776 span.record("path", tracing::field::display(&ack.path_id)); -4777 self.on_path_ack_received(now, SpaceId::Data, ack)?; -4778 } -4779 Frame::Padding | Frame::Ping => {} -4780 Frame::Close(reason) => { -4781 close = Some(reason); -4782 } -4783 Frame::PathChallenge(challenge) => { -4784 let path = &mut self -4785 .path_mut(path_id) -4786 .expect("payload is processed only after the path becomes known"); -4787 path.path_responses.push(number, challenge.0, network_path); -4788 // At this point, update_network_path_or_discard was already called, so -4789 // we don't need to be lenient about `local_ip` possibly mis-matching. -4790 if network_path == path.network_path { -4791 // PATH_CHALLENGE on active path, possible off-path packet forwarding -4792 // attack. Send a non-probing packet to recover the active path. -4793 // TODO(flub): No longer true! We now path_challege also to validate -4794 // the path if the path is new, without an RFC9000-style -4795 // migration involved. This means we add in an extra -4796 // IMMEDIATE_ACK on some challenges. It isn't really wrong to do -4797 // so, but it still is something untidy. We should instead -4798 // suppress this when we know the remote is still validating the -4799 // path. -4800 match self.peer_supports_ack_frequency() { -4801 true => self.immediate_ack(path_id), -4802 false => { -4803 self.ping_path(path_id).ok(); -4804 } -4805 } -4806 } -4807 } -4808 Frame::PathResponse(response) => { -4809 let path = self -4810 .paths -4811 .get_mut(&path_id) -4812 .expect("payload is processed only after the path becomes known"); -4813 -4814 use PathTimer::*; -4815 use paths::OnPathResponseReceived::*; -4816 match path -4817 .data -4818 .on_path_response_received(now, response.0, network_path) -4819 { -4820 OnPath { was_open } => { -4821 let qlog = self.qlog.with_time(now); -4822 -4823 self.timers -4824 .stop(Timer::PerPath(path_id, PathValidationFailed), qlog.clone()); -4825 self.timers -4826 .stop(Timer::PerPath(path_id, PathOpenFailed), qlog.clone()); -4827 -4828 let next_challenge = path -4829 .data -4830 .earliest_on_path_expiring_challenge() -4831 .map(|time| time + self.ack_frequency.max_ack_delay_for_pto()); -4832 self.timers.set_or_stop( -4833 Timer::PerPath(path_id, PathChallengeLost), -4834 next_challenge, -4835 qlog, -4836 ); -4837 -4838 if !was_open { -4839 if is_multipath_negotiated { -4840 self.events -4841 .push_back(Event::Path(PathEvent::Opened { id: path_id })); -4842 } -4843 if let Some(observed) = path.data.last_observed_addr_report.as_ref() -4844 { -4845 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -4846 id: path_id, -4847 addr: observed.socket_addr(), -4848 })); -4849 } -4850 } -4851 if let Some((_, ref mut prev)) = path.prev { -4852 prev.reset_on_path_challenges(); +4775 Frame::Ack(ack) => { +4776 self.on_ack_received(now, SpaceId::Data, ack)?; +4777 } +4778 Frame::PathAck(ack) => { +4779 span.record("path", tracing::field::display(&ack.path_id)); +4780 self.on_path_ack_received(now, SpaceId::Data, ack)?; +4781 } +4782 Frame::Padding | Frame::Ping => {} +4783 Frame::Close(reason) => { +4784 close = Some(reason); +4785 } +4786 Frame::PathChallenge(challenge) => { +4787 let path = &mut self +4788 .path_mut(path_id) +4789 .expect("payload is processed only after the path becomes known"); +4790 path.path_responses.push(number, challenge.0, network_path); +4791 // At this point, update_network_path_or_discard was already called, so +4792 // we don't need to be lenient about `local_ip` possibly mis-matching. +4793 if network_path == path.network_path { +4794 // PATH_CHALLENGE on active path, possible off-path packet forwarding +4795 // attack. Send a non-probing packet to recover the active path. +4796 // TODO(flub): No longer true! We now path_challege also to validate +4797 // the path if the path is new, without an RFC9000-style +4798 // migration involved. This means we add in an extra +4799 // IMMEDIATE_ACK on some challenges. It isn't really wrong to do +4800 // so, but it still is something untidy. We should instead +4801 // suppress this when we know the remote is still validating the +4802 // path. +4803 match self.peer_supports_ack_frequency() { +4804 true => self.immediate_ack(path_id), +4805 false => { +4806 self.ping_path(path_id).ok(); +4807 } +4808 } +4809 } +4810 } +4811 Frame::PathResponse(response) => { +4812 let path = self +4813 .paths +4814 .get_mut(&path_id) +4815 .expect("payload is processed only after the path becomes known"); +4816 +4817 use PathTimer::*; +4818 use paths::OnPathResponseReceived::*; +4819 match path +4820 .data +4821 .on_path_response_received(now, response.0, network_path) +4822 { +4823 OnPath { was_open } => { +4824 let qlog = self.qlog.with_time(now); +4825 +4826 self.timers +4827 .stop(Timer::PerPath(path_id, PathValidationFailed), qlog.clone()); +4828 self.timers +4829 .stop(Timer::PerPath(path_id, PathOpenFailed), qlog.clone()); +4830 +4831 let next_challenge = path +4832 .data +4833 .earliest_on_path_expiring_challenge() +4834 .map(|time| time + self.ack_frequency.max_ack_delay_for_pto()); +4835 self.timers.set_or_stop( +4836 Timer::PerPath(path_id, PathChallengeLost), +4837 next_challenge, +4838 qlog, +4839 ); +4840 +4841 if !was_open { +4842 if is_multipath_negotiated { +4843 self.events +4844 .push_back(Event::Path(PathEvent::Opened { id: path_id })); +4845 } +4846 if let Some(observed) = path.data.last_observed_addr_report.as_ref() +4847 { +4848 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +4849 id: path_id, +4850 addr: observed.socket_addr(), +4851 })); +4852 } 4853 } -4854 } -4855 OffPath => { -4856 debug!(%response, "Valid response to off-path PATH_CHALLENGE"); +4854 if let Some((_, ref mut prev)) = path.prev { +4855 prev.reset_on_path_challenges(); +4856 } 4857 } -4858 Ignored { -4859 sent_on, -4860 current_path, -4861 } => { -4862 debug!(%sent_on, %current_path, %response, "ignoring valid PATH_RESPONSE") -4863 } -4864 Unknown => debug!(%response, "ignoring invalid PATH_RESPONSE"), -4865 } -4866 } -4867 Frame::MaxData(frame::MaxData(bytes)) => { -4868 self.streams.received_max_data(bytes); +4858 OffPath => { +4859 debug!(%response, "Valid response to off-path PATH_CHALLENGE"); +4860 } +4861 Ignored { +4862 sent_on, +4863 current_path, +4864 } => { +4865 debug!(%sent_on, %current_path, %response, "ignoring valid PATH_RESPONSE") +4866 } +4867 Unknown => debug!(%response, "ignoring invalid PATH_RESPONSE"), +4868 } 4869 } -4870 Frame::MaxStreamData(frame::MaxStreamData { id, offset }) => { -4871 self.streams.received_max_stream_data(id, offset)?; +4870 Frame::MaxData(frame::MaxData(bytes)) => { +4871 self.streams.received_max_data(bytes); 4872 } -4873 Frame::MaxStreams(frame::MaxStreams { dir, count }) => { -4874 self.streams.received_max_streams(dir, count)?; +4873 Frame::MaxStreamData(frame::MaxStreamData { id, offset }) => { +4874 self.streams.received_max_stream_data(id, offset)?; 4875 } -4876 Frame::ResetStream(frame) => { -4877 if self.streams.received_reset(frame)?.should_transmit() { -4878 self.spaces[SpaceId::Data].pending.max_data = true; -4879 } -4880 } -4881 Frame::DataBlocked(DataBlocked(offset)) => { -4882 debug!(offset, "peer claims to be blocked at connection level"); +4876 Frame::MaxStreams(frame::MaxStreams { dir, count }) => { +4877 self.streams.received_max_streams(dir, count)?; +4878 } +4879 Frame::ResetStream(frame) => { +4880 if self.streams.received_reset(frame)?.should_transmit() { +4881 self.spaces[SpaceId::Data].pending.max_data = true; +4882 } 4883 } -4884 Frame::StreamDataBlocked(StreamDataBlocked { id, offset }) => { -4885 if id.initiator() == self.side.side() && id.dir() == Dir::Uni { -4886 debug!("got STREAM_DATA_BLOCKED on send-only {}", id); -4887 return Err(TransportError::STREAM_STATE_ERROR( -4888 "STREAM_DATA_BLOCKED on send-only stream", -4889 )); -4890 } -4891 debug!( -4892 stream = %id, -4893 offset, "peer claims to be blocked at stream level" -4894 ); -4895 } -4896 Frame::StreamsBlocked(StreamsBlocked { dir, limit }) => { -4897 if limit > MAX_STREAM_COUNT { -4898 return Err(TransportError::FRAME_ENCODING_ERROR( -4899 "unrepresentable stream limit", -4900 )); -4901 } -4902 debug!( -4903 "peer claims to be blocked opening more than {} {} streams", -4904 limit, dir -4905 ); -4906 } -4907 Frame::StopSending(frame::StopSending { id, error_code }) => { -4908 if id.initiator() != self.side.side() { -4909 if id.dir() == Dir::Uni { -4910 debug!("got STOP_SENDING on recv-only {}", id); -4911 return Err(TransportError::STREAM_STATE_ERROR( -4912 "STOP_SENDING on recv-only stream", -4913 )); -4914 } -4915 } else if self.streams.is_local_unopened(id) { -4916 return Err(TransportError::STREAM_STATE_ERROR( -4917 "STOP_SENDING on unopened stream", -4918 )); -4919 } -4920 self.streams.received_stop_sending(id, error_code); -4921 } -4922 Frame::RetireConnectionId(frame::RetireConnectionId { path_id, sequence }) => { -4923 if let Some(ref path_id) = path_id { -4924 span.record("path", tracing::field::display(&path_id)); -4925 } -4926 let path_id = path_id.unwrap_or_default(); -4927 match self.local_cid_state.get_mut(&path_id) { -4928 None => error!(?path_id, "RETIRE_CONNECTION_ID for unknown path"), -4929 Some(cid_state) => { -4930 let allow_more_cids = cid_state -4931 .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?; -4932 -4933 // If the path has closed, we do not issue more CIDs for this path -4934 // For details see https://www.ietf.org/archive/id/draft-ietf-quic-multipath-17.html#section-3.2.2 -4935 // > an endpoint SHOULD provide new connection IDs for that path, if still open, using PATH_NEW_CONNECTION_ID frames. -4936 let has_path = !self.abandoned_paths.contains(&path_id); -4937 let allow_more_cids = allow_more_cids && has_path; -4938 -4939 debug_assert!(!self.state.is_drained()); // required for adding endpoint events, process_payload is never called for drained connections -4940 self.endpoint_events -4941 .push_back(EndpointEventInner::RetireConnectionId( -4942 now, -4943 path_id, -4944 sequence, -4945 allow_more_cids, -4946 )); -4947 } -4948 } -4949 } -4950 Frame::NewConnectionId(frame) => { -4951 let path_id = if let Some(path_id) = frame.path_id { -4952 if !self.is_multipath_negotiated() { -4953 return Err(TransportError::PROTOCOL_VIOLATION( -4954 "received PATH_NEW_CONNECTION_ID frame when multipath was not negotiated", -4955 )); -4956 } -4957 if path_id > self.local_max_path_id { -4958 return Err(TransportError::PROTOCOL_VIOLATION( -4959 "PATH_NEW_CONNECTION_ID contains path_id exceeding current max", -4960 )); -4961 } -4962 path_id -4963 } else { -4964 PathId::ZERO -4965 }; -4966 -4967 if let Some(ref path_id) = frame.path_id { -4968 span.record("path", tracing::field::display(&path_id)); -4969 } -4970 -4971 if self.abandoned_paths.contains(&path_id) { -4972 trace!("ignoring issued CID for abandoned path"); -4973 continue; -4974 } -4975 let remote_cids = self -4976 .remote_cids -4977 .entry(path_id) -4978 .or_insert_with(|| CidQueue::new(frame.id)); -4979 if remote_cids.active().is_empty() { -4980 return Err(TransportError::PROTOCOL_VIOLATION( -4981 "NEW_CONNECTION_ID when CIDs aren't in use", -4982 )); -4983 } -4984 if frame.retire_prior_to > frame.sequence { -4985 return Err(TransportError::PROTOCOL_VIOLATION( -4986 "NEW_CONNECTION_ID retiring unissued CIDs", -4987 )); -4988 } -4989 -4990 use crate::cid_queue::InsertError; -4991 match remote_cids.insert(frame) { -4992 Ok(None) if self.path(path_id).is_none() => { -4993 // if this gives us CIDs to open a new path and a nat traversal attempt -4994 // is underway we could try to probe a pending remote -4995 self.continue_nat_traversal_round(now); -4996 } -4997 Ok(None) => {} -4998 Ok(Some((retired, reset_token))) => { -4999 let pending_retired = -5000 &mut self.spaces[SpaceId::Data].pending.retire_cids; -5001 /// Ensure `pending_retired` cannot grow without bound. Limit is -5002 /// somewhat arbitrary but very permissive. -5003 const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10; -5004 // We don't bother counting in-flight frames because those are bounded -5005 // by congestion control. -5006 if (pending_retired.len() as u64) -5007 .saturating_add(retired.end.saturating_sub(retired.start)) -5008 > MAX_PENDING_RETIRED_CIDS -5009 { -5010 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR( -5011 "queued too many retired CIDs", -5012 )); -5013 } -5014 pending_retired.extend(retired.map(|seq| (path_id, seq))); -5015 self.set_reset_token(path_id, network_path.remote, reset_token); -5016 } -5017 Err(InsertError::ExceedsLimit) => { -5018 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR("")); +4884 Frame::DataBlocked(DataBlocked(offset)) => { +4885 debug!(offset, "peer claims to be blocked at connection level"); +4886 } +4887 Frame::StreamDataBlocked(StreamDataBlocked { id, offset }) => { +4888 if id.initiator() == self.side.side() && id.dir() == Dir::Uni { +4889 debug!("got STREAM_DATA_BLOCKED on send-only {}", id); +4890 return Err(TransportError::STREAM_STATE_ERROR( +4891 "STREAM_DATA_BLOCKED on send-only stream", +4892 )); +4893 } +4894 debug!( +4895 stream = %id, +4896 offset, "peer claims to be blocked at stream level" +4897 ); +4898 } +4899 Frame::StreamsBlocked(StreamsBlocked { dir, limit }) => { +4900 if limit > MAX_STREAM_COUNT { +4901 return Err(TransportError::FRAME_ENCODING_ERROR( +4902 "unrepresentable stream limit", +4903 )); +4904 } +4905 debug!( +4906 "peer claims to be blocked opening more than {} {} streams", +4907 limit, dir +4908 ); +4909 } +4910 Frame::StopSending(frame::StopSending { id, error_code }) => { +4911 if id.initiator() != self.side.side() { +4912 if id.dir() == Dir::Uni { +4913 debug!("got STOP_SENDING on recv-only {}", id); +4914 return Err(TransportError::STREAM_STATE_ERROR( +4915 "STOP_SENDING on recv-only stream", +4916 )); +4917 } +4918 } else if self.streams.is_local_unopened(id) { +4919 return Err(TransportError::STREAM_STATE_ERROR( +4920 "STOP_SENDING on unopened stream", +4921 )); +4922 } +4923 self.streams.received_stop_sending(id, error_code); +4924 } +4925 Frame::RetireConnectionId(frame::RetireConnectionId { path_id, sequence }) => { +4926 if let Some(ref path_id) = path_id { +4927 span.record("path", tracing::field::display(&path_id)); +4928 } +4929 let path_id = path_id.unwrap_or_default(); +4930 match self.local_cid_state.get_mut(&path_id) { +4931 None => error!(?path_id, "RETIRE_CONNECTION_ID for unknown path"), +4932 Some(cid_state) => { +4933 let allow_more_cids = cid_state +4934 .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?; +4935 +4936 // If the path has closed, we do not issue more CIDs for this path +4937 // For details see https://www.ietf.org/archive/id/draft-ietf-quic-multipath-17.html#section-3.2.2 +4938 // > an endpoint SHOULD provide new connection IDs for that path, if still open, using PATH_NEW_CONNECTION_ID frames. +4939 let has_path = !self.abandoned_paths.contains(&path_id); +4940 let allow_more_cids = allow_more_cids && has_path; +4941 +4942 debug_assert!(!self.state.is_drained()); // required for adding endpoint events, process_payload is never called for drained connections +4943 self.endpoint_events +4944 .push_back(EndpointEventInner::RetireConnectionId( +4945 now, +4946 path_id, +4947 sequence, +4948 allow_more_cids, +4949 )); +4950 } +4951 } +4952 } +4953 Frame::NewConnectionId(frame) => { +4954 let path_id = if let Some(path_id) = frame.path_id { +4955 if !self.is_multipath_negotiated() { +4956 return Err(TransportError::PROTOCOL_VIOLATION( +4957 "received PATH_NEW_CONNECTION_ID frame when multipath was not negotiated", +4958 )); +4959 } +4960 if path_id > self.local_max_path_id { +4961 return Err(TransportError::PROTOCOL_VIOLATION( +4962 "PATH_NEW_CONNECTION_ID contains path_id exceeding current max", +4963 )); +4964 } +4965 path_id +4966 } else { +4967 PathId::ZERO +4968 }; +4969 +4970 if let Some(ref path_id) = frame.path_id { +4971 span.record("path", tracing::field::display(&path_id)); +4972 } +4973 +4974 if self.abandoned_paths.contains(&path_id) { +4975 trace!("ignoring issued CID for abandoned path"); +4976 continue; +4977 } +4978 let remote_cids = self +4979 .remote_cids +4980 .entry(path_id) +4981 .or_insert_with(|| CidQueue::new(frame.id)); +4982 if remote_cids.active().is_empty() { +4983 return Err(TransportError::PROTOCOL_VIOLATION( +4984 "NEW_CONNECTION_ID when CIDs aren't in use", +4985 )); +4986 } +4987 if frame.retire_prior_to > frame.sequence { +4988 return Err(TransportError::PROTOCOL_VIOLATION( +4989 "NEW_CONNECTION_ID retiring unissued CIDs", +4990 )); +4991 } +4992 +4993 use crate::cid_queue::InsertError; +4994 match remote_cids.insert(frame) { +4995 Ok(None) if self.path(path_id).is_none() => { +4996 // if this gives us CIDs to open a new path and a nat traversal attempt +4997 // is underway we could try to probe a pending remote +4998 self.continue_nat_traversal_round(now); +4999 } +5000 Ok(None) => {} +5001 Ok(Some((retired, reset_token))) => { +5002 let pending_retired = +5003 &mut self.spaces[SpaceId::Data].pending.retire_cids; +5004 /// Ensure `pending_retired` cannot grow without bound. Limit is +5005 /// somewhat arbitrary but very permissive. +5006 const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10; +5007 // We don't bother counting in-flight frames because those are bounded +5008 // by congestion control. +5009 if (pending_retired.len() as u64) +5010 .saturating_add(retired.end.saturating_sub(retired.start)) +5011 > MAX_PENDING_RETIRED_CIDS +5012 { +5013 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR( +5014 "queued too many retired CIDs", +5015 )); +5016 } +5017 pending_retired.extend(retired.map(|seq| (path_id, seq))); +5018 self.set_reset_token(path_id, network_path.remote, reset_token); 5019 } -5020 Err(InsertError::Retired) => { -5021 trace!("discarding already-retired"); -5022 // RETIRE_CONNECTION_ID might not have been previously sent if e.g. a -5023 // range of connection IDs larger than the active connection ID limit -5024 // was retired all at once via retire_prior_to. -5025 self.spaces[SpaceId::Data] -5026 .pending -5027 .retire_cids -5028 .push((path_id, frame.sequence)); -5029 continue; -5030 } -5031 }; -5032 -5033 if self.side.is_server() -5034 && path_id == PathId::ZERO -5035 && self -5036 .remote_cids -5037 .get(&PathId::ZERO) -5038 .map(|cids| cids.active_seq() == 0) -5039 .unwrap_or_default() -5040 { -5041 // We're a server still using the initial remote CID for the client, so -5042 // let's switch immediately to enable clientside stateless resets. -5043 self.update_remote_cid(PathId::ZERO); -5044 } -5045 } -5046 Frame::NewToken(NewToken { token }) => { -5047 let ConnectionSide::Client { -5048 token_store, -5049 server_name, -5050 .. -5051 } = &self.side -5052 else { -5053 return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN")); -5054 }; -5055 if token.is_empty() { -5056 return Err(TransportError::FRAME_ENCODING_ERROR("empty token")); -5057 } -5058 trace!("got new token"); -5059 token_store.insert(server_name, token); -5060 } -5061 Frame::Datagram(datagram) => { -5062 if self -5063 .datagrams -5064 .received(datagram, &self.config.datagram_receive_buffer_size)? -5065 { -5066 self.events.push_back(Event::DatagramReceived); -5067 } -5068 } -5069 Frame::AckFrequency(ack_frequency) => { -5070 // This frame can only be sent in the Data space -5071 -5072 if !self.ack_frequency.ack_frequency_received(&ack_frequency)? { -5073 // The AckFrequency frame is stale (we have already received a more -5074 // recent one) -5075 continue; -5076 } -5077 -5078 // Update the params for all of our paths -5079 for (path_id, space) in self.spaces[SpaceId::Data].number_spaces.iter_mut() { -5080 space.pending_acks.set_ack_frequency_params(&ack_frequency); -5081 -5082 // Our `max_ack_delay` has been updated, so we may need to adjust -5083 // its associated timeout -5084 if let Some(timeout) = space -5085 .pending_acks -5086 .max_ack_delay_timeout(self.ack_frequency.max_ack_delay) -5087 { -5088 self.timers.set( -5089 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), -5090 timeout, -5091 self.qlog.with_time(now), -5092 ); -5093 } -5094 } -5095 } -5096 Frame::ImmediateAck => { -5097 // This frame can only be sent in the Data space -5098 for pns in self.spaces[SpaceId::Data].iter_paths_mut() { -5099 pns.pending_acks.set_immediate_ack_required(); -5100 } -5101 } -5102 Frame::HandshakeDone => { -5103 if self.side.is_server() { -5104 return Err(TransportError::PROTOCOL_VIOLATION( -5105 "client sent HANDSHAKE_DONE", -5106 )); -5107 } -5108 if self.crypto_state.has_keys(EncryptionLevel::Handshake) { -5109 self.discard_space(now, SpaceKind::Handshake); +5020 Err(InsertError::ExceedsLimit) => { +5021 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR("")); +5022 } +5023 Err(InsertError::Retired) => { +5024 trace!("discarding already-retired"); +5025 // RETIRE_CONNECTION_ID might not have been previously sent if e.g. a +5026 // range of connection IDs larger than the active connection ID limit +5027 // was retired all at once via retire_prior_to. +5028 self.spaces[SpaceId::Data] +5029 .pending +5030 .retire_cids +5031 .push((path_id, frame.sequence)); +5032 continue; +5033 } +5034 }; +5035 +5036 if self.side.is_server() +5037 && path_id == PathId::ZERO +5038 && self +5039 .remote_cids +5040 .get(&PathId::ZERO) +5041 .map(|cids| cids.active_seq() == 0) +5042 .unwrap_or_default() +5043 { +5044 // We're a server still using the initial remote CID for the client, so +5045 // let's switch immediately to enable clientside stateless resets. +5046 self.update_remote_cid(PathId::ZERO); +5047 } +5048 } +5049 Frame::NewToken(NewToken { token }) => { +5050 let ConnectionSide::Client { +5051 token_store, +5052 server_name, +5053 .. +5054 } = &self.side +5055 else { +5056 return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN")); +5057 }; +5058 if token.is_empty() { +5059 return Err(TransportError::FRAME_ENCODING_ERROR("empty token")); +5060 } +5061 trace!("got new token"); +5062 token_store.insert(server_name, token); +5063 } +5064 Frame::Datagram(datagram) => { +5065 if self +5066 .datagrams +5067 .received(datagram, &self.config.datagram_receive_buffer_size)? +5068 { +5069 self.events.push_back(Event::DatagramReceived); +5070 } +5071 } +5072 Frame::AckFrequency(ack_frequency) => { +5073 // This frame can only be sent in the Data space +5074 +5075 if !self.ack_frequency.ack_frequency_received(&ack_frequency)? { +5076 // The AckFrequency frame is stale (we have already received a more +5077 // recent one) +5078 continue; +5079 } +5080 +5081 // Update the params for all of our paths +5082 for (path_id, space) in self.spaces[SpaceId::Data].number_spaces.iter_mut() { +5083 space.pending_acks.set_ack_frequency_params(&ack_frequency); +5084 +5085 // Our `max_ack_delay` has been updated, so we may need to adjust +5086 // its associated timeout +5087 if let Some(timeout) = space +5088 .pending_acks +5089 .max_ack_delay_timeout(self.ack_frequency.max_ack_delay) +5090 { +5091 self.timers.set( +5092 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), +5093 timeout, +5094 self.qlog.with_time(now), +5095 ); +5096 } +5097 } +5098 } +5099 Frame::ImmediateAck => { +5100 // This frame can only be sent in the Data space +5101 for pns in self.spaces[SpaceId::Data].iter_paths_mut() { +5102 pns.pending_acks.set_immediate_ack_required(); +5103 } +5104 } +5105 Frame::HandshakeDone => { +5106 if self.side.is_server() { +5107 return Err(TransportError::PROTOCOL_VIOLATION( +5108 "client sent HANDSHAKE_DONE", +5109 )); 5110 } -5111 self.events.push_back(Event::HandshakeConfirmed); -5112 trace!("handshake confirmed"); -5113 } -5114 Frame::ObservedAddr(observed) => { -5115 // check if params allows the peer to send report and this node to receive it -5116 trace!(seq_no = %observed.seq_no, ip = %observed.ip, port = observed.port); -5117 if !self -5118 .peer_params -5119 .address_discovery_role -5120 .should_report(&self.config.address_discovery_role) -5121 { -5122 return Err(TransportError::PROTOCOL_VIOLATION( -5123 "received OBSERVED_ADDRESS frame when not negotiated", -5124 )); -5125 } -5126 // must only be sent in data space -5127 if packet.header.space() != SpaceKind::Data { -5128 return Err(TransportError::PROTOCOL_VIOLATION( -5129 "OBSERVED_ADDRESS frame outside data space", -5130 )); -5131 } -5132 -5133 let path = self.path_data_mut(path_id); -5134 if network_path == path.network_path { -5135 if let Some(updated) = path.update_observed_addr_report(observed) -5136 && path.open_status == paths::OpenStatus::Informed -5137 { -5138 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -5139 id: path_id, -5140 addr: updated, -5141 })); -5142 // otherwise the event is reported when the path is deemed open -5143 } -5144 } else { -5145 // include in migration -5146 migration_observed_addr = Some(observed) -5147 } -5148 } -5149 Frame::PathAbandon(frame::PathAbandon { -5150 path_id, -5151 error_code, -5152 }) => { -5153 span.record("path", tracing::field::display(&path_id)); -5154 match self.close_path_inner( -5155 now, -5156 path_id, -5157 PathAbandonReason::RemoteAbandoned { -5158 error_code: error_code.into(), -5159 }, -5160 ) { -5161 Ok(()) => { -5162 trace!("peer abandoned path"); -5163 } -5164 Err(ClosePathError::ClosedPath) => { -5165 trace!("peer abandoned already closed path"); +5111 if self.crypto_state.has_keys(EncryptionLevel::Handshake) { +5112 self.discard_space(now, SpaceKind::Handshake); +5113 } +5114 self.events.push_back(Event::HandshakeConfirmed); +5115 trace!("handshake confirmed"); +5116 } +5117 Frame::ObservedAddr(observed) => { +5118 // check if params allows the peer to send report and this node to receive it +5119 trace!(seq_no = %observed.seq_no, ip = %observed.ip, port = observed.port); +5120 if !self +5121 .peer_params +5122 .address_discovery_role +5123 .should_report(&self.config.address_discovery_role) +5124 { +5125 return Err(TransportError::PROTOCOL_VIOLATION( +5126 "received OBSERVED_ADDRESS frame when not negotiated", +5127 )); +5128 } +5129 // must only be sent in data space +5130 if packet.header.space() != SpaceKind::Data { +5131 return Err(TransportError::PROTOCOL_VIOLATION( +5132 "OBSERVED_ADDRESS frame outside data space", +5133 )); +5134 } +5135 +5136 let path = self.path_data_mut(path_id); +5137 if network_path == path.network_path { +5138 if let Some(updated) = path.update_observed_addr_report(observed) +5139 && path.open_status == paths::OpenStatus::Informed +5140 { +5141 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +5142 id: path_id, +5143 addr: updated, +5144 })); +5145 // otherwise the event is reported when the path is deemed open +5146 } +5147 } else { +5148 // include in migration +5149 migration_observed_addr = Some(observed) +5150 } +5151 } +5152 Frame::PathAbandon(frame::PathAbandon { +5153 path_id, +5154 error_code, +5155 }) => { +5156 span.record("path", tracing::field::display(&path_id)); +5157 match self.close_path_inner( +5158 now, +5159 path_id, +5160 PathAbandonReason::RemoteAbandoned { +5161 error_code: error_code.into(), +5162 }, +5163 ) { +5164 Ok(()) => { +5165 trace!("peer abandoned path"); 5166 } -5167 Err(ClosePathError::MultipathNotNegotiated) => { -5168 return Err(TransportError::PROTOCOL_VIOLATION( -5169 "received PATH_ABANDON frame when multipath was not negotiated", -5170 )); -5171 } -5172 Err(ClosePathError::LastOpenPath) => { -5173 // Not reachable: close_path_inner allows remote abandons -5174 // for the last path. But handle gracefully just in case. -5175 error!( -5176 "peer abandoned last path but close_path_inner returned LastOpenPath" -5177 ); -5178 } -5179 }; -5180 -5181 // Start draining the path if it still exists and hasn't started draining yet. -5182 if let Some(path) = self.paths.get_mut(&path_id) -5183 && !mem::replace(&mut path.data.draining, true) -5184 { -5185 let ack_delay = self.ack_frequency.max_ack_delay_for_pto(); -5186 let pto = path.data.rtt.pto_base() + ack_delay; -5187 self.timers.set( -5188 Timer::PerPath(path_id, PathTimer::PathDrained), -5189 now + 3 * pto, -5190 self.qlog.with_time(now), -5191 ); -5192 -5193 self.set_max_path_id(now, self.local_max_path_id.saturating_add(1u8)); -5194 } -5195 } -5196 Frame::PathStatusAvailable(info) => { -5197 span.record("path", tracing::field::display(&info.path_id)); -5198 if self.is_multipath_negotiated() { -5199 self.on_path_status( -5200 info.path_id, -5201 PathStatus::Available, -5202 info.status_seq_no, -5203 ); -5204 } else { -5205 return Err(TransportError::PROTOCOL_VIOLATION( -5206 "received PATH_STATUS_AVAILABLE frame when multipath was not negotiated", -5207 )); -5208 } -5209 } -5210 Frame::PathStatusBackup(info) => { -5211 span.record("path", tracing::field::display(&info.path_id)); -5212 if self.is_multipath_negotiated() { -5213 self.on_path_status(info.path_id, PathStatus::Backup, info.status_seq_no); -5214 } else { -5215 return Err(TransportError::PROTOCOL_VIOLATION( -5216 "received PATH_STATUS_BACKUP frame when multipath was not negotiated", -5217 )); -5218 } -5219 } -5220 Frame::MaxPathId(frame::MaxPathId(path_id)) => { -5221 span.record("path", tracing::field::display(&path_id)); -5222 if !self.is_multipath_negotiated() { -5223 return Err(TransportError::PROTOCOL_VIOLATION( -5224 "received MAX_PATH_ID frame when multipath was not negotiated", -5225 )); -5226 } -5227 // frames that do not increase the path id are ignored -5228 if path_id > self.remote_max_path_id { -5229 self.remote_max_path_id = path_id; -5230 self.issue_first_path_cids(now); -5231 while let Some(true) = self.continue_nat_traversal_round(now) {} -5232 } -5233 } -5234 Frame::PathsBlocked(frame::PathsBlocked(max_path_id)) => { -5235 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST -5236 // be treated as a connection error of type PROTOCOL_VIOLATION. -5237 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> -5238 if self.is_multipath_negotiated() { -5239 if max_path_id > self.local_max_path_id { -5240 return Err(TransportError::PROTOCOL_VIOLATION( -5241 "PATHS_BLOCKED maximum path identifier was larger than local maximum", -5242 )); -5243 } -5244 debug!("received PATHS_BLOCKED({:?})", max_path_id); -5245 // TODO(@divma): ensure max concurrent paths -5246 } else { -5247 return Err(TransportError::PROTOCOL_VIOLATION( -5248 "received PATHS_BLOCKED frame when not multipath was not negotiated", -5249 )); -5250 } -5251 } -5252 Frame::PathCidsBlocked(frame::PathCidsBlocked { path_id, next_seq }) => { -5253 // Nothing to do. This is recorded in the frame stats, but otherwise we -5254 // always issue all CIDs we're allowed to issue, so either this is an -5255 // impatient peer or a bug on our side. -5256 -5257 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST -5258 // be treated as a connection error of type PROTOCOL_VIOLATION. -5259 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> -5260 if self.is_multipath_negotiated() { -5261 if path_id > self.local_max_path_id { -5262 return Err(TransportError::PROTOCOL_VIOLATION( -5263 "PATH_CIDS_BLOCKED path identifier was larger than local maximum", -5264 )); -5265 } -5266 if next_seq.0 -5267 > self -5268 .local_cid_state -5269 .get(&path_id) -5270 .map(|cid_state| cid_state.active_seq().1 + 1) -5271 .unwrap_or_default() -5272 { -5273 return Err(TransportError::PROTOCOL_VIOLATION( -5274 "PATH_CIDS_BLOCKED next sequence number larger than in local state", -5275 )); -5276 } -5277 debug!(%path_id, %next_seq, "received PATH_CIDS_BLOCKED"); -5278 } else { -5279 return Err(TransportError::PROTOCOL_VIOLATION( -5280 "received PATH_CIDS_BLOCKED frame when not multipath was not negotiated", -5281 )); -5282 } -5283 } -5284 Frame::AddAddress(addr) => { -5285 let client_state = match self.n0_nat_traversal.client_side_mut() { -5286 Ok(state) => state, -5287 Err(err) => { -5288 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5289 "Nat traversal(ADD_ADDRESS): {err}" -5290 ))); -5291 } -5292 }; -5293 -5294 if !client_state.check_remote_address(&addr) { -5295 // if the address is not valid we flag it, but update anyway -5296 warn!(?addr, "server sent illegal ADD_ADDRESS frame"); -5297 } -5298 -5299 match client_state.add_remote_address(addr) { -5300 Ok(maybe_added) => { -5301 if let Some(added) = maybe_added { -5302 self.events.push_back(Event::NatTraversal( -5303 n0_nat_traversal::Event::AddressAdded(added), -5304 )); -5305 } -5306 } -5307 Err(e) => { -5308 warn!(%e, "failed to add remote address") +5167 Err(ClosePathError::ClosedPath) => { +5168 trace!("peer abandoned already closed path"); +5169 } +5170 Err(ClosePathError::MultipathNotNegotiated) => { +5171 return Err(TransportError::PROTOCOL_VIOLATION( +5172 "received PATH_ABANDON frame when multipath was not negotiated", +5173 )); +5174 } +5175 Err(ClosePathError::LastOpenPath) => { +5176 // Not reachable: close_path_inner allows remote abandons +5177 // for the last path. But handle gracefully just in case. +5178 error!( +5179 "peer abandoned last path but close_path_inner returned LastOpenPath" +5180 ); +5181 } +5182 }; +5183 +5184 // Start draining the path if it still exists and hasn't started draining yet. +5185 if let Some(path) = self.paths.get_mut(&path_id) +5186 && !mem::replace(&mut path.data.draining, true) +5187 { +5188 let ack_delay = self.ack_frequency.max_ack_delay_for_pto(); +5189 let pto = path.data.rtt.pto_base() + ack_delay; +5190 self.timers.set( +5191 Timer::PerPath(path_id, PathTimer::PathDrained), +5192 now + 3 * pto, +5193 self.qlog.with_time(now), +5194 ); +5195 +5196 self.set_max_path_id(now, self.local_max_path_id.saturating_add(1u8)); +5197 } +5198 } +5199 Frame::PathStatusAvailable(info) => { +5200 span.record("path", tracing::field::display(&info.path_id)); +5201 if self.is_multipath_negotiated() { +5202 self.on_path_status( +5203 info.path_id, +5204 PathStatus::Available, +5205 info.status_seq_no, +5206 ); +5207 } else { +5208 return Err(TransportError::PROTOCOL_VIOLATION( +5209 "received PATH_STATUS_AVAILABLE frame when multipath was not negotiated", +5210 )); +5211 } +5212 } +5213 Frame::PathStatusBackup(info) => { +5214 span.record("path", tracing::field::display(&info.path_id)); +5215 if self.is_multipath_negotiated() { +5216 self.on_path_status(info.path_id, PathStatus::Backup, info.status_seq_no); +5217 } else { +5218 return Err(TransportError::PROTOCOL_VIOLATION( +5219 "received PATH_STATUS_BACKUP frame when multipath was not negotiated", +5220 )); +5221 } +5222 } +5223 Frame::MaxPathId(frame::MaxPathId(path_id)) => { +5224 span.record("path", tracing::field::display(&path_id)); +5225 if !self.is_multipath_negotiated() { +5226 return Err(TransportError::PROTOCOL_VIOLATION( +5227 "received MAX_PATH_ID frame when multipath was not negotiated", +5228 )); +5229 } +5230 // frames that do not increase the path id are ignored +5231 if path_id > self.remote_max_path_id { +5232 self.remote_max_path_id = path_id; +5233 self.issue_first_path_cids(now); +5234 while let Some(true) = self.continue_nat_traversal_round(now) {} +5235 } +5236 } +5237 Frame::PathsBlocked(frame::PathsBlocked(max_path_id)) => { +5238 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST +5239 // be treated as a connection error of type PROTOCOL_VIOLATION. +5240 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> +5241 if self.is_multipath_negotiated() { +5242 if max_path_id > self.local_max_path_id { +5243 return Err(TransportError::PROTOCOL_VIOLATION( +5244 "PATHS_BLOCKED maximum path identifier was larger than local maximum", +5245 )); +5246 } +5247 debug!("received PATHS_BLOCKED({:?})", max_path_id); +5248 // TODO(@divma): ensure max concurrent paths +5249 } else { +5250 return Err(TransportError::PROTOCOL_VIOLATION( +5251 "received PATHS_BLOCKED frame when not multipath was not negotiated", +5252 )); +5253 } +5254 } +5255 Frame::PathCidsBlocked(frame::PathCidsBlocked { path_id, next_seq }) => { +5256 // Nothing to do. This is recorded in the frame stats, but otherwise we +5257 // always issue all CIDs we're allowed to issue, so either this is an +5258 // impatient peer or a bug on our side. +5259 +5260 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST +5261 // be treated as a connection error of type PROTOCOL_VIOLATION. +5262 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> +5263 if self.is_multipath_negotiated() { +5264 if path_id > self.local_max_path_id { +5265 return Err(TransportError::PROTOCOL_VIOLATION( +5266 "PATH_CIDS_BLOCKED path identifier was larger than local maximum", +5267 )); +5268 } +5269 if next_seq.0 +5270 > self +5271 .local_cid_state +5272 .get(&path_id) +5273 .map(|cid_state| cid_state.active_seq().1 + 1) +5274 .unwrap_or_default() +5275 { +5276 return Err(TransportError::PROTOCOL_VIOLATION( +5277 "PATH_CIDS_BLOCKED next sequence number larger than in local state", +5278 )); +5279 } +5280 debug!(%path_id, %next_seq, "received PATH_CIDS_BLOCKED"); +5281 } else { +5282 return Err(TransportError::PROTOCOL_VIOLATION( +5283 "received PATH_CIDS_BLOCKED frame when not multipath was not negotiated", +5284 )); +5285 } +5286 } +5287 Frame::AddAddress(addr) => { +5288 let client_state = match self.n0_nat_traversal.client_side_mut() { +5289 Ok(state) => state, +5290 Err(err) => { +5291 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5292 "Nat traversal(ADD_ADDRESS): {err}" +5293 ))); +5294 } +5295 }; +5296 +5297 if !client_state.check_remote_address(&addr) { +5298 // if the address is not valid we flag it, but update anyway +5299 warn!(?addr, "server sent illegal ADD_ADDRESS frame"); +5300 } +5301 +5302 match client_state.add_remote_address(addr) { +5303 Ok(maybe_added) => { +5304 if let Some(added) = maybe_added { +5305 self.events.push_back(Event::NatTraversal( +5306 n0_nat_traversal::Event::AddressAdded(added), +5307 )); +5308 } 5309 } -5310 } -5311 } -5312 Frame::RemoveAddress(addr) => { -5313 let client_state = match self.n0_nat_traversal.client_side_mut() { -5314 Ok(state) => state, -5315 Err(err) => { -5316 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5317 "Nat traversal(REMOVE_ADDRESS): {err}" -5318 ))); -5319 } -5320 }; -5321 if let Some(removed_addr) = client_state.remove_remote_address(addr) { -5322 self.events.push_back(Event::NatTraversal( -5323 n0_nat_traversal::Event::AddressRemoved(removed_addr), -5324 )); -5325 } -5326 } -5327 Frame::ReachOut(reach_out) => { -5328 let ipv6 = self.is_ipv6(); -5329 let server_state = match self.n0_nat_traversal.server_side_mut() { -5330 Ok(state) => state, -5331 Err(err) => { -5332 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5333 "Nat traversal(REACH_OUT): {err}" -5334 ))); -5335 } -5336 }; -5337 -5338 if let Err(err) = server_state.handle_reach_out(reach_out, ipv6) { -5339 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5340 "Nat traversal(REACH_OUT): {err}" -5341 ))); -5342 } -5343 } -5344 } -5345 } -5346 -5347 let space = self.spaces[SpaceId::Data].for_path(path_id); -5348 if space -5349 .pending_acks -5350 .packet_received(now, number, ack_eliciting, &space.dedup) -5351 { -5352 if self.abandoned_paths.contains(&path_id) { -5353 // § 3.4.3 QUIC-MULTIPATH: promptly send ACKs for packets received from -5354 // abandoned paths. -5355 space.pending_acks.set_immediate_ack_required(); -5356 } else { -5357 self.timers.set( -5358 Timer::PerPath(path_id, PathTimer::MaxAckDelay), -5359 now + self.ack_frequency.max_ack_delay, -5360 self.qlog.with_time(now), -5361 ); -5362 } -5363 } -5364 -5365 // Issue stream ID credit due to ACKs of outgoing finish/resets and incoming finish/resets -5366 // on stopped streams. Incoming finishes/resets on open streams are not handled here as they -5367 // are only freed, and hence only issue credit, once the application has been notified -5368 // during a read on the stream. -5369 let pending = &mut self.spaces[SpaceId::Data].pending; -5370 self.streams.queue_max_stream_id(pending); -5371 -5372 if let Some(reason) = close { -5373 self.state.move_to_draining(Some(reason.into())); -5374 self.connection_close_pending = true; -5375 } -5376 -5377 if Some(number) == self.spaces[SpaceId::Data].for_path(path_id).rx_packet -5378 && !is_probing_packet -5379 && network_path != self.path_data(path_id).network_path -5380 { -5381 let ConnectionSide::Server { ref server_config } = self.side else { -5382 panic!("packets from unknown remote should be dropped by clients"); -5383 }; -5384 debug_assert!( -5385 server_config.migration, -5386 "migration-initiating packets should have been dropped immediately" -5387 ); -5388 self.migrate(path_id, now, network_path, migration_observed_addr); -5389 // Break linkability, if possible -5390 self.update_remote_cid(path_id); -5391 self.spin = false; -5392 } -5393 -5394 Ok(()) -5395 } +5310 Err(e) => { +5311 warn!(%e, "failed to add remote address") +5312 } +5313 } +5314 } +5315 Frame::RemoveAddress(addr) => { +5316 let client_state = match self.n0_nat_traversal.client_side_mut() { +5317 Ok(state) => state, +5318 Err(err) => { +5319 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5320 "Nat traversal(REMOVE_ADDRESS): {err}" +5321 ))); +5322 } +5323 }; +5324 if let Some(removed_addr) = client_state.remove_remote_address(addr) { +5325 self.events.push_back(Event::NatTraversal( +5326 n0_nat_traversal::Event::AddressRemoved(removed_addr), +5327 )); +5328 } +5329 } +5330 Frame::ReachOut(reach_out) => { +5331 let ipv6 = self.is_ipv6(); +5332 let server_state = match self.n0_nat_traversal.server_side_mut() { +5333 Ok(state) => state, +5334 Err(err) => { +5335 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5336 "Nat traversal(REACH_OUT): {err}" +5337 ))); +5338 } +5339 }; +5340 +5341 if let Err(err) = server_state.handle_reach_out(reach_out, ipv6) { +5342 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5343 "Nat traversal(REACH_OUT): {err}" +5344 ))); +5345 } +5346 } +5347 } +5348 } +5349 +5350 let space = self.spaces[SpaceId::Data].for_path(path_id); +5351 if space +5352 .pending_acks +5353 .packet_received(now, number, ack_eliciting, &space.dedup) +5354 { +5355 if self.abandoned_paths.contains(&path_id) { +5356 // § 3.4.3 QUIC-MULTIPATH: promptly send ACKs for packets received from +5357 // abandoned paths. +5358 space.pending_acks.set_immediate_ack_required(); +5359 } else { +5360 self.timers.set( +5361 Timer::PerPath(path_id, PathTimer::MaxAckDelay), +5362 now + self.ack_frequency.max_ack_delay, +5363 self.qlog.with_time(now), +5364 ); +5365 } +5366 } +5367 +5368 // Issue stream ID credit due to ACKs of outgoing finish/resets and incoming finish/resets +5369 // on stopped streams. Incoming finishes/resets on open streams are not handled here as they +5370 // are only freed, and hence only issue credit, once the application has been notified +5371 // during a read on the stream. +5372 let pending = &mut self.spaces[SpaceId::Data].pending; +5373 self.streams.queue_max_stream_id(pending); +5374 +5375 if let Some(reason) = close { +5376 self.state.move_to_draining(Some(reason.into())); +5377 self.connection_close_pending = true; +5378 } +5379 +5380 if Some(number) == self.spaces[SpaceId::Data].for_path(path_id).rx_packet +5381 && !is_probing_packet +5382 && network_path != self.path_data(path_id).network_path +5383 { +5384 let ConnectionSide::Server { ref server_config } = self.side else { +5385 panic!("packets from unknown remote should be dropped by clients"); +5386 }; +5387 debug_assert!( +5388 server_config.migration, +5389 "migration-initiating packets should have been dropped immediately" +5390 ); +5391 self.migrate(path_id, now, network_path, migration_observed_addr); +5392 // Break linkability, if possible +5393 self.update_remote_cid(path_id); +5394 self.spin = false; +5395 } 5396 -5397 fn migrate( -5398 &mut self, -5399 path_id: PathId, -5400 now: Instant, -5401 network_path: FourTuple, -5402 observed_addr: Option<ObservedAddr>, -5403 ) { -5404 trace!(%network_path, %path_id, "migration initiated"); -5405 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); -5406 // TODO(@divma): conditions for path migration in multipath are very specific, check them -5407 // again to prevent path migrations that should actually create a new path -5408 -5409 // Reset rtt/congestion state for new path unless it looks like a NAT rebinding. -5410 // Note that the congestion window will not grow until validation terminates. Helps mitigate -5411 // amplification attacks performed by spoofing source addresses. -5412 let prev_pto = self.pto(SpaceKind::Data, path_id); -5413 let path = self.paths.get_mut(&path_id).expect("known path"); -5414 let mut new_path_data = if network_path.remote.is_ipv4() -5415 && network_path.remote.ip() == path.data.network_path.remote.ip() -5416 { -5417 PathData::from_previous(network_path, &path.data, self.path_generation_counter, now) -5418 } else { -5419 let peer_max_udp_payload_size = -5420 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()) -5421 .unwrap_or(u16::MAX); -5422 PathData::new( -5423 network_path, -5424 self.allow_mtud, -5425 Some(peer_max_udp_payload_size), -5426 self.path_generation_counter, -5427 now, -5428 &self.config, -5429 ) -5430 }; -5431 new_path_data.last_observed_addr_report = path.data.last_observed_addr_report.clone(); -5432 if let Some(report) = observed_addr -5433 && let Some(updated) = new_path_data.update_observed_addr_report(report) -5434 { -5435 tracing::info!("adding observed addr event from migration"); -5436 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -5437 id: path_id, -5438 addr: updated, -5439 })); -5440 } -5441 new_path_data.pending_on_path_challenge = true; -5442 -5443 let mut prev_path_data = mem::replace(&mut path.data, new_path_data); -5444 -5445 // Only store this as previous path if it was validated. For all we know there could -5446 // already be a previous path stored which might have been validated in the past, -5447 // which is more valuable than one that's not yet validated. -5448 // -5449 // With multipath it is possible that there are no remote CIDs for the path ID -5450 // yet. In this case we would never have sent on this path yet and would not be able -5451 // to send a PATH_CHALLENGE either, which is currently a fire-and-forget affair -5452 // anyway. So don't store such a path either. -5453 if !prev_path_data.validated -5454 && let Some(cid) = self.remote_cids.get(&path_id).map(CidQueue::active) -5455 { -5456 prev_path_data.pending_on_path_challenge = true; -5457 // We haven't updated the remote CID yet, this captures the remote CID we were using on -5458 // the previous path. -5459 path.prev = Some((cid, prev_path_data)); -5460 } -5461 -5462 // We need to re-assign the correct remote to this path in qlog -5463 self.qlog.emit_tuple_assigned(path_id, network_path, now); +5397 Ok(()) +5398 } +5399 +5400 fn migrate( +5401 &mut self, +5402 path_id: PathId, +5403 now: Instant, +5404 network_path: FourTuple, +5405 observed_addr: Option<ObservedAddr>, +5406 ) { +5407 trace!(%network_path, %path_id, "migration initiated"); +5408 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); +5409 // TODO(@divma): conditions for path migration in multipath are very specific, check them +5410 // again to prevent path migrations that should actually create a new path +5411 +5412 // Reset rtt/congestion state for new path unless it looks like a NAT rebinding. +5413 // Note that the congestion window will not grow until validation terminates. Helps mitigate +5414 // amplification attacks performed by spoofing source addresses. +5415 let prev_pto = self.pto(SpaceKind::Data, path_id); +5416 let path = self.paths.get_mut(&path_id).expect("known path"); +5417 let mut new_path_data = if network_path.remote.is_ipv4() +5418 && network_path.remote.ip() == path.data.network_path.remote.ip() +5419 { +5420 PathData::from_previous(network_path, &path.data, self.path_generation_counter, now) +5421 } else { +5422 let peer_max_udp_payload_size = +5423 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()) +5424 .unwrap_or(u16::MAX); +5425 PathData::new( +5426 network_path, +5427 self.allow_mtud, +5428 Some(peer_max_udp_payload_size), +5429 self.path_generation_counter, +5430 now, +5431 &self.config, +5432 ) +5433 }; +5434 new_path_data.last_observed_addr_report = path.data.last_observed_addr_report.clone(); +5435 if let Some(report) = observed_addr +5436 && let Some(updated) = new_path_data.update_observed_addr_report(report) +5437 { +5438 tracing::info!("adding observed addr event from migration"); +5439 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +5440 id: path_id, +5441 addr: updated, +5442 })); +5443 } +5444 new_path_data.pending_on_path_challenge = true; +5445 +5446 let mut prev_path_data = mem::replace(&mut path.data, new_path_data); +5447 +5448 // Only store this as previous path if it was validated. For all we know there could +5449 // already be a previous path stored which might have been validated in the past, +5450 // which is more valuable than one that's not yet validated. +5451 // +5452 // With multipath it is possible that there are no remote CIDs for the path ID +5453 // yet. In this case we would never have sent on this path yet and would not be able +5454 // to send a PATH_CHALLENGE either, which is currently a fire-and-forget affair +5455 // anyway. So don't store such a path either. +5456 if !prev_path_data.validated +5457 && let Some(cid) = self.remote_cids.get(&path_id).map(CidQueue::active) +5458 { +5459 prev_path_data.pending_on_path_challenge = true; +5460 // We haven't updated the remote CID yet, this captures the remote CID we were using on +5461 // the previous path. +5462 path.prev = Some((cid, prev_path_data)); +5463 } 5464 -5465 self.timers.set( -5466 Timer::PerPath(path_id, PathTimer::PathValidationFailed), -5467 now + 3 * cmp::max(self.pto(SpaceKind::Data, path_id), prev_pto), -5468 self.qlog.with_time(now), -5469 ); -5470 } -5471 -5472 /// Handle a change in the local address, i.e. an active migration -5473 /// -5474 /// In the general (non-multipath) case, paths will perform a RFC9000 migration and be pinged -5475 /// for a liveness check. This is the behaviour of a path assumed to be recoverable, even if -5476 /// this is not the case. -5477 /// -5478 /// Clients in a connection in which multipath has been negotiated should migrate paths to new -5479 /// [`PathId`]s. For paths that are known to be non-recoverable can be migrated to a new -5480 /// [`PathId`] by closing the current path, and opening a new one to the same remote. Treating -5481 /// paths as non recoverable when necessary accelerates connectivity re-establishment, or might -5482 /// allow it altogether. -5483 /// -5484 /// The optional `hint` allows callers to indicate when paths are non-recoverable and should be -5485 /// migrated to new a [`PathId`]. -5486 // NOTE: only clients are allowed to migrate, but generally dealing with RFC9000 migrations is -5487 // lacking <https://github.com/n0-computer/noq/issues/364> -5488 pub fn handle_network_change(&mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant) { -5489 debug!("network changed"); -5490 if self.state.is_drained() { -5491 return; -5492 } -5493 if self.highest_space < SpaceKind::Data { -5494 for path in self.paths.values_mut() { -5495 // Clear the local address for it to be obtained from the socket again. -5496 path.data.network_path.local_ip = None; -5497 } -5498 -5499 self.update_remote_cid(PathId::ZERO); -5500 self.ping(); +5465 // We need to re-assign the correct remote to this path in qlog +5466 self.qlog.emit_tuple_assigned(path_id, network_path, now); +5467 +5468 self.timers.set( +5469 Timer::PerPath(path_id, PathTimer::PathValidationFailed), +5470 now + 3 * cmp::max(self.pto(SpaceKind::Data, path_id), prev_pto), +5471 self.qlog.with_time(now), +5472 ); +5473 } +5474 +5475 /// Handle a change in the local address, i.e. an active migration +5476 /// +5477 /// In the general (non-multipath) case, paths will perform a RFC9000 migration and be pinged +5478 /// for a liveness check. This is the behaviour of a path assumed to be recoverable, even if +5479 /// this is not the case. +5480 /// +5481 /// Clients in a connection in which multipath has been negotiated should migrate paths to new +5482 /// [`PathId`]s. For paths that are known to be non-recoverable can be migrated to a new +5483 /// [`PathId`] by closing the current path, and opening a new one to the same remote. Treating +5484 /// paths as non recoverable when necessary accelerates connectivity re-establishment, or might +5485 /// allow it altogether. +5486 /// +5487 /// The optional `hint` allows callers to indicate when paths are non-recoverable and should be +5488 /// migrated to new a [`PathId`]. +5489 // NOTE: only clients are allowed to migrate, but generally dealing with RFC9000 migrations is +5490 // lacking <https://github.com/n0-computer/noq/issues/364> +5491 pub fn handle_network_change(&mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant) { +5492 debug!("network changed"); +5493 if self.state.is_drained() { +5494 return; +5495 } +5496 if self.highest_space < SpaceKind::Data { +5497 for path in self.paths.values_mut() { +5498 // Clear the local address for it to be obtained from the socket again. +5499 path.data.network_path.local_ip = None; +5500 } 5501 -5502 return; -5503 } +5502 self.update_remote_cid(PathId::ZERO); +5503 self.ping(); 5504 -5505 // Paths that can't recover so a new path should be open instead. If multipath is not -5506 // negotiated, this will be empty. -5507 let mut non_recoverable_paths = Vec::default(); -5508 let mut recoverable_paths = Vec::default(); -5509 let mut open_paths = 0; -5510 -5511 let is_multipath_negotiated = self.is_multipath_negotiated(); -5512 let is_client = self.side().is_client(); -5513 let immediate_ack_allowed = self.peer_supports_ack_frequency(); -5514 -5515 for (path_id, path) in self.paths.iter_mut() { -5516 if self.abandoned_paths.contains(path_id) { -5517 continue; -5518 } -5519 open_paths += 1; -5520 -5521 // Read the network path BEFORE clearing local_ip, so the hint can -5522 // check which interface the path was using. -5523 let network_path = path.data.network_path; -5524 -5525 // Clear the local address for it to be obtained from the socket again. This applies to -5526 // all paths, regardless of being considered recoverable or not -5527 path.data.network_path.local_ip = None; -5528 let remote = network_path.remote; -5529 -5530 // Without multipath, the connection tries to recover the single path, whereas with -5531 // multipath, even in a single-path scenario, we attempt to migrate the path to a new -5532 // PathId. -5533 let attempt_to_recover = if is_multipath_negotiated { -5534 if is_client { -5535 hint.map(|h| h.is_path_recoverable(*path_id, network_path)) -5536 .unwrap_or(false) -5537 } else { -5538 // Servers should have stable addresses so this scenario is generally discouraged. -5539 // There is no way to prevent this, so the best hope is to attempt to recover the -5540 // path -5541 true -5542 } -5543 } else { -5544 // In the non multipath case, we try to recover the single active path -5545 true -5546 }; -5547 -5548 if attempt_to_recover { -5549 recoverable_paths.push((*path_id, remote)); -5550 } else { -5551 non_recoverable_paths.push((*path_id, remote, path.data.local_status())) -5552 } -5553 } -5554 -5555 /* NON RECOVERABLE PATHS */ -5556 // This are handled first, so that in case the treatment intended for these fails, we can -5557 // go the recoverable route instead. -5558 -5559 // Decide if we need to close first or open first in the multipath case. -5560 // - Opening first has a higher risk of getting limited by the negotiated MAX_PATH_ID. -5561 // - Closing first risks this being the only open path. -5562 // We prefer closing paths first unless we identify this is the last open path. -5563 let open_first = open_paths == non_recoverable_paths.len(); -5564 -5565 for (path_id, remote, status) in non_recoverable_paths.into_iter() { -5566 let network_path = FourTuple { -5567 remote, -5568 local_ip: None, /* allow the local ip to be discovered */ -5569 }; -5570 -5571 if open_first && let Err(e) = self.open_path(network_path, status, now) { -5572 debug!(%e,"Failed to open new path for network change"); -5573 // if this fails, let the path try to recover itself -5574 recoverable_paths.push((path_id, remote)); -5575 continue; -5576 } -5577 -5578 if let Err(e) = -5579 self.close_path_inner(now, path_id, PathAbandonReason::UnusableAfterNetworkChange) -5580 { -5581 debug!(%e,"Failed to close unrecoverable path after network change"); -5582 recoverable_paths.push((path_id, remote)); -5583 continue; -5584 } -5585 -5586 if !open_first && let Err(e) = self.open_path(network_path, status, now) { -5587 // Path has already been closed if we got here. Since the path was not recoverable, -5588 // this might be desirable in any case, because other paths exist (!open_first) and -5589 // this was is considered non recoverable -5590 debug!(%e,"Failed to open new path for network change"); -5591 } -5592 } -5593 -5594 /* RECOVERABLE PATHS */ -5595 -5596 for (path_id, remote) in recoverable_paths.into_iter() { -5597 let space = &mut self.spaces[SpaceId::Data]; +5505 return; +5506 } +5507 +5508 // Paths that can't recover so a new path should be open instead. If multipath is not +5509 // negotiated, this will be empty. +5510 let mut non_recoverable_paths = Vec::default(); +5511 let mut recoverable_paths = Vec::default(); +5512 let mut open_paths = 0; +5513 +5514 let is_multipath_negotiated = self.is_multipath_negotiated(); +5515 let is_client = self.side().is_client(); +5516 let immediate_ack_allowed = self.peer_supports_ack_frequency(); +5517 +5518 for (path_id, path) in self.paths.iter_mut() { +5519 if self.abandoned_paths.contains(path_id) { +5520 continue; +5521 } +5522 open_paths += 1; +5523 +5524 // Read the network path BEFORE clearing local_ip, so the hint can +5525 // check which interface the path was using. +5526 let network_path = path.data.network_path; +5527 +5528 // Clear the local address for it to be obtained from the socket again. This applies to +5529 // all paths, regardless of being considered recoverable or not +5530 path.data.network_path.local_ip = None; +5531 let remote = network_path.remote; +5532 +5533 // Without multipath, the connection tries to recover the single path, whereas with +5534 // multipath, even in a single-path scenario, we attempt to migrate the path to a new +5535 // PathId. +5536 let attempt_to_recover = if is_multipath_negotiated { +5537 if is_client { +5538 hint.map(|h| h.is_path_recoverable(*path_id, network_path)) +5539 .unwrap_or(false) +5540 } else { +5541 // Servers should have stable addresses so this scenario is generally discouraged. +5542 // There is no way to prevent this, so the best hope is to attempt to recover the +5543 // path +5544 true +5545 } +5546 } else { +5547 // In the non multipath case, we try to recover the single active path +5548 true +5549 }; +5550 +5551 if attempt_to_recover { +5552 recoverable_paths.push((*path_id, remote)); +5553 } else { +5554 non_recoverable_paths.push((*path_id, remote, path.data.local_status())) +5555 } +5556 } +5557 +5558 /* NON RECOVERABLE PATHS */ +5559 // This are handled first, so that in case the treatment intended for these fails, we can +5560 // go the recoverable route instead. +5561 +5562 // Decide if we need to close first or open first in the multipath case. +5563 // - Opening first has a higher risk of getting limited by the negotiated MAX_PATH_ID. +5564 // - Closing first risks this being the only open path. +5565 // We prefer closing paths first unless we identify this is the last open path. +5566 let open_first = open_paths == non_recoverable_paths.len(); +5567 +5568 for (path_id, remote, status) in non_recoverable_paths.into_iter() { +5569 let network_path = FourTuple { +5570 remote, +5571 local_ip: None, /* allow the local ip to be discovered */ +5572 }; +5573 +5574 if open_first && let Err(e) = self.open_path(network_path, status, now) { +5575 debug!(%e,"Failed to open new path for network change"); +5576 // if this fails, let the path try to recover itself +5577 recoverable_paths.push((path_id, remote)); +5578 continue; +5579 } +5580 +5581 if let Err(e) = +5582 self.close_path_inner(now, path_id, PathAbandonReason::UnusableAfterNetworkChange) +5583 { +5584 debug!(%e,"Failed to close unrecoverable path after network change"); +5585 recoverable_paths.push((path_id, remote)); +5586 continue; +5587 } +5588 +5589 if !open_first && let Err(e) = self.open_path(network_path, status, now) { +5590 // Path has already been closed if we got here. Since the path was not recoverable, +5591 // this might be desirable in any case, because other paths exist (!open_first) and +5592 // this was is considered non recoverable +5593 debug!(%e,"Failed to open new path for network change"); +5594 } +5595 } +5596 +5597 /* RECOVERABLE PATHS */ 5598 -5599 // Schedule a Ping for a liveness check. -5600 if let Some(path_space) = space.number_spaces.get_mut(&path_id) { -5601 path_space.ping_pending = true; -5602 -5603 if immediate_ack_allowed { -5604 path_space.immediate_ack_pending = true; -5605 } -5606 } -5607 -5608 let Some((reset_token, retired)) = -5609 self.remote_cids.get_mut(&path_id).and_then(CidQueue::next) -5610 else { -5611 continue; -5612 }; -5613 -5614 // Retire the current remote CID and any CIDs we had to skip. -5615 space -5616 .pending -5617 .retire_cids -5618 .extend(retired.map(|seq| (path_id, seq))); -5619 -5620 debug_assert!(!self.state.is_drained()); // required for endpoint_events, checked above -5621 self.endpoint_events -5622 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); -5623 } -5624 } -5625 -5626 /// Switch to a previously unused remote connection ID, if possible -5627 fn update_remote_cid(&mut self, path_id: PathId) { -5628 let Some((reset_token, retired)) = self -5629 .remote_cids -5630 .get_mut(&path_id) -5631 .and_then(|cids| cids.next()) -5632 else { -5633 return; -5634 }; -5635 -5636 // Retire the current remote CID and any CIDs we had to skip. -5637 self.spaces[SpaceId::Data] -5638 .pending -5639 .retire_cids -5640 .extend(retired.map(|seq| (path_id, seq))); -5641 let remote = self.path_data(path_id).network_path.remote; -5642 self.set_reset_token(path_id, remote, reset_token); -5643 } -5644 -5645 /// Sends this reset token to the endpoint -5646 /// -5647 /// The endpoint needs to know the reset tokens issued by the peer, so that if the peer -5648 /// sends a reset token it knows to route it to this connection. See RFC 9000 section -5649 /// 10.3. Stateless Reset. -5650 /// -5651 /// Reset tokens are different for each path, the endpoint identifies paths by peer -5652 /// socket address however, not by path ID. -5653 fn set_reset_token(&mut self, path_id: PathId, remote: SocketAddr, reset_token: ResetToken) { -5654 debug_assert!(!self.state.is_drained()); // required for endpoint events, set_reset_token is never called for drained connections -5655 self.endpoint_events -5656 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); -5657 -5658 // During the handshake the server sends a reset token in the transport -5659 // parameters. When we are the client and we receive the reset token during the -5660 // handshake we want this to affect our peer transport parameters. -5661 // TODO(flub): Pretty sure this is pointless, the entire params is overwritten -5662 // shortly after this was called. And then the params don't have this anymore. -5663 if path_id == PathId::ZERO { -5664 self.peer_params.stateless_reset_token = Some(reset_token); -5665 } -5666 } -5667 -5668 /// Issue an initial set of connection IDs to the peer upon connection -5669 fn issue_first_cids(&mut self, now: Instant) { -5670 if self -5671 .local_cid_state -5672 .get(&PathId::ZERO) -5673 .expect("PathId::ZERO exists when the connection is created") -5674 .cid_len() -5675 == 0 -5676 { -5677 return; -5678 } -5679 -5680 // Subtract 1 to account for the CID we supplied while handshaking -5681 let mut n = self.peer_params.issue_cids_limit() - 1; -5682 if let ConnectionSide::Server { server_config } = &self.side -5683 && server_config.has_preferred_address() -5684 { -5685 // We also sent a CID in the transport parameters -5686 n -= 1; -5687 } -5688 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events -5689 self.endpoint_events -5690 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); -5691 } -5692 -5693 /// Issues an initial set of CIDs for paths that have not yet had any CIDs issued -5694 /// -5695 /// Later CIDs are issued when CIDs expire or are retired by the peer. -5696 fn issue_first_path_cids(&mut self, now: Instant) { -5697 if let Some(max_path_id) = self.max_path_id() { -5698 let mut path_id = self.max_path_id_with_cids.next(); -5699 while path_id <= max_path_id { -5700 self.endpoint_events -5701 .push_back(EndpointEventInner::NeedIdentifiers( -5702 path_id, -5703 now, -5704 self.peer_params.issue_cids_limit(), -5705 )); -5706 path_id = path_id.next(); -5707 } -5708 self.max_path_id_with_cids = max_path_id; -5709 } -5710 } -5711 -5712 /// Populates a packet with frames -5713 /// -5714 /// This tries to fit as many frames as possible into the packet. -5715 /// -5716 /// *path_exclusive_only* means to only build frames which can only be sent on this -5717 /// *path. This is used in multipath for backup paths while there is still an active -5718 /// *path. -5719 fn populate_packet<'a, 'b>( -5720 &mut self, -5721 now: Instant, -5722 space_id: SpaceId, -5723 path_id: PathId, -5724 scheduling_info: &PathSchedulingInfo, -5725 builder: &mut PacketBuilder<'a, 'b>, -5726 ) { -5727 let is_multipath_negotiated = self.is_multipath_negotiated(); -5728 let space_has_keys = self.crypto_state.has_keys(space_id.encryption_level()); -5729 let is_0rtt = space_id == SpaceId::Data && !space_has_keys; -5730 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -5731 let space = &mut self.spaces[space_id]; -5732 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; -5733 space -5734 .for_path(path_id) -5735 .pending_acks -5736 .maybe_ack_non_eliciting(); -5737 -5738 // HANDSHAKE_DONE -5739 if !is_0rtt -5740 && !scheduling_info.is_abandoned -5741 && scheduling_info.may_send_data -5742 && mem::replace(&mut space.pending.handshake_done, false) -5743 { -5744 builder.write_frame(frame::HandshakeDone, stats); -5745 } -5746 -5747 // PING -5748 if !scheduling_info.is_abandoned -5749 && mem::replace(&mut space.for_path(path_id).ping_pending, false) -5750 { -5751 builder.write_frame(frame::Ping, stats); -5752 } -5753 -5754 // IMMEDIATE_ACK -5755 if !scheduling_info.is_abandoned -5756 && mem::replace(&mut space.for_path(path_id).immediate_ack_pending, false) -5757 { -5758 debug_assert_eq!( -5759 space_id, -5760 SpaceId::Data, -5761 "immediate acks must be sent in the data space" -5762 ); -5763 builder.write_frame(frame::ImmediateAck, stats); -5764 } -5765 -5766 // ACK -5767 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { -5768 for path_id in space -5769 .number_spaces -5770 .iter_mut() -5771 .filter(|(_, pns)| pns.pending_acks.can_send()) -5772 .map(|(&path_id, _)| path_id) -5773 .collect::<Vec<_>>() -5774 { -5775 Self::populate_acks( -5776 now, -5777 self.receiving_ecn, -5778 path_id, -5779 space_id, -5780 space, -5781 is_multipath_negotiated, -5782 builder, -5783 stats, -5784 space_has_keys, -5785 ); -5786 } -5787 } -5788 -5789 // ACK_FREQUENCY -5790 if !scheduling_info.is_abandoned -5791 && scheduling_info.may_send_data -5792 && mem::replace(&mut space.pending.ack_frequency, false) -5793 { -5794 let sequence_number = self.ack_frequency.next_sequence_number(); -5795 -5796 // Safe to unwrap because this is always provided when ACK frequency is enabled -5797 let config = self.config.ack_frequency_config.as_ref().unwrap(); +5599 for (path_id, remote) in recoverable_paths.into_iter() { +5600 let space = &mut self.spaces[SpaceId::Data]; +5601 +5602 // Schedule a Ping for a liveness check. +5603 if let Some(path_space) = space.number_spaces.get_mut(&path_id) { +5604 path_space.ping_pending = true; +5605 +5606 if immediate_ack_allowed { +5607 path_space.immediate_ack_pending = true; +5608 } +5609 } +5610 +5611 let Some((reset_token, retired)) = +5612 self.remote_cids.get_mut(&path_id).and_then(CidQueue::next) +5613 else { +5614 continue; +5615 }; +5616 +5617 // Retire the current remote CID and any CIDs we had to skip. +5618 space +5619 .pending +5620 .retire_cids +5621 .extend(retired.map(|seq| (path_id, seq))); +5622 +5623 debug_assert!(!self.state.is_drained()); // required for endpoint_events, checked above +5624 self.endpoint_events +5625 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); +5626 } +5627 } +5628 +5629 /// Switch to a previously unused remote connection ID, if possible +5630 fn update_remote_cid(&mut self, path_id: PathId) { +5631 let Some((reset_token, retired)) = self +5632 .remote_cids +5633 .get_mut(&path_id) +5634 .and_then(|cids| cids.next()) +5635 else { +5636 return; +5637 }; +5638 +5639 // Retire the current remote CID and any CIDs we had to skip. +5640 self.spaces[SpaceId::Data] +5641 .pending +5642 .retire_cids +5643 .extend(retired.map(|seq| (path_id, seq))); +5644 let remote = self.path_data(path_id).network_path.remote; +5645 self.set_reset_token(path_id, remote, reset_token); +5646 } +5647 +5648 /// Sends this reset token to the endpoint +5649 /// +5650 /// The endpoint needs to know the reset tokens issued by the peer, so that if the peer +5651 /// sends a reset token it knows to route it to this connection. See RFC 9000 section +5652 /// 10.3. Stateless Reset. +5653 /// +5654 /// Reset tokens are different for each path, the endpoint identifies paths by peer +5655 /// socket address however, not by path ID. +5656 fn set_reset_token(&mut self, path_id: PathId, remote: SocketAddr, reset_token: ResetToken) { +5657 debug_assert!(!self.state.is_drained()); // required for endpoint events, set_reset_token is never called for drained connections +5658 self.endpoint_events +5659 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); +5660 +5661 // During the handshake the server sends a reset token in the transport +5662 // parameters. When we are the client and we receive the reset token during the +5663 // handshake we want this to affect our peer transport parameters. +5664 // TODO(flub): Pretty sure this is pointless, the entire params is overwritten +5665 // shortly after this was called. And then the params don't have this anymore. +5666 if path_id == PathId::ZERO { +5667 self.peer_params.stateless_reset_token = Some(reset_token); +5668 } +5669 } +5670 +5671 /// Issue an initial set of connection IDs to the peer upon connection +5672 fn issue_first_cids(&mut self, now: Instant) { +5673 if self +5674 .local_cid_state +5675 .get(&PathId::ZERO) +5676 .expect("PathId::ZERO exists when the connection is created") +5677 .cid_len() +5678 == 0 +5679 { +5680 return; +5681 } +5682 +5683 // Subtract 1 to account for the CID we supplied while handshaking +5684 let mut n = self.peer_params.issue_cids_limit() - 1; +5685 if let ConnectionSide::Server { server_config } = &self.side +5686 && server_config.has_preferred_address() +5687 { +5688 // We also sent a CID in the transport parameters +5689 n -= 1; +5690 } +5691 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events +5692 self.endpoint_events +5693 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); +5694 } +5695 +5696 /// Issues an initial set of CIDs for paths that have not yet had any CIDs issued +5697 /// +5698 /// Later CIDs are issued when CIDs expire or are retired by the peer. +5699 fn issue_first_path_cids(&mut self, now: Instant) { +5700 if let Some(max_path_id) = self.max_path_id() { +5701 let mut path_id = self.max_path_id_with_cids.next(); +5702 while path_id <= max_path_id { +5703 self.endpoint_events +5704 .push_back(EndpointEventInner::NeedIdentifiers( +5705 path_id, +5706 now, +5707 self.peer_params.issue_cids_limit(), +5708 )); +5709 path_id = path_id.next(); +5710 } +5711 self.max_path_id_with_cids = max_path_id; +5712 } +5713 } +5714 +5715 /// Populates a packet with frames +5716 /// +5717 /// This tries to fit as many frames as possible into the packet. +5718 /// +5719 /// *path_exclusive_only* means to only build frames which can only be sent on this +5720 /// *path. This is used in multipath for backup paths while there is still an active +5721 /// *path. +5722 fn populate_packet<'a, 'b>( +5723 &mut self, +5724 now: Instant, +5725 space_id: SpaceId, +5726 path_id: PathId, +5727 scheduling_info: &PathSchedulingInfo, +5728 builder: &mut PacketBuilder<'a, 'b>, +5729 ) { +5730 let is_multipath_negotiated = self.is_multipath_negotiated(); +5731 let space_has_keys = self.crypto_state.has_keys(space_id.encryption_level()); +5732 let is_0rtt = space_id == SpaceId::Data && !space_has_keys; +5733 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +5734 let space = &mut self.spaces[space_id]; +5735 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; +5736 space +5737 .for_path(path_id) +5738 .pending_acks +5739 .maybe_ack_non_eliciting(); +5740 +5741 // HANDSHAKE_DONE +5742 if !is_0rtt +5743 && !scheduling_info.is_abandoned +5744 && scheduling_info.may_send_data +5745 && mem::replace(&mut space.pending.handshake_done, false) +5746 { +5747 builder.write_frame(frame::HandshakeDone, stats); +5748 } +5749 +5750 // PING +5751 if !scheduling_info.is_abandoned +5752 && mem::replace(&mut space.for_path(path_id).ping_pending, false) +5753 { +5754 builder.write_frame(frame::Ping, stats); +5755 } +5756 +5757 // IMMEDIATE_ACK +5758 if !scheduling_info.is_abandoned +5759 && mem::replace(&mut space.for_path(path_id).immediate_ack_pending, false) +5760 { +5761 debug_assert_eq!( +5762 space_id, +5763 SpaceId::Data, +5764 "immediate acks must be sent in the data space" +5765 ); +5766 builder.write_frame(frame::ImmediateAck, stats); +5767 } +5768 +5769 // ACK +5770 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { +5771 for path_id in space +5772 .number_spaces +5773 .iter_mut() +5774 .filter(|(_, pns)| pns.pending_acks.can_send()) +5775 .map(|(&path_id, _)| path_id) +5776 .collect::<Vec<_>>() +5777 { +5778 Self::populate_acks( +5779 now, +5780 self.receiving_ecn, +5781 path_id, +5782 space_id, +5783 space, +5784 is_multipath_negotiated, +5785 builder, +5786 stats, +5787 space_has_keys, +5788 ); +5789 } +5790 } +5791 +5792 // ACK_FREQUENCY +5793 if !scheduling_info.is_abandoned +5794 && scheduling_info.may_send_data +5795 && mem::replace(&mut space.pending.ack_frequency, false) +5796 { +5797 let sequence_number = self.ack_frequency.next_sequence_number(); 5798 -5799 // Ensure the delay is within bounds to avoid a PROTOCOL_VIOLATION error -5800 let max_ack_delay = self.ack_frequency.candidate_max_ack_delay( -5801 path.rtt.get(), -5802 config, -5803 &self.peer_params, -5804 ); -5805 -5806 let frame = frame::AckFrequency { -5807 sequence: sequence_number, -5808 ack_eliciting_threshold: config.ack_eliciting_threshold, -5809 request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX), -5810 reordering_threshold: config.reordering_threshold, -5811 }; -5812 builder.write_frame(frame, stats); -5813 -5814 self.ack_frequency -5815 .ack_frequency_sent(path_id, builder.packet_number, max_ack_delay); -5816 } -5817 -5818 // PATH_CHALLENGE -5819 if !scheduling_info.is_abandoned -5820 && space_id == SpaceId::Data -5821 && path.pending_on_path_challenge -5822 && !self.state.is_closed() -5823 && builder.frame_space_remaining() > frame::PathChallenge::SIZE_BOUND -5824 // we don't want to send new challenges if we are already closing -5825 { -5826 path.pending_on_path_challenge = false; -5827 -5828 let token = self.rng.random(); -5829 path.record_path_challenge_sent(now, token, path.network_path); -5830 // Generate a new challenge every time we send a new PATH_CHALLENGE -5831 let challenge = frame::PathChallenge(token); -5832 builder.write_frame(challenge, stats); -5833 builder.require_padding(); -5834 let pto = self.ack_frequency.max_ack_delay_for_pto() + path.rtt.pto_base(); -5835 if path.open_status == paths::OpenStatus::Pending { -5836 path.open_status = paths::OpenStatus::Sent; -5837 self.timers.set( -5838 Timer::PerPath(path_id, PathTimer::PathOpenFailed), -5839 now + 3 * pto, -5840 self.qlog.with_time(now), -5841 ); -5842 } -5843 -5844 self.timers.set( -5845 Timer::PerPath(path_id, PathTimer::PathChallengeLost), -5846 now + pto, -5847 self.qlog.with_time(now), -5848 ); -5849 -5850 if is_multipath_negotiated && !path.validated && path.pending_on_path_challenge { -5851 // queue informing the path status along with the challenge -5852 space.pending.path_status.insert(path_id); -5853 } -5854 -5855 // Always include an OBSERVED_ADDR frame with a PATH_CHALLENGE, regardless -5856 // of whether one has already been sent on this path. -5857 if space_id == SpaceId::Data -5858 && self -5859 .config -5860 .address_discovery_role -5861 .should_report(&self.peer_params.address_discovery_role) -5862 { -5863 let frame = frame::ObservedAddr::new( -5864 path.network_path.remote, -5865 self.next_observed_addr_seq_no, -5866 ); -5867 if builder.frame_space_remaining() > frame.size() { -5868 builder.write_frame(frame, stats); -5869 -5870 self.next_observed_addr_seq_no = -5871 self.next_observed_addr_seq_no.saturating_add(1u8); -5872 path.observed_addr_sent = true; -5873 -5874 space.pending.observed_addr = false; -5875 } -5876 } -5877 } -5878 -5879 // PATH_RESPONSE -5880 if !scheduling_info.is_abandoned -5881 && space_id == SpaceId::Data -5882 && builder.frame_space_remaining() > frame::PathResponse::SIZE_BOUND -5883 && let Some(token) = path.path_responses.pop_on_path(path.network_path) -5884 { -5885 let response = frame::PathResponse(token); -5886 builder.write_frame(response, stats); -5887 builder.require_padding(); -5888 -5889 // NOTE: this is technically not required but might be useful to ride the -5890 // request/response nature of path challenges to refresh an observation -5891 // Since PATH_RESPONSE is a probing frame, this is allowed by the spec. -5892 if space_id == SpaceId::Data -5893 && self -5894 .config -5895 .address_discovery_role -5896 .should_report(&self.peer_params.address_discovery_role) -5897 { -5898 let frame = frame::ObservedAddr::new( -5899 path.network_path.remote, -5900 self.next_observed_addr_seq_no, -5901 ); -5902 if builder.frame_space_remaining() > frame.size() { -5903 builder.write_frame(frame, stats); -5904 -5905 self.next_observed_addr_seq_no = -5906 self.next_observed_addr_seq_no.saturating_add(1u8); -5907 path.observed_addr_sent = true; -5908 -5909 space.pending.observed_addr = false; -5910 } -5911 } -5912 } -5913 -5914 // REACH_OUT -5915 if !scheduling_info.is_abandoned -5916 && scheduling_info.may_send_data -5917 && let Some((round, addresses)) = space.pending.reach_out.as_mut() -5918 { -5919 while let Some(local_addr) = addresses.iter().next().copied() { -5920 let local_addr = addresses.take(&local_addr).expect("found from iter"); -5921 let reach_out = frame::ReachOut::new(*round, local_addr); -5922 if builder.frame_space_remaining() > reach_out.size() { -5923 builder.write_frame(reach_out, stats); -5924 } else { -5925 addresses.insert(local_addr); -5926 break; -5927 } -5928 } -5929 if addresses.is_empty() { -5930 space.pending.reach_out = None; +5799 // Safe to unwrap because this is always provided when ACK frequency is enabled +5800 let config = self.config.ack_frequency_config.as_ref().unwrap(); +5801 +5802 // Ensure the delay is within bounds to avoid a PROTOCOL_VIOLATION error +5803 let max_ack_delay = self.ack_frequency.candidate_max_ack_delay( +5804 path.rtt.get(), +5805 config, +5806 &self.peer_params, +5807 ); +5808 +5809 let frame = frame::AckFrequency { +5810 sequence: sequence_number, +5811 ack_eliciting_threshold: config.ack_eliciting_threshold, +5812 request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX), +5813 reordering_threshold: config.reordering_threshold, +5814 }; +5815 builder.write_frame(frame, stats); +5816 +5817 self.ack_frequency +5818 .ack_frequency_sent(path_id, builder.packet_number, max_ack_delay); +5819 } +5820 +5821 // PATH_CHALLENGE +5822 if !scheduling_info.is_abandoned +5823 && space_id == SpaceId::Data +5824 && path.pending_on_path_challenge +5825 && !self.state.is_closed() +5826 && builder.frame_space_remaining() > frame::PathChallenge::SIZE_BOUND +5827 // we don't want to send new challenges if we are already closing +5828 { +5829 path.pending_on_path_challenge = false; +5830 +5831 let token = self.rng.random(); +5832 path.record_path_challenge_sent(now, token, path.network_path); +5833 // Generate a new challenge every time we send a new PATH_CHALLENGE +5834 let challenge = frame::PathChallenge(token); +5835 builder.write_frame(challenge, stats); +5836 builder.require_padding(); +5837 let pto = self.ack_frequency.max_ack_delay_for_pto() + path.rtt.pto_base(); +5838 if path.open_status == paths::OpenStatus::Pending { +5839 path.open_status = paths::OpenStatus::Sent; +5840 self.timers.set( +5841 Timer::PerPath(path_id, PathTimer::PathOpenFailed), +5842 now + 3 * pto, +5843 self.qlog.with_time(now), +5844 ); +5845 } +5846 +5847 self.timers.set( +5848 Timer::PerPath(path_id, PathTimer::PathChallengeLost), +5849 now + pto, +5850 self.qlog.with_time(now), +5851 ); +5852 +5853 if is_multipath_negotiated && !path.validated && path.pending_on_path_challenge { +5854 // queue informing the path status along with the challenge +5855 space.pending.path_status.insert(path_id); +5856 } +5857 +5858 // Always include an OBSERVED_ADDR frame with a PATH_CHALLENGE, regardless +5859 // of whether one has already been sent on this path. +5860 if space_id == SpaceId::Data +5861 && self +5862 .config +5863 .address_discovery_role +5864 .should_report(&self.peer_params.address_discovery_role) +5865 { +5866 let frame = frame::ObservedAddr::new( +5867 path.network_path.remote, +5868 self.next_observed_addr_seq_no, +5869 ); +5870 if builder.frame_space_remaining() > frame.size() { +5871 builder.write_frame(frame, stats); +5872 +5873 self.next_observed_addr_seq_no = +5874 self.next_observed_addr_seq_no.saturating_add(1u8); +5875 path.observed_addr_sent = true; +5876 +5877 space.pending.observed_addr = false; +5878 } +5879 } +5880 } +5881 +5882 // PATH_RESPONSE +5883 if !scheduling_info.is_abandoned +5884 && space_id == SpaceId::Data +5885 && builder.frame_space_remaining() > frame::PathResponse::SIZE_BOUND +5886 && let Some(token) = path.path_responses.pop_on_path(path.network_path) +5887 { +5888 let response = frame::PathResponse(token); +5889 builder.write_frame(response, stats); +5890 builder.require_padding(); +5891 +5892 // NOTE: this is technically not required but might be useful to ride the +5893 // request/response nature of path challenges to refresh an observation +5894 // Since PATH_RESPONSE is a probing frame, this is allowed by the spec. +5895 if space_id == SpaceId::Data +5896 && self +5897 .config +5898 .address_discovery_role +5899 .should_report(&self.peer_params.address_discovery_role) +5900 { +5901 let frame = frame::ObservedAddr::new( +5902 path.network_path.remote, +5903 self.next_observed_addr_seq_no, +5904 ); +5905 if builder.frame_space_remaining() > frame.size() { +5906 builder.write_frame(frame, stats); +5907 +5908 self.next_observed_addr_seq_no = +5909 self.next_observed_addr_seq_no.saturating_add(1u8); +5910 path.observed_addr_sent = true; +5911 +5912 space.pending.observed_addr = false; +5913 } +5914 } +5915 } +5916 +5917 // REACH_OUT +5918 if !scheduling_info.is_abandoned +5919 && scheduling_info.may_send_data +5920 && let Some((round, addresses)) = space.pending.reach_out.as_mut() +5921 { +5922 while let Some(local_addr) = addresses.iter().next().copied() { +5923 let local_addr = addresses.take(&local_addr).expect("found from iter"); +5924 let reach_out = frame::ReachOut::new(*round, local_addr); +5925 if builder.frame_space_remaining() > reach_out.size() { +5926 builder.write_frame(reach_out, stats); +5927 } else { +5928 addresses.insert(local_addr); +5929 break; +5930 } 5931 } -5932 } -5933 -5934 // PATH_ABANDON -5935 if space_id == SpaceId::Data -5936 && scheduling_info.is_abandoned -5937 && scheduling_info.may_self_abandon -5938 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() -5939 && let Some(error_code) = space.pending.path_abandon.remove(&path_id) -5940 { -5941 let frame = frame::PathAbandon { -5942 path_id, -5943 error_code, -5944 }; -5945 builder.write_frame(frame, stats); -5946 -5947 // Consider remotely issued CIDs as retired now that we have sent this frame at -5948 // least once. -5949 self.remote_cids.remove(&path_id); -5950 } -5951 while space_id == SpaceId::Data -5952 && scheduling_info.may_send_data -5953 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() -5954 && let Some((abandoned_path_id, error_code)) = space.pending.path_abandon.pop_first() -5955 { -5956 let frame = frame::PathAbandon { -5957 path_id: abandoned_path_id, -5958 error_code, -5959 }; -5960 builder.write_frame(frame, stats); -5961 -5962 // Consider remotely issued CIDs as retired now that we have sent this frame at -5963 // least once. -5964 self.remote_cids.remove(&abandoned_path_id); -5965 } -5966 -5967 // OBSERVED_ADDR -5968 if !scheduling_info.is_abandoned -5969 && scheduling_info.may_send_data -5970 && space_id == SpaceId::Data -5971 && self -5972 .config -5973 .address_discovery_role -5974 .should_report(&self.peer_params.address_discovery_role) -5975 && (!path.observed_addr_sent || space.pending.observed_addr) -5976 { -5977 let frame = -5978 frame::ObservedAddr::new(path.network_path.remote, self.next_observed_addr_seq_no); -5979 if builder.frame_space_remaining() > frame.size() { -5980 builder.write_frame(frame, stats); -5981 -5982 self.next_observed_addr_seq_no = self.next_observed_addr_seq_no.saturating_add(1u8); -5983 path.observed_addr_sent = true; +5932 if addresses.is_empty() { +5933 space.pending.reach_out = None; +5934 } +5935 } +5936 +5937 // PATH_ABANDON +5938 if space_id == SpaceId::Data +5939 && scheduling_info.is_abandoned +5940 && scheduling_info.may_self_abandon +5941 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() +5942 && let Some(error_code) = space.pending.path_abandon.remove(&path_id) +5943 { +5944 let frame = frame::PathAbandon { +5945 path_id, +5946 error_code, +5947 }; +5948 builder.write_frame(frame, stats); +5949 +5950 // Consider remotely issued CIDs as retired now that we have sent this frame at +5951 // least once. +5952 self.remote_cids.remove(&path_id); +5953 } +5954 while space_id == SpaceId::Data +5955 && scheduling_info.may_send_data +5956 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() +5957 && let Some((abandoned_path_id, error_code)) = space.pending.path_abandon.pop_first() +5958 { +5959 let frame = frame::PathAbandon { +5960 path_id: abandoned_path_id, +5961 error_code, +5962 }; +5963 builder.write_frame(frame, stats); +5964 +5965 // Consider remotely issued CIDs as retired now that we have sent this frame at +5966 // least once. +5967 self.remote_cids.remove(&abandoned_path_id); +5968 } +5969 +5970 // OBSERVED_ADDR +5971 if !scheduling_info.is_abandoned +5972 && scheduling_info.may_send_data +5973 && space_id == SpaceId::Data +5974 && self +5975 .config +5976 .address_discovery_role +5977 .should_report(&self.peer_params.address_discovery_role) +5978 && (!path.observed_addr_sent || space.pending.observed_addr) +5979 { +5980 let frame = +5981 frame::ObservedAddr::new(path.network_path.remote, self.next_observed_addr_seq_no); +5982 if builder.frame_space_remaining() > frame.size() { +5983 builder.write_frame(frame, stats); 5984 -5985 space.pending.observed_addr = false; -5986 } -5987 } -5988 -5989 // CRYPTO -5990 while !is_0rtt -5991 && !scheduling_info.is_abandoned -5992 && scheduling_info.may_send_data -5993 && builder.frame_space_remaining() > frame::Crypto::SIZE_BOUND -5994 { -5995 let Some(mut frame) = space.pending.crypto.pop_front() else { -5996 break; -5997 }; -5998 -5999 // Calculate the maximum amount of crypto data we can store in the buffer. -6000 // Since the offset is known, we can reserve the exact size required to encode it. -6001 // For length we reserve 2bytes which allows to encode up to 2^14, -6002 // which is more than what fits into normally sized QUIC frames. -6003 let max_crypto_data_size = builder.frame_space_remaining() -6004 - 1 // Frame Type -6005 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) }) -6006 - 2; // Maximum encoded length for frame size, given we send less than 2^14 bytes -6007 -6008 let len = frame -6009 .data -6010 .len() -6011 .min(2usize.pow(14) - 1) -6012 .min(max_crypto_data_size); -6013 -6014 let data = frame.data.split_to(len); -6015 let offset = frame.offset; -6016 let truncated = frame::Crypto { offset, data }; -6017 builder.write_frame(truncated, stats); -6018 -6019 if !frame.data.is_empty() { -6020 frame.offset += len as u64; -6021 space.pending.crypto.push_front(frame); -6022 } -6023 } -6024 -6025 // PATH_STATUS_AVAILABLE & PATH_STATUS_BACKUP -6026 while space_id == SpaceId::Data -6027 && !scheduling_info.is_abandoned -6028 && scheduling_info.may_send_data -6029 && frame::PathStatusAvailable::SIZE_BOUND <= builder.frame_space_remaining() -6030 { -6031 let Some(path_id) = space.pending.path_status.pop_first() else { -6032 break; -6033 }; -6034 let Some(path) = self.paths.get(&path_id).map(|path_state| &path_state.data) else { -6035 trace!(%path_id, "discarding queued path status for unknown path"); -6036 continue; -6037 }; -6038 -6039 let seq = path.status.seq(); -6040 match path.local_status() { -6041 PathStatus::Available => { -6042 let frame = frame::PathStatusAvailable { -6043 path_id, -6044 status_seq_no: seq, -6045 }; -6046 builder.write_frame(frame, stats); -6047 } -6048 PathStatus::Backup => { -6049 let frame = frame::PathStatusBackup { -6050 path_id, -6051 status_seq_no: seq, -6052 }; -6053 builder.write_frame(frame, stats); -6054 } -6055 } -6056 } -6057 -6058 // MAX_PATH_ID -6059 if space_id == SpaceId::Data -6060 && !scheduling_info.is_abandoned -6061 && scheduling_info.may_send_data -6062 && space.pending.max_path_id -6063 && frame::MaxPathId::SIZE_BOUND <= builder.frame_space_remaining() -6064 { -6065 let frame = frame::MaxPathId(self.local_max_path_id); -6066 builder.write_frame(frame, stats); -6067 space.pending.max_path_id = false; -6068 } -6069 -6070 // PATHS_BLOCKED -6071 if space_id == SpaceId::Data -6072 && !scheduling_info.is_abandoned -6073 && scheduling_info.may_send_data -6074 && space.pending.paths_blocked -6075 && frame::PathsBlocked::SIZE_BOUND <= builder.frame_space_remaining() -6076 { -6077 let frame = frame::PathsBlocked(self.remote_max_path_id); -6078 builder.write_frame(frame, stats); -6079 space.pending.paths_blocked = false; -6080 } -6081 -6082 // PATH_CIDS_BLOCKED -6083 while space_id == SpaceId::Data -6084 && !scheduling_info.is_abandoned -6085 && scheduling_info.may_send_data -6086 && frame::PathCidsBlocked::SIZE_BOUND <= builder.frame_space_remaining() -6087 { -6088 let Some(path_id) = space.pending.path_cids_blocked.pop_first() else { -6089 break; -6090 }; -6091 let next_seq = match self.remote_cids.get(&path_id) { -6092 Some(cid_queue) => VarInt(cid_queue.active_seq() + 1), -6093 None => VarInt(0), -6094 }; -6095 let frame = frame::PathCidsBlocked { path_id, next_seq }; -6096 builder.write_frame(frame, stats); -6097 } -6098 -6099 // RESET_STREAM, STOP_SENDING, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS -6100 if space_id == SpaceId::Data -6101 && !scheduling_info.is_abandoned -6102 && scheduling_info.may_send_data -6103 { -6104 self.streams -6105 .write_control_frames(builder, &mut space.pending, stats); -6106 } -6107 -6108 // NEW_CONNECTION_ID -6109 let cid_len = self -6110 .local_cid_state -6111 .values() -6112 .map(|cid_state| cid_state.cid_len()) -6113 .max() -6114 .expect("some local CID state must exist"); -6115 let new_cid_size_bound = -6116 frame::NewConnectionId::size_bound(is_multipath_negotiated, cid_len); -6117 while !scheduling_info.is_abandoned -6118 && scheduling_info.may_send_data -6119 && builder.frame_space_remaining() > new_cid_size_bound -6120 { -6121 let Some(issued) = space.pending.new_cids.pop() else { -6122 break; -6123 }; -6124 let retire_prior_to = self -6125 .local_cid_state -6126 .get(&issued.path_id) -6127 .map(|cid_state| cid_state.retire_prior_to()) -6128 .unwrap_or_else(|| panic!("missing local CID state for path={}", issued.path_id)); -6129 -6130 let cid_path_id = match is_multipath_negotiated { -6131 true => Some(issued.path_id), -6132 false => { -6133 debug_assert_eq!(issued.path_id, PathId::ZERO); -6134 None -6135 } -6136 }; -6137 let frame = frame::NewConnectionId { -6138 path_id: cid_path_id, -6139 sequence: issued.sequence, -6140 retire_prior_to, -6141 id: issued.id, -6142 reset_token: issued.reset_token, -6143 }; -6144 builder.write_frame(frame, stats); -6145 } -6146 -6147 // RETIRE_CONNECTION_ID -6148 let retire_cid_bound = frame::RetireConnectionId::size_bound(is_multipath_negotiated); -6149 while !scheduling_info.is_abandoned -6150 && scheduling_info.may_send_data -6151 && builder.frame_space_remaining() > retire_cid_bound -6152 { -6153 let (path_id, sequence) = match space.pending.retire_cids.pop() { -6154 Some((PathId::ZERO, seq)) if !is_multipath_negotiated => (None, seq), -6155 Some((path_id, seq)) => (Some(path_id), seq), -6156 None => break, -6157 }; -6158 let frame = frame::RetireConnectionId { path_id, sequence }; -6159 builder.write_frame(frame, stats); -6160 } -6161 -6162 // DATAGRAM -6163 let mut sent_datagrams = false; -6164 while !scheduling_info.is_abandoned -6165 && scheduling_info.may_send_data -6166 && builder.frame_space_remaining() > Datagram::SIZE_BOUND -6167 && space_id == SpaceId::Data -6168 { -6169 match self.datagrams.write(builder, stats) { -6170 true => { -6171 sent_datagrams = true; -6172 } -6173 false => break, -6174 } -6175 } -6176 if self.datagrams.send_blocked && sent_datagrams { -6177 self.events.push_back(Event::DatagramsUnblocked); -6178 self.datagrams.send_blocked = false; -6179 } -6180 -6181 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; -6182 -6183 // NEW_TOKEN -6184 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { -6185 while let Some(network_path) = space.pending.new_tokens.pop() { -6186 debug_assert_eq!(space_id, SpaceId::Data); -6187 let ConnectionSide::Server { server_config } = &self.side else { -6188 panic!("NEW_TOKEN frames should not be enqueued by clients"); -6189 }; -6190 -6191 if !network_path.is_probably_same_path(&path.network_path) { -6192 // NEW_TOKEN frames contain tokens bound to a client's IP address, and are only -6193 // useful if used from the same IP address. Thus, we abandon enqueued NEW_TOKEN -6194 // frames upon an path change. Instead, when the new path becomes validated, -6195 // NEW_TOKEN frames may be enqueued for the new path instead. -6196 continue; -6197 } -6198 -6199 let token = Token::new( -6200 TokenPayload::Validation { -6201 ip: network_path.remote.ip(), -6202 issued: server_config.time_source.now(), -6203 }, -6204 &mut self.rng, -6205 ); -6206 let new_token = NewToken { -6207 token: token.encode(&*server_config.token_key).into(), -6208 }; -6209 -6210 if builder.frame_space_remaining() < new_token.size() { -6211 space.pending.new_tokens.push(network_path); -6212 break; -6213 } -6214 -6215 builder.write_frame(new_token, stats); -6216 builder.retransmits_mut().new_tokens.push(network_path); -6217 } -6218 } -6219 -6220 // STREAM -6221 if !scheduling_info.is_abandoned -6222 && scheduling_info.may_send_data -6223 && space_id == SpaceId::Data -6224 { -6225 self.streams -6226 .write_stream_frames(builder, self.config.send_fairness, stats); -6227 } -6228 -6229 // ADD_ADDRESS -6230 while space_id == SpaceId::Data -6231 && !scheduling_info.is_abandoned -6232 && scheduling_info.may_send_data -6233 && frame::AddAddress::SIZE_BOUND <= builder.frame_space_remaining() -6234 { -6235 if let Some(added_address) = space.pending.add_address.pop_last() { -6236 builder.write_frame(added_address, stats); -6237 } else { -6238 break; -6239 } -6240 } -6241 -6242 // REMOVE_ADDRESS -6243 while space_id == SpaceId::Data -6244 && !scheduling_info.is_abandoned -6245 && scheduling_info.may_send_data -6246 && frame::RemoveAddress::SIZE_BOUND <= builder.frame_space_remaining() -6247 { -6248 if let Some(removed_address) = space.pending.remove_address.pop_last() { -6249 builder.write_frame(removed_address, stats); -6250 } else { -6251 break; -6252 } -6253 } -6254 } -6255 -6256 /// Write pending ACKs into a buffer -6257 fn populate_acks<'a, 'b>( -6258 now: Instant, -6259 receiving_ecn: bool, -6260 path_id: PathId, -6261 space_id: SpaceId, -6262 space: &mut PacketSpace, -6263 is_multipath_negotiated: bool, -6264 builder: &mut PacketBuilder<'a, 'b>, -6265 stats: &mut FrameStats, -6266 space_has_keys: bool, -6267 ) { -6268 // 0-RTT packets must never carry acks (which would have to be of handshake packets) -6269 debug_assert!(space_has_keys, "tried to send ACK in 0-RTT"); -6270 -6271 debug_assert!( -6272 is_multipath_negotiated || path_id == PathId::ZERO, -6273 "Only PathId::ZERO allowed without multipath (have {path_id:?})" -6274 ); -6275 if is_multipath_negotiated { -6276 debug_assert!( -6277 space_id == SpaceId::Data || path_id == PathId::ZERO, -6278 "path acks must be sent in 1RTT space (have {space_id:?})" -6279 ); -6280 } -6281 -6282 let pns = space.for_path(path_id); -6283 let ranges = pns.pending_acks.ranges(); -6284 debug_assert!(!ranges.is_empty(), "can not send empty ACK range"); -6285 let ecn = if receiving_ecn { -6286 Some(&pns.ecn_counters) -6287 } else { -6288 None -6289 }; -6290 -6291 let delay_micros = pns.pending_acks.ack_delay(now).as_micros() as u64; -6292 // TODO: This should come from `TransportConfig` if that gets configurable. -6293 let ack_delay_exp = TransportParameters::default().ack_delay_exponent; -6294 let delay = delay_micros >> ack_delay_exp.into_inner(); -6295 -6296 if is_multipath_negotiated && space_id == SpaceId::Data { -6297 if !ranges.is_empty() { -6298 let frame = frame::PathAck::encoder(path_id, delay, ranges, ecn); -6299 builder.write_frame(frame, stats); -6300 } -6301 } else { -6302 builder.write_frame(frame::Ack::encoder(delay, ranges, ecn), stats); -6303 } -6304 } -6305 -6306 fn close_common(&mut self) { -6307 trace!("connection closed"); -6308 self.timers.reset(); -6309 } -6310 -6311 fn set_close_timer(&mut self, now: Instant) { -6312 // QUIC-MULTIPATH § 2.6 Connection Closure: draining for 3*PTO using the max PTO of -6313 // all paths. -6314 let pto_max = self.max_pto_for_space(self.highest_space); -6315 self.timers.set( -6316 Timer::Conn(ConnTimer::Close), -6317 now + 3 * pto_max, -6318 self.qlog.with_time(now), -6319 ); -6320 } -6321 -6322 /// Handle transport parameters received from the peer -6323 /// -6324 /// *remote_cid* and *local_cid* are the source and destination CIDs respectively of the -6325 /// *packet into which the transport parameters arrived. -6326 fn handle_peer_params( -6327 &mut self, -6328 params: TransportParameters, -6329 local_cid: ConnectionId, -6330 remote_cid: ConnectionId, -6331 now: Instant, -6332 ) -> Result<(), TransportError> { -6333 if Some(self.original_remote_cid) != params.initial_src_cid -6334 || (self.side.is_client() -6335 && (Some(self.initial_dst_cid) != params.original_dst_cid -6336 || self.retry_src_cid != params.retry_src_cid)) -6337 { -6338 return Err(TransportError::TRANSPORT_PARAMETER_ERROR( -6339 "CID authentication failure", -6340 )); -6341 } -6342 if params.initial_max_path_id.is_some() && (local_cid.is_empty() || remote_cid.is_empty()) { -6343 return Err(TransportError::PROTOCOL_VIOLATION( -6344 "multipath must not use zero-length CIDs", -6345 )); -6346 } -6347 -6348 self.set_peer_params(params); -6349 self.qlog.emit_peer_transport_params_received(self, now); +5985 self.next_observed_addr_seq_no = self.next_observed_addr_seq_no.saturating_add(1u8); +5986 path.observed_addr_sent = true; +5987 +5988 space.pending.observed_addr = false; +5989 } +5990 } +5991 +5992 // CRYPTO +5993 while !is_0rtt +5994 && !scheduling_info.is_abandoned +5995 && scheduling_info.may_send_data +5996 && builder.frame_space_remaining() > frame::Crypto::SIZE_BOUND +5997 { +5998 let Some(mut frame) = space.pending.crypto.pop_front() else { +5999 break; +6000 }; +6001 +6002 // Calculate the maximum amount of crypto data we can store in the buffer. +6003 // Since the offset is known, we can reserve the exact size required to encode it. +6004 // For length we reserve 2bytes which allows to encode up to 2^14, +6005 // which is more than what fits into normally sized QUIC frames. +6006 let max_crypto_data_size = builder.frame_space_remaining() +6007 - 1 // Frame Type +6008 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) }) +6009 - 2; // Maximum encoded length for frame size, given we send less than 2^14 bytes +6010 +6011 let len = frame +6012 .data +6013 .len() +6014 .min(2usize.pow(14) - 1) +6015 .min(max_crypto_data_size); +6016 +6017 let data = frame.data.split_to(len); +6018 let offset = frame.offset; +6019 let truncated = frame::Crypto { offset, data }; +6020 builder.write_frame(truncated, stats); +6021 +6022 if !frame.data.is_empty() { +6023 frame.offset += len as u64; +6024 space.pending.crypto.push_front(frame); +6025 } +6026 } +6027 +6028 // PATH_STATUS_AVAILABLE & PATH_STATUS_BACKUP +6029 while space_id == SpaceId::Data +6030 && !scheduling_info.is_abandoned +6031 && scheduling_info.may_send_data +6032 && frame::PathStatusAvailable::SIZE_BOUND <= builder.frame_space_remaining() +6033 { +6034 let Some(path_id) = space.pending.path_status.pop_first() else { +6035 break; +6036 }; +6037 let Some(path) = self.paths.get(&path_id).map(|path_state| &path_state.data) else { +6038 trace!(%path_id, "discarding queued path status for unknown path"); +6039 continue; +6040 }; +6041 +6042 let seq = path.status.seq(); +6043 match path.local_status() { +6044 PathStatus::Available => { +6045 let frame = frame::PathStatusAvailable { +6046 path_id, +6047 status_seq_no: seq, +6048 }; +6049 builder.write_frame(frame, stats); +6050 } +6051 PathStatus::Backup => { +6052 let frame = frame::PathStatusBackup { +6053 path_id, +6054 status_seq_no: seq, +6055 }; +6056 builder.write_frame(frame, stats); +6057 } +6058 } +6059 } +6060 +6061 // MAX_PATH_ID +6062 if space_id == SpaceId::Data +6063 && !scheduling_info.is_abandoned +6064 && scheduling_info.may_send_data +6065 && space.pending.max_path_id +6066 && frame::MaxPathId::SIZE_BOUND <= builder.frame_space_remaining() +6067 { +6068 let frame = frame::MaxPathId(self.local_max_path_id); +6069 builder.write_frame(frame, stats); +6070 space.pending.max_path_id = false; +6071 } +6072 +6073 // PATHS_BLOCKED +6074 if space_id == SpaceId::Data +6075 && !scheduling_info.is_abandoned +6076 && scheduling_info.may_send_data +6077 && space.pending.paths_blocked +6078 && frame::PathsBlocked::SIZE_BOUND <= builder.frame_space_remaining() +6079 { +6080 let frame = frame::PathsBlocked(self.remote_max_path_id); +6081 builder.write_frame(frame, stats); +6082 space.pending.paths_blocked = false; +6083 } +6084 +6085 // PATH_CIDS_BLOCKED +6086 while space_id == SpaceId::Data +6087 && !scheduling_info.is_abandoned +6088 && scheduling_info.may_send_data +6089 && frame::PathCidsBlocked::SIZE_BOUND <= builder.frame_space_remaining() +6090 { +6091 let Some(path_id) = space.pending.path_cids_blocked.pop_first() else { +6092 break; +6093 }; +6094 let next_seq = match self.remote_cids.get(&path_id) { +6095 Some(cid_queue) => VarInt(cid_queue.active_seq() + 1), +6096 None => VarInt(0), +6097 }; +6098 let frame = frame::PathCidsBlocked { path_id, next_seq }; +6099 builder.write_frame(frame, stats); +6100 } +6101 +6102 // RESET_STREAM, STOP_SENDING, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS +6103 if space_id == SpaceId::Data +6104 && !scheduling_info.is_abandoned +6105 && scheduling_info.may_send_data +6106 { +6107 self.streams +6108 .write_control_frames(builder, &mut space.pending, stats); +6109 } +6110 +6111 // NEW_CONNECTION_ID +6112 let cid_len = self +6113 .local_cid_state +6114 .values() +6115 .map(|cid_state| cid_state.cid_len()) +6116 .max() +6117 .expect("some local CID state must exist"); +6118 let new_cid_size_bound = +6119 frame::NewConnectionId::size_bound(is_multipath_negotiated, cid_len); +6120 while !scheduling_info.is_abandoned +6121 && scheduling_info.may_send_data +6122 && builder.frame_space_remaining() > new_cid_size_bound +6123 { +6124 let Some(issued) = space.pending.new_cids.pop() else { +6125 break; +6126 }; +6127 let retire_prior_to = self +6128 .local_cid_state +6129 .get(&issued.path_id) +6130 .map(|cid_state| cid_state.retire_prior_to()) +6131 .unwrap_or_else(|| panic!("missing local CID state for path={}", issued.path_id)); +6132 +6133 let cid_path_id = match is_multipath_negotiated { +6134 true => Some(issued.path_id), +6135 false => { +6136 debug_assert_eq!(issued.path_id, PathId::ZERO); +6137 None +6138 } +6139 }; +6140 let frame = frame::NewConnectionId { +6141 path_id: cid_path_id, +6142 sequence: issued.sequence, +6143 retire_prior_to, +6144 id: issued.id, +6145 reset_token: issued.reset_token, +6146 }; +6147 builder.write_frame(frame, stats); +6148 } +6149 +6150 // RETIRE_CONNECTION_ID +6151 let retire_cid_bound = frame::RetireConnectionId::size_bound(is_multipath_negotiated); +6152 while !scheduling_info.is_abandoned +6153 && scheduling_info.may_send_data +6154 && builder.frame_space_remaining() > retire_cid_bound +6155 { +6156 let (path_id, sequence) = match space.pending.retire_cids.pop() { +6157 Some((PathId::ZERO, seq)) if !is_multipath_negotiated => (None, seq), +6158 Some((path_id, seq)) => (Some(path_id), seq), +6159 None => break, +6160 }; +6161 let frame = frame::RetireConnectionId { path_id, sequence }; +6162 builder.write_frame(frame, stats); +6163 } +6164 +6165 // DATAGRAM +6166 let mut sent_datagrams = false; +6167 while !scheduling_info.is_abandoned +6168 && scheduling_info.may_send_data +6169 && builder.frame_space_remaining() > Datagram::SIZE_BOUND +6170 && space_id == SpaceId::Data +6171 { +6172 match self.datagrams.write(builder, stats) { +6173 true => { +6174 sent_datagrams = true; +6175 } +6176 false => break, +6177 } +6178 } +6179 if self.datagrams.send_blocked && sent_datagrams { +6180 self.events.push_back(Event::DatagramsUnblocked); +6181 self.datagrams.send_blocked = false; +6182 } +6183 +6184 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; +6185 +6186 // NEW_TOKEN +6187 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { +6188 while let Some(network_path) = space.pending.new_tokens.pop() { +6189 debug_assert_eq!(space_id, SpaceId::Data); +6190 let ConnectionSide::Server { server_config } = &self.side else { +6191 panic!("NEW_TOKEN frames should not be enqueued by clients"); +6192 }; +6193 +6194 if !network_path.is_probably_same_path(&path.network_path) { +6195 // NEW_TOKEN frames contain tokens bound to a client's IP address, and are only +6196 // useful if used from the same IP address. Thus, we abandon enqueued NEW_TOKEN +6197 // frames upon an path change. Instead, when the new path becomes validated, +6198 // NEW_TOKEN frames may be enqueued for the new path instead. +6199 continue; +6200 } +6201 +6202 let token = Token::new( +6203 TokenPayload::Validation { +6204 ip: network_path.remote.ip(), +6205 issued: server_config.time_source.now(), +6206 }, +6207 &mut self.rng, +6208 ); +6209 let new_token = NewToken { +6210 token: token.encode(&*server_config.token_key).into(), +6211 }; +6212 +6213 if builder.frame_space_remaining() < new_token.size() { +6214 space.pending.new_tokens.push(network_path); +6215 break; +6216 } +6217 +6218 builder.write_frame(new_token, stats); +6219 builder.retransmits_mut().new_tokens.push(network_path); +6220 } +6221 } +6222 +6223 // STREAM +6224 if !scheduling_info.is_abandoned +6225 && scheduling_info.may_send_data +6226 && space_id == SpaceId::Data +6227 { +6228 self.streams +6229 .write_stream_frames(builder, self.config.send_fairness, stats); +6230 } +6231 +6232 // ADD_ADDRESS +6233 while space_id == SpaceId::Data +6234 && !scheduling_info.is_abandoned +6235 && scheduling_info.may_send_data +6236 && frame::AddAddress::SIZE_BOUND <= builder.frame_space_remaining() +6237 { +6238 if let Some(added_address) = space.pending.add_address.pop_last() { +6239 builder.write_frame(added_address, stats); +6240 } else { +6241 break; +6242 } +6243 } +6244 +6245 // REMOVE_ADDRESS +6246 while space_id == SpaceId::Data +6247 && !scheduling_info.is_abandoned +6248 && scheduling_info.may_send_data +6249 && frame::RemoveAddress::SIZE_BOUND <= builder.frame_space_remaining() +6250 { +6251 if let Some(removed_address) = space.pending.remove_address.pop_last() { +6252 builder.write_frame(removed_address, stats); +6253 } else { +6254 break; +6255 } +6256 } +6257 } +6258 +6259 /// Write pending ACKs into a buffer +6260 fn populate_acks<'a, 'b>( +6261 now: Instant, +6262 receiving_ecn: bool, +6263 path_id: PathId, +6264 space_id: SpaceId, +6265 space: &mut PacketSpace, +6266 is_multipath_negotiated: bool, +6267 builder: &mut PacketBuilder<'a, 'b>, +6268 stats: &mut FrameStats, +6269 space_has_keys: bool, +6270 ) { +6271 // 0-RTT packets must never carry acks (which would have to be of handshake packets) +6272 debug_assert!(space_has_keys, "tried to send ACK in 0-RTT"); +6273 +6274 debug_assert!( +6275 is_multipath_negotiated || path_id == PathId::ZERO, +6276 "Only PathId::ZERO allowed without multipath (have {path_id:?})" +6277 ); +6278 if is_multipath_negotiated { +6279 debug_assert!( +6280 space_id == SpaceId::Data || path_id == PathId::ZERO, +6281 "path acks must be sent in 1RTT space (have {space_id:?})" +6282 ); +6283 } +6284 +6285 let pns = space.for_path(path_id); +6286 let ranges = pns.pending_acks.ranges(); +6287 debug_assert!(!ranges.is_empty(), "can not send empty ACK range"); +6288 let ecn = if receiving_ecn { +6289 Some(&pns.ecn_counters) +6290 } else { +6291 None +6292 }; +6293 +6294 let delay_micros = pns.pending_acks.ack_delay(now).as_micros() as u64; +6295 // TODO: This should come from `TransportConfig` if that gets configurable. +6296 let ack_delay_exp = TransportParameters::default().ack_delay_exponent; +6297 let delay = delay_micros >> ack_delay_exp.into_inner(); +6298 +6299 if is_multipath_negotiated && space_id == SpaceId::Data { +6300 if !ranges.is_empty() { +6301 let frame = frame::PathAck::encoder(path_id, delay, ranges, ecn); +6302 builder.write_frame(frame, stats); +6303 } +6304 } else { +6305 builder.write_frame(frame::Ack::encoder(delay, ranges, ecn), stats); +6306 } +6307 } +6308 +6309 fn close_common(&mut self) { +6310 trace!("connection closed"); +6311 self.timers.reset(); +6312 } +6313 +6314 fn set_close_timer(&mut self, now: Instant) { +6315 // QUIC-MULTIPATH § 2.6 Connection Closure: draining for 3*PTO using the max PTO of +6316 // all paths. +6317 let pto_max = self.max_pto_for_space(self.highest_space); +6318 self.timers.set( +6319 Timer::Conn(ConnTimer::Close), +6320 now + 3 * pto_max, +6321 self.qlog.with_time(now), +6322 ); +6323 } +6324 +6325 /// Handle transport parameters received from the peer +6326 /// +6327 /// *remote_cid* and *local_cid* are the source and destination CIDs respectively of the +6328 /// *packet into which the transport parameters arrived. +6329 fn handle_peer_params( +6330 &mut self, +6331 params: TransportParameters, +6332 local_cid: ConnectionId, +6333 remote_cid: ConnectionId, +6334 now: Instant, +6335 ) -> Result<(), TransportError> { +6336 if Some(self.original_remote_cid) != params.initial_src_cid +6337 || (self.side.is_client() +6338 && (Some(self.initial_dst_cid) != params.original_dst_cid +6339 || self.retry_src_cid != params.retry_src_cid)) +6340 { +6341 return Err(TransportError::TRANSPORT_PARAMETER_ERROR( +6342 "CID authentication failure", +6343 )); +6344 } +6345 if params.initial_max_path_id.is_some() && (local_cid.is_empty() || remote_cid.is_empty()) { +6346 return Err(TransportError::PROTOCOL_VIOLATION( +6347 "multipath must not use zero-length CIDs", +6348 )); +6349 } 6350 -6351 Ok(()) -6352 } +6351 self.set_peer_params(params); +6352 self.qlog.emit_peer_transport_params_received(self, now); 6353 -6354 fn set_peer_params(&mut self, params: TransportParameters) { -6355 self.streams.set_params(&params); -6356 self.idle_timeout = -6357 negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout)); -6358 trace!("negotiated max idle timeout {:?}", self.idle_timeout); -6359 -6360 if let Some(ref info) = params.preferred_address { -6361 // During the handshake PathId::ZERO exists. -6362 self.remote_cids.get_mut(&PathId::ZERO).expect("not yet abandoned").insert(frame::NewConnectionId { -6363 path_id: None, -6364 sequence: 1, -6365 id: info.connection_id, -6366 reset_token: info.stateless_reset_token, -6367 retire_prior_to: 0, -6368 }) -6369 .expect( -6370 "preferred address CID is the first received, and hence is guaranteed to be legal", -6371 ); -6372 let remote = self.path_data(PathId::ZERO).network_path.remote; -6373 self.set_reset_token(PathId::ZERO, remote, info.stateless_reset_token); -6374 } -6375 self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(&params); -6376 -6377 let mut multipath_enabled = None; -6378 if let (Some(local_max_path_id), Some(remote_max_path_id)) = ( -6379 self.config.get_initial_max_path_id(), -6380 params.initial_max_path_id, -6381 ) { -6382 // multipath is enabled, register the local and remote maximums -6383 self.local_max_path_id = local_max_path_id; -6384 self.remote_max_path_id = remote_max_path_id; -6385 let initial_max_path_id = local_max_path_id.min(remote_max_path_id); -6386 debug!(%initial_max_path_id, "multipath negotiated"); -6387 multipath_enabled = Some(initial_max_path_id); -6388 } -6389 -6390 if let Some((max_locally_allowed_remote_addresses, max_remotely_allowed_remote_addresses)) = -6391 self.config -6392 .max_remote_nat_traversal_addresses -6393 .zip(params.max_remote_nat_traversal_addresses) -6394 { -6395 if let Some(max_initial_paths) = -6396 multipath_enabled.map(|path_id| path_id.saturating_add(1u8)) -6397 { -6398 let max_local_addresses = max_remotely_allowed_remote_addresses.get(); -6399 let max_remote_addresses = max_locally_allowed_remote_addresses.get(); -6400 self.n0_nat_traversal = n0_nat_traversal::State::new( -6401 max_remote_addresses, -6402 max_local_addresses, -6403 self.side(), -6404 ); -6405 debug!( -6406 %max_remote_addresses, %max_local_addresses, -6407 "n0's nat traversal negotiated" -6408 ); -6409 -6410 match self.side() { -6411 Side::Client => { -6412 if max_initial_paths.as_u32() < max_remote_addresses as u32 + 1 { -6413 // in this case the client might try to open `max_remote_addresses` new -6414 // paths, but the current multipath configuration will not allow it -6415 debug!(%max_initial_paths, %max_remote_addresses, "local client configuration might cause nat traversal issues") -6416 } else if max_local_addresses as u64 -6417 > params.active_connection_id_limit.into_inner() -6418 { -6419 // the server allows us to send at most `params.active_connection_id_limit` -6420 // but they might need at least `max_local_addresses` to effectively send -6421 // `PATH_CHALLENGE` frames to each advertised local address -6422 debug!(%max_local_addresses, remote_cid_limit=%params.active_connection_id_limit.into_inner(), "remote server configuration might cause nat traversal issues") -6423 } -6424 } -6425 Side::Server => { -6426 if (max_initial_paths.as_u32() as u64) < crate::LOCAL_CID_COUNT { -6427 debug!(%max_initial_paths, local_cid_limit=%crate::LOCAL_CID_COUNT, "local server configuration might cause nat traversal issues") -6428 } -6429 } -6430 } -6431 } else { -6432 debug!("n0 nat traversal enabled for both endpoints, but multipath is missing") -6433 } -6434 } -6435 -6436 self.peer_params = params; -6437 let peer_max_udp_payload_size = -6438 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); -6439 self.path_data_mut(PathId::ZERO) -6440 .mtud -6441 .on_peer_max_udp_payload_size_received(peer_max_udp_payload_size); -6442 } -6443 -6444 /// Decrypts a packet, returning the packet number on success -6445 fn decrypt_packet( -6446 &mut self, -6447 now: Instant, -6448 path_id: PathId, -6449 packet: &mut Packet, -6450 ) -> Result<Option<u64>, Option<TransportError>> { -6451 let result = self -6452 .crypto_state -6453 .decrypt_packet_body(packet, path_id, &self.spaces)?; -6454 -6455 let Some(result) = result else { -6456 return Ok(None); -6457 }; -6458 -6459 if result.outgoing_key_update_acked -6460 && let Some(prev) = self.crypto_state.prev_crypto.as_mut() -6461 { -6462 prev.end_packet = Some((result.number, now)); -6463 self.set_key_discard_timer(now, packet.header.space()); -6464 } -6465 -6466 if result.incoming_key_update { -6467 trace!("key update authenticated"); -6468 self.crypto_state -6469 .update_keys(Some((result.number, now)), true); -6470 self.set_key_discard_timer(now, packet.header.space()); -6471 } -6472 -6473 Ok(Some(result.number)) -6474 } +6354 Ok(()) +6355 } +6356 +6357 fn set_peer_params(&mut self, params: TransportParameters) { +6358 self.streams.set_params(&params); +6359 self.idle_timeout = +6360 negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout)); +6361 trace!("negotiated max idle timeout {:?}", self.idle_timeout); +6362 +6363 if let Some(ref info) = params.preferred_address { +6364 // During the handshake PathId::ZERO exists. +6365 self.remote_cids.get_mut(&PathId::ZERO).expect("not yet abandoned").insert(frame::NewConnectionId { +6366 path_id: None, +6367 sequence: 1, +6368 id: info.connection_id, +6369 reset_token: info.stateless_reset_token, +6370 retire_prior_to: 0, +6371 }) +6372 .expect( +6373 "preferred address CID is the first received, and hence is guaranteed to be legal", +6374 ); +6375 let remote = self.path_data(PathId::ZERO).network_path.remote; +6376 self.set_reset_token(PathId::ZERO, remote, info.stateless_reset_token); +6377 } +6378 self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(&params); +6379 +6380 let mut multipath_enabled = None; +6381 if let (Some(local_max_path_id), Some(remote_max_path_id)) = ( +6382 self.config.get_initial_max_path_id(), +6383 params.initial_max_path_id, +6384 ) { +6385 // multipath is enabled, register the local and remote maximums +6386 self.local_max_path_id = local_max_path_id; +6387 self.remote_max_path_id = remote_max_path_id; +6388 let initial_max_path_id = local_max_path_id.min(remote_max_path_id); +6389 debug!(%initial_max_path_id, "multipath negotiated"); +6390 multipath_enabled = Some(initial_max_path_id); +6391 } +6392 +6393 if let Some((max_locally_allowed_remote_addresses, max_remotely_allowed_remote_addresses)) = +6394 self.config +6395 .max_remote_nat_traversal_addresses +6396 .zip(params.max_remote_nat_traversal_addresses) +6397 { +6398 if let Some(max_initial_paths) = +6399 multipath_enabled.map(|path_id| path_id.saturating_add(1u8)) +6400 { +6401 let max_local_addresses = max_remotely_allowed_remote_addresses.get(); +6402 let max_remote_addresses = max_locally_allowed_remote_addresses.get(); +6403 self.n0_nat_traversal = n0_nat_traversal::State::new( +6404 max_remote_addresses, +6405 max_local_addresses, +6406 self.side(), +6407 ); +6408 debug!( +6409 %max_remote_addresses, %max_local_addresses, +6410 "n0's nat traversal negotiated" +6411 ); +6412 +6413 match self.side() { +6414 Side::Client => { +6415 if max_initial_paths.as_u32() < max_remote_addresses as u32 + 1 { +6416 // in this case the client might try to open `max_remote_addresses` new +6417 // paths, but the current multipath configuration will not allow it +6418 debug!(%max_initial_paths, %max_remote_addresses, "local client configuration might cause nat traversal issues") +6419 } else if max_local_addresses as u64 +6420 > params.active_connection_id_limit.into_inner() +6421 { +6422 // the server allows us to send at most `params.active_connection_id_limit` +6423 // but they might need at least `max_local_addresses` to effectively send +6424 // `PATH_CHALLENGE` frames to each advertised local address +6425 debug!(%max_local_addresses, remote_cid_limit=%params.active_connection_id_limit.into_inner(), "remote server configuration might cause nat traversal issues") +6426 } +6427 } +6428 Side::Server => { +6429 if (max_initial_paths.as_u32() as u64) < crate::LOCAL_CID_COUNT { +6430 debug!(%max_initial_paths, local_cid_limit=%crate::LOCAL_CID_COUNT, "local server configuration might cause nat traversal issues") +6431 } +6432 } +6433 } +6434 } else { +6435 debug!("n0 nat traversal enabled for both endpoints, but multipath is missing") +6436 } +6437 } +6438 +6439 self.peer_params = params; +6440 let peer_max_udp_payload_size = +6441 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); +6442 self.path_data_mut(PathId::ZERO) +6443 .mtud +6444 .on_peer_max_udp_payload_size_received(peer_max_udp_payload_size); +6445 } +6446 +6447 /// Decrypts a packet, returning the packet number on success +6448 fn decrypt_packet( +6449 &mut self, +6450 now: Instant, +6451 path_id: PathId, +6452 packet: &mut Packet, +6453 ) -> Result<Option<u64>, Option<TransportError>> { +6454 let result = self +6455 .crypto_state +6456 .decrypt_packet_body(packet, path_id, &self.spaces)?; +6457 +6458 let Some(result) = result else { +6459 return Ok(None); +6460 }; +6461 +6462 if result.outgoing_key_update_acked +6463 && let Some(prev) = self.crypto_state.prev_crypto.as_mut() +6464 { +6465 prev.end_packet = Some((result.number, now)); +6466 self.set_key_discard_timer(now, packet.header.space()); +6467 } +6468 +6469 if result.incoming_key_update { +6470 trace!("key update authenticated"); +6471 self.crypto_state +6472 .update_keys(Some((result.number, now)), true); +6473 self.set_key_discard_timer(now, packet.header.space()); +6474 } 6475 -6476 fn peer_supports_ack_frequency(&self) -> bool { -6477 self.peer_params.min_ack_delay.is_some() -6478 } -6479 -6480 /// Send an IMMEDIATE_ACK frame to the remote endpoint -6481 /// -6482 /// According to the spec, this will result in an error if the remote endpoint does not support -6483 /// the Acknowledgement Frequency extension -6484 pub(crate) fn immediate_ack(&mut self, path_id: PathId) { -6485 debug_assert_eq!( -6486 self.highest_space, -6487 SpaceKind::Data, -6488 "immediate ack must be written in the data space" -6489 ); -6490 self.spaces[SpaceId::Data] -6491 .for_path(path_id) -6492 .immediate_ack_pending = true; -6493 } -6494 -6495 /// Decodes a packet, returning its decrypted payload, so it can be inspected in tests -6496 #[cfg(test)] -6497 pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> { -6498 let ConnectionEventInner::Datagram(DatagramConnectionEvent { -6499 path_id, -6500 first_decode, -6501 remaining, -6502 .. -6503 }) = &event.0 -6504 else { -6505 return None; -6506 }; -6507 -6508 if remaining.is_some() { -6509 panic!("Packets should never be coalesced in tests"); -6510 } -6511 -6512 let decrypted_header = self -6513 .crypto_state -6514 .unprotect_header(first_decode.clone(), self.peer_params.stateless_reset_token)?; -6515 -6516 let mut packet = decrypted_header.packet?; -6517 self.crypto_state -6518 .decrypt_packet_body(&mut packet, *path_id, &self.spaces) -6519 .ok()?; -6520 -6521 Some(packet.payload.to_vec()) -6522 } +6476 Ok(Some(result.number)) +6477 } +6478 +6479 fn peer_supports_ack_frequency(&self) -> bool { +6480 self.peer_params.min_ack_delay.is_some() +6481 } +6482 +6483 /// Send an IMMEDIATE_ACK frame to the remote endpoint +6484 /// +6485 /// According to the spec, this will result in an error if the remote endpoint does not support +6486 /// the Acknowledgement Frequency extension +6487 pub(crate) fn immediate_ack(&mut self, path_id: PathId) { +6488 debug_assert_eq!( +6489 self.highest_space, +6490 SpaceKind::Data, +6491 "immediate ack must be written in the data space" +6492 ); +6493 self.spaces[SpaceId::Data] +6494 .for_path(path_id) +6495 .immediate_ack_pending = true; +6496 } +6497 +6498 /// Decodes a packet, returning its decrypted payload, so it can be inspected in tests +6499 #[cfg(test)] +6500 pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> { +6501 let ConnectionEventInner::Datagram(DatagramConnectionEvent { +6502 path_id, +6503 first_decode, +6504 remaining, +6505 .. +6506 }) = &event.0 +6507 else { +6508 return None; +6509 }; +6510 +6511 if remaining.is_some() { +6512 panic!("Packets should never be coalesced in tests"); +6513 } +6514 +6515 let decrypted_header = self +6516 .crypto_state +6517 .unprotect_header(first_decode.clone(), self.peer_params.stateless_reset_token)?; +6518 +6519 let mut packet = decrypted_header.packet?; +6520 self.crypto_state +6521 .decrypt_packet_body(&mut packet, *path_id, &self.spaces) +6522 .ok()?; 6523 -6524 /// The number of bytes of packets containing retransmittable frames that have not been -6525 /// acknowledged or declared lost. -6526 #[cfg(test)] -6527 pub(crate) fn bytes_in_flight(&self) -> u64 { -6528 // TODO(@divma): consider including for multipath? -6529 self.path_data(PathId::ZERO).in_flight.bytes -6530 } -6531 -6532 /// Number of bytes worth of non-ack-only packets that may be sent -6533 #[cfg(test)] -6534 pub(crate) fn congestion_window(&self) -> u64 { -6535 let path = self.path_data(PathId::ZERO); -6536 path.congestion -6537 .window() -6538 .saturating_sub(path.in_flight.bytes) -6539 } -6540 -6541 /// Whether no timers but keepalive, idle, rtt, pushnewcid, and key discard are running -6542 #[cfg(test)] -6543 pub(crate) fn is_idle(&self) -> bool { -6544 let current_timers = self.timers.values(); -6545 current_timers -6546 .into_iter() -6547 .filter(|(timer, _)| { -6548 !matches!( -6549 timer, -6550 Timer::Conn(ConnTimer::KeepAlive) -6551 | Timer::PerPath(_, PathTimer::PathKeepAlive) -6552 | Timer::PerPath(_, PathTimer::PathIdle) -6553 | Timer::Conn(ConnTimer::PushNewCid) -6554 | Timer::Conn(ConnTimer::KeyDiscard) -6555 ) -6556 }) -6557 .min_by_key(|(_, time)| *time) -6558 .is_none_or(|(timer, _)| timer == Timer::Conn(ConnTimer::Idle)) -6559 } -6560 -6561 /// Whether explicit congestion notification is in use on outgoing packets. -6562 #[cfg(test)] -6563 pub(crate) fn using_ecn(&self) -> bool { -6564 self.path_data(PathId::ZERO).sending_ecn -6565 } -6566 -6567 /// The number of received bytes in the current path -6568 #[cfg(test)] -6569 pub(crate) fn total_recvd(&self) -> u64 { -6570 self.path_data(PathId::ZERO).total_recvd -6571 } -6572 -6573 #[cfg(test)] -6574 pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) { -6575 self.local_cid_state -6576 .get(&PathId::ZERO) -6577 .unwrap() -6578 .active_seq() -6579 } -6580 -6581 #[cfg(test)] -6582 #[track_caller] -6583 pub(crate) fn active_local_path_cid_seq(&self, path_id: u32) -> (u64, u64) { -6584 self.local_cid_state -6585 .get(&PathId(path_id)) -6586 .unwrap() -6587 .active_seq() -6588 } -6589 -6590 /// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame -6591 /// with updated `retire_prior_to` field set to `v` -6592 #[cfg(test)] -6593 pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) { -6594 let n = self -6595 .local_cid_state -6596 .get_mut(&PathId::ZERO) -6597 .unwrap() -6598 .assign_retire_seq(v); -6599 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events -6600 self.endpoint_events -6601 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); -6602 } -6603 -6604 /// Check the current active remote CID sequence for `PathId::ZERO` -6605 #[cfg(test)] -6606 pub(crate) fn active_remote_cid_seq(&self) -> u64 { -6607 self.remote_cids.get(&PathId::ZERO).unwrap().active_seq() -6608 } -6609 -6610 /// Returns the detected maximum udp payload size for the current path -6611 #[cfg(test)] -6612 pub(crate) fn path_mtu(&self, path_id: PathId) -> u16 { -6613 self.path_data(path_id).current_mtu() -6614 } -6615 -6616 /// Triggers path validation on all paths -6617 #[cfg(test)] -6618 pub(crate) fn trigger_path_validation(&mut self) { -6619 for path in self.paths.values_mut() { -6620 path.data.pending_on_path_challenge = true; -6621 } -6622 } -6623 -6624 /// Simulates a protocol violation error for test purposes. -6625 #[cfg(test)] -6626 pub fn simulate_protocol_violation(&mut self, now: Instant) { -6627 if !self.state.is_closed() { -6628 self.state -6629 .move_to_closed(TransportError::PROTOCOL_VIOLATION("simulated violation")); -6630 self.close_common(); -6631 if !self.state.is_drained() { -6632 self.set_close_timer(now); -6633 } -6634 self.connection_close_pending = true; -6635 } -6636 } -6637 -6638 /// Whether we have on-path 1-RTT data to send. -6639 /// -6640 /// This checks for frames that can only be sent in the data space (1-RTT): -6641 /// - Pending PATH_CHALLENGE frames on the active and previous path if just migrated. -6642 /// - Pending PATH_RESPONSE frames. -6643 /// - Pending data to send in STREAM frames. -6644 /// - Pending DATAGRAM frames to send. -6645 /// -6646 /// See also [`PacketSpace::can_send`] which keeps track of all other frame types that -6647 /// may need to be sent. -6648 fn can_send_1rtt(&self, path_id: PathId, max_size: usize) -> SendableFrames { -6649 let space_specific = self.paths.get(&path_id).is_some_and(|path| { -6650 path.data.pending_on_path_challenge || !path.data.path_responses.is_empty() -6651 }); -6652 -6653 // Stream control frames are checked in PacketSpace::can_send, only check data here. -6654 let other = self.streams.can_send_stream_data() -6655 || self -6656 .datagrams -6657 .outgoing -6658 .front() -6659 .is_some_and(|x| x.size(true) <= max_size); -6660 -6661 // All `false` fields are set in PacketSpace::can_send. -6662 SendableFrames { -6663 acks: false, -6664 close: false, -6665 space_specific, -6666 other, -6667 } -6668 } -6669 -6670 /// Terminate the connection instantly, without sending a close packet -6671 fn kill(&mut self, reason: ConnectionError) { -6672 self.close_common(); -6673 self.state.move_to_drained(Some(reason)); -6674 // move_to_drained checks that we were never in drained before, so we -6675 // never sent a `Drained` event before (it's illegal to send more events after drained). -6676 self.endpoint_events.push_back(EndpointEventInner::Drained); -6677 } -6678 -6679 /// Storage size required for the largest packet that can be transmitted on all currently -6680 /// available paths -6681 /// -6682 /// Buffers passed to [`Connection::poll_transmit`] should be at least this large. -6683 /// -6684 /// When multipath is enabled, this value is the minimum MTU across all available paths. -6685 pub fn current_mtu(&self) -> u16 { -6686 self.paths -6687 .iter() -6688 .filter(|&(path_id, _path_state)| !self.abandoned_paths.contains(path_id)) -6689 .map(|(_path_id, path_state)| path_state.data.current_mtu()) -6690 .min() -6691 .unwrap_or(INITIAL_MTU) -6692 } -6693 -6694 /// Size of non-frame data for a 1-RTT packet -6695 /// -6696 /// Quantifies space consumed by the QUIC header and AEAD tag. All other bytes in a packet are -6697 /// frames. Changes if the length of the remote connection ID changes, which is expected to be -6698 /// rare. If `pn` is specified, may additionally change unpredictably due to variations in -6699 /// latency and packet loss. -6700 fn predict_1rtt_overhead(&mut self, pn: u64, path: PathId) -> usize { -6701 let pn_len = PacketNumber::new( -6702 pn, -6703 self.spaces[SpaceId::Data] -6704 .for_path(path) -6705 .largest_acked_packet -6706 .unwrap_or(0), -6707 ) -6708 .len(); -6709 -6710 // 1 byte for flags -6711 1 + self -6712 .remote_cids -6713 .get(&path) -6714 .map(|cids| cids.active().len()) -6715 .unwrap_or(20) // Max CID len in QUIC v1 -6716 + pn_len -6717 + self.tag_len_1rtt() -6718 } -6719 -6720 fn predict_1rtt_overhead_no_pn(&self) -> usize { -6721 let pn_len = 4; +6524 Some(packet.payload.to_vec()) +6525 } +6526 +6527 /// The number of bytes of packets containing retransmittable frames that have not been +6528 /// acknowledged or declared lost. +6529 #[cfg(test)] +6530 pub(crate) fn bytes_in_flight(&self) -> u64 { +6531 // TODO(@divma): consider including for multipath? +6532 self.path_data(PathId::ZERO).in_flight.bytes +6533 } +6534 +6535 /// Number of bytes worth of non-ack-only packets that may be sent +6536 #[cfg(test)] +6537 pub(crate) fn congestion_window(&self) -> u64 { +6538 let path = self.path_data(PathId::ZERO); +6539 path.congestion +6540 .window() +6541 .saturating_sub(path.in_flight.bytes) +6542 } +6543 +6544 /// Whether no timers but keepalive, idle, rtt, pushnewcid, and key discard are running +6545 #[cfg(test)] +6546 pub(crate) fn is_idle(&self) -> bool { +6547 let current_timers = self.timers.values(); +6548 current_timers +6549 .into_iter() +6550 .filter(|(timer, _)| { +6551 !matches!( +6552 timer, +6553 Timer::Conn(ConnTimer::KeepAlive) +6554 | Timer::PerPath(_, PathTimer::PathKeepAlive) +6555 | Timer::PerPath(_, PathTimer::PathIdle) +6556 | Timer::Conn(ConnTimer::PushNewCid) +6557 | Timer::Conn(ConnTimer::KeyDiscard) +6558 ) +6559 }) +6560 .min_by_key(|(_, time)| *time) +6561 .is_none_or(|(timer, _)| timer == Timer::Conn(ConnTimer::Idle)) +6562 } +6563 +6564 /// Whether explicit congestion notification is in use on outgoing packets. +6565 #[cfg(test)] +6566 pub(crate) fn using_ecn(&self) -> bool { +6567 self.path_data(PathId::ZERO).sending_ecn +6568 } +6569 +6570 /// The number of received bytes in the current path +6571 #[cfg(test)] +6572 pub(crate) fn total_recvd(&self) -> u64 { +6573 self.path_data(PathId::ZERO).total_recvd +6574 } +6575 +6576 #[cfg(test)] +6577 pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) { +6578 self.local_cid_state +6579 .get(&PathId::ZERO) +6580 .unwrap() +6581 .active_seq() +6582 } +6583 +6584 #[cfg(test)] +6585 #[track_caller] +6586 pub(crate) fn active_local_path_cid_seq(&self, path_id: u32) -> (u64, u64) { +6587 self.local_cid_state +6588 .get(&PathId(path_id)) +6589 .unwrap() +6590 .active_seq() +6591 } +6592 +6593 /// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame +6594 /// with updated `retire_prior_to` field set to `v` +6595 #[cfg(test)] +6596 pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) { +6597 let n = self +6598 .local_cid_state +6599 .get_mut(&PathId::ZERO) +6600 .unwrap() +6601 .assign_retire_seq(v); +6602 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events +6603 self.endpoint_events +6604 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); +6605 } +6606 +6607 /// Check the current active remote CID sequence for `PathId::ZERO` +6608 #[cfg(test)] +6609 pub(crate) fn active_remote_cid_seq(&self) -> u64 { +6610 self.remote_cids.get(&PathId::ZERO).unwrap().active_seq() +6611 } +6612 +6613 /// Returns the detected maximum udp payload size for the current path +6614 #[cfg(test)] +6615 pub(crate) fn path_mtu(&self, path_id: PathId) -> u16 { +6616 self.path_data(path_id).current_mtu() +6617 } +6618 +6619 /// Triggers path validation on all paths +6620 #[cfg(test)] +6621 pub(crate) fn trigger_path_validation(&mut self) { +6622 for path in self.paths.values_mut() { +6623 path.data.pending_on_path_challenge = true; +6624 } +6625 } +6626 +6627 /// Simulates a protocol violation error for test purposes. +6628 #[cfg(test)] +6629 pub fn simulate_protocol_violation(&mut self, now: Instant) { +6630 if !self.state.is_closed() { +6631 self.state +6632 .move_to_closed(TransportError::PROTOCOL_VIOLATION("simulated violation")); +6633 self.close_common(); +6634 if !self.state.is_drained() { +6635 self.set_close_timer(now); +6636 } +6637 self.connection_close_pending = true; +6638 } +6639 } +6640 +6641 /// Whether we have on-path 1-RTT data to send. +6642 /// +6643 /// This checks for frames that can only be sent in the data space (1-RTT): +6644 /// - Pending PATH_CHALLENGE frames on the active and previous path if just migrated. +6645 /// - Pending PATH_RESPONSE frames. +6646 /// - Pending data to send in STREAM frames. +6647 /// - Pending DATAGRAM frames to send. +6648 /// +6649 /// See also [`PacketSpace::can_send`] which keeps track of all other frame types that +6650 /// may need to be sent. +6651 fn can_send_1rtt(&self, path_id: PathId, max_size: usize) -> SendableFrames { +6652 let space_specific = self.paths.get(&path_id).is_some_and(|path| { +6653 path.data.pending_on_path_challenge || !path.data.path_responses.is_empty() +6654 }); +6655 +6656 // Stream control frames are checked in PacketSpace::can_send, only check data here. +6657 let other = self.streams.can_send_stream_data() +6658 || self +6659 .datagrams +6660 .outgoing +6661 .front() +6662 .is_some_and(|x| x.size(true) <= max_size); +6663 +6664 // All `false` fields are set in PacketSpace::can_send. +6665 SendableFrames { +6666 acks: false, +6667 close: false, +6668 space_specific, +6669 other, +6670 } +6671 } +6672 +6673 /// Terminate the connection instantly, without sending a close packet +6674 fn kill(&mut self, reason: ConnectionError) { +6675 self.close_common(); +6676 self.state.move_to_drained(Some(reason)); +6677 // move_to_drained checks that we were never in drained before, so we +6678 // never sent a `Drained` event before (it's illegal to send more events after drained). +6679 self.endpoint_events.push_back(EndpointEventInner::Drained); +6680 } +6681 +6682 /// Storage size required for the largest packet that can be transmitted on all currently +6683 /// available paths +6684 /// +6685 /// Buffers passed to [`Connection::poll_transmit`] should be at least this large. +6686 /// +6687 /// When multipath is enabled, this value is the minimum MTU across all available paths. +6688 pub fn current_mtu(&self) -> u16 { +6689 self.paths +6690 .iter() +6691 .filter(|&(path_id, _path_state)| !self.abandoned_paths.contains(path_id)) +6692 .map(|(_path_id, path_state)| path_state.data.current_mtu()) +6693 .min() +6694 .unwrap_or(INITIAL_MTU) +6695 } +6696 +6697 /// Size of non-frame data for a 1-RTT packet +6698 /// +6699 /// Quantifies space consumed by the QUIC header and AEAD tag. All other bytes in a packet are +6700 /// frames. Changes if the length of the remote connection ID changes, which is expected to be +6701 /// rare. If `pn` is specified, may additionally change unpredictably due to variations in +6702 /// latency and packet loss. +6703 fn predict_1rtt_overhead(&mut self, pn: u64, path: PathId) -> usize { +6704 let pn_len = PacketNumber::new( +6705 pn, +6706 self.spaces[SpaceId::Data] +6707 .for_path(path) +6708 .largest_acked_packet +6709 .unwrap_or(0), +6710 ) +6711 .len(); +6712 +6713 // 1 byte for flags +6714 1 + self +6715 .remote_cids +6716 .get(&path) +6717 .map(|cids| cids.active().len()) +6718 .unwrap_or(20) // Max CID len in QUIC v1 +6719 + pn_len +6720 + self.tag_len_1rtt() +6721 } 6722 -6723 let cid_len = self -6724 .remote_cids -6725 .values() -6726 .map(|cids| cids.active().len()) -6727 .max() -6728 .unwrap_or(20); // Max CID len in QUIC v1 -6729 -6730 // 1 byte for flags -6731 1 + cid_len + pn_len + self.tag_len_1rtt() -6732 } -6733 -6734 fn tag_len_1rtt(&self) -> usize { -6735 // encryption_keys for Data space returns 1-RTT keys if available, otherwise 0-RTT keys -6736 let packet_crypto = self -6737 .crypto_state -6738 .encryption_keys(SpaceKind::Data, self.side.side()) -6739 .map(|(_header, packet, _level)| packet); -6740 // If neither Data nor 0-RTT keys are available, make a reasonable tag length guess. As of -6741 // this writing, all QUIC cipher suites use 16-byte tags. We could return `None` instead, -6742 // but that would needlessly prevent sending datagrams during 0-RTT. -6743 packet_crypto.map_or(16, |x| x.tag_len()) -6744 } -6745 -6746 /// Mark the path as validated, and enqueue NEW_TOKEN frames to be sent as appropriate -6747 fn on_path_validated(&mut self, path_id: PathId) { -6748 self.path_data_mut(path_id).validated = true; -6749 let ConnectionSide::Server { server_config } = &self.side else { -6750 return; -6751 }; -6752 let network_path = self.path_data(path_id).network_path; -6753 let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens; -6754 new_tokens.clear(); -6755 for _ in 0..server_config.validation_token.sent { -6756 new_tokens.push(network_path); -6757 } -6758 } -6759 -6760 /// Handle new path status information: PATH_STATUS_AVAILABLE, PATH_STATUS_BACKUP -6761 fn on_path_status(&mut self, path_id: PathId, status: PathStatus, status_seq_no: VarInt) { -6762 if let Some(path) = self.paths.get_mut(&path_id) { -6763 path.data.status.remote_update(status, status_seq_no); -6764 } else { -6765 debug!("PATH_STATUS_AVAILABLE received unknown path {:?}", path_id); -6766 } -6767 self.events.push_back( -6768 PathEvent::RemoteStatus { -6769 id: path_id, -6770 status, -6771 } -6772 .into(), -6773 ); -6774 } -6775 -6776 /// Returns the maximum [`PathId`] to be used for sending in this connection. -6777 /// -6778 /// This is calculated as minimum between the local and remote's maximums when multipath is -6779 /// enabled, or `None` when disabled. +6723 fn predict_1rtt_overhead_no_pn(&self) -> usize { +6724 let pn_len = 4; +6725 +6726 let cid_len = self +6727 .remote_cids +6728 .values() +6729 .map(|cids| cids.active().len()) +6730 .max() +6731 .unwrap_or(20); // Max CID len in QUIC v1 +6732 +6733 // 1 byte for flags +6734 1 + cid_len + pn_len + self.tag_len_1rtt() +6735 } +6736 +6737 fn tag_len_1rtt(&self) -> usize { +6738 // encryption_keys for Data space returns 1-RTT keys if available, otherwise 0-RTT keys +6739 let packet_crypto = self +6740 .crypto_state +6741 .encryption_keys(SpaceKind::Data, self.side.side()) +6742 .map(|(_header, packet, _level)| packet); +6743 // If neither Data nor 0-RTT keys are available, make a reasonable tag length guess. As of +6744 // this writing, all QUIC cipher suites use 16-byte tags. We could return `None` instead, +6745 // but that would needlessly prevent sending datagrams during 0-RTT. +6746 packet_crypto.map_or(16, |x| x.tag_len()) +6747 } +6748 +6749 /// Mark the path as validated, and enqueue NEW_TOKEN frames to be sent as appropriate +6750 fn on_path_validated(&mut self, path_id: PathId) { +6751 self.path_data_mut(path_id).validated = true; +6752 let ConnectionSide::Server { server_config } = &self.side else { +6753 return; +6754 }; +6755 let network_path = self.path_data(path_id).network_path; +6756 let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens; +6757 new_tokens.clear(); +6758 for _ in 0..server_config.validation_token.sent { +6759 new_tokens.push(network_path); +6760 } +6761 } +6762 +6763 /// Handle new path status information: PATH_STATUS_AVAILABLE, PATH_STATUS_BACKUP +6764 fn on_path_status(&mut self, path_id: PathId, status: PathStatus, status_seq_no: VarInt) { +6765 if let Some(path) = self.paths.get_mut(&path_id) { +6766 path.data.status.remote_update(status, status_seq_no); +6767 } else { +6768 debug!("PATH_STATUS_AVAILABLE received unknown path {:?}", path_id); +6769 } +6770 self.events.push_back( +6771 PathEvent::RemoteStatus { +6772 id: path_id, +6773 status, +6774 } +6775 .into(), +6776 ); +6777 } +6778 +6779 /// Returns the maximum [`PathId`] to be used for sending in this connection. 6780 /// -6781 /// For data that's received, we should use [`Self::local_max_path_id`] instead. -6782 /// The reasoning is that the remote might already have updated to its own newer -6783 /// [`Self::max_path_id`] after sending out a `MAX_PATH_ID` frame, but it got re-ordered. -6784 fn max_path_id(&self) -> Option<PathId> { -6785 if self.is_multipath_negotiated() { -6786 Some(self.remote_max_path_id.min(self.local_max_path_id)) -6787 } else { -6788 None -6789 } -6790 } -6791 -6792 /// Returns whether this connection has a socket that supports IPv6. -6793 /// -6794 /// TODO(matheus23): This is related to noq endpoint state's `ipv6` bool. We should move that info -6795 /// here instead of trying to hack around not knowing it exactly. -6796 fn is_ipv6(&self) -> bool { -6797 self.paths -6798 .values() -6799 .any(|p| p.data.network_path.remote.is_ipv6()) -6800 } -6801 -6802 /// Add addresses the local endpoint considers are reachable for nat traversal. -6803 pub fn add_nat_traversal_address( -6804 &mut self, -6805 address: SocketAddr, -6806 ) -> Result<(), n0_nat_traversal::Error> { -6807 if let Some(added) = self.n0_nat_traversal.add_local_address(address)? { -6808 self.spaces[SpaceId::Data].pending.add_address.insert(added); -6809 }; -6810 Ok(()) -6811 } -6812 -6813 /// Removes an address the endpoing no longer considers reachable for nat traversal -6814 /// -6815 /// Addresses not present in the set will be silently ignored. -6816 pub fn remove_nat_traversal_address( -6817 &mut self, -6818 address: SocketAddr, -6819 ) -> Result<(), n0_nat_traversal::Error> { -6820 if let Some(removed) = self.n0_nat_traversal.remove_local_address(address)? { -6821 self.spaces[SpaceId::Data] -6822 .pending -6823 .remove_address -6824 .insert(removed); -6825 } -6826 Ok(()) -6827 } -6828 -6829 /// Get the current local nat traversal addresses -6830 pub fn get_local_nat_traversal_addresses( -6831 &self, -6832 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6833 self.n0_nat_traversal.get_local_nat_traversal_addresses() -6834 } -6835 -6836 /// Get the currently advertised nat traversal addresses by the server -6837 pub fn get_remote_nat_traversal_addresses( -6838 &self, -6839 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6840 Ok(self -6841 .n0_nat_traversal -6842 .client_side()? -6843 .get_remote_nat_traversal_addresses()) -6844 } -6845 -6846 /// Attempts to open a path for nat traversal. -6847 /// -6848 /// On success returns the [`PathId`] and remote address of the path. -6849 fn open_nat_traversal_path( -6850 &mut self, -6851 now: Instant, -6852 ip_port: (IpAddr, u16), -6853 ) -> Result<Option<(PathId, SocketAddr)>, PathError> { -6854 let remote = ip_port.into(); -6855 // TODO(matheus23): Probe the correct 4-tuple, instead of only a remote address? -6856 // By specifying None for `local_ip`, we do two things: 1. open_path_ensure won't -6857 // generate two paths to the same remote and 2. we let the OS choose which -6858 // interface to use for sending on that path. -6859 let network_path = FourTuple { -6860 remote, -6861 local_ip: None, -6862 }; -6863 match self.open_path_ensure(network_path, PathStatus::Backup, now) { -6864 Ok((path_id, path_was_known)) => { -6865 if path_was_known { -6866 trace!(%path_id, %remote, "nat traversal: path existed for remote, revalidating"); -6867 if let Some(path) = self.paths.get_mut(&path_id) { -6868 path.data.pending_on_path_challenge = true; -6869 } -6870 } -6871 Ok(Some((path_id, remote))) -6872 } -6873 Err(e) => { -6874 debug!(%remote, %e, "nat traversal: failed to probe remote"); -6875 Err(e) -6876 } -6877 } -6878 } -6879 -6880 /// Initiates a new nat traversal round -6881 /// -6882 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` -6883 /// frames, and initiating probing of the known remote addresses. When a new round is -6884 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. -6885 /// -6886 /// Returns the server addresses that are now being probed. -6887 /// If addresses fail due to spurious errors, these might succeed later and not be returned in -6888 /// this set. -6889 pub fn initiate_nat_traversal_round( -6890 &mut self, -6891 now: Instant, -6892 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6893 if self.state.is_closed() { -6894 return Err(n0_nat_traversal::Error::Closed); -6895 } -6896 -6897 let ipv6 = self.is_ipv6(); -6898 let client_state = self.n0_nat_traversal.client_side_mut()?; -6899 let n0_nat_traversal::NatTraversalRound { -6900 new_round, -6901 reach_out_at, -6902 addresses_to_probe, -6903 prev_round_path_ids, -6904 } = client_state.initiate_nat_traversal_round(ipv6)?; -6905 -6906 trace!(%new_round, reach_out=reach_out_at.len(), to_probe=addresses_to_probe.len(), -6907 "initiating nat traversal round"); +6781 /// This is calculated as minimum between the local and remote's maximums when multipath is +6782 /// enabled, or `None` when disabled. +6783 /// +6784 /// For data that's received, we should use [`Self::local_max_path_id`] instead. +6785 /// The reasoning is that the remote might already have updated to its own newer +6786 /// [`Self::max_path_id`] after sending out a `MAX_PATH_ID` frame, but it got re-ordered. +6787 fn max_path_id(&self) -> Option<PathId> { +6788 if self.is_multipath_negotiated() { +6789 Some(self.remote_max_path_id.min(self.local_max_path_id)) +6790 } else { +6791 None +6792 } +6793 } +6794 +6795 /// Returns whether this connection has a socket that supports IPv6. +6796 /// +6797 /// TODO(matheus23): This is related to noq endpoint state's `ipv6` bool. We should move that info +6798 /// here instead of trying to hack around not knowing it exactly. +6799 fn is_ipv6(&self) -> bool { +6800 self.paths +6801 .values() +6802 .any(|p| p.data.network_path.remote.is_ipv6()) +6803 } +6804 +6805 /// Add addresses the local endpoint considers are reachable for nat traversal. +6806 pub fn add_nat_traversal_address( +6807 &mut self, +6808 address: SocketAddr, +6809 ) -> Result<(), n0_nat_traversal::Error> { +6810 if let Some(added) = self.n0_nat_traversal.add_local_address(address)? { +6811 self.spaces[SpaceId::Data].pending.add_address.insert(added); +6812 }; +6813 Ok(()) +6814 } +6815 +6816 /// Removes an address the endpoing no longer considers reachable for nat traversal +6817 /// +6818 /// Addresses not present in the set will be silently ignored. +6819 pub fn remove_nat_traversal_address( +6820 &mut self, +6821 address: SocketAddr, +6822 ) -> Result<(), n0_nat_traversal::Error> { +6823 if let Some(removed) = self.n0_nat_traversal.remove_local_address(address)? { +6824 self.spaces[SpaceId::Data] +6825 .pending +6826 .remove_address +6827 .insert(removed); +6828 } +6829 Ok(()) +6830 } +6831 +6832 /// Get the current local nat traversal addresses +6833 pub fn get_local_nat_traversal_addresses( +6834 &self, +6835 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6836 self.n0_nat_traversal.get_local_nat_traversal_addresses() +6837 } +6838 +6839 /// Get the currently advertised nat traversal addresses by the server +6840 pub fn get_remote_nat_traversal_addresses( +6841 &self, +6842 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6843 Ok(self +6844 .n0_nat_traversal +6845 .client_side()? +6846 .get_remote_nat_traversal_addresses()) +6847 } +6848 +6849 /// Attempts to open a path for nat traversal. +6850 /// +6851 /// On success returns the [`PathId`] and remote address of the path. +6852 fn open_nat_traversal_path( +6853 &mut self, +6854 now: Instant, +6855 ip_port: (IpAddr, u16), +6856 ) -> Result<Option<(PathId, SocketAddr)>, PathError> { +6857 let remote = ip_port.into(); +6858 // TODO(matheus23): Probe the correct 4-tuple, instead of only a remote address? +6859 // By specifying None for `local_ip`, we do two things: 1. open_path_ensure won't +6860 // generate two paths to the same remote and 2. we let the OS choose which +6861 // interface to use for sending on that path. +6862 let network_path = FourTuple { +6863 remote, +6864 local_ip: None, +6865 }; +6866 match self.open_path_ensure(network_path, PathStatus::Backup, now) { +6867 Ok((path_id, path_was_known)) => { +6868 if path_was_known { +6869 trace!(%path_id, %remote, "nat traversal: path existed for remote, revalidating"); +6870 if let Some(path) = self.paths.get_mut(&path_id) { +6871 path.data.pending_on_path_challenge = true; +6872 } +6873 } +6874 Ok(Some((path_id, remote))) +6875 } +6876 Err(e) => { +6877 debug!(%remote, %e, "nat traversal: failed to probe remote"); +6878 Err(e) +6879 } +6880 } +6881 } +6882 +6883 /// Initiates a new nat traversal round +6884 /// +6885 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` +6886 /// frames, and initiating probing of the known remote addresses. When a new round is +6887 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. +6888 /// +6889 /// Returns the server addresses that are now being probed. +6890 /// If addresses fail due to spurious errors, these might succeed later and not be returned in +6891 /// this set. +6892 pub fn initiate_nat_traversal_round( +6893 &mut self, +6894 now: Instant, +6895 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6896 if self.state.is_closed() { +6897 return Err(n0_nat_traversal::Error::Closed); +6898 } +6899 +6900 let ipv6 = self.is_ipv6(); +6901 let client_state = self.n0_nat_traversal.client_side_mut()?; +6902 let n0_nat_traversal::NatTraversalRound { +6903 new_round, +6904 reach_out_at, +6905 addresses_to_probe, +6906 prev_round_path_ids, +6907 } = client_state.initiate_nat_traversal_round(ipv6)?; 6908 -6909 self.spaces[SpaceId::Data].pending.reach_out = Some((new_round, reach_out_at)); -6910 -6911 for path_id in prev_round_path_ids { -6912 let Some(path) = self.path(path_id) else { -6913 continue; -6914 }; -6915 let ip = path.network_path.remote.ip(); -6916 let port = path.network_path.remote.port(); -6917 -6918 // We only close paths that aren't validated (thus are working) that we opened -6919 // in a previous round. -6920 // And we only close paths that we don't want to probe anyways. -6921 if !addresses_to_probe -6922 .iter() -6923 .any(|(_, probe)| *probe == (ip, port)) -6924 && !path.validated -6925 && !self.abandoned_paths.contains(&path_id) -6926 { -6927 trace!(%path_id, "closing path from previous round"); -6928 let _ = -6929 self.close_path_inner(now, path_id, PathAbandonReason::NatTraversalRoundEnded); -6930 } -6931 } -6932 -6933 let mut err = None; -6934 -6935 let mut path_ids = Vec::with_capacity(addresses_to_probe.len()); -6936 let mut probed_addresses = Vec::with_capacity(addresses_to_probe.len()); +6909 trace!(%new_round, reach_out=reach_out_at.len(), to_probe=addresses_to_probe.len(), +6910 "initiating nat traversal round"); +6911 +6912 self.spaces[SpaceId::Data].pending.reach_out = Some((new_round, reach_out_at)); +6913 +6914 for path_id in prev_round_path_ids { +6915 let Some(path) = self.path(path_id) else { +6916 continue; +6917 }; +6918 let ip = path.network_path.remote.ip(); +6919 let port = path.network_path.remote.port(); +6920 +6921 // We only close paths that aren't validated (thus are working) that we opened +6922 // in a previous round. +6923 // And we only close paths that we don't want to probe anyways. +6924 if !addresses_to_probe +6925 .iter() +6926 .any(|(_, probe)| *probe == (ip, port)) +6927 && !path.validated +6928 && !self.abandoned_paths.contains(&path_id) +6929 { +6930 trace!(%path_id, "closing path from previous round"); +6931 let _ = +6932 self.close_path_inner(now, path_id, PathAbandonReason::NatTraversalRoundEnded); +6933 } +6934 } +6935 +6936 let mut err = None; 6937 -6938 for (id, address) in addresses_to_probe { -6939 match self.open_nat_traversal_path(now, address) { -6940 Ok(None) => {} -6941 Ok(Some((path_id, remote))) => { -6942 path_ids.push(path_id); -6943 probed_addresses.push(remote); -6944 } -6945 Err(e) => { -6946 self.n0_nat_traversal -6947 .client_side_mut() -6948 .expect("validated") -6949 .report_in_continuation(id, e); -6950 err.get_or_insert(e); -6951 } -6952 } -6953 } -6954 -6955 if let Some(err) = err { -6956 // We failed to probe any addresses, bail out -6957 if probed_addresses.is_empty() { -6958 return Err(n0_nat_traversal::Error::Multipath(err)); -6959 } -6960 } -6961 -6962 self.n0_nat_traversal -6963 .client_side_mut() -6964 .expect("connection side validated") -6965 .set_round_path_ids(path_ids); -6966 -6967 Ok(probed_addresses) -6968 } +6938 let mut path_ids = Vec::with_capacity(addresses_to_probe.len()); +6939 let mut probed_addresses = Vec::with_capacity(addresses_to_probe.len()); +6940 +6941 for (id, address) in addresses_to_probe { +6942 match self.open_nat_traversal_path(now, address) { +6943 Ok(None) => {} +6944 Ok(Some((path_id, remote))) => { +6945 path_ids.push(path_id); +6946 probed_addresses.push(remote); +6947 } +6948 Err(e) => { +6949 self.n0_nat_traversal +6950 .client_side_mut() +6951 .expect("validated") +6952 .report_in_continuation(id, e); +6953 err.get_or_insert(e); +6954 } +6955 } +6956 } +6957 +6958 if let Some(err) = err { +6959 // We failed to probe any addresses, bail out +6960 if probed_addresses.is_empty() { +6961 return Err(n0_nat_traversal::Error::Multipath(err)); +6962 } +6963 } +6964 +6965 self.n0_nat_traversal +6966 .client_side_mut() +6967 .expect("connection side validated") +6968 .set_round_path_ids(path_ids); 6969 -6970 /// Attempts to continue a nat traversal round by trying to open paths for pending client probes. -6971 /// -6972 /// If there was nothing to do, it returns `None`. Otherwise it returns whether the path was -6973 /// successfully open. -6974 fn continue_nat_traversal_round(&mut self, now: Instant) -> Option<bool> { -6975 let ipv6 = self.is_ipv6(); -6976 let client_state = self.n0_nat_traversal.client_side_mut().ok()?; -6977 let (id, address) = client_state.continue_nat_traversal_round(ipv6)?; -6978 let open_result = self.open_nat_traversal_path(now, address); -6979 let client_state = self.n0_nat_traversal.client_side_mut().expect("validated"); -6980 match open_result { -6981 Ok(None) => Some(true), -6982 Ok(Some((path_id, _remote))) => { -6983 client_state.add_round_path_id(path_id); -6984 Some(true) -6985 } -6986 Err(e) => { -6987 client_state.report_in_continuation(id, e); -6988 Some(false) -6989 } -6990 } -6991 } -6992} -6993 -6994impl fmt::Debug for Connection { -6995 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -6996 f.debug_struct("Connection") -6997 .field("handshake_cid", &self.handshake_cid) -6998 .finish() -6999 } -7000} -7001 -7002/// Hints when the caller identifies a network change. -7003pub trait NetworkChangeHint: std::fmt::Debug + 'static { -7004 /// Inform the connection if a path may recover after a network change. -7005 /// -7006 /// After network changes, paths may not be recoverable. In this case, waiting for the path to -7007 /// become idle may take longer than what is desirable. If [`Self::is_path_recoverable`] -7008 /// returns `false`, a multipath-enabled, client-side connection will establish a new path to -7009 /// the same remote, closing the current one, instead of migrating the path. -7010 /// -7011 /// Paths that are deemed recoverable will simply be sent a PING for a liveness check. -7012 fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool; -7013} -7014 -7015/// Return value for [`Connection::poll_transmit_on_path`]. -7016#[derive(Debug)] -7017enum PollPathStatus { -7018 /// Nothing to send on the path, nothing was written into the [`TransmitBuf`]. -7019 NothingToSend { -7020 /// If true there was data to send but congestion control did not allow so. -7021 congestion_blocked: bool, -7022 }, -7023 /// The transmit is ready to be sent. -7024 Send(Transmit), -7025} -7026 -7027/// Return value for [`Connection::poll_transmit_path_space`]. -7028#[derive(Debug)] -7029enum PollPathSpaceStatus { -7030 /// Nothing to send in the space, nothing was written into the [`TransmitBuf`]. -7031 NothingToSend { -7032 /// If true there was data to send but congestion control did not allow so. -7033 congestion_blocked: bool, -7034 }, -7035 /// One or more packets have been written into the [`TransmitBuf`]. -7036 WrotePacket { -7037 /// The highest packet number. -7038 last_packet_number: u64, -7039 /// Whether to pad an already started datagram in the next packet. -7040 /// -7041 /// When packets in Initial, 0-RTT or Handshake packet do not fill the entire -7042 /// datagram they may decide to coalesce with the next packet from a higher -7043 /// encryption level on the same path. But the earlier packet may require specific -7044 /// size requirements for the datagram they are sent in. -7045 /// -7046 /// If a space did not complete the datagram, they use this to request the correct -7047 /// padding in the final packet of the datagram so that the final datagram will have -7048 /// the correct size. -7049 /// -7050 /// If a space did fill an entire datagram, it leaves this to the default of -7051 /// [`PadDatagram::No`]. -7052 pad_datagram: PadDatagram, -7053 }, -7054 /// Send the contents of the transmit immediately. -7055 /// -7056 /// Packets were written and the GSO batch must end now, regardless from whether higher -7057 /// spaces still have frames to write. This is used when the last datagram written would -7058 /// require too much padding to continue a GSO batch, which would waste space on the -7059 /// wire. -7060 Send { -7061 /// The highest packet number written into the transmit. -7062 last_packet_number: u64, -7063 }, -7064} -7065 -7066/// Information used to decide what frames to schedule into which packets. -7067/// -7068/// Primarily used by [`Connection::poll_transmit_on_path`] and the functions that help -7069/// building packets for it: [`Connection::poll_transmit_path_space`] and -7070/// [`Connection::populate_packet`]. -7071#[derive(Debug, Copy, Clone)] -7072struct PathSchedulingInfo { -7073 /// Whether the path is abandoned. -7074 /// -7075 /// Note that a path that is abandoned but still has CIDs can still send a packet. After -7076 /// sending that packet the CIDs issued by the remote have to be considered retired as -7077 /// well. -7078 is_abandoned: bool, -7079 /// Whether the path may send [`SpaceKind::Data`] frames. -7080 /// -7081 /// Some paths should only send frames from [`SendableFrames::space_specific`]. All other -7082 /// frames are essentially frames that can be sent on any [`SpaceKind::Data`] space. For -7083 /// those we want to respect packet scheduling rules however. -7084 /// -7085 /// Roughly speaking data frames are only sent on spaces that have CIDs, are not -7086 /// abandoned and have no *better* spaces. However see to comments where this is -7087 /// populated for the exact packet scheduling implementation. -7088 /// -7089 /// This essentially marks this paths as the best validated space ID. Except during -7090 /// the handshake in which case it does not need to be validated. Several paths could be -7091 /// equally good and all have this set to `true`, in that case packet scheduling can -7092 /// choose which path to use. Currently it chooses the lowest path that is not -7093 /// congestion blocked. -7094 /// -7095 /// Note that once in the closed or draining states this will never be true. -7096 may_send_data: bool, -7097 /// Whether the path may send a CONNECTION_CLOSE frame. -7098 /// -7099 /// This essentially marks this path as the best validated space ID with a fallback -7100 /// to unvalidated spaces if there are no validated spaces. Like for -7101 /// [`Self::may_send_data`] other paths could be equally good. -7102 may_send_close: bool, -7103 may_self_abandon: bool, -7104} -7105 -7106#[derive(Debug, Copy, Clone, PartialEq, Eq)] -7107enum PathBlocked { -7108 No, -7109 AntiAmplification, -7110 Congestion, -7111 Pacing, -7112} -7113 -7114/// Fields of `Connection` specific to it being client-side or server-side -7115enum ConnectionSide { -7116 Client { -7117 /// Sent in every outgoing Initial packet. Always empty after Initial keys are discarded -7118 token: Bytes, -7119 token_store: Arc<dyn TokenStore>, -7120 server_name: String, -7121 }, -7122 Server { -7123 server_config: Arc<ServerConfig>, +6970 Ok(probed_addresses) +6971 } +6972 +6973 /// Attempts to continue a nat traversal round by trying to open paths for pending client probes. +6974 /// +6975 /// If there was nothing to do, it returns `None`. Otherwise it returns whether the path was +6976 /// successfully open. +6977 fn continue_nat_traversal_round(&mut self, now: Instant) -> Option<bool> { +6978 let ipv6 = self.is_ipv6(); +6979 let client_state = self.n0_nat_traversal.client_side_mut().ok()?; +6980 let (id, address) = client_state.continue_nat_traversal_round(ipv6)?; +6981 let open_result = self.open_nat_traversal_path(now, address); +6982 let client_state = self.n0_nat_traversal.client_side_mut().expect("validated"); +6983 match open_result { +6984 Ok(None) => Some(true), +6985 Ok(Some((path_id, _remote))) => { +6986 client_state.add_round_path_id(path_id); +6987 Some(true) +6988 } +6989 Err(e) => { +6990 client_state.report_in_continuation(id, e); +6991 Some(false) +6992 } +6993 } +6994 } +6995} +6996 +6997impl fmt::Debug for Connection { +6998 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +6999 f.debug_struct("Connection") +7000 .field("handshake_cid", &self.handshake_cid) +7001 .finish() +7002 } +7003} +7004 +7005/// Hints when the caller identifies a network change. +7006pub trait NetworkChangeHint: std::fmt::Debug + 'static { +7007 /// Inform the connection if a path may recover after a network change. +7008 /// +7009 /// After network changes, paths may not be recoverable. In this case, waiting for the path to +7010 /// become idle may take longer than what is desirable. If [`Self::is_path_recoverable`] +7011 /// returns `false`, a multipath-enabled, client-side connection will establish a new path to +7012 /// the same remote, closing the current one, instead of migrating the path. +7013 /// +7014 /// Paths that are deemed recoverable will simply be sent a PING for a liveness check. +7015 fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool; +7016} +7017 +7018/// Return value for [`Connection::poll_transmit_on_path`]. +7019#[derive(Debug)] +7020enum PollPathStatus { +7021 /// Nothing to send on the path, nothing was written into the [`TransmitBuf`]. +7022 NothingToSend { +7023 /// If true there was data to send but congestion control did not allow so. +7024 congestion_blocked: bool, +7025 }, +7026 /// The transmit is ready to be sent. +7027 Send(Transmit), +7028} +7029 +7030/// Return value for [`Connection::poll_transmit_path_space`]. +7031#[derive(Debug)] +7032enum PollPathSpaceStatus { +7033 /// Nothing to send in the space, nothing was written into the [`TransmitBuf`]. +7034 NothingToSend { +7035 /// If true there was data to send but congestion control did not allow so. +7036 congestion_blocked: bool, +7037 }, +7038 /// One or more packets have been written into the [`TransmitBuf`]. +7039 WrotePacket { +7040 /// The highest packet number. +7041 last_packet_number: u64, +7042 /// Whether to pad an already started datagram in the next packet. +7043 /// +7044 /// When packets in Initial, 0-RTT or Handshake packet do not fill the entire +7045 /// datagram they may decide to coalesce with the next packet from a higher +7046 /// encryption level on the same path. But the earlier packet may require specific +7047 /// size requirements for the datagram they are sent in. +7048 /// +7049 /// If a space did not complete the datagram, they use this to request the correct +7050 /// padding in the final packet of the datagram so that the final datagram will have +7051 /// the correct size. +7052 /// +7053 /// If a space did fill an entire datagram, it leaves this to the default of +7054 /// [`PadDatagram::No`]. +7055 pad_datagram: PadDatagram, +7056 }, +7057 /// Send the contents of the transmit immediately. +7058 /// +7059 /// Packets were written and the GSO batch must end now, regardless from whether higher +7060 /// spaces still have frames to write. This is used when the last datagram written would +7061 /// require too much padding to continue a GSO batch, which would waste space on the +7062 /// wire. +7063 Send { +7064 /// The highest packet number written into the transmit. +7065 last_packet_number: u64, +7066 }, +7067} +7068 +7069/// Information used to decide what frames to schedule into which packets. +7070/// +7071/// Primarily used by [`Connection::poll_transmit_on_path`] and the functions that help +7072/// building packets for it: [`Connection::poll_transmit_path_space`] and +7073/// [`Connection::populate_packet`]. +7074#[derive(Debug, Copy, Clone)] +7075struct PathSchedulingInfo { +7076 /// Whether the path is abandoned. +7077 /// +7078 /// Note that a path that is abandoned but still has CIDs can still send a packet. After +7079 /// sending that packet the CIDs issued by the remote have to be considered retired as +7080 /// well. +7081 is_abandoned: bool, +7082 /// Whether the path may send [`SpaceKind::Data`] frames. +7083 /// +7084 /// Some paths should only send frames from [`SendableFrames::space_specific`]. All other +7085 /// frames are essentially frames that can be sent on any [`SpaceKind::Data`] space. For +7086 /// those we want to respect packet scheduling rules however. +7087 /// +7088 /// Roughly speaking data frames are only sent on spaces that have CIDs, are not +7089 /// abandoned and have no *better* spaces. However see to comments where this is +7090 /// populated for the exact packet scheduling implementation. +7091 /// +7092 /// This essentially marks this paths as the best validated space ID. Except during +7093 /// the handshake in which case it does not need to be validated. Several paths could be +7094 /// equally good and all have this set to `true`, in that case packet scheduling can +7095 /// choose which path to use. Currently it chooses the lowest path that is not +7096 /// congestion blocked. +7097 /// +7098 /// Note that once in the closed or draining states this will never be true. +7099 may_send_data: bool, +7100 /// Whether the path may send a CONNECTION_CLOSE frame. +7101 /// +7102 /// This essentially marks this path as the best validated space ID with a fallback +7103 /// to unvalidated spaces if there are no validated spaces. Like for +7104 /// [`Self::may_send_data`] other paths could be equally good. +7105 may_send_close: bool, +7106 may_self_abandon: bool, +7107} +7108 +7109#[derive(Debug, Copy, Clone, PartialEq, Eq)] +7110enum PathBlocked { +7111 No, +7112 AntiAmplification, +7113 Congestion, +7114 Pacing, +7115} +7116 +7117/// Fields of `Connection` specific to it being client-side or server-side +7118enum ConnectionSide { +7119 Client { +7120 /// Sent in every outgoing Initial packet. Always empty after Initial keys are discarded +7121 token: Bytes, +7122 token_store: Arc<dyn TokenStore>, +7123 server_name: String, 7124 }, -7125} -7126 -7127impl ConnectionSide { -7128 fn remote_may_migrate(&self, state: &State) -> bool { -7129 match self { -7130 Self::Server { server_config } => server_config.migration, -7131 Self::Client { .. } => { -7132 if let Some(hs) = state.as_handshake() { -7133 hs.allow_server_migration -7134 } else { -7135 false -7136 } -7137 } -7138 } -7139 } -7140 -7141 fn is_client(&self) -> bool { -7142 self.side().is_client() -7143 } -7144 -7145 fn is_server(&self) -> bool { -7146 self.side().is_server() -7147 } -7148 -7149 fn side(&self) -> Side { -7150 match *self { -7151 Self::Client { .. } => Side::Client, -7152 Self::Server { .. } => Side::Server, -7153 } -7154 } -7155} -7156 -7157impl From<SideArgs> for ConnectionSide { -7158 fn from(side: SideArgs) -> Self { -7159 match side { -7160 SideArgs::Client { -7161 token_store, -7162 server_name, -7163 } => Self::Client { -7164 token: token_store.take(&server_name).unwrap_or_default(), -7165 token_store, -7166 server_name, -7167 }, -7168 SideArgs::Server { -7169 server_config, -7170 pref_addr_cid: _, -7171 path_validated: _, -7172 } => Self::Server { server_config }, -7173 } -7174 } -7175} -7176 -7177/// Parameters to `Connection::new` specific to it being client-side or server-side -7178pub(crate) enum SideArgs { -7179 Client { -7180 token_store: Arc<dyn TokenStore>, -7181 server_name: String, -7182 }, -7183 Server { -7184 server_config: Arc<ServerConfig>, -7185 pref_addr_cid: Option<ConnectionId>, -7186 path_validated: bool, -7187 }, -7188} -7189 -7190impl SideArgs { -7191 pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> { -7192 match *self { -7193 Self::Client { .. } => None, -7194 Self::Server { pref_addr_cid, .. } => pref_addr_cid, -7195 } -7196 } -7197 -7198 pub(crate) fn path_validated(&self) -> bool { -7199 match *self { -7200 Self::Client { .. } => true, -7201 Self::Server { path_validated, .. } => path_validated, -7202 } -7203 } -7204 -7205 pub(crate) fn side(&self) -> Side { -7206 match *self { -7207 Self::Client { .. } => Side::Client, -7208 Self::Server { .. } => Side::Server, -7209 } -7210 } -7211} -7212 -7213/// Reasons why a connection might be lost -7214#[derive(Debug, Error, Clone, PartialEq, Eq)] -7215pub enum ConnectionError { -7216 /// The peer doesn't implement any supported version -7217 #[error("peer doesn't implement any supported version")] -7218 VersionMismatch, -7219 /// The peer violated the QUIC specification as understood by this implementation -7220 #[error(transparent)] -7221 TransportError(#[from] TransportError), -7222 /// The peer's QUIC stack aborted the connection automatically -7223 #[error("aborted by peer: {0}")] -7224 ConnectionClosed(frame::ConnectionClose), -7225 /// The peer closed the connection -7226 #[error("closed by peer: {0}")] -7227 ApplicationClosed(frame::ApplicationClose), -7228 /// The peer is unable to continue processing this connection, usually due to having restarted -7229 #[error("reset by peer")] -7230 Reset, -7231 /// Communication with the peer has lapsed for longer than the negotiated idle timeout -7232 /// -7233 /// If neither side is sending keep-alives, a connection will time out after a long enough idle -7234 /// period even if the peer is still reachable. See also [`TransportConfig::max_idle_timeout()`] -7235 /// and [`TransportConfig::keep_alive_interval()`]. -7236 #[error("timed out")] -7237 TimedOut, -7238 /// The local application closed the connection -7239 #[error("closed")] -7240 LocallyClosed, -7241 /// The connection could not be created because not enough of the CID space is available -7242 /// -7243 /// Try using longer connection IDs. -7244 #[error("CIDs exhausted")] -7245 CidsExhausted, -7246} -7247 -7248impl From<Close> for ConnectionError { -7249 fn from(x: Close) -> Self { -7250 match x { -7251 Close::Connection(reason) => Self::ConnectionClosed(reason), -7252 Close::Application(reason) => Self::ApplicationClosed(reason), -7253 } -7254 } -7255} -7256 -7257// For compatibility with API consumers -7258impl From<ConnectionError> for io::Error { -7259 fn from(x: ConnectionError) -> Self { -7260 use ConnectionError::*; -7261 let kind = match x { -7262 TimedOut => io::ErrorKind::TimedOut, -7263 Reset => io::ErrorKind::ConnectionReset, -7264 ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted, -7265 TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => { -7266 io::ErrorKind::Other -7267 } -7268 }; -7269 Self::new(kind, x) -7270 } -7271} -7272 -7273/// Errors that might trigger a path being closed -7274// TODO(@divma): maybe needs to be reworked based on what we want to do with the public API -7275#[derive(Debug, Error, PartialEq, Eq, Clone, Copy)] -7276pub enum PathError { -7277 /// The extension was not negotiated with the peer -7278 #[error("multipath extension not negotiated")] -7279 MultipathNotNegotiated, -7280 /// Paths can only be opened client-side -7281 #[error("the server side may not open a path")] -7282 ServerSideNotAllowed, -7283 /// Current limits do not allow us to open more paths -7284 #[error("maximum number of concurrent paths reached")] -7285 MaxPathIdReached, -7286 /// No remote CIDs available to open a new path -7287 #[error("remoted CIDs exhausted")] -7288 RemoteCidsExhausted, -7289 /// Path could not be validated and will be abandoned -7290 #[error("path validation failed")] -7291 ValidationFailed, -7292 /// The remote address for the path is not supported by the endpoint -7293 #[error("invalid remote address")] -7294 InvalidRemoteAddress(SocketAddr), -7295} -7296 -7297/// Errors triggered when abandoning a path -7298#[derive(Debug, Error, Clone, Eq, PartialEq)] -7299pub enum ClosePathError { -7300 /// Multipath is not negotiated -7301 #[error("Multipath extension not negotiated")] -7302 MultipathNotNegotiated, -7303 /// The path is already closed or was never opened -7304 #[error("closed path")] -7305 ClosedPath, -7306 /// Cannot close the last remaining open path via the local API. -7307 /// -7308 /// Use [`Connection::close`] to end the connection instead. -7309 #[error("last open path")] -7310 LastOpenPath, -7311} -7312 -7313/// Error when the multipath extension was not negotiated, but attempted to be used. -7314#[derive(Debug, Error, Clone, Copy)] -7315#[error("Multipath extension not negotiated")] -7316pub struct MultipathNotNegotiated { -7317 _private: (), -7318} -7319 -7320/// Events of interest to the application -7321#[derive(Debug)] -7322pub enum Event { -7323 /// The connection's handshake data is ready -7324 HandshakeDataReady, -7325 /// The connection was successfully established -7326 Connected, -7327 /// The TLS handshake was confirmed -7328 HandshakeConfirmed, -7329 /// The connection was lost -7330 /// -7331 /// Emitted if the peer closes the connection or an error is encountered. -7332 ConnectionLost { -7333 /// Reason that the connection was closed -7334 reason: ConnectionError, -7335 }, -7336 /// Stream events -7337 Stream(StreamEvent), -7338 /// One or more application datagrams have been received -7339 DatagramReceived, -7340 /// One or more application datagrams have been sent after blocking -7341 DatagramsUnblocked, -7342 /// (Multi)Path events -7343 Path(PathEvent), -7344 /// n0's nat traversal events -7345 NatTraversal(n0_nat_traversal::Event), -7346} -7347 -7348impl From<PathEvent> for Event { -7349 fn from(source: PathEvent) -> Self { -7350 Self::Path(source) -7351 } -7352} -7353 -7354fn get_max_ack_delay(params: &TransportParameters) -> Duration { -7355 Duration::from_micros(params.max_ack_delay.0 * 1000) -7356} -7357 -7358/// Prevents overflow and improves behavior in extreme circumstances. -7359const MAX_BACKOFF_EXPONENT: u32 = 16; +7125 Server { +7126 server_config: Arc<ServerConfig>, +7127 }, +7128} +7129 +7130impl ConnectionSide { +7131 fn remote_may_migrate(&self, state: &State) -> bool { +7132 match self { +7133 Self::Server { server_config } => server_config.migration, +7134 Self::Client { .. } => { +7135 if let Some(hs) = state.as_handshake() { +7136 hs.allow_server_migration +7137 } else { +7138 false +7139 } +7140 } +7141 } +7142 } +7143 +7144 fn is_client(&self) -> bool { +7145 self.side().is_client() +7146 } +7147 +7148 fn is_server(&self) -> bool { +7149 self.side().is_server() +7150 } +7151 +7152 fn side(&self) -> Side { +7153 match *self { +7154 Self::Client { .. } => Side::Client, +7155 Self::Server { .. } => Side::Server, +7156 } +7157 } +7158} +7159 +7160impl From<SideArgs> for ConnectionSide { +7161 fn from(side: SideArgs) -> Self { +7162 match side { +7163 SideArgs::Client { +7164 token_store, +7165 server_name, +7166 } => Self::Client { +7167 token: token_store.take(&server_name).unwrap_or_default(), +7168 token_store, +7169 server_name, +7170 }, +7171 SideArgs::Server { +7172 server_config, +7173 pref_addr_cid: _, +7174 path_validated: _, +7175 } => Self::Server { server_config }, +7176 } +7177 } +7178} +7179 +7180/// Parameters to `Connection::new` specific to it being client-side or server-side +7181pub(crate) enum SideArgs { +7182 Client { +7183 token_store: Arc<dyn TokenStore>, +7184 server_name: String, +7185 }, +7186 Server { +7187 server_config: Arc<ServerConfig>, +7188 pref_addr_cid: Option<ConnectionId>, +7189 path_validated: bool, +7190 }, +7191} +7192 +7193impl SideArgs { +7194 pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> { +7195 match *self { +7196 Self::Client { .. } => None, +7197 Self::Server { pref_addr_cid, .. } => pref_addr_cid, +7198 } +7199 } +7200 +7201 pub(crate) fn path_validated(&self) -> bool { +7202 match *self { +7203 Self::Client { .. } => true, +7204 Self::Server { path_validated, .. } => path_validated, +7205 } +7206 } +7207 +7208 pub(crate) fn side(&self) -> Side { +7209 match *self { +7210 Self::Client { .. } => Side::Client, +7211 Self::Server { .. } => Side::Server, +7212 } +7213 } +7214} +7215 +7216/// Reasons why a connection might be lost +7217#[derive(Debug, Error, Clone, PartialEq, Eq)] +7218pub enum ConnectionError { +7219 /// The peer doesn't implement any supported version +7220 #[error("peer doesn't implement any supported version")] +7221 VersionMismatch, +7222 /// The peer violated the QUIC specification as understood by this implementation +7223 #[error(transparent)] +7224 TransportError(#[from] TransportError), +7225 /// The peer's QUIC stack aborted the connection automatically +7226 #[error("aborted by peer: {0}")] +7227 ConnectionClosed(frame::ConnectionClose), +7228 /// The peer closed the connection +7229 #[error("closed by peer: {0}")] +7230 ApplicationClosed(frame::ApplicationClose), +7231 /// The peer is unable to continue processing this connection, usually due to having restarted +7232 #[error("reset by peer")] +7233 Reset, +7234 /// Communication with the peer has lapsed for longer than the negotiated idle timeout +7235 /// +7236 /// If neither side is sending keep-alives, a connection will time out after a long enough idle +7237 /// period even if the peer is still reachable. See also [`TransportConfig::max_idle_timeout()`] +7238 /// and [`TransportConfig::keep_alive_interval()`]. +7239 #[error("timed out")] +7240 TimedOut, +7241 /// The local application closed the connection +7242 #[error("closed")] +7243 LocallyClosed, +7244 /// The connection could not be created because not enough of the CID space is available +7245 /// +7246 /// Try using longer connection IDs. +7247 #[error("CIDs exhausted")] +7248 CidsExhausted, +7249} +7250 +7251impl From<Close> for ConnectionError { +7252 fn from(x: Close) -> Self { +7253 match x { +7254 Close::Connection(reason) => Self::ConnectionClosed(reason), +7255 Close::Application(reason) => Self::ApplicationClosed(reason), +7256 } +7257 } +7258} +7259 +7260// For compatibility with API consumers +7261impl From<ConnectionError> for io::Error { +7262 fn from(x: ConnectionError) -> Self { +7263 use ConnectionError::*; +7264 let kind = match x { +7265 TimedOut => io::ErrorKind::TimedOut, +7266 Reset => io::ErrorKind::ConnectionReset, +7267 ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted, +7268 TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => { +7269 io::ErrorKind::Other +7270 } +7271 }; +7272 Self::new(kind, x) +7273 } +7274} +7275 +7276/// Errors that might trigger a path being closed +7277// TODO(@divma): maybe needs to be reworked based on what we want to do with the public API +7278#[derive(Debug, Error, PartialEq, Eq, Clone, Copy)] +7279pub enum PathError { +7280 /// The extension was not negotiated with the peer +7281 #[error("multipath extension not negotiated")] +7282 MultipathNotNegotiated, +7283 /// Paths can only be opened client-side +7284 #[error("the server side may not open a path")] +7285 ServerSideNotAllowed, +7286 /// Current limits do not allow us to open more paths +7287 #[error("maximum number of concurrent paths reached")] +7288 MaxPathIdReached, +7289 /// No remote CIDs available to open a new path +7290 #[error("remoted CIDs exhausted")] +7291 RemoteCidsExhausted, +7292 /// Path could not be validated and will be abandoned +7293 #[error("path validation failed")] +7294 ValidationFailed, +7295 /// The remote address for the path is not supported by the endpoint +7296 #[error("invalid remote address")] +7297 InvalidRemoteAddress(SocketAddr), +7298} +7299 +7300/// Errors triggered when abandoning a path +7301#[derive(Debug, Error, Clone, Eq, PartialEq)] +7302pub enum ClosePathError { +7303 /// Multipath is not negotiated +7304 #[error("Multipath extension not negotiated")] +7305 MultipathNotNegotiated, +7306 /// The path is already closed or was never opened +7307 #[error("closed path")] +7308 ClosedPath, +7309 /// Cannot close the last remaining open path via the local API. +7310 /// +7311 /// Use [`Connection::close`] to end the connection instead. +7312 #[error("last open path")] +7313 LastOpenPath, +7314} +7315 +7316/// Error when the multipath extension was not negotiated, but attempted to be used. +7317#[derive(Debug, Error, Clone, Copy)] +7318#[error("Multipath extension not negotiated")] +7319pub struct MultipathNotNegotiated { +7320 _private: (), +7321} +7322 +7323/// Events of interest to the application +7324#[derive(Debug)] +7325pub enum Event { +7326 /// The connection's handshake data is ready +7327 HandshakeDataReady, +7328 /// The connection was successfully established +7329 Connected, +7330 /// The TLS handshake was confirmed +7331 HandshakeConfirmed, +7332 /// The connection was lost +7333 /// +7334 /// Emitted if the peer closes the connection or an error is encountered. +7335 ConnectionLost { +7336 /// Reason that the connection was closed +7337 reason: ConnectionError, +7338 }, +7339 /// Stream events +7340 Stream(StreamEvent), +7341 /// One or more application datagrams have been received +7342 DatagramReceived, +7343 /// One or more application datagrams have been sent after blocking +7344 DatagramsUnblocked, +7345 /// (Multi)Path events +7346 Path(PathEvent), +7347 /// n0's nat traversal events +7348 NatTraversal(n0_nat_traversal::Event), +7349} +7350 +7351impl From<PathEvent> for Event { +7352 fn from(source: PathEvent) -> Self { +7353 Self::Path(source) +7354 } +7355} +7356 +7357fn get_max_ack_delay(params: &TransportParameters) -> Duration { +7358 Duration::from_micros(params.max_ack_delay.0 * 1000) +7359} 7360 -7361/// The max interval between successive tail-loss probes. -7362/// -7363/// This is the "normal" value we use. -7364const MAX_PTO_INTERVAL: Duration = Duration::from_secs(2); -7365 -7366/// The idle time, below which we use the shorter [`MAX_PTO_FAST_INTERVAL`]. -7367const MIN_IDLE_FOR_FAST_PTO: Duration = Duration::from_secs(25); +7361/// Prevents overflow and improves behavior in extreme circumstances. +7362const MAX_BACKOFF_EXPONENT: u32 = 16; +7363 +7364/// The max interval between successive tail-loss probes. +7365/// +7366/// This is the "normal" value we use. +7367const MAX_PTO_INTERVAL: Duration = Duration::from_secs(2); 7368 -7369/// The max interval between successive tail-loss probes with short idle times. -7370/// -7371/// If the path or connection idle time is less than [`MIN_IDLE_FOR_FAST_PTO`] then we use -7372/// this value to ensure we have plenty of retransmits before we reach the idle time. -7373const MAX_PTO_FAST_INTERVAL: Duration = Duration::from_secs(1); -7374 -7375/// The RTT threshold above which we cap the PTO interval to 1.5 * smoothed_rtt -7376/// -7377/// This is RTT time above which 1.5 * RTT > [`MAX_PTO_INTERVAL`], for these links we want -7378/// to extend the interval between tail-loss probes to not fill the entire pipe with them. -7379const SLOW_RTT_THRESHOLD: Duration = Duration::from_millis(610); -7380 -7381/// Minimal remaining size to allow packet coalescing, excluding cryptographic tag -7382/// -7383/// This must be at least as large as the header for a well-formed empty packet to be coalesced, -7384/// plus some space for frames. We only care about handshake headers because short header packets -7385/// necessarily have smaller headers, and initial packets are only ever the first packet in a -7386/// datagram (because we coalesce in ascending packet space order and the only reason to split a -7387/// packet is when packet space changes). -7388const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32; -7389 -7390/// Largest amount of space that could be occupied by a Handshake or 0-RTT packet's header -7391/// -7392/// Excludes packet-type-specific fields such as packet number or Initial token -7393// https://www.rfc-editor.org/rfc/rfc9000.html#name-0-rtt: flags + version + dcid len + dcid + -7394// scid len + scid + length + pn -7395const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize = -7396 1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4; -7397 -7398#[derive(Default)] -7399struct SentFrames { -7400 retransmits: ThinRetransmits, -7401 /// The packet number of the largest acknowledged packet for each path -7402 largest_acked: FxHashMap<PathId, u64>, -7403 stream_frames: StreamMetaVec, -7404 /// Whether the packet contains non-retransmittable frames (like datagrams) -7405 non_retransmits: bool, -7406 /// If the datagram containing these frames should be padded to the min MTU -7407 requires_padding: bool, -7408} -7409 -7410impl SentFrames { -7411 /// Returns whether the packet contains only ACKs -7412 fn is_ack_only(&self, streams: &StreamsState) -> bool { -7413 !self.largest_acked.is_empty() -7414 && !self.non_retransmits -7415 && self.stream_frames.is_empty() -7416 && self.retransmits.is_empty(streams) -7417 } -7418 -7419 fn retransmits_mut(&mut self) -> &mut Retransmits { -7420 self.retransmits.get_or_create() -7421 } -7422 -7423 fn record_sent_frame(&mut self, frame: frame::EncodableFrame<'_>) { -7424 use frame::EncodableFrame::*; -7425 match frame { -7426 PathAck(path_ack_encoder) => { -7427 if let Some(max) = path_ack_encoder.ranges.max() { -7428 self.largest_acked.insert(path_ack_encoder.path_id, max); -7429 } -7430 } -7431 Ack(ack_encoder) => { -7432 if let Some(max) = ack_encoder.ranges.max() { -7433 self.largest_acked.insert(PathId::ZERO, max); -7434 } -7435 } -7436 Close(_) => { /* non retransmittable, but after this we don't really care */ } -7437 PathResponse(_) => self.non_retransmits = true, -7438 HandshakeDone(_) => self.retransmits_mut().handshake_done = true, -7439 ReachOut(frame::ReachOut { round, ip, port }) => { -7440 let (recorded_round, reach_outs) = self -7441 .retransmits_mut() -7442 .reach_out -7443 .get_or_insert_with(|| (round, FxHashSet::default())); -7444 // Only record reach outs for the current round or a newer than the recorded one. -7445 if *recorded_round == round { -7446 // Same round, simply append. -7447 reach_outs.insert((ip, port)); -7448 } else if *recorded_round < round { -7449 // New round. -7450 *recorded_round = round; -7451 reach_outs.drain(); -7452 reach_outs.insert((ip, port)); -7453 } else { -7454 // ignore old reach out that was sent -7455 } -7456 } -7457 -7458 ObservedAddr(_) => self.retransmits_mut().observed_addr = true, -7459 Ping(_) => self.non_retransmits = true, -7460 ImmediateAck(_) => self.non_retransmits = true, -7461 AckFrequency(_) => self.retransmits_mut().ack_frequency = true, -7462 PathChallenge(_) => self.non_retransmits = true, -7463 Crypto(crypto) => self.retransmits_mut().crypto.push_back(crypto), -7464 PathAbandon(path_abandon) => { -7465 self.retransmits_mut() -7466 .path_abandon -7467 .entry(path_abandon.path_id) -7468 .or_insert(path_abandon.error_code); -7469 } -7470 PathStatusAvailable(frame::PathStatusAvailable { path_id, .. }) -7471 | PathStatusBackup(frame::PathStatusBackup { path_id, .. }) => { -7472 self.retransmits_mut().path_status.insert(path_id); -7473 } -7474 MaxPathId(_) => self.retransmits_mut().max_path_id = true, -7475 PathsBlocked(_) => self.retransmits_mut().paths_blocked = true, -7476 PathCidsBlocked(path_cids_blocked) => { -7477 self.retransmits_mut() -7478 .path_cids_blocked -7479 .insert(path_cids_blocked.path_id); -7480 } -7481 ResetStream(reset) => self -7482 .retransmits_mut() -7483 .reset_stream -7484 .push((reset.id, reset.error_code)), -7485 StopSending(stop_sending) => self.retransmits_mut().stop_sending.push(stop_sending), -7486 NewConnectionId(new_cid) => self.retransmits_mut().new_cids.push(new_cid.issued()), -7487 RetireConnectionId(retire_cid) => self -7488 .retransmits_mut() -7489 .retire_cids -7490 .push((retire_cid.path_id.unwrap_or_default(), retire_cid.sequence)), -7491 Datagram(_) => self.non_retransmits = true, -7492 NewToken(_) => {} -7493 AddAddress(add_address) => { -7494 self.retransmits_mut().add_address.insert(add_address); -7495 } -7496 RemoveAddress(remove_address) => { -7497 self.retransmits_mut().remove_address.insert(remove_address); +7369/// The idle time, below which we use the shorter [`MAX_PTO_FAST_INTERVAL`]. +7370const MIN_IDLE_FOR_FAST_PTO: Duration = Duration::from_secs(25); +7371 +7372/// The max interval between successive tail-loss probes with short idle times. +7373/// +7374/// If the path or connection idle time is less than [`MIN_IDLE_FOR_FAST_PTO`] then we use +7375/// this value to ensure we have plenty of retransmits before we reach the idle time. +7376const MAX_PTO_FAST_INTERVAL: Duration = Duration::from_secs(1); +7377 +7378/// The RTT threshold above which we cap the PTO interval to 1.5 * smoothed_rtt +7379/// +7380/// This is RTT time above which 1.5 * RTT > [`MAX_PTO_INTERVAL`], for these links we want +7381/// to extend the interval between tail-loss probes to not fill the entire pipe with them. +7382const SLOW_RTT_THRESHOLD: Duration = Duration::from_millis(610); +7383 +7384/// Minimal remaining size to allow packet coalescing, excluding cryptographic tag +7385/// +7386/// This must be at least as large as the header for a well-formed empty packet to be coalesced, +7387/// plus some space for frames. We only care about handshake headers because short header packets +7388/// necessarily have smaller headers, and initial packets are only ever the first packet in a +7389/// datagram (because we coalesce in ascending packet space order and the only reason to split a +7390/// packet is when packet space changes). +7391const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32; +7392 +7393/// Largest amount of space that could be occupied by a Handshake or 0-RTT packet's header +7394/// +7395/// Excludes packet-type-specific fields such as packet number or Initial token +7396// https://www.rfc-editor.org/rfc/rfc9000.html#name-0-rtt: flags + version + dcid len + dcid + +7397// scid len + scid + length + pn +7398const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize = +7399 1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4; +7400 +7401#[derive(Default)] +7402struct SentFrames { +7403 retransmits: ThinRetransmits, +7404 /// The packet number of the largest acknowledged packet for each path +7405 largest_acked: FxHashMap<PathId, u64>, +7406 stream_frames: StreamMetaVec, +7407 /// Whether the packet contains non-retransmittable frames (like datagrams) +7408 non_retransmits: bool, +7409 /// If the datagram containing these frames should be padded to the min MTU +7410 requires_padding: bool, +7411} +7412 +7413impl SentFrames { +7414 /// Returns whether the packet contains only ACKs +7415 fn is_ack_only(&self, streams: &StreamsState) -> bool { +7416 !self.largest_acked.is_empty() +7417 && !self.non_retransmits +7418 && self.stream_frames.is_empty() +7419 && self.retransmits.is_empty(streams) +7420 } +7421 +7422 fn retransmits_mut(&mut self) -> &mut Retransmits { +7423 self.retransmits.get_or_create() +7424 } +7425 +7426 fn record_sent_frame(&mut self, frame: frame::EncodableFrame<'_>) { +7427 use frame::EncodableFrame::*; +7428 match frame { +7429 PathAck(path_ack_encoder) => { +7430 if let Some(max) = path_ack_encoder.ranges.max() { +7431 self.largest_acked.insert(path_ack_encoder.path_id, max); +7432 } +7433 } +7434 Ack(ack_encoder) => { +7435 if let Some(max) = ack_encoder.ranges.max() { +7436 self.largest_acked.insert(PathId::ZERO, max); +7437 } +7438 } +7439 Close(_) => { /* non retransmittable, but after this we don't really care */ } +7440 PathResponse(_) => self.non_retransmits = true, +7441 HandshakeDone(_) => self.retransmits_mut().handshake_done = true, +7442 ReachOut(frame::ReachOut { round, ip, port }) => { +7443 let (recorded_round, reach_outs) = self +7444 .retransmits_mut() +7445 .reach_out +7446 .get_or_insert_with(|| (round, FxHashSet::default())); +7447 // Only record reach outs for the current round or a newer than the recorded one. +7448 if *recorded_round == round { +7449 // Same round, simply append. +7450 reach_outs.insert((ip, port)); +7451 } else if *recorded_round < round { +7452 // New round. +7453 *recorded_round = round; +7454 reach_outs.drain(); +7455 reach_outs.insert((ip, port)); +7456 } else { +7457 // ignore old reach out that was sent +7458 } +7459 } +7460 +7461 ObservedAddr(_) => self.retransmits_mut().observed_addr = true, +7462 Ping(_) => self.non_retransmits = true, +7463 ImmediateAck(_) => self.non_retransmits = true, +7464 AckFrequency(_) => self.retransmits_mut().ack_frequency = true, +7465 PathChallenge(_) => self.non_retransmits = true, +7466 Crypto(crypto) => self.retransmits_mut().crypto.push_back(crypto), +7467 PathAbandon(path_abandon) => { +7468 self.retransmits_mut() +7469 .path_abandon +7470 .entry(path_abandon.path_id) +7471 .or_insert(path_abandon.error_code); +7472 } +7473 PathStatusAvailable(frame::PathStatusAvailable { path_id, .. }) +7474 | PathStatusBackup(frame::PathStatusBackup { path_id, .. }) => { +7475 self.retransmits_mut().path_status.insert(path_id); +7476 } +7477 MaxPathId(_) => self.retransmits_mut().max_path_id = true, +7478 PathsBlocked(_) => self.retransmits_mut().paths_blocked = true, +7479 PathCidsBlocked(path_cids_blocked) => { +7480 self.retransmits_mut() +7481 .path_cids_blocked +7482 .insert(path_cids_blocked.path_id); +7483 } +7484 ResetStream(reset) => self +7485 .retransmits_mut() +7486 .reset_stream +7487 .push((reset.id, reset.error_code)), +7488 StopSending(stop_sending) => self.retransmits_mut().stop_sending.push(stop_sending), +7489 NewConnectionId(new_cid) => self.retransmits_mut().new_cids.push(new_cid.issued()), +7490 RetireConnectionId(retire_cid) => self +7491 .retransmits_mut() +7492 .retire_cids +7493 .push((retire_cid.path_id.unwrap_or_default(), retire_cid.sequence)), +7494 Datagram(_) => self.non_retransmits = true, +7495 NewToken(_) => {} +7496 AddAddress(add_address) => { +7497 self.retransmits_mut().add_address.insert(add_address); 7498 } -7499 StreamMeta(stream_meta_encoder) => self.stream_frames.push(stream_meta_encoder.meta), -7500 MaxData(_) => self.retransmits_mut().max_data = true, -7501 MaxStreamData(max) => { -7502 self.retransmits_mut().max_stream_data.insert(max.id); -7503 } -7504 MaxStreams(max_streams) => { -7505 self.retransmits_mut().max_stream_id[max_streams.dir as usize] = true -7506 } -7507 } -7508 } -7509} -7510 -7511/// Compute the negotiated idle timeout based on local and remote max_idle_timeout transport parameters. -7512/// -7513/// According to the definition of max_idle_timeout, a value of `0` means the timeout is disabled; see <https://www.rfc-editor.org/rfc/rfc9000#section-18.2-4.4.1.> -7514/// -7515/// According to the negotiation procedure, either the minimum of the timeouts or one specified is used as the negotiated value; see <https://www.rfc-editor.org/rfc/rfc9000#section-10.1-2.> -7516/// -7517/// Returns the negotiated idle timeout as a `Duration`, or `None` when both endpoints have opted out of idle timeout. -7518fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> { -7519 match (x, y) { -7520 (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None, -7521 (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)), -7522 (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)), -7523 (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)), -7524 } -7525} -7526 -7527#[cfg(test)] -7528mod tests { -7529 use super::*; -7530 -7531 #[test] -7532 fn negotiate_max_idle_timeout_commutative() { -7533 let test_params = [ -7534 (None, None, None), -7535 (None, Some(VarInt(0)), None), -7536 (None, Some(VarInt(2)), Some(Duration::from_millis(2))), -7537 (Some(VarInt(0)), Some(VarInt(0)), None), -7538 ( -7539 Some(VarInt(2)), -7540 Some(VarInt(0)), -7541 Some(Duration::from_millis(2)), -7542 ), -7543 ( -7544 Some(VarInt(1)), -7545 Some(VarInt(4)), -7546 Some(Duration::from_millis(1)), -7547 ), -7548 ]; -7549 -7550 for (left, right, result) in test_params { -7551 assert_eq!(negotiate_max_idle_timeout(left, right), result); -7552 assert_eq!(negotiate_max_idle_timeout(right, left), result); -7553 } -7554 } -7555} \ No newline at end of file +7499 RemoveAddress(remove_address) => { +7500 self.retransmits_mut().remove_address.insert(remove_address); +7501 } +7502 StreamMeta(stream_meta_encoder) => self.stream_frames.push(stream_meta_encoder.meta), +7503 MaxData(_) => self.retransmits_mut().max_data = true, +7504 MaxStreamData(max) => { +7505 self.retransmits_mut().max_stream_data.insert(max.id); +7506 } +7507 MaxStreams(max_streams) => { +7508 self.retransmits_mut().max_stream_id[max_streams.dir as usize] = true +7509 } +7510 } +7511 } +7512} +7513 +7514/// Compute the negotiated idle timeout based on local and remote max_idle_timeout transport parameters. +7515/// +7516/// According to the definition of max_idle_timeout, a value of `0` means the timeout is disabled; see <https://www.rfc-editor.org/rfc/rfc9000#section-18.2-4.4.1.> +7517/// +7518/// According to the negotiation procedure, either the minimum of the timeouts or one specified is used as the negotiated value; see <https://www.rfc-editor.org/rfc/rfc9000#section-10.1-2.> +7519/// +7520/// Returns the negotiated idle timeout as a `Duration`, or `None` when both endpoints have opted out of idle timeout. +7521fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> { +7522 match (x, y) { +7523 (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None, +7524 (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)), +7525 (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)), +7526 (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)), +7527 } +7528} +7529 +7530#[cfg(test)] +7531mod tests { +7532 use super::*; +7533 +7534 #[test] +7535 fn negotiate_max_idle_timeout_commutative() { +7536 let test_params = [ +7537 (None, None, None), +7538 (None, Some(VarInt(0)), None), +7539 (None, Some(VarInt(2)), Some(Duration::from_millis(2))), +7540 (Some(VarInt(0)), Some(VarInt(0)), None), +7541 ( +7542 Some(VarInt(2)), +7543 Some(VarInt(0)), +7544 Some(Duration::from_millis(2)), +7545 ), +7546 ( +7547 Some(VarInt(1)), +7548 Some(VarInt(4)), +7549 Some(Duration::from_millis(1)), +7550 ), +7551 ]; +7552 +7553 for (left, right, result) in test_params { +7554 assert_eq!(negotiate_max_idle_timeout(left, right), result); +7555 assert_eq!(negotiate_max_idle_timeout(right, left), result); +7556 } +7557 } +7558} \ No newline at end of file