Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

lol.bin

By: a guest on Jul 12th, 2013  |  syntax: Lua  |  size: 445.69 KB  |  views: 1,060  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. local pkg = {["var"]={["linox.ver"]="Linox v0.0.1",["mpc-get-repo.rpo"]="I staple tape worms on my penis!@#&So the flesh worm will drink brainjuice from your fetus!@#&(4X)!@#&!@#&Feel the blood gushing from your anus!@#&(2X)!@#&!@#&Feel the blood gushing from your anus!@#&(4X)!@#&!@#&Tape worms on my fucking penis!!@#&Penis!!@#&Tape worms!!@#&Tape worms on my penis!!@#&Tape worms on my penis!@#&Tape worms on my peniiiiiii....!",},["etc"]={["linoxim"]="                                                 !@#& 55555                                           !@#& 54445                                           !@#& 54e45                                           !@#& 54e45        555                                !@#& 54e45                                           !@#& 54e45555555  555  55555555  55555  555   555    !@#& 54e44444445  555  55555555  55555   555 555     !@#& 54eeeeeee45  555  555  555  55 55    5555       !@#& 54444444445  555  555  555  55555   555 555     !@#& 55555555555  555  555  555  55555  555   555    !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 ",["linoxm"]="                                                 !@#& 55555                                           !@#& 54445                                           !@#& 54e45                                           !@#& 54e45        555                                !@#& 54e45                                           !@#& 54e45555555  555  55555555  55555  555   555    !@#& 54e44444445  555  55555555  55555   555 555     !@#& 54eeeeeee45  555  555  555  55 55    5555       !@#& 54444444445  555  555  555  55555   555 555     !@#& 55555555555  555  555  555  55555  555   555    !@#&                                                 !@#&  eee    eee   e  e                              !@#& e e e  e   e     e                              !@#& e e e  e   e  e  e                              !@#& e e e   eeeee e   eee                           !@#&                                                 !@#&                                                 ",["bg"]="                                                 !@#& 55555                                           !@#& 54445                                           !@#& 54e45                                           !@#& 54e45        555                                !@#& 54e45                                           !@#& 54e45555555  555  55555555  55555  555   555    !@#& 54e44444445  555  55555555  55555   555 555     !@#& 54eeeeeee45  555  555  555  55 55    55555      !@#& 54444444445  555  555  555  55555   555 555     !@#& 55555555555  555  555  555  55555  555   555    !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 !@#&                                                 ",["mfb"]={},},["startup"]="if not os.getComputerLabel() then!@#&     os.setComputerLabel(\"SEXY_BEAST\")!@#&end!@#&cua = fs.open(\"/lib/usr/users\", \"r\")!@#&if cua.readAll() == \"\" then!@#&     cua.close()!@#& sua = fs.open(\"/lib/usr/users\", \"w\")!@#&    sua.writeLine('{[\"admin\"]=\"d74ff0ee8da3b9806b18c877dbf29bbde50b5bd8e4dad7a3a725000feb82e8f1\",}')!@#&        sua.close()!@#&else!@#& cua.close()!@#&end!@#&motd = {\"Coded by __Hithere\", \"http://zudohackz.koding.com\", \"ALIENS\", \"[xx]* -<I'm a testicle!>\", \"You can only hack my penis on singleplayer!\", \"Internal stack failure, system halted?\", \"Kernel Panic!\", \"Warning: Logging in will make you a nerd\", math.random() .. \" happy customers!\"}!@#&if not term.isColor() then!@#&os.reboot()!@#&end!@#&w, h = term.getSize()!@#&function printc(str, ln)!@#& term.setCursorPos(w/2-#str/2, ln)!@#& print(str)!@#&end!@#&os.loadAPI(\"/lib/load\")!@#&os.loadAPI(\"/lib/linox\")!@#&logo = {\"c    c  ccc   cccc  c   c\",!@#&    \"c       c  c  c  c   c c \",!@#&      \"c    c  c  c  c  c    c  \",!@#&      \"c    c  c  c  c  c   c c \",!@#&      \"ccc  c  c  c  cccc  c   c\"}!@#&local bar = load.init( load.STANDARD, logo, 5, w-4, 17, colors.lime, \"Splitting Uranus Atoms\", \"\", \"Starting \" .. linox.getVerNo() )!@#&help.setPath(\"/rom/help/;/lib/help\")!@#&os.loadAPI(\"/lib/p2\")!@#&function mainBoot()!@#&sleep(1)!@#&bar:triggerUpdate(\"8=========D~~~~~~~\")!@#&sleep(1)!@#&-- Begin VAR setup: change if required!@#&path =  \"/bin\"!@#&-- End VAR setup!@#&os.loadAPI(\"/lib/sysconf\")!@#&shell.run(\"/bin/boot/loadapis\")!@#&sleep(1)!@#&bar:triggerUpdate(\"Initializing Anal Capacitor\")!@#&shell.setPath(shell.path() .. \":\" .. path)!@#&if http then!@#&      if update.ping() then!@#&               udver = update.getVerNo()!@#&           if linox.getVerNo() == udver then!@#&                   spd.setData(\"updates\",nil)!@#&                else!@#&                        spd.setData(\"updates\",udver)!@#&              end!@#& else!@#&                spd.setData(\"updates\",nil)!@#&        end!@#&else!@#&end!@#&!@#&terminate.disable()!@#&sleep(1)!@#&bar:triggerUpdate(\"Smoking detached big black cocks\")!@#&fail = true!@#&sleep(1)!@#&bar:triggerUpdate(\"Raping the future\")!@#&sleep(0.5)!@#&function loginScreen()!@#&term.setBackgroundColor(colors.lightGray)!@#&term.setTextColor(colors.black)!@#&term.clear()!@#&term.setCursorPos(1,1)!@#&quit = \"Stick finger in asshole to shutdown\"!@#&term.setBackgroundColor(colors.pink)!@#&write(string.rep(\" \", w))!@#&term.setCursorPos(1,1)!@#&write(linox.getVerNo())!@#&term.setCursorPos(w-#quit, 1)!@#&write(quit)!@#&term.setTextColor(colors.white)!@#&term.setCursorPos(10, h/2-1)!@#&write(\"                    \")!@#&term.setCursorPos(10, h/2+1)!@#&write(\"                    \")!@#&term.setBackgroundColor(colors.brown)!@#&term.setCursorPos(1, h/2-1)!@#&write(\"Username: \")!@#&term.setCursorPos(1, h/2+1)!@#&write(\"Password: \")!@#&term.setCursorPos(w-15, h/2-1)!@#&write(\"ZudoHacks SUCKS\")!@#&printc(motd[math.random(1,#motd)], h-1)!@#&term.setBackgroundColor(colors.yellow)!@#&term.setTextColor(colors.black)!@#&term.setCursorPos(11, h/2-1)!@#&un = read()!@#&term.setCursorPos(11, h/2+1)!@#&pw = read(\" 8===D \")!@#&if linox.getLoginVerify(un, pw) then!@#&      spd.setData(\"login\", un)!@#&  shell.setDir(\"/home\")!@#&     shell.run(\"/bin/shell\")!@#&else!@#&   loginScreen()!@#&end!@#&end!@#&loginScreen()!@#&end!@#&function enableTerm()!@#&a,b,c = rednet.receive()!@#&if b == \"linox_emergency_terminate\" then!@#&term.clear()!@#&term.setCursorPos(1,1)!@#&print(\"YOU HAVE BEEN PWNED!!!!!!\")!@#&error()!@#&end!@#&end!@#&function loadingBar()!@#&bar:run( true )!@#&end!@#&p2.waitForAny(loadingBar,mainBoot,enableTerm) -- I modified the original parallel API so you could not override the terminate API. MainBoot is the basis for the OS.",["PkgMake"]="sPackage = \"local pkg = %@1 local function makeFile(_path, _content) local file = fs.open(_path, \\\"w\\\") _content = _content:gsub(\\\"\\!@\\\"..\\\"#&\\\", \\\"%\\\\n\\\") _content = textutils.unserialize(_content) file.write(_content) file.close() end local function makeFolder(_path, _content) fs.makeDir(_path) for k,v in pairs(_content) do if type(v) == \\\"table\\\" then makeFolder(_path .. \\\"/\\\" .. k, v) else makeFile(_path .. \\\"/\\\" .. k, v) end end end local sDest = shell.resolve( \\\"%@2\\\" ) or \\\"/\\\" if sDest == \\\"root\\\" then sDest = \\\"/\\\" end local tPackage = pkg makeFolder(sDest, tPackage) print(\\\"Package Extracted to '\\\" .. sDest .. \\\"'!\\\")\"!@#&!@#&function addFile(_package, _path)!@#&   if fs.getName(_path) == \".DS_Store\" then!@#&          return _package!@#&     end!@#& local file, err = fs.open(_path, \"r\")!@#&     local content = file.readAll()!@#&      content = content:gsub(\"%\\n\", \"\\!@\"..\"#&\")!@#&  content = content:gsub(\"%%\", \"%%%%\")!@#&    _package[fs.getName(_path)] = content!@#&       file.close()!@#&        print(\"Added file '\".._path..\"'\")!@#&       return _package!@#&end!@#&!@#&function addFolder(_package, _path)!@#&   if string.sub(_path,1,string.len(\"rom\"))==\"rom\" or string.sub(_path,1,string.len(\"/rom\"))==\"/rom\" then!@#&              print(\"Ignored 'rom' folder. (\".._path..\")\")!@#&            return!@#&      end!@#& _package = _package or {}!@#&   for _,f in ipairs(fs.list(_path)) do!@#&                local path = _path..\"/\"..f!@#&                if fs.isDir(path) then!@#&                      _package[fs.getName(f)] = addFolder(_package[fs.getName(f)], path)!@#&          else!@#&                        _package =  addFile(_package, path)!@#&         end!@#& end!@#& return _package!@#&end!@#&!@#&local tArgs = { ... }!@#&if #tArgs < 2 then!@#&   print( \"Usage: PkgMake <source> <destination>\" )!@#&  return!@#&end!@#&!@#&local sSource = shell.resolve( tArgs[1] )!@#&local sDest = shell.resolve( tArgs[2] )!@#&!@#&if fs.isDir( sDest ) then!@#&  error(\"Destination must not be a folder.\")!@#&end!@#&!@#&if sSource == sDest then!@#& error(\"Source can not be equal to destination.\")!@#&end!@#&!@#&if fs.exists( sSource ) and fs.isDir( sSource ) then!@#&       tPackage = {}!@#&       tPackage = addFolder(tPackage, sSource)!@#&     fPackage = fs.open(sDest,\"w\")!@#&!@#& sPackage = string.gsub(sPackage, \"%%@2\", fs.getName(sSource))!@#&     sPackage = string.gsub(sPackage, \"%%@1\", textutils.serialize(tPackage))!@#&   fPackage.write(sPackage)!@#&    fPackage.close()!@#&    print(\"Package Done! ('\" .. sDest .. \"')\")!@#&      print(\"Type '\" .. sDest .. \"' to run it.\")!@#&else!@#&      error(\"Source does not exist or is not a folder.\")!@#&end",[".Firewolf_Data"]={["server_software"]="!@#&--  !@#&--  Firewolf Server Software!@#&--  Created By GravityScore and 1lann!@#&--  License found here: https://raw.github.com/1lann/Firewolf/master/LICENSE  !@#&--!@#&--  Orignal Idea from RednetExplorer 2.4.1!@#&--  RednetExplorer Made by ComputerCraftFan11!@#&--  !@#&!@#&!@#&--  -------- Variables!@#&!@#&-- Version!@#&local version = \"2.4\"!@#&local serverID = \"release\"!@#&!@#&-- Prevent Control-T!@#&os.pullEvent = os.pullEventRaw!@#&!@#&-- Updating!@#&local autoupdate = true!@#&!@#&-- Responding!@#&local enableSearch = true!@#&local enableResponse = true!@#&local enableRecording = true!@#&!@#&-- Download URLs!@#&local serverURL = \"https://raw.github.com/1lann/firewolf/master/server/server-\" .. serverID .. \".lua\"!@#&!@#&-- Events!@#&local event_stopServer = \"firewolf_stopServerEvent\"!@#&!@#&-- Statistics!@#&local searches = 0!@#&local visits = 0!@#&!@#&-- Theme!@#&local theme = {}!@#&!@#&-- Databases!@#&local ignoreDatabase = {}!@#&local permantentIgnoreDatabase = {}!@#&local suspected = {}!@#&!@#&-- Server!@#&local w, h = term.getSize()!@#&local args = {...}!@#&local website = \"\"!@#&local dataLocation = \"\"!@#&local pages = {}!@#&local totalRecordLines = {}!@#&local recordLines = {}!@#&local serverPassword = nil!@#&local serverLocked = false!@#&!@#&-- Locations!@#&local rootFolder = \"/.Firewolf_Data\"!@#&local serverFolder = rootFolder .. \"/servers\"!@#&local statsLocation = rootFolder .. \"/\" .. website .. \"_stats\"!@#&local themeLocation = rootFolder .. \"/theme\"!@#&local defaultThemeLocation = rootFolder .. \"/default_theme\"!@#&local passwordDataLocation = rootFolder .. \"/.\" .. website .. \"_password\"!@#&local serverLocation = \"/\" .. shell.getRunningProgram()!@#&!@#&-- Parse Arguments!@#&if #args >= 2 then!@#&    website = args[1]:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&    dataLocation = args[2]:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&       statsLocation = rootFolder .. \"/\" .. website .. \"_stats\"!@#&        passwordDataLocation = rootFolder .. \"/.\" .. website .. \"_password\"!@#&else!@#&     print(\"Invalid Arguments! D:\")!@#&    return!@#&end!@#&!@#&!@#&--  -------- Utility Functions!@#&!@#&local function isAdvanced()!@#&  if term.isColor then return term.isColor()!@#&  else return false end!@#&end!@#&!@#&local function oldPullEvent(ex)!@#& event, p1, p2, p3, p4, p5 = os.pullEventRaw(ex)!@#&     if event == \"terminate\" then!@#&              print(\"Terminated\")!@#&               error()!@#&     else!@#&                return event, p1, p2, p3, p4, p5!@#&    end!@#&end!@#&!@#&local function printWithType(t, func)!@#&     if type(t) == \"table\" then!@#&                for k, v in pairs(t) do!@#&                     env.pcall(function() printWithType(v, func) end)!@#&            end!@#& else!@#&                func(tostring(t))!@#&   end!@#&end!@#&!@#&local function centerWrite(text)!@#&  local x, y = term.getCursorPos()!@#&    printWithType(text, function(t)!@#&             term.setCursorPos(math.ceil((w + 1)/2 - t:len()/2), y)!@#&              write(t)!@#&    end)!@#&end!@#&!@#&local function centerPrint(text)!@#& centerWrite(text)!@#&   print()!@#&end!@#&!@#&local function leftWrite(text)!@#&        local x, y = term.getCursorPos()!@#&    printWithType(text, function(t)!@#&             term.setCursorPos(1, y)!@#&             write(text)!@#& end)!@#&end!@#&!@#&local function leftPrint(text)!@#&   leftWrite(text)!@#&     print()!@#&end!@#&!@#&local function rightWrite(text)!@#&       local x, y = term.getCursorPos()!@#&    printWithType(text, function(t)!@#&             term.setCursorPos(w - text:len() + 1, y)!@#&            write(text)!@#& end)!@#&end!@#&!@#&local function rightPrint(text)!@#&  rightWrite(text)!@#&    print()!@#&end!@#&!@#&local function clearPage(r)!@#&   -- Site titles!@#&      title = \"Hosting: rdnt://\" .. website!@#&!@#& -- Address Bar!@#&      term.setTextColor(colors[theme[\"address-bar-text\"]])!@#&      term.setCursorPos(2, 1)!@#&     term.setBackgroundColor(colors[theme[\"address-bar-background\"]])!@#&  term.clearLine()!@#&    term.setCursorPos(2, 1)!@#&     if title:len() > 42 then title = title:sub(1, 39) .. \"...\" end!@#&    write(title)!@#&!@#&    -- Records!@#&  term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&      for i = 1, 11 do!@#&            term.setCursorPos(1, i + 7) !@#&                centerWrite(string.rep(\" \", 47)) !@#& end!@#& if r == true then!@#&           for i, v in ipairs(recordLines) do!@#&                  term.setCursorPos(5, i + 8)!@#&                 write(v)!@#&            end!@#& end!@#&!@#&     term.setBackgroundColor(colors.black)!@#&       term.setTextColor(colors.white)!@#&     print(\"\")!@#&end!@#&!@#&local function prompt(list)!@#&       if isAdvanced() then!@#&                for _, v in pairs(list) do!@#&                  if v.bg then term.setBackgroundColor(v.bg) end!@#&                      if v.tc then term.setTextColor(v.tc) end!@#&                    if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 6)/2) end!@#&!@#&                 term.setCursorPos(v[2], v[3])!@#&                       write(\"[- \" .. v[1])!@#&                      term.setCursorPos(v[2] + v[1]:len() + 3, v[3])!@#&                      write(\" -]\")!@#&              end!@#&!@#&             while true do!@#&                       local e, but, x, y = os.pullEvent()!@#&                 if e == \"mouse_click\" then!@#&                                for _, v in pairs(list) do!@#&                                  if x >= v[2] and x <= v[2] + v[1]:len() + 5 and y == v[3] then!@#&                                              return v[1]!@#&                                 end!@#&                         end!@#&                 end!@#&         end!@#& else!@#&                for _, v in pairs(list) do!@#&                  term.setBackgroundColor(colors.black)!@#&                       term.setTextColor(colors.white)!@#&                     if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 4)/2) end!@#&!@#&                 term.setCursorPos(v[2], v[3])!@#&                       write(\"  \" .. v[1])!@#&                       term.setCursorPos(v[2] + v[1]:len() + 2, v[3])!@#&                      write(\"  \")!@#&               end!@#&!@#&             local key1 = 200!@#&            local key2 = 208!@#&            if dir == \"horizontal\" then!@#&                       key1 = 203!@#&                  key2 = 205!@#&          end!@#&!@#&             local curSel = 1!@#&            term.setCursorPos(list[curSel][2], list[curSel][3])!@#&         write(\"[\")!@#&                term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])!@#&             write(\"]\")!@#&!@#&            while true do!@#&                       local e, key = os.pullEvent()!@#&                       term.setCursorPos(list[curSel][2], list[curSel][3])!@#&                 write(\" \")!@#&                        term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])!@#&                     write(\" \")!@#&                        if e == \"key\" and key == key1 and curSel > 1 then!@#&                         curSel = curSel - 1!@#&                 elseif e == \"key\" and key == key2 and curSel < #list then!@#&                         curSel = curSel + 1!@#&                 elseif e == \"key\" and key == 28 then!@#&                              return list[curSel][1]!@#&                      end!@#&                 term.setCursorPos(list[curSel][2], list[curSel][3])!@#&                 write(\"[\")!@#&                        term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])!@#&                     write(\"]\")!@#&                end!@#& end!@#&end!@#&!@#&local function scrollingPrompt(list, x, y, len, width)!@#&    local wid = width!@#&   if wid == nil then wid = w - 3 end!@#&!@#&      local function updateDisplayList(items, loc, len)!@#&           local ret = {}!@#&              for i = 1, len do!@#&                   local item = items[i + loc - 1]!@#&                     if item ~= nil then table.insert(ret, item) end!@#&             end!@#&         return ret!@#&  end!@#&!@#&     if isAdvanced() then!@#&                local function draw(a)!@#&                      for i, v in ipairs(a) do!@#&                            term.setCursorPos(x, y + i - 1)!@#&                             write(string.rep(\" \", wid))!@#&                               term.setCursorPos(x, y + i - 1)!@#&                             write(\"[ \" .. v:sub(1, wid - 5))!@#&                          term.setCursorPos(wid + x - 2, y + i - 1)!@#&                           write(\"  ]\")!@#&                      end!@#&         end!@#&!@#&             local loc = 1!@#&               local disList = updateDisplayList(list, loc, len)!@#&           draw(disList)!@#&               !@#&            while true do!@#&                       local e, but, clx, cly = os.pullEvent()!@#&                     if e == \"key\" and but == 200 and loc > 1 then!@#&                             loc = loc - 1!@#&                               disList = updateDisplayList(list, loc, len)!@#&                         draw(disList)!@#&                       elseif e == \"key\" and but == 208 and loc + len - 1 < #list then!@#&                           loc = loc + 1!@#&                               disList = updateDisplayList(list, loc, len)!@#&                         draw(disList)!@#&                       elseif e == \"mouse_scroll\" and but > 0 and loc + len - 1 < #list then!@#&                             loc = loc + but!@#&                             disList = updateDisplayList(list, loc, len)!@#&                         draw(disList)!@#&                       elseif e == \"mouse_scroll\" and but < 0 and loc > 1 then!@#&                           loc = loc + but!@#&                             disList = updateDisplayList(list, loc, len)!@#&                         draw(disList)!@#&                       elseif e == \"mouse_click\" then!@#&                            for i, v in ipairs(disList) do!@#&                                      if clx >= x and clx <= x + wid and cly == i + y - 1 then!@#&                                            return v!@#&                                    end!@#&                         end!@#&                 end!@#&         end!@#& else!@#&                local function draw(a)!@#&                      for i, v in ipairs(a) do!@#&                            term.setCursorPos(x, y + i - 1)!@#&                             write(string.rep(\" \", wid))!@#&                               term.setCursorPos(x, y + i - 1)!@#&                             write(\"[ ] \" .. v:sub(1, wid - 5))!@#&                        end!@#&         end!@#&!@#&             local loc = 1!@#&               local curSel = 1!@#&            local disList = updateDisplayList(list, loc, len)!@#&           draw(disList)!@#&               term.setCursorPos(x + 1, y + curSel - 1)!@#&            write(\"x\")!@#&!@#&            while true do!@#&                       local e, key = os.pullEvent()!@#&                       term.setCursorPos(x + 1, y + curSel - 1)!@#&                    write(\" \")!@#&                        if e == \"key\" and key == 200 then!@#&                         if curSel > 1 then!@#&                                  curSel = curSel - 1!@#&                         elseif loc > 1 then!@#&                                 loc = loc - 1!@#&                                       disList = updateDisplayList(list, loc, len)!@#&                                 draw(disList)!@#&                               end!@#&                 elseif e == \"key\" and key == 208 then!@#&                             if curSel < #disList then!@#&                                   curSel = curSel + 1!@#&                         elseif loc + len - 1 < #list then!@#&                                   loc = loc + 1!@#&                                       disList = updateDisplayList(list, loc, len)!@#&                                 draw(disList)!@#&                               end!@#&                 elseif e == \"key\" and key == 28 then!@#&                              return list[curSel + loc - 1]!@#&                       end!@#&                 term.setCursorPos(x + 1, y + curSel - 1)!@#&                    write(\"x\")!@#&                end!@#& end!@#&end!@#&!@#&!@#&--  -------- Themes!@#&!@#&local defaultTheme = {[\"address-bar-text\"] = \"white\", [\"address-bar-background\"] = \"gray\", !@#&        [\"address-bar-base\"] = \"lightGray\", [\"top-box\"] = \"red\", [\"bottom-box\"] = \"orange\", !@#&    [\"text-color\"] = \"white\", [\"background\"] = \"gray\"}!@#&local originalTheme = {[\"address-bar-text\"] = \"white\", [\"address-bar-background\"] = \"black\", !@#& [\"address-bar-base\"] = \"black\", [\"top-box\"] = \"black\", [\"bottom-box\"] = \"black\", !@#&       [\"text-color\"] = \"white\", [\"background\"] = \"black\"}!@#&!@#&local function loadTheme(path)!@#&   if fs.exists(path) and not fs.isDir(path) then!@#&              local a = {}!@#&                local f = io.open(path, \"r\")!@#&              local l = f:read(\"*l\")!@#&            while l ~= nil do!@#&                   l = l:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                        if l ~= \"\" and l ~= nil and l ~= \"\\n\" then!@#&                             local b = l:find(\"=\")!@#&                             if a and b then!@#&                                     local c = l:sub(1, b - 1)!@#&                                   local d = l:sub(b + 1, -1)!@#&                                  if c == \"\" or d == \"\" then return nil!@#&                                   else a[c] = d end!@#&                           else return nil end!@#&                 end!@#&                 l = f:read(\"*l\")!@#&          end!@#&         f:close()!@#&!@#&               return a!@#&    else!@#&                return nil!@#&  end!@#&end!@#&!@#&!@#&--  -------- Filesystem!@#&!@#&local function download(url, path)!@#&     for i = 1, 3 do!@#&             local response = http.get(url)!@#&              if response then!@#&                    local data = response.readAll()!@#&                     response.close()!@#&                    local f = io.open(path, \"w\")!@#&                      f:write(data)!@#&                       f:close()!@#&                   return true!@#&         end!@#& end!@#&!@#&     return false!@#&end!@#&!@#&local function validateFilesystem()!@#&      if not fs.exists(rootFolder) or not fs.exists(serverFolder) or not fs.exists(dataLocation) or!@#&                       not fs.exists(serverLocation) or not fs.exists(dataLocation .. \"/home\") then!@#&              term.setBackgroundColor(colors[theme[\"background\"]])!@#&              term.setTextColor(colors[theme[\"text-color\"]])!@#&            term.clear()!@#&                term.setCursorPos(1, 1)!@#&             print(\"\")!@#&         term.setTextColor(colors[theme[\"text-color\"]])!@#&            term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&         centerPrint(string.rep(\" \", 47))!@#&          centerWrite(string.rep(\" \", 47))!@#&          centerPrint(\"Invalid Filesystem!\")!@#&                centerPrint(string.rep(\" \", 47))!@#&          print(\"\")!@#&!@#&             term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&              centerPrint(string.rep(\" \", 47))!@#&          centerPrint(\"  The files required to run this server        \")!@#&            centerPrint(\"  cannot be found! Run Firewolf to create      \")!@#&            centerPrint(\"  them!                                        \")!@#&            centerPrint(string.rep(\" \", 47))!@#&          centerWrite(string.rep(\" \", 47))!@#&          if isAdvanced() then centerPrint(\"Click to exit...\")!@#&              else centerPrint(\"Press any key to exit...\") end!@#&          centerPrint(string.rep(\" \", 47))!@#&!@#&              while true do!@#&                       local e = os.pullEvent()!@#&                    if e == \"key\" or e == \"mouse_click\" then break end!@#&              end!@#&!@#&             return false!@#&        else!@#&                return true!@#& end!@#&end!@#&!@#&local function updateClient()!@#&     local updateLocation = rootFolder .. \"/server-update\"!@#&     fs.delete(updateLocation)!@#&!@#&       -- Update!@#&   download(serverURL, updateLocation)!@#& local a = io.open(updateLocation, \"r\")!@#&    local b = io.open(serverLocation, \"r\")!@#&    local new = a:read(\"*a\")!@#&  local cur = b:read(\"*a\")!@#&  a:close()!@#&   b:close()!@#&!@#&       if cur ~= new then!@#&          fs.delete(serverLocation)!@#&           fs.move(updateLocation, serverLocation)!@#&             shell.run(serverLocation, args[1], args[2])!@#&         error()!@#&     else!@#&                fs.delete(updateLocation)!@#&   end!@#&end!@#&!@#&!@#&--  -------- Loading!@#&!@#&local serverAPIContent = [[!@#&!@#&--  !@#&--  Custom Server API!@#&--  !@#&!@#&-- Notes:!@#&-- - These functions are called when events occur!@#&-- - Their names are required to be kept the same!@#&-- - These functions must be able to execute!@#&--   instantly, else your server may be DDoS-able!@#&!@#&!@#&uponSuccessfulRequest = function(page, id)!@#&    -- Called when a request for a page is successful!@#&!@#&       -- Your Code Here...!@#&end!@#&!@#&uponFailedRequest = function(page, id)!@#&   -- Called when a request for a page is unsuccessful!@#&!@#&     -- Your Code Here...!@#&end!@#&!@#&uponAnyOtherMessage = function(message, id)!@#&      -- Called when any rendet message is received!@#&       -- that is not requesting a page!@#&!@#&        -- Your Code Here...!@#&end!@#&!@#&uponAnyMessage = function(message, id)!@#&   -- Called when any rednet message is received!@#&!@#&   -- Your Code Here...!@#&end!@#&!@#&parallelWithServer = function()!@#&  -- Runs in a parallel alongside the server!@#&!@#&      -- Your Code Here...!@#&end!@#&!@#&local function uponServerApiLoad()!@#&       -- Called when this Server API is loaded!@#&!@#&        -- Your Code Here...!@#&end!@#&!@#&uponServerApiLoad()!@#&!@#&]]!@#&!@#&local function loadServerAPI()!@#&      if not fs.exists(dataLocation .. \"/serverapi\") then!@#&               local f = io.open(dataLocation .. \"/serverapi\", \"w\")!@#&            f:write(serverAPIContent)!@#&           f:close()!@#&   end!@#&!@#&     shell.run(dataLocation .. \"/serverapi\")!@#&   if type(uponSuccessfulRequest) ~= \"function\" then!@#&         uponSuccessfulRequest = nil!@#& end if type(uponFailedRequest) ~= \"function\" then!@#&         uponFailedRequest = nil!@#&     end if type(uponAnyOtherMessage) ~= \"function\" then!@#&               uponAnyOtherMessage = nil!@#&   end if type(uponAnyMessage) ~= \"function\" then!@#&            uponAnyMessage = nil!@#&        end if type(parallelWithServer) ~= \"function\" then!@#&                parallelWithServer = nil!@#&    end!@#&end!@#&!@#&local function loadPages(loc)!@#&     local a = fs.list(loc)!@#&      local p = {}!@#&        for i = 1, #a do!@#&            if not fs.isDir(loc .. \"/\" .. a[i]) then!@#&                  local f = io.open(loc .. \"/\" .. a[i])!@#&                     local cont = f:read(\"*a\")!@#&                 f:close()!@#&!@#&                       p[loc .. \"/\" .. a[i]] = cont!@#&              else!@#&                        local b = loadPages(loc .. \"/\" .. a[i])!@#&                   for x = 1, #b do!@#&                            table.insert(p, b[x])!@#&                       end!@#&         end!@#& end!@#&!@#&     return p!@#&end!@#&!@#&local function checkForModem()!@#&       while true do!@#&               local present = false!@#&               for _, v in pairs(rs.getSides()) do!@#&                 if peripheral.getType(v) == \"modem\" then!@#&                          rednet.open(v)!@#&                              present = true!@#&                              break!@#&                       end!@#&         end!@#&!@#&             if not present then!@#&                 term.setTextColor(colors[theme[\"text-color\"]])!@#&                    term.setBackgroundColor(colors[theme[\"background\"]])!@#&                      term.clear()!@#&                        term.setCursorPos(1, 2)!@#&                     print(\"\")!@#&                 term.setTextColor(colors[theme[\"text-color\"]])!@#&                    term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                 centerPrint(string.rep(\" \", 43))!@#&                  centerWrite(string.rep(\" \", 43))!@#&                  centerPrint(\"No Modem Attached! D:\")!@#&                      centerPrint(string.rep(\" \", 43))!@#&                  print(\"\")!@#&!@#&                     term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                      centerPrint(string.rep(\" \", 43))!@#&                  centerWrite(string.rep(\" \", 43))!@#&                  centerPrint(\"No wireless modem was found on this\")!@#&                        centerWrite(string.rep(\" \", 43))!@#&                  centerPrint(\"computer, and Firewolf is not able to\")!@#&                      centerWrite(string.rep(\" \", 43))!@#&                  centerPrint(\"run without one!\")!@#&                   centerPrint(string.rep(\" \", 43))!@#&                  centerWrite(string.rep(\" \", 43))!@#&                  centerPrint(\"Waiting for a modem to be attached...\")!@#&                      centerWrite(string.rep(\" \", 43))!@#&                  if isAdvanced() then centerPrint(\"Click to exit...\")!@#&                      else centerPrint(\"Press any key to exit...\") end!@#&                  centerPrint(string.rep(\" \", 43))!@#&!@#&                      while true do!@#&                               local e, id = os.pullEvent()!@#&                                if e == \"key\" or e == \"mouse_click\" then return false!@#&                           elseif e == \"peripheral\" then break end!@#&                   end!@#&         else!@#&                        return true!@#&         end!@#& end!@#&end!@#&!@#&!@#&--  -------- Respond to Messages!@#&!@#&local i = 1!@#&local function record(text)!@#&    local oldX, oldY = term.getCursorPos()!@#&      local a = tostring(i) .. \":\" .. string.rep(\" \", 4 - tostring(i):len()) .. text!@#&  table.insert(totalRecordLines, a)!@#&   if #recordLines > 8 then table.remove(recordLines, 1) end!@#&   table.insert(recordLines, a)!@#&!@#&    if enableRecording then clearPage(true) end!@#& i = i + 1!@#&   term.setCursorPos(oldX, oldY)!@#&       if enableRecording then!@#&     term.setBackgroundColor(colors[theme[\"top-box\"]])!@#& term.setTextColor(colors[theme[\"text-color\"]])!@#&    end!@#&end!@#&!@#&local function respondToEvents()!@#&  if uponSuccessfulRequest == nil or uponFailedRequest == nil or uponAnyMessage == nil or !@#&                    uponAnyOtherMessage == nil or parallelWithServer == nil then!@#&                record(\"Warning - Failed To Load Server API:\")!@#&            if uponSuccessfulRequest == nil then record(\" - uponSuccessfulRequest()\") end!@#&             if uponFailedRequest == nil then record(\" - uponFailedRequest()\") end!@#&             if uponAnyMessage == nil then record(\" - uponAnyMessage()\") end!@#&           if uponAnyOtherMessage == nil then record(\" - uponAnyOtherMessage()\") end!@#&         if parallelWithServer == nil then record(\" - parallelWithServer()\") end!@#&   else record(\"Loaded Server API\") end!@#&!@#&  local writingClock = os.clock()!@#&     local ignoreClock = os.clock()!@#&      while true do!@#&               if os.clock() - ignoreClock < 6 then!@#&                        for k, v in pairs(suspected) do!@#&                             if v > 10 then table.insert(ignoreDatabase, tostring(k)) end!@#&                        end!@#&         else!@#&                        ignoreDatabase = {}!@#&                 suspected = {}!@#&                      ignoreClock = os.clock()!@#&            end!@#&!@#&             local e, id, mes = os.pullEvent()!@#&!@#&               local ignore = false!@#&                for _, v in pairs(ignoreDatabase) do!@#&                        if tostring(id) == v then ignore = true break end!@#&           end for _, v in pairs(permantentIgnoreDatabase) do!@#&                  if tostring(id) == v then ignore = true break end!@#&           end!@#&!@#&             if e == \"rednet_message\" and enableResponse == true and not ignore then!@#&                   if mes == website or mes == website .. \"/\" or mes == website .. \"/home\" then!@#&                            if suspected[tostring(id)] then suspected[tostring(id)] = suspected[tostring(id)] + 1!@#&                               else suspected[tostring(id)] = 1 end!@#&                                for i = 1, 3 do rednet.send(id, pages[dataLocation .. \"/home\"]) end!@#&                               record(\"/home : \" .. tostring(id))!@#&                                visits = visits + 1!@#&!@#&                             if uponSuccessfulRequest ~= nil then uponSuccessfulRequest(\"/home\", id) end!@#&                       elseif mes:find(\"/\") then!@#&                         local a = mes:sub(1, mes:find(\"/\") - 1)!@#&                           if a == website then!@#&                                        if suspected[tostring(id)] then !@#&                                            suspected[tostring(id)] = suspected[tostring(id)] + 1!@#&                                       else suspected[tostring(id)] = 1 end!@#&                                        local b = mes:sub(mes:find(\"/\"), -1)!@#&                                      local c = b!@#&                                 if c:len() > 18 then c = c:sub(1, 15) .. \"...\" end!@#&                                        if pages[dataLocation .. b] and b ~= \"/serverapi\" then!@#&                                            for i = 1, 3 do rednet.send(id, pages[dataLocation .. b]) end!@#&                                               record(c .. \" : \" .. id)!@#&                                          visits = visits + 1!@#&!@#&                                             if uponSuccessfulRequest ~= nil then uponSuccessfulRequest(b, id) end!@#&                                       else!@#&                                                record(\"Failed - \" .. c .. \" : \" .. id)!@#&                                         if uponFailedRequest ~= nil then uponFailedRequest(b, id) end!@#&                                       end!@#&                         end!@#&                 elseif mes == \"firewolf.broadcast.dns.list\" then!@#&                          if suspected[tostring(id)] then suspected[tostring(id)] = suspected[tostring(id)] + 1!@#&                               else suspected[tostring(id)] = 1 end!@#&                                rednet.send(id, \"firewolf-site:\" .. website)!@#&                              searches = searches + 1!@#&                     else!@#&                                if uponAnyOtherMessage ~= nil then uponAnyOtherMessage(mes, id) end!@#&                 end!@#&!@#&                     if uponAnyMessage ~= nil then uponAnyMessage(mes, id) end!@#&           elseif e == event_stopServer then!@#&                   return!@#&              end!@#&!@#&             -- Save stats!@#&               if os.clock() - writingClock > 5 then!@#&                       local f = io.open(statsLocation, \"w\")!@#&                     f:write(tostring(visits) .. \"\\n\" .. tostring(searches) .. \"\\n\" ..!@#&                             textutils.serialize(permantentIgnoreDatabase))!@#&                      f:close()!@#&                   writingClock = os.clock()!@#&           end!@#& end!@#&end!@#&!@#&!@#&--  -------- Interface!@#&!@#&local function edit()!@#&   openAddressBar = false!@#&      local oldLoc = shell.dir()!@#&  local commandHis = {}!@#&       local dir = dataLocation!@#&    term.setBackgroundColor(colors.black)!@#&       term.setTextColor(colors.white)!@#&     term.clear()!@#&        term.setCursorPos(1, 1)!@#&     print(\"\")!@#& print(\" Server Shell Editing\")!@#&    print(\" Type 'exit' to return to Firewolf.\")!@#&      print(\" The 'home' file is the index of your site\")!@#&       print(\"\")!@#&!@#&     local allowed = {\"move\", \"mv\", \"cp\", \"copy\", \"drive\", \"delete\", \"rm\", \"edit\", !@#&              \"eject\", \"exit\", \"help\", \"id\", \"monitor\", \"rename\", \"alias\", \"clear\",!@#&               \"paint\", \"firewolf\", \"lua\", \"redstone\", \"rs\", \"redprobe\", \"redpulse\", \"programs\",!@#&           \"redset\", \"reboot\", \"hello\", \"label\", \"list\", \"ls\", \"easter\", \"pastebin\", \"dir\"}!@#&  !@#&    while true do!@#&               shell.setDir(serverFolder .. \"/\" .. website)!@#&              term.setBackgroundColor(colors.black)!@#&               if isAdvanced() then term.setTextColor(colors.yellow)!@#&               else term.setTextColor(colors.white) end!@#&            write(\"> \")!@#&               term.setTextColor(colors.white)!@#&             local line = read(nil, commandHis)!@#&          table.insert(commandHis, line)!@#&!@#&          local words = {}!@#&            for m in string.gmatch(line, \"[^ \\t]+\") do!@#&                       local a = m:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                  table.insert(words, a)!@#&              end!@#&!@#&             local com = words[1]!@#&                if com == \"exit\" then!@#&                     break!@#&               elseif com then!@#&                     local a = false!@#&                     for _, v in pairs(allowed) do!@#&                               if com == v then a = true break end!@#&                 end!@#&!@#&                     if a then!@#&                           term.setBackgroundColor(colors.black)!@#&                               term.setTextColor(colors.white)!@#&                             shell.run(com, unpack(words, 2))!@#&                    else!@#&                                term.setTextColor(colors.red)!@#&                               print(\"Program Not Allowed!\")!@#&                     end!@#&         end!@#& end!@#& shell.setDir(oldLoc)!@#&end!@#&!@#&local function interface()!@#&       local opt = \"\"!@#&    while true do!@#&               term.setBackgroundColor(colors[theme[\"background\"]])!@#&              term.setTextColor(colors[theme[\"text-color\"]])!@#&            term.clear()!@#&                term.setCursorPos(1, 1)!@#&             clearPage(true)!@#&             term.setCursorPos(1, 2)!@#&             print(\"\")!@#&         term.setTextColor(colors[theme[\"text-color\"]])!@#&            term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&         for i = 1, 4 do centerPrint(string.rep(\" \", 47)) end!@#&              print(\"\")!@#&         term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&!@#&          if enableResponse == false then p1 = \"Unpause Server\" end!@#&         term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&         if not serverLocked and not serverPassword then!@#&                     os.pullEvent = oldPullEvent!@#&                 opt = prompt({{\"Add Lock\", 5, 4}, {\"Edit\", 5, 5}, {\"Manage\", w - 15, 4}, !@#&                             {\"Stop\", w - 13, 5}}, \"vertical\")!@#&               elseif not serverLocked and serverPassword then!@#&                     opt = prompt({{\"Lock Server\", 5, 4}, {\"Edit\", 5, 5}, {\"Manage\", w - 15, 4}, !@#&                          {\"Stop\", w - 13, 5}}, \"vertical\")!@#&               elseif serverLocked then!@#&                    while true do!@#&                               enableRecording = true!@#&                              term.setCursorPos(1, 2)!@#&                             print(\"\")!@#&                         term.setTextColor(colors[theme[\"text-color\"]])!@#&                            term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                         for i = 1, 4 do centerPrint(string.rep(\" \", 47)) end!@#&                              term.setCursorPos(5, 4)!@#&                             print(\"Enter Password:\")!@#&                          term.setCursorPos(5, 5)!@#&                             write(\"> \")!@#&                               local enteredPassword = read(\"*\")!@#&                         if enteredPassword == serverPassword then!@#&                                   term.setCursorPos(1, 2)!@#&                                     print(\"\")!@#&                                 term.setTextColor(colors[theme[\"text-color\"]])!@#&                                    term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                                 for i = 1, 4 do centerPrint(string.rep(\" \", 47)) end!@#&                                      term.setCursorPos(5, 4)!@#&                                     write(\"Password Accepted!\")!@#&                                       opt = \"\"!@#&                                  serverLocked = false!@#&                                        os.pullEvent = oldPullEvent!@#&                                 sleep(1.3)!@#&                                  break!@#&                               else!@#&                                        term.setCursorPos(1, 2)!@#&                                     print(\"\")!@#&                                 term.setTextColor(colors[theme[\"text-color\"]])!@#&                                    term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                                 for i = 1, 4 do centerPrint(string.rep(\" \", 47)) end!@#&                                      term.setCursorPos(5, 4)!@#&                                     write(\"Password Incorrect!\")!@#&                                      sleep(1.3)!@#&                          end!@#&                 end!@#&         end!@#&!@#&             if opt == p1 then!@#&                   enableResponse = not enableResponse!@#&         elseif opt == \"Manage\" then!@#&                       while true do!@#&                               enableRecording = false!@#&                             clearPage()!@#&                         term.setCursorPos(1, 8)!@#&                             term.setTextColor(colors[theme[\"text-color\"]])!@#&                            term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                              for i = 1, 11 do centerPrint(string.rep(\" \", 47)) end!@#&!@#&                         term.setCursorPos(5, 9)!@#&                             write(\"Visits: \" .. tostring(visits))!@#&                             term.setCursorPos(5, 10)!@#&                            write(\"Searches: \" .. tostring(searches))!@#&                         local opt = \"\"!@#&                            if serverPassword then!@#&                                      opt = prompt({{\"Manage Blocked IDs\", 9, 12}, {\"Remove Password\", 9, 13}, !@#&                                               {\"Delete Server\", 9, 14}, {\"Back\", 9, 16}}, \"vertical\")!@#&                               else!@#&                                        opt = prompt({{\"Manage Blocked IDs\", 9, 12}, {\"Delete Server\", 9, 13}, !@#&                                         {\"Back\", 9, 15}}, \"vertical\")!@#&                           end!@#&                         if opt == \"Manage Blocked IDs\" then!@#&                                       while true do!@#&                                               clearPage()!@#&                                         term.setCursorPos(1, 8)!@#&                                             term.setTextColor(colors[theme[\"text-color\"]])!@#&                                            term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                                              for i = 1, 11 do centerPrint(string.rep(\" \", 47)) end!@#&!@#&                                         term.setCursorPos(5, 9)!@#&                                             if isAdvanced() then write(\"Blocked IDs: (Click to Unblock)\")!@#&                                             else write(\"Blocked IDs: (Select to Unblock)\") end!@#&                                                local a = {\"Back\", \"Block New ID\"}!@#&                                              for _, v in pairs(permantentIgnoreDatabase) do!@#&                                                      table.insert(a, v)!@#&                                          end!@#&!@#&                                             local b = scrollingPrompt(a, 5, 11, 7, 43)!@#&                                          if b == \"Back\" then!@#&                                                       break!@#&                                               elseif b == \"Block New ID\" then!@#&                                                   term.setCursorPos(5, 10)!@#&                                                    write(\"ID: \")!@#&                                                     local c = read():gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                                                     local d = tonumber(c)!@#&                                                       local found = false!@#&                                                 for k, v in pairs(permantentIgnoreDatabase) do!@#&                                                              if v == tostring(d) then found = true break end!@#&                                                     end!@#&                                                 if d == nil then!@#&                                                            term.setCursorPos(1, 10)!@#&                                                            centerWrite(string.rep(\" \", 47))!@#&                                                          term.setCursorPos(5, 10)!@#&                                                            write(\"Not a Valid ID!\")!@#&                                                          sleep(1.1)!@#&                                                  elseif found == true then!@#&                                                           term.setCursorPos(1, 10)!@#&                                                            centerWrite(string.rep(\" \", 47))!@#&                                                          term.setCursorPos(5, 10)!@#&                                                            write(\"ID Already Exists!\")!@#&                                                               sleep(1.1)!@#&                                                  else!@#&                                                                term.setCursorPos(1, 10)!@#&                                                            centerWrite(string.rep(\" \", 47))!@#&                                                          term.setCursorPos(5, 10)!@#&                                                            write(\"Blocked ID: \" .. c .. \"!\")!@#&                                                               table.insert(permantentIgnoreDatabase, tostring(d))!@#&                                                         sleep(1.1)!@#&                                                  end!@#&                                         else!@#&                                                        for i, v in ipairs(permantentIgnoreDatabase) do!@#&                                                             if v == b then table.remove(permantentIgnoreDatabase, i) end!@#&                                                        end!@#&                                         end!@#&                                 end!@#&                         elseif opt == \"Delete Server\" then!@#&                                        clearPage()!@#&                                 term.setCursorPos(1, 8)!@#&                                     term.setTextColor(colors[theme[\"text-color\"]])!@#&                                    term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                                      for i = 1, 11 do centerPrint(string.rep(\" \", 47)) end!@#&                                     term.setCursorPos(9, 11)!@#&                                    centerPrint(\"Are you sure you want to delete the server?\")!@#&                                        centerPrint(\"This cannot be undone!\")!@#&                                     local opt = prompt({{\"No\", 11, 14}, {\"Yes\", 35, 14}}, \"horizontal\")!@#&                                   if opt == \"Yes\" then!@#&                                              fs.delete(dataLocation)!@#&                                             os.queueEvent(event_stopServer)!@#&                                             return!@#&                                      end!@#&                         elseif opt == \"Remove Password\" then!@#&                                      clearPage()!@#&                                 term.setCursorPos(1, 8)!@#&                                     term.setTextColor(colors[theme[\"text-color\"]])!@#&                                    term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                                      for i = 1, 11 do centerPrint(string.rep(\" \", 47)) end!@#&                                     term.setCursorPos(9, 11)!@#&                                    print(\"Enter your old password:\")!@#&                                 term.setCursorPos(9, 12)!@#&                                    write(\"> \")!@#&                                       local oldPass = read(\"*\")!@#&                                 if oldPass == serverPassword then!@#&                                           fs.delete(passwordDataLocation)!@#&                                             serverPassword = nil!@#&                                                serverLocked = false!@#&                                                term.setCursorPos(9, 14)!@#&                                            print(\"Password Removed!\")!@#&                                                sleep(1.3)!@#&                                          break!@#&                                       else!@#&                                                term.setCursorPos(9, 14)!@#&                                            print(\"Password incorrect! Locking server...\")!@#&                                            os.pullEvent = os.pullEventRaw!@#&                                              serverLocked = true!@#&                                         sleep(1.3)!@#&                                          break!@#&                                       end!@#&                         elseif opt == \"Back\" then!@#&                                 break!@#&                               end!@#&                 end!@#&                 !@#&                    enableRecording = true!@#&              elseif opt == \"Edit\" then!@#&                 enableRecording = false!@#&                     term.setBackgroundColor(colors.black)!@#&                       term.setTextColor(colors.white)!@#&                     term.clear()!@#&                        term.setCursorPos(1, 1)!@#&                     edit()!@#&!@#&                  term.clear()!@#&                        pages = loadPages(dataLocation)!@#&                     loadServerAPI()!@#&                     if uponSuccessfulRequest == nil or uponFailedRequest == nil or uponAnyMessage == nil or !@#&                                    uponAnyOtherMessage == nil or parallelWithServer == nil then!@#&                                record(\"Warning - Failed To Load Server API:\")!@#&                            if uponSuccessfulRequest == nil then record(\" - uponSuccessfulRequest()\") end!@#&                             if uponFailedRequest == nil then record(\" - uponFailedRequest()\") end!@#&                             if uponAnyMessage == nil then record(\" - uponAnyMessage()\") end!@#&                           if uponAnyOtherMessage == nil then record(\" - uponAnyOtherMessage()\") end!@#&                         if parallelWithServer == nil then record(\" - parallelWithServer()\") end!@#&                   else record(\"Re-Loaded Server API\") end!@#&                   enableRecording = true!@#&              elseif opt == \"Add Lock\" then!@#&                     enableRecording = false!@#&                     clearPage()!@#&                 term.setCursorPos(1, 8)!@#&                     term.setTextColor(colors[theme[\"text-color\"]])!@#&                    term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                      for i = 1, 11 do centerPrint(string.rep(\" \", 47)) end!@#&                     term.setCursorPos(5, 9)!@#&                     write(\"Enter a password to secure your\")!@#&                  term.setCursorPos(5, 10)!@#&                    write(\"server from being managed by others:\")!@#&                     term.setCursorPos(5, 11)!@#&                    write(\"> \")!@#&                       local newPassword = read(\"*\")!@#&                     term.setCursorPos(5, 13)!@#&                    write(\"Enter the password again:\")!@#&                        term.setCursorPos(5, 14)!@#&                    write(\"> \")!@#&                       if read(\"*\") == newPassword then!@#&                          serverPassword = newPassword!@#&                                serverLocked = false!@#&                                local f = io.open(passwordDataLocation, \"w\")!@#&                              f:write(newPassword)!@#&                                f:close()!@#&                           term.setCursorPos(5, 16)!@#&                            write(\"Password Set!\")!@#&                            sleep(1.3)!@#&                  else!@#&                                term.setCursorPos(5, 16)!@#&                            print(\"Passwords did not match!\")!@#&                         sleep(1.3)!@#&                  end!@#&                 enableRecording = false!@#&             elseif opt == \"Lock Server\" then!@#&                          os.pullEvent = os.pullEventRaw!@#&                              serverLocked = true!@#&                         term.setCursorPos(1, 2)!@#&                             print(\"\")!@#&                         term.setTextColor(colors[theme[\"text-color\"]])!@#&                            term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                         for i = 1, 4 do centerPrint(string.rep(\" \", 47)) end!@#&                              term.setCursorPos(5, 4)!@#&                             print(\"Server Locked!\")!@#&                           sleep(2)!@#&            elseif opt == \"Stop\" then!@#&                 -- Stop server!@#&                      os.queueEvent(event_stopServer)!@#&                     return!@#&              end!@#& end!@#&end!@#&!@#&!@#&--  -------- Main!@#&!@#&local function main()!@#&        -- Logo!@#&     term.setBackgroundColor(colors[theme[\"background\"]])!@#&      term.setTextColor(colors[theme[\"text-color\"]])!@#&    term.clear()!@#&        term.setCursorPos(1, 2)!@#&     term.setBackgroundColor(colors[theme[\"top-box\"]])!@#& leftPrint(string.rep(\" \", 47))!@#&    leftPrint([[          ______ ____ ____   ______            ]])!@#&      leftPrint([[ ------- / ____//  _// __ \\ / ____/            ]])!@#&     leftPrint([[ ------ / /_    / / / /_/ // __/               ]])!@#&      leftPrint([[ ----- / __/  _/ / / _  _// /___               ]])!@#&      leftPrint([[ ---- / /    /___//_/ |_|/_____/               ]])!@#&      leftPrint([[ --- / /       _       __ ____   __     ______ ]])!@#&      leftPrint([[ -- /_/       | |     / // __ \\ / /    / ____/ ]])!@#&     leftPrint([[              | | /| / // / / // /    / /_     ]])!@#&      leftPrint([[              | |/ |/ // /_/ // /___ / __/     ]])!@#&      leftPrint([[              |__/|__/ \\____//_____//_/        ]])!@#&     leftPrint(string.rep(\" \", 47))!@#&    print(\"\\n\")!@#&      term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&!@#&  rightPrint(string.rep(\" \", 27 + version:len()))!@#&   rightPrint(\"  Loading Firewolf Server \" .. version .. \" \")!@#&      rightPrint(string.rep(\" \", 27 + version:len()))!@#&!@#&       -- Filesystem!@#&       if not validateFilesystem() then return end!@#&!@#&     -- Update!@#&   if autoupdate then updateClient() end!@#&!@#&   -- Load!@#&     pages = loadPages(dataLocation)!@#&     loadServerAPI()!@#&     if fs.exists(statsLocation) then!@#&            local f = io.open(statsLocation, \"r\")!@#&             local a = tonumber(f:read(\"*l\"))!@#&          local b = tonumber(f:read(\"*l\"))!@#&          local c = f:read(\"*l\")!@#&            if a then visits = a end!@#&            if b then searches = b end!@#&          if c then permantentIgnoreDatabase = textutils.unserialize(c) end!@#&           f:close()!@#&   end!@#& if not checkForModem() then return end!@#&!@#&  -- Start UI!@#& parallel.waitForAll(respondToEvents, interface, parallelWithServer)!@#&end!@#&!@#&local function startup()!@#&  -- HTTP API!@#& if not http then!@#&            term.setTextColor(colors[theme[\"text-color\"]])!@#&            term.setBackgroundColor(colors[theme[\"background\"]])!@#&              term.clear()!@#&                term.setCursorPos(1, 2)!@#&             term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&         leftPrint(string.rep(\" \", 24))!@#&            leftPrint(\" HTTP Not Enabled!  \")!@#&         leftPrint(string.rep(\" \", 24))!@#&            print(\"\")!@#&!@#&             term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&              rightPrint(string.rep(\" \", 36))!@#&           rightPrint(\"  Firewolf is unable to run without \")!@#&                rightPrint(\"       the HTTP Enabled! Please \")!@#&            rightPrint(\"    enable it in your ComputerCraft \")!@#&                rightPrint(\"                            Config! \")!@#&                rightPrint(string.rep(\" \", 36))!@#&!@#&               if isAdvanced() then rightPrint(\"                   Click to exit... \")!@#&           else rightPrint(\"           Press any key to exit... \") end!@#&               rightPrint(string.rep(\" \", 36))!@#&!@#&               while true do!@#&                       local e, but, x, y = os.pullEvent()!@#&                 if e == \"mouse_click\" or e == \"key\" then break end!@#&              end!@#&!@#&             return false !@#&       end!@#&!@#&     -- Turtle!@#&   if turtle then!@#&              term.clear()!@#&                term.setCursorPos(1, 2)!@#&             centerPrint(\"Advanced Comptuer Required!\")!@#&                print(\"\\n\")!@#&              centerPrint(\"This version of Firewolf requires\")!@#&          centerPrint(\"an Advanced Comptuer to run!\")!@#&               print(\"\")!@#&         centerPrint(\"Turtles may not be used to run\")!@#&             centerPrint(\"Firewolf! :(\")!@#&               print(\"\")!@#&         centerPrint(\"Press any key to exit...\")!@#&!@#&               os.pullEvent(\"key\")!@#&               return false!@#&        end!@#&!@#&     -- Run!@#&      local _, err = pcall(main)!@#&  if err and err ~= \"parallel:22: Terminated\" then!@#&          term.setTextColor(colors[theme[\"text-color\"]])!@#&            term.setBackgroundColor(colors[theme[\"background\"]])!@#&              term.clear()!@#&                term.setCursorPos(1, 2)!@#&             term.setCursorBlink(false)!@#&          term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&         leftPrint(string.rep(\" \", 27))!@#&            leftPrint(\" Firewolf has Crashed! D:  \")!@#&          leftPrint(string.rep(\" \", 27))!@#&            print(\"\")!@#&         term.setBackgroundColor(colors[theme[\"background\"]])!@#&              print(\"\")!@#&         print(\"  \" .. err)!@#&                print(\"\")!@#&!@#&             term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&              rightPrint(string.rep(\" \", 41))!@#&           if autoupdate == \"true\" then!@#&                      rightPrint(\"    Please report this error to 1lann or \")!@#&                   rightPrint(\"  GravityScore so we are able to fix it! \")!@#&                   rightPrint(\"  If this problem persists, try deleting \")!@#&                   rightPrint(\"                         \" .. rootFolder .. \" \")!@#&            else!@#&                        rightPrint(\"        Automatic updating is off! A new \")!@#&                   rightPrint(\"     version may have have been released \")!@#&                   rightPrint(\"                that may fix this error! \")!@#&                   rightPrint(\"        If you didn't turn auto updating \")!@#&                   rightPrint(\"             off, delete \" .. rootFolder .. \" \")!@#&            end!@#&!@#&             rightPrint(string.rep(\" \", 41))!@#&           if isAdvanced() then rightPrint(\"                        Click to exit... \")!@#&              else rightPrint(\"                Press any key to exit... \") end!@#&          rightPrint(string.rep(\" \", 41))!@#&!@#&               while true do!@#&                       local e, but, x, y = os.pullEvent()!@#&                 if e == \"mouse_click\" or e == \"key\" then break end!@#&              end!@#&!@#&             return false!@#&        end!@#&!@#&     return true!@#&end!@#&!@#&-- Check If Read Only!@#&if fs.isReadOnly(serverLocation) or fs.isReadOnly(rootFolder) then!@#&       print(\"Firewolf cannot modify itself or its root folder!\")!@#&        print(\"\")!@#& print(\"This cold be caused by Firewolf being placed in\")!@#&  print(\"the rom folder, or another program may be\")!@#&        print(\"preventing the modification of Firewolf.\")!@#&!@#&     -- Reset Environment and Exit!@#&       setfenv(1, oldEnv)!@#&  error()!@#&end!@#&!@#&-- Theme!@#&if not isAdvanced() then !@#& theme = originalTheme!@#&else!@#&       theme = loadTheme(themeLocation)!@#&    if theme == nil then theme = defaultTheme end!@#&end!@#&!@#&-- Pasword!@#&if fs.exists(passwordDataLocation) then!@#&   local f = io.open(passwordDataLocation, \"r\")!@#&      serverPassword = f:read(\"*l\")!@#&     f:close()!@#&   serverLocked = true!@#&else!@#& serverLocked = false!@#&end!@#&!@#&-- Start!@#&startup()!@#&!@#&-- Clear!@#&term.setBackgroundColor(colors.black)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&term.setCursorPos(1, 1)!@#&centerPrint(\"Thank You for Using Firewolf Server \" .. version)!@#&centerPrint(\"Made by 1lann and GravityScore\")!@#&term.setCursorPos(1, 3)!@#&!@#&-- Close Rednet!@#&for _, v in pairs(rs.getSides()) do !@#&    if peripheral.getType(v) == \"modem\" then rednet.close(v) end!@#&end",["servers"]={},["user_whitelist"]="",["cache"]={},["website_data"]={},["user_blacklist"]="",["settings"]="",},["bin"]={["updates"]="udver = update.getVerNo()!@#&w,h = term.getSize()!@#&function printc(str,l)!@#&      term.setCursorPos(w/2-#str/2,l)!@#&     print(str)!@#&end!@#&!@#&term.setBackgroundColor(colors.lightGray)!@#&!@#&function upToDate()!@#&       term.clear()!@#&        term.setCursorPos(1,1)!@#&      term.setBackgroundColor(colors.white)!@#&       write(string.rep(\" \",w))!@#&  term.setTextColor(colors.black)!@#&     printc(\"Your system is up to date\",1)!@#&     term.setCursorPos(w-string.len(\"[Exit]\"),1)!@#&       x,_ = term.getCursorPos()!@#&   write(\"[Exit]\")!@#&   x2,_ = term.getCursorPos()!@#&  term.setBackgroundColor(colors.lightGray)!@#&   term.setTextColor(colors.white)!@#&     term.setCursorPos(2,10)!@#&     write(\"Current Version: \" .. linox.getVerNo())!@#&    term.setCursorPos(2,12)!@#&     write(\"Latest  Version: \" .. udver)!@#&end!@#&!@#&function updatesAvailable(smart)!@#&        term.clear()!@#&        term.setCursorPos(1,1)!@#&      term.setBackgroundColor(colors.white)!@#&       write(string.rep(\" \",w))!@#&  term.setTextColor(colors.black)!@#&     printc(\"Updates are available\",1)!@#& term.setCursorPos(w-string.len(\"[Exit]\"),1)!@#&       write(\"[Exit]\")!@#&   term.setBackgroundColor(colors.lightGray)!@#&   term.setTextColor(colors.white)!@#&     term.setCursorPos(2,10)!@#&     write(\"Current Version: \" .. linox.getVerNo())!@#&    term.setCursorPos(2,12)!@#&     write(\"Latest  Version: \" .. udver)!@#&       term.setCursorPos(2,15)!@#&     term.setBackgroundColor(colors.gray)!@#&        if smart then!@#&               write(\"X\")!@#&        else!@#&                write(\" \")!@#&        end!@#& term.setBackgroundColor(colors.lightGray)!@#&   write(\" Use SmartUpdate (beta)\")!@#&  term.setCursorPos(10,17)!@#&    print(\"[Update]\")!@#& x3,_ = term.getCursorPos()!@#&end!@#&!@#&function getClickPos()!@#&     _,b,xpos,ypos = os.pullEvent(\"mouse_click\")!@#&       if xpos == x+1 or xpos == x+2 or xpos == x+3 or xpos == x+4 or xpos == x+5 or xpos == x2 then!@#&               if ypos == 1 then!@#&                   return \"quit\"!@#&             end!@#& elseif xpos == 2 then!@#&               if ypos == 15 then!@#&                  return \"smart\"!@#&            end!@#& elseif xpos == 10 or xpos == 11 or xpos == 12 or xpos == 13 or xpos == 14 or xpos == 15 or xpos == 16 or xpos == x3 then!@#&            if ypos == 17 then!@#&                  return \"update\"!@#&           end!@#& end!@#&end!@#&!@#&smart = false!@#&!@#&if spd.getData(\"updates\") then!@#&     updatesAvailable(false)!@#&else!@#&     upToDate()!@#&end!@#&!@#&while true do!@#&      click = getClickPos()!@#&       if click == \"quit\" then!@#&           term.setBackgroundColor(colors.black)!@#&               term.setTextColor(colors.white)!@#&             term.clear()!@#&                term.setCursorPos(1,1)!@#&              error()!@#&     elseif click == \"update\" then!@#&             if smart then!@#&                       shell.run(\"gksu\", \"/bin/uplib/smart\")!@#&           else!@#&                        shell.run(\"gksu\", \"/bin/uplib/safe\")!@#&            end!@#&         term.setBackgroundColor(colors.black)!@#&               term.setTextColor(colors.white)!@#&             term.clear()!@#&                term.setCursorPos(1,1)!@#&              print(\"This feature currently does not work. Use the manual update from http://linox-os.co.nr\")!@#&           error()!@#&     elseif click == \"smart\" then!@#&              if not smart then!@#&                   smart = true!@#&                        updatesAvailable(true)!@#&              else!@#&                        smart = false!@#&                       updatesAvailable(false)!@#&             end!@#& end!@#&end",["browser"]="--[[!@#&               Mouse File Browser!@#&          by:!@#&                 Stiepen irc(Kilobyte)!@#&                       Cruor!@#&                       BigSHinyToys!@#&                !@#&            note: send link to nightin9ale on CC forums!@#&--]]!@#&!@#&local tArgs = {...}!@#&local ver = \"1.4\"!@#&local sTitle = \"File Browser\"!@#&local bugTest, norun, dir, showAll!@#&local _tArgs = {}!@#&local config = \"/etc/mfb/mouse.cfg\"!@#&!@#&local temp!@#&if shell and shell.getRunningProgram then!@#& temp = shell.getRunningProgram()!@#&end!@#&!@#&temp = temp or \"/bla\"!@#&local localPath = string.sub(temp,1,#temp-string.len(fs.getName(temp)))!@#&temp = nil -- just because not needed!@#&!@#&-- load config file!@#&!@#&local configSet = {}!@#&local cnf = {}!@#&!@#&if fs.exists(localPath..\"/\"..config) then!@#&      local file = fs.open(localPath..\"/\"..config,\"r\")!@#&        if file then!@#&                local item = file.readLine()!@#&                while item do!@#&                       table.insert(cnf,item)!@#&                      item = file.readLine()!@#&              end!@#&         file.close()!@#&        end     !@#&end!@#&!@#&for i = 1,10 do!@#&      local test,data = pcall(textutils.unserialize,cnf[i])!@#&       if test then!@#&                configSet[i] = data!@#& else!@#&                configSet[i] = nil!@#&  end!@#&end!@#&cnf = nil!@#&!@#&-- color configuration work in progress!@#&local titleBar = configSet[1] or {txt = colors.black,back = colors.blue}!@#&local addressBar = configSet[2] or {txt = colors.black,back = colors.lightGray}!@#&local itemWindo = configSet[3] or {txt = colors.black,back = colors.cyan}!@#&local rcmList = configSet[4] or {txt = colors.black,back = colors.lightGray} -- rcm = Right Click Menu List!@#&local rcmTitle = configSet[5] or {txt = colors.black,back = colors.blue}!@#&local dialogTitle = configSet[6] or {txt = colors.black,back = colors.blue}!@#&local dialogWindo = configSet[7] or {txt = colors.black,back = colors.white}!@#&local scrollCol = configSet[8] or {off = colors.gray, button = colors.gray,back = colors.lightGray}!@#&!@#&local tIcons = configSet[9] or {!@#& back = {tCol = \"lightGray\",bCol = \"blue\",txt = \" < \"},!@#&        disk = {tCol = \"lime\",bCol = \"green\",txt = \"[*]\"},!@#&    audio = {tCol = \"yellow\",bCol = \"red\",txt = \"(o)\"},!@#&   folder = {tCol = \"lightGray\",bCol = \"blue\",txt = \"[=]\"},!@#&      file = {tCol = nil ,bCol = nil ,txt = nil}!@#&}!@#&!@#&local customLaunch = configSet[10] or {!@#&      [\"Edit\"] = \"rom/programs/edit\",!@#& [\"Paint\"] = \"rom/programs/color/paint\"!@#&}!@#&!@#&local function saveCFG(overWrite)!@#&    if not fs.exists(localPath..\"/\"..config) or overWrite then!@#&                local cnf = {}!@#&              local file = fs.open(localPath..\"/\"..config,\"w\")!@#&                if file then!@#&                        file.write(textutils.serialize(titleBar)..\"\\n\")!@#&                  file.write(textutils.serialize(addressBar)..\"\\n\")!@#&                        file.write(textutils.serialize(itemWindo)..\"\\n\")!@#&                 file.write(textutils.serialize(rcmList)..\"\\n\")!@#&                   file.write(textutils.serialize(rcmTitle)..\"\\n\")!@#&                  file.write(textutils.serialize(dialogTitle)..\"\\n\")!@#&                       file.write(textutils.serialize(dialogWindo)..\"\\n\")!@#&                       file.write(textutils.serialize(scrollCol)..\"\\n\")!@#&                 file.write(textutils.serialize(tIcons)..\"\\n\")!@#&                    file.write(textutils.serialize(customLaunch)..\"\\n\")!@#&                      file.close()!@#&                elseif overWrite then!@#&               end!@#& end!@#&end!@#&!@#&saveCFG()!@#&!@#&-- end configuration!@#&!@#&local function help()!@#&        print([[Usage: browser [-d] [-h] [-a] [-u] [--debug] [--help] [--dir <dir>] [--all] [--update]!@#&--debug or -d: enable debug mode!@#&--help or -h: display this screen!@#&--dir: define initial directory!@#&--all or -a: show hidden files!@#&--update -u: update]])!@#&end!@#&!@#&local function inBouwndry(clickX,clickY,boxX,boxY,width,hight)!@#& return ( clickX >= boxX and clickX < boxX + width and clickY >= boxY and clickY < boxY + hight )!@#&end!@#&!@#&local function update()!@#&      print(\"Checking for Updates\")!@#&     local isHTTP = false!@#&        local response!@#&      if http then!@#&                isHTTP = true!@#&               print(\"http on\")!@#&          response = http.get(\"http://pastebin.com/raw.php?i=rLbnyM1U\")!@#&     end!@#& local flag = false!@#&  local isNewFlag = false!@#&     local newVerID!@#&      if response and isHTTP then!@#&         print(\"recived\")!@#&          local sInfo = response.readLine()!@#&           print(sInfo)!@#&                while sInfo do!@#&                      print(sInfo)!@#&                        if flag then!@#&                                if sInfo == ver then!@#&                                        print(\"Mouse File Browser is up to date\")!@#&                                 break!@#&                               else!@#&                                        newVerID = sInfo!@#&                                    flag = false!@#&                                        isNewFlag = true!@#&                            end!@#&                 elseif sInfo == sTitle then!@#&                         flag = true!@#&                 elseif isNewFlag then!@#&                               isNewFlag = sInfo!@#&                           response.close()!@#&                            break!@#&                       end!@#&                 sInfo = response.readLine()!@#&         end!@#&         if isNewFlag then!@#&                   print(\"New vershion avalible \"..newVerID)!@#&                 print('downloading to \\Browser')!@#&                   if fs.exists(\"Browser\") then!@#&                              write(\"Browser exists OverWrite Browser Y/N : \")!@#&                          local input = string.lower(read())!@#&                          while input ~= \"y\" and input ~= \"n\" do!@#&                                  print(\"y or n required\")!@#&                                  input = string.lower(read())!@#&                                end!@#&                         if input == \"y\" then!@#&                                      print(\"Over Writeing Browser\")!@#&                                    print(\"Downloading new File\")!@#&                                     local response = http.get(\"http://pastebin.com/raw.php?i=\"..isNewFlag)!@#&                                    if response then!@#&                                            print(\"file downloaded\")!@#&                                          print(\"installing\")!@#&                                               fs.delete(\"Browser\")!@#&                                              local handel = fs.open(\"Browser\",\"w\")!@#&                                           if handel then!@#&                                                      handel.write(response.readAll())!@#&                                                    handel.close()!@#&                                                      print(\"Update Complete\")!@#&                                          end!@#&                                         response.close()!@#&                                    end!@#&                         else!@#&                                        print(\"Update aborted\")!@#&                           end!@#&                 else!@#&                                print(\"Downloading new File\")!@#&                             local response = http.get(\"http://pastebin.com/raw.php?i=\"..isNewFlag)!@#&                            if response then!@#&                                    print(\"file downloaded\")!@#&                                  print(\"installing\")!@#&                                       local handel = fs.open(\"Browser\",\"w\")!@#&                                   if handel then!@#&                                              handel.write(response.readAll())!@#&                                            handel.close()!@#&                                              print(\"Update Complete\")!@#&                                  end!@#&                                 response.close()!@#&                            end!@#&                 end!@#&         end!@#& elseif isHTTP then!@#&          print(\"Error downloading update file Please contact BigSHinyToys on the CC forums\")!@#&               print(\"http://www.computercraft.info/forums2/index.php?/topic/5509-advanced-computer-mouse-file-browser/\")!@#&        elseif not isHTTP then!@#&              print(\"HTTP API is turned off\")!@#&           print(\"Access Computer Craft Configer and change line\")!@#&           print([[enableapi_http {!@#&# Enable the \"http\" API on Computers!@#&general=false!@#&}!@#&TO THIS :!@#&enableapi_http {!@#&# Enable the \"http\" API on Computers!@#&general=true!@#&}]])!@#& end!@#& notCMD = false!@#&      norun = true!@#&end!@#&!@#&for a = 1, #tArgs do!@#&     if tArgs[a]:sub(1,2) == \"--\" then!@#&         local cmd = tArgs[a]:sub(3):lower()!@#&         if cmd == \"debug\" then!@#&                    bugTest = true!@#&              elseif cmd == \"help\" then!@#&                 help()!@#&                      norun = true!@#&                elseif cmd == \"dir\" then!@#&                  dir = tArgs[a+1]!@#&                    a = a + 1!@#&           elseif cmd == \"all\" then!@#&                  showAll = true!@#&              elseif cmd == \"update\" then!@#&                       update()!@#&            end!@#& elseif tArgs[a]:sub(1,1) == \"-\" then!@#&              for b = 2, #tArgs[a] do!@#&                     cmd = tArgs[a]:sub(b, b)!@#&                    if cmd == \"d\" then!@#&                                bugTest = true!@#&                      elseif cmd == \"h\" then!@#&                            help()!@#&                              norun = true!@#&                        elseif cmd == \"p\" then!@#&                            dir = tArgs[a+1]!@#&                            a = a + 1!@#&                   elseif cmd == \"a\" then!@#&                            showAll = true!@#&                      elseif cmd == \"u\" then!@#&                            update()!@#&                    end!@#&         end!@#& else!@#&                table.insert(_tArgs, tArgs[a])!@#&      end!@#&end!@#&!@#&if (not dir) and shell and shell.dir then!@#& dir = shell.dir()!@#&end!@#&!@#&if dir and shell and shell.resolve then!@#&     dir = shell.resolve(dir)!@#&end!@#&!@#&dir = dir or \"/\"!@#&!@#&if bugTest then -- this is that the var is for testing!@#&     print(\"Dir: \"..dir)!@#&       os.startTimer(4)!@#&    os.pullEvent()!@#&end!@#&!@#&local function clear()!@#& term.setBackgroundColor(colors.black)!@#&       term.setTextColor(colors.white)!@#&     term.clear()!@#&        term.setCursorBlink(false)!@#&  term.setCursorPos(1,1)!@#&end!@#&!@#&--[[!@#&           Code thanks to Cruor !@#&               http://www.computercraft.info/forums2/index.php?/topic/5802-support-for-shell/!@#&]]--!@#&!@#&local function fixArgs(...)!@#&   local tReturn={}!@#&    local str=table.concat({...},\" \")!@#& local sMatch!@#&        while str and #str>0 do!@#&             if string.sub(str,1,1)==\"\\\"\" then!@#&                       sMatch, str=string.match(str, \"\\\"(.-)\\\"%s*(.*)\")!@#&              else!@#&                        sMatch, str=string.match(str, \"(%S+)%s*(.*)\")!@#&             end!@#&         table.insert(tReturn,sMatch)!@#&        end!@#& return tReturn!@#&end!@#&!@#&--[[ end Cruor function ]]--!@#&!@#&!@#&-- modified read made to play nice with coroutines!@#&!@#&local function readMOD( _sReplaceChar, _tHistory,_wdth)!@#&      local sLine = \"\"!@#&  term.setCursorBlink( true )!@#&!@#&     local nHistoryPos = nil!@#&     local nPos = 0!@#&    if _sReplaceChar then!@#&         _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )!@#&   end!@#& !@#&    local sx, sy = term.getCursorPos()      !@#&!@#&        local w, h = term.getSize()!@#& if _wdth and type(_wdth) == \"number\" then!@#&         w = sx + _wdth - 1!@#&  end!@#& !@#&    local function redraw( _sCustomReplaceChar )!@#&                local nScroll = 0!@#&           if sx + nPos >= w then!@#&                      nScroll = (sx + nPos) - w!@#&           end!@#&                 !@#&            term.setCursorPos( sx + _wdth - 1, sy )!@#&             term.write(\" \")!@#&           term.setCursorPos( sx, sy )!@#&         local sReplace = _sCustomReplaceChar or _sReplaceChar!@#&               if sReplace then!@#&                    term.write( string.rep(sReplace,_wdth) )!@#&            else!@#&                        term.write( string.sub( sLine, nScroll + 1 ,nScroll + _wdth) )!@#&              end!@#&         term.setCursorPos( sx + nPos - nScroll, sy )!@#&        end!@#& !@#&    while true do!@#&               local sEvent, param = os.pullEvent()!@#&                if sEvent == \"char\" then!@#&                  sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )!@#&                      nPos = nPos + 1!@#&                     redraw()!@#&                    !@#&            elseif sEvent == \"key\" then!@#&                       !@#&                    if param == keys.left then!@#&                          -- Left!@#&                             if nPos > 0 then!@#&                                    nPos = nPos - 1!@#&                                     redraw()!@#&                            end!@#&                         !@#&                    elseif param == keys.right then!@#&                             -- Right                                !@#&                            if nPos < string.len(sLine) then!@#&                                    nPos = nPos + 1!@#&                                     redraw()!@#&                            end!@#&                 !@#&                    elseif param == keys.up or param == keys.down then!@#&                -- Up or down!@#&                         if _tHistory then!@#&                                   redraw(\" \");!@#&                                      if param == keys.up then!@#&                                            -- Up!@#&                                               if nHistoryPos == nil then!@#&                                                  if #_tHistory > 0 then!@#&                                                              nHistoryPos = #_tHistory!@#&                                                    end!@#&                                         elseif nHistoryPos > 1 then!@#&                                                 nHistoryPos = nHistoryPos - 1!@#&                                               end!@#&                                 else!@#&                                                -- Down!@#&                                             if nHistoryPos == #_tHistory then!@#&                                                   nHistoryPos = nil!@#&                                           elseif nHistoryPos ~= nil then!@#&                                                      nHistoryPos = nHistoryPos + 1!@#&                                               end                                             !@#&                                    end!@#&                                 !@#&                                    if nHistoryPos then!@#&                         sLine = _tHistory[nHistoryPos]!@#&                      nPos = string.len( sLine ) !@#&                    else!@#&                                             sLine = \"\"!@#&                                                nPos = 0!@#&                                    end!@#&                                 redraw()!@#&                end!@#&                     elseif param == keys.backspace then!@#&                         -- Backspace!@#&                                if nPos > 0 then!@#&                                    redraw(\" \");!@#&                                      sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )!@#&                                   nPos = nPos - 1                                 !@#&                                    redraw()!@#&                            end!@#&                 elseif param == keys.home then!@#&                              -- Home!@#&                             nPos = 0!@#&                            redraw()                !@#&                    elseif param == keys.delete then!@#&                            if nPos < string.len(sLine) then!@#&                                    redraw(\" \");!@#&                                      sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )                           !@#&                                    redraw()!@#&                            end!@#&                 elseif param == keys[\"end\"] then!@#&                          -- End!@#&                              nPos = string.len(sLine)!@#&                            redraw()!@#&                    end!@#&         elseif sEvent == \"redraw\" then!@#&                    redraw()!@#&            elseif sEvent == \"return\" then!@#&                    term.setCursorBlink( false )!@#&                        return sLine!@#&                end!@#& end!@#& !@#&    term.setCursorBlink( false )!@#&        !@#&    return sLine!@#&end!@#&!@#&-- end modified read!@#&!@#&local function printC(posX,posY,textCol,backCol,text)!@#&        term.setCursorPos(posX,posY)!@#&        term.setTextColor(colors[textCol] or textCol)!@#&       term.setBackgroundColor(colors[backCol] or backCol)!@#& term.write(text)!@#&end!@#&!@#&local function InputBox(title)!@#&       local boxW,boxH = 26,3!@#&      local termX,termY = term.getSize()!@#&  local ofsX,ofsY = math.ceil((termX/2) - (boxW/2)) , math.ceil((termY/2) - (boxH/2)) -- offset from top left!@#& local options = {\"ok\",\"cancel\"}!@#& !@#&    local selected = 1!@#&  local space = 0!@#&     local range = {}!@#&    for i = 1,#options do!@#&               range[i] = {s = space,f = space + string.len(options[i])}!@#&           space = space + string.len(options[i])+3!@#&    end!@#& local ofC = (boxW/2) - (space/2)!@#&    !@#&    local function drawBox()!@#&            printC(ofsX,ofsY,colors.black,colors.blue,string.rep(\" \",boxW))!@#&           printC(ofsX+1,ofsY,colors.black,colors.blue,(title or \"User Input\"))!@#&              printC(ofsX,ofsY+1,colors.black,colors.white,string.rep(\" \",boxW))!@#&                printC(ofsX,ofsY+2,colors.black,colors.white,string.rep(\" \",boxW))!@#&                printC(ofsX,ofsY+3,colors.black,colors.white,string.rep(\" \",boxW))!@#&                !@#&            for i = 1,#options do!@#&                       if i == selected then!@#&                               term.setBackgroundColor(colors.lightGray)!@#&                           term.setCursorPos(range[i].s + ofC + ofsX - 1,ofsY + 3)!@#&                             term.write(\"[\"..options[i]..\"]\")!@#&                                term.setBackgroundColor(colors.white)!@#&                               term.write(\" \")!@#&                   else!@#&                                term.setCursorPos(range[i].s + ofC + ofsX - 1,ofsY + 3)!@#&                             term.write(\" \"..options[i]..\" \")!@#&                        end!@#&         end!@#&         !@#&            printC(ofsX+2,ofsY+2,colors.black,colors.lightGray,string.rep(\" \",boxW-4))!@#&        end!@#& drawBox()!@#&   term.setCursorPos(ofsX+2,ofsY+2)!@#&    local co = coroutine.create(function() return readMOD(nil,nil,boxW - 4) end)!@#&        while true do!@#&               local event = {os.pullEvent()}!@#&              if event[1] == \"key\" or event[1] == \"char\" then!@#&                 if event[2] == 28 then!@#&                              local test,data = coroutine.resume(co,\"return\")!@#&                           return data!@#&                 else!@#&                                coroutine.resume(co,unpack(event))!@#&                  end!@#&         elseif event[1] == \"mouse_click\" then!@#&                     if event[4] == ofsY + 3 then!@#&                                for i = 1,#options do!@#&                                       if event[3] >= range[i].s + ofC + ofsX - 1 and event[3] <= range[i].f + ofC + ofsX then!@#&                                             if options[i] == \"ok\" then!@#&                                                        local test,data = coroutine.resume(co,\"return\")!@#&                                                   return data!@#&                                         elseif options[i] == \"cancel\" then!@#&                                                        return false!@#&                                                end!@#&                                 end!@#&                         end!@#&                 end!@#&         end!@#& end!@#&end!@#&!@#&local function dialogBox(title,message,options, h, w)!@#&     term.setCursorBlink(false)!@#&  local selected = 1!@#&  title = title or \"\"!@#&       message = message or \"\"!@#&   options = options or {}!@#&     local boxW,boxH = (w or 26), (h or 3)!@#&       local termX,termY = term.getSize()!@#&  local ofsX,ofsY = math.ceil((termX/2) - (boxW/2)) , math.ceil((termY/2) - (boxH/2)) -- offset from top left!@#& !@#&    local space = 0!@#&     local range = {}!@#&    for i = 1,#options do!@#&               range[i] = {s = space,f = space + string.len(options[i])}!@#&           space = space + string.len(options[i])+3!@#&    end!@#& local ofC = math.ceil((boxW/2)) - math.ceil((space/2))!@#&      !@#&    local function drawBox()!@#&            printC(ofsX,ofsY,dialogTitle.txt,dialogTitle.back,\" \"..title..string.rep(\" \",boxW-#title-5)..\"_[]\")!@#&           term.setBackgroundColor(colors.red)!@#&         term.setTextColor(colors.white)!@#&             term.write(\"X\")!@#&           printC(ofsX,ofsY+1,dialogWindo.txt,dialogWindo.back,string.sub(\" \"..message..string.rep(\" \",boxW),1,boxW))!@#&              term.setCursorPos(ofsX,ofsY+2)!@#&              term.write(string.rep(\" \",boxW))!@#&          term.setCursorPos(ofsX,ofsY+3)!@#&              term.write(string.rep(\" \",boxW))!@#&          for i = 1,#options do!@#&                       if i == selected then!@#&                               printC(range[i].s + ofC + ofsX - 1,ofsY + 3,\"black\",\"lightGray\",\"[\"..options[i]..\"]\")!@#&                               term.setBackgroundColor(dialogWindo.back)!@#&                           term.setTextColor(dialogWindo.txt)!@#&                          term.write(\" \")!@#&                   else!@#&                                term.setCursorPos(range[i].s + ofC + ofsX - 1,ofsY + 3)!@#&                             term.write(\" \"..options[i]..\" \")!@#&                        end!@#&         end!@#&         term.setCursorPos(ofsX + ofC + space,ofsY + 3)!@#&              term.write(string.rep(\" \",boxW - (ofC + space)))!@#&          term.setBackgroundColor(colors.black)!@#&               term.setTextColor(colors.white)                 !@#&    end!@#& while true do!@#&               drawBox()!@#&           event = {os.pullEvent()}!@#&            if event[1] == \"key\" then!@#&                 if event[2] == 203 then -- left!@#&                             selected = selected - 1!@#&                             if selected < 1 then!@#&                                        selected = #options!@#&                         end!@#&                 elseif event[2] == 205 then -- right!@#&                                selected = selected + 1!@#&                             if selected > #options then!@#&                                 selected = 1!@#&                                end!@#&                 elseif event[2] == 28 then -- enter!@#&                         return selected , options[selected]!@#&                 end!@#&         elseif event[1] == \"mouse_click\" then!@#&                     !@#&                    if bugTest then term.write(\"M \"..event[2]..\" X \"..event[3]..\" Y \"..event[4]..\"    \") end!@#&                    !@#&                    if event[2] == 1 then!@#&                               if event[4] == ofsY + 3 then!@#&                                        for i = 1,#options do!@#&                                               if event[3] >= range[i].s + ofC + ofsX - 1 and event[3] <= range[i].f + ofC + ofsX then!@#&                                                     return i , options[i]!@#&                                               end!@#&                                 end!@#&                         end!@#&                 end!@#&         end!@#& end!@#&end!@#&!@#&local flag = true!@#&local fSlash = \"/\"!@#&local path = {dir:match(\"[^/]+\")}!@#&local function stringPath() -- compacted this a lot!@#&   return fSlash..table.concat(path,fSlash)!@#&end!@#&!@#&local function osRunSpaces(sFileLocation,...) -- getRunningProgram() [\"shell\"] = shell!@#&     clear()!@#&     if os.newThread then!@#&                os.newThread(false,...)!@#&     else!@#&        local fProg,probblem = loadfile(sFileLocation)!@#&              if fProg then!@#&                       local tEnv = {[\"shell\"] = {}}!@#&                     setmetatable(tEnv.shell,{ __index = shell})!@#&                 tEnv.shell.getRunningProgram = function()!@#&                           return sFileLocation!@#&                        end!@#&                 setmetatable(tEnv,{ __index = _G})!@#&                  setfenv(fProg,tEnv)!@#&                 local test,probblem = pcall(fProg,...)!@#&                      if not test then!@#&                            print(probblem)!@#&                             dialogBox(\"ERROR\",tostring(probblem),{\"ok\"},3,30)!@#&                       else!@#&                                return true!@#&                 end!@#&         else!@#&                        print(probblem)!@#&                     dialogBox(\"ERROR\",tostring(probblem),{\"ok\"},3,30)!@#&               end!@#& end!@#&end!@#&!@#&local function rClickMenu(title,tList,tItem,posX,posY)!@#&!@#&        term.setCursorBlink(false)!@#&  local BoxTitle = title!@#&      local choices = {}!@#&  local termX,termY = term.getSize()!@#&  local offX,offY!@#&     !@#&    local width = #BoxTitle + 2!@#& local hight!@#& !@#&    for k,v in pairs(tList) do!@#&          if v ~= nil then!@#&                    table.insert(choices,k)!@#&             end!@#&         if width < #k + 2 then!@#&                      width = #k + 2!@#&              end!@#& end!@#& !@#&    if #choices == 0 then!@#&               return!@#&      end!@#& !@#&    hight = #choices + 1!@#&        table.sort(choices)!@#& !@#&    offX,offY = math.ceil((termX/2) - (width/2)),math.ceil((termY/2) - (hight/2))!@#&       !@#&    if posX and posY then -- offX,offY = posX,posY!@#&              if posX >= termX - width - 1 then!@#&                   offX = termX - width - 1!@#&            else!@#&                        offX = posX!@#&         end!@#&         if posY >= termY - hight then!@#&                       offY = termY - hight!@#&                else!@#&                        offY = posY!@#&         end!@#& end!@#& !@#&    local function reDrawer()!@#&           printC(offX,offY,rcmTitle.txt,rcmTitle.back,\" \"..BoxTitle..string.rep(\" \",width - #BoxTitle - 1))!@#&               for i = 1,#choices do!@#&                       printC(offX,offY + i,rcmList.txt,rcmList.back,\" \"..choices[i]..string.rep(\" \",width - #choices[i] - 1))!@#&         end!@#& end!@#& !@#&    while true do!@#&               reDrawer()!@#&          local event = {os.pullEvent()}!@#&              if event[1] == \"mouse_click\" then!@#&                 if event[2] == 1 then -- event[3] = x event[4] = y!@#&                          if event[4] > offY and event[4] < hight + offY and event[3] >= offX and event[3] < width + offX then!@#&                                        --dialogBox(\"ERROR:\",type(tList[choices[event[4] - offY]]),{\"ok\"})!@#&                                      if type(tList[choices[event[4] - offY]]) == \"function\" then!@#&                                               return tList[choices[event[4] - offY]](tItem)!@#&                                       elseif type(tList[choices[event[4] - offY]]) == \"table\" then!@#&                                              return rClickMenu(\"Options\",tList[choices[event[4] - offY]],tItem,event[3],event[4])!@#&                                      elseif type(tList[choices[event[4] - offY]]) == \"string\" then!@#&                                             return osRunSpaces(!@#&                                                         unpack(!@#&                                                                     fixArgs(!@#&                                                                            tList[choices[event[4] - offY]]..\" \\\"\"..stringPath()..fSlash..tItem.n..\"\\\"\"!@#&                                                                 )!@#&                                                           )!@#&                                                   )!@#&                                   else!@#&                                                dialogBox(\"ERROR:\",\"somthing up with new rMenu\",{\"ok\"})!@#&                                       end!@#&                         else!@#&                                        return!@#&                              end!@#&                 elseif event[2] == 2 then!@#&                           return!@#&                      end!@#&         end!@#& end!@#& !@#&end!@#&!@#&local function preferences()!@#& local tItem = {!@#&             {txt = \"Title Bar\",it = titleBar},!@#&                {txt = \"Address Bar\",it = addressBar},!@#&            {txt = \"Item Windo\", it = itemWindo},!@#&             {txt = \"Title Right Click Title\",it = rcmTitle},!@#&          {txt = \"Right Click Menu\",it = rcmList},!@#&          {txt = \"Title Dialog Box\",it = dialogTitle},!@#&              {txt = \"Dialog Box\",it = dialogWindo},!@#&            {txt = \"Scroll Bar\",it = scrollCol}!@#&       }!@#&   local topL,topR = 13,5!@#&      local width,hight = 23,6!@#&    local bottomL,bottomR = topL + width,topR + hight!@#&   !@#&    local listOffset = 0!@#&        local sel = 1!@#&       local otherSel = 1!@#&  local otherItems = {}!@#&       !@#&    if tItem[sel] then!@#&          for k,v in pairs(tItem[sel].it) do!@#&                  table.insert(otherItems,{txt = k,it = v})!@#&           end!@#& end!@#& !@#&    local function draw()!@#&               printC(topL,topR,titleBar.txt,titleBar.back,string.sub(\" Preferences \"..string.rep(\" \",width),1,width))!@#&         for i = 0,12,4 do!@#&                   for a = 1,4 do!@#&                              --printC(topL + (a*12)-12 ,topR + ((i+4)/4),4,2^(a+i-1),\" \"..tostring(2^(a+i-1)))!@#&                         printC(topL + a-1 ,topR + ((i+4)/4),4,2^(a+i-1),\" \")!@#&                      end!@#&         end!@#&         local sSel = \" \"!@#&          for i = 1,hight - 2 do!@#&                      if i == sel - listOffset then!@#&                               sSel = \">\"!@#&                        end!@#&                 if tItem[i+listOffset] then!@#&                         printC(topL + 4 ,topR + i,colors.black,colors.white,string.sub(sSel..tItem[i+listOffset].txt..string.rep(\" \",width),1,width - 4))!@#&                 else!@#&                                printC(topL + 4 ,topR + i,colors.black,colors.white,sSel..string.rep(\" \",width-5))!@#&                        end!@#&                 if i == sel - listOffset then!@#&                               sSel = \" \"!@#&                        end!@#&         end!@#&         term.setCursorPos(topL,topR + hight - 1)!@#&            local loop = 1!@#&              local length = 0!@#&                    for i = 1,#otherItems do!@#&                            if otherSel == i then!@#&                                       sSel = \">\"!@#&                                end!@#&                         if colors.black == otherItems[i].it or colors.gray == otherItems[i].it then!@#&                                 term.setTextColor(colors.white)!@#&                             else!@#&                                        term.setTextColor(colors.black)!@#&                             end!@#&                         term.setBackgroundColor(otherItems[i].it)!@#&                           term.write(sSel..tostring(otherItems[i].txt)..\" \")!@#&                                length = length + #otherItems[i].txt + 2!@#&                            if otherSel == i then!@#&                                       sSel = \" \"!@#&                                end!@#&                         loop = loop+1!@#&                       end!@#&         term.setBackgroundColor(colors.white)!@#&               term.write(string.rep(\" \",width - length))!@#&        end!@#& while true do!@#&               draw()!@#&              local event = {os.pullEvent()}!@#&              if event[1] == \"mouse_click\" and event[2] == 1 then!@#&                       if inBouwndry(event[3],event[4],topL,topR,width,hight) then!@#&                         local inSideX,inSideY = event[3] - topL,event[4] - topR!@#&                             if inBouwndry(inSideX+1,inSideY,1,1,4,4) and tItem[sel] then!@#&                                        --[[!@#&                                        term.setCursorPos(1,1)!@#&                                      term.setBackgroundColor(2^(inSideX + ((inSideY*4)-4)))!@#&                                      print(2^(inSideX + ((inSideY*4)-4)),\" \",inSideX + ((inSideY*4)-4),\"     \")!@#&                                      ]]--!@#&                                        tItem[sel][\"it\"][otherItems[otherSel].txt] = (2^(inSideX + ((inSideY*4)-4)))!@#&                              end!@#&                 end!@#&         elseif event[1] == \"key\" then!@#&                     if event[2] == 200 then!@#&                             sel = sel - 1!@#&                       elseif event[2] == 208 then!@#&                         sel = sel + 1!@#&                       elseif event[2] == 203 then!@#&                         otherSel = otherSel - 1!@#&                     elseif event[2] == 205 then!@#&                         otherSel = otherSel + 1!@#&                     elseif event[2] == 28 then!@#&                          if dialogBox(\"Confirm\",\"Save prefrences?\",{\"Yes\",\"No\"}) == 1 then!@#&                                   saveCFG(true)!@#&                               end!@#&                         return!@#&                      end!@#&         end!@#&         if sel < 1 then!@#&                     sel = 1!@#&             elseif sel > #tItem then!@#&                    sel = #tItem!@#&                end!@#&         if sel > listOffset + hight - 2 then!@#&                        listOffset = listOffset + 1!@#&         elseif sel - listOffset < 1 then!@#&                    listOffset = listOffset - 1!@#&         end!@#&         !@#&            otherItems = {}!@#&             if tItem[sel] then!@#&                  for k,v in pairs(tItem[sel].it) do!@#&                          table.insert(otherItems,{txt = k,it = v})!@#&                   end!@#&         end!@#&         !@#&            if otherSel < 1 then!@#&                        otherSel = 1!@#&                elseif otherSel > #otherItems then!@#&                  otherSel = #otherItems!@#&              end!@#&         !@#&            if bugTest then!@#&                     term.setBackgroundColor(colors.black)!@#&                       term.setTextColor(colors.white)!@#&                     term.setCursorPos(1,1)!@#&                      term.clearLine()!@#&                    term.write(\"sel \"..sel..\" offset \"..listOffset)!@#&         end!@#& end!@#&end!@#&!@#&local function fileSelect(mode) -- save_file open_file browse < not yet implemented!@#&       !@#&    local title = sTitle..\" \"..ver!@#&    local bRun = true!@#&   local clipboard = nil!@#&       local cut = false!@#&   !@#&    local termX,termY = term.getSize()!@#&  local offsetX,offsetY = 1,1!@#& local hight,width = math.ceil(termY-2),math.ceil(termX-2)!@#&   local oldHight,oldWidth!@#&     !@#&    -- offsets!@#&  local boxOffX,boxOffY = offsetX,offsetY + 2!@#& local boxH,boxW = hight - 2 ,width - 2!@#&      !@#&    local barX,barY = offsetX + 1,offsetY + 2!@#&   local barH,barW = 1,width - 1!@#&       !@#&    local tbarX,tbarY = offsetX + 1,offsetY + 1!@#& local tbarH,tbarW = 1,width - 1!@#&     !@#&    local exitX,exitY = offsetX + width - 1 ,offsetY + 1!@#&        !@#&    local pading = string.rep(\" \",boxW)!@#&       local list!@#&  !@#&    local listOff = 0!@#&   !@#&    local sPath!@#& local tItemList = {}!@#&        !@#&    local function newList()!@#&            listOff = 0!@#&         flag = true!@#&         tItemList = {{n = \"..\", id = \"back\"}} -- adds a back item at top of list!@#&                sPath = stringPath()!@#&                local folders = {}!@#&          local files = {}!@#&            local disks = {}!@#&            if not fs.exists(sPath) then!@#&                        path = {}!@#&                   sPath = stringPath()!@#&                        dialogBox(\"ERROR:\",\"Path no longer exists\",{\"ok\"})!@#&            end!@#&         local test,list = pcall(fs.list,sPath) -- stopes fs.list crash!@#&              if list == nil then!@#&                 list = {}!@#&                   dialogBox(\"ERROR : \",\"fs.list crashed\",{\"ok\"})!@#&                end!@#&         if #path == 0 then!@#&                  for i,v in pairs(rs.getSides()) do!@#&                          if disk.isPresent(v) then!@#&                                   if disk.hasData(v) then!@#&                                             table.insert(tItemList,{n = disk.getMountPath(v), id = \"disk\",s = v})!@#&                                             disks[disk.getMountPath(v)] = true!@#&                                  elseif disk.hasAudio(v) then!@#&                                                table.insert(tItemList,{n = disk.getAudioTitle(v), id = \"audio\",s = v})!@#&                                   end!@#&                         end!@#&                 end!@#&         end!@#&         for i,v in pairs(list) do!@#&                   if fs.isDir(sPath..fSlash..v) then!@#&                          table.insert(folders,v)!@#&                     else!@#&                                table.insert(files,v)!@#&                       end!@#&         end!@#&         table.sort(folders)!@#&         table.sort(files)!@#&           for i,v in pairs(folders) do!@#&                        if disks[v] == nil then!@#&                             table.insert(tItemList,{n = v, id = \"folder\"})!@#&                    end!@#&         end!@#&         for i,v in pairs(files) do!@#&                  table.insert(tItemList,{n = v, id = \"file\"})!@#&              end!@#& end!@#& !@#&    local function paste()!@#&              if cut then!@#&                 local s, m = pcall(!@#&                         function()!@#&                                  fs.move(clipboard[1]..fSlash..clipboard[2], stringPath()..fSlash..clipboard[2])!@#&                                     cut = false!@#&                                 clipboard = nil!@#&                             end)!@#&                        if not s then!@#&                               dialogBox(\"Error\", (m or \"Couldn't move\"), {\"ok\"}, 4, 30)!@#&                     end!@#&                 if bugTest then!@#&                             local x, y = term.getCursorPos()!@#&                            term.setCursorPos(1, ({term.getSize()})[2])!@#&                         write(\"from \"..clipboard[1]..fSlash..clipboard[2]..\" to \"..stringPath()..fSlash..clipboard[2])!@#&                  end!@#&         else!@#&                        local s, m = pcall(function()!@#&                               if fs.exists(stringPath()..fSlash..clipboard[2]) then!@#&                                       fs.copy(clipboard[1]..fSlash..clipboard[2], stringPath()..fSlash..\"copy-\"..clipboard[2])!@#&                          else!@#&                                        fs.copy(clipboard[1]..fSlash..clipboard[2], stringPath()..fSlash..clipboard[2])!@#&                             end!@#&                 end)!@#&                        if not s then!@#&                               dialogBox(\"Error\", (m or \"Couldn't copy\"), {\"ok\"}, 4, 30)!@#&                     end!@#&                 if bugTest then!@#&                             local x, y = term.getCursorPos()!@#&                            term.setCursorPos(1, ({term.getSize()})[2])!@#&                         write(\"from \"..clipboard[1]..fSlash..clipboard[2]..\" to \"..stringPath()..fSlash..clipboard[2])!@#&                  end!@#&         end!@#&         newList()!@#&   end!@#& !@#&    -- this section bellow handles the right click menu!@#& !@#&    local tmenu = {!@#&             disk = {!@#&                    [\"Open\"] = function(tItem)!@#&                                table.insert(path,tItem.n)!@#&                          newList()!@#&                   end,!@#&                        [\"Copy\"] = function(tItem)!@#&                                clipboard = {stringPath(), tItem.n}!@#&                         cut = false!@#&                 end,!@#&                        [\"Eject\"] = function(tItem)!@#&                               if dialogBox(\"Confirm\",\"Eject \"..fSlash..tItem.n..\" \"..tItem.s,{\"yes\",\"no\"}) == 1 then!@#&                                    disk.eject(tItem.s)!@#&                                 newList()!@#&                           end!@#&                 end,!@#&                        [\"ID label\"] = function(tItem)!@#&                            dialogBox(\"ID label\",disk.getDiskID(tItem.s)..\" \"..tostring(disk.getLabel(tItem.s)),{\"ok\"})!@#&                   end,!@#&                        [\"Set label\"] = function(tItem)!@#&                           local name = InputBox(\"Label?\")!@#&                           if name then!@#&                                        disk.setLabel(tItem.s,name)!@#&                         end!@#&                 end,!@#&                        [\"Clear label\"] = function(tItem)!@#&                         if dialogBox(\"Confirm\",\"Cleal Label from \"..tItem.s,{\"yes\",\"no\"}) == 1 then!@#&                                 disk.setLabel(tItem.s)!@#&                              end!@#&                 end!@#&         },!@#&          folder = {!@#&                  [\"Open\"] = function(temp)!@#&                         table.insert(path,temp.n)!@#&                           newList()!@#&                   end,!@#&                        [\"Copy\"] = function(tItem)!@#&                                clipboard = {stringPath(), tItem.n}!@#&                         cut = false!@#&                 end,!@#&                        [\"Cut\"] = function(tItem)!@#&                         clipboard = {stringPath(), tItem.n}!@#&                         cut = true!@#&                  end,!@#&                        [\"Delete\"] = function(tItem)!@#&                              if dialogBox(\"Confirm\",\"Delete \"..tItem.id..\" \"..tItem.n,{\"yes\",\"no\"}) == 1 then!@#&                                  if fs.isReadOnly(stringPath()..fSlash..tItem.n) then!@#&                                                dialogBox(\"ERROR\",tItem.id..\" Is read Only\",{\"ok\"})!@#&                                   else!@#&                                                fs.delete(stringPath()..fSlash..tItem.n)!@#&                                            newList()!@#&                                   end!@#&                         end!@#&                 end,!@#&                        [\"Rename\"] = function(tItem)!@#&                              local sName = InputBox(\"New Name\")!@#&                                if type(sName) == \"string\" and sName ~= \"\" then!@#&                                 local s, m = pcall(function()!@#&                                               fs.move(stringPath()..fSlash..tItem.n,stringPath()..fSlash..sName)!@#&                                  end)!@#&                                        if not s then!@#&                                               dialogBox(\"Error\", (m or \"Rename failed\"), {\"ok\"})!@#&                                    end!@#&                         end!@#&                         newList()!@#&                   end!@#&         },!@#&          file = {!@#&                    [\"Run\"] = {!@#&                               [\"Run\"] = function(tItem)!@#&                                 osRunSpaces(stringPath()..fSlash..tItem.n)!@#&                          end,!@#&                                [\"Run CMD\"] = function(tItem)!@#&                                     local cmd = InputBox(\"Commands\")!@#&                                  if cmd then!@#&                                         osRunSpaces(stringPath()..fSlash..tItem.n,unpack(fixArgs(cmd)))!@#&                                     end!@#&                         end,!@#&                        },!@#&                  [\"Open With\"] = customLaunch,!@#&                     [\"Rename\"] = function(tItem)!@#&                              local sName = InputBox(\"New Name\")!@#&                                if type(sName) == \"string\" and sName ~= \"\" then!@#&                                 local s, m = pcall(function()!@#&                                               fs.move(stringPath()..fSlash..tItem.n,stringPath()..fSlash..sName)!@#&                                  end)!@#&                                        if not s then!@#&                                               dialogBox(\"Error\", (m or \"Rename failed\"), {\"ok\"})!@#&                                    end!@#&                         end!@#&                         newList()!@#&                   end,!@#&                        [\"Delete\"] = function(tItem)!@#&                              if dialogBox(\"Confirm\",\"Delete \"..tItem.id..\" \"..tItem.n,{\"yes\",\"no\"}) == 1 then!@#&                                  if fs.isReadOnly(stringPath()..fSlash..tItem.n) then!@#&                                                dialogBox(\"ERROR\",tItem.id..\" Is read Only\",{\"ok\"})!@#&                                   else!@#&                                                fs.delete(stringPath()..fSlash..tItem.n)!@#&                                            newList()!@#&                                   end!@#&                         end!@#&                 end,!@#&                        [\"Cut\"] = function(tItem)!@#&                         clipboard = {stringPath(), tItem.n}!@#&                         cut = true!@#&                  end,!@#&                        [\"Copy\"] = function(tItem)!@#&                                clipboard = {stringPath(), tItem.n}!@#&                         cut = false!@#&                 end!@#&         },!@#&          audio = {!@#&                   [\"Play\"] = 1,!@#&                     [\"Eject\"] = 1!@#&             },!@#&          back = {!@#&            },!@#&          blank = { -- tmenu.blank.Paste = !@#&                   [\"Paste\"] = nil,!@#&                  [\"New File\"] = function()!@#&                         local name = InputBox()!@#&                             if name then!@#&                                        if fs.exists(stringPath()..fSlash..name) then!@#&                                               dialogBox(\"ERROR\",\"Name exists\",{\"ok\"})!@#&                                       else!@#&                                                local file = fs.open(stringPath()..fSlash..name,\"w\")!@#&                                              if file then!@#&                                                        file.write(\"\")!@#&                                                    file.close()!@#&                                                        newList()!@#&                                           else!@#&                                                        dialogBox(\"ERROR\",\"File not created\",{\"ok\"})!@#&                                          end!@#&                                 end!@#&                         end!@#&                 end,!@#&                        [\"New Folder\"] = function()!@#&                               local name = InputBox()!@#&                             if name then!@#&                                        if fs.exists(stringPath()..fSlash..name) then!@#&                                               dialogBox(\"ERROR\",\"Name exists\",{\"ok\"})!@#&                                       else!@#&                                                if pcall(fs.makeDir,stringPath()..fSlash..name) then!@#&                                                        newList()!@#&                                           else!@#&                                                        dialogBox(\"ERROR\",\"Access Denied\",{\"ok\"})!@#&                                             end!@#&                                 end!@#&                         end!@#&                 end,!@#&                        [\"Preferences\"] = preferences!@#&             },!@#&  }!@#&   !@#&    -- end right click menu!@#&     !@#&    local function scrollBar(posX,posY)!@#&         if posX == boxOffX+boxW+1 and posY > boxOffY and posY <= boxOffY+boxH then!@#&                  if #tItemList > boxH then!@#&                           if posY == boxOffY + 1 then!@#&                                 listOff = 0!@#&                         elseif posY == boxOffY+boxH then!@#&                                    listOff = #tItemList + 1 - boxH!@#&                             else!@#&                                        listOff = math.ceil((posY - boxOffY - 1 )*(((#tItemList - boxH+2)/boxH)))!@#&                           end!@#&                         flag = true!@#&                 end!@#&         end!@#& end!@#& !@#&    newList()!@#&   !@#&    while bRun do!@#&               if flag then!@#&                        flag = false!@#&                        -- clear!@#&                    if oldHight ~= hight and oldWidth ~= width then!@#&                             term.setBackgroundColor(colors.black)!@#&                               term.clear()!@#&                                oldHight,oldWidth = hight,width!@#&                     end!@#&                 -- draw top title bar!@#&                       local b = tbarW - #title -2!@#&                 if b < 0 then!@#&                               b = 0!@#&                       end!@#&                 printC(tbarX,tbarY,titleBar.txt,titleBar.back,string.sub(\" \"..title,1,tbarW)..string.rep(\" \",b))!@#&                        term.setTextColor(colors.white)!@#&                     term.setBackgroundColor(colors.red)!@#&                 term.write(\"X\")!@#&                   !@#&                    -- draw location bar!@#&                        local a = barW - #sPath - 1!@#&                 if a < 0 then!@#&                               a = 0!@#&                       end!@#&                 local tmppath = sPath!@#&                       if shell and shell.getDisplayName then!@#&                              tmppath = shell.getDisplayName(sPath)!@#&                               --dialogBox(\"yay\")!@#&                        else!@#&                                --dialogBox(\"moop\")!@#&                       end!@#&                 tmppath = tmppath or sPath!@#&                  local a = barW - #tmppath - 1!@#&                       if a < 0 then!@#&                               a = 0!@#&                       end!@#&                 printC(barX,barY,addressBar.txt,addressBar.back,string.sub(\" \"..tmppath,1,barW)..string.rep(\" \",a))!@#&                     !@#&                    -- draw scroll bar!@#&                  if #tItemList > boxH then!@#&                           term.setBackgroundColor(scrollCol.back)!@#&                             for i = 1,boxH do!@#&                                   term.setCursorPos(boxOffX+boxW+1,i + boxOffY)!@#&                                       local scroll = math.floor( boxH* (listOff/(#tItemList-boxH+2)) )+1!@#&                                  if i == scroll then!@#&                                         term.setBackgroundColor(scrollCol.button)!@#&                                           term.write(\" \")!@#&                                           term.setBackgroundColor(scrollCol.back)!@#&                                     else!@#&                                                term.write(\" \")!@#&                                   end!@#&                         end!@#&                 else!@#&                                term.setBackgroundColor(scrollCol.off)!@#&                              for i = 1,boxH do!@#&                                   term.setCursorPos(boxOffX+boxW+1,i + boxOffY)!@#&                                       term.write(\" \")!@#&                           end!@#&                 end!@#&                 !@#&                    -- draw main section!@#&!@#&                    for i = 1,boxH do -- listOff!@#&                                local sel = i+listOff!@#&                               if tItemList[sel] then!@#&                                      printC(1+boxOffX,i+boxOffY,(tIcons[tItemList[sel].id].tCol or itemWindo.txt),(tIcons[tItemList[sel].id].bCol or itemWindo.back),( tIcons[tItemList[sel].id].txt or \"   \"))!@#&                                        printC(4+boxOffX,i+boxOffY,itemWindo.txt,itemWindo.back,string.sub(\" \"..tItemList[sel].n..pading,1,boxW-3))!@#&                               else!@#&                                        printC(1+boxOffX,i+boxOffY,itemWindo.txt,itemWindo.back,pading)!@#&                             end!@#&                 end!@#&                 !@#&                    if bugTest then!@#&                             printC(1,1,\"black\",\"white\",listOff..\" \"..boxOffY..\" \"..boxH)!@#&                        end!@#&                 !@#&            end!@#&         !@#&            -- react to events!@#&          local event = {os.pullEvent()}!@#&              !@#&            if event[1] == \"mouse_click\" then!@#&                 if inBouwndry(event[3],event[4],boxOffX+1,boxOffY+1,boxW,boxH) then!@#&                         local selected = tItemList[event[4]+listOff-boxOffY]!@#&                                if selected and inBouwndry(event[3],event[4],boxOffX+1,event[4],#selected.n + 4,1) then!@#&                                     if event[2] == 1 then -- left mouse!@#&                                         if selected.id == \"back\" then!@#&                                                     table.remove(path,#path)!@#&                                                    newList()!@#&                                           elseif selected.id == \"folder\" or selected.id == \"disk\" then!@#&                                                    table.insert(path,selected.n)!@#&                                                       newList()!@#&                                           elseif selected.id == \"file\" then!@#&                                                 if dialogBox(\"Run file ?\",selected.n,{\"yes\",\"no\"}) == 1 then!@#&                                                          osRunSpaces(stringPath()..fSlash..selected.n)!@#&                                                       end!@#&                                         flag = true!@#&                                         end!@#&                                 elseif event[2] == 2 then -- right mouse!@#&                                            rClickMenu(\"Options\",tmenu[selected.id],selected,event[3],event[4])!@#&                                               flag = true!@#&                                 end!@#&                         elseif event[2] == 2 then -- right clicking not on object!@#&                                   if clipboard then!@#&                                           tmenu.blank.Paste = paste!@#&                                   else!@#&                                                tmenu.blank.Paste = nil!@#&                                     end!@#&                                 rClickMenu(\"Options\",tmenu[\"blank\"],selected,event[3],event[4])!@#&                                 flag = true!@#&                         end!@#&                 elseif event[2] == 1 and event[3] == exitX and event[4] == exitY then!@#&                               if dialogBox(\"Confirm\",\"Exit application\",{\"yes\",\"no\"}) == 1 then!@#&                                   bRun = false!@#&                                end!@#&                         flag = true!@#&                 elseif event[2] == 1 then!@#&                           scrollBar(event[3],event[4])!@#&                        end!@#&         elseif event[1] == \"mouse_scroll\" then -- flag this needs new math!@#&                        local old = listOff!@#&                 listOff = listOff + event[2]!@#&                        if listOff < 0 then!@#&                         listOff = 0!@#&                 end!@#&                 if #tItemList + 1 - boxH > 0 and listOff > #tItemList + 1 - boxH then!@#&                               listOff = #tItemList + 1 - boxH!@#&                     elseif listOff > 0 and #tItemList + 1 - boxH < 0 then!@#&                               listOff = 0!@#&                 end!@#&                 if listOff ~= old then!@#&                              flag = true!@#&                 end!@#&         !@#&            elseif event[1] == \"mouse_drag\" then -- scroll bar!@#&                        scrollBar(event[3],event[4])!@#&                elseif event[1] == \"disk\" or event[1] == \"disk_eject\" then!@#&                      newList()!@#&           elseif event[1] == \"window_resize\" then!@#&                   termX,termY = term.getSize()!@#&                        offsetX,offsetY = 1,1!@#&                       hight,width = math.ceil(termY-2),math.ceil(termX-2)!@#&                 !@#&                    boxOffX,boxOffY = offsetX,offsetY + 2!@#&                       boxH,boxW = hight - 2 ,width - 2!@#&                    !@#&                    barX,barY = offsetX + 1,offsetY + 2!@#&                 barH,barW = 1,width - 1!@#&                     !@#&                    tbarX,tbarY = offsetX + 1,offsetY + 1!@#&                       tbarH,tbarW = 1,width - 1!@#&                   !@#&                    exitX,exitY = offsetX + width - 1 ,offsetY + 1!@#&                      pading = string.rep(\" \",boxW)!@#&                     !@#&                    flag = true!@#&         elseif event[1] == \"redraw\" then!@#&                  flag = true!@#&         end!@#& end!@#&end!@#&!@#&local function main()!@#&     if term.isColor() then!@#&              clear()!@#&             fileSelect()!@#&                clear()!@#&     else!@#&                error(\"Not an Advanced Computer (gold) \")!@#& end!@#&end!@#&!@#&local trash = (norun or main())",["opts"]="",["lmail"]="sel = sysconf.theme_sel!@#&desel = sysconf.theme_desel!@#&background = sysconf.theme_background",["boot"]={["loadapis"]="list = fs.list(\"/lib/libapi/\")!@#&for i = 1,#list do!@#&   api = os.loadAPI(\"/lib/libapi/\" .. list[i])!@#&end",},["optlib"]={["usrs"]="local function createNew(un)!@#& term.setBackgroundColor(colors.black)!@#& term.setTextColor(colors.white)!@#& term.clear()!@#& term.setCursorPos(1,1)!@#& write(\"Password? \")!@#& np = read(\"*\")!@#& usrs[un] = hash.sha256(np)!@#& nf = textutils.serialize(usrs)!@#& sv = fs.open(\"/lib/usr/users\", \"w\")!@#& sv.writeLine(nf)!@#& sv.close()!@#& print(\"OK!\")!@#& sleep(2)!@#& os.reboot()!@#&end!@#&!@#&local function modify(un)!@#& term.setBackgroundColor(colors.black)!@#& term.setTextColor(colors.white)!@#& term.clear()!@#& term.setCursorPos(1,1)!@#& write(\"New password? \")!@#& np = read(\"*\")!@#& usrs[un] = hash.sha256(np)!@#& nf = textutils.serialize(usrs)!@#& sv = fs.open(\"/lib/usr/users\", \"w\")!@#& sv.writeLine(nf)!@#& sv.close()!@#& print(\"OK!\")!@#& sleep(2)!@#& os.reboot()!@#&end!@#&!@#&usrs = linox.getUserFile()!@#&term.setBackgroundColor(colors.black)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&term.setCursorPos(1,1)!@#&print(\"Please enter the name of a user (it doesn't need to exist) or type exit to exit.\")!@#&user = read()!@#&if user == \"exit\" then!@#& os.reboot()!@#&end!@#&if not usrs[user] then!@#& createNew(user)!@#&else!@#& modify(user)!@#&end",["opts"]="if not sudo.isAdmin() then!@#&   print(\"Privs not sufficient.\")!@#&   write(\"For more information go to \")!@#&   term.setTextColor(colors.yellow)!@#&   print(\"http://zudohackz.kd.io\")!@#&   term.setTextColor(colors.white)!@#&   error()!@#&end!@#&!@#&w,h = term.getSize()!@#&function printc(str,l)!@#&              term.setCursorPos(w/2-#str/2,l)!@#&             print(str)!@#&end!@#&!@#&term.setBackgroundColor(colors.lightGray)!@#&term.clear()!@#&term.setCursorPos(1,1)!@#&term.setBackgroundColor(colors.white)!@#&write(string.rep(\" \",w))!@#&term.setTextColor(colors.black)!@#&printc(\"System Settings\",1)!@#&quit = \"[Quit]\"!@#&term.setCursorPos(w-#quit,1)!@#&print(quit)!@#&term.setTextColor(colors.white)!@#&term.setCursorPos(3,8)!@#&term.setBackgroundColor(colors.red)!@#&print(\"         \")!@#&term.setCursorPos(3,9)!@#&print(\" PC Name \")!@#&term.setCursorPos(3,10)!@#&print(\"         \")!@#&term.setBackgroundColor(colors.lime)!@#&term.setCursorPos(20,8)!@#&print(\"         \")!@#&term.setCursorPos(20,9)!@#&print(\"  Users  \")!@#&term.setCursorPos(20,10)!@#&print(\"         \")!@#&function getClickPos()!@#&            _,b,xpos,ypos = os.pullEvent(\"mouse_click\")!@#&      if ypos == 8 or ypos == 9 or ypos == 10 then!@#&         if xpos == 3 or xpos == 4 or xpos == 5 or xpos == 6 or xpos == 7 or xpos == 8 or xpos == 9 or xpos == 10 or xpos == 11 or xpos == 12 then!@#&            return \"pcname\"!@#&         elseif xpos == 20 or xpos == 21 or xpos == 22 or xpos == 23 or xpos == 24 or xpos == 25 or xpos == 26 or xpos == 27 or xpos == 28 or xpos == 29 then!@#&            return \"users\"!@#&         end!@#&      elseif ypos == 1 then!@#&          if xpos == w-#quit or xpos == w-#quit+1 or xpos == w-#quit+2 or xpos == w-#quit+3 or xpos == w-#quit+4 or xpos == w-#quit+5 or w-#quit+6 then!@#&              os.reboot()!@#&          end!@#&      end!@#&end!@#&!@#&while true do!@#&    option = getClickPos()!@#&    if option == \"pcname\" then!@#&        term.setBackgroundColor(colors.black)!@#&        term.clear()!@#&        term.setCursorPos(1,1)!@#&        write(\"New Name: \")!@#&        os.setComputerLabel(read())!@#&        shell.run(\"opts\")!@#&    elseif option == \"users\" then!@#&        shell.run(\"/bin/optlib/usrs\")!@#&    end!@#&end",},["clearc"]="if term.isColor() then!@#&  term.setTextColor(colors.white)!@#&     term.setBackgroundColor(colors.black)!@#&end!@#&term.clear()!@#&term.setCursorPos(1,1)",["plist"]="",["gksu"]="args = {...}!@#&if not sudo.isAdmin() then!@#&term.setCursorPos(w/2-l/2,h/2-2)!@#&term.setBackgroundColor(colors.red)!@#&print(\"            \")!@#&term.setCursorPos(w/2-l/2,h/2-1)!@#&print(\" Password:  \")!@#&term.setCursorPos(w/2-l/2,h/2)!@#&print(\"            \")!@#&term.setCursorPos(w/2-l/2,h/2+1)!@#&print(\"            \")!@#&term.setCursorPos(w/2-l/2,h/2+2)!@#&print(\"            \")!@#&term.setCursorPos(w/2-l/2+2,h/2)!@#&pswd = read(\"*\")!@#&term.setBackgroundColor(colors.black)!@#&term.clear()!@#&term.setCursorPos(1,1)!@#&if pswd == \"\" then!@#&      term.clear()!@#&        term.setCursorPos(1,1)!@#&      error()!@#&end!@#&if sudo.getAdminPrivs(pswd) then!@#&  fail = false!@#&else!@#&        term.clear()!@#&        term.setCursorPos(1,1)!@#&      error()!@#&end!@#&end!@#&shell.run(\"sudo\", args[1])",["luaide"]="!@#&--  !@#&--  Lua IDE!@#&--  Made by GravityScore!@#&--  !@#&!@#&!@#&--  -------- Variables!@#&!@#&-- Version!@#&local version = \"1.0\"!@#&local args = {...}!@#&!@#&-- Editing!@#&local w, h = term.getSize()!@#&local tabWidth = 2!@#&!@#&local autosaveInterval = 20!@#&local allowEditorEvent = true!@#&local keyboardShortcutTimeout = 0.4!@#&!@#&-- Clipboard!@#&local clipboard = nil!@#&!@#&-- Theme!@#&local theme = {}!@#&!@#&-- Language!@#&local languages = {}!@#&local curLanguage = {}!@#&!@#&-- Events!@#&local event_distract = \"luaide_distractionEvent\"!@#&!@#&-- Locations!@#&local updateURL = \"https://raw.github.com/GravityScore/LuaIDE/master/luaide.lua\"!@#&local ideLocation = \"/\" .. shell.getRunningProgram()!@#&local themeLocation = \"/.LuaIDE-Theme\"!@#&!@#&local function isAdvanced() return term.isColor and term.isColor() end!@#&!@#&!@#&--  -------- Utilities!@#&!@#&local function modRead(properties)!@#&        local w, h = term.getSize()!@#& local defaults = {replaceChar = nil, history = nil, visibleLength = nil, textLength = nil, !@#&         liveUpdates = nil, exitOnKey = nil}!@#& if not properties then properties = {} end!@#&  for k, v in pairs(defaults) do if not properties[k] then properties[k] = v end end!@#&  if properties.replaceChar then properties.replaceChar = properties.replaceChar:sub(1, 1) end!@#&        if not properties.visibleLength then properties.visibleLength = w end!@#&!@#&   local sx, sy = term.getCursorPos()!@#&  local line = \"\"!@#&   local pos = 0!@#&       local historyPos = nil!@#&!@#&  local function redraw(repl)!@#&         local scroll = 0!@#&            if properties.visibleLength and sx + pos > properties.visibleLength + 1 then !@#&                       scroll = (sx + pos) - (properties.visibleLength + 1)!@#&                end!@#&!@#&             term.setCursorPos(sx, sy)!@#&           local a = repl or properties.replaceChar!@#&            if a then term.write(string.rep(a, line:len() - scroll))!@#&            else term.write(line:sub(scroll + 1, -1)) end!@#&               term.setCursorPos(sx + pos - scroll, sy)!@#&    end!@#&!@#&     local function sendLiveUpdates(event, ...)!@#&          if type(properties.liveUpdates) == \"function\" then!@#&                        local ox, oy = term.getCursorPos()!@#&                  local a, data = properties.liveUpdates(line, event, ...)!@#&                    if a == true and data == nil then!@#&                           term.setCursorBlink(false)!@#&                          return line!@#&                 elseif a == true and data ~= nil then!@#&                               term.setCursorBlink(false)!@#&                          return data!@#&                 end!@#&                 term.setCursorPos(ox, oy)!@#&           end!@#& end!@#&!@#&     term.setCursorBlink(true)!@#&   while true do!@#&               local e, but, x, y, p4, p5 = os.pullEvent()!@#&!@#&             if e == \"char\" then!@#&                       local s = false!@#&                     if properties.textLength and line:len() < properties.textLength then s = true!@#&                       elseif not properties.textLength then s = true end!@#&!@#&                      local canType = true!@#&                        if not properties.grantPrint and properties.refusePrint then!@#&                                local canTypeKeys = {}!@#&                              if type(properties.refusePrint) == \"table\" then!@#&                                   for _, v in pairs(properties.refusePrint) do!@#&                                                table.insert(canTypeKeys, tostring(v):sub(1, 1))!@#&                                    end!@#&                         elseif type(properties.refusePrint) == \"string\" then!@#&                                      for char in properties.refusePrint:gmatch(\".\") do!@#&                                         table.insert(canTypeKeys, char)!@#&                                     end!@#&                         end!@#&                         for _, v in pairs(canTypeKeys) do if but == v then canType = false end end!@#&                  elseif properties.grantPrint then!@#&                           canType = false!@#&                             local canTypeKeys = {}!@#&                              if type(properties.grantPrint) == \"table\" then!@#&                                    for _, v in pairs(properties.grantPrint) do!@#&                                         table.insert(canTypeKeys, tostring(v):sub(1, 1))!@#&                                    end!@#&                         elseif type(properties.grantPrint) == \"string\" then!@#&                                       for char in properties.grantPrint:gmatch(\".\") do!@#&                                          table.insert(canTypeKeys, char)!@#&                                     end!@#&                         end!@#&                         for _, v in pairs(canTypeKeys) do if but == v then canType = true end end!@#&                   end!@#&!@#&                     if s and canType then!@#&                               line = line:sub(1, pos) .. but .. line:sub(pos + 1, -1)!@#&                             pos = pos + 1!@#&                               redraw()!@#&                    end!@#&         elseif e == \"key\" then!@#&                    if but == keys.enter then break!@#&                     elseif but == keys.left then if pos > 0 then pos = pos - 1 redraw() end!@#&                     elseif but == keys.right then if pos < line:len() then pos = pos + 1 redraw() end!@#&                   elseif (but == keys.up or but == keys.down) and properties.history then!@#&                             redraw(\" \")!@#&                               if but == keys.up then!@#&                                      if historyPos == nil and #properties.history > 0 then !@#&                                              historyPos = #properties.history!@#&                                    elseif historyPos > 1 then !@#&                                         historyPos = historyPos - 1!@#&                                 end!@#&                         elseif but == keys.down then!@#&                                        if historyPos == #properties.history then historyPos = nil!@#&                                  elseif historyPos ~= nil then historyPos = historyPos + 1 end!@#&                               end!@#&!@#&                             if properties.history and historyPos then!@#&                                   line = properties.history[historyPos]!@#&                                       pos = line:len()!@#&                            else!@#&                                        line = \"\"!@#&                                 pos = 0!@#&                             end!@#&!@#&                             redraw()!@#&                            local a = sendLiveUpdates(\"history\")!@#&                              if a then return a end!@#&                      elseif but == keys.backspace and pos > 0 then!@#&                               redraw(\" \")!@#&                               line = line:sub(1, pos - 1) .. line:sub(pos + 1, -1)!@#&                                pos = pos - 1!@#&                               redraw()!@#&                            local a = sendLiveUpdates(\"delete\")!@#&                               if a then return a end!@#&                      elseif but == keys.home then!@#&                                pos = 0!@#&                             redraw()!@#&                    elseif but == keys.delete and pos < line:len() then!@#&                         redraw(\" \")!@#&                               line = line:sub(1, pos) .. line:sub(pos + 2, -1)!@#&                            redraw()!@#&                            local a = sendLiveUpdates(\"delete\")!@#&                               if a then return a end!@#&                      elseif but == keys[\"end\"] then!@#&                            pos = line:len()!@#&                            redraw()!@#&                    elseif properties.exitOnKey then !@#&                           if but == properties.exitOnKey or (properties.exitOnKey == \"control\" and !@#&                                         (but == 29 or but == 157)) then !@#&                                    term.setCursorBlink(false)!@#&                                  return nil!@#&                          end!@#&                 end!@#&         end!@#&         local a = sendLiveUpdates(e, but, x, y, p4, p5)!@#&             if a then return a end!@#&      end!@#&!@#&     term.setCursorBlink(false)!@#&  if line ~= nil then line = line:gsub(\"^%s*(.-)%s*$\", \"%1\") end!@#&  return line!@#&end!@#&!@#&!@#&--  -------- Themes!@#&!@#&local defaultTheme = {!@#&     background = \"gray\",!@#&      backgroundHighlight = \"lightGray\",!@#&        prompt = \"cyan\",!@#&  promptHighlight = \"lightBlue\",!@#&    err = \"red\",!@#&      errHighlight = \"pink\",!@#&!@#&        editorBackground = \"gray\",!@#&        editorLineHightlight = \"lightBlue\",!@#&       editorLineNumbers = \"gray\",!@#&       editorLineNumbersHighlight = \"lightGray\",!@#& editorError = \"pink\",!@#&     editorErrorHighlight = \"red\",!@#&!@#& textColor = \"white\",!@#&      conditional = \"yellow\",!@#&   constant = \"orange\",!@#&      [\"function\"] = \"magenta\",!@#&       string = \"red\",!@#&   comment = \"lime\"!@#&}!@#&!@#&local normalTheme = {!@#&        background = \"black\",!@#&     backgroundHighlight = \"black\",!@#&    prompt = \"black\",!@#& promptHighlight = \"black\",!@#&        err = \"black\",!@#&    errHighlight = \"black\",!@#&!@#&       editorBackground = \"black\",!@#&       editorLineHightlight = \"black\",!@#&   editorLineNumbers = \"black\",!@#&      editorLineNumbersHighlight = \"white\",!@#&     editorError = \"black\",!@#&    editorErrorHighlight = \"black\",!@#&!@#&       textColor = \"white\",!@#&      conditional = \"white\",!@#&    constant = \"white\",!@#&       [\"function\"] = \"white\",!@#& string = \"white\",!@#& comment = \"white\"!@#&}!@#&!@#&local availableThemes = {!@#&   {\"Water (Default)\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/default.txt\"},!@#&    {\"Fire\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/fire.txt\"},!@#&  {\"Sublime Text 2\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/st2.txt\"},!@#& {\"Midnight\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/midnight.txt\"},!@#&  {\"TheOriginalBIT\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/bit.txt\"},!@#& {\"Superaxander\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/superaxander.txt\"},!@#&  {\"Forest\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/forest.txt\"},!@#&      {\"Night\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/night.txt\"},!@#&        {\"Original\", \"https://raw.github.com/GravityScore/LuaIDE/master/themes/original.txt\"},!@#&}!@#&!@#&local function loadTheme(path)!@#&       local f = io.open(path)!@#&     local l = f:read(\"*l\")!@#&    local config = {}!@#&   while l ~= nil do!@#&           local k, v = string.match(l, \"^(%a+)=(%a+)\")!@#&              if k and v then config[k] = v end!@#&           l = f:read(\"*l\")!@#&  end!@#& f:close()!@#&   return config!@#&end!@#&!@#&-- Load Theme!@#&if isAdvanced() then theme = defaultTheme!@#&else theme = normalTheme end!@#&!@#&!@#&--  -------- Drawing!@#&!@#&local function centerPrint(text, ny)!@#&  if type(text) == \"table\" then for _, v in pairs(text) do centerPrint(v) end!@#&       else!@#&                local x, y = term.getCursorPos()!@#&            local w, h = term.getSize()!@#&         term.setCursorPos(w/2 - text:len()/2 + (#text % 2 == 0 and 1 or 0), ny or y)!@#&                print(text)!@#& end!@#&end!@#&!@#&local function title(t)!@#&   term.setTextColor(colors[theme.textColor])!@#&  term.setBackgroundColor(colors[theme.background])!@#&   term.clear()!@#&!@#&    term.setBackgroundColor(colors[theme.backgroundHighlight])!@#&  for i = 2, 4 do term.setCursorPos(1, i) term.clearLine() end!@#&        term.setCursorPos(3, 3)!@#&     term.write(t)!@#&end!@#&!@#&local function centerRead(wid, begt)!@#&    local function liveUpdate(line, e, but, x, y, p4, p5)!@#&               if isAdvanced() and e == \"mouse_click\" and x >= w/2 - wid/2 and x <= w/2 - wid/2 + 10 !@#&                            and y >= 13 and y <= 15 then!@#&                        return true, \"\"!@#&           end!@#& end!@#&!@#&     if not begt then begt = \"\" end!@#&    term.setTextColor(colors[theme.textColor])!@#&  term.setBackgroundColor(colors[theme.promptHighlight])!@#&      for i = 8, 10 do!@#&            term.setCursorPos(w/2 - wid/2, i)!@#&           term.write(string.rep(\" \", wid))!@#&  end!@#&!@#&     if isAdvanced() then!@#&                term.setBackgroundColor(colors[theme.errHighlight])!@#&         for i = 13, 15 do!@#&                   term.setCursorPos(w/2 - wid/2 + 1, i)!@#&                       term.write(string.rep(\" \", 10))!@#&           end!@#&         term.setCursorPos(w/2 - wid/2 + 2, 14)!@#&              term.write(\"> Cancel\")!@#&    end!@#&!@#&     term.setBackgroundColor(colors[theme.promptHighlight])!@#&      term.setCursorPos(w/2 - wid/2 + 1, 9)!@#&       term.write(\"> \" .. begt)!@#&  return modRead({visibleLength = w/2 + wid/2, liveUpdates = liveUpdate})!@#&end!@#&!@#&!@#&--  -------- Prompt!@#&!@#&local function prompt(list, dir, isGrid)!@#&       local function draw(sel)!@#&            for i, v in ipairs(list) do!@#&                 if i == sel then term.setBackgroundColor(v.highlight or colors[theme.promptHighlight])!@#&                      else term.setBackgroundColor(v.bg or colors[theme.prompt]) end!@#&                      term.setTextColor(v.tc or colors[theme.textColor])!@#&                  for i = -1, 1 do!@#&                            term.setCursorPos(v[2], v[3] + i)!@#&                           term.write(string.rep(\" \", v[1]:len() + 4))!@#&                       end!@#&!@#&                     term.setCursorPos(v[2], v[3])!@#&                       if i == sel then!@#&                            term.setBackgroundColor(v.highlight or colors[theme.promptHighlight])!@#&                               term.write(\" > \")!@#&                 else term.write(\" - \") end!@#&                        term.write(v[1] .. \" \")!@#&           end!@#& end!@#&!@#&     local key1 = dir == \"horizontal\" and 203 or 200!@#&   local key2 = dir == \"horizontal\" and 205 or 208!@#&   local sel = 1!@#&       draw(sel)!@#&!@#&       while true do!@#&               local e, but, x, y = os.pullEvent()!@#&         if e == \"key\" and but == 28 then!@#&                  return list[sel][1]!@#&         elseif e == \"key\" and but == key1 and sel > 1 then!@#&                        sel = sel - 1!@#&                       draw(sel)!@#&           elseif e == \"key\" and but == key2 and ((err == true and sel < #list - 1) or (sel < #list)) then!@#&                   sel = sel + 1!@#&                       draw(sel)!@#&           elseif isGrid and e == \"key\" and but == 203 and sel > 2 then!@#&                      sel = sel - 2!@#&                       draw(sel)!@#&           elseif isGrid and e == \"key\" and but == 205 and sel < 3 then!@#&                      sel = sel + 2!@#&                       draw(sel)!@#&           elseif e == \"mouse_click\" then!@#&                    for i, v in ipairs(list) do!@#&                         if x >= v[2] - 1 and x <= v[2] + v[1]:len() + 3 and y >= v[3] - 1 and y <= v[3] + 1 then!@#&                                    return list[i][1]!@#&                           end!@#&                 end!@#&         end!@#& end!@#&end!@#&!@#&local function scrollingPrompt(list)!@#&      local function draw(items, sel, loc)!@#&                for i, v in ipairs(items) do!@#&                        local bg = colors[theme.prompt]!@#&                     local bghigh = colors[theme.promptHighlight]!@#&                        if v:find(\"Back\") or v:find(\"Return\") then!@#&                              bg = colors[theme.err]!@#&                              bghigh = colors[theme.errHighlight]!@#&                 end!@#&!@#&                     if i == sel then term.setBackgroundColor(bghigh)!@#&                    else term.setBackgroundColor(bg) end!@#&                        term.setTextColor(colors[theme.textColor])!@#&                  for x = -1, 1 do!@#&                            term.setCursorPos(3, (i * 4) + x + 4)!@#&                               term.write(string.rep(\" \", w - 13))!@#&                       end!@#&!@#&                     term.setCursorPos(3, i * 4 + 4)!@#&                     if i == sel then!@#&                            term.setBackgroundColor(bghigh)!@#&                             term.write(\" > \")!@#&                 else term.write(\" - \") end!@#&                        term.write(v .. \" \")!@#&              end!@#& end!@#&!@#&     local function updateDisplayList(items, loc, len)!@#&           local ret = {}!@#&              for i = 1, len do!@#&                   local item = items[i + loc - 1]!@#&                     if item then table.insert(ret, item) end!@#&            end!@#&         return ret!@#&  end!@#&!@#&     -- Variables!@#&        local sel = 1!@#&       local loc = 1!@#&       local len = 3!@#&       local disList = updateDisplayList(list, loc, len)!@#&   draw(disList, sel, loc)!@#&!@#& -- Loop!@#&     while true do!@#&               local e, key, x, y = os.pullEvent()!@#&!@#&             if e == \"mouse_click\" then!@#&                        for i, v in ipairs(disList) do!@#&                              if x >= 3 and x <= w - 11 and y >= i * 4 + 3 and y <= i * 4 + 5 then return v end!@#&                   end!@#&         elseif e == \"key\" and key == 200 then!@#&                     if sel > 1 then!@#&                             sel = sel - 1!@#&                               draw(disList, sel, loc)!@#&                     elseif loc > 1 then!@#&                         loc = loc - 1!@#&                               disList = updateDisplayList(list, loc, len)!@#&                         draw(disList, sel, loc)!@#&                     end!@#&         elseif e == \"key\" and key == 208 then!@#&                     if sel < len then!@#&                           sel = sel + 1!@#&                               draw(disList, sel, loc)!@#&                     elseif loc + len - 1 < #list then!@#&                           loc = loc + 1!@#&                               disList = updateDisplayList(list, loc, len)!@#&                         draw(disList, sel, loc)!@#&                     end!@#&         elseif e == \"mouse_scroll\" then!@#&                   os.queueEvent(\"key\", key == -1 and 200 or 208)!@#&            elseif e == \"key\" and key == 28 then!@#&                      return disList[sel]!@#&         end!@#& end!@#&end!@#&!@#&function monitorKeyboardShortcuts()!@#&       local ta, tb = nil, nil!@#&     local allowChar = false!@#&     local shiftPressed = false!@#&  while true do!@#&               local event, char = os.pullEvent()!@#&          if event == \"key\" and (char == 42 or char == 52) then!@#&                     shiftPressed = true!@#&                 tb = os.startTimer(keyboardShortcutTimeout)!@#&         elseif event == \"key\" and (char == 29 or char == 157 or char == 219 or char == 220) then!@#&                  allowEditorEvent = false!@#&                    allowChar = true!@#&                    ta = os.startTimer(keyboardShortcutTimeout)!@#&         elseif event == \"key\" and allowChar then!@#&                  local name = nil!@#&                    for k, v in pairs(keys) do!@#&                          if v == char then!@#&                                   if shiftPressed then os.queueEvent(\"shortcut\", \"ctrl shift\", k:lower())!@#&                                 else os.queueEvent(\"shortcut\", \"ctrl\", k:lower()) end!@#&                                   sleep(0.005)!@#&                                        allowEditorEvent = true!@#&                             end!@#&                 end!@#&                 if shiftPressed then os.queueEvent(\"shortcut\", \"ctrl shift\", char)!@#&                      else os.queueEvent(\"shortcut\", \"ctrl\", char) end!@#&                elseif event == \"timer\" and char == ta then!@#&                       allowEditorEvent = true!@#&                     allowChar = false!@#&           elseif event == \"timer\" and char == tb then!@#&                       shiftPressed = false!@#&                end!@#& end!@#&end!@#&!@#&!@#&--  -------- Saving and Loading!@#&!@#&local function download(url, path)!@#&     for i = 1, 3 do!@#&             local response = http.get(url)!@#&              if response then!@#&                    local data = response.readAll()!@#&                     response.close()!@#&                    if path then!@#&                                local f = io.open(path, \"w\")!@#&                              f:write(data)!@#&                               f:close()!@#&                   end!@#&                 return true!@#&         end!@#& end!@#&!@#&     return false!@#&end!@#&!@#&local function saveFile(path, lines)!@#&     local dir = path:sub(1, path:len() - fs.getName(path):len())!@#&        if not fs.exists(dir) then fs.makeDir(dir) end!@#&      if not fs.isDir(path) and not fs.isReadOnly(path) then!@#&              local a = \"\"!@#&              for _, v in pairs(lines) do a = a .. v .. \"\\n\" end!@#&!@#&           local f = io.open(path, \"w\")!@#&              f:write(a)!@#&          f:close()!@#&           return true!@#& else return false end!@#&end!@#&!@#&local function loadFile(path)!@#&   if not fs.exists(path) then!@#&         local dir = path:sub(1, path:len() - fs.getName(path):len())!@#&                if not fs.exists(dir) then fs.makeDir(dir) end!@#&              local f = io.open(path, \"w\")!@#&              f:write(\"\")!@#&               f:close()!@#&   end!@#&!@#&     local l = {}!@#&        if fs.exists(path) and not fs.isDir(path) then!@#&              local f = io.open(path, \"r\")!@#&              if f then!@#&                   local a = f:read(\"*l\")!@#&                    while a do!@#&                          table.insert(l, a)!@#&                          a = f:read(\"*l\")!@#&                  end!@#&                 f:close()!@#&           end!@#& else return nil end!@#&!@#&     if #l < 1 then table.insert(l, \"\") end!@#&    return l!@#&end!@#&!@#&!@#&--  -------- Languages!@#&!@#&languages.lua = {}!@#&languages.brainfuck = {}!@#&languages.none = {}!@#&!@#&--  Lua!@#&!@#&languages.lua.helpTips = {!@#&     \"A function you tried to call doesn't exist.\",!@#&    \"You made a typo.\",!@#&       \"The index of an array is nil.\",!@#&  \"The wrong variable type was passed.\",!@#&    \"A function/variable doesn't exist.\",!@#&     \"You missed an 'end'.\",!@#&   \"You missed a 'then'.\",!@#&   \"You declared a variable incorrectly.\",!@#&   \"One of your variables is mysteriously nil.\"!@#&}!@#&!@#&languages.lua.defaultHelpTips = {!@#&        2, 5!@#&}!@#&!@#&languages.lua.errors = {!@#&   [\"Attempt to call nil.\"] = {1, 2},!@#&        [\"Attempt to index nil.\"] = {3, 2},!@#&       [\".+ expected, got .+\"] = {4, 2, 9},!@#&      [\"'end' expected\"] = {6, 2},!@#&      [\"'then' expected\"] = {7, 2},!@#&     [\"'=' expected\"] = {8, 2}!@#&}!@#&!@#&languages.lua.keywords = {!@#&  [\"and\"] = \"conditional\",!@#&        [\"break\"] = \"conditional\",!@#&      [\"do\"] = \"conditional\",!@#& [\"else\"] = \"conditional\",!@#&       [\"elseif\"] = \"conditional\",!@#&     [\"end\"] = \"conditional\",!@#&        [\"for\"] = \"conditional\",!@#&        [\"function\"] = \"conditional\",!@#&   [\"if\"] = \"conditional\",!@#& [\"in\"] = \"conditional\",!@#& [\"local\"] = \"conditional\",!@#&      [\"not\"] = \"conditional\",!@#&        [\"or\"] = \"conditional\",!@#& [\"repeat\"] = \"conditional\",!@#&     [\"return\"] = \"conditional\",!@#&     [\"then\"] = \"conditional\",!@#&       [\"until\"] = \"conditional\",!@#&      [\"while\"] = \"conditional\",!@#&!@#&  [\"true\"] = \"constant\",!@#&  [\"false\"] = \"constant\",!@#& [\"nil\"] = \"constant\",!@#&!@#&       [\"print\"] = \"function\",!@#& [\"write\"] = \"function\",!@#& [\"sleep\"] = \"function\",!@#& [\"pairs\"] = \"function\",!@#& [\"ipairs\"] = \"function\",!@#&        [\"loadstring\"] = \"function\",!@#&    [\"loadfile\"] = \"function\",!@#&      [\"dofile\"] = \"function\",!@#&        [\"rawset\"] = \"function\",!@#&        [\"rawget\"] = \"function\",!@#&        [\"setfenv\"] = \"function\",!@#&       [\"getfenv\"] = \"function\",!@#&}!@#&!@#&languages.lua.parseError = function(e)!@#&    local ret = {filename = \"unknown\", line = -1, display = \"Unknown!\", err = \"\"}!@#& if e and e ~= \"\" then!@#&             ret.err = e!@#&         if e:find(\":\") then!@#&                       ret.filename = e:sub(1, e:find(\":\") - 1):gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                   -- The \"\" is needed to circumvent a CC bug!@#&                        e = (e:sub(e:find(\":\") + 1) .. \"\"):gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                       if e:find(\":\") then!@#&                               ret.line = e:sub(1, e:find(\":\") - 1)!@#&                              e = e:sub(e:find(\":\") + 2):gsub(\"^%s*(.-)%s*$\", \"%1\") .. \"\"!@#&                 end!@#&         end!@#&         ret.display = e:sub(1, 1):upper() .. e:sub(2, -1) .. \".\"!@#&  end!@#&!@#&     return ret!@#&end!@#&!@#&languages.lua.getCompilerErrors = function(code)!@#&   code = \"local function ee65da6af1cb6f63fee9a081246f2fd92b36ef2(...)\\n\\n\" .. code .. \"\\n\\nend\"!@#&       local fn, err = loadstring(code)!@#&    if not err then!@#&             local _, e = pcall(fn)!@#&              if e then err = e end!@#&       end!@#&!@#&     if err then!@#&         local a = err:find(\"]\", 1, true)!@#&          if a then err = \"string\" .. err:sub(a + 1, -1) end!@#&                local ret = languages.lua.parseError(err)!@#&           if tonumber(ret.line) then ret.line = tonumber(ret.line) end!@#&                return ret!@#&  else return languages.lua.parseError(nil) end!@#&end!@#&!@#&languages.lua.run = function(path, ar)!@#&  local fn, err = loadfile(path)!@#&      setfenv(fn, getfenv())!@#&      if not err then!@#&             _, err = pcall(function() fn(unpack(ar)) end)!@#&       end!@#& return err!@#&end!@#&!@#&!@#&--  Brainfuck!@#&!@#&languages.brainfuck.helpTips = {!@#&  \"Well idk...\",!@#&    \"Isn't this the whole point of the language?\",!@#&    \"Ya know... Not being able to debug it?\",!@#& \"You made a typo.\"!@#&}!@#&!@#&languages.brainfuck.defaultHelpTips = {!@#&    1, 2, 3!@#&}!@#&!@#&languages.brainfuck.errors = {!@#&  [\"No matching '['\"] = {1, 2, 3, 4}!@#&}!@#&!@#&languages.brainfuck.keywords = {}!@#&!@#&languages.brainfuck.parseError = function(e)!@#&      local ret = {filename = \"unknown\", line = -1, display = \"Unknown!\", err = \"\"}!@#& if e and e ~= \"\" then!@#&             ret.err = e!@#&         ret.line = e:sub(1, e:find(\":\") - 1)!@#&              e = e:sub(e:find(\":\") + 2):gsub(\"^%s*(.-)%s*$\", \"%1\") .. \"\"!@#&         ret.display = e:sub(1, 1):upper() .. e:sub(2, -1) .. \".\"!@#&  end!@#&!@#&     return ret!@#&end!@#&!@#&languages.brainfuck.mapLoops = function(code)!@#&      -- Map loops!@#&        local loopLocations = {}!@#&    local loc = 1!@#&       local line = 1!@#&      for let in string.gmatch(code, \".\") do!@#&            if let == \"[\" then!@#&                        loopLocations[loc] = true!@#&           elseif let == \"]\" then!@#&                    local found = false!@#&                 for i = loc, 1, -1 do !@#&                              if loopLocations[i] == true then!@#&                                    loopLocations[i] = loc!@#&                                      found = true!@#&                                end!@#&                 end!@#&!@#&                     if not found then!@#&                           return line .. \": No matching '['\"!@#&                        end!@#&         end!@#&!@#&             if let == \"\\n\" then line = line + 1 end!@#&          loc = loc + 1!@#&       end!@#& return loopLocations!@#&end!@#&!@#&languages.brainfuck.getCompilerErrors = function(code)!@#&   local a = languages.brainfuck.mapLoops(code)!@#&        if type(a) == \"string\" then return languages.brainfuck.parseError(a)!@#&      else return languages.brainfuck.parseError(nil) end!@#&end!@#&!@#&languages.brainfuck.run = function(path)!@#&  -- Read from file!@#&   local f = io.open(path, \"r\")!@#&      local content = f:read(\"*a\")!@#&      f:close()!@#&!@#&       -- Define environment!@#&       local dataCells = {}!@#&        local dataPointer = 1!@#&       local instructionPointer = 1!@#&!@#&    -- Map loops!@#&        local loopLocations = languages.brainfuck.mapLoops(content)!@#& if type(loopLocations) == \"string\" then return loopLocations end!@#&!@#&      -- Execute code!@#&     while true do!@#&               local let = content:sub(instructionPointer, instructionPointer)!@#&!@#&         if let == \">\" then!@#&                        dataPointer = dataPointer + 1!@#&                       if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&               elseif let == \"<\" then!@#&                    if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&                       dataPointer = dataPointer - 1!@#&                       if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&               elseif let == \"+\" then!@#&                    if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&                       dataCells[tostring(dataPointer)] = dataCells[tostring(dataPointer)] + 1!@#&             elseif let == \"-\" then!@#&                    if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&                       dataCells[tostring(dataPointer)] = dataCells[tostring(dataPointer)] - 1!@#&             elseif let == \".\" then!@#&                    if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&                       if term.getCursorPos() >= w then print(\"\") end!@#&                    write(string.char(math.max(1, dataCells[tostring(dataPointer)])))!@#&           elseif let == \",\" then!@#&                    if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&                       term.setCursorBlink(true)!@#&                   local e, but = os.pullEvent(\"char\")!@#&                       term.setCursorBlink(false)!@#&                  dataCells[tostring(dataPointer)] = string.byte(but)!@#&                 if term.getCursorPos() >= w then print(\"\") end!@#&                    write(but)!@#&          elseif let == \"/\" then!@#&                    if not dataCells[tostring(dataPointer)] then dataCells[tostring(dataPointer)] = 0 end!@#&                       if term.getCursorPos() >= w then print(\"\") end!@#&                    write(dataCells[tostring(dataPointer)])!@#&             elseif let == \"[\" then!@#&                    if dataCells[tostring(dataPointer)] == 0 then!@#&                               for k, v in pairs(loopLocations) do!@#&                                 if k == instructionPointer then instructionPointer = v end!@#&                          end!@#&                 end!@#&         elseif let == \"]\" then!@#&                    for k, v in pairs(loopLocations) do!@#&                         if v == instructionPointer then instructionPointer = k - 1 end!@#&                      end!@#&         end!@#&!@#&             instructionPointer = instructionPointer + 1!@#&         if instructionPointer > content:len() then print(\"\") break end!@#&    end!@#&end!@#&!@#&--  None!@#&!@#&languages.none.helpTips = {}!@#&languages.none.defaultHelpTips = {}!@#&languages.none.errors = {}!@#&languages.none.keywords = {}!@#&!@#&languages.none.parseError = function(err)!@#&        return {filename = \"\", line = -1, display = \"\", err = \"\"}!@#&end!@#&!@#&languages.none.getCompilerErrors = function(code)!@#&     return languages.none.parseError(nil)!@#&end!@#&!@#&languages.none.run = function(path) end!@#&!@#&!@#&-- Load language!@#&curLanguage = languages.lua!@#&!@#&!@#&--  -------- Run GUI!@#&!@#&local function viewErrorHelp(e)!@#&       title(\"LuaIDE - Error Help\")!@#&!@#&  local tips = nil!@#&    for k, v in pairs(curLanguage.errors) do!@#&            if e.display:find(k) then tips = v break end!@#&        end!@#&!@#&     term.setBackgroundColor(colors[theme.err])!@#&  for i = 6, 8 do!@#&             term.setCursorPos(5, i)!@#&             term.write(string.rep(\" \", 35))!@#&   end!@#&!@#&     term.setBackgroundColor(colors[theme.prompt])!@#&       for i = 10, 18 do!@#&           term.setCursorPos(5, i)!@#&             term.write(string.rep(\" \", 46))!@#&   end!@#&!@#&     if tips then!@#&                term.setBackgroundColor(colors[theme.err])!@#&          term.setCursorPos(6, 7)!@#&             term.write(\"Error Help\")!@#&!@#&              term.setBackgroundColor(colors[theme.prompt])!@#&               for i, v in ipairs(tips) do!@#&                 term.setCursorPos(7, i + 10)!@#&                        term.write(\"- \" .. curLanguage.helpTips[v])!@#&               end!@#& else!@#&                term.setBackgroundColor(colors[theme.err])!@#&          term.setCursorPos(6, 7)!@#&             term.write(\"No Error Tips Available!\")!@#&!@#&                term.setBackgroundColor(colors[theme.prompt])!@#&               term.setCursorPos(6, 11)!@#&            term.write(\"There are no error tips available, but\")!@#&              term.setCursorPos(6, 12)!@#&            term.write(\"you could see if it was any of these:\")!@#&!@#&           for i, v in ipairs(curLanguage.defaultHelpTips) do!@#&                  term.setCursorPos(7, i + 12)!@#&                        term.write(\"- \" .. curLanguage.helpTips[v])!@#&               end!@#& end!@#&!@#&     prompt({{\"Back\", w - 8, 7}}, \"horizontal\")!@#&end!@#&!@#&local function run(path, lines, useArgs)!@#&       local ar = {}!@#&       if useArgs then!@#&             title(\"LuaIDE - Run \" .. fs.getName(path))!@#&                local s = centerRead(w - 13, fs.getName(path) .. \" \")!@#&             for m in string.gmatch(s, \"[^ \\t]+\") do ar[#ar + 1] = m:gsub(\"^%s*(.-)%s*$\", \"%1\") end!@#&       end!@#& !@#&    saveFile(path, lines)!@#&       term.setCursorBlink(false)!@#&  term.setBackgroundColor(colors.black)!@#&       term.setTextColor(colors.white)!@#&     term.clear()!@#&        term.setCursorPos(1, 1)!@#&     local err = curLanguage.run(path, ar)!@#&!@#&   term.setBackgroundColor(colors.black)!@#&       print(\"\\n\")!@#&      if err then!@#&         if isAdvanced() then term.setTextColor(colors.red) end!@#&              centerPrint(\"The program has crashed!\")!@#&   end!@#& term.setTextColor(colors.white)!@#&     centerPrint(\"Press any key to return to LuaIDE...\")!@#&       while true do!@#&               local e = os.pullEvent()!@#&            if e == \"key\" then break end!@#&      end!@#&!@#&     -- To prevent key from showing up in editor!@#& os.queueEvent(event_distract)!@#&       os.pullEvent()!@#&!@#&  if err then!@#&         if curLanguage == languages.lua and err:find(\"]\") then!@#&                    err = fs.getName(path) .. err:sub(err:find(\"]\", 1, true) + 1, -1)!@#&         end!@#&!@#&             while true do!@#&                       title(\"LuaIDE - Error!\")!@#&!@#&                      term.setBackgroundColor(colors[theme.err])!@#&                  for i = 6, 8 do!@#&                             term.setCursorPos(3, i)!@#&                             term.write(string.rep(\" \", w - 5))!@#&                        end!@#&                 term.setCursorPos(4, 7)!@#&                     term.write(\"The program has crashed!\")!@#&!@#&                        term.setBackgroundColor(colors[theme.prompt])!@#&                       for i = 10, 14 do!@#&                           term.setCursorPos(3, i)!@#&                             term.write(string.rep(\" \", w - 5))!@#&                        end!@#&!@#&                     local formattedErr = curLanguage.parseError(err)!@#&                    term.setCursorPos(4, 11)!@#&                    term.write(\"Line: \" .. formattedErr.line)!@#&                 term.setCursorPos(4, 12)!@#&                    term.write(\"Error:\")!@#&                      term.setCursorPos(5, 13)!@#&!@#&                        local a = formattedErr.display!@#&                      local b = nil!@#&                       if a:len() > w - 8 then!@#&                             for i = a:len(), 1, -1 do!@#&                                   if a:sub(i, i) == \" \" then!@#&                                                b = a:sub(i + 1, -1)!@#&                                                a = a:sub(1, i)!@#&                                             break!@#&                                       end!@#&                         end!@#&                 end!@#&!@#&                     term.write(a)!@#&                       if b then!@#&                           term.setCursorPos(5, 14)!@#&                            term.write(b)!@#&                       end!@#&                 !@#&                    local opt = prompt({{\"Error Help\", w/2 - 15, 17}, {\"Go To Line\", w/2 + 2, 17}},!@#&                         \"horizontal\")!@#&                     if opt == \"Error Help\" then!@#&                               viewErrorHelp(formattedErr)!@#&                 elseif opt == \"Go To Line\" then!@#&                           -- To prevent key from showing up in editor!@#&                         os.queueEvent(event_distract)!@#&                               os.pullEvent()!@#&!@#&                          return \"go to\", tonumber(formattedErr.line)!@#&                       end!@#&         end!@#& end!@#&end!@#&!@#&!@#&--  -------- Functions!@#&!@#&local function goto()!@#&   term.setBackgroundColor(colors[theme.backgroundHighlight])!@#&  term.setCursorPos(2, 1)!@#&     term.clearLine()!@#&    term.write(\"Line: \")!@#&      local line = modRead({visibleLength = w - 2})!@#&!@#&   local num = tonumber(line)!@#&  if num and num > 0 then return num!@#&  else!@#&                term.setCursorPos(2, 1)!@#&             term.clearLine()!@#&            term.write(\"Not a line number!\")!@#&          sleep(1.6)!@#&          return nil!@#&  end!@#&end!@#&!@#&local function setsyntax()!@#&        local opts = {!@#&              \"[Lua]   Brainfuck    None \",!@#&             \" Lua   [Brainfuck]   None \",!@#&             \" Lua    Brainfuck   [None]\"!@#&      }!@#&   local sel = 1!@#&!@#&   term.setCursorBlink(false)!@#&  term.setBackgroundColor(colors[theme.backgroundHighlight])!@#&  term.setCursorPos(2, 1)!@#&     term.clearLine()!@#&    term.write(opts[sel])!@#&       while true do!@#&               local e, but, x, y = os.pullEvent(\"key\")!@#&          if but == 203 then!@#&                  sel = math.max(1, sel - 1)!@#&                  term.setCursorPos(2, 1)!@#&                     term.clearLine()!@#&                    term.write(opts[sel])!@#&               elseif but == 205 then!@#&                      sel = math.min(#opts, sel + 1)!@#&                      term.setCursorPos(2, 1)!@#&                     term.clearLine()!@#&                    term.write(opts[sel])!@#&               elseif but == 28 then!@#&                       if sel == 1 then curLanguage = languages.lua!@#&                        elseif sel == 2 then curLanguage = languages.brainfuck!@#&                      elseif sel == 3 then curLanguage = languages.none end!@#&                       term.setCursorBlink(true)!@#&                   return!@#&              end!@#& end!@#&end!@#&!@#&!@#&--  -------- Re-Indenting!@#&!@#&local tabWidth = 2!@#&!@#&local comments = {}!@#&local strings = {}!@#&!@#&local increment = {!@#&       \"if%s+.+%s+then%s*$\",!@#&     \"for%s+.+%s+do%s*$\",!@#&      \"while%s+.+%s+do%s*$\",!@#&    \"repeat%s*$\",!@#&     \"function%s+[a-zA-Z_0-9]\\(.*\\)%s*$\"!@#&}!@#&!@#&local decrement = {!@#&     \"end\",!@#&    \"until%s+.+\"!@#&}!@#&!@#&local special = {!@#&        \"else%s*$\",!@#&       \"elseif%s+.+%s+then%s*$\"!@#&}!@#&!@#&local function check(func)!@#&   for _, v in pairs(func) do!@#&          local cLineStart = v[\"lineStart\"]!@#&         local cLineEnd = v[\"lineEnd\"]!@#&             local cCharStart = v[\"charStart\"]!@#&         local cCharEnd = v[\"charEnd\"]!@#&!@#&         if line >= cLineStart and line <= cLineEnd then!@#&                     if line == cLineStart then return cCharStart < charNumb!@#&                     elseif line == cLineEnd then return cCharEnd > charNumb!@#&                     else return true end!@#&                end!@#& end!@#&end!@#&!@#&local function isIn(line, loc)!@#&    if check(comments) then return true end!@#&     if check(strings) then return true end!@#&      return false!@#&end!@#&!@#&local function setComment(ls, le, cs, ce)!@#&        comments[#comments + 1] = {}!@#&        comments[#comments].lineStart = ls!@#&  comments[#comments].lineEnd = le!@#&    comments[#comments].charStart = cs!@#&  comments[#comments].charEnd = ce!@#&end!@#&!@#&local function setString(ls, le, cs, ce)!@#&     strings[#strings + 1] = {}!@#&  strings[#strings].lineStart = ls!@#&    strings[#strings].lineEnd = le!@#&      strings[#strings].charStart = cs!@#&    strings[#strings].charEnd = ce!@#&end!@#&!@#&local function map(contents)!@#&   local inCom = false!@#& local inStr = false!@#&!@#&     for i = 1, #contents do!@#&             if content[i]:find(\"%-%-%[%[\") and not inStr and not inCom then!@#&                   local cStart = content[i]:find(\"%-%-%[%[\")!@#&                        setComment(i, nil, cStart, nil)!@#&                     inCom = true!@#&                elseif content[i]:find(\"%-%-%[=%[\") and not inStr and not inCom then!@#&                      local cStart = content[i]:find(\"%-%-%[=%[\")!@#&                       setComment(i, nil, cStart, nil)!@#&                     inCom = true!@#&                elseif content[i]:find(\"%[%[\") and not inStr and not inCom then!@#&                   local cStart = content[i]:find(\"%[%[\")!@#&                    setString(i, nil, cStart, nil)!@#&                      inStr = true!@#&                elseif content[i]:find(\"%[=%[\") and not inStr and not inCom then!@#&                  local cStart = content[i]:find(\"%[=%[\")!@#&                   setString(i, nil, cStart, nil)!@#&                      inStr = true!@#&                end!@#&!@#&             if content[i]:find(\"%]%]\") and inStr and not inCom then!@#&                   local cStart, cEnd = content[i]:find(\"%]%]\")!@#&                      strings[#strings].lineEnd = i!@#&                       strings[#strings].charEnd = cEnd!@#&                    inStr = false!@#&               elseif content[i]:find(\"%]=%]\") and inStr and not inCom then!@#&                      local cStart, cEnd = content[i]:find(\"%]=%]\")!@#&                     strings[#strings].lineEnd = i!@#&                       strings[#strings].charEnd = cEnd!@#&                    inStr = false!@#&               end!@#&!@#&             if content[i]:find(\"%]%]\") and not inStr and inCom then!@#&                   local cStart, cEnd = content[i]:find(\"%]%]\")!@#&                      comments[#comments].lineEnd = i!@#&                     comments[#comments].charEnd = cEnd!@#&                  inCom = false!@#&               elseif content[i]:find(\"%]=%]\") and not inStr and inCom then!@#&                      local cStart, cEnd = content[i]:find(\"%]=%]\")!@#&                     comments[#comments].lineEnd = i!@#&                     comments[#comments].charEnd = cEnd!@#&                  inCom = false!@#&               end!@#&!@#&             if content[i]:find(\"%-%-\") and not inStr and not inCom then!@#&                       local cStart = content[i]:find(\"%-%-\")!@#&                    setComment(i, i, cStart, -1)!@#&                elseif content[i]:find(\"'\") and not inStr and not inCom then!@#&                      local cStart, cEnd = content[i]:find(\"'\")!@#&                 local nextChar = content[i]:sub(cEnd + 1, string.len(content[i]))!@#&                   local _, cEnd = nextChar:find(\"'\")!@#&                        setString(i, i, cStart, cEnd)!@#&               elseif content[i]:find('\"') and not inStr and not inCom then!@#&                       local cStart, cEnd = content[i]:find('\"')!@#&                  local nextChar = content[i]:sub(cEnd + 1, string.len(content[i]))!@#&                   local _, cEnd = nextChar:find('\"')!@#&                 setString(i, i, cStart, cEnd)!@#&               end!@#& end!@#&end!@#&!@#&local function reindent(contents)!@#& local err = nil!@#&     if curLanguage ~= languages.lua then!@#&                err = \"Cannot indent languages other than Lua!\"!@#&   elseif curLanguage.getCompilerErrors(table.concat(contents, \"\\n\")).line ~= -1 then!@#&               err = \"Cannot indent a program with errors!\"!@#&      end!@#&!@#&     if err then!@#&         term.setCursorBlink(false)!@#&          term.setCursorPos(2, 1)!@#&             term.setBackgroundColor(colors[theme.backgroundHighlight])!@#&          term.clearLine()!@#&            term.write(err)!@#&             sleep(1.6)!@#&          return contents!@#&     end!@#&!@#&     local new = {}!@#&      local level = 0!@#&     for k, v in pairs(contents) do!@#&              local incrLevel = false!@#&             local foundIncr = false!@#&             for _, incr in pairs(increment) do!@#&                  if v:find(incr) and not isIn(k, v:find(incr)) then!@#&                          incrLevel = true!@#&                    end!@#&                 if v:find(incr:sub(1, -2)) and not isIn(k, v:find(incr)) then!@#&                               foundIncr = true!@#&                    end!@#&         end!@#&!@#&             local decrLevel = false!@#&             if not incrLevel then!@#&                       for _, decr in pairs(decrement) do!@#&                          if v:find(decr) and not isIn(k, v:find(decr)) and not foundIncr then!@#&                                        level = math.max(0, level - 1)!@#&                                      decrLevel = true!@#&                            end!@#&                 end!@#&         end!@#&!@#&             if not decrLevel then!@#&                       for _, sp in pairs(special) do!@#&                              if v:find(sp) and not isIn(k, v:find(sp)) then!@#&                                      incrLevel = true!@#&                                    level = math.max(0, level - 1)!@#&                              end!@#&                 end!@#&         end!@#&!@#&             new[k] = string.rep(\" \", level * tabWidth) .. v!@#&           if incrLevel then level = level + 1 end!@#&     end!@#&!@#&     return new!@#&end!@#&!@#&!@#&--  -------- Menu!@#&!@#&local menu = {!@#&        [1] = {\"File\",!@#&--          \"About\",!@#&--                \"Settings\",!@#&--             \"\",!@#&               \"New File  ^+N\",!@#&          \"Open File ^+O\",!@#&          \"Save File ^+S\",!@#&          \"Close     ^+W\",!@#&          \"Print     ^+P\",!@#&          \"Quit      ^+Q\"!@#&   }, [2] = {\"Edit\",!@#&         \"Cut Line   ^+X\",!@#&         \"Copy Line  ^+C\",!@#&         \"Paste Line ^+V\",!@#&         \"Delete Line\",!@#&            \"Clear Line\"!@#&      }, [3] = {\"Functions\",!@#&            \"Go To Line    ^+G\",!@#&              \"Re-Indent     ^+I\",!@#&              \"Set Syntax    ^+E\",!@#&              \"Start of Line ^+<\",!@#&              \"End of Line   ^+>\"!@#&       }, [4] = {\"Run\",!@#&          \"Run Program       ^+R\",!@#&          \"Run w/ Args ^+Shift+R\"!@#&   }!@#&}!@#&!@#&local shortcuts = {!@#&   -- File!@#&     [\"ctrl n\"] = \"New File  ^+N\",!@#&   [\"ctrl o\"] = \"Open File ^+O\",!@#&   [\"ctrl s\"] = \"Save File ^+S\",!@#&   [\"ctrl w\"] = \"Close     ^+W\",!@#&   [\"ctrl p\"] = \"Print     ^+P\",!@#&   [\"ctrl q\"] = \"Quit      ^+Q\",!@#&!@#&       -- Edit!@#&     [\"ctrl x\"] = \"Cut Line   ^+X\",!@#&  [\"ctrl c\"] = \"Copy Line  ^+C\",!@#&  [\"ctrl v\"] = \"Paste Line ^+V\",!@#&!@#&      -- Functions!@#&        [\"ctrl g\"] = \"Go To Line    ^+G\",!@#&       [\"ctrl i\"] = \"Re-Indent     ^+I\",!@#&       [\"ctrl e\"] = \"Set Syntax    ^+E\",!@#&       [\"ctrl 203\"] = \"Start of Line ^+<\",!@#&     [\"ctrl 205\"] = \"End of Line   ^+>\",!@#&!@#& -- Run!@#&      [\"ctrl r\"] = \"Run Program       ^+R\",!@#&   [\"ctrl shift r\"] = \"Run w/ Args ^+Shift+R\"!@#&}!@#&!@#&local menuFunctions = {!@#&  -- File!@#&--   [\"About\"] = function() end,!@#&--     [\"Settings\"] = function() end,!@#&    [\"New File  ^+N\"] = function(path, lines) saveFile(path, lines) return \"new\" end,!@#&       [\"Open File ^+O\"] = function(path, lines) saveFile(path, lines) return \"open\" end,!@#&      [\"Save File ^+S\"] = function(path, lines) saveFile(path, lines) end,!@#&      [\"Close     ^+W\"] = function(path, lines) saveFile(path, lines) return \"menu\" end,!@#&      [\"Print     ^+P\"] = function(path, lines) saveFile(path, lines) return nil end,!@#&   [\"Quit      ^+Q\"] = function(path, lines) saveFile(path, lines) return \"exit\" end,!@#&!@#&  -- Edit!@#&     [\"Cut Line   ^+X\"] = function(path, lines, y)!@#&             clipboard = lines[y] table.remove(lines, y) return nil, lines end,!@#&  [\"Copy Line  ^+C\"] = function(path, lines, y) clipboard = lines[y] end,!@#&   [\"Paste Line ^+V\"] = function(path, lines, y)!@#&             if clipboard then table.insert(lines, y, clipboard) end return nil, lines end,!@#&      [\"Delete Line\"] = function(path, lines, y) table.remove(lines, y) return nil, lines end,!@#&  [\"Clear Line\"] = function(path, lines, y) lines[y] = \"\" return nil, lines, \"cursor\" end,!@#&!@#&  -- Functions!@#&        [\"Go To Line    ^+G\"] = function() return nil, \"go to\", goto() end,!@#&     [\"Re-Indent     ^+I\"] = function(path, lines)!@#&             local a = reindent(lines) saveFile(path, lines) return nil, a!@#&       end,!@#&        [\"Set Syntax    ^+E\"] = function(path, lines)!@#&             setsyntax()!@#&         if curLanguage == languages.brainfuck and lines[1] ~= \"-- Syntax: Brainfuck\" then!@#&                 table.insert(lines, 1, \"-- Syntax: Brainfuck\")!@#&                    return nil, lines!@#&           end!@#& end,!@#&        [\"Start of Line ^+<\"] = function() os.queueEvent(\"key\", 199) end,!@#&       [\"End of Line   ^+>\"] = function() os.queueEvent(\"key\", 207) end,!@#&!@#&   -- Run!@#&      [\"Run Program       ^+R\"] = function(path, lines)!@#&         saveFile(path, lines)!@#&               return nil, run(path, lines, false)!@#& end,!@#&        [\"Run w/ Args ^+Shift+R\"] = function(path, lines)!@#&         saveFile(path, lines)!@#&               return nil, run(path, lines, true)!@#&  end,!@#&}!@#&!@#&local function drawMenu(open)!@#&      term.setCursorPos(1, 1)!@#&     term.setTextColor(colors[theme.textColor])!@#&  term.setBackgroundColor(colors[theme.backgroundHighlight])!@#&  term.clearLine()!@#&    local curX = 0!@#&      for _, v in pairs(menu) do!@#&          term.setCursorPos(3 + curX, 1)!@#&              term.write(v[1])!@#&            curX = curX + v[1]:len() + 3!@#&        end!@#&!@#&     if open then!@#&                local it = {}!@#&               local x = 1!@#&         for _, v in pairs(menu) do!@#&                  if open == v[1] then!@#&                                it = v!@#&                              break!@#&                       end!@#&                 x = x + v[1]:len() + 3!@#&              end!@#&         x = x + 1!@#&!@#&               local items = {}!@#&            for i = 2, #it do!@#&                   table.insert(items, it[i])!@#&          end!@#&!@#&             local len = 1!@#&               for _, v in pairs(items) do if v:len() + 2 > len then len = v:len() + 2 end end!@#&!@#&         for i, v in ipairs(items) do!@#&                        term.setCursorPos(x, i + 1)!@#&                 term.write(string.rep(\" \", len))!@#&                  term.setCursorPos(x + 1, i + 1)!@#&                     term.write(v)!@#&               end!@#&         term.setCursorPos(x, #items + 2)!@#&            term.write(string.rep(\" \", len))!@#&          return items, len!@#&   end!@#&end!@#&!@#&local function triggerMenu(cx, cy)!@#&        -- Determine clicked menu!@#&   local curX = 0!@#&      local open = nil!@#&    for _, v in pairs(menu) do!@#&          if cx >= curX + 3 and cx <= curX + v[1]:len() + 2 then!@#&                      open = v[1]!@#&                 break!@#&               end!@#&         curX = curX + v[1]:len() + 3!@#&        end!@#& local menux = curX + 2!@#&      if not open then return false end!@#&!@#&       -- Flash menu item!@#&  term.setCursorBlink(false)!@#&  term.setCursorPos(menux, 1)!@#& term.setBackgroundColor(colors[theme.background])!@#&   term.write(string.rep(\" \", open:len() + 2))!@#&       term.setCursorPos(menux + 1, 1)!@#&     term.write(open)!@#&    sleep(0.1)!@#&  local items, len = drawMenu(open)!@#&!@#&       local ret = true!@#&!@#&        -- Pull events on menu!@#&      local ox, oy = term.getCursorPos()!@#&  while type(ret) ~= \"string\" do!@#&            local e, but, x, y = os.pullEvent()!@#&         if e == \"mouse_click\" then!@#&                        -- If clicked outside menu!@#&                  if x < menux - 1 or x > menux + len - 1 then break!@#&                  elseif y > #items + 2 then break!@#&                    elseif y == 1 then break end!@#&!@#&                    for i, v in ipairs(items) do!@#&                                if y == i + 1 and x >= menux and x <= menux + len - 2 then!@#&                                  -- Flash when clicked!@#&                                       term.setCursorPos(menux, y)!@#&                                 term.setBackgroundColor(colors[theme.background])!@#&                                   term.write(string.rep(\" \", len))!@#&                                  term.setCursorPos(menux + 1, y)!@#&                                     term.write(v)!@#&                                       sleep(0.1)!@#&                                  drawMenu(open)!@#&!@#&                                  -- Return item!@#&                                      ret = v!@#&                                     break!@#&                               end!@#&                 end!@#&         end!@#& end!@#&!@#&     term.setCursorPos(ox, oy)!@#&   term.setCursorBlink(true)!@#&   return ret!@#&end!@#&!@#&!@#&--  -------- Editing!@#&!@#&local standardsCompletions = {!@#&     \"if%s+.+%s+then%s*$\",!@#&     \"for%s+.+%s+do%s*$\",!@#&      \"while%s+.+%s+do%s*$\",!@#&    \"repeat%s*$\",!@#&     \"function%s+[a-zA-Z_0-9]\\(.*\\)%s*$\",!@#&    \"else%s*$\",!@#&       \"elseif%s+.+%s+then%s*$\"!@#&}!@#&!@#&local liveCompletions = {!@#&    [\"(\"] = \")\",!@#&    [\"{\"] = \"}\",!@#&    [\"[\"] = \"]\",!@#&    [\"\\\"\"] = \"\\\"\",!@#&      [\"'\"] = \"'\",!@#&}!@#&!@#&local x, y = 0, 0!@#&local edw, edh = 0, h - 1!@#&local offx, offy = 0, 1!@#&local scrollx, scrolly = 0, 0!@#&local lines = {}!@#&local liveErr = curLanguage.parseError(nil)!@#&local displayCode = true!@#&local lastEventClock = os.clock()!@#&!@#&local function attemptToHighlight(line, regex, col)!@#&      local match = string.match(line, regex)!@#&     if match then!@#&               if type(col) == \"number\" then term.setTextColor(col)!@#&              elseif type(col) == \"function\" then term.setTextColor(col(match)) end!@#&             term.write(match)!@#&           term.setTextColor(colors[theme.textColor])!@#&          return line:sub(match:len() + 1, -1)!@#&        end!@#& return nil!@#&end!@#&!@#&local function writeHighlighted(line)!@#&      if curLanguage == languages.lua then!@#&                while line:len() > 0 do !@#&                    line = attemptToHighlight(line, \"^%-%-%[%[.-%]%]\", colors[theme.comment]) or!@#&                              attemptToHighlight(line, \"^%-%-.*\", colors[theme.comment]) or!@#&                             attemptToHighlight(line, \"^\\\".*[^\\\\]\\\"\", colors[theme.string]) or!@#&                           attemptToHighlight(line, \"^\\'.*[^\\\\]\\'\", colors[theme.string]) or!@#&                             attemptToHighlight(line, \"^%[%[.-%]%]\", colors[theme.string]) or!@#&                          attemptToHighlight(line, \"^[%w_]+\", function(match)!@#&                                       if curLanguage.keywords[match] then!@#&                                         return colors[theme[curLanguage.keywords[match]]]!@#&                                   end!@#&                                 return colors[theme.textColor]!@#&                              end) or!@#&                             attemptToHighlight(line, \"^[^%w_]\", colors[theme.textColor])!@#&              end!@#& else term.write(line) end!@#&end!@#&!@#&local function draw()!@#&       -- Menu!@#&     term.setTextColor(colors[theme.textColor])!@#&  term.setBackgroundColor(colors[theme.editorBackground])!@#&     term.clear()!@#&        drawMenu()!@#&!@#&      -- Line numbers!@#&     offx, offy = tostring(#lines):len() + 1, 1!@#&  edw, edh = w - offx, h - 1!@#&!@#&      -- Draw text!@#&        for i = 1, edh do!@#&           local a = lines[scrolly + i]!@#&                if a then!@#&                   local ln = string.rep(\" \", offx - 1 - tostring(scrolly + i):len()) .. tostring(scrolly + i) !@#&                      local l = a:sub(scrollx + 1, edw + scrollx + 1)!@#&                     ln = ln .. \":\"!@#&!@#&                        if liveErr.line == scrolly + i then ln = string.rep(\" \", offx - 2) .. \"!:\" end!@#&!@#&                      term.setCursorPos(1, i + offy)!@#&                      term.setBackgroundColor(colors[theme.editorBackground])!@#&                     if scrolly + i == y then!@#&                            if scrolly + i == liveErr.line and os.clock() - lastEventClock > 3 then!@#&                                     term.setBackgroundColor(colors[theme.editorErrorHighlight])!@#&                         else term.setBackgroundColor(colors[theme.editorLineHightlight]) end!@#&                                term.clearLine()!@#&                    elseif scrolly + i == liveErr.line then!@#&                             term.setBackgroundColor(colors[theme.editorError])!@#&                          term.clearLine()!@#&                    end!@#&!@#&                     term.setCursorPos(1 - scrollx + offx, i + offy)!@#&                     if scrolly + i == y then!@#&                            if scrolly + i == liveErr.line and os.clock() - lastEventClock > 3 then!@#&                                     term.setBackgroundColor(colors[theme.editorErrorHighlight])!@#&                         else term.setBackgroundColor(colors[theme.editorLineHightlight]) end!@#&                        elseif scrolly + i == liveErr.line then term.setBackgroundColor(colors[theme.editorError])!@#&                  else term.setBackgroundColor(colors[theme.editorBackground]) end!@#&                    if scrolly + i == liveErr.line then!@#&                         if displayCode then term.write(a)!@#&                           else term.write(liveErr.display) end!@#&                        else writeHighlighted(a) end!@#&!@#&                    term.setCursorPos(1, i + offy)!@#&                      if scrolly + i == y then!@#&                            if scrolly + i == liveErr.line and os.clock() - lastEventClock > 3 then!@#&                                     term.setBackgroundColor(colors[theme.editorError])!@#&                          else term.setBackgroundColor(colors[theme.editorLineNumbersHighlight]) end!@#&                  elseif scrolly + i == liveErr.line then!@#&                             term.setBackgroundColor(colors[theme.editorErrorHighlight])!@#&                 else term.setBackgroundColor(colors[theme.editorLineNumbers]) end!@#&                   term.write(ln)!@#&              end!@#& end!@#& term.setCursorPos(x - scrollx + offx, y - scrolly + offy)!@#&end!@#&!@#&local function drawLine(...)!@#&        local ls = {...}!@#&    offx = tostring(#lines):len() + 1!@#&   for _, ly in pairs(ls) do!@#&           local a = lines[ly]!@#&         if a then!@#&                   local ln = string.rep(\" \", offx - 1 - tostring(ly):len()) .. tostring(ly) !@#&                        local l = a:sub(scrollx + 1, edw + scrollx + 1)!@#&                     ln = ln .. \":\"!@#&!@#&                        if liveErr.line == ly then ln = string.rep(\" \", offx - 2) .. \"!:\" end!@#&!@#&                       term.setCursorPos(1, (ly - scrolly) + offy)!@#&                 term.setBackgroundColor(colors[theme.editorBackground])!@#&                     if ly == y then!@#&                             if ly == liveErr.line and os.clock() - lastEventClock > 3 then!@#&                                      term.setBackgroundColor(colors[theme.editorErrorHighlight])!@#&                         else term.setBackgroundColor(colors[theme.editorLineHightlight]) end!@#&                        elseif ly == liveErr.line then!@#&                              term.setBackgroundColor(colors[theme.editorError])!@#&                  end!@#&                 term.clearLine()!@#&!@#&                        term.setCursorPos(1 - scrollx + offx, (ly - scrolly) + offy)!@#&                        if ly == y then!@#&                             if ly == liveErr.line and os.clock() - lastEventClock > 3 then!@#&                                      term.setBackgroundColor(colors[theme.editorErrorHighlight])!@#&                         else term.setBackgroundColor(colors[theme.editorLineHightlight]) end!@#&                        elseif ly == liveErr.line then term.setBackgroundColor(colors[theme.editorError])!@#&                   else term.setBackgroundColor(colors[theme.editorBackground]) end!@#&                    if ly == liveErr.line then!@#&                          if displayCode then term.write(a)!@#&                           else term.write(liveErr.display) end!@#&                        else writeHighlighted(a) end!@#&!@#&                    term.setCursorPos(1, (ly - scrolly) + offy)!@#&                 if ly == y then!@#&                             if ly == liveErr.line and os.clock() - lastEventClock > 3 then!@#&                                      term.setBackgroundColor(colors[theme.editorError])!@#&                          else term.setBackgroundColor(colors[theme.editorLineNumbersHighlight]) end!@#&                  elseif ly == liveErr.line then!@#&                              term.setBackgroundColor(colors[theme.editorErrorHighlight])!@#&                 else term.setBackgroundColor(colors[theme.editorLineNumbers]) end!@#&                   term.write(ln)!@#&              end!@#& end!@#& term.setCursorPos(x - scrollx + offx, y - scrolly + offy)!@#&end!@#&!@#&local function cursorLoc(x, y, force)!@#&       local sx, sy = x - scrollx, y - scrolly!@#&     local redraw = false!@#&        if sx < 1 then!@#&              scrollx = x - 1!@#&             sx = 1!@#&              redraw = true!@#&       elseif sx > edw then!@#&                scrollx = x - edw!@#&           sx = edw!@#&            redraw = true!@#&       end if sy < 1 then!@#&          scrolly = y - 1!@#&             sy = 1!@#&              redraw = true!@#&       elseif sy > edh then!@#&                scrolly = y - edh!@#&           sy = edh!@#&            redraw = true!@#&       end if redraw or force then draw() end!@#&      term.setCursorPos(sx + offx, sy + offy)!@#&end!@#&!@#&local function executeMenuItem(a, path)!@#&       if type(a) == \"string\" and menuFunctions[a] then!@#&          local opt, nl, gtln = menuFunctions[a](path, lines, y)!@#&              if type(opt) == \"string\" then term.setCursorBlink(false) return opt end!@#&           if type(nl) == \"table\" then!@#&                       if #lines < 1 then table.insert(lines, \"\") end!@#&                    y = math.min(y, #lines)!@#&                     x = math.min(x, lines[y]:len() + 1)!@#&                 lines = nl!@#&          elseif type(nl) == \"string\" then!@#&                  if nl == \"go to\" and gtln then!@#&                            x, y = 1, math.min(#lines, gtln)!@#&                            cursorLoc(x, y)!@#&                     end!@#&         end!@#& end!@#& term.setCursorBlink(true)!@#&   draw()!@#&      term.setCursorPos(x - scrollx + offx, y - scrolly + offy)!@#&end!@#&!@#&local function edit(path)!@#&   -- Variables!@#&        x, y = 1, 1!@#& offx, offy = 0, 1!@#&   scrollx, scrolly = 0, 0!@#&     lines = loadFile(path)!@#&      if not lines then return \"menu\" end!@#&!@#&   -- Enable brainfuck!@#& if lines[1] == \"-- Syntax: Brainfuck\" then!@#&                curLanguage = languages.brainfuck!@#&   end!@#&!@#&     -- Clocks!@#&   local autosaveClock = os.clock()!@#&    local scrollClock = os.clock() -- To prevent redraw flicker!@#& local liveErrorClock = os.clock()!@#&   local hasScrolled = false!@#&!@#&       -- Draw!@#&     draw()!@#&      term.setCursorPos(x + offx, y + offy)!@#&       term.setCursorBlink(true)!@#&   !@#&    -- Main loop!@#&        local tid = os.startTimer(3)!@#&        while true do!@#&               local e, key, cx, cy = os.pullEvent()!@#&               if e == \"key\" and allowEditorEvent then!@#&                   if key == 200 and y > 1 then!@#&                                -- Up!@#&                               x, y = math.min(x, lines[y - 1]:len() + 1), y - 1!@#&                           drawLine(y, y + 1)!@#&                          cursorLoc(x, y)!@#&                     elseif key == 208 and y < #lines then!@#&                               -- Down!@#&                             x, y = math.min(x, lines[y + 1]:len() + 1), y + 1!@#&                           drawLine(y, y - 1)!@#&                          cursorLoc(x, y)!@#&                     elseif key == 203 and x > 1 then!@#&                            -- Left!@#&                             x = x - 1!@#&                           local force = false!@#&                         if y - scrolly + offy < offy + 1 then force = true end!@#&                              cursorLoc(x, y, force)!@#&                      elseif key == 205 and x < lines[y]:len() + 1 then!@#&                           -- Right!@#&                            x = x + 1!@#&                           local force = false!@#&                         if y - scrolly + offy < offy + 1 then force = true end!@#&                              cursorLoc(x, y, force)!@#&                      elseif (key == 28 or key == 156) and (displayCode and true or y + scrolly - 1 ==!@#&                                    liveErr.line) then!@#&                          -- Enter!@#&                            local f = nil!@#&                               for _, v in pairs(standardsCompletions) do!@#&                                  if lines[y]:find(v) then f = v end!@#&                          end!@#&!@#&                             local _, spaces = lines[y]:find(\"^[ ]+\")!@#&                          if not spaces then spaces = 0 end!@#&                           if f then!@#&                                   table.insert(lines, y + 1, string.rep(\" \", spaces + 2))!@#&                                   if not f:find(\"else\", 1, true) and not f:find(\"elseif\", 1, true) then!@#&                                           table.insert(lines, y + 2, string.rep(\" \", spaces) .. !@#&                                                    (f:find(\"repeat\", 1, true) and \"until \" or f:find(\"{\", 1, true) and \"}\" or !@#&                                                 \"end\"))!@#&                                   end!@#&                                 x, y = spaces + 3, y + 1!@#&                                    cursorLoc(x, y, true)!@#&                               else!@#&                                        local oldLine = lines[y]!@#&!@#&                                        lines[y] = lines[y]:sub(1, x - 1)!@#&                                   table.insert(lines, y + 1, string.rep(\" \", spaces) .. oldLine:sub(x, -1))!@#&!@#&                                     x, y = spaces + 1, y + 1!@#&                                    cursorLoc(x, y, true)!@#&                               end!@#&                 elseif key == 14 and (displayCode and true or y + scrolly - 1 == liveErr.line) then!@#&                         -- Backspace!@#&                                if x > 1 then!@#&                                       local f = false!@#&                                     for k, v in pairs(liveCompletions) do!@#&                                               if lines[y]:sub(x - 1, x - 1) == k then f = true end!@#&                                        end!@#&!@#&                                     lines[y] = lines[y]:sub(1, x - 2) .. lines[y]:sub(x + (f and 1 or 0), -1)!@#&                                   drawLine(y)!@#&                                 x = x - 1!@#&                                   cursorLoc(x, y)!@#&                             elseif y > 1 then!@#&                                   local prevLen = lines[y - 1]:len() + 1!@#&                                      lines[y - 1] = lines[y - 1] .. lines[y]!@#&                                     table.remove(lines, y)!@#&                                      x, y = prevLen, y - 1!@#&                                       cursorLoc(x, y, true)!@#&                               end!@#&                 elseif key == 199 then!@#&                              -- Home!@#&                             x = 1!@#&                               local force = false!@#&                         if y - scrolly + offy < offy + 1 then force = true end!@#&                              cursorLoc(x, y, force)!@#&                      elseif key == 207 then!@#&                              -- End!@#&                              x = lines[y]:len() + 1!@#&                              local force = false!@#&                         if y - scrolly + offy < offy + 1 then force = true end!@#&                              cursorLoc(x, y, force)!@#&                      elseif key == 211 and (displayCode and true or y + scrolly - 1 == liveErr.line) then!@#&                                -- Forward Delete!@#&                           if x < lines[y]:len() + 1 then!@#&                                      lines[y] = lines[y]:sub(1, x - 1) .. lines[y]:sub(x + 1)!@#&                                    local force = false!@#&                                 if y - scrolly + offy < offy + 1 then force = true end!@#&                                      drawLine(y)!@#&                                 cursorLoc(x, y, force)!@#&                              elseif y < #lines then!@#&                                      lines[y] = lines[y] .. lines[y + 1]!@#&                                 table.remove(lines, y + 1)!@#&                                  draw()!@#&                                      cursorLoc(x, y)!@#&                             end!@#&                 elseif key == 15 and (displayCode and true or y + scrolly - 1 == liveErr.line) then!@#&                         -- Tab!@#&                              lines[y] = string.rep(\" \", tabWidth) .. lines[y]!@#&                          x = x + 2!@#&                           local force = false!@#&                         if y - scrolly + offy < offy + 1 then force = true end!@#&                              drawLine(y)!@#&                         cursorLoc(x, y, force)!@#&                      elseif key == 201 then!@#&                              -- Page up!@#&                          y = math.min(math.max(y - edh, 1), #lines)!@#&                          x = math.min(lines[y]:len() + 1, x)!@#&                         cursorLoc(x, y, true)!@#&                       elseif key == 209 then!@#&                              -- Page down!@#&                                y = math.min(math.max(y + edh, 1), #lines)!@#&                          x = math.min(lines[y]:len() + 1, x)!@#&                         cursorLoc(x, y, true)!@#&                       end!@#&         elseif e == \"char\" and allowEditorEvent and (displayCode and true or !@#&                             y + scrolly - 1 == liveErr.line) then!@#&                       local shouldIgnore = false!@#&                  for k, v in pairs(liveCompletions) do!@#&                               if key == v and lines[y]:find(k, 1, true) and lines[y]:sub(x, x) == v then!@#&                                  shouldIgnore = true!@#&                         end!@#&                 end!@#&!@#&                     local addOne = false!@#&                        if not shouldIgnore then!@#&                            for k, v in pairs(liveCompletions) do!@#&                                       if key == k and lines[y]:sub(x, x) ~= k then key = key .. v addOne = true end!@#&                               end!@#&                         lines[y] = lines[y]:sub(1, x - 1) .. key .. lines[y]:sub(x, -1)!@#&                     end!@#&!@#&                     x = x + (addOne and 1 or key:len())!@#&                 local force = false!@#&                 if y - scrolly + offy < offy + 1 then force = true end!@#&                      drawLine(y)!@#&                 cursorLoc(x, y, force)!@#&              elseif e == \"mouse_click\" and key == 1 then!@#&                       if cy > 1 then!@#&                              if cx <= offx and cy - offy == liveErr.line - scrolly then!@#&                                  displayCode = not displayCode!@#&                                       drawLine(liveErr.line)!@#&                              else!@#&                                        local oldy = y!@#&                                      y = math.min(math.max(scrolly + cy - offy, 1), #lines)!@#&                                      x = math.min(math.max(scrollx + cx - offx, 1), lines[y]:len() + 1)!@#&                                  if oldy ~= y then drawLine(oldy, y) end!@#&                                     cursorLoc(x, y)!@#&                             end!@#&                 else!@#&                                local a = triggerMenu(cx, cy)!@#&                               if a then!@#&                                   local opt = executeMenuItem(a, path)!@#&                                        if opt then return opt end!@#&                          end!@#&                 end!@#&         elseif e == \"shortcut\" then!@#&                       local a = shortcuts[key .. \" \" .. cx]!@#&                     if a then!@#&                           local parent = nil!@#&                          local curx = 0!@#&                              for i, mv in ipairs(menu) do!@#&                                        for _, iv in pairs(mv) do!@#&                                           if iv == a then!@#&                                                     parent = menu[i][1]!@#&                                                 break!@#&                                               end!@#&                                 end!@#&                                 if parent then break end!@#&                                    curx = curx + mv[1]:len() + 3!@#&                               end!@#&                         local menux = curx + 2!@#&!@#&                          -- Flash menu item!@#&                          term.setCursorBlink(false)!@#&                          term.setCursorPos(menux, 1)!@#&                         term.setBackgroundColor(colors[theme.background])!@#&                           term.write(string.rep(\" \", parent:len() + 2))!@#&                             term.setCursorPos(menux + 1, 1)!@#&                             term.write(parent)!@#&                          sleep(0.1)!@#&                          drawMenu()!@#&!@#&                              -- Execute item!@#&                             local opt = executeMenuItem(a, path)!@#&                                if opt then return opt end!@#&                  end!@#&         elseif e == \"mouse_scroll\" then!@#&                   if key == -1 and scrolly > 0 then!@#&                           scrolly = scrolly - 1!@#&                               if os.clock() - scrollClock > 0.0005 then!@#&                                   draw()!@#&                                      term.setCursorPos(x - scrollx + offx, y - scrolly + offy)!@#&                           end!@#&                         scrollClock = os.clock()!@#&                            hasScrolled = true!@#&                  elseif key == 1 and scrolly < #lines - edh then!@#&                             scrolly = scrolly + 1!@#&                               if os.clock() - scrollClock > 0.0005 then!@#&                                   draw()!@#&                                      term.setCursorPos(x - scrollx + offx, y - scrolly + offy)!@#&                           end!@#&                         scrollClock = os.clock()!@#&                            hasScrolled = true!@#&                  end!@#&         elseif e == \"timer\" and key == tid then!@#&                   drawLine(y)!@#&                 tid = os.startTimer(3)!@#&              end!@#&!@#&             -- Draw!@#&             if hasScrolled and os.clock() - scrollClock > 0.1 then!@#&                      draw()!@#&                      term.setCursorPos(x - scrollx + offx, y - scrolly + offy)!@#&                   hasScrolled = false!@#&         end!@#&!@#&             -- Autosave!@#&         if os.clock() - autosaveClock > autosaveInterval then!@#&                       saveFile(path, lines)!@#&                       autosaveClock = os.clock()!@#&          end!@#&!@#&             -- Errors!@#&           if os.clock() - liveErrorClock > 1 then!@#&                     local prevLiveErr = liveErr!@#&                 liveErr = curLanguage.parseError(nil)!@#&                       local code = \"\"!@#&                   for _, v in pairs(lines) do code = code .. v .. \"\\n\" end!@#&!@#&                     liveErr = curLanguage.getCompilerErrors(code)!@#&                       liveErr.line = math.min(liveErr.line - 2, #lines)!@#&                   if liveErr ~= prevLiveErr then draw() end!@#&                   liveErrorClock = os.clock()!@#&         end!@#& end!@#&!@#&     return \"menu\"!@#&end!@#&!@#&!@#&--  -------- Open File!@#&!@#&local function newFile()!@#&    local wid = w - 13!@#&!@#&      -- Get name!@#& title(\"Lua IDE - New File\")!@#&       local name = centerRead(wid, \"/\")!@#& if not name or name == \"\" then return \"menu\" end!@#&        name = \"/\" .. name!@#&!@#&    -- Clear!@#&    title(\"Lua IDE - New File\")!@#&       term.setTextColor(colors[theme.textColor])!@#&  term.setBackgroundColor(colors[theme.promptHighlight])!@#&      for i = 8, 10 do!@#&            term.setCursorPos(w/2 - wid/2, i)!@#&           term.write(string.rep(\" \", wid))!@#&  end!@#& term.setCursorPos(1, 9)!@#&     if fs.isDir(name) then!@#&              centerPrint(\"Cannot Edit a Directory!\")!@#&           sleep(1.6)!@#&          return \"menu\"!@#&     elseif fs.exists(name) then!@#&         centerPrint(\"File Already Exists!\")!@#&               local opt = prompt({{\"Open\", w/2 - 9, 14}, {\"Cancel\", w/2 + 2, 14}}, \"horizontal\")!@#&            if opt == \"Open\" then return \"edit\", name!@#&               elseif opt == \"Cancel\" then return \"menu\" end!@#&   else return \"edit\", name end!@#&end!@#&!@#&local function openFile()!@#&      local wid = w - 13!@#&!@#&      -- Get name!@#& title(\"Lua IDE - Open File\")!@#&      local name = centerRead(wid, \"/\")!@#& if not name or name == \"\" then return \"menu\" end!@#&        name = \"/\" .. name!@#&!@#&    -- Clear!@#&    title(\"Lua IDE - New File\")!@#&       term.setTextColor(colors[theme.textColor])!@#&  term.setBackgroundColor(colors[theme.promptHighlight])!@#&      for i = 8, 10 do!@#&            term.setCursorPos(w/2 - wid/2, i)!@#&           term.write(string.rep(\" \", wid))!@#&  end!@#& term.setCursorPos(1, 9)!@#&     if fs.isDir(name) then!@#&              centerPrint(\"Cannot Open a Directory!\")!@#&           sleep(1.6)!@#&          return \"menu\"!@#&     elseif not fs.exists(name) then!@#&             centerPrint(\"File Doesn't Exist!\")!@#&                local opt = prompt({{\"Create\", w/2 - 11, 14}, {\"Cancel\", w/2 + 2, 14}}, \"horizontal\")!@#&         if opt == \"Create\" then return \"edit\", name!@#&             elseif opt == \"Cancel\" then return \"menu\" end!@#&   else return \"edit\", name end!@#&end!@#&!@#&!@#&--  -------- Settings!@#&!@#&local function update()!@#&       local function draw(status)!@#&         title(\"LuaIDE - Update\")!@#&          term.setBackgroundColor(colors[theme.prompt])!@#&               term.setTextColor(colors[theme.textColor])!@#&          for i = 8, 10 do!@#&                    term.setCursorPos(w/2 - (status:len() + 4), i)!@#&                      write(string.rep(\" \", status:len() + 4))!@#&          end!@#&         term.setCursorPos(w/2 - (status:len() + 4), 9)!@#&              term.write(\" - \" .. status .. \" \")!@#&!@#&          term.setBackgroundColor(colors[theme.errHighlight])!@#&         for i = 8, 10 do!@#&                    term.setCursorPos(w/2 + 2, i)!@#&                       term.write(string.rep(\" \", 10))!@#&           end!@#&         term.setCursorPos(w/2 + 2, 9)!@#&               term.write(\" > Cancel \")!@#&  end!@#&!@#&     if not http then!@#&            draw(\"HTTP API Disabled!\")!@#&                sleep(1.6)!@#&          return \"settings\"!@#& end!@#&!@#&     draw(\"Updating...\")!@#&       local tID = os.startTimer(10)!@#&       http.request(updateURL)!@#&     while true do!@#&               local e, but, x, y = os.pullEvent()!@#&         if (e == \"key\" and but == 28) or!@#&                          (e == \"mouse_click\" and x >= w/2 + 2 and x <= w/2 + 12 and y == 9) then!@#&                   draw(\"Cancelled\")!@#&                 sleep(1.6)!@#&                  break!@#&               elseif e == \"http_success\" and but == updateURL then!@#&                      local new = x.readAll()!@#&                     local curf = io.open(ideLocation, \"r\")!@#&                    local cur = curf:read(\"*a\")!@#&                       curf:close()!@#&!@#&                    if cur ~= new then!@#&                          draw(\"Update Found\")!@#&                              sleep(1.6)!@#&                          local f = io.open(ideLocation, \"w\")!@#&                               f:write(new)!@#&                                f:close()!@#&!@#&                               draw(\"Click to Exit\")!@#&                             while true do!@#&                                       local e = os.pullEvent()!@#&                                    if e == \"mouse_click\" or (not isAdvanced() and e == \"key\") then break end!@#&                               end!@#&                         return \"exit\"!@#&                     else!@#&                                draw(\"No Updates Found!\")!@#&                         sleep(1.6)!@#&                          break!@#&                       end!@#&         elseif e == \"http_failure\" or (e == \"timer\" and but == tID) then!@#&                        draw(\"Update Failed!\")!@#&                    sleep(1.6)!@#&                  break!@#&               end!@#& end!@#&!@#&     return \"settings\"!@#&end!@#&!@#&local function changeTheme()!@#&      title(\"LuaIDE - Theme\")!@#&!@#&       if isAdvanced() then!@#&                local disThemes = {\"Back\"}!@#&                for _, v in pairs(availableThemes) do table.insert(disThemes, v[1]) end!@#&             local t = scrollingPrompt(disThemes)!@#&                local url = nil!@#&             for _, v in pairs(availableThemes) do if v[1] == t then url = v[2] end end!@#&!@#&              if not url then return \"settings\" end!@#&             if t == \"Dawn (Default)\" then!@#&                     term.setBackgroundColor(colors[theme.backgroundHighlight])!@#&                  term.setCursorPos(3, 3)!@#&                     term.clearLine()!@#&                    term.write(\"LuaIDE - Loaded Theme!\")!@#&                      sleep(1.6)!@#&!@#&                      fs.delete(themeLocation)!@#&                    theme = defaultTheme!@#&                        return \"menu\"!@#&             end!@#&!@#&             term.setBackgroundColor(colors[theme.backgroundHighlight])!@#&          term.setCursorPos(3, 3)!@#&             term.clearLine()!@#&            term.write(\"LuaIDE - Downloading...\")!@#&!@#&         fs.delete(\"/.LuaIDE_temp_theme_file\")!@#&             download(url, \"/.LuaIDE_temp_theme_file\")!@#&         local a = loadTheme(\"/.LuaIDE_temp_theme_file\")!@#&!@#&               term.setCursorPos(3, 3)!@#&             term.clearLine()!@#&            if a then!@#&                   term.write(\"LuaIDE - Loaded Theme!\")!@#&                      fs.delete(themeLocation)!@#&                    fs.move(\"/.LuaIDE_temp_theme_file\", themeLocation)!@#&                        theme = a!@#&                   sleep(1.6)!@#&                  return \"menu\"!@#&             end!@#&         !@#&            term.write(\"LuaIDE - Could Not Load Theme!\")!@#&              fs.delete(\"/.LuaIDE_temp_theme_file\")!@#&             sleep(1.6)!@#&          return \"settings\"!@#& else!@#&                term.setCursorPos(1, 8)!@#&             centerPrint(\"Themes are not available on\")!@#&                centerPrint(\"normal computers!\")!@#&  end!@#&end!@#&!@#&local function settings()!@#& title(\"LuaIDE - Settings\")!@#&!@#&    local opt = prompt({{\"Change Theme\", w/2 - 17, 8}, {\"Return to Menu\", w/2 - 22, 13},!@#&            {\"Check for Updates\", w/2 + 2, 8}, {\"Exit IDE\", w/2 + 2, 13, bg = colors[theme.err], !@#&           highlight = colors[theme.errHighlight]}}, \"vertical\", true)!@#&       if opt == \"Change Theme\" then return changeTheme()!@#&        elseif opt == \"Check for Updates\" then return update()!@#&    elseif opt == \"Return to Menu\" then return \"menu\"!@#&       elseif opt == \"Exit IDE\" then return \"exit\" end!@#&end!@#&!@#&!@#&--  -------- Menu!@#&!@#&local function menu()!@#&        title(\"Welcome to LuaIDE \" .. version)!@#&!@#&        local opt = prompt({{\"New File\", w/2 - 13, 8}, {\"Open File\", w/2 - 14, 13},!@#&             {\"Settings\", w/2 + 2, 8}, {\"Exit IDE\", w/2 + 2, 13, bg = colors[theme.err],!@#&             highlight = colors[theme.errHighlight]}}, \"vertical\", true)!@#&       if opt == \"New File\" then return \"new\"!@#&  elseif opt == \"Open File\" then return \"open\"!@#&    elseif opt == \"Settings\" then return \"settings\"!@#& elseif opt == \"Exit IDE\" then return \"exit\" end!@#&end!@#&!@#&!@#&--  -------- Main!@#&!@#&local function main(arguments)!@#&       local opt, data = \"menu\", nil!@#&!@#& -- Check arguments!@#&  if type(arguments) == \"table\" and #arguments > 0 then!@#&             local f = \"/\" .. shell.resolve(arguments[1])!@#&              if fs.isDir(f) then print(\"Cannot edit a directory.\") end!@#&         opt, data = \"edit\", f!@#&     end!@#&!@#&     -- Main run loop!@#&    while true do!@#&               -- Menu!@#&             if opt == \"menu\" then opt = menu() end!@#&!@#&                -- Other!@#&            if opt == \"new\" then opt, data = newFile()!@#&                elseif opt == \"open\" then opt, data = openFile()!@#&          elseif opt == \"settings\" then opt = settings()!@#&            end if opt == \"exit\" then break end!@#&!@#&           -- Edit!@#&             if opt == \"edit\" and data then opt = edit(data) end!@#&       end!@#&end!@#&!@#&-- Load Theme!@#&if fs.exists(themeLocation) then theme = loadTheme(themeLocation) end!@#&if not theme and isAdvanced() then theme = defaultTheme!@#&elseif not theme then theme = normalTheme end!@#&!@#&-- Run!@#&local _, err = pcall(function()!@#&       parallel.waitForAny(function() main(args) end, monitorKeyboardShortcuts)!@#&end)!@#&!@#&-- Catch errors!@#&if err and not err:find(\"Terminated\") then!@#&     term.setCursorBlink(false)!@#&  title(\"LuaIDE - Crash! D:\")!@#&!@#&   term.setBackgroundColor(colors[theme.err])!@#&  for i = 6, 8 do!@#&             term.setCursorPos(5, i)!@#&             term.write(string.rep(\" \", 36))!@#&   end!@#& term.setCursorPos(6, 7)!@#&     term.write(\"LuaIDE Has Crashed! D:\")!@#&!@#&  term.setBackgroundColor(colors[theme.background])!@#&   term.setCursorPos(2, 10)!@#&    print(err)!@#&!@#&      term.setBackgroundColor(colors[theme.prompt])!@#&       local _, cy = term.getCursorPos()!@#&   for i = cy + 1, cy + 4 do!@#&           term.setCursorPos(5, i)!@#&             term.write(string.rep(\" \", 36))!@#&   end!@#& term.setCursorPos(6, cy + 2)!@#&        term.write(\"Please report this error to\")!@#& term.setCursorPos(6, cy + 3)!@#&        term.write(\"GravityScore! \")!@#&      !@#&    term.setBackgroundColor(colors[theme.background])!@#&   if isAdvanced() then centerPrint(\"Click to Exit...\", h - 1)!@#&       else centerPrint(\"Press Any Key to Exit...\", h - 1) end!@#&   while true do!@#&               local e = os.pullEvent()!@#&            if e == \"mouse_click\" or (not isAdvanced() and e == \"key\") then break end!@#&       end!@#&!@#&     -- Prevent key from being shown!@#&     os.queueEvent(event_distract)!@#&       os.pullEvent()!@#&end!@#&!@#&-- Exit!@#&term.setBackgroundColor(colors.black)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&term.setCursorPos(1, 1)!@#&centerPrint(\"Thank You for Using Lua IDE \" .. version)!@#&centerPrint(\"Made by GravityScore\")",["pgen"]="local args = {...}!@#&local chars = {\"Anus\", \"Cock\", \"Dick\", \"Whore\", \"Prick\", \"Cunt\", \"Faggot\", \"Fuck\", \"Twat\", \"E\", \"f\", \"F\", \"g\", \"G\", \"h\", \"H\", \"i\", \"I\", \"j\", \"J\", \"k\", \"K\", \"l\", \"L\", \"m\", \"M\", \"n\", \"N\", \"o\", \"O\", \"p\", \"P\", \"q\", \"Q\", \"r\", \"R\", \"s\", \"S\", \"t\", \"T\", \"u\", \"U\", \"v\", \"V\", \"w\", \"W\", \"x\", \"X\", \"y\", \"Y\", \"z\", \"Z\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"0\", \"!\", \"@\", \"-\", \"_\", \"#\", \"%\", \"$\", \"*\", \"+\"}!@#&local pass = \"\"!@#&char = math.random(8, 32)!@#&for i = 1, char do!@#&  local ranChar = math.random(1, #chars)!@#&  pass = pass..chars[ranChar]!@#&end!@#&print(pass)",["lightshot"]="!@#&--  !@#&--  Lighshot Screen Recorder!@#&--  Made by GravityScore!@#&--  !@#&!@#&!@#&--  -------- Variables!@#&!@#&--  Lower the loop rate to decrease recording lag but to decrease compression!@#&--  Do not set to below 50 else the file could become really big!@#&local loopRate = 300!@#&!@#&-- Version!@#&local version = \"1.4\"!@#&!@#&-- Terminal!@#&local oldTerm = {}!@#&local newTerm = {}!@#&local w, h = term.getSize()!@#&!@#&-- Events!@#&local event_exitRecording = \"lightshot_exitRecordingEvent\"!@#&!@#&-- Locations!@#&local lightshotURL = \"https://raw.github.com/GravityScore/Lightshot/master/lightshot.lua\"!@#&local lightshotLocation = \"/\" .. shell.getRunningProgram()!@#&!@#&-- Variables!@#&local clock = 0!@#&local nfaRecording = false!@#&local recordData = [[!@#&!@#&local function sp(...) return sleep(...) end!@#&local function c(...) return term.write(...) end!@#&local function d(...) return term.setCursorPos(...) end!@#&local function e(...) return term.setBackgroundColor(...) end!@#&local function f(...) return term.setTextColor(...) end!@#&local function g(...) return term.clear(...) end!@#&local function h(...) return term.clearLine() end!@#&local function i(...) return term.setCursorBlink(...) end!@#&local function j(...) return term.scroll(...) end!@#&!@#&]]!@#&!@#&local recordHeader = [[!@#&--  !@#&--  Recorded by Lightshot!@#&--  !@#&!@#&!@#&]]!@#&!@#&!@#&--  -------- Utilities!@#&!@#&local function modRead(properties)!@#&  local w, h = term.getSize()!@#& local defaults = {replaceChar = nil, history = nil, visibleLength = nil, textLength = nil, !@#&         liveUpdates = nil, exitOnKey = nil}!@#& if not properties then properties = {} end!@#&  for k, v in pairs(defaults) do if not properties[k] then properties[k] = v end end!@#&  if properties.replaceChar then properties.replaceChar = properties.replaceChar:sub(1, 1) end!@#&        if not properties.visibleLength then properties.visibleLength = w end!@#&!@#&   local sx, sy = term.getCursorPos()!@#&  local line = \"\"!@#&   local pos = 0!@#&       local historyPos = nil!@#&!@#&  local function redraw(repl)!@#&         local scroll = 0!@#&            if properties.visibleLength and sx + pos > properties.visibleLength + 1 then !@#&                       scroll = (sx + pos) - (properties.visibleLength + 1)!@#&                end!@#&!@#&             term.setCursorPos(sx, sy)!@#&           local a = repl or properties.replaceChar!@#&            if a then term.write(string.rep(a, line:len() - scroll))!@#&            else term.write(line:sub(scroll + 1, -1)) end!@#&               term.setCursorPos(sx + pos - scroll, sy)!@#&    end!@#&!@#&     local function sendLiveUpdates(event, ...)!@#&          if type(properties.liveUpdates) == \"function\" then!@#&                        local ox, oy = term.getCursorPos()!@#&                  properties.liveUpdates(line, event, ...)!@#&                    if a == true and data == nil then!@#&                           term.setCursorBlink(false)!@#&                          return line!@#&                 elseif a == true and data ~= nil then!@#&                               term.setCursorBlink(false)!@#&                          return data!@#&                 end!@#&                 term.setCursorPos(ox, oy)!@#&           end!@#& end!@#&!@#&     term.setCursorBlink(true)!@#&   while true do!@#&               local e, but, x, y, p4, p5 = os.pullEvent()!@#&!@#&             if e == \"char\" then!@#&                       local s = false!@#&                     if properties.textLength and line:len() < properties.textLength then s = true!@#&                       elseif not properties.textLength then s = true end!@#&!@#&                      local canType = true!@#&                        if not properties.grantPrint and properties.refusePrint then!@#&                                local canTypeKeys = {}!@#&                              if type(properties.refusePrint) == \"table\" then!@#&                                   for _, v in pairs(properties.refusePrint) do!@#&                                                table.insert(canTypeKeys, tostring(v):sub(1, 1))!@#&                                    end!@#&                         elseif type(properties.refusePrint) == \"string\" then!@#&                                      for char in properties.refusePrint:gmatch(\".\") do!@#&                                         table.insert(canTypeKeys, char)!@#&                                     end!@#&                         end!@#&                         for _, v in pairs(canTypeKeys) do if but == v then canType = false end end!@#&                  elseif properties.grantPrint then!@#&                           canType = false!@#&                             local canTypeKeys = {}!@#&                              if type(properties.grantPrint) == \"table\" then!@#&                                    for _, v in pairs(properties.grantPrint) do!@#&                                         table.insert(canTypeKeys, tostring(v):sub(1, 1))!@#&                                    end!@#&                         elseif type(properties.grantPrint) == \"string\" then!@#&                                       for char in properties.grantPrint:gmatch(\".\") do!@#&                                          table.insert(canTypeKeys, char)!@#&                                     end!@#&                         end!@#&                         for _, v in pairs(canTypeKeys) do if but == v then canType = true end end!@#&                   end!@#&!@#&                     if s and canType then!@#&                               line = line:sub(1, pos) .. but .. line:sub(pos + 1, -1)!@#&                             pos = pos + 1!@#&                               redraw()!@#&                    end!@#&         elseif e == \"key\" then!@#&                    if but == keys.enter then break!@#&                     elseif but == keys.left then if pos > 0 then pos = pos - 1 redraw() end!@#&                     elseif but == keys.right then if pos < line:len() then pos = pos + 1 redraw() end!@#&                   elseif (but == keys.up or but == keys.down) and properties.history then!@#&                             redraw(\" \")!@#&                               if but == keys.up then!@#&                                      if historyPos == nil and #properties.history > 0 then !@#&                                              historyPos = #properties.history!@#&                                    elseif historyPos > 1 then !@#&                                         historyPos = historyPos - 1!@#&                                 end!@#&                         elseif but == keys.down then!@#&                                        if historyPos == #properties.history then historyPos = nil!@#&                                  elseif historyPos ~= nil then historyPos = historyPos + 1 end!@#&                               end!@#&!@#&                             if properties.history and historyPos then!@#&                                   line = properties.history[historyPos]!@#&                                       pos = line:len()!@#&                            else!@#&                                        line = \"\"!@#&                                 pos = 0!@#&                             end!@#&!@#&                             redraw()!@#&                            sendLiveUpdates(\"history\")!@#&                        elseif but == keys.backspace and pos > 0 then!@#&                               redraw(\" \")!@#&                               line = line:sub(1, pos - 1) .. line:sub(pos + 1, -1)!@#&                                pos = pos - 1!@#&                               redraw()!@#&                            sendLiveUpdates(\"delete\")!@#&                 elseif but == keys.home then!@#&                                pos = 0!@#&                             redraw()!@#&                    elseif but == keys.delete and pos < line:len() then!@#&                         redraw(\" \")!@#&                               line = line:sub(1, pos) .. line:sub(pos + 2, -1)!@#&                            redraw()!@#&                            sendLiveUpdates(\"delete\")!@#&                 elseif but == keys[\"end\"] then!@#&                            pos = line:len()!@#&                            redraw()!@#&                    elseif properties.exitOnKey then !@#&                           if but == properties.exitOnKey or (properties.exitOnKey == \"control\" and !@#&                                         (but == 29 or but == 157)) then !@#&                                    term.setCursorBlink(false)!@#&                                  return nil!@#&                          end!@#&                 end!@#&         end!@#&!@#&             sendLiveUpdates(e, but, x, y, p4, p5)!@#&       end!@#&!@#&     term.setCursorBlink(false)!@#&  if line ~= nil then line = line:gsub(\"^%s*(.-)%s*$\", \"%1\") end!@#&  return line!@#&end!@#&!@#&local function centerPrint(text, ny)!@#&      if type(text) == \"table\" then for _, v in pairs(text) do centerPrint(v) end!@#&       else!@#&                local x, y = term.getCursorPos()!@#&            local w, h = term.getSize()!@#&         term.setCursorPos(w/2 - text:len()/2 + (#text % 2 == 0 and 1 or 0), ny or y)!@#&                print(text)!@#& end!@#&end!@#&!@#&!@#&--  -------- Updating!@#&!@#&local function download(url, path)!@#&       for i = 1, 3 do!@#&             local response = http.get(url)!@#&              if response then!@#&                    local data = response.readAll()!@#&                     response.close()!@#&                    if path then!@#&                                local f = io.open(path, \"w\")!@#&                              f:write(data)!@#&                               f:close()!@#&                   end!@#&                 return true!@#&         end!@#& end!@#&!@#&     return false!@#&end!@#&!@#&local function updateClient()!@#&    local updateLocation = \"/.lightshot-update\"!@#&       fs.delete(updateLocation)!@#&!@#&       download(lightshotURL, updateLocation)!@#&      local a = io.open(updateLocation, \"r\")!@#&    local b = io.open(lightshotLocation, \"r\")!@#& local new = a:read(\"*a\")!@#&  local cur = b:read(\"*a\")!@#&  a:close()!@#&   b:close()!@#&!@#&       if cur ~= new then!@#&          fs.delete(lightshotLocation)!@#&                fs.move(updateLocation, lightshotLocation)!@#&          return true!@#& else!@#&                fs.delete(updateLocation)!@#&           return false!@#&        end!@#&end!@#&!@#&!@#&--  -------- Compression!@#&!@#&local sD = {{}}!@#&local cD = {}!@#&!@#&local function proccessFunction(data)!@#& if data:len() < 8 then!@#&              if data:sub(-1,-1) == \"]\" then return \"[[\" .. data .. \"] .. \\\"]\\\"\"!@#&                else return \"[[\" .. data .. \"]]\" end!@#&    end!@#& if cD[v] then return cD[v] end!@#&      for k, v in pairs(sD[#sD]) do!@#&               if v == data then!@#&                   cD[v] = (\"sD[\" .. #sD .. \"][\" .. k .. \"]\")!@#&                    return(\"sD[\" .. #sD .. \"][\" .. k .. \"]\")!@#&              end!@#& end!@#& table.insert(sD[#sD], data)!@#& local returnData = (\"sD[\".. #sD .. \"][\" .. #sD[#sD] .. \"]\")!@#&   if #sD[#sD] > loopRate then sD[#sD + 1] = {} end!@#&    return returnData!@#&end!@#&!@#&!@#&--  -------- Terminal Override!@#&!@#&local bg, tc, blnk = -1, -1, nil!@#&for k, v in pairs(term.native) do oldTerm[k] = v end!@#&!@#&newTerm.write = function(...)!@#&     local text = \"\"!@#&   for k, v in pairs({...}) do text = text .. tostring(v) end!@#&  local a = \"\"!@#&      if os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&!@#&  text = proccessFunction(tostring(text))!@#&     local b = \"c(\" .. text .. \")\\n\"!@#&        recordData = recordData .. a .. b!@#&   clock = os.clock()!@#&  if not nfaRecording then return oldTerm.write(...) end!@#&end!@#&!@#&newTerm.setCursorPos = function(x, y)!@#&  local a = \"\"!@#&      if os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&      recordData = recordData .. a .. \"d(\" .. tostring(x) .. \", \" .. tostring(y) .. \")\\n\"!@#&  clock = os.clock()!@#&!@#&      return oldTerm.setCursorPos(x, y)!@#&end!@#&!@#&newTerm.getCursorPos = function(...) return oldTerm.getCursorPos(...) end!@#&!@#&newTerm.setBackgroundColor = function(col)!@#& if bg ~= col then!@#&           local a = \"\"!@#&              if not nfaRecording and os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&!@#&             recordData = recordData .. a .. \"e(\" .. tostring(col) .. \")\\n\"!@#&         clock = os.clock()!@#&          bg = col!@#&    end!@#&!@#&     return oldTerm.setBackgroundColor(col)!@#&end!@#&!@#&newTerm.setTextColor = function(col)!@#&   if tc ~= col then!@#&           local a = \"\"!@#&              if not nfaRecording and os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&!@#&             recordData = recordData .. a .. \"f(\" .. tostring(col) .. \")\\n\"!@#&         clock = os.clock()!@#&          tc = col!@#&    end!@#&!@#&     return oldTerm.setTextColor(col)!@#&end!@#&!@#&newTerm.setBackgroundColour = function(col) return term.setBackgroundColor(col) end!@#&newTerm.setTextColour = function(col) return term.setTextColor(col) end!@#&!@#&newTerm.clear = function(...)!@#&  local a = \"\"!@#&      if os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&      recordData = recordData .. a .. \"g()\\n\"!@#&  clock = os.clock()!@#&!@#&      return oldTerm.clear(...)!@#&end!@#&!@#&newTerm.clearLine = function(...)!@#&   local a = \"\"!@#&      if os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&      recordData = recordData .. a .. \"h()\\n\"!@#&  clock = os.clock()!@#&!@#&      return oldTerm.clearLine(...)!@#&end!@#&!@#&newTerm.setCursorBlink = function(flag)!@#& if flag ~= blnk then!@#&                local a = \"\"!@#&              if os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&              recordData = recordData .. a .. \"i(\" .. tostring(flag) .. \")\\n\"!@#&                clock = os.clock()!@#&          blnk = flag!@#& end!@#&!@#&     return oldTerm.setCursorBlink(flag)!@#&end!@#&!@#&newTerm.scroll = function(n)!@#&      local a = \"\"!@#&      if os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&      recordData = recordData .. a .. \"j(\" .. tostring(n) .. \")\\n\"!@#&   clock = os.clock()!@#&!@#&      return oldTerm.scroll(n)!@#&end!@#&!@#&newTerm.getSize = function(...) return oldTerm.getSize(...) end!@#&newTerm.redirect = function(...) return oldTerm.redirect(...) end!@#&newTerm.restore = function(...) return oldTerm.restore(...) end!@#&newTerm.isColor = function(...) return oldTerm.isColor and oldTerm.isColor(...) end!@#&newTerm.isColour = function(...) return term.isColor(...) end!@#&!@#&!@#&--  -------- Recording!@#&!@#&local function record(location)!@#&     while true do!@#&               local e, key = os.pullEventRaw()!@#&            if (e == \"key\" and key == 59) or e == event_exitRecording or e == \"terminate\" then!@#&                      local a = \"\"!@#&                      if os.clock() - clock > 0 then a = \"sp(\" .. os.clock() - clock .. \") \" end!@#&                      recordData = recordData .. a!@#&!@#&                    recordData = recordData .. \"term.setCursorBlink(false)\\n\"!@#&                        recordData = recordData .. \"if term.isColor() then term.setTextColor(colors.yellow)\\n\"!@#&                   recordData = recordData .. \"else term.setTextColor(colors.white) end\\n\"!@#&                  recordData = recordData .. \"term.setBackgroundColor(colors.black)\\n\"!@#&                     recordData = recordData .. \"term.clear()\\n\"!@#&                      recordData = recordData .. \"term.setCursorPos(1, 1)\\n\"!@#&                   recordData = recordData .. \"print(\\\"End of Recording!\\\")\\n\"!@#&!@#&                      recordHeader = recordHeader .. \"local sD = \" .. textutils.serialize(sD) .. \"\\n\"!@#&                        recordData = recordHeader .. recordData!@#&!@#&                 term.restore()!@#&                      term.setCursorBlink(false)!@#&                  if term.isColor() then term.setTextColor(colors.yellow)!@#&                     else term.setTextColor(colors.white) end!@#&                    term.setBackgroundColor(colors.black)!@#&                       term.clear()!@#&                        term.setCursorPos(1, 1)!@#&                     print(\"Recording Saved!\")!@#&                 sleep(1.1)!@#&!@#&                      local f = io.open(location, \"w\")!@#&                  f:write(recordData)!@#&                 f:close()!@#&                   return!@#&              end!@#& end!@#&end!@#&!@#&!@#&--  -------- Movie!@#&!@#&local function loadNfa(path)!@#&        local ret = {}!@#&      if fs.exists(path) and not fs.isDir(path) then!@#&              local f = io.open(path, \"r\")!@#&              local l = f:read(\"*l\")!@#&            local curFrame = \"\"!@#&               while l do!@#&                  if l ~= \"\" and l ~= \"~\" then curFrame = curFrame .. l .. \"\\n\"!@#&                        elseif l == \"~\" then!@#&                              table.insert(ret, curFrame)!@#&                         curFrame = \"\"!@#&                     end!@#&                 l = f:read(\"*l\")!@#&          end!@#&         f:close()!@#&   end!@#&!@#&     return ret!@#&end!@#&!@#&local function movie(location, duration)!@#&   nfaRecording = true!@#& local frames = loadNfa(location)!@#&    if frames ~= {} then!@#&                for i, v in ipairs(frames) do!@#&                       term.setTextColor(colors.white)!@#&                     term.setBackgroundColor(colors.black)!@#&                       term.clear()!@#&!@#&                    local tempImageLocation = \"/.lightshot-temp-image\"!@#&                        local f = io.open(tempImageLocation, \"w\")!@#&                 f:write(v)!@#&                  f:close()!@#&                   local a = paintutils.loadImage(tempImageLocation)!@#&                   paintutils.drawImage(a, 1, 1)!@#&                       fs.delete(tempImageLocation)!@#&                        recordData = recordData .. \"sp(\" .. duration .. \")\\n\"!@#&          end!@#&!@#&             recordData = recordData .. \"sp(\" .. duration .. \")\\n\"!@#&  end!@#&!@#&     recordData = recordData .. \"term.setCursorBlink(false)\\n\"!@#&        recordData = recordData .. \"if term.isColor() then term.setTextColor(colors.yellow)\\n\"!@#&   recordData = recordData .. \"else term.setTextColor(colors.white) end\\n\"!@#&  recordData = recordData .. \"term.setBackgroundColor(colors.black)\\n\"!@#&     recordData = recordData .. \"term.clear()\\n\"!@#&      recordData = recordData .. \"term.setCursorPos(1, 1)\\n\"!@#&   recordData = recordData .. \"print(\\\"The End! :D\\\")\\n\"!@#&!@#&    nfaRecording = false!@#&        term.restore()!@#&      term.setCursorBlink(false)!@#&  if term.isColor() then term.setTextColor(colors.yellow)!@#&     else term.setTextColor(colors.white) end!@#&    term.setBackgroundColor(colors.black)!@#&       term.clear()!@#&        term.setCursorPos(1, 1)!@#&     print(\"Movie Recorded Successfully!\")!@#&!@#& local f = io.open(location:sub(1, -5) .. \"-movie\", \"w\")!@#& f:write(recordData)!@#& f:close()!@#&end!@#&!@#&!@#&--  -------- Main!@#&!@#&local theme = {}!@#&if term.isColor and term.isColor() then!@#&    theme = {!@#&           [\"prompt\"] = \"cyan\",!@#&            [\"promptHighlight\"] = \"lightBlue\",!@#&              [\"textColor\"] = \"white\",!@#&        }!@#&else!@#&   theme = {!@#&           [\"prompt\"] = \"black\",!@#&           [\"promptHighlight\"] = \"black\",!@#&          [\"textColor\"] = \"white\",!@#&        }!@#&end!@#&!@#&local function drawButton(v, sel)!@#&   if sel then term.setBackgroundColor(v.highlight or colors[theme.promptHighlight])!@#&   else term.setBackgroundColor(v.bg or colors[theme.prompt]) end!@#&      term.setTextColor(v.tc or colors[theme.textColor])!@#&  for i = -1, 1 do!@#&            term.setCursorPos(v[2], v[3] + i)!@#&           term.write(string.rep(\" \", v[1]:len() + 4))!@#&       end!@#&!@#&     term.setCursorPos(v[2], v[3])!@#&       if sel then!@#&         term.setBackgroundColor(v.highlight or colors[theme.promptHighlight])!@#&               term.write(\" > \")!@#& else term.write(\" - \") end!@#&        term.write(v[1] .. \" \")!@#&end!@#&!@#&local function prompt(list, dir)!@#&    local function draw(sel)!@#&            for i, v in ipairs(list) do!@#&                 if i == sel then term.setBackgroundColor(v.highlight or colors[theme.promptHighlight])!@#&                      else term.setBackgroundColor(v.bg or colors[theme.prompt]) end!@#&                      term.setTextColor(v.tc or colors[theme.textColor])!@#&                  for i = -1, 1 do!@#&                            term.setCursorPos(v[2], v[3] + i)!@#&                           term.write(string.rep(\" \", v[1]:len() + 4))!@#&                       end!@#&!@#&                     term.setCursorPos(v[2], v[3])!@#&                       if i == sel then!@#&                            term.setBackgroundColor(v.highlight or colors[theme.promptHighlight])!@#&                               term.write(\" > \")!@#&                 else term.write(\" - \") end!@#&                        term.write(v[1] .. \" \")!@#&           end!@#& end!@#&!@#&     local sel = 1!@#&       draw(sel)!@#&!@#&       while true do!@#&               local e, but, x, y = os.pullEvent()!@#&         if e == \"key\" and but == 28 then return list[sel][1]!@#&              elseif e == \"key\" and but == 200 and sel > 1 then!@#&                 sel = sel - 1!@#&                       draw(sel)!@#&           elseif e == \"key\" and but == 208 and ((err == true and sel < #list - 1) or (sel < #list)) then!@#&                    sel = sel + 1!@#&                       draw(sel)!@#&           elseif e == \"key\" and but == 203 and sel > 2 then!@#&                 sel = sel - 2!@#&                       draw(sel)!@#&           elseif e == \"key\" and but == 205 and sel < 3 then!@#&                 sel = sel + 2!@#&                       draw(sel)!@#&           elseif e == \"mouse_click\" then!@#&                    for i, v in ipairs(list) do!@#&                         if x >= v[2] - 1 and x <= v[2] + v[1]:len() + 3 and y >= v[3] - 1 and y <= v[3] + 1 then!@#&                                    return list[i][1]!@#&                           end!@#&                 end!@#&         end!@#& end!@#&end!@#&!@#&local function menu()!@#&     term.setBackgroundColor(colors.gray)!@#&        term.setTextColor(colors.white)!@#&     term.clear()!@#&        term.setCursorPos(1, 1)!@#&!@#& term.setBackgroundColor(colors.lightGray)!@#&   for i = 2, 4 do term.setCursorPos(1, i) term.clearLine() end!@#&        term.setCursorPos(3, 3)!@#&     term.write(\"Lightshot \" .. version)!@#&!@#&   local opt = prompt({{\"Record a Video\", w/2 - 16, 9}, {\"Record an Animation\", w/2 - 21, 13},!@#&             {\"Update Lightshot\", w/2 + 4, 9}, {\"Exit\", w/2 + 4, 13, bg = (term.isColor and term.isColor())!@#&          and colors.red or colors.black, highlight = (term.isColor and term.isColor()) and colors.pink!@#&               or colors.black}}, \"vertical\")!@#&    if opt == \"Record a Video\" or opt == \"Record an Animation\" then!@#&         term.setBackgroundColor(colors.gray)!@#&                for i = 7, 14 do term.setCursorPos(1, i) term.clearLine() end!@#&               term.setBackgroundColor(colors.cyan)!@#&                for i = 8, 11 do term.setCursorPos(7, i) term.write(string.rep(\" \", w - 14)) end!@#&          drawButton({\"Control to Return to Menu\", 7, 14}, true)!@#&            term.setBackgroundColor(colors.cyan)!@#&                term.setCursorPos(8, 9)!@#&             term.write(\"Path:\")!@#&               term.setCursorPos(9, 10)!@#&            local loc = modRead({visibleLength = w - 14, exitOnKey = \"control\"})!@#&              if not loc or loc == \"\" then return \"menu\" end!@#&!@#&              term.setCursorPos(8, 9)!@#&             term.write(string.rep(\" \", 5))!@#&            term.setCursorPos(8, 9)!@#&             loc = \"/\" .. shell.resolve(loc)!@#&           if fs.isReadOnly(loc) then term.write(\"File is Read Only!\") sleep(1.6) return \"menu\"!@#&            elseif opt == \"Record a Video\" then!@#&                       if fs.exists(loc) then fs.delete(loc) end!@#&                   term.setTextColor(colors.white)!@#&                     term.setBackgroundColor(colors.black)!@#&                       term.clear()!@#&                        term.setCursorPos(2, 5)!@#&                     term.write(\"Press F1 to end the recording\")!@#&!@#&                   if term.isColor and term.isColor() then term.setTextColor(colors.yellow) end!@#&                        for i = 1, 3 do!@#&                             term.setCursorPos(2, 3)!@#&                             term.clearLine()!@#&                            term.write(\"Recording in \" .. 4 - i .. \"...\")!@#&                           sleep(1)!@#&                    end!@#&!@#&                     return \"record\", loc!@#&              elseif opt == \"Record an Animation\" then!@#&                  if loc:sub(-4, -1) ~= \".nfa\" then!@#&                         term.write(\"File Not An Animation!\")!@#&                              sleep(1.6)!@#&                          return \"menu\"!@#&                     end!@#&!@#&                     term.setCursorPos(8, 9)!@#&                     term.write(\"Duration between frames (seconds):\")!@#&                  term.setCursorPos(9, 10)!@#&                    term.write(string.rep(\" \", w - 16))!@#&                       term.setCursorPos(9, 10)!@#&                    local dur = modRead({visibleLength = w - 14, exitOnKey = \"control\"})!@#&                      if not dur or dur == \"\" then return \"menu\" end!@#&!@#&                      term.setCursorPos(8, 9)!@#&                     term.write(string.rep(\" \", 38))!@#&                   term.setCursorPos(8, 9)!@#&                     dur = tonumber(dur)!@#&                 if not dur then term.write(\"Duration must be an integer!\") sleep(1.6) return \"menu\"!@#&                     else return \"tomovie\", loc, dur end!@#&               end!@#& elseif opt == \"Update Lightshot\" then!@#&             term.setTextColor(colors.white)!@#&             term.setBackgroundColor(colors.lightGray)!@#&           term.setCursorPos(3, 3)!@#&             term.clearLine()!@#&            term.write(\"Checking for Updates...\")!@#&             term.setCursorPos(3, 3)!@#&             if updateClient() then!@#&                      term.clearLine()!@#&                    term.write(\"Updated!\")!@#&                    sleep(1.6)!@#&                  opt = \"Exit\"!@#&              else!@#&                        term.clearLine()!@#&                    term.write(\"No Updates Found!\")!@#&                   sleep(1.6)!@#&                  return \"menu\"!@#&             end!@#& end if opt == \"Exit\" then return nil end!@#&end!@#&!@#&local function main()!@#&      local action, location, duration = \"menu\", nil, nil!@#&       while action == \"menu\" do action, location, duration = menu() end!@#&!@#&     if action and location then!@#&         clock = os.clock()!@#&          term.redirect(newTerm)!@#&!@#&          term.setTextColor(colors.white)!@#&             term.setBackgroundColor(colors.black)!@#&               term.clear()!@#&                term.setCursorPos(1, 1)!@#&             if action == \"record\" then!@#&                        parallel.waitForAny(function()!@#&                              record(location)!@#&                    end, function()!@#&                             term.setBackgroundColor(colors.black)!@#&                               term.setTextColor(colors.white)!@#&                             term.clear()!@#&                                term.setCursorPos(1, 1)!@#&                             if fs.exists(\"/startup\") and not fs.isDir(\"/startup\") then shell.run(\"/startup\")!@#&                              else shell.run(\"/rom/programs/shell\") end!@#&                         os.queueEvent(event_exitRecording)!@#&                  end)!@#&                elseif action == \"tomovie\" then!@#&                   movie(location, duration)!@#&           end!@#& end!@#&end!@#&!@#&-- Run!@#&local oldDir = shell.dir()!@#&main()!@#&shell.setDir(oldDir)!@#&!@#&-- Exit Message!@#&term.setBackgroundColor(colors.black)!@#&term.setTextColor(colors.white)!@#&term.clear()!@#&term.setCursorPos(1, 1)!@#&centerPrint(\"Thanks for Using Lightshot \" .. version .. \"!\")!@#&centerPrint(\"Made by GravityScore and 1lann\")",["ev"]="keynos = {[\"1\"] = \"Escape\", [\"59\"] = \"Function 1\", [\"60\"] = \"Function 2\", [\"61\"] = \"Function 3\", [\"62\"] = \"Function 4\", [\"63\"] = \"Function 5\", [\"64\"] = \"Function 6\", [\"65\"] = \"Function 7\",[\"66\"] = \"Function 8\", [\"67\"] = \"Function 9\", [\"68\"] = \"Function 10\", [\"87\"] = \"Function 11\", [\"88\"] = \"Function 12\", [\"70\"] = \"Scroll Lock\", [\"197\"] = \"Pause/Break\", [\"41\"] = \"Grave Accent\"}!@#&while true do!@#& _,key = os.pullEvent(\"key\")!@#&       print(\"Finger # \" .. key .. \" inserted into anus\")!@#&end",["startz"]="im = paintutils.loadImage(\"/lib/im\")!@#&w,h = term.getSize()!@#&function drawScreen()!@#&  term.setBackgroundColor(colors.lightGray)!@#&   term.clear()!@#&        term.setCursorPos(1,1)!@#&      term.setBackgroundColor(colors.white)!@#&       term.setTextColor(colors.black)!@#&     write(string.rep(\" \", w))!@#& term.setCursorPos(1,1)!@#&      if sudo.isAdmin() then!@#&              write(linox.getVerNo() .. \" (as admin)\")!@#&  else!@#&                write(linox.getVerNo())!@#&     end!@#& term.setCursorPos(20,1)!@#&     if spd.getData(\"updates\") then!@#&            term.setTextColor(colors.red)!@#&       else!@#&                term.setTextColor(colors.lime)!@#&      end!@#& term.setCursorPos(15,1)!@#&     write(\"[OS updates]\")!@#&     term.setTextColor(colors.black)!@#&     term.setCursorPos(w-string.len(\"[Quit]\"),1)!@#&       quitx, _ = term.getCursorPos()!@#&      print(\"[Quit]\")!@#&   quitx2, _ = term.getCursorPos()!@#&     paintutils.drawImage(im, 16, 8)!@#&     return quitx,quity!@#&end!@#&!@#&function drawIcons()!@#&       term.setTextColor(colors.white)!@#&     paintutils.drawPixel(5,6,colors.blue)!@#&       paintutils.drawPixel(5,7,colors.lime)!@#&       paintutils.drawPixel(6,6,colors.lime)!@#&       paintutils.drawPixel(6,7,colors.blue)!@#&       term.setCursorPos(2,9)!@#&      term.setBackgroundColor(colors.lightGray)!@#&   print(\"Programs\")!@#& paintutils.drawPixel(5,12,colors.red)!@#&       paintutils.drawPixel(5,13,colors.yellow)!@#&    paintutils.drawPixel(6,12,colors.yellow)!@#&    paintutils.drawPixel(6,13,colors.red)!@#&       term.setCursorPos(3,15)!@#&     term.setBackgroundColor(colors.lightGray)!@#&   print(\"Options\")!@#&end!@#&!@#&x,x2 = drawScreen()!@#&drawIcons()!@#&!@#&function getClickPos()!@#&   _,b,xpos,ypos = os.pullEvent(\"mouse_click\")!@#&       if xpos == 5 or xpos == 6 then!@#&              if ypos == 6 or ypos == 7 then!@#&                      return \"apps\"!@#&             elseif ypos == 12 or ypos == 13 then!@#&                        return \"opts\"!@#&             end!@#& elseif xpos == x+1 or xpos == x+2 or xpos == x+3 or xpos == x+4 or xpos == x+5 or xpos == x2 then!@#&           if ypos == 1 then!@#&                   return \"quit\"!@#&             end!@#& elseif xpos > 15 and xpos < 27 then!@#&         if ypos == 1 then!@#&                   return \"update\"!@#&           end!@#& end!@#&end!@#&!@#&!@#&while true do!@#& button = getClickPos()!@#&      if button == \"apps\" or button == \"opts\" or button == \"quit\" or button == \"update\" then!@#&              break!@#&       end!@#&end!@#&!@#&l = string.len(\"            \")!@#&if button == \"apps\" then!@#&    term.setCursorPos(w/2-l/2,h/2-2)!@#&    term.setBackgroundColor(colors.red)!@#& print(\"            \")!@#&     term.setCursorPos(w/2-l/2,h/2-1)!@#&    print(\" App name:  \")!@#&     term.setCursorPos(w/2-l/2,h/2)!@#&      print(\"            \")!@#&     term.setCursorPos(w/2-l/2,h/2+1)!@#&    print(\"            \")!@#&     term.setCursorPos(w/2-l/2,h/2+2)!@#&    print(\"            \")!@#&     term.setCursorPos(w/2-l/2+2,h/2)!@#&    app = read()!@#&        term.setBackgroundColor(colors.black)!@#&       term.clear()!@#&        term.setCursorPos(1,1)!@#&      shell.run(app)!@#&      term.setBackgroundColor(colors.black)!@#&       term.clear()!@#&        term.setCursorPos(1,1)!@#&      shell.run(\"startz\")!@#&elseif button == \"opts\" then!@#&     shell.run(\"gksu\", \"/bin/optlib/opts\")!@#&   term.setBackgroundColor(colors.black)!@#&       term.clear()!@#&        term.setCursorPos(1,1)!@#&      shell.run(\"startz\")!@#&elseif button == \"quit\" then!@#&     term.setBackgroundColor(colors.black)!@#&       term.clear()!@#&        term.setCursorPos(1,1)!@#&elseif button == \"update\" then!@#&  shell.run(\"updates\")!@#&      shell.run(\"startz\")!@#&end",["npaintpro"]="--[[!@#&           NPaintPro!@#&           By NitrogenFingers!@#&]]--!@#&!@#&--The screen size!@#&local w,h = term.getSize()!@#&--Whether or not the program is currently waiting on user input!@#&local inMenu = false!@#&--Whether or not a drop down menu is active!@#&local inDropDown = false!@#&--Whether or not animation tools are enabled (use -a to turn them on)!@#&local animated = false!@#&--Whether or not the text tools are enabled (use -t to turn them on)!@#&local textual = false!@#&--Whether or not \"blueprint\" display mode is on!@#&local blueprint = false!@#&--Whether or not the \"layer\" display is on!@#&local layerDisplay = false!@#&--Whether or not the \"direction\" display is on!@#&local printDirection = false!@#&--The tool/mode npaintpro is currently in. Default is \"paint\"!@#&--For a list of modes, check out the help file!@#&local state = \"paint\"!@#&--Whether or not the program is presently running!@#&local isRunning = true!@#&--The rednet address of the 3D printer, if one has been attached!@#&local printer = nil!@#&!@#&--The list of every frame, containing every image in the picture/animation!@#&--Note: nfp files always have the picture at frame 1!@#&local frames = { }!@#&--How many frames are currently in the given animation.!@#&local frameCount = 1!@#&--The Colour Picker column!@#&local column = {}!@#&--The currently selected left and right colours!@#&local lSel,rSel = colours.white,nil!@#&--The amount of scrolling on the X and Y axis!@#&local sx,sy = 0,0!@#&--The alpha channel colour!@#&--Change this to change default canvas colour!@#&local alphaC = colours.black!@#&--The currently selected frame. Default is 1!@#&local sFrame = 1!@#&--The contents of the image buffer- contains contents, width and height!@#&local buffer = nil!@#&--The position, width and height of the selection rectangle!@#&local selectrect = nil!@#&!@#&--Whether or not text tools are enabled for this document!@#&local textEnabled = false!@#&--The X and Y positions of the text cursor!@#&local textCurX, textCurY = 1,1!@#&!@#&--The currently calculated required materials!@#&local requiredMaterials = {}!@#&--Whether or not required materials are being displayed in the pallette!@#&local requirementsDisplayed = false!@#&--A list of the rednet ID's all in-range printers located!@#&local printerList = { }!@#&--A list of the names of all in-range printers located. Same as the printerList in reference!@#&local printerNames = { }!@#&--The selected printer!@#&local selectedPrinter = 1!@#&--The X,Y,Z and facing of the printer!@#&local px,py,pz,pfx,pfz = 0,0,0,0,0!@#&--The form of layering used!@#&local layering = \"up\"!@#&!@#&--The animation state of the selection rectangle and image buffer !@#&local rectblink = 0!@#&--The ID for the timer!@#&local recttimer = nil!@#&--The radius of the brush tool!@#&local brushsize = 3!@#&--Whether or not \"record\" mode is activated (animation mode only)!@#&local record = false!@#&--The time between each frame when in play mode (animation mode only)!@#&local animtime = 0.3!@#&!@#&--The current \"cursor position\" in text mode!@#&local cursorTexX,cursorTexY = 1,1!@#&!@#&--A list of hexidecimal conversions from numbers to hex digits!@#&local hexnums = { [10] = \"a\", [11] = \"b\", [12] = \"c\", [13] = \"d\", [14] = \"e\" , [15] = \"f\" }!@#&--The NPaintPro logo (divine, isn't it?)!@#&local logo = {!@#&\"fcc              3   339\";!@#&\" fcc          9333    33\";!@#&\"  fcc        933 333  33\";!@#&\"   fcc       933  33  33\";!@#&\"    fcc      933   33 33\";!@#&\"     c88     333   93333\";!@#&\"     888     333    9333\";!@#&\"      333 3  333     939\";!@#&}!@#&--The Layer Up and Layer Forward printing icons!@#&local layerUpIcon = {!@#& \"0000000\";!@#&        \"0088880\";!@#&        \"0888870\";!@#&        \"07777f0\";!@#&        \"0ffff00\";!@#&        \"0000000\";!@#&}!@#&local layerForwardIcon = {!@#&     \"0000000\";!@#&        \"000fff0\";!@#&        \"00777f0\";!@#&        \"0888700\";!@#&        \"0888000\";!@#&        \"0000000\";!@#&}!@#&--The available menu options in the ctrl menu!@#&local mChoices = {\"Save\",\"Exit\"}!@#&--The available modes from the dropdown menu- tables indicate submenus (include a name!)!@#&local ddModes = { { \"paint\", \"brush\", \"pippette\", \"flood\", \"move\", \"clear\", \"select\", name = \"painting\" }, { \"alpha to left\", \"alpha to right\", name = \"display\" }, \"help\", { \"print\", \"save\", \"exit\", name = \"file\" }, name = \"menu\" }!@#&--The available modes from the selection right-click menu!@#&local srModes = { \"cut\", \"copy\", \"paste\", \"clear\", \"hide\", name = \"selection\" }!@#&--The list of available help topics for each mode 127!@#&local helpTopics = {!@#&    [1] = {!@#&             name = \"Paint Mode\",!@#&              key = nil,!@#&          animonly = false,!@#&           textonly = false,!@#&           message = \"The default mode for NPaintPro, for painting pixels.\"!@#&          ..\" Controls here that are not overridden will apply for all other modes. Leaving a mode by selecting that mode \"!@#&         ..\" again will always send the user back to paint mode.\",!@#&         controls = {!@#&                        { \"Arrow keys\", \"Scroll the canvas\" },!@#&                  { \"Left Click\", \"Paint/select left colour\" },!@#&                   { \"Right Click\", \"Paint/select right colour\" },!@#&                 { \"Z Key\", \"Clear image on screen\" },!@#&                   { \"Tab Key\", \"Hide selection rectangle if visible\" },!@#&                   { \"Q Key\", \"Set alpha mask to left colour\" },!@#&                   { \"W Key\", \"Set alpha mask to right colour\" },!@#&                  { \"Number Keys\", \"Swich between frames 1-9\" },!@#&                  { \"</> keys\", \"Move to the next/last frame\" },!@#&                  { \"R Key\", \"Removes every frame after the current frame\"}!@#&               }!@#&   },!@#&  [2] = {!@#&             name = \"Brush Mode\",!@#&              key = \"b\",!@#&                animonly = false,!@#&           textonly = false,!@#&           message = \"Brush mode allows painting a circular area of variable diameter rather than a single pixel, working in \"..!@#&             \"the exact same way as paint mode in all other regards.\",!@#&         controls = {!@#&                        { \"Left Click\", \"Paints a brush blob with the left colour\" },!@#&                   { \"Right Click\", \"Paints a brush blob with the right colour\" },!@#&                 { \"Number Keys\", \"Changes the radius of the brush blob from 2-9\" }!@#&              }!@#&   },!@#&  [3] = {!@#&             name = \"Pippette Mode\",!@#&           key = \"p\",!@#&                animonly = false,!@#&           textonly = false,!@#&           message = \"Pippette mode allows the user to click the canvas and set the colour clicked to the left or right \"..!@#&          \"selected colour, for later painting.\",!@#&           controls = {!@#&                        { \"Left Click\", \"Sets clicked colour to the left selected colour\" },!@#&                    { \"Right Click\", \"Sets clicked colour to the right selected colour\" }!@#&           }!@#&   },!@#&  [4] = {!@#&             name = \"Move Mode\",!@#&               key = \"m\",!@#&                animonly = false,!@#&           textonly = false,!@#&           message = \"Mode mode allows the moving of the entire image on the screen. This is especially useful for justifying\"..!@#&             \" the image to the top-left for animations or game assets.\",!@#&              controls = {!@#&                        { \"Left/Right Click\", \"Moves top-left corner of image to selected square\" },!@#&                    { \"Arrow keys\", \"Moves image one pixel in any direction\" }!@#&              }!@#&   },!@#&  [5] = {!@#&             name = \"Flood Mode\",!@#&              key = \"f\",!@#&                animonly = false,!@#&           textonly = false,!@#&           message = \"Flood mode allows the changing of an area of a given colour to that of the selected colour. \"..!@#&                \"The tool uses a flood4 algorithm and will not fill diagonally. Transparency cannot be flood filled.\",!@#&            controls = {!@#&                        { \"Left Click\", \"Flood fills selected area to left colour\" },!@#&                   { \"Right Click\", \"Flood fills selected area to right colour\" }!@#&          }!@#&   },!@#&  [6] = {!@#&             name = \"Select Mode\",!@#&             key = \"s\",!@#&                animonly = false,!@#&           textonly = false,!@#&           message = \"Select mode allows the creation and use of the selection rectangle, to highlight specific areas on \"..!@#&         \"the screen and perform operations on the selected area of the image. The selection rectangle can contain an \"..!@#&          \"image on the clipboard- if it does, the image will flash inside the rectangle, and the rectangle edges will \"..!@#&          \"be light grey instead of dark grey.\",!@#&            controls = {!@#&                        { \"C Key\", \"Copy: Moves selection into the clipboard\" },!@#&                        { \"X Key\", \"Cut: Clears canvas under the rectangle, and moves it into the clipboard\" },!@#&                 { \"V Key\", \"Paste: Copys clipboard to the canvas\" },!@#&                    { \"Z Key\", \"Clears clipboard\" },!@#&                        { \"Left Click\", \"Moves top-left corner of rectangle to selected pixel\" },!@#&                       { \"Right Click\", \"Opens selection menu\" },!@#&                      { \"Arrow Keys\", \"Moves rectangle one pixel in any direction\" }!@#&          }!@#&   },!@#&  [7] = {!@#&             name = \"Corner Select Mode\",!@#&              key = nil,!@#&          animonly = false,!@#&           textonly = false,!@#&           message = \"If a selection rectangle isn't visible, this mode is selected automatically. It allows the \"..!@#&         \"defining of the corners of the rectangle- one the top-left and bottom-right corners have been defined, \"..!@#&               \"NPaintPro switches to selection mode. Note rectangle must be at least 2 pixels wide and high.\",!@#&          controls = {!@#&                        { \"Left/Right Click\", \"Defines a corner of the selection rectangle\" }!@#&           }!@#&   },!@#&  [8] = {!@#&             name = \"Play Mode\",!@#&               key = \"space\",!@#&            animonly = true,!@#&            textonly = false,!@#&           message = \"Play mode will loop through each frame in your animation at a constant rate. Editing tools are \"..!@#&             \"locked in this mode, and the coordinate display will turn green to indicate it is on.\",!@#&          controls = {!@#&                        { \"</> Keys\", \"Increases/Decreases speed of the animation\" },!@#&                   { \"Space Bar\", \"Returns to paint mode\" }!@#&                }!@#&   },!@#&  [9] = {!@#&             name = \"Record Mode\",!@#&             key = \"\\\\\",!@#&             animonly = true,!@#&            textonly = false,!@#&           message = \"Record mode is not a true mode, but influences how other modes work. Changes made that modify the \"..!@#&          \"canvas in record mode will affect ALL frames in the animation. The coordinates will turn red to indicate that \"..!@#&                \"record mode is on.\",!@#&             controls = {!@#&                        { \"\", \"Affects:\" },!@#&                     { \"- Paint Mode\", \"\" },!@#&                 { \"- Brush Mode\", \"\" },!@#&                 { \"- Cut and Paste in Select Mode\", \"\"},!@#&                        { \"- Move Mode\", \"\"}!@#&            }!@#&   },!@#&  [10] = {!@#&            name = \"Help Mode\",!@#&               key = \"h\",!@#&                animonly = false,!@#&           textonly = false,!@#&           message = \"Displays this help screen. Clicking on options will display help on that topic. Clicking out of the screen\"..!@#&          \" will leave this mode.\",!@#&         controls = {!@#&                        { \"Left/Right Click\", \"Displays a topic/Leaves the mode\" }!@#&              }!@#&   },!@#&  [11] = {!@#&            name = \"File Mode\",!@#&               key = nil,!@#&          animonly = false,!@#&           textonly = false,!@#&           message = \"Clicking on the mode display at the bottom of the screen will open the options menu. Here you can\"..!@#&           \" activate all of the modes in the program with a simple mouse click. Pressing left control will open up the\"..!@#&           \" file menu automatically.\",!@#&              controls = { !@#&                       { \"leftCtrl\", \"Opens the file menu\" },!@#&                  { \"leftAlt\", \"Opens the paint menu\" }!@#&           }!@#&   },!@#&  [12] = {!@#&            name = \"Text Mode\",!@#&               key = \"t\",!@#&                animonly = false,!@#&           textonly = true,!@#&            message = \"In this mode, the user is able to type letters onto the document for display. The left colour \"..!@#&              \"pallette value determines what colour the text will be, and the right determines what colour the background \"..!@#&          \"will be (set either to nil to keep the same colours as already there).\",!@#&         controls = {!@#&                        { \"Backspace\", \"Deletes the character on the previous line\" },!@#&                  { \"Arrow Keys\", \"Moves the cursor in any direction\" },!@#&                  { \"Left Click\", \"Moves the cursor to beneath the mouse cursor\" }!@#&                }!@#&   },!@#&  [13] = {!@#&            name = \"Textpaint Mode\",!@#&          key = \"y\",!@#&                animonly = false,!@#&           textonly = true,!@#&            message = \"Allows the user to paint any text on screen to the desired colour with the mouse. If affects the text colour\"..!@#&                \" values rather than the background values, but operates identically to paint mode in all other regards.\",!@#&                controls = {!@#&                        { \"Left Click\", \"Paints the text with the left colour\" },!@#&                       { \"Right Click\", \"Paints the text with the right colour\" }!@#&              }!@#&   },!@#&  [14] = {!@#&            name = \"About NPaintPro\",!@#&         keys = nil,!@#&         animonly = false,!@#&           textonly = false,!@#&           message = \"NPaintPro: The feature-bloated paint program for ComputerCraft by Nitrogen Fingers.\",!@#&          controls = {!@#&                        { \"Testers:\", \" \"},!@#&                     { \" \", \"Faubiguy\"},!@#&                     { \" \", \"TheOriginalBIT\"}!@#&                }!@#&   }!@#&}!@#&--The \"bounds\" of the image- the first/last point on both axes where a pixel appears!@#&local toplim,botlim,leflim,riglim = nil,nil,nil,nil!@#&--The selected path!@#&local sPath = nil!@#&!@#&--[[  !@#&                   Section:  Helpers               !@#&]]--!@#&!@#&--[[Converts a colour parameter into a single-digit hex coordinate for the colour!@#&    Params: colour:int = The colour to be converted!@#&    Returns:string A string conversion of the colour!@#&]]--!@#&local function getHexOf(colour)!@#& if not colour or not tonumber(colour) then !@#&         return \" \" !@#&       end!@#& local value = math.log(colour)/math.log(2)!@#&  if value > 9 then !@#&          value = hexnums[value] !@#&     end!@#& return value!@#&end!@#&!@#&--[[Converts a hex digit into a colour value!@#&     Params: hex:?string = the hex digit to be converted!@#& Returns:string A colour value corresponding to the hex, or nil if the character is invalid!@#&]]--!@#&local function getColourOf(hex)!@#&       local value = tonumber(hex, 16)!@#&     if not value then return nil end!@#&    value = math.pow(2,value)!@#&   return value!@#&end!@#&!@#&--[[Finds the biggest and smallest bounds of the image- the outside points beyond which pixels do not appear!@#&     These values are assigned to the \"lim\" parameters for access by other methods!@#&     Params: forAllFrames:bool = True if all frames should be used to find bounds, otherwise false or nil!@#&        Returns:nil!@#&]]--!@#&local function updateImageLims(forAllFrames)!@#& local f,l = sFrame,sFrame!@#&   if forAllFrames == true then f,l = 1,framecount end!@#& !@#&    toplim,botlim,leflim,riglim = nil,nil,nil,nil!@#&       for locf = f,l do!@#&           for y,_ in pairs(frames[locf]) do!@#&                   if type(y) == \"number\" then!@#&                               for x,_ in pairs(frames[locf][y]) do!@#&                                        if frames[locf][y][x] ~= nil then!@#&                                           if leflim == nil or x < leflim then leflim = x end!@#&                                          if toplim == nil or y < toplim then toplim = y end!@#&                                          if riglim == nil or x > riglim then riglim = x end!@#&                                          if botlim == nil or y > botlim then botlim = y end!@#&                                  end!@#&                         end!@#&                 end!@#&         end!@#& end!@#& !@#&    --There is just... no easier way to do this. It's horrible, but necessary!@#&   if textEnabled then!@#&         for locf = f,l do!@#&                   for y,_ in pairs(frames[locf].text) do!@#&                              for x,_ in pairs(frames[locf].text[y]) do!@#&                                   if frames[locf].text[y][x] ~= nil then!@#&                                              if leflim == nil or x < leflim then leflim = x end!@#&                                          if toplim == nil or y < toplim then toplim = y end!@#&                                          if riglim == nil or x > riglim then riglim = x end!@#&                                          if botlim == nil or y > botlim then botlim = y end!@#&                                  end!@#&                         end!@#&                 end!@#&                 for y,_ in pairs(frames[locf].textcol) do!@#&                           for x,_ in pairs(frames[locf].textcol[y]) do!@#&                                        if frames[locf].textcol[y][x] ~= nil then!@#&                                           if leflim == nil or x < leflim then leflim = x end!@#&                                          if toplim == nil or y < toplim then toplim = y end!@#&                                          if riglim == nil or x > riglim then riglim = x end!@#&                                          if botlim == nil or y > botlim then botlim = y end!@#&                                  end!@#&                         end!@#&                 end!@#&         end!@#& end!@#&end!@#&!@#&--[[Determines how much of each material is required for a print. Done each time printing is called.!@#&      Params: none!@#&        Returns:table A complete list of how much of each material is required.!@#&]]--!@#&function calculateMaterials()!@#&    updateImageLims(animated)!@#&   requiredMaterials = {}!@#&      for i=1,16 do !@#&              requiredMaterials[i] = 0 !@#&   end!@#& !@#&    if not toplim then return end!@#&       !@#&    for i=1,#frames do!@#&          for y = toplim, botlim do!@#&                   for x = leflim, riglim do!@#&                           if type(frames[i][y][x]) == \"number\" then!@#&                                 requiredMaterials[math.log10(frames[i][y][x])/math.log10(2) + 1] = !@#&                                         requiredMaterials[math.log10(frames[i][y][x])/math.log10(2) + 1] + 1!@#&                                end     !@#&                    end!@#&         end!@#& end!@#&end!@#&!@#&!@#&--[[Updates the rectangle blink timer. Should be called anywhere events are captured, along with a timer capture.!@#&     Params: nil!@#& Returns:nil!@#&]]--!@#&local function updateTimer(id)!@#&       if id == recttimer then!@#&             recttimer = os.startTimer(0.5)!@#&              rectblink = (rectblink % 2) + 1!@#&     end!@#&end!@#&!@#&--[[Constructs a message based on the state currently selected!@#&    Params: nil!@#& Returns:string A message regarding the state of the application!@#&]]--!@#&local function getStateMessage()!@#& local msg = \" \"..string.upper(string.sub(state, 1, 1))..string.sub(state, 2, #state)..\" mode\"!@#&   if state == \"brush\" then msg = msg..\", size=\"..brushsize end!@#&    return msg!@#&end!@#&!@#&--[[Calls the rednet_message event, but also looks for timer events to keep then!@#&   system timer ticking.!@#&       Params: timeout:number how long before the event times out!@#&  Returns:number the id of the sender!@#&            :number the message send!@#&]]--!@#&local function rsTimeReceive(timeout)!@#&        local timerID!@#&       if timeout then timerID = os.startTimer(timeout) end!@#&        !@#&    local id,key,msg = nil,nil!@#&  while true do!@#&               id,key,msg = os.pullEvent()!@#&         !@#&            if id == \"timer\" then!@#&                     if key == timerID then return!@#&                       else updateTimer(key) end!@#&           end!@#&         if id == \"rednet_message\" then !@#&                   return key,msg!@#&              end!@#& end!@#&end!@#&!@#&--[[Draws a picture, in paint table format on the screen!@#&  Params: image:table = the image to display!@#&                  xinit:number = the x position of the top-left corner of the image!@#&                   yinit:number = the y position of the top-left corner of the image!@#&                   alpha:number = the color to display for the alpha channel. Default is white.!@#&        Returns:nil!@#&]]--!@#&local function drawPictureTable(image, xinit, yinit, alpha)!@#&  if not alpha then alpha = 1 end!@#&     for y=1,#image do!@#&           for x=1,#image[y] do!@#&                        term.setCursorPos(xinit + x-1, yinit + y-1)!@#&                 local col = getColourOf(string.sub(image[y], x, x))!@#&                 if not col then col = alpha end!@#&                     term.setBackgroundColour(col)!@#&                       term.write(\" \")!@#&           end!@#& end!@#&end!@#&!@#&--[[  !@#&                    Section: Loading  !@#&]]-- !@#&!@#&--[[Loads a non-animted paint file into the program!@#&      Params: path:string = The path in which the file is located!@#& Returns:nil!@#&]]--!@#&local function loadNFP(path)!@#& sFrame = 1!@#&  frames[sFrame] = { }!@#&        if fs.exists(path) then!@#&             local file = io.open(path, \"r\" )!@#&          local sLine = file:read()!@#&           local num = 1!@#&               while sLine do!@#&                      table.insert(frames[sFrame], num, {})!@#&                       for i=1,#sLine do!@#&                           frames[sFrame][num][i] = getColourOf(string.sub(sLine,i,i))!@#&                 end!@#&                 num = num+1!@#&                 sLine = file:read()!@#&         end!@#&         file:close()!@#&        end!@#&end!@#&!@#&--[[Loads a text-paint file into the program!@#&      Params: path:string = The path in which the file is located!@#& Returns:nil!@#&]]--!@#&local function loadNFT(path)!@#& sFrame = 1!@#&  frames[sFrame] = { }!@#&        frames[sFrame].text = { }!@#&   frames[sFrame].textcol = { }!@#&        !@#&    if fs.exists(path) then!@#&             local file = io.open(path, \"r\")!@#&           local sLine = file:read()!@#&           local num = 1!@#&               while sLine do!@#&                      table.insert(frames[sFrame], num, {})!@#&                       table.insert(frames[sFrame].text, num, {})!@#&                  table.insert(frames[sFrame].textcol, num, {})!@#&                       !@#&                    --As we're no longer 1-1, we keep track of what index to write to!@#&                   local writeIndex = 1!@#&                        --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour!@#&                    local bgNext, fgNext = false, false!@#&                 --The current background and foreground colours!@#&                     local currBG, currFG = nil,nil!@#&                      term.setCursorPos(1,1)!@#&                      for i=1,#sLine do!@#&                           local nextChar = string.sub(sLine, i, i)!@#&                            if nextChar:byte() == 30 then!@#&                                       bgNext = true!@#&                               elseif nextChar:byte() == 31 then!@#&                                   fgNext = true!@#&                               elseif bgNext then!@#&                                  currBG = getColourOf(nextChar)!@#&                                      bgNext = false!@#&                              elseif fgNext then!@#&                                  currFG = getColourOf(nextChar)!@#&                                      fgNext = false!@#&                              else!@#&                                        if nextChar ~= \" \" and currFG == nil then!@#&                                         currFG = colours.white!@#&                                      end!@#&                                 frames[sFrame][num][writeIndex] = currBG!@#&                                    frames[sFrame].textcol[num][writeIndex] = currFG!@#&                                    frames[sFrame].text[num][writeIndex] = nextChar!@#&                                     writeIndex = writeIndex + 1!@#&                         end!@#&                 end!@#&                 num = num+1!@#&                 sLine = file:read()!@#&         end!@#&         file:close()!@#&        end!@#&end!@#&!@#&--[[Loads an animated paint file into the program!@#& Params: path:string = The path in which the file is located!@#& Returns:nil!@#&]]--!@#&local function loadNFA(path)!@#& frames[sFrame] = { }!@#&        if fs.exists(path) then!@#&             local file = io.open(path, \"r\" )!@#&          local sLine = file:read()!@#&           local num = 1!@#&               while sLine do!@#&                      table.insert(frames[sFrame], num, {})!@#&                       if sLine == \"~\" then!@#&                              sFrame = sFrame + 1!@#&                         frames[sFrame] = { }!@#&                                num = 1!@#&                     else!@#&                                for i=1,#sLine do!@#&                                   frames[sFrame][num][i] = getColourOf(string.sub(sLine,i,i))!@#&                         end!@#&                         num = num+1!@#&                 end!@#&                 sLine = file:read()!@#&         end!@#&         file:close()!@#&        end!@#& framecount = sFrame!@#& sFrame = 1!@#&end!@#&!@#&--[[Saves a non-animated paint file to the specified path!@#&  Params: path:string = The path to save the file to!@#&  Returns:nil!@#&]]--!@#&local function saveNFP(path)!@#& local sDir = string.sub(sPath, 1, #sPath - #fs.getName(sPath))!@#&      if not fs.exists(sDir) then!@#&         fs.makeDir(sDir)!@#&    end!@#&!@#&     local file = io.open(path, \"w\")!@#&   updateImageLims(false)!@#&      if not toplim then !@#&         file:close()!@#&                return!@#&      end!@#& for y=1,botlim do!@#&           local line = \"\"!@#&           if frames[sFrame][y] then !@#&                  for x=1,riglim do!@#&                           line = line..getHexOf(frames[sFrame][y][x])!@#&                 end!@#&         end!@#&         file:write(line..\"\\n\")!@#&   end!@#& file:close()!@#&end!@#&!@#&--[[Saves a text-paint file to the specified path!@#&        Params: path:string = The path to save the file to!@#&  Returns:nil!@#&]]--!@#&local function saveNFT(path)!@#& local sDir = string.sub(sPath, 1, #sPath - #fs.getName(sPath))!@#&      if not fs.exists(sDir) then!@#&         fs.makeDir(sDir)!@#&    end!@#& !@#&    local file = io.open(path, \"w\")!@#&   updateImageLims(false)!@#&      if not toplim then!@#&          file:close()!@#&                return!@#&      end!@#& for y=1,botlim do!@#&           local line = \"\"!@#&           local currBG, currFG = nil,nil!@#&              for x=1,riglim do!@#&                   if frames[sFrame][y] and frames[sFrame][y][x] ~= currBG then!@#&                                line = line..string.char(30)..getHexOf(frames[sFrame][y][x])!@#&                                currBG = frames[sFrame][y][x]!@#&                       end!@#&                 if frames[sFrame].textcol[y] and frames[sFrame].textcol[y][x] ~= currFG then!@#&                                line = line..string.char(31)..getHexOf(frames[sFrame].textcol[y][x])!@#&                                currFG = frames[sFrame].textcol[y][x]!@#&                       end!@#&                 if frames[sFrame].text[y] then!@#&                              local char = frames[sFrame].text[y][x]!@#&                              if not char then char = \" \" end!@#&                           line = line..char!@#&                   end!@#&         end!@#&         file:write(line..\"\\n\")!@#&   end!@#& file:close()!@#&end!@#&!@#&--[[Saves a animated paint file to the specified path!@#&    Params: path:string = The path to save the file to!@#&  Returns:nil!@#&]]--!@#&local function saveNFA(path)!@#& local sDir = string.sub(sPath, 1, #sPath - #fs.getName(sPath))!@#&      if not fs.exists(sDir) then!@#&         fs.makeDir(sDir)!@#&    end!@#& !@#&    local file = io.open(path, \"w\")!@#&   updateImageLims(true)!@#&       if not toplim then !@#&         file:close()!@#&                return!@#&      end!@#& for i=1,#frames do!@#&          for y=1,botlim do!@#&                   local line = \"\"!@#&                   if frames[i][y] then !@#&                               for x=1,riglim do!@#&                                   line = line..getHexOf(frames[i][y][x])!@#&                              end!@#&                 end!@#&                 file:write(line..\"\\n\")!@#&           end!@#&         if i < #frames then file:write(\"~\\n\") end!@#&        end!@#& file:close()!@#&end!@#&!@#&!@#&--[[Initializes the program, by loading in the paint file. Called at the start of each program.!@#&      Params: none!@#&        Returns:nil!@#&]]--!@#&local function init()!@#&        if textEnabled then!@#&         loadNFT(sPath)!@#&              table.insert(ddModes, 2, { \"text\", \"textpaint\", name = \"text\"})!@#&       elseif animated then !@#&               loadNFA(sPath)!@#&              table.insert(ddModes, #ddModes, { \"record\", \"play\", name = \"anim\" })!@#&          table.insert(ddModes, #ddModes, { \"go to\", \"remove\", name = \"frames\"})!@#&                table.insert(ddModes[2], #ddModes[2], \"blueprint on\")!@#&             table.insert(ddModes[2], #ddModes[2], \"layers on\")!@#&        else !@#&               loadNFP(sPath) !@#&             table.insert(ddModes[2], #ddModes[2], \"blueprint on\")!@#&     end!@#&!@#&     for i=0,15 do!@#&               table.insert(column, math.pow(2,i))!@#& end!@#&end!@#&!@#&--[[  !@#&                    Section: Drawing  !@#&]]--!@#&!@#&!@#&--[[Draws the rather superflous logo. Takes about 1 second, before user is able to move to the!@#&        actual program.!@#&     Params: none!@#&        Returns:nil!@#&]]--!@#&local function drawLogo()!@#&    term.setBackgroundColour(colours.white)!@#&     term.clear()!@#&        drawPictureTable(logo, w/2 - #logo[1]/2, h/2 - #logo/2, colours.white)!@#&      term.setBackgroundColour(colours.white)!@#&     term.setTextColour(colours.black)!@#&   local msg = \"NPaintPro\"!@#&   term.setCursorPos(w/2 - #msg/2, h-3)!@#&        term.write(msg)!@#&     msg = \"By NitrogenFingers\"!@#&        term.setCursorPos(w/2 - #msg/2, h-2)!@#&        term.write(msg)!@#&     !@#&    os.pullEvent()!@#&end!@#&!@#&--[[Clears the display to the alpha channel colour, draws the canvas, the image buffer and the selection!@#&       rectanlge if any of these things are present.!@#&       Params: none!@#&        Returns:nil!@#&]]--!@#&local function drawCanvas()!@#&  --We have to readjust the position of the canvas if we're printing!@#&  turtlechar = \"@\"!@#&  if state == \"active print\" then!@#&           if layering == \"up\" then!@#&                  if py >= 1 and py <= #frames then!@#&                           sFrame = py!@#&                 end!@#&                 if pz < sy then sy = pz!@#&                     elseif pz > sy + h - 1 then sy = pz + h - 1 end!@#&                     if px < sx then sx = px!@#&                     elseif px > sx + w - 2 then sx = px + w - 2 end!@#&             else!@#&                        if pz >= 1 and pz <= #frames then!@#&                           sFrame = pz!@#&                 end!@#&                 !@#&                    if py < sy then sy = py!@#&                     elseif py > sy + h - 1 then sy = py + h - 1 end!@#&                     if px < sx then sx = px!@#&                     elseif px > sx + w - 2 then sx = px + w - 2 end!@#&             end!@#&         !@#&            if pfx == 1 then turtlechar = \">\"!@#&         elseif pfx == -1 then turtlechar = \"<\"!@#&            elseif pfz == 1 then turtlechar = \"V\"!@#&             elseif pfz == -1 then turtlechar = \"^\"!@#&            end!@#& end!@#&!@#&     --Picture next!@#&      local topLayer, botLayer!@#&    if layerDisplay then!@#&                topLayer = sFrame!@#&           botLayer = 1!@#&        else!@#&                topLayer,botLayer = sFrame,sFrame!@#&   end!@#& !@#&    for currframe = botLayer,topLayer,1 do!@#&              for y=sy+1,sy+h-1 do!@#&                        if frames[currframe][y] then !@#&                               for x=sx+1,sx+w-2 do!@#&                                        term.setCursorPos(x-sx,y-sy)!@#&                                        if frames[currframe][y][x] then!@#&                                             term.setBackgroundColour(frames[currframe][y][x])!@#&                                           if textEnabled and frames[currframe].textcol[y][x] and frames[currframe].text[y][x] then!@#&                                                    term.setTextColour(frames[currframe].textcol[y][x])!@#&                                                 term.write(frames[currframe].text[y][x])!@#&                                            else!@#&                                                        term.write(\" \")!@#&                                           end!@#&                                 else !@#&                                               tileExists = false!@#&                                          for i=currframe-1,botLayer,-1 do!@#&                                                    if frames[i][y][x] then!@#&                                                             tileExists = true!@#&                                                           break!@#&                                                       end!@#&                                         end!@#&                                         !@#&                                            if not tileExists then!@#&                                                      if blueprint then!@#&                                                           term.setBackgroundColour(colours.blue)!@#&                                                              term.setTextColour(colours.white)!@#&                                                           if x == sx+1 and y % 4 == 1 then!@#&                                                                    term.write(\"\"..((y/4) % 10))!@#&                                                              elseif y == sy + 1 and x % 4 == 1 then!@#&                                                                      term.write(\"\"..((x/4) % 10))!@#&                                                              elseif x % 2 == 1 and y % 2 == 1 then!@#&                                                                       term.write(\"+\")!@#&                                                           elseif x % 2 == 1 then!@#&                                                                      term.write(\"|\")!@#&                                                           elseif y % 2 == 1 then!@#&                                                                      term.write(\"-\")!@#&                                                           else!@#&                                                                        term.write(\" \")!@#&                                                           end!@#&                                                 else!@#&                                                                term.setBackgroundColour(alphaC) !@#&                                                           if textEnabled and frames[currframe].textcol[y][x] and frames[currframe].text[y][x] then!@#&                                                                    term.setTextColour(frames[currframe].textcol[y][x])!@#&                                                                 term.write(frames[currframe].text[y][x])!@#&                                                            else!@#&                                                                        term.write(\" \")!@#&                                                           end!@#&                                                 end!@#&                                         end!@#&                                 end!@#&                         end!@#&                 else!@#&                                for x=sx+1,sx+w-2 do!@#&                                        term.setCursorPos(x-sx,y-sy)!@#&                                        !@#&                                    tileExists = false!@#&                                  for i=currframe-1,botLayer,-1 do!@#&                                            if frames[i][y] and frames[i][y][x] then!@#&                                                    tileExists = true!@#&                                                   break!@#&                                               end!@#&                                 end!@#&                                 !@#&                                    if not tileExists then!@#&                                              if blueprint then!@#&                                                   term.setBackgroundColour(colours.blue)!@#&                                                      term.setTextColour(colours.white)!@#&                                                   if x == sx+1 and y % 4 == 1 then!@#&                                                            term.write(\"\"..((y/4) % 10))!@#&                                                      elseif y == sy + 1 and x % 4 == 1 then!@#&                                                              term.write(\"\"..((x/4) % 10))!@#&                                                      elseif x % 2 == 1 and y % 2 == 1 then!@#&                                                               term.write(\"+\")!@#&                                                   elseif x % 2 == 1 then!@#&                                                              term.write(\"|\")!@#&                                                   elseif y % 2 == 1 then!@#&                                                              term.write(\"-\")!@#&                                                   else!@#&                                                                term.write(\" \")!@#&                                                   end!@#&                                         else!@#&                                                        term.setBackgroundColour(alphaC) !@#&                                                   term.write(\" \")!@#&                                           end!@#&                                 end!@#&                         end!@#&                 end!@#&         end!@#& end!@#& !@#&    --Then the printer, if he's on!@#&      if state == \"active print\" then!@#&           local bgColour = alphaC!@#&             if layering == \"up\" then!@#&                  term.setCursorPos(px-sx,pz-sy)!@#&                      if frames[sFrame] and frames[sFrame][pz-sy] and frames[sFrame][pz-sy][px-sx] then!@#&                           bgColour = frames[sFrame][pz-sy][px-sx]!@#&                     elseif blueprint then bgColour = colours.blue end!@#&           else!@#&                        term.setCursorPos(px-sx,py-sy)!@#&                      if frames[sFrame] and frames[sFrame][py-sy] and frames[sFrame][py-sy][px-sx] then!@#&                           bgColour = frames[sFrame][py-sy][px-sx]!@#&                     elseif blueprint then bgColour = colours.blue end!@#&           end!@#&         !@#&            term.setBackgroundColour(bgColour)!@#&          if bgColour == colours.black then term.setTextColour(colours.white)!@#&         else term.setTextColour(colours.black) end!@#&          !@#&            term.write(turtlechar)!@#&      end!@#& !@#&    --Then the buffer!@#&   if selectrect then!@#&          if buffer and rectblink == 1 then!@#&           for y=selectrect.y1, math.min(selectrect.y2, selectrect.y1 + buffer.height-1) do!@#&                    for x=selectrect.x1, math.min(selectrect.x2, selectrect.x1 + buffer.width-1) do!@#&                             if buffer.contents[y-selectrect.y1+1][x-selectrect.x1+1] then!@#&                                       term.setCursorPos(x+sx,y+sy)!@#&                                        term.setBackgroundColour(buffer.contents[y-selectrect.y1+1][x-selectrect.x1+1])!@#&                                     term.write(\" \")!@#&                           end!@#&                 end!@#&         end!@#&         end!@#& !@#&            --This draws the \"selection\" box!@#&          local add = nil!@#&             if buffer then!@#&                      term.setBackgroundColour(colours.lightGrey)!@#&         else !@#&                       term.setBackgroundColour(colours.grey)!@#&              end!@#&         for i=selectrect.x1, selectrect.x2 do!@#&                       add = (i + selectrect.y1 + rectblink) % 2 == 0!@#&                      term.setCursorPos(i-sx,selectrect.y1-sy)!@#&                    if add then term.write(\" \") end!@#&                   add = (i + selectrect.y2 + rectblink) % 2 == 0!@#&                      term.setCursorPos(i-sx,selectrect.y2-sy)!@#&                    if add then term.write(\" \") end!@#&           end!@#&         for i=selectrect.y1 + 1, selectrect.y2 - 1 do!@#&                       add = (i + selectrect.x1 + rectblink) % 2 == 0!@#&                      term.setCursorPos(selectrect.x1-sx,i-sy)!@#&                    if add then term.write(\" \") end!@#&                   add = (i + selectrect.x2 + rectblink) % 2 == 0!@#&                      term.setCursorPos(selectrect.x2-sx,i-sy)!@#&                    if add then term.write(\" \") end!@#&           end!@#& end!@#&end!@#&!@#&--[[Draws the colour picker on the right side of the screen, the colour pallette and the footer with any !@#& messages currently being displayed!@#&  Params: none!@#&        Returns:nil!@#&]]--!@#&local function drawInterface()!@#&       --Picker!@#&    for i=1,#column do!@#&          term.setCursorPos(w-1, i)!@#&           term.setBackgroundColour(column[i])!@#&         if state == \"print\" then!@#&                  if i == 16 then!@#&                             term.setTextColour(colours.white)!@#&                   else!@#&                                term.setTextColour(colours.black)!@#&                   end!@#&                 if requirementsDisplayed then!@#&                               if requiredMaterials[i] < 10 then term.write(\" \") end!@#&                             term.setCursorPos(w-#tostring(requiredMaterials[i])+1, i)!@#&                           term.write(requiredMaterials[i])!@#&                    else!@#&                                if i < 10 then term.write(\" \") end!@#&                                term.write(i)!@#&                       end!@#&         else!@#&                        term.write(\"  \")!@#&          end!@#& end!@#& term.setCursorPos(w-1,#column+1)!@#&    term.setBackgroundColour(colours.black)!@#&     term.setTextColour(colours.red)!@#&     term.write(\"XX\")!@#&  --Pallette!@#&  term.setCursorPos(w-1,h-1)!@#&  if not lSel then!@#&            term.setBackgroundColour(colours.black)!@#&             term.setTextColour(colours.red)!@#&             term.write(\"X\")!@#&   else!@#&                term.setBackgroundColour(lSel)!@#&              term.setTextColour(lSel)!@#&            term.write(\" \")!@#&   end!@#& if not rSel then!@#&            term.setBackgroundColour(colours.black)!@#&             term.setTextColour(colours.red)!@#&             term.write(\"X\")!@#&   else!@#&                term.setBackgroundColour(rSel)!@#&              term.setTextColour(rSel)!@#&            term.write(\" \")!@#&   end!@#& --Footer!@#&    if inMenu then return end!@#&   !@#&    term.setCursorPos(1, h)!@#&     term.setBackgroundColour(colours.lightGrey)!@#& term.setTextColour(colours.grey)!@#&    term.clearLine()!@#&    if inDropDown then!@#&          term.write(string.rep(\" \", 6))!@#&    else!@#&                term.setBackgroundColour(colours.grey)!@#&              term.setTextColour(colours.lightGrey)!@#&               term.write(\"menu  \")!@#&      end!@#& term.setBackgroundColour(colours.lightGrey)!@#& term.setTextColour(colours.grey)!@#&    term.write(getStateMessage())!@#&       !@#&    local coords=\"X:\"..sx..\" Y:\"..sy!@#&        if animated then coords = coords..\" Frame:\"..sFrame..\"/\"..framecount..\"   \" end!@#&       term.setCursorPos(w-#coords+1,h)!@#&    if state == \"play\" then term.setBackgroundColour(colours.lime)!@#&    elseif record then term.setBackgroundColour(colours.red) end!@#&        term.write(coords)!@#&  !@#&    if animated then!@#&            term.setCursorPos(w-1,h)!@#&            term.setBackgroundColour(colours.grey)!@#&              term.setTextColour(colours.lightGrey)!@#&               term.write(\"<>\")!@#&  end!@#&end!@#&!@#&--[[Runs an interface where users can select topics of help. Will return once the user quits the help screen.!@#&     Params: none!@#&        Returns:nil!@#&]]--!@#&local function drawHelpScreen()!@#&      local selectedHelp = nil!@#&    while true do!@#&               term.setBackgroundColour(colours.lightGrey)!@#&         term.clear()!@#&                if not selectedHelp then!@#&                    term.setCursorPos(4, 1)!@#&                     term.setTextColour(colours.brown)!@#&                   term.write(\"Available modes (click for info):\")!@#&                   for i=1,#helpTopics do!@#&                              term.setCursorPos(2, 2 + i)!@#&                         term.setTextColour(colours.black)!@#&                           term.write(helpTopics[i].name)!@#&                              if helpTopics[i].key then!@#&                                   term.setTextColour(colours.red)!@#&                                     term.write(\" (\"..helpTopics[i].key..\")\")!@#&                                end!@#&                 end!@#&                 term.setCursorPos(4,h)!@#&                      term.setTextColour(colours.black)!@#&                   term.write(\"Press any key to exit\")!@#&               else!@#&                        term.setCursorPos(4,1)!@#&                      term.setTextColour(colours.brown)!@#&                   term.write(helpTopics[selectedHelp].name)!@#&                   if helpTopics[selectedHelp].key then!@#&                                term.setTextColour(colours.red)!@#&                             term.write(\" (\"..helpTopics[selectedHelp].key..\")\")!@#&                     end!@#&                 term.setCursorPos(1,3)!@#&                      term.setTextColour(colours.black)!@#&                   print(helpTopics[selectedHelp].message..\"\\n\")!@#&                    for i=1,#helpTopics[selectedHelp].controls do!@#&                               term.setTextColour(colours.brown)!@#&                           term.write(helpTopics[selectedHelp].controls[i][1]..\" \")!@#&                          term.setTextColour(colours.black)!@#&                           print(helpTopics[selectedHelp].controls[i][2])!@#&                      end!@#&         end!@#&         !@#&            local id,p1,p2,p3 = os.pullEvent()!@#&          !@#&            if id == \"timer\" then updateTimer(p1)!@#&             elseif id == \"key\" then !@#&                  if selectedHelp then selectedHelp = nil!@#&                     else break end!@#&              elseif id == \"mouse_click\" then!@#&                   if not selectedHelp then !@#&                           if p3 >=3 and p3 <= 2+#helpTopics then!@#&                                      selectedHelp = p3-2 !@#&                                else break end!@#&                      else!@#&                                selectedHelp = nil!@#&                  end!@#&         end!@#& end!@#&end!@#&!@#&--[[Draws a message in the footer bar. A helper for DrawInterface, but can be called for custom messages, if the!@#&  inMenu paramter is set to true while this is being done (remember to set it back when done!)!@#&        Params: message:string = The message to be drawn!@#&    Returns:nil!@#&]]--!@#&local function drawMessage(message)!@#&  term.setCursorPos(1,h)!@#&      term.setBackgroundColour(colours.lightGrey)!@#& term.setTextColour(colours.grey)!@#&    term.clearLine()!@#&    term.write(message)!@#&end!@#&!@#&--[[!@#&                      Section: Generic Interfaces!@#&]]--!@#&!@#&!@#&--[[One of my generic text printing methods, printing a message at a specified position with width and offset.!@#&       No colour materials included.!@#&       Params: msg:string = The message to print off-center!@#&                        height:number = The starting height of the message!@#&                  width:number = The limit as to how many characters long each line may be!@#&                    offset:number = The starting width offset of the message!@#&    Returns:number the number of lines used in printing the message!@#&]]--!@#&local function wprintOffCenter(msg, height, width, offset)!@#&       local inc = 0!@#&       local ops = 1!@#&       while #msg - ops > width do!@#&         local nextspace = 0!@#&         while string.find(msg, \" \", ops + nextspace) and!@#&                          string.find(msg, \" \", ops + nextspace) - ops < width do!@#&                   nextspace = string.find(msg, \" \", nextspace + ops) + 1 - ops!@#&              end!@#&         local ox,oy = term.getCursorPos()!@#&           term.setCursorPos(width/2 - (nextspace)/2 + offset, height + inc)!@#&           inc = inc + 1!@#&               term.write(string.sub(msg, ops, nextspace + ops - 1))!@#&               ops = ops + nextspace!@#&       end!@#& term.setCursorPos(width/2 - #string.sub(msg, ops)/2 + offset, height + inc)!@#& term.write(string.sub(msg, ops))!@#&    !@#&    return inc + 1!@#&end!@#&!@#&--[[Draws a message that must be clicked on or a key struck to be cleared. No options, so used for displaying!@#&  generic information.!@#&        Params: ctitle:string = The title of the confirm dialogue!@#&                   msg:string = The message displayed in the dialogue!@#&  Returns:nil!@#&]]--!@#&local function displayConfirmDialogue(ctitle, msg)!@#&   local dialogoffset = 8!@#&      --We actually print twice- once to get the lines, second time to print proper. Easier this way.!@#&     local lines = wprintOffCenter(msg, 5, w - (dialogoffset+2) * 2, dialogoffset + 2)!@#&   !@#&    term.setCursorPos(dialogoffset, 3)!@#&  term.setBackgroundColour(colours.grey)!@#&      term.setTextColour(colours.lightGrey)!@#&       term.write(string.rep(\" \", w - dialogoffset * 2))!@#& term.setCursorPos(dialogoffset + (w - dialogoffset * 2)/2 - #ctitle/2, 3)!@#&   term.write(ctitle)!@#&  term.setTextColour(colours.grey)!@#&    term.setBackgroundColour(colours.lightGrey)!@#& term.setCursorPos(dialogoffset, 4)!@#&  term.write(string.rep(\" \", w - dialogoffset * 2))!@#& for i=5,5+lines do!@#&          term.setCursorPos(dialogoffset, i) !@#&         term.write(\" \"..string.rep(\" \", w - (dialogoffset) * 2 - 2)..\" \")!@#&     end!@#& wprintOffCenter(msg, 5, w - (dialogoffset+2) * 2, dialogoffset + 2)!@#& !@#&    --In the event of a message, the player hits anything to continue!@#&   while true do!@#&               local id,key = os.pullEvent()!@#&               if id == \"timer\" then updateTimer(key);!@#&           elseif id == \"key\" or id == \"mouse_click\" or id == \"mouse_drag\" then break end!@#&        end!@#&end!@#&!@#&--[[Produces a nice dropdown menu based on a table of strings. Depending on the position, this will auto-adjust the position!@#&      of the menu drawn, and allows nesting of menus and sub menus. Clicking anywhere outside the menu will cancel and return nothing!@#&     Params: x:int = the x position the menu should be displayed at!@#&                      y:int = the y position the menu should be displayed at!@#&                      options:table = the list of options available to the user, as strings or submenus (tables of strings, with a name parameter)!@#&        Returns:string the selected menu option.!@#&]]--!@#&local function displayDropDown(x, y, options)!@#&   inDropDown = true!@#&   --Figures out the dimensions of our thing!@#&   local longestX = #options.name!@#&      for i=1,#options do!@#&         local currVal = options[i]!@#&          if type(currVal) == \"table\" then currVal = currVal.name end!@#&               !@#&            longestX = math.max(longestX, #currVal)!@#&     end!@#& local xOffset = math.max(0, longestX - ((w-2) - x) + 1)!@#&     local yOffset = math.max(0, #options - ((h-1) - y))!@#& !@#&    local clickTimes = 0!@#&        local tid = nil!@#&     local selection = nil!@#&       while clickTimes < 2 do!@#&             drawCanvas()!@#&                drawInterface()!@#&             !@#&            term.setCursorPos(x-xOffset,y-yOffset)!@#&              term.setBackgroundColour(colours.grey)!@#&              term.setTextColour(colours.lightGrey)!@#&               term.write(options.name..string.rep(\" \", longestX-#options.name + 2))!@#&     !@#&            for i=1,#options do!@#&                 term.setCursorPos(x-xOffset, y-yOffset+i)!@#&                   if i==selection and clickTimes % 2 == 0 then!@#&                                term.setBackgroundColour(colours.grey)!@#&                              term.setTextColour(colours.lightGrey)!@#&                       else!@#&                                term.setBackgroundColour(colours.lightGrey)!@#&                         term.setTextColour(colours.grey)!@#&                    end!@#&                 local currVal = options[i]!@#&                  if type(currVal) == \"table\" then !@#&                         term.write(currVal.name..string.rep(\" \", longestX-#currVal.name + 1))!@#&                             term.setBackgroundColour(colours.grey)!@#&                              term.setTextColour(colours.lightGrey)!@#&                               term.write(\">\")!@#&                   else!@#&                                term.write(currVal..string.rep(\" \", longestX-#currVal + 2))!@#&                       end!@#&         end!@#&         !@#&            local id, p1, p2, p3 = os.pullEvent()!@#&               if id == \"timer\" then!@#&                     if p1 == tid then !@#&                          clickTimes = clickTimes + 1!@#&                         if clickTimes > 2 then !@#&                                     break!@#&                               else !@#&                                       tid = os.startTimer(0.1) !@#&                           end!@#&                 else !@#&                               updateTimer(p1) !@#&                            drawCanvas()!@#&                                drawInterface()!@#&                     end!@#&         elseif id == \"mouse_click\" then!@#&                   if p2 >=x-xOffset and p2 <= x-xOffset + longestX + 1 and p3 >= y-yOffset+1 and p3 <= y-yOffset+#options then!@#&                                selection = p3-(y-yOffset)!@#&                          tid = os.startTimer(0.1)!@#&                    else!@#&                                selection = \"\"!@#&                            break!@#&                       end!@#&         end!@#& end!@#& !@#&    if type(selection) == \"number\" then!@#&               selection = options[selection]!@#&      end!@#& !@#&    if type(selection) == \"string\" then !@#&              inDropDown = false!@#&          return selection!@#&    elseif type(selection) == \"table\" then !@#&           return displayDropDown(x, y, selection)!@#&     end!@#&end!@#&!@#&--[[A custom io.read() function with a few differences- it limits the number of characters being printed,!@#& waits a 1/100th of a second so any keys still in the event library are removed before input is read and!@#&     the timer for the selectionrectangle is continuously updated during the process.!@#&    Params: lim:int = the number of characters input is allowed!@#& Returns:string the inputted string, trimmed of leading and tailing whitespace!@#&]]--!@#&local function readInput(lim)!@#&      term.setCursorBlink(true)!@#&!@#&       local inputString = \"\"!@#&    if not lim or type(lim) ~= \"number\" or lim < 1 then lim = w - ox end!@#&      local ox,oy = term.getCursorPos()!@#&   --We only get input from the footer, so this is safe. Change if recycling!@#&   term.setBackgroundColour(colours.lightGrey)!@#& term.setTextColour(colours.grey)!@#&    term.write(string.rep(\" \", lim))!@#&  term.setCursorPos(ox, oy)!@#&   --As events queue immediately, we may get an unwanted key... this will solve that problem!@#&   local inputTimer = os.startTimer(0.01)!@#&      local keysAllowed = false!@#&   !@#&    while true do!@#&               local id,key = os.pullEvent()!@#&               !@#&            if keysAllowed then!@#&                 if id == \"key\" and key == 14 and #inputString > 0 then!@#&                            inputString = string.sub(inputString, 1, #inputString-1)!@#&                            term.setCursorPos(ox + #inputString,oy)!@#&                             term.write(\" \")!@#&                   elseif id == \"key\" and key == 28 and inputString ~= string.rep(\" \", #inputString) then !@#&                         break!@#&                       elseif id == \"key\" and key == keys.leftCtrl then!@#&                          return \"\"!@#&                 elseif id == \"char\" and #inputString < lim then!@#&                           inputString = inputString..key!@#&                      end!@#&         end!@#&         !@#&            if id == \"timer\" then!@#&                     if key == inputTimer then !@#&                          keysAllowed = true!@#&                  else!@#&                                updateTimer(key)!@#&                            drawCanvas()!@#&                                drawInterface()!@#&                             term.setBackgroundColour(colours.lightGrey)!@#&                         term.setTextColour(colours.grey)!@#&                    end!@#&         end!@#&         term.setCursorPos(ox,oy)!@#&            term.write(inputString)!@#&             term.setCursorPos(ox + #inputString, oy)!@#&    end!@#& !@#&    while string.sub(inputString, 1, 1) == \" \" do!@#&             inputString = string.sub(inputString, 2, #inputString)!@#&      end!@#& while string.sub(inputString, #inputString, #inputString) == \" \" do!@#&               inputString = string.sub(inputString, 1, #inputString-1)!@#&    end!@#& term.setCursorBlink(false)!@#&  !@#&    return inputString!@#&end!@#&!@#&--[[  !@#&                     Section: Image tools !@#&]]--!@#&!@#&!@#&--[[Copies all pixels beneath the selection rectangle into the image buffer. Empty buffers are converted to nil.!@#&   Params: removeImage:bool = true if the image is to be erased after copying, false otherwise!@#& Returns:nil!@#&]]--!@#&local function copyToBuffer(removeImage)!@#&     buffer = { width = selectrect.x2 - selectrect.x1 + 1, height = selectrect.y2 - selectrect.y1 + 1, contents = { } }!@#&  !@#&    local containsSomething = false!@#&     for y=1,buffer.height do!@#&            buffer.contents[y] = { }!@#&            local f,l = sFrame,sFrame!@#&           if record then f,l = 1, framecount end!@#&              !@#&            for fra = f,l do!@#&                    if frames[fra][selectrect.y1 + y - 1] then!@#&                          for x=1,buffer.width do!@#&                                     buffer.contents[y][x] = frames[sFrame][selectrect.y1 + y - 1][selectrect.x1 + x - 1]!@#&                                        if removeImage then frames[fra][selectrect.y1 + y - 1][selectrect.x1 + x - 1] = nil end!@#&                                     if buffer.contents[y][x] then containsSomething = true end!@#&                          end!@#&                 end!@#&         end!@#& end!@#& --I don't classify an empty buffer as a real buffer- confusing to the user.!@#& if not containsSomething then buffer = nil end!@#&end!@#&!@#&--[[Replaces all pixels under the selection rectangle with the image buffer (or what can be seen of it). Record-dependent.!@#&     Params: removeBuffer:bool = true if the buffer is to be emptied after copying, false otherwise!@#&      Returns:nil!@#&]]--!@#&local function copyFromBuffer(removeBuffer)!@#&  if not buffer then return end!@#&!@#&   for y = 1, math.min(buffer.height,selectrect.y2-selectrect.y1+1) do!@#&         local f,l = sFrame, sFrame!@#&          if record then f,l = 1, framecount end!@#&              !@#&            for fra = f,l do!@#&                    if not frames[fra][selectrect.y1+y-1] then frames[fra][selectrect.y1+y-1] = { } end!@#&                 for x = 1, math.min(buffer.width,selectrect.x2-selectrect.x1+1) do!@#&                          frames[fra][selectrect.y1+y-1][selectrect.x1+x-1] = buffer.contents[y][x]!@#&                   end!@#&         end!@#& end!@#& !@#&    if removeBuffer then buffer = nil end!@#&end!@#&!@#&--[[Moves the entire image (or entire animation) to the specified coordinates. Record-dependent.!@#&        Params: newx:int = the X coordinate to move the image to!@#&                    newy:int = the Y coordinate to move the image to!@#&    Returns:nil!@#&]]--!@#&local function moveImage(newx,newy)!@#&  if not leflim or not toplim then return end!@#& if newx <=0 or newy <=0 then return end!@#&     local f,l = sFrame,sFrame!@#&   if record then f,l = 1,framecount end!@#&       !@#&    for i=f,l do!@#&                local newlines = { }!@#&                for y=toplim,botlim do!@#&                      local line = frames[i][y]!@#&                   if line then!@#&                                newlines[y-toplim+newy] = { }!@#&                               for x,char in pairs(line) do!@#&                                        newlines[y-toplim+newy][x-leflim+newx] = char!@#&                               end!@#&                 end!@#&         end!@#&         --Exceptions that allow us to move the text as well!@#&         if textEnabled then!@#&                 newlines.text = { }!@#&                 for y=toplim,botlim do!@#&                              local line = frames[i].text[y]!@#&                              if line then!@#&                                        newlines.text[y-toplim+newy] = { }!@#&                                  for x,char in pairs(line) do!@#&                                                newlines.text[y-toplim+newy][x-leflim+newx] = char!@#&                                  end!@#&                         end!@#&                 end!@#&                 !@#&                    newlines.textcol = { }!@#&                      for y=toplim,botlim do!@#&                              local line = frames[i].textcol[y]!@#&                           if line then!@#&                                        newlines.textcol[y-toplim+newy] = { }!@#&                                       for x,char in pairs(line) do!@#&                                                newlines.textcol[y-toplim+newy][x-leflim+newx] = char!@#&                                       end!@#&                         end!@#&                 end!@#&         end!@#&         !@#&            frames[i] = newlines!@#&        end!@#&end!@#&!@#&--[[Prompts the user to clear the current frame or all frames. Record-dependent.,!@#& Params: none!@#&        Returns:nil!@#&]]--!@#&local function clearImage()!@#&  inMenu = true!@#&       if not animated then!@#&                drawMessage(\"Clear image? Y/N: \")!@#& elseif record then!@#&          drawMessage(\"Clear ALL frames? Y/N: \")!@#&    else!@#&                drawMessage(\"Clear current frame? Y/N :\")!@#& end!@#& if string.find(string.upper(readInput(1)), \"Y\") then!@#&              local f,l = sFrame,sFrame!@#&           if record then f,l = 1,framecount end!@#&               !@#&            for i=f,l do!@#&                        frames[i] = { }!@#&             end!@#& end!@#& inMenu = false!@#&end!@#&!@#&--[[A recursively called method (watch out for big calls!) in which every pixel of a set colour is!@#&     changed to another colour. Does not work on the nil colour, for obvious reasons.!@#&    Params: x:int = The X coordinate of the colour to flood-fill!@#&                        y:int = The Y coordinate of the colour to flood-fill!@#&                        targetColour:colour = the colour that is being flood-filled!@#&                 newColour:colour = the colour with which to replace the target colour!@#&       Returns:nil!@#&]]--!@#&local function floodFill(x, y, targetColour, newColour)!@#&      if not newColour or not targetColour then return end!@#&        local nodeList = { }!@#&        !@#&    table.insert(nodeList, {x = x, y = y})!@#&      !@#&    while #nodeList > 0 do!@#&              local node = nodeList[1]!@#&            if frames[sFrame][node.y] and frames[sFrame][node.y][node.x] == targetColour then!@#&                   frames[sFrame][node.y][node.x] = newColour!@#&                  table.insert(nodeList, { x = node.x + 1, y = node.y})!@#&                       table.insert(nodeList, { x = node.x, y = node.y + 1})!@#&                       if x > 1 then table.insert(nodeList, { x = node.x - 1, y = node.y}) end!@#&                     if y > 1 then table.insert(nodeList, { x = node.x, y = node.y - 1}) end!@#&             end!@#&         table.remove(nodeList, 1)!@#&   end!@#&end!@#&!@#&--[[  !@#&                    Section: Animation Tools  !@#&]]--!@#&!@#&--[[Enters play mode, allowing the animation to play through. Interface is restricted to allow this,!@#&      and method only leaves once the player leaves play mode.!@#&    Params: none!@#&        Returns:nil!@#&]]--!@#&local function playAnimation()!@#&       state = \"play\"!@#&    selectedrect = nil!@#&  !@#&    local animt = os.startTimer(animtime)!@#&       repeat!@#&              drawCanvas()!@#&                drawInterface()!@#&             !@#&            local id,key,_,y = os.pullEvent()!@#&           !@#&            if id==\"timer\" then!@#&                       if key == animt then!@#&                                animt = os.startTimer(animtime)!@#&                             sFrame = (sFrame % framecount) + 1!@#&                  else!@#&                                updateTimer(key)!@#&                    end!@#&         elseif id==\"key\" then!@#&                     if key == keys.comma and animtime > 0.1 then animtime = animtime - 0.05!@#&                     elseif key == keys.period and animtime < 0.5 then animtime = animtime + 0.05!@#&                        elseif key == keys.space then state = \"paint\" end!@#&         elseif id==\"mouse_click\" and y == h then!@#&                  state = \"paint\"!@#&           end!@#& until state ~= \"play\"!@#&     os.startTimer(0.5)!@#&end!@#&!@#&--[[Changes the selected frame (sFrame) to the chosen frame. If this frame is above the framecount,!@#&        additional frames are created with a copy of the image on the selected frame.!@#&       Params: newframe:int = the new frame to move to!@#&     Returns:nil!@#&]]--!@#&local function changeFrame(newframe)!@#& inMenu = true!@#&       if not tonumber(newframe) then!@#&              term.setCursorPos(1,h)!@#&              term.setBackgroundColour(colours.lightGrey)!@#&         term.setTextColour(colours.grey)!@#&            term.clearLine()!@#&    !@#&            term.write(\"Go to frame: \")!@#&               newframe = tonumber(readInput(2))!@#&           if not newframe or newframe <= 0 then!@#&                       inMenu = false!@#&                      return !@#&             end!@#& elseif newframe <= 0 then return end!@#&        !@#&    if newframe > framecount then!@#&               for i=framecount+1,newframe do!@#&                      frames[i] = {}!@#&                      for y,line in pairs(frames[sFrame]) do!@#&                              frames[i][y] = { }!@#&                          for x,v in pairs(line) do!@#&                                   frames[i][y][x] = v!@#&                         end!@#&                 end!@#&         end!@#&         framecount = newframe!@#&       end!@#& sFrame = newframe!@#&   inMenu = false!@#&end!@#&!@#&--[[Removes every frame leading after the frame passed in!@#&      Params: frame:int the non-inclusive lower bounds of the delete!@#&      Returns:nil!@#&]]--!@#&local function removeFramesAfter(frame)!@#&      inMenu = true!@#&       if frame==framecount then return end!@#&        drawMessage(\"Remove frames \"..(frame+1)..\"/\"..framecount..\"? Y/N :\")!@#&  local answer = string.upper(readInput(1))!@#&   !@#&    if string.find(answer, string.upper(\"Y\")) ~= 1 then !@#&              inMenu = false!@#&              return !@#&     end!@#& !@#&    for i=frame+1, framecount do!@#&                frames[i] = nil!@#&     end!@#& framecount = frame!@#&  inMenu = false!@#&end!@#&!@#&--[[!@#&                   Section: Printing Tools!@#&]]--!@#&!@#&--[[Constructs a new facing to the left of the current facing!@#&        Params: curx:number = The facing on the X axis!@#&                      curz:number = The facing on the Z axis!@#&                      hand:string = The hand of the axis (\"right\" or \"left\")!@#&  Returns:number,number = the new facing on the X and Z axis after a left turn!@#&]]--!@#&local function getLeft(curx, curz)!@#&  local hand = \"left\"!@#&       if layering == \"up\" then hand = \"right\" end!@#&     !@#&    if hand == \"right\" then!@#&           if curx == 1 then return 0,-1 end!@#&           if curx == -1 then return 0,1 end!@#&           if curz == 1 then return 1,0 end!@#&            if curz == -1 then return -1,0 end!@#&  else!@#&                if curx == 1 then return 0,1 end!@#&            if curx == -1 then return 0,-1 end!@#&          if curz == 1 then return -1,0 end!@#&           if curz == -1 then return 1,0 end!@#&   end!@#&end!@#&!@#&--[[Constructs a new facing to the right of the current facing!@#&    Params: curx:number = The facing on the X axis!@#&                      curz:number = The facing on the Z axis!@#&                      hand:string = The hand of the axis (\"right\" or \"left\")!@#&  Returns:number,number = the new facing on the X and Z axis after a right turn!@#&]]--!@#&local function getRight(curx, curz)!@#&        local hand = \"left\"!@#&       if layering == \"up\" then hand = \"right\" end!@#&     !@#&    if hand == \"right\" then!@#&           if curx == 1 then return 0,1 end!@#&            if curx == -1 then return 0,-1 end!@#&          if curz == 1 then return -1,0 end!@#&           if curz == -1 then return 1,0 end!@#&   else!@#&                if curx == 1 then return 0,-1 end!@#&           if curx == -1 then return 0,1 end!@#&           if curz == 1 then return 1,0 end!@#&            if curz == -1 then return -1,0 end!@#&  end!@#&end!@#&!@#&!@#&--[[Sends out a rednet signal requesting local printers, and will listen for any responses. Printers found are added to the!@#&   printerList (for ID's) and printerNames (for names)!@#& Params: nil!@#& Returns:nil!@#&]]--!@#&local function locatePrinters()!@#&      printerList = { }!@#&   printerNames = { name = \"Printers\" }!@#&      local oldState = state!@#&      state = \"Locating printers, please wait...   \"!@#&    drawCanvas()!@#&        drawInterface()!@#&     state = oldState!@#&    !@#&    local modemOpened = false!@#&   for k,v in pairs(rs.getSides()) do!@#&          if peripheral.isPresent(v) and peripheral.getType(v) == \"modem\" then!@#&                      rednet.open(v)!@#&                      modemOpened = true!@#&                  break!@#&               end!@#& end!@#& !@#&    if not modemOpened then!@#&             displayConfirmDialogue(\"Modem not found!\", \"No modem peripheral. Must have network modem to locate printers.\")!@#&          return false!@#&        end!@#& !@#&    rednet.broadcast(\"$3DPRINT IDENTIFY\")!@#&     !@#&    while true do!@#&               local id, msg = rsTimeReceive(1)!@#&            !@#&            if not id then break end!@#&            if string.find(msg, \"$3DPRINT IDACK\") == 1 then!@#&                   msg = string.gsub(msg, \"$3DPRINT IDACK \", \"\")!@#&                   table.insert(printerList, id)!@#&                       table.insert(printerNames, msg)!@#&             end!@#& end!@#& !@#&    if #printerList == 0 then!@#&           displayConfirmDialogue(\"Printers not found!\", \"No active printers found in proximity of this computer.\")!@#&                return false!@#&        else!@#&                return true!@#& end!@#&end!@#&!@#&--[[Sends a request to the printer. Waits on a response and updates the state of the application accordingly.!@#&     Params: command:string the command to send!@#&                  param:string a parameter to send, if any!@#&    Returns:nil!@#&]]--!@#&local function sendPC(command,param)!@#& local msg = \"$PC \"..command!@#&       if param then msg = msg..\" \"..param end!@#&   rednet.send(printerList[selectedPrinter], msg)!@#&      !@#&    while true do!@#&               local id,key = rsTimeReceive()!@#&              if id == printerList[selectedPrinter] then!@#&                  if key == \"$3DPRINT ACK\" then!@#&                             break!@#&                       elseif key == \"$3DPRINT DEP\" then!@#&                         displayConfirmDialogue(\"Printer Empty\", \"The printer has exhasted a material. Please refill slot \"..param..!@#&                                     \", and click this message when ready to continue.\")!@#&                               rednet.send(printerList[selectedPrinter], msg)!@#&                      elseif key == \"$3DPRINT OOF\" then!@#&                         displayConfirmDialogue(\"Printer Out of Fuel\", \"The printer has no fuel. Please replace the material \"..!@#&                                 \"in slot 1 with a fuel source, then click this message.\")!@#&                         rednet.send(printerList[selectedPrinter], \"$PC SS 1\")!@#&                             id,key = rsTimeReceive()!@#&                            rednet.send(printerList[selectedPrinter], \"$PC RF\")!@#&                               id,key = rsTimeReceive()!@#&                            rednet.send(printerList[selectedPrinter], msg)!@#&                      end!@#&         end!@#& end!@#& !@#&    --Changes to position are handled after the event has been successfully completed!@#&   if command == \"FW\" then!@#&           px = px + pfx!@#&               pz = pz + pfz!@#&       elseif command == \"BK\" then!@#&               px = px - pfx!@#&               pz = pz - pfz!@#&       elseif command == \"UP\" then!@#&               if layering == \"up\" then!@#&                  py = py + 1!@#&         else !@#&                       py = py - 1!@#&         end!@#& elseif command == \"DW\" then!@#&               if layering == \"up\" then!@#&                  py = py - 1!@#&         else    !@#&                    py = py + 1!@#&         end!@#& elseif command == \"TL\" then!@#&               pfx,pfz = getLeft(pfx,pfz)!@#&  elseif command == \"TR\" then!@#&               pfx,pfz = getRight(pfx,pfz)!@#& elseif command == \"TU\" then!@#&               pfx = -pfx!@#&          pfz = -pfz!@#&  end!@#& !@#&    drawCanvas()!@#&        drawInterface()!@#&end!@#&!@#&--[[A printing function that commands the printer to turn to face the desired direction, if it is not already doing so!@#&        Params: desx:number = the normalized x direction to face!@#&                    desz:number = the normalized z direction to face!@#&    Returns:nil!@#&]]--!@#&local function turnToFace(desx,desz)!@#& if desx ~= 0 then!@#&           if pfx ~= desx then!@#&                 local temppfx,_ = getLeft(pfx,pfz)!@#&                  if temppfx == desx then!@#&                             sendPC(\"TL\")!@#&                      elseif temppfx == -desx then!@#&                                sendPC(\"TR\")!@#&                      else!@#&                                sendPC(\"TU\")!@#&                      end!@#&         end!@#& else!@#&                print(\"on the z axis\")!@#&            if pfz ~= desz then!@#&                 local _,temppfz = getLeft(pfx,pfz)!@#&                  if temppfz == desz then!@#&                             sendPC(\"TL\")!@#&                      elseif temppfz == -desz then!@#&                                sendPC(\"TR\")!@#&                      else!@#&                                sendPC(\"TU\")!@#&                      end!@#&         end!@#& end!@#&end!@#&!@#&--[[Performs the print!@#&    Params: nil!@#& Returns:nil!@#&]]--!@#&local function performPrint()!@#&        state = \"active print\"!@#&    if layering == \"up\" then!@#&          --An up layering starts our builder bot on the bottom left corner of our build!@#&              px,py,pz = leflim, 0, botlim + 1!@#&            pfx,pfz = 0,-1!@#&              !@#&            --We move him forward and up a bit from his original position.!@#&              sendPC(\"FW\")!@#&              sendPC(\"UP\")!@#&              --For each layer that needs to be completed, we go up by one each time!@#&              for layers=1,#frames do!@#&                     --We first decide if we're going forwards or back, depending on what side we're on!@#&                  local rowbot,rowtop,rowinc = nil,nil,nil!@#&                    if pz == botlim then!@#&                                rowbot,rowtop,rowinc = botlim,toplim,-1!@#&                     else!@#&                                rowbot,rowtop,rowinc = toplim,botlim,1!@#&                      end!@#&                 !@#&                    for rows = rowbot,rowtop,rowinc do!@#&                          --Then we decide if we're going left or right, depending on what side we're on!@#&                              local linebot,linetop,lineinc = nil,nil,nil!@#&                         if px == leflim then!@#&                                        --Facing from the left side has to be easterly- it's changed here!@#&                                   turnToFace(1,0)!@#&                                     linebot,linetop,lineinc = leflim,riglim,1!@#&                           else!@#&                                        --Facing from the right side has to be westerly- it's changed here!@#&                                  turnToFace(-1,0)!@#&                                    linebot,linetop,lineinc = riglim,leflim,-1!@#&                          end!@#&                         !@#&                            for lines = linebot,linetop,lineinc do!@#&                                      --We move our turtle forward, placing the right material at each step!@#&                                       local material = frames[py][pz][px]!@#&                                 if material then!@#&                                            material = math.log10(frames[py][pz][px])/math.log10(2) + 1!@#&                                         sendPC(\"SS\", material)!@#&                                            sendPC(\"PD\")!@#&                                      end!@#&                                 if lines ~= linetop then!@#&                                            sendPC(\"FW\")!@#&                                      end!@#&                         end!@#&                         !@#&                            --The printer then has to do a U-turn, depending on which way he's facing and!@#&                               --which way he needs to go!@#&                          local temppfx,temppfz = getLeft(pfx,pfz)!@#&                            if temppfz == rowinc and rows ~= rowtop then!@#&                                        sendPC(\"TL\")!@#&                                      sendPC(\"FW\")!@#&                                      sendPC(\"TL\")!@#&                              elseif temppfz == -rowinc and rows ~= rowtop then!@#&                                   sendPC(\"TR\")!@#&                                      sendPC(\"FW\")!@#&                                      sendPC(\"TR\")!@#&                              end!@#&                 end!@#&                 --Now at the end of a run he does a 180 and moves up to begin the next part of the print!@#&                    sendPC(\"TU\")!@#&                      if layers ~= #frames then!@#&                           sendPC(\"UP\")!@#&                      end!@#&         end!@#&         --All done- now we head back to where we started.!@#&           if px ~= leflim then!@#&                        turnToFace(-1,0)!@#&                    while px ~= leflim do!@#&                               sendPC(\"FW\")!@#&                      end!@#&         end!@#&         if pz ~= botlim then!@#&                        turnToFace(0,-1)!@#&                    while pz ~= botlim do!@#&                               sendPC(\"BK\")!@#&                      end!@#&         end!@#&         turnToFace(0,-1)!@#&            sendPC(\"BK\")!@#&              while py > 0 do!@#&                     sendPC(\"DW\")!@#&              end!@#& else!@#&                --The front facing is at the top-left corner, facing south not north!@#&                px,py,pz = leflim, botlim, 1!@#&                pfx,pfz = 0,1!@#&               --We move the printer to the last layer- he prints from the back forwards!@#&           while pz < #frames do!@#&                       sendPC(\"FW\")!@#&              end!@#&         !@#&            --For each layer in the frame we build our wall, the move back!@#&              for layers = 1,#frames do!@#&                   --We first decide if we're going left or right based on our position!@#&                        local rowbot,rowtop,rowinc = nil,nil,nil!@#&                    if px == leflim then!@#&                                rowbot,rowtop,rowinc = leflim,riglim,1!@#&                      else!@#&                                rowbot,rowtop,rowinc = riglim,leflim,-1!@#&                     end!@#&                 !@#&                    for rows = rowbot,rowtop,rowinc do!@#&                          --Then we decide if we're going up or down, depending on our given altitude!@#&                         local linebot,linetop,lineinc = nil,nil,nil!@#&                         if py == botlim then!@#&                                        linebot,linetop,lineinc = botlim,toplim,-1!@#&                          else!@#&                                        linebot,linetop,lineinc = toplim,botlim,1!@#&                           end!@#&                         !@#&                            for lines = linebot,linetop,lineinc do!@#&                              --We move our turtle up/down, placing the right material at each step!@#&                                       local material = frames[pz][py][px]!@#&                                 if material then!@#&                                            material = math.log10(frames[pz][py][px])/math.log10(2) + 1!@#&                                         sendPC(\"SS\", material)!@#&                                            sendPC(\"PF\")!@#&                                      end!@#&                                 if lines ~= linetop then!@#&                                            if lineinc == 1 then sendPC(\"DW\")!@#&                                         else sendPC(\"UP\") end!@#&                                     end!@#&                         end!@#&                                 !@#&                            if rows ~= rowtop then!@#&                                      turnToFace(rowinc,0)!@#&                                        sendPC(\"FW\")!@#&                                      turnToFace(0,1)!@#&                             end!@#&                 end!@#&                 !@#&                    if layers ~= #frames then!@#&                           sendPC(\"TU\")!@#&                              sendPC(\"FW\")!@#&                              sendPC(\"TU\")!@#&                      end!@#&         end!@#&         --He's easy to reset!@#&                while px ~= leflim do!@#&                       turnToFace(-1,0)!@#&                    sendPC(\"FW\")!@#&              end!@#&         turnToFace(0,1)!@#&     end!@#& !@#&    sendPC(\"DE\")!@#&      !@#&    displayConfirmDialogue(\"Print complete\", \"The 3D print was successful.\")!@#&end!@#&!@#&--[[  !@#&                   Section: Interface  !@#&]]--!@#&!@#&--[[Runs the printing interface. Allows users to find/select a printer, the style of printing to perform and to begin the operation!@#&     Params: none!@#&        Returns:boolean true if printing was started, false otherwse!@#&]]--!@#&local function runPrintInterface()!@#&  calculateMaterials()!@#&        --There's nothing on canvas yet!!@#&    if not botlim then!@#&          displayConfirmDialogue(\"Cannot Print Empty Canvas\", \"There is nothing on canvas that \"..!@#&                                \"can be printed, and the operation cannot be completed.\")!@#&         return false!@#&        end!@#& --No printers nearby!@#&        if not locatePrinters() then!@#&                return false!@#&        end!@#& !@#&    layering = \"up\"!@#&   requirementsDisplayed = false!@#&       selectedPrinter = 1!@#& while true do!@#&               drawCanvas()!@#&                term.setBackgroundColour(colours.lightGrey)!@#&         for i=1,10 do!@#&                       term.setCursorPos(1,i)!@#&                      term.clearLine()!@#&            end!@#&         drawInterface()!@#&             term.setBackgroundColour(colours.lightGrey)!@#&         term.setTextColour(colours.black)!@#&           !@#&            local msg = \"3D Printing\"!@#&         term.setCursorPos(w/2-#msg/2 - 2, 1)!@#&                term.write(msg)!@#&             term.setBackgroundColour(colours.grey)!@#&              term.setTextColour(colours.lightGrey)!@#&               if(requirementsDisplayed) then!@#&                      msg = \"Count:\"!@#&            else!@#&                        msg = \" Slot:\"!@#&            end!@#&         term.setCursorPos(w-3-#msg, 1)!@#&              term.write(msg)!@#&             term.setBackgroundColour(colours.lightGrey)!@#&         term.setTextColour(colours.black)!@#&           !@#&            term.setCursorPos(7, 2)!@#&             term.write(\"Layering\")!@#&            drawPictureTable(layerUpIcon, 3, 3, colours.white)!@#&          drawPictureTable(layerForwardIcon, 12, 3, colours.white)!@#&            if layering == \"up\" then!@#&                  term.setBackgroundColour(colours.red)!@#&               else!@#&                        term.setBackgroundColour(colours.lightGrey)!@#&         end!@#&         term.setCursorPos(3, 9)!@#&             term.write(\"Upwards\")!@#&             if layering == \"forward\" then!@#&                     term.setBackgroundColour(colours.red)!@#&               else!@#&                        term.setBackgroundColour(colours.lightGrey)!@#&         end!@#&         term.setCursorPos(12, 9)!@#&            term.write(\"Forward\")!@#&             !@#&            term.setBackgroundColour(colours.lightGrey)!@#&         term.setTextColour(colours.black)!@#&           term.setCursorPos(31, 2)!@#&            term.write(\"Printer ID\")!@#&          term.setCursorPos(33, 3)!@#&            if #printerList > 1 then!@#&                    term.setBackgroundColour(colours.grey)!@#&                      term.setTextColour(colours.lightGrey)!@#&               else!@#&                        term.setTextColour(colours.red)!@#&             end!@#&         term.write(\" \"..printerNames[selectedPrinter]..\" \")!@#&             !@#&            term.setBackgroundColour(colours.grey)!@#&              term.setTextColour(colours.lightGrey)!@#&               term.setCursorPos(25, 10)!@#&           term.write(\" Cancel \")!@#&            term.setCursorPos(40, 10)!@#&           term.write(\" Print \")!@#&             !@#&            local id, p1, p2, p3 = os.pullEvent()!@#&               !@#&            if id == \"timer\" then!@#&                     updateTimer(p1)!@#&             elseif id == \"mouse_click\" then!@#&                   --Layering Buttons!@#&                  if p2 >= 3 and p2 <= 9 and p3 >= 3 and p3 <= 9 then!@#&                         layering = \"up\"!@#&                   elseif p2 >= 12 and p2 <= 18 and p3 >= 3 and p3 <= 9 then!@#&                           layering = \"forward\"!@#&                      --Count/Slot!@#&                        elseif p2 >= w - #msg - 3 and p2 <= w - 3 and p3 == 1 then!@#&                          requirementsDisplayed = not requirementsDisplayed!@#&                   --Printer ID!@#&                        elseif p2 >= 33 and p2 <= 33 + #printerNames[selectedPrinter] and p3 == 3 and #printerList > 1 then!@#&                         local chosenName = displayDropDown(33, 3, printerNames)!@#&                             for i=1,#printerNames do!@#&                                    if printerNames[i] == chosenName then!@#&                                               selectedPrinter = i!@#&                                         break;!@#&                                      end!@#&                         end!@#&                 --Print and Cancel!@#&                  elseif p2 >= 25 and p2 <= 32 and p3 == 10 then!@#&                              break!@#&                       elseif p2 >= 40 and p2 <= 46 and p3 == 10 then!@#&                              rednet.send(printerList[selectedPrinter], \"$3DPRINT ACTIVATE\")!@#&                            ready = false!@#&                               while true do!@#&                                       local id,msg = rsTimeReceive(10)!@#&                                    !@#&                                    if id == printerList[selectedPrinter] and msg == \"$3DPRINT ACTACK\" then!@#&                                           ready = true!@#&                                                break!@#&                                       end!@#&                         end!@#&                         if ready then!@#&                                       performPrint()!@#&                                      break!@#&                               else!@#&                                        displayConfirmDialogue(\"Printer Didn't Respond\", \"The printer didn't respond to the activation command. Check to see if it's online\")!@#&                           end!@#&                 end!@#&         end!@#& end!@#& state = \"paint\"!@#&end!@#&!@#&--[[This function changes the current paint program to another tool or mode, depending on user input. Handles!@#&       any necessary changes in logic involved in that.!@#&    Params: mode:string = the name of the mode to change to!@#&     Returns:nil!@#&]]--!@#&local function performSelection(mode)!@#&        if not mode or mode == \"\" then return!@#&     !@#&    elseif mode == \"help\" then!@#&                drawHelpScreen()!@#&            !@#&    elseif mode == \"blueprint on\" then!@#&                blueprint = true!@#&            ddModes[2][3] = \"blueprint off\"!@#&           !@#&    elseif mode == \"blueprint off\" then!@#&               blueprint = false!@#&           ddModes[2][3] = \"blueprint on\"!@#&            !@#&    elseif mode == \"layers on\" then!@#&           layerDisplay = true!@#&         ddModes[2][4] = \"layers off\"!@#&      !@#&    elseif mode == \"layers off\" then!@#&          layerDisplay = false!@#&                ddModes[2][4] = \"layers on\"!@#&       !@#&    elseif mode == \"direction on\" then!@#&                printDirection = true!@#&               ddModes[2][5] = \"direction off\"!@#&           !@#&    elseif mode == \"direction off\" then!@#&               printDirection = false!@#&              ddModes[2][5] = \"direction on\"!@#&    !@#&    elseif mode == \"go to\" then!@#&               changeFrame()!@#&       !@#&    elseif mode == \"remove\" then!@#&              removeFramesAfter(sFrame)!@#&   !@#&    elseif mode == \"play\" then!@#&                playAnimation()!@#&             !@#&    elseif mode == \"copy\" then!@#&                if selectrect and selectrect.x1 ~= selectrect.x2 then!@#&                       copyToBuffer(false)!@#&         end!@#& !@#&    elseif mode == \"cut\" then!@#&         if selectrect and selectrect.x1 ~= selectrect.x2 then !@#&                      copyToBuffer(true)!@#&          end!@#&         !@#&    elseif mode == \"paste\" then!@#&               if selectrect and selectrect.x1 ~= selectrect.x2 then !@#&                      copyFromBuffer(false)!@#&               end!@#&         !@#&    elseif mode == \"hide\" then!@#&                selectrect = nil!@#&            if state == \"select\" then state = \"corner select\" end!@#&           !@#&    elseif mode == \"alpha to left\" then!@#&               if lSel then alphaC = lSel end!@#&              !@#&    elseif mode == \"alpha to right\" then!@#&              if rSel then alphaC = rSel end!@#&              !@#&    elseif mode == \"record\" then!@#&              record = not record!@#&         !@#&    elseif mode == \"clear\" then!@#&               if state==\"select\" then buffer = nil!@#&              else clearImage() end!@#&       !@#&    elseif mode == \"select\" then!@#&              if state==\"corner select\" or state==\"select\" then!@#&                       state = \"paint\"!@#&           elseif selectrect and selectrect.x1 ~= selectrect.x2 then!@#&                   state = \"select\"!@#&          else!@#&                        state = \"corner select\" !@#&          end!@#&         !@#&    elseif mode == \"print\" then!@#&               state = \"print\"!@#&           runPrintInterface()!@#&         state = \"paint\"!@#&           !@#&    elseif mode == \"save\" then!@#&                if animated then saveNFA(sPath)!@#&             elseif textEnabled then saveNFT(sPath)!@#&              else saveNFP(sPath) end!@#&             !@#&    elseif mode == \"exit\" then!@#&                isRunning = false!@#&   !@#&    elseif mode ~= state then state = mode!@#&      else state = \"paint\"!@#&      !@#&    end!@#&end!@#&!@#&--[[The main function of the program, reads and handles all events and updates them accordingly. Mode changes,!@#&    painting to the canvas and general selections are done here.!@#&        Params: none!@#&        Returns:nil!@#&]]--!@#&local function handleEvents()!@#&        recttimer = os.startTimer(0.5)!@#&      while isRunning do!@#&          drawCanvas()!@#&                drawInterface()!@#&             !@#&            if state == \"text\" then!@#&                   term.setCursorPos(textCurX - sx, textCurY - sy)!@#&                     term.setCursorBlink(true)!@#&           end!@#&         !@#&            local id,p1,p2,p3 = os.pullEvent()!@#&                  term.setCursorBlink(false)!@#&          if id==\"timer\" then!@#&                       updateTimer(p1)!@#&             elseif id==\"mouse_click\" or id==\"mouse_drag\" then!@#&                       if p2 >=w-1 and p3 < #column+1 then!@#&                         if p1==1 then lSel = column[p3]!@#&                             else rSel = column[p3] end!@#&                  elseif p2 >=w-1 and p3==#column+1 then!@#&                              if p1==1 then lSel = nil!@#&                            else rSel = nil end!@#&                 elseif p2==w-1 and p3==h and animated then!@#&                          changeFrame(sFrame-1)!@#&                       elseif p2==w and p3==h and animated then!@#&                            changeFrame(sFrame+1)!@#&                       elseif p2 < w-10 and p3==h then!@#&                             local sel = displayDropDown(1, h-1, ddModes)!@#&                                performSelection(sel)!@#&                       elseif p2 < w-1 and p3 <= h-1 then!@#&                          if state==\"pippette\" then!@#&                                 if p1==1 then!@#&                                               if frames[sFrame][p3+sy] and frames[sFrame][p3+sy][p2+sx] then!@#&                                                      lSel = frames[sFrame][p3+sy][p2+sx] !@#&                                                end!@#&                                 elseif p1==2 then!@#&                                           if frames[sFrame][p3+sy] and frames[sFrame][p3+sy][p2+sx] then!@#&                                                      rSel = frames[sFrame][p3+sy][p2+sx] !@#&                                                end!@#&                                 end!@#&                         elseif state==\"move\" then!@#&                                 updateImageLims(record)!@#&                                     moveImage(p2,p3)!@#&                            elseif state==\"flood\" then!@#&                                        if p1 == 1 and lSel and frames[sFrame][p3+sy]  then !@#&                                                floodFill(p2,p3,frames[sFrame][p3+sy][p2+sx],lSel)!@#&                                  elseif p1 == 2 and rSel and frames[sFrame][p3+sy] then !@#&                                             floodFill(p2,p3,frames[sFrame][p3+sy][p2+sx],rSel)!@#&                                  end!@#&                         elseif state==\"corner select\" then!@#&                                        if not selectrect then!@#&                                              selectrect = { x1=p2+sx, x2=p2+sx, y1=p3+sy, y2=p3+sy }!@#&                                     elseif selectrect.x1 ~= p2+sx and selectrect.y1 ~= p3+sy then!@#&                                               if p2+sx<selectrect.x1 then selectrect.x1 = p2+sx!@#&                                           else selectrect.x2 = p2+sx end!@#&                                              !@#&                                            if p3+sy<selectrect.y1 then selectrect.y1 = p3+sy!@#&                                           else selectrect.y2 = p3+sy end!@#&                                              !@#&                                            state = \"select\"!@#&                                  end!@#&                         elseif state==\"textpaint\" then!@#&                                    local paintCol = lSel!@#&                                       if p1 == 2 then paintCol = rSel end!@#&                                 if frames[sFrame].textcol[p3+sy] then!@#&                                               frames[sFrame].textcol[p3+sy][p2+sx] = paintCol!@#&                                     end!@#&                         elseif state==\"text\" then!@#&                                 textCurX = p2 + sx!@#&                                  textCurY = p3 + sy!@#&                          elseif state==\"select\" then!@#&                                       if p1 == 1 then!@#&                                             local swidth = selectrect.x2 - selectrect.x1!@#&                                                local sheight = selectrect.y2 - selectrect.y1!@#&                                       !@#&                                            selectrect.x1 = p2 + sx!@#&                                             selectrect.y1 = p3 + sy!@#&                                             selectrect.x2 = p2 + swidth + sx!@#&                                            selectrect.y2 = p3 + sheight + sy!@#&                                   elseif p1 == 2 and p2 < w-2 and p3 < h-1 then!@#&                                               inMenu = true!@#&                                               local sel = displayDropDown(p2, p3, srModes) !@#&                                               inMenu = false!@#&                                              performSelection(sel)!@#&                                       end!@#&                         else!@#&                                        local f,l = sFrame,sFrame!@#&                                   if record then f,l = 1,framecount end!@#&                                       local bwidth = 0!@#&                                    if state == \"brush\" then bwidth = brushsize-1 end!@#&                         !@#&                                    for i=f,l do!@#&                                                for x = math.max(1,p2+sx-bwidth),p2+sx+bwidth do!@#&                                                    for y = math.max(1,p3+sy-bwidth), p3+sy+bwidth do!@#&                                                           if math.abs(x - (p2+sx)) + math.abs(y - (p3+sy)) <= bwidth then!@#&                                                                     if not frames[i][y] then frames[i][y] = {} end!@#&                                                                      if p1==1 then frames[i][y][x] = lSel!@#&                                                                        else frames[i][y][x] = rSel end!@#&                                                                     !@#&                                                                    if textEnabled then!@#&                                                                         if not frames[i].text[y] then frames[i].text[y] = { } end!@#&                                                                           if not frames[i].textcol[y] then frames[i].textcol[y] = { } end!@#&                                                                     end!@#&                                                         end!@#&                                                 end!@#&                                         end!@#&                                 end!@#&                         end!@#&                 end!@#&         elseif id==\"char\" then!@#&                    if state==\"text\" then!@#&                             if not frames[sFrame][textCurY] then frames[sFrame][textCurY] = { } end!@#&                             if not frames[sFrame].text[textCurY] then frames[sFrame].text[textCurY] = { } end!@#&                           if not frames[sFrame].textcol[textCurY] then frames[sFrame].textcol[textCurY] = { } end!@#&                             !@#&                            if rSel then frames[sFrame][textCurY][textCurX] = rSel end!@#&                          if lSel then !@#&                                       frames[sFrame].text[textCurY][textCurX] = p1!@#&                                        frames[sFrame].textcol[textCurY][textCurX] = lSel!@#&                           else!@#&                                        frames[sFrame].text[textCurY][textCurX] = \" \"!@#&                                     frames[sFrame].textcol[textCurY][textCurX] = rSel!@#&                           end!@#&                         !@#&                            textCurX = textCurX+1!@#&                               if textCurX > w + sx - 2 then sx = textCurX - w + 2 end!@#&                     elseif tonumber(p1) then!@#&                            if state==\"brush\" and tonumber(p1) > 1 then!@#&                                       brushsize = tonumber(p1)!@#&                            elseif animated and tonumber(p1) > 0 then!@#&                                   changeFrame(tonumber(p1))!@#&                           end!@#&                 end!@#&         elseif id==\"key\" then!@#&                     --Text needs special handlers (all other keyboard shortcuts are of course reserved for typing)!@#&                      if state==\"text\" then!@#&                             if p1==keys.backspace and textCurX > 1 then!@#&                                 textCurX = textCurX-1!@#&                                       if frames[sFrame].text[textCurY] then!@#&                                               frames[sFrame].text[textCurY][textCurX] = nil!@#&                                               frames[sFrame].textcol[textCurY][textCurX] = nil!@#&                                    end!@#&                                 if textCurX < sx then sx = textCurX end!@#&                             elseif p1==keys.left and textCurX > 1 then!@#&                                  textCurX = textCurX-1!@#&                                       if textCurX-1 < sx then sx = textCurX-1 end!@#&                         elseif p1==keys.right then!@#&                                  textCurX = textCurX+1!@#&                                       if textCurX > w + sx - 2 then sx = textCurX - w + 2 end!@#&                             elseif p1==keys.up and textCurY > 1 then!@#&                                    textCurY = textCurY-1!@#&                                       if textCurY-1 < sy then sy = textCurY-1 end!@#&                         elseif p1==keys.down then!@#&                                   textCurY = textCurY+1!@#&                                       if textCurY > h + sy - 1 then sy = textCurY - h + 1 end!@#&                             end!@#&                 !@#&                    elseif p1==keys.leftCtrl then!@#&                               local sel = displayDropDown(1, h-1, ddModes[#ddModes]) !@#&                             performSelection(sel)!@#&                       elseif p1==keys.leftAlt then!@#&                                local sel = displayDropDown(1, h-1, ddModes[1]) !@#&                            performSelection(sel)!@#&                       elseif p1==keys.h then !@#&                             performSelection(\"help\")!@#&                  elseif p1==keys.x then !@#&                             performSelection(\"cut\")!@#&                   elseif p1==keys.c then!@#&                              performSelection(\"copy\")!@#&                  elseif p1==keys.v then!@#&                              performSelection(\"paste\")!@#&                 elseif p1==keys.z then!@#&                              performSelection(\"clear\")!@#&                 elseif p1==keys.s then!@#&                              performSelection(\"select\")!@#&                        elseif p1==keys.tab then!@#&                            performSelection(\"hide\")!@#&                  elseif p1==keys.q then!@#&                              performSelection(\"alpha to left\")!@#&                 elseif p1==keys.w then!@#&                              performSelection(\"alpha to right\")!@#&                        elseif p1==keys.f then!@#&                              performSelection(\"flood\")!@#&                 elseif p1==keys.b then!@#&                              performSelection(\"brush\")!@#&                 elseif p1==keys.m then!@#&                              performSelection(\"move\")!@#&                  elseif p1==keys.backslash and animated then!@#&                         performSelection(\"record\")!@#&                        elseif p1==keys.p then!@#&                              performSelection(\"pippette\")!@#&                      elseif p1==keys.g and animated then!@#&                         performSelection(\"go to\")!@#&                 elseif p1==keys.period and animated then!@#&                            changeFrame(sFrame+1)!@#&                       elseif p1==keys.comma and animated then!@#&                             changeFrame(sFrame-1)!@#&                       elseif p1==keys.r and animated then!@#&                         performSelection(\"remove\")!@#&                        elseif p1==keys.space and animated then!@#&                             performSelection(\"play\")!@#&                  elseif p1==keys.t and textEnabled then!@#&                              performSelection(\"text\")!@#&                          sleep(0.01)!@#&                 elseif p1==keys.y and textEnabled then!@#&                              performSelection(\"textpaint\")!@#&                     elseif p1==keys.left then!@#&                           if state == \"move\" and toplim then!@#&                                        updateImageLims(record)!@#&                                     if toplim and leflim then!@#&                                           moveImage(leflim-1,toplim)!@#&                                  end!@#&                         elseif state==\"select\" and selectrect.x1 > 1 then!@#&                                 selectrect.x1 = selectrect.x1-1!@#&                                     selectrect.x2 = selectrect.x2-1!@#&                             elseif sx > 0 then sx=sx-1 end!@#&                      elseif p1==keys.right then!@#&                          if state == \"move\" then!@#&                                   updateImageLims(record)!@#&                                     if toplim and leflim then!@#&                                           moveImage(leflim+1,toplim)!@#&                                  end!@#&                         elseif state==\"select\" then!@#&                                       selectrect.x1 = selectrect.x1+1!@#&                                     selectrect.x2 = selectrect.x2+1!@#&                             else sx=sx+1 end!@#&                    elseif p1==keys.up then!@#&                             if state == \"move\" then!@#&                                   updateImageLims(record)!@#&                                     if toplim and leflim then!@#&                                           moveImage(leflim,toplim-1)!@#&                                  end!@#&                         elseif state==\"select\" and selectrect.y1 > 1 then!@#&                                 selectrect.y1 = selectrect.y1-1!@#&                                     selectrect.y2 = selectrect.y2-1!@#&                             elseif sy > 0 then sy=sy-1 end!@#&                      elseif p1==keys.down then !@#&                          if state == \"move\" then!@#&                                   updateImageLims(record)!@#&                                     if toplim and leflim then!@#&                                           moveImage(leflim,toplim+1)!@#&                                  end!@#&                         elseif state==\"select\" then!@#&                                       selectrect.y1 = selectrect.y1+1!@#&                                     selectrect.y2 = selectrect.y2+1!@#&                             else sy=sy+1 end!@#&                    end!@#&         end!@#& end!@#&end!@#&!@#&--[[!@#&                      Section: Main  !@#&]]--!@#&!@#&if not term.isColour() then!@#&  print(\"For colour computers only\")!@#&        return!@#&end!@#&!@#&--Taken almost directly from edit (for consistency)!@#&local tArgs = {...}!@#&!@#&local ca = 1!@#&!@#&if tArgs[ca] == \"-a\" then!@#&      animated = true!@#&     ca = ca + 1!@#&end!@#&!@#&if tArgs[ca] == \"-t\" then!@#&       textEnabled = true!@#&  ca = ca + 1!@#&end!@#&!@#&if #tArgs < ca then!@#&       print(\"Usage: npaintpro [-a,-t] <path>\")!@#&  return!@#&end!@#&!@#&--Yeah you can't have animated text files YET... I haven't supported that, maybe later?!@#&if animated and textEnabled then!@#&    print(\"No support for animated text files- cannot have both -a and -t\")!@#&end!@#&!@#&sPath = shell.resolve(tArgs[ca])!@#&local bReadOnly = fs.isReadOnly(sPath)!@#&if fs.exists(sPath) then!@#&      if fs.isDir(sPath) then!@#&             print(\"Cannot edit a directory.\")!@#&         return!@#&      elseif string.find(sPath, \".nfp\") ~= #sPath-3 and string.find(sPath, \".nfa\") ~= #sPath-3 and!@#&                    string.find(sPath, \".nft\") ~= #sPath-3 then!@#&               print(\"Can only edit .nfp, .nft and .nfa files:\",string.find(sPath, \".nfp\"),#sPath-3)!@#&           return!@#&      end!@#& !@#&    if string.find(sPath, \".nfa\") == #sPath-3 then!@#&            animated = true!@#&     end!@#& !@#&    if string.find(sPath, \".nft\") == #sPath-3 then!@#&            textEnabled = true!@#&  end     !@#&    !@#&    if string.find(sPath, \".nfp\") == #sPath-3 and animated then!@#&               print(\"Convert to nfa? Y/N\")!@#&              if string.find(string.lower(io.read()), \"y\") then!@#&                 local nsPath = string.sub(sPath, 1, #sPath-1)..\"a\"!@#&                        fs.move(sPath, nsPath)!@#&                      sPath = nsPath!@#&              else!@#&                        animated = false!@#&            end!@#& end!@#& !@#&    --Again this is possible, I just haven't done it. Maybe I will?!@#&     if textEnabled and (string.find(sPath, \".nfp\") == #sPath-3 or string.find(sPath, \".nfa\") == #sPath-3) then!@#&              print(\"Cannot convert to nft\")!@#&    end!@#&else!@#& if not animated and not textEnabled and string.find(sPath, \".nfp\") ~= #sPath-3 then !@#&              sPath = sPath..\".nfp\"!@#&     elseif animated and string.find(sPath, \".nfa\") ~= #sPath-3 then !@#&          sPath = sPath..\".nfa\"!@#&     elseif textEnabled and string.find(sPath, \".nft\") ~= #sPath-3 then!@#&                sPath = sPath..\".nft\"!@#&     end!@#&end !@#&!@#&drawLogo()!@#&init()!@#&handleEvents()!@#&!@#&term.setBackgroundColour(colours.black)!@#&shell.run(\"clear\")",["gitdl"]="args = {...}!@#&if not #args == 2 then!@#& print(\"Usage: gitdl <user/*> <file>\")!@#& error()!@#&else!@#& h2f = fs.open(args[2], \"w\")!@#& h2f.write(http.get(\"https://raw.github.com/\" .. args[1]).readAll())!@#& h2f.close()!@#&end",["sudo"]="args = {...}!@#&fail = true!@#&if not sudo.isAdmin() then!@#&while fail do!@#&        write(\"[sudo] password for \" .. spd.getData(\"login\").. \": \")!@#&  pswd = read(\"*\")!@#&  if pswd == \"\" then!@#&                error()!@#&     end!@#& if sudo.getAdminPrivs(pswd) then!@#&            fail = false!@#&        else!@#&                print(\"sorry, try again\")!@#& end!@#&end!@#&end!@#&shell.run(args[1])!@#&sudo.setPrivID(2,pswd)",["shell"]="w, h = term.getSize()!@#&!@#&local function printc(str, ln)!@#&   term.setCursorPos(w/2-#str/2, ln)!@#&   print(str)!@#&end!@#&!@#&local commandHistory = {\"startz\"}!@#&!@#&if sysconf.z_auto then!@#&  shell.run(\"startz\")!@#&end!@#&!@#&local function execute()!@#&        shell.run(program)!@#&  return true!@#&end!@#&!@#&while true do!@#&     term.setTextColor(colors.lime)!@#&      write(spd.getData(\"login\") .. \"@\" .. os.getComputerLabel())!@#&     term.setTextColor(colors.blue)!@#&      write(\": /\" .. shell.dir() .. \" $ \")!@#&    term.setTextColor(colors.white)!@#&     program = read(nil,commandHistory)!@#&  table.insert(commandHistory,program)!@#&        local ok, err = pcall(execute)!@#&end!@#&!@#&if not ok then!@#& term.setBackgroundColor(colors.lightGray)!@#&   term.clear()!@#&        printc(\"This program has encountered an error!\", 1)!@#&       printc(\"Error:\", h/2-1)!@#&   printc(err, h/2)!@#&    printc(\"Press any key to reboot!\", h-1)!@#&   os.pullEvent(\"key\")!@#&       os.reboot()!@#&end!@#&  ",["cat"]="args = {...}!@#&file = args[1]!@#&h = fs.open(file,\"r\")!@#&print(h.readAll())",["ehelp"]="args = {...}!@#&if not args[1] then!@#&  print(\"Usage: rape <anusfile>\")!@#&else!@#&   shell.run(\"ev\")!@#&end",["getapis"]="for k,v in pairs(_G) do!@#&  if type(v) == 'table' and k ~= '_G' then!@#&        print(k)!@#&        sleep(0.1)!@#&  end!@#&end",["crash"]="poo face : lol",["uplib"]={["smart"]="",["safe"]="",},["pkgmake"]="sPackage = \"local pkg = %@1 local function makeFile(_path, _content) local file = fs.open(_path, \\\"w\\\") _content = _content:gsub(\\\"\\!@\\\"..\\\"#&\\\", \\\"%\\\\n\\\") _content = textutils.unserialize(_content) file.write(_content) file.close() end local function makeFolder(_path, _content) fs.makeDir(_path) for k,v in pairs(_content) do if type(v) == \\\"table\\\" then makeFolder(_path .. \\\"/\\\" .. k, v) else makeFile(_path .. \\\"/\\\" .. k, v) end end end local sDest = shell.resolve( \\\"%@2\\\" ) or \\\"/\\\" if sDest == \\\"root\\\" then sDest = \\\"/\\\" end local tPackage = pkg makeFolder(sDest, tPackage) print(\\\"Package Extracted to '\\\" .. sDest .. \\\"'!\\\")\"!@#&!@#&function addFile(_package, _path)!@#&        if fs.getName(_path) == \".DS_Store\" then!@#&          return _package!@#&     end!@#& local file, err = fs.open(_path, \"r\")!@#&     local content = file.readAll()!@#&      content = content:gsub(\"%\\n\", \"\\!@\"..\"#&\")!@#&  content = content:gsub(\"%%\", \"%%%%\")!@#&    _package[fs.getName(_path)] = content!@#&       file.close()!@#&        print(\"Added file '\".._path..\"'\")!@#&       return _package!@#&end!@#&!@#&function addFolder(_package, _path)!@#&   if string.sub(_path,1,string.len(\"rom\"))==\"rom\" or string.sub(_path,1,string.len(\"/rom\"))==\"/rom\" then!@#&              print(\"Ignored 'rom' folder. (\".._path..\")\")!@#&            return!@#&      end!@#& _package = _package or {}!@#&   for _,f in ipairs(fs.list(_path)) do!@#&                local path = _path..\"/\"..f!@#&                if fs.isDir(path) then!@#&                      _package[fs.getName(f)] = addFolder(_package[fs.getName(f)], path)!@#&          else!@#&                        _package =  addFile(_package, path)!@#&         end!@#& end!@#& return _package!@#&end!@#&!@#&local tArgs = { ... }!@#&if #tArgs < 2 then!@#&   print( \"Usage: PkgMake <source> <destination>\" )!@#&  return!@#&end!@#&!@#&local sSource = shell.resolve( tArgs[1] )!@#&local sDest = shell.resolve( tArgs[2] )!@#&!@#&if fs.isDir( sDest ) then!@#&  error(\"Destination must not be a folder.\")!@#&end!@#&!@#&if sSource == sDest then!@#& error(\"Source can not be equal to destination.\")!@#&end!@#&!@#&if fs.exists( sSource ) and fs.isDir( sSource ) then!@#&       tPackage = {}!@#&       tPackage = addFolder(tPackage, sSource)!@#&     fPackage = fs.open(sDest,\"w\")!@#&!@#& sPackage = string.gsub(sPackage, \"%%@2\", fs.getName(sSource))!@#&     sPackage = string.gsub(sPackage, \"%%@1\", textutils.serialize(tPackage))!@#&   fPackage.write(sPackage)!@#&    fPackage.close()!@#&    print(\"Package Done! ('\" .. sDest .. \"')\")!@#&      print(\"Type '\" .. sDest .. \"' to run it.\")!@#&else!@#&      error(\"Source does not exist or is not a folder.\")!@#&end",["mpc-get"]="repolist = \"/var/mpc-get-repo.rpo\"!@#&repos = {}!@#&local file = fs.open(repolist, \"r\")!@#&if file then!@#&  repos = {}!@#&  local line = file.readLine()!@#&  while line do!@#&        table.insert(repos, line)!@#&        line = file.readLine()!@#&  end!@#&  file.close()!@#&end!@#&!@#&textutils.tabulate(repos)",},["firewolf"]="if fs.isReadOnly(shell.getRunningProgram()) then!@#&      fs.delete(\"/firewolf\")!@#&    fs.copy(shell.getRunningProgram(),\"/firewolf\")!@#&    error()!@#&end!@#&--  !@#&--  Firewolf Website Browser!@#&--  Made by GravityScore and 1lann!@#&--  License found here: https://raw.github.com/1lann/Firewolf/master/LICENSE!@#&--  !@#&--  Original Concept From RednetExplorer 2.4.1!@#&--  RednetExplorer Made by ComputerCraftFan11!@#&--  !@#& !@#& !@#&--  -------- Variables!@#& !@#&-- Version!@#&local version = \"2.4\"!@#&local build = 29!@#&local browserAgentTemplate = \"Firewolf \" .. version!@#&browserAgent = browserAgentTemplate!@#&local tArgs = {...}!@#& !@#&-- Server Identification!@#&local serverID = \"other\"!@#&local serverList = {experimental = \"Experimental\", other = \"Other\"}!@#& !@#&-- Updating!@#&local autoupdate = \"true\"!@#&local noInternet = false!@#& !@#&-- Resources!@#&local graphics = {}!@#&local files = {}!@#&local w, h = term.getSize()!@#& !@#&-- Debugging!@#&local debugFile = nil!@#& !@#&-- Environment!@#&local oldpullevent = os.pullEvent!@#&local oldEnv = {}!@#&local env = {}!@#&local backupEnv = {}!@#& !@#&local api = {}!@#&local override = {}!@#&local antivirus = {}!@#& !@#&-- Themes!@#&local theme = {}!@#& !@#&-- Databases!@#&local blacklist = {}!@#&local whitelist = {}!@#&local dnsDatabase = {[1] = {}, [2] = {}}!@#& !@#&-- Website Loading!@#&local pages = {}!@#&local errorPages = {}!@#& !@#&local website = \"\"!@#&local homepage = \"\"!@#&local timeout = 0.2!@#&local loadingRate = 0!@#&local openAddressBar = true!@#&local clickableAddressBar = true!@#&local menuBarOpen = false!@#& !@#&-- Protocols!@#&local curProtocol = {}!@#&local protocols = {}!@#& !@#&-- History!@#&local addressBarHistory = {}!@#& !@#&-- Events!@#&local event_loadWebsite = \"firewolf_loadWebsiteEvent\"!@#&local event_exitWebsite = \"firewolf_exitWebsiteEvent\"!@#&local event_redirect = \"firewolf_redirectEvent\"!@#&local event_exitApp = \"firewolf_exitAppEvent\"!@#& !@#&-- Download URLs!@#&local firewolfURL = \"https://raw.github.com/1lann/firewolf/master/entities/\" .. serverID .. \".lua\"!@#&local a = \"release\"!@#&if serverID == \"experimental\" then a = \"experimental\" end!@#&local serverURL = \"https://raw.github.com/1lann/firewolf/master/server/server-\" .. a .. \".lua\"!@#&local buildURL = \"https://raw.github.com/1lann/firewolf/master/build\"!@#& !@#&-- Data Locations!@#&local rootFolder = \"/.Firewolf_Data\"!@#&local cacheFolder = rootFolder .. \"/cache\"!@#&local serverFolder = rootFolder .. \"/servers\"!@#&local websiteDataFolder = rootFolder .. \"/website_data\"!@#&local themeLocation = rootFolder .. \"/theme\"!@#&local serverLocation = rootFolder .. \"/server_software\"!@#&local settingsLocation = rootFolder .. \"/settings\"!@#&local debugLogLocation = \"/firewolf-log\"!@#&local firewolfLocation = \"/\" .. shell.getRunningProgram()!@#& !@#&local userBlacklist = rootFolder .. \"/user_blacklist\"!@#&local userWhitelist = rootFolder .. \"/user_whitelist\"!@#& !@#& !@#&--  -------- Utilities!@#& !@#&local function debugLog(n, ...)!@#&        local lArgs = {...}!@#&        if debugFile then!@#&                if n == nil then n = \"\" end!@#&                debugFile:write(\"\\n\" .. tostring(n) .. \" : \")!@#&                for k, v in pairs(lArgs) do!@#&                        if type(v) == \"string\" or type(v) == \"number\" or type(v) == nil or!@#&                                        type(v) == \"boolean\" then!@#&                                debugFile:write(tostring(v) .. \", \")!@#&                        else debugFile:write(\"type-\" .. type(v) .. \", \") end!@#&                end!@#&        end!@#&end!@#& !@#&local function modRead(properties)!@#&        local w, h = term.getSize()!@#&        local defaults = {replaceChar = nil, history = nil, visibleLength = nil, textLength = nil,!@#&                liveUpdates = nil, exitOnKey = nil}!@#&        if not properties then properties = {} end!@#&        for k, v in pairs(defaults) do if not properties[k] then properties[k] = v end end!@#&        if properties.replaceChar then properties.replaceChar = properties.replaceChar:sub(1, 1) end!@#&        if not properties.visibleLength then properties.visibleLength = w end!@#& !@#&        local sx, sy = term.getCursorPos()!@#&        local line = \"\"!@#&        local pos = 0!@#&        local historyPos = nil!@#& !@#&        local function redraw(repl)!@#&                local scroll = 0!@#&                if properties.visibleLength and sx + pos > properties.visibleLength + 1 then!@#&                        scroll = (sx + pos) - (properties.visibleLength + 1)!@#&                end!@#& !@#&                term.setCursorPos(sx, sy)!@#&                local a = repl or properties.replaceChar!@#&                if a then term.write(string.rep(a, line:len() - scroll))!@#&                else term.write(line:sub(scroll + 1, -1)) end!@#&                term.setCursorPos(sx + pos - scroll, sy)!@#&        end!@#& !@#&        local function sendLiveUpdates(event, ...)!@#&                if type(properties.liveUpdates) == \"function\" then!@#&                        local ox, oy = term.getCursorPos()!@#&                        local a, data = properties.liveUpdates(line, event, ...)!@#&                        if a == true and data == nil then!@#&                                term.setCursorBlink(false)!@#&                                return line!@#&                        elseif a == true and data ~= nil then!@#&                                term.setCursorBlink(false)!@#&                                return data!@#&                        end!@#&                        term.setCursorPos(ox, oy)!@#&                end!@#&        end!@#& !@#&        local a = sendLiveUpdates(\"delete\")!@#&        if a then return a end!@#&        term.setCursorBlink(true)!@#&        while true do!@#&                local e, but, x, y, p4, p5 = os.pullEvent()!@#& !@#&                if e == \"char\" then!@#&                        local s = false!@#&                        if properties.textLength and line:len() < properties.textLength then s = true!@#&                        elseif not properties.textLength then s = true end!@#& !@#&                        local canType = true!@#&                        if not properties.grantPrint and properties.refusePrint then!@#&                                local canTypeKeys = {}!@#&                                if type(properties.refusePrint) == \"table\" then!@#&                                        for _, v in pairs(properties.refusePrint) do!@#&                                                table.insert(canTypeKeys, tostring(v):sub(1, 1))!@#&                                        end!@#&                                elseif type(properties.refusePrint) == \"string\" then!@#&                                        for char in properties.refusePrint:gmatch(\".\") do!@#&                                                table.insert(canTypeKeys, char)!@#&                                        end!@#&                                end!@#&                                for _, v in pairs(canTypeKeys) do if but == v then canType = false end end!@#&                        elseif properties.grantPrint then!@#&                                canType = false!@#&                                local canTypeKeys = {}!@#&                                if type(properties.grantPrint) == \"table\" then!@#&                                        for _, v in pairs(properties.grantPrint) do!@#&                                                table.insert(canTypeKeys, tostring(v):sub(1, 1))!@#&                                        end!@#&                                elseif type(properties.grantPrint) == \"string\" then!@#&                                        for char in properties.grantPrint:gmatch(\".\") do!@#&                                                table.insert(canTypeKeys, char)!@#&                                        end!@#&                                end!@#&                                for _, v in pairs(canTypeKeys) do if but == v then canType = true end end!@#&                        end!@#& !@#&                        if s and canType then!@#&                                line = line:sub(1, pos) .. but .. line:sub(pos + 1, -1)!@#&                                pos = pos + 1!@#&                                redraw()!@#&                        end!@#&                elseif e == \"key\" then!@#&                        if but == keys.enter then!@#&                                break!@#&                        elseif but == keys.left then!@#&                                if pos > 0 then pos = pos - 1 redraw() end!@#&                        elseif but == keys.right then!@#&                                if pos < line:len() then pos = pos + 1 redraw() end!@#&                        elseif (but == keys.up or but == keys.down) and properties.history and!@#&                                        #properties.history > 0 then!@#&                                redraw(\" \")!@#&                                if but == keys.up then!@#&                                        if historyPos == nil and #properties.history > 0 then!@#&                                                historyPos = #properties.history!@#&                                        elseif historyPos > 1 then!@#&                                                historyPos = historyPos - 1!@#&                                        end!@#&                                elseif but == keys.down then!@#&                                        if historyPos == #properties.history then historyPos = nil!@#&                                        elseif historyPos ~= nil then historyPos = historyPos + 1 end!@#&                                end!@#& !@#&                                if properties.history and historyPos then!@#&                                        line = properties.history[historyPos]!@#&                                        pos = line:len()!@#&                                else!@#&                                        line = \"\"!@#&                                        pos = 0!@#&                                end!@#& !@#&                                redraw()!@#&                                local a = sendLiveUpdates(\"history\")!@#&                                if a then return a end!@#&                        elseif but == keys.backspace and pos > 0 then!@#&                                redraw(\" \")!@#&                                line = line:sub(1, pos - 1) .. line:sub(pos + 1, -1)!@#&                                pos = pos - 1!@#&                                redraw()!@#&                                local a = sendLiveUpdates(\"delete\")!@#&                                if a then return a end!@#&                        elseif but == keys.home then!@#&                                pos = 0!@#&                                redraw()!@#&                        elseif but == keys.delete and pos < line:len() then!@#&                                redraw(\" \")!@#&                                line = line:sub(1, pos) .. line:sub(pos + 2, -1)!@#&                                redraw()!@#&                                local a = sendLiveUpdates(\"delete\")!@#&                                if a then return a end!@#&                        elseif but == keys[\"end\"] then!@#&                                pos = line:len()!@#&                                redraw()!@#&                        elseif properties.exitOnKey then!@#&                                if but == properties.exitOnKey or (properties.exitOnKey == \"control\" and!@#&                                                (but == 29 or but == 157)) then!@#&                                        term.setCursorBlink(false)!@#&                                        return nil!@#&                                end!@#&                        end!@#&                end!@#& !@#&                local a = sendLiveUpdates(e, but, x, y, p4, p5)!@#&                if a then return a end!@#&        end!@#& !@#&        term.setCursorBlink(false)!@#&        if line ~= nil then line = line:gsub(\"^%s*(.-)%s*$\", \"%1\") end!@#&        return line!@#&end!@#& !@#& !@#&--  -------- Environment and APIs!@#& !@#&local function isAdvanced()!@#&        return term.isColor and term.isColor()!@#&end!@#& !@#&local function clearPage(site, color, redraw, tcolor)!@#&        -- Site titles!@#&        local titles = {firewolf = \"Firewolf Homepage\", [\"server/rdnt\"] = \"RDNT Server Management\",!@#&                [\"server/http\"] = \"HTTP Server Management\", help = \"Firewolf Help\",!@#&                settings = \"Firewolf Settings\", credits = \"Firewolf Credits\",!@#&                crash = \"Website Has Crashed!\", overspeed = \"Too Fast!\"}!@#&        local title = titles[site]!@#& !@#&        -- Clear!@#&        term.setBackgroundColor(color or colors.black)!@#&        term.setTextColor(colors[theme[\"address-bar-text\"]])!@#&        if redraw ~= true then term.clear() end!@#& !@#&        if not menuBarOpen then!@#&                term.setBackgroundColor(colors[theme[\"address-bar-background\"]])!@#&                term.setCursorPos(2, 1)!@#&                term.clearLine()!@#&                local a = site!@#&                if a:len() > w - 10 then a = a:sub(1, 38) .. \"...\" end!@#&                if curProtocol == protocols.rdnt then write(\"rdnt://\" .. a)!@#&                elseif curProtocol == protocols.http then write(\"http://\" .. a) end!@#& !@#&                if title ~= nil then!@#&                        term.setCursorPos(w - title:len() - 1, 1)!@#&                        write(title)!@#&                end if isAdvanced() then!@#&                        term.setCursorPos(w, 1)!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        write(\"<\")!@#&                end!@#& !@#&                term.setBackgroundColor(color or colors.black)!@#&                term.setTextColor(tcolor or colors.white)!@#&        else!@#&                term.setCursorPos(1, 1)!@#&                term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                term.setTextColor(colors[theme[\"text-color\"]])!@#&                term.clearLine()!@#&                write(\"> [- Exit Firewolf -]                              \")!@#&        end!@#& !@#&        print(\"\")!@#&end!@#& !@#&local function printWithType(t, func)!@#&        if type(t) == \"table\" then!@#&                for k, v in pairs(t) do!@#&                        env.pcall(function() printWithType(v, func) end)!@#&                end!@#&        else!@#&                func(tostring(t))!@#&        end!@#&end!@#& !@#&-- Drawing Functions!@#&api.centerWrite = function(text)!@#&        printWithType(text, function(t)!@#&                local x, y = term.getCursorPos()!@#&                term.setCursorPos(math.ceil((w + 1)/2 - t:len()/2), y)!@#&                write(t)!@#&        end)!@#&end!@#& !@#&api.centerPrint = function(text)!@#&        printWithType(text, function(t)!@#&                local x, y = term.getCursorPos()!@#&                term.setCursorPos(math.ceil((w + 1)/2 - t:len()/2), y)!@#&                print(t)!@#&        end)!@#&end!@#& !@#&api.leftWrite = function(text)!@#&        printWithType(text, function(t)!@#&                local x, y = term.getCursorPos()!@#&                term.setCursorPos(1, y)!@#&                write(t)!@#&        end)!@#&end!@#& !@#&api.leftPrint = function(text)!@#&        printWithType(text, function(t)!@#&                local x, y = term.getCursorPos()!@#&                term.setCursorPos(1, y)!@#&                print(t)!@#&        end)!@#&end!@#& !@#&api.rightWrite = function(text)!@#&        printWithType(text, function(t)!@#&                local x, y = term.getCursorPos()!@#&                term.setCursorPos(w - t:len() + 1, y)!@#&                write(t)!@#&        end)!@#&end!@#& !@#&api.rightPrint = function(text)!@#&        printWithType(text, function(t)!@#&                local x, y = term.getCursorPos()!@#&                term.setCursorPos(w - t:len() + 1, y)!@#&                print(t)!@#&        end)!@#&end!@#& !@#&-- Server Interation Functions!@#& !@#&api.loadFileFromServer = function(path)!@#&        if type(path) ~= \"string\" then error(\"loadFile: expected string\") end!@#&        sleep(0.05)!@#&        if path:sub(1, 1) == \"/\" then path = path:sub(2, -1) end!@#&        local id, content = curProtocol.getWebsite(website .. \"/\" .. path)!@#&        if id then!@#&                return content!@#&        end!@#&        return nil!@#&end!@#& !@#&api.ioReadFileFromServer = function(path)!@#&        local content = api.loadFileFromServer(path)!@#&        if content then!@#&                local f = env.io.open(rootFolder .. \"/temp_file\", \"w\")!@#&                f:write(content)!@#&                f:close()!@#&                local fi = env.io.open(rootFolder .. \"/temp_file\", \"r\")!@#&                return fi!@#&        end!@#&        return nil!@#&end!@#& !@#&api.loadImageFromServer = function(path)!@#&        local content = api.loadFileFromServer(path)!@#&        if content then!@#&                local f = env.io.open(rootFolder .. \"/temp_file\", \"w\")!@#&                f:write(content)!@#&                f:close()!@#& !@#&                local image = paintutils.loadImage(rootFolder .. \"/temp_file\")!@#&                env.fs.delete(\"/temp_file\")!@#&                return image!@#&        end!@#&        return nil!@#&end!@#& !@#&api.writeDataFile = function(path, content)!@#&        if type(path) ~= \"string\" or type(content) ~= \"string\" then!@#&                error(\"writeDataFile: expected string, string\") end!@#&        if path:sub(1, 1) == \"/\" then path = path:sub(2, -1) end!@#&        local dataPath = websiteDataFolder .. \"/\" .. path:gsub(\"/\", \"$slazh$\")!@#& !@#&        if env.fs.isReadOnly(dataPath) then return false end!@#&        if env.fs.exists(dataPath) then env.fs.delete(dataPath) end!@#&        local f = env.io.open(dataPath, \"w\")!@#&        if not f then return false end!@#&        f:write(content)!@#&        f:close()!@#&        return true!@#&end!@#& !@#&api.readDataFile = function(path)!@#&        if type(path) ~= \"string\" then error(\"readDataFile: expected string\") end!@#&        if path:sub(1, 1) == \"/\" then path = path:sub(2, -1) end!@#&        local dataPath = websiteDataFolder .. \"/\" .. path:gsub(\"/\", \"$slazh$\")!@#& !@#&        if env.fs.isDir(dataPath) then env.fs.delete(dataPath) end!@#&        if env.fs.exists(dataPath) then!@#&                local f = env.io.open(dataPath, \"r\")!@#&                local cont = f:read(\"*a\")!@#&                f:close()!@#&                return cont!@#&        end!@#&        return nil!@#&end!@#& !@#&api.saveFileToUserComputer = function(content)!@#&        if type(content) ~= \"string\" then error(\"saveFileToUserComputer: expected string\") end!@#&        local oldback, oldtext = term.getBackgroundColor(), term.getTextColor()!@#&        local ox, oy = term.getCursorPos()!@#& !@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        term.setCursorPos(1, 1)!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        print(\"\")!@#&        leftPrint(string.rep(\" \", 20))!@#&        leftPrint(\" Save File Request  \")!@#&        leftPrint(string.rep(\" \", 20))!@#&        print(\"\")!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        for i = 1, 11 do rightPrint(string.rep(\" \", 36)) end!@#&        term.setCursorPos(1, 7)!@#&        rightPrint(\"The website: \")!@#&        rightPrint(website .. \" \")!@#&        rightPrint(\"Is requesting to save a file \")!@#&        rightPrint(\"to your computer. \")!@#& !@#&        local ret = nil!@#&        local opt = prompt({{\"Save File\", w - 16, 12}, {\"Cancel\", w - 13, 13}}, \"vertical\")!@#&        if opt == \"Save File\" then!@#&                while true do!@#&                        term.setCursorPos(1, 15)!@#&                        rightWrite(string.rep(\" \", 36))!@#&                        term.setCursorPos(w - 34, 15)!@#&                        write(\"Path: /\")!@#&                        local p = read()!@#& !@#&                        term.setCursorPos(1, 15)!@#&                        rightWrite(string.rep(\" \", 36))!@#&                        if p == \"\" or p == nil then!@#&                                rightWrite(\"File Name Empty! Cancelling... \")!@#&                                break!@#&                        elseif fs.exists(\"/\" .. p) then!@#&                                rightWrite(\"File Already Exists! \")!@#&                        else!@#&                                rightWrite(\"File Saved! \")!@#&                                ret = \"/\" .. p!@#&                                break!@#&                        end!@#& !@#&                        openAddressBar = false!@#&                        sleep(1.3)!@#&                        openAddressBar = true!@#&                end!@#&        elseif opt == \"Cancel\" then!@#&                term.setCursorPos(1, 15)!@#&                rightWrite(\"Saving Cancelled! \")!@#&        end!@#& !@#&        openAddressBar = false!@#&        sleep(1.3)!@#&        openAddressBar = true!@#& !@#&        term.setBackgroundColor(oldback or colors.black)!@#&        term.setTextColor(oldtext or colors.white)!@#&        term.clear()!@#&        term.setCursorPos(ox, oy)!@#&        return ret!@#&end!@#& !@#&api.urlDownload = function(url)!@#&        if type(url) ~= \"string\" then error(\"download: expected string\") end!@#&        local source = nil!@#&        http.request(url)!@#&        local a = os.startTimer(10)!@#&        while true do!@#&                local e, surl, handle = os.pullEvent()!@#&                if e == \"http_success\" then!@#&                        source = handle.readAll()!@#&                        break!@#&                elseif e == \"http_failure\" or (e == \"timer\" and surl == a) then!@#&                        break!@#&                end!@#&        end!@#& !@#&        if type(source) == \"string\" then!@#&                local saveFunc = api.saveFileToUserComputer!@#&                env.setfenv(saveFunc, override)!@#&                return saveFunc(source)!@#&        else return nil end!@#&end!@#& !@#&api.pastebinDownload = function(code)!@#&        return api.urlDownload(\"http://pastebin.com/raw.php?i=\" .. tostring(code))!@#&end!@#& !@#&-- Redirect!@#&api.redirect = function(url)!@#&        if type(url) ~= \"string\" then url = \"home\" end!@#&        os.queueEvent(event_redirect, url:gsub(\"rdnt://\"):gsub(\"http://\"))!@#&        error()!@#&end!@#& !@#&-- Theme Function!@#&api.themeColor = function(tag, default)!@#&        if type(tag) ~= \"string\" then error(\"themeColor: expected string\") end!@#&        if theme[tag] then!@#&                return colors[theme[tag]]!@#&        elseif defaultTheme[tag] then!@#&                return colors[defaultTheme[tag]]!@#&        else!@#&                return default or colors.white!@#&        end!@#&end!@#& !@#&api.themeColour = function(tag, default)!@#&        return api.themeColor(tag, default)!@#&end!@#& !@#&-- Prompt Software!@#&api.prompt = function(list, dir)!@#&        if isAdvanced() then!@#&                for _, v in pairs(list) do!@#&                        if v.bg then term.setBackgroundColor(v.bg) end!@#&                        if v.tc then term.setTextColor(v.tc) end!@#&                        if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 6)/2) end!@#& !@#&                        term.setCursorPos(v[2], v[3])!@#&                        write(\"[- \" .. v[1])!@#&                        term.setCursorPos(v[2] + v[1]:len() + 3, v[3])!@#&                        write(\" -]\")!@#&                end!@#& !@#&                while true do!@#&                        local e, but, x, y = os.pullEvent()!@#&                        if e == \"mouse_click\" then!@#&                                for _, v in pairs(list) do!@#&                                        if x >= v[2] and x <= v[2] + v[1]:len() + 5 and y == v[3] then!@#&                                                return v[1]!@#&                                        end!@#&                                end!@#&                        end!@#&                end!@#&        else!@#&                for _, v in pairs(list) do!@#&                        term.setBackgroundColor(colors.black)!@#&                        term.setTextColor(colors.white)!@#&                        if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 4)/2) end!@#& !@#&                        term.setCursorPos(v[2], v[3])!@#&                        write(\"  \" .. v[1])!@#&                        term.setCursorPos(v[2] + v[1]:len() + 2, v[3])!@#&                        write(\"  \")!@#&                end!@#& !@#&                local key1, key2 = 200, 208!@#&                if dir == \"horizontal\" then key1, key2 = 203, 205 end!@#& !@#&                local curSel = 1!@#&                term.setCursorPos(list[curSel][2], list[curSel][3])!@#&                write(\"[\")!@#&                term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])!@#&                write(\"]\")!@#& !@#&                while true do!@#&                        local e, key = os.pullEvent()!@#&                        term.setCursorPos(list[curSel][2], list[curSel][3])!@#&                        write(\" \")!@#&                        term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])!@#&                        write(\" \")!@#&                        if e == \"key\" and key == key1 and curSel > 1 then!@#&                                curSel = curSel - 1!@#&                        elseif e == \"key\" and key == key2 and curSel < #list then!@#&                                curSel = curSel + 1!@#&                        elseif e == \"key\" and key == 28 then!@#&                                return list[curSel][1]!@#&                        end!@#&                        term.setCursorPos(list[curSel][2], list[curSel][3])!@#&                        write(\"[\")!@#&                        term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])!@#&                        write(\"]\")!@#&                end!@#&        end!@#&end!@#& !@#&api.scrollingPrompt = function(list, x, y, len, width)!@#&        local wid = width!@#&        if wid == nil then wid = w - 3 end!@#& !@#&        local function updateDisplayList(items, loc, len)!@#&                local ret = {}!@#&                for i = 1, len do!@#&                        local item = items[i + loc - 1]!@#&                        if item ~= nil then table.insert(ret, item) end!@#&                end!@#&                return ret!@#&        end!@#& !@#&        if isAdvanced() then!@#&                local function draw(a)!@#&                        for i, v in ipairs(a) do!@#&                                term.setCursorPos(x, y + i - 1)!@#&                                write(string.rep(\" \", wid))!@#&                                term.setCursorPos(x, y + i - 1)!@#&                                write(\"[ \" .. v:sub(1, wid - 5))!@#&                                term.setCursorPos(wid + x - 2, y + i - 1)!@#&                                write(\"  ]\")!@#&                        end!@#&                end!@#& !@#&                local loc = 1!@#&                local disList = updateDisplayList(list, loc, len)!@#&                draw(disList)!@#&               !@#&                while true do!@#&                        local e, but, clx, cly = os.pullEvent()!@#&                        if e == \"key\" and but == 200 and loc > 1 then!@#&                                loc = loc - 1!@#&                                disList = updateDisplayList(list, loc, len)!@#&                                draw(disList)!@#&                        elseif e == \"key\" and but == 208 and loc + len - 1 < #list then!@#&                                loc = loc + 1!@#&                                disList = updateDisplayList(list, loc, len)!@#&                                draw(disList)!@#&                        elseif e == \"mouse_scroll\" and but > 0 and loc + len - 1 < #list then!@#&                                loc = loc + but!@#&                                disList = updateDisplayList(list, loc, len)!@#&                                draw(disList)!@#&                        elseif e == \"mouse_scroll\" and but < 0 and loc > 1 then!@#&                                loc = loc + but!@#&                                disList = updateDisplayList(list, loc, len)!@#&                                draw(disList)!@#&                        elseif e == \"mouse_click\" then!@#&                                for i, v in ipairs(disList) do!@#&                                        if clx >= x and clx <= x + wid and cly == i + y - 1 then!@#&                                                return v!@#&                                        end!@#&                                end!@#&                        end!@#&                end!@#&        else!@#&                local function draw(a)!@#&                        for i, v in ipairs(a) do!@#&                                term.setCursorPos(x, y + i - 1)!@#&                                write(string.rep(\" \", wid))!@#&                                term.setCursorPos(x, y + i - 1)!@#&                                write(\"[ ] \" .. v:sub(1, wid - 5))!@#&                        end!@#&                end!@#& !@#&                local loc = 1!@#&                local curSel = 1!@#&                local disList = updateDisplayList(list, loc, len)!@#&                draw(disList)!@#&                term.setCursorPos(x + 1, y + curSel - 1)!@#&                write(\"x\")!@#& !@#&                while true do!@#&                        local e, key = os.pullEvent()!@#&                        term.setCursorPos(x + 1, y + curSel - 1)!@#&                        write(\" \")!@#&                        if e == \"key\" and key == 200 then!@#&                                if curSel > 1 then!@#&                                        curSel = curSel - 1!@#&                                elseif loc > 1 then!@#&                                        loc = loc - 1!@#&                                        disList = updateDisplayList(list, loc, len)!@#&                                        draw(disList)!@#&                                end!@#&                        elseif e == \"key\" and key == 208 then!@#&                                if curSel < #disList then!@#&                                        curSel = curSel + 1!@#&                                elseif loc + len - 1 < #list then!@#&                                        loc = loc + 1!@#&                                        disList = updateDisplayList(list, loc, len)!@#&                                        draw(disList)!@#&                                end!@#&                        elseif e == \"key\" and key == 28 then!@#&                                return list[curSel + loc - 1]!@#&                        end!@#&                        term.setCursorPos(x + 1, y + curSel - 1)!@#&                        write(\"x\")!@#&                end!@#&        end!@#&end!@#& !@#&api.clearArea = function() api.clearPage(website) end!@#&api.cPrint = function(text) api.centerPrint(text) end!@#&api.cWrite = function(text) api.centerWrite(text) end!@#&api.lPrint = function(text) api.leftPrint(text) end!@#&api.lWrite = function(text) api.leftWrite(text) end!@#&api.rPrint = function(text) api.rightPrint(text) end!@#&api.rWrite = function(text) api.rightWrite(text) end!@#& !@#&local pullevent = function(data)!@#&        while true do!@#&                local e, p1, p2, p3, p4, p5 = os.pullEventRaw()!@#&                if e == event_exitWebsite or e == \"terminate\" then!@#&                        error()!@#&                end!@#& !@#&                if data then!@#&                        if e == data then return e, p1, p2, p3, p4, p5 end!@#&                else return e, p1, p2, p3, p4, p5 end!@#&        end!@#&end!@#& !@#&-- Set Environment!@#&for k, v in pairs(getfenv(0)) do env[k] = v end!@#&for k, v in pairs(getfenv(1)) do env[k] = v end!@#&for k, v in pairs(env) do oldEnv[k] = v end!@#&for k, v in pairs(api) do env[k] = v end!@#&for k, v in pairs(env) do backupEnv[k] = v end!@#& !@#&oldEnv[\"os\"][\"pullEvent\"] = oldpullevent!@#&env[\"os\"][\"pullEvent\"] = pullevent!@#&os.pullEvent = pullevent!@#& !@#& !@#&--  -------- Website Overrides!@#& !@#&for k, v in pairs(env) do override[k] = v end!@#&local curtext, curbackground = colors.white, colors.black!@#&override.term = {}!@#&for k, v in pairs(env.term) do override.term[k] = v end!@#&override.os = {}!@#&for k, v in pairs(env.os) do override.os[k] = v end!@#& !@#&override.write = function( sText )!@#&        local w,h = override.term.getSize()            !@#&        local x,y = override.term.getCursorPos()!@#&       !@#&        local nLinesPrinted = 0!@#&        local function newLine()!@#&                if y + 1 <= h then!@#&                        override.term.setCursorPos(1, y + 1)!@#&                else!@#&                        override.term.setCursorPos(1, h)!@#&                        override.term.scroll(1)!@#&                end!@#&                x, y = override.term.getCursorPos()!@#&                nLinesPrinted = nLinesPrinted + 1!@#&        end!@#&       !@#&        -- Print the line with proper word wrapping!@#&        while string.len(sText) > 0 do!@#&                local whitespace = string.match( sText, \"^[ \\t]+\" )!@#&                if whitespace then!@#&                        -- Print whitespace!@#&                        term.write( whitespace )!@#&                        x,y = override.term.getCursorPos()!@#&                        sText = string.sub( sText, string.len(whitespace) + 1 )!@#&                end!@#&               !@#&                local newline = string.match( sText, \"^\\n\" )!@#&                if newline then!@#&                        -- Print newlines!@#&                        newLine()!@#&                        sText = string.sub( sText, 2 )!@#&                end!@#&               !@#&                local text = string.match( sText, \"^[^ \\t\\n]+\" )!@#&                if text then!@#&                        sText = string.sub( sText, string.len(text) + 1 )!@#&                        if string.len(text) > w then!@#&                                -- Print a multiline word                              !@#&                                while string.len( text ) > 0 do!@#&                                        if x > w then!@#&                                                newLine()!@#&                                        end!@#&                                        term.write( text )!@#&                                        text = string.sub( text, (w-x) + 2 )!@#&                                        x,y = override.term.getCursorPos()!@#&                                end!@#&                        else!@#&                                -- Print a word normally!@#&                                if x + string.len(text) - 1 > w then!@#&                                        newLine()!@#&                                end!@#&                                term.write( text )!@#&                                x,y = override.term.getCursorPos()!@#&                        end!@#&                end!@#&        end!@#&       !@#&        return nLinesPrinted!@#&end!@#& !@#&override.print = function( ... )!@#&        local nLinesPrinted = 0!@#&        for n,v in ipairs( { ... } ) do!@#&                nLinesPrinted = nLinesPrinted + override.write( tostring( v ) )!@#&        end!@#&        nLinesPrinted = nLinesPrinted + override.write( \"\\n\" )!@#&        return nLinesPrinted!@#&end!@#& !@#&override.term.getSize = function()!@#&        local a, b = env.term.getSize()!@#&        return a, b - 1!@#&end!@#& !@#&override.term.setCursorPos = function(x, y)!@#&        if y < 1 then!@#&                return env.term.setCursorPos(x, 2)!@#&        else!@#&                return env.term.setCursorPos(x, y+1)!@#&        end!@#&end!@#& !@#&override.term.getCursorPos = function()!@#&        local x, y = env.term.getCursorPos()!@#&        return x, y - 1!@#&end!@#& !@#&override.term.getBackgroundColor = function()!@#&        return curbackground!@#&end!@#& !@#&override.term.getBackgroundColour = function()!@#&        return override.term.getBackgroundColor()!@#&end!@#& !@#&override.term.setBackgroundColor = function(col)!@#&        curbackground = col!@#&        return env.term.setBackgroundColor(col)!@#&end!@#& !@#&override.term.setBackgroundColour = function(col)!@#&        return override.term.setBackgroundColor(col)!@#&end!@#& !@#&override.term.getTextColor = function()!@#&        return curtext!@#&end!@#& !@#&override.term.getTextColour = function()!@#&        return override.term.getTextColor()!@#&end!@#& !@#&override.term.setTextColor = function(col)!@#&        curtext = col!@#&        return env.term.setTextColor(col)!@#&end!@#& !@#&override.term.setTextColour = function(col)!@#&        return override.term.setTextColor(col)!@#&end!@#& !@#&override.term.clear = function()!@#&        local x, y = term.getCursorPos()!@#&        local oldbackground = override.term.getBackgroundColor()!@#&        local oldtext = override.term.getTextColor()!@#&        clearPage(website, curbackground)!@#& !@#&        term.setBackgroundColor(oldbackground)!@#&        term.setTextColor(oldtext)!@#&        term.setCursorPos(x, y)!@#&end!@#& !@#&override.term.scroll = function(n)!@#&        local x, y = term.getCursorPos()!@#&        local oldbackground = override.term.getBackgroundColor()!@#&        local oldtext = override.term.getTextColor()!@#& !@#&        env.term.scroll(n)!@#&        clearPage(website, curbackground, true)!@#&        term.setBackgroundColor(oldbackground)!@#&        term.setTextColor(oldtext)!@#&        term.setCursorPos(x, y)!@#&end!@#& !@#&override.term.isColor = function() return isAdvanced() end!@#&override.term.isColour = function() return override.term.isColor() end!@#& !@#&override.os.queueEvent = function(event, ...)!@#&        if event == \"terminate\" or event == event_exitApp then!@#&                os.queueEvent(event_exitWebsite)!@#&        else!@#&                env.os.queueEvent(event, ...)!@#&        end!@#&end!@#& !@#&override.os.pullEvent = function(data)!@#&        while true do!@#&                local e, p1, p2, p3, p4, p5 = os.pullEventRaw()!@#&                if e == event_exitWebsite or e == \"terminate\" then!@#&                        error()!@#&                elseif (e == \"mouse_click\" or e == \"mouse_drag\") and not data then!@#&                        return e, p1, p2, p3 - 1!@#&                elseif e == \"mouse_click\" and data == \"mouse_click\" then!@#&                        return e, p1, p2, p3 - 1!@#&                elseif e == \"mouse_drag\" and data == \"mouse_drag\" then!@#&                        return e, p1, p2, p3 - 1!@#&                end!@#&               !@#&                if data then!@#&                        if e == data then return e, p1, p2, p3, p4, p5 end!@#&                else return e, p1, p2, p3, p4, p5 end!@#&        end!@#&end!@#& !@#&local overridePullEvent = override.os.pullEvent!@#& !@#&override.prompt = function(list, dir)!@#&        local a = {}!@#&        for k, v in pairs(list) do!@#&                table.insert(a, {v[1], v[2], v[3] + 1, tc = v.tc or curtext, bg = v.bg or curbackground})!@#&        end!@#&        return env.prompt(a, dir)!@#&end!@#& !@#&override.scrollingPrompt = function(list, x, y, len, width)!@#&        return env.scrollingPrompt(list, x, y + 1, len, width)!@#&end!@#& !@#&local barTerm = {}!@#&for k, v in pairs(override.term) do barTerm[k] = v end!@#& !@#&barTerm.clear = override.term.clear!@#&barTerm.scroll = override.term.scroll!@#& !@#&local safeTerm = {}!@#&for k, v in pairs(term) do safeTerm[k] = v end!@#& !@#&override.showBar = function()!@#&        clickableAddressBar = true!@#&        os.pullEvent = overridePullEvent!@#&        return os.pullEvent, barTerm!@#&end!@#& !@#&override.hideBar = function()!@#&        clickableAddressBar = false!@#&        os.pullEvent = pullevent!@#&        return os.pullEvent, safeTerm!@#&end!@#& !@#& !@#&--  -------- Antivirus System!@#& !@#&-- Overrides!@#&local antivirusOverrides = {!@#&        [\"Run Files\"] = {\"shell.run\", \"os.run\"},!@#&        [\"Modify System\"] = {\"shell.setAlias\", \"shell.clearAlias\", \"os.setComputerLabel\", \"shell.setDir\",!@#&                \"shell.setPath\"},!@#&        [\"Modify Files\"] = {\"fs.makeDir\", \"fs.move\", \"fs.copy\", \"fs.delete\", \"fs.open\",!@#&                \"io.open\", \"io.write\", \"io.read\", \"io.close\"},!@#&        [\"Shutdown Computer\"] = {\"os.shutdown\", \"os.reboot\", \"shell.exit\"},!@#&        [\"Use pcall\"] = {\"pcall\"},!@#&}!@#& !@#&local antivirusDestroy = {!@#&        \"rawset\", \"rawget\", \"setfenv\", \"loadfile\", \"loadstring\", \"dofile\"!@#&}!@#& !@#&-- Graphical Function!@#&local function triggerAntivirus(offence, onlyCancel)!@#&        local oldback, oldtext = curbackground, curtext!@#& !@#&        local ox, oy = term.getCursorPos()!@#&        openAddressBar = false!@#&        term.setBackgroundColor(colors[theme[\"address-bar-background\"]])!@#&        term.setTextColor(colors[theme[\"address-bar-text\"]])!@#&        term.setCursorPos(2, 1)!@#&        term.clearLine()!@#&        write(\"Request: \" .. offence)!@#&        local a = {{\"Allow\", w - 24, 1}, {\"Cancel\", w - 12, 1}}!@#&        if onlyCancel == true then a = {{\"Cancel\", w - 12, 1}} end!@#&        local opt = prompt(a, \"horizontal\")!@#& !@#&        clearPage(website, nil, true)!@#&        term.setTextColor(colors.white)!@#&        term.setBackgroundColor(colors.black)!@#&        term.setCursorPos(ox, oy)!@#&        term.setBackgroundColor(oldback)!@#&        term.setTextColor(oldtext)!@#&        if opt == \"Allow\" then!@#&                -- To prevent the menu bar from opening!@#&                os.queueEvent(\"firewolf_requiredEvent\")!@#&                os.pullEvent()!@#& !@#&                openAddressBar = true!@#&                return true!@#&        elseif opt == \"Cancel\" then!@#&                redirect(\"home\")!@#&        end!@#&end!@#& !@#&-- Copy from override!@#&for k, v in pairs(override) do antivirus[k] = v end!@#& !@#&antivirus.shell = {}!@#&for k, v in pairs(override.shell) do antivirus.shell[k] = v end!@#&antivirus.os = {}!@#&for k, v in pairs(override.os) do antivirus.os[k] = v end!@#&antivirus.fs = {}!@#&for k, v in pairs(override.fs) do antivirus.fs[k] = v end!@#&antivirus.io = {}!@#&for k, v in pairs(override.io) do antivirus.io[k] = v end!@#& !@#&-- Override malicious functions!@#&for warning, v in pairs(antivirusOverrides) do!@#&        for k, func in pairs(v) do!@#&                if func:find(\".\", 1, true) then!@#&                        -- Functions in another table!@#&                        local table = func:sub(1, func:find(\".\", 1, true) - 1)!@#&                        local funcname = func:sub(func:find(\".\", 1, true) + 1, -1)!@#& !@#&                        antivirus[table][funcname] = function(...)!@#&                                env.setfenv(triggerAntivirus, env)!@#&                                if triggerAntivirus(warning) then!@#&                                        return override[table][funcname](...)!@#&                                end!@#&                        end!@#&                else!@#&                        -- Plain functions!@#&                        antivirus[func] = function(...)!@#&                                env.setfenv(triggerAntivirus, env)!@#&                                if triggerAntivirus(warning) then!@#&                                        return override[func](...)!@#&                                end!@#&                        end!@#&                end!@#&        end!@#&end!@#& !@#&-- Override functions to destroy!@#&for k, v in pairs(antivirusDestroy) do!@#&        antivirus[v] = function(...)!@#&                env.setfenv(triggerAntivirus, env)!@#&                triggerAntivirus(\"Destory your System! D:\", true)!@#&                return nil!@#&        end!@#&end!@#& !@#&antivirus.pcall = function(...)!@#&        local suc, err = env.pcall(...)!@#&        if err:lower():find(\"terminate\") then!@#&                error(\"terminate\")!@#&        elseif err:lower():find(event_exitWebsite) then!@#&                error(event_exitWebsite)!@#&        end!@#&       !@#&        return suc, err!@#&end!@#& !@#& !@#&--  -------- Graphics and Files!@#& !@#&graphics.githubImage = [[!@#&f       f!@#&fffffffff!@#&fffffffff!@#&f4244424f!@#&f4444444f!@#&fffffefffe!@#&   fffe e!@#& fffff e  !@#&ff f fe e!@#&     e   e!@#&]]!@#& !@#&files.availableThemes = [[!@#&https://raw.github.com/1lann/firewolf/master/themes/default.txt| |Fire (default)!@#&https://raw.github.com/1lann/firewolf/master/themes/ice.txt| |Ice!@#&https://raw.github.com/1lann/firewolf/master/themes/carbon.txt| |Carbon!@#&https://raw.github.com/1lann/firewolf/master/themes/christmas.txt| |Christmas!@#&https://raw.github.com/1lann/firewolf/master/themes/original.txt| |Original!@#&https://raw.github.com/1lann/firewolf/master/themes/ocean.txt| |Ocean!@#&https://raw.github.com/1lann/firewolf/master/themes/forest.txt| |Forest!@#&https://raw.github.com/1lann/firewolf/master/themes/pinky.txt| |Pinky!@#&https://raw.github.com/1lann/firewolf/master/themes/azhftech.txt| |AzhfTech!@#&]]!@#& !@#&files.newTheme = [[!@#&-- Text color of the address bar!@#&address-bar-text=!@#& !@#&-- Background color of the address bar!@#&address-bar-background=!@#& !@#&-- Color of separator bar when live searching!@#&address-bar-base=!@#& !@#&-- Top box color!@#&top-box=!@#& !@#&-- Bottom box color!@#&bottom-box=!@#& !@#&-- Background color!@#&background=!@#& !@#&-- Main text color!@#&text-color=!@#& !@#&]]!@#& !@#& !@#&--  -------- Themes!@#& !@#&local defaultTheme = {[\"address-bar-text\"] = \"white\", [\"address-bar-background\"] = \"gray\",!@#&        [\"address-bar-base\"] = \"lightGray\", [\"top-box\"] = \"red\", [\"bottom-box\"] = \"orange\",!@#&        [\"text-color\"] = \"white\", [\"background\"] = \"gray\"}!@#&local originalTheme = {[\"address-bar-text\"] = \"white\", [\"address-bar-background\"] = \"black\",!@#&        [\"address-bar-base\"] = \"black\", [\"top-box\"] = \"black\", [\"bottom-box\"] = \"black\",!@#&        [\"text-color\"] = \"white\", [\"background\"] = \"black\"}!@#& !@#&local function loadTheme(path)!@#&        if fs.exists(path) and not fs.isDir(path) then!@#&                local a = {}!@#&                local f = io.open(path, \"r\")!@#&                local l = f:read(\"*l\")!@#&                while l ~= nil do!@#&                        l = l:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                        if l ~= \"\" and l ~= nil and l ~= \"\\n\" and l:sub(1, 2) ~= \"--\" then!@#&                                local b = l:find(\"=\")!@#&                                if a and b then!@#&                                        local c = l:sub(1, b - 1)!@#&                                        local d = l:sub(b + 1, -1)!@#&                                        if c == \"\" or d == \"\" then return nil!@#&                                        else a[c] = d end!@#&                                else return nil end!@#&                        end!@#&                        l = f:read(\"*l\")!@#&                end!@#&                f:close()!@#& !@#&                return a!@#&        end!@#&end!@#& !@#& !@#&--  -------- Filesystem and HTTP!@#& !@#&local function download(url, path)!@#&        for i = 1, 3 do!@#&                local response = http.get(url)!@#&                if response then!@#&                        local data = response.readAll()!@#&                        response.close()!@#&                        if path then!@#&                                local f = io.open(path, \"w\")!@#&                                f:write(data)!@#&                                f:close()!@#&                        end!@#&                        return true!@#&                end!@#&        end!@#& !@#&        return false  !@#&end!@#& !@#&local function updateClient()!@#&        local skipNormal = false!@#&        if serverID ~= \"experimental\" then!@#&                http.request(buildURL)!@#&                local a = os.startTimer(10)!@#&                while true do!@#&                        local e, url, handle = os.pullEvent()!@#&                        if e == \"http_success\" then!@#&                                if tonumber(handle.readAll()) > build then break!@#&                                else return false end!@#&                        elseif e == \"http_failure\" or (e == \"timer\" and url == a) then!@#&                                skipNormal = true!@#&                                break!@#&                        end!@#&                end!@#&        end!@#& !@#&        local source = nil!@#& !@#&        if not skipNormal then!@#&                local _, y = term.getCursorPos()!@#&                term.setCursorPos(1, y - 2)!@#&                rightWrite(string.rep(\" \", 32))!@#&                rightWrite(\"Updating Firewolf... \")!@#& !@#&                http.request(firewolfURL)!@#&                local a = os.startTimer(10)!@#&                while true do!@#&                        local e, url, handle = os.pullEvent()!@#&                        if e == \"http_success\" then!@#&                                source = handle!@#&                                break!@#&                        elseif e == \"http_failure\" or (e == \"timer\" and url == a) then!@#&                                break!@#&                        end!@#&                end!@#&        end!@#& !@#&        if not source then!@#&                if isAdvanced() then!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        term.setBackgroundColor(colors[theme[\"background\"]])!@#&                        term.clear()!@#&                        if not fs.exists(rootFolder) then fs.makeDir(rootFolder) end!@#&                        local f = io.open(rootFolder .. \"/temp_file\", \"w\")!@#&                        f:write(graphics.githubImage)!@#&                        f:close()!@#&                        local a = paintutils.loadImage(rootFolder .. \"/temp_file\")!@#&                        paintutils.drawImage(a, 5, 5)!@#&                        fs.delete(rootFolder .. \"/temp_file\")!@#& !@#&                        term.setCursorPos(19, 4)!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        write(string.rep(\" \", 32))!@#&                        term.setCursorPos(19, 5)!@#&                        write(\"  Could Not Connect to GitHub!  \")!@#&                        term.setCursorPos(19, 6)!@#&                        write(string.rep(\" \", 32))!@#&                        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                        term.setCursorPos(19, 8)!@#&                        write(string.rep(\" \", 32))!@#&                        term.setCursorPos(19, 9)!@#&                        write(\"    Sorry, Firewolf could not   \")!@#&                        term.setCursorPos(19, 10)!@#&                        write(\" connect to GitHub to download  \")!@#&                        term.setCursorPos(19, 11)!@#&                        write(\" necessary files. Please check: \")!@#&                        term.setCursorPos(19, 12)!@#&                        write(\"    http://status.github.com    \")!@#&                        term.setCursorPos(19, 13)!@#&                        write(string.rep(\" \", 32))!@#&                        term.setCursorPos(19, 14)!@#&                        write(\"        Click to exit...        \")!@#&                        term.setCursorPos(19, 15)!@#&                        write(string.rep(\" \", 32))!@#&                else!@#&                        term.clear()!@#&                        term.setCursorPos(1, 1)!@#&                        term.setBackgroundColor(colors.black)!@#&                        term.setTextColor(colors.white)!@#&                        print(\"\\n\")!@#&                        centerPrint(\"Could not connect to GitHub!\")!@#&                        print(\"\")!@#&                        centerPrint(\"Sorry, Firewolf could not connect to\")!@#&                        centerPrint(\"GitHub to download necessary files.\")!@#&                        centerPrint(\"Please check:\")!@#&                        centerPrint(\"http://status.github.com\")!@#&                        print(\"\")!@#&                        centerPrint(\"Press any key to exit...\")!@#&                end!@#& !@#&                while true do!@#&                        local e = oldpullevent()!@#&                        if e == \"mouse_click\" or e == \"key\" then break end!@#&                end!@#& !@#&                return false!@#&        elseif source and autoupdate == \"true\" then!@#&                local b = io.open(firewolfLocation, \"r\")!@#&                local new = source.readAll()!@#&                local cur = b:read(\"*a\")!@#&                source.close()!@#&                b:close()!@#& !@#&                if cur ~= new then!@#&                        fs.delete(firewolfLocation)!@#&                        local f = io.open(firewolfLocation, \"w\")!@#&                        f:write(new)!@#&                        f:close()!@#&                        return true!@#&                else!@#&                        return false!@#&                end!@#&        end!@#&end!@#& !@#&local function resetFilesystem()!@#&        -- Migrate!@#&        fs.delete(rootFolder .. \"/available_themes\")!@#&        fs.delete(rootFolder .. \"/default_theme\")!@#& !@#&        -- Reset!@#&        if not fs.exists(rootFolder) then fs.makeDir(rootFolder)!@#&        elseif not fs.isDir(rootFolder) then fs.move(rootFolder, \"/Firewolf_Data.old\") end!@#& !@#&        if not fs.isDir(serverFolder) then fs.delete(serverFolder) end!@#&        if not fs.exists(serverFolder) then fs.makeDir(serverFolder) end!@#&        if not fs.isDir(cacheFolder) then fs.delete(cacheFolder) end!@#&        if not fs.exists(cacheFolder) then fs.makeDir(cacheFolder) end!@#&        if not fs.isDir(websiteDataFolder) then fs.delete(websiteDataFolder) end!@#&        if not fs.exists(websiteDataFolder) then fs.makeDir(websiteDataFolder) end!@#& !@#&        if fs.isDir(settingsLocation) then fs.delete(settingsLocation) end!@#&        if fs.isDir(serverLocation) then fs.delete(serverLocation) end!@#& !@#&        if not fs.exists(settingsLocation) then!@#&                local f = io.open(settingsLocation, \"w\")!@#&                f:write(textutils.serialize({auto = \"true\", incog = \"false\", home = \"firewolf\"}))!@#&                f:close()!@#&        end!@#& !@#&        if not fs.exists(serverLocation) then!@#&                download(serverURL, serverLocation)!@#&        end!@#& !@#&        fs.delete(rootFolder .. \"/temp_file\")!@#& !@#&        for _, v in pairs({userWhitelist, userBlacklist}) do!@#&                if fs.isDir(v) then fs.delete(v) end!@#&                if not fs.exists(v) then!@#&                        local f = io.open(v, \"w\")!@#&                        f:write(\"\")!@#&                        f:close()!@#&                end!@#&        end!@#&end!@#& !@#&local function checkForModem(display)!@#&        while true do!@#&                local present = false!@#&                for _, v in pairs(rs.getSides()) do!@#&                        if peripheral.getType(v) == \"modem\" then!@#&                                rednet.open(v)!@#&                                present = true!@#&                                break!@#&                        end!@#&                end!@#& !@#&                if not present and type(display) == \"function\" then!@#&                        display()!@#&                        os.pullEvent(\"peripheral\")!@#&                else!@#&                        return true!@#&                end!@#&        end!@#&end!@#& !@#& !@#&--  -------- Databases!@#& !@#&local function loadDatabases()!@#&        -- Blacklist!@#&        if fs.exists(userBlacklist) and not fs.isDir(userBlacklist) then!@#&                local bf = io.open(userBlacklist, \"r\")!@#&                local l = bf:read(\"*l\")!@#&                while l ~= nil do!@#&                        if l ~= nil and l ~= \"\" and l ~= \"\\n\" then!@#&                                l = l:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                                table.insert(blacklist, l)!@#&                        end!@#&                        l = bf:read(\"*l\")!@#&                end!@#&                bf:close()!@#&        end!@#& !@#&        -- Whitelist!@#&        if fs.exists(userWhitelist) and not fs.isDir(userWhitelist) then!@#&                local wf = io.open(userWhitelist, \"r\")!@#&                local l = wf:read(\"*l\")!@#&                while l ~= nil do!@#&                        if l ~= nil and l ~= \"\" and l ~= \"\\n\" then!@#&                                l = l:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                                local a, b = l:find(\"| |\")!@#&                                table.insert(whitelist, {l:sub(1, a - 1), l:sub(b + 1, -1)})!@#&                        end!@#&                        l = wf:read(\"*l\")!@#&                end!@#&                wf:close()!@#&        end!@#&end!@#& !@#&local function verifyBlacklist(id)!@#&        for _, v in pairs(blacklist) do!@#&                if tostring(id) == v then return true end!@#&        end!@#&        return false!@#&end!@#& !@#&local function verifyWhitelist(id, url)!@#&        for _, v in pairs(whitelist) do!@#&                if v[2] == tostring(args[1]) and v[1] == tostring(args[2]) then!@#&                        return true!@#&                end!@#&        end!@#&        return false!@#&end!@#& !@#& !@#&--  -------- Protocols!@#& !@#&protocols.rdnt = {}!@#&protocols.http = {}!@#& !@#&protocols.rdnt.getSearchResults = function()!@#&        dnsDatabase = {[1] = {}, [2] = {}}!@#&        local resultIDs = {}!@#&        local conflict = {}!@#& !@#&        rednet.broadcast(\"firewolf.broadcast.dns.list\")!@#&        local startClock = os.clock()!@#&        while os.clock() - startClock < timeout do!@#&                local id, i = rednet.receive(timeout)!@#&                if id then!@#&                        if i:sub(1, 14) == \"firewolf-site:\" then!@#&                                i = i:sub(15, -1)!@#&                                local bl, wl = verifyBlacklist(id), verifyWhitelist(id, i)!@#&                                if not i:find(\" \") and i:len() < 40 and (not bl or (bl and wl)) then!@#&                                        if not resultIDs[tostring(id)] then resultIDs[tostring(id)] = 1!@#&                                        else resultIDs[tostring(id)] = resultIDs[tostring(id)] + 1!@#&                                        end!@#&                                       !@#&                                        if not i:find(\"rdnt://\") then i = (\"rdnt://\" .. i) end!@#&                                        local x = false!@#&                                        if conflict[i] then!@#&                                                x = true!@#&                                                table.insert(conflict[i], id)!@#&                                        else!@#&                                                for m, n in pairs(dnsDatabase[1]) do!@#&                                                        if n:lower() == i:lower() then!@#&                                                                x = true!@#&                                                                table.remove(dnsDatabase[1], m)!@#&                                                                table.remove(dnsDatabase[2], m)!@#&                                                                if conflict[i] then!@#&                                                                        table.insert(conflict[i], id)!@#&                                                                else!@#&                                                                        conflict[i] = {}!@#&                                                                        table.insert(conflict[i], id)!@#&                                                                end!@#&                                                                break!@#&                                                        end!@#&                                                end!@#&                                        end!@#& !@#&                                        if not x and resultIDs[tostring(id)] <= 3 then!@#&                                                table.insert(dnsDatabase[1], i)!@#&                                                table.insert(dnsDatabase[2], id)!@#&                                        end!@#&                                end!@#&                        end!@#&                else!@#&                        break!@#&                end!@#&        end!@#&        for k,v in pairs(conflict) do!@#&                table.sort(v)!@#&                table.insert(dnsDatabase[1], k)!@#&                table.insert(dnsDatabase[2], v[1])!@#&        end!@#& !@#&        return dnsDatabase[1]!@#&end!@#& !@#&protocols.rdnt.getWebsite = function(site)!@#&        local id, content, status = nil, nil, nil!@#&        local clock = os.clock()!@#&        local websiteID = nil!@#&        for k, v in pairs(dnsDatabase[1]) do!@#&                local web = site:gsub(\"rdnt://\", \"\")!@#&                if web:find(\"/\") then web = web:sub(1, web:find(\"/\") - 1) end!@#&                if web == v:gsub(\"rdnt://\", \"\") then!@#&                        websiteID = dnsDatabase[2][k]!@#&                        break!@#&                end!@#&        end!@#&        if not websiteID then return nil, nil, nil end!@#& !@#&        sleep(timeout)!@#&        rednet.send(websiteID, site)!@#&        clock = os.clock()!@#&        while os.clock() - clock < timeout do!@#&                id, content = rednet.receive(timeout)!@#&                if id then!@#&                        if id == websiteID then!@#&                                local bl = verifyBlacklist(id)!@#&                                local wl = verifyWhitelist(id, site)!@#&                                status = nil!@#&                                if (bl and not wl) or site == \"\" or site == \".\" or site == \"..\" then!@#&                                        -- Ignore!@#&                                elseif wl then!@#&                                        status = \"whitelist\"!@#&                                        break!@#&                                else!@#&                                        status = \"safe\"!@#&                                        break!@#&                                end!@#&                        end!@#&                end!@#&        end!@#& !@#&        return id, content, status!@#&end!@#& !@#&protocols.http.getSearchResults = function()!@#&        dnsDatabase = {[1] = {}, [2] = {}}!@#&        return dnsDatabase[1]!@#&end!@#& !@#&protocols.http.getWebsite = function()!@#&        return nil, nil, nil!@#&end!@#& !@#& !@#&--  -------- Homepage!@#& !@#&pages[\"firewolf\"] = function(site)!@#&        openAddressBar = true!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        print(\"\")!@#&        leftPrint(string.rep(\" \", 42))!@#&        leftPrint([[        _,-='\"-.__               /\\_/\\    ]])!@#&        leftPrint([[         -.}        =._,.-==-._.,  @ @._, ]])!@#&        leftPrint([[            -.__  __,-.   )       _,.-'   ]])!@#&        leftPrint([[ Firewolf ]] .. version .. string.rep(\" \", 8 - version:len()) ..!@#&                [[\"    G..m-\"^m m'        ]])!@#&        leftPrint(string.rep(\" \", 42))!@#&        print(\"\\n\")!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        rightPrint(string.rep(\" \", 42))!@#&        if isAdvanced() then rightPrint(\"  News:                       [- Sites -] \")!@#&        else rightPrint(\"  News:                                   \") end!@#&        rightPrint(\"    Firewolf 2.4 is out! It cuts out 1500 \")!@#&        rightPrint(\"   lines, and contains many improvements! \")!@#&        rightPrint(string.rep(\" \", 42))!@#&        rightPrint(\"   Firewolf 3.0 will be out soon! It will \")!@#&        rightPrint(\"     bring the long awaited HTTP support! \")!@#&        rightPrint(string.rep(\" \", 42))!@#& !@#&        while true do!@#&                local e, but, x, y = os.pullEvent()!@#&                if isAdvanced() and e == \"mouse_click\" and x >= 40 and x <= 50 and y == 11 then!@#&                        redirect(\"firewolf/sites\")!@#&                end!@#&        end!@#&end!@#& !@#&pages[\"firefox\"] = function(site) redirect(\"firewolf\") end!@#& !@#&pages[\"firewolf/sites\"] = function(site)!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        print(\"\\n\")!@#&        leftPrint(string.rep(\" \", 17))!@#&        leftPrint(\" Built-In Sites  \")!@#&        leftPrint(string.rep(\" \", 17))!@#& !@#&        local sx = 8!@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        term.setCursorPos(1, sx)!@#&        rightPrint(string.rep(\" \", 40))!@#&        rightPrint(\"  rdnt://firewolf              Homepage \")!@#&        rightPrint(\"  rdnt://firewolf/sites           Sites \")!@#&        rightPrint(\"  rdnt://server       Server Management \")!@#&        rightPrint(\"  rdnt://help                 Help Page \")!@#&        rightPrint(\"  rdnt://settings              Settings \")!@#&        rightPrint(\"  rdnt://credits                Credits \")!@#&        rightPrint(\"  rdnt://exit                      Exit \")!@#&        rightPrint(string.rep(\" \", 40))!@#& !@#&        local a = {\"firewolf\", \"firewolf/sites\", \"server\", \"help\", \"settings\", \"credits\", \"exit\"}!@#&        while true do!@#&                local e, but, x, y = os.pullEvent()!@#&                if isAdvanced() and e == \"mouse_click\" and x >= 14 and x <= 50 then!@#&                        for i, v in ipairs(a) do!@#&                                if y == sx + i then!@#&                                        if v == \"exit\" then return true end!@#&                                        redirect(v)!@#&                                end!@#&                        end!@#&                end!@#&        end!@#&end!@#& !@#&pages[\"sites\"] = function(site) redirect(\"firewolf/sites\") end!@#& !@#& !@#&--  -------- Server Management!@#& !@#&local function manageServers(site, protocol, functionList, startServerName)!@#&        local servers = functionList[\"reload servers\"]()!@#&        local sy = 7!@#& !@#&        if startServerName == nil then startServerName = \"Start\" end!@#&        if isAdvanced() then!@#&                local function draw(l, sel)!@#&                        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                        term.setCursorPos(4, sy)!@#&                        write(\"[- New Server -]\")!@#&                        for i, v in ipairs(l) do!@#&                                term.setCursorPos(3, i + sy)!@#&                                write(string.rep(\" \", 24))!@#&                                term.setCursorPos(4, i + sy)!@#&                                local nv = v!@#&                                if nv:len() > 18 then nv = nv:sub(1, 15) .. \"...\" end!@#&                                if i == sel then write(\"[ \" .. nv .. \" ]\")!@#&                                else write(\"  \" .. nv) end!@#&                        end!@#&                        if #l < 1 then!@#&                                term.setCursorPos(4, sy + 2)!@#&                                write(\"A website is literally\")!@#&                                term.setCursorPos(4, sy + 3)!@#&                                write(\"just a lua script!\")!@#&                                term.setCursorPos(4, sy + 4)!@#&                                write(\"Go ahead and make one!\")!@#&                                term.setCursorPos(4, sy + 6)!@#&                                write(\"Also, be sure to check\")!@#&                                term.setCursorPos(4, sy + 7)!@#&                                write(\"out Firewolf's APIs to\")!@#&                                term.setCursorPos(4, sy + 8)!@#&                                write(\"help you make your\")!@#&                                term.setCursorPos(4, sy + 9)!@#&                                write(\"site, at rdnt://help\")!@#&                        end!@#& !@#&                        term.setCursorPos(30, sy)!@#&                        write(string.rep(\" \", 19))!@#&                        term.setCursorPos(30, sy)!@#&                        if l[sel] then!@#&                                local nl = l[sel]!@#&                                if nl:len() > 19 then nl = nl:sub(1, 16) .. \"...\" end!@#&                                write(nl)!@#&                        else write(\"No Server Selected!\") end!@#&                        term.setCursorPos(30, sy + 2)!@#&                        write(\"[- \" .. startServerName .. \" -]\")!@#&                        term.setCursorPos(30, sy + 4)!@#&                        write(\"[- Edit -]\")!@#&                        term.setCursorPos(30, sy + 6)!@#&                        if functionList[\"run on boot\"] then write(\"[- Run on Boot -]\") end!@#&                        term.setCursorPos(30, sy + 8)!@#&                        write(\"[- Delete -]\")!@#&                end!@#& !@#&                local function updateDisplayList(items, loc, len)!@#&                        local ret = {}!@#&                        for i = 1, len