windows-pr 0.2.0 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,6 +1,51 @@
1
+ = 0.5.3 - 10-Aug-2006
2
+ * Added wide character functions to the EventLog module.
3
+ * Added a test suite for the EventLog module.
4
+ * Fixed method wrapper for MapViewOfFileEx.
5
+ * Finer grained method wrapping/checking for the Windows::Registry module (the
6
+ RegSaveKeyEx might not be defined).
7
+
8
+ = 0.5.2 - 29-Jul-2006
9
+ * Prototype fixes/changes for CreateProcess, GlobalLock, GlobalMemoryStatusEx,
10
+ and CreateFileMapping.
11
+ * Finer grained method wrapping/checking for the Windows::Process module (only
12
+ two methods might not be defined).
13
+ * Added method wrappers for the Handle constants.
14
+ * Added mmap related methods and constants.
15
+ * Added more test cases.
16
+ * Added wide character methods to the Windows::Directory class.
17
+ * Added wide character helper methods.
18
+ * Added a few more methods to MSVCRT::String.
19
+
20
+ = 0.5.1 - 26-May-2006
21
+ * Minor updates and fixes for the Unicode and DeviceIO modules.
22
+ * Added some wide character support, based on $KCODE values (which should
23
+ not be used at this time).
24
+
25
+ = 0.5.0 - 23-May-2006
26
+ * Added the Registry module
27
+ * Added the EventLog module
28
+ * Added the National module
29
+ * Added the SystemInfo module
30
+
31
+ = 0.4.0 - 7-May-2006
32
+ * Bug fix for the WaitForMultipleObjects method in synchronize.rb
33
+ * Added the Window module (just a few constants for now)
34
+ * Added the Console module (AttachConsole, etc)
35
+ * Added the Library module (LoadLibrary, etc)
36
+ * Added the Directory module (CreateDirectory, etc)
37
+ * Added the Shell module (some constants, a few methods for now)
38
+ * Added the Unicode module (WideCharToMultiByte, etc)
39
+ * Added process creation, priority and startf flags to the Process module
40
+
41
+ = 0.3.0 - 22-Apr-2006
42
+ * Added the Limits module.
43
+ * Added the Security module.
44
+ * Fixed a signature bug in the MSVCRT/Buffer module.
45
+
1
46
  = 0.2.0 - 13-Apr-2006
2
- * Added the filesystem module.
3
- * Fixed signature and dll mistakes in the file module.
47
+ * Added the FileSystem module.
48
+ * Fixed signature and dll mistakes in the File module.
4
49
 
5
50
  = 0.1.0 - 4-Apr-2006
6
51
  * Initial release
data/MANIFEST CHANGED
@@ -7,15 +7,28 @@ windows-pr.gemspec
7
7
  doc/conversion_guide.txt
8
8
 
9
9
  lib/windows/clipboard.rb
10
+ lib/windows/console.rb
10
11
  lib/windows/device_io.rb
12
+ lib/windows/directory.rb
11
13
  lib/windows/error.rb
14
+ lib/windows/eventlog.rb
12
15
  lib/windows/file.rb
13
16
  lib/windows/filesystem.rb
14
17
  lib/windows/handle.rb
18
+ lib/windows/library.rb
19
+ lib/windows/limits.rb
15
20
  lib/windows/memory.rb
21
+ lib/windows/national.rb
16
22
  lib/windows/path.rb
23
+ lib/windows/process.rb
24
+ lib/windows/registry.rb
25
+ lib/windows/security.rb
26
+ lib/windows/shell.rb
17
27
  lib/windows/sound.rb
18
28
  lib/windows/synchronize.rb
29
+ lib/windows/system_info.rb
30
+ lib/windows/unicode.rb
31
+ lib/windows/window.rb
19
32
 
20
33
  lib/windows/msvcrt/buffer.rb
21
34
  lib/windows/msvcrt/file.rb
data/README CHANGED
@@ -45,6 +45,17 @@
45
45
  file contains clipboard related functions, such as CloseClipboard(), as
46
46
  well as constants such as CF_TEXT, CF_BITMAP, etc.
47
47
 
48
+ == Wide character functions
49
+ I decided that the $KCODE handling was a bad idea, so most of the $KCODE
50
+ handling has been removed. The only methods that change their behavior
51
+ based on $KCODE are the multi_to_wide and wide_to_multi helper methods
52
+ in the Windows::Unicode module. If $KCODE is set to UTF8, then the code
53
+ point used is CP_UTF8. Otherwise, CP_ACP is used.
54
+
55
+ In the future I'll add the wide character functions explicitly. I haven't
56
+ added many yet (as of 29-Jul-2006) but I plan on adding as many as I can
57
+ as time permits.
58
+
48
59
  == Where are the tests, dude?
49
60
  While I've made some effort to test these functions, there are simply too
50
61
  many for me to effectively test them all. We're ultimately talking about
@@ -12,7 +12,7 @@ LPDWORD => 'P'
12
12
  LPTSTR => 'P'
13
13
  UINT => 'I'
14
14
  VOID => 'V'
15
- WORD => 'I'
15
+ WORD => 'I'
16
16
 
17
17
  = C Data Types
18
18
  void => 'V'
@@ -20,6 +20,6 @@ void* => 'P'
20
20
  char* => 'P'
21
21
  const char* => 'L'
22
22
  int => 'I'
23
- long => 'L'
23
+ long => 'L'
24
24
  struct => 'P'
25
25
  struct* => 'P'
@@ -1,36 +1,3 @@
1
- #############################################################################
2
- # clipboard.rb
3
- #
4
- # Includes the following functions:
5
- #
6
- # CloseClipboard()
7
- # CoundClipboardFormats()
8
- # EmptyClipboard()
9
- # EnumClipboardFormats()
10
- # GetClipboardData()
11
- # GetClipboardFormatName()
12
- # IsClipboardFormatAvailable()
13
- # OpenClipboard()
14
- # RegisterClipboardFormat()
15
- # SetClipboardData()
16
- #
17
- # Defines the following constants:
18
- #
19
- # CF_TEXT
20
- # CF_BITMAP
21
- # CF_METAFILEPICT
22
- # CF_SYLK
23
- # CF_DIF
24
- # CF_TIFF
25
- # CF_OEMTEXT
26
- # CF_DIB
27
- # CF_PALETTE
28
- # CF_PENDATA
29
- # CF_RIFF
30
- # CF_WAVE
31
- # CF_UNICODETEXT
32
- # CF_ENHMETAFILE
33
- #############################################################################
34
1
  require 'Win32API'
35
2
 
36
3
  module Windows
@@ -0,0 +1,323 @@
1
+ require 'Win32API'
2
+
3
+ module Windows
4
+ module Console
5
+ CTRL_C_EVENT = 0
6
+ CTRL_BREAK_EVENT = 1
7
+ CTRL_LOGOFF_EVENT = 5
8
+ CTRL_SHUTDOWN_EVENT = 6
9
+
10
+ ENABLE_PROCESSED_INPUT = 0x0001
11
+ ENABLE_LINE_INPUT = 0x0002
12
+ ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002
13
+ ENABLE_ECHO_INPUT = 0x0004
14
+ ENABLE_WINDOW_INPUT = 0x0008
15
+ ENABLE_MOUSE_INPUT = 0x0010
16
+ ENABLE_INSERT_MODE = 0x0020
17
+ ENABLE_QUICK_EDIT_MODE = 0x0040
18
+
19
+ STD_INPUT_HANDLE = -10
20
+ STD_OUTPUT_HANDLE = -11
21
+ STD_ERROR_HANDLE = -12
22
+
23
+ # Console window constants
24
+ FOREGROUND_BLUE = 0x0001
25
+ FOREGROUND_GREEN = 0x0002
26
+ FOREGROUND_RED = 0x0004
27
+ FOREGROUND_INTENSITY = 0x0008
28
+ BACKGROUND_BLUE = 0x0010
29
+ BACKGROUND_GREEN = 0x0020
30
+ BACKGROUND_RED = 0x0040
31
+ BACKGROUND_INTENSITY = 0x0080
32
+ COMMON_LVB_LEADING_BYTE = 0x0100
33
+ COMMON_LVB_TRAILING_BYTE = 0x0200
34
+ COMMON_LVB_GRID_HORIZONTAL = 0x0400
35
+ COMMON_LVB_GRID_LVERTICAL = 0x0800
36
+ COMMON_LVB_GRID_RVERTICAL = 0x1000
37
+ COMMON_LVB_REVERSE_VIDEO = 0x4000
38
+ COMMON_LVB_UNDERSCORE = 0x8000
39
+ COMMON_LVB_SBCSDBCS = 0x0300
40
+
41
+ CONSOLE_FULLSCREEN = 1
42
+ CONSOLE_OVERSTRIKE = 1
43
+ CONSOLE_FULLSCREEN_HARDWARE = 2
44
+
45
+ AddConsoleAlias = Win32API.new('kernel32', 'AddConsoleAlias', 'PPP', 'I')
46
+ AllocConsole = Win32API.new('kernel32', 'AllocConsole', 'V', 'I')
47
+ AttachConsole = Win32API.new('kernel32', 'AttachConsole', 'L', 'I')
48
+ CreateConsoleScreenBuffer = Win32API.new('kernel32', 'CreateConsoleScreenBuffer', 'LLPLP', 'L')
49
+ FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', 'LILLP', 'I')
50
+ FillConsoleOutputCharacter = Win32API.new('kernel32', 'FillConsoleOutputCharacter', 'LILLP', 'I')
51
+ FlushConsoleInputBuffer = Win32API.new('kernel32', 'FlushConsoleInputBuffer', 'L', 'I')
52
+ FreeConsole = Win32API.new('kernel32', 'FreeConsole', 'V', 'I')
53
+ GenerateConsoleCtrlEvent = Win32API.new('kernel32', 'GenerateConsoleCtrlEvent', 'LL', 'I')
54
+ GetConsoleAlias = Win32API.new('kernel32', 'GetConsoleAlias', 'PPLP', 'L')
55
+ GetConsoleAliases = Win32API.new('kernel32', 'GetConsoleAliases', 'PLP', 'L')
56
+ GetConsoleAliasesLength = Win32API.new('kernel32', 'GetConsoleAliasesLength', 'P', 'L')
57
+ GetConsoleAliasExes = Win32API.new('kernel32', 'GetConsoleAliasExes', 'PL', 'L')
58
+ GetConsoleAliasExesLength = Win32API.new('kernel32', 'GetConsoleAliasExesLength', 'V', 'L')
59
+ GetConsoleCP = Win32API.new('kernel32', 'GetConsoleCP', 'V', 'I')
60
+ GetConsoleCursorInfo = Win32API.new('kernel32', 'GetConsoleCursorInfo', 'LP', 'I')
61
+ GetConsoleDisplayMode = Win32API.new('kernel32', 'GetConsoleDisplayMode', 'P', 'L')
62
+ GetConsoleFontSize = Win32API.new('kernel32', 'GetConsoleFontSize', 'LL', 'L')
63
+ GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', 'LP', 'I')
64
+ GetConsoleOutputCP = Win32API.new('kernel32', 'GetConsoleOutputCP', 'V', 'I')
65
+ GetConsoleProcessList = Win32API.new('kernel32', 'GetConsoleProcessList', 'PL', 'L')
66
+ GetConsoleScreenBufferInfo = Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', 'LP', 'I')
67
+ GetConsoleSelectionInfo = Win32API.new('kernel32', 'GetConsoleSelectionInfo', 'P', 'I')
68
+ GetConsoleTitle = Win32API.new('kernel32', 'GetConsoleTitle', 'PL', 'L')
69
+ GetConsoleWindow = Win32API.new('kernel32', 'GetConsoleWindow', 'V', 'L')
70
+ GetCurrentConsoleFont = Win32API.new('kernel32', 'GetCurrentConsoleFont' , 'LIP', 'I')
71
+ GetLargestConsoleWindowSize = Win32API.new('kernel32', 'GetLargestConsoleWindowSize', 'L', 'L')
72
+ GetNumberOfConsoleInputEvents = Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', 'LP', 'I')
73
+ GetNumberOfConsoleMouseButtons = Win32API.new('kernel32', 'GetNumberOfConsoleMouseButtons', 'L', 'I')
74
+ GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', 'L', 'L')
75
+ PeekConsoleInput = Win32API.new('kernel32', 'PeekConsoleInput', 'LPLP', 'I')
76
+ ReadConsole = Win32API.new('kernel32', 'ReadConsole', 'LPLPP', 'I')
77
+ ReadConsoleInput = Win32API.new('kernel32', 'ReadConsoleInput', 'LPLP', 'I')
78
+ ReadConsoleOutput = Win32API.new('kernel32', 'ReadConsoleOutput', 'LPLLP', 'I')
79
+ ReadConsoleOutputAttribute = Win32API.new('kernel32', 'ReadConsoleOutputAttribute', 'LPLLP', 'I')
80
+ ReadConsoleOutputCharacter = Win32API.new('kernel32', 'ReadConsoleOutputCharacter', 'LPLLP', 'I')
81
+ ScrollConsoleScreenBuffer = Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', 'LPPLP', 'I')
82
+ SetConsoleActiveScreenBuffer = Win32API.new('kernel32', 'SetConsoleActiveScreenBuffer', 'L', 'I')
83
+ SetConsoleCommandHistoryMode = Win32API.new('kernel32', 'SetConsoleCommandHistoryMode', 'L', 'I')
84
+ SetConsoleCP = Win32API.new('kernel32', 'SetConsoleCP', 'L', 'I')
85
+ SetConsoleCtrlHandler = Win32API.new('kernel32', 'SetConsoleCtrlHandler', 'PI', 'I')
86
+ SetConsoleCursorInfo = Win32API.new('kernel32', 'SetConsoleCursorInfo', 'LP', 'I')
87
+ SetConsoleCursorPosition = Win32API.new('kernel32', 'SetConsoleCursorPosition', 'LP', 'I')
88
+ SetConsoleDisplayMode = Win32API.new('kernel32', 'SetConsoleDisplayMode', 'LLP', 'I')
89
+ SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', 'LL', 'I')
90
+ SetConsoleOutputCP = Win32API.new('kernel32', 'SetConsoleOutputCP', 'I', 'I')
91
+ SetConsoleScreenBufferSize = Win32API.new('kernel32', 'SetConsoleScreenBufferSize', 'LL', 'I')
92
+ SetConsoleTextAttribute = Win32API.new('kernel32', 'SetConsoleTextAttribute', 'LL', 'I')
93
+ SetConsoleTitle = Win32API.new('kernel32', 'SetConsoleTitle', 'P', 'I')
94
+ SetConsoleWindowInfo = Win32API.new('kernel32', 'SetConsoleWindowInfo', 'LIP', 'I')
95
+ SetStdHandle = Win32API.new('kernel32', 'SetStdHandle', 'LL', 'I')
96
+ WriteConsole = Win32API.new('kernel32', 'WriteConsole', 'LPLPP', 'I')
97
+ WriteConsoleInput = Win32API.new('kernel32', 'WriteConsoleInput', 'LPLP', 'I')
98
+ WriteConsoleOutput = Win32API.new('kernel32', 'WriteConsoleOutput', 'LPLLP', 'I')
99
+ WriteConsoleOutputAttribute = Win32API.new('kernel32', 'WriteConsoleOutputAttribute', 'LPLLP', 'I')
100
+ WriteConsoleOutputCharacter = Win32API.new('kernel32', 'WriteConsoleOutputCharacter', 'LPLLP', 'I')
101
+
102
+ def AddConsoleAlias(source, target, exe)
103
+ AddConsoleAlias.call(source, target, exe) != 0
104
+ end
105
+
106
+ def AllocConsole()
107
+ AllocConsole.call != 0
108
+ end
109
+
110
+ def AttachConsole(pid)
111
+ AttachConsole.call(pid)
112
+ end
113
+
114
+ def CreateConsoleScreenBuffer(access, mode, sec, flags, data)
115
+ CreateConsoleScreenBuffer.call(access, mode, sec, flags, data)
116
+ end
117
+
118
+ def FillConsoleOutputAttribute(handle, attribute, length, coord, num)
119
+ FillConsoleOutputAttribute.call(handle, attribute, length, coord, num) != 0
120
+ end
121
+
122
+ def FlushConsoleInputBuffer(handle)
123
+ FlushConsoleInputBuffer.call(handle) != 0
124
+ end
125
+
126
+ def FreeConsole()
127
+ FreeConsole.call != 0
128
+ end
129
+
130
+ def GenerateConsoleCtrlEvent(ctrl_event, process_group_id)
131
+ GenerateConsoleCtrlEvent.call(ctrl_event, process_group_id) != 0
132
+ end
133
+
134
+ def GetConsoleAliases(buffer, buffer_length, exe_name)
135
+ GetConsoleAliases.call(buffer, buffer_length, exe_name)
136
+ end
137
+
138
+ def GetConsoleAliasesLength(exe_name)
139
+ GetConsoleAliasesLength.call(exe_name)
140
+ end
141
+
142
+ def GetConsoleAliasExes(buffer, buffer_length)
143
+ GetConsoleAliasExes.call(buffer, buffer_length)
144
+ end
145
+
146
+ def GetConsoleAliasExesLength()
147
+ GetConsoleAliasExesLength.call
148
+ end
149
+
150
+ def GetConsoleCP()
151
+ GetConsoleCP.call
152
+ end
153
+
154
+ def GetConsoleCursorInfo(handle, cursor_info_ptr)
155
+ GetConsoleCursorInfo.call(handle, cursor_info_ptr)
156
+ end
157
+
158
+ # The docs say this returns a BOOL, but really it's a DWORD
159
+ def GetConsoleDisplayMode(flags)
160
+ GetConsoleDisplayMode.call(flags)
161
+ end
162
+
163
+ def GetConsoleFontSize(handle, font)
164
+ GetConsoleFontSize.call(handle, font)
165
+ end
166
+
167
+ def GetConsoleMode(handle, mode)
168
+ GetConsoleMode.call(handle, mode) != 0
169
+ end
170
+
171
+ def GetConsoleOutputCP()
172
+ GetConsoleOutputCP.call
173
+ end
174
+
175
+ def GetConsoleProcessList(proc_list, proc_count)
176
+ GetConsoleProcessList.call(proc_list, proc_count)
177
+ end
178
+
179
+ def GetConsoleScreenBufferInfo(handle, buf_info)
180
+ GetConsoleScreenBufferInfo.call(handle, buf_info) != 0
181
+ end
182
+
183
+ def GetConsoleSelectionInfo(info_struct)
184
+ GetConsoleSelectionInfo.call(info_struct) != 0
185
+ end
186
+
187
+ def GetConsoleTitle(title, size)
188
+ GetConsoleTitle.call(title, size)
189
+ end
190
+
191
+ def GetConsoleWindow()
192
+ GetConsoleWindow.call
193
+ end
194
+
195
+ def GetCurrentConsoleFont(handle, max_window, current_font_struct)
196
+ GetCurrentConsoleFont.call(handle, max_window, current_font_struct)
197
+ end
198
+
199
+ def GetLargestConsoleWindowSize(handle)
200
+ GetLargestConsoleWindowSize.call(handle)
201
+ end
202
+
203
+ def GetNumberOfConsoleInputEvents(handle, num_events)
204
+ GetNumberOfConsoleInputEvents.call(handle, num_events)
205
+ end
206
+
207
+ def GetNumberOfConsoleMouseButtons(num_mouse_buttons)
208
+ GetNumberOfConsoleMouseButtons.call(num_mouse_buttons)
209
+ end
210
+
211
+ def GetStdHandle(std_handle)
212
+ GetStdHandle.call(std_handle)
213
+ end
214
+
215
+ def PeekConsoleInput(handle, buffer, length, num_events)
216
+ PeekConsoleInput.call(handle, buffer, length, num_events) != 0
217
+ end
218
+
219
+ def ReadConsole(handle, buffer, num_to_read, num_read, res = 0)
220
+ ReadConsole.call(handle, buffer, num_to_read, num_read, res) != 0
221
+ end
222
+
223
+ def ReadConsoleInput(handle, buffer, length, num_read)
224
+ ReadConsoleInput.call(handle, buffer, length, num_read) != 0
225
+ end
226
+
227
+ def ReadConsoleOutput(handle, buffer, buf_size, buf_coord, reg)
228
+ ReadConsoleOutput.call(handle, buffer, buf_size, buf_coord, reg) != 0
229
+ end
230
+
231
+ def ReadConsoleOutputAttribute(handle, attrib, len, coord, num_read)
232
+ ReadConsoleOutputAttribute.call(handle, attrib, len, coord, num_read) != 0
233
+ end
234
+
235
+ def ReadConsoleOutputCharacter(handle, char, length, coord, num_read)
236
+ ReadConsoleOutputCharacter.call(handle, char, length, coord, num_read) != 0
237
+ end
238
+
239
+ def ScrollConsoleScreenBuffer(handle, scroll, clip, coord, fill)
240
+ ScrollConsoleScreenBuffer.call(handle, scroll, clip, coord, fill) != 0
241
+ end
242
+
243
+ def SetConsoleActiveScreenBuffer(handle)
244
+ SetConsoleActiveScreenBuffer.call(handle) != 0
245
+ end
246
+
247
+ def SetConsoleCommandHistoryMode(flags)
248
+ SetConsoleCommandHistoryMode.call(flags) != 0
249
+ end
250
+
251
+ def SetConsoleCP(code_page_id)
252
+ SetConsoleCP.call(code_page_id) != 0
253
+ end
254
+
255
+ def SetConsoleCtrlHandler(handler, add)
256
+ SetConsoleCtrlHandler.call(handler, add) != 0
257
+ end
258
+
259
+ def SetConsoleCursorInfo(handle, cursor)
260
+ SetConsoleCursorInfo.call(handle, cursor) != 0
261
+ end
262
+
263
+ def SetConsoleCursorPosition(handle, coord)
264
+ SetConsoleCursorPosition.call(handle, coord) != 0
265
+ end
266
+
267
+ def SetConsoleDisplayMode(handle, flags, coord)
268
+ SetConsoleDisplayMode.call(handle, flags, coord) != 0
269
+ end
270
+
271
+ def SetConsoleHistoryInfo(info)
272
+ SetConsoleHistoryInfo.call(info) != 0
273
+ end
274
+
275
+ def SetConsoleMode(handle, mode)
276
+ SetConsoleMode.call(handle, mode) != 0
277
+ end
278
+
279
+ def SetConsoleOutputCP(code_page_id)
280
+ SetConsoleOutputCP.call(code_page_id) != 0
281
+ end
282
+
283
+ def SetConsoleScreenBufferSize(handle, size)
284
+ SetConsoleScreenBufferSize.call(handle, size) != 0
285
+ end
286
+
287
+ def SetConsoleTextAttribute(handle, attribute)
288
+ SetConsoleTextAttribute.call(handle, attribute) != 0
289
+ end
290
+
291
+ def SetConsoleTitle(title)
292
+ SetConsoleTitle.call(title) != 0
293
+ end
294
+
295
+ def SetConsoleWindowInfo(handle, absolute, window)
296
+ SetConsoleWindowInfo.call(handle, absolute, window) != 0
297
+ end
298
+
299
+ def SetStdHandle(std_handle, handle)
300
+ SetStdHandle.call(std_handle, handle) != 0
301
+ end
302
+
303
+ def WriteConsole(handle, buffer, num_to_write, num_written, res = 0)
304
+ WriteConsole.call(handle, buffer, num_to_write, num_written, res) != 0
305
+ end
306
+
307
+ def WriteConsoleInput(handle, buffer, length, num_events)
308
+ WriteConsoleInput.call(handle, buffer, length, num_events) != 0
309
+ end
310
+
311
+ def WriteConsoleOutput(handle, buffer, buf_size, coord, region)
312
+ WriteConsoleOutput.call(handle, buffer, buf_size, coord, region) != 0
313
+ end
314
+
315
+ def WriteConsoleOutputAttribute(handle, attrib, length, coord, num)
316
+ WriteConsoleOutputAttribute.call(handle, attrib, length, coord, num) != 0
317
+ end
318
+
319
+ def WriteConsoleOutputCharacter(handle, char, length, coord, num)
320
+ WriteConsoleOutputCharacter.call(handle, char, length, coord, num) != 0
321
+ end
322
+ end
323
+ end