Advertisement
Guest User

Compiled

a guest
May 23rd, 2015
610
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 407.05 KB | None | 0 0
  1. local tbl={
  2.   [ "/rom/apis/turtle/turtle" ] = "\
  3. if not turtle then\
  4.     error( \"Cannot load turtle API on computer\", 2 )\
  5. end\
  6. native = turtle.native or turtle\
  7. \
  8. local function addCraftMethod( object )\
  9.    if peripheral.getType( \"left\" ) == \"workbench\" then\
  10.        object.craft = function( ... )\
  11.            return peripheral.call( \"left\", \"craft\", ... )\
  12.        end\
  13.    elseif peripheral.getType( \"right\" ) == \"workbench\" then\
  14.        object.craft = function( ... )\
  15.            return peripheral.call( \"right\", \"craft\", ... )\
  16.        end\
  17.    else\
  18.        object.craft = nil\
  19.    end\
  20. end\
  21. \
  22. -- Put commands into environment table\
  23. local env = getfenv()\
  24. for k,v in pairs( native ) do\
  25.    if k == \"equipLeft\" or k == \"equipRight\" then\
  26.        env[k] = function( ... )\
  27.            local result, err = v( ... )\
  28.            addCraftMethod( turtle )\
  29.            return result, err\
  30.        end\
  31.    else\
  32.         env[k] = v\
  33.    end\
  34. end\
  35. addCraftMethod( env )",
  36.   [ "/rom/help/id" ] = "id prints the unique identifier of this computer, or a Disk in an attached Disk Drive.\
  37. \
  38. ex:\
  39. \"id\" will print this Computers ID and label\
  40. \"id left\" will print the ID and label of the disk in the Disk Drive on the left",
  41.   [ "/rom/help/rs" ] = "Functions in the Redstone API:\
  42. rs.getSides( )\
  43. rs.getInput( side )\
  44. rs.setOutput( side, boolean )\
  45. rs.getOutput( side )\
  46. rs.getAnalogInput( side )\
  47. rs.setAnalogOutput( side, number )\
  48. rs.getAnalogOutput( side )\
  49. \
  50. Functions in the Redstone API for working with RedPower bundled cables:\
  51. rs.getBundledInput( side )\
  52. rs.testBundledInput( side, color )\
  53. rs.setBundledOutput( side, colors )\
  54. rs.getBundledOutput( side )\
  55. Type \"help bundled\" for usage examples.\
  56. \
  57. Events emitted by the redstone API:\
  58. \"redstone\", when the state of any redstone input changes. Use getInput() or getBundledInput() to inspect the changes\
  59. Type \"help events\" to learn about the event system.",
  60.   [ "/rom/programs/cd" ] = "\
  61. local tArgs = { ... }\
  62. if #tArgs < 1 then\
  63.     print( \"Usage: cd <path>\" )\
  64.     return\
  65. end\
  66. \
  67. local sNewDir = shell.resolve( tArgs[1] )\
  68. if fs.isDir( sNewDir ) then\
  69.     shell.setDir( sNewDir )\
  70. else\
  71.     print( \"Not a directory\" )\
  72.     return\
  73. end",
  74.   [ "/rom/programs/advanced/fg" ] = "\
  75. local tArgs = { ... }\
  76. if #tArgs > 0 then\
  77.    local nTask = shell.openTab( unpack( tArgs ) )\
  78.    if nTask then\
  79.        shell.switchTab( nTask )\
  80.    end\
  81. else\
  82.    local nTask = shell.openTab( \"shell\" )\
  83.    if nTask then\
  84.        shell.switchTab( nTask )\
  85.    end\
  86. end",
  87.   [ "/rom/help/window" ] = "Functions in the window API:\
  88. window.create( parent, x, y, width, height, visible )\
  89. \
  90. Windows created with the window API have the following methods:\
  91. write( text )\
  92. clear()\
  93. clearLine()\
  94. getCursorPos()\
  95. setCursorPos( x, y )\
  96. setCursorBlink( blink )\
  97. isColor()\
  98. setTextColor( color )\
  99. setBackgroundColor( color )\
  100. getSize()\
  101. scroll( n )\
  102. setVisible( bVisible )\
  103. redraw()\
  104. restoreCursor()\
  105. getPosition()\
  106. reposition( x, y, width, height )",
  107.   [ "/startup" ] = "shell.run('run')\
  108. ",
  109.   [ "/rom/help/peripherals" ] = "Peripherals are external devices which CraftOS Computers and Turtles can interact with using the peripheral API.\
  110. Type \"help peripheral\" to learn about using the peripheral API.\
  111. Type \"help drives\" to learn about using Disk Drives.\
  112. Type \"help modems\" to learn about using Wireless Modems.\
  113. Type \"help monitors\" to learn about using Monitors.\
  114. Type \"help printers\" to learn about using Printers.",
  115.   [ "/rom/programs/delete" ] = "\
  116. local tArgs = { ... }\
  117. if #tArgs < 1 then\
  118.     print( \"Usage: rm <path>\" )\
  119.     return\
  120. end\
  121. \
  122. local sPath = shell.resolve( tArgs[1] )\
  123. local tFiles = fs.find( sPath )\
  124. if #tFiles > 0 then\
  125.    for n,sFile in ipairs( tFiles ) do\
  126.        fs.delete( sFile )\
  127.    end\
  128. else\
  129.    printError( \"No matching files\" )\
  130. end",
  131.   [ "/rom/programs/fun/advanced/levels/9" ] = "2\
  132.    777  777\
  133.  777877778777\
  134.  788838888887\
  135. 7778bbbbbbbb8777\
  136. 7888b888888b8897\
  137. 7878be8888eb8787\
  138. 7588b888888b8887\
  139. 7778bbbbbbbb8777\
  140.  788888818887\
  141.  777877778777\
  142.    777  777",
  143.   [ "/Flare/version/1.2/lib/UI/draw/pixelbatch.lua" ] = "\
  144. local function pixelbatch( buffer, pixels )\
  145.     local bc, tc = buffer:getColours()\
  146.     for i = 1, #pixels do\
  147.         if pixels[i].bc ~= bc or pixels[i].tc ~= tc then\
  148.             buffer:setColours( pixels[i].bc, pixels[i].tc )\
  149.             bc, tc = pixels[i].bc, pixels[i].tc\
  150.         end\
  151.         buffer:drawPixel( pixels[i].x, pixels[i].y, pixels[i].char )\
  152.     end\
  153. end\
  154. \
  155. return pixelbatch",
  156.   [ "/rom/apis/textutils" ] = "\
  157. function slowWrite( sText, nRate )\
  158.    nRate = nRate or 20\
  159.    if nRate < 0 then\
  160.        error( \"Rate must be positive\", 2 )\
  161.    end\
  162.    local nSleep = 1 / nRate\
  163.        \
  164.    sText = tostring( sText )\
  165.    local x,y = term.getCursorPos(x,y)\
  166.    local len = string.len( sText )\
  167.    \
  168.    for n=1,len do\
  169.        term.setCursorPos( x, y )\
  170.        sleep( nSleep )\
  171.        local nLines = write( string.sub( sText, 1, n ) )\
  172.        local newX, newY = term.getCursorPos()\
  173.        y = newY - nLines\
  174.    end\
  175. end\
  176. \
  177. function slowPrint( sText, nRate )\
  178.    slowWrite( sText, nRate)\
  179.    print()\
  180. end\
  181. \
  182. function formatTime( nTime, bTwentyFourHour )\
  183.    local sTOD = nil\
  184.    if not bTwentyFourHour then\
  185.        if nTime >= 12 then\
  186.            sTOD = \"PM\"\
  187.        else\
  188.            sTOD = \"AM\"\
  189.        end\
  190.        if nTime >= 13 then\
  191.            nTime = nTime - 12\
  192.        end\
  193.    end\
  194. \
  195.    local nHour = math.floor(nTime)\
  196.    local nMinute = math.floor((nTime - nHour)*60)\
  197.    if sTOD then\
  198.        return string.format( \"%d:%02d %s\", nHour, nMinute, sTOD )\
  199.    else\
  200.        return string.format( \"%d:%02d\", nHour, nMinute )\
  201.    end\
  202. end\
  203. \
  204. local function makePagedScroll( _term, _nFreeLines )\
  205.    local nativeScroll = _term.scroll\
  206.    local nFreeLines = _nFreeLines or 0\
  207.    return function( _n )\
  208.        for n=1,_n do\
  209.            nativeScroll( 1 )\
  210.            \
  211.            if nFreeLines <= 0 then\
  212.                local w,h = _term.getSize()\
  213.                _term.setCursorPos( 1, h )\
  214.                _term.write( \"Press any key to continue\" )\
  215.                os.pullEvent( \"key\" )\
  216.                _term.clearLine()\
  217.                _term.setCursorPos( 1, h )\
  218.            else\
  219.                nFreeLines = nFreeLines - 1\
  220.            end\
  221.        end\
  222.    end\
  223. end\
  224. \
  225. function pagedPrint( _sText, _nFreeLines )\
  226.    -- Setup a redirector\
  227.    local oldTerm = term.current()\
  228.    local newTerm = {}\
  229.    for k,v in pairs( oldTerm ) do\
  230.        newTerm[k] = v\
  231.    end\
  232.    newTerm.scroll = makePagedScroll( oldTerm, _nFreeLines )\
  233.    term.redirect( newTerm )\
  234. \
  235.    -- Print the text\
  236.    local result\
  237.    local ok, err = pcall( function()\
  238.        result = print( _sText )\
  239.    end )\
  240. \
  241.    -- Removed the redirector\
  242.    term.redirect( oldTerm )\
  243. \
  244.    -- Propogate errors\
  245.    if not ok then\
  246.        error( err, 0 )\
  247.    end\
  248.    return result\
  249. end\
  250. \
  251. local function tabulateCommon( bPaged, ... )\
  252.    local tAll = { ... }\
  253.    \
  254.    local w,h = term.getSize()\
  255.    local nMaxLen = w / 8\
  256.    for n, t in ipairs( tAll ) do\
  257.        if type(t) == \"table\" then\
  258.            for n, sItem in pairs(t) do\
  259.                nMaxLen = math.max( string.len( sItem ) + 1, nMaxLen )\
  260.            end\
  261.        end\
  262.    end\
  263.    local nCols = math.floor( w / nMaxLen )\
  264.    local nLines = 0\
  265.    local function newLine()\
  266.        if bPaged and nLines >= (h-3) then\
  267.            pagedPrint()\
  268.        else\
  269.            print()\
  270.        end\
  271.        nLines = nLines + 1\
  272.    end\
  273.    \
  274.    local function drawCols( _t )\
  275.        local nCol = 1\
  276.        for n, s in ipairs( _t ) do\
  277.            if nCol > nCols then\
  278.                nCol = 1\
  279.                newLine()\
  280.            end\
  281. \
  282.            local cx, cy = term.getCursorPos()\
  283.            cx = 1 + ((nCol - 1) * nMaxLen)\
  284.            term.setCursorPos( cx, cy )\
  285.            term.write( s )\
  286. \
  287.            nCol = nCol + 1      \
  288.        end\
  289.        print()\
  290.    end\
  291.    for n, t in ipairs( tAll ) do\
  292.        if type(t) == \"table\" then\
  293.            if #t > 0 then\
  294.                drawCols( t )\
  295.            end\
  296.        elseif type(t) == \"number\" then\
  297.            term.setTextColor( t )\
  298.        end\
  299.    end    \
  300. end\
  301. \
  302. function tabulate( ... )\
  303.    tabulateCommon( false, ... )\
  304. end\
  305. \
  306. function pagedTabulate( ... )\
  307.    tabulateCommon( true, ... )\
  308. end\
  309. \
  310. local function serializeImpl( t, tTracking, sIndent )\
  311.    local sType = type(t)\
  312.    if sType == \"table\" then\
  313.        if tTracking[t] ~= nil then\
  314.            error( \"Cannot serialize table with recursive entries\", 0 )\
  315.        end\
  316.        tTracking[t] = true\
  317. \
  318.        if next(t) == nil then\
  319.            -- Empty tables are simple\
  320.            return \"{}\"\
  321.        else\
  322.            -- Other tables take more work\
  323.            local sResult = \"{\\n\"\
  324.            local sSubIndent = sIndent .. \"  \"\
  325.            local tSeen = {}\
  326.            for k,v in ipairs(t) do\
  327.                tSeen[k] = true\
  328.                sResult = sResult .. sSubIndent .. serializeImpl( v, tTracking, sSubIndent ) .. \",\\n\"\
  329.            end\
  330.            for k,v in pairs(t) do\
  331.                if not tSeen[k] then\
  332.                    local sEntry\
  333.                    if type(k) == \"string\" and string.match( k, \"^[%a_][%a%d_]*$\" ) then\
  334.                        sEntry = k .. \" = \" .. serializeImpl( v, tTracking, sSubIndent ) .. \",\\n\"\
  335.                    else\
  336.                        sEntry = \"[ \" .. serializeImpl( k, tTracking, sSubIndent ) .. \" ] = \" .. serializeImpl( v, tTracking, sSubIndent ) .. \",\\n\"\
  337.                    end\
  338.                    sResult = sResult .. sSubIndent .. sEntry\
  339.                end\
  340.            end\
  341.            sResult = sResult .. sIndent .. \"}\"\
  342.            return sResult\
  343.        end\
  344.        \
  345.    elseif sType == \"string\" then\
  346.        return string.format( \"%q\", t )\
  347.    \
  348.    elseif sType == \"number\" or sType == \"boolean\" or sType == \"nil\" then\
  349.        return tostring(t)\
  350.        \
  351.    else\
  352.        error( \"Cannot serialize type \"..sType, 0 )\
  353.        \
  354.    end\
  355. end\
  356. \
  357. function serialize( t )\
  358.    local tTracking = {}\
  359.    return serializeImpl( t, tTracking, \"\" )\
  360. end\
  361. \
  362. function unserialize( s )\
  363.    local func = loadstring( \"return \"..s, \"unserialize\" )\
  364.    if func then\
  365.        setfenv( func, {} )\
  366.        local ok, result = pcall( func )\
  367.        if ok then\
  368.            return result\
  369.        end\
  370.    end\
  371.    return nil\
  372. end\
  373. \
  374. function urlEncode( str )\
  375.    if str then\
  376.        str = string.gsub(str, \"\\n\", \"\\r\\n\")\
  377.        str = string.gsub(str, \"([^%w ])\", function(c)\
  378.            return string.format(\"%%%02X\", string.byte(c))\
  379.        end )\
  380.        str = string.gsub(str, \" \", \"+\")\
  381.    end\
  382.    return str    \
  383. end\
  384. \
  385. -- GB versions\
  386. serialise = serialize\
  387. unserialise = unserialize",
  388.   [ "/rom/help/adventure" ] = "adventure is a text adventure game for CraftOS. To navigate around the world of adventure, type simple instructions to the interpreter, for example: \"go north\", \"punch tree\", \"craft planks\", \"mine coal with pickaxe\", \"hit creeper with sword\"",
  389.   [ "/Flare/version/1.2/lib/UI/elements/ProgressBar.lua" ] = "\
  390. local class = require \"lib.class\"\
  391. local base = require \"lib.UI.base\"\
  392. local mouse = require \"lib.UI.event.mouse\"\
  393. local graphics = require \"lib.graphics\"\
  394. local formatter = require \"lib.UI.text.formatter\"\
  395. local drawtext = require \"lib.UI.draw.text\"\
  396. \
  397. local ProgressBar = class \"ProgressBar\"\
  398. ProgressBar:extend( base )\
  399. \
  400. ProgressBar.pc = \"lightGrey\" -- progress colour\
  401. ProgressBar.bc = \"grey\" -- background colour\
  402. ProgressBar.tc = \"white\" -- text colour\
  403. \
  404. ProgressBar.direction = \"horizontal\"\
  405. \
  406. ProgressBar.showPercentage = false\
  407. ProgressBar.label = nil\
  408. \
  409. ProgressBar.value = 9\
  410. \
  411. function ProgressBar:ProgressBar( x, y, w, h, value )\
  412.     self:base( x, y, w, h )\
  413.     self.value = value\
  414. end\
  415. \
  416. function ProgressBar:draw( x, y, buffer )\
  417.     buffer:setColours( graphics.colour( self.bc ) )\
  418.     buffer:drawFilledRectangle( x, y, self.width, self.height )\
  419. \
  420.     buffer:setColours( graphics.colour( self.pc ) )\
  421. \
  422.     if self.direction == \"vertical\" then\
  423.         local h = math.floor( self.height * self.value ) - .5\
  424.         buffer:drawFilledRectangle( x, y, self.width, h )\
  425.         if self.showPercentage then\
  426.             local lines = formatter.renderPrep( math.floor( self.value * 100 ) .. \"%\", { width = self.width, bc = 0, tc = self.tc } )\
  427.             formatter.fixAlignment( lines, self.width, self.height, \"centre\", \"centre\" )\
  428.             drawtext( self, lines, x, y, buffer )\
  429.         end\
  430.     else\
  431.         local w = math.floor( self.width * self.value ) - .5\
  432.         buffer:drawFilledRectangle( x, y, w, self.height )\
  433.         if self.showPercentage then\
  434.             local lines = formatter.renderPrep( math.floor( self.value * 100 ) .. \"%\", { width = self.width, bc = 0, tc = self.tc } )\
  435.             formatter.fixAlignment( lines, self.width, self.height, \"centre\", \"centre\" )\
  436.             drawtext( self, lines, x, y, buffer )\
  437.         elseif self.label then\
  438.             local lines = formatter.renderPrep( self.label, { width = self.width, bc = 0, tc = self.tc } )\
  439.             formatter.fixAlignment( lines, self.width, self.height, \"centre\", \"centre\" )\
  440.             drawtext( self, lines, x, y, buffer )\
  441.         end\
  442.     end\
  443. end\
  444. \
  445. function ProgressBar:handle( event )\
  446.     if event.name == \"mouse_ping\" then\
  447.         mouse_event.ping( self, event )\
  448.     end\
  449. end\
  450. \
  451. return ProgressBar",
  452.   [ "/rom/help/redstone" ] = "The redstone program can be used to get, set or pulse redstone inputs and outputs from the computer.\
  453. \
  454. ex:\
  455. \"redstone probe\" will list all the redstone inputs to the computer\
  456. \"redstone set left true\" turns on the left redstone output.\
  457. \"redstone set right blue false\" turns off the blue wire in the bundled cable on the right redstone output.\
  458. \"redstone pulse front 10 1\" emits 10 one second redstone pulses on the front redstone output.\
  459. \
  460. Type \"help redstoneapi\" or \"help rs\" for information on the redstone Lua API.",
  461.   [ "/rom/programs/fun/advanced/levels/5" ] = "3\
  462. 777777777\
  463. 788888887\
  464. 787787787\
  465. 787787787\
  466. 788888887\
  467. 787787787\
  468. 787787787\
  469. 78e748887\
  470. 777777777",
  471.   [ "/rom/help/excavate" ] = "excavate is a program for Mining Turtles. When excavate is run, the turtle will mine a rectangular shaft into the ground, collecting blocks as it goes, and return to the surface once bedrock is hit.\
  472. \
  473. ex:\
  474. \"excavate 3\" will mine a 3x3 shaft.",
  475.   [ "/Flare/version/1.2/lib/UI/event/mouse.lua" ] = "\
  476. local up_stops_drag = true\
  477. if not _CC_VERSION or _CC_VERSION:match \"(1.74)pr%d+\" < 1.74 then\
  478.     up_stops_drag = false\
  479. end\
  480. \
  481. local mouse = {}\
  482. \
  483. function mouse.within( self, event )\
  484.     if event.name ~= \"mouse_down\" and event.name ~= \"mouse_up\" and event.name ~= \"mouse_drag\" and event.name ~= \"mouse_scroll\" and event.name ~= \"mouse_ping\" then return false end\
  485.     local x, y, within = event:getParam \"x\", event:getParam \"y\", event:getParam \"within\"\
  486.     return x >= 1\
  487.     and x <= self.width\
  488.     and y >= 1\
  489.     and y <= self.height\
  490.     and within ~= false\
  491. end\
  492. \
  493. function mouse.click( self, event )\
  494.     if event.handled then\
  495.         return\
  496.     elseif event.name == \"mouse_drag\" then\
  497.         self.current_mouse_event = nil\
  498.     elseif mouse.within( self, event ) then\
  499.         if event.name == \"mouse_down\" and event:getParam \"button\" == 1 then\
  500.             event.handled = true\
  501.             self.current_mouse_event = {\
  502.                 time = os.clock();\
  503.                 button = event:getParam \"button\";\
  504.                 moved = false;\
  505.             }\
  506.         elseif event.name == \"mouse_up\" then\
  507.             event.handled = true\
  508.             if self.current_mouse_event then\
  509.                 if self.current_mouse_event.button == event:getParam \"button\" then\
  510.                     if os.clock() - self.current_mouse_event.time <= ( self.mouse_click_timeout or .4 ) then\
  511.                         self.current_mouse_event = nil\
  512.                         return true\
  513.                     end\
  514.                     self.current_mouse_event = nil\
  515.                 end\
  516.             end\
  517.         end\
  518.     end\
  519. end\
  520. \
  521. function mouse.drag( self, event )\
  522.     if event.handled then\
  523.         return\
  524.     elseif event.name == \"mouse_drag\" and self.current_mouse_event then\
  525.         event.handled = true\
  526.         self.current_mouse_event.moved = true\
  527.         if self.current_mouse_event.button == event:getParam \"button\" then\
  528.             return \"drag\", event:getParam \"x\", event:getParam \"y\"\
  529.         end\
  530.     elseif mouse.within( self, event ) then\
  531.         if event.name == \"mouse_down\" and event:getParam \"button\" == 1 then\
  532.             event.handled = true\
  533.             self.current_mouse_event = {\
  534.                 time = os.clock();\
  535.                 button = event:getParam \"button\";\
  536.                 moved = false;\
  537.             }\
  538.             return \"down\", event:getParam \"x\", event:getParam \"y\"\
  539.         elseif event.name == \"mouse_up\" then\
  540.             event.handled = true\
  541.             if self.current_mouse_event then\
  542.                 if self.current_mouse_event.button == event:getParam \"button\" then\
  543.                     if os.clock() - self.current_mouse_event.time <= ( self.mouse_click_timeout or .4 ) and not self.current_mouse_event.moved then\
  544.                         if up_stops_drag then\
  545.                             self.current_mouse_event = nil\
  546.                         end\
  547.                         return \"click\", event:getParam \"x\", event:getParam \"y\"\
  548.                     end\
  549.                     if up_stops_drag then\
  550.                         self.current_mouse_event = nil\
  551.                     end\
  552.                 end\
  553.             end\
  554.         end\
  555.     end\
  556. end\
  557. \
  558. function mouse.ping( self, event )\
  559.     if mouse.within( self, event ) then\
  560.         local elements = event:getParam \"elements\"\
  561.         elements[#elements + 1] = self\
  562.     end\
  563. end\
  564. \
  565. function mouse.text_link_check( lines, x, y, offset )\
  566.     if offset then\
  567.         y = y - ( offset.y or 0 )\
  568.     end\
  569.     if lines[y] then\
  570.         if offset and offset[y] then\
  571.             x = x - offset[y]\
  572.         end\
  573.         if lines[y].link[x] then\
  574.             return lines[y].link[x].protocol, lines[y].link[x].target\
  575.         end\
  576.     end\
  577. end\
  578. \
  579. return mouse",
  580.   [ "/rom/programs/turtle/equip" ] = "\
  581. local tArgs = { ... }\
  582. local function printUsage()\
  583.     print( \"Usage: equip <slot> <side>\" )\
  584. end\
  585. \
  586. if #tArgs ~= 2 then\
  587.    printUsage()\
  588.     return\
  589. end\
  590. \
  591. local function equip( nSlot, fnEquipFunction )\
  592.    turtle.select( nSlot )\
  593.    local nOldCount = turtle.getItemCount( nSlot )\
  594.    if nOldCount == 0 then\
  595.        print( \"Nothing to equip\" )\
  596.    elseif fnEquipFunction() then\
  597.        local nNewCount = turtle.getItemCount( nSlot )\
  598.        if nNewCount > 0 then\
  599.            print( \"Items swapped\" )\
  600.        else\
  601.            print( \"Item equipped\" )\
  602.        end\
  603.    else\
  604.        print( \"Item not equippable\" )\
  605.    end\
  606. end\
  607. \
  608. local nSlot = tonumber( tArgs[1] )\
  609. local sSide = tArgs[2]\
  610. if sSide == \"left\" then\
  611.    equip( nSlot, turtle.equipLeft )\
  612. elseif sSide == \"right\" then\
  613.    equip( nSlot, turtle.equipRight )\
  614. else\
  615.    printUsage()\
  616.    return\
  617. end",
  618.   [ "/Shop/run" ] = "local Dir = 'Shop'\
  619. local FlareVersion = '1.2'\
  620. -- Check and install Flare --\
  621. \
  622. if not fs.isDir( \"Flare/version/\" .. FlareVersion ) then\
  623.     fs.delete( \"Flare/version/\" .. FlareVersion )\
  624.     print \"Installing Flare\"\
  625.     local h = http.get( \"https://raw.githubusercontent.com/awsumben13/Flare/master/version/\" .. FlareVersion .. \"/install.lua\" )\
  626.     if h then\
  627.         local content = h.readAll()\
  628.         h.close()\
  629. \
  630.         local f, err = loadstring( content, \"Flare Installer\" )\
  631.         if f then\
  632.             f()\
  633.         else\
  634.             print( err )\
  635.             return\
  636.         end\
  637.     else\
  638.         print \"Failed to install Flare\"\
  639.         return\
  640.     end\
  641. end\
  642. \
  643. if not fs.isDir( Dir ) then\
  644.     Dir = fs.getDir( shell.getRunningProgram() )\
  645. end\
  646. \
  647. local FDK = dofile( \"Flare/version/\" .. FlareVersion .. \"/FDK.lua\" )\
  648. \
  649. FDK.setup( Dir ) -- set up relative paths\
  650. FDK.dofile \"main\" -- load the starting file\
  651. FDK.begin() -- begin running Flare",
  652.   [ "/rom/help/type" ] = "type determines the type of a file or directory. Prints \"file\", \"directory\" or \"does not exist\".",
  653.   [ "/rom/help/list" ] = "ls will list all the directories and files in the current location. Use \"type\" to find out if an item is a file or a directory.",
  654.   [ "/rom/help/alias" ] = "alias assigns shell commands to run other programs.\
  655. \
  656. ex:\
  657. \"alias dir ls\" will make the \"dir\" command run the \"ls\" program\
  658. \"alias dir\" will remove the alias set on \"dir\"\
  659. \"alias\" will list all current aliases.",
  660.   [ "/rom/help/rename" ] = "rename renames a file or directory.\
  661. \
  662. ex:\
  663. \"rename foo bar\" renames the file \"foo\" to \"bar\".",
  664.   [ "/rom/help/programs" ] = "programs lists all the programs on the rom of the computer.",
  665.   [ "/rom/programs/gps" ] = "\
  666. local function printUsage()\
  667.     print( \"Usages:\" )\
  668.     print( \"gps host\" )\
  669.     print( \"gps host <x> <y> <z>\" )\
  670.     print( \"gps locate\" )\
  671. end\
  672. \
  673. local tArgs = { ... }\
  674. if #tArgs < 1 then\
  675.     printUsage()\
  676.     return\
  677. end\
  678.     \
  679. local sCommand = tArgs[1]\
  680. if sCommand == \"locate\" then\
  681.     -- \"gps locate\"\
  682.     -- Just locate this computer (this will print the results)\
  683.     gps.locate( 2, true )\
  684.     \
  685. elseif sCommand == \"host\" then\
  686.     -- \"gps host\"\
  687.     -- Act as a GPS host\
  688.     if pocket then\
  689.         print( \"GPS Hosts must be stationary\" )\
  690.         return\
  691.     end\
  692. \
  693.     -- Find a modem\
  694.     local sModemSide = nil\
  695.     for n,sSide in ipairs( rs.getSides() ) do\
  696.         if peripheral.getType( sSide ) == \"modem\" and peripheral.call( sSide, \"isWireless\" ) then   \
  697.             sModemSide = sSide\
  698.             break\
  699.         end\
  700.     end\
  701. \
  702.     if sModemSide == nil then\
  703.         print( \"No wireless modems found. 1 required.\" )\
  704.         return\
  705.     end\
  706.     \
  707.     -- Open a channel\
  708.     local modem = peripheral.wrap( sModemSide )\
  709.    print( \"Opening channel on modem \"..sModemSide )\
  710.    modem.open( gps.CHANNEL_GPS )\
  711. \
  712.     -- Determine position\
  713.     local x,y,z\
  714.     if #tArgs >= 4 then\
  715.         -- Position is manually specified\
  716.         x = tonumber(tArgs[2])\
  717.         y = tonumber(tArgs[3])\
  718.         z = tonumber(tArgs[4])\
  719.         if x == nil or y == nil or z == nil then\
  720.             printUsage()\
  721.             return\
  722.         end\
  723.         print( \"Position is \"..x..\",\"..y..\",\"..z )\
  724.     else\
  725.         -- Position is to be determined using locate        \
  726.         x,y,z = gps.locate( 2, true )\
  727.         if x == nil then\
  728.             print( \"Run \\\"gps host <x> <y> <z>\\\" to set position manually\" )\
  729.             if bCloseChannel then\
  730.                 print( \"Closing GPS channel\" )\
  731.                 modem.close( gps.CHANNEL_GPS )\
  732.             end\
  733.             return\
  734.         end\
  735.     end\
  736.     \
  737.     -- Serve requests indefinately\
  738.     local nServed = 0\
  739.     while true do\
  740.         local e, p1, p2, p3, p4, p5 = os.pullEvent( \"modem_message\" )\
  741.         if e == \"modem_message\" then\
  742.             -- We received a message from a modem\
  743.             local sSide, sChannel, sReplyChannel, sMessage, nDistance = p1, p2, p3, p4, p5\
  744.             if sSide == sModemSide and sChannel == gps.CHANNEL_GPS and sMessage == \"PING\" then\
  745.                 -- We received a ping message on the GPS channel, send a response\
  746.                 modem.transmit( sReplyChannel, gps.CHANNEL_GPS, { x, y, z } )\
  747.             \
  748.                 -- Print the number of requests handled\
  749.                 nServed = nServed + 1\
  750.                 if nServed > 1 then\
  751.                     local x,y = term.getCursorPos()\
  752.                     term.setCursorPos(1,y-1)\
  753.                 end\
  754.                 print( nServed..\" GPS requests served\" )\
  755.             end\
  756.         end\
  757.     end\
  758.     \
  759.    print( \"Closing channel\" )\
  760.    modem.close( gps.CHANNEL_GPS )\
  761. \
  762. else\
  763.     -- \"gps somethingelse\"\
  764.     -- Error\
  765.     printUsage()\
  766.     \
  767. end",
  768.   [ "/Flare/version/1.2/lib/UI/animation.lua" ] = "\
  769. local tween = require \"lib.tween\"\
  770. local base = require \"lib.UI.base\"\
  771. local process = require \"lib.process\"\
  772. \
  773. local animation = {}\
  774. \
  775. animation.DEFAULT_TIME = .3\
  776. animation.SCALE_TIME = 1\
  777. animation.TWEEN = \"inOutSine\"\
  778. \
  779. function base:move( x, y, time, onFinish )\
  780.     if x == \"centre\" and self.parent then\
  781.         x = math.floor( self.parent.width / 2 - self.width / 2 + .5 ) + 1\
  782.     end\
  783.     if y == \"centre\" and self.parent then\
  784.         y = math.floor( self.parent.height / 2 - self.height / 2 + .5 ) + 1\
  785.     end\
  786.     if self.move_animation_thread then\
  787.         self.move_animation_thread:stop()\
  788.     end\
  789. \
  790.     if type( time ) == \"function\" then\
  791.         onFinish = time\
  792.         time = nil\
  793.     end\
  794. \
  795.     local t = tween.new( ( time or animation.DEFAULT_TIME ) * animation.SCALE_TIME, self, { x = x, y = y }, animation.TWEEN )\
  796.     t.round = true\
  797.     if process.thread.current then\
  798.         self.move_animation_thread = process.thread.current.parent:spawnThread( function()\
  799.             t:run()\
  800.             if onFinish then\
  801.                 onFinish( self )\
  802.             end\
  803.         end )\
  804.     else\
  805.         t:run()\
  806.     end\
  807. end\
  808. \
  809. function base:resize( w, h, time, onFinish )\
  810.     if self.resize_animation_thread then\
  811.         self.resize_animation_thread:stop()\
  812.     end\
  813. \
  814.     if type( time ) == \"function\" then\
  815.         onFinish = time\
  816.         time = nil\
  817.     end\
  818. \
  819.     local t = tween.new( ( time or animation.DEFAULT_TIME ) * animation.SCALE_TIME, self, { width = w, height = h }, animation.TWEEN )\
  820.     t.round = true\
  821.     if process.thread.current then\
  822.         self.resize_animation_thread = process.thread.current.parent:spawnThread( function()\
  823.             t:run()\
  824.             if onFinish then\
  825.                 onFinish( self )\
  826.             end\
  827.         end )\
  828.     else\
  829.         t:run()\
  830.     end\
  831. end\
  832. \
  833. function base:animateValue( index, value, time, onFinish )\
  834.     if self[index .. \"_animation_thread\"] then\
  835.         self[index .. \"_animation_thread\"]:stop()\
  836.     end\
  837. \
  838.     if type( time ) == \"function\" then\
  839.         onFinish = time\
  840.         time = nil\
  841.     end\
  842. \
  843.     local t = tween.new( ( time or animation.DEFAULT_TIME ) * animation.SCALE_TIME, self, { [index] = value }, animation.TWEEN )\
  844.     t.round = true\
  845.     if process.thread.current then\
  846.         self[index .. \"_animation_thread\"] = process.thread.current.parent:spawnThread( function()\
  847.             t:run()\
  848.             if onFinish then\
  849.                 onFinish()\
  850.             end\
  851.         end )\
  852.     else\
  853.         t:run()\
  854.     end\
  855. end\
  856. \
  857. return animation",
  858.   [ "/rom/programs/shell" ] = "\
  859. local multishell = multishell\
  860. local parentShell = shell\
  861. local parentTerm = term.current()\
  862. \
  863. if multishell then\
  864.    multishell.setTitle( multishell.getCurrent(), \"shell\" )\
  865. end\
  866. \
  867. local bExit = false\
  868. local sDir = (parentShell and parentShell.dir()) or \"\"\
  869. local sPath = (parentShell and parentShell.path()) or \".:/rom/programs\"\
  870. local tAliases = (parentShell and parentShell.aliases()) or {}\
  871. local tProgramStack = {}\
  872. \
  873. local shell = {}\
  874. local tEnv = {\
  875.     [ \"shell\" ] = shell,\
  876.     [ \"multishell\" ] = multishell,\
  877. }\
  878. \
  879. -- Colours\
  880. local promptColour, textColour, bgColour\
  881. if term.isColour() then\
  882.     promptColour = colours.yellow\
  883.     textColour = colours.white\
  884.     bgColour = colours.black\
  885. else\
  886.     promptColour = colours.white\
  887.     textColour = colours.white\
  888.     bgColour = colours.black\
  889. end\
  890. \
  891. local function run( _sCommand, ... )\
  892.     local sPath = shell.resolveProgram( _sCommand )\
  893.     if sPath ~= nil then\
  894.         tProgramStack[#tProgramStack + 1] = sPath\
  895.         if multishell then\
  896.             multishell.setTitle( multishell.getCurrent(), fs.getName( sPath ) )\
  897.         end\
  898.         local result = os.run( tEnv, sPath, ... )\
  899.         tProgramStack[#tProgramStack] = nil\
  900.         if multishell then\
  901.             if #tProgramStack > 0 then\
  902.                 multishell.setTitle( multishell.getCurrent(), fs.getName( tProgramStack[#tProgramStack] ) )\
  903.             else\
  904.                 multishell.setTitle( multishell.getCurrent(), \"shell\" )\
  905.             end\
  906.         end\
  907.         return result\
  908.     else\
  909.         printError( \"No such program\" )\
  910.         return false\
  911.    end\
  912. end\
  913. \
  914. local function tokenise( ... )\
  915.    local sLine = table.concat( { ... }, \" \" )\
  916.     local tWords = {}\
  917.    local bQuoted = false\
  918.    for match in string.gmatch( sLine .. \"\\\"\", \"(.-)\\\"\" ) do\
  919.        if bQuoted then\
  920.            table.insert( tWords, match )\
  921.        else\
  922.            for m in string.gmatch( match, \"[^ \\t]+\" ) do\
  923.                table.insert( tWords, m )\
  924.            end\
  925.        end\
  926.        bQuoted = not bQuoted\
  927.    end\
  928.    return tWords\
  929. end\
  930. \
  931. -- Install shell API\
  932. function shell.run( ... )\
  933.     local tWords = tokenise( ... )\
  934.     local sCommand = tWords[1]\
  935.     if sCommand then\
  936.         return run( sCommand, unpack( tWords, 2 ) )\
  937.     end\
  938.     return false\
  939. end\
  940. \
  941. function shell.exit()\
  942.    bExit = true\
  943. end\
  944. \
  945. function shell.dir()\
  946.     return sDir\
  947. end\
  948. \
  949. function shell.setDir( _sDir )\
  950.     sDir = _sDir\
  951. end\
  952. \
  953. function shell.path()\
  954.     return sPath\
  955. end\
  956. \
  957. function shell.setPath( _sPath )\
  958.     sPath = _sPath\
  959. end\
  960. \
  961. function shell.resolve( _sPath )\
  962.     local sStartChar = string.sub( _sPath, 1, 1 )\
  963.     if sStartChar == \"/\" or sStartChar == \"\\\\\" then\
  964.         return fs.combine( \"\", _sPath )\
  965.     else\
  966.         return fs.combine( sDir, _sPath )\
  967.     end\
  968. end\
  969. \
  970. function shell.resolveProgram( _sCommand )\
  971.     -- Substitute aliases firsts\
  972.     if tAliases[ _sCommand ] ~= nil then\
  973.         _sCommand = tAliases[ _sCommand ]\
  974.     end\
  975. \
  976.    -- If the path is a global path, use it directly\
  977.    local sStartChar = string.sub( _sCommand, 1, 1 )\
  978.    if sStartChar == \"/\" or sStartChar == \"\\\\\" then\
  979.         local sPath = fs.combine( \"\", _sCommand )\
  980.         if fs.exists( sPath ) and not fs.isDir( sPath ) then\
  981.             return sPath\
  982.         end\
  983.         return nil\
  984.    end\
  985.    \
  986.     -- Otherwise, look on the path variable\
  987.    for sPath in string.gmatch(sPath, \"[^:]+\") do\
  988.         sPath = fs.combine( shell.resolve( sPath ), _sCommand )\
  989.         if fs.exists( sPath ) and not fs.isDir( sPath ) then\
  990.             return sPath\
  991.         end\
  992.    end\
  993.     \
  994.     -- Not found\
  995.     return nil\
  996. end\
  997. \
  998. function shell.programs( _bIncludeHidden )\
  999.     local tItems = {}\
  1000.     \
  1001.     -- Add programs from the path\
  1002.    for sPath in string.gmatch(sPath, \"[^:]+\") do\
  1003.         sPath = shell.resolve( sPath )\
  1004.         if fs.isDir( sPath ) then\
  1005.             local tList = fs.list( sPath )\
  1006.             for n,sFile in pairs( tList ) do\
  1007.                 if not fs.isDir( fs.combine( sPath, sFile ) ) and\
  1008.                    (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= \".\") then\
  1009.                     tItems[ sFile ] = true\
  1010.                 end\
  1011.             end\
  1012.         end\
  1013.     end \
  1014. \
  1015.     -- Sort and return\
  1016.     local tItemList = {}\
  1017.     for sItem, b in pairs( tItems ) do\
  1018.         table.insert( tItemList, sItem )\
  1019.     end\
  1020.     table.sort( tItemList )\
  1021.     return tItemList\
  1022. end\
  1023. \
  1024. function shell.getRunningProgram()\
  1025.     if #tProgramStack > 0 then\
  1026.         return tProgramStack[#tProgramStack]\
  1027.     end\
  1028.     return nil\
  1029. end\
  1030. \
  1031. function shell.setAlias( _sCommand, _sProgram )\
  1032.     tAliases[ _sCommand ] = _sProgram\
  1033. end\
  1034. \
  1035. function shell.clearAlias( _sCommand )\
  1036.     tAliases[ _sCommand ] = nil\
  1037. end\
  1038. \
  1039. function shell.aliases()\
  1040.     -- Add aliases\
  1041.     local tCopy = {}\
  1042.     for sAlias, sCommand in pairs( tAliases ) do\
  1043.         tCopy[sAlias] = sCommand\
  1044.     end\
  1045.     return tCopy\
  1046. end\
  1047. \
  1048. if multishell then\
  1049.    function shell.openTab( ... )\
  1050.        local tWords = tokenise( ... )\
  1051.        local sCommand = tWords[1]\
  1052.        if sCommand then\
  1053.             local sPath = shell.resolveProgram( sCommand )\
  1054.             if sPath == \"rom/programs/shell\" then\
  1055.                return multishell.launch( tEnv, sPath, unpack( tWords, 2 ) )\
  1056.            elseif sPath ~= nil then\
  1057.                return multishell.launch( tEnv, \"rom/programs/shell\", sPath, unpack( tWords, 2 ) )\
  1058.            else\
  1059.                printError( \"No such program\" )\
  1060.            end\
  1061.        end\
  1062.    end\
  1063. \
  1064.    function shell.switchTab( nID )\
  1065.        multishell.setFocus( nID )\
  1066.    end\
  1067. end\
  1068. \
  1069. local tArgs = { ... }\
  1070. if #tArgs > 0 then\
  1071.    -- \"shell x y z\"\
  1072.    -- Run the program specified on the commandline\
  1073.    shell.run( ... )\
  1074. \
  1075. else\
  1076.    -- \"shell\"\
  1077.    -- Print the header\
  1078.    term.setBackgroundColor( bgColour )\
  1079.    term.setTextColour( promptColour )\
  1080.    print( os.version() )\
  1081.    term.setTextColour( textColour )\
  1082. \
  1083.    -- Run the startup program\
  1084.    if parentShell == nil then\
  1085.        shell.run( \"/rom/startup\" )\
  1086.    end\
  1087. \
  1088.    -- Read commands and execute them\
  1089.    local tCommandHistory = {}\
  1090.    while not bExit do\
  1091.        term.redirect( parentTerm )\
  1092.        term.setBackgroundColor( bgColour )\
  1093.        term.setTextColour( promptColour )\
  1094.        write( shell.dir() .. \"> \" )\
  1095.        term.setTextColour( textColour )\
  1096. \
  1097.        local sLine = read( nil, tCommandHistory )\
  1098.        table.insert( tCommandHistory, sLine )\
  1099.        shell.run( sLine )\
  1100.    end\
  1101. end",
  1102.   [ "/compress" ] = "local function Decompile(CompiledTbl)\
  1103.  local Str = ''\
  1104.  for k, v in pairs(CompiledTbl) do\
  1105.    Str = Str .. string.char(v)\
  1106.  end\
  1107.  return Str\
  1108. end\
  1109. \
  1110. local function Compile(Str)\
  1111.  local Compiled = {string.byte(Str,1,#tostring(Str))}\
  1112.  return Compiled, table.concat(Compiled, ',')\
  1113. end\
  1114. \
  1115. local Args = {...}\
  1116. \
  1117. if Args[1] ~= '-String' or Args[1] ~= '-File' then\
  1118.  printError([[\
  1119. Usage:\
  1120.  -String <str> \
  1121.  -File]])\
  1122. end\
  1123. if Args[1] == '-String' then\
  1124.  String = Args[2]\
  1125. elseif Args[1] == '-File' then\
  1126. \
  1127.  local Blacklist={\
  1128.    shell.getRunningProgram(),\
  1129.    'rom',\
  1130.  }\
  1131. \
  1132.  local function Blacklisted(Path)\
  1133.    for k, v in pairs(Blacklist) do\
  1134.      if v == Path then\
  1135.        return true\
  1136.      end\
  1137.    end\
  1138.    return false\
  1139.  end\
  1140. \
  1141.  local Path = '/'\
  1142.  local Contents = {}\
  1143. \
  1144.  local function GetDir(Path)\
  1145.    if Blacklisted(Path) then\
  1146.    else\
  1147.      local List = fs.list(Path or '/')\
  1148.      for k, v in pairs(List) do\
  1149. \
  1150.        local CurrentPath = Path..fs.getName(\
  1151.          fs.combine(\
  1152.            Path,\
  1153.            v\
  1154.          )\
  1155.        )\
  1156.        if fs.isDir(CurrentPath) then\
  1157.          CurrentPath = CurrentPath .. '/'\
  1158.        end\
  1159.        print(tostring(CurrentPath))\
  1160.        if fs.isDir(CurrentPath) then\
  1161.          GetDir(CurrentPath)\
  1162.        else\
  1163.          local File = fs.open(CurrentPath, 'r')\
  1164.          if File then\
  1165.            local Data = File.readAll()\
  1166.            -- Compile data --\
  1167.            --Data = --{string.byte(Data,1,#tostring(Data))}\
  1168.            --print(table.concat(Data, ', '))\
  1169.            --os.pullEvent()\
  1170.            File.close()\
  1171.            Contents[CurrentPath] = Data\
  1172.            os.queueEvent('Ping')\
  1173.            os.pullEvent('Ping')\
  1174.          end\
  1175.        end\
  1176.      end\
  1177.    end\
  1178.  end\
  1179. \
  1180. \
  1181.  GetDir(Path)\
  1182. \
  1183.  --print('Waiting for input...')\
  1184.  --os.pullEvent('key')\
  1185.  --term.clear()\
  1186.  --term.setCursorPos(1,1)\
  1187.  local Pre = [[local tbl=]]\
  1188.  local Extra = [[\
  1189.  for k, v in pairs(tbl) do\
  1190.    local X = fs.open(k, 'w')\
  1191.    X.write(v)\
  1192.    X.close()\
  1193.  end\
  1194.  ]]\
  1195.  Compiled = fs.open('Compiled', 'w')\
  1196.  Compiled.write(Pre..textutils.serialize(Contents)..Extra)\
  1197.  Compiled.close()\
  1198.  --\
  1199.  --Decompiled = textutils.unserialize(Compiled.readAll())\
  1200. end",
  1201.   [ "/rom/programs/clear" ] = "term.clear()\
  1202. term.setCursorPos( 1, 1 )",
  1203.   [ "/rom/help/dance" ] = "dance is a program for Turtles. Turtles love to get funky.",
  1204.   [ "/Flare/version/1.2/lib/UI/elements/Input.lua" ] = "\
  1205. local class = require \"lib.class\"\
  1206. local base = require \"lib.UI.base\"\
  1207. local mouse = require \"lib.UI.event.mouse\"\
  1208. local graphics = require \"lib.graphics\"\
  1209. \
  1210. local Input = class \"Input\"\
  1211. Input:extend( base )\
  1212. \
  1213. function Input:Input( x, y, w, mask )\
  1214.     self:base( x, y, w, 1 )\
  1215. \
  1216.     self.text = \"\"\
  1217.     self.cpos = 1\
  1218.     self.selecting = false\
  1219.     self.scroll = 0\
  1220.     self.mask = mask\
  1221.     self.focussed = false\
  1222.     self.down = false\
  1223. \
  1224.     self.fc  = colours.white\
  1225.     self.bc  = colours.lightGrey\
  1226.     self.tc  = colours.grey\
  1227.     self.hc  = colours.blue\
  1228.     self.htc = colours.white\
  1229. \
  1230.     self.downRequiredToDrag = os.version() == \"CraftOS 1.7\"\
  1231. end\
  1232. \
  1233. function Input:setCursorPos( pos )\
  1234.     self.cpos = math.min( math.max( pos, 1 ), #self.text + 1 )\
  1235.     if self.cpos - self.scroll <= 0 then\
  1236.         self.scroll = self.cpos - 1\
  1237.     elseif self.cpos > self.scroll + self.width then\
  1238.         self.scroll = self.cpos - self.width\
  1239.     end\
  1240. end\
  1241. \
  1242. function Input:write( content )\
  1243.     if self.selecting then\
  1244.         self.text = self.text:sub( 1, math.min( self.cpos, self.selecting ) - 1 ) .. content .. self.text:sub( math.max( self.cpos, self.selecting ) + 1 )\
  1245.         self:setCursorPos( math.min( self.cpos, self.selecting ) + #content )\
  1246.         self.selecting = false\
  1247.     else\
  1248.         self.text = self.text:sub( 1, self.cpos - 1 ) .. content .. self.text:sub( self.cpos )\
  1249.         self:setCursorPos( self.cpos + #content )\
  1250.     end\
  1251. end\
  1252. \
  1253. function Input:getSelection()\
  1254.     if self.selecting then\
  1255.         return self.text:sub( math.min( self.cpos, self.selecting ), math.max( self.cpos, self.selecting ) )\
  1256.     end\
  1257. end\
  1258. \
  1259. function Input:focusOn()\
  1260.     self.focussed = true\
  1261. end\
  1262. \
  1263. function Input:unFocus()\
  1264.     self.focussed = false\
  1265. end\
  1266. \
  1267. function Input:draw( x, y, buffer )\
  1268.     if self.focussed then\
  1269.         buffer:setCursorBlink( x - self.scroll + self.cpos - 1, y, self.tc )\
  1270.     end\
  1271. \
  1272.     local _bc, _tc = buffer:getColours()\
  1273.     for i = 1, self.width do\
  1274.         local char = i + self.scroll\
  1275.         local bc, tc = graphics.colour( self.bc ), graphics.colour( self.tc )\
  1276.         if self.focussed then\
  1277.             bc = graphics.colour( self.fc )\
  1278.         end\
  1279.         if self.selecting and char >= math.min( self.cpos, self.selecting ) and char <= math.max( self.cpos, self.selecting ) then\
  1280.             bc, tc = graphics.colour( self.hc ), graphics.colour( self.htc )\
  1281.         end\
  1282.         local c = self.text:sub( char, char )\
  1283.         if self.mask and c ~= \"\" then\
  1284.             c = self.mask\
  1285.         end\
  1286.         if _bc ~= bc or _tc ~= tc then\
  1287.             buffer:setColours( bc, tc )\
  1288.             _bc, _tc = bc, tc\
  1289.         end\
  1290.         buffer:drawPixel( x, y, c )\
  1291.         x = x + 1\
  1292.     end\
  1293. end\
  1294. \
  1295. function Input:handle( event )\
  1296.     if type( self.onChange ) ~= \"function\" then self.onChange = nil end\
  1297.     if event.name == \"mouse_down\" and ( event.handled or not mouse.within( self, event ) ) then\
  1298.         self.focussed = false\
  1299.         self.down = false\
  1300.     elseif not event.handled and event.name == \"mouse_down\" and mouse.within( self, event ) then\
  1301.         event.handled = true\
  1302.         self.focussed = true\
  1303.         self.selecting = false\
  1304. \
  1305.         if self.down and os.clock() - self.downTime < .5 then\
  1306.             local x = math.min( event:getParam \"x\" + self.scroll, #self.text )\
  1307.             local char = self.text:sub( x, x )\
  1308.             local m = \"\"\
  1309.             if char:find \"%s\" then\
  1310.                 m = \"%s\"\
  1311.             elseif char:find \"%w\" then\
  1312.                 m = \"[%w_]\"\
  1313.             else\
  1314.                 m = \"[^%s%w]\"\
  1315.             end\
  1316.             local min, max = x, x\
  1317.             for i = x, 1, -1 do\
  1318.                 if self.text:sub( i, i ):find( m ) then\
  1319.                     min = i\
  1320.                 else\
  1321.                     break\
  1322.                 end\
  1323.             end\
  1324.             for i = x, #self.text do\
  1325.                 if self.text:sub( i, i ):find( m ) then\
  1326.                     max = i\
  1327.                 else\
  1328.                     break\
  1329.                 end\
  1330.             end\
  1331.             self.cpos = min\
  1332.             self.selecting = max\
  1333.             self.down = nil\
  1334.             self.downTime = nil\
  1335.         else\
  1336.             self.down = event:getParam \"x\"\
  1337.             self.downTime = os.clock()\
  1338.             self.cpos = math.min( #self.text + 1, self.down + self.scroll )\
  1339.         end\
  1340.     elseif not event.handled and event.name == \"mouse_up\" and mouse.within( self, event ) then\
  1341.         event.handled = true\
  1342.         if self.downRequiredToDrag then\
  1343.             self.down = false\
  1344.         end\
  1345.     elseif not event.handled and event.name == \"mouse_drag\" and self.down then\
  1346.         event.handled = true\
  1347. \
  1348.         local rx = event:getParam \"x\"\
  1349.         self.selecting = math.max( math.min( #self.text + 1, rx + self.scroll ), 1 )\
  1350.     elseif not event.handled and event.name == \"key\" and self.focussed then\
  1351.         local key = event:getParam \"key\"\
  1352. \
  1353.         if key == \"left\" then\
  1354.             if self.selecting then\
  1355.                 self:setCursorPos( math.min( self.cpos, self.selecting ) )\
  1356.             else\
  1357.                 self:setCursorPos( self.cpos - 1 )\
  1358.             end\
  1359.             event.handled = true\
  1360.         elseif key == \"right\" then\
  1361.             if self.selecting then\
  1362.                 self:setCursorPos( math.max( self.cpos, self.selecting ) )\
  1363.             else\
  1364.                 self:setCursorPos( self.cpos + 1 )\
  1365.             end\
  1366.             event.handled = true\
  1367.         elseif key == \"backspace\" then\
  1368.             if self.selecting then\
  1369.                 self.text = self.text:sub( 1, math.min( self.cpos, self.selecting ) - 1 ) .. self.text:sub( math.max( self.cpos, self.selecting ) + 1 )\
  1370.                 self:setCursorPos( math.min( self.cpos, self.selecting ) )\
  1371.                 self.selecting = false\
  1372.             elseif self.cpos > 1 then\
  1373.                 self.text = self.text:sub( 1, self.cpos - 2 ) .. self.text:sub( self.cpos )\
  1374.                 self:setCursorPos( self.cpos - 1 )\
  1375.             end\
  1376.             event.handled = true\
  1377.             if self.onChange then\
  1378.                 self:onChange()\
  1379.             end\
  1380.         elseif key == \"delete\" then\
  1381.             if self.selecting then\
  1382.                 self.text = self.text:sub( 1, math.min( self.cpos, self.selecting ) - 1 ) .. self.text:sub( math.max( self.cpos, self.selecting ) + 1 )\
  1383.                 self:setCursorPos( math.min( self.cpos, self.selecting ) )\
  1384.                 self.selecting = false\
  1385.             else\
  1386.                 self.text = self.text:sub( 1, self.cpos - 1 ) .. self.text:sub( self.cpos + 1 )\
  1387.             end\
  1388.             event.handled = true\
  1389.             if self.onChange then\
  1390.                 self:onChange()\
  1391.             end\
  1392.         elseif key == \"home\" then\
  1393.             self.selecting = false\
  1394.             self:setCursorPos( 1 )\
  1395.             event.handled = true\
  1396.         elseif key == \"end\" then\
  1397.             self.selecting = false\
  1398.             self:setCursorPos( #self.text + 1 )\
  1399.             event.handled = true\
  1400.         elseif key == \"enter\" then\
  1401.             if self.selecting then\
  1402.                 self.selecting = false\
  1403.                 self:write \"\"\
  1404.                 if self.onChange then\
  1405.                     self:onChange()\
  1406.                 end\
  1407.             end\
  1408.             if self.onEnter then\
  1409.                 self:onEnter()\
  1410.             end\
  1411.             event.handled = true\
  1412.         elseif key == \"tab\" then\
  1413.             if self.onTab then\
  1414.                 self:onTab()\
  1415.             else\
  1416.                 self:write \" \"\
  1417.                 if self.onChange then\
  1418.                     self:onChange()\
  1419.                 end\
  1420.             end\
  1421.             event.handled = true\
  1422.         end\
  1423.     elseif not event.handled and event.name == \"char\" and self.focussed then\
  1424.         if self.selecting then\
  1425.             self.text = self.text:sub( 1, math.min( self.cpos, self.selecting ) - 1 ) .. event:getParam \"char\" .. self.text:sub( math.max( self.cpos, self.selecting ) + 1 )\
  1426.             self:setCursorPos( math.min( self.cpos, self.selecting ) + 1 )\
  1427.             self.selecting = false\
  1428.         else\
  1429.             self.text = self.text:sub( 1, self.cpos - 1 ) .. event:getParam \"char\" .. self.text:sub( self.cpos )\
  1430.             self:setCursorPos( self.cpos + 1 )\
  1431.         end\
  1432.         if self.onChange then\
  1433.             self:onChange()\
  1434.         end\
  1435.     elseif not event.handled and event.name == \"paste\" and self.focussed then\
  1436.         self:write( event:getParam \"data\" )\
  1437.         if self.onChange then\
  1438.             self:onChange()\
  1439.         end\
  1440.     elseif event.name == \"mouse_ping\" then\
  1441.         mouse.ping( self, event )\
  1442.     end\
  1443. end\
  1444. \
  1445. return Input",
  1446.   [ "/rom/programs/rename" ] = "local tArgs = { ... }\
  1447. if #tArgs < 2 then\
  1448.     print( \"Usage: rename <source> <destination>\" )\
  1449.     return\
  1450. end\
  1451. \
  1452. local sSource = shell.resolve( tArgs[1] )\
  1453. local sDest = shell.resolve( tArgs[2] )\
  1454. fs.move( sSource, sDest )",
  1455.   [ "/rom/programs/edit" ] = "-- Get file to edit\
  1456. local tArgs = { ... }\
  1457. if #tArgs == 0 then\
  1458.     print( \"Usage: edit <path>\" )\
  1459.     return\
  1460. end\
  1461. \
  1462. -- Error checking\
  1463. local sPath = shell.resolve( tArgs[1] )\
  1464. local bReadOnly = fs.isReadOnly( sPath )\
  1465. if fs.exists( sPath ) and fs.isDir( sPath ) then\
  1466.     print( \"Cannot edit a directory.\" )\
  1467.     return\
  1468. end\
  1469. \
  1470. local x,y = 1,1\
  1471. local w,h = term.getSize()\
  1472. local scrollX, scrollY = 0,0\
  1473. \
  1474. local tLines = {}\
  1475. local bRunning = true\
  1476. \
  1477. -- Colours\
  1478. local highlightColour, keywordColour, commentColour, textColour, bgColour\
  1479. if term.isColour() then\
  1480.     bgColour = colours.black\
  1481.     textColour = colours.white\
  1482.     highlightColour = colours.yellow\
  1483.     keywordColour = colours.yellow\
  1484.     commentColour = colours.green\
  1485.     stringColour = colours.red\
  1486. else\
  1487.     bgColour = colours.black\
  1488.     textColour = colours.white\
  1489.     highlightColour = colours.white\
  1490.     keywordColour = colours.white\
  1491.     commentColour = colours.white\
  1492.     stringColour = colours.white\
  1493. end\
  1494. \
  1495. -- Menus\
  1496. local bMenu = false\
  1497. local nMenuItem = 1\
  1498. local tMenuItems\
  1499. if bReadOnly then\
  1500.     tMenuItems = { \"Exit\", \"Print\" }\
  1501. else\
  1502.     tMenuItems = { \"Save\", \"Exit\", \"Print\" }\
  1503. end\
  1504.     \
  1505. local sStatus = \"Press Ctrl to access menu\"\
  1506. \
  1507. local function load( _sPath )\
  1508.     tLines = {}\
  1509.     if fs.exists( _sPath ) then\
  1510.         local file = io.open( _sPath, \"r\" )\
  1511.         local sLine = file:read()\
  1512.         while sLine do\
  1513.             table.insert( tLines, sLine )\
  1514.             sLine = file:read()\
  1515.         end\
  1516.         file:close()\
  1517.     end\
  1518.     \
  1519.     if #tLines == 0 then\
  1520.         table.insert( tLines, \"\" )\
  1521.     end\
  1522. end\
  1523. \
  1524. local function save( _sPath )\
  1525.     -- Create intervening folder\
  1526.     local sDir = sPath:sub(1, sPath:len() - fs.getName(sPath):len() )\
  1527.     if not fs.exists( sDir ) then\
  1528.         fs.makeDir( sDir )\
  1529.     end\
  1530. \
  1531.     -- Save\
  1532.     local file = nil\
  1533.     local function innerSave()\
  1534.         file = fs.open( _sPath, \"w\" )\
  1535.         if file then\
  1536.             for n, sLine in ipairs( tLines ) do\
  1537.                 file.write( sLine .. \"\\n\" )\
  1538.             end\
  1539.         else\
  1540.             error( \"Failed to open \".._sPath )\
  1541.         end\
  1542.     end\
  1543.     \
  1544.     local ok = pcall( innerSave )\
  1545.     if file then \
  1546.         file.close()\
  1547.     end\
  1548.     return ok\
  1549. end\
  1550. \
  1551. local tKeywords = {\
  1552.     [\"and\"] = true,\
  1553.     [\"break\"] = true,\
  1554.     [\"do\"] = true,\
  1555.     [\"else\"] = true,\
  1556.     [\"elseif\"] = true,\
  1557.     [\"end\"] = true,\
  1558.     [\"false\"] = true,\
  1559.     [\"for\"] = true,\
  1560.     [\"function\"] = true,\
  1561.     [\"if\"] = true,\
  1562.     [\"in\"] = true,\
  1563.     [\"local\"] = true,\
  1564.     [\"nil\"] = true,\
  1565.     [\"not\"] = true,\
  1566.     [\"or\"] = true,\
  1567.     [\"repeat\"] = true,\
  1568.     [\"return\"] = true,\
  1569.     [\"then\"] = true,\
  1570.     [\"true\"] = true,\
  1571.     [\"until\"]= true,\
  1572.     [\"while\"] = true,\
  1573. }\
  1574. \
  1575. local function tryWrite( sLine, regex, colour )\
  1576.     local match = string.match( sLine, regex )\
  1577.     if match then\
  1578.         if type(colour) == \"number\" then\
  1579.             term.setTextColour( colour )\
  1580.         else\
  1581.             term.setTextColour( colour(match) )\
  1582.         end\
  1583.         term.write( match )\
  1584.         term.setTextColour( textColour )\
  1585.         return string.sub( sLine, string.len(match) + 1 )\
  1586.     end\
  1587.     return nil\
  1588. end\
  1589. \
  1590. local function writeHighlighted( sLine )\
  1591.     while string.len(sLine) > 0 do  \
  1592.         sLine = \
  1593.             tryWrite( sLine, \"^%-%-%[%[.-%]%]\", commentColour ) or\
  1594.             tryWrite( sLine, \"^%-%-.*\", commentColour ) or\
  1595.             tryWrite( sLine, \"^\\\".-[^\\\\]\\\"\", stringColour ) or\
  1596.             tryWrite( sLine, \"^\\'.-[^\\\\]\\'\", stringColour ) or\
  1597.             tryWrite( sLine, \"^%[%[.-%]%]\", stringColour ) or\
  1598.             tryWrite( sLine, \"^[%w_]+\", function( match )\
  1599.                 if tKeywords[ match ] then\
  1600.                     return keywordColour\
  1601.                 end\
  1602.                 return textColour\
  1603.             end ) or\
  1604.             tryWrite( sLine, \"^[^%w_]\", textColour )\
  1605.     end\
  1606. end\
  1607. \
  1608. local function redrawText()\
  1609.     for y=1,h-1 do\
  1610.         term.setCursorPos( 1 - scrollX, y )\
  1611.         term.clearLine()\
  1612. \
  1613.         local sLine = tLines[ y + scrollY ]\
  1614.         if sLine ~= nil then\
  1615.             writeHighlighted( sLine )\
  1616.         end\
  1617.     end\
  1618.     term.setCursorPos( x - scrollX, y - scrollY )\
  1619. end\
  1620. \
  1621. local function redrawLine(_nY)\
  1622.     local sLine = tLines[_nY]\
  1623.     term.setCursorPos( 1 - scrollX, _nY - scrollY )\
  1624.     term.clearLine()\
  1625.     writeHighlighted( sLine )\
  1626.     term.setCursorPos( x - scrollX, _nY - scrollY )\
  1627. end\
  1628. \
  1629. local function redrawMenu()\
  1630.    -- Clear line\
  1631.    term.setCursorPos( 1, h )\
  1632.     term.clearLine()\
  1633. \
  1634.    -- Draw line numbers\
  1635.    term.setCursorPos( w - string.len( \"Ln \"..y ) + 1, h )\
  1636.    term.setTextColour( highlightColour )\
  1637.    term.write( \"Ln \" )\
  1638.    term.setTextColour( textColour )\
  1639.    term.write( y )\
  1640. \
  1641.    term.setCursorPos( 1, h )\
  1642.     if bMenu then\
  1643.        -- Draw menu\
  1644.         term.setTextColour( textColour )\
  1645.         for nItem,sItem in pairs( tMenuItems ) do\
  1646.             if nItem == nMenuItem then\
  1647.                 term.setTextColour( highlightColour )\
  1648.                 term.write( \"[\" )\
  1649.                 term.setTextColour( textColour )\
  1650.                 term.write( sItem )\
  1651.                 term.setTextColour( highlightColour )\
  1652.                 term.write( \"]\" )\
  1653.                 term.setTextColour( textColour )\
  1654.             else\
  1655.                 term.write( \" \"..sItem..\" \" )\
  1656.             end\
  1657.         end\
  1658.    else\
  1659.        -- Draw status\
  1660.        term.setTextColour( highlightColour )\
  1661.        term.write( sStatus )\
  1662.        term.setTextColour( textColour )\
  1663.    end\
  1664. \
  1665.     -- Reset cursor\
  1666.     term.setCursorPos( x - scrollX, y - scrollY )\
  1667. end\
  1668. \
  1669. local tMenuFuncs = { \
  1670.     Save=function()\
  1671.         if bReadOnly then\
  1672.             sStatus = \"Access denied\"\
  1673.         else\
  1674.             local ok, err = save( sPath )\
  1675.             if ok then\
  1676.                 sStatus=\"Saved to \"..sPath\
  1677.             else\
  1678.                 sStatus=\"Error saving to \"..sPath\
  1679.             end\
  1680.         end\
  1681.         redrawMenu()\
  1682.     end,\
  1683.     Print=function()\
  1684.         local printer = peripheral.find( \"printer\" )\
  1685.         if not printer then\
  1686.             sStatus = \"No printer attached\"\
  1687.             return\
  1688.         end\
  1689. \
  1690.         local nPage = 0\
  1691.         local sName = fs.getName( sPath )\
  1692.         if printer.getInkLevel() < 1 then\
  1693.             sStatus = \"Printer out of ink\"\
  1694.             return\
  1695.         elseif printer.getPaperLevel() < 1 then\
  1696.             sStatus = \"Printer out of paper\"\
  1697.             return\
  1698.         end\
  1699. \
  1700.         local screenTerminal = term.current()\
  1701.         local printerTerminal = {\
  1702.             getCursorPos = printer.getCursorPos,\
  1703.             setCursorPos = printer.setCursorPos,\
  1704.             getSize = printer.getPageSize,\
  1705.             write = printer.write,\
  1706.         }\
  1707.         printerTerminal.scroll = function()\
  1708.             if nPage == 1 then\
  1709.                 printer.setPageTitle( sName..\" (page \"..nPage..\")\" )            \
  1710.             end\
  1711.             \
  1712.             while not printer.newPage() do\
  1713.                 if printer.getInkLevel() < 1 then\
  1714.                     sStatus = \"Printer out of ink, please refill\"\
  1715.                 elseif printer.getPaperLevel() < 1 then\
  1716.                     sStatus = \"Printer out of paper, please refill\"\
  1717.                 else\
  1718.                     sStatus = \"Printer output tray full, please empty\"\
  1719.                 end\
  1720.     \
  1721.                 term.redirect( screenTerminal )\
  1722.                 redrawMenu()\
  1723.                 term.redirect( printerTerminal )\
  1724.                 \
  1725.                 local timer = os.startTimer(0.5)\
  1726.                 sleep(0.5)\
  1727.             end\
  1728. \
  1729.             nPage = nPage + 1\
  1730.             if nPage == 1 then\
  1731.                 printer.setPageTitle( sName )\
  1732.             else\
  1733.                 printer.setPageTitle( sName..\" (page \"..nPage..\")\" )\
  1734.             end\
  1735.         end\
  1736.         \
  1737.         bMenu = false\
  1738.         term.redirect( printerTerminal )\
  1739.         local ok, error = pcall( function()\
  1740.             term.scroll()\
  1741.             for n, sLine in ipairs( tLines ) do\
  1742.                 print( sLine )\
  1743.             end\
  1744.         end )\
  1745.        term.redirect( screenTerminal )\
  1746.         if not ok then\
  1747.             print( error )\
  1748.         end\
  1749.         \
  1750.         while not printer.endPage() do\
  1751.             sStatus = \"Printer output tray full, please empty\"\
  1752.             redrawMenu()\
  1753.             sleep( 0.5 )\
  1754.         end\
  1755.         bMenu = true\
  1756.             \
  1757.         if nPage > 1 then\
  1758.             sStatus = \"Printed \"..nPage..\" Pages\"\
  1759.         else\
  1760.             sStatus = \"Printed 1 Page\"\
  1761.         end\
  1762.         redrawMenu()\
  1763.     end,\
  1764.     Exit=function()\
  1765.         bRunning = false\
  1766.     end\
  1767. }\
  1768. \
  1769. local function doMenuItem( _n )\
  1770.     tMenuFuncs[tMenuItems[_n]]()\
  1771.     if bMenu then\
  1772.         bMenu = false\
  1773.         term.setCursorBlink( true )\
  1774.     end\
  1775.     redrawMenu()\
  1776. end\
  1777. \
  1778. local function setCursor( x, y )\
  1779.     local screenX = x - scrollX\
  1780.     local screenY = y - scrollY\
  1781.     \
  1782.     local bRedraw = false\
  1783.     if screenX < 1 then\
  1784.         scrollX = x - 1\
  1785.         screenX = 1\
  1786.         bRedraw = true\
  1787.     elseif screenX > w then\
  1788.         scrollX = x - w\
  1789.         screenX = w\
  1790.         bRedraw = true\
  1791.     end\
  1792.     \
  1793.     if screenY < 1 then\
  1794.         scrollY = y - 1\
  1795.         screenY = 1\
  1796.         bRedraw = true\
  1797.     elseif screenY > h-1 then\
  1798.         scrollY = y - (h-1)\
  1799.         screenY = h-1\
  1800.         bRedraw = true\
  1801.     end\
  1802.     \
  1803.     if bRedraw then\
  1804.         redrawText()\
  1805.     end\
  1806.     term.setCursorPos( screenX, screenY )\
  1807.     \
  1808.     -- Statusbar now pertains to menu, it would probably be safe to redraw the menu on every key event.\
  1809.     redrawMenu()\
  1810. end\
  1811. \
  1812. -- Actual program functionality begins\
  1813. load(sPath)\
  1814. \
  1815. term.setBackgroundColour( bgColour )\
  1816. term.clear()\
  1817. term.setCursorPos(x,y)\
  1818. term.setCursorBlink( true )\
  1819. \
  1820. redrawText()\
  1821. redrawMenu()\
  1822. \
  1823. -- Handle input\
  1824. while bRunning do\
  1825.     local sEvent, param, param2, param3 = os.pullEvent()\
  1826.     if sEvent == \"key\" then\
  1827.         if param == keys.up then\
  1828.             -- Up\
  1829.             if not bMenu then\
  1830.                 if y > 1 then\
  1831.                     -- Move cursor up\
  1832.                     y = y - 1\
  1833.                     x = math.min( x, string.len( tLines[y] ) + 1 )\
  1834.                     setCursor( x, y )\
  1835.                 end\
  1836.             end\
  1837.         elseif param == keys.down then\
  1838.             -- Down\
  1839.             if not bMenu then\
  1840.                 -- Move cursor down\
  1841.                 if y < #tLines then\
  1842.                     y = y + 1\
  1843.                     x = math.min( x, string.len( tLines[y] ) + 1 )\
  1844.                     setCursor( x, y )\
  1845.                 end\
  1846.             end\
  1847.         elseif param == keys.tab then\
  1848.             -- Tab\
  1849.             if not bMenu and not bReadOnly then\
  1850.                 -- Indent line\
  1851.                 tLines[y]=\"  \"..tLines[y]\
  1852.                 x = x + 2\
  1853.                 setCursor( x, y )\
  1854.                 redrawLine(y)\
  1855.             end\
  1856.         elseif param == keys.pageUp then\
  1857.             -- Page Up\
  1858.             if not bMenu then\
  1859.                 -- Move up a page\
  1860.                 if y - (h - 1) >= 1 then\
  1861.                     y = y - (h - 1)\
  1862.                 else\
  1863.                     y = 1\
  1864.                 end\
  1865.                 x = math.min( x, string.len( tLines[y] ) + 1 )\
  1866.                 setCursor( x, y )\
  1867.             end\
  1868.         elseif param == keys.pageDown then\
  1869.             -- Page Down\
  1870.             if not bMenu then\
  1871.                 -- Move down a page\
  1872.                 if y + (h - 1) <= #tLines then\
  1873.                     y = y + (h - 1)\
  1874.                 else\
  1875.                     y = #tLines\
  1876.                 end\
  1877.                 x = math.min( x, string.len( tLines[y] ) + 1 )\
  1878.                 setCursor( x, y )\
  1879.             end\
  1880.         elseif param == keys.home then\
  1881.             -- Home\
  1882.             if not bMenu then\
  1883.                 -- Move cursor to the beginning\
  1884.                 x=1\
  1885.                 setCursor(x,y)\
  1886.             end\
  1887.         elseif param == keys[\"end\"] then\
  1888.             -- End\
  1889.             if not bMenu then\
  1890.                 -- Move cursor to the end\
  1891.                 x = string.len( tLines[y] ) + 1\
  1892.                 setCursor(x,y)\
  1893.             end\
  1894.         elseif param == keys.left then\
  1895.             -- Left\
  1896.             if not bMenu then\
  1897.                 if x > 1 then\
  1898.                     -- Move cursor left\
  1899.                     x = x - 1\
  1900.                 elseif x==1 and y>1 then\
  1901.                     x = string.len( tLines[y-1] ) + 1\
  1902.                     y = y - 1\
  1903.                 end\
  1904.                 setCursor( x, y )\
  1905.             else\
  1906.                 -- Move menu left\
  1907.                 nMenuItem = nMenuItem - 1\
  1908.                 if nMenuItem < 1 then\
  1909.                     nMenuItem = #tMenuItems\
  1910.                 end\
  1911.                 redrawMenu()\
  1912.             end\
  1913.         elseif param == keys.right then\
  1914.             -- Right\
  1915.             if not bMenu then\
  1916.                 if x < string.len( tLines[y] ) + 1 then\
  1917.                     -- Move cursor right\
  1918.                     x = x + 1\
  1919.                 elseif x==string.len( tLines[y] ) + 1 and y<#tLines then\
  1920.                     x = 1\
  1921.                     y = y + 1\
  1922.                 end\
  1923.                 setCursor( x, y )\
  1924.             else\
  1925.                 -- Move menu right\
  1926.                 nMenuItem = nMenuItem + 1\
  1927.                 if nMenuItem > #tMenuItems then\
  1928.                     nMenuItem = 1\
  1929.                 end\
  1930.                 redrawMenu()\
  1931.             end\
  1932.         elseif param == keys.delete then\
  1933.             -- Delete\
  1934.             if not bMenu and not bReadOnly then\
  1935.                 if  x < string.len( tLines[y] ) + 1 then\
  1936.                     local sLine = tLines[y]\
  1937.                     tLines[y] = string.sub(sLine,1,x-1) .. string.sub(sLine,x+1)\
  1938.                     redrawLine(y)\
  1939.                 elseif y<#tLines then\
  1940.                     tLines[y] = tLines[y] .. tLines[y+1]\
  1941.                     table.remove( tLines, y+1 )\
  1942.                     redrawText()\
  1943.                     redrawMenu()\
  1944.                 end\
  1945.             end\
  1946.         elseif param == keys.backspace then\
  1947.             -- Backspace\
  1948.             if not bMenu and not bReadOnly then\
  1949.                 if x > 1 then\
  1950.                     -- Remove character\
  1951.                     local sLine = tLines[y]\
  1952.                     tLines[y] = string.sub(sLine,1,x-2) .. string.sub(sLine,x)\
  1953.                     redrawLine(y)\
  1954.             \
  1955.                     x = x - 1\
  1956.                     setCursor( x, y )\
  1957.                 elseif y > 1 then\
  1958.                     -- Remove newline\
  1959.                     local sPrevLen = string.len( tLines[y-1] )\
  1960.                     tLines[y-1] = tLines[y-1] .. tLines[y]\
  1961.                     table.remove( tLines, y )\
  1962.                     redrawText()\
  1963.                 \
  1964.                     x = sPrevLen + 1\
  1965.                     y = y - 1\
  1966.                     setCursor( x, y )\
  1967.                 end\
  1968.             end\
  1969.         elseif param == keys.enter then\
  1970.             -- Enter\
  1971.             if not bMenu and not bReadOnly then\
  1972.                 -- Newline\
  1973.                 local sLine = tLines[y]\
  1974.                 local _,spaces=string.find(sLine,\"^[ ]+\")\
  1975.                 if not spaces then\
  1976.                     spaces=0\
  1977.                 end\
  1978.                 tLines[y] = string.sub(sLine,1,x-1)\
  1979.                 table.insert( tLines, y+1, string.rep(' ',spaces)..string.sub(sLine,x) )\
  1980.                 redrawText()\
  1981.             \
  1982.                 x = spaces+1\
  1983.                 y = y + 1\
  1984.                 setCursor( x, y )\
  1985.             elseif bMenu then\
  1986.                 -- Menu selection\
  1987.                 doMenuItem( nMenuItem )\
  1988.             end\
  1989.         elseif param == keys.leftCtrl or param == keys.rightCtrl then\
  1990.             -- Menu toggle\
  1991.             bMenu = not bMenu\
  1992.             if bMenu then\
  1993.                 term.setCursorBlink( false )\
  1994.             else\
  1995.                 term.setCursorBlink( true )\
  1996.             end\
  1997.             redrawMenu()\
  1998.         end\
  1999.         \
  2000.     elseif sEvent == \"char\" then\
  2001.         if not bMenu and not bReadOnly then\
  2002.             -- Input text\
  2003.             local sLine = tLines[y]\
  2004.             tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)\
  2005.             redrawLine(y)\
  2006.         \
  2007.             x = x + 1\
  2008.             setCursor( x, y )\
  2009.         elseif bMenu then\
  2010.             -- Select menu items\
  2011.             for n,sMenuItem in ipairs( tMenuItems ) do\
  2012.                 if string.lower(string.sub(sMenuItem,1,1)) == string.lower(param) then\
  2013.                     doMenuItem( n )\
  2014.                     break\
  2015.                 end\
  2016.             end\
  2017.         end\
  2018. \
  2019.     elseif sEvent == \"paste\" then\
  2020.         if not bMenu and not bReadOnly then\
  2021.             -- Input text\
  2022.             local sLine = tLines[y]\
  2023.             tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)\
  2024.             redrawLine(y)\
  2025. \
  2026.             x = x + string.len( param )\
  2027.             setCursor( x, y )\
  2028.         end\
  2029.         \
  2030.     elseif sEvent == \"mouse_click\" then\
  2031.         if not bMenu then\
  2032.             if param == 1 then\
  2033.                 -- Left click\
  2034.                 local cx,cy = param2, param3\
  2035.                 if cy < h then\
  2036.                     y = math.min( math.max( scrollY + cy, 1 ), #tLines )\
  2037.                     x = math.min( math.max( scrollX + cx, 1 ), string.len( tLines[y] ) + 1 )\
  2038.                     setCursor( x, y )\
  2039.                 end\
  2040.             end\
  2041.         end\
  2042.         \
  2043.     elseif sEvent == \"mouse_scroll\" then\
  2044.         if not bMenu then\
  2045.             if param == -1 then\
  2046.                 -- Scroll up\
  2047.                 if scrollY > 0 then\
  2048.                     -- Move cursor up\
  2049.                     scrollY = scrollY - 1\
  2050.                     redrawText()\
  2051.                 end\
  2052.             \
  2053.             elseif param == 1 then\
  2054.                 -- Scroll down\
  2055.                 local nMaxScroll = #tLines - (h-1)\
  2056.                 if scrollY < nMaxScroll then\
  2057.                     -- Move cursor down\
  2058.                     scrollY = scrollY + 1\
  2059.                     redrawText()\
  2060.                 end\
  2061.                 \
  2062.             end\
  2063.         end\
  2064. \
  2065.     elseif sEvent == \"term_resize\" then\
  2066.         w,h = term.getSize()\
  2067.        setCursor( x, y )\
  2068.        redrawMenu()\
  2069.        redrawText()\
  2070. \
  2071.     end\
  2072. end\
  2073. \
  2074. -- Cleanup\
  2075. term.clear()\
  2076. term.setCursorBlink( false )\
  2077. term.setCursorPos( 1, 1 )",
  2078.   [ "/rom/programs/fun/worm" ] = "\
  2079. -- Display the start screen\
  2080. local w,h = term.getSize()\
  2081. \
  2082. local titleColour, headingColour, textColour, wormColour, fruitColour\
  2083. if term.isColour() then\
  2084.    titleColour = colours.red\
  2085.     headingColour = colours.yellow\
  2086.     textColour = colours.white\
  2087.     wormColour = colours.green\
  2088.     fruitColour = colours.red\
  2089. else\
  2090.    titleColour = colours.white\
  2091.     headingColour = colours.white\
  2092.     textColour = colours.white\
  2093.     wormColour = colours.white\
  2094.     fruitColour = colours.white\
  2095. end\
  2096. \
  2097. function printCentred( y, s )\
  2098.     local x = math.floor((w - string.len(s)) / 2)\
  2099.     term.setCursorPos(x,y)\
  2100.     --term.clearLine()\
  2101.     term.write( s )\
  2102. end\
  2103. \
  2104. local xVel,yVel = 1,0\
  2105. local xPos, yPos = math.floor(w/2), math.floor(h/2)\
  2106. local pxVel, pyVel = nil, nil\
  2107. \
  2108. local nLength = 1\
  2109. local nExtraLength = 6\
  2110. local bRunning = true\
  2111. \
  2112. local tailX,tailY = xPos,yPos\
  2113. local nScore = 0\
  2114. local nDifficulty = 2\
  2115. local nSpeed, nInterval\
  2116. \
  2117. -- Setup the screen\
  2118. local screen = {}\
  2119. for x=1,w do\
  2120.     screen[x] = {}\
  2121.     for y=1,h do\
  2122.         screen[x][y] = {}\
  2123.     end\
  2124. end\
  2125. screen[xPos][yPos] = { snake = true }\
  2126. \
  2127. local nFruit = 1\
  2128. local tFruits = {\
  2129.     \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\",\
  2130.     \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\",\
  2131.     \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\",\
  2132.     \"Y\", \"Z\",\
  2133.     \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\",\
  2134.     \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\",\
  2135.     \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\",\
  2136.     \"y\", \"z\",\
  2137.     \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"0\",\
  2138.     \"@\", \"$\", \"%\", \"#\", \"&\", \"!\", \"?\", \"+\", \"*\", \"~\"\
  2139. }\
  2140. \
  2141. local function addFruit()\
  2142.     while true do\
  2143.         local x = math.random(1,w)\
  2144.         local y = math.random(2,h)\
  2145.         local fruit = screen[x][y]\
  2146.         if fruit.snake == nil and fruit.wall == nil and fruit.fruit == nil then\
  2147.             screen[x][y] = { fruit = true }\
  2148.             term.setCursorPos(x,y)\
  2149.             term.setBackgroundColour( fruitColour )\
  2150.             term.write(\" \")\
  2151.             term.setBackgroundColour( colours.black )\
  2152.             break\
  2153.         end\
  2154.     end\
  2155.     \
  2156.     nFruit = nFruit + 1\
  2157.     if nFruit > #tFruits then\
  2158.         nFruit = 1\
  2159.     end\
  2160. end\
  2161. \
  2162. local function drawMenu()\
  2163.     term.setTextColour( headingColour )\
  2164.     term.setCursorPos(1,1)\
  2165.     term.write( \"SCORE \" )\
  2166.     \
  2167.     term.setTextColour( textColour )\
  2168.     term.setCursorPos(7,1)\
  2169.     term.write( tostring(nScore) )\
  2170. \
  2171.     term.setTextColour( headingColour )\
  2172.     term.setCursorPos(w-11,1)\
  2173.     term.write( \"DIFFICULTY \")\
  2174. \
  2175.     term.setTextColour( textColour )\
  2176.     term.setCursorPos(w,1)\
  2177.     term.write( tostring(nDifficulty or \"?\") ) \
  2178. \
  2179.     term.setTextColour( colours.white )\
  2180. end\
  2181. \
  2182. local function update( )\
  2183.     local x,y = xPos,yPos\
  2184.     if pxVel and pyVel then\
  2185.         xVel, yVel = pxVel, pyVel\
  2186.         pxVel, pyVel = nil, nil\
  2187.     end\
  2188. \
  2189.     -- Remove the tail\
  2190.     if nExtraLength == 0 then\
  2191.         local tail = screen[tailX][tailY]\
  2192.         screen[tailX][tailY] = {}\
  2193.         term.setCursorPos(tailX,tailY)\
  2194.         term.write(\" \")\
  2195.         tailX = tail.nextX\
  2196.         tailY = tail.nextY\
  2197.     else\
  2198.         nExtraLength = nExtraLength - 1\
  2199.     end\
  2200.     \
  2201.     -- Update the head\
  2202.     local head = screen[xPos][yPos]\
  2203.     local newXPos = xPos + xVel\
  2204.     local newYPos = yPos + yVel\
  2205.     if newXPos < 1 then\
  2206.         newXPos = w\
  2207.     elseif newXPos > w then\
  2208.         newXPos = 1\
  2209.     end\
  2210.     if newYPos < 2 then\
  2211.         newYPos = h\
  2212.     elseif newYPos > h then\
  2213.         newYPos = 2\
  2214.     end\
  2215.     \
  2216.     local newHead = screen[newXPos][newYPos]\
  2217.     term.setCursorPos(1,1);\
  2218.     print( newHead.snake )\
  2219.     if newHead.snake == true or newHead.wall == true then\
  2220.         bRunning = false\
  2221.         \
  2222.     else\
  2223.         if newHead.fruit == true then\
  2224.             nScore = nScore + 10\
  2225.             nExtraLength = nExtraLength + 1\
  2226.             addFruit()\
  2227.         end\
  2228.         xPos = newXPos\
  2229.         yPos = newYPos\
  2230.         head.nextX = newXPos\
  2231.         head.nextY = newYPos\
  2232.         screen[newXPos][newYPos] = { snake = true }\
  2233.         \
  2234.     end\
  2235.     \
  2236.     term.setCursorPos(xPos,yPos)\
  2237.     term.setBackgroundColour( wormColour )\
  2238.     term.write(\" \")\
  2239.     term.setBackgroundColour( colours.black )\
  2240. \
  2241.     drawMenu()\
  2242. end\
  2243. \
  2244. -- Display the frontend\
  2245. term.clear()\
  2246. local function drawFrontend()\
  2247.     --term.setTextColour( titleColour )\
  2248.    --printCentred( math.floor(h/2) - 4, \" W O R M \" )\
  2249. \
  2250.     term.setTextColour( headingColour )\
  2251.     printCentred( math.floor(h/2) - 3, \"\" )\
  2252.     printCentred( math.floor(h/2) - 2, \" SELECT DIFFICULTY \" )\
  2253.     printCentred( math.floor(h/2) - 1, \"\" )\
  2254.     \
  2255.     printCentred( math.floor(h/2) + 0, \"            \" )\
  2256.     printCentred( math.floor(h/2) + 1, \"            \" )\
  2257.     printCentred( math.floor(h/2) + 2, \"            \" )\
  2258.     printCentred( math.floor(h/2) - 1 + nDifficulty, \" [        ] \" )\
  2259. \
  2260.     term.setTextColour( textColour )\
  2261.     printCentred( math.floor(h/2) + 0, \"EASY\" )\
  2262.     printCentred( math.floor(h/2) + 1, \"MEDIUM\" )\
  2263.     printCentred( math.floor(h/2) + 2, \"HARD\" )\
  2264.     printCentred( math.floor(h/2) + 3, \"\" )\
  2265. \
  2266.     term.setTextColour( colours.white )\
  2267. end\
  2268. \
  2269. drawMenu()\
  2270. drawFrontend()\
  2271. while true do\
  2272.     local e,key = os.pullEvent( \"key\" )\
  2273.     if key == keys.up or key == keys.w then\
  2274.         -- Up\
  2275.         if nDifficulty > 1 then\
  2276.             nDifficulty = nDifficulty - 1\
  2277.             drawMenu()\
  2278.             drawFrontend()\
  2279.         end\
  2280.     elseif key == keys.down or key == keys.s then\
  2281.         -- Down\
  2282.         if nDifficulty < 3 then\
  2283.             nDifficulty = nDifficulty + 1\
  2284.             drawMenu()\
  2285.             drawFrontend()\
  2286.         end\
  2287.     elseif key == keys.enter then\
  2288.         -- Enter\
  2289.         break\
  2290.     end\
  2291. end\
  2292. \
  2293. local tSpeeds = { 5, 10, 25 }\
  2294. nSpeed = tSpeeds[nDifficulty]\
  2295. nInterval = 1 / nSpeed\
  2296. \
  2297. -- Grow the snake to its intended size\
  2298. term.clear()\
  2299. drawMenu()\
  2300. screen[tailX][tailY].snake = true\
  2301. while nExtraLength > 0 do\
  2302.     update()\
  2303. end\
  2304. addFruit()\
  2305. addFruit()\
  2306. \
  2307. -- Play the game\
  2308. local timer = os.startTimer(0)\
  2309. while bRunning do\
  2310.     local event, p1, p2 = os.pullEvent()\
  2311.     if event == \"timer\" and p1 == timer then\
  2312.         timer = os.startTimer(nInterval)\
  2313.         update( false )\
  2314.     \
  2315.     elseif event == \"key\" then\
  2316.         local key = p1\
  2317.         if key == keys.up or key == keys.w then\
  2318.             -- Up\
  2319.             if yVel == 0 then\
  2320.                 pxVel,pyVel = 0,-1\
  2321.             end\
  2322.         elseif key == keys.down or key == keys.s then\
  2323.             -- Down\
  2324.             if yVel == 0 then\
  2325.                 pxVel,pyVel = 0,1\
  2326.             end\
  2327.         elseif key == keys.left or key == keys.a then\
  2328.             -- Left\
  2329.             if xVel == 0 then\
  2330.                 pxVel,pyVel = -1,0\
  2331.             end\
  2332.         \
  2333.         elseif key == keys.right or key == keys.d then\
  2334.             -- Right\
  2335.             if xVel == 0 then\
  2336.                 pxVel,pyVel = 1,0\
  2337.             end\
  2338.         \
  2339.         end \
  2340.     end\
  2341. end\
  2342. \
  2343. -- Display the gameover screen\
  2344. term.setTextColour( headingColour )\
  2345. printCentred( math.floor(h/2) - 2, \"                   \" )\
  2346. printCentred( math.floor(h/2) - 1, \" G A M E   O V E R \" )\
  2347. \
  2348. term.setTextColour( textColour )\
  2349. printCentred( math.floor(h/2) + 0, \"                 \" )\
  2350. printCentred( math.floor(h/2) + 1, \" FINAL SCORE \"..nScore..\" \" )\
  2351. printCentred( math.floor(h/2) + 2, \"                 \" )\
  2352. term.setTextColour( colours.white )\
  2353. \
  2354. local timer = os.startTimer(2.5)\
  2355. repeat\
  2356.     local e,p = os.pullEvent()\
  2357.     if e == \"timer\" and p == timer then\
  2358.         term.setTextColour( textColour )\
  2359.         printCentred( math.floor(h/2) + 2, \" PRESS ANY KEY \" )\
  2360.         printCentred( math.floor(h/2) + 3, \"               \" )\
  2361.         term.setTextColour( colours.white )\
  2362.     end\
  2363. until e == \"char\"\
  2364. \
  2365. term.clear()\
  2366. term.setCursorPos(1,1)\
  2367. \
  2368.         ",
  2369.   [ "/rom/programs/fun/advanced/levels/10" ] = "5\
  2370. 777    77777\
  2371. 727777778837\
  2372. 788888878787\
  2373. 787777888887\
  2374. 77877778777777\
  2375. 7e8b7888b888e7\
  2376. 7787787b777877\
  2377. 777887887887\
  2378.   7487807487\
  2379.   7777777777",
  2380.   [ "/Flare/version/1.2/lib/process.lua" ] = "\
  2381. local thread = {}\
  2382. \
  2383. function thread:new( f )\
  2384. \
  2385.     local t = {}\
  2386. \
  2387.     t.state = \"running\"\
  2388.     t.environment = setmetatable( {}, { __index = getfenv( f ) } )\
  2389. \
  2390.     t.filter = nil\
  2391. \
  2392.     t.raw_environment = setmetatable( {}, {\
  2393.         __index = function( _, k )\
  2394.             if k == \"thread\" then\
  2395.                 return t\
  2396.             end\
  2397.             return t.environment[k]\
  2398.         end,\
  2399.         __newindex = function( _, k, v )\
  2400.             t.environment[k] = v\
  2401.         end\
  2402.     } )\
  2403. \
  2404.     setfenv( f, t.raw_environment )\
  2405.     t.func = f\
  2406.     t.co = coroutine.create( f )\
  2407. \
  2408.     setmetatable( t, {\
  2409.         __index = self;\
  2410.         __type = \"thread\";\
  2411.         __tostring = function()\
  2412.             return \"thread\"\
  2413.         end;\
  2414.     } )\
  2415. \
  2416.     return t\
  2417. end\
  2418. \
  2419. function thread:stop()\
  2420.     if self.state ~= \"dead\" then\
  2421.         self.state = \"stopped\"\
  2422.     end\
  2423. end\
  2424. \
  2425. function thread:pause()\
  2426.     if self.state == \"running\" then\
  2427.         self.state = \"paused\"\
  2428.     end\
  2429. end\
  2430. \
  2431. function thread:resume()\
  2432.     if self.state == \"paused\" then\
  2433.         self.state = \"running\"\
  2434.     end\
  2435. end\
  2436. \
  2437. function thread:restart()\
  2438.     self.state = \"running\"\
  2439.     self.co = coroutine.create( self.func )\
  2440. end\
  2441. \
  2442. function thread:update( event, ... )\
  2443.     if self.state ~= \"running\" then return true, self.state end -- if not running, don't update\
  2444.     if self.filter ~= nil and self.filter ~= event then return true, self.filter end -- if filtering an event, don't update\
  2445.     thread.current = self\
  2446.     local ok, data = coroutine.resume( self.co, event, ... )\
  2447.     thread.current = nil\
  2448.     if not ok then\
  2449.         self.state = \"stopped\"\
  2450.         return false, data\
  2451.     end\
  2452.     if coroutine.status( self.co ) == \"dead\" then\
  2453.         self.state = \"stopped\"\
  2454.         return true, \"die\"\
  2455.     end\
  2456.     self.filter = data\
  2457.     return true, data\
  2458. end\
  2459. \
  2460. function thread:type()\
  2461.     return \"thread\"\
  2462. end\
  2463. \
  2464. local process = {}\
  2465. \
  2466. process.thread = thread\
  2467. \
  2468. function process:new( name )\
  2469.     local p = {}\
  2470. \
  2471.     p.name = name\
  2472.     p.children = {}\
  2473. \
  2474.     setmetatable( p, {\
  2475.         __index = self;\
  2476.         __type = \"process\";\
  2477.         __tostring = function()\
  2478.             return \"process\"\
  2479.         end;\
  2480.     } )\
  2481. \
  2482.     return p\
  2483. end\
  2484. \
  2485. function process:spawnThread( f )\
  2486.     local t = thread:new( f )\
  2487.     t.parent = self\
  2488.     self.children[#self.children + 1] = t\
  2489.     return t\
  2490. end\
  2491. \
  2492. function process:spawnSubProcess( name )\
  2493.     local p = process:new( name )\
  2494.     p.parent = self\
  2495.     self.children[#self.children + 1] = p\
  2496.     return p\
  2497. end\
  2498. \
  2499. function process:update( event, ... )\
  2500.     for i = #self.children, 1, -1 do\
  2501.         local ok, data = self.children[i]:update( event, ... )\
  2502.         if not ok then\
  2503.             if self.exceptionHandler then\
  2504.                 self:exceptionHandler( self.children[i], data )\
  2505.             else\
  2506.                 return false, data\
  2507.             end\
  2508.         end\
  2509.         if data == \"die\" or self.children[i].state == \"stopped\" then\
  2510.             self.children[i].state = \"dead\"\
  2511.             table.remove( self.children, i )\
  2512.         end\
  2513.     end\
  2514.     return true, #self.children == 0 and \"die\"\
  2515. end\
  2516. \
  2517. function process:stop()\
  2518.     for i = 1, #self.children do\
  2519.         self.children[i]:stop()\
  2520.     end\
  2521. end\
  2522. \
  2523. function process:pause()\
  2524.     for i = 1, #self.children do\
  2525.         self.children[i]:pause()\
  2526.     end\
  2527. end\
  2528. \
  2529. function process:resume()\
  2530.     for i = 1, #self.children do\
  2531.         self.children[i]:resume()\
  2532.     end\
  2533. end\
  2534. \
  2535. function process:restart()\
  2536.     for i = 1, #self.children do\
  2537.         self.children[i]:restart()\
  2538.     end\
  2539. end\
  2540. \
  2541. function process:list( deep )\
  2542.     local t = {}\
  2543.     for i = #self.children, 1, -1 do\
  2544.         if self.children[i]:type() == \"process\" then\
  2545.             if deep then\
  2546.                 local c = self.children[i]:list( true )\
  2547.                 c.name = self.children[i].name\
  2548.                 t[#t + 1] = c\
  2549.             else\
  2550.                 t[#t + 1] = self.children[i]\
  2551.             end\
  2552.         elseif self.children[i]:type() == \"thread\" then\
  2553.             t[#t + 1] = self.children[i]\
  2554.         end\
  2555.     end\
  2556.     return t\
  2557. end\
  2558. \
  2559. function process:type()\
  2560.     return \"process\"\
  2561. end\
  2562. \
  2563. process.main = process:new \"main\"\
  2564. \
  2565. return process",
  2566.   [ "/rom/help/refuel" ] = "refuel is a program for Turtles. Refuel will consume items from the inventory as fuel for turtle.\
  2567. \
  2568. ex:\
  2569. \"refuel\" will refuel with at most one fuel item\
  2570. \"refuel 10\" will refuel with at most 10 fuel items\
  2571. \"refuel all\" will refuel with as many fuel items as possible",
  2572.   [ "/rom/help/events" ] = "The function os.pullEvent() will yield the program until a system event occurs. The first return value is the event name, followed by any arguments.\
  2573. \
  2574. Some events which can occur are:\
  2575. \"char\" when text is typed on the keyboard. Argument is the letter typed.\
  2576. \"key\" when a key is pressed on the keyboard. Argument is the numerical keycode. Compare to the values in keys API to see which key was pressed.\
  2577. \"paste\" when text is pasted from the users keyboard. Argument is the line of text pasted.\
  2578. \
  2579. Events only on advanced computers:\
  2580. \"mouse_click\" when a user clicks the mouse. Arguments are button, xPos, yPos.\
  2581. \"mouse_drag\" when a user moves the mouse when held. Arguments are button, xPos, yPos.\
  2582. \"mouse_scroll\" when a user uses the scrollwheel on the mouse. Arguments are direction, xPos, yPos.\
  2583. \
  2584. Other APIs and peripherals will emit their own events. See their respective help pages for details.",
  2585.   [ "/rom/help/exit" ] = "exit will exit the current shell.",
  2586.   [ "/rom/help/string" ] = "string is a standard Lua5.1 API.\
  2587. Refer to http://www.lua.org/manual/5.1/ for more information.",
  2588.   [ "/rom/programs/label" ] = "\
  2589. local function printUsage()\
  2590.     print( \"Usages:\" )\
  2591.     print( \"label get\" )\
  2592.     print( \"label get <drive>\" )\
  2593.     print( \"label set <text>\" )\
  2594.     print( \"label set <drive> <text>\" )\
  2595.     print( \"label clear\" )\
  2596.     print( \"label clear <drive>\" )\
  2597. end\
  2598. \
  2599. local function checkDrive( sDrive )\
  2600.    if peripheral.getType( sDrive ) == \"drive\" then\
  2601.        -- Check the disk exists\
  2602.        local bData = disk.hasData( sDrive )\
  2603.        if not bData then\
  2604.            print( \"No disk in \"..sDrive..\" drive\" )\
  2605.            return false\
  2606.        end\
  2607.    else\
  2608.         print( \"No disk drive named \"..sDrive )\
  2609.        return false\
  2610.     end\
  2611.     return true\
  2612. end\
  2613. \
  2614. local function get( sDrive )\
  2615.     if sDrive ~= nil then\
  2616.         if checkDrive( sDrive ) then\
  2617.            local sLabel = disk.getLabel( sDrive )\
  2618.            if sLabel then\
  2619.                print( \"Disk label is \\\"\"..sLabel..\"\\\"\" )\
  2620.            else\
  2621.                print( \"No Disk label\" )\
  2622.            end\
  2623.        end\
  2624.     else\
  2625.         local sLabel = os.getComputerLabel()\
  2626.         if sLabel then\
  2627.             print( \"Computer label is \\\"\"..sLabel..\"\\\"\" )\
  2628.         else\
  2629.             print( \"No Computer label\" )\
  2630.         end\
  2631.     end\
  2632. end\
  2633. \
  2634. local function set( sDrive, sText )\
  2635.     if sDrive ~= nil then\
  2636.         if checkDrive( sDrive ) then\
  2637.            disk.setLabel( sDrive, sText )\
  2638.            local sLabel = disk.getLabel( sDrive )\
  2639.            if sLabel then\
  2640.                print( \"Disk label set to \\\"\"..sLabel..\"\\\"\" )\
  2641.            else\
  2642.                print( \"Disk label cleared\" )\
  2643.            end\
  2644.        end\
  2645.     else\
  2646.         os.setComputerLabel( sText )\
  2647.         local sLabel = os.getComputerLabel()\
  2648.         if sLabel then\
  2649.             print( \"Computer label set to \\\"\"..sLabel..\"\\\"\" )\
  2650.         else\
  2651.             print( \"Computer label cleared\" )\
  2652.         end\
  2653.     end\
  2654. end\
  2655. \
  2656. local tArgs = { ... }\
  2657. local sCommand = tArgs[1]\
  2658. if sCommand == \"get\" then\
  2659.    -- Get a label\
  2660.    if #tArgs == 1 then\
  2661.        get( nil )\
  2662.    elseif #tArgs == 2 then\
  2663.        get( tArgs[2] )\
  2664.    else\
  2665.        printUsage()\
  2666.    end\
  2667. elseif sCommand == \"set\" then\
  2668.    -- Set a label\
  2669.    if #tArgs == 2 then\
  2670.        set( nil, tArgs[2] )\
  2671.    elseif #tArgs == 3 then\
  2672.        set( tArgs[2], tArgs[3] )\
  2673.    else\
  2674.        printUsage()\
  2675.    end\
  2676. elseif sCommand == \"clear\" then\
  2677.    -- Clear a label\
  2678.    if #tArgs == 1 then\
  2679.        set( nil, nil )\
  2680.    elseif #tArgs == 2 then\
  2681.        set( tArgs[2], nil )\
  2682.    else\
  2683.        printUsage()\
  2684.    end\
  2685. else\
  2686.    printUsage()\
  2687. end",
  2688.   [ "/Shop/States/Main.lua" ] = "local StateLib = FDK.require('lib.state')\
  2689. local State = StateLib.names.Init\
  2690. local Main = StateLib.names.Main\
  2691. local Search = StateLib.names.Search\
  2692. local Account = StateLib.names.Account\
  2693. local Items = StateLib.names.Items\
  2694. \
  2695. local Field = FDK.require('lib.UI.elements.Field')\
  2696. local Text = FDK.require('lib.UI.elements.Text')\
  2697. local Button = FDK.require('lib.UI.elements.Button')\
  2698. \
  2699. -- Main Field\
  2700. Main.frame:newChild(Field(1, 1, Main.frame.width, Main.frame.height, colors.white))\
  2701. -- Header Field\
  2702. Main.frame:newChild(Field(1, 1, Main.frame.width, 3, colors.lightGray))\
  2703. \
  2704. local Header = Main.frame:newChild(Text(0, 0, 13, 1, '&b8&t0Menu'))\
  2705. Header.y = 2\
  2706. Header.width = #Header.text - #'&b7&t8'\
  2707. Header:alignX('centre')\
  2708. \
  2709. -- Buttons --\
  2710. local Buttons = {\
  2711.  _Search = {func=Search, Frame=Main.frame:newChild(Button(0, 5, 18, 3, '&t0Search'))},\
  2712.  _Items = {func=Items, Frame=Main.frame:newChild(Button(0, 10, 18, 3, '&t0Items'))},\
  2713.  _Account = {func=Account, Frame=Main.frame:newChild(Button(0, 15, 18, 3, '&t0Account'))},\
  2714.  --Search = Main.frame:newChild(Button(2, 5, 18, 3, '&t0Search')),\
  2715. }\
  2716. \
  2717. for k, v in pairs(Buttons) do\
  2718.  v.Frame.bc = colors.gray\
  2719.  v.Frame:alignX('centre')\
  2720.  function v.Frame:onClick()\
  2721.    v.func:show()\
  2722.  end\
  2723. end\
  2724. \
  2725. \
  2726. --Buttons.Search:align('centre', 'centre')\
  2727. \
  2728. --Main.frame:newChild( Text( 2, 5, 46, 3, '&t7What would you like to see a demonstration of?' ) )",
  2729.   [ "/rom/help/fs" ] = "Functions in the Filesystem API:\
  2730. fs.list( path )\
  2731. fs.find( wildcard )\
  2732. fs.exists( path )\
  2733. fs.isDir( path )\
  2734. fs.isReadOnly( path )\
  2735. fs.getDir( path )\
  2736. fs.getName( path )\
  2737. fs.getSize( path )\
  2738. fs.getDrive( path )\
  2739. fs.getFreeSpace( path )\
  2740. fs.makeDir( path )\
  2741. fs.move( path, path )\
  2742. fs.copy( path, path )\
  2743. fs.delete( path )\
  2744. fs.combine( path, localpath )\
  2745. fs.open( path, mode )\
  2746. Available fs.open() modes are \"r\", \"w\", \"a\", \"rb\", \"wb\" and \"ab\".\
  2747. \
  2748. Functions on files opened with mode \"r\":\
  2749. readLine()\
  2750. readAll()\
  2751. close()\
  2752. \
  2753. Functions on files opened with mode \"w\" or \"a\":\
  2754. write( string )\
  2755. writeLine( string )\
  2756. flush()\
  2757. close()\
  2758. \
  2759. Functions on files opened with mode \"rb\":\
  2760. read()\
  2761. close()\
  2762. \
  2763. Functions on files opened with mode \"wb\" or \"ab\":\
  2764. write( byte )\
  2765. flush()\
  2766. close()",
  2767.   [ "/rom/help/colours" ] = "Functions in the colours api\
  2768. (used for redstone.setBundledOutput):\
  2769. colours.combine( colour1, colour2, colour3, ...)\
  2770. colours.subtract( colours, colour1, colour2, ...)\
  2771. colours.test( colours, colour )\
  2772. \
  2773. Colour constants in the colours api, in ascending bit order:\
  2774. colours.white, colours.orange, colours.magenta, colours.lightBlue, colours.yellow, colours.lime, colours.pink, colours.grey, colours.lightGrey, colours.cyan, colours.purple, colours.blue, colours.brown, colours.green, colours.red, colours.black.",
  2775.   [ "/Flare/version/1.2/lib/UI/draw/pixel.lua" ] = "\
  2776. local function pixel( buffer, x, y, bc, tc, char )\
  2777.     buffer:setColours( bc, tc )\
  2778.     buffer:drawPixel( x, y, char )\
  2779. end\
  2780. \
  2781. return pixel",
  2782.   [ "/rom/apis/paintutils" ] = "\
  2783. local function drawPixelInternal( xPos, yPos )\
  2784.    term.setCursorPos( xPos, yPos )\
  2785.    term.write(\" \")\
  2786. end\
  2787. \
  2788. local tColourLookup = {}\
  2789. for n=1,16 do\
  2790.    tColourLookup[ string.byte( \"0123456789abcdef\",n,n ) ] = 2^(n-1)\
  2791. end\
  2792. \
  2793. function loadImage( sPath )\
  2794.    if type( sPath ) ~= \"string\" then\
  2795.        error( \"Expected path\", 2 )\
  2796.    end\
  2797. \
  2798.    local tImage = {}\
  2799.    if fs.exists( sPath ) then\
  2800.        local file = io.open(sPath, \"r\" )\
  2801.        local sLine = file:read()\
  2802.        while sLine do\
  2803.            local tLine = {}\
  2804.            for x=1,sLine:len() do\
  2805.                tLine[x] = tColourLookup[ string.byte(sLine,x,x) ] or 0\
  2806.            end\
  2807.            table.insert( tImage, tLine )\
  2808.            sLine = file:read()\
  2809.        end\
  2810.        file:close()\
  2811.        return tImage\
  2812.    end\
  2813.    return nil\
  2814. end\
  2815. \
  2816. function drawPixel( xPos, yPos, nColour )\
  2817.    if type( xPos ) ~= \"number\" or type( yPos ) ~= \"number\" or (nColour ~= nil and type( nColour ) ~= \"number\") then\
  2818.        error( \"Expected x, y, colour\", 2 )\
  2819.    end\
  2820.    if nColour then\
  2821.        term.setBackgroundColor( nColour )\
  2822.    end\
  2823.    drawPixelInternal( xPos, yPos )\
  2824. end\
  2825. \
  2826. function drawLine( startX, startY, endX, endY, nColour )\
  2827.    if type( startX ) ~= \"number\" or type( startX ) ~= \"number\" or\
  2828.       type( endX ) ~= \"number\" or type( endY ) ~= \"number\" or\
  2829.       (nColour ~= nil and type( nColour ) ~= \"number\") then\
  2830.        error( \"Expected startX, startY, endX, endY, colour\", 2 )\
  2831.    end\
  2832.    \
  2833.    startX = math.floor(startX)\
  2834.    startY = math.floor(startY)\
  2835.    endX = math.floor(endX)\
  2836.    endY = math.floor(endY)\
  2837. \
  2838.    if nColour then\
  2839.        term.setBackgroundColor( nColour )\
  2840.    end\
  2841.    if startX == endX and startY == endY then\
  2842.        drawPixelInternal( startX, startY )\
  2843.        return\
  2844.    end\
  2845.    \
  2846.    local minX = math.min( startX, endX )\
  2847.    if minX == startX then\
  2848.        minY = startY\
  2849.        maxX = endX\
  2850.        maxY = endY\
  2851.    else\
  2852.        minY = endY\
  2853.        maxX = startX\
  2854.        maxY = startY\
  2855.    end\
  2856. \
  2857.    -- TODO: clip to screen rectangle?\
  2858.        \
  2859.    local xDiff = maxX - minX\
  2860.    local yDiff = maxY - minY\
  2861.            \
  2862.    if xDiff > math.abs(yDiff) then\
  2863.        local y = minY\
  2864.        local dy = yDiff / xDiff\
  2865.        for x=minX,maxX do\
  2866.            drawPixelInternal( x, math.floor( y + 0.5 ) )\
  2867.            y = y + dy\
  2868.        end\
  2869.    else\
  2870.        local x = minX\
  2871.        local dx = xDiff / yDiff\
  2872.        if maxY >= minY then\
  2873.            for y=minY,maxY do\
  2874.                drawPixelInternal( math.floor( x + 0.5 ), y )\
  2875.                x = x + dx\
  2876.            end\
  2877.        else\
  2878.            for y=minY,maxY,-1 do\
  2879.                drawPixelInternal( math.floor( x + 0.5 ), y )\
  2880.                x = x - dx\
  2881.            end\
  2882.        end\
  2883.    end\
  2884. end\
  2885. \
  2886. function drawBox( startX, startY, endX, endY, nColour )\
  2887.    if type( startX ) ~= \"number\" or type( startX ) ~= \"number\" or\
  2888.       type( endX ) ~= \"number\" or type( endY ) ~= \"number\" or\
  2889.       (nColour ~= nil and type( nColour ) ~= \"number\") then\
  2890.        error( \"Expected startX, startY, endX, endY, colour\", 2 )\
  2891.    end\
  2892. \
  2893.    startX = math.floor(startX)\
  2894.    startY = math.floor(startY)\
  2895.    endX = math.floor(endX)\
  2896.    endY = math.floor(endY)\
  2897. \
  2898.    if nColour then\
  2899.        term.setBackgroundColor( nColour )\
  2900.    end\
  2901.    if startX == endX and startY == endY then\
  2902.        drawPixelInternal( startX, startY )\
  2903.        return\
  2904.    end\
  2905. \
  2906.    local minX = math.min( startX, endX )\
  2907.    if minX == startX then\
  2908.        minY = startY\
  2909.        maxX = endX\
  2910.        maxY = endY\
  2911.    else\
  2912.        minY = endY\
  2913.        maxX = startX\
  2914.        maxY = startY\
  2915.    end\
  2916. \
  2917.    for x=minX,maxX do\
  2918.        drawPixelInternal( x, minY )\
  2919.        drawPixelInternal( x, maxY )\
  2920.    end\
  2921. \
  2922.    if (maxY - minY) >= 2 then\
  2923.        for y=(minY+1),(maxY-1) do\
  2924.            drawPixelInternal( minX, y )\
  2925.            drawPixelInternal( maxX, y )\
  2926.        end\
  2927.    end\
  2928. end\
  2929. \
  2930. function drawFilledBox( startX, startY, endX, endY, nColour )\
  2931.    if type( startX ) ~= \"number\" or type( startX ) ~= \"number\" or\
  2932.       type( endX ) ~= \"number\" or type( endY ) ~= \"number\" or\
  2933.       (nColour ~= nil and type( nColour ) ~= \"number\") then\
  2934.        error( \"Expected startX, startY, endX, endY, colour\", 2 )\
  2935.    end\
  2936. \
  2937.    startX = math.floor(startX)\
  2938.    startY = math.floor(startY)\
  2939.    endX = math.floor(endX)\
  2940.    endY = math.floor(endY)\
  2941. \
  2942.    if nColour then\
  2943.        term.setBackgroundColor( nColour )\
  2944.    end\
  2945.    if startX == endX and startY == endY then\
  2946.        drawPixelInternal( startX, startY )\
  2947.        return\
  2948.    end\
  2949. \
  2950.    local minX = math.min( startX, endX )\
  2951.    if minX == startX then\
  2952.        minY = startY\
  2953.        maxX = endX\
  2954.        maxY = endY\
  2955.    else\
  2956.        minY = endY\
  2957.        maxX = startX\
  2958.        maxY = startY\
  2959.    end\
  2960. \
  2961.    for x=minX,maxX do\
  2962.        for y=minY,maxY do\
  2963.            drawPixelInternal( x, y )\
  2964.        end\
  2965.    end\
  2966. end\
  2967. \
  2968. function drawImage( tImage, xPos, yPos )\
  2969.    if type( tImage ) ~= \"table\" or type( xPos ) ~= \"number\" or type( yPos ) ~= \"number\" then\
  2970.        error( \"Expected image, x, y\", 2 )\
  2971.    end\
  2972.    for y=1,#tImage do\
  2973.        local tLine = tImage[y]\
  2974.        for x=1,#tLine do\
  2975.            if tLine[x] > 0 then\
  2976.                term.setBackgroundColor( tLine[x] )\
  2977.                drawPixelInternal( x + xPos - 1, y + yPos - 1 )\
  2978.            end\
  2979.        end\
  2980.    end\
  2981. end",
  2982.   [ "/rom/help/credits" ] = "ComputerCraft was created by Daniel \"dan200\" Ratcliffe, with additional code by Aaron \"Cloudy\" Mills.\
  2983. Thanks to nitrogenfingers, GopherATL and RamiLego for program contributions.\
  2984. Thanks to Mojang, the Forge team, and the MCP team.\
  2985. Uses LuaJ from http://luaj.sourceforge.net/\
  2986. \
  2987. Join the ComputerCraft community online at http://www.computercraft.info\
  2988. Follow @DanTwoHundred on Twitter!",
  2989.   [ "/rom/help/redstoneapi" ] = "Functions in the Redstone API:\
  2990. redstone.getSides( )\
  2991. redstone.getInput( side )\
  2992. redstone.setOutput( side, boolean )\
  2993. redstone.getOutput( side )\
  2994. redstone.getAnalogInput( side )\
  2995. redstone.setAnalogOutput( side, number )\
  2996. redstone.getAnalogOutput( side )\
  2997. \
  2998. Functions in the Redstone API for working with bundled cables:\
  2999. redstone.getBundledInput( side )\
  3000. redstone.testBundledInput( side, color )\
  3001. redstone.setBundledOutput( side, colors )\
  3002. redstone.getBundledOutput( side )\
  3003. Type \"help bundled\" for usage examples.\
  3004. \
  3005. Events emitted by the redstone API:\
  3006. \"redstone\", when the state of any redstone input changes. Use getInput() or getBundledInput() to inspect the changes\
  3007. Type \"help events\" to learn about the event system.",
  3008.   [ "/rom/help/shell" ] = "shell is the toplevel program which interprets commands and runs program.\
  3009. Type \"help shellapi\" for information about the shell lua api.",
  3010.   [ "/Flare/version/1.2/lib/UI/elements/Button.lua" ] = "\
  3011. local class = require \"lib.class\"\
  3012. local base = require \"lib.UI.base\"\
  3013. local formatter = require \"lib.UI.text.formatter\"\
  3014. local drawtext = require \"lib.UI.draw.text\"\
  3015. local mouse = require \"lib.UI.event.mouse\"\
  3016. \
  3017. local Button = class \"Button\"\
  3018. Button:extend( base )\
  3019. \
  3020. Button.bc = \"white\"\
  3021. Button.tc = \"grey\"\
  3022. \
  3023. Button.noAlign = false\
  3024. \
  3025. Button.mouse_click_timeout = .4\
  3026. \
  3027. function Button:Button( x, y, w, h, text )\
  3028.     self:base( x, y, w, h )\
  3029. \
  3030.     self.text = text or \"\"\
  3031.     self:update( 0 )\
  3032. end\
  3033. \
  3034. function Button:update( dt )\
  3035.     self.metadata = {\
  3036.         bc = self.bc;\
  3037.         tc = self.tc;\
  3038.         width = self.width;\
  3039.         height = self.height;\
  3040.     }\
  3041.     self.lines = formatter.lines( self.text, self.metadata )\
  3042.     self.fmt = formatter.renderPrep( self.lines, self.metadata )\
  3043. end\
  3044. \
  3045. function Button:draw( x, y, buffer )\
  3046.     if not self.noAlign then\
  3047.         formatter.fixAlignment( self.fmt, self.width, self.height, \"centre\", \"centre\" )\
  3048.     end\
  3049.     drawtext( self, self.fmt, x, y, buffer )\
  3050. end\
  3051. \
  3052. function Button:handle( event )\
  3053.     if mouse.click( self, event ) then\
  3054.         local protocol, target = mouse.text_link_check( self.lines, event:getParam \"x\", event:getParam \"y\", self.fmt.offset )\
  3055.         if protocol and self.onLinkOpened then\
  3056.             self:onLinkOpened( protocol, target )\
  3057.         elseif self.onClick then\
  3058.             self:onClick( protocol, target )\
  3059.         end\
  3060.     elseif event.name == \"mouse_ping\" then\
  3061.         mouse.ping( self, event )\
  3062.     end\
  3063. end\
  3064. \
  3065. return Button",
  3066.   [ "/rom/help/copy" ] = "cp copies a file or directory from one location to another.\
  3067. \
  3068. ex:\
  3069. \"cp rom myrom\" copies \"rom\" to \"myrom\".\
  3070. \"cp rom mystuff/rom\" copies \"rom\" to \"mystuff/rom\".\
  3071. \"cp disk/* disk2\" copies the contents of one disk to another",
  3072.   [ "/Flare/version/1.2/lib/UI/elements/Frame.lua" ] = "\
  3073. local class = require \"lib.class\"\
  3074. local base = require \"lib.UI.base\"\
  3075. local mouse = require \"lib.UI.event.mouse\"\
  3076. \
  3077. local Frame = class \"Frame\"\
  3078. Frame:extend( base )\
  3079. \
  3080. function Frame:Frame( x, y, w, h )\
  3081.     self:base( x, y, w, h )\
  3082.     \
  3083.     self.children = {}\
  3084.     self.ox = 0\
  3085.     self.oy = 0\
  3086. \
  3087.     self.stack = \"none\"\
  3088.     self.padding = 0\
  3089. \
  3090.     return self\
  3091. end\
  3092. \
  3093. function Frame:newChild( child )\
  3094.     if child.parent then\
  3095.         child.parent:removeChild( child )\
  3096.     end\
  3097.     self.children[#self.children + 1] = child\
  3098.     child.parent = self\
  3099.     child.root.__index = self.root\
  3100.     child.root.__newindex = self.root\
  3101.     return child\
  3102. end\
  3103. \
  3104. function Frame:removeChild( child )\
  3105.     for i = #self.children, 1, -1 do\
  3106.         if self.children[i] == child then\
  3107.             table.remove( self.children, i )\
  3108.             child.parent = nil\
  3109.             child.root.__index = nil\
  3110.             child.root.__newindex = nil\
  3111.             break\
  3112.         end\
  3113.     end\
  3114.     return self\
  3115. end\
  3116. \
  3117. function Frame:draw( x, y, buffer )\
  3118.     for i = 1, #self.children do\
  3119.         self.children[i]:draw( x + self.children[i].x - 1 + self.ox, y + self.children[i].y - 1 + self.oy, buffer )\
  3120.     end\
  3121. end\
  3122. \
  3123. function Frame:update( dt )\
  3124.     if self.stack == \"vertical\" then\
  3125.         for i = 2, #self.children do\
  3126.             self.children[i].y = self.children[i-1].y + self.children[i-1].height + self.padding\
  3127.         end\
  3128.     elseif self.stack == \"horizontal\" then\
  3129.         for i = 2, #self.children do\
  3130.             self.children[i].x = self.children[i-1].x + self.children[i-1].width + self.padding\
  3131.         end\
  3132.     end\
  3133.     local ch = self:getContentHeight()\
  3134.     if ch <= self.height then\
  3135.     elseif self.oy < self.height - ch then\
  3136.         self.oy = self.height - ch\
  3137.     elseif self.oy > 0 then\
  3138.         self.oy = 0\
  3139.     end\
  3140.     local cw = self:getContentWidth()\
  3141.     if cw <= self.width then\
  3142.     elseif self.ox < self.width - cw then\
  3143.         self.ox = self.width - cw\
  3144.     elseif self.ox > 0 then\
  3145.         self.ox = 0\
  3146.     end\
  3147.     for i = #self.children, 1, -1 do\
  3148.         self.children[i]:update( dt )\
  3149.     end\
  3150. end\
  3151. \
  3152. function Frame:handle( event )\
  3153.     if event.name == \"mouse_down\" or event.name == \"mouse_up\" or event.name == \"mouse_drag\" then\
  3154.         local within = event:getParam \"within\" ~= false and mouse.within( self, event ) or false\
  3155.         for i = #self.children, 1, -1 do\
  3156.             local child = self.children[i]\
  3157.             child:handle( event:clone {\
  3158.                 x = event:getParam \"x\" - child.x + 1 - self.ox;\
  3159.                 y = event:getParam \"y\" - child.y + 1 - self.oy;\
  3160.                 within = within;\
  3161.             } )\
  3162.         end\
  3163.     elseif event.name == \"mouse_scroll\" then\
  3164.         local within = event:getParam \"within\" ~= false and mouse.within( self, event ) or false\
  3165.         for i = #self.children, 1, -1 do\
  3166.             local child = self.children[i]\
  3167.             child:handle( event:clone {\
  3168.                 x = event:getParam \"x\" - child.x + 1 - self.ox;\
  3169.                 y = event:getParam \"y\" - child.y + 1 - self.oy;\
  3170.                 within = within;\
  3171.             } )\
  3172.         end\
  3173.         if not event.handled and mouse.within( self, event ) and event:getParam \"direction\" == 1 and self.height - self.oy < self:getContentHeight() then\
  3174.             event.handled = true\
  3175.             self.oy = self.oy - 1\
  3176.         elseif not event.handled and mouse.within( self, event ) and event:getParam \"direction\" == -1 and self.oy < 0 then\
  3177.             event.handled = true\
  3178.             self.oy = self.oy + 1\
  3179.         end\
  3180.     elseif event.name == \"mouse_ping\" then\
  3181.         mouse.ping( self, event )\
  3182.         for i = #self.children, 1, -1 do\
  3183.             self.children[i]:handle( event )\
  3184.         end\
  3185.     else\
  3186.         for i = #self.children, 1, -1 do\
  3187.             self.children[i]:handle( event )\
  3188.         end\
  3189.     end\
  3190. end\
  3191. \
  3192. function Frame:getContentWidth()\
  3193.     local w = 0\
  3194.     for i = 1, #self.children do\
  3195.         w = math.max( self.children[i].x + self.children[i].width - 1, w )\
  3196.     end\
  3197.     return w\
  3198. end\
  3199. \
  3200. function Frame:getContentHeight()\
  3201.     local h = 0\
  3202.     for i = 1, #self.children do\
  3203.         h = math.max( self.children[i].y + self.children[i].height - 1, h )\
  3204.     end\
  3205.     return h\
  3206. end\
  3207. \
  3208. function Frame:getContentScrollX()\
  3209.     return -self.ox\
  3210. end\
  3211. \
  3212. function Frame:setContentScrollX( scroll )\
  3213.     self.ox = math.min( math.max( -scroll, self.width - self:getContentWidth() ), 0 )\
  3214. end\
  3215. \
  3216. function Frame:getContentScrollY()\
  3217.     return -self.oy\
  3218. end\
  3219. \
  3220. function Frame:setContentScrollY( scroll )\
  3221.     self.oy = math.min( math.max( -scroll, self.height - self:getContentHeight() ), 0 )\
  3222. end\
  3223. \
  3224. return Frame",
  3225.   [ "/rom/programs/fun/adventure" ] = "\
  3226. local tBiomes = {\
  3227.     \"in a forest\",\
  3228.     \"in a pine forest\",\
  3229.     \"knee deep in a swamp\",\
  3230.     \"in a mountain range\",\
  3231.     \"in a desert\",\
  3232.     \"in a grassy plain\",\
  3233.     \"in frozen tundra\",\
  3234. }\
  3235. \
  3236. local function hasTrees( _nBiome )\
  3237.     return _nBiome <= 3\
  3238. end\
  3239. \
  3240. local function hasStone( _nBiome )\
  3241.     return _nBiome == 4\
  3242. end\
  3243. \
  3244. local function hasRivers( _nBiome )\
  3245.     return _nBiome ~= 3 and _nBiome ~= 5\
  3246. end\
  3247. \
  3248. local items = {\
  3249.     [\"no tea\"] = {\
  3250.         droppable = false,\
  3251.         desc = \"Pull yourself together man.\",\
  3252.     },\
  3253.     [\"a pig\"] = {\
  3254.         heavy = true,\
  3255.         creature = true,\
  3256.         drops = { \"some pork\" },\
  3257.         aliases = { \"pig\" },\
  3258.         desc = \"The pig has a square nose.\",\
  3259.     },\
  3260.     [\"a cow\"] = {\
  3261.         heavy = true,\
  3262.         creature = true,\
  3263.         aliases = { \"cow\" },\
  3264.         desc = \"The cow stares at you blankly.\",\
  3265.     },\
  3266.     [\"a sheep\"] = {\
  3267.         heavy = true,\
  3268.         creature = true,\
  3269.         hitDrops = { \"some wool\" },\
  3270.         aliases = { \"sheep\" },\
  3271.         desc = \"The sheep is fluffy.\",\
  3272.     },\
  3273.     [\"a chicken\"] = {\
  3274.         heavy = true,\
  3275.         creature = true,\
  3276.         drops = { \"some chicken\" },\
  3277.         aliases = { \"chicken\" },\
  3278.         desc = \"The chicken looks delicious.\",\
  3279.     },\
  3280.     [\"a creeper\"] = {\
  3281.         heavy = true,\
  3282.         creature = true,\
  3283.         monster = true,\
  3284.         aliases = { \"creeper\" },\
  3285.         desc = \"The creeper needs a hug.\",\
  3286.     },\
  3287.     [\"a skeleton\"] = {\
  3288.         heavy = true,\
  3289.         creature = true,\
  3290.         monster = true,\
  3291.         aliases = { \"skeleton\" },\
  3292.         nocturnal = true,\
  3293.         desc = \"The head bone's connected to the neck bone, the neck bone's connected to the chest bone, the chest bone's connected to the arm bone, the arm bone's connected to the bow, and the bow is pointed at you.\",\
  3294.     },\
  3295.     [\"a zombie\"] = {\
  3296.         heavy = true,\
  3297.         creature = true,\
  3298.         monster = true,\
  3299.         aliases = { \"zombie\" },\
  3300.         nocturnal = true,\
  3301.         desc = \"All he wants to do is eat your brains.\",\
  3302.     },\
  3303.     [\"a spider\"] = {\
  3304.         heavy = true,\
  3305.         creature = true,\
  3306.         monster = true,\
  3307.         aliases = { \"spider\" },\
  3308.         desc = \"Dozens of eyes stare back at you.\",\
  3309.     },\
  3310.     [\"a cave entrance\"] = {\
  3311.         heavy = true,\
  3312.         aliases = { \"cave entance\", \"cave\", \"entrance\" },\
  3313.         desc = \"The entrance to the cave is dark, but it looks like you can climb down.\",\
  3314.     },\
  3315.     [\"an exit to the surface\"] = {\
  3316.         heavy = true,\
  3317.         aliases = { \"exit to the surface\", \"exit\", \"opening\" },\
  3318.         desc = \"You can just see the sky through the opening.\",\
  3319.     },\
  3320.     [\"a river\"] = {\
  3321.         heavy = true,\
  3322.         aliases = { \"river\" },\
  3323.         desc = \"The river flows majestically towards the horizon. It doesn't do anything else.\",\
  3324.     },\
  3325.     [\"some wood\"] = {\
  3326.         aliases = { \"wood\" },\
  3327.         material = true,\
  3328.         desc = \"You could easilly craft this wood into planks.\",\
  3329.     },\
  3330.     [\"some planks\"] = {\
  3331.         aliases = { \"planks\", \"wooden planks\", \"wood planks\" },\
  3332.         desc = \"You could easilly craft these planks into sticks.\",\
  3333.     },\
  3334.     [\"some sticks\"] = {\
  3335.         aliases = { \"sticks\", \"wooden sticks\", \"wood sticks\" },\
  3336.         desc = \"A perfect handle for torches or a pickaxe.\",\
  3337.     },\
  3338.     [\"a crafting table\"] = {\
  3339.         aliases = { \"crafting table\", \"craft table\", \"work bench\", \"workbench\", \"crafting bench\", \"table\", },\
  3340.         desc = \"It's a crafting table. I shouldn't tell you this, but these don't actually do anything in this game, you can craft tools whenever you like.\",\
  3341.     },\
  3342.     [\"a furnace\"] = {\
  3343.         aliases = { \"furnace\" },\
  3344.         desc = \"It's a furnace. Between you and me, these don't actually do anything in this game.\",\
  3345.     },\
  3346.     [\"a wooden pickaxe\"] = {\
  3347.         aliases = { \"pickaxe\", \"pick\", \"wooden pick\", \"wooden pickaxe\", \"wood pick\", \"wood pickaxe\" },\
  3348.         tool = true,\
  3349.         toolLevel = 1,\
  3350.         toolType = \"pick\",\
  3351.         desc = \"The pickaxe looks good for breaking stone and coal.\",\
  3352.     },\
  3353.     [\"a stone pickaxe\"] = {\
  3354.         aliases = { \"pickaxe\", \"pick\", \"stone pick\", \"stone pickaxe\" },\
  3355.         tool = true,\
  3356.         toolLevel = 2,\
  3357.         toolType = \"pick\",\
  3358.         desc = \"The pickaxe looks good for breaking iron.\",\
  3359.     },\
  3360.     [\"an iron pickaxe\"] = {\
  3361.         aliases = { \"pickaxe\", \"pick\", \"iron pick\", \"iron pickaxe\" },\
  3362.         tool = true,\
  3363.         toolLevel = 3,\
  3364.         toolType = \"pick\",\
  3365.         desc = \"The pickaxe looks strong enough to break diamond.\",\
  3366.     },\
  3367.     [\"a diamond pickaxe\"] = {\
  3368.         aliases = { \"pickaxe\", \"pick\", \"diamond pick\", \"diamond pickaxe\" },\
  3369.         tool = true,\
  3370.         toolLevel = 4,\
  3371.         toolType = \"pick\",\
  3372.         desc = \"Best. Pickaxe. Ever.\",\
  3373.     },\
  3374.     [\"a wooden sword\"] = {\
  3375.         aliases = { \"sword\", \"wooden sword\", \"wood sword\" },\
  3376.         tool = true,\
  3377.         toolLevel = 1,\
  3378.         toolType = \"sword\",\
  3379.         desc = \"Flimsy, but better than nothing.\",\
  3380.     },\
  3381.     [\"a stone sword\"] = {\
  3382.         aliases = { \"sword\", \"stone sword\" },\
  3383.         tool = true,\
  3384.         toolLevel = 2,\
  3385.         toolType = \"sword\",\
  3386.         desc = \"A pretty good sword.\",\
  3387.     },\
  3388.     [\"an iron sword\"] = {\
  3389.         aliases = { \"sword\", \"iron sword\" },\
  3390.         tool = true,\
  3391.         toolLevel = 3,\
  3392.         toolType = \"sword\",\
  3393.         desc = \"This sword can slay any enemy.\",\
  3394.     },\
  3395.     [\"a diamond sword\"] = {\
  3396.         aliases = { \"sword\", \"diamond sword\" },\
  3397.         tool = true,\
  3398.         toolLevel = 4,\
  3399.         toolType = \"sword\",\
  3400.         desc = \"Best. Sword. Ever.\",\
  3401.     },\
  3402.     [\"a wooden shovel\"] = {\
  3403.         aliases = { \"shovel\", \"wooden shovel\", \"wood shovel\" },\
  3404.         tool = true,\
  3405.         toolLevel = 1,\
  3406.         toolType = \"shovel\",\
  3407.         desc = \"Good for digging holes.\",\
  3408.     },\
  3409.     [\"a stone shovel\"] = {\
  3410.         aliases = { \"shovel\", \"stone shovel\" },\
  3411.         tool = true,\
  3412.         toolLevel = 2,\
  3413.         toolType = \"shovel\",\
  3414.         desc = \"Good for digging holes.\",\
  3415.     },\
  3416.     [\"an iron shovel\"] = {\
  3417.         aliases = { \"shovel\", \"iron shovel\" },\
  3418.         tool = true,\
  3419.         toolLevel = 3,\
  3420.         toolType = \"shovel\",\
  3421.         desc = \"Good for digging holes.\",\
  3422.     },\
  3423.     [\"a diamond shovel\"] = {\
  3424.         aliases = { \"shovel\", \"diamond shovel\" },\
  3425.         tool = true,\
  3426.         toolLevel = 4,\
  3427.         toolType = \"shovel\",\
  3428.         desc = \"Good for digging holes.\",\
  3429.     },\
  3430.     [\"some coal\"] = {\
  3431.         aliases = { \"coal\" },\
  3432.         ore = true,\
  3433.         toolLevel = 1,\
  3434.         toolType = \"pick\",\
  3435.         desc = \"That coal looks useful for building torches, if only you had a pickaxe to mine it.\",\
  3436.     },\
  3437.     [\"some dirt\"] = {\
  3438.         aliases = { \"dirt\" },\
  3439.         material = true,\
  3440.         desc = \"Why not build a mud hut?\",\
  3441.     },\
  3442.     [\"some stone\"] = {\
  3443.         aliases = { \"stone\", \"cobblestone\" },\
  3444.         material = true,\
  3445.         ore = true,\
  3446.         infinite = true,\
  3447.         toolLevel = 1,\
  3448.         toolType = \"pick\",\
  3449.         desc = \"Stone is useful for building things, and making stone pickaxes.\",\
  3450.     },\
  3451.     [\"some iron\"] = {\
  3452.         aliases = { \"iron\" },\
  3453.         material = true,\
  3454.         ore = true,\
  3455.         toolLevel = 2,\
  3456.         toolType = \"pick\",\
  3457.         desc = \"That iron looks mighty strong, you'll need a stone pickaxe to mine it.\",\
  3458.     },\
  3459.     [\"some diamond\"] = {\
  3460.         aliases = { \"diamond\", \"diamonds\" },\
  3461.         material = true,\
  3462.         ore = true,\
  3463.         toolLevel = 3,\
  3464.         toolType = \"pick\",\
  3465.         desc = \"Sparkly, rare, and impossible to mine without an iron pickaxe.\",\
  3466.     },\
  3467.     [\"some torches\"] = {\
  3468.         aliases = { \"torches\", \"torch\" },\
  3469.         desc = \"These won't run out for a while.\",\
  3470.     },\
  3471.     [\"a torch\"] = {\
  3472.         aliases = { \"torch\" },\
  3473.         desc = \"Fire, fire, burn so bright, won't you light my cave tonight?\",\
  3474.     },\
  3475.     [\"some wool\"] = {\
  3476.         aliases = { \"wool\" },\
  3477.         material = true,\
  3478.         desc = \"Soft and good for building.\",\
  3479.     },\
  3480.     [\"some pork\"] = {\
  3481.         aliases = { \"pork\", \"porkchops\" },\
  3482.         food = true,\
  3483.         desc = \"Delicious and nutricious.\",\
  3484.     },\
  3485.     [\"some chicken\"] = {\
  3486.         aliases = { \"chicken\" },\
  3487.         food = true,\
  3488.         desc = \"Finger licking good.\",\
  3489.     },\
  3490. }\
  3491. \
  3492. local tAnimals = {\
  3493.     \"a pig\", \"a cow\", \"a sheep\", \"a chicken\",\
  3494. }\
  3495. \
  3496. local tMonsters = {\
  3497.     \"a creeper\", \"a skeleton\", \"a zombie\", \"a spider\"\
  3498. }\
  3499. \
  3500. local tRecipes = {\
  3501.     [\"some planks\"] = { \"some wood\" },\
  3502.     [\"some sticks\"] = { \"some planks\" },\
  3503.     [\"some sticks\"] = { \"some planks\" },\
  3504.     [\"a crafting table\"] = { \"some planks\" },\
  3505.     [\"a furnace\"] = { \"some stone\" },\
  3506.     [\"some torches\"] = { \"some sticks\", \"some coal\" },\
  3507.     \
  3508.     [\"a wooden pickaxe\"] = { \"some planks\", \"some sticks\" },\
  3509.     [\"a stone pickaxe\"] = { \"some stone\", \"some sticks\" },\
  3510.     [\"an iron pickaxe\"] = { \"some iron\", \"some sticks\" },\
  3511.     [\"a diamond pickaxe\"] = { \"some diamond\", \"some sticks\" },\
  3512. \
  3513.     [\"a wooden sword\"] = { \"some planks\", \"some sticks\" },\
  3514.     [\"a stone sword\"] = { \"some stone\", \"some sticks\" },\
  3515.     [\"an iron sword\"] = { \"some iron\", \"some sticks\" },\
  3516.     [\"a diamond sword\"] = { \"some diamond\", \"some sticks\" },\
  3517. \
  3518.     [\"a wooden shovel\"] = { \"some planks\", \"some sticks\" },\
  3519.     [\"a stone shovel\"] = { \"some stone\", \"some sticks\" },\
  3520.     [\"an iron shovel\"] = { \"some iron\", \"some sticks\" },\
  3521.     [\"a diamond shovel\"] = { \"some diamond\", \"some sticks\" },\
  3522. }\
  3523. \
  3524. local tGoWest = {\
  3525.     \"(life is peaceful there)\",\
  3526.     \"(lots of open air)\",\
  3527.     \"(to begin life anew)\",\
  3528.     \"(this is what we'll do)\",\
  3529.     \"(sun in winter time)\",\
  3530.     \"(we will do just fine)\",\
  3531.     \"(where the skies are blue)\",\
  3532.     \"(this and more we'll do)\",\
  3533. }\
  3534. local nGoWest = 0\
  3535. \
  3536. local bRunning = true\
  3537. local tMap = { { {}, }, }\
  3538. local x,y,z = 0,0,0\
  3539. local inventory = {\
  3540.     [\"no tea\"] = items[\"no tea\"],\
  3541. }\
  3542. \
  3543. local nTurn = 0\
  3544. local nTimeInRoom = 0\
  3545. local bInjured = false\
  3546. \
  3547. local tDayCycle = {\
  3548.     \"It is daytime.\",\
  3549.     \"It is daytime.\",\
  3550.     \"It is daytime.\",\
  3551.     \"It is daytime.\",\
  3552.     \"It is daytime.\",\
  3553.     \"It is daytime.\",\
  3554.     \"It is daytime.\",\
  3555.     \"It is daytime.\",\
  3556.     \"The sun is setting.\",\
  3557.     \"It is night.\",\
  3558.     \"It is night.\",\
  3559.     \"It is night.\",\
  3560.     \"It is night.\",\
  3561.     \"It is night.\",\
  3562.     \"The sun is rising.\",\
  3563. }\
  3564. \
  3565. local function getTimeOfDay()\
  3566.     return math.fmod( math.floor(nTurn/3), #tDayCycle ) + 1\
  3567. end\
  3568. \
  3569. local function isSunny()\
  3570.     return (getTimeOfDay() < 10)\
  3571. end\
  3572. \
  3573. local function getRoom( x, y, z, dontCreate )\
  3574.     tMap[x] = tMap[x] or {}\
  3575.     tMap[x][y] = tMap[x][y] or {}\
  3576.     if not tMap[x][y][z] and dontCreate ~= true then\
  3577.         local room = {\
  3578.             items = {},\
  3579.             exits = {},\
  3580.             nMonsters = 0,\
  3581.         }\
  3582.         tMap[x][y][z] = room\
  3583.         \
  3584.         if y == 0 then\
  3585.             -- Room is above ground\
  3586. \
  3587.             -- Pick biome\
  3588.             room.nBiome = math.random( 1, #tBiomes )\
  3589.             room.trees = hasTrees( room.nBiome )\
  3590.         \
  3591.             -- Add animals\
  3592.             if math.random(1,3) == 1 then\
  3593.                 for n = 1,math.random(1,2) do\
  3594.                     local sAnimal = tAnimals[ math.random( 1, #tAnimals ) ]\
  3595.                     room.items[ sAnimal ] = items[ sAnimal ]\
  3596.                 end\
  3597.             end\
  3598.             \
  3599.             -- Add surface ore\
  3600.             if math.random(1,5) == 1 or hasStone( room.nBiome ) then\
  3601.                 room.items[ \"some stone\" ] = items[ \"some stone\" ]\
  3602.             end\
  3603.             if math.random(1,8) == 1 then\
  3604.                 room.items[ \"some coal\" ] = items[ \"some coal\" ]\
  3605.             end\
  3606.             if math.random(1,8) == 1 and hasRivers( room.nBiome ) then\
  3607.                 room.items[ \"a river\" ] = items[ \"a river\" ]\
  3608.             end\
  3609. \
  3610.             -- Add exits\
  3611.             room.exits = {\
  3612.                 [\"north\"] = true,\
  3613.                 [\"south\"] = true,\
  3614.                 [\"east\"] = true,\
  3615.                 [\"west\"] = true,\
  3616.             }\
  3617.             if math.random(1,8) == 1 then\
  3618.                 room.exits[\"down\"] = true\
  3619.                 room.items[\"a cave entrance\"] = items[\"a cave entrance\"]\
  3620.             end\
  3621.                         \
  3622.         else\
  3623.             -- Room is underground\
  3624.             -- Add exits\
  3625.             local function tryExit( sDir, sOpp, x, y, z )\
  3626.                 local adj = getRoom( x, y, z, true )\
  3627.                 if adj then\
  3628.                     if adj.exits[sOpp] then\
  3629.                         room.exits[sDir] = true\
  3630.                     end\
  3631.                 else\
  3632.                     if math.random(1,3) == 1 then\
  3633.                         room.exits[sDir] = true\
  3634.                     end\
  3635.                 end\
  3636.             end\
  3637.             \
  3638.             if y == -1 then\
  3639.                 local above = getRoom( x, y + 1, z )\
  3640.                 if above.exits[\"down\"] then\
  3641.                     room.exits[\"up\"] = true\
  3642.                     room.items[\"an exit to the surface\"] = items[\"an exit to the surface\"]\
  3643.                 end\
  3644.             else\
  3645.                 tryExit( \"up\", \"down\", x, y + 1, z )\
  3646.             end\
  3647.             \
  3648.             if y > -3 then\
  3649.                 tryExit( \"down\", \"up\", x, y - 1, z )\
  3650.             end\
  3651.             \
  3652.             tryExit( \"east\", \"west\", x - 1, y, z )\
  3653.             tryExit( \"west\", \"east\", x + 1, y, z )\
  3654.             tryExit( \"north\", \"south\", x, y, z + 1 )\
  3655.             tryExit( \"south\", \"north\", x, y, z - 1 )    \
  3656.             \
  3657.             -- Add ores\
  3658.             room.items[ \"some stone\" ] = items[ \"some stone\" ]\
  3659.             if math.random(1,3) == 1 then\
  3660.                 room.items[ \"some coal\" ] = items[ \"some coal\" ]\
  3661.             end\
  3662.             if math.random(1,8) == 1 then\
  3663.                 room.items[ \"some iron\" ] = items[ \"some iron\" ]\
  3664.             end\
  3665.             if y == -3 and math.random(1,15) == 1 then\
  3666.                 room.items[ \"some diamond\" ] = items[ \"some diamond\" ]\
  3667.             end\
  3668.             \
  3669.             -- Turn out the lights\
  3670.             room.dark = true\
  3671.         end\
  3672.     end\
  3673.     return tMap[x][y][z]\
  3674. end\
  3675. \
  3676. local function itemize( t )\
  3677.     local item = next( t )\
  3678.     if item == nil then\
  3679.         return \"nothing\"\
  3680.     end\
  3681.     \
  3682.     local text = \"\"\
  3683.     while item do\
  3684.         text = text .. item\
  3685.         \
  3686.         local nextItem = next( t, item )\
  3687.         if nextItem ~= nil then\
  3688.             local nextNextItem = next( t, nextItem )\
  3689.             if nextNextItem == nil then\
  3690.                 text = text .. \" and \"\
  3691.             else\
  3692.                 text = text .. \", \"\
  3693.             end\
  3694.         end\
  3695.         item = nextItem\
  3696.     end\
  3697.     return text\
  3698. end\
  3699. \
  3700. function findItem( _tList, _sQuery )\
  3701.     for sItem, tItem in pairs( _tList ) do\
  3702.         if sItem == _sQuery then\
  3703.             return sItem\
  3704.         end\
  3705.         if tItem.aliases ~= nil then\
  3706.             for n, sAlias in pairs( tItem.aliases ) do\
  3707.                 if sAlias == _sQuery then\
  3708.                     return sItem\
  3709.                 end\
  3710.             end\
  3711.         end\
  3712.     end\
  3713.     return nil\
  3714. end\
  3715. \
  3716. local tMatches = {\
  3717.     [\"wait\"] = {\
  3718.         \"wait\",\
  3719.     },\
  3720.     [\"look\"] = {\
  3721.         \"look at the ([%a ]+)\",\
  3722.         \"look at ([%a ]+)\",\
  3723.         \"look\",\
  3724.         \"inspect ([%a ]+)\",\
  3725.         \"inspect the ([%a ]+)\",\
  3726.         \"inspect\",\
  3727.     },\
  3728.     [\"inventory\"] = {\
  3729.         \"check self\",\
  3730.         \"check inventory\",\
  3731.         \"inventory\",\
  3732.         \"i\",\
  3733.     },\
  3734.     [\"go\"] = {\
  3735.         \"go (%a+)\",\
  3736.         \"travel (%a+)\",\
  3737.         \"walk (%a+)\",\
  3738.         \"run (%a+)\",\
  3739.         \"go\",\
  3740.     },\
  3741.     [\"dig\"] = {\
  3742.         \"dig (%a+) using ([%a ]+)\",\
  3743.         \"dig (%a+) with ([%a ]+)\",\
  3744.         \"dig (%a+)\",\
  3745.         \"dig\",\
  3746.     },\
  3747.     [\"take\"] = {\
  3748.         \"pick up the ([%a ]+)\",\
  3749.         \"pick up ([%a ]+)\",\
  3750.         \"pickup ([%a ]+)\",\
  3751.         \"take the ([%a ]+)\",\
  3752.         \"take ([%a ]+)\",\
  3753.         \"take\",\
  3754.     },\
  3755.     [\"drop\"] = {\
  3756.         \"put down the ([%a ]+)\",\
  3757.         \"put down ([%a ]+)\",\
  3758.         \"drop the ([%a ]+)\",\
  3759.         \"drop ([%a ]+)\",\
  3760.         \"drop\",\
  3761.     },\
  3762.     [\"place\"] = {\
  3763.         \"place the ([%a ]+)\",\
  3764.         \"place ([%a ]+)\",\
  3765.         \"place\",\
  3766.     },\
  3767.     [\"cbreak\"] = {\
  3768.         \"punch the ([%a ]+)\",\
  3769.         \"punch ([%a ]+)\",\
  3770.         \"punch\",\
  3771.         \"break the ([%a ]+) with the ([%a ]+)\",\
  3772.         \"break ([%a ]+) with ([%a ]+) \",\
  3773.         \"break the ([%a ]+)\",\
  3774.         \"break ([%a ]+)\",\
  3775.         \"break\",\
  3776.     },\
  3777.     [\"mine\"] = {\
  3778.         \"mine the ([%a ]+) with the ([%a ]+)\",\
  3779.         \"mine ([%a ]+) with ([%a ]+)\",\
  3780.         \"mine ([%a ]+)\",\
  3781.         \"mine\",\
  3782.     },\
  3783.     [\"attack\"] = {\
  3784.         \"attack the ([%a ]+) with the ([%a ]+)\",\
  3785.         \"attack ([%a ]+) with ([%a ]+)\",\
  3786.         \"attack ([%a ]+)\",\
  3787.         \"attack\",\
  3788.         \"kill the ([%a ]+) with the ([%a ]+)\",\
  3789.         \"kill ([%a ]+) with ([%a ]+)\",\
  3790.         \"kill ([%a ]+)\",\
  3791.         \"kill\",\
  3792.         \"hit the ([%a ]+) with the ([%a ]+)\",\
  3793.         \"hit ([%a ]+) with ([%a ]+)\",\
  3794.         \"hit ([%a ]+)\",\
  3795.         \"hit\",\
  3796.     },\
  3797.     [\"craft\"] = {\
  3798.         \"craft a ([%a ]+)\",\
  3799.         \"craft some ([%a ]+)\",\
  3800.         \"craft ([%a ]+)\",\
  3801.         \"craft\",\
  3802.         \"make a ([%a ]+)\",\
  3803.         \"make some ([%a ]+)\",\
  3804.         \"make ([%a ]+)\",\
  3805.         \"make\",\
  3806.     },\
  3807.     [\"build\"] = {\
  3808.         \"build ([%a ]+) out of ([%a ]+)\",\
  3809.         \"build ([%a ]+) from ([%a ]+)\",\
  3810.         \"build ([%a ]+)\",\
  3811.         \"build\",\
  3812.     },\
  3813.     [\"eat\"] = {\
  3814.         \"eat a ([%a ]+)\",\
  3815.         \"eat the ([%a ]+)\",\
  3816.         \"eat ([%a ]+)\",\
  3817.         \"eat\",\
  3818.     },\
  3819.     [\"help\"] = {\
  3820.         \"help me\",\
  3821.         \"help\",\
  3822.     },\
  3823.     [\"exit\"] = {\
  3824.         \"exit\",\
  3825.         \"quit\",\
  3826.         \"goodbye\",\
  3827.         \"good bye\",\
  3828.         \"bye\",\
  3829.         \"farewell\",\
  3830.     },\
  3831. }\
  3832. \
  3833. local commands = {}\
  3834. function doCommand( text )\
  3835.     if text == \"\" then\
  3836.         commands[ \"noinput\" ]()\
  3837.         return\
  3838.     end\
  3839.     \
  3840.     for sCommand, t in pairs( tMatches ) do\
  3841.         for n, sMatch in pairs( t ) do\
  3842.             local tCaptures = { string.match( text, \"^\" .. sMatch .. \"$\" ) }\
  3843.             if #tCaptures ~= 0 then\
  3844.                 local fnCommand = commands[ sCommand ]\
  3845.                 if #tCaptures == 1 and tCaptures[1] == sMatch then\
  3846.                     fnCommand()\
  3847.                 else\
  3848.                     fnCommand( unpack( tCaptures ) )\
  3849.                 end\
  3850.                 return\
  3851.             end\
  3852.         end\
  3853.     end\
  3854.     commands[ \"badinput\" ]()\
  3855. end\
  3856. \
  3857. function commands.wait()\
  3858.     print( \"Time passes...\" )\
  3859. end\
  3860. \
  3861. function commands.look( _sTarget )\
  3862.     local room = getRoom( x,y,z )\
  3863.     if room.dark then\
  3864.         print( \"It is pitch dark.\" )\
  3865.         return\
  3866.     end\
  3867. \
  3868.     if _sTarget == nil then\
  3869.         -- Look at the world\
  3870.         if y == 0 then\
  3871.             io.write( \"You are standing \" .. tBiomes[room.nBiome] .. \". \" )\
  3872.             print( tDayCycle[ getTimeOfDay() ] )\
  3873.         else\
  3874.             io.write( \"You are underground. \" )\
  3875.             if next( room.exits ) ~= nil then\
  3876.                 print( \"You can travel \"..itemize( room.exits )..\".\" )\
  3877.             else\
  3878.                 print()\
  3879.             end\
  3880.         end\
  3881.         if next( room.items ) ~= nil then\
  3882.             print( \"There is \" .. itemize( room.items ) .. \" here.\" )\
  3883.         end\
  3884.         if room.trees then\
  3885.             print( \"There are trees here.\" )\
  3886.         end\
  3887.         \
  3888.     else\
  3889.         -- Look at stuff\
  3890.         if room.trees and (_sTarget == \"tree\" or _sTarget == \"trees\") then\
  3891.             print( \"The trees look easy to break.\" )\
  3892.         elseif _sTarget == \"self\" or _sTarget == \"myself\" then\
  3893.             print( \"Very handsome.\" )\
  3894.         else\
  3895.             local tItem = nil\
  3896.             local sItem = findItem( room.items, _sTarget )\
  3897.             if sItem then\
  3898.                 tItem = room.items[sItem]\
  3899.             else\
  3900.                 sItem = findItem( inventory, _sTarget )\
  3901.                 if sItem then\
  3902.                     tItem = inventory[sItem]\
  3903.                 end\
  3904.             end\
  3905.             \
  3906.             if tItem then\
  3907.                 print( tItem.desc or (\"You see nothing special about \"..sItem..\".\") )\
  3908.             else\
  3909.                 print( \"You don't see any \".._sTarget..\" here.\" )\
  3910.             end\
  3911.         end\
  3912.     end\
  3913. end\
  3914. \
  3915. function commands.go( _sDir )\
  3916.     local room = getRoom( x,y,z )\
  3917.     if _sDir == nil then\
  3918.         print( \"Go where?\" )\
  3919.         return\
  3920.     end\
  3921.     \
  3922.     if nGoWest ~= nil then\
  3923.         if _sDir == \"west\" then\
  3924.             nGoWest = nGoWest + 1\
  3925.             if nGoWest > #tGoWest then\
  3926.                 nGoWest = 1\
  3927.             end\
  3928.             print( tGoWest[ nGoWest ] )\
  3929.         else\
  3930.             if nGoWest > 0 or nTurn > 6 then\
  3931.                 nGoWest = nil\
  3932.             end\
  3933.         end\
  3934.     end\
  3935.     \
  3936.     if room.exits[_sDir] == nil then\
  3937.         print( \"You can't go that way.\" )\
  3938.         return\
  3939.     end\
  3940.     \
  3941.     if _sDir == \"north\" then\
  3942.         z = z + 1\
  3943.     elseif _sDir == \"south\" then\
  3944.         z = z - 1\
  3945.     elseif _sDir == \"east\" then\
  3946.         x = x - 1\
  3947.     elseif _sDir == \"west\" then\
  3948.         x = x + 1\
  3949.     elseif _sDir == \"up\" then\
  3950.         y = y + 1\
  3951.     elseif _sDir == \"down\" then\
  3952.         y = y - 1\
  3953.     else\
  3954.         print( \"I don't understand that direction.\" )\
  3955.         return\
  3956.     end\
  3957.     \
  3958.     nTimeInRoom = 0\
  3959.     doCommand( \"look\" )\
  3960. end\
  3961. \
  3962. function commands.dig( _sDir, _sTool )\
  3963.     local room = getRoom( x,y,z )\
  3964.     if _sDir == nil then\
  3965.         print( \"Dig where?\" )\
  3966.         return\
  3967.     end\
  3968.     \
  3969.     local sTool = nil\
  3970.     local tTool = nil\
  3971.     if _sTool ~= nil then\
  3972.         sTool = findItem( inventory, _sTool )\
  3973.         if not sTool then\
  3974.             print( \"You're not carrying a \".._sTool..\".\" )\
  3975.             return\
  3976.         end\
  3977.         tTool = inventory[ sTool ]\
  3978.     end\
  3979.     \
  3980.     local room = getRoom( x, y, z )\
  3981.     local bActuallyDigging = (room.exits[ _sDir ] ~= true)\
  3982.     if bActuallyDigging then\
  3983.         if sTool == nil or tTool.toolType ~= \"pick\" then\
  3984.             print( \"You need to use a pickaxe to dig through stone.\" )\
  3985.             return\
  3986.         end\
  3987.     end\
  3988.     \
  3989.     if _sDir == \"north\" then\
  3990.         room.exits[\"north\"] = true\
  3991.         z = z + 1\
  3992.         getRoom( x, y, z ).exits[\"south\"] = true\
  3993. \
  3994.     elseif _sDir == \"south\" then\
  3995.         room.exits[\"south\"] = true\
  3996.         z = z - 1\
  3997.         getRoom( x, y, z ).exits[\"north\"] = true\
  3998.         \
  3999.     elseif _sDir == \"east\" then\
  4000.         room.exits[\"east\"] = true\
  4001.         x = x - 1\
  4002.         getRoom( x, y, z ).exits[\"west\"] = true\
  4003.         \
  4004.     elseif _sDir == \"west\" then\
  4005.         room.exits[\"west\"] = true\
  4006.         x = x + 1\
  4007.         getRoom( x, y, z ).exits[\"east\"] = true\
  4008.         \
  4009.     elseif _sDir == \"up\" then\
  4010.         if y == 0 then\
  4011.             print( \"You can't dig that way.\" )\
  4012.             return\
  4013.         end\
  4014. \
  4015.         room.exits[\"up\"] = true\
  4016.         if y == -1 then\
  4017.             room.items[ \"an exit to the surface\" ] = items[ \"an exit to the surface\" ]\
  4018.         end\
  4019.         y = y + 1\
  4020.         \
  4021.         room = getRoom( x, y, z )\
  4022.         room.exits[\"down\"] = true\
  4023.         if y == 0 then\
  4024.             room.items[ \"a cave entrance\" ] = items[ \"a cave entrance\" ]\
  4025.         end\
  4026.         \
  4027.     elseif _sDir == \"down\" then\
  4028.         if y <= -3 then\
  4029.             print( \"You hit bedrock.\" )\
  4030.             return\
  4031.         end\
  4032. \
  4033.         room.exits[\"down\"] = true\
  4034.         if y == 0 then\
  4035.             room.items[ \"a cave entrance\" ] = items[ \"a cave entrance\" ]\
  4036.         end\
  4037.         y = y - 1\
  4038.         \
  4039.         room = getRoom( x, y, z )\
  4040.         room.exits[\"up\"] = true\
  4041.         if y == -1 then\
  4042.             room.items[ \"an exit to the surface\" ] = items[ \"an exit to the surface\" ]\
  4043.         end\
  4044.         \
  4045.     else\
  4046.         print( \"I don't understand that direction.\" )\
  4047.         return\
  4048.     end\
  4049.     \
  4050.     --\
  4051.     if bActuallyDigging then\
  4052.         if _sDir == \"down\" and y == -1 or\
  4053.            _sDir == \"up\" and y == 0 then\
  4054.             inventory[ \"some dirt\" ] = items[ \"some dirt\" ]\
  4055.             inventory[ \"some stone\" ] = items[ \"some stone\" ]\
  4056.             print( \"You dig \".._sDir..\" using \"..sTool..\" and collect some dirt and stone.\" )\
  4057.         else\
  4058.             inventory[ \"some stone\" ] = items[ \"some stone\" ]\
  4059.             print( \"You dig \".._sDir..\" using \"..sTool..\" and collect some stone.\" )\
  4060.         end\
  4061.     end\
  4062.     \
  4063.     nTimeInRoom = 0\
  4064.     doCommand( \"look\" )\
  4065. end\
  4066. \
  4067. function commands.inventory()\
  4068.     print( \"You are carrying \" .. itemize( inventory ) .. \".\" )\
  4069. end\
  4070. \
  4071. function commands.drop( _sItem )\
  4072.     if _sItem == nil then\
  4073.         print( \"Drop what?\" )\
  4074.         return\
  4075.     end\
  4076.     \
  4077.     local room = getRoom( x,y,z )\
  4078.     local sItem = findItem( inventory, _sItem )\
  4079.     if sItem then\
  4080.         local tItem = inventory[ sItem ]\
  4081.         if tItem.droppable == false then\
  4082.             print( \"You can't drop that.\" )\
  4083.         else\
  4084.             room.items[ sItem ] = tItem\
  4085.             inventory[ sItem ] = nil\
  4086.             print( \"Dropped.\" )\
  4087.         end\
  4088.     else\
  4089.         print( \"You don't have a \".._sItem..\".\" )\
  4090.     end\
  4091. end\
  4092. \
  4093. function commands.place( _sItem )\
  4094.     if _sItem == nil then\
  4095.         print( \"Place what?\" )\
  4096.         return\
  4097.     end\
  4098.     \
  4099.     if _sItem == \"torch\" or _sItem == \"a torch\" then\
  4100.         local room = getRoom( x,y,z )\
  4101.         if inventory[\"some torches\"] or inventory[\"a torch\"] then\
  4102.             inventory[\"a torch\"] = nil\
  4103.             room.items[\"a torch\"] = items[\"a torch\"]\
  4104.             if room.dark then\
  4105.                 print( \"The cave lights up under the torchflame.\" )\
  4106.                 room.dark = false\
  4107.             elseif y == 0 and not isSunny() then\
  4108.                 print( \"The night gets a little brighter.\" )\
  4109.             else\
  4110.                 print( \"Placed.\" )\
  4111.             end\
  4112.         else\
  4113.             print( \"You don't have torches.\" )\
  4114.         end\
  4115.         return\
  4116.     end\
  4117.     \
  4118.     commands.drop( _sItem )\
  4119. end\
  4120. \
  4121. function commands.take( _sItem )\
  4122.     if _sItem == nil then\
  4123.         print( \"Take what?\" )\
  4124.         return\
  4125.     end\
  4126. \
  4127.     local room = getRoom( x,y,z )\
  4128.     local sItem = findItem( room.items, _sItem )\
  4129.     if sItem then\
  4130.         local tItem = room.items[ sItem ]\
  4131.         if tItem.heavy == true then\
  4132.             print( \"You can't carry \"..sItem..\".\" )\
  4133.         elseif tItem.ore == true then\
  4134.             print( \"You need to mine this ore.\" )\
  4135.         else\
  4136.             if tItem.infinite ~= true then\
  4137.                 room.items[ sItem ] = nil\
  4138.             end\
  4139.             inventory[ sItem ] = tItem\
  4140.             \
  4141.             if inventory[\"some torches\"] and inventory[\"a torch\"] then\
  4142.                 inventory[\"a torch\"] = nil\
  4143.             end\
  4144.             if sItem == \"a torch\" and y < 0 then\
  4145.                 room.dark = true\
  4146.                 print( \"The cave plunges into darkness.\" )\
  4147.             else\
  4148.                 print( \"Taken.\" )\
  4149.             end\
  4150.         end\
  4151.     else\
  4152.         print( \"You don't see a \".._sItem..\" here.\" )\
  4153.     end\
  4154. end\
  4155. \
  4156. function commands.mine( _sItem, _sTool )\
  4157.     if _sItem == nil then\
  4158.         print( \"Mine what?\" )\
  4159.         return\
  4160.     end\
  4161.     if _sTool == nil then\
  4162.         print( \"Mine \".._sItem..\" with what?\" )\
  4163.         return\
  4164.     end \
  4165.     commands.cbreak( _sItem, _sTool )\
  4166. end\
  4167. \
  4168. function commands.attack( _sItem, _sTool )\
  4169.     if _sItem == nil then\
  4170.         print( \"Attack what?\" )\
  4171.         return\
  4172.     end\
  4173.     commands.cbreak( _sItem, _sTool )\
  4174. end\
  4175. \
  4176. function commands.cbreak( _sItem, _sTool )\
  4177.     if _sItem == nil then\
  4178.         print( \"Break what?\" )\
  4179.         return\
  4180.     end\
  4181.     \
  4182.     local sTool = nil\
  4183.     if _sTool ~= nil then\
  4184.         sTool = findItem( inventory, _sTool )\
  4185.         if sTool == nil then\
  4186.             print( \"You're not carrying a \".._sTool..\".\" )\
  4187.             return\
  4188.         end\
  4189.     end\
  4190. \
  4191.     local room = getRoom( x,y,z )\
  4192.     if _sItem == \"tree\" or _sItem == \"trees\" or _sItem == \"a tree\" then\
  4193.         print( \"The tree breaks into blocks of wood, which you pick up.\" )\
  4194.         inventory[ \"some wood\" ] = items[ \"some wood\" ]\
  4195.         return\
  4196.     elseif _sItem == \"self\" or _sItem == \"myself\" then\
  4197.         if term.isColour() then\
  4198.             term.setTextColour( colours.red )\
  4199.         end\
  4200.         print( \"You have died.\" )\
  4201.         print( \"Score: &e0\" )\
  4202.         term.setTextColour( colours.white )\
  4203.         bRunning = false\
  4204.         return\
  4205.     end\
  4206.     \
  4207.     local sItem = findItem( room.items, _sItem )\
  4208.     if sItem then\
  4209.         local tItem = room.items[ sItem ]\
  4210.         if tItem.ore == true then\
  4211.             -- Breaking ore\
  4212.             if not sTool then\
  4213.                 print( \"You need a tool to break this ore.\" )\
  4214.                 return\
  4215.             end\
  4216.             local tTool = inventory[ sTool ]\
  4217.             if tTool.tool then\
  4218.                 if tTool.toolLevel < tItem.toolLevel then\
  4219.                     print( sTool ..\" is not strong enough to break this ore.\" )\
  4220.                 elseif tTool.toolType ~= tItem.toolType then\
  4221.                     print( \"You need a different kind of tool to break this ore.\" )\
  4222.                 else\
  4223.                     print( \"The ore breaks, dropping \"..sItem..\", which you pick up.\" )\
  4224.                     inventory[ sItem ] = items[ sItem ]\
  4225.                     if tItem.infinite ~= true then\
  4226.                         room.items[ sItem ] = nil\
  4227.                     end\
  4228.                 end\
  4229.             else\
  4230.                 print( \"You can't break \"..sItem..\" with \"..sTool..\".\")\
  4231.             end\
  4232.             \
  4233.         elseif tItem.creature == true then\
  4234.             -- Fighting monsters (or pigs)\
  4235.             local toolLevel = 0\
  4236.             local tTool = nil\
  4237.             if sTool then\
  4238.                 tTool = inventory[ sTool ]\
  4239.                 if tTool.toolType == \"sword\" then\
  4240.                     toolLevel = tTool.toolLevel\
  4241.                 end\
  4242.             end\
  4243.                         \
  4244.             local tChances = { 0.2, 0.4, 0.55, 0.8, 1 }\
  4245.             if math.random() <= tChances[ toolLevel + 1 ] then\
  4246.                 room.items[ sItem ] = nil\
  4247.                 print( \"The \"..tItem.aliases[1]..\" dies.\" )\
  4248.     \
  4249.                 if tItem.drops then\
  4250.                     for n, sDrop in pairs( tItem.drops ) do\
  4251.                         if not room.items[sDrop] then\
  4252.                             print( \"The \"..tItem.aliases[1]..\" dropped \"..sDrop..\".\" )\
  4253.                             room.items[sDrop] = items[sDrop]\
  4254.                         end\
  4255.                     end\
  4256.                 end\
  4257.                 \
  4258.                 if tItem.monster then\
  4259.                     room.nMonsters = room.nMonsters - 1\
  4260.                 end\
  4261.             else\
  4262.                 print( \"The \"..tItem.aliases[1]..\" is injured by your blow.\" )\
  4263.             end\
  4264.             \
  4265.             if tItem.hitDrops then\
  4266.                 for n, sDrop in pairs( tItem.hitDrops ) do\
  4267.                     if not room.items[sDrop] then\
  4268.                         print( \"The \"..tItem.aliases[1]..\" dropped \"..sDrop..\".\" )\
  4269.                         room.items[sDrop] = items[sDrop]\
  4270.                     end\
  4271.                 end\
  4272.             end\
  4273.         \
  4274.         else\
  4275.             print( \"You can't break \"..sItem..\".\" )\
  4276.         end\
  4277.     else\
  4278.         print( \"You don't see a \".._sItem..\" here.\" )\
  4279.     end\
  4280. end\
  4281. \
  4282. function commands.craft( _sItem )\
  4283.     if _sItem == nil then\
  4284.         print( \"Craft what?\" )\
  4285.         return\
  4286.     end\
  4287.     \
  4288.     if _sItem == \"computer\" or _sItem == \"a computer\" then\
  4289.         print( \"By creating a computer in a computer in a computer, you tear a hole in the spacetime continuum from which no mortal being can escape.\" )\
  4290.         if term.isColour() then\
  4291.             term.setTextColour( colours.red )\
  4292.         end\
  4293.         print( \"You have died.\" )\
  4294.         print( \"Score: &e0\" )\
  4295.         term.setTextColour( colours.white )\
  4296.         bRunning = false\
  4297.         return\
  4298.     end\
  4299.     \
  4300.     local room = getRoom( x,y,z )\
  4301.     local sItem = findItem( items, _sItem )\
  4302.     local tRecipe = (sItem and tRecipes[ sItem ]) or nil\
  4303.     if tRecipe then\
  4304.         for n,sReq in ipairs( tRecipe ) do\
  4305.             if inventory[sReq] == nil then\
  4306.                 print( \"You don't have the items you need to craft \"..sItem..\".\" )\
  4307.                 return\
  4308.             end\
  4309.         end\
  4310.         \
  4311.         for n,sReq in ipairs( tRecipe ) do\
  4312.             inventory[sReq] = nil\
  4313.         end\
  4314.         inventory[ sItem ] = items[ sItem ]\
  4315.         if inventory[\"some torches\"] and inventory[\"a torch\"] then\
  4316.             inventory[\"a torch\"] = nil\
  4317.         end\
  4318.         print( \"Crafted.\" )\
  4319.     else\
  4320.         print( \"You don't know how to make \"..(sItem or _sItem)..\".\" )\
  4321.     end \
  4322. end\
  4323. \
  4324. function commands.build( _sThing, _sMaterial )\
  4325.     if _sThing == nil then\
  4326.         print( \"Build what?\" )\
  4327.         return\
  4328.     end\
  4329.         \
  4330.     local sMaterial = nil\
  4331.     if _sMaterial == nil then\
  4332.         for sItem, tItem in pairs( inventory ) do\
  4333.             if tItem.material then\
  4334.                 sMaterial = sItem\
  4335.                 break\
  4336.             end\
  4337.         end\
  4338.         if sMaterial == nil then\
  4339.             print( \"You don't have any building materials.\" )\
  4340.             return\
  4341.         end\
  4342.     else\
  4343.         sMaterial = findItem( inventory, _sMaterial )\
  4344.         if not sMaterial then\
  4345.             print( \"You don't have any \".._sMaterial )\
  4346.             return\
  4347.         end\
  4348.         \
  4349.         if inventory[sMaterial].material ~= true then\
  4350.             print( sMaterial..\" is not a good building material.\" )\
  4351.             return\
  4352.         end\
  4353.     end\
  4354.     \
  4355.     local alias = nil\
  4356.     if string.sub(_sThing, 1, 1) == \"a\" then\
  4357.         alias = string.match( _sThing, \"a ([%a ]+)\" )\
  4358.     end\
  4359.     \
  4360.     local room = getRoom( x,y,z )\
  4361.     inventory[sMaterial] = nil\
  4362.     room.items[ _sThing ] = {\
  4363.         heavy = true,\
  4364.         aliases = { alias },\
  4365.         desc = \"As you look at your creation (made from \"..sMaterial..\"), you feel a swelling sense of pride.\",\
  4366.     }\
  4367. \
  4368.     print( \"Your construction is complete.\" )\
  4369. end\
  4370. \
  4371. function commands.help()\
  4372.     local sText = \
  4373.         \"Welcome to adventure, the greatest text adventure game on CraftOS. \" ..\
  4374.         \"To get around the world, type actions, and the adventure will \" ..\
  4375.         \"be read back to you. The actions availiable to you are go, look, inspect, inventory, \" ..\
  4376.         \"take, drop, place, punch, attack, mine, dig, craft, build, eat and exit.\"\
  4377.     print( sText )\
  4378. end\
  4379. \
  4380. function commands.eat( _sItem )\
  4381.     if _sItem == nil then\
  4382.         print( \"Eat what?\" )\
  4383.         return\
  4384.     end\
  4385. \
  4386.     local sItem = findItem( inventory, _sItem )\
  4387.     if not sItem then\
  4388.         print( \"You don't have any \".._sItem..\".\" )\
  4389.         return\
  4390.     end\
  4391.     \
  4392.     local tItem = inventory[sItem]\
  4393.     if tItem.food then\
  4394.         print( \"That was delicious!\" )\
  4395.         inventory[sItem] = nil\
  4396.         \
  4397.         if bInjured then\
  4398.             print( \"You are no longer injured.\" )\
  4399.             bInjured = false\
  4400.         end\
  4401.     else\
  4402.         print( \"You can't eat \"..sItem..\".\" )\
  4403.     end\
  4404. end\
  4405. \
  4406. function commands.exit()\
  4407.     bRunning = false\
  4408. end\
  4409. \
  4410. function commands.badinput()\
  4411.     local tResponses = {\
  4412.         \"I don't understand.\",\
  4413.         \"I don't understand you.\",\
  4414.         \"You can't do that.\",\
  4415.         \"Nope.\",\
  4416.         \"Huh?\",\
  4417.         \"Say again?\",\
  4418.         \"That's crazy talk.\",\
  4419.         \"Speak clearly.\",\
  4420.         \"I'll think about it.\",\
  4421.         \"Let me get back to you on that one.\",\
  4422.         \"That doesn't make any sense.\",\
  4423.         \"What?\",\
  4424.     }\
  4425.     print( tResponses[ math.random(1,#tResponses) ] )\
  4426. end\
  4427. \
  4428. function commands.noinput()\
  4429.     local tResponses = {\
  4430.         \"Speak up.\",\
  4431.         \"Enunciate.\",\
  4432.         \"Project your voice.\",\
  4433.         \"Don't be shy.\",\
  4434.         \"Use your words.\",\
  4435.     }\
  4436.     print( tResponses[ math.random(1,#tResponses) ] )\
  4437. end\
  4438. \
  4439. local function simulate()\
  4440.     local bNewMonstersThisRoom = false\
  4441.     \
  4442.     -- Spawn monsters in nearby rooms\
  4443.     for sx = -2,2 do\
  4444.         for sy = -1,1 do\
  4445.             for sz = -2,2 do\
  4446.                 local h = y + sy\
  4447.                 if h >= -3 and h <= 0 then\
  4448.                     local room = getRoom( x + sx, h, z + sz )\
  4449.                     \
  4450.                     -- Spawn monsters\
  4451.                     if room.nMonsters < 2 and\
  4452.                        ((h == 0 and not isSunny() and not room.items[\"a torch\"]) or room.dark) and\
  4453.                        math.random(1,6) == 1 then\
  4454.                        \
  4455.                         local sMonster = tMonsters[ math.random(1,#tMonsters) ]\
  4456.                         if room.items[ sMonster ] == nil then\
  4457.                             room.items[ sMonster ] = items[ sMonster ]\
  4458.                             room.nMonsters = room.nMonsters + 1\
  4459.                             \
  4460.                             if sx == 0 and sy == 0 and sz == 0 and not room.dark then\
  4461.                                 print( \"From the shadows, \"..sMonster..\" appears.\" )\
  4462.                                 bNewMonstersThisRoom = true\
  4463.                             end\
  4464.                         end \
  4465.                     end\
  4466.                     \
  4467.                     -- Burn monsters\
  4468.                     if h == 0 and isSunny() then\
  4469.                         for n,sMonster in ipairs( tMonsters ) do\
  4470.                             if room.items[sMonster] and items[sMonster].nocturnal then\
  4471.                                 room.items[sMonster] = nil\
  4472.                                 if sx == 0 and sy == 0 and sz == 0 and not room.dark then\
  4473.                                     print( \"With the sun high in the sky, the \"..items[sMonster].aliases[1]..\" bursts into flame and dies.\" )\
  4474.                                 end\
  4475.                                 room.nMonsters = room.nMonsters - 1\
  4476.                             end\
  4477.                         end\
  4478.                     end \
  4479.                 end\
  4480.             end\
  4481.         end\
  4482.     end\
  4483. \
  4484.     -- Make monsters attack\
  4485.     local room = getRoom( x, y, z )\
  4486.     if nTimeInRoom >= 2 and not bNewMonstersThisRoom then\
  4487.         for n,sMonster in ipairs( tMonsters ) do\
  4488.             if room.items[sMonster] then\
  4489.                 if math.random(1,4) == 1 and\
  4490.                    not (y == 0 and isSunny() and (sMonster == \"a spider\")) then\
  4491.                     if sMonster == \"a creeper\" then\
  4492.                         if room.dark then\
  4493.                             print( \"A creeper explodes.\" )\
  4494.                         else\
  4495.                             print( \"The creeper explodes.\" )\
  4496.                         end\
  4497.                         room.items[sMonster] = nil\
  4498.                         room.nMonsters = room.nMonsters - 1\
  4499.                     else\
  4500.                         if room.dark then\
  4501.                             print( \"A \"..items[sMonster].aliases[1]..\" attacks you.\" )\
  4502.                         else\
  4503.                             print( \"The \"..items[sMonster].aliases[1]..\" attacks you.\" )\
  4504.                         end\
  4505.                     end\
  4506.                     \
  4507.                     if bInjured then\
  4508.                         if term.isColour() then\
  4509.                             term.setTextColour( colours.red )\
  4510.                         end\
  4511.                         print( \"You have died.\" )\
  4512.                         print( \"Score: &e0\" )\
  4513.                         term.setTextColour( colours.white )\
  4514.                         bRunning = false\
  4515.                         return\
  4516.                     else\
  4517.                         bInjured = true\
  4518.                     end\
  4519.                     \
  4520.                     break\
  4521.                 end\
  4522.             end\
  4523.         end\
  4524.     end\
  4525.     \
  4526.     -- Always print this\
  4527.     if bInjured then\
  4528.         if term.isColour() then\
  4529.             term.setTextColour( colours.red )\
  4530.         end\
  4531.         print( \"You are injured.\" )\
  4532.         term.setTextColour( colours.white )\
  4533.     end\
  4534.     \
  4535.     -- Advance time\
  4536.     nTurn = nTurn + 1\
  4537.     nTimeInRoom = nTimeInRoom + 1\
  4538. end\
  4539. \
  4540. doCommand( \"look\" )\
  4541. simulate()\
  4542. \
  4543. local tCommandHistory = {}\
  4544. while bRunning do\
  4545.     if term.isColour() then\
  4546.         term.setTextColour( colours.yellow )\
  4547.     end\
  4548.    write( \"? \" )\
  4549.     term.setTextColour( colours.white )\
  4550.         \
  4551.    local sRawLine = read( nil, tCommandHistory )\
  4552.    table.insert( tCommandHistory, sRawLine )\
  4553.    \
  4554.    local sLine = nil\
  4555.     for match in string.gmatch(sRawLine, \"%a+\") do\
  4556.         if sLine then\
  4557.             sLine = sLine .. \" \" .. string.lower(match)\
  4558.         else\
  4559.             sLine = string.lower(match)\
  4560.         end\
  4561.     end\
  4562.     \
  4563.     doCommand( sLine or \"\" )\
  4564.    if bRunning then\
  4565.         simulate()\
  4566.     end\
  4567. end",
  4568.   [ "/Shop/States/Search.lua" ] = "local StateLib = FDK.require('lib.state')\
  4569. local State = StateLib.names.Init\
  4570. local Main = StateLib.names.Main\
  4571. local Search = StateLib.names.Search\
  4572. local Account = StateLib.names.Account\
  4573. local Items = StateLib.names.Items\
  4574. \
  4575. local Field = FDK.require('lib.UI.elements.Field')\
  4576. local Text = FDK.require('lib.UI.elements.Text')\
  4577. local Button = FDK.require('lib.UI.elements.Button')\
  4578. local ScrollBar = FDK.require('lib.UI.elements.ScrollBar')\
  4579. local Frame = FDK.require('lib.UI.elements.ClippingFrame')\
  4580. \
  4581. -- Main Field\
  4582. Search.frame:newChild(Field(1, 1, Search.frame.width, Search.frame.height, colors.white))\
  4583. -- Header Field\
  4584. Search.frame:newChild(Field(1, 1, Search.frame.width, 3, colors.lightGray))\
  4585. \
  4586. local back = Search.frame:newChild( Button( 1, 1, 8, 3, \"< back\" ) )\
  4587. back.bc = colors.lightGray\
  4588. back.tc = colors.white\
  4589. \
  4590. function back:onClick()\
  4591.  Main:show()\
  4592. end\
  4593. \
  4594. local SearchFrame = Search.frame:newChild(Frame(1, 4,\
  4595.  Search.frame.width-2,\
  4596.  Search.frame.height-3\
  4597. ))\
  4598. local SearchBar = Search.frame:newChild(ScrollBar(Search.frame.width, 4, 1, Search.frame.height-3, SearchFrame))",
  4599.   [ "/Flare/version/1.2/lib/UI/draw/draw.lua" ] = "\
  4600. local image = require \"lib.UI.draw.image\"\
  4601. local pixel = require \"lib.UI.draw.pixel\"\
  4602. local pixelbatch = require \"lib.UI.draw.pixelbatch\"\
  4603. local text = require \"lib.UI.draw.text\"\
  4604. \
  4605. return {\
  4606.     image = image;\
  4607.     pixel = pixel;\
  4608.     pixelbatch = pixelbatch;\
  4609.     text = text;\
  4610. }",
  4611.   [ "/rom/help/edit" ] = "edit is a text editor for creating or modifying programs or text files. After creating a program with edit, type its filename in the shell to run it. You can open any of the builtin programs with edit to learn how to program.\
  4612. \
  4613. ex:\
  4614. \"edit hello\" opens a file called \"hello\" for editing.",
  4615.   [ "/rom/help/clear" ] = "clear clears the screen.",
  4616.   [ "/Flare/version/1.2/lib/UI/elements/ScrollBar.lua" ] = "\
  4617. local class = require \"lib.class\"\
  4618. local base = require \"lib.UI.base\"\
  4619. local mouse = require \"lib.UI.event.mouse\"\
  4620. local graphics = require \"lib.graphics\"\
  4621. \
  4622. -- bar / tray = object / children\
  4623. -- scroll = ( height - bar ) * tscroll / ( tcontent - theight )\
  4624. \
  4625. local function scrollStats( self )\
  4626.     if not self.target then\
  4627.         return 0, self.direction == \"vertical\" and self.height or self.width\
  4628.     end\
  4629.     local objectsize = self.direction == \"vertical\" and self.target.height or self.target.width\
  4630.     local childrensize = self.direction == \"vertical\" and self.target:getContentHeight() or self.target:getContentWidth()\
  4631.     local trayheight = self.direction == \"vertical\" and self.height or self.width\
  4632.     local barheight = math.min( math.max( math.ceil( trayheight * ( objectsize / childrensize ) ), 1 ), trayheight )\
  4633. \
  4634.     local tscroll = self.direction == \"vertical\" and self.target:getContentScrollY() or self.target:getContentScrollX()\
  4635.     local scroll = math.floor( ( trayheight - barheight ) * tscroll / ( childrensize - objectsize ) )\
  4636. \
  4637.     return scroll, barheight, objectsize, childrensize, trayheight, tscroll\
  4638. end\
  4639. \
  4640. local ScrollBar = class \"ScrollBar\"\
  4641. ScrollBar:extend( base )\
  4642. \
  4643. ScrollBar.tc = \"grey\" -- tray colour\
  4644. ScrollBar.bc = \"lightGrey\" -- bar colour\
  4645. \
  4646. ScrollBar.direction = \"vertical\"\
  4647. \
  4648. function ScrollBar:ScrollBar( x, y, w, h, target )\
  4649.     self:base( x, y, w, h )\
  4650.     self.target = target\
  4651. end\
  4652. \
  4653. function ScrollBar:draw( x, y, buffer )\
  4654.     buffer:setColours( graphics.colour( self.tc ) )\
  4655.     buffer:drawFilledRectangle( x, y, self.width, self.height )\
  4656. \
  4657.     local scroll, size = scrollStats( self )\
  4658. \
  4659.     buffer:setColours( graphics.colour( self.bc ) )\
  4660. \
  4661.     if self.direction == \"vertical\" then\
  4662.         buffer:drawFilledRectangle( x, y + scroll, self.width, size )\
  4663.     else\
  4664.         buffer:drawFilledRectangle( x + scroll, y, size, self.height )\
  4665.     end\
  4666. end\
  4667. \
  4668. function ScrollBar:handle( event )\
  4669.     local mode, x, y = mouse.drag( self, event )\
  4670.     if mode == \"down\" then\
  4671.         local scroll, barheight, objectsize, childrensize, trayheight, tscroll = scrollStats( self )\
  4672.         local pos\
  4673.         if self.direction == \"vertical\" then\
  4674.             if y > scroll and y <= scroll + barheight then\
  4675.                 pos = \"inside\"\
  4676.             elseif y <= scroll then\
  4677.                 pos = \"below\"\
  4678.             elseif y > scroll + barheight then\
  4679.                 pos = \"above\"\
  4680.             end\
  4681.         else\
  4682.             if x > scroll and x <= scroll + barheight then\
  4683.                 pos = \"inside\"\
  4684.             elseif x <= scroll then\
  4685.                 pos = \"below\"\
  4686.             elseif x > scroll + barheight then\
  4687.                 pos = \"above\"\
  4688.             end\
  4689.         end\
  4690. \
  4691.         if pos == \"inside\" then\
  4692.             self.down = self.direction == \"vertical\" and ( y - scroll ) or ( x - scroll )\
  4693.         elseif pos == \"below\" then\
  4694.             scroll = self.direction == \"vertical\" and y - 1 or x - 1\
  4695.         elseif pos == \"above\" then\
  4696.             scroll = self.direction == \"vertical\" and y - barheight or x - barheight\
  4697.         end\
  4698. \
  4699.         if pos ~= \"inside\" then\
  4700.             self.down = false\
  4701.             local method = self.direction == \"vertical\" and \"setContentScrollY\" or \"setContentScrollX\"\
  4702.             self.target[method]( self.target, math.floor( scroll / ( trayheight - barheight ) * ( childrensize - objectsize ) + .5 ) )\
  4703.         end\
  4704.     elseif mode == \"drag\" and self.down then\
  4705.         event.handled = true\
  4706.         local x, y = event:getParam \"x\", event:getParam \"y\"\
  4707.         local scroll, barheight, objectsize, childrensize, trayheight, tscroll = scrollStats( self )\
  4708. \
  4709.         scroll = ( self.direction == \"vertical\" and ( y - self.down ) or ( x - self.down ) )\
  4710. \
  4711.         local method = self.direction == \"vertical\" and \"setContentScrollY\" or \"setContentScrollX\"\
  4712.         self.target[method]( self.target, math.floor( scroll / ( trayheight - barheight ) * ( childrensize - objectsize ) + .5 ) )\
  4713.     end\
  4714.     if event.name == \"mouse_scroll\" and not event.handled and mouse.within( self, event ) then\
  4715.         event.handled = true\
  4716.         local scroll, barheight, objectsize, childrensize, trayheight, tscroll = scrollStats( self )\
  4717.         if event:getParam \"direction\" == 1 then\
  4718.             scroll = scroll + 1\
  4719.         elseif event:getParam \"direction\" == -1 then\
  4720.             scroll = scroll - 1\
  4721.         end\
  4722.         local method = self.direction == \"vertical\" and \"setContentScrollY\" or \"setContentScrollX\"\
  4723.         self.target[method]( self.target, math.floor( scroll / ( trayheight - barheight ) * ( childrensize - objectsize ) + .5 ) )\
  4724.     elseif event.name == \"mouse_ping\" then\
  4725.         mouse_event.ping( self, event )\
  4726.     end\
  4727. end\
  4728. \
  4729. return ScrollBar",
  4730.   [ "/rom/help/label" ] = "label gets or sets the label of the Computer, or of Floppy Disks in attached disk drives.\
  4731. \
  4732. ex:\
  4733. \"label get\" prints the label of the computer.\
  4734. \"label get left\" prints the label of the disk in the left drive.\
  4735. \"label set \"My Computer\"\" set the label of the computer to \"My Computer\".\
  4736. \"label set left \"My Programs\"\" - sets the label of the disk in the left drive to \"My Programs\".\
  4737. \"label clear\" clears the label of the computer.\
  4738. \"label clear left\" clears the label of the disk in the left drive.",
  4739.   [ "/rom/programs/fun/hello" ] = "if term.isColour() then\
  4740.     term.setTextColour( 2^math.random(0,15) )\
  4741. end\
  4742. textutils.slowPrint( \"Hello World!\" )\
  4743. term.setTextColour( colours.white )",
  4744.   [ "/rom/help/colors" ] = "Functions in the colors api\
  4745. (used for redstone.setBundledOutput):\
  4746. colors.combine( color1, color2, color3, ... )\
  4747. colors.subtract( colors, color1, color2, ... )\
  4748. colors.test( colors, color )\
  4749. \
  4750. Color constants in the colors api, in ascending bit order:\
  4751. colors.white, colors.orange, colors.magenta, colors.lightBlue, colors.yellow, colors.lime, colors.pink, colors.gray, colors.lightGray, colors.cyan, colors.purple, colors.blue, colors.brown, colors.green, colors.red, colors.black.",
  4752.   [ "/rom/programs/fun/advanced/levels/3" ] = "2\
  4753.  77777777\
  4754. 777888188777\
  4755. 7b78777787b7\
  4756. 78787  78787\
  4757. 78787  78787\
  4758. 78887  78887\
  4759. 777877778777\
  4760.  78838887\
  4761.  77777777",
  4762.   [ "/rom/programs/advanced/bg" ] = "\
  4763. local tArgs = { ... }\
  4764. if #tArgs > 0 then\
  4765.    shell.openTab( unpack( tArgs ) )\
  4766. else\
  4767.    shell.openTab( \"shell\" )\
  4768. end",
  4769.   [ "/run" ] = "shell.run('Shop/run')",
  4770.   [ "/rom/apis/colours" ] = "-- Colours (for lovers of british spelling)\
  4771. local fnFile, err = loadfile(\"/rom/apis/colors\")\
  4772. if not fnFile then\
  4773.     error( err )\
  4774. end\
  4775. \
  4776. local tColors = {}\
  4777. setmetatable( tColors, { __index = _G } )\
  4778. setfenv( fnFile, tColors )\
  4779. fnFile( tColors )\
  4780. \
  4781. local tColours = getfenv()\
  4782. for k,v in pairs( tColors ) do\
  4783.     tColours[k] = v\
  4784. end\
  4785. \
  4786. tColours.gray = nil\
  4787. tColours.grey = tColors.gray\
  4788. \
  4789. tColours.lightGray = nil\
  4790. tColours.lightGrey = tColors.lightGray",
  4791.   [ "/rom/help/gpsapi" ] = "Functions in the GPS API:\
  4792. gps.locate( timeout )\
  4793. \
  4794. The locate function will send a signal to nearby gps servers, and wait for responses before the timeout. If it receives enough responses to determine this computers position then x, y and z co-ordinates will be returned, otherwise it will return nil. If GPS hosts do not have their positions configured correctly, results will be inaccurate.",
  4795.   [ "/rom/help/pastebin" ] = "pastebin is a program for uploading files to and downloading files from pastebin.com. This is useful for sharing programs with other players.\
  4796. The HTTP API must be enabled in ComputerCraft.cfg to use this program.\
  4797. \
  4798. ex:\
  4799. \"pastebin put foo\" will upload the file \"foo\" to pastebin.com, and print the URL.\
  4800. \"pastebin get xq5gc7LB foo\" will download the file from the URL http://pastebin.com/xq5gc7LB, and save it as \"foo\".\
  4801. \"pastebin run CxaWmPrX\" will download the file from the URL http://pastebin.com/CxaWmPrX, and immediately run it.",
  4802.   [ "/rom/autorun/.ignoreme" ] = "--[[\
  4803. Alright then, don't ignore me. This file is to ensure the existance of the \"autorun\" folder, files placed in this folder\
  4804. using resource packs will always run when computers startup.\
  4805. ]]",
  4806.   [ "/rom/programs/time" ] = "local nTime = os.time()\
  4807. local nDay = os.day()\
  4808. print( \"The time is \"..textutils.formatTime( nTime, false )..\" on Day \"..nDay )",
  4809.   [ "/rom/help/monitor" ] = "monitor will connect to an attached Monitor peripheral, and run a program on its display.\
  4810. \
  4811. ex:\
  4812. \"monitor left hello\" will run the \"hello\" program on the monitor to the left of the computer.\
  4813. \"monitor top edit foo\" will run the edit program on the top monitor, editing the file \"foo\".",
  4814.   [ "/rom/help/io" ] = "io is a standard Lua5.1 API, reimplemented for CraftOS. Not all the features are availiable.\
  4815. Refer to http://www.lua.org/manual/5.1/ for more information.",
  4816.   [ "/rom/programs/http/pastebin" ] = "\
  4817. local function printUsage()\
  4818.    print( \"Usages:\" )\
  4819.    print( \"pastebin put <filename>\" )\
  4820.    print( \"pastebin get <code> <filename>\" )\
  4821.    print( \"pastebin run <code> <arguments>\" )\
  4822. end\
  4823. \
  4824. local tArgs = { ... }\
  4825. if #tArgs < 2 then\
  4826.    printUsage()\
  4827.    return\
  4828. end\
  4829. \
  4830. if not http then\
  4831.    printError( \"Pastebin requires http API\" )\
  4832.    printError( \"Set http_enable to true in ComputerCraft.cfg\" )\
  4833.    return\
  4834. end\
  4835. \
  4836. local function get(paste)\
  4837.    write( \"Connecting to pastebin.com... \" )\
  4838.    local response = http.get(\
  4839.        \"http://pastebin.com/raw.php?i=\"..textutils.urlEncode( paste )\
  4840.    )\
  4841.        \
  4842.    if response then\
  4843.        print( \"Success.\" )\
  4844.        \
  4845.        local sResponse = response.readAll()\
  4846.        response.close()\
  4847.        return sResponse\
  4848.    else\
  4849.        printError( \"Failed.\" )\
  4850.    end\
  4851. end\
  4852. \
  4853. local sCommand = tArgs[1]\
  4854. if sCommand == \"put\" then\
  4855.    -- Upload a file to pastebin.com\
  4856.    -- Determine file to upload\
  4857.    local sFile = tArgs[2]\
  4858.    local sPath = shell.resolve( sFile )\
  4859.    if not fs.exists( sPath ) or fs.isDir( sPath ) then\
  4860.        print( \"No such file\" )\
  4861.        return\
  4862.    end\
  4863.    \
  4864.    -- Read in the file\
  4865.    local sName = fs.getName( sPath )\
  4866.    local file = fs.open( sPath, \"r\" )\
  4867.    local sText = file.readAll()\
  4868.    file.close()\
  4869.    \
  4870.    -- POST the contents to pastebin\
  4871.    write( \"Connecting to pastebin.com... \" )\
  4872.    local key = \"0ec2eb25b6166c0c27a394ae118ad829\"\
  4873.    local response = http.post(\
  4874.        \"http://pastebin.com/api/api_post.php\", \
  4875.        \"api_option=paste&\"..\
  4876.        \"api_dev_key=\"..key..\"&\"..\
  4877.        \"api_paste_format=lua&\"..\
  4878.        \"api_paste_name=\"..textutils.urlEncode(sName)..\"&\"..\
  4879.        \"api_paste_code=\"..textutils.urlEncode(sText)\
  4880.    )\
  4881.        \
  4882.    if response then\
  4883.        print( \"Success.\" )\
  4884.        \
  4885.        local sResponse = response.readAll()\
  4886.        response.close()\
  4887.                \
  4888.        local sCode = string.match( sResponse, \"[^/]+$\" )\
  4889.        print( \"Uploaded as \"..sResponse )\
  4890.        print( \"Run \\\"pastebin get \"..sCode..\"\\\" to download anywhere\" )\
  4891. \
  4892.    else\
  4893.        print( \"Failed.\" )\
  4894.    end\
  4895.    \
  4896. elseif sCommand == \"get\" then\
  4897.    -- Download a file from pastebin.com\
  4898.    if #tArgs < 3 then\
  4899.        printUsage()\
  4900.        return\
  4901.    end\
  4902. \
  4903.    -- Determine file to download\
  4904.    local sCode = tArgs[2]\
  4905.    local sFile = tArgs[3]\
  4906.    local sPath = shell.resolve( sFile )\
  4907.    if fs.exists( sPath ) then\
  4908.        print( \"File already exists\" )\
  4909.        return\
  4910.    end\
  4911.    \
  4912.    -- GET the contents from pastebin\
  4913.    local res = get(sCode)\
  4914.    if res then        \
  4915.        local file = fs.open( sPath, \"w\" )\
  4916.        file.write( res )\
  4917.        file.close()\
  4918.        \
  4919.        print( \"Downloaded as \"..sFile )\
  4920.    end \
  4921. elseif sCommand == \"run\" then\
  4922.    local sCode = tArgs[2]\
  4923. \
  4924.    local res = get(sCode)\
  4925.    if res then\
  4926.        local func, err = loadstring(res)\
  4927.        if not func then\
  4928.            printError( err )\
  4929.            return\
  4930.        end\
  4931.        setfenv(func, getfenv())\
  4932.        local success, msg = pcall(func, unpack(tArgs, 3))\
  4933.        if not success then\
  4934.            printError( msg )\
  4935.        end\
  4936.    end\
  4937. else\
  4938.    printUsage()\
  4939.    return\
  4940. end",
  4941.   [ "/rom/programs/pocket/falling" ] = "--[[\
  4942. Falling - Based on Tetris by Alexey Pajitnov\
  4943. This version written by Gopher, at the request of Dan200, for\
  4944. ComputerCraft v1.6. No particular rights are reserved.\
  4945. --]]\
  4946. \
  4947. local function colorass(c,bw)\
  4948.  return term.isColor() and c or bw\
  4949. end\
  4950. \
  4951. local block_s1= {\
  4952.    {\
  4953.      { 1,0,0,0, },\
  4954.      { 1,1,0,0, },\
  4955.      { 0,1,0,0, },\
  4956.      { 0,0,0,0, },\
  4957.    },\
  4958.    {\
  4959.      { 0,0,0,0, },\
  4960.      { 0,1,1,0, },\
  4961.      { 1,1,0,0, },\
  4962.      { 0,0,0,0, },\
  4963.    },\
  4964.    ch=colorass(\"  \",\"{}\"),\
  4965.    fg=colorass(colors.blue,colors.black),\
  4966.    bg=colorass(colors.cyan,colors.white),\
  4967.  }\
  4968. local block_s2= {\
  4969.    {\
  4970.      { 0,1,0,0, },\
  4971.      { 1,1,0,0, },\
  4972.      { 1,0,0,0, },\
  4973.      { 0,0,0,0, },\
  4974.    },\
  4975.    {\
  4976.      { 0,0,0,0, },\
  4977.      { 1,1,0,0, },\
  4978.      { 0,1,1,0, },\
  4979.      { 0,0,0,0, },\
  4980.    },\
  4981.    ch=colorass(\"  \",\"{}\"),\
  4982.    fg=colorass(colors.green,colors.black),\
  4983.    bg=colorass(colors.lime,colors.white),\
  4984.  }\
  4985. local block_line = {\
  4986.    {\
  4987.      { 0,1,0,0, },\
  4988.      { 0,1,0,0, },\
  4989.      { 0,1,0,0, },\
  4990.      { 0,1,0,0, },\
  4991.    },\
  4992.    {\
  4993.      { 0,0,0,0, },\
  4994.      { 1,1,1,1, },\
  4995.      { 0,0,0,0, },\
  4996.      { 0,0,0,0, },\
  4997.    },\
  4998.    ch=colorass(\"  \",\"[]\"),\
  4999.    fg=colorass(colors.pink,colors.black),\
  5000.    bg=colorass(colors.red,colors.white),\
  5001.  }\
  5002. local block_square = {\
  5003.    {\
  5004.      { 1,1,0,0, },\
  5005.      { 1,1,0,0, },\
  5006.      { 0,0,0,0, },\
  5007.      { 0,0,0,0, },\
  5008.    },\
  5009.    ch=colorass(\"  \",\"[]\"),\
  5010.    fg=colorass(colors.lightBlue,colors.black),\
  5011.    bg=colorass(colors.blue,colors.white),\
  5012.  }\
  5013. local block_L1 = {\
  5014.    {\
  5015.      { 1,1,0,0, },\
  5016.      { 0,1,0,0, },\
  5017.      { 0,1,0,0, },\
  5018.      { 0,0,0,0, },\
  5019.    },\
  5020.    {\
  5021.      { 0,0,0,0, },\
  5022.      { 1,1,1,0, },\
  5023.      { 1,0,0,0, },\
  5024.      { 0,0,0,0, },\
  5025.    },\
  5026.    {\
  5027.      { 0,1,0,0, },\
  5028.      { 0,1,0,0, },\
  5029.      { 0,1,1,0, },\
  5030.      { 0,0,0,0, },\
  5031.    },\
  5032.    {\
  5033.      { 0,0,1,0, },\
  5034.      { 1,1,1,0, },\
  5035.      { 0,0,0,0, },\
  5036.      { 0,0,0,0, },\
  5037.    },\
  5038.    ch=colorass(\"  \",\"()\"),\
  5039.    fg=colorass(colors.orange,colors.black),\
  5040.    bg=colorass(colors.yellow,colors.white),\
  5041.  }\
  5042. local block_L2 = {\
  5043.    {\
  5044.      { 0,1,0,0, },\
  5045.      { 0,1,0,0, },\
  5046.      { 1,1,0,0, },\
  5047.      { 0,0,0,0, },\
  5048.    },\
  5049.    {\
  5050.      { 0,0,0,0, },\
  5051.      { 1,1,1,0, },\
  5052.      { 0,0,1,0, },\
  5053.      { 0,0,0,0, },\
  5054.    },\
  5055.    {\
  5056.      { 0,1,1,0, },\
  5057.      { 0,1,0,0, },\
  5058.      { 0,1,0,0, },\
  5059.      { 0,0,0,0, },\
  5060.    },\
  5061.    {\
  5062.      { 1,0,0,0, },\
  5063.      { 1,1,1,0, },\
  5064.      { 0,0,0,0, },\
  5065.      { 0,0,0,0, },\
  5066.    },\
  5067.    ch=colorass(\"  \",\"()\"),\
  5068.    fg=colorass(colors.brown,colors.black),\
  5069.    bg=colorass(colors.orange,colors.white),\
  5070.  }\
  5071. local block_T = {\
  5072.    {\
  5073.      { 0,1,0,0, },\
  5074.      { 1,1,0,0, },\
  5075.      { 0,1,0,0, },\
  5076.      { 0,0,0,0, },\
  5077.    },\
  5078.    {\
  5079.      { 0,0,0,0, },\
  5080.      { 1,1,1,0, },\
  5081.      { 0,1,0,0, },\
  5082.      { 0,0,0,0, },\
  5083.    },\
  5084.    {\
  5085.      { 0,1,0,0, },\
  5086.      { 0,1,1,0, },\
  5087.      { 0,1,0,0, },\
  5088.      { 0,0,0,0, },\
  5089.    },\
  5090.    {\
  5091.      { 0,1,0,0, },\
  5092.      { 1,1,1,0, },\
  5093.      { 0,0,0,0, },\
  5094.      { 0,0,0,0, },\
  5095.    },\
  5096.    ch=colorass(\"  \",\"<>\"),\
  5097.    fg=colorass(colors.cyan,colors.black),\
  5098.    bg=colorass(colors.purple,colors.white),\
  5099.  }\
  5100. \
  5101. local blocks={ block_line, block_square, block_s1, block_s2, block_L1, block_L2, block_T}\
  5102. \
  5103. local points={4,10,30,120}\
  5104. \
  5105. local function lpad(text,amt)\
  5106.  text=tostring(text)\
  5107.  return string.rep(\" \",amt-#text)..text\
  5108. end\
  5109. \
  5110. local width,height=term.getSize()\
  5111. \
  5112. if height<19 or width<26 then\
  5113.  print(\"Your screen is too small to play :(\")\
  5114.  return\
  5115. end\
  5116. \
  5117. \
  5118. local speedsByLevel={\
  5119.  1.2,\
  5120.  1.0,\
  5121.   .8,\
  5122.   .65,\
  5123.   .5,\
  5124.   .4,\
  5125.   .3,\
  5126.   .25,\
  5127.   .2,\
  5128.   .15,\
  5129.   .1,\
  5130.   .05,}\
  5131. \
  5132. local level=1\
  5133. \
  5134. local function playGame()\
  5135.  local score=0\
  5136.  local lines=0\
  5137.  local initialLevel=level\
  5138.  local next=blocks[math.random(1,#blocks)]\
  5139. \
  5140.  local pit={}\
  5141. \
  5142. \
  5143.  local heightAdjust=0\
  5144. \
  5145.  if height<=19 then\
  5146.    heightAdjust=1\
  5147.  end\
  5148. \
  5149. \
  5150. \
  5151.  local function drawScreen()\
  5152.    term.setTextColor(colors.white)\
  5153.    term.setBackgroundColor(colors.black)\
  5154.    term.clear()\
  5155. \
  5156.    term.setTextColor(colors.black)\
  5157.    term.setBackgroundColor(colorass(colors.lightGray, colors.white))\
  5158.    term.setCursorPos(22,2)\
  5159.    term.write(\"Score\") --score\
  5160.    term.setCursorPos(22,5)\
  5161.    term.write(\"Level\")  --level\
  5162.    term.setCursorPos(22,8)\
  5163.    term.write(\"Lines\")  --lines\
  5164.    term.setCursorPos(22,12)\
  5165.    term.write(\"Next\") --next\
  5166. \
  5167.    term.setCursorPos(21,1)\
  5168.    term.write(\"      \")\
  5169.    term.setCursorPos(21,2)\
  5170.    term.write(\" \") --score\
  5171.    term.setCursorPos(21,3)\
  5172.    term.write(\" \")\
  5173.    term.setCursorPos(21,4)\
  5174.    term.write(\"      \")\
  5175.    term.setCursorPos(21,5)\
  5176.    term.write(\" \")  --level\
  5177.    term.setCursorPos(21,6)\
  5178.    term.write(\" \")\
  5179.    term.setCursorPos(21,7)\
  5180.    term.write(\"      \")\
  5181.    term.setCursorPos(21,8)\
  5182.    term.write(\" \")  --lines\
  5183.    term.setCursorPos(21,9)\
  5184.    term.write(\" \")\
  5185.    term.setCursorPos(21,10)\
  5186.    term.write(\"      \")\
  5187.    term.setCursorPos(21,11)\
  5188.    term.write(\"      \")\
  5189.    term.setCursorPos(21,12)\
  5190.    term.write(\" \") --next\
  5191.    term.setCursorPos(26,12)\
  5192.    term.write(\" \") --next\
  5193.    term.setCursorPos(21,13)\
  5194.    term.write(\"      \")\
  5195.    term.setCursorPos(21,14)\
  5196.    term.write(\" \")\
  5197.    term.setCursorPos(21,15)\
  5198.    term.write(\" \")\
  5199.    term.setCursorPos(21,16)\
  5200.    term.write(\" \")\
  5201.    term.setCursorPos(21,17)\
  5202.    term.write(\" \")\
  5203.    term.setCursorPos(21,18)\
  5204.    term.write(\" \")\
  5205.    term.setCursorPos(21,19)\
  5206.    term.write(\"      \")\
  5207.    term.setCursorPos(21,20)\
  5208.    term.write(\"      \")\
  5209.  end\
  5210. \
  5211.  local function updateNumbers()\
  5212.    term.setTextColor(colors.white)\
  5213.    term.setBackgroundColor(colors.black)\
  5214. \
  5215.    term.setCursorPos(22,3)\
  5216.    term.write(lpad(score,5)) --score\
  5217.    term.setCursorPos(22,6)\
  5218.    term.write(lpad(level,5))  --level\
  5219.    term.setCursorPos(22,9)\
  5220.    term.write(lpad(lines,5))  --lines\
  5221.  end\
  5222. \
  5223.  local function drawBlockAt(block,xp,yp,rot)\
  5224.    term.setTextColor(block.fg)\
  5225.    term.setBackgroundColor(block.bg)\
  5226.    for y=1,4 do\
  5227.      for x=1,4 do\
  5228.        if block[rot][y][x]==1 then\
  5229.          term.setCursorPos((xp+x)*2-3,yp+y-1-heightAdjust)\
  5230.          term.write(block.ch)\
  5231.        end\
  5232.      end\
  5233.    end\
  5234.  end\
  5235. \
  5236.  local function eraseBlockAt(block,xp,yp,rot)\
  5237.    term.setTextColor(colors.white)\
  5238.    term.setBackgroundColor(colors.black)\
  5239.    for y=1,4 do\
  5240.      for x=1,4 do\
  5241.        if block[rot][y][x]==1 then\
  5242.          term.setCursorPos((xp+x)*2-3,yp+y-1-heightAdjust)\
  5243.          term.write(\"  \")\
  5244.        end\
  5245.      end\
  5246.    end\
  5247.  end\
  5248. \
  5249.  local function testBlockAt(block,xp,yp,rot)\
  5250.    for y=1,4 do\
  5251.      local ty=yp+y-1\
  5252.      for x=1,4 do\
  5253.        local tx=xp+x-1\
  5254.        if block[rot][y][x]==1 then\
  5255.          if tx>10 or tx<1 or ty>20 or pit[ty][tx]~=0 then\
  5256.            return true\
  5257.          end\
  5258.        end\
  5259.      end\
  5260.    end\
  5261.  end\
  5262. \
  5263.  local function pitBlock(block,xp,yp,rot)\
  5264.    for y=1,4 do\
  5265.      for x=1,4 do\
  5266.        if block[rot][y][x]==1 then\
  5267.          pit[yp+y-1][xp+x-1]=block\
  5268.        end\
  5269.      end\
  5270.    end\
  5271.  end\
  5272. \
  5273. \
  5274.  local function clearPit()\
  5275.    for row=1,20 do\
  5276.      pit[row]={}\
  5277.      for col=1,10 do\
  5278.        pit[row][col]=0\
  5279.      end\
  5280.    end\
  5281.  end\
  5282. \
  5283. \
  5284. \
  5285.  drawScreen()\
  5286.  updateNumbers()\
  5287. \
  5288.  --declare & init the pit\
  5289.  clearPit()\
  5290. \
  5291. \
  5292. \
  5293.  local halt=false\
  5294.  local dropSpeed=speedsByLevel[math.min(level,12)]\
  5295. \
  5296. \
  5297.  local curBlock=next\
  5298.  next=blocks[math.random(1,7)]\
  5299. \
  5300.  local curX, curY, curRot=4, 1, 1\
  5301.  local dropTimer=os.startTimer(dropSpeed)\
  5302. \
  5303.  drawBlockAt(next,11.5,15+heightAdjust,1)\
  5304.  drawBlockAt(curBlock,curX,curY,curRot)\
  5305. \
  5306.  local function redrawPit()\
  5307.    for r=1+heightAdjust,20 do\
  5308.      term.setCursorPos(1,r-heightAdjust)\
  5309.      for c=1,10 do\
  5310.        if pit[r][c]==0 then\
  5311.          term.setTextColor(colors.black)\
  5312.          term.setBackgroundColor(colors.black)\
  5313.          term.write(\"  \")\
  5314.        else\
  5315.          term.setTextColor(pit[r][c].fg)\
  5316.          term.setBackgroundColor(pit[r][c].bg)\
  5317.          term.write(pit[r][c].ch)\
  5318.        end\
  5319.      end\
  5320.    end\
  5321.  end\
  5322. \
  5323.  local function hidePit()\
  5324.    for r=1+heightAdjust,20 do\
  5325.      term.setCursorPos(1,r-heightAdjust)\
  5326.      term.setTextColor(colors.black)\
  5327.      term.setBackgroundColor(colors.black)\
  5328.      term.write(\"                    \")\
  5329.    end\
  5330.  end\
  5331. \
  5332.  local function msgBox(message)\
  5333.    local x=math.floor((17-#message)/2)\
  5334.    term.setBackgroundColor(colorass(colors.lightGray,colors.white))\
  5335.    term.setTextColor(colors.black)\
  5336.    term.setCursorPos(x,9)\
  5337.    term.write(\"+\"..string.rep(\"-\",#message+2)..\"+\")\
  5338.    term.setCursorPos(x,10)\
  5339.    term.write(\"|\")\
  5340.    term.setCursorPos(x+#message+3,10)\
  5341.    term.write(\"|\")\
  5342.    term.setCursorPos(x,11)\
  5343.    term.write(\"+\"..string.rep(\"-\",#message+2)..\"+\")\
  5344.    term.setTextColor(colors.white)\
  5345.    term.setBackgroundColor(colors.black)\
  5346.    term.setCursorPos(x+1,10)\
  5347.    term.write(\" \"..message..\" \")\
  5348.  end\
  5349. \
  5350.  local function clearRows()\
  5351.    local rows={}\
  5352.    for r=1,20 do\
  5353.      local count=0\
  5354.      for c=1,10 do\
  5355.        if pit[r][c]~=0 then\
  5356.          count=count+1\
  5357.        else\
  5358.          break\
  5359.        end\
  5360.      end\
  5361.      if count==10 then\
  5362.        rows[#rows+1]=r\
  5363.      end\
  5364.    end\
  5365. \
  5366.    if #rows>0 then\
  5367.      for i=1,4 do\
  5368.        sleep(.1)\
  5369.        for r=1,#rows do\
  5370.          r=rows[r]\
  5371.          term.setCursorPos(1,r-heightAdjust)\
  5372.          for c=1,10 do\
  5373.            term.setTextColor(pit[r][c].bg)\
  5374.            term.setBackgroundColor(pit[r][c].fg)\
  5375.            term.write(pit[r][c].ch)\
  5376.          end\
  5377.        end\
  5378.        sleep(.1)\
  5379.        for r=1,#rows do\
  5380.          r=rows[r]\
  5381.          term.setCursorPos(1,r-heightAdjust)\
  5382.          for c=1,10 do\
  5383.            term.setTextColor(pit[r][c].fg)\
  5384.            term.setBackgroundColor(pit[r][c].bg)\
  5385.            term.write(pit[r][c].ch)\
  5386.          end\
  5387.        end\
  5388.      end\
  5389.      --now remove the rows and drop everythign else\
  5390.      term.setBackgroundColor(colors.black)\
  5391.      for r=1,#rows do\
  5392.        r=rows[r]\
  5393.        term.setCursorPos(1,r-heightAdjust)\
  5394.        term.write(\"                    \")\
  5395.      end\
  5396.      sleep(.25)\
  5397.      for r=1,#rows do\
  5398.        table.remove(pit,rows[r])\
  5399.        table.insert(pit,1,{0,0,0,0,0,0,0,0,0,0})\
  5400.      end\
  5401.      redrawPit()\
  5402.      lines=lines+#rows\
  5403.      score=score+points[#rows]*math.min(level,20)\
  5404.      level=math.floor(lines/10)+initialLevel\
  5405.      dropSpeed=speedsByLevel[math.min(level,12)]\
  5406.      updateNumbers()\
  5407.    end\
  5408.    sleep(.25)\
  5409.  end\
  5410. \
  5411.  local function blockFall()\
  5412.    local result = false\
  5413.    if testBlockAt(curBlock,curX,curY+1,curRot) then\
  5414.      pitBlock(curBlock,curX,curY,curRot)\
  5415.      --detect rows that clear\
  5416.      clearRows(rows)\
  5417. \
  5418.      curBlock=next\
  5419.      curX=4\
  5420.      curY=1\
  5421.      curRot=1\
  5422.      if testBlockAt(curBlock,curX,curY,curRot) then\
  5423.        halt=true\
  5424.      end\
  5425.      drawBlockAt(curBlock,curX,curY,curRot)\
  5426.      eraseBlockAt(next,11.5,15+heightAdjust,1)\
  5427.      next=blocks[math.random(1,7)]\
  5428.      drawBlockAt(next,11.5,15+heightAdjust,1)\
  5429.      return true\
  5430.    else\
  5431.      eraseBlockAt(curBlock,curX,curY,curRot)\
  5432.      curY=curY+1\
  5433.      drawBlockAt(curBlock,curX,curY,curRot)\
  5434.      return false\
  5435.    end\
  5436.  end\
  5437. \
  5438. \
  5439.  while not halt do\
  5440.    local e={os.pullEvent()}\
  5441.    if e[1]==\"timer\" then\
  5442.      if e[2]==dropTimer then\
  5443.        blockFall()\
  5444.        dropTimer=os.startTimer(dropSpeed)\
  5445.      end\
  5446.    elseif e[1]==\"key\" then\
  5447.      local key=e[2]\
  5448.      local dx,dy,dr=0,0,0\
  5449.      if key==keys.left or key==keys.a then\
  5450.        dx=-1\
  5451.      elseif key==keys.right or key==keys.d then\
  5452.        dx=1\
  5453.      elseif key==keys.up or key==keys.w then\
  5454.        dr=1\
  5455.      elseif key==keys.down or key==keys.s then\
  5456.        while not blockFall() do end\
  5457.        dropTimer=os.startTimer(dropSpeed)\
  5458.      elseif key==keys.space then\
  5459.        hidePit()\
  5460.        msgBox(\"Paused\")\
  5461.        while ({os.pullEvent(\"key\")})[2]~=keys.space do end\
  5462.        redrawPit()\
  5463.        drawBlockAt(curBlock,curX,curY,curRot)\
  5464.        dropTimer=os.startTimer(dropSpeed)\
  5465.      end\
  5466.      if dx+dr~=0 then\
  5467.        if not testBlockAt(curBlock,curX+dx,curY+dy,(dr>0 and curRot%#curBlock+dr or curRot)) then\
  5468.          eraseBlockAt(curBlock,curX,curY,curRot)\
  5469.          curX=curX+dx\
  5470.          curY=curY+dy\
  5471.          curRot=dr==0 and curRot or (curRot%#curBlock+dr)\
  5472.          drawBlockAt(curBlock,curX,curY,curRot)\
  5473.        end\
  5474.      end\
  5475.    elseif e[1]==\"term_resize\" then\
  5476.      local w,h=term.getSize()\
  5477.      if h==20 then\
  5478.        heightAdjust=0\
  5479.      else\
  5480.        heightAdjust=1\
  5481.      end\
  5482.      redrawPit()\
  5483.      drawBlockAt(curBlock,curX,curY,curRot)\
  5484.    end\
  5485.  end\
  5486. \
  5487.  msgBox(\"Game Over!\")\
  5488.  while true do\
  5489.    local _,k=os.pullEvent(\"key\")\
  5490.    if k==keys.space or k==keys.enter then\
  5491.      break\
  5492.    end\
  5493.  end\
  5494. \
  5495.  level = math.min(level,9)\
  5496. end\
  5497. \
  5498. \
  5499. local selected=1\
  5500. local playersDetected=false\
  5501. \
  5502. local function drawMenu()\
  5503.  term.setBackgroundColor(colors.black)\
  5504.  term.setTextColor(colorass(colors.red,colors.white))\
  5505.  term.clear()\
  5506. \
  5507.  local cx,cy=math.floor(width/2),math.floor(height/2)\
  5508. \
  5509.  term.setCursorPos(cx-6,cy-2)\
  5510.  term.write(\"F A L L I N G\")\
  5511. \
  5512.  if playersDetected then\
  5513.    if selected==0 then\
  5514.      term.setTextColor(colorass(colors.blue,colors.black))\
  5515.      term.setBackgroundColor(colorass(colors.gray,colors.white))\
  5516.    else\
  5517.      term.setTextColor(colorass(colors.lightBlue,colors.white))\
  5518.      term.setBackgroundColor(colors.black)\
  5519.    end\
  5520.    term.setCursorPos(cx-12,cy)\
  5521.    term.write(\" Play head-to-head game! \")\
  5522.  end\
  5523. \
  5524.  term.setCursorPos(cx-10,cy+1)\
  5525.  if selected==1 then\
  5526.    term.setTextColor(colorass(colors.blue,colors.black))\
  5527.    term.setBackgroundColor(colorass(colors.lightGray,colors.white))\
  5528.  else\
  5529.    term.setTextColor(colorass(colors.lightBlue,colors.white))\
  5530.    term.setBackgroundColor(colors.black)\
  5531.  end\
  5532.  term.write(\" Play from level: <\" .. level .. \"> \")\
  5533. \
  5534.  term.setCursorPos(cx-3,cy+3)\
  5535.  if selected==2 then\
  5536.    term.setTextColor(colorass(colors.blue,colors.black))\
  5537.    term.setBackgroundColor(colorass(colors.lightGray,colors.white))\
  5538.  else\
  5539.    term.setTextColor(colorass(colors.lightBlue,colors.white))\
  5540.    term.setBackgroundColor(colors.black)\
  5541.  end\
  5542.  term.write(\" Quit \")\
  5543. end\
  5544. \
  5545. \
  5546. local function runMenu()\
  5547.  drawMenu()\
  5548. \
  5549.  while true do\
  5550.    local event={os.pullEvent()}\
  5551.    if event[1]==\"key\" then\
  5552.      local key=event[2]\
  5553.      if key==keys.right or key==keys.d and selected==1 then\
  5554.        level=math.min(level+1,9)\
  5555.        drawMenu()\
  5556.      elseif key==keys.left or key==keys.a and selected==1 then\
  5557.        level=math.max(level-1,1)\
  5558.        drawMenu()\
  5559.      elseif key>=keys.one and key<=keys.nine and selected==1 then\
  5560.        level=(key-keys.one) + 1\
  5561.        drawMenu()\
  5562.      elseif key==keys.up or key==keys.w then\
  5563.        selected=selected-1\
  5564.        if selected==0 then\
  5565.          selected=2\
  5566.        end\
  5567.        drawMenu()\
  5568.      elseif key==keys.down or key==keys.s then\
  5569.        selected=selected%2+1\
  5570.        drawMenu()\
  5571.      elseif key==keys.enter or key==keys.space then\
  5572.        break --begin play!\
  5573.      end\
  5574.    end\
  5575.  end\
  5576. end\
  5577. \
  5578. while true do\
  5579.  runMenu()\
  5580.  if selected==2 then\
  5581.    break\
  5582.  end\
  5583. \
  5584.  playGame()\
  5585. end\
  5586. \
  5587. \
  5588. term.setTextColor(colors.white)\
  5589. term.setBackgroundColor(colors.black)\
  5590. term.clear()\
  5591. term.setCursorPos(1,1)",
  5592.   [ "/Shop/States/Account.lua" ] = "local StateLib = FDK.require('lib.state')\
  5593. local State = StateLib.names.Init\
  5594. local Main = StateLib.names.Main\
  5595. local Search = StateLib.names.Search\
  5596. local Account = StateLib.names.Account\
  5597. local Items = StateLib.names.Items\
  5598. \
  5599. local Field = FDK.require('lib.UI.elements.Field')\
  5600. local Text = FDK.require('lib.UI.elements.Text')\
  5601. local Button = FDK.require('lib.UI.elements.Button')\
  5602. \
  5603. -- Main Field\
  5604. Account.frame:newChild(Field(1, 1, Account.frame.width, Account.frame.height, colors.white))\
  5605. -- Header Field\
  5606. Account.frame:newChild(Field(1, 1, Account.frame.width, 3, colors.lightGray))\
  5607. \
  5608. local back = Account.frame:newChild( Button( 1, 1, 8, 3, \"< back\" ) )\
  5609. back.bc = colors.lightGray\
  5610. back.tc = colors.white\
  5611. \
  5612. function back:onClick()\
  5613.  Main:show()\
  5614. end\
  5615. \
  5616. local Header = Account.frame:newChild(Text(0, 0, 13, 1, '&b8&t0Account info'))\
  5617. Header.y = 2\
  5618. Header.width = #Header.text - #'&b7&t8'\
  5619. Header:alignX('centre')\
  5620. \
  5621. local Data = {\
  5622.  User = nil,\
  5623.  Balance = 100.00,\
  5624.  Position = {X = 1, Y = 50, Z = 100},\
  5625.  SkyblockPosition = {X = 1, Y = 50, Z = 100},\
  5626. }\
  5627. \
  5628. Account.process:spawnThread(function()\
  5629.  while true do\
  5630.    local Event, Side, SenderID, ReceiverID, Msg, Distance = coroutine.yield()\
  5631.    if Event == 'modem_message' then\
  5632.      if SenderID == 2773 then\
  5633.        --local File = fs.open('log','a')\
  5634.        --File.writeLine(Decompile(textutils.unserialize(Msg)))\
  5635.        --File.close()\
  5636.        --Data = textutils.unserialize(Decompile(textutils.unserialize(Msg)))\
  5637.      end\
  5638.    end\
  5639.  end\
  5640. end)\
  5641. Account.process:spawnThread(function()\
  5642.  while true do\
  5643.    local Texts = {\
  5644.      Username = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Username:')),\
  5645.      _Username = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&td' .. tostring(Data.User)..'                ')),\
  5646.      Balance = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Balance:')),\
  5647.      _Balance = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t1' .. tostring(Data.Balance)..'                ')),\
  5648.      Position = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Position')),\
  5649.      PositionX = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7X:&b0&tb' .. tostring(Data.Position.X)..'                ')),\
  5650.      PositionY = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Y:&b0&tb' .. tostring(Data.Position.Y)..'                ')),\
  5651.      PositionZ = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Z:&b0&tb' .. tostring(Data.Position.Z)..'                ')),\
  5652.      SkyblockPosition = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Skyblock Location')),\
  5653.      SkyblockPositionX = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7X:&b0&tb' .. tostring(Data.SkyblockPosition.X)..'   ')),\
  5654.      SkyblockPositionY = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Y:&b0&tb' .. tostring(Data.SkyblockPosition.Y)..'   ')),\
  5655.      SkyblockPositionZ = Account.frame:newChild(Text(1, 1, 0, 1, '&b0&t7Z:&b0&tb' .. tostring(Data.SkyblockPosition.Z)..'   ')),\
  5656.    }\
  5657.    function SetData(Name, Y, X, _D) Texts[Name].width = #Texts[Name].text - (_D == true and 12 or 6) Texts[Name].y, Texts[Name].x = Y, X end\
  5658.    SetData('Username', 5, 2)\
  5659.    SetData('_Username', 5, #Texts.Username.text - 3)\
  5660.    SetData('Balance', 7, 2)\
  5661.    SetData('_Balance', 7, #Texts.Balance.text - 3)\
  5662.    SetData('Position', 9, 2)\
  5663.    SetData('PositionX', 10, 6, true)\
  5664.    SetData('PositionY', 11, 6, true)\
  5665.    SetData('PositionZ', 12, 6, true)\
  5666.    SetData('SkyblockPosition', 9, 33)\
  5667.    SetData('SkyblockPositionX', 10, 39, true)\
  5668.    SetData('SkyblockPositionY', 11, 39, true)\
  5669.    SetData('SkyblockPositionZ', 12, 39, true)\
  5670.    sleep(0.5)\
  5671.  end\
  5672. end)\
  5673. ",
  5674.   [ "/rom/apis/io" ] = "-- Definition for the IO API\
  5675. \
  5676. local g_defaultInput = {\
  5677.     bFileHandle = true,\
  5678.     bClosed = false,\
  5679.     close = function( self )\
  5680.     end,\
  5681.     read = function( self, _sFormat )\
  5682.         if _sFormat and _sFormat ~= \"*l\" then\
  5683.             error( \"Unsupported format\" )\
  5684.         end\
  5685.         return _G.read()\
  5686.     end,\
  5687.     lines = function( self )\
  5688.         return function()\
  5689.             return _G.read()\
  5690.         end\
  5691.     end,\
  5692. }\
  5693. \
  5694. local g_defaultOutput = {\
  5695.     bFileHandle = true,\
  5696.     bClosed = false,\
  5697.     close = function( self )\
  5698.     end,\
  5699.     write = function( self, _sText )\
  5700.         _G.write( _sText )\
  5701.     end,\
  5702.     flush = function( self )\
  5703.     end,\
  5704. }\
  5705. \
  5706. local g_currentInput = g_defaultInput\
  5707. local g_currentOutput = g_defaultOutput\
  5708. \
  5709. function close( _file )\
  5710.     (_file or g_currentOutput):close()\
  5711. end\
  5712. \
  5713. function flush()\
  5714.     g_currentOutput:flush()\
  5715. end\
  5716. \
  5717. function input( _arg )\
  5718.     if _G.type( _arg ) == \"string\" then\
  5719.         g_currentInput = open( _arg, \"r\" )\
  5720.     elseif _G.type( _arg ) == \"table\" then\
  5721.         g_currentInput = _arg\
  5722.     elseif _G.type( _arg ) == \"nil\" then\
  5723.         return g_currentInput\
  5724.     else\
  5725.         error( \"Expected file name or file handle\" )\
  5726.     end\
  5727. end\
  5728. \
  5729. function lines( _sFileName )\
  5730.     if _sFileName then\
  5731.         return open( _sFileName, \"r\" ):lines()\
  5732.     else\
  5733.         return g_currentInput:lines()\
  5734.     end\
  5735. end\
  5736. \
  5737. function open( _sPath, _sMode )\
  5738.     local sMode = _sMode or \"r\"\
  5739.     local file = fs.open( _sPath, sMode )\
  5740.     if not file then\
  5741.         return nil\
  5742.     end\
  5743.     \
  5744.     if sMode == \"r\"then\
  5745.         return {\
  5746.             bFileHandle = true,\
  5747.             bClosed = false,                \
  5748.             close = function( self )\
  5749.                 file.close()\
  5750.                 self.bClosed = true\
  5751.             end,\
  5752.             read = function( self, _sFormat )\
  5753.                 local sFormat = _sFormat or \"*l\"\
  5754.                 if sFormat == \"*l\" then\
  5755.                     return file.readLine()\
  5756.                 elseif sFormat == \"*a\" then\
  5757.                     return file.readAll()\
  5758.                 else\
  5759.                     error( \"Unsupported format\" )\
  5760.                 end\
  5761.                 return nil\
  5762.             end,\
  5763.             lines = function( self )\
  5764.                 return function()\
  5765.                     local sLine = file.readLine()\
  5766.                     if sLine == nil then\
  5767.                         file.close()\
  5768.                         self.bClosed = true\
  5769.                     end\
  5770.                     return sLine\
  5771.                 end\
  5772.             end,\
  5773.         }\
  5774.     elseif sMode == \"w\" or sMode == \"a\" then\
  5775.         return {\
  5776.             bFileHandle = true,\
  5777.             bClosed = false,                \
  5778.             close = function( self )\
  5779.                 file.close()\
  5780.                 self.bClosed = true\
  5781.             end,\
  5782.             write = function( self, _sText )\
  5783.                 file.write( _sText )\
  5784.             end,\
  5785.             flush = function( self )\
  5786.                 file.flush()\
  5787.             end,\
  5788.         }\
  5789.     \
  5790.     elseif sMode == \"rb\" then\
  5791.         return {\
  5792.             bFileHandle = true,\
  5793.             bClosed = false,                \
  5794.             close = function( self )\
  5795.                 file.close()\
  5796.                 self.bClosed = true\
  5797.             end,\
  5798.             read = function( self )\
  5799.                 return file.read()\
  5800.             end,\
  5801.         }\
  5802.         \
  5803.     elseif sMode == \"wb\" or sMode == \"ab\" then\
  5804.         return {\
  5805.             bFileHandle = true,\
  5806.             bClosed = false,                \
  5807.             close = function( self )\
  5808.                 file.close()\
  5809.                 self.bClosed = true\
  5810.             end,\
  5811.             write = function( self, _number )\
  5812.                 file.write( _number )\
  5813.             end,\
  5814.             flush = function( self )\
  5815.                 file.flush()\
  5816.             end,\
  5817.         }\
  5818.     \
  5819.     else\
  5820.         file.close()\
  5821.         error( \"Unsupported mode\" )\
  5822.         \
  5823.     end\
  5824. end\
  5825. \
  5826. function output( _arg )\
  5827.     if _G.type( _arg ) == \"string\" then\
  5828.         g_currentOutput = open( _arg, \"w\" )\
  5829.     elseif _G.type( _arg ) == \"table\" then\
  5830.         g_currentOutput = _arg\
  5831.     elseif _G.type( _arg ) == \"nil\" then\
  5832.         return g_currentOutput\
  5833.     else\
  5834.         error( \"Expected file name or file handle\" )\
  5835.     end\
  5836. end\
  5837. \
  5838. function read( ... )\
  5839.     return input():read( ... )\
  5840. end\
  5841. \
  5842. function type( _handle )\
  5843.     if _G.type( _handle ) == \"table\" and _handle.bFileHandle == true then\
  5844.         if _handle.bClosed then\
  5845.             return \"closed file\"\
  5846.         else\
  5847.             return \"file\"\
  5848.         end\
  5849.     end\
  5850.     return nil\
  5851. end\
  5852. \
  5853. function write( ... )\
  5854.     return output():write( ... )\
  5855. end",
  5856.   [ "/rom/programs/type" ] = "\
  5857. local tArgs = { ... }\
  5858. if #tArgs < 1 then\
  5859.     print( \"Usage: type <path>\" )\
  5860.     return\
  5861. end\
  5862. \
  5863. local sPath = shell.resolve( tArgs[1] )\
  5864. if fs.exists( sPath ) then\
  5865.     if fs.isDir( sPath ) then\
  5866.         print( \"directory\" )\
  5867.     else\
  5868.         print( \"file\" )\
  5869.     end\
  5870. else\
  5871.     print( \"No such path\" )\
  5872. end\
  5873. ",
  5874.   [ "/Flare/version/1.2/lib/class.lua" ] = "\
  5875. local class = {}\
  5876. \
  5877. function class:new( name )\
  5878. \
  5879.     local c = {}\
  5880.     c.name = name\
  5881. \
  5882.     local mt = {}\
  5883. \
  5884.     function c:new( ... )\
  5885.         local ob = {}\
  5886.         ob.class = self\
  5887. \
  5888.         setmetatable( ob, { __index = self, __tostring = self.tostring, __type = self.name } )\
  5889. \
  5890.         if ob[name] then\
  5891.             ob[name]( ob, ... )\
  5892.         end\
  5893. \
  5894.         return ob\
  5895.     end\
  5896. \
  5897.     function c:extend( e )\
  5898.         mt.__index = e\
  5899.         self.extends = e\
  5900.     end\
  5901. \
  5902.     function c:tostring()\
  5903.         return self.class and self.class.name or self.name\
  5904.     end\
  5905. \
  5906.     function c:type()\
  5907.         return self.class and self.class.name or self.name\
  5908.     end\
  5909. \
  5910.     function c:typeOf( class )\
  5911.         if self.class then\
  5912.             self = self.class\
  5913.         end\
  5914.         while self ~= class do\
  5915.             self = self.extends\
  5916.             if not self then\
  5917.                 return false\
  5918.             end\
  5919.         end\
  5920.         return true\
  5921.     end\
  5922. \
  5923.     function c:can( method )\
  5924.         return type( self[method] ) == \"function\"\
  5925.     end\
  5926. \
  5927.     mt.__type = name\
  5928.     mt.__call = c.new\
  5929.     mt.__tostring = c.tostring\
  5930.     setmetatable( c, mt )\
  5931. \
  5932.     return c\
  5933. \
  5934. end\
  5935. \
  5936. setmetatable( class, { __call = class.new } )\
  5937. \
  5938. return class",
  5939.   [ "/rom/programs/exit" ] = "shell.exit()",
  5940.   [ "/rom/help/bg" ] = "bg is a program for Advanced Computers which opens a new tab in the background.\
  5941. \
  5942. ex:\
  5943. \"bg\" will open a background tab running the shell\
  5944. \"bg worm\" will open a background tab running the \"worm\" program",
  5945.   [ "/rom/help/keys" ] = "The keys API contains constants for all the key codes that can be returned by the \"key\" event:\
  5946. \
  5947. Example usage:\
  5948. local sEvent, nKey = os.pullEvent()\
  5949. if sEvent == \"key\" and nKey == keys.enter then\
  5950.   -- Do something  \
  5951. end\
  5952. \
  5953. See http://www.minecraftwiki.net/wiki/Key_codes, or the source code, for a complete reference.",
  5954.   [ "/rom/help/workbench" ] = "Workbenches are peripheral devices found on Crafty Turtles running CraftOS. Type \"help peripheral\" to learn about using the Peripheral API to connect with peripherals. When a workbench is attached to a turtle, peripheral.getType() will return \"workbench\".\
  5955. \
  5956. Methods exposed by Workbenches:\
  5957. craft( channel )",
  5958.   [ "/rom/help/programming" ] = "To learn the lua programming language, visit http://lua-users.org/wiki/TutorialDirectory.\
  5959. \
  5960. To experiment with lua in CraftOS, run the \"lua\" program and start typing code.\
  5961. To create programs, use \"edit\" to create files, then type their names in the shell to run them. If you name a program \"startup\" and place it in the root or on a disk drive, it will run automatically when the computer starts.\
  5962. \
  5963. To terminate a program stuck in a loop, hold Ctrl+T for 1 second.\
  5964. To quickly shutdown a computer, hold Ctrl+S for 1 second.\
  5965. To quickly reboot a computer, hold Ctrl+R for 1 second.\
  5966. \
  5967. To learn about the programming APIs availiable, type \"apis\" or \"help apis\".\
  5968. If you get stuck, visit the forums at http://www.computercraft.info/ for advice and tutorials.",
  5969.   [ "/rom/help/falling" ] = "\"From Russia with Fun\" comes a fun, new, suspiciously-familiar falling block game for CraftOS. Only on Pocket Computers!",
  5970.   [ "/rom/apis/disk" ] = "\
  5971. local function isDrive( name )\
  5972.     return peripheral.getType( name ) == \"drive\"\
  5973. end\
  5974. \
  5975. function isPresent( name )\
  5976.     if isDrive( name ) then\
  5977.         return peripheral.call( name, \"isDiskPresent\" )\
  5978.     end\
  5979.     return false\
  5980. end\
  5981. \
  5982. function getLabel( name )\
  5983.     if isDrive( name ) then\
  5984.         return peripheral.call( name, \"getDiskLabel\" )\
  5985.     end\
  5986.     return nil\
  5987. end\
  5988. \
  5989. function setLabel( name, label )\
  5990.     if isDrive( name ) then\
  5991.         peripheral.call( name, \"setDiskLabel\", label )\
  5992.     end\
  5993. end\
  5994. \
  5995. function hasData( name )\
  5996.     if isDrive( name ) then\
  5997.         return peripheral.call( name, \"hasData\" )\
  5998.     end\
  5999.     return false\
  6000. end\
  6001. \
  6002. function getMountPath( name )\
  6003.     if isDrive( name ) then\
  6004.         return peripheral.call( name, \"getMountPath\" )\
  6005.     end\
  6006.     return nil\
  6007. end\
  6008. \
  6009. function hasAudio( name )\
  6010.     if isDrive( name ) then\
  6011.         return peripheral.call( name, \"hasAudio\" )\
  6012.     end\
  6013.     return false\
  6014. end\
  6015. \
  6016. function getAudioTitle( name )\
  6017.     if isDrive( name ) then\
  6018.         return peripheral.call( name, \"getAudioTitle\" )\
  6019.     end\
  6020.     return nil\
  6021. end\
  6022. \
  6023. function playAudio( name )\
  6024.     if isDrive( name ) then\
  6025.         peripheral.call( name, \"playAudio\" )\
  6026.     end\
  6027. end\
  6028. \
  6029. function stopAudio( name )\
  6030.     if not name then\
  6031.         for n,sName in ipairs( peripheral.getNames() ) do\
  6032.             stopAudio( sName )\
  6033.         end\
  6034.     else\
  6035.         if isDrive( name ) then\
  6036.             peripheral.call( name, \"stopAudio\" )\
  6037.         end\
  6038.     end\
  6039. end\
  6040. \
  6041. function eject( name )\
  6042.     if isDrive( name ) then\
  6043.         peripheral.call( name, \"ejectDisk\" )\
  6044.     end\
  6045. end\
  6046. \
  6047. function getID( name )\
  6048.     if isDrive( name ) then\
  6049.         return peripheral.call( name, \"getDiskID\" )\
  6050.     end\
  6051.     return nil\
  6052. end\
  6053. ",
  6054.   [ "/rom/help/tunnel" ] = "tunnel is a program for Mining Turtles. Tunnel will mine a 3x2 tunnel of the depth specified.\
  6055. \
  6056. ex:\
  6057. \"tunnel 20\" will tunnel a tunnel 20 blocks long.",
  6058.   [ "/rom/help/go" ] = "go is a program for Turtles, used to control the turtle without programming. It accepts one or more commands as a direction followed by a distance.\
  6059. \
  6060. ex:\
  6061. \"go forward\" moves the turtle 1 space forward.\
  6062. \"go forward 3\" moves the turtle 3 spaces forward.\
  6063. \"go forward 3 up left 2\" moves the turtle 3 spaces forward, 1 spaces up, then left 180 degrees.",
  6064.   [ "/rom/programs/shutdown" ] = "if term.isColour() then\
  6065.     term.setTextColour( colours.yellow )\
  6066. end\
  6067. print( \"Goodbye\" )\
  6068. term.setTextColour( colours.white )\
  6069. \
  6070. sleep( 1 )\
  6071. os.shutdown()",
  6072.   [ "/rom/programs/advanced/multishell" ] = "\
  6073. -- Setup process switching\
  6074. local parentTerm = term.current()\
  6075. local w,h = parentTerm.getSize()\
  6076. \
  6077. local tProcesses = {}\
  6078. local nCurrentProcess = nil\
  6079. local nRunningProcess = nil\
  6080. local bShowMenu = false\
  6081. local bWindowsResized = false\
  6082. \
  6083. local function selectProcess( n )\
  6084.    if nCurrentProcess ~= n then\
  6085.        if nCurrentProcess then\
  6086.            local tOldProcess = tProcesses[ nCurrentProcess ]\
  6087.            tOldProcess.window.setVisible( false )\
  6088.        end\
  6089.        nCurrentProcess = n\
  6090.        if nCurrentProcess then\
  6091.            local tNewProcess = tProcesses[ nCurrentProcess ]\
  6092.            tNewProcess.window.setVisible( true )\
  6093.            tNewProcess.bInteracted = true\
  6094.        end\
  6095.    end\
  6096. end\
  6097. \
  6098. local function setProcessTitle( n, sTitle )\
  6099.    tProcesses[ n ].sTitle = sTitle\
  6100. end\
  6101. \
  6102. local function resumeProcess( nProcess, sEvent, ... )\
  6103.    local tProcess = tProcesses[ nProcess ]\
  6104.    local sFilter = tProcess.sFilter\
  6105.    if sFilter == nil or sFilter == sEvent or sEvent == \"terminate\" then\
  6106.        local nPreviousProcess = nRunningProcess\
  6107.        nRunningProcess = nProcess\
  6108.        term.redirect( tProcess.terminal )\
  6109.        local ok, result = coroutine.resume( tProcess.co, sEvent, ... )\
  6110.        tProcess.terminal = term.current()\
  6111.        if ok then\
  6112.            tProcess.sFilter = result\
  6113.        else\
  6114.            printError( result )\
  6115.        end\
  6116.        nRunningProcess = nPreviousProcess\
  6117.    end\
  6118. end\
  6119. \
  6120. local function launchProcess( tProgramEnv, sProgramPath, ... )\
  6121.    local tProgramArgs = { ... }\
  6122.    local nProcess = #tProcesses + 1\
  6123.    local tProcess = {}\
  6124.    tProcess.sTitle = fs.getName( sProgramPath )\
  6125.    if bShowMenu then\
  6126.        tProcess.window = window.create( parentTerm, 1, 2, w, h-1, false )\
  6127.    else\
  6128.        tProcess.window = window.create( parentTerm, 1, 1, w, h, false )\
  6129.    end\
  6130.    tProcess.co = coroutine.create( function()\
  6131.        os.run( tProgramEnv, sProgramPath, unpack( tProgramArgs ) )\
  6132.        if not tProcess.bInteracted then\
  6133.            term.setCursorBlink( false )\
  6134.            print( \"Press any key to continue\" )\
  6135.            os.pullEvent( \"char\" )\
  6136.        end\
  6137.    end )\
  6138.    tProcess.sFilter = nil\
  6139.    tProcess.terminal = tProcess.window\
  6140.    tProcess.bInteracted = false\
  6141.    tProcesses[ nProcess ] = tProcess\
  6142.    resumeProcess( nProcess )\
  6143.    return nProcess\
  6144. end\
  6145. \
  6146. local function cullProcess( nProcess )\
  6147.    local tProcess = tProcesses[ nProcess ]\
  6148.    if coroutine.status( tProcess.co ) == \"dead\" then\
  6149.        if nCurrentProcess == nProcess then\
  6150.            selectProcess( nil )\
  6151.        end\
  6152.        table.remove( tProcesses, nProcess )\
  6153.        if nCurrentProcess == nil then\
  6154.            if nProcess > 1 then\
  6155.                selectProcess( nProcess - 1 )\
  6156.            elseif #tProcesses > 0 then\
  6157.                selectProcess( 1 )\
  6158.            end\
  6159.        end\
  6160.        return true\
  6161.    end\
  6162.    return false\
  6163. end\
  6164. \
  6165. local function cullProcesses()\
  6166.    local culled = false\
  6167.    for n=#tProcesses,1,-1 do\
  6168.        culled = culled or cullProcess( n )\
  6169.    end\
  6170.    return culled\
  6171. end\
  6172. \
  6173. -- Setup the main menu\
  6174. local menuMainTextColor, menuMainBgColor, menuOtherTextColor, menuOtherBgColor\
  6175. if parentTerm.isColor() then\
  6176.    menuMainTextColor, menuMainBgColor = colors.yellow, colors.black\
  6177.    menuOtherTextColor, menuOtherBgColor = colors.black, colors.gray\
  6178. else\
  6179.    menuMainTextColor, menuMainBgColor = colors.white, colors.black\
  6180.    menuOtherTextColor, menuOtherBgColor = colors.black, colors.white\
  6181. end\
  6182. \
  6183. local function redrawMenu()\
  6184.    if bShowMenu then\
  6185.        -- Draw menu\
  6186.        parentTerm.setCursorPos( 1, 1 )\
  6187.        parentTerm.setBackgroundColor( menuOtherBgColor )\
  6188.        parentTerm.clearLine()\
  6189.        for n=1,#tProcesses do\
  6190.            if n == nCurrentProcess then\
  6191.                parentTerm.setTextColor( menuMainTextColor )\
  6192.                parentTerm.setBackgroundColor( menuMainBgColor )\
  6193.            else\
  6194.                parentTerm.setTextColor( menuOtherTextColor )\
  6195.                parentTerm.setBackgroundColor( menuOtherBgColor )\
  6196.            end\
  6197.            parentTerm.write( \" \" .. tProcesses[n].sTitle .. \" \" )\
  6198.        end\
  6199. \
  6200.        -- Put the cursor back where it should be\
  6201.        local tProcess = tProcesses[ nCurrentProcess ]\
  6202.        if tProcess then\
  6203.            tProcess.window.restoreCursor()\
  6204.        end\
  6205.    end\
  6206. end\
  6207. \
  6208. local function resizeWindows()\
  6209.    local windowY, windowHeight\
  6210.    if bShowMenu then\
  6211.        windowY = 2\
  6212.        windowHeight = h-1\
  6213.    else\
  6214.        windowY = 1\
  6215.        windowHeight = h\
  6216.    end\
  6217.    for n=1,#tProcesses do\
  6218.        local tProcess = tProcesses[n]\
  6219.        local window = tProcess.window\
  6220.        local x,y = tProcess.window.getCursorPos()\
  6221.        if y > windowHeight then\
  6222.            tProcess.window.scroll( y - windowHeight )\
  6223.            tProcess.window.setCursorPos( x, windowHeight )\
  6224.        end\
  6225.        tProcess.window.reposition( 1, windowY, w, windowHeight )\
  6226.    end\
  6227.    bWindowsResized = true\
  6228. end\
  6229. \
  6230. local function setMenuVisible( bVis )\
  6231.    if bShowMenu ~= bVis then\
  6232.        bShowMenu = bVis\
  6233.        resizeWindows()\
  6234.        redrawMenu()\
  6235.    end\
  6236. end\
  6237. \
  6238. local multishell = {}\
  6239. \
  6240. function multishell.getFocus()\
  6241.    return nCurrentProcess\
  6242. end\
  6243. \
  6244. function multishell.setFocus( n )\
  6245.    if n >= 1 and n <= #tProcesses then\
  6246.        selectProcess( n )\
  6247.        redrawMenu()\
  6248.        return true\
  6249.    end\
  6250.    return false\
  6251. end\
  6252. \
  6253. function multishell.getTitle( n )\
  6254.    if n >= 1 and n <= #tProcesses then\
  6255.        return tProcesses[n].sTitle\
  6256.    end\
  6257.    return nil\
  6258. end\
  6259. \
  6260. function multishell.setTitle( n, sTitle )\
  6261.    if n >= 1 and n <= #tProcesses then\
  6262.        setProcessTitle( n, sTitle )\
  6263.        redrawMenu()\
  6264.    end\
  6265. end\
  6266. \
  6267. function multishell.getCurrent()\
  6268.    return nRunningProcess\
  6269. end\
  6270. \
  6271. function multishell.launch( tProgramEnv, sProgramPath, ... )\
  6272.    local previousTerm = term.current()\
  6273.    setMenuVisible( (#tProcesses + 1) >= 2 )\
  6274.    local nResult = launchProcess( tProgramEnv, sProgramPath, ... )\
  6275.    redrawMenu()\
  6276.    term.redirect( previousTerm )\
  6277.    return nResult\
  6278. end\
  6279. \
  6280. function multishell.getCount()\
  6281.    return #tProcesses\
  6282. end\
  6283. \
  6284. -- Begin\
  6285. parentTerm.clear()\
  6286. setMenuVisible( false )\
  6287. selectProcess( launchProcess( {\
  6288.    [\"shell\"] = shell,\
  6289.    [\"multishell\"] = multishell,\
  6290. }, \"/rom/programs/shell\" ) )\
  6291. redrawMenu()\
  6292. \
  6293. -- Run processes\
  6294. while #tProcesses > 0 do\
  6295.    -- Get the event\
  6296.    local tEventData = { os.pullEventRaw() }\
  6297.    local sEvent = tEventData[1]\
  6298.    if sEvent == \"term_resize\" then\
  6299.        -- Resize event\
  6300.        w,h = parentTerm.getSize()\
  6301.        resizeWindows()\
  6302.        redrawMenu()\
  6303. \
  6304.    elseif sEvent == \"char\" or sEvent == \"key\" or sEvent == \"paste\" or sEvent == \"terminate\" then\
  6305.        -- Keyboard event\
  6306.        -- Passthrough to current process\
  6307.        resumeProcess( nCurrentProcess, unpack( tEventData ) )\
  6308.        if cullProcess( nCurrentProcess ) then\
  6309.            setMenuVisible( #tProcesses >= 2 )\
  6310.            redrawMenu()\
  6311.        end\
  6312. \
  6313.    elseif sEvent == \"mouse_click\" then\
  6314.        -- Click event\
  6315.        local button, x, y = tEventData[2], tEventData[3], tEventData[4]\
  6316.        if bShowMenu and y == 1 then\
  6317.            -- Switch process\
  6318.            local tabStart = 1\
  6319.            for n=1,#tProcesses do\
  6320.                tabEnd = tabStart + string.len( tProcesses[n].sTitle ) + 1\
  6321.                if x >= tabStart and x <= tabEnd then\
  6322.                    selectProcess( n )\
  6323.                    redrawMenu()\
  6324.                    break\
  6325.                end\
  6326.                tabStart = tabEnd + 1\
  6327.            end\
  6328.        else\
  6329.            -- Passthrough to current process\
  6330.            resumeProcess( nCurrentProcess, sEvent, button, x, (bShowMenu and y-1) or y )\
  6331.            if cullProcess( nCurrentProcess ) then\
  6332.                setMenuVisible( #tProcesses >= 2 )\
  6333.                redrawMenu()\
  6334.            end\
  6335.        end\
  6336. \
  6337.    elseif sEvent == \"mouse_drag\" or sEvent == \"mouse_scroll\" then\
  6338.        -- Other mouse event\
  6339.        local p1, x, y = tEventData[2], tEventData[3], tEventData[4]\
  6340.        if not (bShowMenu and y == 1) then\
  6341.            -- Passthrough to current process\
  6342.            resumeProcess( nCurrentProcess, sEvent, p1, x, (bShowMenu and y-1) or y )\
  6343.            if cullProcess( nCurrentProcess ) then\
  6344.                setMenuVisible( #tProcesses >= 2 )\
  6345.                redrawMenu()\
  6346.            end\
  6347.        end\
  6348. \
  6349.    else\
  6350.        -- Other event\
  6351.        -- Passthrough to all processes\
  6352.        local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event\
  6353.        for n=1,nLimit do\
  6354.            resumeProcess( n, unpack( tEventData ) )\
  6355.        end\
  6356.        if cullProcesses() then\
  6357.            setMenuVisible( #tProcesses >= 2 )\
  6358.            redrawMenu()\
  6359.        end\
  6360.    end\
  6361. \
  6362.    if bWindowsResized then\
  6363.        -- Pass term_resize to all processes\
  6364.        local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event\
  6365.        for n=1,nLimit do\
  6366.            resumeProcess( n, \"term_resize\" )\
  6367.        end\
  6368.        bWindowsResized = false\
  6369.        if cullProcesses() then\
  6370.            setMenuVisible( #tProcesses >= 2 )\
  6371.            redrawMenu()\
  6372.        end\
  6373.    end\
  6374. end\
  6375. \
  6376. -- Shutdown\
  6377. term.redirect( parentTerm )",
  6378.   [ "/rom/programs/rednet/repeat" ] = "\
  6379. -- Find modems\
  6380. local tModems = {}\
  6381. for n,sModem in ipairs( peripheral.getNames() ) do\
  6382.    if peripheral.getType( sModem ) == \"modem\" then\
  6383.        table.insert( tModems, sModem )\
  6384.    end\
  6385. end\
  6386. if #tModems == 0 then\
  6387.    print( \"No modems found.\" )\
  6388.    return\
  6389. elseif #tModems == 1 then\
  6390.    print( \"1 modem found.\" )\
  6391. else\
  6392.    print( #tModems .. \" modems found.\" )\
  6393. end\
  6394. \
  6395. function open( nChannel )\
  6396.    for n=1,#tModems do\
  6397.        local sModem = tModems[n]\
  6398.        peripheral.call( sModem, \"open\", nChannel )\
  6399.    end\
  6400. end\
  6401. \
  6402. function close( nChannel )\
  6403.    for n=1,#tModems do\
  6404.        local sModem = tModems[n]\
  6405.        peripheral.call( sModem, \"close\", nChannel )\
  6406.    end\
  6407. end\
  6408. \
  6409. -- Open channels\
  6410. print( \"0 messages repeated.\" )\
  6411. open( rednet.CHANNEL_REPEAT )\
  6412. \
  6413. -- Main loop (terminate to break)\
  6414. local ok, error = pcall( function()\
  6415.    local tReceivedMessages = {}\
  6416.    local tReceivedMessageTimeouts = {}\
  6417.    local nTransmittedMessages = 0\
  6418. \
  6419.    while true do\
  6420.        local sEvent, sModem, nChannel, nReplyChannel, tMessage = os.pullEvent()\
  6421.        if sEvent == \"modem_message\" then\
  6422.            -- Got a modem message, rebroadcast it if it's a rednet thing\
  6423.            if nChannel == rednet.CHANNEL_REPEAT then\
  6424.                if type( tMessage ) == \"table\" and tMessage.nMessageID and tMessage.nRecipient then\
  6425.                    if not tReceivedMessages[ tMessage.nMessageID ] then\
  6426.                        -- Ensure we only repeat a message once\
  6427.                        tReceivedMessages[ tMessage.nMessageID ] = true\
  6428.                        tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = tMessage.nMessageID\
  6429. \
  6430.                        -- Send on all other open modems, to the target and to other repeaters\
  6431.                        for n=1,#tModems do\
  6432.                            local sOtherModem = tModems[n]\
  6433.                            peripheral.call( sOtherModem, \"transmit\", rednet.CHANNEL_REPEAT, nReplyChannel, tMessage )\
  6434.                            peripheral.call( sOtherModem, \"transmit\", tMessage.nRecipient, nReplyChannel, tMessage )\
  6435.                        end\
  6436. \
  6437.                        -- Log the event\
  6438.                        nTransmittedMessages = nTransmittedMessages + 1\
  6439.                        local x,y = term.getCursorPos()\
  6440.                        term.setCursorPos( 1, y - 1 )\
  6441.                        term.clearLine()\
  6442.                        if nTransmittedMessages == 1 then\
  6443.                            print( nTransmittedMessages .. \" message repeated.\" )\
  6444.                        else\
  6445.                            print( nTransmittedMessages .. \" messages repeated.\" )\
  6446.                        end\
  6447.                    end\
  6448.                end\
  6449.            end\
  6450. \
  6451.        elseif sEvent == \"timer\" then\
  6452.            -- Got a timer event, use it to clear the message history\
  6453.            local nTimer = sModem\
  6454.            local nMessageID = tReceivedMessageTimeouts[ nTimer ]\
  6455.            if nMessageID then\
  6456.                tReceivedMessageTimeouts[ nTimer ] = nil\
  6457.                tReceivedMessages[ nMessageID ] = nil\
  6458.            end\
  6459. \
  6460.        end\
  6461.    end\
  6462. end )\
  6463. if not ok then\
  6464.    printError( error )\
  6465. end\
  6466. \
  6467. -- Close channels\
  6468. close( rednet.CHANNEL_REPEAT )",
  6469.   [ "/rom/help/sleep" ] = "sleep makes the computer idle for a specific number of seconds.\
  6470. \
  6471. ex:\
  6472. \"sleep 10\" puts the computer to sleep for 10 seconds",
  6473.   [ "/rom/programs/turtle/dance" ] = "\
  6474. local tMoves = {\
  6475.     function()\
  6476.         turtle.up()\
  6477.         turtle.down()\
  6478.     end,\
  6479.     function()\
  6480.         turtle.up()\
  6481.         turtle.turnLeft()\
  6482.         turtle.turnLeft()\
  6483.         turtle.turnLeft()\
  6484.         turtle.turnLeft()\
  6485.         turtle.down()\
  6486.     end,\
  6487.     function()\
  6488.         turtle.up()\
  6489.         turtle.turnRight()\
  6490.         turtle.turnRight()\
  6491.         turtle.turnRight()\
  6492.         turtle.turnRight()\
  6493.         turtle.down()\
  6494.     end,\
  6495.     function()\
  6496.         turtle.turnLeft()\
  6497.         turtle.turnLeft()\
  6498.         turtle.turnLeft()\
  6499.         turtle.turnLeft()\
  6500.     end,\
  6501.     function()\
  6502.         turtle.turnRight()\
  6503.         turtle.turnRight()\
  6504.         turtle.turnRight()\
  6505.         turtle.turnRight()\
  6506.     end,\
  6507.     function()\
  6508.         turtle.turnLeft()\
  6509.         turtle.back()\
  6510.         turtle.back()\
  6511.         turtle.turnRight()\
  6512.         turtle.turnRight()\
  6513.         turtle.back()\
  6514.         turtle.back()\
  6515.         turtle.turnLeft()\
  6516.     end,\
  6517.     function()\
  6518.         turtle.turnRight()\
  6519.         turtle.back()\
  6520.         turtle.back()\
  6521.         turtle.turnLeft()\
  6522.         turtle.turnLeft()\
  6523.         turtle.back()\
  6524.         turtle.back()\
  6525.         turtle.turnRight()\
  6526.     end,\
  6527.     function()\
  6528.         turtle.back()\
  6529.         turtle.turnLeft()\
  6530.         turtle.back()\
  6531.         turtle.turnLeft()\
  6532.         turtle.back()\
  6533.         turtle.turnLeft()\
  6534.         turtle.back()\
  6535.         turtle.turnLeft()\
  6536.     end,\
  6537.     function()\
  6538.         turtle.back()\
  6539.         turtle.turnRight()\
  6540.         turtle.back()\
  6541.         turtle.turnRight()\
  6542.         turtle.back()\
  6543.         turtle.turnRight()\
  6544.         turtle.back()\
  6545.         turtle.turnRight()\
  6546.     end,\
  6547. }\
  6548. \
  6549. textutils.slowWrite( \"Preparing to get down.\" )\
  6550. textutils.slowPrint( \"..\", 0.75 )\
  6551. \
  6552. local sAudio = nil\
  6553. for n,sName in pairs( peripheral.getNames() ) do\
  6554.     if disk.hasAudio( sName ) then\
  6555.         disk.playAudio( sName )\
  6556.         print( \"Jamming to \"..disk.getAudioTitle( sName ) )\
  6557.         sAudio = sName\
  6558.         break\
  6559.     end\
  6560. end\
  6561. \
  6562. print( \"Press any key to stop the groove\" )\
  6563. \
  6564. local bEnd = false\
  6565. parallel.waitForAll(\
  6566.     function()\
  6567.         while not bEnd do\
  6568.             local event, key = os.pullEvent(\"key\")\
  6569.             if key ~= keys.escape then\
  6570.                 bEnd = true\
  6571.             end\
  6572.         end     \
  6573.     end,\
  6574.     function()\
  6575.         while not bEnd do\
  6576.             local fnMove = tMoves[math.random(1,#tMoves)]\
  6577.             fnMove()\
  6578.         end\
  6579.     end\
  6580. )\
  6581. \
  6582. if sAudio then\
  6583.     disk.stopAudio( sAudio )\
  6584. end",
  6585.   [ "/Shop/main.lua" ] = "_G.DB = {}\
  6586. _G.DB.Items = {}\
  6587. \
  6588. function Decompile(CompiledTbl)\
  6589.  local Str = ''\
  6590.  for k, v in pairs(CompiledTbl) do\
  6591.    Str = Str .. string.char(v)\
  6592.  end\
  6593.  return Str\
  6594. end\
  6595. \
  6596. function Compile(Str)\
  6597.  local Compiled = {string.byte(Str,1,#tostring(Str))}\
  6598.  return Compiled, table.concat(Compiled, ',')\
  6599. end\
  6600. \
  6601. Modem = peripheral.wrap('top')\
  6602. Modem.open(2773)\
  6603. \
  6604. FDK.process:spawnThread(function()\
  6605.     coroutine.yield('terminate')\
  6606.     --os.reboot()\
  6607.  FDK.running = false\
  6608. end)\
  6609. \
  6610. local State = FDK.require('lib.state')\
  6611. \
  6612. State:new('Init')\
  6613. State:new('Main')\
  6614. State:new('Search')\
  6615. State:new('Account')\
  6616. State:new('Items')\
  6617. \
  6618. FDK.dofile('States.Init')\
  6619. FDK.dofile('States.Main')\
  6620. FDK.dofile('States.Search')\
  6621. FDK.dofile('States.Account')\
  6622. FDK.dofile('States.Items')\
  6623. \
  6624. --[[\
  6625. local GotData = false\
  6626. \
  6627. local StateLib = FDK.require('lib.state')\
  6628. local State = StateLib.names.init\
  6629. \
  6630. local Field = FDK.require('lib.UI.elements.Field')\
  6631. local Text = FDK.require('lib.UI.elements.Text')\
  6632. local Button = FDK.require('lib.UI.elements.Button')\
  6633. \
  6634. -- Main Field\
  6635. State.frame:newChild(Field(1, 1, State.frame.width, State.frame.height, colours.grey))\
  6636. -- Header Field\
  6637. State.frame:newChild(Field(1, 1, State.frame.width, 3, colors.lightGray))\
  6638. \
  6639. -- Header Text\
  6640. local Header = State.frame:newChild(Text(0, 0, 13, 1, '&b8&t0Shop - Client'))\
  6641. Header:alignX('centre')\
  6642. Header.width = #Header.text - #'&b7&t8'\
  6643. Header.y = 2\
  6644. \
  6645. local Desc = State.frame:newChild(Text(0, 0, 17, 1, '&b7&t8Requesting data..'))\
  6646. Desc:alignX('centre')\
  6647. Desc.width = #Desc.text - #'&b7&t8'\
  6648. Desc.y = math.ceil(State.frame.height/2.3)\
  6649. \
  6650. local CurrentRead = State.frame:newChild(Text(0, 0, 0, 1, '&b7&tfNo data available'))\
  6651. CurrentRead.width = #CurrentRead.text - #'&b7&t8'\
  6652. CurrentRead.y = math.ceil(State.frame.height/2)+1\
  6653. CurrentRead:alignX('centre')\
  6654. \
  6655. \
  6656. ]]\
  6657. \
  6658. \
  6659. \
  6660. -- Hello\
  6661. --[[\
  6662. State.process:spawnThread(function()\
  6663.  while not GotData do\
  6664.    -- File Event System --\
  6665.    if fs.exists('.Call') then\
  6666.      local File = fs.open('.Call', 'r')\
  6667.      local Call = textutils.unserialize(File.readAll())\
  6668.      File.close()\
  6669.      \
  6670.      if #Call > 0 then\
  6671.        for i, J in pairs(Call) do\
  6672.          local Line = ''\
  6673.          for k, v in pairs(J) do\
  6674.            Line = Line .. tostring(v) .. ','\
  6675.            -- Process File\
  6676.          end\
  6677.          CurrentRead.text = '&b7&tfRemote://' .. Line\
  6678.          CurrentRead.width = #CurrentRead.text - #'&b7&t8'\
  6679. \
  6680.          CurrentRead.x = 2\
  6681.          sleep(.5)\
  6682.        end\
  6683.        local File = fs.open('.Call', 'w')\
  6684.        File.writeLine('{}')\
  6685.        File.close()\
  6686.      else\
  6687.        CurrentRead.text = '&b7&tfNo data available'\
  6688.        CurrentRead.width = #CurrentRead.text - #'&b7&t8'\
  6689.        CurrentRead:alignX('centre')\
  6690.      end\
  6691.    end\
  6692.    sleep(.05)\
  6693.  end\
  6694. end)\
  6695. --]]",
  6696.   [ "/Flare/version/1.2/lib/state.lua" ] = "\
  6697. local Frame = FDK.require \"lib.UI.elements.Frame\"\
  6698. local keybind = FDK.require \"lib.UI.keybind\"\
  6699. \
  6700. local state = {}\
  6701. local states = 1\
  6702. \
  6703. state.names = {}\
  6704. \
  6705. function state:new( name )\
  6706.     local s = {}\
  6707.     s.show = self.show\
  6708. \
  6709.     s.bindings = {}\
  6710. \
  6711.     s.pos = states\
  6712.     states = states + 1\
  6713. \
  6714.     s.name = name\
  6715.     s.frame = Frame( 1, 1, FDK.frame.width, FDK.frame.height )\
  6716.     s.process = FDK.process:spawnSubProcess( name .. \"-state\" )\
  6717.     s.process:pause()\
  6718. \
  6719.     if not state.current then\
  6720.         FDK.frame:newChild( s.frame )\
  6721.         s.process:resume()\
  6722.         state.current = s\
  6723.     end\
  6724. \
  6725.     state.names[name] = s\
  6726. \
  6727.     return s\
  6728. end\
  6729. \
  6730. function state:show()\
  6731.     if state.current == self then return end\
  6732.     local x = FDK.frame.width + 1\
  6733.     if state.current then\
  6734.         local pos = state.current.pos\
  6735.         if pos < self.pos then\
  6736.             self.frame.x = 1 + FDK.frame.width\
  6737.             state.current.frame:move( 1 - FDK.frame.width, 1 )\
  6738.         else\
  6739.             self.frame.x = 1 - FDK.frame.width\
  6740.             state.current.frame:move( 1 + FDK.frame.width, 1 )\
  6741.         end\
  6742.     end\
  6743.     FDK.frame:newChild( self.frame )\
  6744.     self.frame:move( 1, 1, nil, function()\
  6745.         if state.current.onHide then\
  6746.             state.current:onHide()\
  6747.         end\
  6748.         state.current.process:pause()\
  6749.         for k, v in pairs( state.current.bindings ) do\
  6750.             keybind.unbind( k, v )\
  6751.         end\
  6752.         if self.onShow then\
  6753.             self:onShow()\
  6754.         end\
  6755.         self.process:resume()\
  6756.         state.current.frame:remove()\
  6757.         state.current = self\
  6758.         for k, v in pairs( self.bindings ) do\
  6759.             keybind.bind( k, v )\
  6760.         end\
  6761.     end )\
  6762. end\
  6763. \
  6764. return state",
  6765.   [ "/rom/help/http" ] = "Functions in the HTTP API:\
  6766. http.checkURL( url )\
  6767. http.request( url, [postData], [headers] )\
  6768. http.get( url, [headers] )\
  6769. http.post( url, postData, [headers] )\
  6770. \
  6771. The HTTP API may be disabled in ComputerCraft.cfg\
  6772. A period of time after a http.request() call is made, a \"http_success\" or \"http_failure\" event will be raised. Arguments are the url and a file handle if successful. http.get() and http.post() block until this event fires instead.",
  6773.   [ "/rom/programs/turtle/refuel" ] = "\
  6774. local tArgs = { ... }\
  6775. local nLimit = 1\
  6776. if #tArgs > 1 then\
  6777.     print( \"Usage: refuel [number]\" )\
  6778.     return\
  6779. elseif #tArgs > 0 then\
  6780.     if tArgs[1] == \"all\" then\
  6781.         nLimit = 64 * 16\
  6782.     else\
  6783.         nLimit = tonumber( tArgs[1] )\
  6784.     end\
  6785. end\
  6786. \
  6787. if turtle.getFuelLevel() ~= \"unlimited\" then\
  6788.     for n=1,16 do\
  6789.         local nCount = turtle.getItemCount(n)\
  6790.         if nLimit > 0 and nCount > 0 and turtle.getFuelLevel() < turtle.getFuelLimit() then\
  6791.             local nBurn = math.min( nLimit, nCount )\
  6792.             turtle.select( n )\
  6793.             if turtle.refuel( nBurn ) then\
  6794.                 local nNewCount = turtle.getItemCount(n)\
  6795.                 nLimit = nLimit - (nCount - nNewCount)\
  6796.             end\
  6797.         end\
  6798.     end\
  6799.    print( \"Fuel level is \"..turtle.getFuelLevel() )\
  6800.    if turtle.getFuelLevel() == turtle.getFuelLimit() then\
  6801.        print( \"Fuel limit reached\" )\
  6802.    end\
  6803. else\
  6804.    print( \"Fuel level is unlimited\" )\
  6805. end",
  6806.   [ "/Flare/version/1.2/lib/UI/elements/Field.lua" ] = "\
  6807. local class = require \"lib.class\"\
  6808. local base = require \"lib.UI.base\"\
  6809. local mouse = require \"lib.UI.event.mouse\"\
  6810. local graphics = require \"lib.graphics\"\
  6811. \
  6812. local Field = class \"Field\"\
  6813. Field:extend( base )\
  6814. \
  6815. Field.bc = \"white\"\
  6816. \
  6817. Field.mouse_click_timeout = .4\
  6818. \
  6819. function Field:Field( x, y, w, h, colour )\
  6820.     self:base( x, y, w, h )\
  6821.     self.bc = colour\
  6822. end\
  6823. \
  6824. function Field:draw( x, y, buffer )\
  6825.     buffer:setColours( graphics.colour( self.bc ) )\
  6826.     buffer:drawFilledRectangle( x, y, self.width, self.height )\
  6827. end\
  6828. \
  6829. function Field:handle( event )\
  6830.     if mouse.click( self, event ) then\
  6831.         if self.onClick then\
  6832.             self:onClick()\
  6833.         end\
  6834.     elseif event.name == \"mouse_ping\" then\
  6835.         mouse.ping( self, event )\
  6836.     end\
  6837. end\
  6838. \
  6839. return Field",
  6840.   [ "/rom/help/reboot" ] = "reboot will turn the computer off and on again.\
  6841. You can also hold Ctrl+R at any time to quickly reboot.",
  6842.   [ "/Flare/version/1.2/lib/video.lua" ] = "\
  6843. local image = require \"lib.image\"\
  6844. \
  6845. local colour = {}\
  6846. \
  6847. colour.lookup = {\
  6848.     [\"0\"] = colours.white;\
  6849.     [\"1\"] = colours.orange;\
  6850.     [\"2\"] = colours.magenta;\
  6851.     [\"3\"] = colours.lightBlue;\
  6852.     [\"4\"] = colours.yellow;\
  6853.     [\"5\"] = colours.lime;\
  6854.     [\"6\"] = colours.pink;\
  6855.     [\"7\"] = colours.grey;\
  6856.     [\"8\"] = colours.lightGrey;\
  6857.     [\"9\"] = colours.cyan;\
  6858.     [\"A\"] = colours.purple;\
  6859.     [\"B\"] = colours.blue;\
  6860.     [\"C\"] = colours.brown;\
  6861.     [\"D\"] = colours.green;\
  6862.     [\"E\"] = colours.red;\
  6863.     [\"F\"] = colours.black;\
  6864.     [\" \"] = 0;\
  6865. }\
  6866. \
  6867. colour.save = {}\
  6868. for k, v in pairs( colour.lookup ) do\
  6869.     colour.save[v] = k\
  6870. end\
  6871. \
  6872. local function changed( f1, f2, x, y )\
  6873.     local bc1, tc1, char1 = f1:getPixel( x, y )\
  6874.     local bc2, tc2, char2 = f2:getPixel( x, y )\
  6875.     return bc1 ~= bc2 or tc1 ~= tc2 or char1 ~= char2\
  6876. end\
  6877. \
  6878. local function px( x, y, width )\
  6879.     return ( y - 1 ) * width + x - 1\
  6880. end\
  6881. local function pad( n, w )\
  6882.     n = tostring( n )\
  6883.     return (\" \"):rep( math.max( w - #n, 0 ) ) .. n\
  6884. end\
  6885. local function pxstr( bc, tc, char )\
  6886.     if char == \"\" then\
  6887.         bc = 0\
  6888.         char = \" \"\
  6889.     end\
  6890.     return colour.save[bc] .. colour.save[tc] .. char\
  6891. end\
  6892. local function upx( s, w )\
  6893.     s = s:gsub( \"^%s*\", \"\" )\
  6894.     local n = tonumber( s )\
  6895.     return n % w + 1, math.floor( n / w ) + 1\
  6896. end\
  6897. \
  6898. local video = {}\
  6899. \
  6900. function video.save( frames )\
  6901.     local frame = frames[1]\
  6902.     local w, h = frame.width, frame.height\
  6903.     local output = w .. \",\" .. h .. \"\\n\"\
  6904.     output = output .. frame:save() .. \"\\n\"\
  6905.     local pxwidth = #tostring( px( w, h, w ) )\
  6906.     for i = 2, #frames do\
  6907.         local nframe = frames[i]\
  6908.         for x = 1, w do\
  6909.             for y = 1, h do\
  6910.                 if changed( frame, nframe, x, y ) then\
  6911.                     output = output .. pad( px( x, y, w ), pxwidth ) .. pxstr( nframe:getPixel( x, y ) )\
  6912.                 end\
  6913.             end\
  6914.         end\
  6915.         frame = nframe\
  6916.         output = output .. \"\\n\"\
  6917.     end\
  6918.     return output:sub( 1, -2 )\
  6919. end\
  6920. \
  6921. function video.load( str )\
  6922.     local width, height = str:match \"(%d+),(%d+)\\n\"\
  6923.     str = str:sub( #width + #height + 3 )\
  6924.     width, height = tonumber( width ), tonumber( height )\
  6925.     local is = ( ( width * 3 ) + 1 ) * height\
  6926.     local frames = { image.load( str:sub( 1, is - 1 ) ) }\
  6927.     frames[2] = frames[1]:clone()\
  6928.     str = str:sub( is + 1 )\
  6929.     local pxwidth = #tostring( px( width, height, width ) )\
  6930.     while #str > 0 do\
  6931.         if str:sub( 1, 1 ) == \"\\n\" then\
  6932.             frames[#frames+1] = frames[#frames]:clone()\
  6933.             str = str:sub( 2 )\
  6934.         else\
  6935.             local x, y = upx( str:sub( 1, pxwidth ), width )\
  6936.             local bc, tc, char = str:sub( pxwidth + 1, pxwidth + 1 ), str:sub( pxwidth + 2, pxwidth + 2 ), str:sub( pxwidth + 3, pxwidth + 3 )\
  6937.             bc = colour.lookup[bc]\
  6938.             tc = colour.lookup[tc]\
  6939.             frames[#frames]:setPixel( x, y, bc, tc, char )\
  6940.             str = str:sub( pxwidth + 4 )\
  6941.         end\
  6942.     end\
  6943.     return frames\
  6944. end\
  6945. \
  6946. return video",
  6947.   [ "/rom/programs/help" ] = "tArgs = { ... }\
  6948. if #tArgs > 0 then\
  6949.     sTopic = tArgs[1]\
  6950. else\
  6951.     sTopic = \"intro\"\
  6952. end\
  6953. \
  6954. if sTopic == \"index\" then\
  6955.     print( \"Help topics availiable:\" )\
  6956.     local tTopics = help.topics()\
  6957.     textutils.pagedTabulate( tTopics )\
  6958.     return\
  6959. end\
  6960.     \
  6961. local w,h = term.getSize()\
  6962. local sFile = help.lookup( sTopic )\
  6963. local file = ((sFile ~= nil) and io.open( sFile )) or nil\
  6964. local nLinesPrinted = 0\
  6965. if file then\
  6966.     local sLine = file:read()\
  6967.     local nLines = 0\
  6968.     while sLine do\
  6969.         nLines = nLines + textutils.pagedPrint( sLine, (h-3) - nLines )\
  6970.         sLine = file:read()\
  6971.    end\
  6972.     file:close()\
  6973. else\
  6974.     print( \"No help available\" )\
  6975. end",
  6976.   [ "/rom/help/shutdown" ] = "shutdown will turn off the computer.",
  6977.   [ "/rom/apis/vector" ] = "\
  6978. local vector = {\
  6979.     add = function( self, o )\
  6980.         return vector.new(\
  6981.             self.x + o.x,\
  6982.             self.y + o.y,\
  6983.             self.z + o.z\
  6984.         )\
  6985.     end,\
  6986.     sub = function( self, o )\
  6987.         return vector.new(\
  6988.             self.x - o.x,\
  6989.             self.y - o.y,\
  6990.             self.z - o.z\
  6991.         )\
  6992.     end,\
  6993.     mul = function( self, m )\
  6994.         return vector.new(\
  6995.             self.x * m,\
  6996.             self.y * m,\
  6997.             self.z * m\
  6998.         )\
  6999.     end,\
  7000.     dot = function( self, o )\
  7001.         return self.x*o.x + self.y*o.y + self.z*o.z\
  7002.     end,\
  7003.     cross = function( self, o )\
  7004.         return vector.new(\
  7005.             self.y*o.z - self.z*o.y,\
  7006.             self.z*o.x - self.x*o.z,\
  7007.             self.x*o.y - self.y*o.x\
  7008.         )\
  7009.     end,\
  7010.     length = function( self )\
  7011.         return math.sqrt( self.x*self.x + self.y*self.y + self.z*self.z )\
  7012.     end,\
  7013.     normalize = function( self )\
  7014.         return self:mul( 1 / self:length() )\
  7015.     end,\
  7016.     round = function( self, nTolerance )\
  7017.         nTolerance = nTolerance or 1.0\
  7018.         return vector.new(\
  7019.             math.floor( (self.x + (nTolerance * 0.5)) / nTolerance ) * nTolerance,\
  7020.             math.floor( (self.y + (nTolerance * 0.5)) / nTolerance ) * nTolerance,\
  7021.             math.floor( (self.z + (nTolerance * 0.5)) / nTolerance ) * nTolerance\
  7022.         )\
  7023.     end,\
  7024.     tostring = function( self )\
  7025.         return self.x..\",\"..self.y..\",\"..self.z\
  7026.     end,\
  7027. }\
  7028. \
  7029. local vmetatable = {\
  7030.     __index = vector,\
  7031.     __add = vector.add,\
  7032.     __sub = vector.sub,\
  7033.     __mul = vector.mul,\
  7034.     __unm = function( v ) return v:mul(-1) end,\
  7035.     __tostring = vector.tostring,\
  7036. }\
  7037. \
  7038. function new( x, y, z )\
  7039.     local v = {\
  7040.         x = x or 0,\
  7041.         y = y or 0,\
  7042.         z = z or 0\
  7043.     }\
  7044.     setmetatable( v, vmetatable )\
  7045.     return v\
  7046. end",
  7047.   [ "/rom/programs/monitor" ] = "\
  7048. function printUsage()\
  7049.     print( \"Usage: monitor <name> <program> <arguments>\" )\
  7050.     return\
  7051. end\
  7052. \
  7053. local tArgs = { ... }\
  7054. if #tArgs < 2 then\
  7055.     printUsage()\
  7056.     return\
  7057. end\
  7058. \
  7059. local sName = tArgs[1]\
  7060. if peripheral.getType( sName ) ~= \"monitor\" then\
  7061.     print( \"No monitor named \".. sName )\
  7062.     return\
  7063. end\
  7064. \
  7065. local sProgram = tArgs[2]\
  7066. local sPath = shell.resolveProgram( sProgram )\
  7067. if sPath == nil then\
  7068.     print( \"No such program: \"..sProgram )\
  7069.     return\
  7070. end\
  7071. \
  7072. print( \"Running \"..sProgram..\" on monitor \"..sName )\
  7073. \
  7074. local monitor = peripheral.wrap( sName )\
  7075. local previousTerm = term.redirect( monitor )\
  7076. \
  7077. local co = coroutine.create( function()\
  7078.    shell.run( sProgram, unpack( tArgs, 3 ) )\
  7079. end )\
  7080. \
  7081. local function resume( ... )\
  7082.    local ok, param = coroutine.resume( co, ... )\
  7083.    if not ok then\
  7084.         printError( param )\
  7085.    end\
  7086.    return param\
  7087. end\
  7088. \
  7089. local ok, param = pcall( function()\
  7090.     local sFilter = resume()\
  7091.     while coroutine.status( co ) ~= \"dead\" do\
  7092.         local tEvent = { os.pullEventRaw() }\
  7093.         if sFilter == nil or tEvent[1] == sFilter or tEvent[1] == \"terminate\" then\
  7094.             sFilter = resume( unpack( tEvent ) )\
  7095.         end\
  7096.         if coroutine.status( co ) ~= \"dead\" and (sFilter == nil or sFilter == \"mouse_click\") then\
  7097.             if tEvent[1] == \"monitor_touch\" and tEvent[2] == sName then\
  7098.                 sFilter = resume( \"mouse_click\", 1, unpack( tEvent, 3 ) )\
  7099.             end\
  7100.         end\
  7101.         if coroutine.status( co ) ~= \"dead\" and (sFilter == nil or sFilter == \"term_resize\") then\
  7102.             if tEvent[1] == \"monitor_resize\" and tEvent[2] == sName then\
  7103.                 sFilter = resume( \"term_resize\" )\
  7104.             end\
  7105.         end\
  7106.     end\
  7107. end )\
  7108. \
  7109. term.redirect( previousTerm )\
  7110. if not ok then\
  7111.     printError( param )\
  7112. end\
  7113.     ",
  7114.   [ "/rom/help/coroutine" ] = "coroutine is a standard Lua5.1 API.\
  7115. Refer to http://www.lua.org/manual/5.1/ for more information.",
  7116.   [ "/Flare/version/1.2/lib/UI/text/code.lua" ] = "\
  7117. local lang = {}\
  7118. local code = {}\
  7119. \
  7120. function code.registerLanguage( language, formatter )\
  7121.     lang[language] = formatter\
  7122. end\
  7123. \
  7124. function code.format( language, text )\
  7125.     local lines = {}\
  7126.     local last = 1\
  7127.     for i = 1, #text do\
  7128.         if text:sub( i, i ) == \"\\n\" then\
  7129.             lines[#lines + 1] = text:sub( last, i - 1 )\
  7130.             last = i + 1\
  7131.         end\
  7132.     end\
  7133.     lines[#lines + 1] = text:sub( last )\
  7134. \
  7135.     local str = \"\"\
  7136.     local lw = #tostring( #lines )\
  7137. \
  7138.     if not lang[language] then\
  7139.         str = \"&b0&tElanguage [\" .. language .. \"] not defined\\n&t7\"\
  7140.     end\
  7141. \
  7142.     local data = {}\
  7143.     local function pushLine( line )\
  7144.         str = str .. \"&b8&tF\" .. (\" \"):rep( lw - #tostring( line ) ) .. line .. \" &b0&t7 \"\
  7145.         if lang[language] then\
  7146.             str = str .. lang[language]( lines[line], data, line ) .. \"\\n\"\
  7147.         else\
  7148.             str = str .. \"`\" .. lines[line] .. \"`\\n\"\
  7149.         end\
  7150.     end\
  7151. \
  7152.     for i = 1, #lines do\
  7153.         pushLine( i )\
  7154.     end\
  7155. \
  7156.     if not lang[language] then\
  7157.         str = tostring( str:sub( 1, -2 ) )\
  7158.     end\
  7159.     return str\
  7160. end\
  7161. \
  7162. return code",
  7163.   [ "/Flare/version/1.2/lib/UI/keybind.lua" ] = "\
  7164. local bindings = {}\
  7165. \
  7166. local keybind = {}\
  7167. \
  7168. function keybind.isBound( key )\
  7169.     if bindings[key] and #bindings[key] > 0 then\
  7170.         return true\
  7171.     end\
  7172.     return false\
  7173. end\
  7174. \
  7175. function keybind.bind( key, action )\
  7176.     bindings[key] = bindings[key] or {}\
  7177.     bindings[key][#bindings[key] + 1] = action\
  7178. end\
  7179. \
  7180. function keybind.unbind( key, action )\
  7181.     if bindings[key] then\
  7182.         if action then\
  7183.             for i = #bindings[key], 1, -1 do\
  7184.                 if bindings[key][i] == action then\
  7185.                     table.remove( bindings[key], i )\
  7186.                     return\
  7187.                 end\
  7188.             end\
  7189.         else\
  7190.             bindings[key][#bindings[key]] = nil\
  7191.         end\
  7192.     end\
  7193. end\
  7194. \
  7195. function keybind.call( key )\
  7196.     if bindings[key] and bindings[key][#bindings[key]] then\
  7197.         bindings[key][#bindings[key]]()\
  7198.     end\
  7199. end\
  7200. \
  7201. return keybind",
  7202.   [ "/rom/programs/turtle/turn" ] = "local tArgs = { ... }\
  7203. if #tArgs < 1 then\
  7204.     print( \"Usage: turn <direction> <turns>\" )\
  7205.     return\
  7206. end\
  7207. \
  7208. local tHandlers = {\
  7209.     [\"lt\"] = turtle.turnLeft,\
  7210.     [\"left\"] = turtle.turnLeft,\
  7211.     [\"rt\"] = turtle.turnRight,\
  7212.     [\"right\"] = turtle.turnRight,\
  7213. }\
  7214. \
  7215. local nArg = 1\
  7216. while nArg <= #tArgs do\
  7217.     local sDirection = tArgs[nArg]\
  7218.     local nDistance = 1\
  7219.     if nArg < #tArgs then\
  7220.         local num = tonumber( tArgs[nArg + 1] )\
  7221.         if num then\
  7222.             nDistance = num\
  7223.             nArg = nArg + 1\
  7224.         end\
  7225.     end\
  7226.     nArg = nArg + 1\
  7227. \
  7228.     local fnHandler = tHandlers[string.lower(sDirection)]\
  7229.     if fnHandler then\
  7230.         for n=1,nDistance do\
  7231.             fnHandler( nArg )\
  7232.         end\
  7233.     else\
  7234.         print( \"No such direction: \"..sDirection )\
  7235.         print( \"Try: left, right\" )\
  7236.         return\
  7237.     end\
  7238.     \
  7239. end",
  7240.   [ "/Flare/version/1.2/lib/graphics.lua" ] = "\
  7241. local function linewrap( str, w )\
  7242.     if str:sub( 1, w + 1 ):find \"\\n\" then\
  7243.         return str:match \"(.-)\\n(.+)\"\
  7244.     end\
  7245.     if str:sub( 1, w + 1 ):find \"%s\" then\
  7246.         local pos = w - str:sub( 1, w + 1 ):reverse():find \"%s\" + 1\
  7247.         return str:sub( 1, pos), str:sub( pos + 2 ):gsub( \"^%s+\", \"\" )\
  7248.     end\
  7249.     return str:sub( 1, w ), str:sub( w + 1 )\
  7250. end\
  7251. \
  7252. local function wordwrap( str, w, h )\
  7253.     local s1, s2 = linewrap( str, w )\
  7254.     local lines = { s1 }\
  7255.     while #s2 > 0 do\
  7256.         s1, s2 = linewrap( s2, w )\
  7257.         lines[#lines + 1] = s1\
  7258.     end\
  7259.     while h and #lines > h do\
  7260.         lines[#lines] = nil\
  7261.     end\
  7262.     return lines\
  7263. end\
  7264. \
  7265. local graphics = {}\
  7266. \
  7267. function graphics:mixin( element ) -- graphics:mixin( buffer )  buffer:drawRectangle()\
  7268.     for k, v in pairs( self ) do\
  7269.         if k ~= \"mixin\" and not element[k] then\
  7270.             element[k] = v\
  7271.         end\
  7272.     end\
  7273. end\
  7274. \
  7275. function graphics:drawPixel( x, y, char )\
  7276.     if self.stencil then\
  7277.         if not self.stencil:withinBounds( x, y ) then\
  7278.             return false\
  7279.         end\
  7280.     end\
  7281.     local bc, tc = graphics.getColours( self )\
  7282.     return self:setPixel( x, y, bc, tc, char or \" \" )\
  7283. end\
  7284. \
  7285. function graphics:drawRectangle( x, y, w, h, char )\
  7286.     local x2, y2 = x + w - 1, y + h - 1\
  7287.     for _x = x, x2 do\
  7288.         graphics.drawPixel( self, _x, y, char )\
  7289.         graphics.drawPixel( self, _x, y2, char )\
  7290.     end\
  7291.     for _y = y + 1, y2 - 1 do\
  7292.         graphics.drawPixel( self, x, _y, char )\
  7293.         graphics.drawPixel( self, x2, _y, char )\
  7294.     end\
  7295. end\
  7296. \
  7297. function graphics:drawFilledRectangle( x, y, w, h, char )\
  7298.     for _x = x, x + w - 1 do\
  7299.         for _y = y, y + h - 1 do\
  7300.             graphics.drawPixel( self, _x, _y, char )\
  7301.         end\
  7302.     end\
  7303. end\
  7304. \
  7305. function graphics:drawCircle( x, y, r, char )\
  7306.     local function pixel( x, y )\
  7307.         graphics.drawPixel( self, x, y, char )\
  7308.     end\
  7309. \
  7310.     local c = 2 * math.pi * r\
  7311.     local n = 2 * math.pi * 2 / c\
  7312.     local c8 = c / 8\
  7313.     for i = 0, c8 do\
  7314.         local _x, _y = math.floor( math.sin( i * n ) * r + .5 ), math.floor( math.cos( i * n ) * r + .5 )\
  7315.         pixel( x + _x, y + _y )\
  7316.         pixel( x + _x, y - _y )\
  7317.         pixel( x - _x, y + _y )\
  7318.         pixel( x - _x, y - _y )\
  7319.         pixel( x + _y, y + _x )\
  7320.         pixel( x - _y, y + _x )\
  7321.         pixel( x + _y, y - _x )\
  7322.         pixel( x - _y, y - _x )\
  7323.     end\
  7324. end\
  7325. \
  7326. function graphics:drawFilledCircle( x, y, r, char, correction )\
  7327.     local r2 = r ^ 2\
  7328.     for _x = -r, r do\
  7329.         for _y = -r, r do\
  7330.             if _x ^ 2 + ( _y ^ 2 ) * ( correction or 1 ) < r2 then\
  7331.                 graphics.drawPixel( self, x + _x, y + _y, char )\
  7332.             end\
  7333.         end\
  7334.     end\
  7335. end\
  7336. \
  7337. function graphics:drawVerticalLine( x, y, height, char )\
  7338.     for i = y, y + height - 1 do\
  7339.         grpahics.drawPixel( self, x, i, char )\
  7340.     end\
  7341. end\
  7342. \
  7343. function graphics:drawHorizontalLine( x, y, width, char )\
  7344.     for i = x, x + width - 1 do\
  7345.         grpahics.drawPixel( self, i, y, char )\
  7346.     end\
  7347. end\
  7348. \
  7349. function graphics:drawLine( x1, y1, x2, y2, char )\
  7350.     if x1 > x2 then\
  7351.         x1, x2 = x2, x1\
  7352.         y1, y2 = y2, y1\
  7353.     end\
  7354.     if x1 == x2 then\
  7355.         for i = math.min( y1, y2 ), math.max( y1, y2 ) do\
  7356.             graphics.drawPixel( self, x1, i, char )\
  7357.         end\
  7358.         return\
  7359.     elseif y1 == y2 then\
  7360.         for i = math.min( x1, x2 ), math.max( x1, x2 ) do\
  7361.             graphics.drawPixel( self, i, y1, char )\
  7362.         end\
  7363.         return\
  7364.     end\
  7365.     local dx, dy = x2 - x1, y2 - y1\
  7366.     local m = dy / dx\
  7367.     local c = y1 - m * x1\
  7368. \
  7369.     for x = x1, x2, math.min( math.abs( 1 / m ), 1 ) do\
  7370.         local y = m * x + c\
  7371.         graphics.drawPixel( self, math.floor( x + .5 ), math.floor( y + .5 ), char )\
  7372.     end\
  7373. end\
  7374. \
  7375. function graphics:applyShader( shader )\
  7376.     local new = {}\
  7377.     for x = 1, self.width do\
  7378.         new[x] = {}\
  7379.         for y = 1, self.height do\
  7380.             local bc, tc, char = self:getPixel( x, y )\
  7381.             local _bc, _tc, _char = shader( x, y, bc, tc, char )\
  7382.             local c = false\
  7383.             if _bc and _bc ~= bc then c = true end\
  7384.             if _tc and _tc ~= tc then c = true end\
  7385.             if _char and _char ~= char then c = true end\
  7386.             if c then\
  7387.                 new[x][y] = { bc = _bc or bc, tc = _tc or tc, char = _char or char }\
  7388.             end\
  7389.         end\
  7390.     end\
  7391.     local _bc, _tc = self:getColours()\
  7392.     for x = 1, self.width do\
  7393.         for y = 1, self.height do\
  7394.             local px = new[x][y]\
  7395.             if px then\
  7396.                 if px.bc ~= _bc or px.tc ~= _tc then\
  7397.                     _bc, _tc = px.bc, px.tc\
  7398.                     self:setColours( _bc, _tc )\
  7399.                 end\
  7400.                 self:drawPixel( x, y, px.char )\
  7401.             end\
  7402.         end\
  7403.     end\
  7404. end\
  7405. \
  7406. function graphics:drawPolygon( ... )\
  7407.     local points, char = { ... }, nil\
  7408.     if #points % 2 == 0 then\
  7409.         char = \" \"\
  7410.     else\
  7411.         char = points[#points]\
  7412.         points[#points] = nil\
  7413.     end\
  7414.     if #points < 6 then\
  7415.         return error \"expected at least 6 parameters (3 x,y pairs)\"\
  7416.     end\
  7417.     for i = 1, #points / 2 do\
  7418.         graphics.drawLine( self, points[2 * i - 1], points[2 * i], points[2 * ( i + 1 ) - 1], points[2 * ( i + 1 )], char )\
  7419.     end\
  7420.     graphics.drawLine( self, points[#points - 1], points[#points], points[1], points[2], char )\
  7421. end\
  7422. \
  7423. function graphics:drawTextLine( x, y, text )\
  7424.     for i = 1, #text do\
  7425.         graphics.drawPixel( self, x, y, text:sub( i, i ) )\
  7426.         x = x + 1\
  7427.     end\
  7428. end\
  7429. \
  7430. function graphics:drawTextWrapped( x, y, w, h, text )\
  7431.     self:drawFilledRectangle( x, y, w, h )\
  7432.     local lines = wordwrap( text, w, h )\
  7433.     for i = 1, #lines do\
  7434.         self:drawTextLine( x, y, lines[i] )\
  7435.         y = y + 1\
  7436.     end\
  7437. end\
  7438. \
  7439. function graphics:drawTextFormatted( x, y, w, h, formatted_text ) -- formatted_text is a table of lines containing an offset, colours, and the actual text\
  7440. \
  7441.     self:setColours( formatted_text.bc, formatted_text.tc )\
  7442.     local bc, tc = self:getColours()\
  7443.     local obc, otc = bc, tc\
  7444.     self:drawFilledRectangle( x, y, w, h )\
  7445.     y = y + ( formatted_text.offset.y or 0 )\
  7446.     for l = 1, #formatted_text.lines do\
  7447.         local text = formatted_text.lines[l].text\
  7448.         local colour = formatted_text.lines[l].colour or {}\
  7449.         local x = x + ( formatted_text.offset[l] or 0 )\
  7450.         for c = 1, #text do\
  7451.             colour[c] = colour[c] or {}\
  7452.             local _bc, _tc = colour[c].bc or formatted_text.bc, colour[c].tc or formatted_text.tc\
  7453.             if _bc ~= bc or _tc ~= tc then\
  7454.                 self:setColours( _bc, _tc )\
  7455.                 bc, tc = _bc, _tc\
  7456.             end\
  7457.             local char = text:sub( c, c )\
  7458.             if char == \"\\t\" then\
  7459.                 char = \"    \"\
  7460.             end\
  7461.             if char ~= \"\\n\" then\
  7462.                 graphics.drawPixel( self, x, y, char )\
  7463.                 x = x + #char\
  7464.             end\
  7465.         end\
  7466.         y = y + 1\
  7467.     end\
  7468.     self:setColours( obc, otc )\
  7469. end\
  7470. \
  7471. function graphics:setColours( bc, tc )\
  7472.     self.graphics_bc = bc or self.graphics_bc\
  7473.     self.graphics_tc = tc or self.graphics_tc\
  7474. end\
  7475. \
  7476. function graphics:getColours()\
  7477.     return self.graphics_bc or 1, self.graphics_tc or 32768\
  7478. end\
  7479. \
  7480. graphics.colour = {}\
  7481. \
  7482. graphics.colour.short = {\
  7483.     [\"0\"] = colours.white;\
  7484.     [\"1\"] = colours.orange;\
  7485.     [\"2\"] = colours.magenta;\
  7486.     [\"3\"] = colours.lightBlue;\
  7487.     [\"4\"] = colours.yellow;\
  7488.     [\"5\"] = colours.lime;\
  7489.     [\"6\"] = colours.pink;\
  7490.     [\"7\"] = colours.grey;\
  7491.     [\"8\"] = colours.lightGrey;\
  7492.     [\"9\"] = colours.cyan;\
  7493.     [\"A\"] = colours.purple;\
  7494.     [\"B\"] = colours.blue;\
  7495.     [\"C\"] = colours.brown;\
  7496.     [\"D\"] = colours.green;\
  7497.     [\"E\"] = colours.red;\
  7498.     [\"F\"] = colours.black;\
  7499.     [\" \"] = 0;\
  7500. }\
  7501. \
  7502. graphics.colour.names = {\
  7503.     [\"white\"] = colours.white;\
  7504.     [\"orange\"] = colours.orange;\
  7505.     [\"magenta\"] = colours.magenta;\
  7506.     [\"lightBlue\"] = colours.lightBlue;\
  7507.     [\"yellow\"] = colours.yellow;\
  7508.     [\"lime\"] = colours.lime;\
  7509.     [\"pink\"] = colours.pink;\
  7510.     [\"grey\"] = colours.grey;\
  7511.     [\"lightGrey\"] = colours.lightGrey;\
  7512.     [\"cyan\"] = colours.cyan;\
  7513.     [\"purple\"] = colours.purple;\
  7514.     [\"blue\"] = colours.blue;\
  7515.     [\"brown\"] = colours.brown;\
  7516.     [\"green\"] = colours.green;\
  7517.     [\"red\"] = colours.red;\
  7518.     [\"black\"] = colours.black;\
  7519.     [\"invisible\"] = 0;\
  7520. }\
  7521. \
  7522. for k, v in pairs( graphics.colour.short ) do\
  7523.     graphics.colour.short[k:lower()] = v\
  7524. end\
  7525. for k, v in pairs( graphics.colour.short ) do\
  7526.     graphics.colour.short[v] = k\
  7527. end\
  7528. \
  7529. for k, v in pairs( graphics.colour.names ) do\
  7530.     graphics.colour.names[v] = k\
  7531. end\
  7532. \
  7533. setmetatable( graphics.colour, { __call = function( self, colour )\
  7534.     if type( colour ) == \"number\" then\
  7535.         return colour\
  7536.     end\
  7537.     if colour == \"R\" or colour == \"r\" or colour == \"random\" then\
  7538.         return 2 ^ math.random( 0, 15 )\
  7539.     end\
  7540.     return self.names[colour] or self.short[colour] or 0\
  7541. end } )\
  7542. \
  7543. graphics.shader = {}\
  7544. \
  7545. graphics.shader.darken = {\
  7546.     [colours.white] = colours.lightGrey, [colours.orange] = colours.red, [colours.magenta] = colours.purple, [colours.lightBlue] = colours.cyan;\
  7547.     [colours.yellow] = colours.orange, [colours.lime] = colours.green, [colours.pink] = colours.magenta, [colours.grey] = colours.black;\
  7548.     [colours.lightGrey] = colours.grey, [colours.cyan] = colours.blue, [colours.purple] = colours.black, [colours.blue] = colours.black;\
  7549.     [colours.brown] = colours.black, [colours.green] = colours.black, [colours.red] = colours.brown, [colours.black] = colours.black;\
  7550. }\
  7551. graphics.shader.lighten = {\
  7552.     [colours.white] = colours.white, [colours.orange] = colours.yellow, [colours.magenta] = colours.pink, [colours.lightBlue] = colours.white;\
  7553.     [colours.yellow] = colours.white, [colours.lime] = colours.white, [colours.pink] = colours.white, [colours.grey] = colours.lightGrey;\
  7554.     [colours.lightGrey] = colours.white, [colours.cyan] = colours.lightBlue, [colours.purple] = colours.magenta, [colours.blue] = colours.cyan;\
  7555.     [colours.brown] = colours.red, [colours.green] = colours.lime, [colours.red] = colours.orange, [colours.black] = colours.grey;\
  7556. }\
  7557. graphics.shader.greyscale = {\
  7558.     [colours.white] = 1, [colours.orange] = 256, [colours.magenta] = 256, [colours.lightBlue] = 256;\
  7559.     [colours.yellow] = 1, [colours.lime] = 256, [colours.pink] = 1, [colours.grey] = 256;\
  7560.     [colours.lightGrey] = 256, [colours.cyan] = 128, [colours.purple] = 128, [colours.blue] = 32768;\
  7561.     [colours.brown] = 32768, [colours.green] = 128, [colours.red] = 128, [colours.black] = 32768;\
  7562. }\
  7563. graphics.shader.sepia = {\
  7564.     [colours.white] = 1, [colours.orange] = 2, [colours.magenta] = 2, [colours.lightBlue] = 2;\
  7565.     [colours.yellow] = 1, [colours.lime] = 2, [colours.pink] = 1, [colours.grey] = 2;\
  7566.     [colours.lightGrey] = 2, [colours.cyan] = 16, [colours.purple] = 16, [colours.blue] = 4096;\
  7567.     [colours.brown] = 4096, [colours.green] = 16, [colours.red] = 16, [colours.black] = 4096;\
  7568. }\
  7569. \
  7570. return graphics",
  7571.   [ "/rom/help/lua" ] = "lua is an interactive prompt for the lua programming language. It's a useful tool for learning the language.",
  7572.   [ "/rom/programs/fun/advanced/redirection" ] = "--CCRedirection by : RamiLego4Game and Dan200--\
  7573. --Based on Redirection by Dan200: http://www.redirectiongame.com--\
  7574. --Clearing Screen--\
  7575. \
  7576. --Vars--\
  7577. local TermW,TermH = term.getSize()\
  7578. \
  7579. local sLevelTitle\
  7580. local tScreen\
  7581. local oScreen\
  7582. local SizeW,SizeH\
  7583. local aExits\
  7584. local fExit\
  7585. local nSpeed\
  7586. local Speed\
  7587. local fSpeed\
  7588. local fSpeedS\
  7589. local bPaused\
  7590. local Tick\
  7591. local Blocks\
  7592. local XOrgin,YOrgin\
  7593. \
  7594. local function reset()\
  7595.    sLevelTitle = \"\"\
  7596.    tScreen = {}\
  7597.    oScreen = {}\
  7598.    SizeW,SizeH = TermW,TermH\
  7599.    aExits = 0\
  7600.    fExit = \"nop\"\
  7601.    nSpeed = 0.6\
  7602.    Speed = nSpeed\
  7603.    fSpeed = 0.2\
  7604.    fSpeedS = false\
  7605.    bPaused = false\
  7606.    Tick = os.startTimer(Speed)\
  7607.    Blocks = 0\
  7608.    XOrgin,YOrgin = 1,1\
  7609. \
  7610.    term.setBackgroundColor(colors.black)\
  7611.    term.setTextColor(colors.white)\
  7612.    term.clear()\
  7613. end\
  7614. \
  7615. local InterFace = {}\
  7616. InterFace.cExit = colors.red\
  7617. InterFace.cSpeedD = colors.white\
  7618. InterFace.cSpeedA = colors.red\
  7619. InterFace.cTitle = colors.red\
  7620. \
  7621. local cG = colors.lightGray\
  7622. local cW = colors.gray\
  7623. local cS = colors.black\
  7624. local cR1 = colors.blue\
  7625. local cR2 = colors.red\
  7626. local cR3 = colors.green\
  7627. local cR4 = colors.yellow\
  7628. \
  7629. local tArgs = { ... }\
  7630. \
  7631. --Functions--\
  7632. local function printCentred( yc, stg )\
  7633.     local xc = math.floor((TermW - string.len(stg)) / 2) + 1\
  7634.     term.setCursorPos(xc,yc)\
  7635.     term.write( stg )\
  7636. end\
  7637. \
  7638. local function centerOrgin()\
  7639.     XOrgin = math.floor((TermW/2)-(SizeW/2))\
  7640.     YOrgin = math.floor((TermH/2)-(SizeH/2))\
  7641. end\
  7642. \
  7643. local function reMap()\
  7644.     tScreen = nil\
  7645.     tScreen = {}\
  7646.     for x=1,SizeW do\
  7647.         tScreen[x] = {}\
  7648.         for y=1,SizeH do\
  7649.             tScreen[x][y] = { space = true, wall = false, ground = false, robot = \"zz\", start = \"zz\", exit = \"zz\" }\
  7650.         end\
  7651.     end\
  7652. end\
  7653. \
  7654. local function tablecopy(t)\
  7655.  local t2 = {}\
  7656.  for k,v in pairs(t) do\
  7657.    t2[k] = v\
  7658.  end\
  7659.  return t2\
  7660. end\
  7661. \
  7662. local function buMap()\
  7663.     oScreen = nil\
  7664.     oScreen = {}\
  7665.     for x=1,SizeW do\
  7666.         oScreen[x] = {}\
  7667.         for y=1,SizeH do\
  7668.             oScreen[x][y] = tablecopy(tScreen[x][y])\
  7669.         end\
  7670.     end\
  7671. end\
  7672. \
  7673. local function addRobot(x,y,side,color)\
  7674.     local obj = tScreen[x][y]\
  7675.     local data = side..color\
  7676.     if obj.wall == nil and obj.robot == nil then\
  7677.         tScreen[x][y].robot = data\
  7678.     else\
  7679.         obj.wall = nil\
  7680.         obj.robot = \"zz\"\
  7681.         tScreen[x][y].robot = data\
  7682.     end\
  7683. end\
  7684. \
  7685. local function addStart(x,y,side,color)\
  7686.     local obj = tScreen[x][y]\
  7687.     local data = side..color\
  7688.     if obj.wall == nil and obj.space == nil then\
  7689.         tScreen[x][y].start = data\
  7690.     else\
  7691.         obj.wall = nil\
  7692.         obj.space = nil\
  7693.         tScreen[x][y].start = data\
  7694.     end\
  7695.     aExits = aExits+1\
  7696. end\
  7697. \
  7698. local function addGround(x,y)\
  7699.     local obj = tScreen[x][y]\
  7700.     if obj.space == nil and obj.exit == nil and obj.wall == nil and obj.robot == nil and obj.start == nil then\
  7701.         tScreen[x][y].ground = true\
  7702.     else\
  7703.         obj.space = nil\
  7704.         obj.exit = \"zz\"\
  7705.         obj.wall = nil\
  7706.         obj.robot = \"zz\"\
  7707.         obj.start = \"zz\"\
  7708.         tScreen[x][y].ground = true\
  7709.     end\
  7710. end\
  7711. \
  7712. local function addExit(x,y,cl)\
  7713.     local obj = tScreen[x][y]\
  7714.     if obj.space == nil and obj.ground == nil and obj.wall == nil and obj.robot == nil and obj.start == nil then\
  7715.         tScreen[x][y].exit = cl\
  7716.     else\
  7717.         obj.space = nil\
  7718.         obj.ground = nil\
  7719.         obj.wall = nil\
  7720.         obj.robot = \"zz\"\
  7721.         obj.start = \"zz\"\
  7722.         tScreen[x][y].exit = cl\
  7723.     end\
  7724. end\
  7725. \
  7726. local function addWall(x,y)\
  7727.     local obj = tScreen[x][y]\
  7728.     if obj == nil then\
  7729.         return error(\"Here X\"..x..\" Y\"..y)\
  7730.     end\
  7731.     if obj.space == nil and obj.exit == nil and obj.ground == nil and obj.robot == nil and obj.start == nil then\
  7732.         tScreen[x][y].wall = true\
  7733.     else\
  7734.         obj.space = nil\
  7735.         obj.exit = nil\
  7736.         obj.ground = nil\
  7737.         obj.robot = nil\
  7738.         obj.start = nil\
  7739.         tScreen[x][y].wall = true\
  7740.     end\
  7741. end\
  7742. \
  7743. local function loadLevel(nNum)\
  7744.    sLevelTitle = \"Level \"..nNum\
  7745.     if nNum == nil then return error(\"nNum == nil\") end\
  7746.     local sDir = fs.getDir( shell.getRunningProgram() )\
  7747.     local sLevelD = sDir .. \"/levels/\" .. tostring(nNum)\
  7748.     if not ( fs.exists(sLevelD) or fs.isDir(sLevelD) ) then return error(\"Level Not Exists : \"..sLevelD) end\
  7749.     fLevel = fs.open(sLevelD,\"r\")\
  7750.     local Line = 0\
  7751.     local wl = true\
  7752.     Blocks = tonumber(string.sub(fLevel.readLine(),1,1))\
  7753.     local xSize = string.len(fLevel.readLine())+2\
  7754.     local Lines = 3\
  7755.     while wl do\
  7756.         local wLine = fLevel.readLine()\
  7757.         if wLine == nil then\
  7758.             fLevel.close()\
  7759.             wl = false\
  7760.         else\
  7761.             xSize = math.max(string.len(wLine)+2,xSize)\
  7762.             Lines = Lines + 1\
  7763.         end\
  7764.     end\
  7765.     SizeW,SizeH = xSize,Lines\
  7766.     reMap()\
  7767.     fLevel = fs.open(sLevelD,\"r\")\
  7768.     fLevel.readLine()\
  7769.     for Line=2,Lines-1 do\
  7770.         sLine = fLevel.readLine()\
  7771.         local chars = string.len(sLine)\
  7772.         for char = 1, chars do\
  7773.             local el = string.sub(sLine,char,char)\
  7774.             if el == \"8\" then\
  7775.                 addGround(char+1,Line)\
  7776.             elseif el == \"0\" then\
  7777.                 addStart(char+1,Line,\"a\",\"a\")\
  7778.             elseif el == \"1\" then\
  7779.                 addStart(char+1,Line,\"b\",\"a\")\
  7780.             elseif el == \"2\" then\
  7781.                 addStart(char+1,Line,\"c\",\"a\")\
  7782.             elseif el == \"3\" then\
  7783.                 addStart(char+1,Line,\"d\",\"a\")\
  7784.             elseif el == \"4\" then\
  7785.                 addStart(char+1,Line,\"a\",\"b\")\
  7786.             elseif el == \"5\" then\
  7787.                 addStart(char+1,Line,\"b\",\"b\")\
  7788.             elseif el == \"6\" then\
  7789.                 addStart(char+1,Line,\"c\",\"b\")\
  7790.             elseif el == \"9\" then\
  7791.                 addStart(char+1,Line,\"d\",\"b\")\
  7792.             elseif el == \"b\" then\
  7793.                 addExit(char+1,Line,\"a\")\
  7794.             elseif el == \"e\" then\
  7795.                 addExit(char+1,Line,\"b\")\
  7796.             elseif el == \"7\" then\
  7797.                 addWall(char+1,Line)\
  7798.             end\
  7799.         end\
  7800.     end\
  7801.     fLevel.close()\
  7802. end\
  7803. \
  7804. local function drawStars()\
  7805.     --CCR Background By : RamiLego--\
  7806.     local cStar,cStarG,crStar,crStarB = colors.lightGray,colors.gray,\".\",\"*\"\
  7807.     local DStar,BStar,nStar,gStar = 14,10,16,3\
  7808.     local TermW,TermH = term.getSize()\
  7809. \
  7810.    term.clear()\
  7811.    term.setCursorPos(1,1)\
  7812.     for x=1,TermW do\
  7813.         for y=1,TermH do\
  7814.             local StarT = math.random(1,30)\
  7815.             if StarT == DStar then\
  7816.                 term.setCursorPos(x,y)\
  7817.                 term.setTextColor(cStar)\
  7818.                 write(crStar)\
  7819.             elseif StarT == BStar then\
  7820.                 term.setCursorPos(x,y)\
  7821.                 term.setTextColor(cStar)\
  7822.                 write(crStarB)\
  7823.             elseif StarT == nStar then\
  7824.                 term.setCursorPos(x,y)\
  7825.                 term.setTextColor(cStarG)\
  7826.                 write(crStar)\
  7827.             elseif StarT == gStar then\
  7828.                 term.setCursorPos(x,y)\
  7829.                 term.setTextColor(cStarG)\
  7830.                 write(crStarB)\
  7831.             end\
  7832.         end\
  7833.     end\
  7834. end\
  7835. \
  7836. local function drawMap()\
  7837.     for x=1,SizeW do\
  7838.         for y=1,SizeH do\
  7839.           \
  7840.             local obj = tScreen[x][y]\
  7841.             if obj.ground == true then\
  7842.                 paintutils.drawPixel(XOrgin+x,YOrgin+y+1,cG)\
  7843.             end\
  7844.             if obj.wall == true then\
  7845.                 paintutils.drawPixel(XOrgin+x,YOrgin+y+1,cW)\
  7846.             end\
  7847.          \
  7848.          local ex = tostring(tScreen[x][y].exit)\
  7849.             if not(ex == \"zz\" or ex == \"nil\") then\
  7850.                 if ex == \"a\" then\
  7851.                     ex = cR1\
  7852.                 elseif ex == \"b\" then\
  7853.                     ex = cR2\
  7854.                 elseif ex == \"c\" then\
  7855.                     ex = cR3\
  7856.                 elseif ex == \"d\" then\
  7857.                     ex = cR4\
  7858.                 else\
  7859.                     return error(\"Exit Color Out\")\
  7860.                 end\
  7861.                 term.setBackgroundColor(cG)\
  7862.                 term.setTextColor(ex)\
  7863.                 term.setCursorPos(XOrgin+x,YOrgin+y+1)\
  7864.                 print(\"X\")\
  7865.             end\
  7866.          \
  7867.          local st = tostring(tScreen[x][y].start)\
  7868.             if not(st == \"zz\" or st == \"nil\") then\
  7869.                 local Cr = string.sub(st,2,2)\
  7870.                 if Cr == \"a\" then\
  7871.                     Cr = cR1\
  7872.                 elseif Cr == \"b\" then\
  7873.                     Cr = cR2\
  7874.                 elseif Cr == \"c\" then\
  7875.                     Cr = cR3\
  7876.                 elseif Cr == \"d\" then\
  7877.                     Cr = cR4\
  7878.                 else\
  7879.                     return error(\"Start Color Out\")\
  7880.                 end\
  7881.             \
  7882.                 term.setTextColor(Cr)\
  7883.             term.setBackgroundColor(cG)\
  7884.                 term.setCursorPos(XOrgin+x,YOrgin+y+1)\
  7885.             \
  7886.                 sSide = string.sub(st,1,1)\
  7887.                 if sSide == \"a\" then\
  7888.                     print(\"^\")\
  7889.                 elseif sSide == \"b\" then\
  7890.                     print(\">\")\
  7891.                 elseif sSide == \"c\" then\
  7892.                     print(\"v\")\
  7893.                 elseif sSide == \"d\" then\
  7894.                     print(\"<\")\
  7895.                 else\
  7896.                     print(\"@\")\
  7897.                 end\
  7898.             end\
  7899.             \
  7900.             if obj.space == true then\
  7901.                 paintutils.drawPixel(XOrgin+x,YOrgin+y+1,cS)\
  7902.             end\
  7903.             \
  7904.             local rb = tostring(tScreen[x][y].robot)\
  7905.             if not(rb == \"zz\" or rb == \"nil\") then\
  7906.                 local Cr = string.sub(rb,2,2)\
  7907.                 if Cr == \"a\" then\
  7908.                     Cr = cR1\
  7909.                 elseif Cr == \"b\" then\
  7910.                     Cr = cR2\
  7911.                 elseif Cr == \"c\" then\
  7912.                     Cr = cR3\
  7913.                 elseif Cr == \"d\" then\
  7914.                     Cr = cR4\
  7915.                 else\
  7916.                     Cr = colors.white\
  7917.                 end\
  7918.                 term.setBackgroundColor(Cr)\
  7919.                 term.setTextColor(colors.white)\
  7920.                 term.setCursorPos(XOrgin+x,YOrgin+y+1)\
  7921.                 sSide = string.sub(rb,1,1)\
  7922.                 if sSide == \"a\" then\
  7923.                     print(\"^\")\
  7924.                 elseif sSide == \"b\" then\
  7925.                     print(\">\")\
  7926.                 elseif sSide == \"c\" then\
  7927.                     print(\"v\")\
  7928.                 elseif sSide == \"d\" then\
  7929.                     print(\"<\")\
  7930.                 else\
  7931.                     print(\"@\")\
  7932.                 end\
  7933.             end\
  7934.         end\
  7935.     end\
  7936. end\
  7937. \
  7938. local function isBrick(x,y)\
  7939.     local brb = tostring(tScreen[x][y].robot)\
  7940.     local bobj = oScreen[x][y]\
  7941.     if (brb == \"zz\" or brb == \"nil\") and not bobj.wall == true then\
  7942.         return false\
  7943.     else\
  7944.         return true\
  7945.     end\
  7946. end\
  7947. \
  7948. local function gRender(sContext)\
  7949.     if sContext == \"start\" then\
  7950.         for x=1,SizeW do\
  7951.             for y=1,SizeH do\
  7952.                 local st = tostring(tScreen[x][y].start)\
  7953.                 if not(st == \"zz\" or st == \"nil\") then\
  7954.                     local Cr = string.sub(st,2,2)\
  7955.                     local sSide = string.sub(st,1,1)\
  7956.                     addRobot(x,y,sSide,Cr)\
  7957.                 end\
  7958.             end\
  7959.         end\
  7960.     elseif sContext == \"tick\" then\
  7961.         buMap()\
  7962.        for x=1,SizeW do\
  7963.            for y=1,SizeH do\
  7964.                local rb = tostring(oScreen[x][y].robot)\
  7965.                if not(rb == \"zz\" or rb == \"nil\") then\
  7966.                    local Cr = string.sub(rb,2,2)\
  7967.                    local sSide = string.sub(rb,1,1)\
  7968.                    local sobj = oScreen[x][y]\
  7969.                    if sobj.space == true then\
  7970.                        tScreen[x][y].robot = \"zz\"\
  7971.                        if not sSide == \"g\" then\
  7972.                            addRobot(x,y,\"g\",Cr)\
  7973.                        end\
  7974.                    elseif sobj.exit == Cr then\
  7975.                        if sSide == \"a\" or sSide == \"b\" or sSide == \"c\" or sSide == \"d\" then\
  7976.                        tScreen[x][y].robot = \"zz\"\
  7977.                        addRobot(x,y,\"g\",Cr)\
  7978.                        aExits = aExits-1\
  7979.                        end\
  7980.                    elseif sSide == \"a\" then\
  7981.                        local obj = isBrick(x,y-1)\
  7982.                        tScreen[x][y].robot = \"zz\"\
  7983.                        if not obj == true then\
  7984.                            addRobot(x,y-1,sSide,Cr)\
  7985.                        else\
  7986.                            local obj2 = isBrick(x-1,y)\
  7987.                            local obj3 = isBrick(x+1,y)\
  7988.                            if not obj2 == true and not obj3 == true then\
  7989.                                if Cr == \"a\" then\
  7990.                                    addRobot(x,y,\"d\",Cr)\
  7991.                                elseif Cr == \"b\" then\
  7992.                                    addRobot(x,y,\"b\",Cr)\
  7993.                                end\
  7994.                            elseif obj == true and obj2 == true and obj3 == true then\
  7995.                                addRobot(x,y,\"c\",Cr)\
  7996.                            else\
  7997.                                if obj3 == true then\
  7998.                                    addRobot(x,y,\"d\",Cr)\
  7999.                                elseif obj2 == true then\
  8000.                                    addRobot(x,y,\"b\",Cr)\
  8001.                                end\
  8002.                            end\
  8003.                        end\
  8004.                    elseif sSide == \"b\" then\
  8005.                        local obj = isBrick(x+1,y)\
  8006.                        tScreen[x][y].robot = \"zz\"\
  8007.                        if not obj == true then\
  8008.                            addRobot(x+1,y,sSide,Cr)\
  8009.                        else\
  8010.                            local obj2 = isBrick(x,y-1)\
  8011.                            local obj3 = isBrick(x,y+1)\
  8012.                            if not obj2 == true and not obj3 == true then\
  8013.                                if Cr == \"a\" then\
  8014.                                    addRobot(x,y,\"a\",Cr)\
  8015.                                elseif Cr == \"b\" then\
  8016.                                    addRobot(x,y,\"c\",Cr)\
  8017.                                end\
  8018.                            elseif obj == true and obj2 == true and obj3 == true then\
  8019.                                addRobot(x,y,\"d\",Cr)\
  8020.                            else\
  8021.                                if obj3 == true then\
  8022.                                    addRobot(x,y,\"a\",Cr)\
  8023.                                elseif obj2 == true then\
  8024.                                    addRobot(x,y,\"c\",Cr)\
  8025.                                end\
  8026.                            end\
  8027.                        end\
  8028.                    elseif sSide == \"c\" then\
  8029.                        local obj = isBrick(x,y+1)\
  8030.                        tScreen[x][y].robot = \"zz\"\
  8031.                        if not obj == true then\
  8032.                            addRobot(x,y+1,sSide,Cr)\
  8033.                        else\
  8034.                            local obj2 = isBrick(x-1,y)\
  8035.                            local obj3 = isBrick(x+1,y)\
  8036.                            if not obj2 == true and not obj3 == true then\
  8037.                                if Cr == \"a\" then\
  8038.                                    addRobot(x,y,\"b\",Cr)\
  8039.                                elseif Cr == \"b\" then\
  8040.                                    addRobot(x,y,\"d\",Cr)\
  8041.                                end\
  8042.                            elseif obj == true and obj2 == true and obj3 == true then\
  8043.                                addRobot(x,y,\"a\",Cr)\
  8044.                            else\
  8045.                                if obj3 == true then\
  8046.                                    addRobot(x,y,\"d\",Cr)\
  8047.                                elseif obj2 == true then\
  8048.                                    addRobot(x,y,\"b\",Cr)\
  8049.                                end\
  8050.                            end\
  8051.                        end\
  8052.                    elseif sSide == \"d\" then\
  8053.                        local obj = isBrick(x-1,y)\
  8054.                        tScreen[x][y].robot = \"zz\"\
  8055.                        if not obj == true then\
  8056.                            addRobot(x-1,y,sSide,Cr)\
  8057.                        else\
  8058.                            local obj2 = isBrick(x,y-1)\
  8059.                            local obj3 = isBrick(x,y+1)\
  8060.                            if not obj2 == true and not obj3 == true then\
  8061.                                if Cr == \"a\" then\
  8062.                                    addRobot(x,y,\"c\",Cr)\
  8063.                                elseif Cr == \"b\" then\
  8064.                                    addRobot(x,y,\"a\",Cr)\
  8065.                                end\
  8066.                            elseif obj == true and obj2 == true and obj3 == true then\
  8067.                                addRobot(x,y,\"b\",Cr)\
  8068.                            else\
  8069.                                if obj3 == true then\
  8070.                                    addRobot(x,y,\"a\",Cr)\
  8071.                                elseif obj2 == true then\
  8072.                                    addRobot(x,y,\"c\",Cr)\
  8073.                                end\
  8074.                            end\
  8075.                        end\
  8076.                    else\
  8077.                        addRobot(x,y,sSide,\"g\")\
  8078.                    end\
  8079.                end\
  8080.            end\
  8081.        end\
  8082.    end\
  8083. end\
  8084. \
  8085. function InterFace.drawBar()\
  8086.     term.setBackgroundColor( colors.black )\
  8087.     term.setTextColor( InterFace.cTitle )\
  8088.     printCentred( 1, \"  \"..sLevelTitle..\"  \" )\
  8089.     \
  8090.     term.setCursorPos(1,1)\
  8091.     term.setBackgroundColor( cW )\
  8092.     write( \" \" )\
  8093.     term.setBackgroundColor( colors.black )\
  8094.     write( \" x \"..tostring(Blocks)..\" \" )\
  8095.     \
  8096.     term.setCursorPos( TermW-8,TermH )\
  8097.     term.setBackgroundColor( colors.black )\
  8098.    term.setTextColour(InterFace.cSpeedD)\
  8099.     write(\" <<\" )\
  8100.     if bPaused then\
  8101.         term.setTextColour(InterFace.cSpeedA)\
  8102.     else\
  8103.         term.setTextColour(InterFace.cSpeedD)\
  8104.     end\
  8105.     write(\" ||\")\
  8106.     if fSpeedS then\
  8107.         term.setTextColour(InterFace.cSpeedA)\
  8108.     else\
  8109.         term.setTextColour(InterFace.cSpeedD)\
  8110.     end\
  8111.     write(\" >>\")\
  8112. \
  8113.     term.setCursorPos( TermW-1, 1 )\
  8114.     term.setBackgroundColor( colors.black )\
  8115.     term.setTextColour( InterFace.cExit )\
  8116.     write(\" X\")\
  8117.     term.setBackgroundColor(colors.black)\
  8118. end\
  8119. \
  8120. function InterFace.render()\
  8121.     local id,p1,p2,p3 = os.pullEvent()\
  8122.     if id == \"mouse_click\" then\
  8123.         if p3 == 1 and p2 == TermW then\
  8124.            return \"end\"\
  8125.        elseif p3 == TermH and p2 >= TermW-7 and p2 <= TermW-6 then\
  8126.            return \"retry\"\
  8127.        elseif p3 == TermH and p2 >= TermW-4 and p2 <= TermW-3 then\
  8128.            bPaused = not bPaused\
  8129.            fSpeedS = false\
  8130.            Speed = (bPaused and 0) or nSpeed\
  8131.            if Speed > 0 then\
  8132.                Tick = os.startTimer(Speed)\
  8133.            else\
  8134.                Tick = nil\
  8135.            end\
  8136.            InterFace.drawBar()\
  8137.        elseif p3 == TermH and p2 >= TermW-1 then\
  8138.            bPaused = false\
  8139.            fSpeedS = not fSpeedS\
  8140.            Speed = (fSpeedS and fSpeed) or nSpeed\
  8141.            Tick = os.startTimer(Speed)\
  8142.            InterFace.drawBar()\
  8143.         elseif p3-1 < YOrgin+SizeH+1 and p3-1 > YOrgin and\
  8144.               p2 < XOrgin+SizeW+1 and p2 > XOrgin then\
  8145.            local eobj = tScreen[p2-XOrgin][p3-YOrgin-1]\
  8146.            local erobj = tostring(tScreen[p2-XOrgin][p3-YOrgin-1].robot)\
  8147.            if (erobj == \"zz\" or erobj == \"nil\") and not eobj.wall == true and not eobj.space == true and Blocks > 0 then\
  8148.                addWall(p2-XOrgin,p3-YOrgin-1)\
  8149.                Blocks = Blocks-1\
  8150.                InterFace.drawBar()\
  8151.                drawMap()\
  8152.            end\
  8153.         end\
  8154.     elseif id == \"timer\" and p1 == Tick then\
  8155.         gRender(\"tick\")\
  8156.        drawMap()\
  8157.        if Speed > 0 then\
  8158.            Tick = os.startTimer(Speed)\
  8159.        else\
  8160.            Tick = nil\
  8161.        end\
  8162.     end\
  8163. end\
  8164. \
  8165. local function startG(LevelN)\
  8166.     drawStars()\
  8167.     loadLevel(LevelN)\
  8168.     centerOrgin()\
  8169.     local create = true\
  8170.     drawMap()\
  8171.     InterFace.drawBar()\
  8172.     gRender(\"start\")\
  8173.     drawMap()\
  8174.     \
  8175.     local NExit = true\
  8176.     if aExits == 0 then\
  8177.         NExit = false\
  8178.     end\
  8179.     \
  8180.     while true do\
  8181.         local isExit = InterFace.render()\
  8182.         if isExit == \"end\" then\
  8183.             return nil\
  8184.         elseif isExit == \"retry\" then\
  8185.             return LevelN\
  8186.         elseif fExit == \"yes\" then\
  8187.             if fs.exists( fs.getDir( shell.getRunningProgram() ) .. \"/levels/\" .. tostring(LevelN + 1) ) then\
  8188.                 return LevelN + 1\
  8189.             else\
  8190.                 return nil\
  8191.             end\
  8192.         end\
  8193.         if aExits == 0 and NExit == true then\
  8194.             fExit = \"yes\"\
  8195.         end\
  8196.     end\
  8197. end\
  8198. \
  8199. local ok, err = true, nil\
  8200. \
  8201. --Menu--\
  8202. local sStartLevel = tArgs[1]\
  8203. if ok and not sStartLevel then\
  8204.    ok, err = pcall( function()\
  8205.        term.setTextColor(colors.white)\
  8206.        term.setBackgroundColor( colors.black )\
  8207.        term.clear()\
  8208.        drawStars()\
  8209.        term.setTextColor( colors.red )\
  8210.        printCentred( TermH/2 - 1, \"  REDIRECTION  \" )\
  8211.        printCentred( TermH/2 - 0, \"  ComputerCraft Edition  \" )\
  8212.        term.setTextColor( colors.yellow )\
  8213.        printCentred( TermH/2 + 2, \"  Click to Begin  \" )\
  8214.        os.pullEvent( \"mouse_click\" )\
  8215.    end )\
  8216. end\
  8217. \
  8218. --Game--\
  8219. if ok then\
  8220.    ok,err = pcall( function()\
  8221.        local nLevel\
  8222.        if sStartLevel then\
  8223.            nLevel = tonumber( sStartLevel )\
  8224.        else\
  8225.            nLevel = 1\
  8226.        end\
  8227.        while nLevel do\
  8228.            reset()\
  8229.            nLevel = startG(nLevel)\
  8230.        end\
  8231.    end )\
  8232. end\
  8233. \
  8234. --Upsell screen--\
  8235. if ok then\
  8236.    ok, err = pcall( function()\
  8237.        term.setTextColor(colors.white)\
  8238.        term.setBackgroundColor( colors.black )\
  8239.        term.clear()\
  8240.        drawStars()\
  8241.        term.setTextColor( colors.red )\
  8242.        if TermW >= 40 then\
  8243.            printCentred( TermH/2 - 1, \"  Thank you for playing Redirection  \" )\
  8244.            printCentred( TermH/2 - 0, \"  ComputerCraft Edition  \" )\
  8245.            printCentred( TermH/2 + 2, \"  Check out the full game:  \" )\
  8246.            term.setTextColor( colors.yellow )\
  8247.            printCentred( TermH/2 + 3, \"  http://www.redirectiongame.com  \" )\
  8248.        else\
  8249.            printCentred( TermH/2 - 2, \"  Thank you for  \" )\
  8250.            printCentred( TermH/2 - 1, \"  playing Redirection  \" )\
  8251.            printCentred( TermH/2 - 0, \"  ComputerCraft Edition  \" )\
  8252.            printCentred( TermH/2 + 2, \"  Check out the full game:  \" )\
  8253.            term.setTextColor( colors.yellow )\
  8254.            printCentred( TermH/2 + 3, \"  www.redirectiongame.com  \" )\
  8255.        end\
  8256.        parallel.waitForAll(\
  8257.            function() sleep(2) end,\
  8258.            function() os.pullEvent( \"mouse_click\" ) end\
  8259.        )\
  8260.    end )\
  8261. end\
  8262. \
  8263. --Clear and exit--\
  8264. term.setCursorPos(1,1)\
  8265. term.setTextColor(colors.white)\
  8266. term.setBackgroundColor(colors.black)\
  8267. term.clear()\
  8268. if not ok then\
  8269.    if err == \"Terminated\" then\
  8270.        print( \"Check out the full version of Redirection:\" )\
  8271.        print( \"http://www.redirectiongame.com\" )\
  8272.    else\
  8273.        printError( err )\
  8274.    end\
  8275. end",
  8276.   [ "/rom/help/repeat" ] = "repeat is a program for repeating rednet messages across long distances. To use, connect 2 or more modems to a computer and run the \"repeat\" program; from then on, any rednet message sent from any computer in wireless range or connected by networking cable to either of the modems will be repeated to those on the other side.",
  8277.   [ "/rom/programs/fun/advanced/levels/1" ] = "1\
  8278.     777\
  8279.     7b7\
  8280.     787\
  8281. 7777778777\
  8282. 7188888887\
  8283. 7777777777",
  8284.   [ "/rom/apis/peripheral" ] = "local native = peripheral\
  8285. \
  8286. function getNames()\
  8287.     local tResults = {}\
  8288.     for n,sSide in ipairs( rs.getSides() ) do\
  8289.         if native.isPresent( sSide ) then\
  8290.             table.insert( tResults, sSide )\
  8291.             if native.getType( sSide ) == \"modem\" and not native.call( sSide, \"isWireless\" ) then\
  8292.                 local tRemote = native.call( sSide, \"getNamesRemote\" )\
  8293.                 for n,sName in ipairs( tRemote ) do\
  8294.                     table.insert( tResults, sName )\
  8295.                 end\
  8296.             end\
  8297.         end\
  8298.     end\
  8299.     return tResults\
  8300. end\
  8301. \
  8302. function isPresent( _sSide )\
  8303.    if type( _sSide ) ~= \"string\" then\
  8304.        error( \"Expected string\", 2 )\
  8305.    end\
  8306.     if native.isPresent( _sSide ) then\
  8307.         return true\
  8308.     end\
  8309.     for n,sSide in ipairs( rs.getSides() ) do\
  8310.         if native.getType( sSide ) == \"modem\" and not native.call( sSide, \"isWireless\" ) then\
  8311.             if native.call( sSide, \"isPresentRemote\", _sSide )  then\
  8312.                 return true\
  8313.             end\
  8314.         end\
  8315.     end\
  8316.     return false\
  8317. end\
  8318. \
  8319. function getType( _sSide )\
  8320.    if type( _sSide ) ~= \"string\" then\
  8321.        error( \"Expected string\", 2 )\
  8322.    end\
  8323.     if native.isPresent( _sSide ) then\
  8324.         return native.getType( _sSide )\
  8325.     end\
  8326.     for n,sSide in ipairs( rs.getSides() ) do\
  8327.         if native.getType( sSide ) == \"modem\" and not native.call( sSide, \"isWireless\" ) then\
  8328.             if native.call( sSide, \"isPresentRemote\", _sSide )  then\
  8329.                 return native.call( sSide, \"getTypeRemote\", _sSide ) \
  8330.             end\
  8331.         end\
  8332.     end\
  8333.     return nil\
  8334. end\
  8335. \
  8336. function getMethods( _sSide )\
  8337.    if type( _sSide ) ~= \"string\" then\
  8338.        error( \"Expected string\", 2 )\
  8339.    end\
  8340.     if native.isPresent( _sSide ) then\
  8341.         return native.getMethods( _sSide )\
  8342.     end\
  8343.     for n,sSide in ipairs( rs.getSides() ) do\
  8344.         if native.getType( sSide ) == \"modem\" and not native.call( sSide, \"isWireless\" ) then\
  8345.             if native.call( sSide, \"isPresentRemote\", _sSide )  then\
  8346.                 return native.call( sSide, \"getMethodsRemote\", _sSide ) \
  8347.             end\
  8348.         end\
  8349.     end\
  8350.     return nil\
  8351. end\
  8352. \
  8353. function call( _sSide, _sMethod, ... )\
  8354.    if type( _sSide ) ~= \"string\" or type( _sMethod ) ~= \"string\" then\
  8355.        error( \"Expected string, string\", 2 )\
  8356.    end\
  8357.     if native.isPresent( _sSide ) then\
  8358.         return native.call( _sSide, _sMethod, ... )\
  8359.     end\
  8360.     for n,sSide in ipairs( rs.getSides() ) do\
  8361.         if native.getType( sSide ) == \"modem\" and not native.call( sSide, \"isWireless\" ) then\
  8362.             if native.call( sSide, \"isPresentRemote\", _sSide )  then\
  8363.                 return native.call( sSide, \"callRemote\", _sSide, _sMethod, ... ) \
  8364.             end\
  8365.         end\
  8366.     end\
  8367.     return nil\
  8368. end\
  8369. \
  8370. function wrap( _sSide )\
  8371.    if type( _sSide ) ~= \"string\"  then\
  8372.        error( \"Expected string\", 2 )\
  8373.    end\
  8374.     if peripheral.isPresent( _sSide ) then\
  8375.         local tMethods = peripheral.getMethods( _sSide )\
  8376.         local tResult = {}\
  8377.         for n,sMethod in ipairs( tMethods ) do\
  8378.             tResult[sMethod] = function( ... )\
  8379.                 return peripheral.call( _sSide, sMethod, ... )\
  8380.             end\
  8381.         end\
  8382.         return tResult\
  8383.     end\
  8384.     return nil\
  8385. end\
  8386. \
  8387. function find( sType, fnFilter )\
  8388.    if type( sType ) ~= \"string\" or (fnFilter ~= nil and type( fnFilter ) ~= \"function\") then\
  8389.        error( \"Expected string, [function]\", 2 )\
  8390.    end\
  8391.     local tResults = {}\
  8392.     for n,sName in ipairs( peripheral.getNames() ) do\
  8393.         if peripheral.getType( sName ) == sType then\
  8394.             local wrapped = peripheral.wrap( sName )\
  8395.             if fnFilter == nil or fnFilter( sName, wrapped ) then\
  8396.                 table.insert( tResults, wrapped )\
  8397.             end\
  8398.         end\
  8399.     end\
  8400.     return unpack( tResults )\
  8401. end",
  8402.   [ "/rom/help/textutils" ] = "Functions in the Text Utilities API:\
  8403. textutils.slowPrint( text )\
  8404. textutils.tabulate( table, table2, ... )\
  8405. textutils.pagedTabulate( table, table2, ... )\
  8406. textutils.formatTime( time, bTwentyFourHour )\
  8407. textutils.serialize( table )\
  8408. textutils.unserialize( string )\
  8409. textutils.urlEncode( string )",
  8410.   [ "/rom/help/apis" ] = "apis lists the currently loaded APIs available to programs in CraftOS.\
  8411. \
  8412. Type \"help <api>\" to see help for a specific api.\
  8413. Call os.loadAPI( path ) to load extra apis.",
  8414.   [ "/rom/help/cd" ] = "cd changes the the directory you're in.\
  8415. \
  8416. ex:\
  8417. \"cd rom\" will move to \"rom\" folder.\
  8418. \"cd ..\" will move up one folder.\
  8419. \"cd /\" will move to the root.",
  8420.   [ "/Shop/States/Init.lua" ] = "\
  8421. local StateLib = FDK.require('lib.state')\
  8422. local State = StateLib.names.Init\
  8423. local Main = StateLib.names.Main\
  8424. \
  8425. local Field = FDK.require('lib.UI.elements.Field')\
  8426. local Text = FDK.require('lib.UI.elements.Text')\
  8427. local Button = FDK.require('lib.UI.elements.Button')\
  8428. \
  8429. -- Main Field\
  8430. State.frame:newChild(Field(1, 1, State.frame.width, State.frame.height, colors.gray))\
  8431. -- Header Field\
  8432. State.frame:newChild(Field(1, 1, State.frame.width, 3, colors.lightGray))\
  8433. \
  8434. -- Header Text\
  8435. local Header = State.frame:newChild(Text(0, 0, 13, 1, '&b8&t0Shop - Client'))\
  8436. Header.width = #Header.text - #'&b7&t8'\
  8437. Header.y = 2\
  8438. Header:alignX('centre')\
  8439. \
  8440. local Desc = State.frame:newChild(Text(0, 0, 17, 1, '&b7&t8Requesting data..'))\
  8441. Desc.width = #Desc.text - #'&b7&t8'\
  8442. Desc.y = math.ceil(State.frame.height/2.3)\
  8443. Desc:alignX('centre')\
  8444. local CurrentRead = State.frame:newChild(Text(0, 0, 0, 1, '&b7&tfNo data available'))\
  8445. CurrentRead.width = #CurrentRead.text - #'&b7&t8'\
  8446. CurrentRead.y = math.ceil(State.frame.height/2)+1 \
  8447. CurrentRead:alignX('centre')\
  8448.  \
  8449. State.process:spawnThread(function()\
  8450.  while true do\
  8451.    -- Gather data --\
  8452.    Modem.transmit(2773, 2773, '@RequestData')\
  8453.    local Events, Side, Channel, Channel, Msg, Dist = coroutine.yield('modem_message')\
  8454.    --_G.DB = textutils.unserialize(Decompile(textutils.unserialize(Msg)))\
  8455.    break\
  8456.  end\
  8457.  Main:show()\
  8458. end)",
  8459.   [ "/rom/help/shellapi" ] = "Functions in the Shell API:\
  8460. shell.exit()\
  8461. shell.dir()\
  8462. shell.setDir( path )\
  8463. shell.path()\
  8464. shell.setPath( path )\
  8465. shell.resolve( localpath )\
  8466. shell.resolveProgram( name )\
  8467. shell.aliases()\
  8468. shell.setAlias( alias, command )\
  8469. shell.clearAlias( alias )\
  8470. shell.programs()\
  8471. shell.run( program, arguments )\
  8472. shell.getRunningProgram()\
  8473. shell.openTab( program, arguments ) (Advanced Computer required)\
  8474. shell.switchTab( n ) (Advanced Computer required)",
  8475.   [ "/Flare/version/1.2/lib/UI/base.lua" ] = "\
  8476. local class = require \"lib.class\"\
  8477. \
  8478. local base = class \"base\"\
  8479. \
  8480. function base:base( x, y, w, h )\
  8481.     self.x = x\
  8482.     self.y = y\
  8483.     self.width = w\
  8484.     self.height = h\
  8485.     self.root = {}\
  8486.     setmetatable( self.root, self.root )\
  8487. end\
  8488. \
  8489. function base:setX( x )\
  8490.     if type( x ) == \"string\" and x:find \"%d+%%$\" and self.parent then\
  8491.         x = math.floor( tonumber( x:sub( 1, -2 ) ) * self.parent.width + .5 )\
  8492.     end\
  8493.     self.x = x\
  8494. end\
  8495. \
  8496. function base:setY( y )\
  8497.     if type( y ) == \"string\" and y:find \"%d+%%$\" and self.parent then\
  8498.         y = math.floor( tonumber( y:sub( 1, -2 ) ) * self.parent.height + .5 )\
  8499.     end\
  8500.     self.y = y\
  8501. end\
  8502. \
  8503. function base:setWidth( width )\
  8504.     if type( width ) == \"string\" and width:find \"%d+%%$\" and self.parent then\
  8505.         width = math.floor( tonumber( width:sub( 1, -2 ) ) * self.parent.width + .5 )\
  8506.     end\
  8507.     self.width = width\
  8508. end\
  8509. \
  8510. function base:setHeight( width )\
  8511.     if type( height ) == \"string\" and height:find \"%d+%%$\" and self.parent then\
  8512.         height = math.floor( tonumber( height:sub( 1, -2 ) ) * self.parent.height + .5 )\
  8513.     end\
  8514.     self.height = height\
  8515. end\
  8516. \
  8517. function base:alignX( mode )\
  8518.     if mode == \"left\" then\
  8519.         self.x = 1\
  8520.     elseif mode == \"centre\" or mode == \"center\" or mode == \"middle\" then\
  8521.         self.x = math.floor( self.parent.width / 2 - self.width / 2 ) + 1\
  8522.     elseif mode == \"right\" then\
  8523.         self.x = self.parent.width - self.width + 1\
  8524.     else\
  8525.         return error( \"invalid x-alignment mode [\" .. mode .. \"]\" )\
  8526.     end\
  8527. end\
  8528. \
  8529. function base:alignY( mode )\
  8530.     if mode == \"top\" then\
  8531.         self.y = 1\
  8532.     elseif mode == \"centre\" or mode == \"center\" or mode == \"middle\" then\
  8533.         self.y = math.floor( self.parent.height / 2 - self.height / 2 ) + 1\
  8534.     elseif mode == \"bottom\" then\
  8535.         self.y = self.parent.height - self.height + 1\
  8536.     else\
  8537.         return error( \"invalid y-alignment mode [\" .. mode .. \"]\" )\
  8538.     end\
  8539. end\
  8540. \
  8541. function base:align( mode_x, mode_y )\
  8542.     if not mode_y then\
  8543.         return function( mode_y )\
  8544.             self:align( mode_x, mode_y )\
  8545.         end\
  8546.     end\
  8547.     self:alignX( mode_x )\
  8548.     self:alignY( mode_y )\
  8549. end\
  8550. \
  8551. function base:alignXTo( element, mode )\
  8552.     mode = mode or \"similar\"\
  8553.     if mode == \"similar\" or mode == \"same\" or mode == \"equal\" then\
  8554.         self.x = element.x\
  8555.     elseif mode == \"left\" then\
  8556.         self.x = element.x - self.width + 1\
  8557.     elseif mode == \"right\" then\
  8558.         self.x = element.x + element.width\
  8559.     else\
  8560.         return error( \"invalid x-alignment mode [\" .. mode .. \"]\" )\
  8561.     end\
  8562. end\
  8563. \
  8564. function base:alignYTo( element, mode )\
  8565.     mode = mode or \"similar\"\
  8566.     if mode == \"similar\" or mode == \"same\" or mode == \"equal\" then\
  8567.         self.y = element.y\
  8568.     elseif mode == \"above\" or mode == \"top\" then\
  8569.         self.y = element.y - self.height + 1\
  8570.     elseif mode == \"below\" or mode == \"bottom\" then\
  8571.         self.y = element.y + element.height\
  8572.     else\
  8573.         return error( \"invalid y-alignment mode [\" .. mode .. \"]\" )\
  8574.     end\
  8575. end\
  8576. \
  8577. function base:alignTo( element, mode_x, mode_y )\
  8578.     self:alignXTo( element, mode_x )\
  8579.     self:alignYTo( element, mode_y )\
  8580. end\
  8581. \
  8582. function base:remove()\
  8583.     if self.parent then\
  8584.         self.parent:removeChild( self )\
  8585.     end\
  8586. end\
  8587. \
  8588. function base:draw( x, y, buffer )\
  8589. \
  8590. end\
  8591. \
  8592. function base:update( dt )\
  8593. \
  8594. end\
  8595. \
  8596. function base:handle( event )\
  8597. \
  8598. end\
  8599. \
  8600. return base",
  8601.   [ "/rom/help/dj" ] = "dj plays Music Discs from disk drives attached to the computer.\
  8602. \
  8603. ex:\
  8604. \"dj\" or \"dj play\" plays a random disc.\
  8605. \"dj play left\" plays the disc in the drive on the left of the computer.\
  8606. \"dj stop\" stops the current disc.",
  8607.   [ "/Flare/version/1.2/lib/stencil.lua" ] = "\
  8608. local function bbox( x1, y1, w1, h1, x2, y2, w2, h2 )\
  8609.     local x = math.max( x1, x2 )\
  8610.     local y = math.max( y1, y2 )\
  8611.     local w = math.min( x1 + w1, x2 + w2 ) - x\
  8612.     local h = math.min( y1 + h1, y2 + h2 ) - y\
  8613.     if w < 1 or h < 1 then return false end\
  8614.     return x, y, w, h\
  8615. end\
  8616. \
  8617. local stencil = {}\
  8618. \
  8619. function stencil:new()\
  8620. \
  8621.     local s = {}\
  8622. \
  8623.     s.bounds = false\
  8624.     s.layers = {}\
  8625. \
  8626.     setmetatable( s, { __index = self, __type = \"stencil\" } )\
  8627.     return s\
  8628. \
  8629. end\
  8630. \
  8631. function stencil:newLayer( x, y, w, h )\
  8632.     if self.bounds then\
  8633.         if self.bounds.x then\
  8634.             local t = self.bounds\
  8635.             local _x, _y, _w, _h = bbox( x, y, w, h, t.x, t.y, t.width, t.height )\
  8636.             if _x then\
  8637.                 self.bounds = {\
  8638.                     x = _x;\
  8639.                     y = _y;\
  8640.                     width = _w;\
  8641.                     height = _h;\
  8642.                 }\
  8643.             else\
  8644.                 self.bounds = {}\
  8645.             end\
  8646.         end\
  8647.     else\
  8648.         self.bounds = {\
  8649.             x = x;\
  8650.             y = y;\
  8651.             width = w;\
  8652.             height = h;\
  8653.         }\
  8654.     end\
  8655.     local id = {}\
  8656.     self.layers[#self.layers + 1] = {\
  8657.         x = x;\
  8658.         y = y;\
  8659.         width = w;\
  8660.         height = h;\
  8661.         id = id;\
  8662.     }\
  8663.     return id\
  8664. end\
  8665. \
  8666. function stencil:removeLayer( l )\
  8667.     for i = 1, #self.layers do\
  8668.         if self.layers[i].id == l then\
  8669.             while self.layers[i] do\
  8670.                 table.remove( self.layers, i )\
  8671.             end\
  8672.         end\
  8673.     end\
  8674.     local t = self.layers\
  8675.     self.bounds = false\
  8676.     self.layers = {}\
  8677.     if #t > 0 then\
  8678.         for i = 1, #t do\
  8679.             self:newLayer( t[i].x, t[i].y, t[i].width, t[i].height )\
  8680.             self.layers[#self.layers].id = t[i].id\
  8681.             if not self.bounds.x then\
  8682.                 break\
  8683.             end\
  8684.         end\
  8685.     end\
  8686. end\
  8687. \
  8688. function stencil:getBounds( x, y, w, h )\
  8689.     if self.bounds then\
  8690.         if self.bounds.x then\
  8691.             return self.bounds.x, self.bounds.y, self.bounds.width, self.bounds.height\
  8692.         end\
  8693.         return false\
  8694.     end\
  8695.     return x or true, y, w, h\
  8696. end\
  8697. \
  8698. function stencil:clearLayers()\
  8699.     self.layers = {}\
  8700.     self.bounds = false\
  8701. end\
  8702. \
  8703. function stencil:withinBounds( px, py )\
  8704.     local x, y, w, h = self:getBounds()\
  8705.     if x == true then return true end\
  8706.     if x == false then return false end\
  8707.     return px >= x and px < x + w and py >= y and py < y + h\
  8708. end\
  8709. \
  8710. return stencil",
  8711.   [ "/rom/programs/fun/advanced/levels/7" ] = "3\
  8712. 728777778b7\
  8713. 78888888887\
  8714. 78777877787\
  8715. 787 787 787\
  8716. 787 7877788\
  8717. 787 7888889\
  8718. 88777877777\
  8719. e888887\
  8720. 7777887",
  8721.   [ "/rom/apis/term" ] = "\
  8722. local native = (term.native and term.native()) or term\
  8723. local redirectTarget = native\
  8724. \
  8725. local function wrap( _sFunction )\
  8726.     return function( ... )\
  8727.         return redirectTarget[ _sFunction ]( ... )\
  8728.     end\
  8729. end\
  8730. \
  8731. local term = {}\
  8732. \
  8733. term.redirect = function( target )\
  8734.     if target == nil or type( target ) ~= \"table\" then\
  8735.         error( \"Invalid redirect target\", 2 )\
  8736.     end\
  8737.    if target == term then\
  8738.        error( \"term is not a recommended redirect target, try term.current() instead\", 2 )\
  8739.    end\
  8740.     for k,v in pairs( native ) do\
  8741.         if type( k ) == \"string\" and type( v ) == \"function\" then\
  8742.             if type( target[k] ) ~= \"function\" then\
  8743.                 target[k] = function()\
  8744.                     error( \"Redirect object is missing method \"..k..\".\", 2 )\
  8745.                 end\
  8746.             end\
  8747.         end\
  8748.     end\
  8749.     local oldRedirectTarget = redirectTarget\
  8750.     redirectTarget = target\
  8751.     return oldRedirectTarget\
  8752. end\
  8753. \
  8754. term.current = function()\
  8755.    return redirectTarget\
  8756. end\
  8757. \
  8758. term.native = function()\
  8759.    -- NOTE: please don't use this function unless you have to.\
  8760.    -- If you're running in a redirected or multitasked enviorment, term.native() will NOT be\
  8761.    -- the current terminal when your program starts up. It is far better to use term.current()\
  8762.    return native\
  8763. end\
  8764. \
  8765. for k,v in pairs( native ) do\
  8766.     if type( k ) == \"string\" and type( v ) == \"function\" then\
  8767.         if term[k] == nil then\
  8768.             term[k] = wrap( k )\
  8769.         end\
  8770.     end\
  8771. end\
  8772.     \
  8773. local env = getfenv()\
  8774. for k,v in pairs( term ) do\
  8775.     env[k] = v\
  8776. end",
  8777.   [ "/Flare/version/1.2/module.lua" ] = "\
  8778. local modules = {\
  8779.     [\"core\"] = {\
  8780.         files = {\
  8781.             \"buffer\";\
  8782.             \"class\";\
  8783.             \"graphics\";\
  8784.             \"image\";\
  8785.             \"process\";\
  8786.             \"sha256\";\
  8787.             \"state\";\
  8788.             \"stencil\";\
  8789.             \"trace\";\
  8790.             \"tween\";\
  8791.             \"video\";\
  8792.             \"UI.animation\";\
  8793.             \"UI.base\";\
  8794.             \"UI.keybind\";\
  8795.             \"UI.draw.draw\";\
  8796.             \"UI.draw.image\";\
  8797.             \"UI.draw.pixel\";\
  8798.             \"UI.draw.pixelbatch\";\
  8799.             \"UI.draw.text\";\
  8800.             \"UI.event.Dispatcher\";\
  8801.             \"UI.event.Event\";\
  8802.             \"UI.event.mouse\";\
  8803.             \"UI.text.code\";\
  8804.             \"UI.text.formatter\";\
  8805.             \"UI.elements.Button\";\
  8806.             \"UI.elements.ClippingFrame\";\
  8807.             \"UI.elements.Field\";\
  8808.             \"UI.elements.Frame\";\
  8809.             \"UI.elements.Image\";\
  8810.             \"UI.elements.Input\";\
  8811.             \"UI.elements.ProgressBar\";\
  8812.             \"UI.elements.ScrollBar\";\
  8813.             \"UI.elements.Text\";\
  8814.         };\
  8815.     };\
  8816.     [\"application\"] = {\
  8817.         files = {\
  8818.             \"UI.elements.DropdownButton\";\
  8819.             \"page\";\
  8820.         };\
  8821.     };\
  8822. }\
  8823. \
  8824. local module = {}\
  8825. \
  8826. function module.isInstalled( name )\
  8827.     if modules[name] then\
  8828.         for i = 1, #modules[name].files do\
  8829.             if not fs.exists( FDK.lib_path .. \"/\" .. modules[name].files[i]:gsub( \"%.\", \"/\" ) .. \".lua\" ) then\
  8830.                 return false\
  8831.             end\
  8832.         end\
  8833.         return true\
  8834.     else\
  8835.         return error( (\"no such module %q\"):format( name ) )\
  8836.     end\
  8837. end\
  8838. \
  8839. function module.install( name )\
  8840.     if modules[name] then\
  8841.         if modules[name].pre then\
  8842.             modules[name].pre()\
  8843.         end\
  8844.         for i = 1, #modules[name].files do\
  8845.             print( \"Downloading \" .. modules[name].files[i] )\
  8846.             local file = modules[name].files[i]:gsub( \"%.\", \"/\" ) .. \".lua\"\
  8847.             local url = \"https://raw.githubusercontent.com/awsumben13/Flare/master/version/\" .. FDK.version.local_major() .. \"/module/\" .. textutils.urlEncode( name ) .. \"/\" .. textutils.urlEncode( file )\
  8848.             local h = http.get( url )\
  8849.             if h then\
  8850.                 local content = h.readAll()\
  8851.                 h.close()\
  8852. \
  8853.                 local h = fs.open( FDK.lib_path .. \"/\" .. file, \"w\" )\
  8854.                 if h then\
  8855.                     h.write( content )\
  8856.                     h.close()\
  8857.                 else\
  8858.                     print \"Install failed\"\
  8859.                     return false\
  8860.                 end\
  8861.             else\
  8862.                 print \"Download failed\"\
  8863.                 return false\
  8864.             end\
  8865.         end\
  8866.         if modules[name].post then\
  8867.             modules[name].post()\
  8868.         end\
  8869.         return true\
  8870.     else\
  8871.         return error( (\"no such module %q\"):format( name ) )\
  8872.     end\
  8873. end\
  8874. \
  8875. function module.shouldInstall( t )\
  8876.     for i = 1, #t do\
  8877.         if not module.isInstalled( t[i] ) then\
  8878.             module.install( t[i] )\
  8879.         end\
  8880.     end\
  8881. end\
  8882. \
  8883. return module",
  8884.   [ "/rom/apis/help" ] = "\
  8885. local sPath = \"/rom/help\"\
  8886. \
  8887. function path()\
  8888.     return sPath\
  8889. end\
  8890. \
  8891. function setPath( _sPath )\
  8892.     sPath = _sPath\
  8893. end\
  8894. \
  8895. function lookup( _sTopic )\
  8896.     -- Look on the path variable\
  8897.    for sPath in string.gmatch(sPath, \"[^:]+\") do\
  8898.         sPath = fs.combine( sPath, _sTopic )\
  8899.         if fs.exists( sPath ) and not fs.isDir( sPath ) then\
  8900.             return sPath\
  8901.         end\
  8902.    end\
  8903.     \
  8904.     -- Not found\
  8905.     return nil\
  8906. end\
  8907. \
  8908. function topics()\
  8909.     local tItems = {}\
  8910.     \
  8911.     -- Add topics from the path\
  8912.    for sPath in string.gmatch(sPath, \"[^:]+\") do\
  8913.         if fs.isDir( sPath ) then\
  8914.             local tList = fs.list( sPath )\
  8915.             for n,sFile in pairs( tList ) do\
  8916.                 if string.sub( sFile, 1, 1 ) ~= \".\" then\
  8917.                     if not fs.isDir( fs.combine( sPath, sFile ) ) then\
  8918.                         tItems[ sFile ] = true\
  8919.                     end\
  8920.                 end\
  8921.             end\
  8922.         end\
  8923.     end \
  8924. \
  8925.     -- Sort and return\
  8926.     local tItemList = {}\
  8927.     for sItem, b in pairs( tItems ) do\
  8928.         table.insert( tItemList, sItem )\
  8929.     end\
  8930.     table.sort( tItemList )\
  8931.     return tItemList\
  8932. end",
  8933.   [ "/rom/programs/reboot" ] = "if term.isColour() then\
  8934.     term.setTextColour( colours.yellow )\
  8935. end\
  8936. print( \"Goodbye\" )\
  8937. term.setTextColour( colours.white )\
  8938. \
  8939. sleep( 1 )\
  8940. os.reboot()",
  8941.   [ "/rom/help/bundled" ] = "To set bundled outputs:\
  8942. c = colors.combine( colors.red, colors.blue )\
  8943. rs.setBundledOutput( \"left\", c )\
  8944. \
  8945. c = colors.combine( c, colors.green )\
  8946. rs.setBundledOutput( \"left\", c )\
  8947. \
  8948. c = colors.subtract( c, colors.blue )\
  8949. rs.setBundledOutput( \"left\", c )\
  8950. \
  8951. To get bundled inputs:\
  8952. c = rs.getBundledInput( \"right\" )\
  8953. red = colors.test( c, colors.red )\
  8954. \
  8955. Type \"help colors\" for the list of wire colors.",
  8956.   [ "/rom/help/multishell" ] = "multishell is the toplevel program on Advanced Computers which manages background tabs.\
  8957. Type \"help shellapi\" for information about the shell lua api.",
  8958.   [ "/rom/help/delete" ] = "rm deletes a file or a directory and its contents.\
  8959. \
  8960. ex:\
  8961. \"rm foo\" will delete the file foo.\
  8962. \"rm disk/*\" will delete the contents of a disk.",
  8963.   [ "/rom/help/mkdir" ] = "mkdir creates a directory in the current location.\
  8964. \
  8965. ex:\
  8966. \"mkdir foo\" creates a directory named \"foo\".\
  8967. \"mkdir ../foo\" creates a directory named \"foo\" in the directory above the current directory.",
  8968.   [ "/rom/help/help" ] = "help is the help tool you're currently using.\
  8969. Type \"help index\" to see all help topics.\
  8970. Type \"help\" to see the help intro.\
  8971. Type \"help helpapi\" for information on the help Lua API.",
  8972.   [ "/rom/help/helpapi" ] = "Functions in the help API:\
  8973. help.setPath( path )\
  8974. help.lookup( topic )\
  8975. help.topics()",
  8976.   [ "/rom/help/gps" ] = "gps can be used to host a GPS server, or to determine a position using trilateration.\
  8977. Type \"help gpsapi\" for help using GPS functions in lua programs.\
  8978. \
  8979. ex:\
  8980. \"gps locate\" will connect to nearby GPS servers, and try to determine the position of the computer or turtle.\
  8981. \"gps host\" will try to determine the position, and host a GPS server if successful.\
  8982. \"gps host 10 20 30\" will host a GPS server, using the manually entered position 10,20,30. \
  8983. \
  8984. Take care when manually entering host positions. If the positions entered into multiple GPS hosts\
  8985. are not consistent, the results of locate calls will be incorrect.",
  8986.   [ "/rom/programs/fun/advanced/levels/6" ] = "4\
  8987. 7777777777\
  8988. 7288888837\
  8989. 78      87\
  8990. 788888b 87\
  8991. 788888b 87\
  8992. 788888b 87\
  8993. 788888b 87\
  8994. 78      87\
  8995. 7188888807\
  8996. 7777777777",
  8997.   [ "/Flare/version/1.2/lib/tween.lua" ] = "local tween = {\
  8998.  _VERSION     = 'tween 2.0.0',\
  8999.  _DESCRIPTION = 'tweening for lua',\
  9000.  _URL         = 'https://github.com/kikito/tween.lua',\
  9001.  _LICENSE     = \"\"\
  9002. }\
  9003. \
  9004. -- easing\
  9005. \
  9006. -- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for credits.\
  9007. -- For all easing functions:\
  9008. -- t = time == how much time has to pass for the tweening to complete\
  9009. -- b = begin == starting property value\
  9010. -- c = change == ending - beginning\
  9011. -- d = duration == running time. How much time has passed *right now*\
  9012. \
  9013. local math, assert, tostring, type = math, assert, tostring, type\
  9014. local pow, sin, cos, pi, sqrt, abs, asin = math.pow, math.sin, math.cos, math.pi, math.sqrt, math.abs, math.asin\
  9015. \
  9016. -- linear\
  9017. local function linear(t, b, c, d) return c * t / d + b end\
  9018. \
  9019. -- quad\
  9020. local function inQuad(t, b, c, d) return c * pow(t / d, 2) + b end\
  9021. local function outQuad(t, b, c, d)\
  9022.  t = t / d\
  9023.  return -c * t * (t - 2) + b\
  9024. end\
  9025. local function inOutQuad(t, b, c, d)\
  9026.  t = t / d * 2\
  9027.  if t < 1 then return c / 2 * pow(t, 2) + b end\
  9028.  return -c / 2 * ((t - 1) * (t - 3) - 1) + b\
  9029. end\
  9030. local function outInQuad(t, b, c, d)\
  9031.  if t < d / 2 then return outQuad(t * 2, b, c / 2, d) end\
  9032.  return inQuad((t * 2) - d, b + c / 2, c / 2, d)\
  9033. end\
  9034. \
  9035. -- cubic\
  9036. local function inCubic (t, b, c, d) return c * pow(t / d, 3) + b end\
  9037. local function outCubic(t, b, c, d) return c * (pow(t / d - 1, 3) + 1) + b end\
  9038. local function inOutCubic(t, b, c, d)\
  9039.  t = t / d * 2\
  9040.  if t < 1 then return c / 2 * t * t * t + b end\
  9041.  t = t - 2\
  9042.  return c / 2 * (t * t * t + 2) + b\
  9043. end\
  9044. local function outInCubic(t, b, c, d)\
  9045.  if t < d / 2 then return outCubic(t * 2, b, c / 2, d) end\
  9046.  return inCubic((t * 2) - d, b + c / 2, c / 2, d)\
  9047. end\
  9048. \
  9049. -- quart\
  9050. local function inQuart(t, b, c, d) return c * pow(t / d, 4) + b end\
  9051. local function outQuart(t, b, c, d) return -c * (pow(t / d - 1, 4) - 1) + b end\
  9052. local function inOutQuart(t, b, c, d)\
  9053.  t = t / d * 2\
  9054.  if t < 1 then return c / 2 * pow(t, 4) + b end\
  9055.  return -c / 2 * (pow(t - 2, 4) - 2) + b\
  9056. end\
  9057. local function outInQuart(t, b, c, d)\
  9058.  if t < d / 2 then return outQuart(t * 2, b, c / 2, d) end\
  9059.  return inQuart((t * 2) - d, b + c / 2, c / 2, d)\
  9060. end\
  9061. \
  9062. -- quint\
  9063. local function inQuint(t, b, c, d) return c * pow(t / d, 5) + b end\
  9064. local function outQuint(t, b, c, d) return c * (pow(t / d - 1, 5) + 1) + b end\
  9065. local function inOutQuint(t, b, c, d)\
  9066.  t = t / d * 2\
  9067.  if t < 1 then return c / 2 * pow(t, 5) + b end\
  9068.  return c / 2 * (pow(t - 2, 5) + 2) + b\
  9069. end\
  9070. local function outInQuint(t, b, c, d)\
  9071.  if t < d / 2 then return outQuint(t * 2, b, c / 2, d) end\
  9072.  return inQuint((t * 2) - d, b + c / 2, c / 2, d)\
  9073. end\
  9074. \
  9075. -- sine\
  9076. local function inSine(t, b, c, d) return -c * cos(t / d * (pi / 2)) + c + b end\
  9077. local function outSine(t, b, c, d) return c * sin(t / d * (pi / 2)) + b end\
  9078. local function inOutSine(t, b, c, d) return -c / 2 * (cos(pi * t / d) - 1) + b end\
  9079. local function outInSine(t, b, c, d)\
  9080.  if t < d / 2 then return outSine(t * 2, b, c / 2, d) end\
  9081.  return inSine((t * 2) -d, b + c / 2, c / 2, d)\
  9082. end\
  9083. \
  9084. -- expo\
  9085. local function inExpo(t, b, c, d)\
  9086.  if t == 0 then return b end\
  9087.  return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001\
  9088. end\
  9089. local function outExpo(t, b, c, d)\
  9090.  if t == d then return b + c end\
  9091.  return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b\
  9092. end\
  9093. local function inOutExpo(t, b, c, d)\
  9094.  if t == 0 then return b end\
  9095.  if t == d then return b + c end\
  9096.  t = t / d * 2\
  9097.  if t < 1 then return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005 end\
  9098.  return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b\
  9099. end\
  9100. local function outInExpo(t, b, c, d)\
  9101.  if t < d / 2 then return outExpo(t * 2, b, c / 2, d) end\
  9102.  return inExpo((t * 2) - d, b + c / 2, c / 2, d)\
  9103. end\
  9104. \
  9105. -- circ\
  9106. local function inCirc(t, b, c, d) return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b) end\
  9107. local function outCirc(t, b, c, d)  return(c * sqrt(1 - pow(t / d - 1, 2)) + b) end\
  9108. local function inOutCirc(t, b, c, d)\
  9109.  t = t / d * 2\
  9110.  if t < 1 then return -c / 2 * (sqrt(1 - t * t) - 1) + b end\
  9111.  t = t - 2\
  9112.  return c / 2 * (sqrt(1 - t * t) + 1) + b\
  9113. end\
  9114. local function outInCirc(t, b, c, d)\
  9115.  if t < d / 2 then return outCirc(t * 2, b, c / 2, d) end\
  9116.  return inCirc((t * 2) - d, b + c / 2, c / 2, d)\
  9117. end\
  9118. \
  9119. -- elastic\
  9120. local function calculatePAS(p,a,c,d)\
  9121.  p, a = p or d * 0.3, a or 0\
  9122.  if a < abs(c) then return p, c, p / 4 end -- p, a, s\
  9123.  return p, a, p / (2 * pi) * asin(c/a) -- p,a,s\
  9124. end\
  9125. local function inElastic(t, b, c, d, a, p)\
  9126.  local s\
  9127.  if t == 0 then return b end\
  9128.  t = t / d\
  9129.  if t == 1  then return b + c end\
  9130.  p,a,s = calculatePAS(p,a,c,d)\
  9131.  t = t - 1\
  9132.  return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b\
  9133. end\
  9134. local function outElastic(t, b, c, d, a, p)\
  9135.  local s\
  9136.  if t == 0 then return b end\
  9137.  t = t / d\
  9138.  if t == 1 then return b + c end\
  9139.  p,a,s = calculatePAS(p,a,c,d)\
  9140.  return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b\
  9141. end\
  9142. local function inOutElastic(t, b, c, d, a, p)\
  9143.  local s\
  9144.  if t == 0 then return b end\
  9145.  t = t / d * 2\
  9146.  if t == 2 then return b + c end\
  9147.  p,a,s = calculatePAS(p,a,c,d)\
  9148.  t = t - 1\
  9149.  if t < 0 then return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b end\
  9150.  return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b\
  9151. end\
  9152. local function outInElastic(t, b, c, d, a, p)\
  9153.  if t < d / 2 then return outElastic(t * 2, b, c / 2, d, a, p) end\
  9154.  return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)\
  9155. end\
  9156. \
  9157. -- back\
  9158. local function inBack(t, b, c, d, s)\
  9159.  s = s or 1.70158\
  9160.  t = t / d\
  9161.  return c * t * t * ((s + 1) * t - s) + b\
  9162. end\
  9163. local function outBack(t, b, c, d, s)\
  9164.  s = s or 1.70158\
  9165.  t = t / d - 1\
  9166.  return c * (t * t * ((s + 1) * t + s) + 1) + b\
  9167. end\
  9168. local function inOutBack(t, b, c, d, s)\
  9169.  s = (s or 1.70158) * 1.525\
  9170.  t = t / d * 2\
  9171.  if t < 1 then return c / 2 * (t * t * ((s + 1) * t - s)) + b end\
  9172.  t = t - 2\
  9173.  return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b\
  9174. end\
  9175. local function outInBack(t, b, c, d, s)\
  9176.  if t < d / 2 then return outBack(t * 2, b, c / 2, d, s) end\
  9177.  return inBack((t * 2) - d, b + c / 2, c / 2, d, s)\
  9178. end\
  9179. \
  9180. -- bounce\
  9181. local function outBounce(t, b, c, d)\
  9182.  t = t / d\
  9183.  if t < 1 / 2.75 then return c * (7.5625 * t * t) + b end\
  9184.  if t < 2 / 2.75 then\
  9185.    t = t - (1.5 / 2.75)\
  9186.    return c * (7.5625 * t * t + 0.75) + b\
  9187.  elseif t < 2.5 / 2.75 then\
  9188.    t = t - (2.25 / 2.75)\
  9189.    return c * (7.5625 * t * t + 0.9375) + b\
  9190.  end\
  9191.  t = t - (2.625 / 2.75)\
  9192.  return c * (7.5625 * t * t + 0.984375) + b\
  9193. end\
  9194. local function inBounce(t, b, c, d) return c - outBounce(d - t, 0, c, d) + b end\
  9195. local function inOutBounce(t, b, c, d)\
  9196.  if t < d / 2 then return inBounce(t * 2, 0, c, d) * 0.5 + b end\
  9197.  return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b\
  9198. end\
  9199. local function outInBounce(t, b, c, d)\
  9200.  if t < d / 2 then return outBounce(t * 2, b, c / 2, d) end\
  9201.  return inBounce((t * 2) - d, b + c / 2, c / 2, d)\
  9202. end\
  9203. \
  9204. tween.easing = {\
  9205.  linear    = linear,\
  9206.  inQuad    = inQuad,    outQuad    = outQuad,    inOutQuad    = inOutQuad,    outInQuad    = outInQuad,\
  9207.  inCubic   = inCubic,   outCubic   = outCubic,   inOutCubic   = inOutCubic,   outInCubic   = outInCubic,\
  9208.  inQuart   = inQuart,   outQuart   = outQuart,   inOutQuart   = inOutQuart,   outInQuart   = outInQuart,\
  9209.  inQuint   = inQuint,   outQuint   = outQuint,   inOutQuint   = inOutQuint,   outInQuint   = outInQuint,\
  9210.  inSine    = inSine,    outSine    = outSine,    inOutSine    = inOutSine,    outInSine    = outInSine,\
  9211.  inExpo    = inExpo,    outExpo    = outExpo,    inOutExpo    = inOutExpo,    outInExpo    = outInExpo,\
  9212.  inCirc    = inCirc,    outCirc    = outCirc,    inOutCirc    = inOutCirc,    outInCirc    = outInCirc,\
  9213.  inElastic = inElastic, outElastic = outElastic, inOutElastic = inOutElastic, outInElastic = outInElastic,\
  9214.  inBack    = inBack,    outBack    = outBack,    inOutBack    = inOutBack,    outInBack    = outInBack,\
  9215.  inBounce  = inBounce,  outBounce  = outBounce,  inOutBounce  = inOutBounce,  outInBounce  = outInBounce\
  9216. }\
  9217. \
  9218. \
  9219. \
  9220. -- private stuff\
  9221. \
  9222. local function copyTables(destination, keysTable, valuesTable)\
  9223.  valuesTable = valuesTable or keysTable\
  9224.  local mt = getmetatable(keysTable)\
  9225.  if mt and getmetatable(destination) == nil then\
  9226.    setmetatable(destination, mt)\
  9227.  end\
  9228.  for k,v in pairs(keysTable) do\
  9229.    if type(v) == 'table' then\
  9230.      destination[k] = copyTables({}, v, valuesTable[k])\
  9231.    else\
  9232.      destination[k] = valuesTable[k]\
  9233.    end\
  9234.  end\
  9235.  return destination\
  9236. end\
  9237. \
  9238. local function checkSubjectAndTargetRecursively(subject, target, path)\
  9239.  path = path or {}\
  9240.  local targetType, newPath\
  9241.  for k,targetValue in pairs(target) do\
  9242.    targetType, newPath = type(targetValue), copyTables({}, path)\
  9243.    table.insert(newPath, tostring(k))\
  9244.    if targetType == 'number' then\
  9245.      assert(type(subject[k]) == 'number', \"Parameter '\" .. table.concat(newPath,'/') .. \"' is missing from subject or isn't a number\")\
  9246.    elseif targetType == 'table' then\
  9247.      checkSubjectAndTargetRecursively(subject[k], targetValue, newPath)\
  9248.    else\
  9249.      assert(targetType == 'number', \"Parameter '\" .. table.concat(newPath,'/') .. \"' must be a number or table of numbers\")\
  9250.    end\
  9251.  end\
  9252. end\
  9253. \
  9254. local function checkNewParams(duration, subject, target, easing)\
  9255.  assert(type(duration) == 'number' and duration > 0, \"duration must be a positive number. Was \" .. tostring(duration))\
  9256.  local tsubject = type(subject)\
  9257.  assert(tsubject == 'table' or tsubject == 'userdata', \"subject must be a table or userdata. Was \" .. tostring(subject))\
  9258.  assert(type(target)== 'table', \"target must be a table. Was \" .. tostring(target))\
  9259.  assert(type(easing)=='function', \"easing must be a function. Was \" .. tostring(easing))\
  9260.  checkSubjectAndTargetRecursively(subject, target)\
  9261. end\
  9262. \
  9263. local function getEasingFunction(easing)\
  9264.  easing = easing or \"linear\"\
  9265.  if type(easing) == 'string' then\
  9266.    local name = easing\
  9267.    easing = tween.easing[name]\
  9268.    if type(easing) ~= 'function' then\
  9269.      error(\"The easing function name '\" .. name .. \"' is invalid\")\
  9270.    end\
  9271.  end\
  9272.  return easing\
  9273. end\
  9274. \
  9275. local function performEasingOnSubject(subject, target, initial, clock, duration, easing, round)\
  9276.  local t,b,c,d\
  9277.  for k,v in pairs(target) do\
  9278.    if type(v) == 'table' then\
  9279.      performEasingOnSubject(subject[k], v, initial[k], clock, duration, easing)\
  9280.    else\
  9281.      t,b,c,d = clock, initial[k], v - initial[k], duration\
  9282.      if round then\
  9283.        subject[k] = math.floor( easing(t,b,c,d) + 0.5 )\
  9284.      else\
  9285.        subject[k] = easing(t,b,c,d)\
  9286.      end\
  9287.    end\
  9288.  end\
  9289. end\
  9290. \
  9291. -- Tween methods\
  9292. \
  9293. local Tween = {}\
  9294. local Tween_mt = {__index = Tween}\
  9295. \
  9296. function Tween:set(clock)\
  9297.  assert(type(clock) == 'number', \"clock must be a positive number or 0\")\
  9298. \
  9299.  self.clock = clock\
  9300. \
  9301.  if self.clock <= 0 then\
  9302. \
  9303.    self.clock = 0\
  9304.    copyTables(self.subject, self.initial)\
  9305. \
  9306.  elseif self.clock >= self.duration then -- the tween has expired\
  9307. \
  9308.    self.clock = self.duration\
  9309.    copyTables(self.subject, self.target)\
  9310. \
  9311.  else\
  9312. \
  9313.    performEasingOnSubject(self.subject, self.target, self.initial, self.clock, self.duration, self.easing, self.round)\
  9314. \
  9315.  end\
  9316. \
  9317.  return self.clock >= self.duration\
  9318. end\
  9319. \
  9320. function Tween:reset()\
  9321.  return self:set(0)\
  9322. end\
  9323. \
  9324. function Tween:update(dt)\
  9325.  assert(type(dt) == 'number', \"dt must be a number\")\
  9326.  return self:set(self.clock + dt)\
  9327. end\
  9328. \
  9329. function Tween:isFinished()\
  9330.  return self.clock >= self.duration\
  9331. end\
  9332. \
  9333. function Tween:run()\
  9334.  local time = os.clock()\
  9335.  while not self:isFinished() do\
  9336.    self:update( os.clock() - time )\
  9337.    time = os.clock()\
  9338.    coroutine.yield()\
  9339.  end\
  9340. end\
  9341. \
  9342. -- Public interface\
  9343. \
  9344. function tween.new(duration, subject, target, easing)\
  9345.  easing = getEasingFunction(easing)\
  9346.  checkNewParams(duration, subject, target, easing)\
  9347.  return setmetatable({\
  9348.    duration  = duration,\
  9349.    subject   = subject,\
  9350.    target    = target,\
  9351.    easing    = easing,\
  9352. \
  9353.    initial   = copyTables({},target,subject),\
  9354.    clock     = 0\
  9355.  }, Tween_mt)\
  9356. end\
  9357. \
  9358. return tween",
  9359.   [ "/rom/help/term" ] = "Functions in the Terminal API:\
  9360. term.write( text )\
  9361. term.clear()\
  9362. term.clearLine()\
  9363. term.getCursorPos()\
  9364. term.setCursorPos( x, y )\
  9365. term.setCursorBlink( blink )\
  9366. term.isColor()\
  9367. term.setTextColor( color )\
  9368. term.setBackgroundColor( color )\
  9369. term.getSize()\
  9370. term.scroll( n )\
  9371. term.redirect( object )\
  9372. term.current()\
  9373. \
  9374. Events emitted by the terminals:\
  9375. \"term_resize\", when the size of a terminal changes. This can happen in multitasking environments, or when the terminal out is being redirected by the \"monitor\" program.",
  9376.   [ "/Flare/version/1.2/lib/image.lua" ] = "\
  9377. local colour = {}\
  9378. \
  9379. colour.lookup = {\
  9380.     [\"0\"] = colours.white;\
  9381.     [\"1\"] = colours.orange;\
  9382.     [\"2\"] = colours.magenta;\
  9383.     [\"3\"] = colours.lightBlue;\
  9384.     [\"4\"] = colours.yellow;\
  9385.     [\"5\"] = colours.lime;\
  9386.     [\"6\"] = colours.pink;\
  9387.     [\"7\"] = colours.grey;\
  9388.     [\"8\"] = colours.lightGrey;\
  9389.     [\"9\"] = colours.cyan;\
  9390.     [\"A\"] = colours.purple;\
  9391.     [\"B\"] = colours.blue;\
  9392.     [\"C\"] = colours.brown;\
  9393.     [\"D\"] = colours.green;\
  9394.     [\"E\"] = colours.red;\
  9395.     [\"F\"] = colours.black;\
  9396.     [\" \"] = 0;\
  9397. }\
  9398. \
  9399. colour.save = {}\
  9400. for k, v in pairs( colour.lookup ) do\
  9401.     colour.save[v] = k\
  9402. end\
  9403. \
  9404. local image = {}\
  9405. \
  9406. image.colour = colour\
  9407. \
  9408. function image:new( width, height )\
  9409. \
  9410.     local i = {}\
  9411. \
  9412.     i.width = width or 0\
  9413.     i.height = height or 0\
  9414. \
  9415.     i.pixels = {}\
  9416. \
  9417.     for y = 1, height or 0 do\
  9418.         i.pixels[y] = {}\
  9419.         for x = 1, width or 0 do\
  9420.             i.pixels[y][x] = { bc = 0, tc = 0, char = \"\" }\
  9421.         end\
  9422.     end\
  9423. \
  9424.     setmetatable( i, { __index = self, __type = \"image\" } )\
  9425.     return i\
  9426. \
  9427. end\
  9428. \
  9429. function image:setPixel( x, y, bc, tc, char )\
  9430.     if self.pixels[y] and self.pixels[y][x] then\
  9431.         self.pixels[y][x] = {\
  9432.             bc = bc;\
  9433.             tc = tc;\
  9434.             char = char;\
  9435.         }\
  9436.     end\
  9437. end\
  9438. \
  9439. function image:getPixel( x, y )\
  9440.     if self.pixels[y] and self.pixels[y][x] then\
  9441.         return self.pixels[y][x].bc, self.pixels[y][x].tc, self.pixels[y][x].char\
  9442.     end\
  9443. end\
  9444. \
  9445. function image:save()\
  9446.     local str = \"\"\
  9447.     for y = 1, self.height do\
  9448.         for x = 1, self.width do\
  9449.             local bc, tc, char = self:getPixel( x, y )\
  9450.             bc = colour.save[bc]\
  9451.             tc = colour.save[tc]\
  9452.             if #char == 0 then\
  9453.                 char = \" \"\
  9454.                 bc = colours.save[0]\
  9455.             end\
  9456.             str = str .. bc .. tc .. char\
  9457.         end\
  9458.         str = str .. \"\\n\"\
  9459.     end\
  9460.     return str:sub( 1, -2 )\
  9461. end\
  9462. \
  9463. function image:clone()\
  9464.     local new = image:new( self.width, self.height )\
  9465.     for x = 1, self.width do\
  9466.         for y = 1, self.height do\
  9467.             new:setPixel( x, y, self:getPixel( x, y ) )\
  9468.         end\
  9469.     end\
  9470.     return new\
  9471. end\
  9472. \
  9473. function image.load( str )\
  9474.     local lines = {}\
  9475.     local last = 1\
  9476.     for i = 1, #str do\
  9477.         if str:sub( i, i ) == \"\\n\" then\
  9478.             table.insert( lines, str:sub( last, i - 1 ) )\
  9479.             last = i + 1\
  9480.         end\
  9481.     end\
  9482.     table.insert( lines, str:sub( last ) )\
  9483.     local width = #lines[1] / 3\
  9484.     local height = #lines\
  9485.     local frame = image:new( width, height )\
  9486.     for i = 1, #lines do\
  9487.         local x = 1\
  9488.         for pixel in lines[i]:gmatch( \"[0123456789ABCDEF ][0123456789ABCDEF ].\" ) do\
  9489.             local bc = colour.lookup[pixel:sub( 1, 1 )]\
  9490.             local tc = colour.lookup[pixel:sub( 2, 2 )]\
  9491.             local ch = pixel:sub( 3, 3 )\
  9492.             frame:setPixel( x, i, bc, tc, ch )\
  9493.             x = x + 1\
  9494.         end\
  9495.     end\
  9496.     return frame\
  9497. end\
  9498. \
  9499. return image",
  9500.   [ "/rom/programs/turtle/excavate" ] = "\
  9501. local tArgs = { ... }\
  9502. if #tArgs ~= 1 then\
  9503.     print( \"Usage: excavate <diameter>\" )\
  9504.     return\
  9505. end\
  9506. \
  9507. -- Mine in a quarry pattern until we hit something we can't dig\
  9508. local size = tonumber( tArgs[1] )\
  9509. if size < 1 then\
  9510.     print( \"Excavate diameter must be positive\" )\
  9511.     return\
  9512. end\
  9513.     \
  9514. local depth = 0\
  9515. local unloaded = 0\
  9516. local collected = 0\
  9517. \
  9518. local xPos,zPos = 0,0\
  9519. local xDir,zDir = 0,1\
  9520. \
  9521. local goTo -- Filled in further down\
  9522. local refuel -- Filled in further down\
  9523. \
  9524. local function unload( _bKeepOneFuelStack )\
  9525.     print( \"Unloading items...\" )\
  9526.     for n=1,16 do\
  9527.         local nCount = turtle.getItemCount(n)\
  9528.         if nCount > 0 then\
  9529.             turtle.select(n)            \
  9530.             local bDrop = true\
  9531.             if _bKeepOneFuelStack and turtle.refuel(0) then\
  9532.                 bDrop = false\
  9533.                 _bKeepOneFuelStack = false\
  9534.             end         \
  9535.             if bDrop then\
  9536.                 turtle.drop()\
  9537.                 unloaded = unloaded + nCount\
  9538.             end\
  9539.         end\
  9540.     end\
  9541.     collected = 0\
  9542.     turtle.select(1)\
  9543. end\
  9544. \
  9545. local function returnSupplies()\
  9546.     local x,y,z,xd,zd = xPos,depth,zPos,xDir,zDir\
  9547.     print( \"Returning to surface...\" )\
  9548.     goTo( 0,0,0,0,-1 )\
  9549.     \
  9550.     local fuelNeeded = 2*(x+y+z) + 1\
  9551.     if not refuel( fuelNeeded ) then\
  9552.         unload( true )\
  9553.         print( \"Waiting for fuel\" )\
  9554.         while not refuel( fuelNeeded ) do\
  9555.             os.pullEvent( \"turtle_inventory\" )\
  9556.         end\
  9557.     else\
  9558.         unload( true )  \
  9559.     end\
  9560.     \
  9561.     print( \"Resuming mining...\" )\
  9562.     goTo( x,y,z,xd,zd )\
  9563. end\
  9564. \
  9565. local function collect()    \
  9566.     local bFull = true\
  9567.     local nTotalItems = 0\
  9568.     for n=1,16 do\
  9569.         local nCount = turtle.getItemCount(n)\
  9570.         if nCount == 0 then\
  9571.             bFull = false\
  9572.         end\
  9573.         nTotalItems = nTotalItems + nCount\
  9574.     end\
  9575.     \
  9576.     if nTotalItems > collected then\
  9577.         collected = nTotalItems\
  9578.         if math.fmod(collected + unloaded, 50) == 0 then\
  9579.             print( \"Mined \"..(collected + unloaded)..\" items.\" )\
  9580.         end\
  9581.     end\
  9582.     \
  9583.     if bFull then\
  9584.         print( \"No empty slots left.\" )\
  9585.         return false\
  9586.     end\
  9587.     return true\
  9588. end\
  9589. \
  9590. function refuel( ammount )\
  9591.     local fuelLevel = turtle.getFuelLevel()\
  9592.     if fuelLevel == \"unlimited\" then\
  9593.         return true\
  9594.     end\
  9595.     \
  9596.     local needed = ammount or (xPos + zPos + depth + 2)\
  9597.     if turtle.getFuelLevel() < needed then\
  9598.         local fueled = false\
  9599.         for n=1,16 do\
  9600.             if turtle.getItemCount(n) > 0 then\
  9601.                 turtle.select(n)\
  9602.                 if turtle.refuel(1) then\
  9603.                     while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do\
  9604.                         turtle.refuel(1)\
  9605.                     end\
  9606.                     if turtle.getFuelLevel() >= needed then\
  9607.                         turtle.select(1)\
  9608.                         return true\
  9609.                     end\
  9610.                 end\
  9611.             end\
  9612.         end\
  9613.         turtle.select(1)\
  9614.         return false\
  9615.     end\
  9616.     \
  9617.     return true\
  9618. end\
  9619. \
  9620. local function tryForwards()\
  9621.     if not refuel() then\
  9622.         print( \"Not enough Fuel\" )\
  9623.         returnSupplies()\
  9624.     end\
  9625.     \
  9626.     while not turtle.forward() do\
  9627.         if turtle.detect() then\
  9628.             if turtle.dig() then\
  9629.                 if not collect() then\
  9630.                     returnSupplies()\
  9631.                 end\
  9632.             else\
  9633.                 return false\
  9634.             end\
  9635.         elseif turtle.attack() then\
  9636.             if not collect() then\
  9637.                 returnSupplies()\
  9638.             end\
  9639.         else\
  9640.             sleep( 0.5 )\
  9641.         end\
  9642.     end\
  9643.     \
  9644.     xPos = xPos + xDir\
  9645.     zPos = zPos + zDir\
  9646.     return true\
  9647. end\
  9648. \
  9649. local function tryDown()\
  9650.     if not refuel() then\
  9651.         print( \"Not enough Fuel\" )\
  9652.         returnSupplies()\
  9653.     end\
  9654.     \
  9655.     while not turtle.down() do\
  9656.         if turtle.detectDown() then\
  9657.             if turtle.digDown() then\
  9658.                 if not collect() then\
  9659.                     returnSupplies()\
  9660.                 end\
  9661.             else\
  9662.                 return false\
  9663.             end\
  9664.         elseif turtle.attackDown() then\
  9665.             if not collect() then\
  9666.                 returnSupplies()\
  9667.             end\
  9668.         else\
  9669.             sleep( 0.5 )\
  9670.         end\
  9671.     end\
  9672. \
  9673.     depth = depth + 1\
  9674.     if math.fmod( depth, 10 ) == 0 then\
  9675.         print( \"Descended \"..depth..\" metres.\" )\
  9676.     end\
  9677. \
  9678.     return true\
  9679. end\
  9680. \
  9681. local function turnLeft()\
  9682.     turtle.turnLeft()\
  9683.     xDir, zDir = -zDir, xDir\
  9684. end\
  9685. \
  9686. local function turnRight()\
  9687.     turtle.turnRight()\
  9688.     xDir, zDir = zDir, -xDir\
  9689. end\
  9690. \
  9691. function goTo( x, y, z, xd, zd )\
  9692.     while depth > y do\
  9693.         if turtle.up() then\
  9694.             depth = depth - 1\
  9695.         elseif turtle.digUp() or turtle.attackUp() then\
  9696.             collect()\
  9697.         else\
  9698.             sleep( 0.5 )\
  9699.         end\
  9700.     end\
  9701. \
  9702.     if xPos > x then\
  9703.         while xDir ~= -1 do\
  9704.             turnLeft()\
  9705.         end\
  9706.         while xPos > x do\
  9707.             if turtle.forward() then\
  9708.                 xPos = xPos - 1\
  9709.             elseif turtle.dig() or turtle.attack() then\
  9710.                 collect()\
  9711.             else\
  9712.                 sleep( 0.5 )\
  9713.             end\
  9714.         end\
  9715.     elseif xPos < x then\
  9716.         while xDir ~= 1 do\
  9717.             turnLeft()\
  9718.         end\
  9719.         while xPos < x do\
  9720.             if turtle.forward() then\
  9721.                 xPos = xPos + 1\
  9722.             elseif turtle.dig() or turtle.attack() then\
  9723.                 collect()\
  9724.             else\
  9725.                 sleep( 0.5 )\
  9726.             end\
  9727.         end\
  9728.     end\
  9729.     \
  9730.     if zPos > z then\
  9731.         while zDir ~= -1 do\
  9732.             turnLeft()\
  9733.         end\
  9734.         while zPos > z do\
  9735.             if turtle.forward() then\
  9736.                 zPos = zPos - 1\
  9737.             elseif turtle.dig() or turtle.attack() then\
  9738.                 collect()\
  9739.             else\
  9740.                 sleep( 0.5 )\
  9741.             end\
  9742.         end\
  9743.     elseif zPos < z then\
  9744.         while zDir ~= 1 do\
  9745.             turnLeft()\
  9746.         end\
  9747.         while zPos < z do\
  9748.             if turtle.forward() then\
  9749.                 zPos = zPos + 1\
  9750.             elseif turtle.dig() or turtle.attack() then\
  9751.                 collect()\
  9752.             else\
  9753.                 sleep( 0.5 )\
  9754.             end\
  9755.         end \
  9756.     end\
  9757.     \
  9758.     while depth < y do\
  9759.         if turtle.down() then\
  9760.             depth = depth + 1\
  9761.         elseif turtle.digDown() or turtle.attackDown() then\
  9762.             collect()\
  9763.         else\
  9764.             sleep( 0.5 )\
  9765.         end\
  9766.     end\
  9767.     \
  9768.     while zDir ~= zd or xDir ~= xd do\
  9769.         turnLeft()\
  9770.     end\
  9771. end\
  9772. \
  9773. if not refuel() then\
  9774.     print( \"Out of Fuel\" )\
  9775.     return\
  9776. end\
  9777. \
  9778. print( \"Excavating...\" )\
  9779. \
  9780. local reseal = false\
  9781. turtle.select(1)\
  9782. if turtle.digDown() then\
  9783.     reseal = true\
  9784. end\
  9785. \
  9786. local alternate = 0\
  9787. local done = false\
  9788. while not done do\
  9789.     for n=1,size do\
  9790.         for m=1,size-1 do\
  9791.             if not tryForwards() then\
  9792.                 done = true\
  9793.                 break\
  9794.             end\
  9795.         end\
  9796.         if done then\
  9797.             break\
  9798.         end\
  9799.         if n<size then\
  9800.             if math.fmod(n + alternate,2) == 0 then\
  9801.                 turnLeft()\
  9802.                 if not tryForwards() then\
  9803.                     done = true\
  9804.                     break\
  9805.                 end\
  9806.                 turnLeft()\
  9807.             else\
  9808.                 turnRight()\
  9809.                 if not tryForwards() then\
  9810.                     done = true\
  9811.                     break\
  9812.                 end\
  9813.                 turnRight()\
  9814.             end\
  9815.         end\
  9816.     end\
  9817.     if done then\
  9818.         break\
  9819.     end\
  9820.     \
  9821.     if size > 1 then\
  9822.         if math.fmod(size,2) == 0 then\
  9823.             turnRight()\
  9824.         else\
  9825.             if alternate == 0 then\
  9826.                 turnLeft()\
  9827.             else\
  9828.                 turnRight()\
  9829.             end\
  9830.             alternate = 1 - alternate\
  9831.         end\
  9832.     end\
  9833.     \
  9834.     if not tryDown() then\
  9835.         done = true\
  9836.         break\
  9837.     end\
  9838. end\
  9839. \
  9840. print( \"Returning to surface...\" )\
  9841. \
  9842. -- Return to where we started\
  9843. goTo( 0,0,0,0,-1 )\
  9844. unload( false )\
  9845. goTo( 0,0,0,0,1 )\
  9846. \
  9847. -- Seal the hole\
  9848. if reseal then\
  9849.     turtle.placeDown()\
  9850. end\
  9851. \
  9852. print( \"Mined \"..(collected + unloaded)..\" items total.\" )",
  9853.   [ "/rom/programs/id" ] = "\
  9854. local sDrive = nil\
  9855. local tArgs = { ... }\
  9856. if #tArgs > 0 then\
  9857.     sDrive = tostring( tArgs[1] )\
  9858. end\
  9859. \
  9860. if sDrive == nil then\
  9861.     print( \"This is computer #\"..os.getComputerID() )\
  9862.     \
  9863.     local label = os.getComputerLabel()\
  9864.     if label then\
  9865.         print( \"This computer is labelled \\\"\"..label..\"\\\"\" )\
  9866.     end\
  9867. \
  9868. else\
  9869.     local bData = disk.hasData( sDrive )\
  9870.     if not bData then\
  9871.         print( \"No disk in drive \"..sDrive )\
  9872.         return\
  9873.     end\
  9874.     \
  9875.     print( \"The disk is #\"..disk.getID( sDrive ) )\
  9876. \
  9877.     local label = disk.getLabel( sDrive )\
  9878.     if label then\
  9879.         print( \"The disk is labelled \\\"\"..label..\"\\\"\" )\
  9880.     end\
  9881. end\
  9882. ",
  9883.   [ "/rom/help/drives" ] = "The Disk Drive is a peripheral device available for CraftOS. Type \"help peripheral\" to learn about using the Peripheral API to connect with peripherals. When a Disk Drive is connected, peripheral.getType() will return \"drive\".\
  9884. \
  9885. Methods exposed by the Disk Drive:\
  9886. isDiskPresent()\
  9887. getDiskLabel()\
  9888. setDiskLabel( label )\
  9889. hasData()\
  9890. getMountPath()\
  9891. hasAudio()\
  9892. getAudioTitle()\
  9893. playAudio()\
  9894. stopAudio()\
  9895. ejectDisk()\
  9896. getDiskID()\
  9897. \
  9898. Events fired by the Disk Drive:\
  9899. \"disk\" when a disk or other item is inserted into the drive. Argument is the name of the drive.\
  9900. \"disk_eject\" when a disk is removed from a  drive. Argument is the name of the drive.\
  9901. Type \"help events\" to learn about the event system.",
  9902.   [ "/rom/help/fg" ] = "fg is a program for Advanced Computers which opens a new tab in the foreground.\
  9903. \
  9904. ex:\
  9905. \"fg\" will open a foreground tab running the shell\
  9906. \"fg worm\" will open a foreground tab running the \"worm\" program",
  9907.   [ "/rom/help/bit" ] = "Functions in the bit manipulation API:\
  9908. bit.bnot(n)          -- bitwise not (~n)\
  9909. bit.band(m, n)       -- bitwise and (m & n)\
  9910. bit.bor(m, n)        -- bitwise or (m | n)\
  9911. bit.bxor(m, n)       -- bitwise xor (m ^ n)\
  9912. bit.brshift(n, bits) -- right shift (n >> bits)\
  9913. bit.blshift(n, bits) -- left shift (n << bits)",
  9914.   [ "/rom/help/eject" ] = "eject ejects the contents of an attached disk drive.\
  9915. \
  9916. ex:\
  9917. \"eject left\" ejects the contents of the disk drive to the left of the computer.",
  9918.   [ "/rom/help/hello" ] = "hello prints the text \"Hello World!\" to the screen.",
  9919.   [ "/rom/apis/rednet" ] = "\
  9920. CHANNEL_BROADCAST = 65535\
  9921. CHANNEL_REPEAT = 65533\
  9922. \
  9923. local tReceivedMessages = {}\
  9924. local tReceivedMessageTimeouts = {}\
  9925. local tHostnames = {}\
  9926. \
  9927. function open( sModem )\
  9928.     if type( sModem ) ~= \"string\" then\
  9929.         error( \"expected string\", 2 )\
  9930.     end\
  9931.     if peripheral.getType( sModem ) ~= \"modem\" then   \
  9932.         error( \"No such modem: \"..sModem, 2 )\
  9933.     end\
  9934.     peripheral.call( sModem, \"open\", os.getComputerID() )\
  9935.     peripheral.call( sModem, \"open\", CHANNEL_BROADCAST )\
  9936. end\
  9937. \
  9938. function close( sModem )\
  9939.    if sModem then\
  9940.        -- Close a specific modem\
  9941.        if type( sModem ) ~= \"string\" then\
  9942.            error( \"expected string\", 2 )\
  9943.        end\
  9944.        if peripheral.getType( sModem ) ~= \"modem\" then\
  9945.            error( \"No such modem: \"..sModem, 2 )\
  9946.        end\
  9947.        peripheral.call( sModem, \"close\", os.getComputerID() )\
  9948.        peripheral.call( sModem, \"close\", CHANNEL_BROADCAST )\
  9949.    else\
  9950.        -- Close all modems\
  9951.        for n,sModem in ipairs( peripheral.getNames() ) do\
  9952.            if isOpen( sModem ) then\
  9953.                close( sModem )\
  9954.            end\
  9955.        end\
  9956.    end\
  9957. end\
  9958. \
  9959. function isOpen( sModem )\
  9960.    if sModem then\
  9961.        -- Check if a specific modem is open\
  9962.        if type( sModem ) ~= \"string\" then\
  9963.            error( \"expected string\", 2 )\
  9964.        end\
  9965.        if peripheral.getType( sModem ) == \"modem\" then\
  9966.            return peripheral.call( sModem, \"isOpen\", os.getComputerID() ) and peripheral.call( sModem, \"isOpen\", CHANNEL_BROADCAST )\
  9967.        end\
  9968.    else\
  9969.        -- Check if any modem is open\
  9970.        for n,sModem in ipairs( peripheral.getNames() ) do\
  9971.            if isOpen( sModem ) then\
  9972.                return true\
  9973.            end\
  9974.        end\
  9975.    end\
  9976.     return false\
  9977. end\
  9978. \
  9979. function send( nRecipient, message, sProtocol )\
  9980.    -- Generate a (probably) unique message ID\
  9981.    -- We could do other things to guarantee uniqueness, but we really don't need to\
  9982.    -- Store it to ensure we don't get our own messages back\
  9983.    local nMessageID = math.random( 1, 2147483647 )\
  9984.    tReceivedMessages[ nMessageID ] = true\
  9985.    tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = nMessageID\
  9986. \
  9987.    -- Create the message\
  9988.    local nReplyChannel = os.getComputerID()\
  9989.    local tMessage = {\
  9990.        nMessageID = nMessageID,\
  9991.        nRecipient = nRecipient,\
  9992.        message = message,\
  9993.        sProtocol = sProtocol,\
  9994.    }\
  9995. \
  9996.    if nRecipient == os.getComputerID() then\
  9997.        -- Loopback to ourselves\
  9998.        os.queueEvent( \"rednet_message\", nReplyChannel, message, sProtocol )\
  9999. \
  10000.    else\
  10001.        -- Send on all open modems, to the target and to repeaters\
  10002.        local sent = false\
  10003.        for n,sModem in ipairs( peripheral.getNames() ) do\
  10004.            if isOpen( sModem ) then\
  10005.                peripheral.call( sModem, \"transmit\", nRecipient, nReplyChannel, tMessage );\
  10006.                peripheral.call( sModem, \"transmit\", CHANNEL_REPEAT, nReplyChannel, tMessage );\
  10007.                sent = true\
  10008.            end\
  10009.        end\
  10010.    end\
  10011. end\
  10012. \
  10013. function broadcast( message, sProtocol )\
  10014.     send( CHANNEL_BROADCAST, message, sProtocol )\
  10015. end\
  10016. \
  10017. function receive( sProtocolFilter, nTimeout )\
  10018.    -- The parameters used to be ( nTimeout ), detect this case for backwards compatibility\
  10019.    if type(sProtocolFilter) == \"number\" and nTimeout == nil then\
  10020.        sProtocolFilter, nTimeout = nil, sProtocolFilter\
  10021.    end\
  10022. \
  10023.    -- Start the timer\
  10024.     local timer = nil\
  10025.     local sFilter = nil\
  10026.     if nTimeout then\
  10027.         timer = os.startTimer( nTimeout )\
  10028.         sFilter = nil\
  10029.     else\
  10030.         sFilter = \"rednet_message\"\
  10031.     end\
  10032. \
  10033.     -- Wait for events\
  10034.     while true do\
  10035.         local sEvent, p1, p2, p3 = os.pullEvent( sFilter )\
  10036.         if sEvent == \"rednet_message\" then\
  10037.             -- Return the first matching rednet_message\
  10038.             local nSenderID, message, sProtocol = p1, p2, p3\
  10039.             if sProtocolFilter == nil or sProtocol == sProtocolFilter then\
  10040.                 return nSenderID, message, sProtocol\
  10041.             end\
  10042.         elseif sEvent == \"timer\" then\
  10043.             -- Return nil if we timeout\
  10044.             if p1 == timer then\
  10045.                 return nil\
  10046.             end\
  10047.         end\
  10048.     end\
  10049. end\
  10050. \
  10051. function host( sProtocol, sHostname )\
  10052.    if type( sProtocol ) ~= \"string\" or type( sHostname ) ~= \"string\" then\
  10053.        error( \"expected string, string\", 2 )\
  10054.    end\
  10055.    if sHostname == \"localhost\" then\
  10056.        error( \"Reserved hostname\", 2 )\
  10057.    end\
  10058.    if tHostnames[ sProtocol ] ~= sHostname then\
  10059.        if lookup( sProtocol, sHostname ) ~= nil then\
  10060.            error( \"Hostname in use\", 2 )\
  10061.        end\
  10062.        tHostnames[ sProtocol ] = sHostname\
  10063.    end\
  10064. end\
  10065. \
  10066. function unhost( sProtocol )\
  10067.    if type( sProtocol ) ~= \"string\" then\
  10068.        error( \"expected string\", 2 )\
  10069.    end\
  10070.    tHostnames[ sProtocol ] = nil\
  10071. end\
  10072. \
  10073. function lookup( sProtocol, sHostname )\
  10074.    if type( sProtocol ) ~= \"string\" then\
  10075.        error( \"expected string\", 2 )\
  10076.    end\
  10077. \
  10078.    -- Build list of host IDs\
  10079.    local tResults = nil\
  10080.    if sHostname == nil then\
  10081.        tResults = {}\
  10082.    end\
  10083. \
  10084.    -- Check localhost first\
  10085.    if tHostnames[ sProtocol ] then\
  10086.        if sHostname == nil then\
  10087.            table.insert( tResults, os.getComputerID() )\
  10088.        elseif sHostname == \"localhost\" or sHostname == tHostnames[ sProtocol ] then\
  10089.            return os.getComputerID()\
  10090.        end\
  10091.    end\
  10092. \
  10093.    if not isOpen() then\
  10094.        if tResults then\
  10095.            return unpack( tResults )\
  10096.        end\
  10097.        return nil\
  10098.    end\
  10099. \
  10100.    -- Broadcast a lookup packet\
  10101.    broadcast( {\
  10102.        sType = \"lookup\",\
  10103.        sProtocol = sProtocol,\
  10104.        sHostname = sHostname,\
  10105.    }, \"dns\" )\
  10106. \
  10107.    -- Start a timer\
  10108.    local timer = os.startTimer( 2 )\
  10109. \
  10110.    -- Wait for events\
  10111.    while true do\
  10112.        local event, p1, p2, p3 = os.pullEvent()\
  10113.        if event == \"rednet_message\" then\
  10114.            -- Got a rednet message, check if it's the response to our request\
  10115.            local nSenderID, tMessage, sMessageProtocol = p1, p2, p3\
  10116.            if sMessageProtocol == \"dns\" and tMessage.sType == \"lookup response\" then\
  10117.                if tMessage.sProtocol == sProtocol then\
  10118.                    if sHostname == nil then\
  10119.                        table.insert( tResults, nSenderID )\
  10120.                    elseif tMessage.sHostname == sHostname then\
  10121.                        return nSenderID\
  10122.                    end\
  10123.                end\
  10124.            end\
  10125.        else\
  10126.            -- Got a timer event, check it's the end of our timeout\
  10127.            if p1 == timer then\
  10128.                break\
  10129.            end\
  10130.        end\
  10131.    end\
  10132.    if tResults then\
  10133.        return unpack( tResults )\
  10134.    end\
  10135.    return nil\
  10136. end\
  10137. \
  10138. local bRunning = false\
  10139. function run()\
  10140.     if bRunning then\
  10141.         error( \"rednet is already running\", 2 )\
  10142.     end\
  10143.     bRunning = true\
  10144.     \
  10145.     while bRunning do\
  10146.         local sEvent, p1, p2, p3, p4 = os.pullEventRaw()\
  10147.         if sEvent == \"modem_message\" then\
  10148.             -- Got a modem message, process it and add it to the rednet event queue\
  10149.             local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4\
  10150.             if isOpen( sModem ) and ( nChannel == os.getComputerID() or nChannel == CHANNEL_BROADCAST ) then\
  10151.                 if type( tMessage ) == \"table\" and tMessage.nMessageID then\
  10152.                     if not tReceivedMessages[ tMessage.nMessageID ] then\
  10153.                         tReceivedMessages[ tMessage.nMessageID ] = true\
  10154.                        tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = nMessageID\
  10155.                         os.queueEvent( \"rednet_message\", nReplyChannel, tMessage.message, tMessage.sProtocol )\
  10156.                     end\
  10157.                 end\
  10158.             end\
  10159. \
  10160.         elseif sEvent == \"rednet_message\" then\
  10161.             -- Got a rednet message (queued from above), respond to dns lookup\
  10162.             local nSenderID, tMessage, sProtocol = p1, p2, p3\
  10163.             if sProtocol == \"dns\" and tMessage.sType == \"lookup\" then\
  10164.                 local sHostname = tHostnames[ tMessage.sProtocol ]\
  10165.                 if sHostname ~= nil and (tMessage.sHostname == nil or tMessage.sHostname == sHostname) then\
  10166.                     rednet.send( nSenderID, {\
  10167.                         sType = \"lookup response\",\
  10168.                         sHostname = sHostname,\
  10169.                         sProtocol = tMessage.sProtocol,\
  10170.                     }, \"dns\" )\
  10171.                 end\
  10172.             end\
  10173. \
  10174.         elseif sEvent == \"timer\" then\
  10175.            -- Got a timer event, use it to clear the event queue\
  10176.            local nTimer = p1\
  10177.            local nMessage = tReceivedMessageTimeouts[ nTimer ]\
  10178.            if nMessage then\
  10179.                tReceivedMessageTimeouts[ nTimer ] = nil\
  10180.                tReceivedMessages[ nMessage ] = nil\
  10181.            end\
  10182.         end\
  10183.     end\
  10184. end",
  10185.   [ "/rom/programs/fun/advanced/levels/12" ] = "6\
  10186. 77  777  77\
  10187. 72888888897\
  10188. 8   8   8\
  10189. 8 8b888 8\
  10190. 78 e8888 87\
  10191. 78888788887\
  10192. 78 8888e 87\
  10193. 8 888b8 8\
  10194. 8   8   8\
  10195. 75888888807\
  10196. 77  777  77",
  10197.   [ "/rom/apis/gps" ] = "\
  10198. CHANNEL_GPS = 65534\
  10199. \
  10200. local function trilaterate( A, B, C )\
  10201.     local a2b = B.vPosition - A.vPosition\
  10202.     local a2c = C.vPosition - A.vPosition\
  10203.         \
  10204.     if math.abs( a2b:normalize():dot( a2c:normalize() ) ) > 0.999 then\
  10205.         return nil\
  10206.     end\
  10207.     \
  10208.     local d = a2b:length()\
  10209.     local ex = a2b:normalize( )\
  10210.     local i = ex:dot( a2c )\
  10211.     local ey = (a2c - (ex * i)):normalize()\
  10212.     local j = ey:dot( a2c )\
  10213.     local ez = ex:cross( ey )\
  10214. \
  10215.     local r1 = A.nDistance\
  10216.     local r2 = B.nDistance\
  10217.     local r3 = C.nDistance\
  10218.         \
  10219.     local x = (r1*r1 - r2*r2 + d*d) / (2*d)\
  10220.     local y = (r1*r1 - r3*r3 - x*x + (x-i)*(x-i) + j*j) / (2*j)\
  10221.         \
  10222.     local result = A.vPosition + (ex * x) + (ey * y)\
  10223. \
  10224.     local zSquared = r1*r1 - x*x - y*y\
  10225.     if zSquared > 0 then\
  10226.         local z = math.sqrt( zSquared )\
  10227.         local result1 = result + (ez * z)\
  10228.         local result2 = result - (ez * z)\
  10229.         \
  10230.         local rounded1, rounded2 = result1:round( 0.01 ), result2:round( 0.01 )\
  10231.         if rounded1.x ~= rounded2.x or rounded1.y ~= rounded2.y or rounded1.z ~= rounded2.z then\
  10232.             return rounded1, rounded2\
  10233.         else\
  10234.             return rounded1\
  10235.         end\
  10236.     end\
  10237.     return result:round( 0.01 )\
  10238.     \
  10239. end\
  10240. \
  10241. local function narrow( p1, p2, fix )\
  10242.     local dist1 = math.abs( (p1 - fix.vPosition):length() - fix.nDistance )\
  10243.     local dist2 = math.abs( (p2 - fix.vPosition):length() - fix.nDistance )\
  10244.     \
  10245.     if math.abs(dist1 - dist2) < 0.01 then\
  10246.         return p1, p2\
  10247.     elseif dist1 < dist2 then\
  10248.         return p1:round( 0.01 )\
  10249.     else\
  10250.         return p2:round( 0.01 )\
  10251.     end\
  10252. end\
  10253. \
  10254. function locate( _nTimeout, _bDebug )\
  10255. \
  10256.     -- Find a modem\
  10257.     local sModemSide = nil\
  10258.     for n,sSide in ipairs( rs.getSides() ) do\
  10259.         if peripheral.getType( sSide ) == \"modem\" and peripheral.call( sSide, \"isWireless\" ) then   \
  10260.             sModemSide = sSide\
  10261.             break\
  10262.         end\
  10263.     end\
  10264. \
  10265.     if sModemSide == nil then\
  10266.         if _bDebug then\
  10267.             print( \"No wireless modem attached\" )\
  10268.         end\
  10269.         return nil\
  10270.     end\
  10271.     \
  10272.     if _bDebug then\
  10273.         print( \"Finding position...\" )\
  10274.     end\
  10275.     \
  10276.     -- Open a channel\
  10277.     local modem = peripheral.wrap( sModemSide )\
  10278.     local bCloseChannel = false\
  10279.     if not modem.isOpen( os.getComputerID() ) then\
  10280.         modem.open( os.getComputerID() )\
  10281.         bCloseChannel = true\
  10282.     end\
  10283.     \
  10284.     -- Send a ping to listening GPS hosts\
  10285.     modem.transmit( CHANNEL_GPS, os.getComputerID(), \"PING\" )\
  10286.         \
  10287.     -- Wait for the responses\
  10288.     local tFixes = {}\
  10289.     local pos1, pos2 = nil, nil\
  10290.     local timeout = os.startTimer( _nTimeout or 2 )\
  10291.     while true do\
  10292.         local e, p1, p2, p3, p4, p5 = os.pullEvent()\
  10293.         if e == \"modem_message\" then\
  10294.             -- We received a message from a modem\
  10295.             local sSide, sChannel, sReplyChannel, tMessage, nDistance = p1, p2, p3, p4, p5\
  10296.             if sSide == sModemSide and sChannel == os.getComputerID() and sReplyChannel == CHANNEL_GPS then\
  10297.                 -- Received the correct message from the correct modem: use it to determine position\
  10298.                 if type(tMessage) == \"table\" and #tMessage == 3 then\
  10299.                     local tFix = { vPosition = vector.new( tMessage[1], tMessage[2], tMessage[3] ), nDistance = nDistance }\
  10300.                     if _bDebug then\
  10301.                         print( tFix.nDistance..\" metres from \"..tostring( tFix.vPosition ) )\
  10302.                     end\
  10303.                     if tFix.nDistance == 0 then\
  10304.                         pos1, pos2 = tFix.vPosition, nil\
  10305.                     else\
  10306.                        table.insert( tFixes, tFix )\
  10307.                        if #tFixes >= 3 then\
  10308.                            if not pos1 then\
  10309.                                pos1, pos2 = trilaterate( tFixes[1], tFixes[2], tFixes[#tFixes] )\
  10310.                            else\
  10311.                                pos1, pos2 = narrow( pos1, pos2, tFixes[#tFixes] )\
  10312.                            end\
  10313.                        end\
  10314.                    end\
  10315.                     if pos1 and not pos2 then\
  10316.                         break\
  10317.                     end\
  10318.                 end\
  10319.             end\
  10320.             \
  10321.         elseif e == \"timer\" then\
  10322.             -- We received a timeout\
  10323.             local timer = p1\
  10324.             if timer == timeout then\
  10325.                 break\
  10326.             end\
  10327.         \
  10328.         end \
  10329.     end\
  10330.     \
  10331.     -- Close the channel, if we opened one\
  10332.     if bCloseChannel then\
  10333.         modem.close( os.getComputerID() )\
  10334.     end\
  10335.     \
  10336.     -- Return the response\
  10337.     if pos1 and pos2 then\
  10338.         if _bDebug then\
  10339.             print( \"Ambiguous position\" )\
  10340.             print( \"Could be \"..pos1.x..\",\"..pos1.y..\",\"..pos1.z..\" or \"..pos2.x..\",\"..pos2.y..\",\"..pos2.z )\
  10341.         end\
  10342.         return nil\
  10343.     elseif pos1 then\
  10344.         if _bDebug then\
  10345.             print( \"Position is \"..pos1.x..\",\"..pos1.y..\",\"..pos1.z )\
  10346.         end\
  10347.         return pos1.x, pos1.y, pos1.z\
  10348.     else\
  10349.         if _bDebug then\
  10350.             print( \"Could not determine position\" )\
  10351.         end\
  10352.         return nil\
  10353.     end\
  10354. end",
  10355.   [ "/rom/programs/fun/advanced/levels/4" ] = "2\
  10356.    77777777\
  10357. 777778888887\
  10358. 788888777787\
  10359. 7b77787  787\
  10360. 787 787  787\
  10361. 7b77787  787\
  10362. 7888887  787\
  10363. 7777707  707\
  10364.    777  777",
  10365.   [ "/Flare/version/1.2/lib/sha256.lua" ] = "local MOD = 2^32\
  10366. local MODM = MOD-1\
  10367. local function memoize(f)\
  10368.    local mt = {}\
  10369.    local t = setmetatable({}, mt)\
  10370.    function mt:__index(k)\
  10371.        local v = f(k)\
  10372.        t[k] = v\
  10373.        return v\
  10374.    end\
  10375.    return t\
  10376. end\
  10377. local function make_bitop_uncached(t, m)\
  10378.    local function bitop(a, b)\
  10379.        local res,p = 0,1\
  10380.        while a ~= 0 and b ~= 0 do\
  10381.            local am, bm = a % m, b % m\
  10382.            res = res + t[am][bm] * p\
  10383.            a = (a - am) / m\
  10384.            b = (b - bm) / m\
  10385.            p = p*m\
  10386.        end\
  10387.        res = res + (a + b) * p\
  10388.        return res\
  10389.    end\
  10390.    return bitop\
  10391. end\
  10392. local function make_bitop(t)\
  10393.    local op1 = make_bitop_uncached(t,2^1)\
  10394.    local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)\
  10395.    return make_bitop_uncached(op2, 2 ^ (t.n or 1))\
  10396. end\
  10397. local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})\
  10398. local function bxor(a, b, c, ...)\
  10399.    local z = nil\
  10400.    if b then\
  10401.        a = a % MOD\
  10402.        b = b % MOD\
  10403.        z = bxor1(a, b)\
  10404.        if c then z = bxor(z, c, ...) end\
  10405.        return z\
  10406.    elseif a then return a % MOD\
  10407.    else return 0 end\
  10408. end\
  10409. local function band(a, b, c, ...)\
  10410.    local z\
  10411.    if b then\
  10412.        a = a % MOD\
  10413.        b = b % MOD\
  10414.        z = ((a + b) - bxor1(a,b)) / 2\
  10415.        if c then z = bit32_band(z, c, ...) end\
  10416.        return z\
  10417.    elseif a then return a % MOD\
  10418.    else return MODM end\
  10419. end\
  10420. local function bnot(x) return (-1 - x) % MOD end\
  10421. local function rshift1(a, disp)\
  10422.    if disp < 0 then return lshift(a,-disp) end\
  10423.    return math.floor(a % 2 ^ 32 / 2 ^ disp)\
  10424. end\
  10425. local function rshift(x, disp)\
  10426.    if disp > 31 or disp < -31 then return 0 end\
  10427.    return rshift1(x % MOD, disp)\
  10428. end\
  10429. local function lshift(a, disp)\
  10430.    if disp < 0 then return rshift(a,-disp) end \
  10431.    return (a * 2 ^ disp) % 2 ^ 32\
  10432. end\
  10433. local function rrotate(x, disp)\
  10434.    x = x % MOD\
  10435.    disp = disp % 32\
  10436.    local low = band(x, 2 ^ disp - 1)\
  10437.    return rshift(x, disp) + lshift(low, 32 - disp)\
  10438. end\
  10439. local k = {\
  10440.    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\
  10441.    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\
  10442.    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\
  10443.    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\
  10444.    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\
  10445.    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\
  10446.    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\
  10447.    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\
  10448.    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\
  10449.    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\
  10450.    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\
  10451.    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\
  10452.    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\
  10453.    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\
  10454.    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\
  10455.    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\
  10456. }\
  10457. local function str2hexa(s)\
  10458.    return (string.gsub(s, \".\", function(c) return string.format(\"%02x\", string.byte(c)) end))\
  10459. end\
  10460. local function num2s(l, n)\
  10461.    local s = \"\"\
  10462.    for i = 1, n do\
  10463.        local rem = l % 256\
  10464.        s = string.char(rem) .. s\
  10465.        l = (l - rem) / 256\
  10466.    end\
  10467.    return s\
  10468. end\
  10469. local function s232num(s, i)\
  10470.    local n = 0\
  10471.    for i = i, i + 3 do n = n*256 + string.byte(s, i) end\
  10472.    return n\
  10473. end\
  10474. local function preproc(msg, len)\
  10475.    local extra = 64 - ((len + 9) % 64)\
  10476.    len = num2s(8 * len, 8)\
  10477.    msg = msg .. \"\\128\" .. string.rep(\"\\0\", extra) .. len\
  10478.    assert(#msg % 64 == 0)\
  10479.    return msg\
  10480. end\
  10481. local function initH256(H)\
  10482.    H[1] = 0x6a09e667\
  10483.    H[2] = 0xbb67ae85\
  10484.    H[3] = 0x3c6ef372\
  10485.    H[4] = 0xa54ff53a\
  10486.    H[5] = 0x510e527f\
  10487.    H[6] = 0x9b05688c\
  10488.    H[7] = 0x1f83d9ab\
  10489.    H[8] = 0x5be0cd19\
  10490.    return H\
  10491. end\
  10492. local function digestblock(msg, i, H)\
  10493.    local w = {}\
  10494.    for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end\
  10495.    for j = 17, 64 do\
  10496.        local v = w[j - 15]\
  10497.        local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))\
  10498.        v = w[j - 2]\
  10499.        w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))\
  10500.    end\
  10501.    local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]\
  10502.    for i = 1, 64 do\
  10503.        local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))\
  10504.        local maj = bxor(band(a, b), band(a, c), band(b, c))\
  10505.        local t2 = s0 + maj\
  10506.        local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))\
  10507.        local ch = bxor (band(e, f), band(bnot(e), g))\
  10508.        local t1 = h + s1 + ch + k[i] + w[i]\
  10509.        h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2\
  10510.    end\
  10511.    H[1] = band(H[1] + a)\
  10512.    H[2] = band(H[2] + b)\
  10513.    H[3] = band(H[3] + c)\
  10514.    H[4] = band(H[4] + d)\
  10515.    H[5] = band(H[5] + e)\
  10516.    H[6] = band(H[6] + f)\
  10517.    H[7] = band(H[7] + g)\
  10518.    H[8] = band(H[8] + h)\
  10519. end\
  10520. local function sha256(msg)\
  10521.    msg = preproc(msg, #msg)\
  10522.    local H = initH256({})\
  10523.    for i = 1, #msg, 64 do digestblock(msg, i, H) end\
  10524.    return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..\
  10525.        num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))\
  10526. end\
  10527. \
  10528. return sha256",
  10529.   [ "/rom/help/parallel" ] = "Functions in the Parallel API:\
  10530. parallel.waitForAny( function1, function2, ... )\
  10531. parallel.waitForAll( function1, function2, ... )\
  10532. These methods provide an easy way to run multiple lua functions simultaneously.",
  10533.   [ "/rom/programs/lua" ] = "\
  10534. local tArgs = { ... }\
  10535. if #tArgs > 0 then\
  10536.     print( \"This is an interactive Lua prompt.\" )\
  10537.     print( \"To run a lua program, just type its name.\" )\
  10538.     return\
  10539. end\
  10540. \
  10541. local bRunning = true\
  10542. local tCommandHistory = {}\
  10543. local tEnv = {\
  10544.     [\"exit\"] = function()\
  10545.         bRunning = false\
  10546.     end,\
  10547.     [\"_echo\"] = function( ... )\
  10548.         return ...\
  10549.     end,\
  10550. }\
  10551. setmetatable( tEnv, { __index = getfenv() } )\
  10552. \
  10553. if term.isColour() then\
  10554.     term.setTextColour( colours.yellow )\
  10555. end\
  10556. print( \"Interactive Lua prompt.\" )\
  10557. print( \"Call exit() to exit.\" )\
  10558. term.setTextColour( colours.white )\
  10559. \
  10560. while bRunning do\
  10561.     --if term.isColour() then\
  10562.     --  term.setTextColour( colours.yellow )\
  10563.     --end\
  10564.     write( \"lua> \" )\
  10565.     --term.setTextColour( colours.white )\
  10566.     \
  10567.     local s = read( nil, tCommandHistory )\
  10568.     table.insert( tCommandHistory, s )\
  10569.     \
  10570.     local nForcePrint = 0\
  10571.     local func, e = loadstring( s, \"lua\" )\
  10572.     local func2, e2 = loadstring( \"return _echo(\"..s..\");\", \"lua\" )\
  10573.     if not func then\
  10574.         if func2 then\
  10575.             func = func2\
  10576.             e = nil\
  10577.             nForcePrint = 1\
  10578.         end\
  10579.     else\
  10580.         if func2 then\
  10581.             func = func2\
  10582.         end\
  10583.     end\
  10584.     \
  10585.     if func then\
  10586.        setfenv( func, tEnv )\
  10587.        local tResults = { pcall( func ) }\
  10588.        if tResults[1] then\
  10589.             local n = 1\
  10590.             while (tResults[n + 1] ~= nil) or (n <= nForcePrint) do\
  10591.                 local value = tResults[ n + 1 ]\
  10592.                 if type( value ) == \"table\" then\
  10593.                     local ok, serialised = pcall( textutils.serialise, value )\
  10594.                     if ok then\
  10595.                         print( serialised )\
  10596.                     else\
  10597.                         print( tostring( value ) )\
  10598.                     end\
  10599.                 else\
  10600.                     print( tostring( value ) )\
  10601.                 end\
  10602.                 n = n + 1\
  10603.             end\
  10604.        else\
  10605.             printError( tResults[2] )\
  10606.        end\
  10607.    else\
  10608.         printError( e )\
  10609.    end\
  10610.    \
  10611. end",
  10612.   [ "/rom/programs/move" ] = "\
  10613. local tArgs = { ... }\
  10614. if #tArgs < 2 then\
  10615.     print( \"Usage: mv <source> <destination>\" )\
  10616.     return\
  10617. end\
  10618. \
  10619. local sSource = shell.resolve( tArgs[1] )\
  10620. local sDest = shell.resolve( tArgs[2] )\
  10621. local tFiles = fs.find( sSource )\
  10622. if #tFiles > 0 then\
  10623.    for n,sFile in ipairs( tFiles ) do\
  10624.        if fs.isDir( sDest ) then\
  10625.            fs.move( sFile, fs.combine( sDest, fs.getName(sFile) ) )\
  10626.        elseif #tFiles == 1 then\
  10627.            fs.move( sFile, sDest )\
  10628.        else\
  10629.            printError( \"Cannot overwrite file multiple times\" )\
  10630.            return\
  10631.        end\
  10632.    end\
  10633. else\
  10634.    printError( \"No matching files\" )\
  10635. end",
  10636.   [ "/rom/help/move" ] = "mv moves a file or directory from one location to another.\
  10637. \
  10638. ex:\
  10639. \"mv foo bar\" renames the file \"foo\" to \"bar\".\
  10640. \"mv foo bar/foo\" moves the file \"foo\" to a folder called \"bar\".\
  10641. \"mv disk/* disk2\" moves the contents of one disk to another",
  10642.   [ "/rom/help/drive" ] = "drive tells you which disk drive the current or specified directory is located in.\
  10643. \
  10644. ex:\
  10645. \"drive\" tell you the disk drive of the current directory.\
  10646. \"drive foo\" tells you the disk drive of the subdirectory \"foo\"",
  10647.   [ "/Flare/version/1.2/lib/UI/event/Event.lua" ] = "\
  10648. local class = require \"lib.class\"\
  10649. \
  10650. local Event = class \"Event\"\
  10651. \
  10652. function Event:Event( name, ... )\
  10653.     self.handled = false\
  10654.     self.name = name\
  10655.     self.parameters = {}\
  10656. end\
  10657. \
  10658. function Event:setParam( pname, value )\
  10659.     self.parameters[pname] = value\
  10660.     return self\
  10661. end\
  10662. \
  10663. function Event:getParam( pname )\
  10664.     return self.parameters[pname]\
  10665. end\
  10666. \
  10667. function Event:checkParam( pname, value )\
  10668.     return self:getParam( pname ) == value\
  10669. end\
  10670. \
  10671. function Event:clone( t )\
  10672.     local e = Event( self.name )\
  10673.     e.handled = nil\
  10674.     for k, v in pairs( self.parameters ) do\
  10675.         e:setParam( k, v )\
  10676.     end\
  10677.     for k, v in pairs( t ) do\
  10678.         e:setParam( k, v )\
  10679.     end\
  10680.     getmetatable( e ).__index = function( t, k )\
  10681.         return k == \"handled\" and self.handled or Event[k]\
  10682.     end\
  10683.     getmetatable( e ).__newindex = function( t, k, v )\
  10684.         if k == \"handled\" then\
  10685.             self.handled = v\
  10686.         else\
  10687.             rawset( t, k, v )\
  10688.         end\
  10689.     end\
  10690.     return e\
  10691. end\
  10692. \
  10693. function Event:isHandled()\
  10694.     return self.handled\
  10695. end\
  10696. \
  10697. return Event",
  10698.   [ "/Flare/version/1.2/lib/UI/draw/image.lua" ] = "\
  10699. local pixelbatch = require \"lib.UI.draw.pixelbatch\"\
  10700. \
  10701. local function image( image, _x, _y, buffer )\
  10702.     _x, _y = _x - 1, _y - 1\
  10703.     local pixels = {}\
  10704.     for x = 1, image.width do\
  10705.         for y = 1, image.height do\
  10706.             local t = {\
  10707.                 x = _x + x;\
  10708.                 y = _y + y;\
  10709.             }\
  10710.             t.bc, t.tc, t.char = image:getPixel( x, y )\
  10711.             pixels[#pixels + 1] = t\
  10712.         end\
  10713.     end\
  10714.     pixelbatch( buffer, pixels )\
  10715. end\
  10716. \
  10717. return pixelbatch",
  10718.   [ "/rom/apis/colors" ] = "-- Colors\
  10719. white = 1\
  10720. orange = 2\
  10721. magenta = 4\
  10722. lightBlue = 8\
  10723. yellow = 16\
  10724. lime = 32\
  10725. pink = 64\
  10726. gray = 128\
  10727. lightGray = 256\
  10728. cyan = 512\
  10729. purple = 1024\
  10730. blue = 2048\
  10731. brown = 4096\
  10732. green = 8192\
  10733. red = 16384\
  10734. black = 32768\
  10735. \
  10736. function combine( ... )\
  10737.    local r = 0\
  10738.    for n,c in ipairs( { ... } ) do\
  10739.        r = bit.bor(r,c)\
  10740.    end\
  10741.    return r\
  10742. end\
  10743. \
  10744. function subtract( colors, ... )\
  10745.     local r = colors\
  10746.     for n,c in ipairs( { ... } ) do\
  10747.         r = bit.band(r, bit.bnot(c))\
  10748.     end\
  10749.     return r\
  10750. end\
  10751. \
  10752. function test( colors, color )\
  10753.    return ((bit.band(colors, color)) == color)\
  10754. end",
  10755.   [ "/rom/programs/fun/advanced/levels/0" ] = "0\
  10756. 77     77\
  10757. 718888887\
  10758. 8     8\
  10759. 8     8\
  10760. 8     8\
  10761. 788888897\
  10762. 77     77",
  10763.   [ "/Flare/version/1.2/lib/UI/draw/text.lua" ] = " \
  10764. local function text( self, fmt, x, y, buffer )\
  10765.     local layer = buffer.stencil and buffer.stencil:newLayer( x, y, self.width, self.height )\
  10766. \
  10767.     local _lines = fmt.lines\
  10768.     fmt.lines = {}\
  10769.     for i = 1, #_lines do\
  10770.         fmt.lines[i] = _lines[i]\
  10771.     end\
  10772. \
  10773.     while ( fmt.offset.y or 0 ) < 0 do\
  10774.         fmt.offset.y = ( fmt.offset.y or 0 ) + 1\
  10775.         table.remove( fmt.lines, 1 )\
  10776.     end\
  10777.     while #fmt.lines + ( fmt.offset.y or 0 ) > self.height do\
  10778.         fmt.lines[#fmt.lines] = nil\
  10779.     end\
  10780.     buffer:drawTextFormatted( x, y, self.width, self.height, fmt )\
  10781. \
  10782.     if layer then\
  10783.         buffer.stencil:removeLayer( layer )\
  10784.     end\
  10785. end\
  10786. \
  10787. return text",
  10788.   [ "/Flare/version/1.2/lib/UI/text/formatter.lua" ] = "\
  10789. local class = require \"lib.class\"\
  10790. local graphics = require \"lib.graphics\"\
  10791. \
  10792. local function linewrap( str, w )\
  10793.     if str:sub( 1, w + 1 ):find \"\\n\" then\
  10794.         if str:sub( 1, 1 ) == \"\\n\" then\
  10795.             return \"\\n\", str:sub( 2 )\
  10796.         end\
  10797.         return str:match \"^(.-\\n)(.*)$\"\
  10798.     end\
  10799.     if #str <= w then\
  10800.         return str, nil\
  10801.     end\
  10802.     if str:sub( 1, w + 1 ):find \"%s\" then\
  10803.         local pos = w - str:sub( 1, w + 1 ):reverse():find \"%s\" + 2\
  10804.         while str:sub( pos, pos ):find \"%s\" do\
  10805.             if str:sub( pos, pos ) == \"\\n\" then\
  10806.                 pos = pos + 1\
  10807.                 break\
  10808.             end\
  10809.             pos = pos + 1\
  10810.         end\
  10811.         return str:sub( 1, pos - 1 ), str:sub( pos )\
  10812.     end\
  10813.     return str:sub( 1, w ), str:sub( w + 1 )\
  10814. end\
  10815. \
  10816. local formatter = {}\
  10817. \
  10818. function formatter.tostream( text, metadata )\
  10819.     local stream = {\
  10820.         text = \"\";\
  10821.         colour = {};\
  10822.         link = {};\
  10823.         mark = {};\
  10824.     }\
  10825.     local markstack, mark, link = {}\
  10826.     local bc, tc = graphics.colour( metadata.bc or 1 ), graphics.colour( metadata.tc or 32768 )\
  10827.     local escaping = false\
  10828.     local function append( text )\
  10829.         stream.text = stream.text .. text\
  10830.         local streampos = #stream.colour + 1\
  10831.         for i = 1, #text do\
  10832.             local c = { bc = bc, tc = tc }\
  10833.             if link and link.protocol == \"default\" then\
  10834.                 c.bc = graphics.colour( metadata.bc or 1 )\
  10835.                 c.tc = colours.blue\
  10836.             end\
  10837.             stream.link[streampos] = link\
  10838.             stream.mark[streampos] = mark\
  10839.             stream.colour[streampos] = c\
  10840.             streampos = streampos + 1\
  10841.         end\
  10842.     end\
  10843.     local i = 1\
  10844.     while i <= #text do\
  10845.         if text:sub( i, i ) == \"|\" then\
  10846.             escaping = not escaping\
  10847.             i = i + 1\
  10848.         elseif not escaping and text:sub( i, i ) == \"&\" then\
  10849.             local code = text:sub( i + 1, i + 1 )\
  10850.             if code == \"b\" then\
  10851.                 local c = text:sub( i + 2, i + 2 )\
  10852.                 if graphics.colour( c ) then\
  10853.                     bc = graphics.colour( c )\
  10854.                     i = i + 3\
  10855.                 else\
  10856.                     bc, tc = colours.white, colours.red\
  10857.                     append \"expected valid colour modifier after &b code in text\"\
  10858.                     break\
  10859.                 end\
  10860.             elseif code == \"t\" then\
  10861.                 local c = text:sub( i + 2, i + 2 )\
  10862.                 if graphics.colour( c ) then\
  10863.                     tc = graphics.colour( c )\
  10864.                     i = i + 3\
  10865.                 else\
  10866.                     bc, tc = colours.white, colours.red\
  10867.                     append \"expected valid colour modifier after &t code in text\"\
  10868.                     break\
  10869.                 end\
  10870.             elseif code == \"l\" then\
  10871.                 if text:find( \"^%[[^\\n]-%]%([^\\n]-%)\", i + 2 ) then\
  10872.                     local display, target = text:match( \"^%[([^\\n]-)%]%(([^\\n]-)%)\", i + 2 )\
  10873.                     i = i + 6 + #display + #target\
  10874.                     local protocol = \"default\"\
  10875.                     if target:find \"^!%w+:\" then\
  10876.                         protocol, target = target:match( \"^!(%w+):(.*)$\" )\
  10877.                     end\
  10878.                     link = { protocol = protocol, target = target }\
  10879.                     append( display )\
  10880.                     link = nil\
  10881.                 else\
  10882.                     bc, tc = colours.white, colours.red\
  10883.                     append \"expected []() after &l code in text\"\
  10884.                     break\
  10885.                 end\
  10886.             elseif code == \"m\" then\
  10887.                 if text:find( \"^%[[^\\n]-%]\", i + 2 ) then\
  10888.                     local m = text:match( \"^%[([^\\n]-)%]\", i + 2 )\
  10889.                     i = i + 4 + #m\
  10890.                     markstack[#markstack + 1] = m\
  10891.                     mark = m\
  10892.                 elseif text:sub( i + 2, i + 2 ) == \"-\" then\
  10893.                     markstack[#markstack] = nil\
  10894.                     mark = markstack[#markstack]\
  10895.                     i = i + 3\
  10896.                 else\
  10897.                     bc, tc = colours.white, colours.red\
  10898.                     append \"expected [] or - after &m code in text\"\
  10899.                     break\
  10900.                 end\
  10901.             else\
  10902.                 append( code )\
  10903.                 i = i + 2\
  10904.             end\
  10905.         else\
  10906.             append( text:sub( i, i ) )\
  10907.             i = i + 1\
  10908.         end\
  10909.     end\
  10910.     return stream\
  10911. end\
  10912. \
  10913. function formatter.wrapstream( stream, metadata )\
  10914.     if metadata.width < 1 then return {} end\
  10915.     local pos = 1\
  10916.     local lines = {}\
  10917.     local text, line = stream.text, \"\"\
  10918.     while text do\
  10919.         line, text = linewrap( text, metadata.width )\
  10920. \
  10921.         local l = {\
  10922.             text = line;\
  10923.             colour = {};\
  10924.             link = {};\
  10925.             mark = {};\
  10926.         }\
  10927. \
  10928.         for i = 1, #line do\
  10929.             l.link[i] = stream.link[pos]\
  10930.             l.mark[i] = stream.mark[pos]\
  10931.             l.colour[i] = stream.colour[pos]\
  10932.             pos = pos + 1\
  10933.         end\
  10934. \
  10935.         lines[#lines + 1] = l\
  10936.     end\
  10937.     return lines\
  10938. end\
  10939. \
  10940. function formatter.lines( text, metadata )\
  10941.     local stream = formatter.tostream( text, metadata )\
  10942.     return formatter.wrapstream( stream, metadata )\
  10943. end\
  10944. \
  10945. function formatter.renderPrep( lines, metadata )\
  10946.     if type( lines ) == \"string\" then\
  10947.         lines = formatter.lines( lines, metadata )\
  10948.     end\
  10949.     return {\
  10950.         lines = lines;\
  10951.         bc = graphics.colour( metadata.bc or 1 );\
  10952.         tc = graphics.colour( metadata.tc or 32768 );\
  10953.         offset = {\
  10954.             y = 0;\
  10955.         }\
  10956.     }\
  10957. end\
  10958. \
  10959. function formatter.fixAlignment( fmt, width, height, horizontal, vertical )\
  10960.     fmt.offset.y = vertical == \"centre\" and math.floor( height / 2 - #fmt.lines / 2 )\
  10961.                 or vertical == \"bottom\" and height - #fmt.lines\
  10962.                 or 0\
  10963.     for i = 1, #fmt.lines do\
  10964.         fmt.offset[i] = horizontal == \"centre\" and math.floor( width / 2 - #fmt.lines[i].text / 2 )\
  10965.                      or horizontal == \"right\"  and width - #fmt.lines[i].text\
  10966.                      or 0\
  10967.     end\
  10968. end\
  10969. \
  10970. return formatter",
  10971.   [ "/rom/apis/parallel" ] = "\
  10972. local function create( first, ... )\
  10973.     if first ~= nil then\
  10974.         if type( first ) ~= \"function\" then\
  10975.             error( \"Expected function, got \"..type( first ), 3 )\
  10976.         end\
  10977.         return coroutine.create(first), create( ... )\
  10978.    end\
  10979.    return nil\
  10980. end\
  10981. \
  10982. local function runUntilLimit( _routines, _limit )\
  10983.    local count = #_routines\
  10984.    local living = count\
  10985.    \
  10986.    local tFilters = {}\
  10987.    local eventData = {}\
  10988.    while true do\
  10989.         for n=1,count do\
  10990.             local r = _routines[n]\
  10991.             if r then\
  10992.                 if tFilters[r] == nil or tFilters[r] == eventData[1] or eventData[1] == \"terminate\" then\
  10993.                     local ok, param = coroutine.resume( r, unpack(eventData) )\
  10994.                     if not ok then\
  10995.                         error( param, 0 )\
  10996.                     else\
  10997.                         tFilters[r] = param\
  10998.                     end\
  10999.                     if coroutine.status( r ) == \"dead\" then\
  11000.                         _routines[n] = nil\
  11001.                         living = living - 1\
  11002.                         if living <= _limit then\
  11003.                             return n\
  11004.                         end\
  11005.                     end\
  11006.                 end\
  11007.             end\
  11008.         end\
  11009.         for n=1,count do\
  11010.             local r = _routines[n]\
  11011.             if r and coroutine.status( r ) == \"dead\" then\
  11012.                 _routines[n] = nil\
  11013.                 living = living - 1\
  11014.                 if living <= _limit then\
  11015.                     return n\
  11016.                 end\
  11017.             end\
  11018.         end\
  11019.         eventData = { os.pullEventRaw() }\
  11020.    end\
  11021. end\
  11022. \
  11023. function waitForAny( ... )\
  11024.    local routines = { create( ... ) }\
  11025.    return runUntilLimit( routines, #routines - 1 )\
  11026. end\
  11027. \
  11028. function waitForAll( ... )\
  11029.    local routines = { create( ... ) }\
  11030.     runUntilLimit( routines, 0 )\
  11031. end",
  11032.   [ "/rom/programs/list" ] = "\
  11033. local tArgs = { ... }\
  11034. \
  11035. -- Get all the files in the directory\
  11036. local sDir = shell.dir()\
  11037. if tArgs[1] ~= nil then\
  11038.     sDir = shell.resolve( tArgs[1] )\
  11039. end\
  11040. \
  11041. -- Sort into dirs/files, and calculate column count\
  11042. local tAll = fs.list( sDir )\
  11043. local tFiles = {}\
  11044. local tDirs = {}\
  11045. \
  11046. for n, sItem in pairs( tAll ) do\
  11047.     if string.sub( sItem, 1, 1 ) ~= \".\" then\
  11048.         local sPath = fs.combine( sDir, sItem )\
  11049.         if fs.isDir( sPath ) then\
  11050.             table.insert( tDirs, sItem )\
  11051.         else\
  11052.             table.insert( tFiles, sItem )\
  11053.         end\
  11054.     end\
  11055. end\
  11056. table.sort( tDirs )\
  11057. table.sort( tFiles )\
  11058. \
  11059. if term.isColour() then\
  11060.     textutils.pagedTabulate( colors.green, tDirs, colors.white, tFiles )\
  11061. else\
  11062.     textutils.pagedTabulate( tDirs, tFiles )\
  11063. end",
  11064.   [ "/rom/help/os" ] = "Functions in the os (Operating System) API:\
  11065. os.version()\
  11066. os.getComputerID()\
  11067. os.getComputerLabel()\
  11068. os.setComputerLabel()\
  11069. os.run( environment, programpath, arguments )\
  11070. os.loadAPI( path )\
  11071. os.unloadAPI( name )\
  11072. os.pullEvent( [filter] )\
  11073. os.queueEvent( event, arguments )\
  11074. os.clock()\
  11075. os.startTimer( timeout )\
  11076. os.cancelTimer( token )\
  11077. os.sleep( timeout )\
  11078. os.time()\
  11079. os.day()\
  11080. os.setAlarm( time )\
  11081. os.cancelAlarm( token )\
  11082. os.shutdown()\
  11083. os.reboot()\
  11084. \
  11085. Events emitted by the os API:\
  11086. \"timer\" when a timeout started by os.startTimer() completes. Argument is the token returned by os.startTimer().\
  11087. \"alarm\" when a time passed to os.setAlarm() is reached. Argument is the token returned by os.setAlarm().\
  11088. Type \"help events\" to learn about the event system.",
  11089.   [ "/Flare/version/1.2/lib/UI/elements/Image.lua" ] = "\
  11090. local class = require \"lib.class\"\
  11091. local base = require \"lib.UI.base\"\
  11092. local mouse = require \"lib.UI.event.mouse\"\
  11093. local drawimage = require \"lib.UI.draw.image\"\
  11094. local image = require \"lib.image\"\
  11095. \
  11096. local Image = class \"Image\"\
  11097. Image:extend( base )\
  11098. \
  11099. Image.mouse_click_timeout = .4\
  11100. \
  11101. function Image:Image( x, y, im )\
  11102. \
  11103.     if type( im ) == \"string\" then\
  11104.         if fs.exists( im ) then\
  11105.             local h = fs.open( im, \"r\" )\
  11106.             if h then\
  11107.                 im = h.readAll()\
  11108.                 h.close()\
  11109.             end\
  11110.         end\
  11111.         im = image.load( im )\
  11112.     end\
  11113. \
  11114.     self.image = im\
  11115. \
  11116.     self:base( x, y, im.width, im.height )\
  11117. end\
  11118. \
  11119. function Image:draw( x, y, buffer )\
  11120.     drawimage( self.image, x, y, buffer )\
  11121. end\
  11122. \
  11123. function Image:handle( event )\
  11124.     if mouse.click( self, event ) then\
  11125.         if self.onClick then\
  11126.             self:onClick()\
  11127.         end\
  11128.     elseif event.name == \"mouse_ping\" then\
  11129.         mouse.ping( self, event )\
  11130.     end\
  11131. end\
  11132. \
  11133. return Image",
  11134.   [ "/rom/help/licenses/luaj" ] = "Copyright (c) 2007 LuaJ. All rights reserved.\
  11135. \
  11136. Permission is hereby granted, free of charge, to any person obtaining a copy\
  11137. of this software and associated documentation files (the \"Software\"), to deal\
  11138. in the Software without restriction, including without limitation the rights\
  11139. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\
  11140. copies of the Software, and to permit persons to whom the Software is\
  11141. furnished to do so, subject to the following conditions:\
  11142. \
  11143. The above copyright notice and this permission notice shall be included in\
  11144. all copies or substantial portions of the Software.\
  11145. \
  11146. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\
  11147. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\
  11148. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\
  11149. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\
  11150. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\
  11151. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\
  11152. THE SOFTWARE.",
  11153.   [ "/rom/programs/mkdir" ] = "local tArgs = { ... }\
  11154. if #tArgs < 1 then\
  11155.     print( \"Usage: mkdir <path>\" )\
  11156.     return\
  11157. end\
  11158. \
  11159. local sNewDir = shell.resolve( tArgs[1] )\
  11160. fs.makeDir( sNewDir )\
  11161. ",
  11162.   [ "/rom/programs/turtle/tunnel" ] = "\
  11163. local tArgs = { ... }\
  11164. if #tArgs ~= 1 then\
  11165.     print( \"Usage: tunnel <length>\" )\
  11166.     return\
  11167. end\
  11168. \
  11169. -- Mine in a quarry pattern until we hit something we can't dig\
  11170. local length = tonumber( tArgs[1] )\
  11171. if length < 1 then\
  11172.     print( \"Tunnel length must be positive\" )\
  11173.     return\
  11174. end\
  11175.     \
  11176. local depth = 0\
  11177. local collected = 0\
  11178. \
  11179. local function collect()\
  11180.     collected = collected + 1\
  11181.     if math.fmod(collected, 25) == 0 then\
  11182.         print( \"Mined \"..collected..\" items.\" )\
  11183.     end\
  11184. end\
  11185. \
  11186. local function tryDig()\
  11187.     while turtle.detect() do\
  11188.         if turtle.dig() then\
  11189.             collect()\
  11190.             sleep(0.5)\
  11191.         else\
  11192.             return false\
  11193.         end\
  11194.     end\
  11195.     return true\
  11196. end\
  11197. \
  11198. local function tryDigUp()\
  11199.     while turtle.detectUp() do\
  11200.         if turtle.digUp() then\
  11201.             collect()\
  11202.             sleep(0.5)\
  11203.         else\
  11204.             return false\
  11205.         end\
  11206.     end\
  11207.     return true\
  11208. end\
  11209. \
  11210. local function tryDigDown()\
  11211.     while turtle.detectDown() do\
  11212.         if turtle.digDown() then\
  11213.             collect()\
  11214.             sleep(0.5)\
  11215.         else\
  11216.             return false\
  11217.         end\
  11218.     end\
  11219.     return true\
  11220. end\
  11221. \
  11222. local function refuel()\
  11223.     local fuelLevel = turtle.getFuelLevel()\
  11224.     if fuelLevel == \"unlimited\" or fuelLevel > 0 then\
  11225.         return\
  11226.     end\
  11227.     \
  11228.     local function tryRefuel()\
  11229.         for n=1,16 do\
  11230.             if turtle.getItemCount(n) > 0 then\
  11231.                 turtle.select(n)\
  11232.                 if turtle.refuel(1) then\
  11233.                     turtle.select(1)\
  11234.                     return true\
  11235.                 end\
  11236.             end\
  11237.         end\
  11238.         turtle.select(1)\
  11239.         return false\
  11240.     end\
  11241.     \
  11242.     if not tryRefuel() then\
  11243.         print( \"Add more fuel to continue.\" )\
  11244.         while not tryRefuel() do\
  11245.             os.pullEvent( \"turtle_inventory\" )\
  11246.         end\
  11247.         print( \"Resuming Tunnel.\" )\
  11248.     end\
  11249. end\
  11250. \
  11251. local function tryUp()\
  11252.     refuel()\
  11253.     while not turtle.up() do\
  11254.         if turtle.detectUp() then\
  11255.             if not tryDigUp() then\
  11256.                 return false\
  11257.             end\
  11258.         elseif turtle.attackUp() then\
  11259.             collect()\
  11260.         else\
  11261.             sleep( 0.5 )\
  11262.         end\
  11263.     end\
  11264.     return true\
  11265. end\
  11266. \
  11267. local function tryDown()\
  11268.     refuel()\
  11269.     while not turtle.down() do\
  11270.         if turtle.detectDown() then\
  11271.             if not tryDigDown() then\
  11272.                 return false\
  11273.             end\
  11274.         elseif turtle.attackDown() then\
  11275.             collect()\
  11276.         else\
  11277.             sleep( 0.5 )\
  11278.         end\
  11279.     end\
  11280.     return true\
  11281. end\
  11282. \
  11283. local function tryForward()\
  11284.     refuel()\
  11285.     while not turtle.forward() do\
  11286.         if turtle.detect() then\
  11287.             if not tryDig() then\
  11288.                 return false\
  11289.             end\
  11290.         elseif turtle.attack() then\
  11291.             collect()\
  11292.         else\
  11293.             sleep( 0.5 )\
  11294.         end\
  11295.     end\
  11296.     return true\
  11297. end\
  11298. \
  11299. print( \"Tunnelling...\" )\
  11300. \
  11301. for n=1,length do\
  11302.     turtle.placeDown()\
  11303.     tryDigUp()\
  11304.     turtle.turnLeft()\
  11305.     tryDig()\
  11306.     tryUp()\
  11307.     tryDig()\
  11308.     turtle.turnRight()\
  11309.     turtle.turnRight()\
  11310.     tryDig()\
  11311.     tryDown()\
  11312.     tryDig()\
  11313.     turtle.turnLeft()\
  11314.     \
  11315.     if n<length then\
  11316.         tryDig()\
  11317.         if not tryForward() then\
  11318.             print( \"Aborting Tunnel.\" )\
  11319.             break\
  11320.         end\
  11321.     else\
  11322.         print( \"Tunnel complete.\" )\
  11323.     end\
  11324. \
  11325. end\
  11326. \
  11327. --[[\
  11328. print( \"Returning to start...\" )\
  11329. \
  11330. -- Return to where we started\
  11331. turtle.turnLeft()\
  11332. turtle.turnLeft()\
  11333. while depth > 0 do\
  11334.     if turtle.forward() then\
  11335.         depth = depth - 1\
  11336.     else\
  11337.         turtle.dig()\
  11338.     end\
  11339. end\
  11340. turtle.turnRight()\
  11341. turtle.turnRight()\
  11342. ]]\
  11343. \
  11344. print( \"Tunnel complete.\" )\
  11345. print( \"Mined \"..collected..\" items total.\" )",
  11346.   [ "/rom/apis/keys" ] = "\
  11347. -- Minecraft key code bindings\
  11348. -- See http://www.minecraftwiki.net/wiki/Key_codes for more info\
  11349. \
  11350. local nothing = 42\
  11351. local tKeys = {\
  11352.     nil,        \"one\",        \"two\",        \"three\",  \"four\",           -- 1\
  11353.     \"five\",   \"six\",        \"seven\",  \"eight\",  \"nine\",           -- 6\
  11354.     \"zero\",   \"minus\",  \"equals\",     \"backspace\",\"tab\",          -- 11\
  11355.     \"q\",      \"w\",      \"e\",      \"r\",      \"t\",          -- 16\
  11356.     \"y\",      \"u\",      \"i\",      \"o\",      \"p\",          -- 21\
  11357.     \"leftBracket\",\"rightBracket\",\"enter\",\"leftCtrl\",\"a\",          -- 26\
  11358.     \"s\",      \"d\",      \"f\",      \"g\",      \"h\",          -- 31\
  11359.     \"j\",      \"k\",      \"l\",      \"semiColon\",\"apostrophe\",   -- 36\
  11360.     \"grave\"\"leftShift\",\"backslash\",\"z\",      \"x\",          -- 41\
  11361.     \"c\",      \"v\",      \"b\",      \"n\",      \"m\",          -- 46\
  11362.     \"comma\"\"period\", \"slash\"\"rightShift\",\"multiply\",    -- 51\
  11363.     \"leftAlt\",    \"space\"\"capsLock\",   \"f1\",     \"f2\",         -- 56\
  11364.     \"f3\",     \"f4\",     \"f5\",     \"f6\",     \"f7\",         -- 61\
  11365.     \"f8\",     \"f9\",     \"f10\",        \"numLock\",    \"scollLock\",  -- 66   \
  11366.     \"numPad7\",    \"numPad8\",    \"numPad9\",    \"numPadSubtract\",\"numPad4\", -- 71\
  11367.     \"numPad5\",    \"numPad6\",    \"numPadAdd\",\"numPad1\"\"numPad2\",        -- 76\
  11368.     \"numPad3\",    \"numPad0\",    \"numPadDecimal\",nil,  nil,            -- 81\
  11369.     nil,        \"f11\",        \"f12\",        nil,        nil,            -- 86\
  11370.     nil,        nil,        nil,        nil,        nil,            -- 91\
  11371.     nil,        nil,        nil,        nil,        \"f13\",            -- 96\
  11372.     \"f14\",        \"f15\",        nil,        nil,        nil,            -- 101\
  11373.     nil,        nil,        nil,        nil,        nil,            -- 106\
  11374.     nil,        \"kana\",       nil,        nil,        nil,            -- 111\
  11375.     nil,        nil,        nil,        nil,        nil,            -- 116  \
  11376.     \"convert\",    nil,        \"noconvert\",nil,      \"yen\",            -- 121\
  11377.     nil,        nil,        nil,        nil,        nil,            -- 126\
  11378.     nil,        nil,        nil,        nil,        nil,            -- 131\
  11379.     nil,        nil,        nil,        nil,        nil,            -- 136\
  11380.     \"numPadEquals\",nil,       nil,        \"cimcumflex\",\"at\",          -- 141\
  11381.     \"colon\"\"underscore\",\"kanji\",   \"stop\",       \"ax\",         -- 146\
  11382.     nil,        \"numPadEnter\",\"rightCtrl\",nil,      nil,            -- 151\
  11383.     nil,        nil,        nil,        nil,        nil,            -- 156\
  11384.     nil,        nil,        nil,        nil,        nil,            -- 161\
  11385.     nil,        nil,        nil,        nil,        nil,            -- 166\
  11386.     nil,        nil,        nil,        nil,        nil,            -- 171\
  11387.     nil,        nil,        nil,        \"numPadComma\",nil,            -- 176\
  11388.     \"numPadDivide\",nil,       nil,        \"rightAlt\",   nil,            -- 181\
  11389.     nil,        nil,        nil,        nil,        nil,            -- 186\
  11390.     nil,        nil,        nil,        nil,        nil,            -- 191\
  11391.     nil,        \"pause\",  nil,        \"home\",       \"up\",         -- 196\
  11392.     \"pageUp\", nil,        \"left\",       nil,        \"right\",      -- 201\
  11393.     nil,        \"end\",        \"down\",       \"pageDown\",   \"insert\",     -- 206\
  11394.     \"delete\"                                                      -- 211\
  11395. }\
  11396. \
  11397. local keys = getfenv()\
  11398. for nKey, sKey in pairs( tKeys ) do\
  11399.     keys[sKey] = nKey\
  11400. end\
  11401. keys[\"return\"] = keys.enter\
  11402. \
  11403. function getName( _nKey )\
  11404.     return tKeys[ _nKey ]\
  11405. end",
  11406.   [ "/rom/programs/fun/advanced/paint" ] = "-- Paint created by nitrogenfingers (edited by dan200)\
  11407. -- http://www.youtube.com/user/NitrogenFingers\
  11408. \
  11409. ------------\
  11410. -- Fields --\
  11411. ------------\
  11412. \
  11413. -- The width and height of the terminal\
  11414. local w,h = term.getSize()\
  11415. \
  11416. -- The selected colours on the left and right mouse button, and the colour of the canvas\
  11417. local leftColour, rightColour = colours.white, nil\
  11418. local canvasColour = colours.black\
  11419. \
  11420. -- The values stored in the canvas\
  11421. local canvas = {}\
  11422. \
  11423. -- The menu options\
  11424. local mChoices = { \"Save\",\"Exit\" }\
  11425. \
  11426. -- The message displayed in the footer bar\
  11427. local fMessage = \"Press Ctrl to access menu\"\
  11428. \
  11429. -------------------------\
  11430. -- Initialisation --\
  11431. -------------------------\
  11432. \
  11433. -- Determine if we can even run this\
  11434. if not term.isColour() then\
  11435.     print(\"Requires an Advanced Computer\")\
  11436.     return\
  11437. end\
  11438. \
  11439. -- Determines if the file exists, and can be edited on this computer\
  11440. local tArgs = {...}\
  11441. if #tArgs == 0 then\
  11442.     print(\"Usage: paint <path>\")\
  11443.     return\
  11444. end\
  11445. local sPath = shell.resolve(tArgs[1])\
  11446. local bReadOnly = fs.isReadOnly(sPath)\
  11447. if fs.exists(sPath) and fs.isDir(sPath) then\
  11448.     print(\"Cannot edit a directory.\")\
  11449.     return\
  11450. end\
  11451. \
  11452. ---------------\
  11453. -- Functions --\
  11454. ---------------\
  11455. \
  11456. local function getCanvasPixel( x, y )\
  11457.    if canvas[y] then\
  11458.        return canvas[y][x]\
  11459.    end\
  11460.    return nil\
  11461. end\
  11462. \
  11463. --[[\
  11464.     Converts a colour value to a text character\
  11465.     params: colour = the number to convert to a hex value\
  11466.     returns: a string representing the chosen colour\
  11467. ]]\
  11468. local function getCharOf( colour )\
  11469.     -- Incorrect values always convert to nil\
  11470.     if type(colour) == \"number\" then\
  11471.         local value = math.floor( math.log(colour) / math.log(2) ) + 1\
  11472.         if value >= 1 and value <= 16 then\
  11473.             return string.sub( \"0123456789abcdef\", value, value )\
  11474.         end\
  11475.     end\
  11476.     return \" \"\
  11477. end \
  11478. \
  11479. --[[\
  11480.     Converts a text character to colour value\
  11481.     params: char = the char (from string.byte) to convert to number\
  11482.     returns: the colour number of the hex value\
  11483. ]]\
  11484. local tColourLookup = {}\
  11485. for n=1,16 do\
  11486.     tColourLookup[ string.byte( \"0123456789abcdef\",n,n ) ] = 2^(n-1)\
  11487. end\
  11488. local function getColourOf( char )\
  11489.     -- Values not in the hex table are transparent (canvas coloured)\
  11490.     return tColourLookup[char]\
  11491. end\
  11492. \
  11493. --[[ \
  11494.     Loads the file into the canvas\
  11495.     params: path = the path of the file to open\
  11496.     returns: nil\
  11497. ]]\
  11498. local function load(path)\
  11499.     -- Load the file\
  11500.     if fs.exists(path) then\
  11501.         local file = fs.open(sPath, \"r\")\
  11502.         local sLine = file.readLine()\
  11503.         while sLine do\
  11504.             local line = {}\
  11505.             for x=1,w-2 do\
  11506.                 line[x] = getColourOf( string.byte(sLine,x,x) )\
  11507.             end\
  11508.             table.insert( canvas, line )\
  11509.             sLine = file.readLine()\
  11510.         end\
  11511.         file.close()\
  11512.     end\
  11513. end\
  11514. \
  11515. --[[  \
  11516.     Saves the current canvas to file  \
  11517.     params: path = the path of the file to save\
  11518.     returns: true if save was successful, false otherwise\
  11519. ]]\
  11520. local function save(path)\
  11521.    -- Open file\
  11522.     local sDir = string.sub(sPath, 1, #sPath - #fs.getName(sPath))\
  11523.     if not fs.exists(sDir) then\
  11524.         fs.makeDir(sDir)\
  11525.     end\
  11526. \
  11527.     local file = fs.open( path, \"w\" )\
  11528.     if not file then\
  11529.         return false\
  11530.     end\
  11531. \
  11532.    -- Encode (and trim)\
  11533.     local tLines = {}\
  11534.     local nLastLine = 0\
  11535.     for y=1,h-1 do\
  11536.         local sLine = \"\"\
  11537.         local nLastChar = 0\
  11538.         for x=1,w-2 do\
  11539.             local c = getCharOf( getCanvasPixel( x, y ) )\
  11540.             sLine = sLine .. c\
  11541.             if c ~= \" \" then\
  11542.                 nLastChar = x\
  11543.             end\
  11544.         end\
  11545.         sLine = string.sub( sLine, 1, nLastChar )\
  11546.         tLines[y] = sLine\
  11547.         if string.len( sLine ) > 0 then\
  11548.             nLastLine = y\
  11549.         end\
  11550.     end\
  11551. \
  11552.    -- Save out\
  11553.     for n=1,nLastLine do\
  11554.         file.writeLine( tLines[ n ] )\
  11555.     end\
  11556.     file.close()\
  11557.     return true\
  11558. end\
  11559. \
  11560. --[[  \
  11561.     Draws colour picker sidebar, the pallette and the footer\
  11562.     returns: nil\
  11563. ]]\
  11564. local function drawInterface()\
  11565.     -- Footer\
  11566.     term.setCursorPos(1, h)\
  11567.     term.setBackgroundColour(colours.black)\
  11568.     term.setTextColour(colours.yellow)\
  11569.     term.clearLine()\
  11570.     term.write(fMessage)\
  11571.     \
  11572.     -- Colour Picker\
  11573.     for i=1,16 do\
  11574.         term.setCursorPos(w-1, i)\
  11575.         term.setBackgroundColour( 2^(i-1) )\
  11576.         term.write(\"  \")\
  11577.     end\
  11578. \
  11579.     term.setCursorPos(w-1, 17)\
  11580.     term.setBackgroundColour( canvasColour )\
  11581.     term.setTextColour( colours.grey )\
  11582.     term.write(\"XX\")\
  11583.             \
  11584.     -- Left and Right Selected Colours\
  11585.     for i=18,18 do\
  11586.         term.setCursorPos(w-1, i)\
  11587.         if leftColour ~= nil then\
  11588.             term.setBackgroundColour( leftColour )\
  11589.             term.write(\" \")\
  11590.         else\
  11591.             term.setBackgroundColour( canvasColour )\
  11592.             term.setTextColour( colours.grey )\
  11593.             term.write(\"X\")\
  11594.         end\
  11595.         if rightColour ~= nil then\
  11596.             term.setBackgroundColour( rightColour )\
  11597.             term.write(\" \")\
  11598.         else\
  11599.             term.setBackgroundColour( canvasColour )\
  11600.             term.setTextColour( colours.grey )\
  11601.             term.write(\"X\")\
  11602.         end\
  11603.     end\
  11604. \
  11605.     -- Padding\
  11606.     term.setBackgroundColour( canvasColour )\
  11607.     for i=20,h-1 do\
  11608.         term.setCursorPos(w-1, i)\
  11609.         term.write(\"  \")\
  11610.     end\
  11611. end\
  11612. \
  11613. --[[  \
  11614.     Converts a single pixel of a single line of the canvas and draws it\
  11615.     returns: nil\
  11616. ]]\
  11617. local function drawCanvasPixel( x, y )\
  11618.     local pixel = getCanvasPixel( x, y )\
  11619.     if pixel then\
  11620.         term.setBackgroundColour( pixel or canvasColour )\
  11621.         term.setCursorPos(x, y)\
  11622.         term.write(\" \")\
  11623.     else\
  11624.         term.setBackgroundColour( canvasColour )\
  11625.         term.setTextColour( colours.grey )\
  11626.         term.setCursorPos(x, y)\
  11627.        term.write(\"-\")\
  11628.     end\
  11629. end\
  11630. \
  11631. --[[  \
  11632.     Converts each colour in a single line of the canvas and draws it\
  11633.     returns: nil\
  11634. ]]\
  11635. local function drawCanvasLine( y )\
  11636.     for x = 1, w-2 do\
  11637.         drawCanvasPixel( x, y )\
  11638.     end\
  11639. end\
  11640. \
  11641. --[[  \
  11642.     Converts each colour in the canvas and draws it\
  11643.     returns: nil\
  11644. ]]\
  11645. local function drawCanvas()\
  11646.     for y = 1, h-1 do\
  11647.         drawCanvasLine( y )\
  11648.     end\
  11649. end\
  11650. \
  11651. --[[\
  11652.     Draws menu options and handles input from within the menu.\
  11653.     returns: true if the program is to be exited; false otherwise\
  11654. ]]\
  11655. local function accessMenu()\
  11656.     -- Selected menu option\
  11657.     local selection = 1\
  11658.     \
  11659.     term.setBackgroundColour(colours.black)\
  11660.     while true do\
  11661.         -- Draw the menu\
  11662.         term.setCursorPos(1,h)\
  11663.         term.clearLine()\
  11664.         term.setTextColour(colours.white)\
  11665.         for k,v in pairs(mChoices) do\
  11666.             if selection==k then \
  11667.                 term.setTextColour(colours.yellow)\
  11668.                 local ox,_ = term.getCursorPos()\
  11669.                 term.write(\"[\"..string.rep(\" \",#v)..\"]\")\
  11670.                 term.setCursorPos(ox+1,h)\
  11671.                 term.setTextColour(colours.white)\
  11672.                 term.write(v)\
  11673.                 term.setCursorPos(term.getCursorPos()+1,h)\
  11674.             else\
  11675.                 term.write(\" \"..v..\" \")\
  11676.             end\
  11677.         end\
  11678.         \
  11679.         -- Handle input in the menu\
  11680.         local id,key = os.pullEvent(\"key\")\
  11681.         if id == \"key\" then\
  11682.             -- S and E are shortcuts\
  11683.             if key == keys.s then\
  11684.                 selection = 1\
  11685.                 key = keys.enter\
  11686.             elseif key == keys.e then\
  11687.                 selection = 2\
  11688.                 key = keys.enter\
  11689.             end\
  11690.         \
  11691.             if key == keys.right then\
  11692.                 -- Move right\
  11693.                 selection = selection + 1\
  11694.                 if selection > #mChoices then\
  11695.                     selection = 1\
  11696.                 end\
  11697.                 \
  11698.             elseif key == keys.left and selection > 1 then\
  11699.                 -- Move left\
  11700.                 selection = selection - 1\
  11701.                 if selection < 1 then\
  11702.                     selection = #mChoices\
  11703.                 end\
  11704.                 \
  11705.             elseif key == keys.enter then\
  11706.                 -- Select an option\
  11707.                 if mChoices[selection]==\"Save\" then \
  11708.                     if bReadOnly then \
  11709.                         fMessage = \"Access Denied\"\
  11710.                         return false\
  11711.                     end\
  11712.                     local success = save(sPath)\
  11713.                     if success then\
  11714.                         fMessage = \"Saved to \"..sPath\
  11715.                     else\
  11716.                         fMessage = \"Error saving to \"..sPath\
  11717.                     end\
  11718.                     return false\
  11719.                 elseif mChoices[selection]==\"Exit\" then \
  11720.                     return true\
  11721.                 end\
  11722.             elseif key == keys.leftCtrl or keys == keys.rightCtrl then\
  11723.                 -- Cancel the menu\
  11724.                 return false \
  11725.             end\
  11726.         end\
  11727.     end\
  11728. end\
  11729. \
  11730. --[[  \
  11731.     Runs the main thread of execution. Draws the canvas and interface, and handles\
  11732.     mouse and key events.\
  11733.     returns: nil\
  11734. ]]\
  11735. local function handleEvents()\
  11736.     local programActive = true\
  11737.     while programActive do\
  11738.         local id,p1,p2,p3 = os.pullEvent()\
  11739.         if id==\"mouse_click\" or id==\"mouse_drag\" then\
  11740.             if p2 >= w-1 and p3 >= 1 and p3 <= 17 then\
  11741.                 if id ~= \"mouse_drag\" then\
  11742.                     -- Selecting an items in the colour picker\
  11743.                     if p3 <= 16 then\
  11744.                         if p1==1 then\
  11745.                             leftColour = 2^(p3-1)\
  11746.                         else\
  11747.                             rightColour = 2^(p3-1)\
  11748.                         end\
  11749.                     else\
  11750.                         if p1==1 then\
  11751.                             leftColour = nil\
  11752.                         else\
  11753.                             rightColour = nil\
  11754.                         end\
  11755.                     end\
  11756.                     --drawCanvas()\
  11757.                     drawInterface()\
  11758.                 end\
  11759.             elseif p2 < w-1 and p3 <= h-1 then\
  11760.                 -- Clicking on the canvas\
  11761.                 local paintColour = nil\
  11762.                 if p1==1 then\
  11763.                     paintColour = leftColour\
  11764.                 elseif p1==2 then\
  11765.                     paintColour = rightColour\
  11766.                 end\
  11767.                 if not canvas[p3] then\
  11768.                    canvas[p3] = {}\
  11769.                 end\
  11770.                canvas[p3][p2] = paintColour\
  11771. \
  11772.                 drawCanvasPixel( p2, p3 )\
  11773.             end\
  11774.         elseif id==\"key\" then\
  11775.             if p1==keys.leftCtrl or p1==keys.rightCtrl then\
  11776.                 programActive = not accessMenu()\
  11777.                 drawInterface()\
  11778.             end\
  11779.         elseif id==\"term_resize\" then\
  11780.             w,h = term.getSize()\
  11781.            drawCanvas()\
  11782.            drawInterface()\
  11783.        end\
  11784.     end\
  11785. end\
  11786. \
  11787. -- Init\
  11788. load(sPath)\
  11789. drawCanvas()\
  11790. drawInterface()\
  11791. \
  11792. -- Main loop\
  11793. handleEvents()\
  11794. \
  11795. -- Shutdown\
  11796. term.setBackgroundColour(colours.black)\
  11797. term.setTextColour(colours.white)\
  11798. term.clear()\
  11799. term.setCursorPos(1,1)",
  11800.   [ "/rom/programs/copy" ] = "\
  11801. local tArgs = { ... }\
  11802. if #tArgs < 2 then\
  11803.     print( \"Usage: cp <source> <destination>\" )\
  11804.     return\
  11805. end\
  11806. \
  11807. local sSource = shell.resolve( tArgs[1] )\
  11808. local sDest = shell.resolve( tArgs[2] )\
  11809. local tFiles = fs.find( sSource )\
  11810. if #tFiles > 0 then\
  11811.    for n,sFile in ipairs( tFiles ) do\
  11812.        if fs.isDir( sDest ) then\
  11813.            fs.copy( sFile, fs.combine( sDest, fs.getName(sFile) ) )\
  11814.        elseif #tFiles == 1 then\
  11815.            fs.copy( sFile, sDest )\
  11816.        else\
  11817.            printError( \"Cannot overwrite file multiple times\" )\
  11818.            return\
  11819.        end\
  11820.    end\
  11821. else\
  11822.    printError( \"No matching files\" )\
  11823. end",
  11824.   [ "/rom/apis/window" ] = "\
  11825. function create( parent, nX, nY, nWidth, nHeight, bStartVisible )\
  11826. \
  11827.    if type( parent ) ~= \"table\" or\
  11828.       type( nX ) ~= \"number\" or\
  11829.       type( nY ) ~= \"number\" or\
  11830.       type( nWidth ) ~= \"number\" or\
  11831.       type( nHeight ) ~= \"number\" or\
  11832.       (bStartVisible ~= nil and type( bStartVisible ) ~= \"boolean\") then\
  11833.        error( \"Expected object, number, number, number, number, [boolean]\", 2 )\
  11834.    end\
  11835. \
  11836.    if parent == term then\
  11837.        error( \"term is not a recommended window parent, try term.current() instead\", 2 )\
  11838.    end\
  11839. \
  11840.    -- Setup\
  11841.    local bVisible = (bStartVisible ~= false)\
  11842.    local nCursorX = 1\
  11843.    local nCursorY = 1\
  11844.    local bCursorBlink = false\
  11845.    local nTextColor = colors.white\
  11846.    local nBackgroundColor = colors.black\
  11847.    local sEmpty = string.rep( \" \", nWidth )\
  11848.    local tLines = {}\
  11849.    do\
  11850.        local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }\
  11851.        for y=1,nHeight do\
  11852.            tLines[y] = tEmpty\
  11853.        end\
  11854.    end\
  11855. \
  11856.    -- Helper functions\
  11857.    local function updateCursorPos()\
  11858.        if nCursorX >= 1 and nCursorY >= 1 and\
  11859.           nCursorX <= nWidth and nCursorY <= nHeight then\
  11860.            parent.setCursorPos( nX + nCursorX - 1, nY + nCursorY - 1 )\
  11861.        else\
  11862.            parent.setCursorPos( 0, 0 )\
  11863.        end\
  11864.    end\
  11865.    \
  11866.    local function updateCursorBlink()\
  11867.        parent.setCursorBlink( bCursorBlink )\
  11868.    end\
  11869.    \
  11870.    local function updateCursorColor()\
  11871.        parent.setTextColor( nTextColor )\
  11872.    end\
  11873.    \
  11874.    local function redrawLine( n )\
  11875.        parent.setCursorPos( nX, nY + n - 1 )\
  11876.        local tLine = tLines[ n ]\
  11877.        for m=1,#tLine do\
  11878.            local tBit = tLine[ m ]\
  11879.            parent.setTextColor( tBit[2] )\
  11880.            parent.setBackgroundColor( tBit[3] )\
  11881.            parent.write( tBit[1] )\
  11882.        end\
  11883.    end\
  11884. \
  11885.    local function lineLen( tLine )\
  11886.        local nLength = 0\
  11887.        for n=1,#tLine do\
  11888.            nLength = nLength + string.len( tLine[n][1] )\
  11889.        end\
  11890.        return nLength\
  11891.    end\
  11892. \
  11893.    local function lineSub( tLine, nStart, nEnd )\
  11894.        --assert( math.floor(nStart) == nStart )\
  11895.        --assert( math.floor(nEnd) == nEnd )\
  11896.        --assert( nStart >= 1 )\
  11897.        --assert( nEnd >= nStart )\
  11898.        --assert( nEnd <= lineLen( tLine ) )\
  11899.        local tSubLine = {}\
  11900.        local nBitStart = 1\
  11901.        for n=1,#tLine do\
  11902.            local tBit = tLine[n]\
  11903.            local sBit = tBit[1]\
  11904.            local nBitEnd = nBitStart + string.len( sBit ) - 1\
  11905.            if nBitEnd >= nStart and nBitStart <= nEnd then\
  11906.                if nBitStart >= nStart and nBitEnd <= nEnd then\
  11907.                    -- Include bit wholesale\
  11908.                    table.insert( tSubLine, tBit )\
  11909.                    --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )\
  11910.                elseif nBitStart < nStart and nBitEnd <= nEnd then\
  11911.                    -- Include end of bit\
  11912.                    table.insert( tSubLine, {\
  11913.                        string.sub( sBit, nStart - nBitStart + 1 ),\
  11914.                        tBit[2], tBit[3]\
  11915.                    } )\
  11916.                    --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )\
  11917.                elseif nBitStart >= nStart and nBitEnd > nEnd then\
  11918.                    -- Include beginning of bit\
  11919.                    table.insert( tSubLine, {\
  11920.                        string.sub( sBit, 1, nEnd - nBitStart + 1 ),\
  11921.                        tBit[2], tBit[3]\
  11922.                    } )\
  11923.                    --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )\
  11924.                else\
  11925.                    -- Include middle of bit\
  11926.                    table.insert( tSubLine, {\
  11927.                        string.sub( sBit, nStart - nBitStart + 1, nEnd - nBitStart + 1 ),\
  11928.                        tBit[2], tBit[3]\
  11929.                    } )\
  11930.                    --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )\
  11931.                end\
  11932.            end\
  11933.            nBitStart = nBitEnd + 1\
  11934.        end\
  11935.        --assert( lineLen( tSubLine ) == (nEnd - nStart + 1) )\
  11936.        return tSubLine\
  11937.    end\
  11938. \
  11939.    local function lineJoin( tLine1, tLine2 )\
  11940.        local tNewLine = {}\
  11941.        if tLine1[#tLine1][2] == tLine2[1][2] and\
  11942.           tLine1[#tLine1][3] == tLine2[1][3] then\
  11943.            -- Merge middle bits\
  11944.            for n=1,#tLine1-1 do\
  11945.                table.insert( tNewLine, tLine1[n] )\
  11946.            end\
  11947.            table.insert( tNewLine, {\
  11948.                tLine1[#tLine1][1] .. tLine2[1][1],\
  11949.                tLine2[1][2], tLine2[1][3]\
  11950.            } )\
  11951.            for n=2,#tLine2 do\
  11952.                table.insert( tNewLine, tLine2[n] )\
  11953.            end\
  11954.            --assert( lineLen( tNewLine ) == lineLen(tLine1) + lineLen(tLine2) )\
  11955.        else\
  11956.            -- Just concatenate\
  11957.            for n=1,#tLine1 do\
  11958.                table.insert( tNewLine, tLine1[n] )\
  11959.            end\
  11960.            for n=1,#tLine2 do\
  11961.                table.insert( tNewLine, tLine2[n] )\
  11962.            end\
  11963.            --assert( lineLen( tNewLine ) == lineLen(tLine1) + lineLen(tLine2) )\
  11964.        end\
  11965.        return tNewLine\
  11966.    end\
  11967. \
  11968.    local function redraw()\
  11969.        for n=1,nHeight do\
  11970.            redrawLine( n )\
  11971.        end\
  11972.    end\
  11973. \
  11974.    local window = {}\
  11975. \
  11976.    -- Terminal implementation\
  11977.    function window.write( sText )\
  11978.        local nLen = string.len( sText )\
  11979.        local nStart = nCursorX\
  11980.        local nEnd = nStart + nLen - 1\
  11981.        if nCursorY >= 1 and nCursorY <= nHeight then\
  11982.            -- Work out where to put new line\
  11983.            --assert( math.floor(nStart) == nStart )\
  11984.            --assert( math.floor(nEnd) == nEnd )\
  11985.            if nStart <= nWidth and nEnd >= 1 then\
  11986.                -- Construct new line\
  11987.                local tLine = tLines[ nCursorY ]\
  11988.                if nStart == 1 and nEnd == nWidth then\
  11989.                    -- Exactly replace line\
  11990.                    tLine = {\
  11991.                        { sText, nTextColor, nBackgroundColor }\
  11992.                    }\
  11993.                    --assert( lineLen( tLine ) == nWidth )\
  11994.                elseif nStart <= 1 and nEnd >= nWidth then\
  11995.                    -- Overwrite line with subset\
  11996.                    tLine = {\
  11997.                        { string.sub( sText, 1 - nStart + 1, nWidth - nStart + 1 ), nTextColor, nBackgroundColor }\
  11998.                    }\
  11999.                    --assert( lineLen( tLine ) == nWidth )\
  12000.                elseif nStart <= 1 then\
  12001.                    -- Overwrite beginning of line\
  12002.                    tLine = lineJoin(\
  12003.                        { { string.sub( sText, 1 - nStart + 1 ), nTextColor, nBackgroundColor } },\
  12004.                        lineSub( tLine, nEnd + 1, nWidth )\
  12005.                    )\
  12006.                    --assert( lineLen( tLine ) == nWidth )\
  12007.                elseif nEnd >= nWidth then\
  12008.                    -- Overwrite end of line\
  12009.                    tLine = lineJoin(\
  12010.                        lineSub( tLine, 1, nStart - 1 ),\
  12011.                        { { string.sub( sText, 1, nWidth - nStart + 1 ), nTextColor, nBackgroundColor } }\
  12012.                    )\
  12013.                    --assert( lineLen( tLine ) == nWidth )\
  12014.                else\
  12015.                    -- Overwrite middle of line\
  12016.                    tLine = lineJoin(\
  12017.                        lineJoin(\
  12018.                            lineSub( tLine, 1, nStart - 1 ),\
  12019.                            { { sText, nTextColor, nBackgroundColor } }\
  12020.                        ),\
  12021.                        lineSub( tLine, nEnd + 1, nWidth )\
  12022.                    )\
  12023.                    --assert( lineLen( tLine ) == nWidth )\
  12024.                end\
  12025. \
  12026.                -- Store and redraw new line\
  12027.                tLines[ nCursorY ] = tLine\
  12028.                if bVisible then\
  12029.                    redrawLine( nCursorY )\
  12030.                end\
  12031.            end\
  12032.        end\
  12033. \
  12034.        -- Move and redraw cursor\
  12035.        nCursorX = nEnd + 1\
  12036.        if bVisible then\
  12037.            updateCursorColor()\
  12038.            updateCursorPos()\
  12039.        end\
  12040.    end\
  12041. \
  12042.    function window.clear()\
  12043.        local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }\
  12044.        for y=1,nHeight do\
  12045.            tLines[y] = tEmpty\
  12046.        end\
  12047.        if bVisible then\
  12048.            redraw()\
  12049.            updateCursorColor()\
  12050.            updateCursorPos()\
  12051.        end\
  12052.    end\
  12053. \
  12054.    function window.clearLine()\
  12055.        if nCursorY >= 1 and nCursorY <= nHeight then\
  12056.            tLines[ nCursorY ] = { { sEmpty, nTextColor, nBackgroundColor } }\
  12057.            if bVisible then\
  12058.                redrawLine( nCursorY )\
  12059.                updateCursorColor()\
  12060.                updateCursorPos()\
  12061.            end\
  12062.        end\
  12063.    end\
  12064. \
  12065.    function window.getCursorPos()\
  12066.        return nCursorX, nCursorY\
  12067.    end\
  12068. \
  12069.    function window.setCursorPos( x, y )\
  12070.        nCursorX = math.floor( x )\
  12071.        nCursorY = math.floor( y )\
  12072.        if bVisible then\
  12073.            updateCursorPos()\
  12074.        end\
  12075.    end\
  12076. \
  12077.    function window.setCursorBlink( blink )\
  12078.        bCursorBlink = blink\
  12079.        if bVisible then\
  12080.            updateCursorBlink()\
  12081.        end\
  12082.    end\
  12083. \
  12084.    function window.isColor()\
  12085.        return parent.isColor()\
  12086.    end\
  12087. \
  12088.    function window.isColour()\
  12089.        return parent.isColor()\
  12090.    end\
  12091. \
  12092.    local function setTextColor( color )\
  12093.        if not parent.isColor() then\
  12094.            if color ~= colors.white and color ~= colors.black then\
  12095.                error( \"Colour not supported\", 3 )\
  12096.            end\
  12097.        end\
  12098.        nTextColor = color\
  12099.        if bVisible then\
  12100.            updateCursorColor()\
  12101.        end\
  12102.    end\
  12103. \
  12104.    function window.setTextColor( color )\
  12105.        setTextColor( color )\
  12106.    end\
  12107. \
  12108.    function window.setTextColour( color )\
  12109.        setTextColor( color )\
  12110.    end\
  12111. \
  12112.    local function setBackgroundColor( color )\
  12113.        if not parent.isColor() then\
  12114.            if color ~= colors.white and color ~= colors.black then\
  12115.                error( \"Colour not supported\", 3 )\
  12116.            end\
  12117.        end\
  12118.        nBackgroundColor = color\
  12119.    end\
  12120. \
  12121.    function window.setBackgroundColor( color )\
  12122.        setBackgroundColor( color )\
  12123.    end\
  12124. \
  12125.    function window.setBackgroundColour( color )\
  12126.        setBackgroundColor( color )\
  12127.    end\
  12128. \
  12129.    function window.getSize()\
  12130.        return nWidth, nHeight\
  12131.    end\
  12132. \
  12133.    function window.scroll( n )\
  12134.        if n ~= 0 then\
  12135.            local tNewLines = {}\
  12136.            local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }\
  12137.            for newY=1,nHeight do\
  12138.                local y = newY + n\
  12139.                if y >= 1 and y <= nHeight then\
  12140.                    tNewLines[newY] = tLines[y]\
  12141.                else\
  12142.                    tNewLines[newY] = tEmpty\
  12143.                end\
  12144.            end\
  12145.            tLines = tNewLines\
  12146.            if bVisible then\
  12147.                redraw()\
  12148.                updateCursorColor()\
  12149.                updateCursorPos()\
  12150.            end\
  12151.        end\
  12152.    end\
  12153. \
  12154.    -- Other functions\
  12155.    function window.setVisible( bVis )\
  12156.        if bVisible ~= bVis then\
  12157.            bVisible = bVis\
  12158.            if bVisible then\
  12159.                window.redraw()\
  12160.            end\
  12161.        end\
  12162.    end\
  12163. \
  12164.    function window.redraw()\
  12165.        if bVisible then\
  12166.            redraw()\
  12167.            updateCursorBlink()\
  12168.            updateCursorColor()\
  12169.            updateCursorPos()\
  12170.        end\
  12171.    end\
  12172. \
  12173.    function window.restoreCursor()\
  12174.        if bVisible then\
  12175.            updateCursorBlink()\
  12176.            updateCursorColor()\
  12177.            updateCursorPos()\
  12178.        end\
  12179.    end\
  12180. \
  12181.    function window.getPosition()\
  12182.        return nX, nY\
  12183.    end\
  12184. \
  12185.    function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight )\
  12186.        nX = nNewX\
  12187.        nY = nNewY\
  12188.        if nNewWidth and nNewHeight then\
  12189.            sEmpty = string.rep( \" \", nNewWidth )\
  12190.            local tNewLines = {}\
  12191.            local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }\
  12192.            for y=1,nNewHeight do\
  12193.                if y > nHeight then\
  12194.                    tNewLines[y] = tEmpty\
  12195.                else\
  12196.                    if nNewWidth == nWidth then\
  12197.                        tNewLines[y] = tLines[y]\
  12198.                    elseif nNewWidth < nWidth then\
  12199.                        tNewLines[y] = lineSub( tLines[y], 1, nNewWidth )\
  12200.                    else\
  12201.                        tNewLines[y] = lineJoin( tLines[y], { { string.sub( sEmpty, nWidth + 1, nNewWidth ), nTextColor, nBackgroundColor } } )\
  12202.                    end\
  12203.                end\
  12204.            end\
  12205.            nWidth = nNewWidth\
  12206.            nHeight = nNewHeight\
  12207.            tLines = tNewLines\
  12208.        end\
  12209.        if bVisible then\
  12210.            window.redraw()\
  12211.        end\
  12212.    end\
  12213. \
  12214.    if bVisible then\
  12215.        window.redraw()\
  12216.    end\
  12217.    return window\
  12218. end",
  12219.   [ "/rom/help/turtle" ] = "turtle is an api availiable on Turtles, which controls their movement.\
  12220. Functions in the Turtle API:\
  12221. turtle.forward()\
  12222. turtle.back()\
  12223. turtle.up()\
  12224. turtle.down()\
  12225. turtle.turnLeft()\
  12226. turtle.turnRight()\
  12227. turtle.select( slotNum )\
  12228. turtle.getSelectedSlot()\
  12229. turtle.getItemCount( [slotNum] )\
  12230. turtle.getItemSpace( [slotNum] )\
  12231. turtle.getItemDetail( [slotNum] )\
  12232. turtle.equipLeft()\
  12233. turtle.equipRight()\
  12234. turtle.dig( [toolSide] )\
  12235. turtle.digUp( [toolSide] )\
  12236. turtle.digDown( [toolSide] )\
  12237. turtle.place()\
  12238. turtle.placeUp()\
  12239. turtle.placeDown()\
  12240. turtle.attack( [toolSide] )\
  12241. turtle.attackUp( [toolSide] )\
  12242. turtle.attackDown( [toolSide] )\
  12243. turtle.detect()\
  12244. turtle.detectUp()\
  12245. turtle.detectDown()\
  12246. turtle.compare()\
  12247. turtle.compareUp()\
  12248. turtle.compareDown()\
  12249. turtle.inspect()\
  12250. turtle.inspectUp()\
  12251. turtle.inspectDown()\
  12252. turtle.inspectSlot( [slotNum] )\
  12253. turtle.compareTo( slotNum )\
  12254. turtle.transferTo( slotNum, [quantity] )\
  12255. turtle.drop( [quantity] )\
  12256. turtle.dropUp( [quantity] )\
  12257. turtle.dropDown( [quantity] )\
  12258. turtle.suck( [quantity] )\
  12259. turtle.suckUp( [quantity] )\
  12260. turtle.suckDown( [quantity] )\
  12261. turtle.getFuelLevel()\
  12262. turtle.getFuelLimit()\
  12263. turtle.refuel( [quantity] )\
  12264. turtle.craft( [quantity] ) (requires Crafty Turtle)\
  12265. \
  12266. Events fired by the Turtle API:\
  12267. \"turtle_inventory\" when any of the items in the inventory are changed. Use comparison operations to inspect the changes.",
  12268.   [ "/rom/help/paintutils" ] = "Functions in the Paint Utilities API:\
  12269. paintutils.drawPixel( x, y, colour )\
  12270. paintutils.drawLine( startX, startY, endX, endY, colour )\
  12271. paintutils.drawBox( startX, startY, endX, endY, colour )\
  12272. paintutils.drawFilledBox( startX, startY, endX, endY, colour )\
  12273. paintutils.loadImage( path )\
  12274. paintutils.drawImage( image, x, y )",
  12275.   [ "/rom/help/modems" ] = "Wired and Wireless Modems are peripheral devices available for CraftOS. Type \"help peripheral\" to learn about using the Peripheral API to connect with peripherals. When a Modem is connected, peripheral.getType() will return \"modem\".\
  12276. \
  12277. Methods exposed by Modems:\
  12278. open( channel )\
  12279. isOpen( channel )\
  12280. close( channel )\
  12281. closeAll()\
  12282. transmit( channel, replyChannel, message )\
  12283. isWireless()\
  12284. \
  12285. Events fired by Modems:\
  12286. \"modem_message\" when a message is received on an open channel. Arguments are name, channel, replyChannel, message, distance",
  12287.   [ "/rom/programs/fun/advanced/levels/2" ] = "1\
  12288. 777777777\
  12289. 7888888b7\
  12290. 787778887\
  12291. 787 78777\
  12292. 7877787\
  12293. 7888887\
  12294. 7777787\
  12295.    707\
  12296.    777",
  12297.   [ "/rom/help/worm" ] = "You've played it in the arcades, now experience the high-octane thrills of the hit game \"WORM!\" on your home computer! Only on CraftOS!",
  12298.   [ "/Shop/States/Items.lua" ] = "local StateLib = FDK.require('lib.state')\
  12299. local State = StateLib.names.Init\
  12300. local Main = StateLib.names.Main\
  12301. local Search = StateLib.names.Search\
  12302. local Account = StateLib.names.Account\
  12303. local Items = StateLib.names.Items\
  12304. \
  12305. local Field = FDK.require('lib.UI.elements.Field')\
  12306. local Text = FDK.require('lib.UI.elements.Text')\
  12307. local Button = FDK.require('lib.UI.elements.Button')\
  12308. local ScrollBar = FDK.require('lib.UI.elements.ScrollBar')\
  12309. local Frame = FDK.require('lib.UI.elements.ClippingFrame')\
  12310. \
  12311. -- Main Field\
  12312. Items.frame:newChild(Field(1, 1, Items.frame.width, Items.frame.height, colors.white))\
  12313. -- Header Field\
  12314. Items.frame:newChild(Field(1, 1, Items.frame.width, 3, colors.lightGray))\
  12315. \
  12316. local back = Items.frame:newChild( Button( 1, 1, 8, 3, \"< back\" ) )\
  12317. back.bc = colors.lightGray\
  12318. back.tc = colors.white\
  12319. \
  12320. function back:onClick()\
  12321.  Main:show()\
  12322. end\
  12323. \
  12324. local ItemsFrame = Items.frame:newChild(Frame(1, 4,\
  12325.  Items.frame.width-2,\
  12326.  Items.frame.height-3\
  12327. ))\
  12328. local ItemsBar = Items.frame:newChild(ScrollBar(Items.frame.width, 4, 1, Items.frame.height-3, ItemsFrame))\
  12329. -- Add every Item from the database\
  12330. \
  12331. for k,v  in pairs(_G.DB.Items) do\
  12332. \
  12333. \
  12334. end",
  12335.   [ "/rom/help/changelog" ] = "New Features in ComputerCraft 1.65:\
  12336. \
  12337. * Fixed a multiplayer-only crash with turtle.place()\
  12338. * Fixed some problems with http.post()\
  12339. * Fixed fs.getDrive() returning incorrect results on remote peripherals\
  12340. \
  12341. New Features in ComputerCraft 1.64:\
  12342. \
  12343. * Ported to Minecraft 1.7.10\
  12344. * New turtle functions: turtle.inspect(), turtle.inspectUp(), turtle.inspectDown(), turtle.getItemDetail()\
  12345. * Lots of bug and crash fixes, a huge stability improvement over previous versions\
  12346. \
  12347. New Features in ComputerCraft 1.63:\
  12348. \
  12349. * Turtles can now be painted with dyes, and cleaned with water buckets\
  12350. * Added a new game: Redirection - ComputerCraft Edition\
  12351. * Turtle label nameplates now only show when the Turtle is moused-over\
  12352. * The HTTP API is now enabled by default, and can be configured with a whitelist of permitted domains\
  12353. * http.get() and http.post() now accept parameters to control the request headers\
  12354. * New fs function: fs.getDir( path )\
  12355. * Fixed some bugs\
  12356. \
  12357. New Features in ComputerCraft 1.62:\
  12358. \
  12359. * Added IRC-style commands to the \"chat\" program\
  12360. * Fixed some bugs and crashes\
  12361. \
  12362. New Features in ComputerCraft 1.6:\
  12363. \
  12364. * Added Pocket Computers\
  12365. * Added a multi-tasking system for Advanced Computers and Turtles\
  12366. * Turtles can now swap out their tools and peripherals at runtime\
  12367. * Turtles can now carry two tools or peripherals at once in any combination\
  12368. * Turtles and Computers can now be labelled using Name Tags and Anvils\
  12369. * Added a configurable fuel limit for Turtles\
  12370. * Added hostnames, protocols and long distance routing to the rednet API\
  12371. * Added a peer-to-peer chat program to demonstrate new rednet capabilities\
  12372. * Added a new game, only on Pocket Computers: \"falling\" by GopherATL\
  12373. * File system commands in the shell now accept wildcard arguments\
  12374. * The shell now accepts long arguments in quotes\
  12375. * Terminal redirection now no longer uses a stack-based system. Instead: term.current() gets the current terminal object and term.redirect() replaces it. term.restore() has been removed.\
  12376. * Added a new Windowing API for addressing sub-areas of the terminal\
  12377. * New programs: fg, bg, multishell, chat, repeat, redstone, equip, unequip\
  12378. * Improved programs: copy, move, delete, rename, paint, shell\
  12379. * Removed programs: redset, redprobe, redpulse\
  12380. * New APIs: window, multishell\
  12381. * New turtle functions: turtle.equipLeft() and turtle.equipRight()\
  12382. * New peripheral functions: peripheral.find( [type] )\
  12383. * New rednet functions: rednet.host( protocol, hostname ), rednet.unhost( protocol ), rednet.locate( protocol, [hostname] )\
  12384. * New fs function: fs.find( wildcard )\
  12385. * New shell functions: shell.openTab(), shell.switchTab( [number] )\
  12386. * New event \"term_resize\" fired when the size of a terminal changes\
  12387. * Improved rednet functions: rednet.send(), rednet.broadcast() and rednet.receive() now take optional protocol parameters\
  12388. * turtle.craft(0) and turtle.refuel(0) now return true if there is a valid recipe or fuel item, but do not craft of refuel anything\
  12389. * turtle.suck( [limit] ) can now be used to limit the number of items picked up\
  12390. * Users of turtle.dig() and turtle.attack() can now specify which side of the turtle to look for a tool to use (by default, both will be considered)\
  12391. * textutils.serialise( text ) now produces human-readable output\
  12392. * Refactored most of the codebase and fixed many old bugs and instabilities, turtles should never ever lose their content now\
  12393. * Fixed the \"turtle_inventory\" event firing when it shouldn't have\
  12394. * Added error messages to many more turtle functions after they return false\
  12395. * Documented all new programs and API changes in the \"help\" system\
  12396. \
  12397. New Features in ComputerCraft 1.58:\
  12398. \
  12399. * Fixed a long standing bug where turtles could lose their identify if they travel too far away\
  12400. * Fixed use of deprecated code, ensuring mod compatibility with the latest versions of Minecraft Forge, and world compatibility with future versions of Minecraft\
  12401. \
  12402. New Features in ComputerCraft 1.57:\
  12403. \
  12404. * Ported to Minecraft 1.6.4\
  12405. * Added two new Treasure Disks: ConwayåA2?2¬?4¢s Game of Life by vilsol and Protector by fredthead\
  12406. * Fixed a very nasty item duplication bug\
  12407. \
  12408. New Features in ComputerCraft 1.56:\
  12409. \
  12410. * Added Treasure Disks: Floppy Disks in dungeons which contain interesting community made programs. Find them all!\
  12411. * All turtle functions now return additional error messages when they fail.\
  12412. * Resource Packs with Lua Programs can now be edited when extracted to a folder, for easier editing.\
  12413. \
  12414. New Features in ComputerCraft 1.55:\
  12415. \
  12416. * Ported to Minecraft 1.6.2\
  12417. * Added Advanced Turtles\
  12418. * Added \"turtle_inventory\" event. Fires when any change is made to the inventory of a turtle\
  12419. * Added missing functions io.close, io.flush, io.input, io.lines, io.output\
  12420. * Tweaked the screen colours used by Advanced Computers, Monitors and Turtles\
  12421. * Added new features for Peripheral authors\
  12422. * Lua programs can now be included in Resource Packs\
  12423. \
  12424. New Features in ComputerCraft 1.52:\
  12425. \
  12426. * Ported to Minecraft 1.5.1\
  12427. \
  12428. New Features in ComputerCraft 1.51:\
  12429. \
  12430. * Ported to Minecraft 1.5\
  12431. * Added Wired Modems\
  12432. * Added Networking Cables\
  12433. * Made Wireless Modems more expensive to craft\
  12434. * New redstone API functions: getAnalogInput(), setAnalogOutput(), getAnalogOutput()\
  12435. * Peripherals can now be controlled remotely over wired networks. New peripheral API function: getNames()\
  12436. * New event: \"monitor_resize\" when the size of a monitor changes\
  12437. * Except for labelled computers and turtles, ComputerCraft blocks no longer drop items in creative mode\
  12438. * The pick block function works in creative mode now works for all ComputerCraft blocks\
  12439. * All blocks and items now use the IDs numbers assigned by FTB by default\
  12440. * Fixed turtles sometimes placing blocks with incorrect orientations\
  12441. * Fixed Wireless modems being able to send messages to themselves\
  12442. * Fixed turtle.attack() having a very short range\
  12443. * Various bugfixes\
  12444. \
  12445. New Features in ComputerCraft 1.5:\
  12446. \
  12447. * Redesigned Wireless Modems; they can now send and receive on multiple channels, independent of the computer ID. To use these features, interface with modem peripherals directly. The rednet API still functions as before\
  12448. * Floppy Disks can now be dyed with multiple dyes, just like armour\
  12449. * The \"excavate\" program now retains fuel in it's inventory, so can run unattended\
  12450. * turtle.place() now tries all possible block orientations before failing\
  12451. * turtle.refuel(0) returns true if a fuel item is selected\
  12452. * turtle.craft(0) returns true if the inventory is a valid recipe\
  12453. * The in-game help system now has documentation for all the peripherals and their methods, including the new modem functionality\
  12454. * A romantic surprise\
  12455. \
  12456. New Features in ComputerCraft 1.48:\
  12457. \
  12458. * Ported to Minecraft 1.4.6\
  12459. * Advanced Monitors now emit a \"monitor_touch\" event when right clicked\
  12460. * Advanced Monitors are now cheaper to craft\
  12461. * Turtles now get slightly less fuel from items\
  12462. * Computers can now interact with Command Blocks (if enabled in ComputerCraft.cfg)\
  12463. * New API function: os.day()\
  12464. * A christmas surprise\
  12465. \
  12466. New Features in ComputerCraft 1.45:\
  12467. \
  12468. * Added Advanced Computers\
  12469. * Added Advanced Monitors\
  12470. * New program: paint by nitrogenfingers\
  12471. * New API: paintutils\
  12472. * New term functions: term.setBackgroundColor, term.setTextColor, term.isColor\
  12473. * New turtle function: turtle.transferTo\
  12474. \
  12475. New Features in ComputerCraft 1.43:\
  12476. \
  12477. * Added Printed Pages\
  12478. * Added Printed Books\
  12479. * Fixed incompatibility with Forge 275 and above\
  12480. * Labelled Turtles now keep their fuel when broken\
  12481. \
  12482. New Features in ComputerCraft 1.42:\
  12483. \
  12484. * Ported to Minecraft 1.3.2\
  12485. * Added Printers\
  12486. * Floppy Disks can be dyed different colours\
  12487. * Wireless Crafty Turtles can now be crafted\
  12488. * New textures\
  12489. * New forge config file\
  12490. * Bug fixes\
  12491. \
  12492. New Features in ComputerCraft 1.4:\
  12493. \
  12494. * Ported to Forge Mod Loader. ComputerCraft can now be ran directly from the .zip without extraction\
  12495. * Added Farming Turtles\
  12496. * Added Felling Turtles\
  12497. * Added Digging Turtles\
  12498. * Added Melee Turtles\
  12499. * Added Crafty Turtles\
  12500. * Added 14 new Turtle Combinations accessible by combining the turtle upgrades above\
  12501. * Labelled computers and turtles can now be crafted into turtles or other turtle types without losing their ID, label and data\
  12502. * Added a \"Turtle Upgrade API\" for mod developers to create their own tools and peripherals for turtles\
  12503. * Turtles can now attack entities with turtle.attack(), and collect their dropped items\
  12504. * Turtles can now use turtle.place() with any item the player can, and can interact with entities\
  12505. * Turtles can now craft items with turtle.craft()\
  12506. * Turtles can now place items into inventories with turtle.drop()\
  12507. * Changed the behaviour of turtle.place() and turtle.drop() to only consider the currently selected slot\
  12508. * Turtles can now pick up items from the ground, or from inventories, with turtle.suck()\
  12509. * Turtles can now compare items in their inventories\
  12510. * Turtles can place signs with text on them with turtle.place( [signText] )\
  12511. * Turtles now optionally require fuel items to move, and can refuel themselves\
  12512. * The size of the the turtle inventory has been increased to 16\
  12513. * The size of the turtle screen has been increased\
  12514. * New turtle functions: turtle.compareTo( [slotNum] ), turtle.craft(), turtle.attack(), turtle.attackUp(), turtle.attackDown(), turtle.dropUp(), turtle.dropDown(), turtle.getFuelLevel(), turtle.refuel()\
  12515. * New disk function: disk.getID()\
  12516. * New turtle programs: craft, refuel\
  12517. * \"excavate\" program now much smarter: Will return items to a chest when full, attack mobs, and refuel itself automatically\
  12518. * New API: keys\
  12519. * Added optional Floppy Disk and Hard Drive space limits for computers and turtles\
  12520. * New fs function: fs.getFreeSpace( path ), also fs.getDrive() works again\
  12521. * The send and receive range of wireless modems now increases with altitude, allowing long range networking from high-altitude computers (great for GPS networks)\
  12522. * http.request() now supports https:// URLs\
  12523. * Right clicking a Disk Drive with a Floppy Disk or a Record when sneaking will insert the item into the Disk Drive automatically\
  12524. * The default size of the computer screen has been increased\
  12525. * Several stability and security fixes. LuaJ can now no longer leave dangling threads when a computer is unloaded, turtles can no longer be destroyed by tree leaves or walking off the edge of the loaded map. Computers no longer crash when used with RedPower frames.\
  12526. \
  12527. New Features in ComputerCraft 1.31:\
  12528. \
  12529. * Ported to Minecraft 1.2.3\
  12530. * Added Monitors (thanks to Cloudy)\
  12531. * Updated LuaJ to a newer, less memory hungry version\
  12532. * rednet_message event now has a third parameter, \"distance\", to support position triangulation.\
  12533. * New programs: gps, monitor, pastebin.\
  12534. * Added a secret program. Use with large monitors!\
  12535. * New apis: gps, vector\
  12536. * New turtle functions: turtle.compare(), turtle.compareUp(), turtle.compareDown(), turtle.drop( quantity )\
  12537. * New http functions: http.post().\
  12538. * New term functions: term.redirect(), term.restore()\
  12539. * New textutils functions: textutils.urlEncode()\
  12540. * New rednet functions: rednet.isOpen()\
  12541. * New config options: modem_range, modem_rangeDuringStorm\
  12542. * Bug fixes, program tweaks, and help updates\
  12543. \
  12544. New Features in ComputerCraft 1.3:\
  12545. \
  12546. * Ported to Minecraft Forge\
  12547. * Added Turtles\
  12548. * Added Wireless Modems\
  12549. * Added Mining Turtles\
  12550. * Added Wireless Turtles\
  12551. * Added Wireless Mining Turtles\
  12552. * Computers and Disk Drives no longer get destroyed by water.\
  12553. * Computers and Turtles can now be labelled with the label program, and labelled devices keep their state when destroyed.\
  12554. * Computers/Turtles can connect to adjacent devices, and turn them on and off\
  12555. * User programs now give line numbers in their error messages\
  12556. * New APIs: turtle, peripheral\
  12557. * New programs for turtles: tunnel, excavate, go, turn, dance\
  12558. * New os functions: os.getComputerLabel(), os.setComputerLabel()\
  12559. * Added \"filter\" parameter to os.pullEvent()\
  12560. * New shell function: shell.getCurrentProgram()\
  12561. * New textutils functions: textutils.serialize(), textutils.unserialize(), textutils.tabulate(), textutils.pagedTabulate(), textutils.slowWrite()\
  12562. * New io file function: file:lines()\
  12563. * New fs function: fs.getSize()\
  12564. * Disk Drives can now play records from other mods\
  12565. * Bug fixes, program tweaks, and help updates\
  12566. \
  12567. New Features in ComputerCraft 1.2:\
  12568. \
  12569. * Added Disk Drives and Floppy Disks\
  12570. * Added Ctrl+T shortcut to terminate the current program (hold)\
  12571. * Added Ctrl+S shortcut to shutdown the computer (hold)\
  12572. * Added Ctrl+R shortcut to reboot the computer (hold)\
  12573. * New Programs: alias, apis, copy, delete, dj, drive, eject, id, label, list, move, reboot, redset, rename, time, worm.\
  12574. * New APIs: bit, colours, disk, help, rednet, parallel, textutils.\
  12575. * New color functions: colors.combine(), colors.subtract(), colors.test()\
  12576. * New fs functions: fs.getName(), new modes for fs.open()\
  12577. * New os functions: os.loadAPI(), os.unloadAPI(),\
  12578. os.clock(), os.time(), os.setAlarm(),\
  12579. os.reboot(), os.queueEvent()\
  12580. * New redstone function: redstone.getSides()\
  12581. * New shell functions: shell.setPath(), shell.programs(), shell.resolveProgram(), shell.setAlias()\
  12582. * Lots of updates to the help pages\
  12583. * Bug fixes\
  12584. \
  12585. New Features in ComputerCraft 1.1:\
  12586. \
  12587. * Added Multiplayer support throughout.\
  12588. * Added connectivity with RedPower bundled cables\
  12589. * Added HTTP api, enabled via the mod config, to allow computers to access the real world internet\
  12590. * Added command history to the shell.\
  12591. * Programs which spin in an infinite loop without yielding will no longer freeze minecraft\
  12592. * Help updates and bug fixes\
  12593. \
  12594. New Features in ComputerCraft 1.0:\
  12595. \
  12596. * First Release!",
  12597.   [ "/rom/startup" ] = "\
  12598. -- Setup paths\
  12599. local sPath = \".:/rom/programs\"\
  12600. if term.isColor() then\
  12601.     sPath = sPath..\":/rom/programs/advanced\"\
  12602. end\
  12603. if turtle then\
  12604.     sPath = sPath..\":/rom/programs/turtle\"\
  12605. else\
  12606.    sPath = sPath..\":/rom/programs/rednet:/rom/programs/fun\"\
  12607.    if term.isColor() then\
  12608.         sPath = sPath..\":/rom/programs/fun/advanced\"\
  12609.    end\
  12610. end\
  12611. if pocket then\
  12612.    sPath = sPath..\":/rom/programs/pocket\"\
  12613. end\
  12614. if http then\
  12615.     sPath = sPath..\":/rom/programs/http\"\
  12616. end\
  12617. shell.setPath( sPath )\
  12618. help.setPath( \"/rom/help\" )\
  12619. \
  12620. -- Setup aliases\
  12621. shell.setAlias( \"ls\", \"list\" )\
  12622. shell.setAlias( \"dir\", \"list\" )\
  12623. shell.setAlias( \"cp\", \"copy\" )\
  12624. shell.setAlias( \"mv\", \"move\" )\
  12625. shell.setAlias( \"rm\", \"delete\" )\
  12626. shell.setAlias( \"clr\", \"clear\" )\
  12627. shell.setAlias( \"rs\", \"redstone\" )\
  12628. shell.setAlias( \"sh\", \"shell\" )\
  12629. if term.isColor() then\
  12630.    shell.setAlias( \"background\", \"bg\" )\
  12631.    shell.setAlias( \"foreground\", \"fg\" )\
  12632. end\
  12633. \
  12634. -- Run autorun files\
  12635. if fs.exists( \"/rom/autorun\" ) and fs.isDir( \"/rom/autorun\" ) then\
  12636.     local tFiles = fs.list( \"/rom/autorun\" )\
  12637.     table.sort( tFiles )\
  12638.     for n, sFile in ipairs( tFiles ) do\
  12639.         if string.sub( sFile, 1, 1 ) ~= \".\" then\
  12640.             local sPath = \"/rom/autorun/\"..sFile\
  12641.             if not fs.isDir( sPath ) then\
  12642.                 shell.run( sPath )\
  12643.             end\
  12644.         end\
  12645.     end\
  12646. end\
  12647. \
  12648. -- Run the user created startup, either from disk drives or the root\
  12649. local sUserStartup = shell.resolveProgram( \"/startup\" )\
  12650. for n,sName in pairs( peripheral.getNames() ) do\
  12651.    if disk.isPresent( sName ) and disk.hasData( sName ) then\
  12652.        local sDiskStartup = shell.resolveProgram( \"/\" .. disk.getMountPath( sName ) .. \"/startup\" )\
  12653.        if sDiskStartup then\
  12654.            sUserStartup = sDiskStartup\
  12655.            break\
  12656.        end\
  12657.    end\
  12658. end\
  12659. if sUserStartup then\
  12660.    shell.run( sUserStartup )\
  12661. end",
  12662.   [ "/rom/programs/redstone" ] = "\
  12663. local tArgs = { ... }\
  12664. \
  12665. local function printUsage()\
  12666.    print( \"Usages:\" )\
  12667.    print( \"redstone probe\" )\
  12668.    print( \"redstone set <side> <value>\" )\
  12669.    print( \"redstone set <side> <color> <value>\" )\
  12670.    print( \"redstone pulse <side> <count> <period>\" )\
  12671. end\
  12672. \
  12673. local sCommand = tArgs[1]\
  12674. if sCommand == \"probe\" then\
  12675.    -- \"redstone probe\"\
  12676.    -- Regular input\
  12677.    print( \"Redstone inputs: \" )\
  12678. \
  12679.    local count = 0\
  12680.    local bundledCount = 0\
  12681.    for n,sSide in ipairs( redstone.getSides() ) do\
  12682.        if redstone.getBundledInput( sSide ) > 0 then\
  12683.            bundledCount = bundledCount + 1\
  12684.        end\
  12685.        if redstone.getInput( sSide ) then\
  12686.            if count > 0 then\
  12687.                io.write( \", \" )\
  12688.            end\
  12689.            io.write( sSide )\
  12690.            count = count + 1\
  12691.        end\
  12692.    end\
  12693.    if count > 0 then\
  12694.        print( \".\" )\
  12695.    else\
  12696.        print( \"None.\" )\
  12697.    end\
  12698. \
  12699.    -- Bundled input\
  12700.    if bundledCount > 0 then\
  12701.        print()\
  12702.        print( \"Bundled inputs:\" )\
  12703.        for i,sSide in ipairs( redstone.getSides() ) do\
  12704.            local nInput = redstone.getBundledInput( sSide )\
  12705.            if nInput ~= 0 then\
  12706.                write( sSide..\": \" )\
  12707.                local count = 0\
  12708.                for sColour,nColour in pairs( colors ) do\
  12709.                    if type( nColour ) == \"number\" and colors.test( nInput, nColour ) then\
  12710.                        if count > 0 then\
  12711.                            write( \", \" )\
  12712.                        end\
  12713.                        if term.isColour() then\
  12714.                            term.setTextColour( nColour )\
  12715.                        end\
  12716.                        write( sColour )\
  12717.                        if term.isColour() then\
  12718.                            term.setTextColour( colours.white )\
  12719.                        end\
  12720.                        count = count + 1\
  12721.                    end\
  12722.                end\
  12723.                print( \".\" )\
  12724.            end\
  12725.        end\
  12726.    end\
  12727. \
  12728. elseif sCommand == \"pulse\" then\
  12729.    -- \"redstone pulse\"\
  12730.    local sSide = tArgs[2]\
  12731.    local nCount = tonumber( tArgs[3] ) or 1\
  12732.    local nPeriod = tonumber( tArgs[4] ) or 0.5\
  12733.    for n=1,nCount do\
  12734.        redstone.setOutput( sSide, true )\
  12735.        sleep( nPeriod / 2 )\
  12736.        redstone.setOutput( sSide, false )\
  12737.        sleep( nPeriod / 2 )\
  12738.    end\
  12739. \
  12740. elseif sCommand == \"set\" then\
  12741.    -- \"redstone set\"\
  12742.    local sSide = tArgs[2]\
  12743.    if #tArgs > 3 then\
  12744.        -- Bundled cable output\
  12745.        local sColour = tArgs[3]\
  12746.        local nColour = colors[sColour] or colours[sColour]\
  12747.        if type(nColour) ~= \"number\" then\
  12748.            printError( \"No such color\" )\
  12749.            return\
  12750.        end\
  12751. \
  12752.        local sValue = tArgs[4]\
  12753.        if sValue == \"true\" then\
  12754.            rs.setBundledOutput( sSide, colors.combine( rs.getBundledOutput( sSide ), nColour ) )\
  12755.        elseif sValue == \"false\" then\
  12756.            rs.setBundledOutput( sSide, colors.subtract( rs.getBundledOutput( sSide ), nColour ) )\
  12757.        else\
  12758.            print( \"Value must be boolean\" )\
  12759.        end\
  12760.    else\
  12761.        -- Regular output\
  12762.        local sValue = tArgs[3]\
  12763.        local nValue = tonumber(sValue)\
  12764.        if sValue == \"true\" then\
  12765.            rs.setOutput( sSide, true )\
  12766.        elseif sValue == \"false\" then\
  12767.            rs.setOutput( sSide, false )\
  12768.        elseif nValue and nValue >= 0 and nValue <= 15 then\
  12769.            rs.setAnalogOutput( sSide, nValue )\
  12770.        else\
  12771.            print( \"Value must be boolean or 0-15\" )\
  12772.        end\
  12773.    end\
  12774. \
  12775. else\
  12776.    -- Something else\
  12777.    printUsage()\
  12778. \
  12779. end",
  12780.   [ "/rom/programs/apis" ] = "\
  12781. local tApis = {}\
  12782. for k,v in pairs( _G ) do\
  12783.     if type(k) == \"string\" and type(v) == \"table\" and k ~= \"_G\" then\
  12784.         table.insert( tApis, k )\
  12785.     end\
  12786. end\
  12787. table.insert( tApis, \"shell\" )\
  12788. table.sort( tApis )\
  12789. \
  12790. textutils.pagedTabulate( tApis )",
  12791.   [ "/rom/help/earth" ] = "Mostly harmless.",
  12792.   [ "/Flare/version/1.2/lib/UI/event/Dispatcher.lua" ] = "\
  12793. local class = require \"lib.class\"\
  12794. local event = require \"lib.UI.event\"\
  12795. \
  12796. local Dispatcher = class \"Dispatcher\"\
  12797. \
  12798. function Dispatcher:Dispatcher()\
  12799.     self.timer = os.startTimer( 0 )\
  12800.     self.updateTime = .05\
  12801.     self.time = os.clock()\
  12802. end\
  12803. \
  12804. function Dispatcher:handle( ev, ... )\
  12805.     local params = { ... }\
  12806.     local event_obj\
  12807.     if ev == \"timer\" and params[1] == self.timer then\
  12808. \
  12809.         self.timer = os.startTimer( self.updateTime )\
  12810.         local dt = os.clock() - self.time\
  12811.         self.time = os.clock()\
  12812. \
  12813.         ev = \"update\"\
  12814.         params = { dt }\
  12815. \
  12816.     elseif ev == \"mouse_click\" then\
  12817.         event_obj = event:new \"mouse_down\"\
  12818.             :setParam( \"button\", params[1] )\
  12819.             :setParam( \"x\", params[2] )\
  12820.             :setParam( \"y\", params[3] )\
  12821.         if not _CC_VERSION or _CC_VERSION:match \"(1.74)pr%d+\" < 1.74 then\
  12822.             os.queueEvent( \"mouse_up\", params[1], params[2], params[3] )\
  12823.         end\
  12824.     elseif ev == \"mouse_up\" then\
  12825.         event_obj = event:new \"mouse_up\"\
  12826.             :setParam( \"button\", params[1] )\
  12827.             :setParam( \"x\", params[2] )\
  12828.             :setParam( \"y\", params[3] )\
  12829.     elseif ev == \"mouse_drag\" then\
  12830.         event_obj = event:new \"mouse_drag\"\
  12831.             :setParam( \"button\", params[1] )\
  12832.             :setParam( \"x\", params[2] )\
  12833.             :setParam( \"y\", params[3] )\
  12834.     elseif ev == \"mouse_scroll\" then\
  12835.         event_obj = event:new \"mouse_scroll\"\
  12836.             :setParam( \"direction\", params[1] )\
  12837.             :setParam( \"x\", params[2] )\
  12838.             :setParam( \"y\", params[3] )\
  12839.     elseif ev == \"key\" then\
  12840.         local name = keys.getName( params[1] )\
  12841.         event_obj = event:new \"key\"\
  12842.             :setParam( \"key\", name )\
  12843.             :setParam( \"keycode\", params[1] )\
  12844.     elseif ev == \"char\" then\
  12845.         event_obj = event:new \"char\"\
  12846.             :setParam( \"char\", params[1] )\
  12847.     elseif ev == \"paste\" then\
  12848.         event_obj = event:new \"paste\"\
  12849.             :setParam( \"data\", params[1] )\
  12850.     end\
  12851. \
  12852.     if event_obj then\
  12853.         return true, event_obj, { ev, unpack( params ) }\
  12854.     end\
  12855.     return false, ev, params\
  12856. end\
  12857. \
  12858. return Dispatcher",
  12859.   [ "/rom/help/unequip" ] = "unequip is a program for Turtles. unequip will remove tools of peripherals from the specified side of the turtle.\
  12860. \
  12861. ex:\
  12862. \"unequip left\" will remove the item on the left side of the turtle",
  12863.   [ "/rom/help/chat" ] = "Surf the rednet superhighway with \"chat\", the networked chat program for CraftOS! Host chatrooms and invite your friends! Requires a Wired or Wireless Modem on each computer. When running chat, type \"/help\" to see a list of available commands.\
  12864. \
  12865. ex:\
  12866. \"chat host forgecraft\" will create a chatroom with the name \"forgecraft\"\
  12867. \"chat join forgecraft direwolf20\" will connect to the chatroom with the name \"forgecraft\", using the nickname \"direwolf20\"",
  12868.   [ "/Flare/version/1.2/version.lua" ] = "\
  12869. local version = {}\
  12870. \
  12871. version.current = \"1.2.1\"\
  12872. version.name = \"PRERELEASE\"\
  12873. \
  12874. function version.local_major()\
  12875.     return version.current:match \"(%d+%.%d+)%.%d+\"\
  12876. end\
  12877. \
  12878. function version.local_patch()\
  12879.     return version.current:match \"%d+%.%d+%.(%d+)\"\
  12880. end\
  12881. \
  12882. function version.online_major()\
  12883.     local h = http.get \"https://raw.githubusercontent.com/awsumben13/Flare/master/version.txt\"\
  12884.     if h then\
  12885.         local content = h.readAll()\
  12886.         h.close()\
  12887.         if content:find \"%d+%.%d+%.%d+\" then\
  12888.             return content:match \"(%d+%.%d+)%.%d+\"\
  12889.         end\
  12890.     end\
  12891.     return version.local_major()\
  12892. end\
  12893. \
  12894. function version.online_version_patch( v )\
  12895.     local h = http.get( \"https://raw.githubusercontent.com/awsumben13/Flare/master/version/\" .. v .. \"/patch.txt\" )\
  12896.     if h then\
  12897.         local content = h.readAll()\
  12898.         h.close()\
  12899.         if content:find \"^%d+$\" then\
  12900.             return content\
  12901.         end\
  12902.     end\
  12903.     return version.local_patch()\
  12904. end\
  12905. \
  12906. function version.compareVersions( v1, v2 )\
  12907.     local v1ma, v1mi, v1p = v1:match \"(%d+)%.(%d+)%.(%d+)\"\
  12908.     local v2ma, v2mi, v2p = v2:match \"(%d+)%.(%d+)%.(%d+)\"\
  12909.     if v1ma and v1mi and v1p and v2ma and v2mi and v2p then\
  12910.         if v1ma > v2ma then return true end\
  12911.         if v1ma == v2ma and v1mi > v2mi then return true end\
  12912.         if v1ma == v2ma and v1mi == v2mi and v1p > v2p then return true end\
  12913.         return false\
  12914.     end\
  12915. end\
  12916. \
  12917. function version.shouldUpdate()\
  12918.     return version.local_patch() < version.online_version_patch( version.local_major() )\
  12919. end\
  12920. \
  12921. function version.install( version )\
  12922.     local h = http.get( \"https://raw.githubusercontent.com/awsumben13/Flare/master/version/\" .. version .. \"/install.lua\" )\
  12923.     if h then\
  12924.         local content = h.readAll()\
  12925.         h.close()\
  12926.         local f, err = loadstring( content, \"Installer\" )\
  12927.         return f()\
  12928.     end\
  12929.     return false\
  12930. end\
  12931. \
  12932. return version",
  12933.   [ "/rom/programs/drive" ] = "local tArgs = { ... }\
  12934. \
  12935. -- Get where a directory is mounted\
  12936. local sPath = shell.dir()\
  12937. if tArgs[1] ~= nil then\
  12938.     sPath = shell.resolve( tArgs[1] )\
  12939. end\
  12940. \
  12941. if fs.exists( sPath ) then\
  12942.     write( fs.getDrive( sPath ) .. \" (\" )\
  12943.     local nSpace = fs.getFreeSpace( sPath )\
  12944.     if nSpace > 1024 * 1024 then\
  12945.         print( (math.floor( nSpace / (100 * 1000) ) / 10) .. \"MB remaining)\" )\
  12946.     elseif nSpace > 1024 then\
  12947.         print( math.floor( nSpace / 1000 ) .. \"KB remaining)\" )\
  12948.     else\
  12949.         print ( nSpace .. \"B remaining)\" )\
  12950.     end\
  12951. else\
  12952.     print( \"No such path\" )\
  12953. end",
  12954.   [ "/Flare/version/1.2/FDK.lua" ] = "\
  12955. -- Flare Development Kit\
  12956. \
  12957. local FDK = {}\
  12958. FDK.name = \"Flare\"\
  12959. FDK.install_path = \"Flare/version/1.2\"\
  12960. FDK.lib_path = FDK.install_path .. \"/lib\"\
  12961. FDK.running = true\
  12962. FDK.updateTime = .05\
  12963. FDK.source_path = nil -- loaded later\
  12964. FDK.module = nil -- loaded later\
  12965. FDK.environment = setmetatable( { FDK = FDK }, { __index = getfenv() } )\
  12966. \
  12967. local function load_internal_file( file )\
  12968.     local f, err = loadfile( FDK.install_path .. \"/\" .. file:gsub( \"%.\", \"/\" ) .. \".lua\" )\
  12969.     if f then\
  12970.         setfenv( f, FDK.environment )\
  12971.         return f()\
  12972.     else\
  12973.         error( err, 0 )\
  12974.     end\
  12975. end\
  12976. \
  12977. FDK.version = load_internal_file \"version\"\
  12978. FDK.module = load_internal_file \"module\"\
  12979. \
  12980. local _type = type\
  12981. function FDK.type( object )\
  12982.     local rawtype = _type( object )\
  12983.     if rawtype == \"table\" then\
  12984.         pcall( function()\
  12985.             rawtype = getmetatable( object ).__type or rawtype\
  12986.         end )\
  12987.     end\
  12988.     if rawtype == \"table\" and _type( object.type ) == \"function\" then\
  12989.         pcall( function()\
  12990.             rawtype = object:type()\
  12991.         end )\
  12992.     end\
  12993.     return rawtype\
  12994. end\
  12995. \
  12996. function FDK.sleep( time )\
  12997.     local t = os.clock() + ( time or -1 )\
  12998.     repeat\
  12999.         coroutine.yield \"update\"\
  13000.     until os.clock() >= t\
  13001. end\
  13002. \
  13003. function FDK.setup( project )\
  13004.     FDK.source_path = project\
  13005. end\
  13006. \
  13007. local function getFilePath( file )\
  13008.     local _dir = \"\"\
  13009.     if FDK.source_path then\
  13010.         _dir = FDK.source_path\
  13011.     end\
  13012.     if file:sub( 1, 4 ):lower() == \"lib.\" then\
  13013.         path = fs.combine( FDK.lib_path, tostring( file:sub( 5 ):gsub( \"%.\", \"/\" ) ) )\
  13014.     else\
  13015.         path = fs.combine( _dir, tostring( file:gsub( \"%.\", \"/\" ) ) )\
  13016.     end\
  13017.     if fs.isDir( path ) then\
  13018.         local name = fs.getName( path )\
  13019.         if fs.exists( path .. \"/\" .. name .. \".lua\" ) then\
  13020.             return path .. \"/\" .. name .. \".lua\"\
  13021.         elseif fs.exists( path .. \"/main.lua\" ) then\
  13022.             return path .. \"/main.lua\"\
  13023.         end\
  13024.     elseif fs.exists( path .. \".lua\" ) then\
  13025.         return path .. \".lua\"\
  13026.     end\
  13027. end\
  13028. \
  13029. local r = {}\
  13030. local d = {}\
  13031. function FDK.require( file )\
  13032.     local path = getFilePath( file )\
  13033.     if not path then return error( (\"No such file %q\"):format( file ) ) end\
  13034.     if r[path] then return d[path] end\
  13035.     r[path] = true\
  13036.     local f, err = loadfile( path )\
  13037.     if f then\
  13038.         local ok\
  13039.         setfenv( f, FDK.environment )\
  13040.         ok, d[path] = pcall( f, fs.getDir( path ) )\
  13041.         if not ok then\
  13042.             error( d[path], 0 )\
  13043.         end\
  13044.         return d[path]\
  13045.     else\
  13046.         error( (\"Failed to load %q (%q): %s\"):format( file, path, tostring( err ) ), 0 )\
  13047.     end\
  13048. end\
  13049. \
  13050. FDK.environment.require = FDK.require\
  13051. \
  13052. if FDK.version.shouldUpdate() then\
  13053.     FDK.version.install( FDK.version.local_major() )\
  13054. end\
  13055. \
  13056. if not FDK.module.isInstalled \"core\" then\
  13057.     if not FDK.module.install \"core\" then\
  13058.         error \"Failed to download core module\"\
  13059.     end\
  13060. end\
  13061. \
  13062. local process          = FDK.require \"lib.process\"\
  13063. local buffer           = FDK.require \"lib.buffer\"\
  13064. local graphics         = FDK.require \"lib.graphics\"\
  13065. local stencil          = FDK.require \"lib.stencil\"\
  13066. local Frame            = FDK.require \"lib.UI.elements.Frame\"\
  13067. local animation        = FDK.require \"lib.UI.animation\"\
  13068. local event            = FDK.require \"lib.UI.event\"\
  13069. local keybind          = FDK.require \"lib.UI.keybind\"\
  13070. local trace            = FDK.require \"lib.trace\"\
  13071. local event_dispatcher = FDK.require \"lib.UI.event.Dispatcher\"\
  13072. \
  13073. local main_event_dispatcher = event_dispatcher:new()\
  13074. \
  13075. FDK.process = process:new \"main\"\
  13076. FDK.buffer = buffer:new( term.getSize() )\
  13077. FDK.buffer.stencil = stencil:new()\
  13078. graphics:mixin( FDK.buffer )\
  13079. FDK.frame = Frame( 1, 1, term.getSize() )\
  13080. \
  13081. function FDK.begin()\
  13082.     local timer = os.startTimer( 0 )\
  13083.     local time = os.clock()\
  13084.     FDK.running = true\
  13085.     while FDK.running do\
  13086.         main_event_dispatcher.updateTime = FDK.updateTime\
  13087.         local handled, event, params = main_event_dispatcher:handle( coroutine.yield() )\
  13088. \
  13089.         if not handled and event == \"update\" then\
  13090. \
  13091.             FDK.frame:update( params[1] )\
  13092. \
  13093.             FDK.buffer:clear()\
  13094.             FDK.buffer:setCursorBlink()\
  13095.             FDK.frame:draw( 1, 1, FDK.buffer )\
  13096.             FDK.buffer:draw()\
  13097. \
  13098.         end\
  13099.         \
  13100.         if handled then\
  13101.             local ok, err = FDK.process:spawnThread( function()\
  13102.                 FDK.frame:handle( event )\
  13103.                 if not event.handled then\
  13104.                     handled = false\
  13105.                     event = params[1]\
  13106.                     params = { unpack( params, 2 ) }\
  13107.                 end\
  13108.             end ):update()\
  13109.             if not ok then\
  13110.                 printError( err )\
  13111.                 break\
  13112.             end\
  13113.         end\
  13114. \
  13115.         if not handled then\
  13116.             if event == \"key\" and keybind.isBound( keys.getName( params[1] ) ) then\
  13117.                 keybind.call( keys.getName( params[1] ) )\
  13118.             else\
  13119.                 local ok, data = FDK.process:update( event, unpack( params ) )\
  13120.                 if not ok then\
  13121.                     printError( data )\
  13122.                     break\
  13123.                 end\
  13124.             end\
  13125.         end\
  13126.     end\
  13127. end\
  13128. \
  13129. function FDK.dofile( file, ... )\
  13130.     local args = { ... }\
  13131.     local path = getFilePath( file )\
  13132.     if not path then return error( (\"No such file %q\"):format( file ) ) end\
  13133.     local f, err = loadfile( path )\
  13134.     if f then\
  13135.         local thread = FDK.process:spawnThread( function()\
  13136.             setfenv( f, getfenv() )\
  13137.             local ok, err = trace( f, unpack( args ) )\
  13138.             if not ok then\
  13139.                 error( err, 0 )\
  13140.             end\
  13141.         end )\
  13142.         thread.environment = FDK.environment\
  13143.         return thread\
  13144.     else\
  13145.         error( (\"Failed to load %q (%q): %s\"):format( tostring( file ), tostring( path ), tostring( err ) ), 0 )\
  13146.     end\
  13147. end\
  13148. \
  13149. return FDK",
  13150.   [ "/rom/help/time" ] = "time prints the current time of day.",
  13151.   [ "/rom/help/whatsnew" ] = "New Features in ComputerCraft 1.65:\
  13152. \
  13153. * Fixed a multiplayer-only crash with turtle.place()\
  13154. * Fixed some problems with http.post()\
  13155. * Fixed fs.getDrive() returning incorrect results on remote peripherals\
  13156. \
  13157. Type \"help changelog\" to see the full version history.",
  13158.   [ "/Flare/version/1.2/lib/UI/elements/ClippingFrame.lua" ] = "\
  13159. local class = require \"lib.class\"\
  13160. local Frame = require \"lib.UI.elements.Frame\"\
  13161. \
  13162. local ClippingFrame = class \"ClippingFrame\"\
  13163. ClippingFrame:extend( Frame )\
  13164. \
  13165. function ClippingFrame:ClippingFrame( x, y, w, h )\
  13166.     self:Frame( x, y, w, h )\
  13167. end\
  13168. \
  13169. function ClippingFrame:draw( x, y, buffer )\
  13170.     local layer = buffer.stencil:newLayer( x, y, self.width, self.height )\
  13171.     for i = 1, #self.children do\
  13172.         self.children[i]:draw( x + self.children[i].x - 1 + self.ox, y + self.children[i].y - 1 + self.oy, buffer )\
  13173.     end\
  13174.     buffer.stencil:removeLayer( layer )\
  13175. end\
  13176. \
  13177. return ClippingFrame",
  13178.   [ "/rom/help/math" ] = "math is a standard Lua5.1 API.\
  13179. Refer to http://www.lua.org/manual/5.1/ for more information.",
  13180.   [ "/rom/help/turn" ] = "turn is a program for Turtles, used to turn the turtle around without programming. It accepts one or more commands as a direction and a number of turns. The \"go\" program can also be used for turning.\
  13181. \
  13182. ex:\
  13183. \"turn left\" turns the turtle 90 degrees left.\
  13184. \"turn right 2\" turns the turtle 180 degrees right.\
  13185. \"turn left 2 right\" turns left 180 degrees, then right 90 degrees.",
  13186.   [ "/rom/help/redirection" ] = "Redirection ComputerCraft Edition is the CraftOS version of a fun new puzzle game by Dan200, the author of ComputerCraft.\
  13187. Play it on any Advanced Computer, then visit http://www.redirectiongame.com to play the full game!",
  13188.   [ "/Flare/version/1.2/lib/trace.lua" ] = "\
  13189. local trace = {}\
  13190. \
  13191. function trace.traceback(ignore, level)\
  13192.     level = type(level) == \"number\" and level\
  13193.     local errorLevel = 3 + (type(ignore) == \"number\" and ignore or 0)\
  13194.     local errorDiff = errorLevel\
  13195.     local errorPos, result = nil, {}\
  13196.     repeat\
  13197.         errorPos = select(2, pcall(error, \"@\", errorLevel)):match(\"^(.+): @$\")\
  13198.         if errorPos then\
  13199.             result[#result + 1] = errorPos\
  13200.             errorLevel = errorLevel + 1\
  13201.             if errorLevel - errorDiff == level then return result end\
  13202.         end\
  13203.     until not errorPos\
  13204.     return result\
  13205. end\
  13206. \
  13207. function trace.trace( f, ... )\
  13208.     local args = { ... }\
  13209.     return xpcall( function() return f( unpack( args ) ) end, function( err )\
  13210.         local t = trace.traceback( 2 )\
  13211.         for i = #t, 1, -1 do\
  13212.             if t[i] == \"xpcall\" then\
  13213.                 table.remove( t, i )\
  13214.                 break\
  13215.             end\
  13216.             table.remove( t, i )\
  13217.         end\
  13218.         local txt = tostring( err )\
  13219.         for i = 1, #t do\
  13220.             txt = txt .. \"\\n  in \" .. tostring( t[i] )\
  13221.         end\
  13222.         return txt\
  13223.     end )\
  13224. end\
  13225. \
  13226. setmetatable( trace, { __call = function( self, ... )\
  13227.     return self.trace( ... )\
  13228. end } )\
  13229. \
  13230. return trace",
  13231.   [ "/rom/programs/fun/dj" ] = "local tArgs = { ... }\
  13232. \
  13233. local function printUsage()\
  13234.     print( \"Usages:\")\
  13235.     print( \"dj play\" )\
  13236.     print( \"dj play <drive>\" )\
  13237.     print( \"dj stop\" )\
  13238. end\
  13239. \
  13240. if #tArgs > 2 then\
  13241.     printUsage()\
  13242.     return\
  13243. end\
  13244. \
  13245. local sCommand = tArgs[1]\
  13246. if sCommand == \"stop\" then\
  13247.     -- Stop audio\
  13248.     disk.stopAudio()\
  13249. \
  13250. elseif sCommand == \"play\" or sCommand == nil then\
  13251.     -- Play audio\
  13252.     local sName = tArgs[2]\
  13253.     if sName == nil then\
  13254.         -- No disc specified, pick one at random\
  13255.         local tNames = {}\
  13256.         for n,sName in ipairs( peripheral.getNames() ) do\
  13257.             if disk.isPresent( sName ) and disk.hasAudio( sName ) then\
  13258.                 table.insert( tNames, sName )\
  13259.             end\
  13260.         end\
  13261.         if #tNames == 0 then\
  13262.             print( \"No Music Discs in attached disk drives\" )\
  13263.             return\
  13264.         end\
  13265.         sName = tNames[ math.random(1,#tNames) ]\
  13266.     end\
  13267. \
  13268.     -- Play the disc\
  13269.     if disk.isPresent( sName ) and disk.hasAudio( sName ) then\
  13270.         print( \"Playing \"..disk.getAudioTitle( sName ) )\
  13271.         disk.playAudio( sName )\
  13272.     else\
  13273.         print( \"No Music Disc in disk drive: \"..sName )\
  13274.         return\
  13275.     end\
  13276.     \
  13277. else\
  13278.     printUsage()\
  13279.     \
  13280. end",
  13281.   [ "/rom/programs/turtle/craft" ] = "\
  13282. if not turtle.craft then\
  13283.    print( \"Requires a Crafty Turtle\" )\
  13284.    return\
  13285. end\
  13286. \
  13287. local tArgs = { ... }\
  13288. local nLimit = nil\
  13289. if #tArgs < 1 then\
  13290.     print( \"Usage: craft [number]\" )\
  13291.     return\
  13292. else\
  13293.     nLimit = tonumber( tArgs[1] )\
  13294. end\
  13295. \
  13296. local nCrafted = 0\
  13297. local nOldCount = turtle.getItemCount( turtle.getSelectedSlot() )\
  13298. if turtle.craft( nLimit ) then\
  13299.    local nNewCount = turtle.getItemCount( turtle.getSelectedSlot() )\
  13300.    if nOldCount <= nLimit then\
  13301.        nCrafted = nNewCount\
  13302.    else\
  13303.        nCrafted = nOldCount - nNewCount\
  13304.    end\
  13305. end\
  13306. \
  13307. if nCrafted > 1 then\
  13308.    print( nCrafted..\" items crafted\" )\
  13309. elseif nCrafted == 1 then\
  13310.    print( \"1 item crafted\" )\
  13311. else\
  13312.    print( \"No items crafted\" )\
  13313. end",
  13314.   [ "/rom/help/craft" ] = "craft is a program for Crafty Turtles. Craft will craft a stack of items using the current inventory.\
  13315. \
  13316. ex:\
  13317. \"craft\" will craft as many items as possible\
  13318. \"craft 5\" will craft at most 5 times",
  13319.   [ "/rom/programs/fun/advanced/levels/11" ] = "4\
  13320.   777777777\
  13321.   727872787\
  13322.   787878787\
  13323. 777787878787777\
  13324. 7be888888888be7\
  13325. 777787878787777\
  13326.   787878787\
  13327.   787478747\
  13328.   777777777",
  13329.   [ "/rom/help/intro" ] = "Welcome to CraftOS!\
  13330. Type \"programs\" to see the programs you can run.\
  13331. Type \"help <program>\" to see help for a specific program.\
  13332. Type \"help programming\" to learn about programming.\
  13333. Type \"help whatsnew\" to find out about new features.\
  13334. Type \"help credits\" to learn who made all this.\
  13335. Type \"help index\" to see all help topics.",
  13336.   [ "/rom/help/disk" ] = "Functions in the disk API. These functions are for interacting with disk drives:\
  13337. disk.isPresent( drive )\
  13338. disk.setLabel( drive, label )\
  13339. disk.getLabel( drive )\
  13340. disk.hasData( drive )\
  13341. disk.getMountPath( drive )\
  13342. disk.hasAudio( drive )\
  13343. disk.getAudioTitle( drive )\
  13344. disk.playAudio( drive )\
  13345. disk.stopAudio( )\
  13346. disk.eject( drive )\
  13347. disk.getID( drive )\
  13348. \
  13349. Events fired by the disk API:\
  13350. \"disk\" when a disk or other item is inserted into a disk drive. Argument is the name of the drive\
  13351. \"disk_eject\" when a disk is removed from a disk drive. Argument is the name of the drive\
  13352. Type \"help events\" to learn about the event system.",
  13353.   [ "/rom/help/equip" ] = "equip is a program for Turtles. equip will equip an item from the Turtle's inventory for use as a tool of peripheral.\
  13354. \
  13355. ex:\
  13356. \"equip 5 left\" will equip the item from slot 5 of the turtle onto the left side of the turtle",
  13357.   [ "/rom/programs/turtle/unequip" ] = "\
  13358. local tArgs = { ... }\
  13359. local function printUsage()\
  13360.     print( \"Usage: unequip <side>\" )\
  13361. end\
  13362. \
  13363. if #tArgs ~= 1 then\
  13364.    printUsage()\
  13365.     return\
  13366. end\
  13367. \
  13368. local function unequip( fnEquipFunction )\
  13369.    for nSlot=1,16 do\
  13370.        local nOldCount = turtle.getItemCount( nSlot )\
  13371.        if nOldCount == 0 then\
  13372.            turtle.select( nSlot )\
  13373.            if fnEquipFunction() then\
  13374.                local nNewCount = turtle.getItemCount( nSlot )\
  13375.                if nNewCount > 0 then\
  13376.                    print( \"Item unequipped\" )\
  13377.                    return\
  13378.                else\
  13379.                    print( \"Nothing to unequip\" )\
  13380.                    return\
  13381.                end\
  13382.            end\
  13383.        end\
  13384.    end\
  13385.    print( \"No space to unequip item\" )\
  13386. end\
  13387. \
  13388. local sSide = tArgs[1]\
  13389. if sSide == \"left\" then\
  13390.    unequip( turtle.equipLeft )\
  13391. elseif sSide == \"right\" then\
  13392.    unequip( turtle.equipRight )\
  13393. else\
  13394.    printUsage()\
  13395.    return\
  13396. end",
  13397.   [ "/rom/programs/eject" ] = "\
  13398. -- Get arguments\
  13399. local tArgs = { ... }\
  13400. if #tArgs == 0 then\
  13401.     print( \"Usage: eject <drive>\" )\
  13402.     return\
  13403. end\
  13404. \
  13405. local sDrive = tArgs[1]\
  13406. \
  13407. -- Check the disk exists\
  13408. local bPresent = disk.isPresent( sDrive )\
  13409. if not bPresent then\
  13410.     print( \"Nothing in \"..sDrive..\" drive\" )\
  13411.     return\
  13412. end\
  13413. \
  13414. disk.eject( sDrive )",
  13415.   [ "/rom/help/table" ] = "table is a standard Lua5.1 API.\
  13416. Refer to http://www.lua.org/manual/5.1/ for more information.",
  13417.   [ "/Flare/version/1.2/lib/buffer.lua" ] = "\
  13418. local function hasChanged( p1, p2 )\
  13419.     return p1.bc ~= p2.bc or p1.char ~= p2.char or ( p1.tc ~= p2.tc and p1.char ~= \" \" )\
  13420. end\
  13421. local function drawCurrent( state )\
  13422.     local t = state.target\
  13423.     if state.text ~= \"\" then\
  13424.         t.setCursorPos( state.x, state.y )\
  13425.         local bc = state.bc\
  13426.         bc = ( type( bc ) == \"function\" and bc() ) or ( bc == 0 and state.buffer.bc ) or bc\
  13427.         local tc = state.tc\
  13428.         tc = ( type( tc ) == \"function\" and tc() ) or ( tc == 0 and state.buffer.tc ) or tc\
  13429.         t.setBackgroundColour( bc )\
  13430.         t.setTextColour( tc )\
  13431.         t.write( state.text )\
  13432.         state.x = state.x + #state.text\
  13433.         state.text = \"\"\
  13434.     end\
  13435. end\
  13436. local function px( buffer, state, x, y )\
  13437.     local px = buffer.pixels[y][x]\
  13438.     if not hasChanged( px, buffer.last[y][x] ) and not state.all then\
  13439.         drawCurrent( state )\
  13440.         state.x = state.x + 1\
  13441.         state.bc = nil\
  13442.         return\
  13443.     end\
  13444.     if not state.bc then\
  13445.         state.bc = px.bc\
  13446.         state.tc = px.tc\
  13447.         state.text = px.char\
  13448.         return\
  13449.     end\
  13450.     if state.bc ~= px.bc or ( state.tc ~= px.tc and px.char ~= \" \" ) then\
  13451.         drawCurrent( state )\
  13452.         state.bc = px.bc\
  13453.         state.tc = px.tc\
  13454.         state.text = px.char\
  13455.     else\
  13456.         state.text = state.text .. px.char\
  13457.     end\
  13458. end\
  13459. \
  13460. local col_lookup = {}\
  13461. for i = 0, 15 do\
  13462.     col_lookup[2 ^ i] = (\"%01x\"):format( i )\
  13463. end\
  13464. \
  13465. local function toHex( c )\
  13466.     return col_lookup[c] or \"0\"\
  13467. end\
  13468. \
  13469. local function blitline( line )\
  13470.     local s, b, t = \"\", \"\", \"\"\
  13471.     for i = 1, #line do\
  13472.         s = s .. line[i].char:sub( 1, 1 )\
  13473.         if line[i].char == \"\" then s = s .. \" \" end\
  13474.         b = b .. toHex( line[i].bc )\
  13475.         t = t .. toHex( line[i].tc )\
  13476.     end\
  13477.     term.blit( s, t, b )\
  13478. end\
  13479. \
  13480. local buffer = {}\
  13481. local main\
  13482. \
  13483. function buffer:new( width, height, bc, tc, char )\
  13484.     local b = {}\
  13485. \
  13486.     b.allowInvisiblePixels = false\
  13487. \
  13488.     b.width = width\
  13489.     b.height = height\
  13490. \
  13491.     b.bc = bc or 1\
  13492.     b.tc = tc or 32768\
  13493.     b.char = char or \" \"\
  13494. \
  13495.     b.pixels = {}\
  13496.     b.last = {}\
  13497. \
  13498.     b.cb = false\
  13499. \
  13500.     for y = 1, height do\
  13501.         b.pixels[y] = {}\
  13502.         b.last[y] = {}\
  13503.         for x = 1, width do\
  13504.             b.pixels[y][x] = { bc = b.bc, tc = b.tc, char = b.char }\
  13505.             b.last[y][x] = {}\
  13506.         end\
  13507.     end\
  13508. \
  13509.     setmetatable( b, { __index = self, __type = \"buffer\" } )\
  13510. \
  13511.     return b\
  13512. end\
  13513. \
  13514. function buffer:setPixel( x, y, bc, tc, char )\
  13515.     if self.pixels[y] and self.pixels[y][x] then\
  13516.         local px = self.pixels[y][x]\
  13517.         px.bc = ( bc == 0 and not self.allowInvisiblePixels and px.bc ) or bc\
  13518.         px.tc = ( tc == 0 and not self.allowInvisiblePixels and px.tc ) or tc\
  13519.         px.char = ( tc == 0 and px.char ) or ( char == \"\" and px.char ) or char\
  13520.     end\
  13521. end\
  13522. \
  13523. function buffer:getPixel( x, y )\
  13524.     if self.pixels[y] and self.pixels[y][x] then\
  13525.         local px = self.pixels[y][x]\
  13526.         return px.bc, px.tc, px.char\
  13527.     end\
  13528. end\
  13529. \
  13530. function buffer:clear()\
  13531.     for y = 1, self.height do\
  13532.         for x = 1, self.width do\
  13533.             self.pixels[y][x] = { bc = self.bc, tc = self.tc, char = self.char }\
  13534.         end\
  13535.     end\
  13536. end\
  13537. \
  13538. function buffer:foreach( f )\
  13539.     local new = {}\
  13540.     for x = 1, self.width do\
  13541.         new[x] = {}\
  13542.         for y = 1, self.height do\
  13543.             local bc, tc, char = self:getPixel( x, y )\
  13544.             local _bc, _tc, _char = f( x, y, bc, tc, char )\
  13545.             local c = false\
  13546.             if _bc and _bc ~= bc then c = true end\
  13547.             if _tc and _tc ~= tc then c = true end\
  13548.             if _char and _char ~= char then c = true end\
  13549.             if c then\
  13550.                 new[x][y] = { bc = _bc or bc, tc = _tc or tc, char = _char or char }\
  13551.             end\
  13552.         end\
  13553.     end\
  13554.     for x = 1, self.width do\
  13555.         for y = 1, self.height do\
  13556.             local px = new[x][y]\
  13557.             if px then\
  13558.                 self:setPixel( x, y, px.bc, px.tc, px.char )\
  13559.             end\
  13560.         end\
  13561.     end\
  13562. end\
  13563. \
  13564. function buffer:resize( width, height )\
  13565.     while self.height < height do\
  13566.         local t = {}\
  13567.         for i = 1, self.width do\
  13568.             t[i] = { bc = self.bc, tc = self.tc, char = self.char }\
  13569.         end\
  13570.         self.pixels[#self.pixels + 1] = t\
  13571.         self.last[#self.last + 1] = {}\
  13572.         self.height = self.height + 1\
  13573.     end\
  13574.     while self.height > height do\
  13575.         self.pixels[#self.pixels] = nil\
  13576.         self.last[#self.last] = nil\
  13577.         self.height = self.height - 1\
  13578.     end\
  13579.     while self.width < width do\
  13580.         for i = 1, self.height do\
  13581.             self.pixels[i][#self.pixels[i] + 1] = { bc = self.bc, tc = self.tc, char = self.char }\
  13582.         end\
  13583.         self.width = self.width + 1\
  13584.     end\
  13585.     while self.width > width do\
  13586.         for i = 1, self.height do\
  13587.             self.pixels[i][#self.pixels[i]] = nil\
  13588.         end\
  13589.         self.width = self.width - 1\
  13590.     end\
  13591. end\
  13592. \
  13593. function buffer:setCursorBlink( x, y, tc )\
  13594.     if x then\
  13595.         self.cb = { x = x, y = y, tc = tc }\
  13596.     else\
  13597.         self.cb = false\
  13598.     end\
  13599. end\
  13600. \
  13601. function buffer:getCursorBlink()\
  13602.     if self.cb then\
  13603.         return self.cb.x, self.cb.y, self.cb.tc\
  13604.     end\
  13605. end\
  13606. \
  13607. local function drawToBuffer( buffer, target, _x, _y )\
  13608.     buffer:foreach( function( x, y, bc, tc, char )\
  13609.         target:setPixel( x + _x - 1, y + _y - 1, bc, tc, char )\
  13610.     end )\
  13611. end\
  13612. \
  13613. function buffer:draw( target, x, y, all )\
  13614.     target = target or term.current()\
  13615. \
  13616.     if pcall( function()\
  13617.         if getmetatable( target ).__type ~= \"buffer\" then\
  13618.             error \"\"\
  13619.         end\
  13620.     end ) then\
  13621.         return drawToBuffer( self, target, x, y )\
  13622.     end\
  13623. \
  13624.     x = x or 1\
  13625.     y = y or 1\
  13626.     if target.blit then\
  13627.         for i = 1, self.height do\
  13628.             term.setCursorPos( x, y + i - 1 )\
  13629.             blitline( self.pixels[i] )\
  13630.         end\
  13631.     else\
  13632.         for i = 1, self.height do\
  13633.             local state = {\
  13634.                 x = x;\
  13635.                 y = y;\
  13636.                 target = target;\
  13637.                 text = \"\";\
  13638.                 all = all;\
  13639.                 buffer = self;\
  13640.             }\
  13641.             for x = 1, self.width do\
  13642.                 px( self, state, x, i )\
  13643.             end\
  13644.             drawCurrent( state )\
  13645.             y = y + 1\
  13646.         end\
  13647.     end\
  13648. \
  13649.     if self.cb then\
  13650.         term.setTextColour( self.cb.tc )\
  13651.         term.setCursorPos( self.cb.x, self.cb.y )\
  13652.         term.setCursorBlink( true )\
  13653.     else\
  13654.         term.setCursorBlink( false )\
  13655.     end\
  13656. end\
  13657. \
  13658. function buffer:redirect()\
  13659.     main = self\
  13660. end\
  13661. \
  13662. function buffer.current()\
  13663.     return main\
  13664. end\
  13665. \
  13666. return buffer",
  13667.   [ "/rom/programs/fun/advanced/levels/8" ] = "4\
  13668. 777777 7777\
  13669. 7287b7 7867\
  13670. 788787 7887\
  13671. 77878777877\
  13672. 7888eb8887\
  13673. 77877787877\
  13674. 7887 787887\
  13675. 7487 7e7807\
  13676. 7777 777777",
  13677.   [ "/rom/programs/turtle/go" ] = "local tArgs = { ... }\
  13678. if #tArgs < 1 then\
  13679.     print( \"Usage: go <direction> <distance>\" )\
  13680.     return\
  13681. end\
  13682. \
  13683. local tHandlers = {\
  13684.     [\"fd\"] = turtle.forward,\
  13685.     [\"forward\"] = turtle.forward,\
  13686.     [\"forwards\"] = turtle.forward,\
  13687.     [\"bk\"] = turtle.back,\
  13688.     [\"back\"] = turtle.back,\
  13689.     [\"up\"] = turtle.up,\
  13690.     [\"dn\"] = turtle.down,\
  13691.     [\"down\"] = turtle.down,\
  13692.     [\"lt\"] = turtle.turnLeft,\
  13693.     [\"left\"] = turtle.turnLeft,\
  13694.     [\"rt\"] = turtle.turnRight,\
  13695.     [\"right\"] = turtle.turnRight,\
  13696. }\
  13697. \
  13698. local nArg = 1\
  13699. while nArg <= #tArgs do\
  13700.     local sDirection = tArgs[nArg]\
  13701.     local nDistance = 1\
  13702.     if nArg < #tArgs then\
  13703.         local num = tonumber( tArgs[nArg + 1] )\
  13704.         if num then\
  13705.             nDistance = num\
  13706.             nArg = nArg + 1\
  13707.         end\
  13708.     end\
  13709.     nArg = nArg + 1\
  13710. \
  13711.     local fnHandler = tHandlers[string.lower(sDirection)]\
  13712.     if fnHandler then\
  13713.         while nDistance > 0 do\
  13714.             if fnHandler() then\
  13715.                 nDistance = nDistance - 1\
  13716.             elseif turtle.getFuelLevel() == 0 then\
  13717.                 print( \"Out of fuel\" )\
  13718.                 return\
  13719.             else\
  13720.                 sleep(0.5)\
  13721.             end\
  13722.         end\
  13723.     else\
  13724.         print( \"No such direction: \"..sDirection )\
  13725.         print( \"Try: forward, back, up, down\" )\
  13726.         return\
  13727.     end\
  13728. \
  13729. end",
  13730.   [ "/Flare/version/1.2/lib/UI/elements/Text.lua" ] = "\
  13731. local class = require \"lib.class\"\
  13732. local base = require \"lib.UI.base\"\
  13733. local formatter = require \"lib.UI.text.formatter\"\
  13734. local drawtext = require \"lib.UI.draw.text\"\
  13735. local mouse = require \"lib.UI.event.mouse\"\
  13736. \
  13737. local Text = class \"Text\"\
  13738. Text:extend( base )\
  13739. \
  13740. Text.bc = \"white\"\
  13741. Text.tc = \"grey\"\
  13742. \
  13743. Text.noAlign = false\
  13744. \
  13745. Text.xAlign = \"left\"\
  13746. Text.yAlign = \"top\"\
  13747. \
  13748. Text.mouse_click_timeout = .4\
  13749. \
  13750. function Text:Text( x, y, w, h, text )\
  13751.     self:base( x, y, w, h )\
  13752. \
  13753.     self.text = text or \"\"\
  13754.     self:update( 0 )\
  13755. end\
  13756. \
  13757. function Text:update( dt )\
  13758.     self.metadata = {\
  13759.         bc = self.bc;\
  13760.         tc = self.tc;\
  13761.         width = self.width;\
  13762.         height = self.height;\
  13763.     }\
  13764.     self.lines = formatter.lines( self.text, self.metadata )\
  13765.     self.fmt = formatter.renderPrep( self.lines, self.metadata )\
  13766. end\
  13767. \
  13768. function Text:draw( x, y, buffer )\
  13769.     formatter.fixAlignment( self.fmt, self.width, self.height, self.xAlign, self.yAlign )\
  13770.     drawtext( self, self.fmt, x, y, buffer )\
  13771. end\
  13772. \
  13773. function Text:handle( event )\
  13774.     if mouse.click( self, event ) then\
  13775.         local protocol, target = mouse.text_link_check( self.lines, event:getParam \"x\", event:getParam \"y\", self.fmt.offset )\
  13776.         if protocol and self.onLinkOpened then\
  13777.             self:onLinkOpened( protocol, target )\
  13778.         end\
  13779.     elseif event.name == \"mouse_ping\" then\
  13780.         mouse.ping( self, event )\
  13781.     end\
  13782. end\
  13783. \
  13784. return Text",
  13785.   [ "/rom/help/vector" ] = "Functions in the 3D Vector Math API:\
  13786. vector.new( x,y,z )\
  13787. \
  13788. Vectors returned by vector.new() have the following fields and methods:\
  13789. vector.x\
  13790. vector.y\
  13791. vector.z\
  13792. vector:add( vector )\
  13793. vector:sub( vector )\
  13794. vector:mul( number )\
  13795. vector:dot( vector )\
  13796. vector:cross( vector )\
  13797. vector:length()\
  13798. vector:normalize()\
  13799. vector:round()\
  13800. vector:tostring()\
  13801. The +, - and * operators can also be used on vectors.",
  13802.   [ "/rom/programs/programs" ] = "\
  13803. local bAll = false\
  13804. local tArgs = { ... }\
  13805. if #tArgs > 0 and tArgs[1] == \"all\" then\
  13806.     bAll = true\
  13807. end\
  13808. \
  13809. local tPrograms = shell.programs( bAll )\
  13810. textutils.pagedTabulate( tPrograms )",
  13811.   [ "/rom/help/monitors" ] = "The Monitor is a peripheral device available for CraftOS. Type \"help peripheral\" to learn about using the Peripheral API to connect with peripherals. When a Monitor is connected, peripheral.getType() will return \"monitor\". A wrapped monitor can be used with term.redirect() to send all terminal output to the monitor.\
  13812. \
  13813. Methods exposed by the Monitor:\
  13814. write( text )\
  13815. clear()\
  13816. clearLine()\
  13817. getCursorPos()\
  13818. setCursorPos( x, y )\
  13819. setCursorBlink( blink )\
  13820. isColor()\
  13821. setTextColor( color )\
  13822. setBackgroundColor( color )\
  13823. getSize()\
  13824. scroll( n )\
  13825. \
  13826. Events fired by the Monitor:\
  13827. \"monitor_touch\" when an Advanced Monitor is touched by the player. Arguments are name, x, y\
  13828. \"monitor_resize\" when the size of a Monitor changes. Argument is the name of the monitor.",
  13829.   [ "/rom/programs/alias" ] = "\
  13830. local tArgs = { ... }\
  13831. if #tArgs > 2 then\
  13832.     print( \"Usage: alias <alias> <program>\" )\
  13833.     return\
  13834. end\
  13835. \
  13836. local sAlias = tArgs[1]\
  13837. local sProgram = tArgs[2]\
  13838. \
  13839. if sAlias and sProgram then\
  13840.     -- Set alias\
  13841.     shell.setAlias( sAlias, sProgram )\
  13842. elseif sAlias then\
  13843.     -- Clear alias\
  13844.     shell.clearAlias( sAlias )\
  13845. else\
  13846.     -- List aliases\
  13847.     local tAliases = shell.aliases()\
  13848.     local tList = {}\
  13849.     for sAlias, sCommand in pairs( tAliases ) do\
  13850.         table.insert( tList, sAlias )\
  13851.     end\
  13852.     table.sort( tList )\
  13853.     textutils.pagedTabulate( tList )\
  13854. end\
  13855.     ",
  13856.   [ "/rom/help/peripheral" ] = "The peripheral API is for interacting with external peripheral devices. Type \"help peripherals\" to learn about the peripherals available.\
  13857. \
  13858. Functions in the peripheral API:\
  13859. peripheral.getNames()\
  13860. peripheral.isPresent( name )\
  13861. peripheral.getType( name )\
  13862. peripheral.getMethods( name )\
  13863. peripheral.call( name, methodName, param1, param2, etc )\
  13864. peripheral.wrap( name )\
  13865. peripheral.find( type, [fnFilter] )\
  13866. \
  13867. Events fired by the peripheral API:\
  13868. \"peripheral\" when a new peripheral is attached. Argument is the name.\
  13869. \"peripheral_detach\" when a peripheral is removed. Argument is the name.\
  13870. Type \"help events\" to learn about the event system.",
  13871.   [ "/rom/help/paint" ] = "paint is a program for creating images on Advanced Computers. Select colors from the color pallette on the right, and click on the canvas to draw. Press Ctrl to access the menu and save your pictures.\
  13872. \
  13873. ex:\
  13874. \"edit mario\" opens an image called \"mario\" for editing.",
  13875.   [ "/rom/programs/rednet/chat" ] = "\
  13876. local tArgs = { ... }\
  13877. \
  13878. local function printUsage()\
  13879.     print( \"Usages:\" )\
  13880.     print( \"chat host <hostname>\" )\
  13881.     print( \"chat join <hostname> <nickname>\" )\
  13882. end\
  13883. \
  13884. local sOpenedModem = nil\
  13885. local function openModem()\
  13886.    for n,sModem in ipairs( peripheral.getNames() ) do\
  13887.        if peripheral.getType( sModem ) == \"modem\" then\
  13888.            if not rednet.isOpen( sModem ) then\
  13889.                rednet.open( sModem )\
  13890.                sOpenedModem = sModem\
  13891.            end\
  13892.            return true\
  13893.        end\
  13894.    end\
  13895.    print( \"No modems found.\" )\
  13896.    return false\
  13897. end\
  13898. \
  13899. local function closeModem()\
  13900.    if sOpenedModem ~= nil then\
  13901.        rednet.close( sOpenedModem )\
  13902.        sOpenedModem = nil\
  13903.    end\
  13904. end\
  13905. \
  13906. -- Colours\
  13907. local highlightColour, textColour\
  13908. if term.isColour() then\
  13909.     textColour = colours.white\
  13910.     highlightColour = colours.yellow\
  13911. else\
  13912.     textColour = colours.white\
  13913.     highlightColour = colours.white\
  13914. end\
  13915. \
  13916. local sCommand = tArgs[1]\
  13917. if sCommand == \"host\" then\
  13918.    -- \"chat host\"\
  13919.    -- Get hostname\
  13920.    local sHostname = tArgs[2]\
  13921.    if sHostname == nil then\
  13922.        printUsage()\
  13923.        return\
  13924.    end\
  13925. \
  13926.    -- Host server\
  13927.    if not openModem() then\
  13928.        return\
  13929.    end\
  13930.    rednet.host( \"chat\", sHostname )\
  13931.    print( \"0 users connected.\" )\
  13932. \
  13933.    local tUsers = {}\
  13934.    local nUsers = 0\
  13935.    function send( sText, nUserID )\
  13936.        if nUserID then\
  13937.            local tUser = tUsers[ nUserID ]\
  13938.            if tUser then\
  13939.                rednet.send( tUser.nID, {\
  13940.                    sType = \"text\",\
  13941.                    nUserID = nUserID,\
  13942.                    sText = sText,\
  13943.                }, \"chat\" )\
  13944.            end\
  13945.        else\
  13946.            for nUserID, tUser in pairs( tUsers ) do\
  13947.                rednet.send( tUser.nID, {\
  13948.                    sType = \"text\",\
  13949.                    nUserID = nUserID,\
  13950.                    sText = sText,\
  13951.                }, \"chat\" )\
  13952.            end\
  13953.        end\
  13954.    end\
  13955. \
  13956.    -- Setup ping pong\
  13957.    local tPingPongTimer = {}\
  13958.    function ping( nUserID )\
  13959.        local tUser = tUsers[ nUserID ]\
  13960.        rednet.send( tUser.nID, {\
  13961.            sType = \"ping to client\",\
  13962.            nUserID = nUserID,\
  13963.        }, \"chat\" )\
  13964. \
  13965.        local timer = os.startTimer( 15 )\
  13966.        tUser.bPingPonged = false\
  13967.        tPingPongTimer[ timer ] = nUserID\
  13968.    end\
  13969. \
  13970.    function printUsers()\
  13971.        local x,y = term.getCursorPos()\
  13972.        term.setCursorPos( 1, y - 1 )\
  13973.        term.clearLine()\
  13974.        if nUsers == 1 then\
  13975.            print( nUsers .. \" user connected.\" )\
  13976.        else\
  13977.            print( nUsers .. \" users connected.\" )\
  13978.        end\
  13979.    end\
  13980. \
  13981.    -- Handle messages\
  13982.    local ok, error = pcall( function()\
  13983.        parallel.waitForAny( function()\
  13984.            while true do\
  13985.                local sEvent, timer = os.pullEvent( \"timer\" )\
  13986.                local nUserID = tPingPongTimer[ timer ]\
  13987.                if nUserID and tUsers[ nUserID ] then\
  13988.                    local tUser = tUsers[ nUserID ]\
  13989.                    if tUser then\
  13990.                        if not tUser.bPingPonged then\
  13991.                            send( \"* \"..tUser.sUsername..\" has timed out\" )\
  13992.                            tUsers[ nUserID ] = nil\
  13993.                            nUsers = nUsers - 1\
  13994.                            printUsers()\
  13995.                        else\
  13996.                            ping( nUserID )\
  13997.                        end\
  13998.                    end\
  13999.                end\
  14000.            end\
  14001.        end,\
  14002.        function()\
  14003.            while true do\
  14004.                local tCommands\
  14005.                tCommands = {\
  14006.                    [\"me\"] = function( tUser, sContent )\
  14007.                        if string.len(sContent) > 0 then\
  14008.                            send( \"* \"..tUser.sUsername..\" \"..sContent )\
  14009.                        else\
  14010.                            send( \"* Usage: /me [words]\", tUser.nUserID )\
  14011.                        end\
  14012.                    end,\
  14013.                    [\"nick\"] = function( tUser, sContent )\
  14014.                        if string.len(sContent) > 0 then\
  14015.                            local sOldName = tUser.sUsername\
  14016.                            tUser.sUsername = sContent\
  14017.                            send( \"* \"..sOldName..\" is now known as \"..tUser.sUsername )\
  14018.                        else\
  14019.                            send( \"* Usage: /nick [nickname]\", tUser.nUserID )\
  14020.                        end\
  14021.                    end,\
  14022.                    [\"users\"] = function( tUser, sContent )\
  14023.                        send( \"* Connected Users:\", tUser.nUserID )\
  14024.                        local sUsers = \"*\"\
  14025.                        for nUserID, tUser in pairs( tUsers ) do\
  14026.                            sUsers = sUsers .. \" \" .. tUser.sUsername\
  14027.                        end\
  14028.                        send( sUsers, tUser.nUserID )\
  14029.                    end,\
  14030.                    [\"help\"] = function( tUser, sContent )\
  14031.                        send( \"* Available commands:\", tUser.nUserID )\
  14032.                        local sCommands = \"*\"\
  14033.                        for sCommand, fnCommand in pairs( tCommands ) do\
  14034.                            sCommands = sCommands .. \" /\" .. sCommand\
  14035.                        end\
  14036.                        send( sCommands..\" /logout\", tUser.nUserID )\
  14037.                    end,\
  14038.                }\
  14039. \
  14040.                local nSenderID, tMessage = rednet.receive( \"chat\" )\
  14041.                if type( tMessage ) == \"table\" then\
  14042.                    if tMessage.sType == \"login\" then\
  14043.                        -- Login from new client\
  14044.                        local nUserID = tMessage.nUserID\
  14045.                        local sUsername = tMessage.sUsername\
  14046.                        if nUserID and sUsername then\
  14047.                            tUsers[ nUserID ] = {\
  14048.                                nID = nSenderID,\
  14049.                                nUserID = nUserID,\
  14050.                                sUsername = sUsername,\
  14051.                            }\
  14052.                            nUsers = nUsers + 1\
  14053.                            printUsers()\
  14054.                            send( \"* \"..sUsername..\" has joined the chat\" )\
  14055.                            ping( nUserID )\
  14056.                        end\
  14057. \
  14058.                    else\
  14059.                        -- Something else from existing client\
  14060.                        local nUserID = tMessage.nUserID\
  14061.                        local tUser = tUsers[ nUserID ]\
  14062.                        if tUser and tUser.nID == nSenderID then\
  14063.                            if tMessage.sType == \"logout\" then\
  14064.                                send( \"* \"..tUser.sUsername..\" has left the chat\" )\
  14065.                                tUsers[ nUserID ] = nil\
  14066.                                nUsers = nUsers - 1\
  14067.                                printUsers()\
  14068. \
  14069.                            elseif tMessage.sType == \"chat\" then\
  14070.                                local sMessage = tMessage.sText\
  14071.                                if sMessage then\
  14072.                                    local sCommand = string.match( sMessage, \"^/([a-z]+)\" )\
  14073.                                    if sCommand then\
  14074.                                        local fnCommand = tCommands[ sCommand ]\
  14075.                                        if fnCommand then\
  14076.                                            local sContent = string.sub( sMessage, string.len(sCommand)+3 )\
  14077.                                            fnCommand( tUser, sContent )\
  14078.                                        else\
  14079.                                            send( \"* Unrecognised command: /\"..sCommand, tUser.nUserID )\
  14080.                                        end\
  14081.                                    else\
  14082.                                        send( \"<\"..tUser.sUsername..\"> \"..tMessage.sText )\
  14083.                                    end\
  14084.                                end\
  14085. \
  14086.                            elseif tMessage.sType == \"ping to server\" then\
  14087.                                rednet.send( tUser.nID, {\
  14088.                                    sType = \"pong to client\",\
  14089.                                    nUserID = nUserID,\
  14090.                                }, \"chat\" )\
  14091. \
  14092.                            elseif tMessage.sType == \"pong to server\" then\
  14093.                                tUser.bPingPonged = true\
  14094. \
  14095.                            end\
  14096.                        end\
  14097.                    end\
  14098.                 end\
  14099.            end\
  14100.        end )\
  14101.    end )\
  14102.    if not ok then\
  14103.        printError( error )\
  14104.    end\
  14105. \
  14106.    -- Unhost server\
  14107.    for nUserID, tUser in pairs( tUsers ) do\
  14108.        rednet.send( tUser.nID, {\
  14109.            sType = \"kick\",\
  14110.            nUserID = nUserID,\
  14111.        }, \"chat\" )\
  14112.    end\
  14113.    rednet.unhost( \"chat\" )\
  14114.    closeModem()\
  14115. \
  14116. elseif sCommand == \"join\" then\
  14117.    -- \"chat join\"\
  14118.    -- Get hostname and username\
  14119.    local sHostname = tArgs[2]\
  14120.    local sUsername = tArgs[3]\
  14121.    if sHostname == nil or sUsername == nil then\
  14122.        printUsage()\
  14123.        return\
  14124.    end\
  14125. \
  14126.    -- Connect\
  14127.    if not openModem() then\
  14128.        return\
  14129.    end\
  14130.    write( \"Looking up \" .. sHostname .. \"... \" )\
  14131.    local nHostID = rednet.lookup( \"chat\", sHostname )\
  14132.    if nHostID == nil then\
  14133.        print( \"Failed.\" )\
  14134.        return\
  14135.    else\
  14136.        print( \"Success.\" )\
  14137.    end\
  14138. \
  14139.    -- Login\
  14140.    local nUserID = math.random( 1, 2147483647 )\
  14141.    rednet.send( nHostID, {\
  14142.        sType = \"login\",\
  14143.        nUserID = nUserID,\
  14144.        sUsername = sUsername,\
  14145.    }, \"chat\" )\
  14146. \
  14147.    -- Setup ping pong\
  14148.    local bPingPonged = true\
  14149.    local pingPongTimer = os.startTimer( 0 )\
  14150. \
  14151.    function ping()\
  14152.        rednet.send( nHostID, {\
  14153.            sType = \"ping to server\",\
  14154.            nUserID = nUserID,\
  14155.        }, \"chat\" )\
  14156.        bPingPonged = false\
  14157.        pingPongTimer = os.startTimer( 15 )\
  14158.    end\
  14159. \
  14160.    -- Handle messages\
  14161.    local w,h = term.getSize()\
  14162.    local parentTerm = term.current()\
  14163.    local titleWindow = window.create( parentTerm, 1, 1, w, 1, true )\
  14164.    local historyWindow = window.create( parentTerm, 1, 2, w, h-2, true )\
  14165.    local promptWindow = window.create( parentTerm, 1, h, w, 1, true )\
  14166.    historyWindow.setCursorPos( 1, h-2 )\
  14167. \
  14168.    term.clear()\
  14169.    term.setTextColour( textColour )\
  14170.    term.redirect( promptWindow )\
  14171.    promptWindow.restoreCursor()\
  14172. \
  14173.    function drawTitle()\
  14174.        local x,y = titleWindow.getCursorPos()\
  14175.        local w,h = titleWindow.getSize()\
  14176.        local sTitle = sUsername..\" on \"..sHostname\
  14177.        titleWindow.setTextColour( highlightColour )\
  14178.        titleWindow.setCursorPos( math.floor( w/2 - string.len(sTitle)/2 ), 1 )\
  14179.        titleWindow.clearLine()\
  14180.        titleWindow.write( sTitle )\
  14181.        promptWindow.restoreCursor()\
  14182.    end\
  14183. \
  14184.    function printMessage( sMessage )\
  14185.        term.redirect( historyWindow )\
  14186.        print()\
  14187.        if string.match( sMessage, \"^\\*\" ) then\
  14188.            -- Information\
  14189.            term.setTextColour( highlightColour )\
  14190.            write( sMessage )\
  14191.            term.setTextColour( textColour )\
  14192.        else\
  14193.            -- Chat\
  14194.            local sUsernameBit = string.match( sMessage, \"^\\<[^\\>]*\\>\" )\
  14195.            if sUsernameBit then\
  14196.                term.setTextColour( highlightColour )\
  14197.                write( sUsernameBit )\
  14198.                term.setTextColour( textColour )\
  14199.                write( string.sub( sMessage, string.len( sUsernameBit ) + 1 ) )\
  14200.            else\
  14201.                write( sMessage )\
  14202.            end\
  14203.        end\
  14204.        term.redirect( promptWindow )\
  14205.        promptWindow.restoreCursor()\
  14206.    end\
  14207. \
  14208.    drawTitle()\
  14209. \
  14210.    local ok, error = pcall( function()\
  14211.        parallel.waitForAny( function()\
  14212.            while true do\
  14213.                local sEvent, timer = os.pullEvent()\
  14214.                if sEvent == \"timer\" then\
  14215.                    if timer == pingPongTimer then\
  14216.                        if not bPingPonged then\
  14217.                            printMessage( \"Server timeout.\" )\
  14218.                            return\
  14219.                        else\
  14220.                            ping()\
  14221.                        end\
  14222.                    end\
  14223. \
  14224.                elseif sEvent == \"term_resize\" then\
  14225.                    local w,h = parentTerm.getSize()\
  14226.                    titleWindow.reposition( 1, 1, w, 1 )\
  14227.                    historyWindow.reposition( 1, 2, w, h-2 )\
  14228.                    promptWindow.reposition( 1, h, w, 1 )\
  14229. \
  14230.                end\
  14231.            end\
  14232.        end,\
  14233.        function()\
  14234.            while true do\
  14235.                local nSenderID, tMessage = rednet.receive( \"chat\" )\
  14236.                if nSenderID == nHostID and type( tMessage ) == \"table\" and tMessage.nUserID == nUserID then\
  14237.                    if tMessage.sType == \"text\" then\
  14238.                        local sText = tMessage.sText\
  14239.                        if sText then\
  14240.                            printMessage( sText )\
  14241.                        end\
  14242. \
  14243.                    elseif tMessage.sType == \"ping to client\" then\
  14244.                        rednet.send( nSenderID, {\
  14245.                            sType = \"pong to server\",\
  14246.                            nUserID = nUserID,\
  14247.                        }, \"chat\" )\
  14248. \
  14249.                    elseif tMessage.sType == \"pong to client\" then\
  14250.                        bPingPonged = true\
  14251. \
  14252.                    elseif tMessage.sType == \"kick\" then\
  14253.                        return\
  14254. \
  14255.                    end\
  14256.                end\
  14257.            end\
  14258.        end,\
  14259.        function()\
  14260.            local tSendHistory = {}\
  14261.            while true do\
  14262.                promptWindow.setCursorPos( 1,1 )\
  14263.                promptWindow.clearLine()\
  14264.                promptWindow.setTextColor( highlightColour )\
  14265.                promptWindow.write( \": \")\
  14266.                promptWindow.setTextColor( textColour )\
  14267. \
  14268.                local sChat = read( nil, tSendHistory )\
  14269.                if string.match( sChat, \"^/logout\" ) then\
  14270.                    break\
  14271.                else\
  14272.                    rednet.send( nHostID, {\
  14273.                        sType = \"chat\",\
  14274.                        nUserID = nUserID,\
  14275.                        sText = sChat,\
  14276.                    }, \"chat\" )\
  14277.                    table.insert( tSendHistory, sChat )\
  14278.                end\
  14279.            end\
  14280.        end )\
  14281.    end )\
  14282. \
  14283.    -- Close the windows\
  14284.    term.redirect( parentTerm )\
  14285. \
  14286.    -- Print error notice\
  14287.    local w,h = term.getSize()\
  14288.    term.setCursorPos( 1, h )\
  14289.    term.clearLine()\
  14290.    term.setCursorBlink( false )\
  14291.    if not ok then\
  14292.        printError( error )\
  14293.    end\
  14294. \
  14295.    -- Logout\
  14296.    rednet.send( nHostID, {\
  14297.        sType = \"logout\",\
  14298.        nUserID = nUserID,\
  14299.    }, \"chat\" )\
  14300.    closeModem()\
  14301. \
  14302.    -- Print disconnection notice\
  14303.    print( \"Disconnected.\" )\
  14304. \
  14305. else\
  14306.    -- \"chat somethingelse\"\
  14307.    printUsage()\
  14308. \
  14309. end",
  14310.   [ "/rom/help/rednet" ] = "The rednet API provides a simple computer networking model using modems.\
  14311. \
  14312. Functions in the rednet API:\
  14313. rednet.open( side )\
  14314. rednet.close( [side] )\
  14315. rednet.isOpen( [side] )\
  14316. rednet.send( receiverID, message, [protocol] ) -- Send to a specific computer\
  14317. rednet.broadcast( message, [protocol] ) -- Send to all computers\
  14318. rednet.receive( [protocol], [timeout] ) -- Returns: senderID, message, protocol\
  14319. rednet.host( protocol, hostname )\
  14320. rednet.unhost( protocol )\
  14321. rednet.lookup( protocol, [hostname] ) -- Returns: ID\
  14322. \
  14323. Events fired by the rednet API:\
  14324. \"rednet_message\" when a message is received. Arguments are senderID, message, protocol\
  14325. Type \"help events\" to learn about the event system.\
  14326. \
  14327. Rednet is not the only way to use modems for networking. Interfacing with the modem directly using the peripheral API and listening for the \"modem_message\" event allows for lower level control, at the expense of powerful high level networking features.",
  14328.   [ "/rom/help/printers" ] = "The Printer is a peripheral device available for CraftOS. Type \"help peripheral\" to learn about using the Peripheral API to connect with peripherals. When a Printer is connected, peripheral.getType() will return \"printer\".\
  14329. \
  14330. Methods exposed by the Printer:\
  14331. getInkLevel()\
  14332. getPaperLevel()\
  14333. newPage()\
  14334. setPageTitle( title )\
  14335. getPageSize()\
  14336. setCursorPos( x, y )\
  14337. getCursorPos()\
  14338. write( text )\
  14339. endPage()",
  14340. }  for k, v in pairs(tbl) do
  14341.     local X = fs.open(k, 'w')
  14342.     X.write(v)
  14343.     X.close()
  14344.   end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement