diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fc50cb1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +# we do not want to copy git metadata +.git + +# nor Python virtual environment +.venv + +# sample images and other files +*.svs +*.pdf +*.pth +*.log diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..477fdc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +*.py[cod] +__pycache__/ +_build* +build +logs +training +.*.swp +.*.swo +.eggs +.tox +.vagrant +.venv +.venv9 +.DS_Store +**/.DS_Store +multic.egg-info diff --git a/Dockerfile b/Dockerfile index 456ea20..e2a02ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,6 @@ LABEL com.nvidia.volumes.needed="nvidia_driver" LABEL maintainer="Sayat Mimar - Sarder Lab. " -CMD echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! STARTING THE BUILD !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # RUN mkdir /usr/local/nvidia && ln -s /usr/local/cuda-10.0/compat /usr/local/nvidia/lib ENV NVIDIA_VISIBLE_DEVICES all @@ -67,8 +66,6 @@ RUN apt-get update && \ #apt-get autoremove && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -CMD echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CHECKPOINT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - RUN apt-get update ##[edited] RUN apt-get install 'ffmpeg'\ 'libsm6'\ diff --git a/multic/cli/MultiCompartmentSegment/MultiCompartmentSegment.py b/multic/cli/MultiCompartmentSegment/MultiCompartmentSegment.py index 7f0152d..e8940e3 100644 --- a/multic/cli/MultiCompartmentSegment/MultiCompartmentSegment.py +++ b/multic/cli/MultiCompartmentSegment/MultiCompartmentSegment.py @@ -47,7 +47,7 @@ def main(args): print(f'This is slide path: {file_path}') print('new version') - _ = os.system("printf '\n---\n\nFOUND: [{}]\n'".format(args.input_file)) + _ = os.system("echo '\n---\n\nFOUND: [{}]\n'".format(args.input_file)) cwd = os.getcwd() print(cwd) diff --git a/multic/segmentationschool/Codes/InitializeFolderStructure.py b/multic/segmentationschool/Codes/InitializeFolderStructure.py index 9aef99f..add9b7a 100644 --- a/multic/segmentationschool/Codes/InitializeFolderStructure.py +++ b/multic/segmentationschool/Codes/InitializeFolderStructure.py @@ -59,11 +59,11 @@ def initializeFolderStructure(dirs,args): folder_base = args.base_dir base_directory_id = folder_base.split('/')[-2] - _ = os.system("printf '\nIn the base directory: {} {}\n'".format(base_directory_id,folder_base)) + _ = os.system("echo '\nIn the base directory: {} {}\n'".format(base_directory_id,folder_base)) folder_project = args.project project_directory_id = folder_project.split('/')[-2] - _ = os.system("printf '\nIn the base directory: {}{}\n'".format(project_directory_id,folder_base)) + _ = os.system("echo '\nIn the base directory: {}{}\n'".format(project_directory_id,folder_base)) gc = girder_client.GirderClient(apiUrl=args.girderApiUrl) gc.setToken(args.girderToken) diff --git a/multic/segmentationschool/Codes/IterativePredict_1X.py b/multic/segmentationschool/Codes/IterativePredict_1X.py index eab9718..994de96 100644 --- a/multic/segmentationschool/Codes/IterativePredict_1X.py +++ b/multic/segmentationschool/Codes/IterativePredict_1X.py @@ -241,7 +241,7 @@ def xml_suey(wsiMask, args, classNum, downsample,glob_offset): annots = convert_xml_json(Annotations, NAMES) for annot in annots: _ = gc.post(path='annotation',parameters={'itemId':args.item_id}, data = json.dumps(annot)) - print('uploating layers') + print('uploading layers') print('annotation uploaded...\n') def get_contour_points(mask, args, downsample,value, offset={'X': 0,'Y': 0}): diff --git a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-36.pyc deleted file mode 100644 index 2d37438..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-37.pyc deleted file mode 100644 index 760a91b..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-38.pyc b/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-38.pyc deleted file mode 100644 index 770f60b..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-38.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-39.pyc b/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-39.pyc deleted file mode 100644 index ac7c38c..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/InitializeFolderStructure.cpython-39.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/IterativePredict_1X.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/IterativePredict_1X.cpython-36.pyc deleted file mode 100644 index 03a70ce..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/IterativePredict_1X.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/IterativePredict_1X.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/IterativePredict_1X.cpython-37.pyc deleted file mode 100644 index 7cfb0f4..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/IterativePredict_1X.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/IterativeTraining.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/IterativeTraining.cpython-36.pyc deleted file mode 100644 index 3550355..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/IterativeTraining.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-36.pyc deleted file mode 100644 index 269be83..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-37.pyc deleted file mode 100644 index f839392..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-38.pyc b/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-38.pyc deleted file mode 100644 index 0f28ecc..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-38.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-39.pyc b/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-39.pyc deleted file mode 100644 index 88d011b..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/IterativeTraining_1X.cpython-39.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/PAS_deconvolution.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/PAS_deconvolution.cpython-36.pyc deleted file mode 100644 index 002ed7e..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/PAS_deconvolution.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/TransformXMLs.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/TransformXMLs.cpython-36.pyc deleted file mode 100644 index 608752d..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/TransformXMLs.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/TransformXMLs.cpython-39.pyc b/multic/segmentationschool/Codes/__pycache__/TransformXMLs.cpython-39.pyc deleted file mode 100644 index 03c61ea..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/TransformXMLs.cpython-39.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/XML_to_Json_cortex.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/XML_to_Json_cortex.cpython-36.pyc deleted file mode 100644 index f128e34..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/XML_to_Json_cortex.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/__init__.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 61e88b4..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/extract_reference_features.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/extract_reference_features.cpython-36.pyc deleted file mode 100644 index 5a3e968..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/extract_reference_features.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/extract_reference_features.cpython-39.pyc b/multic/segmentationschool/Codes/__pycache__/extract_reference_features.cpython-39.pyc deleted file mode 100644 index 0adae13..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/extract_reference_features.cpython-39.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/generateTrainSet.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/generateTrainSet.cpython-36.pyc deleted file mode 100644 index d0886a2..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/generateTrainSet.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-36.pyc deleted file mode 100644 index fcdf846..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-37.pyc deleted file mode 100644 index ed94d7a..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-39.pyc b/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-39.pyc deleted file mode 100644 index 43a1eea..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/getWsi.cpython-39.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-36.pyc deleted file mode 100644 index cda3781..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-37.pyc deleted file mode 100644 index 9dccf83..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-39.pyc b/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-39.pyc deleted file mode 100644 index f1642d8..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/get_choppable_regions.cpython-39.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/get_dataset_list.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/get_dataset_list.cpython-36.pyc deleted file mode 100644 index 5c8d1d4..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/get_dataset_list.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/get_dataset_list.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/get_dataset_list.cpython-37.pyc deleted file mode 100644 index 25f6f3a..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/get_dataset_list.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/get_network_performance.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/get_network_performance.cpython-36.pyc deleted file mode 100644 index 5fea3ef..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/get_network_performance.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/get_network_performance.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/get_network_performance.cpython-37.pyc deleted file mode 100644 index 5b7c0eb..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/get_network_performance.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/randomCropGenerator.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/randomCropGenerator.cpython-36.pyc deleted file mode 100644 index c236d83..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/randomCropGenerator.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/randomHSVshift.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/randomHSVshift.cpython-36.pyc deleted file mode 100644 index b8cdeea..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/randomHSVshift.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/utils.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/utils.cpython-36.pyc deleted file mode 100644 index 6d05d8e..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/utils.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/utils.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/utils.cpython-37.pyc deleted file mode 100644 index 9c39dd0..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/utils.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/wsi_loader_utils.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/wsi_loader_utils.cpython-36.pyc deleted file mode 100644 index 8011c3f..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/wsi_loader_utils.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/xml_to_mask.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/xml_to_mask.cpython-36.pyc deleted file mode 100644 index e0da475..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/xml_to_mask.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/xml_to_mask.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/xml_to_mask.cpython-37.pyc deleted file mode 100644 index 7985b8a..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/xml_to_mask.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-36.pyc deleted file mode 100644 index f78cc82..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-37.pyc b/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-37.pyc deleted file mode 100644 index e350667..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-37.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-39.pyc b/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-39.pyc deleted file mode 100644 index e6515e0..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/xml_to_mask2.cpython-39.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/__pycache__/xml_to_mask_minmax.cpython-36.pyc b/multic/segmentationschool/Codes/__pycache__/xml_to_mask_minmax.cpython-36.pyc deleted file mode 100644 index d408898..0000000 Binary files a/multic/segmentationschool/Codes/__pycache__/xml_to_mask_minmax.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/Codes/wsi_loader_utils.py b/multic/segmentationschool/Codes/wsi_loader_utils.py index ea87ae6..d128bcd 100644 --- a/multic/segmentationschool/Codes/wsi_loader_utils.py +++ b/multic/segmentationschool/Codes/wsi_loader_utils.py @@ -13,7 +13,7 @@ def save_thumb(args,slide_loc): print(slide_loc) - slideID,slideExt=os.path.splitext(slide_loc.split('/')[-1]) + slideID,slideExt=os.path.splitext(slide_loc.split(os.sep)[-1]) slide=openslide.OpenSlide(slide_loc) if slideExt =='.scn': dim_x=int(slide.properties['openslide.bounds-width'])## add to columns @@ -62,7 +62,7 @@ def __init__(self,args, wsi_directory=None, transform=None): usable_slides=[] for slide_loc in all_slides: - slideID,slideExt=os.path.splitext(slide_loc.split('/')[-1]) + slideID,slideExt=os.path.splitext(slide_loc.split(os.sep)[-1]) print("working slide... "+ slideID,end='\r') slide=openslide.OpenSlide(slide_loc) @@ -88,9 +88,9 @@ def __init__(self,args, wsi_directory=None, transform=None): print('Getting slide metadata and usable regions...') usable_slides=[] - for slide_loc in all_slides: - slideID,slideExt=os.path.splitext(slide_loc.split('/')[-1]) - print("working slide... "+ slideID,end='\r') + for iteration, slide_loc in enumerate(all_slides): + slideID,slideExt=os.path.splitext(slide_loc.split(os.sep)[-1]) + print(f"slide {iteration + 1}/{len(all_slides)}: {slideID}" ,end='\r') slide=openslide.OpenSlide(slide_loc) chop_array=get_choppable_regions(slide,args,slideID,slideExt,mask_out_loc) diff --git a/multic/segmentationschool/Codes/xml_to_json.py b/multic/segmentationschool/Codes/xml_to_json.py index 22c01a8..4367f93 100644 --- a/multic/segmentationschool/Codes/xml_to_json.py +++ b/multic/segmentationschool/Codes/xml_to_json.py @@ -19,7 +19,7 @@ def convert_xml_json(root, names, colorList=None, alpha=0.4): for n, child in enumerate(anns): dataDict = dict() name = names[n] - _ = os.system("printf 'Building JSON layer: [{}]\n'".format(name)) + _ = os.system("echo 'Building JSON layer: [{}]\n'".format(name)) element = [] reg = child.find('Regions') for i in reg.findall('Region'): diff --git a/multic/segmentationschool/__pycache__/__init__.cpython-36.pyc b/multic/segmentationschool/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index f732ded..0000000 Binary files a/multic/segmentationschool/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/multic/segmentationschool/hail.out b/multic/segmentationschool/hail.out deleted file mode 100644 index fc04660..0000000 --- a/multic/segmentationschool/hail.out +++ /dev/null @@ -1,21 +0,0 @@ -SLURM_JOBID=43858554 -SLURM_JOB_NODELIST=c38a-s13 -SLURM_NNODES=1 -SLURMTMPDIR= -working directory = /home/nlucarelli/detectron2_HAIL -Launch job -time="2022-08-03T17:56:35-04:00" level=warning msg="\"/run/user/6265\" directory set by $XDG_RUNTIME_DIR does not exist. Either create the directory or unset $XDG_RUNTIME_DIR.: stat /run/user/6265: no such file or directory: Trying to pull image in the event that it is a public image." -Failed to load OpenCL runtime -Traceback (most recent call last): - File "/exec/segmentation_school.py", line 275, in - main(args=args) - File "/exec/segmentation_school.py", line 49, in main - from IterativePredict_1X import predict - File "/home/nlucarelli/detectron2_HAIL/Codes/IterativePredict_1X.py", line 31, in - import openslide - File "/home/nlucarelli/privatemodules/openslide-master/openslide/__init__.py", line 35, in - from openslide import lowlevel - File "/home/nlucarelli/privatemodules/openslide-master/openslide/lowlevel.py", line 40, in - from . import _convert -ImportError: cannot import name '_convert' -All Done! diff --git a/setup.py b/setup.py index f0bb8af..8d8290c 100644 --- a/setup.py +++ b/setup.py @@ -45,13 +45,14 @@ def prerelease_local_scheme(version): install_requires=[ # scientific packages 'nimfa>=1.3.2', - 'numpy>=1.21.1', + 'numpy>=1.21.1,<2.0', 'scipy>=0.19.0', 'Pillow==9.5.0', 'pandas>=0.19.2', 'imageio>=2.3.0', # 'shapely[vectorized]', - #'opencv-python-headless<4.7', + # 'opencv-python-headless', + # 'imgaug==0.4.0', #'sqlalchemy', # 'matplotlib', 'pyvips', @@ -78,6 +79,8 @@ def prerelease_local_scheme(version): 'girder-client', # cli 'ctk-cli', + # detectron2 is installed in the dockerfile, so it needs to be commented out here + # 'detectron2 @ git+https://github.com/facebookresearch/detectron2@main', # v0.6+patches ], license='Apache Software License 2.0', keywords='multic', diff --git "a/\342\200\216.gitattributes" "b/\342\200\216.gitattributes" new file mode 100644 index 0000000..21f6efb --- /dev/null +++ "b/\342\200\216.gitattributes" @@ -0,0 +1,2 @@ +*.sh text eol=lf +*.conf text eol=lf