SHOW:
|
|
- or go back to the newest paste.
1 | - | local tArgs = {...} |
1 | + | |
2 | local w, h = term.getSize() | |
3 | local lChanged = false | |
4 | local pChanged = true | |
5 | local mChanged = true | |
6 | local numlength = 1 | |
7 | local type = 1 | |
8 | local tabNum = 0 | |
9 | local mode = "edit" | |
10 | local clickStart, clickEnd, prevline, currentLine, currentPos | |
11 | local cTables, cComTab, program, colTab = {}, {}, {}, {} | |
12 | cParTab = {} | |
13 | if mode == "edit" then | |
14 | colTab[1] = colors.lightGray | |
15 | colTab[2] = colors.green | |
16 | colTab[3] = colors.red | |
17 | colTab[4] = colors.orange | |
18 | colTab[5] = colors.lightBlue | |
19 | colTab[6] = colors.white | |
20 | elseif mode == "read" then | |
21 | colTab[1] = colors.white | |
22 | colTab[2] = colors.white | |
23 | colTab[3] = colors.white | |
24 | colTab[4] = colors.white | |
25 | colTab[5] = colors.white | |
26 | colTab[6] = colors.white | |
27 | end | |
28 | local location = { | |
29 | ["x"] = 1, | |
30 | ["y"] = 1 | |
31 | } | |
32 | local position = { | |
33 | ["x"] = 1, | |
34 | ["y"] = 1 | |
35 | } | |
36 | local conditionals = { | |
37 | ["if"] = {"end", colors.red, colors.pink}, | |
38 | ["while"] = {"end", colors.red, colors.pink}, | |
39 | ["for"] = {"end", colors.red, colors.pink}, | |
40 | ["function"] = {"end", colors.red, colors.pink} | |
41 | } | |
42 | local keywords = { | |
43 | ["if"] = colors.yellow, | |
44 | ["then"] = colors.yellow, | |
45 | ["else"] = colors.yellow, | |
46 | ["elseif"] = colors.yellow, | |
47 | ["end"] = colors.yellow, | |
48 | ["function"] = colors.yellow, | |
49 | ["while"] = colors.yellow, | |
50 | ["for"] = colors.yellow, | |
51 | ["in"] = colors.yellow, | |
52 | ["do"] = colors.yellow, | |
53 | ["local"] = colors.yellow, | |
54 | ["repeat"] = colors.yellow, | |
55 | ["until"] = colors.yellow, | |
56 | ["next"] = colors.yellow, | |
57 | ["and"] = colors.orange, | |
58 | ["or"] = colors.orange, | |
59 | ["not"] = colors.orange, | |
60 | ["true"] = colors.orange, | |
61 | ["false"] = colors.orange, | |
62 | ["nil"] = colors.gray, | |
63 | ["break"] = colors.purple, | |
64 | ["return"] = colors.purple, | |
65 | ["print"] = colors.pink, | |
66 | ["write"] = colors.pink, | |
67 | ["pairs"] = colors.pink, | |
68 | ["ipairs"] = colors.pink, | |
69 | ["type"] = colors.blue, | |
70 | ["tostring"] = colors.blue, | |
71 | ["tonumber"] = colors.blue, | |
72 | ["assert"] = colors.blue, | |
73 | ["setmetatable"] = colors.blue | |
74 | } | |
75 | ||
76 | - | if tArgs[1] and fs.exists(tArgs[1]) then |
76 | + | |
77 | - | for line in io.lines(tArgs[1]) do |
77 | + | |
78 | - | program[#program + 1] = tostring(line) |
78 | + | |
79 | - | program[#program] = program[#program]:gsub(" ", "$___") |
79 | + | |
80 | term.setCursorPos(xPos, yPos) | |
81 | - | if #program == 0 then |
81 | + | |
82 | - | program[1] = "" |
82 | + | |
83 | term.write(string) | |
84 | - | elseif tArgs[1] then |
84 | + | |
85 | - | program[1] = "" |
85 | + | |
86 | local function codeDraw(string, xPos, yPos) | |
87 | local string = string or "" | |
88 | local xPos = xPos - location["x"] + 1 | |
89 | local sStart, sEnd = 1, 1 + w - numlength | |
90 | local tabDraw = true | |
91 | local multiComment = false | |
92 | while #string > 0 and xPos <= sEnd do | |
93 | --[[for i in pairs(cComTab) do | |
94 | if mode == "edit" then | |
95 | if not multiComment and (yPos-1 == cComTab[i][1][2]-location["y"] + 1 and xPos-3 >= cComTab[i][1][1]-location["x"] + 1) or (yPos-1 == cComTab[i][2][2]-location["y"]+1 and xPos-2 <= cComTab[i][2][1]-location["x"]+1) or (yPos-1 > cComTab[i][1][2]-location["y"]+1 and yPos-1 < cComTab[i][2][2]-location["y"]+1) then | |
96 | colTab[1] = colors.green | |
97 | colTab[2] = colors.green | |
98 | colTab[3] = colors.green | |
99 | colTab[4] = colors.green | |
100 | colTab[5] = colors.green | |
101 | colTab[6] = colors.green | |
102 | multiComment = true | |
103 | break | |
104 | elseif multiComment then | |
105 | colTab[1] = colors.lightGray | |
106 | colTab[2] = colors.green | |
107 | colTab[3] = colors.red | |
108 | colTab[4] = colors.orange | |
109 | colTab[5] = colors.lightBlue | |
110 | colTab[6] = colors.white | |
111 | multiComment = false | |
112 | end | |
113 | end | |
114 | end]]-- | |
115 | if string:find("^%$___") then | |
116 | local _, en = string:find("^%$___") | |
117 | if en >= sStart and xPos <= sEnd then | |
118 | if tabDraw and not multiComment then | |
119 | draw(" |", xPos, yPos, colTab[1], colors.black) | |
120 | else | |
121 | draw(" ", xPos, yPos, colTab[1], colors.black) | |
122 | end | |
123 | end | |
124 | string = string:sub(en + 1) | |
125 | xPos = xPos + en | |
126 | elseif string:find("^%-%-.*") then | |
127 | tabDraw = false | |
128 | local _, en = string:find("^%-%-.*") | |
129 | if en >= sStart and xPos <= sEnd then | |
130 | draw(string:sub(1, en), xPos, yPos, colTab[2], colors.black) | |
131 | end | |
132 | string = string:sub(en + 1) | |
133 | xPos = xPos + en | |
134 | elseif string:find("^\".-[^\\]\"") then | |
135 | tabDraw = false | |
136 | local _, en = string:find("^\".-[^\\]\"") | |
137 | if en >= sStart and xPos <= sEnd then | |
138 | draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black) | |
139 | end | |
140 | string = string:sub(en + 1) | |
141 | xPos = xPos + en | |
142 | elseif string:find("^\'.-[^\\]\'") then | |
143 | tabDraw = false | |
144 | local _, en = string:find("^\'.-[^\\]\'") | |
145 | if en >= sStart and xPos <= sEnd then | |
146 | draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black) | |
147 | end | |
148 | string = string:sub(en + 1) | |
149 | xPos = xPos + en | |
150 | elseif string:find("^\"\"") then | |
151 | tabDraw = false | |
152 | local _, en = string:find("^\"\"") | |
153 | if en >= sStart and xPos <= sEnd then | |
154 | draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black) | |
155 | end | |
156 | string = string:sub(en + 1) | |
157 | xPos = xPos + en | |
158 | elseif string:find("^\'\'") then | |
159 | tabDraw = false | |
160 | local _, en = string:find("^\'\'") | |
161 | if en >= sStart and xPos <= sEnd then | |
162 | draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black) | |
163 | end | |
164 | string = string:sub(en + 1) | |
165 | xPos = xPos + en | |
166 | elseif string:find("^%[%[.-%]%]") then | |
167 | tabDraw = false | |
168 | local _, en = string:find("^%[%[.-%]%]") | |
169 | if en >= sStart and xPos <= sEnd then | |
170 | draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black) | |
171 | end | |
172 | string = string:sub(en + 1) | |
173 | xPos = xPos + en | |
174 | elseif string:find("^%d+") then | |
175 | tabDraw = false | |
176 | local _, en = string:find("^%d+") | |
177 | if en >= sStart and xPos <= sEnd then | |
178 | draw(string:sub(1, en), xPos, yPos, colTab[4], colors.black) | |
179 | end | |
180 | string = string:sub(en + 1) | |
181 | xPos = xPos + en | |
182 | elseif string:find("^%p") then | |
183 | tabDraw = false | |
184 | local _, en = string:find("^%p") | |
185 | if en >= sStart and xPos <= sEnd then | |
186 | draw(string:sub(1, en), xPos, yPos, colTab[5], colors.black) | |
187 | end | |
188 | string = string:sub(en + 1) | |
189 | xPos = xPos + en | |
190 | elseif string:find("^[%a_]+") then | |
191 | tabDraw = false | |
192 | local _, en = string:find("^[%a_]+") | |
193 | local test = string:sub(1, en) | |
194 | local color = colors.white | |
195 | if keywords[test] and mode == "edit" then | |
196 | color = keywords[test] | |
197 | end | |
198 | if multiComment then | |
199 | color = colors.green | |
200 | end | |
201 | if en >= sStart and xPos <= sEnd then | |
202 | draw(string:sub(1, en), xPos, yPos, color, colors.black) | |
203 | end | |
204 | string = string:sub(en + 1) | |
205 | xPos = xPos + en | |
206 | elseif string:find("^[^%w_]") then | |
207 | tabDraw = false | |
208 | local _, en = string:find("^[^%w_]") | |
209 | if en >= sStart and xPos <= sEnd then | |
210 | draw(string:sub(1, en), xPos, yPos, colTab[6], colors.black) | |
211 | end | |
212 | string = string:sub(en + 1) | |
213 | xPos = xPos + en | |
214 | end | |
215 | end | |
216 | end | |
217 | ||
218 | local function printMenu() | |
219 | term.setCursorPos(1, 1) | |
220 | term.setBackgroundColor(colors.lightGray) | |
221 | term.clearLine() | |
222 | draw("Press CTRL for menu...", 1, 1, colors.gray, colors.lightGray) | |
223 | end | |
224 | ||
225 | local function saveFile(codeTable, filename) | |
226 | local tempFile = {} | |
227 | for i, v in ipairs(codeTable) do | |
228 | tempFile[i] = v:gsub("$___", " ") | |
229 | end | |
230 | local sFile = fs.open(filename, "w") | |
231 | for _, v in ipairs(tempFile) do | |
232 | sFile.writeLine(v) | |
233 | end | |
234 | sFile.close() | |
235 | end | |
236 | ||
237 | local function showProgram() | |
238 | multiComment = false | |
239 | numlength = #tostring(#program - location["y"] + 1 >= h and location["y"] + h - 1 or #program) | |
240 | for y = location["y"], #program - location["y"] + 1 >= h - 1 and location["y"] + h - 2 or #program do | |
241 | codeDraw(program[y], 1 + numlength, y - location["y"] + 2) | |
242 | end | |
243 | end | |
244 | ||
245 | local function showProgramLine(line) | |
246 | numlength = #tostring(#program - location["y"] + 1 >= h and location["y"] + h - 1 or #program) | |
247 | codeDraw(program[line], 1 + numlength, line - location["y"] + 2) | |
248 | end | |
249 | ||
250 | local function showNumbers() | |
251 | local activeLoops = {} | |
252 | local up, down | |
253 | for _, v in pairs(cTables) do | |
254 | if currentLine >= v[1] and currentLine <= v[2] then | |
255 | activeLoops[#activeLoops + 1] = {v[1], v[2]} | |
256 | end | |
257 | end | |
258 | if #activeLoops > 0 then | |
259 | local key, mini = 0, #program | |
260 | for i, v in pairs(activeLoops) do | |
261 | if v[2] - v[1] < mini then | |
262 | key, mini = i, v[2] - v[1] | |
263 | end | |
264 | end | |
265 | if key > 0 then | |
266 | up, down = activeLoops[key][1], activeLoops[key][2] | |
267 | end | |
268 | end | |
269 | for y = location["y"], #program - location["y"] + 1 >= h - 1 and location["y"] + h - 2 or #program do | |
270 | local text, back = colors.gray, colors.lightGray | |
271 | if up and down and y > up and y < down then | |
272 | text, back = colors.red, colors.pink | |
273 | elseif up and down and (y == up or y == down) then | |
274 | text, back = colors.pink, colors.red | |
275 | end | |
276 | draw(tostring(y), 1, y - location["y"] + 2, text, back) | |
277 | if #tostring(y) < numlength then | |
278 | write(" ") | |
279 | end | |
280 | end | |
281 | end | |
282 | ||
283 | local function addLetter(char, str, pos) | |
284 | return str:sub(0, pos - 1) .. tostring(char) .. str:sub(pos) | |
285 | end | |
286 | ||
287 | local function removeLetter(str, pos) | |
288 | return str:sub(0, pos) .. str:sub(pos + 2) | |
289 | end | |
290 | ||
291 | local function fixCursorPos() | |
292 | if position["y"] < 1 then | |
293 | pChanged = true | |
294 | location["y"] = location["y"] + position["y"] - 1 | |
295 | - | local function checkParenthesis() |
295 | + | |
296 | - | local cancelNum = 0 |
296 | + | |
297 | - | local pString = "" |
297 | + | |
298 | - | pBreaks = {} |
298 | + | |
299 | - | local cBrackets = {} |
299 | + | |
300 | - | pBreaks[1] = 0 |
300 | + | |
301 | - | for y = 1, #program do |
301 | + | |
302 | - | pString = pString .. program[y] |
302 | + | |
303 | - | pBreaks[y+1] = #program[y] + pBreaks[y] |
303 | + | |
304 | elseif location["y"] + h - 1 > #program then | |
305 | - | while pString:find("[%[%{%(]") do |
305 | + | |
306 | - | local oppChar |
306 | + | |
307 | - | local st, en = pString:find("[%[%{%(]") |
307 | + | |
308 | - | term.setBackgroundColor(colors.magenta) |
308 | + | |
309 | - | local char = pString:sub(st, st) |
309 | + | |
310 | - | if char == "[" then oppChar = "]" |
310 | + | |
311 | - | elseif char == "{" then oppChar = "}" |
311 | + | |
312 | - | elseif char == "(" then oppChar = ")" end |
312 | + | |
313 | - | st, en = pString:find("%b" .. char .. oppChar) |
313 | + | |
314 | - | if st and en then |
314 | + | |
315 | - | local x1, y1, x2, y2 |
315 | + | |
316 | - | local active = true |
316 | + | |
317 | - | for i, v in pairs(pBreaks) do |
317 | + | |
318 | - | if st <= v and active then |
318 | + | |
319 | - | x1 = st - pBreaks[i - 1] |
319 | + | |
320 | - | y1 = i - 1 |
320 | + | |
321 | - | active = false |
321 | + | |
322 | dollarNum = nil | |
323 | - | if en <= v then |
323 | + | |
324 | - | x2 = en - pBreaks[i - 1] |
324 | + | |
325 | - | y2 = i - 1 |
325 | + | |
326 | end | |
327 | - | if x1 and y1 and x2 and y2 then |
327 | + | |
328 | - | cBrackets[#cBrackets + 1] = {x1, y1, x2, y2, char, oppChar} |
328 | + | |
329 | - | break |
329 | + | |
330 | end | |
331 | if position["x"] + location["x"] - 1 > #program[position["y"] + location["y"] - 1] then | |
332 | - | pString = pString:sub(1, st - 1) .. " " .. pString:sub(st + 1) |
332 | + | |
333 | - | pString = pString:sub(1, en - 1) .. " " .. pString:sub(en + 1) |
333 | + | |
334 | - | else |
334 | + | |
335 | - | st, en = pString:find("[%[%{%(]") |
335 | + | |
336 | - | pString = pString:sub(1, st - 1) .. " " .. pString:sub(st + 1) |
336 | + | |
337 | position["x"] = 1 | |
338 | elseif position["x"] > w - numlength then | |
339 | - | return cBrackets |
339 | + | |
340 | location["x"] = location["x"] + position["x"] - (w-numlength) | |
341 | position["x"] = w - numlength | |
342 | - | local function checkConditionals() |
342 | + | |
343 | - | local cWords = {} |
343 | + | |
344 | - | local active = false |
344 | + | |
345 | - | local cancelNum = 0 |
345 | + | |
346 | - | local cConditional = {} |
346 | + | |
347 | - | for y = 1, #program do |
347 | + | |
348 | - | for i in pairs(conditionals) do |
348 | + | |
349 | - | local test = program[y]:gsub(" ", "") |
349 | + | |
350 | - | local st = test:find(i) |
350 | + | |
351 | - | local _, en = program[y]:find(i) |
351 | + | |
352 | - | if st and en then |
352 | + | |
353 | - | if st == 1 and (en == #program[y] or program[y]:sub(en + 1, en + 1) == " ") then |
353 | + | |
354 | - | cWords[#cWords + 1] = {} |
354 | + | |
355 | - | cWords[#cWords][1] = y |
355 | + | |
356 | - | cancelNum = cancelNum + 1 |
356 | + | |
357 | - | cConditional[cancelNum] = #cWords |
357 | + | |
358 | - | active = true |
358 | + | |
359 | term.setCursorBlink(true) | |
360 | while true do | |
361 | if mode == "edit" then | |
362 | - | if active and program[y]:find("end") then |
362 | + | |
363 | - | cWords[cConditional[cancelNum]][2] = y |
363 | + | |
364 | - | cancelNum = cancelNum - 1 |
364 | + | |
365 | - | if cancelNum == 0 then |
365 | + | |
366 | - | active = false |
366 | + | |
367 | - | if y > location["y"] + h - 2 then |
367 | + | |
368 | if pChanged or program[currentLine]:sub(currentPos - 2, currentPos - 1) == "]]" then | |
369 | --cTables = checkConditionals() | |
370 | term.setBackgroundColor(colors.black) | |
371 | term.clear() | |
372 | showProgram() | |
373 | - | local rem = {} |
373 | + | |
374 | - | for i = 1, #cWords do |
374 | + | |
375 | - | if not (cWords[i][1] and cWords[i][2]) then |
375 | + | |
376 | - | rem[#rem + 1] = i |
376 | + | |
377 | term.setBackgroundColor(colors.black) | |
378 | term.clearLine() | |
379 | - | for i, v in pairs(rem) do |
379 | + | |
380 | - | table.remove(cWords, v - i + 1) |
380 | + | |
381 | end | |
382 | - | return cWords |
382 | + | |
383 | printMenu() | |
384 | mChanged = false | |
385 | - | function checkMultiComments() |
385 | + | |
386 | - | local cComments = {} |
386 | + | |
387 | - | local active = false |
387 | + | |
388 | - | local cancelNum = 0 |
388 | + | |
389 | - | local cConditional = {} |
389 | + | |
390 | - | for y = 1, #program do |
390 | + | |
391 | - | if program[y]:find("%-%-%[%[") and not active then |
391 | + | |
392 | - | active = true |
392 | + | |
393 | - | local st = program[y]:find("%-%-%[%[") |
393 | + | |
394 | - | cComments[#cComments + 1] = {} |
394 | + | |
395 | - | cComments[#cComments][1]= {st, y} |
395 | + | |
396 | - | elseif program[y]:find("%]%]") and active then |
396 | + | |
397 | - | active = false |
397 | + | |
398 | - | local _, en = program[y]:find("%]%]") |
398 | + | |
399 | - | cComments[#cComments][2] = {en, y} |
399 | + | |
400 | end]] | |
401 | if mode == "edit" then | |
402 | - | local rem = {} |
402 | + | |
403 | - | for i = 1, #cComments do |
403 | + | |
404 | - | if #cComments[i] < 2 then |
404 | + | |
405 | - | rem[#rem + 1] = i |
405 | + | |
406 | local events = {os.pullEvent()} | |
407 | if events[1] == "char" and mode == "edit" then | |
408 | - | for i, v in pairs(rem) do |
408 | + | |
409 | - | table.remove(cComments, v - i + 1) |
409 | + | |
410 | position["x"] = position["x"] + 1 | |
411 | - | return cComments |
411 | + | |
412 | if events[2] == keys.up then --^ | |
413 | position["y"] = position["y"] - 1 | |
414 | elseif events[2] == keys.down then --v | |
415 | position["y"] = position["y"] + 1 | |
416 | elseif events[2] == keys.right then --> | |
417 | if (position["x"] + location["x"] - 1) % 4 == 1 and position["x"] + location["x"] - 1 < #program[currentLine] and program[currentLine]:sub(position["x"] + location["x"] - 1, position["x"] + location["x"] + 2) == "$___" then | |
418 | position["x"] = position["x"] + 4 | |
419 | elseif currentLine < #program and currentPos > #program[currentLine] then | |
420 | position["x"] = 1 - location["x"] + 1 | |
421 | position["y"] = position["y"] + 1 | |
422 | else | |
423 | position["x"] = position["x"] + 1 | |
424 | end | |
425 | elseif events[2] == keys.left then --< | |
426 | if (position["x"] + location["x"] - 1) % 4 == 1 and position["x"] + location["x"] - 1 > 4 and program[currentLine]:sub(position["x"] + location["x"] - 5, position["x"] + location["x"] - 2) == "$___" then | |
427 | position["x"] = position["x"] - 4 | |
428 | elseif currentLine > 1 and currentPos == 1 then | |
429 | position["x"] = #program[currentLine - 1] + 1 | |
430 | position["y"] = position["y"] - 1 | |
431 | else | |
432 | position["x"] = position["x"] - 1 | |
433 | end | |
434 | end | |
435 | if events[2] == keys.backspace and mode == "edit" then | |
436 | lChanged = true | |
437 | if (position["x"] + location["x"] - 1) % 4 == 1 and position["x"] + location["x"] - 1 > 4 and program[currentLine]:sub(position["x"] + location["x"] - 5, position["x"] + location["x"] - 2) == "$___" then | |
438 | for i = 1, 4 do | |
439 | program[currentLine] = removeLetter(program[currentLine], location["x"] + position["x"] - 6) | |
440 | position["x"] = position["x"] - 4 | |
441 | end | |
442 | elseif currentLine > 1 and currentPos == 1 then | |
443 | position["y"] = position["y"] - 1 | |
444 | location["x"] = (location["x"] > #program[currentLine - 1] or location["x"] + w - #tostring(currentLine - 1) < #program[currentLine - 1]) and #program[currentLine - 1] + 1 or location["x"] | |
445 | position["x"] = #program[currentLine - 1] - location["x"] + 2 | |
446 | program[currentLine - 1] = program[currentLine - 1] .. (table.remove(program, currentLine)) | |
447 | pChanged = true | |
448 | else | |
449 | program[currentLine] = removeLetter(program[currentLine], currentPos - 2) | |
450 | position["x"] = position["x"] - 1 | |
451 | end | |
452 | end | |
453 | if events[2] == keys.enter and mode == "edit" then | |
454 | pChanged = true | |
455 | table.insert(program, currentLine + 1, program[currentLine]:sub(position["x"] + location["x"] - 1)) | |
456 | program[currentLine] = program[currentLine]:sub(1, position["x"] + location["x"] - 2) | |
457 | program[currentLine + 1] = string.rep("$___", tabNum) .. program[currentLine + 1] | |
458 | position["y"] = position["y"] + 1 | |
459 | position["x"] = 1 + tabNum * 4 | |
460 | end | |
461 | if events[2] == keys.tab and mode == "edit" then | |
462 | lChanged = true | |
463 | if (position["x"] + location["x"] - 1) % 4 == 1 then | |
464 | program[currentLine] = addLetter("$___", program[currentLine], position["x"] + location["x"] - 1) | |
465 | else | |
466 | local num = (position["x"] + location["x"] - 1) % 4 + 1 | |
467 | if num == 4 then num = 2 end | |
468 | program[currentLine] = addLetter(string.rep(" ", num), program[currentLine], position["x"] + location["x"] - 1) | |
469 | end | |
470 | position["x"] = position["x"] + 4 | |
471 | end | |
472 | end | |
473 | if events[1] == "mouse_click" and events[2] == 1 and #program >= events[4] + location["y"] - 2 and events[4] > 1 then | |
474 | position["y"] = events[4] - 1 | |
475 | position["x"] = events[3] - numlength | |
476 | elseif events[1] == "mouse_drag" and events[2] == 1 then | |
477 | clickEnd = {events[3] + location["x"] - 1, events[4] + location["y"] - 1} | |
478 | end | |
479 | if events[1] == "mouse_scroll" then | |
480 | pChanged = true | |
481 | location["y"] = location["y"] + events[2] | |
482 | end | |
483 | end |