




from dataclasses import dataclass
from typing import Optional

import numpy as np
import torch
import torch.nn as nn

from ..utils import BaseOutput, is_torch_version, randn_tensor
from .attention_processor import SpatialNorm
from .unet_ad_blocks import UNetMidBlockaD, get_down_block, get_up_block







@dataclass
class 		lowercase							(     UpperCamelCase__	):
     _a											=		42







class 		lowercase							(     nn.Module	):

     def __init__(						self	,  _a=3	,  _a=3	,  _a=("DownEncoderBlock2D",)	,  _a=(64,)	,  _a=2	,  _a=32	,  _a="silu"	,  _a=True	,  )		->							Any:
           super().__init__()
           _A							:  Optional[int]    =		layers_per_block

           _A							:  Tuple    =		torch.nn.Convad(
               _a	,  block_out_channels[0]	,  kernel_size=3	,  stride=1	,  padding=1	,  )

           _A							:  str    =		None
           _A							:  int    =		nn.ModuleList([]       )

           # down
           _A							:  Tuple    =		block_out_channels[0]
           for i, down_block_type in enumerate(_a       ):
                 _A							:  Optional[int]    =		output_channel
                 _A							:  List[Any]    =		block_out_channels[i]
                 _A							:  List[Any]    =		i == len(_a       ) - 1

                 _A							:  Union[str, Any]    =		get_down_block(
                     _a	,  num_layers=self.layers_per_block	,  in_channels=_a	,  out_channels=_a	,  add_downsample=not is_final_block	,  resnet_eps=1e-6	,  downsample_padding=0	,  resnet_act_fn=_a	,  resnet_groups=_a	,  attention_head_dim=_a	,  temb_channels=_a	,  )
                 self.down_blocks.append(_a       )

           # mid
           _A							:  List[str]    =		UNetMidBlockaD(
               in_channels=block_out_channels[-1]	,  resnet_eps=1e-6	,  resnet_act_fn=_a	,  output_scale_factor=1	,  resnet_time_scale_shift="""default"""	,  attention_head_dim=block_out_channels[-1]	,  resnet_groups=_a	,  temb_channels=_a	,  )

           # out
           _A							:  Dict    =		nn.GroupNorm(num_channels=block_out_channels[-1]	,  num_groups=_a	,  eps=1e-6       )
           _A							:  Optional[int]    =		nn.SiLU()

           _A							:  List[str]    =		2 * out_channels if double_z else out_channels
           _A							:  List[str]    =		nn.Convad(block_out_channels[-1]	,  _a	,  3	,  padding=1       )

           _A							:  int    =		False



     def       a__			(						self	,  _a       )		->							Optional[Any]:
           _A							:  Dict    =		x
           _A							:  Tuple    =		self.conv_in(_a       )

           if self.training and self.gradient_checkpointing:

                 def create_custom_forward(_a       ):
                       def custom_forward(*_a       ):
                             return module(*_a       )

                       return custom_forward

                 # down
                 if is_torch_version(""">="""	,  """1.11.0"""       ):
                       for down_block in self.down_blocks:
                             _A							:  Tuple    =		torch.utils.checkpoint.checkpoint(
                                 create_custom_forward(_a       )	,  _a	,  use_reentrant=_a       )
                       # middle
                       _A							:  Optional[int]    =		torch.utils.checkpoint.checkpoint(
                           create_custom_forward(self.mid_block       )	,  _a	,  use_reentrant=_a       )
                 else:
                       for down_block in self.down_blocks:
                             _A							:  Optional[Any]    =		torch.utils.checkpoint.checkpoint(create_custom_forward(_a       )	,  _a       )
                       # middle
                       _A							:  Union[str, Any]    =		torch.utils.checkpoint.checkpoint(create_custom_forward(self.mid_block       )	,  _a       )

           else:
                 # down
                 for down_block in self.down_blocks:
                       _A							:  Optional[int]    =		down_block(_a       )

                 # middle
                 _A							:  int    =		self.mid_block(_a       )

           # post-process
           _A							:  Tuple    =		self.conv_norm_out(_a       )
           _A							:  Optional[int]    =		self.conv_act(_a       )
           _A							:  Optional[int]    =		self.conv_out(_a       )

           return sample







class 		lowercase							(     nn.Module	):

     def __init__(						self	,  _a=3	,  _a=3	,  _a=("UpDecoderBlock2D",)	,  _a=(64,)	,  _a=2	,  _a=32	,  _a="silu"	,  _a="group"	,  )		->							Optional[int]:
           super().__init__()
           _A							:  str    =		layers_per_block

           _A							:  str    =		nn.Convad(
               _a	,  block_out_channels[-1]	,  kernel_size=3	,  stride=1	,  padding=1	,  )

           _A							:  Optional[int]    =		None
           _A							:  int    =		nn.ModuleList([]       )

           _A							:  Dict    =		in_channels if norm_type == """spatial""" else None

           # mid
           _A							:  Tuple    =		UNetMidBlockaD(
               in_channels=block_out_channels[-1]	,  resnet_eps=1e-6	,  resnet_act_fn=_a	,  output_scale_factor=1	,  resnet_time_scale_shift="""default""" if norm_type == """group""" else norm_type	,  attention_head_dim=block_out_channels[-1]	,  resnet_groups=_a	,  temb_channels=_a	,  )

           # up
           _A							:  Union[str, Any]    =		list(reversed(_a       )       )
           _A							:  int    =		reversed_block_out_channels[0]
           for i, up_block_type in enumerate(_a       ):
                 _A							:  List[Any]    =		output_channel
                 _A							:  Tuple    =		reversed_block_out_channels[i]

                 _A							:  Optional[Any]    =		i == len(_a       ) - 1

                 _A							:  Optional[int]    =		get_up_block(
                     _a	,  num_layers=self.layers_per_block + 1	,  in_channels=_a	,  out_channels=_a	,  prev_output_channel=_a	,  add_upsample=not is_final_block	,  resnet_eps=1e-6	,  resnet_act_fn=_a	,  resnet_groups=_a	,  attention_head_dim=_a	,  temb_channels=_a	,  resnet_time_scale_shift=_a	,  )
                 self.up_blocks.append(_a       )
                 _A							:  str    =		output_channel

           # out
           if norm_type == "spatial":
                 _A							:  str    =		SpatialNorm(block_out_channels[0]	,  _a       )
           else:
                 _A							:  int    =		nn.GroupNorm(num_channels=block_out_channels[0]	,  num_groups=_a	,  eps=1e-6       )
           _A							:  Dict    =		nn.SiLU()
           _A							:  str    =		nn.Convad(block_out_channels[0]	,  _a	,  3	,  padding=1       )

           _A							:  int    =		False



     def       a__			(						self	,  _a	,  _a=None       )		->							Tuple:
           _A							:  Union[str, Any]    =		z
           _A							:  int    =		self.conv_in(_a       )

           _A							:  Any    =		next(iter(self.up_blocks.parameters()       )       ).dtype
           if self.training and self.gradient_checkpointing:

                 def create_custom_forward(_a       ):
                       def custom_forward(*_a       ):
                             return module(*_a       )

                       return custom_forward

                 if is_torch_version(""">="""	,  """1.11.0"""       ):
                       # middle
                       _A							:  List[str]    =		torch.utils.checkpoint.checkpoint(
                           create_custom_forward(self.mid_block       )	,  _a	,  _a	,  use_reentrant=_a       )
                       _A							:  List[Any]    =		sample.to(_a       )

                       # up
                       for up_block in self.up_blocks:
                             _A							:  Optional[int]    =		torch.utils.checkpoint.checkpoint(
                                 create_custom_forward(_a       )	,  _a	,  _a	,  use_reentrant=_a       )
                 else:
                       # middle
                       _A							:  int    =		torch.utils.checkpoint.checkpoint(
                           create_custom_forward(self.mid_block       )	,  _a	,  _a       )
                       _A							:  int    =		sample.to(_a       )

                       # up
                       for up_block in self.up_blocks:
                             _A							:  int    =		torch.utils.checkpoint.checkpoint(create_custom_forward(_a       )	,  _a	,  _a       )
           else:
                 # middle
                 _A							:  Any    =		self.mid_block(_a	,  _a       )
                 _A							:  Union[str, Any]    =		sample.to(_a       )

                 # up
                 for up_block in self.up_blocks:
                       _A							:  Union[str, Any]    =		up_block(_a	,  _a       )

        # post-process
           if latent_embeds is None:
                 _A							:  Any    =		self.conv_norm_out(_a       )
           else:
                 _A							:  Union[str, Any]    =		self.conv_norm_out(_a	,  _a       )
           _A							:  str    =		self.conv_act(_a       )
           _A							:  Tuple    =		self.conv_out(_a       )

           return sample







class 		lowercase							(     nn.Module	):

     def __init__(						self	,  _a	,  _a	,  _a	,  _a=None	,  _a="random"	,  _a=False	,  _a=True       )		->							Any:
           super().__init__()
           _A							:  Tuple    =		n_e
           _A							:  Optional[Any]    =		vq_embed_dim
           _A							:  Tuple    =		beta
           _A							:  Dict    =		legacy

           _A							:  List[str]    =		nn.Embedding(self.n_e	,  self.vq_embed_dim       )
           self.embedding.weight.data.uniform_(-1.0 / self.n_e	,  1.0 / self.n_e       )

           _A							:  Tuple    =		remap
           if self.remap is not None:
                 self.register_buffer("""used"""	,  torch.tensor(np.load(self.remap       )       )       )
                 _A							:  int    =		self.used.shape[0]
                 _A							:  Optional[int]    =		unknown_index  # "random" or "extra" or integer
                 if self.unknown_index == "extra":
                       _A							:  Optional[int]    =		self.re_embed
                       _A							:  Optional[Any]    =		self.re_embed + 1
                 print(
                     F'''Remapping {self.n_e} indices to {self.re_embed} indices. '''
                     F'''Using {self.unknown_index} for unknown indices.'''       )
           else:
                 _A							:  Dict    =		n_e

           _A							:  Dict    =		sane_index_shape

     def       a__			(						self	,  _a       )		->							int:
           _A							:  Tuple    =		inds.shape
           assert len(_a       ) > 1
           _A							:  Union[str, Any]    =		inds.reshape(ishape[0]	,  -1       )
           _A							:  Union[str, Any]    =		self.used.to(_a       )
           _A							:  Optional[Any]    =		(inds[:, :, None] == used[None, None, ...]).long()
           _A							:  int    =		match.argmax(-1       )
           _A							:  Any    =		match.sum(2       ) < 1
           if self.unknown_index == "random":
                 _A							:  List[str]    =		torch.randint(0	,  self.re_embed	,  size=new[unknown].shape       ).to(device=new.device       )
           else:
                 _A							:  int    =		self.unknown_index
           return new.reshape(_a       )

     def       a__			(						self	,  _a       )		->							Dict:
           _A							:  Tuple    =		inds.shape
           assert len(_a       ) > 1
           _A							:  List[Any]    =		inds.reshape(ishape[0]	,  -1       )
           _A							:  Union[str, Any]    =		self.used.to(_a       )
           if self.re_embed > self.used.shape[0]:  # extra token
                 _A							:  str    =		0  # simply set to zero
           _A							:  Any    =		torch.gather(used[None, :][inds.shape[0] * [0], :]	,  1	,  _a       )
           return back.reshape(_a       )

     def       a__			(						self	,  _a       )		->							str:
           # reshape z -> (batch, height, width, channel) and flatten
           _A							:  Any    =		z.permute(0	,  2	,  3	,  1       ).contiguous()
           _A							:  int    =		z.view(-1	,  self.vq_embed_dim       )

           # distances from z to embeddings e_j (z - e)^2 = z^2 + e^2 - 2 e * z
           _A							:  Tuple    =		torch.argmin(torch.cdist(_a	,  self.embedding.weight       )	,  dim=1       )

           _A							:  Any    =		self.embedding(_a       ).view(z.shape       )
           _A							:  Optional[Any]    =		None
           _A							:  Any    =		None

           # compute loss for embedding
           if not self.legacy:
                 _A							:  List[str]    =		self.beta * torch.mean((z_q.detach() - z) ** 2       ) + torch.mean((z_q - z.detach()) ** 2       )
           else:
                 _A							:  Any    =		torch.mean((z_q.detach() - z) ** 2       ) + self.beta * torch.mean((z_q - z.detach()) ** 2       )

           # preserve gradients
           _A							:  List[str]    =		z + (z_q - z).detach()

           # reshape back to match original input shape
           _A							:  Dict    =		z_q.permute(0	,  3	,  1	,  2       ).contiguous()

           if self.remap is not None:
                 _A							:  str    =		min_encoding_indices.reshape(z.shape[0]	,  -1       )  # add batch axis
                 _A							:  int    =		self.remap_to_used(_a       )
                 _A							:  List[Any]    =		min_encoding_indices.reshape(-1	,  1       )  # flatten

           if self.sane_index_shape:
                 _A							:  int    =		min_encoding_indices.reshape(z_q.shape[0]	,  z_q.shape[2]	,  z_q.shape[3]       )

           return z_q, loss, (perplexity, min_encodings, min_encoding_indices)



     def       a__			(						self	,  _a	,  _a       )		->							List[str]:
           # shape specifying (batch, height, width, channel)
           if self.remap is not None:
                 _A							:  List[str]    =		indices.reshape(shape[0]	,  -1       )  # add batch axis
                 _A							:  Optional[int]    =		self.unmap_to_all(_a       )
                 _A							:  Any    =		indices.reshape(-1       )  # flatten again

           # get quantized latent vectors
           _A							:  str    =		self.embedding(_a       )

           if shape is not None:
                 _A							:  int    =		z_q.view(_a       )
                 # reshape back to match original input shape
                 _A							:  Optional[Any]    =		z_q.permute(0	,  3	,  1	,  2       ).contiguous()

           return z_q







class 		lowercase							(     UpperCamelCase__	):

     def __init__(						self	,  _a	,  _a=False       )		->							Any:
           _A							:  Dict    =		parameters
           _A    ,     _A							:  Tuple    =		torch.chunk(_a	,  2	,  dim=1       )
           _A							:  Optional[Any]    =		torch.clamp(self.logvar	,  -30.0	,  20.0       )
           _A							:  Tuple    =		deterministic
           _A							:  Any    =		torch.exp(0.5 * self.logvar       )
           _A							:  Optional[int]    =		torch.exp(self.logvar       )
           if self.deterministic:
                 _A							:  List[Any]    =		torch.zeros_like(
                     self.mean	,  device=self.parameters.device	,  dtype=self.parameters.dtype       )

     def       a__			(						self	,  _a = None       )		->							torch.FloatTensor:
           # make sure sample is on the same device as the parameters and has same dtype
           _A							:  Union[str, Any]    =		randn_tensor(
               self.mean.shape	,  generator=_a	,  device=self.parameters.device	,  dtype=self.parameters.dtype       )
           _A							:  int    =		self.mean + self.std * sample
           return x

     def       a__			(						self	,  _a=None       )		->							Tuple:
           if self.deterministic:
                 return torch.Tensor([0.0]       )
           else:
                 if other is None:
                       return 0.5 * torch.sum(torch.pow(self.mean	,  2       ) + self.var - 1.0 - self.logvar	,  dim=[1, 2, 3]       )
                 else:
                       return 0.5 * torch.sum(
                           torch.pow(self.mean - other.mean	,  2       ) / other.var
                           + self.var / other.var
                           - 1.0
                           - self.logvar
                           + other.logvar	,  dim=[1, 2, 3]	,  )

     def       a__			(						self	,  _a	,  _a=[1, 2, 3]       )		->							Optional[Any]:
           if self.deterministic:
                 return torch.Tensor([0.0]       )
           _A							:  List[str]    =		np.log(2.0 * np.pi       )
           return 0.5 * torch.sum(logtwopi + self.logvar + torch.pow(sample - self.mean	,  2       ) / self.var	,  dim=_a       )



     def       a__			(						self       )		->							str:
           return self.mean







def        lowerCAmelCase_			(  snake_case_,snake_case_  ):
      _A							:  Union[str, Any]    =		""""""
      for i in table:
            res += inp[i - 1]
      return res







def        lowerCAmelCase_			(  snake_case_  ):
      return data[1:] + data[0]







def        lowerCAmelCase_			(  snake_case_,snake_case_  ):
      _A							:  Dict    =		""""""
      for i in range(len(snake_case_  )  ):
            if a[i] == b[i]:
                  res += "0"
            else:
                  res += "1"
      return res







def        lowerCAmelCase_			(  snake_case_,snake_case_  ):
      _A							:  int    =		int("""0b""" + data[0] + data[-1],2  )
      _A							:  Any    =		int("""0b""" + data[1:3],2  )
      return bin(s[row][col]  )[2:]







def        lowerCAmelCase_			(  snake_case_,snake_case_,snake_case_,snake_case_,snake_case_  ):
      _A							:  List[str]    =		message[:4]
      _A							:  List[Any]    =		message[4:]
      _A							:  Union[str, Any]    =		apply_table(snake_case_,snake_case_  )
      _A							:  List[Any]    =		xor(snake_case_,snake_case_  )
      _A							:  Optional[Any]    =		apply_sbox(snake_case_,temp[:4]  )  # noqa: E741
      _A							:  List[Any]    =		apply_sbox(snake_case_,temp[4:]  )
      _A							:  int    =		"""0""" * (2 - len(snake_case_  )) + l  # noqa: E741
      _A							:  Union[str, Any]    =		"""0""" * (2 - len(snake_case_  )) + r
      _A							:  List[Any]    =		apply_table(l + r,snake_case_  )
      _A							:  Any    =		xor(snake_case_,snake_case_  )
      return temp + right


if __name__ == "__main__":
  _snake_case            = input("Enter 10 bit key: ")
  _snake_case            = input("Enter 8 bit message: ")

  _snake_case            = [6, 3, 7, 4, 8, 5, 10, 9]
  _snake_case            = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
  _snake_case            = [2, 4, 3, 1]
  _snake_case            = [2, 6, 3, 1, 4, 8, 5, 7]
  _snake_case            = [4, 1, 3, 5, 7, 2, 8, 6]
  _snake_case            = [4, 1, 2, 3, 2, 3, 4, 1]
  _snake_case            = [[1, 0, 3, 2], [3, 2, 1, 0], [0, 2, 1, 3], [3, 1, 3, 2]]
  _snake_case            = [[0, 1, 2, 3], [2, 0, 1, 3], [3, 0, 1, 0], [2, 1, 0, 3]]

  # key generation
  _snake_case            = apply_table(key, paa_table)
  _snake_case            = temp[:5]
  _snake_case            = temp[5:]
  _snake_case            = left_shift(left)
  _snake_case            = left_shift(right)
  _snake_case            = apply_table(left + right, pa_table)
  _snake_case            = left_shift(left)
  _snake_case            = left_shift(right)
  _snake_case            = left_shift(left)
  _snake_case            = left_shift(right)
  _snake_case            = apply_table(left + right, pa_table)

  # encryption
  _snake_case            = apply_table(message, IP)
  _snake_case            = function(expansion, sa, sa, keya, temp)
  _snake_case            = temp[4:] + temp[:4]
  _snake_case            = function(expansion, sa, sa, keya, temp)
  _snake_case            = apply_table(temp, IP_inv)
  print("Cipher text is:", CT)

  # decryption
  _snake_case            = apply_table(CT, IP)
  _snake_case            = function(expansion, sa, sa, keya, temp)
  _snake_case            = temp[4:] + temp[:4]
  _snake_case            = function(expansion, sa, sa, keya, temp)
  _snake_case            = apply_table(temp, IP_inv)
  print("Plain text after decypting is:", PT)

