




# This model implementation is heavily based on:

import gc
import random
import tempfile
import unittest

import numpy as np
import torch
from PIL import Image
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    ControlNetModel,
    DDIMScheduler,
    StableDiffusionControlNetInpaintPipeline,
    UNetaDConditionModel,
)
from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion_controlnet import MultiControlNetModel
from diffusers.utils import floats_tensor, load_image, load_numpy, randn_tensor, slow, torch_device
from diffusers.utils.import_utils import is_xformers_available
from diffusers.utils.testing_utils import enable_full_determinism, require_torch_gpu

from ..pipeline_params import (
    TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS,
    TEXT_GUIDED_IMAGE_INPAINTING_PARAMS,
    TEXT_TO_IMAGE_IMAGE_PARAMS,
)
from ..test_pipelines_common import (
    PipelineKarrasSchedulerTesterMixin,
    PipelineLatentTesterMixin,
    PipelineTesterMixin,
)


enable_full_determinism()



class       lowercase_		(_a       ,  _a       ,  _a       ,  unittest.TestCase   ):
						lowerCAmelCase__ 			=StableDiffusionControlNetInpaintPipeline
						lowerCAmelCase__ 			=TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
						lowerCAmelCase__ 			=TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS
						lowerCAmelCase__ 			=frozenset({"control_image"}   )  # skip `image` and `mask` for now, only test for control_image
						lowerCAmelCase__ 			=TEXT_TO_IMAGE_IMAGE_PARAMS



						def   __a				( self  :      Tuple     ):

								"""simple docstring"""

								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       UNetaDConditionModel(
								    block_out_channels=(32, 64)				,       layers_per_block=2				,       sample_size=32				,       in_channels=9				,       out_channels=4				,       down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')				,       up_block_types=('CrossAttnUpBlock2D', 'UpBlock2D')				,       cross_attention_dim=32				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       ControlNetModel(
								    block_out_channels=(32, 64)				,       layers_per_block=2				,       in_channels=4				,       down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')				,       cross_attention_dim=32				,       conditioning_embedding_out_channels=(16, 32)				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       DDIMScheduler(
								    beta_start=0.0_00_85				,       beta_end=0.0_12				,       beta_schedule='scaled_linear'				,       clip_sample=snake_case__				,       set_alpha_to_one=snake_case__				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       AutoencoderKL(
								    block_out_channels=[32, 64]				,       in_channels=3				,       out_channels=3				,       down_block_types=['DownEncoderBlock2D', 'DownEncoderBlock2D']				,       up_block_types=['UpDecoderBlock2D', 'UpDecoderBlock2D']				,       latent_channels=4				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       CLIPTextConfig(
								    bos_token_id=0				,       eos_token_id=2				,       hidden_size=32				,       intermediate_size=37				,       layer_norm_eps=1e-05				,       num_attention_heads=4				,       num_hidden_layers=5				,       pad_token_id=1				,       vocab_size=10_00				,       )
								SCREAMING_SNAKE_CASE_							=       CLIPTextModel(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       CLIPTokenizer.from_pretrained('hf-internal-testing/tiny-random-clip'     )

								SCREAMING_SNAKE_CASE_							=       {
								    'unet': unet,
								    'controlnet': controlnet,
								    'scheduler': scheduler,
								    'vae': vae,
								    'text_encoder': text_encoder,
								    'tokenizer': tokenizer,
								    'safety_checker': None,
								    'feature_extractor': None,
								}
								return components



						def   __a				( self  :      Tuple				,       snake_case__  :      Optional[Any]				,       snake_case__  :      Dict=0     ):

								"""simple docstring"""

								if str(snake_case__     ).startswith('mps'     ):
										SCREAMING_SNAKE_CASE_							=       torch.manual_seed(snake_case__     )
								else:
										SCREAMING_SNAKE_CASE_							=       torch.Generator(device=snake_case__     ).manual_seed(snake_case__     )

								SCREAMING_SNAKE_CASE_							=       2
								SCREAMING_SNAKE_CASE_							=       randn_tensor(
								    (1, 3, 32 * controlnet_embedder_scale_factor, 32 * controlnet_embedder_scale_factor)				,       generator=snake_case__				,       device=torch.device(snake_case__     )				,       )
								SCREAMING_SNAKE_CASE_							=       floats_tensor((1, 3, 32, 32)				,       rng=random.Random(snake_case__     )     ).to(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       init_image.cpu().permute(0				,       2				,       3				,       1     )[0]

								SCREAMING_SNAKE_CASE_							=       Image.fromarray(np.uinta(snake_case__     )     ).convert('RGB'     ).resize((64, 64)     )
								SCREAMING_SNAKE_CASE_							=       Image.fromarray(np.uinta(init_image + 4     )     ).convert('RGB'     ).resize((64, 64)     )

								SCREAMING_SNAKE_CASE_							=       {
								    'prompt': 'A painting of a squirrel eating a burger',
								    'generator': generator,
								    'num_inference_steps': 2,
								    'guidance_scale': 6.0,
								    'output_type': 'numpy',
								    'image': image,
								    'mask_image': mask_image,
								    'control_image': control_image,
								}

								return inputs



						def   __a				( self  :      Any     ):

								"""simple docstring"""

								return self._test_attention_slicing_forward_pass(expected_max_diff=2e-3     )



						@unittest.skipIf(
						    torch_device != 'cuda' or not is_xformers_available()				,       reason='XFormers attention is only available with CUDA and `xformers` installed'				,       )
						def   __a				( self  :      List[Any]     ):

								"""simple docstring"""

								self._test_xformers_attention_forwardGenerator_pass(expected_max_diff=2e-3     )






						def   __a				( self  :      Any     ):

								"""simple docstring"""

								self._test_inference_batch_single_identical(expected_max_diff=2e-3     )



class       lowercase_		(_a   ):
						lowerCAmelCase__ 			=StableDiffusionControlNetInpaintPipeline
						lowerCAmelCase__ 			=TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
						lowerCAmelCase__ 			=TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS
						lowerCAmelCase__ 			=frozenset([]   )



						def   __a				( self  :      int     ):

								"""simple docstring"""

								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       UNetaDConditionModel(
								    block_out_channels=(32, 64)				,       layers_per_block=2				,       sample_size=32				,       in_channels=4				,       out_channels=4				,       down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')				,       up_block_types=('CrossAttnUpBlock2D', 'UpBlock2D')				,       cross_attention_dim=32				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       ControlNetModel(
								    block_out_channels=(32, 64)				,       layers_per_block=2				,       in_channels=4				,       down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')				,       cross_attention_dim=32				,       conditioning_embedding_out_channels=(16, 32)				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       DDIMScheduler(
								    beta_start=0.0_00_85				,       beta_end=0.0_12				,       beta_schedule='scaled_linear'				,       clip_sample=snake_case__				,       set_alpha_to_one=snake_case__				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       AutoencoderKL(
								    block_out_channels=[32, 64]				,       in_channels=3				,       out_channels=3				,       down_block_types=['DownEncoderBlock2D', 'DownEncoderBlock2D']				,       up_block_types=['UpDecoderBlock2D', 'UpDecoderBlock2D']				,       latent_channels=4				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       CLIPTextConfig(
								    bos_token_id=0				,       eos_token_id=2				,       hidden_size=32				,       intermediate_size=37				,       layer_norm_eps=1e-05				,       num_attention_heads=4				,       num_hidden_layers=5				,       pad_token_id=1				,       vocab_size=10_00				,       )
								SCREAMING_SNAKE_CASE_							=       CLIPTextModel(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       CLIPTokenizer.from_pretrained('hf-internal-testing/tiny-random-clip'     )

								SCREAMING_SNAKE_CASE_							=       {
								    'unet': unet,
								    'controlnet': controlnet,
								    'scheduler': scheduler,
								    'vae': vae,
								    'text_encoder': text_encoder,
								    'tokenizer': tokenizer,
								    'safety_checker': None,
								    'feature_extractor': None,
								}
								return components



class       lowercase_		(_a       ,  _a       ,  unittest.TestCase   ):
						lowerCAmelCase__ 			=StableDiffusionControlNetInpaintPipeline
						lowerCAmelCase__ 			=TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
						lowerCAmelCase__ 			=TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS



						def   __a				( self  :      Dict     ):

								"""simple docstring"""

								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       UNetaDConditionModel(
								    block_out_channels=(32, 64)				,       layers_per_block=2				,       sample_size=32				,       in_channels=9				,       out_channels=4				,       down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')				,       up_block_types=('CrossAttnUpBlock2D', 'UpBlock2D')				,       cross_attention_dim=32				,       )
								torch.manual_seed(0     )

								def init_weights(snake_case__  :      Optional[int]     ):
										if isinstance(snake_case__				,       torch.nn.Convad     ):
												torch.nn.init.normal(m.weight     )
												m.bias.data.fill_(1.0     )

								SCREAMING_SNAKE_CASE_							=       ControlNetModel(
								    block_out_channels=(32, 64)				,       layers_per_block=2				,       in_channels=4				,       down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')				,       cross_attention_dim=32				,       conditioning_embedding_out_channels=(16, 32)				,       )
								controlneta.controlnet_down_blocks.apply(snake_case__     )

								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       ControlNetModel(
								    block_out_channels=(32, 64)				,       layers_per_block=2				,       in_channels=4				,       down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')				,       cross_attention_dim=32				,       conditioning_embedding_out_channels=(16, 32)				,       )
								controlneta.controlnet_down_blocks.apply(snake_case__     )

								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       DDIMScheduler(
								    beta_start=0.0_00_85				,       beta_end=0.0_12				,       beta_schedule='scaled_linear'				,       clip_sample=snake_case__				,       set_alpha_to_one=snake_case__				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       AutoencoderKL(
								    block_out_channels=[32, 64]				,       in_channels=3				,       out_channels=3				,       down_block_types=['DownEncoderBlock2D', 'DownEncoderBlock2D']				,       up_block_types=['UpDecoderBlock2D', 'UpDecoderBlock2D']				,       latent_channels=4				,       )
								torch.manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       CLIPTextConfig(
								    bos_token_id=0				,       eos_token_id=2				,       hidden_size=32				,       intermediate_size=37				,       layer_norm_eps=1e-05				,       num_attention_heads=4				,       num_hidden_layers=5				,       pad_token_id=1				,       vocab_size=10_00				,       )
								SCREAMING_SNAKE_CASE_							=       CLIPTextModel(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       CLIPTokenizer.from_pretrained('hf-internal-testing/tiny-random-clip'     )

								SCREAMING_SNAKE_CASE_							=       MultiControlNetModel([controlneta, controlneta]     )

								SCREAMING_SNAKE_CASE_							=       {
								    'unet': unet,
								    'controlnet': controlnet,
								    'scheduler': scheduler,
								    'vae': vae,
								    'text_encoder': text_encoder,
								    'tokenizer': tokenizer,
								    'safety_checker': None,
								    'feature_extractor': None,
								}
								return components



						def   __a				( self  :      Optional[int]				,       snake_case__  :      Dict				,       snake_case__  :      Any=0     ):

								"""simple docstring"""

								if str(snake_case__     ).startswith('mps'     ):
										SCREAMING_SNAKE_CASE_							=       torch.manual_seed(snake_case__     )
								else:
										SCREAMING_SNAKE_CASE_							=       torch.Generator(device=snake_case__     ).manual_seed(snake_case__     )

								SCREAMING_SNAKE_CASE_							=       2

								SCREAMING_SNAKE_CASE_							=       [
								    randn_tensor(
								        (1, 3, 32 * controlnet_embedder_scale_factor, 32 * controlnet_embedder_scale_factor)				,       generator=snake_case__				,       device=torch.device(snake_case__     )				,       ),
								    randn_tensor(
								        (1, 3, 32 * controlnet_embedder_scale_factor, 32 * controlnet_embedder_scale_factor)				,       generator=snake_case__				,       device=torch.device(snake_case__     )				,       ),
								]
								SCREAMING_SNAKE_CASE_							=       floats_tensor((1, 3, 32, 32)				,       rng=random.Random(snake_case__     )     ).to(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       init_image.cpu().permute(0				,       2				,       3				,       1     )[0]

								SCREAMING_SNAKE_CASE_							=       Image.fromarray(np.uinta(snake_case__     )     ).convert('RGB'     ).resize((64, 64)     )
								SCREAMING_SNAKE_CASE_							=       Image.fromarray(np.uinta(init_image + 4     )     ).convert('RGB'     ).resize((64, 64)     )

								SCREAMING_SNAKE_CASE_							=       {
								    'prompt': 'A painting of a squirrel eating a burger',
								    'generator': generator,
								    'num_inference_steps': 2,
								    'guidance_scale': 6.0,
								    'output_type': 'numpy',
								    'image': image,
								    'mask_image': mask_image,
								    'control_image': control_image,
								}

								return inputs



						def   __a				( self  :      Optional[Any]     ):

								"""simple docstring"""

								SCREAMING_SNAKE_CASE_							=       self.get_dummy_components()
								SCREAMING_SNAKE_CASE_							=       self.pipeline_class(**snake_case__     )
								pipe.to(snake_case__     )

								SCREAMING_SNAKE_CASE_							=       10.0
								SCREAMING_SNAKE_CASE_							=       4

								SCREAMING_SNAKE_CASE_							=       self.get_dummy_inputs(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       steps
								SCREAMING_SNAKE_CASE_							=       scale
								SCREAMING_SNAKE_CASE_							=       pipe(**snake_case__     )[0]

								SCREAMING_SNAKE_CASE_							=       self.get_dummy_inputs(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       steps
								SCREAMING_SNAKE_CASE_							=       scale
								SCREAMING_SNAKE_CASE_							=       pipe(**snake_case__				,       control_guidance_start=0.1				,       control_guidance_end=0.2     )[0]

								SCREAMING_SNAKE_CASE_							=       self.get_dummy_inputs(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       steps
								SCREAMING_SNAKE_CASE_							=       scale
								SCREAMING_SNAKE_CASE_							=       pipe(**snake_case__				,       control_guidance_start=[0.1, 0.3]				,       control_guidance_end=[0.2, 0.7]     )[0]

								SCREAMING_SNAKE_CASE_							=       self.get_dummy_inputs(snake_case__     )
								SCREAMING_SNAKE_CASE_							=       steps
								SCREAMING_SNAKE_CASE_							=       scale
								SCREAMING_SNAKE_CASE_							=       pipe(**snake_case__				,       control_guidance_start=0.4				,       control_guidance_end=[0.5, 0.8]     )[0]

								# make sure that all outputs are different
								assert np.sum(np.abs(output_a - output_a     )     ) > 1e-3
								assert np.sum(np.abs(output_a - output_a     )     ) > 1e-3
								assert np.sum(np.abs(output_a - output_a     )     ) > 1e-3



						def   __a				( self  :      Tuple     ):

								"""simple docstring"""

								return self._test_attention_slicing_forward_pass(expected_max_diff=2e-3     )



						@unittest.skipIf(
						    torch_device != 'cuda' or not is_xformers_available()				,       reason='XFormers attention is only available with CUDA and `xformers` installed'				,       )
						def   __a				( self  :      Any     ):

								"""simple docstring"""

								self._test_xformers_attention_forwardGenerator_pass(expected_max_diff=2e-3     )



						def   __a				( self  :      Any     ):

								"""simple docstring"""

								self._test_inference_batch_single_identical(expected_max_diff=2e-3     )






						def   __a				( self  :      List[str]     ):

								"""simple docstring"""

								SCREAMING_SNAKE_CASE_							=       self.get_dummy_components()
								SCREAMING_SNAKE_CASE_							=       self.pipeline_class(**snake_case__     )
								pipe.to(snake_case__     )
								pipe.set_progress_bar_config(disable=snake_case__     )
								with tempfile.TemporaryDirectory() as tmpdir:
										try:
												# save_pretrained is not implemented for Multi-ControlNet
												pipe.save_pretrained(snake_case__     )
										except NotImplementedError:
												pass



@slow
@require_torch_gpu
class       lowercase_		(unittest.TestCase   ):



						def   __a				( self  :      List[str]     ):

								"""simple docstring"""

								super().tearDown()
								gc.collect()
								torch.cuda.empty_cache()



						def   __a				( self  :      Union[str, Any]     ):

								"""simple docstring"""

								SCREAMING_SNAKE_CASE_							=       ControlNetModel.from_pretrained('lllyasviel/sd-controlnet-canny'     )

								SCREAMING_SNAKE_CASE_							=       StableDiffusionControlNetInpaintPipeline.from_pretrained(
								    'runwayml/stable-diffusion-inpainting'				,       safety_checker=snake_case__				,       controlnet=snake_case__     )
								pipe.enable_model_cpu_offload()
								pipe.set_progress_bar_config(disable=snake_case__     )

								SCREAMING_SNAKE_CASE_							=       torch.Generator(device='cpu'     ).manual_seed(0     )
								SCREAMING_SNAKE_CASE_							=       load_image(
								    'https://huggingface.co/lllyasviel/sd-controlnet-canny/resolve/main/images/bird.png'     ).resize((5_12, 5_12)     )

								SCREAMING_SNAKE_CASE_							=       load_image(
								    'https://huggingface.co/datasets/diffusers/test-arrays/resolve/main'
								    '/stable_diffusion_inpaint/input_bench_mask.png'     ).resize((5_12, 5_12)     )

								SCREAMING_SNAKE_CASE_							=       'pitch black hole'

								SCREAMING_SNAKE_CASE_							=       load_image(
								    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/bird_canny.png'     ).resize((5_12, 5_12)     )

								SCREAMING_SNAKE_CASE_							=       pipe(
								    snake_case__				,       image=snake_case__				,       mask_image=snake_case__				,       control_image=snake_case__				,       generator=snake_case__				,       output_type='np'				,       num_inference_steps=3				,       )

								SCREAMING_SNAKE_CASE_							=       output.images[0]

								assert image.shape == (5_12, 5_12, 3)

								SCREAMING_SNAKE_CASE_							=       load_numpy(
								    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/inpaint.npy'     )

								assert np.abs(expected_image - image     ).max() < 9e-2






						def   __a				( self  :      Dict     ):

								"""simple docstring"""

								SCREAMING_SNAKE_CASE_							=       ControlNetModel.from_pretrained('lllyasviel/control_v11p_sd15_inpaint'     )

								SCREAMING_SNAKE_CASE_							=       StableDiffusionControlNetInpaintPipeline.from_pretrained(
								    'runwayml/stable-diffusion-v1-5'				,       safety_checker=snake_case__				,       controlnet=snake_case__     )
								SCREAMING_SNAKE_CASE_							=       DDIMScheduler.from_config(pipe.scheduler.config     )
								pipe.enable_model_cpu_offload()
								pipe.set_progress_bar_config(disable=snake_case__     )

								SCREAMING_SNAKE_CASE_							=       torch.Generator(device='cpu'     ).manual_seed(33     )

								SCREAMING_SNAKE_CASE_							=       load_image(
								    'https://huggingface.co/datasets/diffusers/test-arrays/resolve/main/stable_diffusion_inpaint/boy.png'     )
								SCREAMING_SNAKE_CASE_							=       init_image.resize((5_12, 5_12)     )

								SCREAMING_SNAKE_CASE_							=       load_image(
								    'https://huggingface.co/datasets/diffusers/test-arrays/resolve/main/stable_diffusion_inpaint/boy_mask.png'     )
								SCREAMING_SNAKE_CASE_							=       mask_image.resize((5_12, 5_12)     )

								SCREAMING_SNAKE_CASE_							=       'a handsome man with ray-ban sunglasses'

								def make_inpaint_condition(snake_case__  :      Any				,       snake_case__  :      Optional[int]     ):
										SCREAMING_SNAKE_CASE_							=       np.array(image.convert('RGB'     )     ).astype(np.floataa     ) / 2_55.0
										SCREAMING_SNAKE_CASE_							=       np.array(image_mask.convert('L'     )     ).astype(np.floataa     ) / 2_55.0

										assert image.shape[0:1] == image_mask.shape[0:1], "image and image_mask must have the same image size"
										SCREAMING_SNAKE_CASE_							=       -1.0  # set as masked pixel
										SCREAMING_SNAKE_CASE_							=       np.expand_dims(snake_case__				,       0     ).transpose(0				,       3				,       1				,       2     )
										SCREAMING_SNAKE_CASE_							=       torch.from_numpy(snake_case__     )
										return image

								SCREAMING_SNAKE_CASE_							=       make_inpaint_condition(snake_case__				,       snake_case__     )

								SCREAMING_SNAKE_CASE_							=       pipe(
								    snake_case__				,       image=snake_case__				,       mask_image=snake_case__				,       control_image=snake_case__				,       guidance_scale=9.0				,       eta=1.0				,       generator=snake_case__				,       num_inference_steps=20				,       output_type='np'				,       )
								SCREAMING_SNAKE_CASE_							=       output.images[0]

								assert image.shape == (5_12, 5_12, 3)

								SCREAMING_SNAKE_CASE_							=       load_numpy(
								    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/boy_ray_ban.npy'     )

								assert np.abs(expected_image - image     ).max() < 9e-2











from __future__ import annotations


def 				_a       (				lowerCAmelCase   )->  list[int]:
		if not list_of_ints:
				return []

		if min(lowerCAmelCase   ) < 0:
				raise ValueError('All numbers must be positive'   )

		SCREAMING_SNAKE_CASE_							=       max(len(bin(lowerCAmelCase   )[2:]   ) for x in list_of_ints   )
		return _msd_radix_sort(lowerCAmelCase						,	lowerCAmelCase   )


def 				_a       (				lowerCAmelCase						,	lowerCAmelCase   )->  list[int]:
		if bit_position == 0 or len(lowerCAmelCase   ) in [0, 1]:
				return list_of_ints

		SCREAMING_SNAKE_CASE_							=       []
		SCREAMING_SNAKE_CASE_							=       []
		# Split numbers based on bit at bit_position from the right
		for number in list_of_ints:
				if (number >> (bit_position - 1)) & 1:
						# number has a one at bit bit_position
						ones.append(lowerCAmelCase   )
				else:
						# number has a zero at bit bit_position
						zeros.append(lowerCAmelCase   )

    # recursively split both lists further
		SCREAMING_SNAKE_CASE_							=       _msd_radix_sort(lowerCAmelCase						,	bit_position - 1   )
		SCREAMING_SNAKE_CASE_							=       _msd_radix_sort(lowerCAmelCase						,	bit_position - 1   )

		# recombine lists
		SCREAMING_SNAKE_CASE_							=       zeros
		res.extend(lowerCAmelCase   )

		return res


def 				_a       (				lowerCAmelCase   )->  Dict:
		SCREAMING_SNAKE_CASE_							=       len(lowerCAmelCase   )
		if not list_of_ints or length == 1:
				return

		if min(lowerCAmelCase   ) < 0:
				raise ValueError('All numbers must be positive'   )

		SCREAMING_SNAKE_CASE_							=       max(len(bin(lowerCAmelCase   )[2:]   ) for x in list_of_ints   )
		_msd_radix_sort_inplace(lowerCAmelCase						,	lowerCAmelCase						,	0						,	lowerCAmelCase   )


def 				_a       (				lowerCAmelCase						,	lowerCAmelCase						,	lowerCAmelCase						,	lowerCAmelCase   )->  Optional[int]:
		if bit_position == 0 or end_index - begin_index <= 1:
				return

		bit_position -= 1

		SCREAMING_SNAKE_CASE_							=       begin_index
		SCREAMING_SNAKE_CASE_							=       end_index - 1
		while i <= j:
				SCREAMING_SNAKE_CASE_							=       False
				if not (list_of_ints[i] >> bit_position) & 1:
						# found zero at the beginning
						i += 1
						SCREAMING_SNAKE_CASE_							=       True
				if (list_of_ints[j] >> bit_position) & 1:
						# found one at the end
						j -= 1
						SCREAMING_SNAKE_CASE_							=       True

				if changed:
						continue

				SCREAMING_SNAKE_CASE_			,							SCREAMING_SNAKE_CASE_							=       list_of_ints[j], list_of_ints[i]
				j -= 1
				if j != i:
						i += 1

		_msd_radix_sort_inplace(lowerCAmelCase						,	lowerCAmelCase						,	lowerCAmelCase						,	lowerCAmelCase   )
		_msd_radix_sort_inplace(lowerCAmelCase						,	lowerCAmelCase						,	lowerCAmelCase						,	lowerCAmelCase   )


if __name__ == "__main__":
						import doctest

						doctest.testmod()