kssdtree 2.0.2__tar.gz → 2.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {kssdtree-2.0.2/kssdtree.egg-info → kssdtree-2.0.4}/PKG-INFO +6 -3
  2. kssdtree-2.0.4/README.md +8 -0
  3. {kssdtree-2.0.2 → kssdtree-2.0.4}/command_set.c +0 -1
  4. {kssdtree-2.0.2 → kssdtree-2.0.4/kssdtree.egg-info}/PKG-INFO +6 -3
  5. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdtree.py +22 -20
  6. {kssdtree-2.0.2 → kssdtree-2.0.4}/mman.c +0 -1
  7. {kssdtree-2.0.2 → kssdtree-2.0.4}/pykssd.c +35 -5
  8. {kssdtree-2.0.2 → kssdtree-2.0.4}/setup.py +5 -9
  9. {kssdtree-2.0.2 → kssdtree-2.0.4}/toolutils.py +1 -1
  10. kssdtree-2.0.2/README.md +0 -12
  11. {kssdtree-2.0.2 → kssdtree-2.0.4}/MANIFEST.in +0 -0
  12. {kssdtree-2.0.2 → kssdtree-2.0.4}/align.c +0 -0
  13. {kssdtree-2.0.2 → kssdtree-2.0.4}/buildtree.c +0 -0
  14. {kssdtree-2.0.2 → kssdtree-2.0.4}/bytescale.c +0 -0
  15. {kssdtree-2.0.2 → kssdtree-2.0.4}/cluster.c +0 -0
  16. {kssdtree-2.0.2 → kssdtree-2.0.4}/co2mco.c +0 -0
  17. {kssdtree-2.0.2 → kssdtree-2.0.4}/command_composite.c +0 -0
  18. {kssdtree-2.0.2 → kssdtree-2.0.4}/command_dist.c +0 -0
  19. {kssdtree-2.0.2 → kssdtree-2.0.4}/command_dist_wrapper.c +0 -0
  20. {kssdtree-2.0.2 → kssdtree-2.0.4}/command_shuffle.c +0 -0
  21. {kssdtree-2.0.2 → kssdtree-2.0.4}/distancemat.c +0 -0
  22. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnj.c +0 -0
  23. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/bytescale.h +0 -0
  24. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/dnj.h +0 -0
  25. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/filebuff.h +0 -0
  26. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/hclust.h +0 -0
  27. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/matrix.h +0 -0
  28. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/mman.h +0 -0
  29. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/nj.h +0 -0
  30. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/nwck.h +0 -0
  31. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/pherror.h +0 -0
  32. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/phy.h +0 -0
  33. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/qseqs.h +0 -0
  34. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/str.h +0 -0
  35. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/threader.h +0 -0
  36. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/tmp.h +0 -0
  37. {kssdtree-2.0.2 → kssdtree-2.0.4}/dnjheaders/vector.h +0 -0
  38. {kssdtree-2.0.2 → kssdtree-2.0.4}/filebuff.c +0 -0
  39. {kssdtree-2.0.2 → kssdtree-2.0.4}/global_basic.c +0 -0
  40. {kssdtree-2.0.2 → kssdtree-2.0.4}/hclust.c +0 -0
  41. {kssdtree-2.0.2 → kssdtree-2.0.4}/iseq2comem.c +0 -0
  42. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/co2mco.h +0 -0
  43. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/command_composite.h +0 -0
  44. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/command_dist.h +0 -0
  45. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/command_dist_wrapper.h +0 -0
  46. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/command_set.h +0 -0
  47. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/command_shuffle.h +0 -0
  48. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/global_basic.h +0 -0
  49. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/iseq2comem.h +0 -0
  50. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/mman.h +0 -0
  51. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdheaders/mytime.h +0 -0
  52. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdtree.egg-info/SOURCES.txt +0 -0
  53. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdtree.egg-info/dependency_links.txt +0 -0
  54. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdtree.egg-info/not-zip-safe +0 -0
  55. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdtree.egg-info/requires.txt +0 -0
  56. {kssdtree-2.0.2 → kssdtree-2.0.4}/kssdtree.egg-info/top_level.txt +0 -0
  57. {kssdtree-2.0.2 → kssdtree-2.0.4}/matrix.c +0 -0
  58. {kssdtree-2.0.2 → kssdtree-2.0.4}/mytime.c +0 -0
  59. {kssdtree-2.0.2 → kssdtree-2.0.4}/nj.c +0 -0
  60. {kssdtree-2.0.2 → kssdtree-2.0.4}/njheaders/align.h +0 -0
  61. {kssdtree-2.0.2 → kssdtree-2.0.4}/njheaders/buildtree.h +0 -0
  62. {kssdtree-2.0.2 → kssdtree-2.0.4}/njheaders/cluster.h +0 -0
  63. {kssdtree-2.0.2 → kssdtree-2.0.4}/njheaders/distancemat.h +0 -0
  64. {kssdtree-2.0.2 → kssdtree-2.0.4}/njheaders/sequence.h +0 -0
  65. {kssdtree-2.0.2 → kssdtree-2.0.4}/njheaders/tree.h +0 -0
  66. {kssdtree-2.0.2 → kssdtree-2.0.4}/njheaders/util.h +0 -0
  67. {kssdtree-2.0.2 → kssdtree-2.0.4}/nwck.c +0 -0
  68. {kssdtree-2.0.2 → kssdtree-2.0.4}/pherror.c +0 -0
  69. {kssdtree-2.0.2 → kssdtree-2.0.4}/phy.c +0 -0
  70. {kssdtree-2.0.2 → kssdtree-2.0.4}/pydnj.c +0 -0
  71. {kssdtree-2.0.2 → kssdtree-2.0.4}/pynj.c +0 -0
  72. {kssdtree-2.0.2 → kssdtree-2.0.4}/qseqs.c +0 -0
  73. {kssdtree-2.0.2 → kssdtree-2.0.4}/sequence.c +0 -0
  74. {kssdtree-2.0.2 → kssdtree-2.0.4}/setup.cfg +0 -0
  75. {kssdtree-2.0.2 → kssdtree-2.0.4}/str.c +0 -0
  76. {kssdtree-2.0.2 → kssdtree-2.0.4}/tmp.c +0 -0
  77. {kssdtree-2.0.2 → kssdtree-2.0.4}/tree.c +0 -0
  78. {kssdtree-2.0.2 → kssdtree-2.0.4}/util.c +0 -0
  79. {kssdtree-2.0.2 → kssdtree-2.0.4}/vector.c +0 -0
@@ -1,8 +1,11 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 1.1
2
2
  Name: kssdtree
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: Kssdtree is a versatile Python package for phylogenetic analysis. It also provides one-stop tree construction and visualization. It can handle DNA sequences of both fasta or fastq format, whether gzipped or not.
5
5
  Home-page: https://github.com/yhlink/kssdtree
6
- Download-URL: https://pypi.org/project/kssdtree
7
6
  Author: Hang Yang
8
7
  Author-email: yhlink1207@gmail.com
8
+ License: UNKNOWN
9
+ Download-URL: https://pypi.org/project/kssdtree
10
+ Description: UNKNOWN
11
+ Platform: UNKNOWN
@@ -0,0 +1,8 @@
1
+ Kssdtree is a versatile Python package for phylogenetic analysis, offering three distinct pipelines: the Routine Pipeline, the Reference Subtraction Pipeline, and the GTDB-based Phylogenetic Placement Pipeline.
2
+
3
+ Routine Pipeline: A general-purpose tool for phylogenetic analysis of user genomic data.
4
+ Reference Subtraction Pipeline: Designed for intra-species phylogenomic analysis.
5
+ GTDB-based Phylogenetic Placement Pipeline: Facilitates the search for similar genomes in the Genome Taxonomy Database (GTDB), conducting phylogenetic analysis alongside these genomes and positioning the input genomes within the entire prokaryotic tree of life.
6
+ Kssdtree also provides one-stop tree construction and visualization. It can handle DNA sequences in both fasta and fastq formats, whether gzipped or not. Additionally, Kssdtree is compatible with multiple platforms (Linux, MacOS, and Windows) and can be run using Jupyter notebooks.
7
+
8
+ More usages about Kssdtree, please see Kssdtree documentation (https://kssdtree.readthedocs.io/en/latest).
@@ -25,7 +25,6 @@
25
25
  #include <errno.h>
26
26
  #include <math.h>
27
27
  #include <unistd.h>
28
-
29
28
  const char skch_prefix[]="combco";
30
29
  const char idx_prefix[]="combco.index";
31
30
  const char pan_prefix[]="pan";
@@ -1,8 +1,11 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 1.1
2
2
  Name: kssdtree
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: Kssdtree is a versatile Python package for phylogenetic analysis. It also provides one-stop tree construction and visualization. It can handle DNA sequences of both fasta or fastq format, whether gzipped or not.
5
5
  Home-page: https://github.com/yhlink/kssdtree
6
- Download-URL: https://pypi.org/project/kssdtree
7
6
  Author: Hang Yang
8
7
  Author-email: yhlink1207@gmail.com
8
+ License: UNKNOWN
9
+ Download-URL: https://pypi.org/project/kssdtree
10
+ Description: UNKNOWN
11
+ Platform: UNKNOWN
@@ -28,23 +28,18 @@ def sketch(shuf_file=None, genome_files=None, output=None, set_opt=None):
28
28
  if not os.path.exists(shuf_file):
29
29
  if shuf_file in ['L3K9.shuf', './L3K9.shuf', 'L3K10.shuf', './L3K10.shuf']:
30
30
  print('Downloading...', shuf_file)
31
- import http.client
32
- http.client.HTTPConnection._http_vsn = 10
33
- http.client.HTTPConnection._http_vsn_str = 'HTTP/1.0'
34
31
  if shuf_file == 'L3K9.shuf' or shuf_file == './L3K9.shuf':
35
32
  url = 'https://zenodo.org/records/12699159/files/L3K9.shuf?download=1'
36
33
  else:
37
34
  url = 'https://zenodo.org/records/12699159/files/L3K10.shuf?download=1'
38
- start_time = time.time()
39
- response = requests.get(url, stream=True)
40
- with open(shuf_file, 'wb') as file:
41
- for chunk in response.iter_content(chunk_size=1024):
42
- if chunk:
43
- file.write(chunk)
35
+ headers = {'Accept-Encoding': 'gzip, deflate'}
36
+ response = requests.get(url, headers=headers, stream=True)
37
+ with open(shuf_file, 'wb') as f:
38
+ for chunk in response.iter_content(chunk_size=8192):
39
+ f.write(chunk)
44
40
  end_time = time.time()
45
- if end_time - start_time > 120:
46
- print(
47
- "Network timeout, please manually download from https://zenodo.org/records/12699159")
41
+ if end_time - start_time > 200:
42
+ print("Network timeout, please manually download from https://zenodo.org/records/12699159")
48
43
  return False
49
44
  print('Download finished: ', shuf_file)
50
45
  elif shuf_file in ['L2K8.shuf', 'L2K9.shuf', 'L3K11.shuf', './L2K8.shuf', './L2K9.shuf', './L3K11.shuf']:
@@ -64,9 +59,9 @@ def sketch(shuf_file=None, genome_files=None, output=None, set_opt=None):
64
59
  print('Sketching...')
65
60
  start = time.time()
66
61
  if set_opt:
67
- kssd.dist_dispatch(shuf_file, genome_files, output, 1, 0, 0)
62
+ kssd.dist_dispatch(shuf_file, genome_files, output, 1, 0, 0, '')
68
63
  else:
69
- kssd.dist_dispatch(shuf_file, genome_files, output, 0, 0, 0)
64
+ kssd.dist_dispatch(shuf_file, genome_files, output, 0, 0, 0, '')
70
65
  end = time.time()
71
66
  print('Sketch spend time:%.2fs' % (end - start))
72
67
  print('Sketch finished!')
@@ -76,7 +71,7 @@ def sketch(shuf_file=None, genome_files=None, output=None, set_opt=None):
76
71
  return False
77
72
 
78
73
 
79
- def dist(genome_sketch=None, output=None, flag=None):
74
+ def dist(genome_sketch=None, output=None, metric = None, flag=None):
80
75
  if genome_sketch is not None and output is not None:
81
76
  if not os.path.exists(genome_sketch):
82
77
  print('No such file or directory: ', genome_sketch)
@@ -86,6 +81,9 @@ def dist(genome_sketch=None, output=None, flag=None):
86
81
  # return False
87
82
  if flag is None:
88
83
  flag = 0
84
+ if metric is None:
85
+ metric = 'mash'
86
+
89
87
  print('Disting...')
90
88
  start = time.time()
91
89
  if '/' in output:
@@ -97,11 +95,15 @@ def dist(genome_sketch=None, output=None, flag=None):
97
95
  else:
98
96
  output_name = output
99
97
  if output_name.endswith(".phy") or output_name.endswith(".phylip"):
100
- kssd.dist_dispatch(genome_sketch, output, genome_sketch, 2, 0, flag)
101
- end = time.time()
102
- print('Dist spend time:%.2fs' % (end - start))
103
- print('Dist finished!')
104
- return True
98
+ if metric not in ['mash', 'aaf']:
99
+ print('Metric type error, only supports mash or aaf distance')
100
+ return False
101
+ else:
102
+ kssd.dist_dispatch(genome_sketch, output, genome_sketch, 2, 0, flag, metric)
103
+ end = time.time()
104
+ print('Dist spend time:%.2fs' % (end - start))
105
+ print('Dist finished!')
106
+ return True
105
107
  else:
106
108
  print('Output type error, only supports .phylip (.phy) format:', output_name)
107
109
  return False
@@ -1,4 +1,3 @@
1
-
2
1
  #ifdef _WIN32
3
2
  #include <windows.h>
4
3
  #include <io.h>
@@ -121,12 +121,18 @@ int create_matrix(char *input_name, char *output_name, int flag) {
121
121
  for (int j = 0; j <= i; j++)
122
122
  distances[i][j] = 0.0;
123
123
  }
124
- } else {
124
+ } else if (flag == 1) {
125
125
  for (int i = 0; i < num_seqs; i++) {
126
126
  distances[i] = malloc(i * sizeof(double));
127
127
  for (int j = 0; j < i; j++)
128
128
  distances[i][j] = 0.0;
129
129
  }
130
+ } else {
131
+ for (int i = 0; i < num_seqs; i++) {
132
+ distances[i] = malloc(num_seqs * sizeof(double));
133
+ for (int j = 0; j < num_seqs; j++)
134
+ distances[i][j] = 0.0;
135
+ }
130
136
  }
131
137
  rewind(fp);
132
138
  fgets(line, PATHLEN, fp);
@@ -144,7 +150,7 @@ int create_matrix(char *input_name, char *output_name, int flag) {
144
150
  j += 1;
145
151
  }
146
152
  }
147
- } else {
153
+ } else if (flag == 1) {
148
154
  while (fgets(line, PATHLEN, fp) != NULL) {
149
155
  sscanf(line, "%*s %*s %*s %*s %lf", &distance);
150
156
  if (j < i) {
@@ -156,6 +162,16 @@ int create_matrix(char *input_name, char *output_name, int flag) {
156
162
  j += 1;
157
163
  }
158
164
  }
165
+ } else {
166
+ while (fgets(line, PATHLEN, fp) != NULL) {
167
+ sscanf(line, "%*s %*s %*s %*s %lf", &distance);
168
+ distances[i][j] = distance;
169
+ i += 1;
170
+ if (i == num_seqs && j < num_seqs) {
171
+ i = 0;
172
+ j += 1;
173
+ }
174
+ }
159
175
  }
160
176
 
161
177
  for (int i = 0; i < num_seqs; i++) {
@@ -187,7 +203,7 @@ int create_matrix(char *input_name, char *output_name, int flag) {
187
203
  }
188
204
  fprintf(fo, "\n");
189
205
  }
190
- } else {
206
+ } else if (flag == 1) {
191
207
  for (int i = 0; i < num_seqs; i++) {
192
208
  fprintf(fo, "%s\t", seq_names[i]);
193
209
  for (int j = 0; j < num_seqs; j++) {
@@ -197,6 +213,14 @@ int create_matrix(char *input_name, char *output_name, int flag) {
197
213
  }
198
214
  fprintf(fo, "\n");
199
215
  }
216
+ } else {
217
+ for (int i = 0; i < num_seqs; i++) {
218
+ fprintf(fo, "%s\t", seq_names[i]);
219
+ for (int j = 0; j < num_seqs; j++) {
220
+ fprintf(fo, "%.6f\t", distances[i][j]);
221
+ }
222
+ fprintf(fo, "\n");
223
+ }
200
224
  }
201
225
  for (int i = 0; i < num_seqs; i++) {
202
226
  free(distances[i]);
@@ -235,8 +259,9 @@ static PyObject *py_dist_dispatch(PyObject *self, PyObject *args) {
235
259
  char *str3;
236
260
  int flag1;
237
261
  int flag2;
262
+ char *str4;
238
263
  int N;
239
- if (!PyArg_ParseTuple(args, "sssiii", &str1, &str2, &str3, &flag1, &N, &flag2)) {
264
+ if (!PyArg_ParseTuple(args, "sssiiis", &str1, &str2, &str3, &flag1, &N, &flag2, &str4)) {
240
265
  return NULL;
241
266
  }
242
267
  if (flag1 == 0) {
@@ -394,6 +419,11 @@ static PyObject *py_dist_dispatch(PyObject *self, PyObject *args) {
394
419
  dist_opt_val3.num_remaining_args = 1;
395
420
  dist_opt_val3.remaining_args = &str3;
396
421
  dist_opt_val3.num_neigb = N;
422
+ if (strcmp(str4, "mash") == 0) {
423
+ dist_opt_val3.metric = 0;
424
+ } else {
425
+ dist_opt_val3.metric = 1;
426
+ }
397
427
  #ifdef _OPENMP
398
428
  if(dist_opt_val3.p == 0)
399
429
  dist_opt_val3.p = omp_get_num_procs();
@@ -628,4 +658,4 @@ static struct PyModuleDef kssdmodule = {
628
658
 
629
659
  PyMODINIT_FUNC PyInit_kssd(void) {
630
660
  return PyModule_Create(&kssdmodule);
631
- }
661
+ }
@@ -3,11 +3,6 @@ from setuptools import setup, Extension, find_packages
3
3
  from os import environ
4
4
  import os
5
5
 
6
- # def get_gcc_version():
7
- # gcc_version = subprocess.check_output(['gcc', '--version']).decode('utf-8')
8
- # version_line = gcc_version.split('\n', 1)[0]
9
- # version_str = version_line.split()[-1]
10
- # return version_str
11
6
  extra_compile_args = []
12
7
  extra_link_args = []
13
8
  if 'darwin' in sys.platform:
@@ -24,12 +19,12 @@ if 'darwin' in sys.platform:
24
19
  gcc_path = "/opt/homebrew/bin/gcc-11"
25
20
  elif 'gcc-12' == gcc_version:
26
21
  gcc_path = "/opt/homebrew/bin/gcc-12"
22
+ elif 'gcc-13' == gcc_version:
23
+ gcc_path = "/opt/homebrew/bin/gcc-13"
27
24
  elif 'gcc-14' == gcc_version:
28
25
  gcc_path = "/opt/homebrew/bin/gcc-14"
29
- elif 'gcc-15' == gcc_version:
30
- gcc_path = "/opt/homebrew/bin/gcc-15"
31
26
  else:
32
- gcc_path = "/opt/homebrew/bin/gcc-13"
27
+ gcc_path = ""
33
28
  extra_compile_args = ['-fopenmp']
34
29
  extra_link_args = ['-fopenmp']
35
30
  os.environ["CC"] = gcc_path
@@ -92,7 +87,7 @@ require_pakages = [
92
87
 
93
88
  setup(
94
89
  name='kssdtree',
95
- version='2.0.2',
90
+ version='2.0.4',
96
91
  author='Hang Yang',
97
92
  author_email='yhlink1207@gmail.com',
98
93
  description="Kssdtree is a versatile Python package for phylogenetic analysis. It also provides one-stop tree construction and visualization. It can handle DNA sequences of both fasta or fastq format, whether gzipped or not. ",
@@ -114,3 +109,4 @@ setup(
114
109
  zip_safe=False,
115
110
  include_package_data=True
116
111
  )
112
+
@@ -8,7 +8,7 @@ import pandas as pd
8
8
  import string
9
9
 
10
10
  def allowed_file(filename):
11
- allowed_extensions = ['.fa', '.fa.gz', '.fasta', '.fasta.gz', '.fna', '.fna.gz', '.fastq', '.fastq.gz']
11
+ allowed_extensions = ['.fa', '.fa.gz', '.fasta', '.fasta.gz', '.fna', '.fna.gz', '.fastq', '.fastq.gz', '.fq', '.fq.gz']
12
12
  return any(filename.endswith(ext) for ext in allowed_extensions)
13
13
 
14
14
  def rs():
kssdtree-2.0.2/README.md DELETED
@@ -1,12 +0,0 @@
1
- # Kssdree: an interactive Python package for phylogenetic analysis based on sketching technique
2
-
3
- Kssdtree is a versatile Python package for phylogenetic analysis, including three different pipelines: routine pipeline, reference subtraction pipeline and phylogenetic placement pipeline. The routine pipeline serves as a versatile tool for general-purpose phylogenetic analysis of users' genomic data. The reference subtraction pipeline designs for population-level phylogenetic analysis. The phylogenetic placement pipeline facilitates the search for similar genomes in the Genome Taxonomy Database (GTDB). It conducts phylogenetic analysis alongside these similar genomes and positions the input genomes within the entire prokaryotic tree of life.
4
-
5
- It also provides one-stop tree construction and visualization. It can handle DNA sequences of both fasta or fastq format, whether gzipped or not. Kssdtree can run on multiple platforms (Linux, Windows, and MacOS) with Jupyter notebooks.
6
-
7
- More usages about Kssdtree, please see Kssdtree documentation (https://kssdtree.readthedocs.io/en/latest).
8
-
9
-
10
-
11
-
12
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes