bioroebe 0.10.80 → 0.11.12

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bioroebe might be problematic. Click here for more details.

Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +507 -310
  3. data/bioroebe.gemspec +3 -3
  4. data/doc/README.gen +506 -309
  5. data/doc/todo/bioroebe_todo.md +29 -40
  6. data/lib/bioroebe/aminoacids/display_aminoacid_table.rb +1 -0
  7. data/lib/bioroebe/base/colours_for_base/colours_for_base.rb +18 -8
  8. data/lib/bioroebe/base/commandline_application/commandline_arguments.rb +13 -11
  9. data/lib/bioroebe/base/commandline_application/misc.rb +18 -8
  10. data/lib/bioroebe/base/prototype/misc.rb +1 -1
  11. data/lib/bioroebe/codons/show_codon_tables.rb +6 -2
  12. data/lib/bioroebe/constants/aminoacids_and_proteins.rb +1 -0
  13. data/lib/bioroebe/constants/files_and_directories.rb +8 -1
  14. data/lib/bioroebe/count/count_amount_of_nucleotides.rb +3 -0
  15. data/lib/bioroebe/gui/gtk3/protein_to_DNA/protein_to_DNA.rb +18 -18
  16. data/lib/bioroebe/gui/shared_code/protein_to_DNA/protein_to_DNA_module.rb +14 -14
  17. data/lib/bioroebe/parsers/genbank_parser.rb +353 -24
  18. data/lib/bioroebe/python/README.md +1 -0
  19. data/lib/bioroebe/python/__pycache__/mymodule.cpython-39.pyc +0 -0
  20. data/lib/bioroebe/python/gui/gtk3/widget1.py +22 -0
  21. data/lib/bioroebe/python/mymodule.py +8 -0
  22. data/lib/bioroebe/python/protein_to_dna.py +30 -0
  23. data/lib/bioroebe/python/shell/shell.py +19 -0
  24. data/lib/bioroebe/python/to_rna.py +14 -0
  25. data/lib/bioroebe/python/toplevel_methods/to_camelcase.py +11 -0
  26. data/lib/bioroebe/sequence/nucleotide_module/nucleotide_module.rb +28 -25
  27. data/lib/bioroebe/sequence/sequence.rb +54 -2
  28. data/lib/bioroebe/shell/menu.rb +3336 -3304
  29. data/lib/bioroebe/shell/readline/readline.rb +1 -1
  30. data/lib/bioroebe/shell/shell.rb +11233 -28
  31. data/lib/bioroebe/siRNA/siRNA.rb +81 -1
  32. data/lib/bioroebe/string_matching/find_longest_substring.rb +3 -2
  33. data/lib/bioroebe/toplevel_methods/aminoacids_and_proteins.rb +31 -24
  34. data/lib/bioroebe/toplevel_methods/nucleotides.rb +22 -5
  35. data/lib/bioroebe/toplevel_methods/open_in_browser.rb +2 -0
  36. data/lib/bioroebe/toplevel_methods/to_camelcase.rb +5 -0
  37. data/lib/bioroebe/version/version.rb +2 -2
  38. data/lib/bioroebe/yaml/configuration/browser.yml +1 -1
  39. data/lib/bioroebe/yaml/restriction_enzymes/restriction_enzymes.yml +3 -3
  40. metadata +17 -36
  41. data/doc/setup.rb +0 -1655
  42. data/lib/bioroebe/genbank/genbank_parser.rb +0 -291
  43. data/lib/bioroebe/shell/add.rb +0 -108
  44. data/lib/bioroebe/shell/assign.rb +0 -360
  45. data/lib/bioroebe/shell/chop_and_cut.rb +0 -281
  46. data/lib/bioroebe/shell/constants.rb +0 -166
  47. data/lib/bioroebe/shell/download.rb +0 -335
  48. data/lib/bioroebe/shell/enable_and_disable.rb +0 -158
  49. data/lib/bioroebe/shell/enzymes.rb +0 -310
  50. data/lib/bioroebe/shell/fasta.rb +0 -345
  51. data/lib/bioroebe/shell/gtk.rb +0 -76
  52. data/lib/bioroebe/shell/history.rb +0 -132
  53. data/lib/bioroebe/shell/initialize.rb +0 -217
  54. data/lib/bioroebe/shell/loop.rb +0 -74
  55. data/lib/bioroebe/shell/misc.rb +0 -4341
  56. data/lib/bioroebe/shell/prompt.rb +0 -107
  57. data/lib/bioroebe/shell/random.rb +0 -289
  58. data/lib/bioroebe/shell/reset.rb +0 -335
  59. data/lib/bioroebe/shell/scan_and_parse.rb +0 -135
  60. data/lib/bioroebe/shell/search.rb +0 -337
  61. data/lib/bioroebe/shell/sequences.rb +0 -200
  62. data/lib/bioroebe/shell/show_report_and_display.rb +0 -2901
  63. data/lib/bioroebe/shell/startup.rb +0 -127
  64. data/lib/bioroebe/shell/taxonomy.rb +0 -14
  65. data/lib/bioroebe/shell/tk.rb +0 -23
  66. data/lib/bioroebe/shell/user_input.rb +0 -88
  67. data/lib/bioroebe/shell/xorg.rb +0 -45
@@ -1,337 +0,0 @@
1
- #!/usr/bin/ruby -w
2
- # Encoding: UTF-8
3
- # frozen_string_literal: true
4
- # =========================================================================== #
5
- # require 'bioroebe/shell/search.rb'
6
- # =========================================================================== #
7
- module Bioroebe
8
-
9
- class Shell < ::Bioroebe::CommandlineApplication
10
-
11
- require 'bioroebe/toplevel_methods/matches.rb'
12
- # ========================================================================= #
13
- # === search_sequence_for_open_reading_frames
14
- #
15
- # Use this method to search for Open Reading Frames (i.e. "AUG" codons).
16
- #
17
- # Since we use Bioroebe.start_codon?, this may also default to another
18
- # start codon.
19
- # ========================================================================= #
20
- def search_sequence_for_open_reading_frames(
21
- i = string?,
22
- use_which_frame = :frame1,
23
- use_this_start_codon = ::Bioroebe.start_codon?
24
- )
25
- i.upcase!
26
- if i
27
- if i.include? use_this_start_codon # This asks whether the string includes 'ATG'.
28
- report_n_start_codons # Will report how many Start sequences we have.
29
- e
30
- erev "These can be found (and will start) at these positions):#{N}#{N}"
31
- copy = i.to_s.dup # Work on a copy here.
32
- if use_which_frame == :frame2 # Chop off the first entry then.
33
- copy[0,1] = ''
34
- end
35
- # =================================================================== #
36
- # We will search for both ATG and AUG though, respectively the
37
- # input variants given to us. If the following regex appears to
38
- # be complicated to you, here is the old variant for the regex:
39
- #
40
- # use_this_regex = /(ATG|AUG)/i
41
- #
42
- # =================================================================== #
43
- array_results = []
44
- array_results << Bioroebe.return_array_of_sequence_matches(copy, use_this_start_codon)
45
- if use_this_start_codon.include? 'T'
46
- array_results << Bioroebe.return_array_of_sequence_matches(copy, use_this_start_codon.tr('T','U'))
47
- end
48
- array_results.flatten!
49
- array_results.compact!
50
- # =================================================================== #
51
- # This will hold data such as:
52
- # [16, ["ATG"]]
53
- # At the least up until April 2020, before it was changed.
54
- # =================================================================== #
55
- return array_results
56
- else
57
- []
58
- end
59
- else
60
- ewarn 'It seems as if you have not yet assigned a string.'
61
- ewarn 'You could run "random" to assign a random string.'
62
- end
63
- end
64
-
65
- # ========================================================================= #
66
- # === show_ccaat_sites
67
- #
68
- # Use this method to locate CCAAT sites in the DNA string (the main
69
- # string).
70
- #
71
- # A CCAAT box, sometimes abbreviated a "CAAT box" or a "CAT box",
72
- # is a distinct pattern of nucleotides with the sequence
73
- # "GGCCAATCT" or a sequence similar to that string.
74
- #
75
- # This sequence usually occurs upstream by 60-100 bases to the
76
- # initial transcription start site.
77
- #
78
- # To test this method, you can try:
79
- #
80
- # assign ATTTACGCGCCCGGCCAATCTGGCCGCGTACCCCCCCCCCGGCCAATCTATTTACGCGCCCGGCCAATCTGGCCGCGTACCCCCCCCCCGGCCAATCT; ccaat?
81
- #
82
- # ========================================================================= #
83
- def show_ccaat_sites(
84
- search_for_this_sequence = 'CCAAT' # 'GGCCAATCT'
85
- )
86
- find_this_sequence(search_for_this_sequence)
87
- n_entries = raw_sequence?.scan("#{search_for_this_sequence}").size
88
- erev "The main sequence has #{simp(n_entries)}#{rev} CCAAT sites."
89
- end; alias show_CCAAT_sites show_ccaat_sites # === show_CCAAT_sites
90
-
91
- # ========================================================================= #
92
- # === search_for?
93
- #
94
- # This method can be queried from the interactive-bioshell via:
95
- #
96
- # search_for?
97
- #
98
- # ========================================================================= #
99
- def search_for?
100
- @internal_hash[:search_for]
101
- end
102
-
103
- # ========================================================================= #
104
- # === show_cpg_islands
105
- #
106
- # Use this method to "search" for CpG islands in a sequence. These will
107
- # then be highlighted, sort of.
108
- #
109
- # To invoke this, try:
110
- #
111
- # CG?
112
- #
113
- # ========================================================================= #
114
- def show_cpg_islands
115
- display_nucleotide_sequence(main_sequence?.to_str) {{
116
- colourize_this_subsequence: 'CG'
117
- }}
118
- end
119
-
120
- # ========================================================================= #
121
- # === search_for_known_promoters
122
- #
123
- # This method will attempt to identify promoter elements.
124
- # ========================================================================= #
125
- def search_for_known_promoters
126
- erev 'Next searching for known promoters.'
127
- e
128
- erev "35S Promoter (#{sfancy('TGAGACTTTT')}#{rev}):"
129
- how_many_35S_promoters_are_in_the_sequence =
130
- search_for 'TGAGACTTTT', :be_quiet
131
- if how_many_35S_promoters_are_in_the_sequence > 0
132
- erev 'There appears to be at the least one 35S promoter '\
133
- 'in the target sequence.'
134
- end
135
- end
136
-
137
- # ========================================================================= #
138
- # === search_for (search_for tag)
139
- #
140
- # This method essentially combines the two methods set_search_for()
141
- # and start_search().
142
- # ========================================================================= #
143
- def search_for(
144
- i, be_verbose = true
145
- )
146
- if i.is_a? Array
147
- i = i.join(' ').strip
148
- end
149
- set_search_for(i, be_verbose)
150
- start_search(be_verbose)
151
- end
152
-
153
- # ========================================================================= #
154
- # === run_nls_search
155
- #
156
- # Search the sequence for NLS.
157
- # ========================================================================= #
158
- def run_nls_search
159
- if @aminoacids
160
- erev 'We will try to run a NLS search on '+simp(aminoacids?.to_s)+':'
161
- e
162
- erev " #{sfancy(aminoacids?.to_s)}"
163
- e
164
- ARRAY_NLS_SEQUENCES.each {|sequence|
165
- if @aminoacids.include? sequence
166
- erev 'We found a result for -> '+swarn(sequence)
167
- else
168
- e sfancy(sequence)+' <- This NLS is not included.'
169
- end
170
- }
171
- else
172
- erev 'Please first assign an '+sfancy('aminoacid sequence')+
173
- ' such as by doing:'
174
- e
175
- erev ' set_aminoacids '+
176
- ::Bioroebe.colourize_aa('PAAKRVKLKKKKKKKKKRKKKPPKLKVKVKLKLKAA')
177
- e
178
- end
179
- end
180
-
181
- # ========================================================================= #
182
- # === search_for_tata_consensus_sequence
183
- #
184
- # Use this method to search for a TATA consensus sequence in the target
185
- # string (the so-called "TATA box"). The TATA box is an AT-rich
186
- # sequence that can be found upstream of the transcription start site.
187
- #
188
- # A short overview of this sequence format can be found here:
189
- #
190
- # https://en.wikiversity.org/wiki/Gene_transcriptions/Boxes/TATA#Consensus_sequence
191
- #
192
- # The major consensus sequence is:
193
- #
194
- # 3'-TATAAA-5'
195
- #
196
- # This is just the major one; there are variants of this sequences such as
197
- #
198
- # 3'-TATAAA(A)AAA-5'
199
- #
200
- # And similar variants.
201
- #
202
- # Usage example:
203
- #
204
- # set_string GGGCTATAAAAATTGGGATATAAAATTGTATATA; find_TATA?
205
- #
206
- # ========================================================================= #
207
- def search_for_tata_consensus_sequence
208
- full_sequence = sequence? # Grab hold of the sequence.
209
- # ======================================================================= #
210
- # Next define our TATA box which we will try to discover:
211
- # ======================================================================= #
212
- tata_box_sequence = 'TATAAA'
213
- results = full_sequence.scan(/#{tata_box_sequence}/)
214
- if results.empty?
215
- erev 'Our target string does not include `'+
216
- simp(tata_box_sequence)+rev+'`.'
217
- else
218
- n_results = results.size.to_s # <- Determine how many matches were found.
219
- erev "We did find #{simp(n_results)} "\
220
- "#{sfancy(tata_box_sequence)}#{rev} entries."
221
- erev 'Their starting positions are at:'
222
- array = []
223
- splitted_sequence = full_sequence.split(//)
224
- splitted_sequence.each_with_index {|entry, index|
225
- case entry
226
- when 'T' # This could be a TATA sequence.
227
- # ================================================================= #
228
- # Next we will compare whether the sequence matches.
229
- # ================================================================= #
230
- subsequence = full_sequence[index, tata_box_sequence.size]
231
- if tata_box_sequence == subsequence
232
- array << index # <- Append into our Array here.
233
- end
234
- end
235
- }
236
- e
237
- print ' '
238
- pp array
239
- # ===================================================================== #
240
- # As of May 2016 we will also use find() to find the TATA box.
241
- # ===================================================================== #
242
- e
243
- erev 'We will also show the sequence in a highlighted manner next:'
244
- e
245
- try_to_find_restriction_enzymes_for(tata_box_sequence)
246
- end
247
- end
248
-
249
- # ========================================================================= #
250
- # === ncbi_nucleotide_search_for
251
- # ========================================================================= #
252
- def ncbi_nucleotide_search_for(i = '')
253
- i = '' if i.nil? # Reset to default then, in this case.
254
- i = i.join('+') if i.is_a? Array
255
- i.strip!
256
- _ = 'https://www.ncbi.nlm.nih.gov/'.dup
257
- _ << 'nucgss?term="'+i+'"' unless i.empty? # Use "" quotes to escape shell-code.
258
- erev 'Now opening '+simp(_)+rev
259
- open_in_browser _
260
- end
261
-
262
- # ========================================================================= #
263
- # === start_search (start_search tag)
264
- #
265
- # This will attempt to locate @search_for substring in the main
266
- # nucleotide sequence.
267
- # ========================================================================= #
268
- def start_search(
269
- be_verbose = true
270
- )
271
- case be_verbose
272
- when :be_quiet
273
- be_verbose = false
274
- end
275
- _ = search_for? # Obtain a handle to the sequence we are trying to find.
276
- if _
277
- results = sequence?.scan(_)
278
- if be_verbose
279
- erev "Trying to now find `#{simp(_)}#{rev}`."
280
- pp results
281
- end
282
- msg = "We found `#{simp(results.size.to_s)}#{rev}` entr".dup
283
- if (results.size > 1) or (results.size == 0)
284
- msg << 'ies' # Plural form.
285
- else
286
- msg << 'y' # Singular form.
287
- end
288
- msg << '.'
289
- erev msg
290
- return results.size
291
- else
292
- erev "No value for #{paleturquoise('@search_for')}#{rev} was "\
293
- "set yet. Please set one via invoking:"
294
- e
295
- erev ' set_search_for'
296
- e
297
- end
298
- end
299
-
300
- # ========================================================================= #
301
- # === search_for_nucleotide_sequence
302
- #
303
- # This method will use the NCBI interface to search for
304
- # nucleotide sequences.
305
- #
306
- # Usage example:
307
- #
308
- # snuc lady slipper orchid
309
- #
310
- # ========================================================================= #
311
- def search_for_nucleotide_sequence(i)
312
- i = i.join '+' if i.is_a? Array
313
- open_in_browser "https://www.ncbi.nlm.nih.gov/nucgss?term=#{i}"
314
- end
315
-
316
- # ========================================================================= #
317
- # === set_search_for
318
- #
319
- # This setter-method can be used to designate for which subsequence
320
- # we may search-for, if this is necessary, e. g. to detect "AUG"
321
- # in a sequence of "GGCAUGGGC".
322
- # ========================================================================= #
323
- def set_search_for(
324
- i, be_verbose = true
325
- )
326
- case be_verbose
327
- when :be_quiet
328
- be_verbose = false
329
- end
330
- i = i.join if i.is_a? Array
331
- if be_verbose
332
- erev "We will now search for: #{simp(i.to_s)}" if i
333
- end
334
- @internal_hash[:search_for] = i
335
- end; alias set_search_string set_search_for # === set_search_string
336
-
337
- end; end
@@ -1,200 +0,0 @@
1
- #!/usr/bin/ruby -w
2
- # Encoding: UTF-8
3
- # frozen_string_literal: true
4
- # =========================================================================== #
5
- # require 'bioroebe/shell/sequence.rb'
6
- # =========================================================================== #
7
- module Bioroebe
8
-
9
- class Shell < ::Bioroebe::CommandlineApplication
10
-
11
- # ========================================================================= #
12
- # === dna_sequence? (string? tag)
13
- #
14
- # Return the DNA sequence in question.
15
- #
16
- # Must always return a String.
17
- #
18
- # Several aliases exist. It is recommended to use the more explicit name,
19
- # since this will more accurately reflect the name (and intent) of this
20
- # method.
21
- # ========================================================================= #
22
- def dna_sequence?
23
- @internal_hash[:array_dna_sequence].last.to_str
24
- end; alias dna_string? dna_sequence? # === dna_string?
25
- alias dna_string? dna_sequence? # === dna_string?
26
- alias seq? dna_sequence? # === seq?
27
- alias sequence_1 dna_sequence? # === sequence_1
28
- alias seq1 dna_sequence? # === seq1
29
- alias seq1? dna_sequence? # === seq1?
30
- alias dna_seq? dna_sequence? # === dna_seq?
31
- alias string? dna_sequence? # === string?
32
- alias main_string? dna_sequence? # === main_string?
33
- alias nucleotide_sequence? dna_sequence? # === nucleotide_sequence?
34
- alias sequence_as_string? dna_sequence? # === sequence_as_string?
35
- alias dna_sequence_as_string? dna_sequence? # === dna_sequence_as_string?
36
- alias dna_sequence_object_as_string? dna_sequence? # === dna_sequence_object_as_string?
37
-
38
- # ========================================================================= #
39
- # === return_dna_sequence_as_sequence_object
40
- #
41
- # This method will always return the main "sequence object" in question,
42
- # which is (almost always) a DNA sequence (dsDNA).
43
- # ========================================================================= #
44
- def return_dna_sequence_as_sequence_object
45
- @internal_hash[:array_dna_sequence].last
46
- end; alias main_sequence? return_dna_sequence_as_sequence_object # === main_sequence?
47
- alias dna_sequence_object? return_dna_sequence_as_sequence_object # === dna_sequence_object?
48
- alias sequence_object? return_dna_sequence_as_sequence_object # === sequence_object?
49
- alias sequence? return_dna_sequence_as_sequence_object # === sequence?
50
- alias seq_object? return_dna_sequence_as_sequence_object # === seq_object?
51
- alias sequence return_dna_sequence_as_sequence_object # === sequence (sequence? tag)
52
- alias seq_obj? return_dna_sequence_as_sequence_object # === seq_obj?
53
-
54
- # ========================================================================= #
55
- # === dna_sequences?
56
- # ========================================================================= #
57
- def dna_sequences?
58
- @internal_hash[:array_dna_sequence]
59
- end
60
-
61
- # ========================================================================= #
62
- # === is_any_nucleotide_assigned?
63
- # ========================================================================= #
64
- def is_any_nucleotide_assigned?
65
- !sequence_object?.empty? # If the sequence is not empty, it is assigned.
66
- end
67
-
68
- # ========================================================================= #
69
- # === assign_sequence
70
- # ========================================================================= #
71
- def assign_sequence(
72
- i, be_verbose = true
73
- )
74
- case be_verbose
75
- when :be_silent
76
- be_verbose = false
77
- end
78
- if be_verbose
79
- e 'Now assigning a sequence.'
80
- end
81
- set_sequence(i)
82
- end
83
-
84
- # ========================================================================= #
85
- # === sequence?
86
- # ========================================================================= #
87
- def sequence?
88
- @sequence
89
- end; alias dna_sequence? sequence? # === dna_sequence?
90
-
91
- # ========================================================================= #
92
- # === sequence3
93
- # ========================================================================= #
94
- def sequence_3
95
- @sequence_3.to_str
96
- end; alias seq3 sequence_3 # === seq3
97
- alias seq3? sequence_3 # === seq3?
98
-
99
- # ========================================================================= #
100
- # === sequence4
101
- # ========================================================================= #
102
- def sequence_4
103
- @sequence_4.to_str
104
- end; alias seq4 sequence_4 # === seq4
105
- alias seq4? sequence_4 # === seq4?
106
-
107
- # ========================================================================= #
108
- # === sequence5
109
- # ========================================================================= #
110
- def sequence_5
111
- @sequence_5.to_str
112
- end; alias seq5 sequence_5 # === seq5
113
- alias seq5? sequence_5 # === seq5?
114
-
115
- # ========================================================================= #
116
- # === sequence6
117
- # ========================================================================= #
118
- def sequence_6
119
- @sequence_6.to_str
120
- end; alias seq6 sequence_6 # === seq6
121
- alias seq6? sequence_6 # === seq6?
122
-
123
- # ========================================================================= #
124
- # === sequence2
125
- # ========================================================================= #
126
- def sequence_2
127
- @sequence_2.to_str
128
- end; alias seq2 sequence_2 # === seq2
129
- alias seq2? sequence_2 # === seq2?
130
-
131
- # ========================================================================= #
132
- # === set_sequence_2
133
- # ========================================================================= #
134
- def set_sequence_2(i = '')
135
- i = i.join(' ').strip if i.is_a? Array
136
- i.delete!(N)
137
- i = i.to_str unless i.is_a? String
138
- @sequence_2 = ::Bioroebe.sequence(i)
139
- end
140
-
141
- # ========================================================================= #
142
- # === set_sequence_3
143
- # ========================================================================= #
144
- def set_sequence_3(i = '')
145
- i = i.join(' ').strip if i.is_a? Array
146
- i.delete!(N)
147
- i = i.to_str unless i.is_a? String
148
- @sequence_3 = ::Bioroebe.sequence(i)
149
- end
150
-
151
- # ========================================================================= #
152
- # === set_sequence_4
153
- # ========================================================================= #
154
- def set_sequence_4(i = '')
155
- i = i.join(' ').strip if i.is_a? Array
156
- i.delete!(N)
157
- i = i.to_str unless i.is_a? String
158
- @sequence_4 = ::Bioroebe.sequence(i)
159
- end
160
-
161
- # ========================================================================= #
162
- # === set_sequence_5
163
- # ========================================================================= #
164
- def set_sequence_5(i = '')
165
- i = i.join(' ').strip if i.is_a? Array
166
- i.delete!(N)
167
- i = i.to_str unless i.is_a? String
168
- @sequence_5 = ::Bioroebe.sequence(i)
169
- end
170
-
171
- # ========================================================================= #
172
- # === set_sequence_6
173
- # ========================================================================= #
174
- def set_sequence_6(i = '')
175
- i = i.join(' ').strip if i.is_a? Array
176
- i.delete!(N)
177
- i = i.to_str unless i.is_a? String
178
- @sequence_6 = ::Bioroebe.sequence(i)
179
- end
180
-
181
- require 'bioroebe/codons/codons.rb'
182
- # ========================================================================= #
183
- # === aminoacid_sequence?
184
- #
185
- # This here will return the most likely aminoacid sequence of the target
186
- # main sequence.
187
- # ========================================================================= #
188
- # def aminoacid_sequence?(
189
- # main_sequence = @sequence
190
- # )
191
- # if main_sequence.respond_to? :sequence?
192
- # main_sequence = main_sequence.sequence?
193
- # end
194
- # _ = ::Bioroebe.dna_to_aa(
195
- # main_sequence
196
- # )
197
- # return _ # .join.strip
198
- # end
199
-
200
- end; end