prawn 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/COPYING +340 -0
  2. data/LICENSE +56 -0
  3. data/README +30 -0
  4. data/Rakefile +83 -0
  5. data/data/fonts/Activa.ttf +0 -0
  6. data/data/fonts/Chalkboard.ttf +0 -0
  7. data/data/fonts/Courier-Bold.afm +342 -0
  8. data/data/fonts/Courier-BoldOblique.afm +342 -0
  9. data/data/fonts/Courier-Oblique.afm +342 -0
  10. data/data/fonts/Courier.afm +342 -0
  11. data/data/fonts/DejaVuSans.ttf +0 -0
  12. data/data/fonts/Dustismo_Roman.ttf +0 -0
  13. data/data/fonts/Helvetica-Bold.afm +2827 -0
  14. data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
  15. data/data/fonts/Helvetica-Oblique.afm +3051 -0
  16. data/data/fonts/Helvetica.afm +3051 -0
  17. data/data/fonts/MustRead.html +19 -0
  18. data/data/fonts/Symbol.afm +213 -0
  19. data/data/fonts/Times-Bold.afm +2588 -0
  20. data/data/fonts/Times-BoldItalic.afm +2384 -0
  21. data/data/fonts/Times-Italic.afm +2667 -0
  22. data/data/fonts/Times-Roman.afm +2419 -0
  23. data/data/fonts/ZapfDingbats.afm +225 -0
  24. data/data/fonts/comicsans.ttf +0 -0
  25. data/data/fonts/gkai00mp.ttf +0 -0
  26. data/data/images/dice.png +0 -0
  27. data/data/images/pigs.jpg +0 -0
  28. data/data/images/ruport.png +0 -0
  29. data/data/images/ruport_data.dat +0 -0
  30. data/data/images/ruport_transparent.png +0 -0
  31. data/data/images/stef.jpg +0 -0
  32. data/data/shift_jis_text.txt +1 -0
  33. data/examples/addressbook.csv +6 -0
  34. data/examples/alignment.rb +16 -0
  35. data/examples/bounding_boxes.pdf +62 -0
  36. data/examples/bounding_boxes.rb +30 -0
  37. data/examples/canvas.pdf +81 -0
  38. data/examples/canvas.rb +12 -0
  39. data/examples/cell.rb +27 -0
  40. data/examples/currency.csv +1834 -0
  41. data/examples/curves.rb +10 -0
  42. data/examples/fancy_table.rb +48 -0
  43. data/examples/font_size.rb +19 -0
  44. data/examples/hexagon.rb +14 -0
  45. data/examples/image.pdf +0 -0
  46. data/examples/image.rb +23 -0
  47. data/examples/image2.rb +13 -0
  48. data/examples/inline_styles.pdf +117 -0
  49. data/examples/kerning.rb +27 -0
  50. data/examples/line.rb +31 -0
  51. data/examples/multi_page_layout.rb +14 -0
  52. data/examples/on_page_start.rb +17 -0
  53. data/examples/page_geometry.rb +28 -0
  54. data/examples/polygons.rb +16 -0
  55. data/examples/ruport_formatter.rb +47 -0
  56. data/examples/ruport_helpers.rb +17 -0
  57. data/examples/russian_boxes.rb +34 -0
  58. data/examples/simple_text.rb +15 -0
  59. data/examples/simple_text_ttf.rb +16 -0
  60. data/examples/sjis.rb +19 -0
  61. data/examples/table.rb +45 -0
  62. data/examples/table_bench.rb +92 -0
  63. data/examples/text_flow.rb +65 -0
  64. data/examples/utf8.rb +12 -0
  65. data/lib/prawn.rb +33 -0
  66. data/lib/prawn/compatibility.rb +33 -0
  67. data/lib/prawn/document.rb +334 -0
  68. data/lib/prawn/document/bounding_box.rb +253 -0
  69. data/lib/prawn/document/page_geometry.rb +78 -0
  70. data/lib/prawn/document/table.rb +253 -0
  71. data/lib/prawn/document/text.rb +346 -0
  72. data/lib/prawn/errors.rb +33 -0
  73. data/lib/prawn/font.rb +5 -0
  74. data/lib/prawn/font/cmap.rb +59 -0
  75. data/lib/prawn/font/metrics.rb +414 -0
  76. data/lib/prawn/font/wrapping.rb +45 -0
  77. data/lib/prawn/graphics.rb +285 -0
  78. data/lib/prawn/graphics/cell.rb +226 -0
  79. data/lib/prawn/images.rb +241 -0
  80. data/lib/prawn/images/jpg.rb +43 -0
  81. data/lib/prawn/images/png.rb +178 -0
  82. data/lib/prawn/pdf_object.rb +64 -0
  83. data/lib/prawn/reference.rb +47 -0
  84. data/spec/bounding_box_spec.rb +120 -0
  85. data/spec/box_calculation_spec.rb +17 -0
  86. data/spec/document_spec.rb +152 -0
  87. data/spec/graphics_spec.rb +250 -0
  88. data/spec/images_spec.rb +42 -0
  89. data/spec/jpg_spec.rb +25 -0
  90. data/spec/metrics_spec.rb +60 -0
  91. data/spec/pdf_object_spec.rb +102 -0
  92. data/spec/png_spec.rb +35 -0
  93. data/spec/reference_spec.rb +29 -0
  94. data/spec/spec_helper.rb +29 -0
  95. data/spec/table_spec.rb +145 -0
  96. data/spec/text_spec.rb +190 -0
  97. data/vendor/font_ttf/ttf.rb +20 -0
  98. data/vendor/font_ttf/ttf/datatypes.rb +189 -0
  99. data/vendor/font_ttf/ttf/encodings.rb +140 -0
  100. data/vendor/font_ttf/ttf/exceptions.rb +28 -0
  101. data/vendor/font_ttf/ttf/file.rb +290 -0
  102. data/vendor/font_ttf/ttf/fontchunk.rb +77 -0
  103. data/vendor/font_ttf/ttf/table/cmap.rb +408 -0
  104. data/vendor/font_ttf/ttf/table/cvt.rb +49 -0
  105. data/vendor/font_ttf/ttf/table/fpgm.rb +48 -0
  106. data/vendor/font_ttf/ttf/table/gasp.rb +88 -0
  107. data/vendor/font_ttf/ttf/table/glyf.rb +452 -0
  108. data/vendor/font_ttf/ttf/table/head.rb +86 -0
  109. data/vendor/font_ttf/ttf/table/hhea.rb +96 -0
  110. data/vendor/font_ttf/ttf/table/hmtx.rb +98 -0
  111. data/vendor/font_ttf/ttf/table/kern.rb +186 -0
  112. data/vendor/font_ttf/ttf/table/loca.rb +75 -0
  113. data/vendor/font_ttf/ttf/table/maxp.rb +81 -0
  114. data/vendor/font_ttf/ttf/table/name.rb +222 -0
  115. data/vendor/font_ttf/ttf/table/os2.rb +172 -0
  116. data/vendor/font_ttf/ttf/table/post.rb +120 -0
  117. data/vendor/font_ttf/ttf/table/prep.rb +27 -0
  118. data/vendor/font_ttf/ttf/table/vhea.rb +45 -0
  119. data/vendor/font_ttf/ttf/table/vmtx.rb +36 -0
  120. metadata +180 -0
@@ -0,0 +1,86 @@
1
+ # TTF/Ruby, a library to read and write TrueType fonts in Ruby.
2
+ # Copyright (C) 2006 Mathieu Blondel
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ module Font
19
+ module TTF
20
+ module Table
21
+
22
+ # Head is the font header table, which gives global informations about the font.
23
+ class Head < Font::TTF::FontChunk
24
+
25
+ LONG_FORMAT = 1
26
+ SHORT_FORMAT = 0
27
+
28
+ attr_accessor :version, :font_revision, :check_sum_adjustment,
29
+ :magic_number, :flags, :units_per_em, :created,
30
+ :modified, :x_min, :y_min, :x_max, :y_max, :mac_style,
31
+ :lowest_rec_ppem, :font_direction_hint,
32
+ :index_to_loc_format, :glyph_data_format
33
+
34
+ def initialize(*args)
35
+ super(*args)
36
+
37
+ if exists_in_file?
38
+ @font.at_offset(@offset) do
39
+ @version = @font.read_fixed
40
+ @font_revision = @font.read_fixed
41
+ @check_sum_adjustment = @font.read_ulong
42
+ @magic_number = @font.read_ulong
43
+ @flags = @font.read_ushort
44
+ @units_per_em = @font.read_ushort
45
+ @created = @font.read_long_date_time
46
+ @modified = @font.read_long_date_time
47
+ @x_min = @font.read_fword
48
+ @y_min = @font.read_fword
49
+ @x_max = @font.read_fword
50
+ @y_max = @font.read_fword
51
+ @mac_style = @font.read_ushort
52
+ @lowest_rec_ppem = @font.read_ushort
53
+ @font_direction_hint = @font.read_short
54
+ @index_to_loc_format = @font.read_short
55
+ @glyph_data_format = @font.read_short
56
+ end
57
+ end
58
+ end
59
+
60
+ # Dumps the head table in binary raw format as may be found in a font
61
+ # file.
62
+ def dump
63
+ raw = (@version || 0).to_fixed
64
+ raw += (@font_revision || 0).to_fixed
65
+ raw += (@check_sum_adjustment || 0).to_ulong
66
+ raw += (@magic_number || 0).to_ulong
67
+ raw += (@flags || 0).to_ushort
68
+ raw += (@units_per_em || 0).to_ushort
69
+ raw += (@created || "").to_long_date_time
70
+ raw += (@modified || "").to_long_date_time
71
+ raw += (@x_min || 0).to_fword
72
+ raw += (@y_min || 0).to_fword
73
+ raw += (@x_max || 0).to_fword
74
+ raw += (@y_max || 0).to_fword
75
+ raw += (@mac_style || 0).to_ushort
76
+ raw += (@lowest_rec_ppem || 0).to_ushort
77
+ raw += (@font_direction_hint || 0).to_short
78
+ raw += (@index_to_loc_format || 0).to_short
79
+ raw += (@glyph_data_format || 0).to_short
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,96 @@
1
+ # TTF/Ruby, a library to read and write TrueType fonts in Ruby.
2
+ # Copyright (C) 2006 Mathieu Blondel
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ module Font
19
+ module TTF
20
+ module Table
21
+
22
+ # Hea is a base class for Hhea and Vhea.
23
+ class Hea < Font::TTF::FontChunk
24
+
25
+ attr_accessor :version, :ascender, :descender, :line_gap,
26
+ :advance_max, :min_side_bearing_1,
27
+ :min_side_bearing_2, :max_extent,
28
+ :caret_slope_rise, :caret_slope_run,
29
+ :metric_data_format, :number_of_metrics
30
+
31
+ def initialize(*args)
32
+ super(*args)
33
+
34
+ if exists_in_file?
35
+ @font.at_offset(@offset) do
36
+ @version = @font.read_fixed
37
+ @ascender = @font.read_fword
38
+ @descender = @font.read_fword
39
+ @line_gap = @font.read_fword
40
+ @advance_max = @font.read_ufword
41
+ @min_side_bearing_1 = @font.read_fword
42
+ @min_side_bearing_2 = @font.read_fword
43
+ @max_extent = @font.read_fword
44
+ @caret_slope_rise = @font.read_short
45
+ @caret_slope_run = @font.read_short
46
+ 5.times { @font.read_fword } # reserved, unused fields
47
+ @metric_data_format = @font.read_short
48
+ @number_of_metrics = @font.read_ushort
49
+ end
50
+ end
51
+ end
52
+
53
+ # Dumps the hhea table in binary raw format as may be found in a font
54
+ # file.
55
+ def dump
56
+ raw = (@version || 0).to_fixed
57
+ raw += (@ascender || 0).to_fword
58
+ raw += (@descender || 0).to_fword
59
+ raw += (@line_grap || 0).to_fword
60
+ raw += (@advance_max || 0).to_ufword
61
+ raw += (@min_side_bearing_1 || 0).to_fword
62
+ raw += (@min_side_bearing_2 || 0).to_fword
63
+ raw += (@max_extent || 0).to_fword
64
+ raw += (@caret_slope_rise || 0).to_short
65
+ raw += (@caret_slope_run || 0).to_short
66
+ 5.times { raw += 0.to_fword } # reserved, unused fields
67
+ raw += (@metric_data_format || 0).to_short
68
+ raw += (@number_of_metrics || 0).to_ushort
69
+ end
70
+
71
+ end
72
+
73
+ # Hhea is the Horizontal header table.
74
+ class Hhea < Hea
75
+
76
+ alias :advance_width_max :advance_max
77
+ alias :min_left_side_bearing :min_side_bearing_1
78
+ alias :min_right_side_bearing :min_side_bearing_2
79
+ alias :x_max_extent :max_extent
80
+ alias :number_of_hmetrics :number_of_metrics
81
+
82
+ alias :advance_width_max= :advance_max=
83
+ alias :min_left_side_bearing= :min_side_bearing_1=
84
+ alias :min_right_side_bearing= :min_side_bearing_2=
85
+ alias :x_max_extent= :max_extent=
86
+ alias :number_of_hmetrics= :number_of_metrics=
87
+
88
+ def initialize(*args)
89
+ super(*args)
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,98 @@
1
+ # TTF/Ruby, a library to read and write TrueType fonts in Ruby.
2
+ # Copyright (C) 2006 Mathieu Blondel
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ module Font
19
+ module TTF
20
+ module Table
21
+
22
+ # Mtx is a base class for Hmtx and Vmtx.
23
+ class Mtx < Font::TTF::FontChunk
24
+
25
+ def initialize(*args)
26
+ super(*args)
27
+
28
+ if self.tag == :hmtx
29
+ @hea = :hhea
30
+ else
31
+ @hea = :vhea
32
+ end
33
+
34
+ if exists_in_file?
35
+ @font.at_offset(@offset) do
36
+ @metrics = []
37
+
38
+ num_metrics = @font.get_table(@hea).number_of_metrics
39
+ num_metrics.times do
40
+ @metrics << [@font.read_ufword, @font.read_fword]
41
+ end
42
+
43
+ @side_bearings = []
44
+
45
+ (@font.get_table(:maxp).num_glyphs - num_metrics).times do
46
+ @side_bearings << @font.read_fword
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ # Returns an Array of [advance_width, left/top_side_bearing] pairs.
53
+ def metrics
54
+ last_aw = @metrics.last[0]
55
+ @metrics + @side_bearings.collect { |sb| [last_aw, sb] }
56
+ end
57
+
58
+ # Sets metrics.
59
+ def metrics=(mtrx)
60
+ len = mtrx.length
61
+ raise "Number of (h/v)metrics must be equal to number of glyphs" \
62
+ if len != @font.get_table(:maxp).num_glyphs
63
+ @font.get_table(@hea).number_of_metrics = len
64
+ @side_bearings = []
65
+ @metrics = mtrx
66
+ end
67
+
68
+ # Dumps the (h/v)mtx table in binary raw format as may be found in a font
69
+ # file.
70
+ def dump
71
+ raw = ""
72
+ (@metrics || []).each do |advanced_width, side_bearing|
73
+ raw += advanced_width.to_ufword
74
+ raw += side_bearing.to_fword
75
+ end
76
+ (@side_bearings || []).each do |side_bearing|
77
+ raw += side_bearing.to_fword
78
+ end
79
+ raw
80
+ end
81
+
82
+ end
83
+
84
+ # Hmtx is the horizontal metrics table.
85
+ class Hmtx < Mtx
86
+
87
+ alias :hmetrics :metrics
88
+ alias :hmetrics= :metrics=
89
+
90
+ def initialize(*args)
91
+ super(*args)
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,186 @@
1
+ # TTF/Ruby, a library to read and write TrueType fonts in Ruby.
2
+ # Copyright (C) 2006 Mathieu Blondel
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ module Font
19
+ module TTF
20
+ module Table
21
+
22
+ # Kern is the Kerning table, which contains values for intercharacter spacing.
23
+ class Kern < Font::TTF::FontChunk
24
+
25
+ # KerningSubtable is a base class for KerningSubtable0 and KerningSubtable2.
26
+ class KerningSubtable < Font::TTF::FontChunk
27
+
28
+ HORIZONTAL = 0b1
29
+ MINIMUM = 0b10
30
+ CROSS_STREAM = 0b100
31
+ OVERRIDE = 0b1000
32
+
33
+ attr_accessor :version, :coverage
34
+
35
+ def initialize(table, offs_from_table=nil, length=nil)
36
+
37
+ if not offs_from_table.nil? and not length.nil?
38
+ super(table.font, table.offset + offs_from_table, length)
39
+ @font.at_offset(@offset) do
40
+ @version = @font.read_ushort
41
+ @length = @font.read_ushort
42
+ @coverage = @font.read_ushort
43
+ end
44
+ end
45
+ end
46
+
47
+ # Returns the format (Fixnum) of the KerningSubtable.
48
+ def format
49
+ @coverage >> 8
50
+ end
51
+ end
52
+
53
+ # KerningTable in format 0.
54
+ class KerningSubtable0 < KerningSubtable
55
+
56
+ KerningPair = Struct.new(:left, :right, :value)
57
+ KERNING_PAIR_SIZE = 2 * IO::SIZEOF_USHORT + IO::SIZEOF_FWORD
58
+
59
+ # An Array of KerningPair structures.
60
+ attr_accessor :kerning_pairs
61
+
62
+ def initialize(*args)
63
+ super(*args)
64
+
65
+ @kerning_pairs = []
66
+
67
+ if exists_in_file?
68
+ @font.at_offset(@offset + 3 * IO::SIZEOF_USHORT) do
69
+ @num_pairs = @font.read_ushort
70
+ @search_range = @font.read_ushort
71
+ @entry_selector = @font.read_ushort
72
+ @range_shift = @font.read_ushort
73
+
74
+ @num_pairs.times do
75
+ kp = KerningPair.new
76
+ kp.left = @font.read_ushort
77
+ kp.right = @font.read_ushort
78
+ kp.value = @font.read_fword
79
+ @kerning_pairs << kp
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ def update_for_search!
87
+ res = 1
88
+ power = 0
89
+ while res <= @kerning_pairs.length
90
+ res *= 2
91
+ power += 1
92
+ end
93
+ @search_range = res * KERNING_PAIR_SIZE
94
+ @entry_selector = power - 1
95
+ @range_shift = (@kerning_pairs.length - res) * KERNING_PAIR_SIZE
96
+ end
97
+ private :update_for_search!
98
+
99
+ def dump
100
+ update_for_search!
101
+ raw = (@version || 0).to_ushort
102
+ len = 7 * IO::SIZEOF_USHORT + \
103
+ @kerning_pairs.length * KERNING_PAIR_SIZE
104
+ raw += len.to_ushort
105
+ raw += (@coverage || 1).to_ushort
106
+ raw += @kerning_pairs.length.to_ushort
107
+ raw += @search_range.to_ushort
108
+ raw += @entry_selector.to_ushort
109
+ raw += @range_shift.to_ushort
110
+ @kerning_pairs.each do |kp|
111
+ raw += kp.left.to_ushort
112
+ raw += kp.right.to_ushort
113
+ raw += kp.value.to_fword
114
+ end
115
+ raw
116
+ end
117
+
118
+ end
119
+
120
+ # KerningTable in format 2. Not implemented.
121
+ class KerningSubtable2 < KerningSubtable
122
+
123
+ end
124
+
125
+ # An Array of KerningSubtable (KerningSubtable0 or KerningSubtable2)
126
+ # objects.
127
+ attr_accessor :subtables
128
+
129
+ def initialize(*args)
130
+ super(*args)
131
+
132
+ @subtables = []
133
+
134
+ if exists_in_file?
135
+ @font.at_offset(@offset) do
136
+ @version = @font.read_ushort
137
+ @num_tables = @font.read_ushort
138
+ end
139
+
140
+ offs = 2 * IO::SIZEOF_USHORT
141
+ @num_tables.times do
142
+ @font.at_offset(@offset + offs) do
143
+ version = @font.read_ushort
144
+ length = @font.read_ushort
145
+ coverage = @font.read_ushort
146
+
147
+ @subtables << case coverage >> 8
148
+ when 0
149
+ KerningSubtable0.new(self, offs, length)
150
+ when 2
151
+ KerningSubtable2.new(self, offs, length)
152
+ end
153
+ offs += length
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ # Returns an empty kerning subtable in format 0 that then may be added to
160
+ # the subtables array.
161
+ def get_new_kerning_subtable0
162
+ KerningSubtable0.new(self)
163
+ end
164
+
165
+ # Returns an empty kerning subtable in format 2 that then may be added to
166
+ # the subtables array.
167
+ def get_new_kerning_subtable2
168
+ KerningSubtable2.new(self)
169
+ end
170
+
171
+ # Dumps the kern table in binary raw format as may be found in a font
172
+ # file.
173
+ def dump
174
+ raw = (@version || 0).to_ushort
175
+ raw += @subtables.length.to_ushort
176
+ @subtables.each do |subtbl|
177
+ raw += subtbl.dump
178
+ end
179
+ raw
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+ end
186
+ end