Advertisement
Guest User

lol.bin

a guest
Jul 12th, 2013
1,532
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 445.69 KB | None | 0 0
  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 do!@#&                                if items[i + loc - 1] then table.insert(ret, items[i + loc - 1]) end!@#&                        end!@#&                        return ret!@#&                end!@#& !@#&                while true do!@#&                        term.setBackgroundColor(colors[theme[\"background\"]])!@#&                        term.clear()!@#&                        term.setCursorPos(1, 1)!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        print(\"\")!@#&                        leftPrint(string.rep(\" \", 27))!@#&                        leftPrint(\" Server Management - \" .. protocol:upper() .. \"  \")!@#&                        leftPrint(string.rep(\" \", 27))!@#&                        print(\"\")!@#& !@#&                        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                        for i = 1, 12 do!@#&                                term.setCursorPos(3, i + sy - 2)!@#&                                write(string.rep(\" \", 24))!@#&                                term.setCursorPos(29, i + sy - 2)!@#&                                write(string.rep(\" \", 21))!@#&                        end!@#& !@#&                        local sel = 1!@#&                        local loc = 1!@#&                        local len = 10!@#&                        local disList = updateDisplayList(servers, loc, len)!@#&                        draw(disList, sel)!@#& !@#&                        while true do!@#&                                local e, but, x, y = os.pullEvent()!@#&                                if e == \"key\" and but == 200 and #servers > 0 and loc > 1 then!@#&                                        loc = loc - 1!@#&                                        disList = updateDisplayList(servers, loc, len)!@#&                                        draw(disList, sel)!@#&                                elseif e == \"key\" and but == 208 and #servers > 0 and loc + len - 1 < #servers then!@#&                                        loc = loc + 1!@#&                                        disList = updateDisplayList(servers, loc, len)!@#&                                        draw(disList, sel)!@#&                                elseif e == \"mouse_click\" then!@#&                                        if x >= 4 and x <= 25 then!@#&                                                if y == 7 then!@#&                                                        functionList[\"new server\"]()!@#&                                                        servers = functionList[\"reload servers\"]()!@#&                                                        break!@#&                                                elseif #servers > 0 then!@#&                                                        for i, v in ipairs(disList) do!@#&                                                                if y == i + 7 then!@#&                                                                        sel = i!@#&                                                                        draw(disList, sel)!@#&                                                                end!@#&                                                        end!@#&                                                end!@#&                                        elseif x >= 30 and x <= 40 and y == 9 and #servers > 0 then!@#&                                                functionList[\"start\"](disList[sel])!@#&                                                servers = functionList[\"reload servers\"]()!@#&                                                break!@#&                                        elseif x >= 30 and x <= 39 and y == 11 and #servers > 0 then!@#&                                                functionList[\"edit\"](disList[sel])!@#&                                                servers = functionList[\"reload servers\"]()!@#&                                                break!@#&                                        elseif x >= 30 and x <= 46 and y == 13 and #servers > 0 and!@#&                                                        functionList[\"run on boot\"] then!@#&                                                functionList[\"run on boot\"](disList[sel])!@#&                                                term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                                                term.setCursorPos(32, 15)!@#&                                                write(\"Will Run on Boot!\")!@#&                                                openAddressBar = false!@#&                                                sleep(1.3)!@#&                                                openAddressBar = true!@#&                                                term.setCursorPos(32, 15)!@#&                                                write(string.rep(\" \", 18))!@#&                                                break!@#&                                        elseif x >= 30 and x <= 41 and y == 15 and #servers > 0 then!@#&                                                functionList[\"delete\"](disList[sel])!@#&                                                servers = functionList[\"reload servers\"]()!@#&                                                break!@#&                                        end!@#&                                end!@#&                        end!@#&                end!@#&        else!@#&                while true do!@#&                        term.setBackgroundColor(colors[theme[\"background\"]])!@#&                        term.clear()!@#&                        term.setCursorPos(1, 1)!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        print(\"\")!@#&                        centerPrint(string.rep(\" \", 27))!@#&                        centerPrint(\" Server Management - \" .. protocol:upper() .. \"  \")!@#&                        centerPrint(string.rep(\" \", 27))!@#&                        print(\"\")!@#& !@#&                        local a = {\"New Server\"}!@#&                        for _, v in pairs(servers) do table.insert(a, v) end!@#&                        local server = scrollingPrompt(a, 4, 7, 10)!@#&                        if server == \"New Server\" then!@#&                                functionList[\"new server\"]()!@#&                                servers = functionList[\"reload servers\"]()!@#&                        else!@#&                                term.setCursorPos(30, 8)!@#&                                write(server)!@#&                                local a = {{\"Start\", 30, 9}, {\"Edit\", 30, 11}, {\"Run on Boot\", 30, 12},!@#&                                        {\"Delete\", 30, 13}, {\"Back\", 30, 15}}!@#&                                if not functionList[\"run on boot\"] then!@#&                                        a = {{\"Start\", 30, 9}, {\"Edit\", 30, 11}, {\"Delete\", 30, 13}, {\"Back\", 30, 15}}!@#&                                end!@#&                                local opt = prompt(a, \"vertical\")!@#&                                if opt == \"Start\" then!@#&                                        functionList[\"start\"](server)!@#&                                        servers = functionList[\"reload servers\"]()!@#&                                elseif opt == \"Edit\" then!@#&                                        functionList[\"edit\"](server)!@#&                                        servers = functionList[\"reload servers\"](server)!@#&                                elseif opt == \"Run on Boot\" and functionList[\"run on boot\"] then!@#&                                        functionList[\"run on boot\"](server)!@#&                                        term.setCursorPos(32, 16)!@#&                                        write(\"Will Run on Boot!\")!@#&                                        openAddressBar = false!@#&                                        sleep(1.3)!@#&                                        openAddressBar = true!@#&                                elseif opt == \"Delete\" then!@#&                                        functionList[\"delete\"](server)!@#&                                        servers = functionList[\"reload servers\"]()!@#&                                end!@#&                        end!@#&                end!@#&        end!@#&end!@#& !@#&local function editPages(dir)!@#&        local oldLoc = shell.dir()!@#&        local commandHis = {}!@#&        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(dir)!@#&                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 newServer(onCreate)!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        for i = 1, 12 do!@#&                term.setCursorPos(3, i + 5)!@#&                term.clearLine()!@#&        end!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        term.setCursorPos(1, 7)!@#&        for i = 1, 8 do centerPrint(string.rep(\" \", 47)) end!@#&        term.setCursorPos(5, 8)!@#&        write(\"Name: \")!@#&        local name = modRead({refusePrint = \"`\", visibleLength = w - 4, textLength = 200})!@#&        term.setCursorPos(5, 10)!@#&        write(\"URL:\")!@#&        term.setCursorPos(8, 11)!@#&        write(\"rdnt://\")!@#&        local url = modRead({grantPrint = \"abcdefghijklmnopqrstuvwxyz1234567890-_.+\",!@#&                visibleLength = w - 4, textLength = 200})!@#&        url = url:gsub(\" \", \"\")!@#&        if name == \"\" or url == \"\" then!@#&                term.setCursorPos(5, 13)!@#&                write(\"URL or Name is Empty!\")!@#&                openAddressBar = false!@#&                sleep(1.3)!@#&                openAddressBar = true!@#&        else!@#&                local c = onCreate(name, url)!@#& !@#&                term.setCursorPos(5, 13)!@#&                if c and c == \"true\" then!@#&                        write(\"Successfully Created Server!\")!@#&                elseif c == \"false\" or c == nil then!@#&                        write(\"Server Creation Failed!\")!@#&                else!@#&                        write(c)!@#&                end!@#&                openAddressBar = false!@#&                sleep(1.3)!@#&                openAddressBar = true!@#&        end!@#&end!@#& !@#&pages[\"server/rdnt\"] = function(site)!@#&        manageServers(site, \"rdnt\", {[\"reload servers\"] = function()!@#&                local servers = {}!@#&                for _, v in pairs(fs.list(serverFolder)) do!@#&                        if fs.isDir(serverFolder .. \"/\" .. v) then table.insert(servers, v) end!@#&                end!@#& !@#&                return servers!@#&        end, [\"new server\"] = function()!@#&                newServer(function(name, url)!@#&                        if fs.exists(serverFolder .. \"/\" .. url) then!@#&                                return \"Server Already Exists!\"!@#&                        end!@#& !@#&                        fs.makeDir(serverFolder .. \"/\" .. url)!@#&                        local f = io.open(serverFolder .. \"/\" .. url .. \"/home\", \"w\")!@#&                        f:write(\"print(\\\"\\\")\\ncenterPrint(\\\"Welcome To \" .. name .. \"!\\\")\\n\\n\")!@#&                        f:close()!@#&                        return \"true\"!@#&                end)!@#&        end, [\"start\"] = function(server)!@#&                term.clear()!@#&                term.setCursorPos(1, 1)!@#&                term.setBackgroundColor(colors.black)!@#&                term.setTextColor(colors.white)!@#&                openAddressBar = false!@#&                setfenv(1, oldEnv)!@#&                shell.run(serverLocation, server, serverFolder .. \"/\" .. server)!@#&                setfenv(1, override)!@#&                openAddressBar = true!@#&                checkForModem()!@#&        end, [\"edit\"] = function(server)!@#&                openAddressBar = false!@#&                editPages(serverFolder .. \"/\" .. server)!@#&                openAddressBar = true!@#&                if not fs.exists(serverFolder .. \"/\" .. server .. \"/home\") then!@#&                        local f = io.open(serverFolder .. \"/\" .. server .. \"/home\", \"w\")!@#&                        f:write(\"print(\\\"\\\")\\ncenterPrint(\\\"Welcome To \" .. server .. \"!\\\")\\n\\n\")!@#&                        f:close()!@#&                end!@#&        end, [\"run on boot\"] = function(server)!@#&                fs.delete(\"/old-startup\")!@#&                if fs.exists(\"/startup\") then fs.move(\"/startup\", \"/old-startup\") end!@#&                local f = io.open(\"/startup\", \"w\")!@#&                f:write(\"shell.run(\\\"\" .. serverLocation .. \"\\\", \\\"\" .. server .. \"\\\", \\\"\" ..!@#&                        serverFolder .. \"/\" .. server .. \"\\\")\")!@#&                f:close()!@#&        end, [\"delete\"] = function(server)!@#&                fs.delete(serverFolder .. \"/\" .. server)!@#&        end})!@#&end!@#& !@#&pages[\"server/http\"] = function(site)!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        print(\"\\n\\n\")!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        centerPrint(string.rep(\" \", 17))!@#&        centerPrint(\"  Comming Soon!  \")!@#&        centerPrint(string.rep(\" \", 17))!@#&end!@#& !@#&pages[\"server\"] = function(site)!@#&        setfenv(manageServers, override)!@#&        setfenv(newServer, override)!@#&        setfenv(editPages, env)!@#&        if curProtocol == protocols.rdnt then redirect(\"server/rdnt\")!@#&        elseif curProtocol == protocols.http then redirect(\"server/http\") end!@#&end!@#& !@#& !@#&--  -------- Help!@#& !@#&pages[\"help\"] = function(site)!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        print(\"\")!@#&        leftPrint(string.rep(\" \", 16))!@#&        leftPrint(\" Firewolf Help  \")!@#&        leftPrint(string.rep(\" \", 16))!@#&        print(\"\")!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        for i = 1, 12 do rightPrint(string.rep(\" \", 41)) end!@#&        term.setCursorPos(1, 15)!@#&        rightPrint(\"       View the full documentation here: \")!@#&        rightPrint(\"  https://github.com/1lann/Firewolf/wiki \")!@#& !@#&        local opt = prompt({{\"Getting Started\", w - 21, 8}, {\"Making a Theme\", w - 20, 10},!@#&                {\"API Documentation\", w - 23, 12}}, \"vertical\")!@#&        local pages = {}!@#&        if opt == \"Getting Started\" then!@#&                pages[1] = {title = \"Getting Started - Intoduction\", content = {!@#&                        \"Hey there!\",!@#&                        \"\",!@#&                        \"Firewolf is an app that allows you to create\",!@#&                        \"and visit websites! Each site has an address\",!@#&                        \"(the URL) which you can type into the address\",!@#&                        \"bar above, and then visit the site.\",!@#&                        \"\",!@#&                        \"You can open the address bar by clicking on\",!@#&                        \"it, or by pressing control.\"!@#&                }} pages[2] = {title = \"Getting Started - Searching\", content = {!@#&                        \"The address bar can be also be used to\",!@#&                        \"search for sites, by simply typing in the\",!@#&                        \"search term.\",!@#&                        \"\",!@#&                        \"To view all sites, just open it and hit\",!@#&                        \"enter (leave the field blank).\"!@#&                }} pages[3] = {title = \"Getting Started - Built-In Websites\", content = {!@#&                        \"Firewolf has a set of built-in websites\",!@#&                        \"available for use:\",!@#&                        \"\",!@#&                        \"rdnt://firewolf   Normal hompage\",!@#&                        \"rdnt://sites      Built-In Site\",!@#&                        \"rdnt://server     Create websites\",!@#&                        \"rdnt://help       Help and documentation\"!@#&                }} pages[4] = {title = \"Getting Started - Built-In Websites\", content = {!@#&                        \"More built-in websites:\",!@#&                        \"\",!@#&                        \"rdnt://settings   Firewolf settings\",!@#&                        \"rdnt://credits    View the credits\",!@#&                        \"rdnt://exit       Exit the app\"!@#&                }}!@#&        elseif opt == \"Making a Theme\" then!@#&                pages[1] = {title = \"Making a Theme - Introduction\", content = {!@#&                        \"Firewolf themes are files that tell Firewolf\",!@#&                        \"to color which things what.\",!@#&                        \"Several themes can already be downloaded for\",!@#&                        \"Firewolf from rdnt://settings/themes.\",!@#&                        \"\",!@#&                        \"You can also make your own theme, use it in\",!@#&                        \"your copy of Firewolf.Your theme can also be\",!@#&                        \"submitted it to the themes list!\"!@#&                }} pages[2] = {title = \"Making a Theme - Example\", content = {!@#&                        \"A theme file consists of several lines of\",!@#&                        \"text. Here is the default theme file:\",!@#&                        \"address-bar-text=white\",!@#&                        \"address-bar-background=gray\",!@#&                        \"address-bar-base=lightGray\",!@#&                        \"top-box=red\",!@#&                        \"bottom-box=orange\",!@#&                        \"background=gray\",!@#&                        \"text-color=white\"!@#&                }} pages[3] = {title = \"Making a Theme - Explanation\", content = {!@#&                        \"On each line of the example, something is\",!@#&                        \"given a color, like on the last line, the\",!@#&                        \"text of the page is told to be white.\",!@#&                        \"\",!@#&                        \"The color specified after the = is the same\",!@#&                        \"as when you call colors.[color name].\",!@#&                        \"For example, specifying 'red' after the =\",!@#&                        \"colors that object red.\"!@#&                }} pages[4] = {title = \"Making a Theme - Have a Go\", content = {!@#&                        \"Themes can be made at rdnt://settings/themes,\",!@#&                        \"click on 'Change Theme' button, and click on\",!@#&                        \"'New Theme'.\",!@#&                        \"\",!@#&                        \"Enter a theme name, then exit Firewolf and\",!@#&                        \"edit the newly created file\",!@#&                        \"Specify the colors for each of the keys,\",!@#&                        \"and return to the themes section of the\",!@#&                        \"downloads center. Click 'Load Theme'.\"!@#&                }} pages[5] = {title = \"Making a Theme - Submitting\", content = {!@#&                        \"To submit a theme to the theme list,\",!@#&                        \"send GravityScore a message on the CCForums\",!@#&                        \"that contains your theme file and name.\",!@#&                        \"\",!@#&                        \"He will message you back saying whether your\",!@#&                        \"theme has been added, or if anything needs to\",!@#&                        \"be changed before it is added.\"!@#&                }}!@#&        elseif opt == \"API Documentation\" then!@#&                pages[1] = {title = \"API Documentation - 1\", content = {!@#&                        \"The Firewolf API is a bunch of global\",!@#&                        \"functions that aim to simplify your life when\",!@#&                        \"designing and coding websites.\",!@#&                        \"\",!@#&                        \"For a full documentation on these functions,\",!@#&                        \"visit the Firewolf Wiki Page here:\",!@#&                        \"https://github.com/1lann/Firewolf/wiki\"!@#&                }} pages[2] = {title = \"API Documentation - 2\", content = {!@#&                        \"centerPrint(string text)\",!@#&                        \"cPrint(string text)\",!@#&                        \"centerWrite(string text)\",!@#&                        \"cWrite(string text)\",!@#&                        \"\",!@#&                        \"leftPrint(string text)\",!@#&                        \"lPrint(string text)\",!@#&                }} pages[3] = {title = \"API Documentation - 3\", content = {!@#&                        \"leftWrite(string text)\",!@#&                        \"lWrite(string text)\",!@#&                        \"\",!@#&                        \"rightPrint(string text)\",!@#&                        \"rPrint(string text)\",!@#&                        \"rightWrite(string text)\",!@#&                        \"rWrite(string text)\"!@#&                }} pages[4] = {title = \"API Documentation - 4\", content = {!@#&                        \"prompt(table list, string direction)\",!@#&                        \"scrollingPrompt(table list, integer x,\",!@#&                        \"   integer y, integer length[,\",!@#&                        \"   integer width])\",!@#&                        \"\",!@#&                        \"urlDownload(string url)\",!@#&                        \"pastebinDownload(string code)\",!@#&                        \"redirect(string site)\",!@#&                }} pages[5] = {title = \"API Documentation - 5\", content = {!@#&                        \"loadImageFromServer(string imagePath)\",!@#&                        \"ioReadFileFromServer(string filePath)\",!@#&                        \"fileFileFromServer(string filePath)\",!@#&                        \"saveFileToUserComputer(string content)\",!@#&                        \"\",!@#&                        \"writeDataFile(string path, string contents)\",!@#&                        \"readDataFile(string path)\"!@#&                }}!@#&        end!@#& !@#&        local function drawPage(page)!@#&                term.setBackgroundColor(colors[theme[\"background\"]])!@#&                term.clear()!@#&                term.setCursorPos(1, 1)!@#&                term.setTextColor(colors[theme[\"text-color\"]])!@#&                term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                print(\"\")!@#&                leftPrint(string.rep(\" \", page.title:len() + 3))!@#&                leftPrint(\" \" .. page.title .. \"  \")!@#&                leftPrint(string.rep(\" \", page.title:len() + 3))!@#&                print(\"\")!@#& !@#&                term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                for i = 1, 12 do print(string.rep(\" \", w)) end!@#&                for i, v in ipairs(page.content) do!@#&                        term.setCursorPos(4, i + 7)!@#&                        write(v)!@#&                end!@#&        end!@#& !@#&        local curPage = 1!@#&        local a = {{\"Prev\", 26, 17}, {\"Next\", 38, 17}, {\"Back\",  14, 17}}!@#&        drawPage(pages[curPage])!@#& !@#&        while true do!@#&                local b = {a[3]}!@#&                if curPage == 1 then table.insert(b, a[2])!@#&                elseif curPage == #pages then table.insert(b, a[1])!@#&                else table.insert(b, a[1]) table.insert(b, a[2]) end!@#& !@#&                local opt = prompt(b, \"horizontal\")!@#&                if opt == \"Prev\" then!@#&                        curPage = curPage - 1!@#&                elseif opt == \"Next\" then!@#&                        curPage = curPage + 1!@#&                elseif opt == \"Back\" then!@#&                        break!@#&                end!@#& !@#&                drawPage(pages[curPage])!@#&        end!@#& !@#&        redirect(\"help\")!@#&end!@#& !@#& !@#&--  -------- Settings!@#& !@#&pages[\"settings/themes\"] = function(site)!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        print(\"\")!@#&        leftPrint(string.rep(\" \", 17))!@#&        leftPrint(\" Theme Settings  \")!@#&        leftPrint(string.rep(\" \", 17))!@#&        print(\"\")!@#& !@#&        if isAdvanced() then!@#&                term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                for i = 1, 12 do rightPrint(string.rep(\" \", 36)) end!@#& !@#&                local themes = {}!@#&                local themenames = {\"Back\", \"New Theme\", \"Load Theme\"}!@#&                local f = io.open(rootFolder .. \"/temp_file\", \"w\")!@#&                f:write(files.availableThemes)!@#&                f:close()!@#&                local f = io.open(rootFolder .. \"/temp_file\", \"r\")!@#&                local l = f:read(\"*l\")!@#&                while l do!@#&                        l = l:gsub(\"^%s*(.-)%s*$\", \"%1\")!@#&                        local a, b = l:find(\"| |\")!@#&                        table.insert(themenames, l:sub(b + 1, -1))!@#&                        table.insert(themes, {name = l:sub(b + 1, -1), url = l:sub(1, a - 1)})!@#&                        l = f:read(\"*l\")!@#&                end!@#&                f:close()!@#&                fs.delete(rootFolder .. \"/temp_file\")!@#& !@#&                local t = scrollingPrompt(themenames, w - 33, 7, 10, 32)!@#&                if t == \"Back\" then!@#&                        redirect(\"settings\")!@#&                elseif t == \"New Theme\" then!@#&                        term.setCursorPos(w - 33, 17)!@#&                        write(\"Path: /\")!@#&                        local n = modRead({visibleLength = w - 2, textLength = 100})!@#&                        if n ~= \"\" and n ~= nil then!@#&                                n = \"/\" .. n!@#&                                local f = io.open(n, \"w\")!@#&                                f:write(files.newTheme)!@#&                                f:close()!@#& !@#&                                term.setCursorPos(1, 17)!@#&                                rightWrite(string.rep(\" \", 36))!@#&                                term.setCursorPos(1, 17)!@#&                                rightWrite(\"File Created! \")!@#&                                openAddressBar = false!@#&                                sleep(1.1)!@#&                                openAddressBar = true!@#&                        end!@#&                elseif t == \"Load Theme\" then!@#&                        term.setCursorPos(w - 33, 17)!@#&                        write(\"Path: /\")!@#&                        local n = modRead({visibleLength = w - 2, textLength = 100})!@#&                        if n ~= \"\" and n ~= nil then!@#&                                n = \"/\" .. n!@#&                                term.setCursorPos(1, 17)!@#&                                rightWrite(string.rep(\" \", 36))!@#&                               !@#&                                term.setCursorPos(1, 17)!@#&                                if fs.exists(n) and not fs.isDir(n) then!@#&                                        local a = loadTheme(n)!@#&                                        if a ~= nil then!@#&                                                fs.delete(themeLocation)!@#&                                                fs.copy(n, themeLocation)!@#&                                                theme = a!@#&                                                rightWrite(\"Theme File Loaded! :D \")!@#&                                        else!@#&                                                rightWrite(\"Theme File is Corrupt! D: \")!@#&                                        end!@#&                                elseif not fs.exists(n) then!@#&                                        rightWrite(\"File does not exist! \")!@#&                                elseif fs.isDir(n) then!@#&                                        rightWrite(\"File is a directory! \")!@#&                                end!@#& !@#&                                openAddressBar = false!@#&                                sleep(1.1)!@#&                                openAddressBar = true!@#&                        end!@#&                else!@#&                        local url = \"\"!@#&                        for _, v in pairs(themes) do if v.name == t then url = v.url break end end!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        term.setCursorPos(1, 3)!@#&                        leftWrite(string.rep(\" \", 17))!@#&                        leftWrite(\" Downloading...  \")!@#& !@#&                        fs.delete(rootFolder .. \"/temp_file\")!@#&                        download(url, rootFolder .. \"/temp_file\")!@#&                        local th = loadTheme(rootFolder .. \"/temp_file\")!@#&                        if th == nil then!@#&                                term.setCursorPos(1, 3)!@#&                                leftWrite(string.rep(\" \", 17))!@#&                                leftWrite(\" Theme Corrupt!  \")!@#&                                openAddressBar = false!@#&                                sleep(1.3)!@#&                                openAddressBar = true!@#& !@#&                                fs.delete(rootFolder .. \"/temp_file\")!@#&                        else!@#&                                term.setCursorPos(1, 3)!@#&                                leftWrite(string.rep(\" \", 17))!@#&                                leftWrite(\" Theme Loaded!   \")!@#&                                openAddressBar = false!@#&                                sleep(1.3)!@#&                                openAddressBar = true!@#& !@#&                                fs.delete(themeLocation)!@#&                                fs.move(rootFolder .. \"/temp_file\", themeLocation)!@#&                                theme = th!@#&                                redirect(\"home\")!@#&                        end!@#&                end!@#&        else!@#&                print(\"\")!@#&                rightPrint(string.rep(\" \", 30))!@#&                rightPrint(\"  Themes are not available on \")!@#&                rightPrint(\"         normal computers! :( \")!@#&                rightPrint(string.rep(\" \", 30))!@#&        end!@#&end!@#& !@#&pages[\"downloads\"] = function(site) redirect(\"settings/themes\") end!@#& !@#&pages[\"settings\"] = function(site)!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        print(\"\")!@#&        leftPrint(string.rep(\" \", 17 + serverList[serverID]:len()))!@#&        leftPrint(\" Firewolf Settings  \" .. string.rep(\" \", serverList[serverID]:len() - 3))!@#&        leftPrint(\" Designed For: \" .. serverList[serverID] .. \"  \")!@#&        leftPrint(string.rep(\" \", 17 + serverList[serverID]:len()))!@#&        print(\"\\n\")!@#& !@#&        local a = \"Automatic Updating - On\"!@#&        if autoupdate == \"false\" then a = \"Automatic Updating - Off\" end!@#&        local b = \"Home - rdnt://\" .. homepage!@#&        if b:len() >= 28 then b = b:sub(1, 24) .. \"...\" end!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        for i = 1, 9 do rightPrint(string.rep(\" \", 36)) end!@#&        local c = {{a, w - a:len() - 6, 9}, {\"Change Theme\", w - 18, 11}, {b, w - b:len() - 6, 13},!@#&                {\"Reset Firewolf\", w - 20, 15}}!@#&        if not isAdvanced() then!@#&                c = {{a, w - a:len(), 9}, {b, w - b:len(), 11}, {\"Reset Firewolf\", w - 14, 13}}!@#&        end!@#& !@#&        local opt = prompt(c, \"vertical\")!@#&        if opt == a then!@#&                if autoupdate == \"true\" then autoupdate = \"false\"!@#&                elseif autoupdate == \"false\" then autoupdate = \"true\" end!@#&        elseif opt == \"Change Theme\" and isAdvanced() then!@#&                redirect(\"settings/themes\")!@#&        elseif opt == b then!@#&                if isAdvanced() then term.setCursorPos(w - 30, 14)!@#&                else term.setCursorPos(w - 30, 12) end!@#&                write(\"rdnt://\")!@#&                local a = read()!@#&                if a ~= \"\" then homepage = a end!@#&        elseif opt == \"Reset Firewolf\" then!@#&                term.setBackgroundColor(colors[theme[\"background\"]])!@#&                term.clear()!@#&                term.setCursorPos(1, 1)!@#&                term.setTextColor(colors[theme[\"text-color\"]])!@#&                term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                print(\"\")!@#&                leftPrint(string.rep(\" \", 17))!@#&                leftPrint(\" Reset Firewolf  \")!@#&                leftPrint(string.rep(\" \", 17))!@#&                print(\"\\n\")!@#&                term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                for i = 1, 11 do rightPrint(string.rep(\" \", 26)) end!@#&                local opt = prompt({{\"Reset History\", w - 19, 8}, {\"Reset Servers\", w - 19, 9},!@#&                        {\"Reset Theme\", w - 17, 10}, {\"Reset Cache\", w - 17, 11}, {\"Reset Databases\", w - 21, 12},!@#&                        {\"Reset Settings\", w - 20, 13}, {\"Back\", w - 10, 14}, {\"Reset All\", w - 15, 16}},!@#&                        \"vertical\")!@#& !@#&                openAddressBar = false!@#&                if opt == \"Reset All\" then!@#&                        fs.delete(rootFolder)!@#&                elseif opt == \"Reset History\" then!@#&                        fs.delete(historyLocation)!@#&                elseif opt == \"Reset Servers\" then!@#&                        fs.delete(serverFolder)!@#&                        fs.delete(serverLocation)!@#&                elseif opt == \"Reset Cache\" then!@#&                        fs.delete(cacheFolder)!@#&                elseif opt == \"Reset Databases\" then!@#&                        fs.delete(userWhitelist)!@#&                        fs.delete(userBlacklist)!@#&                elseif opt == \"Reset Settings\" then!@#&                        fs.delete(settingsLocation)!@#&                elseif opt == \"Reset Theme\" then!@#&                        fs.delete(themeLocation)!@#&                elseif opt == \"Back\" then!@#&                        openAddressBar = true!@#&                        redirect(\"settings\")!@#&                end!@#& !@#&                term.setBackgroundColor(colors[theme[\"background\"]])!@#&                term.clear()!@#&                term.setCursorPos(1, 1)!@#&                term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                print(\"\\n\\n\")!@#&                leftPrint(string.rep(\" \", 17))!@#&                leftPrint(\" Reset Firewolf  \")!@#&                leftPrint(string.rep(\" \", 17))!@#&                print(\"\")!@#& !@#&                term.setCursorPos(1, 10)!@#&                term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                rightPrint(string.rep(\" \", 27))!@#&                rightPrint(\"  Firewolf has been reset! \")!@#&                rightWrite(string.rep(\" \", 27))!@#&                if isAdvanced() then rightPrint(\"          Click to exit... \")!@#&                else rightPrint(\"  Press any key to exit... \") end!@#&                rightPrint(string.rep(\" \", 27))!@#& !@#&                while true do!@#&                        local e = os.pullEvent()!@#&                        if e == \"mouse_click\" or e == \"key\" then return true end!@#&                end!@#&        end!@#& !@#&        -- Save!@#&        local f = io.open(settingsLocation, \"w\")!@#&        f:write(textutils.serialize({auto = autoupdate, incog = incognito, home = homepage}))!@#&        f:close()!@#& !@#&        redirect(\"settings\")!@#&end!@#& !@#& !@#&--  -------- Credits!@#& !@#&pages[\"credits\"] = function(site)!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        print(\"\\n\")!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        leftPrint(string.rep(\" \", 19))!@#&        leftPrint(\" Firewolf Credits  \")!@#&        leftPrint(string.rep(\" \", 19))!@#&        print(\"\\n\")!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        rightPrint(string.rep(\" \", 38))!@#&        rightPrint(\"  Coded by:              GravityScore \")!@#&        rightPrint(\"                            and 1lann \")!@#&        rightPrint(string.rep(\" \", 38))!@#&        rightPrint(\"  Based off:     RednetExplorer 2.4.1 \")!@#&        rightPrint(\"           Made by ComputerCraftFan11 \")!@#&        rightPrint(string.rep(\" \", 38))!@#&end!@#& !@#& !@#&--  -------- Error Pages!@#& !@#&errorPages[\"overspeed\"] = function(site)!@#&        clearPage(\"overspeed\", colors[theme[\"background\"]])!@#&        print(\"\")!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        leftPrint(string.rep(\" \", 14))!@#&        leftPrint(\" Warning! D:  \")!@#&        leftPrint(string.rep(\" \", 14))!@#&        print(\"\")!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        rightPrint(string.rep(\" \", 40))!@#&        rightPrint(\"  Website browsing sleep limit reached! \")!@#&        rightPrint(string.rep(\" \", 40))!@#&        rightPrint(\"      To prevent Firewolf from spamming \")!@#&        rightPrint(\"   rednet, Firewolf has stopped loading \")!@#&        rightPrint(\"                              the page. \")!@#&        for i = 1, 3 do rightPrint(string.rep(\" \", 40)) end!@#& !@#&        openAddressBar = false!@#&        for i = 1, 5 do!@#&                term.setCursorPos(1, 14)!@#&                rightWrite(string.rep(\" \", 43))!@#&                if 6 - i == 1 then rightWrite(\"                Please wait 1 second... \")!@#&                else rightWrite(\"                Please wait \" .. tostring(6 - i) .. \" seconds... \") end!@#&                sleep(1)!@#&        end!@#&        openAddressBar = true!@#& !@#&        term.setCursorPos(1, 14)!@#&        rightWrite(string.rep(\" \", 43))!@#&        rightWrite(\"            You may now browse normally \")!@#&end!@#& !@#&errorPages[\"crash\"] = function(error)!@#&        clearPage(\"crash\", colors[theme[\"background\"]])!@#&        print(\"\")!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&        leftPrint(string.rep(\" \", 30))!@#&        leftPrint(\" The Website Has Crashed! D:  \")!@#&        leftPrint(string.rep(\" \", 30))!@#&        print(\"\")!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        rightPrint(string.rep(\" \", 31))!@#&        rightPrint(\"      The website has crashed! \")!@#&        rightPrint(\"  Report this to the operator: \")!@#&        rightPrint(string.rep(\" \", 31))!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        print(\"\")!@#&        print(\" \" .. tostring(error))!@#&        print(\"\")!@#& !@#&        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&        rightPrint(string.rep(\" \", 31))!@#&        rightPrint(\"   You may now browse normally \")!@#&        rightPrint(string.rep(\" \", 31))!@#&end!@#& !@#& !@#&--  -------- External Page!@#& !@#&local function external(site)!@#&        -- Clear!@#&        term.setTextColor(colors[theme[\"text-color\"]])!@#&        term.setBackgroundColor(colors[theme[\"background\"]])!@#&        term.clear()!@#&        term.setCursorPos(1, 1)!@#&        print(\"\\n\\n\\n\")!@#&        centerWrite(\"Connecting to Website...\")!@#&        loadingRate = loadingRate + 1!@#& !@#&        -- Modem!@#&        if curProtocol == protocols.rdnt then!@#&                setfenv(checkForModem, override)!@#&                checkForModem(function()!@#&                        term.setBackgroundColor(colors[theme[\"background\"]])!@#&                        term.clear()!@#&                        term.setCursorPos(1, 1)!@#&                        print(\"\\n\")!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        leftPrint(string.rep(\" \", 24))!@#&                        leftPrint(\" No Modem Attached! D:  \")!@#&                        leftPrint(string.rep(\" \", 24))!@#&                        print(\"\\n\")!@#& !@#&                        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                        rightPrint(string.rep(\" \", 40))!@#&                        rightPrint(\"    No wireless modem was found on this \")!@#&                        rightPrint(\"  computer, and Firewolf cannot use the \")!@#&                        rightPrint(\"             RDNT protocol without one! \")!@#&                        rightPrint(string.rep(\" \", 40))!@#&                        rightPrint(\"  Waiting for a modem to be attached... \")!@#&                        rightPrint(string.rep(\" \", 40))!@#&                end)!@#&        end!@#& !@#&        -- Get website!@#&        local webFunc = curProtocol.getWebsite!@#&        setfenv(webFunc, override)!@#&        local id, content, status = nil, nil, nil!@#&        pcall(function() id, content, status = webFunc(site) end)!@#& !@#&        local cacheLoc = cacheFolder .. \"/\" .. site:gsub(\"/\", \"$slazh$\")!@#&        if id and status then!@#&                -- Clear!@#&                term.setBackgroundColor(colors.black)!@#&                term.setTextColor(colors.white)!@#&                term.clear()!@#&                term.setCursorPos(1, 1)!@#& !@#&                -- Save!@#&                local f = io.open(cacheLoc, \"w\")!@#&                f:write(content)!@#&                f:close()!@#& !@#&                local fn, err = loadfile(cacheLoc)!@#&                if not err then!@#&                        setfenv(fn, antivirus)!@#&                        if status == \"whitelist\" then setfenv(fn, override) end!@#&                        _, err = pcall(function() fn() end)!@#&                        setfenv(1, override)!@#&                end!@#& !@#&                if err then!@#&                        local errFunc = errorPages[\"crash\"]!@#&                        setfenv(errFunc, override)!@#&                        pcall(function() errFunc(err) end)!@#&                end!@#&        else!@#&                if fs.exists(cacheLoc) and not fs.isDir(cacheLoc) then!@#&                        term.clearLine()!@#&                        centerPrint(\"Could Not Connect to Website!\")!@#&                        print(\"\")!@#&                        centerPrint(\"A Cached Version was Found.\")!@#&                        local opt = prompt({{\"Load Cache\", -1, 10}, {\"Continue to Search Results\", -1, 12}},!@#&                                \"vertical\")!@#&                        if opt == \"Load Cache\" then!@#&                                -- Clear!@#&                                term.setBackgroundColor(colors.black)!@#&                                term.setTextColor(colors.white)!@#&                                term.clear()!@#&                                term.setCursorPos(1, 1)!@#& !@#&                                -- Run!@#&                                local fn, err = loadfile(cacheLoc)!@#&                                if not err then!@#&                                        setfenv(fn, antivirus)!@#&                                        _, err = pcall(function() fn() end)!@#&                                        setfenv(1, override)!@#&                                end!@#& !@#&                                return!@#&                        end!@#&                end!@#& !@#&                openAddressBar = true!@#&                local res = {}!@#&                if site ~= \"\" then!@#&                        for _, v in pairs(dnsDatabase[1]) do!@#&                                if v:find(site:lower(), 1, true) then!@#&                                        table.insert(res, v)!@#&                                end!@#&                        end!@#&                else!@#&                        for _, v in pairs(dnsDatabase[1]) do!@#&                                table.insert(res, v)!@#&                        end!@#&                end!@#& !@#&                table.sort(res)!@#&                table.sort(res, function(a, b)!@#&                        local _, ac = a:gsub(\"rdnt://\", \"\"):gsub(\"http://\", \"\"):gsub(site:lower(), \"\")!@#&                        local _, bc = b:gsub(\"rdnt://\", \"\"):gsub(\"http://\", \"\"):gsub(site:lower(), \"\")!@#&                        return ac > bc!@#&                end)!@#& !@#&                term.setBackgroundColor(colors[theme[\"background\"]])!@#&                term.clear()!@#&                term.setCursorPos(1, 1)!@#&                if #res > 0 then!@#&                        print(\"\")!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        local t = \"1 Search Result\"!@#&                        if #res > 1 then t = #res .. \" Search Results\" end!@#&                        leftPrint(string.rep(\" \", t:len() + 3))!@#&                        leftPrint(\" \" .. t .. \"  \")!@#&                        leftPrint(string.rep(\" \", t:len() + 3))!@#&                        print(\"\")!@#& !@#&                        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                        for i = 1, 12 do rightPrint(string.rep(\" \", 42)) end!@#&                        local opt = scrollingPrompt(res, w - 39, 7, 10, 38)!@#&                        if opt then redirect(opt:gsub(\"rdnt://\", \"\"):gsub(\"http://\", \"\")) end!@#&                elseif site == \"\" and #res < 1 then!@#&                        print(\"\\n\\n\")!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        centerPrint(string.rep(\" \", 47))!@#&                        centerWrite(string.rep(\" \", 47))!@#&                        centerPrint(\"No Websites are Currently Online! D:\")!@#&                        centerWrite(string.rep(\" \", 47))!@#&                        centerPrint(string.rep(\" \", 47))!@#&                        centerWrite(string.rep(\" \", 47))!@#&                        centerPrint(\"Why not make one yourself?\")!@#&                        centerWrite(string.rep(\" \", 47))!@#&                        centerPrint(\"Visit rdnt://server!\")!@#&                        centerPrint(string.rep(\" \", 47))!@#&                else!@#&                        print(\"\")!@#&                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                        leftPrint(string.rep(\" \", 11))!@#&                        leftPrint(\" Oh Noes!  \")!@#&                        leftPrint(string.rep(\" \", 11))!@#&                        print(\"\\n\")!@#& !@#&                        term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                        rightPrint(string.rep(\" \", 43))!@#&                        rightPrint([[       ______                          __  ]])!@#&                        rightPrint([[      / ____/_____ _____ ____   _____ / /  ]])!@#&                        rightPrint([[     / __/  / ___// ___// __ \\ / ___// /   ]])!@#&                        rightPrint([[    / /___ / /   / /   / /_/ // /   /_/    ]])!@#&                        rightPrint([[   /_____//_/   /_/    \\____//_/   (_)     ]])!@#&                        rightPrint(string.rep(\" \", 43))!@#&                        if verifyBlacklist(id) then!@#&                                rightPrint(\"  Could not connect to the website! It has \")!@#&                                rightPrint(\"  been blocked by a database admin!        \")!@#&                        else!@#&                                rightPrint(\"  Could not connect to the website! It may \")!@#&                                rightPrint(\"  be down, or not exist!                   \")!@#&                        end!@#&                        rightPrint(string.rep(\" \", 43))!@#&                end!@#&        end!@#&end!@#& !@#& !@#&--  -------- Website Coroutine!@#& !@#&local function websitecoroutine()!@#&        local loadingClock = os.clock()!@#&        while true do!@#&                -- Reset and clear!@#&                setfenv(1, backupEnv)!@#&                os.pullEvent = pullevent!@#&                browserAgent = browserAgentTemplate!@#&                w, h = term.getSize()!@#&                curbackground = colors.black!@#&                curtext = colors.white!@#& !@#&                clearPage(website)!@#&                term.setBackgroundColor(colors.black)!@#&                term.setTextColor(colors.white)!@#& !@#&                -- Add to history!@#&                if website ~= \"exit\" and website ~= addressBarHistory[#addressBarHistory] then!@#&                        table.insert(addressBarHistory, website)!@#&                end!@#& !@#&                -- Overspeed!@#&                checkForModem()!@#&                if os.clock() - loadingClock > 5 then!@#&                        -- Reset loading rate!@#&                        loadingRate = 0!@#&                        loadingClock = os.clock()!@#&                end!@#& !@#&                -- Run site!@#&                if loadingRate >= 8 then!@#&                        -- Overspeed error!@#&                        local overspeedFunc = errorPages[\"overspeed\"]!@#&                        setfenv(overspeedFunc, override)!@#&                        overspeedFunc()!@#& !@#&                        loadingRate = 0!@#&                        loadingClock = os.clock()!@#&                elseif type(pages[website]) == \"function\" then!@#&                        -- Run site function!@#&                        local siteFunc = pages[website]!@#&                        setfenv(siteFunc, override)!@#&                        local exit = false!@#&                        local _, err = pcall(function() exit = siteFunc() end)!@#& !@#&                        if err then!@#&                                local errFunc = errorPages[\"crash\"]!@#&                                setfenv(errFunc, override)!@#&                                errFunc(err)!@#&                        end!@#& !@#&                        if exit then!@#&                                os.queueEvent(\"terminate\")!@#&                                return!@#&                        end!@#&                else!@#&                        setfenv(external, override)!@#&                        local _, err = pcall(function() external(website) end)!@#& !@#&                        if err then!@#&                                local errFunc = errorPages[\"crash\"]!@#&                                setfenv(errFunc, override)!@#&                                errFunc(err)!@#&                        end!@#&                end!@#& !@#&                -- Clear data folder!@#&                fs.delete(websiteDataFolder)!@#&                fs.makeDir(websiteDataFolder)!@#& !@#&                -- Wait for load!@#&                oldpullevent(event_loadWebsite)!@#&        end!@#&end!@#& !@#& !@#&--  -------- Address Bar Coroutine!@#& !@#&local function searchresults()!@#&        local mod = true!@#&        if curProtocol == protocols.rdnt then!@#&                mod = false!@#&                for _, v in pairs(rs.getSides()) do if rednet.isOpen(v) then mod = true end end!@#&        end!@#&        if mod then curProtocol.getSearchResults() end!@#& !@#&        local lastCheck = os.clock()!@#&        while true do!@#&                local e = oldpullevent()!@#&                if website ~= \"exit\" and e == event_loadWebsite then!@#&                        mod = true!@#&                        if curProtocol == protocols.rdnt then!@#&                                mod = false!@#&                                for _, v in pairs(rs.getSides()) do if rednet.isOpen(v) then mod = true end end!@#&                        end!@#&                        if mod and os.clock() - lastCheck > 5 then!@#&                                curProtocol.getSearchResults()!@#&                                lastCheck = os.clock()!@#&                        end!@#&                end!@#&        end!@#&end!@#& !@#&local function addressbarread()!@#&        local len = 4!@#&        local list = {}!@#& !@#&        local function draw(l)!@#&                local ox, oy = term.getCursorPos()!@#&                for i = 1, len do!@#&                        term.setTextColor(colors[theme[\"address-bar-text\"]])!@#&                        term.setBackgroundColor(colors[theme[\"address-bar-background\"]])!@#&                        term.setCursorPos(1, i + 1)!@#&                        write(string.rep(\" \", w))!@#&                end!@#&                if theme[\"address-bar-base\"] then term.setBackgroundColor(colors[theme[\"address-bar-base\"]])!@#&                else term.setBackgroundColor(colors[theme[\"bottom-box\"]]) end!@#&                term.setCursorPos(1, len + 2)!@#&                write(string.rep(\" \", w))!@#&                term.setBackgroundColor(colors[theme[\"address-bar-background\"]])!@#& !@#&                for i, v in ipairs(l) do!@#&                        term.setCursorPos(2, i + 1)!@#&                        write(v)!@#&                end!@#&                term.setCursorPos(ox, oy)!@#&        end!@#& !@#&        local function update(line, event, ...)!@#&                local params = {...}!@#&                local y = params[3]!@#&                if event == \"char\" or event == \"history\" or event == \"delete\" then!@#&                        list = {}!@#&                        for _, v in pairs(dnsDatabase[1]) do!@#&                                if #list < len and!@#&                                                v:gsub(\"rdnt://\", \"\"):gsub(\"http://\", \"\"):find(line:lower(), 1, true) then!@#&                                        table.insert(list, v)!@#&                                end!@#&                        end!@#& !@#&                        table.sort(list)!@#&                        table.sort(list, function(a, b)!@#&                                local _, ac = a:gsub(\"rdnt://\", \"\"):gsub(\"http://\", \"\"):gsub(line:lower(), \"\")!@#&                                local _, bc = b:gsub(\"rdnt://\", \"\"):gsub(\"http://\", \"\"):gsub(line:lower(), \"\")!@#&                                return ac > bc!@#&                        end)!@#&                        draw(list)!@#&                        return false!@#&                elseif event == \"mouse_click\" then!@#&                        for i = 1, #list do!@#&                                if y == i + 1 then!@#&                                        return true, list[i]:gsub(\"rdnt://\", \"\"):gsub(\"http://\", \"\")!@#&                                end!@#&                        end!@#&                end!@#&        end!@#& !@#&        local mod = true!@#&        if curProtocol == protocols.rdnt then!@#&                mod = false!@#&                for _, v in pairs(rs.getSides()) do if rednet.isOpen(v) then mod = true end end!@#&        end!@#&        if isAdvanced() and mod then!@#&                return modRead({history = addressBarHistory, visibleLength = w - 2, textLength = 300,!@#&                        liveUpdates = update, exitOnKey = \"control\"})!@#&        else!@#&                return modRead({history = addressBarHistory, visibleLength = w - 2, textLength = 300,!@#&                        exitOnKey = \"control\"})!@#&        end!@#&end!@#& !@#&local function addressbarcoroutine()!@#&        while true do!@#&                local e, but, x, y = oldpullevent()!@#&                if (e == \"key\" and (but == 29 or but == 157)) or!@#&                                (e == \"mouse_click\" and y == 1 and clickableAddressBar) then!@#&                        clickableAddressBar = true!@#&                        if openAddressBar then!@#&                                if e == \"key\" then x = -1 end!@#&                                if x == w then!@#&                                        -- Open menu bar!@#&                                        menuBarOpen = true!@#&                                        term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                                        term.setTextColor(colors[theme[\"text-color\"]])!@#&                                        term.setCursorPos(1, 1)!@#&                                        write(\"> [- Exit Firewolf -]                              \")!@#&                                elseif menuBarOpen and (x == 1 or (but == 29 or but == 157)) then!@#&                                        -- Close menu bar!@#&                                        menuBarOpen = false!@#&                                        clearPage(website, nil, true)!@#&                                elseif x > 2 and x < 22 and menuBarOpen then!@#&                                        -- Exit!@#&                                        menuBarOpen = false!@#&                                        os.queueEvent(event_exitWebsite)!@#&                                        os.queueEvent(\"terminate\")!@#&                                        return!@#&                                elseif not menuBarOpen then!@#&                                        -- Exit website!@#&                                        os.queueEvent(event_exitWebsite)!@#& !@#&                                        -- Clear!@#&                                        term.setBackgroundColor(colors[theme[\"address-bar-background\"]])!@#&                                        term.setTextColor(colors[theme[\"address-bar-text\"]])!@#&                                        term.setCursorPos(2, 1)!@#&                                        term.clearLine()!@#&                                        if curProtocol == protocols.rdnt then write(\"rdnt://\")!@#&                                        elseif curProtocol == protocols.http then write(\"http://\") end!@#& !@#&                                        -- Read!@#&                                        local oldWebsite = website!@#&                                        os.pullEvent = oldpullevent!@#&                                        website = addressbarread()!@#&                                        os.pullEvent = pullevent!@#&                                        if website == nil then!@#&                                                website = oldWebsite!@#&                                        elseif website == \"home\" or website == \"homepage\" then!@#&                                                website = homepage!@#&                                        elseif website == \"exit\" then!@#&                                                os.queueEvent(\"terminate\")!@#&                                                return!@#&                                        end!@#& !@#&                                        -- Load!@#&                                        os.queueEvent(event_loadWebsite)!@#&                                end!@#&                        end!@#&                elseif e == event_redirect then!@#&                        -- Exit website!@#&                        os.queueEvent(event_exitWebsite)!@#& !@#&                        -- Set website!@#&                        local oldWebsite = website!@#&                        website = but!@#&                        if website == nil or website == \"exit\" then!@#&                                website = oldWebsite!@#&                        elseif website == \"home\" or website == \"homepage\" then!@#&                                website = homepage!@#&                        end!@#& !@#&                        -- Load!@#&                        os.queueEvent(event_loadWebsite)!@#&                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\"]])!@#& !@#&        -- Load Settings!@#&        if fs.exists(settingsLocation) and not fs.isDir(settingsLocation) then!@#&                local f = io.open(settingsLocation, \"r\")!@#&                local a = textutils.unserialize(f:read(\"*l\"))!@#&                if type(a) == \"table\" then!@#&                        autoupdate = a.auto!@#&                        incognito = a.incog!@#&                        homepage = a.home!@#&                end!@#&                f:close()!@#&        else!@#&                autoupdate = \"true\"!@#&                incognito = \"false\"!@#&                homepage = \"firewolf\"!@#&        end!@#&        curProtocol = protocols.rdnt!@#& !@#&        -- Update!@#&        rightPrint(string.rep(\" \", 32))!@#&        rightPrint(\"        Checking for Updates... \")!@#&        rightPrint(string.rep(\" \", 32))!@#&        setfenv(updateClient, env)!@#&        if not noInternet then!@#&                if updateClient() then!@#&                        if debugFile then debugFile:close() end!@#& !@#&                        -- Reset Environment!@#&                        setfenv(1, oldEnv)!@#&                        os.pullEvent = oldpullevent!@#&                        shell.run(firewolfLocation)!@#&                        error()!@#&                end!@#&        end!@#& !@#&        -- Download Files!@#&        local x, y = term.getCursorPos()!@#&        term.setCursorPos(1, y - 2)!@#&        rightWrite(string.rep(\" \", 32))!@#&        rightWrite(\"  Downloading Required Files... \")!@#& !@#&        if not noInternet then resetFilesystem() end!@#&        loadDatabases()!@#& !@#&        -- Modem!@#&        checkForModem()!@#&        website = homepage!@#& !@#&        -- Run!@#&        parallel.waitForAll(websitecoroutine, addressbarcoroutine, searchresults)!@#&end!@#& !@#&local function startup()!@#&        -- HTTP!@#&        if not http and not noInternet then!@#&                term.setTextColor(colors[theme[\"text-color\"]])!@#&                term.setBackgroundColor(colors[theme[\"background\"]])!@#&                term.clear()!@#&                term.setCursorPos(1, 2)!@#&                term.setBackgroundColor(colors[theme[\"top-box\"]])!@#&                api.leftPrint(string.rep(\" \", 24))!@#&                api.leftPrint(\" HTTP API Not Enabled!  \")!@#&                api.leftPrint(string.rep(\" \", 24))!@#&                print(\"\")!@#& !@#&                term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                api.rightPrint(string.rep(\" \", 36))!@#&                api.rightPrint(\"  Firewolf is unable to run without \")!@#&                api.rightPrint(\"       the HTTP API Enabled! Please \")!@#&                api.rightPrint(\"    enable it in your ComputerCraft \")!@#&                api.rightPrint(\"                            Config! \")!@#&                api.rightPrint(string.rep(\" \", 36))!@#& !@#&                if isAdvanced() then api.rightPrint(\"                   Click to exit... \")!@#&                else api.rightPrint(\"           Press any key to exit... \") end!@#&                api.rightPrint(string.rep(\" \", 36))!@#& !@#&                while true do!@#&                        local e, but, x, y = oldpullevent()!@#&                        if e == \"mouse_click\" or e == \"key\" then break end!@#&                end!@#& !@#&                return false!@#&        end!@#& !@#&        -- Turtle!@#&        if turtle then!@#&                term.clear()!@#&                term.setCursorPos(1, 2)!@#&                api.centerPrint(\"Advanced computer Required!\")!@#&                print(\"\\n\")!@#&                api.centerPrint(\"  This version of Firewolf requires  \")!@#&                api.centerPrint(\"  an Advanced computer to run!       \")!@#&                print(\"\")!@#&                api.centerPrint(\"  Turtles may not be used to run     \")!@#&                api.centerPrint(\"  Firewolf! :(                       \")!@#&                print(\"\")!@#&                api.centerPrint(\"Press any key to exit...\")!@#& !@#&                oldpullevent(\"key\")!@#&                return false!@#&        end!@#& !@#&        -- Run!@#&        setfenv(main, env)!@#&        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\"]])!@#&                api.leftPrint(string.rep(\" \", 27))!@#&                api.leftPrint(\" Firewolf has Crashed! D:  \")!@#&                api.leftPrint(string.rep(\" \", 27))!@#&                print(\"\")!@#&                term.setBackgroundColor(colors[theme[\"background\"]])!@#&                print(\"\")!@#&                print(\"  \" .. err)!@#&                print(\"\")!@#& !@#&                term.setBackgroundColor(colors[theme[\"bottom-box\"]])!@#&                api.rightPrint(string.rep(\" \", 41))!@#&                if autoupdate == \"true\" then!@#&                        api.rightPrint(\"    Please report this error to 1lann or \")!@#&                        api.rightPrint(\"  GravityScore so we are able to fix it! \")!@#&                        api.rightPrint(\"  If this problem persists, try deleting \")!@#&                        api.rightPrint(\"                         \" .. rootFolder .. \" \")!@#&                else!@#&                        api.rightPrint(\"        Automatic updating is off! A new \")!@#&                        api.rightPrint(\"     version may have have been released \")!@#&                        api.rightPrint(\"                that may fix this error! \")!@#&                        api.rightPrint(\"        If you didn't turn auto updating \")!@#&                        api.rightPrint(\"             off, delete \" .. rootFolder .. \" \")!@#&                end!@#& !@#&                api.rightPrint(string.rep(\" \", 41))!@#&                if isAdvanced() then api.rightPrint(\"                        Click to exit... \")!@#&                else api.rightPrint(\"                Press any key to exit... \") end!@#&                api.rightPrint(string.rep(\" \", 41))!@#& !@#&                while true do!@#&                        local e, but, x, y = oldpullevent()!@#&                        if e == \"mouse_click\" or e == \"key\" then break end!@#&                end!@#& !@#&                return false!@#&        end!@#&end!@#& !@#&-- Check If Read Only!@#&if fs.isReadOnly(firewolfLocation) 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!@#& !@#&-- Debug File!@#&if #tArgs > 0 and tArgs[1] == \"debug\" then!@#&        print(\"Debug Mode Enabled!\")!@#& !@#&        if fs.exists(debugLogLocation) then debugFile = io.open(debugLogLocation, \"a\")!@#&        else debugFile = io.open(debugLogLocation, \"w\") end!@#&        debugFile:write(\"\\n-- [\" .. textutils.formatTime(os.time()) .. \"] New Log --\")!@#&        sleep(1.3)!@#&end!@#& !@#&-- Start!@#&startup()!@#& !@#&-- Exit Message!@#&term.setBackgroundColor(colors.black)!@#&term.setTextColor(colors.white)!@#&term.setCursorBlink(false)!@#&term.clear()!@#&term.setCursorPos(1, 1)!@#&api.centerPrint(\"Thank You for Using Firewolf \" .. version)!@#&api.centerPrint(\"Made by 1lann and GravityScore\")!@#& !@#&-- Close!@#&for _, v in pairs(rs.getSides()) do!@#&        if peripheral.getType(v) == \"modem\" then rednet.close(v) end!@#&end!@#&if debugFile then debugFile:close() end!@#& !@#&-- Reset Environment!@#&setfenv(1, oldEnv)!@#&os.pullEvent = oldpullevent",["lib"]={["im"]="7    7  777   7777  5   5!@#&7       7  7  7  7   5 5 !@#&7    7  7  7  7  7    5  !@#&7    7  7  7  7  7   5 5 !@#&777  7  7  7  7777  5   5",["linox"]="!@#&function getVerNo()!@#& gvn = fs.open(\"/var/linox.ver\", \"r\")!@#&    ver = gvn.readAll()!@#& gvn.close()!@#& return ver!@#&end!@#&!@#&function getLoginVerify(username,password)!@#& glv = fs.open(\"/lib/usr/users\", \"r\")!@#&    users = textutils.unserialize(glv.readLine())!@#&   glv.close()!@#& if users[username] == hash.sha256(password) then!@#&        return true!@#& else!@#&        return false!@#&    end!@#&end!@#&!@#&function getUserFile()!@#&    guf = fs.open(\"/lib/usr/users\", \"r\")!@#&    userf = textutils.unserialize(guf.readLine())!@#&   guf.close()!@#& return userf!@#&end",["load"]="--[[!@#&Author: TheOriginalBIT!@#&Version: 2.0.4!@#&Created: 03 Jan 2013!@#&Last Update: 17 Feb 2013!@#&!@#&License:!@#&!@#&COPYRIGHT NOTICE!@#&Copyright åAF¥BF¥BD82åAF¥BF¥BDA9 2013 Joshua Assberry a.k.a TheOriginaShit [theoriginalbit@gmail.com]!@#&!@#&Permission is hereby granted, free of charge, to any person obtaining a copy of this software and!@#&associated documentation files (the \"Software\"), to deal in the Software without restriction,!@#&including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,!@#&copies of the Software, and to permit persons to whom the Software is furnished to do so,!@#&subject to the following conditions:!@#&!@#&-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.!@#&-Visible credit is given to the original author.!@#&-The software is distributed in a non-profit way.!@#&!@#&THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE!@#&WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR!@#&COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,!@#&ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.!@#&]]--!@#&!@#&--[[ PRIVATE CLASS VARIABLES AND FUNCTIONS ]]--!@#&!@#&local version = 2.0!@#&local apiIdentifier = string.format( \"Loading Bar API v%.2f Object\", version )!@#&local sizeX, sizeY = term.getSize()!@#&local isAdvanced = term.isColor and term.isColor()!@#&local usedIds = {}!@#&!@#&local function generateId()!@#&   if #usedIds > 999 then error( \"Maximum load bars reached, you have used 999, how?! Tell me on the forum post! Better yet, SHOW ME!\" ) end!@#& local objId = #usedIds!@#&  while usedIds[ objId ] do!@#&       objId = objId + 1!@#&       if objId > 999 then!@#&         objId = 1!@#&       end!@#& end!@#& usedIds[ objId ] = true!@#& return objId!@#&end!@#&!@#&local function modeToText( mode )!@#&    if mode == STANDARD then!@#&        return \"STANDARD\"!@#& elseif mode == BAR_ONLY then!@#&        return \"BAR_ONLY\"!@#& elseif mode == ASCII_BAR_ONLY then!@#&      return \"ASCII_BAR_ONLY\"!@#&   elseif mode == LOGO_IS_LOAD then!@#&        return \"LOGO_IS_LOAD\"!@#& elseif mode == LOGO_IS_OVERLAY then!@#&     return \"LOGO_IS_OVERLAY\"!@#&  elseif mode == ASCII then!@#&       return \"ASCII\"!@#&    else!@#&        return \"UNKNOWN\"!@#&  end!@#&end!@#&!@#&local function hexLookup( char )!@#&  local value = tonumber(char, 16)!@#&    return ( value and math.pow(2, value) or false )!@#&end!@#&!@#&local function clearScreen( color )!@#&  term.setCursorPos(1,1)!@#&  if isAdvanced then!@#&      term.setBackgroundColor( color or colors.blue )!@#& end!@#& term.clear()!@#&end!@#&!@#&local function isValidMode( mode )!@#&   return mode ~= nil and ( mode >= STANDARD and mode <= ASCII )!@#&end!@#&!@#&local function isValidParams( mode, tLogo, count, barWidth, y, loadCol, openingMsg, headMsg, footMsg )!@#&  if mode == STANDARD then!@#&        if type( tLogo ) ~= \"table\" then!@#&          return false, \"Logo must be table, got \"..type( tLogo )!@#&       elseif type( count ) ~= \"number\" then!@#&         return false, \"Event count must be a number, got \"..type( count )!@#&     elseif type( barWidth ) ~= \"number\" then!@#&          return false, \"Bar width must be a number, got \"..type( barWidth )!@#&        elseif type( y ) ~= \"number\" then!@#&         return false, \"Y position must be a number, got \"..type( y )!@#&      elseif type( loadCol ) ~= \"number\" then!@#&           return false, \"Load bar color must be a number, got \"..type( loadCol )!@#&        elseif type( loadCol ) == \"number\" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then!@#&         return false, \"Invalid load bar color, must be in range 1-65535, got \"..loadCol!@#&       elseif type( openingMsg ) ~= \"string\" and type( openingMsg ) ~= \"nil\" then!@#&          return false, \"Invalid opening message, expected string or nil, got \"..type( openingMsg )!@#&     elseif type( headMsg ) ~= \"string\" and type( headMsg ) ~= \"nil\" then!@#&            return false, \"Invalid header message, expected string or nil, got \"..type( headMsg )!@#&     elseif type( footMsg ) ~= \"string\" and type( footMsg ) ~= \"nil\" then!@#&            return false, \"Invalid footer message, expected string or nil, got \"..type( footMsg )!@#&     end!@#&     !@#&        return true, nil!@#&    elseif mode == BAR_ONLY then!@#&        if type( tLogo ) ~= \"nil\" then!@#&            return false, \"Logo must be nil, got \"..type( tLogo )!@#&     elseif type( count ) ~= \"number\" then!@#&         return false, \"Event count must be a number, got \"..type( count )!@#&     elseif type( barWidth ) ~= \"number\" then!@#&          return false, \"Bar width must be a number, got \"..type( barWidth )!@#&        elseif type( y ) ~= \"number\" then!@#&         return false, \"Y position must be a number, got \"..type( y )!@#&      elseif type( loadCol ) ~= \"number\" then!@#&           return false, \"Load bar color must be a number, got \"..type( loadCol )!@#&        elseif type( loadCol ) == \"number\" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then!@#&         return false, \"Invalid load bar color, must be in range 1-65535, got \"..loadCol!@#&       elseif type( openingMsg ) ~= \"string\" and type( openingMsg ) ~= \"nil\" then!@#&          return false, \"Invalid opening message, expected string or nil, got \"..type( openingMsg )!@#&     elseif type( headMsg ) ~= \"string\" and type( headMsg ) ~= \"nil\" then!@#&            return false, \"Invalid header message, expected string or nil, got \"..type( headMsg )!@#&     elseif type( footMsg ) ~= \"string\" and type( footMsg ) ~= \"nil\" then!@#&            return false, \"Invalid footer message, expected string or nil, got \"..type( footMsg )!@#&     end!@#&     !@#&        return true, nil!@#&    elseif mode == ASCII_BAR_ONLY then!@#&      if type( tLogo ) ~= \"nil\" then!@#&            return false, \"Logo must be nil, got \"..type( tLogo )!@#&     elseif type( count ) ~= \"number\" then!@#&         return false, \"Event count must be a number, got \"..type( count )!@#&     elseif type( barWidth ) ~= \"number\" then!@#&          return false, \"Bar width must be a number, got \"..type( barWidth )!@#&        elseif type( y ) ~= \"number\" then!@#&         return false, \"Y position must be a number, got \"..type( y )!@#&      elseif type( loadCol ) ~= \"nil\" then!@#&          return false, \"Load bar color must be nil, got \"..type( loadCol )!@#&     elseif type( loadCol ) == \"number\" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then!@#&         return false, \"Invalid load bar color, must be in range 1-65535, got \"..loadCol!@#&       elseif type( openingMsg ) ~= \"string\" and type( openingMsg ) ~= \"nil\" then!@#&          return false, \"Invalid opening message, expected string or nil, got \"..type( openingMsg )!@#&     elseif type( headMsg ) ~= \"string\" and type( headMsg ) ~= \"nil\" then!@#&            return false, \"Invalid header message, expected string or nil, got \"..type( headMsg )!@#&     elseif type( footMsg ) ~= \"string\" and type( footMsg ) ~= \"nil\" then!@#&            return false, \"Invalid footer message, expected string or nil, got \"..type( footMsg )!@#&     end!@#&     !@#&        return true, nil!@#&    elseif mode == LOGO_IS_LOAD or mode == LOGO_IS_OVERLAY then!@#&     if type( tLogo ) ~= \"table\" then!@#&          return false, \"Logo must be table, got \"..type( tLogo )!@#&       elseif type( count ) ~= \"number\" then!@#&         return false, \"Event count must be a number, got \"..type( count )!@#&     elseif type( barWidth ) ~= \"nil\" then!@#&         return false, \"Bar width must be a nil, got \"..type( barWidth )!@#&       elseif type( y ) ~= \"number\" then!@#&         return false, \"Y position must be a number, got \"..type( y )!@#&      elseif mode == LOGO_IS_LOAD and type( loadCol ) ~= \"number\" then!@#&          return false, \"Load bar color must be a number, got \"..type( loadCol )!@#&        elseif mode == LOGO_IS_OVERLAY and type( loadCol ) ~= \"nil\" then!@#&          return false, \"Load bar color must be nil, got \"..type( loadCol )!@#&     elseif type( loadCol ) == \"number\" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then!@#&         return false, \"Invalid load bar color, must be in range 1-65535, got \"..loadCol!@#&       elseif type( openingMsg ) ~= \"string\" and type( openingMsg ) ~= \"nil\" then!@#&          return false, \"Invalid opening message, expected string or nil, got \"..type( openingMsg )!@#&     elseif type( headMsg ) ~= \"string\" and type( headMsg ) ~= \"nil\" then!@#&            return false, \"Invalid header message, expected string or nil, got \"..type( headMsg )!@#&     elseif type( footMsg ) ~= \"string\" and type( footMsg ) ~= \"nil\" then!@#&            return false, \"Invalid footer message, expected string or nil, got \"..type( footMsg )!@#&     end!@#&     !@#&        return true, nil!@#&    elseif mode == ASCII then!@#&       if type( tLogo ) ~= \"table\" then!@#&          return false, \"Logo must be table, got \"..type( tLogo )!@#&       elseif type( count ) ~= \"number\" then!@#&         return false, \"Event count must be a number, got \"..type( count )!@#&     elseif type( barWidth ) ~= \"number\" then!@#&          return false, \"Bar width must be a number, got \"..type( barWidth )!@#&        elseif type( y ) ~= \"number\" then!@#&         return false, \"Y position must be a number, got \"..type( y )!@#&      elseif type( loadCol ) ~= \"nil\" then!@#&          return false, \"Load bar color must be a nil, got \"..type( loadCol )!@#&       elseif type( loadCol ) == \"number\" and ( ( loadCol < 1 ) or ( loadCol > ( 2^16 ) - 1 ) ) then!@#&         return false, \"Invalid load bar color, must be in range 1-65535, got \"..loadCol!@#&       elseif type( openingMsg ) ~= \"string\" and type( openingMsg ) ~= \"nil\" then!@#&          return false, \"Invalid opening message, expected string or nil, got \"..type( openingMsg )!@#&     elseif type( headMsg ) ~= \"string\" and type( headMsg ) ~= \"nil\" then!@#&            return false, \"Invalid header message, expected string or nil, got \"..type( headMsg )!@#&     elseif type( footMsg ) ~= \"string\" and type( footMsg ) ~= \"nil\" then!@#&            return false, \"Invalid footer message, expected string or nil, got \"..type( footMsg )!@#&     end!@#&     !@#&        return true, nil!@#&    end!@#& !@#&    return false, \"Something went seriously wrong, please report this bug with the code 169:\"..tostring( mode )..\" and your call to this api.\"!@#&end!@#&!@#&local function getYFromMode( mode, logo, y )   !@#&    if mode == STANDARD or mode == BAR_ONLY or mode == ASCII_BAR_ONLY or mode == ASCII then!@#&     return ( y + 1 > sizeY and (y - 1) < 1) and sizeY - 4 or y!@#&  elseif mode == LOGO_IS_LOAD or mode == LOGO_IS_OVERLAY then!@#&     return math.ceil( sizeY / 2 - #logo / 2 )!@#&   end!@#&end!@#&!@#&local function getWidthFromMode( mode, logo, width )!@#&  if mode == STANDARD or mode == BAR_ONLY or mode == ASCII_BAR_ONLY or mode == ASCII then!@#&     return width or 20!@#&  elseif mode == LOGO_IS_LOAD or mode == LOGO_IS_OVERLAY then!@#&     return logo[1] ~= nil and #logo[1] or 20!@#&    end!@#&end!@#&!@#&local function draw_header_footer( data )!@#& if isAdvanced then!@#&      term.setBackgroundColor( colors.white )!@#&     term.setTextColor( colors.black )!@#&   end!@#& term.setCursorPos( math.ceil( sizeX / 2 ) - math.ceil( string.len( data.headerMessage ) / 2 ), 1 )!@#&  write( data.headerMessage )!@#& term.setCursorPos( math.ceil( sizeX / 2 ) - math.ceil( string.len( data.footerMessage ) / 2 ), sizeY )!@#&  write( data.footerMessage )!@#&end!@#&!@#&local function draw_box( data )!@#&   for x = 1, data.barWidth + 2 do!@#&     for y = 1, 3 do!@#&         term.setCursorPos( (sizeX - data.barWidth - 1) / 2 + x - 1, data.yPos + y -2 )!@#&          local char = \" \"!@#&          if x == 1 and y == 1 or x == data.barWidth + 2 and y == 1 then!@#&              char = \".\"!@#&            elseif x == 1 and y == 3 or x == data.barWidth + 2 and y == 3 then!@#&              char = \"'\"!@#&            elseif x == 1 or x == data.barWidth + 2 then!@#&                char = \"|\"!@#&            elseif y == 1 then!@#&              char = \"_\"!@#&            elseif y == 3 then!@#&              char = \"-\"!@#&            end!@#&         !@#&            write( char )!@#&       end!@#& end!@#&end!@#&!@#&local function draw_progress_bar( self )!@#&  if self.mode == ASCII_BAR_ONLY or self.mode == ASCII then!@#&       draw_box( self.data )!@#&   end!@#& !@#&    for i = 1, self.data.barWidth do!@#&        term.setCursorPos( (sizeX - self.data.barWidth) / 2 + i, self.data.yPos)!@#&        local char = ' '!@#&        if i < (( self.data.currentEventCount / self.data.totalEventCount ) * self.data.barWidth + 1) then!@#&          if isAdvanced and self.data.barColor then!@#&               term.setBackgroundColor( self.data.barColor )!@#&           else!@#&                char = '|'!@#&          end!@#&     else!@#&            if isAdvanced and self.data.barColor then!@#&               term.setBackgroundColor( colors.gray )!@#&          end!@#&     end!@#&     !@#&        write( char )!@#&   end!@#&end!@#&!@#&local function draw_message( self )!@#&   if self.data.progressMessage then!@#&       term.setCursorPos( sizeX / 2 - self.data.progressMessage:len() / 2, sizeY - 3 )!@#&     if isAdvanced then!@#&          term.setTextColor( colors.black )!@#&           term.setBackgroundColor( colors.white )!@#&     end!@#&     term.clearLine()!@#&        term.write( self.data.progressMessage )!@#& end!@#&end!@#&!@#&local function drawScreen( self )!@#& if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then!@#&        draw_header_footer( self.data )!@#& end!@#& !@#&    for row = 1, #self.data.logo do!@#&     for col = 1, self.data.logo[row]:len() do!@#&           term.setCursorPos( math.ceil( sizeX / 2 - #self.data.logo[1] / 2 ) + col, self.data.isLogoLoad and self.data.yPos + row or (math.ceil( sizeY / 2 - #self.data.logo / 2 ) + row) - 2  )!@#&          local char = self.data.logo[row]:sub( col, col )!@#&            if char ~= \" \" then!@#&               if not self.data.isLogoLoad or col > ( ( self.data.currentEventCount / self.data.totalEventCount ) * self.data.logo[1]:len() + ( self.data.currentEventCount == 0 and self.data.currentEventCount or 1 ) ) then!@#&                 if not ( self.mode == LOGO_IS_OVERLAY ) then!@#&                        term.setBackgroundColor( hexLookup( char ) )!@#&                    else!@#&                        term.setBackgroundColor( colors.lightGray )!@#&                 end!@#&             else!@#&                    if not ( self.mode == LOGO_IS_OVERLAY ) then!@#&                        term.setBackgroundColor( self.data.barColor )!@#&                   else!@#&                        term.setBackgroundColor( hexLookup( char ) )!@#&                    end!@#&             end!@#&             write(\" \")!@#&            end!@#&     end!@#&     print()!@#& end!@#& !@#&    if not self.data.isLogoLoad then!@#&        draw_progress_bar( self )!@#&   end!@#& !@#&    if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then!@#&        draw_message( self )!@#&    end!@#&end!@#&!@#&local function drawScreenASCII( self )!@#&    if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then!@#&        draw_header_footer( self.data )!@#& end!@#& !@#&    for row = 1, #self.data.logo do!@#&     for col = 1, self.data.logo[row]:len() do!@#&           term.setCursorPos( math.ceil( sizeX / 2 - #self.data.logo[1] / 2 ) + col, (math.ceil( sizeY / 2 - #self.data.logo / 2 ) + row) - 2  )!@#&           local char = self.data.logo[row]:sub( col, col )!@#&            if char ~= \" \" then!@#&               if col > ( ( self.data.currentEventCount / self.data.totalEventCount ) * self.data.logo[1]:len() + ( self.data.currentEventCount == 0 and self.data.currentEventCount or 1 ) ) then!@#&                 write( char )!@#&               end!@#&         end!@#&     end!@#&     print()!@#& end!@#& !@#&    draw_progress_bar( self )!@#&   !@#&    if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then!@#&        draw_message( self )!@#&    end!@#&end!@#&!@#&--[[ PUBLIC CLASS VARIABLES AND FUNCTIONS ]]--!@#&!@#&function getVersion() return version end!@#&!@#&function getApiIdentifier() return apiIdentifier end!@#&!@#&--[[ OBJECT ]]--!@#&!@#&load = {}!@#&!@#&load.__index = load!@#&load.__tostring = function( self ) return apiIdentifier end!@#&load.__gc = function( self ) usedIds[ self.id ] = nil self.data.logo = nil self.data = nil self = nil end!@#&!@#&--[[ GETTERS ]]--!@#&!@#&function load.getId( self )!@#&    return self.id!@#&end!@#&!@#&function load.getCurrentProgress( self )!@#&   return self.data.currentEventCount!@#&end!@#&!@#&function load.getFormattedProgress( self )!@#& return self.data.currentEventCount..\"/\"..self.data.totalEventCount!@#&end!@#&!@#&--[[ SETTERS ]]--!@#&!@#&function load.setMessage( self, msg )!@#&   if not self.data then error( \"Object does not exist\", 2 ) end!@#& self.data.progressMessage = msg!@#& os.queueEvent( \"load_update_\"..self.id )!@#&end!@#&!@#&--[[ CONTRUCTORS / DESTRUCTORS ]]--!@#&!@#&function init( lmode, tLogo, count, width, y, loadColor, openingMsg, headMsg, footMsg )!@#& if not isValidMode( lmode ) then error( \"Bad argument: Invalid mode: \"..type( lmode )..\" : \"..tostring( lmode ), 2 ) end!@#&    if not isAdvanced and ( lmode ~= ASCII_BAR_ONLY and lmode ~= ASCII ) then error( \"Invalid mode: Can only run in ASCII mode, attempted \"..modeToText( lmode ), 2 ) end!@#& !@#&    local valid, errorMsg = isValidParams( lmode, tLogo, count, width, y, loadColor, openingMsg, headMsg, footMsg )!@#& if not valid then error( \"Bad argument: Invalid paramters for mode: \"..modeToText( lmode )..\" : \"..errorMsg, 2 ) end!@#&    !@#&    local loadObject = { id = generateId(), data = {!@#&        isLogoLoad = ( lmode == LOGO_IS_LOAD or lmode == LOGO_IS_OVERLAY ),!@#&     isAscii = ( lmode == ASCII_BAR_ONLY or lmode == ASCII ),!@#&        isBarOnly = ( lmode == BAR_ONLY or lmode == ASCII_BAR_ONLY ),!@#&       logo = type( tLogo ) == \"table\" and tLogo or {},!@#&      barWidth  = getWidthFromMode( lmode, tLogo, width ),!@#&        yPos = getYFromMode( lmode, tLogo, y ),!@#&     barColor = loadColor,!@#&       totalEventCount = count,!@#&        currentEventCount = 0,!@#&      progressMessage = openingMsg or \"\",!@#&       headerMessage = headMsg or \"\",!@#&        footerMessage = footMsg or \"\",!@#&    }, mode = lmode }!@#&   !@#&    setmetatable( loadObject, load )!@#&    !@#&    return loadObject!@#&end!@#&!@#&function load.dealloc( self )!@#&   usedIds[ self.id ] = nil!@#&    self.data.logo = nil!@#&    self.data = nil!@#& self = nil!@#&end!@#&!@#&--[[ OBJECT FUNCTIONS ]]--!@#&!@#&function load.reset( self )!@#&  if not self.data then error( \"Object does not exist\", 2 ) end!@#& self.data.currentEventCount = 0!@#&end!@#&!@#&function load.forceStop( self )!@#&   if not self.data then error( \"Object does not exist\", 2 ) end!@#& self.data.currentEventCount = self.data.totalEventCount!@#& os.queueEvent( \"load_update_\"..self.id )!@#&end!@#&!@#&function load.triggerUpdate( self, msg )!@#&   if not self.data then error( \"Object does not exist\", 2 ) end!@#& self.data.currentEventCount = self.data.currentEventCount + 1!@#&   if msg and msg:len() ~= 0 then self.data.progressMessage = msg end!@#&  os.queueEvent( \"load_update_\"..self.id )!@#&end!@#&!@#&function load.removeMessage( self )!@#&    if not self.data then error( \"Object does not exist\", 2 ) end!@#& self.data.progressMessage = \"\"!@#&    os.queueEvent( \"load_update_\"..self.id )!@#&end!@#&!@#&function load.forceDraw( self )!@#&    if not self.data then return end!@#&    if not ( self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY ) then error( \"Object function can only be called in mode: BAR_ONLY and ASCII_BAR_ONLY\", 2 ) end!@#&    draw_progress_bar( self )!@#&end!@#&!@#&function load.run( self, cleanup )!@#&  if not self.data then error( \"Object is not initialized\", 2 ) end!@#& !@#&    if self.mode ~= BAR_ONLY and self.mode ~= ASCII_BAR_ONLY then!@#&       clearScreen( colors.white )!@#& end!@#& !@#&    if self.data.isAscii then!@#&       drawScreenASCII( self )!@#& else!@#&        drawScreen( self )!@#&  end!@#&!@#& while true do!@#&       if self.data.currentEventCount == self.data.totalEventCount then break end!@#&      !@#&        event = { os.pullEventRaw( \"load_update_\"..self.id ) }!@#&        !@#&        if self.mode == BAR_ONLY or self.mode == ASCII_BAR_ONLY then!@#&            draw_progress_bar( self )!@#&       elseif self.mode == ASCII then!@#&          drawScreenASCII( self )!@#&     else!@#&            drawScreen( self )!@#&      end!@#& end!@#& !@#&    if cleanup == true then self:dealloc() end!@#&end!@#&!@#&STANDARD           = 1     -- Load screen with logo, text and bar !@#&BAR_ONLY         = 2     -- Progress bar only!@#&ASCII_BAR_ONLY      = 3     -- Progress bar only - in ascii!@#&LOGO_IS_LOAD     = 4     -- Load screen with logo and text - no bar, logo is progress indicator!@#&LOGO_IS_OVERLAY       = 5     -- Load screen with logo and text - no bar, logo is progress indicator ( initially greyed out )!@#&ASCII                = 6     -- Load screen with logo, text and bar - in ascii",["help"]={},["libapi"]={["terminate"]="_pullevent_ = os.pullEvent!@#&!@#&function disable()!@#&  os.pullEvent = os.pullEventRaw!@#&  return true!@#&end!@#&!@#&function enable()!@#& os.pullEvent = _pullevent_!@#&  return true!@#&end",["pers"]="!@#&-- ================================================!@#&-- Persistent variables!@#&-- ================================================!@#&local function getVariableFilename(tbl,name)  !@#&        assert(name:sub(1,1)~=\"_\",\"Variable names cannot start with _\")!@#&        assert(not name:find(\"[:/*|<>;%s]\"),\"Variable name contains illegal variable, you cannot use ://*|<>;%s\")!@#&        local filePath=rawget(tbl,\"_PVarPath\")!@#&        local fileName = fs.combine(filePath,name..\".var\")!@#&        if not fs.exists(filePath) then!@#&                        fs.makeDir(filePath)!@#&        end!@#&        return fileName!@#&end!@#&function new(tbl,pathName)!@#&        local v={_PVarPath=pathName or \"/vars/\"}  !@#&        setmetatable(v,!@#&        {       __index=function(tbl,name)!@#&                        local vFile=getVariableFilename(tbl,name)!@#&                        local f = io.open(vFile, \"r\")!@#&                        if f then!@#&                                local content = textutils.unserialize(f:read())!@#&                                f:close()!@#&                                return content!@#&                        else!@#&                                return nil!@#&                        end!@#&                end,!@#&                __newindex=function(tbl,name,value)!@#&                        local vFile=getVariableFilename(tbl,name)!@#&                        if value then   !@#&                            local f = io.open(vFile, \"w\")       !@#&                            assert(f,\"FAIL: could not open file\")!@#&                            f:write(textutils.serialize(value))!@#&                            f:close()!@#&                        else!@#&                            fs.delete(vFile)!@#&                        end!@#&                end!@#&        })!@#&        return v!@#&end",["hash"]="!@#&--  !@#&--  Adaptation of the Secure Hashing Algorithm (SHA-244/256)!@#&--  Found Here: http://lua-users.org/wiki/SecureHashAlgorithm!@#&--  !@#&--  Using an adapted version of the bit library!@#&--  Found Here: https://bitbucket.org/Boolsheet/bslf/src/1ee664885805/bit.lua!@#&--  !@#&!@#&local MOD = 2^32!@#&local MODM = MOD-1!@#&!@#&local function memoize(f)!@#&    local mt = {}!@#&   local t = setmetatable({}, mt)!@#&  function mt:__index(k)!@#&      local v = f(k)!@#&      t[k] = v!@#&        return v!@#&    end!@#& return t!@#&end!@#&!@#&local function make_bitop_uncached(t, m)!@#& local function bitop(a, b)!@#&      local res,p = 0,1!@#&       while a ~= 0 and b ~= 0 do!@#&          local am, bm = a % m, b % m!@#&         res = res + t[am][bm] * p!@#&           a = (a - am) / m!@#&            b = (b - bm) / m!@#&            p = p*m!@#&     end!@#&     res = res + (a + b) * p!@#&     return res!@#&  end!@#& return bitop!@#&end!@#&!@#&local function make_bitop(t)!@#& local op1 = make_bitop_uncached(t,2^1)!@#&  local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)!@#&   return make_bitop_uncached(op2, 2 ^ (t.n or 1))!@#&end!@#&!@#&local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})!@#&!@#&local function bxor(a, b, c, ...)!@#& local z = nil!@#&   if b then!@#&       a = a % MOD!@#&     b = b % MOD!@#&     z = bxor1(a, b)!@#&     if c then z = bxor(z, c, ...) end!@#&       return z!@#&    elseif a then return a % MOD!@#&    else return 0 end!@#&end!@#&!@#&local function band(a, b, c, ...)!@#&   local z!@#& if b then!@#&       a = a % MOD!@#&     b = b % MOD!@#&     z = ((a + b) - bxor1(a,b)) / 2!@#&      if c then z = bit32_band(z, c, ...) end!@#&     return z!@#&    elseif a then return a % MOD!@#&    else return MODM end!@#&end!@#&!@#&local function bnot(x) return (-1 - x) % MOD end!@#&!@#&local function rshift1(a, disp)!@#&  if disp < 0 then return lshift(a,-disp) end!@#& return math.floor(a % 2 ^ 32 / 2 ^ disp)!@#&end!@#&!@#&local function rshift(x, disp)!@#&   if disp > 31 or disp < -31 then return 0 end!@#&    return rshift1(x % MOD, disp)!@#&end!@#&!@#&local function lshift(a, disp)!@#&  if disp < 0 then return rshift(a,-disp) end !@#&    return (a * 2 ^ disp) % 2 ^ 32!@#&end!@#&!@#&local function rrotate(x, disp)!@#&    x = x % MOD!@#&    disp = disp % 32!@#&    local low = band(x, 2 ^ disp - 1)!@#&    return rshift(x, disp) + lshift(low, 32 - disp)!@#&end!@#&!@#&local k = {!@#&   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,!@#& 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,!@#& 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,!@#& 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,!@#& 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,!@#& 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,!@#& 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,!@#& 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,!@#& 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,!@#& 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,!@#& 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,!@#& 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,!@#& 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,!@#& 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,!@#& 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,!@#& 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,!@#&}!@#&!@#&local function str2hexa(s)!@#&  return (string.gsub(s, \".\", function(c) return string.format(\"%02x\", string.byte(c)) end))!@#&end!@#&!@#&local function num2s(l, n)!@#& local s = \"\"!@#&  for i = 1, n do!@#&     local rem = l % 256!@#&     s = string.char(rem) .. s!@#&       l = (l - rem) / 256!@#& end!@#& return s!@#&end!@#&!@#&local function s232num(s, i)!@#& local n = 0!@#& for i = i, i + 3 do n = n*256 + string.byte(s, i) end!@#&   return n!@#&end!@#&!@#&local function preproc(msg, len)!@#& local extra = 64 - ((len + 9) % 64)!@#& len = num2s(8 * len, 8)!@#& msg = msg .. \"\\128\" .. string.rep(\"\\0\", extra) .. len!@#& assert(#msg % 64 == 0)!@#&  return msg!@#&end!@#&!@#&local function initH256(H)!@#& H[1] = 0x6a09e667!@#&   H[2] = 0xbb67ae85!@#&   H[3] = 0x3c6ef372!@#&   H[4] = 0xa54ff53a!@#&   H[5] = 0x510e527f!@#&   H[6] = 0x9b05688c!@#&   H[7] = 0x1f83d9ab!@#&   H[8] = 0x5be0cd19!@#&   return H!@#&end!@#&!@#&local function digestblock(msg, i, H)!@#&    local w = {}!@#&    for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end!@#& for j = 17, 64 do!@#&       local v = w[j - 15]!@#&     local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))!@#&        v = w[j - 2]!@#&        w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))!@#&  end!@#&!@#& local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]!@#&   for i = 1, 64 do!@#&        local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))!@#&      local maj = bxor(band(a, b), band(a, c), band(b, c))!@#&        local t2 = s0 + maj!@#&     local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))!@#&      local ch = bxor (band(e, f), band(bnot(e), g))!@#&      local t1 = h + s1 + ch + k[i] + w[i]!@#&        h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2!@#&  end!@#&!@#& H[1] = band(H[1] + a)!@#&   H[2] = band(H[2] + b)!@#&   H[3] = band(H[3] + c)!@#&   H[4] = band(H[4] + d)!@#&   H[5] = band(H[5] + e)!@#&   H[6] = band(H[6] + f)!@#&   H[7] = band(H[7] + g)!@#&   H[8] = band(H[8] + h)!@#&end!@#&function sha256(msg)!@#&    msg = preproc(msg, #msg)!@#&    local H = initH256({})!@#&  for i = 1, #msg, 64 do digestblock(msg, i, H) end!@#&   return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..!@#&     num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))!@#&end",["crypt"]="local function enc(str, key)!@#&   if not key then return false end!@#&    local f = \"\"!@#&  local kb = {}!@#&   for i = 1, #key do!@#&      kb[i] = string.byte(key:sub(i,i)) - 31!@#&  end!@#& local c = 1!@#& for i = 1, #str do!@#&      local t1 = string.byte(str:sub(i,i))!@#&        if t1 == 10 then!@#&            f = f .. string.char(10)!@#&        else!@#&            local t2 = t1 + kb[c]!@#&           if t2 > 126 then!@#&                local t3 = t2 - 126!@#&             t2 = 31 + t3!@#&            end!@#&     f = f .. string.char(t2)!@#&        end!@#&     c = c + 1!@#&       if c > #key then!@#&            c = 1!@#&       end!@#& end!@#& return f!@#&end!@#&!@#&local function dec(str, key)!@#& if not key then return false end!@#&    local f = \"\"!@#&  local kb = {}!@#&   for i = 1, #key do!@#&      kb[i] = string.byte(key:sub(i,i)) - 31!@#&  end!@#& local c = 1!@#& for i = 1, #str do!@#&      local t2 = string.byte(str:sub(i,i)) - 31!@#&       if t2 == -21 then!@#&           f = f .. string.char(10)!@#&        else!@#&            local t3 = t2 - kb[c] + 31!@#&          if t3 < 32 then!@#&             t3 = t3 + 126 - 31!@#&          end!@#&         if t3 < 32 then return false, t3 end!@#&            if t3 > 126 then return false, t3 end!@#&           f = f .. string.char(t3)!@#&        end!@#&     c = c + 1!@#&       if c > #key then!@#&            c = 1!@#&       end!@#& end!@#& return f!@#&end!@#&!@#&function encrypt(str, key)!@#&   if not key then return false end!@#&    if #key < 3 then return false end!@#&   local f = str!@#&   key = key .. key .. \"#me1\"!@#&    for i = 0, #key - 1 do!@#&      f = enc(f, key:sub(i,i + 1))!@#&    end!@#& f = enc(f, key:sub(1,2) .. key:sub(#key - 1, #key) .. enc(key, key .. key))!@#& return f!@#&end!@#&!@#&function decrypt(str, key)!@#&   if not key then return false end!@#&    if #key < 3 then return false end!@#&   local f = str!@#&   key = key .. key .. \"#me1\"!@#&    for i = 0, #key - 1 do!@#&      f = dec(f, key:sub(i,i + 1))!@#&    end!@#& f = dec(f, key:sub(1,2) .. key:sub(#key - 1, #key) .. enc(key, key .. key))!@#& return f!@#&end",["spd"]="local data = {}!@#&!@#&function getData(key)!@#&  return data[key]!@#&end!@#&!@#&function setData(key, value)!@#& data[key] = value!@#&end",["update"]="function getVerNo()!@#&   handle = http.get(\"http://api.linox-cc.comuf.com/getVerNo\")!@#&   return handle.readLine()!@#&end!@#&!@#&function ping()!@#&  http.request(\"http://linox-cc.comuf.com\")!@#& ev = os.pullEvent()!@#& if ev == \"http_success\" then !@#&     return true!@#& elseif ev == \"http_failure\" then !@#&     return false!@#&    end!@#&end",["sudo"]="function setPrivID(id, root)!@#&  if linox.getLoginVerify(spd.getData(\"login\"),root) then!@#&       spd.setData(\"privid\",tostring(id))!@#&        return true!@#& else!@#&        return false!@#&    end!@#&end!@#&!@#&function checkPrivs()!@#& return spd.getData(\"privid\")!@#&end!@#&!@#&function getAdminPrivs(root)!@#&   if linox.getLoginVerify(spd.getData(\"login\"),root) then!@#&       spd.setData(\"privid\",3)!@#&       return true!@#& else!@#&        return false!@#&    end!@#&end!@#&!@#&!@#&function isAdmin()!@#&    if spd.getData(\"privid\") == 3 then!@#&        return true!@#& else!@#&        return false!@#&    end!@#&end",},["p2"]="!@#&local function create( first, ... )!@#&   if first ~= nil then!@#&        return coroutine.create(first), create( ... )!@#&    end!@#&    return nil!@#&end!@#&!@#&local function runUntilLimit( _routines, _limit )!@#&    local count = #_routines!@#&    local living = count!@#&    !@#&    local tFilters = {}!@#&    local eventData = {}!@#&    while true do!@#&      for n=1,count do!@#&            local r = _routines[n]!@#&          if r then!@#&               if tFilters[r] == nil or tFilters[r] == eventData[1] then!@#&                   local ok, param = coroutine.resume( r, unpack(eventData) )!@#&                  if not ok then!@#&                      error( param )!@#&                  else!@#&                        tFilters[r] = param!@#&                 end!@#&                 if coroutine.status( r ) == \"dead\" then!@#&                       _routines[n] = nil!@#&                      living = living - 1!@#&                     if living <= _limit then!@#&                            return n!@#&                        end!@#&                 end!@#&             end!@#&         end!@#&     end!@#&     for n=1,count do!@#&            local r = _routines[n]!@#&          if r and coroutine.status( r ) == \"dead\" then!@#&             _routines[n] = nil!@#&              living = living - 1!@#&             if living <= _limit then!@#&                    return n!@#&                end!@#&         end!@#&     end!@#&     eventData = { os.pullEventRaw() }!@#&    end!@#&end!@#&!@#&function waitForAny( ... )!@#&    local routines = { create( ... ) }!@#&    return runUntilLimit( routines, #routines - 1 )!@#&end!@#&!@#&function waitForAll( ... )!@#&    local routines = { create( ... ) }!@#&   runUntilLimit( routines, 0 )!@#&end",["usr"]={["users"]="{[\"admin\"]=\"d74ff0ee8da3b9806b18c877dbf29bbde50b5bd8e4dad7a3a725000feb82e8f1\",}",},["sysconf"]="-- System Configuration File!@#&-- Begin file!@#&!@#&-- Pre-installed themes!@#&fire = {[\"sel\"] = colors.yellow, [\"desel\"] = colors.orange, [\"background\"] = colors.red}!@#&night = {[\"sel\"] = colors.lightGray, [\"desel\"] = colors.gray, [\"background\"] = colors.black}!@#&!@#&-- Theme setup (sel=color for selected option,desel=color for deselected option,background=obvious)!@#&theme_sel = night[\"sel\"]!@#&theme_desel = night[\"desel\"]!@#&theme_background = night[\"background\"]!@#&-- Themes end!@#&!@#&-- Autostart the Z server?!@#&z_auto = true",},["home"]={},["test"]="",} 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( "root" ) or "/" if sDest == "root" then sDest = "/" end local tPackage = pkg makeFolder(sDest, tPackage) print("Package Extracted to '" .. sDest .. "'!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement