



"""simple docstring"""

import copy
from typing import Any, Dict, List, Optional, Union

import numpy as np
import torch

from ...audio_utils import mel_filter_bank, spectrogram, window_function
from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
from ...feature_extraction_utils import BatchFeature
from ...utils import TensorType, logging


lowercase__			   =  logging.get_logger(__name__)




class SCREAMING_SNAKE_CASE__					(       UpperCAmelCase__      ):
						_lowerCAmelCase							=					["input_features", "is_longer"]



						def __init__(self						,     _lowercase=64						,     _lowercase=48000						,     _lowercase=480						,     _lowercase=10						,     _lowercase=1024						,     _lowercase=0.0						,     _lowercase=False						,     _lowercase = 0						,     _lowercase = 14000						,     _lowercase = None						,     _lowercase = "fusion"						,     _lowercase = "repeatpad"						,     **_lowercase						,     ):





													'''simple docstring'''

													super().__init__(
													    feature_size=lowerCamelCase__						,     sampling_rate=lowerCamelCase__						,     padding_value=lowerCamelCase__						,     return_attention_mask=lowerCamelCase__						,     **lowerCamelCase__						,     )
													__a		:		int									=       top_db
													__a		:		Any									=       truncation
													__a		:		Optional[Any]									=       padding
													__a		:		int									=       fft_window_size
													__a		:		Optional[int]									=       (fft_window_size >> 1) + 1
													__a		:		Optional[int]									=       hop_length
													__a		:		Union[str, Any]									=       max_length_s
													__a		:		Union[str, Any]									=       max_length_s * sampling_rate
													__a		:		List[str]									=       sampling_rate
													__a		:		Optional[int]									=       frequency_min
													__a		:		List[Any]									=       frequency_max
													__a		:		Union[str, Any]									=       mel_filter_bank(
													    num_frequency_bins=self.nb_frequency_bins						,     num_mel_filters=lowerCamelCase__						,     min_frequency=lowerCamelCase__						,     max_frequency=lowerCamelCase__						,     sampling_rate=lowerCamelCase__						,     norm=lowerCamelCase__						,     mel_scale="""htk"""						,     )
													__a		:		Tuple									=       mel_filter_bank(
													    num_frequency_bins=self.nb_frequency_bins						,     num_mel_filters=lowerCamelCase__						,     min_frequency=lowerCamelCase__						,     max_frequency=lowerCamelCase__						,     sampling_rate=lowerCamelCase__						,     norm="""slaney"""						,     mel_scale="""slaney"""						,     )



						def     lowerCAmelCase__(self							):





													'''simple docstring'''

													__a		:		List[Any]									=       copy.deepcopy(self.__dict__							)
													__a		:		Optional[Any]									=       self.__class__.__name__
													if "mel_filters" in output:
																				del output["mel_filters"]
													if "mel_filters_slaney" in output:
																				del output["mel_filters_slaney"]
													return output



						def     lowerCAmelCase__(self						,     _lowercase						,     _lowercase = None							):





													'''simple docstring'''

													__a		:		int									=       spectrogram(
													    lowerCamelCase__						,     window_function(self.fft_window_size						,     """hann"""							)						,     frame_length=self.fft_window_size						,     hop_length=self.hop_length						,     power=2.0						,     mel_filters=lowerCamelCase__						,     log_mel="""dB"""						,     )
													return log_mel_spectrogram.T



						def     lowerCAmelCase__(self						,     _lowercase						,     _lowercase						,     _lowercase							):





													'''simple docstring'''

													__a		:		List[Any]									=       np.array_split(list(range(0						,     total_frames - chunk_frames + 1							)							)						,     3							)
													if len(ranges[1]							) == 0:
																				# if the audio is too short, we just use the first chunk
																				__a		:		int									=       [0]
													if len(ranges[2]							) == 0:
																				# if the audio is too short, we just use the first chunk
																				__a		:		List[Any]									=       [0]
													# randomly choose index for each part
													__a		:		List[Any]									=       np.random.choice(ranges[0]							)
													__a		:		List[str]									=       np.random.choice(ranges[1]							)
													__a		:		List[str]									=       np.random.choice(ranges[2]							)

													__a		:		Dict									=       mel[idx_front : idx_front + chunk_frames, :]
													__a		:		int									=       mel[idx_middle : idx_middle + chunk_frames, :]
													__a		:		int									=       mel[idx_back : idx_back + chunk_frames, :]

													__a		:		Dict									=       torch.tensor(mel[None, None, :]							)
													__a		:		Any									=       torch.nn.functional.interpolate(
													    lowerCamelCase__						,     size=[chunk_frames, 64]						,     mode="""bilinear"""						,     align_corners=lowerCamelCase__							)
													__a		:		List[str]									=       mel_shrink[0][0].numpy()
													__a		:		List[str]									=       np.stack([mel_shrink, mel_chunk_front, mel_chunk_middle, mel_chunk_back]						,     axis=0							)
													return mel_fusion



						def     lowerCAmelCase__(self						,     _lowercase						,     _lowercase						,     _lowercase						,     _lowercase							):





													'''simple docstring'''

													if waveform.shape[0] > max_length:
																				if truncation == "rand_trunc":
																											__a		:		Optional[int]									=       True
																											# random crop to max_length (for compatibility) -> this should be handled by self.pad
																											__a		:		Optional[Any]									=       len(lowerCamelCase__							) - max_length
																											__a		:		List[Any]									=       np.random.randint(0						,     overflow + 1							)
																											__a		:		str									=       waveform[idx : idx + max_length]
																											__a		:		Dict									=       self._np_extract_fbank_features(lowerCamelCase__						,     self.mel_filters_slaney							)[None, :]
																				elif truncation == "fusion":
																											__a		:		List[str]									=       self._np_extract_fbank_features(lowerCamelCase__						,     self.mel_filters							)
																											__a		:		List[Any]									=       max_length // self.hop_length + 1  # the +1 related to how the spectrogram is computed
																											__a		:		str									=       mel.shape[0]
																											if chunk_frames == total_frames:
																																		# there is a corner case where the audio length is larger than max_length but smaller than max_length+hop_length.
																																		# In this case, we just use the whole audio.
																																		__a		:		Optional[Any]									=       np.stack([mel, mel, mel, mel]						,     axis=0							)
																																		__a		:		List[str]									=       False
																											else:
																																		__a		:		Optional[Any]									=       self._random_mel_fusion(lowerCamelCase__						,     lowerCamelCase__						,     lowerCamelCase__							)
																																		__a		:		Union[str, Any]									=       True
																				else:
																											raise NotImplementedError(F'''data_truncating {truncation} not implemented'''							)

													else:
																				__a		:		Union[str, Any]									=       False
																				# only use repeat as a new possible value for padding. you repeat the audio before applying the usual max_length padding
																				if waveform.shape[0] < max_length:
																											if padding == "repeat":
																																		__a		:		Optional[int]									=       int(max_length / len(lowerCamelCase__							)							)
																																		__a		:		int									=       np.stack(np.tile(lowerCamelCase__						,     n_repeat + 1							)							)[:max_length]
																											if padding == "repeatpad":
																																		__a		:		Optional[Any]									=       int(max_length / len(lowerCamelCase__							)							)
																																		__a		:		str									=       np.stack(np.tile(lowerCamelCase__						,     lowerCamelCase__							)							)
																											__a		:		Any									=       np.pad(lowerCamelCase__						,     (0, max_length - waveform.shape[0])						,     mode="""constant"""						,     constant_values=0							)

																				if truncation == "fusion":
																											__a		:		List[Any]									=       self._np_extract_fbank_features(lowerCamelCase__						,     self.mel_filters							)
																											__a		:		Tuple									=       np.stack([input_mel, input_mel, input_mel, input_mel]						,     axis=0							)
																				else:
																											__a		:		List[str]									=       self._np_extract_fbank_features(lowerCamelCase__						,     self.mel_filters_slaney							)[None, :]

													return input_mel, longer





						def __call__(self						,     _lowercase						,     _lowercase = None						,     _lowercase = None						,     _lowercase = None						,     _lowercase = None						,     _lowercase = None						,     **_lowercase						,     ):





													'''simple docstring'''

													__a		:		Any									=       truncation if truncation is not None else self.truncation
													__a		:		Any									=       padding if padding else self.padding

													if sampling_rate is not None:
																				if sampling_rate != self.sampling_rate:
																											raise ValueError(
																											    F'''The model corresponding to this feature extractor: {self.__class__.__name__} was trained using a'''
																											    F''' sampling rate of {self.sampling_rate}. Please make sure that the provided `raw_speech` input'''
																											    F''' was sampled with {self.sampling_rate} and not {sampling_rate}.'''							)
													else:
																				logger.warning(
																				    """It is strongly recommended to pass the `sampling_rate` argument to this function. """
																				    """Failing to do so can result in silent errors that might be hard to debug."""							)

													__a		:		Tuple									=       isinstance(lowerCamelCase__						,     np.ndarray							) and len(raw_speech.shape							) > 1
													if is_batched_numpy and len(raw_speech.shape							) > 2:
																				raise ValueError(F'''Only mono-channel audio is supported for input to {self}'''							)
													__a		:		int									=       is_batched_numpy or (
													    isinstance(lowerCamelCase__						,     (list, tuple)							) and (isinstance(raw_speech[0]						,     (np.ndarray, tuple, list)							))
													)

													if is_batched:
																				__a		:		Tuple									=       [np.asarray(lowerCamelCase__						,     dtype=np.floataa							) for speech in raw_speech]
													elif not is_batched and not isinstance(lowerCamelCase__						,     np.ndarray							):
																				__a		:		int									=       np.asarray(lowerCamelCase__						,     dtype=np.floataa							)
													elif isinstance(lowerCamelCase__						,     np.ndarray							) and raw_speech.dtype is np.dtype(np.floataa							):
																				__a		:		str									=       raw_speech.astype(np.floataa							)

													# always return batch
													if not is_batched:
																				__a		:		int									=       [np.asarray(lowerCamelCase__							)]

													# convert to mel spectrogram, truncate and pad if needed.
													__a		:		List[str]									=       [
													    self._get_input_mel(lowerCamelCase__						,     max_length if max_length else self.nb_max_samples						,     lowerCamelCase__						,     lowerCamelCase__							)
													    for waveform in raw_speech
													]

													__a		:		Optional[int]									=       []
													__a		:		Tuple									=       []
													for mel, longer in padded_inputs:
																				input_mel.append(lowerCamelCase__							)
																				is_longer.append(lowerCamelCase__							)

													if truncation == "fusion" and sum(lowerCamelCase__							) == 0:
																				# if no audio is longer than 10s, then randomly select one audio to be longer
																				__a		:		List[Any]									=       np.random.randint(0						,     len(lowerCamelCase__							)							)
																				__a		:		List[str]									=       True

													if isinstance(input_mel[0]						,     lowerCamelCase__							):
																				__a		:		Dict									=       [np.asarray(lowerCamelCase__						,     dtype=np.floataa							) for feature in input_mel]

													# is_longer is a list of bool
													__a		:		Any									=       [[longer] for longer in is_longer]

													__a		:		str									=       {"input_features": input_mel, "is_longer": is_longer}
													__a		:		Dict									=       BatchFeature(lowerCamelCase__							)

													if return_tensors is not None:
																				__a		:		Optional[int]									=       input_features.convert_to_tensors(lowerCamelCase__							)

													return input_features






"""simple docstring"""

import os





def       __magic_name__    (   _lowerCamelCase				: Dict					):
							__a		:		List[str]									=       len(grid[0]					)
							__a		:		int									=       len(_lowerCamelCase					)

							__a		:		Tuple									=       0
							__a		:		List[Any]									=       0
							__a		:		List[str]									=       0

							# Check vertically, horizontally, diagonally at the same time (only works
							# for nxn grid)
							for i in range(_lowerCamelCase					):
														for j in range(n_rows - 3					):
																					__a		:		List[Any]									=       grid[j][i] * grid[j + 1][i] * grid[j + 2][i] * grid[j + 3][i]
																					__a		:		Tuple									=       grid[i][j] * grid[i][j + 1] * grid[i][j + 2] * grid[i][j + 3]

																					# Left-to-right diagonal (\) product
																					if i < n_columns - 3:
																												__a		:		List[Any]									=       (
																												    grid[i][j]
																												    * grid[i + 1][j + 1]
																												    * grid[i + 2][j + 2]
																												    * grid[i + 3][j + 3]
																												)

																					# Right-to-left diagonal(/) product
																					if i > 2:
																												__a		:		List[Any]									=       (
																												    grid[i][j]
																												    * grid[i - 1][j + 1]
																												    * grid[i - 2][j + 2]
																												    * grid[i - 3][j + 3]
																												)

																					__a		:		str									=       max(
																					    _lowerCamelCase  ,       _lowerCamelCase  ,       _lowerCamelCase  ,       _lowerCamelCase					)
																					if max_product > largest:
																												__a		:		Optional[Any]									=       max_product

							return largest





def       __magic_name__    (   ):
							__a		:		Tuple									=       []
							with open(os.path.dirname(_lowerCamelCase					) + """/grid.txt"""					) as file:
														for line in file:
																					grid.append(line.strip("""\n"""					).split(""" """					)					)

							__a		:		Tuple									=       [[int(_lowerCamelCase					) for i in grid[j]] for j in range(len(_lowerCamelCase					)					)]

							return largest_product(_lowerCamelCase					)


if __name__ == "__main__":
	print(solution())

