

import tempfile
import unittest

import numpy as np

from diffusers import (
    DDIMScheduler,
    DPMSolverMultistepScheduler,
    EulerAncestralDiscreteScheduler,
    EulerDiscreteScheduler,
    LMSDiscreteScheduler,
    OnnxStableDiffusionPipeline,
    PNDMScheduler,
)
from diffusers.utils.testing_utils import is_onnx_available, nightly, require_onnxruntime, require_torch_gpu

from ..test_pipelines_onnx_common import OnnxPipelineTesterMixin


if is_onnx_available():
     import onnxruntime as ort





class 				__lowerCAmelCase  (      a__    ,    unittest.TestCase							):
  _a		    =						"hf-internal-testing/tiny-random-OnnxStableDiffusionPipeline"




  def 						A__  (       self							,     lowerCAmelCase=0      )						->				Tuple:
        '''simple docstring'''






        _lowercase			 =np.random.RandomState(lowerCamelCase_      )
        _lowercase			 ={
            'prompt': 'A painting of a squirrel eating a burger',
            'generator': generator,
            'num_inference_steps': 2,
            'guidance_scale': 7.5,
            'output_type': 'numpy',
        }
        return inputs




  def 						A__  (       self      )						->				Tuple:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =pipe(**lowerCamelCase_      ).images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 128, 128, 3)
        _lowercase			 =np.array([0.65072, 0.58492, 0.48219, 0.55521, 0.53180, 0.55939, 0.50697, 0.39800, 0.46455]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2




  def 						A__  (       self      )						->				str:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        _lowercase			 =PNDMScheduler.from_config(pipe.scheduler.config							,     skip_prk_steps=lowerCamelCase_      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =pipe(**lowerCamelCase_      ).images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 128, 128, 3)
        _lowercase			 =np.array([0.65863, 0.59425, 0.49326, 0.56313, 0.53875, 0.56627, 0.51065, 0.39777, 0.46330]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2




  def 						A__  (       self      )						->				int:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        _lowercase			 =LMSDiscreteScheduler.from_config(pipe.scheduler.config      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =pipe(**lowerCamelCase_      ).images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 128, 128, 3)
        _lowercase			 =np.array([0.53755, 0.60786, 0.47402, 0.49488, 0.51869, 0.49819, 0.47985, 0.38957, 0.44279]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2




  def 						A__  (       self      )						->				Optional[Any]:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        _lowercase			 =EulerDiscreteScheduler.from_config(pipe.scheduler.config      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =pipe(**lowerCamelCase_      ).images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 128, 128, 3)
        _lowercase			 =np.array([0.53755, 0.60786, 0.47402, 0.49488, 0.51869, 0.49819, 0.47985, 0.38957, 0.44279]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2




  def 						A__  (       self      )						->				Optional[Any]:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        _lowercase			 =EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =pipe(**lowerCamelCase_      ).images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 128, 128, 3)
        _lowercase			 =np.array([0.53817, 0.60812, 0.47384, 0.49530, 0.51894, 0.49814, 0.47984, 0.38958, 0.44271]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2




  def 						A__  (       self      )						->				Dict:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        _lowercase			 =DPMSolverMultistepScheduler.from_config(pipe.scheduler.config      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =pipe(**lowerCamelCase_      ).images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 128, 128, 3)
        _lowercase			 =np.array([0.53895, 0.60808, 0.47933, 0.49608, 0.51886, 0.49950, 0.48053, 0.38957, 0.44200]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2




  def 						A__  (       self      )						->				Optional[Any]:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =3 * [inputs['prompt']]

        # forward
        _lowercase			 =pipe(**lowerCamelCase_      )
        _lowercase			 =output.images[0, -3:, -3:, -1]

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =3 * [inputs.pop('prompt'      )]

        _lowercase			 =pipe.tokenizer(
            lowerCamelCase_							,     padding='max_length'							,     max_length=pipe.tokenizer.model_max_length							,     truncation=lowerCamelCase_							,     return_tensors='np'							,     )
        _lowercase			 =text_inputs['input_ids']

        _lowercase			 =pipe.text_encoder(input_ids=text_inputs.astype(np.intaa      )      )[0]

        _lowercase			 =prompt_embeds

        # forward
        _lowercase			 =pipe(**lowerCamelCase_      )
        _lowercase			 =output.images[0, -3:, -3:, -1]

        assert np.abs(image_slice_a.flatten() - image_slice_a.flatten()      ).max() < 1e-4




  def 						A__  (       self      )						->				List[str]:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint							,     provider='CPUExecutionProvider'      )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =3 * ['this is a negative prompt']
        _lowercase			 =negative_prompt
        _lowercase			 =3 * [inputs['prompt']]

        # forward
        _lowercase			 =pipe(**lowerCamelCase_      )
        _lowercase			 =output.images[0, -3:, -3:, -1]

        _lowercase			 =self.get_dummy_inputs()
        _lowercase			 =3 * [inputs.pop('prompt'      )]

        _lowercase			 =[]
        for p in [prompt, negative_prompt]:
              _lowercase			 =pipe.tokenizer(
                  lowerCamelCase_							,     padding='max_length'							,     max_length=pipe.tokenizer.model_max_length							,     truncation=lowerCamelCase_							,     return_tensors='np'							,     )
              _lowercase			 =text_inputs['input_ids']

              embeds.append(pipe.text_encoder(input_ids=text_inputs.astype(np.intaa      )      )[0]      )

        _lowercase , _lowercase			 =embeds

        # forward
        _lowercase			 =pipe(**lowerCamelCase_      )
        _lowercase			 =output.images[0, -3:, -3:, -1]

        assert np.abs(image_slice_a.flatten() - image_slice_a.flatten()      ).max() < 1e-4





@nightly
@require_onnxruntime
@require_torch_gpu
class 				__lowerCAmelCase  (      unittest.TestCase							):




  @property
  def 						A__  (       self      )						->				Tuple:
        '''simple docstring'''






        return (
            "CUDAExecutionProvider",
            {
                "gpu_mem_limit": "15000000000",  # 15GB
                "arena_extend_strategy": "kSameAsRequested",
            },
        )




  @property
  def 						A__  (       self      )						->				Optional[Any]:
        '''simple docstring'''






        _lowercase			 =ort.SessionOptions()
        _lowercase			 =False
        return options




  def 						A__  (       self      )						->				List[str]:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(
            'CompVis/stable-diffusion-v1-4'							,     revision='onnx'							,     safety_checker=lowerCamelCase_							,     feature_extractor=lowerCamelCase_							,     provider=self.gpu_provider							,     sess_options=self.gpu_options							,     )
        sd_pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 ='A painting of a squirrel eating a burger'
        np.random.seed(0      )
        _lowercase			 =sd_pipe([prompt]							,     guidance_scale=6.0							,     num_inference_steps=10							,     output_type='np'      )
        _lowercase			 =output.images

        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 512, 512, 3)
        _lowercase			 =np.array([0.0452, 0.0390, 0.0087, 0.0350, 0.0617, 0.0364, 0.0544, 0.0523, 0.0720]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-3




  def 						A__  (       self      )						->				Optional[Any]:
        '''simple docstring'''






        _lowercase			 =DDIMScheduler.from_pretrained(
            'runwayml/stable-diffusion-v1-5'							,     subfolder='scheduler'							,     revision='onnx'      )
        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(
            'runwayml/stable-diffusion-v1-5'							,     revision='onnx'							,     scheduler=lowerCamelCase_							,     safety_checker=lowerCamelCase_							,     feature_extractor=lowerCamelCase_							,     provider=self.gpu_provider							,     sess_options=self.gpu_options							,     )
        sd_pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 ='open neural network exchange'
        _lowercase			 =np.random.RandomState(0      )
        _lowercase			 =sd_pipe([prompt]							,     guidance_scale=7.5							,     num_inference_steps=10							,     generator=lowerCamelCase_							,     output_type='np'      )
        _lowercase			 =output.images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 512, 512, 3)
        _lowercase			 =np.array([0.2867, 0.1974, 0.1481, 0.7294, 0.7251, 0.6667, 0.4194, 0.5642, 0.6486]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-3




  def 						A__  (       self      )						->				Union[str, Any]:
        '''simple docstring'''






        _lowercase			 =LMSDiscreteScheduler.from_pretrained(
            'runwayml/stable-diffusion-v1-5'							,     subfolder='scheduler'							,     revision='onnx'      )
        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(
            'runwayml/stable-diffusion-v1-5'							,     revision='onnx'							,     scheduler=lowerCamelCase_							,     safety_checker=lowerCamelCase_							,     feature_extractor=lowerCamelCase_							,     provider=self.gpu_provider							,     sess_options=self.gpu_options							,     )
        sd_pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 ='open neural network exchange'
        _lowercase			 =np.random.RandomState(0      )
        _lowercase			 =sd_pipe([prompt]							,     guidance_scale=7.5							,     num_inference_steps=10							,     generator=lowerCamelCase_							,     output_type='np'      )
        _lowercase			 =output.images
        _lowercase			 =image[0, -3:, -3:, -1]

        assert image.shape == (1, 512, 512, 3)
        _lowercase			 =np.array([0.2306, 0.1959, 0.1593, 0.6549, 0.6394, 0.5408, 0.5065, 0.6010, 0.6161]      )

        assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-3




  def 						A__  (       self      )						->				Dict:
        '''simple docstring'''






        _lowercase			 =0

        def test_callback_fn(lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase      ) -> None:
              _lowercase			 =True
              nonlocal number_of_steps
              number_of_steps += 1
              if step == 0:
                    assert latents.shape == (1, 4, 64, 64)
                    _lowercase			 =latents[0, -3:, -3:, -1]
                    _lowercase			 =np.array(
                        [-0.6772, -0.3835, -1.2456, 0.1905, -1.0974, 0.6967, -1.9353, 0.0178, 1.0167]      )

                    assert np.abs(latents_slice.flatten() - expected_slice      ).max() < 1e-3
              elif step == 5:
                    assert latents.shape == (1, 4, 64, 64)
                    _lowercase			 =latents[0, -3:, -3:, -1]
                    _lowercase			 =np.array(
                        [-0.3351, 0.2241, -0.1837, -0.2325, -0.6577, 0.3393, -0.0241, 0.5899, 1.3875]      )

                    assert np.abs(latents_slice.flatten() - expected_slice      ).max() < 1e-3

        _lowercase			 =False

        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(
            'runwayml/stable-diffusion-v1-5'							,     revision='onnx'							,     safety_checker=lowerCamelCase_							,     feature_extractor=lowerCamelCase_							,     provider=self.gpu_provider							,     sess_options=self.gpu_options							,     )
        pipe.set_progress_bar_config(disable=lowerCamelCase_      )

        _lowercase			 ='Andromeda galaxy in a bottle'

        _lowercase			 =np.random.RandomState(0      )
        pipe(
            prompt=lowerCamelCase_							,     num_inference_steps=5							,     guidance_scale=7.5							,     generator=lowerCamelCase_							,     callback=lowerCamelCase_							,     callback_steps=1							,     )
        assert test_callback_fn.has_been_called
        assert number_of_steps == 6




  def 						A__  (       self      )						->				int:
        '''simple docstring'''






        _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(
            'runwayml/stable-diffusion-v1-5'							,     revision='onnx'							,     safety_checker=lowerCamelCase_							,     feature_extractor=lowerCamelCase_							,     provider=self.gpu_provider							,     sess_options=self.gpu_options							,     )
        assert isinstance(lowerCamelCase_							,     lowerCamelCase_      )
        assert pipe.safety_checker is None

        _lowercase			 =pipe('example prompt'							,     num_inference_steps=2      ).images[0]
        assert image is not None

        # check that there's no error when saving a pipeline with one of the models being None
        with tempfile.TemporaryDirectory() as tmpdirname:
              pipe.save_pretrained(lowerCamelCase_      )
              _lowercase			 =OnnxStableDiffusionPipeline.from_pretrained(lowerCamelCase_      )

        # sanity check that the pipeline still works
        assert pipe.safety_checker is None
        _lowercase			 =pipe('example prompt'							,     num_inference_steps=2      ).images[0]
        assert image is not None





import os
import re
import shutil
from argparse import ArgumentParser, Namespace

from datasets.commands import BaseDatasetsCLICommand
from datasets.utils.logging import get_logger


lowercase_             =     '<<<<<<< This should probably be modified because it mentions: '

lowercase_             =     '=======\n>>>>>>>\n'

lowercase_             =     [
    'TextEncoderConfig',
    'ByteTextEncoder',
    'SubwordTextEncoder',
    'encoder_config',
    'maybe_build_from_corpus',
    'manual_dir',
]

lowercase_             =     [
    # (pattern, replacement)
    # Order is important here for some replacements
    (R'tfds\.core', R'datasets'),
    (R'tf\.io\.gfile\.GFile', R'open'),
    (R'tf\.([\w\d]+)', R'datasets.Value(\'\1\')'),
    (R'tfds\.features\.Text\(\)', R'datasets.Value(\'string\')'),
    (R'tfds\.features\.Text\(', R'datasets.Value(\'string\'),'),
    (R'features\s*=\s*tfds.features.FeaturesDict\(', R'features=datasets.Features('),
    (R'tfds\.features\.FeaturesDict\(', R'dict('),
    (R'The TensorFlow Datasets Authors', R'The TensorFlow Datasets Authors and the HuggingFace Datasets Authors'),
    (R'tfds\.', R'datasets.'),
    (R'dl_manager\.manual_dir', R'self.config.data_dir'),
    (R'self\.builder_config', R'self.config'),
]
def   a   (    A__			:     Namespace  )					->   Any:





      """simple docstring"""



      return ConvertCommand(args.tfds_path   ,     args.datasets_directory  )







class 				__lowerCAmelCase  (      SCREAMING_SNAKE_CASE							):




  @staticmethod
  def 						A__  (       lowerCAmelCase      )						->				Tuple:
        '''simple docstring'''






        _lowercase			 =parser.add_parser(
            'convert'							,     help='Convert a TensorFlow Datasets dataset to a HuggingFace Datasets dataset.'							,     )
        train_parser.add_argument(
            '--tfds_path'							,     type=lowerCAmelCase							,     required=lowerCAmelCase							,     help='Path to a TensorFlow Datasets folder to convert or a single tfds file to convert.'							,     )
        train_parser.add_argument(
            '--datasets_directory'							,     type=lowerCAmelCase							,     required=lowerCAmelCase							,     help='Path to the HuggingFace Datasets folder.'      )
        train_parser.set_defaults(func=lowerCAmelCase      )




  def __init__(       self							,     lowerCAmelCase							,     lowerCAmelCase							,     *lowerCAmelCase      )						->				List[Any]:
        '''simple docstring'''






        _lowercase			 =get_logger('datasets-cli/converting'      )

        _lowercase			 =tfds_path
        _lowercase			 =datasets_directory




  def 						A__  (       self      )						->				List[str]:
        '''simple docstring'''






        if os.path.isdir(self._tfds_path      ):
              _lowercase			 =os.path.abspath(self._tfds_path      )
        elif os.path.isfile(self._tfds_path      ):
              _lowercase			 =os.path.dirname(self._tfds_path      )
        else:
              raise ValueError('--tfds_path is neither a directory nor a file. Please check path.'      )

        _lowercase			 =os.path.abspath(self._datasets_directory      )

        self._logger.info(F'''Converting datasets from {abs_tfds_path} to {abs_datasets_path}'''      )

        _lowercase			 =[]
        _lowercase			 =[]
        _lowercase			 ={}

        if os.path.isdir(self._tfds_path      ):
              _lowercase			 =os.listdir(lowerCAmelCase      )
        else:
              _lowercase			 =[os.path.basename(self._tfds_path      )]

        for f_name in file_names:
              self._logger.info(F'''Looking at file {f_name}'''      )
              _lowercase			 =os.path.join(lowerCAmelCase							,     lowerCAmelCase      )
              _lowercase			 =os.path.join(lowerCAmelCase							,     lowerCAmelCase      )

              if not os.path.isfile(lowerCAmelCase      ) or "__init__" in f_name or "_test" in f_name or ".py" not in f_name:
                    self._logger.info('Skipping file'      )
                    continue

              with open(lowerCAmelCase							,     encoding='utf-8'      ) as f:
                    _lowercase			 =f.readlines()

              _lowercase			 =[]
              _lowercase			 =False
              _lowercase			 =False
              _lowercase			 =[]
              for line in lines:
                    _lowercase			 =line

                    # Convert imports
                    if "import tensorflow.compat.v2 as tf" in out_line:
                          continue
                    elif "@tfds.core" in out_line:
                          continue
                    elif "builder=self" in out_line:
                          continue
                    elif "import tensorflow_datasets.public_api as tfds" in out_line:
                          _lowercase			 ='import datasets\n'
                    elif "import tensorflow" in out_line:
                          # order is important here
                          _lowercase			 =''
                          continue
                    elif "from absl import logging" in out_line:
                          _lowercase			 ='from datasets import logging\n'
                    elif "getLogger" in out_line:
                          _lowercase			 =out_line.replace('getLogger'							,     'get_logger'      )
                    elif any(expression in out_line for expression in TO_HIGHLIGHT      ):
                          _lowercase			 =True
                          _lowercase			 =list(filter(lambda lowerCAmelCase      : e in out_line							,     lowerCAmelCase      )      )
                          out_lines.append(HIGHLIGHT_MESSAGE_PRE + str(lowerCAmelCase      ) + '\n'      )
                          out_lines.append(lowerCAmelCase      )
                          out_lines.append(lowerCAmelCase      )
                          continue
                    else:
                          for pattern, replacement in TO_CONVERT:
                                _lowercase			 =re.sub(lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase      )

                # Take care of saving utilities (to later move them together with main script)
                    if "tensorflow_datasets" in out_line:
                          _lowercase			 =re.match(R'from\stensorflow_datasets.*import\s([^\.\r\n]+)'							,     lowerCAmelCase      )
                          tfds_imports.extend(imp.strip() for imp in match.group(1      ).split(','      )      )
                          _lowercase			 ='from . import ' + match.group(1      )

                    # Check we have not forget anything
                    if "tf." in out_line or "tfds." in out_line or "tensorflow_datasets" in out_line:
                          raise ValueError(F'''Error converting {out_line.strip()}'''      )

                    if "GeneratorBasedBuilder" in out_line or "BeamBasedBuilder" in out_line:
                          _lowercase			 =True
                    out_lines.append(lowerCAmelCase      )

              if is_builder or "wmt" in f_name:
                    # We create a new directory for each dataset
                    _lowercase			 =f_name.replace('.py'							,     ''      )
                    _lowercase			 =os.path.join(lowerCAmelCase							,     lowerCAmelCase      )
                    _lowercase			 =os.path.join(lowerCAmelCase							,     lowerCAmelCase      )
                    os.makedirs(lowerCAmelCase							,     exist_ok=lowerCAmelCase      )
                    self._logger.info(F'''Adding directory {output_dir}'''      )
                    imports_to_builder_map.update({imp: output_dir for imp in tfds_imports}      )
              else:
                    # Utilities will be moved at the end
                    utils_files.append(lowerCAmelCase      )

              if needs_manual_update:
                    with_manual_update.append(lowerCAmelCase      )

              with open(lowerCAmelCase							,     'w'							,     encoding='utf-8'      ) as f:
                    f.writelines(lowerCAmelCase      )
              self._logger.info(F'''Converted in {output_file}'''      )

        for utils_file in utils_files:
              try:
                    _lowercase			 =os.path.basename(lowerCAmelCase      )
                    _lowercase			 =imports_to_builder_map[f_name.replace('.py'							,     ''      )]
                    self._logger.info(F'''Moving {dest_folder} to {utils_file}'''      )
                    shutil.copy(lowerCAmelCase							,     lowerCAmelCase      )
              except KeyError:
                    self._logger.error(F'''Cannot find destination folder for {utils_file}. Please copy manually.'''      )

        if with_manual_update:
              for file_path in with_manual_update:
                    self._logger.warning(
                        F'''You need to manually update file {file_path} to remove configurations using \'TextEncoderConfig\'.'''      )


