
"""simple docstring"""

import os
from dataclasses import dataclass, field
from io import BytesIO
from typing import TYPE_CHECKING, Any, ClassVar, Dict, Optional, Union

import numpy as np
import pyarrow as pa

from .. import config
from ..download.streaming_download_manager import xopen, xsplitext
from ..table import array_cast
from ..utils.py_utils import no_op_if_value_is_null, string_to_dict


if TYPE_CHECKING:
     from .features import FeatureType


UpperCamelCase     :    Optional[Any]       =			False, False, False

@dataclass
class __lowerCAmelCase		:
     lowercase						       =						None
     lowercase						       =						True
     lowercase						       =						True
     lowercase						       =						None
     # Automatically constructed
     lowercase						       =						"dict"
     lowercase						       =						pa.struct({"bytes": pa.binary(), "path": pa.string()}      )
     lowercase						       =						field(default="Audio"      ,  init=__SCREAMING_SNAKE_CASE      ,  repr=__SCREAMING_SNAKE_CASE      )





     def __call__(     self				):

      '''simple docstring'''




      return self.pa_type





     def 						UpperCAmelCase (     self     ,					__UpperCAmelCase				):

      '''simple docstring'''




      try:
       import soundfile as sf  # soundfile is a dependency of librosa, needed to decode audio files.
      except ImportError as err:
       raise ImportError('To support encoding audio data, please install \'soundfile\'.'				) from err
      if isinstance(__UpperCAmelCase     ,					__UpperCAmelCase				):
       return {"bytes": None, "path": value}
      elif isinstance(__UpperCAmelCase     ,					__UpperCAmelCase				):
       return {"bytes": value, "path": None}
      elif "array" in value:
       # convert the audio array to wav bytes
       __UpperCamelCase      =	BytesIO()
       sf.write(__UpperCAmelCase     ,					value['array']     ,					value['sampling_rate']     ,					format='wav'				)
       return {"bytes": buffer.getvalue(), "path": None}
      elif value.get('path'				) is not None and os.path.isfile(value['path']				):
       # we set "bytes": None to not duplicate the data if they're already available locally
       if value["path"].endswith('pcm'				):
        # "PCM" only has raw audio bytes
        if value.get('sampling_rate'				) is None:
         # At least, If you want to convert "PCM-byte" to "WAV-byte", you have to know sampling rate
         raise KeyError('To use PCM files, please specify a \'sampling_rate\' in Audio object'				)
        if value.get('bytes'				):
         # If we already had PCM-byte, we don`t have to make "read file, make bytes" (just use it!)
         __UpperCamelCase      =	np.frombuffer(value['bytes']     ,					dtype=np.intaa				).astype(np.floataa				) / 3_2767
        else:
         __UpperCamelCase      =	np.memmap(value['path']     ,					dtype='h'     ,					mode='r'				).astype(np.floataa				) / 3_2767

        __UpperCamelCase      =	BytesIO(bytes()				)
        sf.write(__UpperCAmelCase     ,					__UpperCAmelCase     ,					value['sampling_rate']     ,					format='wav'				)
        return {"bytes": buffer.getvalue(), "path": None}
       else:
        return {"bytes": None, "path": value.get('path'				)}
      elif value.get('bytes'				) is not None or value.get('path'				) is not None:
       # store the audio bytes, and path is used to infer the audio format using the file extension
       return {"bytes": value.get('bytes'				), "path": value.get('path'				)}
      else:
       raise ValueError(
           F'An audio sample should have one of \'path\' or \'bytes\' but they are missing or None in {value}.'				)





     def 						UpperCAmelCase (     self     ,					__UpperCAmelCase     ,					__UpperCAmelCase = None				):

      '''simple docstring'''




      if not self.decode:
       raise RuntimeError('Decoding is disabled for this feature. Please use Audio(decode=True) instead.'				)

      __UpperCamelCase  ,     __UpperCamelCase      =	(value['path'], BytesIO(value['bytes']				)) if value['bytes'] is not None else (value['path'], None)
      if path is None and file is None:
       raise ValueError(F'An audio sample should have one of \'path\' or \'bytes\' but both are None in {value}.'				)

      try:
       import librosa
       import soundfile as sf
      except ImportError as err:
       raise ImportError('To support decoding audio files, please install \'librosa\' and \'soundfile\'.'				) from err

      __UpperCamelCase      =	xsplitext(__UpperCAmelCase				)[1][1:].lower() if path is not None else None
      if not config.IS_OPUS_SUPPORTED and audio_format == "opus":
       raise RuntimeError(
           'Decoding \'opus\' files requires system library \'libsndfile\'>=1.0.31, '
           'You can try to update `soundfile` python library: `pip install "soundfile>=0.12.1"`. '				)
      elif not config.IS_MP3_SUPPORTED and audio_format == "mp3":
       raise RuntimeError(
           'Decoding \'mp3\' files requires system library \'libsndfile\'>=1.1.0, '
           'You can try to update `soundfile` python library: `pip install "soundfile>=0.12.1"`. '				)

      if file is None:
       __UpperCamelCase      =	token_per_repo_id or {}
       __UpperCamelCase      =	path.split('::'				)[-1]
       try:
        __UpperCamelCase      =	string_to_dict(__UpperCAmelCase     ,					config.HUB_DATASETS_URL				)['repo_id']
        __UpperCamelCase      =	token_per_repo_id[repo_id]
       except (ValueError, KeyError):
        __UpperCamelCase      =	None

       with xopen(__UpperCAmelCase     ,					'rb'     ,					use_auth_token=__UpperCAmelCase				) as f:
        __UpperCamelCase  ,     __UpperCamelCase      =	sf.read(__UpperCAmelCase				)

      else:
       __UpperCamelCase  ,     __UpperCamelCase      =	sf.read(__UpperCAmelCase				)

      __UpperCamelCase      =	array.T
      if self.mono:
       __UpperCamelCase      =	librosa.to_mono(__UpperCAmelCase				)
      if self.sampling_rate and self.sampling_rate != sampling_rate:
       __UpperCamelCase      =	librosa.resample(__UpperCAmelCase     ,					orig_sr=__UpperCAmelCase     ,					target_sr=self.sampling_rate				)
       __UpperCamelCase      =	self.sampling_rate

      return {"path": path, "array": array, "sampling_rate": sampling_rate}





     def 						UpperCAmelCase (     self				):

      '''simple docstring'''




      from .features import Value

      if self.decode:
       raise ValueError('Cannot flatten a decoded Audio feature.'				)
      return {
          "bytes": Value('binary'				),
          "path": Value('string'				),
      }





     def 						UpperCAmelCase (     self     ,					__UpperCAmelCase				):

      '''simple docstring'''




      if pa.types.is_string(storage.type				):
       __UpperCamelCase      =	pa.array([None] * len(__UpperCAmelCase				)     ,					type=pa.binary()				)
       __UpperCamelCase      =	pa.StructArray.from_arrays([bytes_array, storage]     ,					['bytes', 'path']     ,					mask=storage.is_null()				)
      elif pa.types.is_binary(storage.type				):
       __UpperCamelCase      =	pa.array([None] * len(__UpperCAmelCase				)     ,					type=pa.string()				)
       __UpperCamelCase      =	pa.StructArray.from_arrays([storage, path_array]     ,					['bytes', 'path']     ,					mask=storage.is_null()				)
      elif pa.types.is_struct(storage.type				) and storage.type.get_all_field_indices('array'				):
       __UpperCamelCase      =	pa.array([Audio().encode_example(__UpperCAmelCase				) if x is not None else None for x in storage.to_pylist()]				)
      elif pa.types.is_struct(storage.type				):
       if storage.type.get_field_index('bytes'				) >= 0:
        __UpperCamelCase      =	storage.field('bytes'				)
       else:
        __UpperCamelCase      =	pa.array([None] * len(__UpperCAmelCase				)     ,					type=pa.binary()				)
       if storage.type.get_field_index('path'				) >= 0:
        __UpperCamelCase      =	storage.field('path'				)
       else:
        __UpperCamelCase      =	pa.array([None] * len(__UpperCAmelCase				)     ,					type=pa.string()				)
       __UpperCamelCase      =	pa.StructArray.from_arrays([bytes_array, path_array]     ,					['bytes', 'path']     ,					mask=storage.is_null()				)
      return array_cast(__UpperCAmelCase     ,					self.pa_type				)







     def 						UpperCAmelCase (     self     ,					__UpperCAmelCase				):

      '''simple docstring'''




      @no_op_if_value_is_null
      def path_to_bytes(__UpperCAmelCase				):
       with xopen(__UpperCAmelCase     ,					'rb'				) as f:
        __UpperCamelCase      =	f.read()
       return bytes_

      __UpperCamelCase      =	pa.array(
          [
              (path_to_bytes(x['path']				) if x['bytes'] is None else x['bytes']) if x is not None else None
              for x in storage.to_pylist()
          ]     ,					type=pa.binary()     ,					)
      __UpperCamelCase      =	pa.array(
          [os.path.basename(__UpperCAmelCase				) if path is not None else None for path in storage.field('path'				).to_pylist()]     ,					type=pa.string()     ,					)
      __UpperCamelCase      =	pa.StructArray.from_arrays([bytes_array, path_array]     ,					['bytes', 'path']     ,					mask=bytes_array.is_null()				)
      return array_cast(__UpperCAmelCase     ,					self.pa_type				)





"""simple docstring"""

import heapq as hq
import math
from collections.abc import Iterator

class __lowerCAmelCase		:





     def __init__(     self     ,					__UpperCAmelCase				):

      '''simple docstring'''




      __UpperCamelCase      =	str(id_				)
      __UpperCamelCase      =	None
      __UpperCamelCase      =	None
      __UpperCamelCase      =	[]
      __UpperCamelCase      =	{}  # {vertex:distance}





     def __lt__(     self     ,					__UpperCAmelCase				):

      '''simple docstring'''




      return self.key < other.key





     def __repr__(     self				):

      '''simple docstring'''




      return self.id





     def 						UpperCAmelCase (     self     ,					__UpperCAmelCase				):

      '''simple docstring'''




      self.neighbors.append(__UpperCAmelCase				)







     def 						UpperCAmelCase (     self     ,					__UpperCAmelCase     ,					__UpperCAmelCase				):

      '''simple docstring'''




      __UpperCamelCase      =	weight






def 							A						(    snake_case				:List[Any]    , snake_case				:Dict    , snake_case				:Any    , snake_case				:str		)				->     List[str]:
 # add the neighbors:
 graph[a - 1].add_neighbor(graph[b - 1]		)
 graph[b - 1].add_neighbor(graph[a - 1]		)
 # add the edges:
 graph[a - 1].add_edge(graph[b - 1]    , snake_case		)
 graph[b - 1].add_edge(graph[a - 1]    , snake_case		)






def 							A						(    snake_case				:list    , snake_case				:Vertex		)				->     list:
 __UpperCamelCase      =	[]
 for u in graph:
  __UpperCamelCase      =	math.inf
  __UpperCamelCase      =	None
 __UpperCamelCase      =	0
 __UpperCamelCase      =	graph[:]
 while q:
  __UpperCamelCase      =	min(snake_case		)
  q.remove(snake_case		)
  for v in u.neighbors:
   if (v in q) and (u.edges[v.id] < v.key):
    __UpperCamelCase      =	u
    __UpperCamelCase      =	u.edges[v.id]
 for i in range(1    , len(snake_case		)		):
  a.append((int(graph[i].id		) + 1, int(graph[i].pi.id		) + 1)		)
 return a






def 							A						(    snake_case				:list    , snake_case				:Vertex		)				->     Iterator[tuple]:
 for u in graph:
  __UpperCamelCase      =	math.inf
  __UpperCamelCase      =	None
 __UpperCamelCase      =	0

 __UpperCamelCase      =	list(snake_case		)
 hq.heapify(snake_case		)

 while h:
  __UpperCamelCase      =	hq.heappop(snake_case		)
  for v in u.neighbors:
   if (v in h) and (u.edges[v.id] < v.key):
    __UpperCamelCase      =	u
    __UpperCamelCase      =	u.edges[v.id]
    hq.heapify(snake_case		)

 for i in range(1    , len(snake_case		)		):
  yield (int(graph[i].id		) + 1, int(graph[i].pi.id		) + 1)






def 							A						(    )				->     None:
 pass


if __name__ == "__main__":
      import doctest

      doctest.testmod()



