· 8 years ago · Dec 07, 2017, 11:40 PM
1local tmpTbl = {
2 [ "BASE/core/user_login_menu.lua" ] = "--[[\
3\009User Login Menu\
4\009Launched when the operating system starts\
5]]--\
6\
7-- Generates a new salt for a user password\
8local function generateSalt()\
9\009local str = \"\"\
10\009local alph = \"ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuwxyz1234567890\"\
11\009local tbl = base.text.explode(alph)\
12\009local tbl = base.text.shuffleArray(tbl)\
13\009for i = 1, 10 do\
14\009\009str = str .. tbl[math.random(1, 60)]\
15\009end\
16\009\
17\009return str\
18end\
19\
20-- Loads all user profiles stored in the user profile file\
21local function loadUserProfiles()\
22\009local tbl = base.io.loadTable(\"/BASE/system/users\")\
23\009return tbl\
24end\
25\
26-- This takes in a user name, password and existing table of users, hashes the password and adds it to the user profile file\
27local function createNewUser(name, password, users)\
28\009password = password .. generateSalt() -- Add salt to the password\
29\
30\009local newUser = {\
31\009\009name = name,\
32\009\009password = base.sha256.hash(password),\
33\009\009color = colors.blue\
34\009}\
35\009\
36\009table.insert(users, newUser)\
37\009\
38\009base.io.saveTable(users, \"/BASE/system/users\")\
39\009return users\
40end\
41\
42-- Deletes a user account from the user profile file\
43local function deleteUser(id, users)\
44\009if #users >= id then\
45\009\009users[id] = nil\
46\009end\
47\009\
48\009base.io.saveTable(users, \"/BASE/system/users\")\
49\009\
50\009return users\
51end\
52\
53-- Main loop\
54local function main()\
55\009local selectedPos = -1\
56\009local viewPos = 1\
57\009local pass\
58\009local users\
59\009local passWindow = window.create(term.current(), 18, 17, 16, 1)\
60\009passWindow.setVisible(false)\
61\009local orig = term.current()\
62\
63\009-- Draws the main screen\
64\009local function drawMain() -- Draws the main screen\
65\009\009base.gui.flash(colors.lightGray)\
66\009\009term.setTextColor(colors.white)\
67\009\009base.text.ctxt(\"Please select a user account to login with:\", 4)\
68\009\009base.gui.rect(1, 6, 51, 10, colors.white, true)\
69\009\009paintutils.drawLine(1, 1, 51, 1, colors.gray)\
70\009\009term.setTextColor(colors.white)\
71\009\009base.text.ptxt(\"Menu\", 1, 1)\
72\009\009\
73\009\009base.gui.rect(4, 7, 13, 8, colors.gray, true)\
74\009\009base.gui.rect(20, 7, 13, 8, colors.gray, true)\
75\009\009base.gui.rect(36, 7, 13, 8, colors.gray, true)\
76\009\009\
77\009\009if selectedPos ~= -1 then\
78\009\009\009term.setTextColor(colors.black)\
79\009\009\009paintutils.drawLine(18, 17, 33, 17, colors.white)\
80\009\009\009base.text.ctxt(\"Password\", 17)\
81\009\009\009paintutils.drawPixel(34, 17, colors.gray)\
82\009\009\009term.setTextColor(colors.white)\
83\009\009\009base.text.ptxt(\">\", 34, 17)\
84\009\009end\
85\009\009\
86\009\009if selectedPos == 1 then\
87\009\009\009term.setTextColor(colors.black)\
88\009\009\009term.setBackgroundColor(colors.white)\
89\009\009\009base.text.ptxt(\">\", 3, 11)\
90\009\009\009base.text.ptxt(\"<\", 17, 11)\
91\009\009\009\
92\009\009elseif selectedPos == 2 then\
93\009\009\009term.setTextColor(colors.black)\
94\009\009\009term.setBackgroundColor(colors.white)\
95\009\009\009base.text.ptxt(\">\", 19, 11)\
96\009\009\009base.text.ptxt(\"<\", 33, 11)\
97\009\009\009\
98\009\009elseif selectedPos == 3 then\
99\009\009\009term.setTextColor(colors.black)\
100\009\009\009term.setBackgroundColor(colors.white)\
101\009\009\009base.text.ptxt(\">\", 35, 11)\
102\009\009\009base.text.ptxt(\"<\", 49, 11)\
103\009\009end\
104\009end\
105\009\
106\009users = loadUserProfiles()\
107\009\
108\009while true do\
109\009\009drawMain()\
110\009\009\
111\009\009local _, b, x, y = os.pullEvent(\"mouse_click\")\
112\009\009if b == 1 then\
113\009\009\009if x>=1 and x<=4 and y == 1 then\
114\009\009\009\009local options = base.gui.dropdown(1, 2, {\"Shut down\", \"Reboot\", \"Add a new account\"})\
115\009\009\009\009if options == 1 then\
116\009\009\009\009\009os.shutdown()\
117\009\009\009\009elseif options == 2 then\
118\009\009\009\009\009os.reboot()\
119\009\009\009\009end\
120\009\009\009\009\
121\009\009\009elseif x>=4 and x<=16 and y>=7 and y<=14 then\
122\009\009\009\009selectedPos = 1\
123\009\009\009\009\
124\009\009\009elseif x>=20 and x<=32 and y>=7 and y<=14 then\
125\009\009\009\009selectedPos = 2\
126\009\009\009\009\
127\009\009\009elseif x>=36 and x<=48 and y>=7 and y<=14 then\
128\009\009\009\009selectedPos = 3\
129\009\009\009\009\
130\009\009\009elseif x>=18 and x<=33 and y==17 then\
131\009\009\009\009passWindow.setVisible(true)\
132\009\009\009\009term.redirect(passWindow)\
133\009\009\009\009term.setBackgroundColor(colors.white)\
134\009\009\009\009term.setTextColor(colors.black)\
135\009\009\009\009term.clear()\
136\009\009\009\009local pass = read(\"*\")\
137\009\009\009\009term.redirect(orig)\
138\009\009\009\009passWindow.setVisible(false)\
139\009\009\009\009orig.redraw()\
140\009\009\009end\
141\009\009end\
142\009end\
143end\
144\
145\
146\
147main()",
148 [ "BASE/.git/FETCH_HEAD" ] = "",
149 [ "BASE/.git/objects/b5/d43e9093e9d1371bd806ba751298e52e87c517" ] = "x\001}Uao?6\016?W?W\028?\015?\001[Y?\
150\005\022?C?.]? \
151`??`\004\001-?,\"\020i?T???~{?r?:?X\020?????ym??\127??O??j?\019-\030C??^_???y??t?gI\1279S\007?W^?^???@??Lp?me?\026;?uL}?7??n?U\023??<???\007?,?P???|?+M>?=\027???F????E\030\006\004??J?\
152?<?/????V?O??s????q???Q?m\031?W^5?2??Kl\0214??e??ERc????????h?\027\003???M?l\0204?w\029M?????9??T??ZR{N?\028?*b\023*t?Aw:0?H??E??Y?\000?\026\"\
153?>???y?+?\008b???Z??????\019?|??\024W)C?3?5??U??eSZ?-U?;\007?k|<D?(?\030?\019yF\"???m=?8k??\019L??v-C\012\015RI??8???}T\000m\021j?\015:?P>?\014\028?U????\028??i?\029\020q??\027?\031??g\003\009???y)9'\007??\016?\029??#D'3\020????l?\020#^??\005?oH?pa\019?K?\008?\025\025,??\002\011???I?????;!?????Y??\020?&?5??r`\026?!?akt<??|\029\024\031\023S??G??Q??u??u???sga?@?\025??4\003Z?\023ok?~;??%s?)???\030`??#?,\027?!f?/?\"???Ak?LN?\006Z:?rR???U?j?\\\001?dD?=\021?Z?\024m?Y??\005?0\031?kl?D??X?4?p??V?\027#@?\028?b.?t?\020???|6V?|1Y?\\?^?tS?g????f\003??O??\015h?Uv?Z8????\000D\026\004\
154R\008s4??'?\001/\026???Ng?8_?PP<C?\009????1?j?\031\015\"????\015?b?}}\016?ku\020;?\002i?u?\028K8? hmTu?z??2??????7\022??v??\028e @Q~X?.\"???\
155J=\028\015??r|I?p??\012?0?\007???\007?????IR?\020,???=???(vX+\025??b??W?Nh\002",
156 [ "BASE/.git/objects/12/513210bfaef59ba5e8e34960cce7aa217f56b4" ] = "x\001??1\014\002!\016\005PkN?{\027p??M???\007?\004#?J\001k`???\026/`????Z??Q?i\023?|?B?D?\\\020???,?$??3?D\007\014?zÛ>?+W\\???8??????|t\011??Yk?o?/?o?9g?X_?YK{`??JEi(:???)????\000\028L8?",
157 [ "BASE/.git/objects/3f/8c929a09884f0f6789ac4053ce2f049280ee14" ] = "x\001+)JMU02?d040031QH,(??K?M-f(i??[??K????\026Y\004?????\009?()?85-?(??AE,-W?jS??u+??j_G?7?\004U?^???\022?\031???x.X?Mr??9A????\012'\004?\0057\\?K??C???5??Y?P?????\028????{?b??L???m?B??b?P\021??%??\012[??M????\
158?]?B3??\031\021??(I?(a(\016?\009?V?q???\031???u?ON??g??3D??}\127????m??????4Z??.\006\000??q?",
159 [ "BASE/apis/baseforms.lua" ] = "--[[\
160\009BASE Forms API. \
161\009A utility to easily create custom programs that work around the design of BASE 2.\
162\009Documentation coming soon.\
163\009Copyright (C) 2016, Sam Gunner.\
164\009Licensed under Creative Commons BY-NC-SA 4.0\
165\
166\009Currently available types:\
167\009p: Simple text. Like the HTML <p> tag.\
168\009button: A button that the user can press. Includes functions and stuff like that which can be run upon being pressed.\
169]]--\
170\
171-- Launch a baseForms app from a certain path.\
172function launchApp(path)\
173\009local h = fs.open(path, \"r\")\
174\009local data = base.text.unserialise(h.readAll())\
175\009h.close()\
176\009mainLoop(data)\
177end\
178\
179-- Main function for redrawing app contents.\
180local function drawMain(topBar, mainWin, pageDetails, currentScrollPos)\
181\009local beg = term.redirect(topBar)\
182\009if pageDetails.titleBackCol ~= nil then\
183\009\009term.setBackgroundColor(pageDetails.titleBackCol)\
184\009else\
185\009\009term.setBackgroundColor(colors.gray)\
186\009end\
187\009term.clear()\
188\009term.setTextColor(colors.white)\
189\009base.text.ptxt(\"<\", 1, 1)\
190\009base.text.ptxt(\">\", 49, 1)\
191\009term.setTextColor(colors.red)\
192\009base.text.ptxt(\"x\", 51, 1)\
193\
194\009term.redirect(mainWin)\
195\009if pageDetails.backgroundColor ~= nil then\
196\009\009term.setBackgroundColor(pageDetails.backgroundColor)\
197\009else\
198\009\009term.setBackgroundColor(colors.white)\
199\009end\
200\009term.clear()\
201\
202\009local cLine = 1\
203\009for i = currentScrollPos, currentScrollPos + 16 do\
204\009\009if pageDetails[i] ~= nil then\
205\009\009\009local bar = pageDetails[i]\
206\009\009\009if bar.backgroundColor ~= nil then\
207\009\009\009\009term.setBackgroundColor(bar.backgroundColor)\
208\009\009\009else\
209\009\009\009\009term.setBackgroundColor(colors.white)\
210\009\009\009end\
211\009\009\009term.setCursorPos(1, cLine)\
212\009\009\009term.clearLine()\
213\
214\009\009\009-- Begin processing the current bar.\
215\009\009\009if bar.type == \"p\" then\
216\009\009\009\009if bar.textColor ~= nil then\
217\009\009\009\009\009term.setTextColor(bar.textColor)\
218\009\009\009\009else\
219\009\009\009\009\009term.setTextColor(colors.black)\
220\009\009\009\009end\
221\
222\009\009\009\009if bar.textPosition ~= nil then -- Check to see if the text position has been specified.\
223\009\009\009\009\009if bar.textPosition == \"center\" then\
224\009\009\009\009\009\009base.text.ctxt(bar.text, cLine)\
225\009\009\009\009\009else\
226\009\009\009\009\009\009base.text.ptxt(bar.text, 1, cLine)\
227\009\009\009\009\009end\
228\009\009\009\009else\
229\009\009\009\009\009base.text.ptxt(bar.text, 1, cLine)\
230\009\009\009\009end\
231\
232\009\009\009elseif bar.type == \"button\" then\
233\009\009\009\009if bar.buttonColor ~= nil then -- Check to see if a custom button colour has been specified.\
234\009\009\009\009\009paintutils.drawLine(2, cLine, 50, cLine, bar.buttonColor)\
235\009\009\009\009else\
236\009\009\009\009\009paintutils.drawLine(2, cLine, 50, cLine, colors.lightGray)\
237\009\009\009\009end\
238\
239\009\009\009\009if bar.text ~= nil then -- Check to see if there is text specified to go on the button.\
240\009\009\009\009\009base.text.ctxt(bar.text, cLine)\
241\009\009\009\009end\
242\
243\009\009\009elseif bar.type == \"textbox\" then\
244\009\009\009\009if bar.buttonColor ~= nil then\
245\009\009\009\009\009paintutils.drawLine(2, cLine, 50, cLine, bar.buttonColor)\
246\009\009\009\009else\
247\009\009\009\009\009paintutils.drawLine(2, cLine, 50, cLine, colors.lightGray)\
248\009\009\009\009end\
249\
250\009\009\009\009if bar.textColor ~= nil then\
251\009\009\009\009\009term.setTextColor(bar.textColor)\
252\009\009\009\009else\
253\009\009\009\009\009term.setTextColor(colors.gray)\
254\009\009\009\009end\
255\
256\009\009\009\009if bar.placeholder ~= nil then\
257\009\009\009\009\009base.text.ctxt(bar.placeholder, cLine)\
258\009\009\009\009else\
259\009\009\009\009\009base.text.ctxt(\"Enter text here...\", cLine)\
260\009\009\009\009end\
261\009\009\009end\
262\009\009end\
263\
264\009\009cLine = cLine + 1\
265\009end\
266\
267end\
268\
269-- Main loop for the app; handles redrawing and events.\
270function mainLoop(pages)\
271\009local height, width = term.getSize()\
272\009local topBar = window.create(term.current(), 1, 1, 51, 1) -- The title bar for the application.\
273\009local mainWin = window.create(term.current(), 1, 2, 51, height - 2) -- Compensate for the taskbar\
274\009currentPage = 1\
275\009currentScrollPos = 1\
276\009appExit = false\
277\
278\009while not appExit do\
279\009\009if pages[currentPage] ~= nil then\
280\009\009\009local cPage = pages[currentPage]\
281\009\009\009drawMain(topBar, mainWin, pages[currentPage], currentScrollPos)\
282\009\009\009local evt, b, x, y = os.pullEvent()\
283\009\009\009if evt == \"mouse_click\" then\
284\009\009\009\009if b == 1 then\
285\009\009\009\009\009if y == 1 then\
286\009\009\009\009\009\009if x == 1 then\
287\009\009\009\009\009\009\009if currentPage > 1 then -- The user requested the previous page.\
288\009\009\009\009\009\009\009\009currentPage = currentPage - 1\
289\009\009\009\009\009\009\009end\
290\
291\009\009\009\009\009\009elseif x == 49 then -- The user requested the next page.\
292\009\009\009\009\009\009\009local pagesLength = #pages\
293\009\009\009\009\009\009\009if currentPage < pagesLength then\
294\009\009\009\009\009\009\009\009currentPage = currentPage + 1\
295\009\009\009\009\009\009\009end\
296\
297\009\009\009\009\009\009elseif x == 51 then -- The user pressed the exit button.\
298\009\009\009\009\009\009\009appExit = true\
299\009\009\009\009\009\009end\
300\
301\009\009\009\009\009else\
302\009\009\009\009\009\009if cPage[barY].type == \"button\" or cPage[barY].type == \"p\" then\
303\009\009\009\009\009\009\009local barY = y - 1 -- Compensate for the title bar.\
304\009\009\009\009\009\009\009barY = barY + currentScrollPos - 1 -- Compensate for the current view position. (scrolling)\
305\009\009\009\009\009\009\009if cPage[barY] ~= nil then\
306\009\009\009\009\009\009\009\009local bar = cPage[barY]\
307\009\009\009\009\009\009\009\009if bar.onClick ~= nil and type(bar.onClick) == \"function\" then -- Check to see if the program should do anything when the user presses on the button.\
308\009\009\009\009\009\009\009\009\009bar.onClick(x, y)\
309\009\009\009\009\009\009\009\009end\
310\009\009\009\009\009\009\009end\
311\009\009\009\009\009\009elseif cPage[barY].type == \"textbox\" then\
312\009\009\009\009\009\009\009\
313\009\009\009\009\009\009end\
314\009\009\009\009\009end\
315\
316\009\009\009\009elseif b == 2 then\
317\009\009\009\009\009local barY = y - 1\
318\009\009\009\009\009barY = barY + currentScrollPos - 1\
319\009\009\009\009\009if cPage[barY] ~= nil then\
320\009\009\009\009\009\009local bar = cPage[barY]\
321\009\009\009\009\009\009if bar.onRightClick ~= nil and type(bar.onRightClick) == \"function\" then\
322\009\009\009\009\009\009\009bar.onRightClick(x, y)\
323\009\009\009\009\009\009end\
324\009\009\009\009\009end\
325\009\009\009\009end\
326\009\009\009end\
327\009\009end\
328\009end\
329end",
330 [ "BASE/apis/io.lua" ] = "--[[\
331\009BASE io API\
332]]--\
333\
334-- Load a table from a path and return it as a table object\
335function loadTable(path)\
336\009if fs.exists(path) and not fs.isDir(path) then\
337\009\009local h = fs.open(path, \"r\")\
338\009\009local data = h.readAll()\
339\009\009h.close()\
340\009\009return base.text.unserialise(data)\
341\009elseif not fs.exists(path) then\
342\009\009local h = fs.open(path, \"w\")\
343\009\009h.write(\"{}\")\
344\009\009h.close()\
345\009\009return {}\
346\009end\
347end\
348\
349-- Save a table to a certain path: serialises and writes to path specified.\
350function saveTable(tbl, path)\
351\009local h = fs.open(path, \"w\")\
352\009h.write(textutils.serialise(tbl))\
353\009h.close()\
354end\
355\
356-- Check to see if a *file* exists within the file system.\
357function checkFile(path)\
358\009if fs.exists(path) and not fs.isDir(path) then\
359\009\009return true\
360\009else\
361\009\009return false\
362\009end\
363end\
364\
365-- Create a new file containing \"{}\" as a new table.\
366function createTableFile(path)\
367\009local h = fs.open(path, \"w\")\
368\009h.write(\"{}\")\
369\009h.close()\
370end\
371\
372-- Appends text to a file\
373function appendText(path, text)\
374\009local content\
375\
376\009if fs.exists(path) then\
377\009\009local h = fs.open(path, \"r\")\
378\009\009content = h.readAll()\
379\009\009h.close()\
380\009\009content = content .. \"\\n\" .. text\
381\009else\
382\009\009content = text\
383\009end\
384\009h = fs.open(path, \"w\")\
385\009h.write(content)\
386\009h.close()\
387end\
388\
389-- Clears an existing file of its contents\
390function clearFile(path)\
391\009local h = fs.open(path, \"w\")\
392\009h.write(\"\")\
393\009h.close()\
394end",
395 [ "BASE/apis/log.lua" ] = "--[[\
396\009Logging API for BASE 2\
397]]--\
398\
399local obj = {\
400\009path = \"\",\
401\009setPath = function(self, path)\
402\009\009self.path = path\
403\009end,\
404\009log = function(self, text)\
405\009\009base.io.appendText(self.path, tostring(text))\
406\009end,\
407\009clear = function(self)\
408\009\009base.io.clearFile(self.path)\
409\009end\
410}\
411\
412function new(path)\
413\009local tempObj = obj\
414\009tempObj:setPath(path)\
415\009return tempObj\
416end",
417 [ "BASE/core/context_menu" ] = "--[[\
418 Context menu application.\
419 This is used to display context menus when a right click is issued.\
420]]\
421",
422 [ "BASE/files/images/unknown_icon_small" ] = "80888088\
42388080888\
42488808888\
42588080888\
42680888088",
427 [ "BASE/.git/objects/86/312dbd3eda864e2e0b6dc2b50b84c6d60db815" ] = "x\001+)JMU0?d040031Q0dH??b\028????]??\025e|+?o}??\002\000?N\
428?",
429 [ "BASE/.git/objects/74/828a6eaeb3f485efa1b6a53238506fdbbfff02" ] = "x\001u??o?@\012??>???\011??R?t\000??V\009:E\017r8CN?\127?\029???w??a?{???rmC\
430O?/\015EQ?*[-w\027X?\008\030\029?\\e??0??%8\006/h<?4\004\017?a\008'?\024\025??a ?P???Y\
4315?6\028-^H\003????e???]??\022??\000i#?\025Cf?1]\003??B\014??[H?B???B)???W?QY???.b\027?-:^?w???6?R??????i\006d??3?\019@?L\007&\017??<?????K???}_?Ì??1>U?C1?O???\028,\
432?z\020\019[??Q?p$/?H\127\\-X\015?L??\001????",
433 [ "BASE/programs/explorer" ] = "bNo = '0.1.1'\
434\
435-- GUI Based File Explorer, Version 1.0 --\
436-- Copyright (C) 2015, Sam Gunner --\
437-- You may redistribute and modify this, as long--\
438-- as you give credit to the original creator --\
439-- Other than that, enjoy the program! --\
440\
441function diagBox(txt)\
442 for i=8, 12 do\
443 paintutils.drawLine(4, i, 47, i, colors.gray)\
444 end\
445 paintutils.drawLine(5, 9, 46, 9, colors.white)\
446 term.setTextColor(colors.black)\
447 ctxt(txt, 9)\
448 paintutils.drawLine(48, 9, 48, 13, colors.black)\
449 paintutils.drawLine(6, 13, 48, 13, colors.black)\
450 local beg = term.current()\
451 local tmpWin = window.create(term.native(), 5, 11, 42, 1)\
452 term.redirect(tmpWin)\
453 term.setBackgroundColor(colors.white)\
454 term.clear()\
455 term.setCursorPos(1, 1)\
456 term.setTextColor(colors.black)\
457 local tmpVal = read()\
458 term.redirect(beg)\
459 return tmpVal\
460end\
461\
462function drawScroll(things, scrollPos)\
463 --[[\
464 local beg = term.current()\
465 term.redirect(scBar)\
466 local totLen = #things.files + #things.folds\
467 --if \
468 paintutils.drawLine(1, tmpVal, 1, tmpVal, colors.gray)\
469 term.redirect(beg)\
470 --end\
471 ]]--\
472end\
473\
474function drawMain(things, dPos)\
475 if topBar== nil or sideBar == nil or mainSec == nil then\
476 topBar = window.create(term.current(), 1, 1, 51, 1)\
477 sideBar = window.create(term.current(), 31, 2, 21, 18)\
478 mainSec = window.create(term.current(), 1, 2, 29, 19)\
479 scBar = window.create(term.current(), 30, 2, 1, 18)\
480 end\
481 local beg = term.current()\
482 \
483 term.redirect(scBar)\
484 term.setBackgroundColor(colors.white)\
485 term.clear()\
486 local allLen = #things.files+#things.folds\
487 print(allLen)\
488 term.redirect(beg)\
489 \
490 term.redirect(topBar)\
491 term.setBackgroundColor(colors.gray)\
492 term.clear()\
493 term.setTextColor(colors.white)\
494 ctxt('File Explorer - Version '..bNo..' - by Sam Gunner', 1)\
495 term.setTextColor(colors.red)\
496 ptxt('x', 51, 1)\
497 term.setTextColor(colors.black)\
498 term.redirect(beg)\
499 \
500 term.redirect(sideBar)\
501 term.setBackgroundColor(colors.lightGray)\
502 term.clear()\
503 term.setTextColor(colors.black)\
504 if things.sel == '' then\
505 ctxt('File Explorer', 1)\
506 ctxt('Version '..bNo, 2)\
507 ctxt('Click on a file', 8)\
508 ctxt('to get started!', 9)\
509 elseif fs.isDir(fs.combine(dir, things.sel)) then\
510 ctxt('Options - Folder', 1)\
511 ctxt(string.sub(things.sel, 1, 21), 2)\
512 ctxt('------', 4)\
513 ctxt('Open Folder', 6)\
514 ctxt('Rename', 7)\
515 ctxt('Delete', 8)\
516 elseif not fs.isDir(fs.combine(dir, things.sel)) then\
517 ctxt('Options - File', 1)\
518 ctxt(string.sub(things.sel, 1, 21), 2)\
519 ctxt('------', 4)\
520 ctxt('Run as program', 6)\
521 ctxt('Edit as text file', 7)\
522 ctxt('Rename', 8)\
523 ctxt('Delete', 9)\
524 local size = fs.getSize(fs.combine(dir, things.sel))\
525 local sSize = math.ceil(size/1000, 1)\
526 ctxt('Size: ' .. sSize .. ' KB', 12)\
527 end\
528 term.redirect(beg)\
529 \
530 term.redirect(mainSec)\
531 term.setBackgroundColor(colors.white)\
532 term.clear()\
533 term.redirect(beg)\
534 \
535 local files = things.files\
536 local folds = things.folds\
537 local fSel = things.sel\
538 \
539 table.sort(files)\
540 table.sort(folds)\
541 \
542 local tmpTbl = {}\
543 for i=1, #folds do\
544 table.insert(tmpTbl, folds[i])\
545 end\
546 \
547 for i=1, #files do\
548 table.insert(tmpTbl, files[i])\
549 end\
550 \
551 term.redirect(mainSec)\
552 term.setTextColor(colors.black)\
553 \
554 for i=dPos, dPos+17 do\
555 if tmpTbl[i] ~= nil then\
556\009 if fs.isDir(fs.combine(dir, tmpTbl[i])) then\
557\009 if fs.combine(dir, fSel) == fs.combine(dir, tmpTbl[i]) then\
558\009\009 term.setTextColor(colors.lightGray)\
559\009\009 write('[] ' .. string.sub(tmpTbl[i], 1, 26) .. '\\n')\
560\009\009else\
561\009\009 term.setTextColor(colors.black)\
562\009 write('[] ' .. string.sub(tmpTbl[i], 1, 26) .. '\\n')\
563\009\009end\
564\009 else\
565\009 if fs.combine(dir, fSel) == fs.combine(dir, tmpTbl[i]) then\
566\009\009 term.setTextColor(colors.lightGray)\
567\009 write('() ' .. string.sub(tmpTbl[i], 1, 26) .. '\\n')\
568\009\009else\
569\009\009 term.setTextColor(colors.black)\
570\009\009 write('() ' .. string.sub(tmpTbl[i], 1, 26) .. '\\n')\
571\009\009end\
572\009 end\
573\009end\
574 end\
575 \
576 term.redirect(beg)\
577 \
578end\
579\
580function nread()\
581 tmpVal = read()\
582end\
583\
584function handClick(b, x, y, stuff)\
585 if b == 1 then\
586 \
587 if x>=1 and x<=51 and y==1 then\
588 if x == 51 then\
589 terminate = true\
590 end\
591 elseif x>=1 and x<=29 and y>=2 and y<=19 then\
592 local fileSel = ((y-1)+drawPos)-1\
593 local totLen = #stuff.files + #stuff.folds\
594 if fileSel > #stuff.folds then\
595 local fileSel = fileSel - #stuff.folds\
596 selVal = stuff.files[fileSel]\
597 else\
598 selVal = stuff.folds[fileSel]\
599 end\
600 elseif x>=31 and x<=51 and y>=2 and y<=19 then\
601 local xP = x-30\
602 local yP = y-1\
603 local beg = term.current()\
604 if selVal ~= nil then\
605 if fs.isDir(fs.combine(dir, selVal)) then -- Assume folder mode\
606 if yP==6 then\
607 dir = fs.combine(dir, selVal)\
608 selVal = ('')\
609 elseif yP==7 then\
610 term.redirect(sideBar)\
611 ctxt('Enter a new name', 15)\
612 paintutils.drawLine(1, 16, 21, 16, colors.white)\
613 term.setTextColor(colors.black)\
614 term.setCursorPos(1, 16)\
615 local pid = parallel.waitForAny(click, nread)\
616 if pid == 2 then\
617 if #tmpVal>0 then\
618 fs.move(fs.combine(dir, selVal),fs.combine(dir, tmpVal))\
619 selVal = ''\
620 end\
621 end\
622 term.redirect(beg)\
623 elseif yP == 8 then\
624 term.redirect(sideBar)\
625 ctxt('Are you sure you want', 14)\
626 ctxt('to delete this?', 15)\
627 paintutils.drawLine(1, 16, 10, 16, colors.green)\
628 ptxt('Yes', 4, 16)\
629 paintutils.drawLine(11, 16, 21, 16, colors.red)\
630 ptxt('No', 15, 16)\
631 local _, button, x, y = os.pullEvent('mouse_click')\
632 local x, y = x-30, y-1\
633 if button == 1 and x>=1 and x<=10 and y==16 then\
634 fs.delete(fs.combine(dir, selVal))\
635 end\
636 selVal = ''\
637 term.redirect(beg)\
638 end\
639 elseif not fs.isDir(fs.combine(dir, selVal)) then -- Assume file mode\
640 if yP == 6 then\
641 term.setBackgroundColor(colors.black)\
642 term.setTextColor(colors.white)\
643 term.clear()\
644 term.setCursorPos(1, 1)\
645 shell.run(fs.combine(dir, selVal))\
646 elseif yP == 7 then\
647 shell.run('edit ' .. fs.combine(dir, selVal))\
648 elseif yP == 8 then\
649 term.redirect(sideBar)\
650 ctxt('Enter a new name', 15)\
651 paintutils.drawLine(1, 16, 31, 16, colors.white)\
652 term.setCursorPos(1, 16)\
653 local pid = parallel.waitForAny(click, nread)\
654 if pid == 2 then\
655 if #tmpVal > 0 then\
656 fs.move(fs.combine(dir, selVal), fs.combine(dir, tmpVal))\
657 selVal = ''\
658 end\
659 end\
660 term.redirect(beg)\
661 elseif yP == 9 then\
662 term.redirect(sideBar)\
663 ctxt('Are you sure you want', 14)\
664 ctxt('to delete this?', 15)\
665 paintutils.drawLine(1, 16, 11, 16, colors.green)\
666 ptxt('Yes', 5, 16)\
667 paintutils.drawLine(12, 16, 21, 16, colors.red)\
668 ptxt('No', 16, 16)\
669 local _, button, x, y = os.pullEvent('mouse_click')\
670 local x, y = x-30, y-1\
671 if button == 1 and x>=1 and x<=11 and y==16 then\
672 fs.delete(fs.combine(dir, selVal))\
673 selVal = ''\
674 end\
675 term.redirect(beg)\
676 end\
677 end\
678 end\
679 end\
680 elseif b == 2 then\
681 if x>=1 and x<=30 and y>1 then\
682 local ans = dropMenu(x, y)\
683 if ans == 1 then\
684 if dir ~= '/' and dir ~= '' then\
685 dir = fs.getDir(dir)\
686 selVal = nil\
687 end\
688 elseif ans == 2 then\
689 local tmp = diagBox('Enter the name of the new file')\
690 local tmpFile = fs.combine(dir, tmp)\
691 if not fs.exists(tmpFile) then\
692 local h = fs.open(fs.combine(dir, tmp), 'w')\
693 h.close()\
694 end\
695 elseif ans == 3 then\
696 local tmp = diagBox('Enter the name of the new folder')\
697 if not fs.exists(fs.combine(dir, tmp)) then\
698 fs.makeDir(fs.combine(dir, tmp))\
699 end\
700 end\
701 end\
702 end\
703end\
704\
705function dropMenu(x, y)\
706 for i=1, 3 do\
707 paintutils.drawLine(x, (y+i)-1, x+10, (y+i)-1, colors.gray)\
708 end\
709 term.setTextColor(colors.white)\
710 ptxt('Back up', x+2, y)\
711 ptxt('New file', x+2, y+1)\
712 ptxt('New folder', x+1, y+2)\
713 paintutils.drawLine(x+11, y+1, x+11, y+3, colors.black)\
714 paintutils.drawLine(x+1, y+3, x+11, y+3, colors.black)\
715 local event, button, xP, yP = os.pullEvent('mouse_click')\
716 if xP>=x and xP<=x+10 and yP>=y and yP<=y+2 then\
717 return (yP-y)+1\
718 end\
719end\
720\
721function getStuff(dir)\
722 if fs.isDir(dir) then\
723 local tmpVal = fs.list(dir)\
724 local files = {}\
725 local folds = {}\
726 for k, v in ipairs(tmpVal) do\
727 if not fs.isDir(fs.combine(dir, v)) then\
728 table.insert(files, v)\
729 else\
730 table.insert(folds, v)\
731 end\
732 end\
733 \
734 local tmpTbl = {}\
735 tmpTbl.files, tmpTbl.folds = files, folds\
736 return tmpTbl\
737 \
738 end\
739end\
740\
741function handScroll(dir, x, y)\
742 if dir == 1 then\
743 if drawPos+17 < (#stuff.files+#stuff.folds) then\
744 drawPos = drawPos+1\
745\009end\
746 elseif dir == -1 then\
747 if drawPos >1 then\
748 drawPos = drawPos-1\
749 \009 end\
750 end\
751end\
752\
753function ctxt(txt, y)\
754 local w, h = term.getSize()\
755 local x = ((w/2)-(#txt/2))+1\
756 term.setCursorPos(x, y)\
757 write(txt)\
758end\
759\
760function ptxt(txt, x, y)\
761 term.setCursorPos(x, y)\
762 write(txt)\
763end\
764\
765function mScroll()\
766 _, sDir, x, y = os.pullEvent('mouse_scroll')\
767end\
768\
769\
770\
771function click()\
772 _, button, x, y = os.pullEvent('mouse_click')\
773end\
774\
775\
776dir = '/'\
777\
778selVal = nil\
779terminate = nil\
780drawPos = 1\
781\
782term.setBackgroundColor(colors.white)\
783term.clear()\
784term.setTextColor(colors.black)\
785ctxt('File Browser - Version '..bNo, 9)\
786sleep(2)\
787\
788repeat\
789 mainSec, sideBar, topBar = nil\
790 stuff = getStuff(dir)\
791 if selVal == nil then\
792 stuff.sel = ''\
793 else\
794 stuff.sel = selVal\
795 end\
796 drawMain(stuff, drawPos)\
797 --drawScroll(stuff)\
798 --[[\
799 local h = fs.open('tmp', 'w')\
800 h.write(textutils.serialize(stuff))\
801 h.close()\
802 ]]--\
803 local pid = parallel.waitForAny(click, mScroll)\
804 if pid == 1 then\
805 local tB = button\
806\009local tX = x\
807\009local tY = y\
808\009handClick(tB, tX, tY, stuff)\
809 elseif pid == 2 then\
810 handScroll(sDir, x, y)\
811 end\
812until terminate == true\
813\
814term.setBackgroundColor(colors.black)\
815term.clear()\
816term.setCursorPos(1, 1)",
817 [ "BASE/files/images/settings_icon_small" ] = "33333333\
8183d3ffff3\
81933333333\
8203e3ffff3\
82133333333",
822 [ "BASE/.git/objects/c9/59db8d265cfd84958fc56b32a828d9e6d9163f" ] = "x\001?Z[s??\021?+?+6??\025??\028;M??,?\026?v$%i??x@b)\"\002?\012.??????}??\002?M?L\031?\025??b/????b???9:z???_\014\015?????'????6?l:4??H\\f?FOGG/???YR?eT??\022?mfcS,?$?&?(MWf?r#?\
823M??3?f\018e?+?m\021?QVZk?YT??4?$M???w?V?`e\\9??y\1279?vN?b?'????O\007??????2??7U???9?\030?I???\
824?Qe1V??6*?{kN?|?¼??????\019?\028\028x?g -?\005??`^?eRF?]??\030????M?\
8250\001n-??gn?<Zb??+&?????|HmTX\003\022=gd??\008????B*?3c\012??]?qu?-?Y??6w^?\020?I \030|??ETNf???qv?\003|?0y??!J!?i?MJ????(3'\031?k?C?\016QQ:???D<7q??K?? \017O??F9??\019\018 \
826?????d?\028?\000M6?~%\
827`??vH\
828N\\??f\022A???\019W\021\024?:~?l6?\005)UK26?a\027\019\007????92??\
8292W??Qz0\030?\016\020=??K\017o3??|???8?5VoN??r????hU?P??,y4??\\??_iR?b????n\004?%%?-?(/?2?2?$?L\022P9qR,?hE??\
830ZN??????n??L?r643+&{l????????0?????\016#??f\019?W;P??(n?\0252?\024H_\006???A?4\021????^a?Ki??>??l??D???I??6+a?cK\019?\015vR?\022?.?\005g\019{Uo?`Q?2?czP?]?\022?p??DM\004?????e?)\"?Ce??\000??]?f8?N??%?-?K;3^63?7?P)??'x???H??{?[c?K?\019(????^\000D(?c3?\023???t?2\018????p\008\008???C???%??I?u\\??.)???:\000!<.*UC?.X??e???\000?b?4n?+a&*\
8317I??X\029?\022Q??9%??????NbT?X\"\028????\031t;???J?n??f?Gv\001,??W??\002?S\023???~???\004????x\"?\030?O?\006\008??\022?o??ò??]U&?\029?q???@\024}c??`\007@$&??)?\003????R\007N?2'C?#???\005?N?|???\000\002\009?]?\012?\0258?;?<??\023u\
832?Q\009S!?^=\016??\025GN^???z???\127|???w???xqy??/?????$???Y??]:???(??????g_>\127?????i?[9N??\024?>*?C9?\015?\020???)????Y??NS{??????I?L????@\026??\016?????hd0?z\030??\017?c??}L????\006?1\003\028\019??lU??\019???\019W?F????\0092\019V\017z ??@i\005?\028???<?\0009\"?$?N\002?Æ?@?\018?W\020\021?|C-\012Vy\022??\003o?$??R?9&????(??\127??NY?????zs?\
833\004\0037??`?y?P?9????z?8??\028a\028B\019S\0239\009??BhB|e?l\003?N???Da??Q?\002{\003c~??\022?\004?\012O?\020V???0+????u>~$|???AjY?I~?=\004v?@?w{Q?I\028?D?Z?\001\019_{~Uo?1???]9P??[????n?S\023?\028?v? ??e???Ak8pP??5bp???HrP?Lm?d2Z2?\028??ma\023?\014D?\000\127??]&qL??\\K??\012U??\021??\019\023?\"?C$-?\004??\001?\025?5?\004x\001\\dO?0?Lw?+?/X???\012?q?#?;n?????\014?V!4k$-?\
834??\014J?)?[?\018?\"?<?o?9,\0232?\002z3?'\014???f?\028??$?\016??8d?F\028n#xn\011l????\027\002?\023??n??p?@\018\027?E(??\003?b+\020?\020?s??S?`]\003?\
835???\
836-\009?f?A\003?\024??,H?d}:\031?\024ms???ml??ld~\"T\"<-l\014????Q0??\011X??Zc????G?Q\029\017???G?\008???+?o\011c?}???\026????]\002.l\018t???F??6??J?J??\025E?\0276D\001?t?vD'?Z3D???L?\027?m?%??U?LçSTW????\
837}z8qs??*O?Hn?\029?4i?d?\026?W??G???=??f?\
838???&??Vl?\023)??\003?S??@<?\"\015bR+#X??\008?^?-?(?\022?\011D????[?l???\018A??|?\023?F\015a???j???+\004?\029;?Z??????\015\028?<\005[?C71/8\"????\030T|@a?5-Fna3/?\030?E?4?l\026????\019?\008x2\027MRT???\009?\026??03%?\020???\030V????'[?x:???B\000??\001??i\000?????G\029?q<????H\005?`?\\)??g?>\011?_\000?e?HlD\001563??\006?qw??L;p*?hv?N?\015?jl?*????wH\019??R?\023?|?_K??&???\023?d52C\0315?#??d?\029\019E?\014??\017??U?\001???B\029????.????$8???\027?V\020&UR????9)\011?NM?=?=\000\025@?81?_\0126!w\030%?[?\022?.DX???b?@*?(?E\006?);\022?\014?zn?0l??`??H?\012'?\003??\003??nM??f6?\0159-u???\022?E\015A??r???>?F???U?_?q???7l???g?'\022??r?Q?\030«\027?$W?kT6i(qr<?;?!?\005?cl??H\019?\021X??[\020`X?<\016\004??\025??r?sxx??#\008?^J??G??l?_OR\019\018?AZ???)Q\008?~??\024H???`??.??%e??\004\023?:?'\127?\004??C?\
839?DpA/\005q\004\014?.Y?\145?\030?\012?tf'?:A&hi2\022?\023?6S?\001??i??($??l??+\127?????:\016?@c???{?A?ix??\020?F??S??AT?V???V.???#?W?|k?ur??????\008?a??????p??¦?\017\021??S\\1Z@\006??b?\015>?L??[\014?\029?\012??d\017?\006?=\028qx\018?\017=\008\023\"?r,???3??PC\001??h??\019t??z\006\030?g\002?h?i??\0250???W??@l?9?p???J? ?h??(\022?|^?HK?t?!??l?\017i?62\139r '?\"a&-X54?\007U???\009>??????\001??mojx^YW?mY\000?%XPM?i??????^?\029?h??i7R?'??~M??C?;-\0075?n????0????\028??\004?(m??\011??a?*?+??M?\
840?Z2F?\009?LY\019\025????fw}?x??~??N??Z0K7\026??\002?\015(>???Y??A\0267k????\031??a?????V?d\025??Nu8?_p?j??b\
841dZ??\008-??+?m?*r9??+??T?%\029??oD\027\030??(?cI\027?m\004??\
842_?7[?0?\019\016??l???\127#??k?}Y\"?????h\017%?'f?C??{?m??=??\017??T\016\030?v???!?%?^?&?????\000??#?\009??3?N??\001u<O??\022øG??????l?G??ya\011?a_??\031{u?z????\005?r\
843?3)?$\007T?^3/a?SW'9+????WOG:/>??`??/??hR??[Y\005?\016??X\024J?v?\007L\008\003?]??\004KB??p?5\016j\009??u???>??7?`?S????C?v?7@\003??S???U??\028B?\025YL???hU??4???tVq??<?%K?D\003A?<??Z??\031??(?y?Y\004a?!*a???f????$???()??\015{?W\\?W?{??U??*x?B??hfHZ????\014j?PC)??P\
844#?????tH!\020\127??*\018?X\016??\027/?@\011d?\011o???????Cs$?J{T?n???@ih;?7!a??@?G6\017?\017??k\022?7\027M?N?\019?\008??kh?ZO??o?3??kI??wS<4\
845\004|v?\016Z???\015?Y<)????a\008M?@\015{\021??\015\\?Ex!B: \029/\015?\023*UY??\
846mqi?e??Q_=?\020=????M?$t;?z\008d?\023\024?\008?g\021?].\"??????z?\008???!\027?\021?>h?.????u?5\018?Gk?{\019i?\009?J??k\016?#$l??i???W?\030?\022F??P???\018}A???lX?=?6\018\014??\016?C????%?p???\008H.??\000Q9???I??i?sk?$m?g?0?\
847\
848H??!OA'.???M\1279?????U?\028???9)\018\008??\009H?-BI\009w?[?h&??[?o\008???A??6\000???V?7=\
849?{?B??w?\
850?\007?X?5?Q??\0032?z?|p??u\019\008?y(???#?`9;\004?\031y\127??@x?+??w?K2?\030kXU\001???;3-???Z?@lBN??8??\025Nj?HU0?BB?q?+??%?:\015???l ??\003???W?zWB?_\031$?\012)-:D>d?\021??\004????\003\029\016?Z??9??Bo?#??\023?\000\030M?P?t?ND?\018??a?\011kp6&?????\026\
851?!?>?\024\004????\001?y-?#!y?f??bQ?J?9z???dk\127~\014K?\031??D??:???!?\008?6_???\024K\0086: ?t\025?7\025m?._'b&?\030)?\
852???\025?yB\030??4?N\021\020\028}?6?&i????J????J??=??]?|?????8?o?0??=???\015?.m??)_?@\031??a\000?|C\008|pN\030??`???-?|??5\024???w\029???\0118?b4??=6??f???l0??G\007?U?'?\025\007??T?~??-?d??n\
853?\003??J????\"\018??\
854?l\014l???8z0??x?\017\\?f??\\?F?\003!\\.%??'?50k\\???,)f\024?]?=\015?^\019N??3?HJ\003\004???\014???`}O%?\030*U?J#,\000P?W??4????R?l\006W\006?uX}+??U?\025?`e????\009?\016?P?\002\004D?\001aX? ?,pi\016R\017z\127#?]?\005Y\006??+\008?u?\011??$????\000?%?\005\\#??'y'???h",
855 [ "BASE/system/program_files/base_tour/1" ] = "ddd7777888888888888777788888888888877777777777777",
856 [ "BASE/core/boot/load_api.lua" ] = "--[[\
857\009API Loader for BASE\
858\009Built as part of the bootloader\
859]]--\
860\
861local failedAPIs = {}\
862\
863if base ~= nil then\
864\009error(\"You do not have the required permissions to do this!\")\
865end\
866\
867-- Loads an API from a specified path\
868local function loadAPI(path)\
869\009local name = fs.getName(path)\
870\009local tEnv = {}\
871\009setmetatable(tEnv, {__index = _G})\
872\009local fnAPI, err = loadfile(path)\
873\
874\009if fnAPI then\
875\009\009setfenv(fnAPI, tEnv)\
876\009\009fnAPI()\
877\009else\
878\009\009return false\
879\009end\
880\
881\009local tAPI = {}\
882\009for k, v in pairs(tEnv) do\
883\009\009tAPI[k] = v\
884\009end\
885\
886\009return tAPI\
887end\
888\
889-- Split a string up by a certain character\
890string.split = function(text, charToDo)\
891\009local reTbl = {}\
892\009reTbl = string.match(text, \"([^\" .. charToDo .. \"]+)\")\
893\009return reTbl\
894end\
895\
896-- Removes the file extension from a filename\
897local function removeFilename(filename)\
898\009local parts = string.split(filename, \".\")\
899\009if type(parts) == \"table\" then\
900\009\009return parts[1]\
901\009else\
902\009\009return parts\
903\009end\
904end\
905\
906\
907-- Recursively loads APIs from the APIs folder\
908local function loadAPIs(path)\
909\009local dirList = fs.list(path)\
910\009local currentPath\
911\009local currentlyLoaded = {}\
912\009local loadName\
913\009local currentAPI\
914\
915\009for i = 1, #dirList do\
916\009\009currentPath = fs.combine(path, dirList[i])\
917\009\009loadName = removeFilename(dirList[i])\
918\009\009if (fs.isDir(currentPath)) then -- If it's a directory, recursively search it for APIs to load\
919\009\009\009currentlyLoaded[loadName] = loadAPIs(fs.combine(path, dirList[i]))\
920\
921\009\009else -- Otherwise load it into the current API table\
922\009\009\009currentAPI = loadAPI(fs.combine(path, dirList[i]))\
923\009\009\009if currentAPI then\
924\009\009\009\009currentlyLoaded[loadName] = currentAPI\
925\009\009\009else\
926\009\009\009\009table.insert(failedAPIs, loadName)\
927\009\009\009end\
928\009\009end\
929\009end\
930\
931\009return currentlyLoaded -- Return all loaded APIs\
932end\
933\
934-- Load APIs into base.<name>\
935local APIs = loadAPIs(\"/BASE/apis/\")\
936_G.base = APIs -- Load these into public memory\
937\
938-- Create notifications for all failed APIs\
939for i = 1, #failedAPIs do\
940\009local noti = base.notifications.newNotification(\"\", \"'\" .. failedAPIs[i] .. \"' Failed\" .. i, \"This API failed to load on startup\")\
941\009print(\"'\" .. failedAPIs[i] .. \"' Failed\")\
942end",
943 [ "BASE/.git/objects/c4/fe6b17159cb8934109fb5530a07be195a191fb" ] = "x\001?Vmo?6\016?W?W\028?/6jk?S?C?\012h????\
944?Rl\024\002#????\"\005???\021?o?s?\020'A0?K|\"????sY\025??????W???? {???\029???1\017?a\023]???\014T(K+&VA?#y??*????[RT4!???e?k:?\006\023a;??pNkg?;P?2\005U1?}?b>?\022?>z??F\026-?t?*z?X??-?'?\006???V\019????\028d\031u?6?ocK?-<???L\011WU?\006z???????\
945??\015\006?'?`??5?\026??? ?B?F??T?m\002\029?lS?m ???\014yP?>*mI?E ?N?]I?????\
946S?6\008\020\026??\003?T?U?2\029?D?S\026,???`p?j<??a*\029b??<p|????;$?p???J\005??1D?u??]y?V?\003?\011gK?Iu?\025)\012+?\026\015?Sz?1\005\\{??\
947?mt??!§q?2\020??#???!???P ?M?h\008�]\"?????FtO??\012????p??h\031F???d?e@?u?D?u??~\004A??-?v\014#?qB\158?9?a~qy}\025??dfa+?_?Hb?#?? ?A?Q\005??vC?C?\002??Ihq????\002\008?k?(??@??4?0M)F6?\030?\
948???\007g}!?$ ?/\008??|B??\009!??{\012?\028???t\127\018?N?N?,?:Y?\007)]????B'??N\020\011\"v\022fg?Ll=???EoE?DN?tr?$???????????6aVW2\016?\006D??~)?\026h?ACI\022[.vRQ\000?R;p\002&?\029\027a\008y&\012??+m?\027 3 ?\012x????????A??c???DZ\030???j?<???X?_?)?#y.A$^*P\030?\020?????\015?t\024n?l\027?J\012?:b?6\012???\023?????\030|@??R?b{\020?\004\"H?\007ue:heV\008\020X??e7??e*G?{G?e?\021(:??\127L?hb??(\004?kp???\007c???2`??\007M?\004\019\018d?\000?\015W?\029\
949;???U?\025Nhx\016.??\007?#??}?6\139V`\030~?j??\011?p1?s??\008NP~??\002??X???\017\012?\0315?r???k? X?,?\005\023:Y^\000l?A????co?\008;O?\015?d?k\002_?%?:???U\019???S|??9>?!?\012q?9\008????z\028?!\028?FT??-?*?\031?\022\020X??nB_?hAK??\019????s???0??\000|~?2?\\\127???3??W9{?\002???j???#:?B?'?e???Q?-????\003??]g\015{+A\
950\"S?>?\023\0240\025t???\001?8?\018?)A?<x\002+???ci?)k???!?\011?,?{",
951 [ "BASE/.git/objects/30/cdb32f56c242ef4ef82d05d4eeb2ca0cb13fbe" ] = "x\001M?A\014? \016E]s?\127\001M?\
952^?\029q?0)?R ?!??/u????\127?r`??a\028?5?[KV?*^?\027?jM?r????N\019\
953??R?;?o??\019)????????oX?Q??\027?\003\027|'?",
954 [ "BASE/apis/json.lua" ] = "------------------------------------------------------------------ utils\
955local controls = {[\"\\n\"]=\"\\\\n\", [\"\\r\"]=\"\\\\r\", [\"\\t\"]=\"\\\\t\", [\"\\b\"]=\"\\\\b\", [\"\\f\"]=\"\\\\f\", [\"\\\"\"]=\"\\\\\\\"\", [\"\\\\\"]=\"\\\\\\\\\"}\
956\
957local function isArray(t)\
958\009local max = 0\
959\009for k,v in pairs(t) do\
960\009\009if type(k) ~= \"number\" then\
961\009\009\009return false\
962\009\009elseif k > max then\
963\009\009\009max = k\
964\009\009end\
965\009end\
966\009return max == #t\
967end\
968\
969local whites = {['\\n']=true; ['\\r']=true; ['\\t']=true; [' ']=true; [',']=true; [':']=true}\
970function removeWhite(str)\
971\009while whites[str:sub(1, 1)] do\
972\009\009str = str:sub(2)\
973\009end\
974\009return str\
975end\
976\
977------------------------------------------------------------------ encoding\
978\
979local function encodeCommon(val, pretty, tabLevel, tTracking)\
980\009local str = \"\"\
981\
982\009-- Tabbing util\
983\009local function tab(s)\
984\009\009str = str .. (\"\\t\"):rep(tabLevel) .. s\
985\009end\
986\
987\009local function arrEncoding(val, bracket, closeBracket, iterator, loopFunc)\
988\009\009str = str .. bracket\
989\009\009if pretty then\
990\009\009\009str = str .. \"\\n\"\
991\009\009\009tabLevel = tabLevel + 1\
992\009\009end\
993\009\009for k,v in iterator(val) do\
994\009\009\009tab(\"\")\
995\009\009\009loopFunc(k,v)\
996\009\009\009str = str .. \",\"\
997\009\009\009if pretty then str = str .. \"\\n\" end\
998\009\009end\
999\009\009if pretty then\
1000\009\009\009tabLevel = tabLevel - 1\
1001\009\009end\
1002\009\009if str:sub(-2) == \",\\n\" then\
1003\009\009\009str = str:sub(1, -3) .. \"\\n\"\
1004\009\009elseif str:sub(-1) == \",\" then\
1005\009\009\009str = str:sub(1, -2)\
1006\009\009end\
1007\009\009tab(closeBracket)\
1008\009end\
1009\
1010\009-- Table encoding\
1011\009if type(val) == \"table\" then\
1012\009\009assert(not tTracking[val], \"Cannot encode a table holding itself recursively\")\
1013\009\009tTracking[val] = true\
1014\009\009if isArray(val) then\
1015\009\009\009arrEncoding(val, \"[\", \"]\", ipairs, function(k,v)\
1016\009\009\009\009str = str .. encodeCommon(v, pretty, tabLevel, tTracking)\
1017\009\009\009end)\
1018\009\009else\
1019\009\009\009arrEncoding(val, \"{\", \"}\", pairs, function(k,v)\
1020\009\009\009\009assert(type(k) == \"string\", \"JSON object keys must be strings\", 2)\
1021\009\009\009\009str = str .. encodeCommon(k, pretty, tabLevel, tTracking)\
1022\009\009\009\009str = str .. (pretty and \": \" or \":\") .. encodeCommon(v, pretty, tabLevel, tTracking)\
1023\009\009\009end)\
1024\009\009end\
1025\009-- String encoding\
1026\009elseif type(val) == \"string\" then\
1027\009\009str = '\"' .. val:gsub(\"[%c\\\"\\\\]\", controls) .. '\"'\
1028\009-- Number encoding\
1029\009elseif type(val) == \"number\" or type(val) == \"boolean\" then\
1030\009\009str = tostring(val)\
1031\009else\
1032\009\009error(\"JSON only supports arrays, objects, numbers, booleans, and strings\", 2)\
1033\009end\
1034\009return str\
1035end\
1036\
1037function encode(val)\
1038\009return encodeCommon(val, false, 0, {})\
1039end\
1040\
1041function encodePretty(val)\
1042\009return encodeCommon(val, true, 0, {})\
1043end\
1044\
1045------------------------------------------------------------------ decoding\
1046\
1047local decodeControls = {}\
1048for k,v in pairs(controls) do\
1049\009decodeControls[v] = k\
1050end\
1051\
1052function parseBoolean(str)\
1053\009if str:sub(1, 4) == \"true\" then\
1054\009\009return true, removeWhite(str:sub(5))\
1055\009else\
1056\009\009return false, removeWhite(str:sub(6))\
1057\009end\
1058end\
1059\
1060function parseNull(str)\
1061\009return nil, removeWhite(str:sub(5))\
1062end\
1063\
1064local numChars = {['e']=true; ['E']=true; ['+']=true; ['-']=true; ['.']=true}\
1065function parseNumber(str)\
1066\009local i = 1\
1067\009while numChars[str:sub(i, i)] or tonumber(str:sub(i, i)) do\
1068\009\009i = i + 1\
1069\009end\
1070\009local val = tonumber(str:sub(1, i - 1))\
1071\009str = removeWhite(str:sub(i))\
1072\009return val, str\
1073end\
1074\
1075function parseString(str)\
1076\009str = str:sub(2)\
1077\009local s = \"\"\
1078\009while str:sub(1,1) ~= \"\\\"\" do\
1079\009\009local next = str:sub(1,1)\
1080\009\009str = str:sub(2)\
1081\009\009assert(next ~= \"\\n\", \"Unclosed string\")\
1082\
1083\009\009if next == \"\\\\\" then\
1084\009\009\009local escape = str:sub(1,1)\
1085\009\009\009str = str:sub(2)\
1086\
1087\009\009\009next = assert(decodeControls[next..escape], \"Invalid escape character\")\
1088\009\009end\
1089\
1090\009\009s = s .. next\
1091\009end\
1092\009return s, removeWhite(str:sub(2))\
1093end\
1094\
1095function parseArray(str)\
1096\009str = removeWhite(str:sub(2))\
1097\
1098\009local val = {}\
1099\009local i = 1\
1100\009while str:sub(1, 1) ~= \"]\" do\
1101\009\009local v = nil\
1102\009\009v, str = parseValue(str)\
1103\009\009val[i] = v\
1104\009\009i = i + 1\
1105\009\009str = removeWhite(str)\
1106\009end\
1107\009str = removeWhite(str:sub(2))\
1108\009return val, str\
1109end\
1110\
1111function parseObject(str)\
1112\009str = removeWhite(str:sub(2))\
1113\
1114\009local val = {}\
1115\009while str:sub(1, 1) ~= \"}\" do\
1116\009\009local k, v = nil, nil\
1117\009\009k, v, str = parseMember(str)\
1118\009\009val[k] = v\
1119\009\009str = removeWhite(str)\
1120\009end\
1121\009str = removeWhite(str:sub(2))\
1122\009return val, str\
1123end\
1124\
1125function parseMember(str)\
1126\009local k = nil\
1127\009k, str = parseValue(str)\
1128\009local val = nil\
1129\009val, str = parseValue(str)\
1130\009return k, val, str\
1131end\
1132\
1133function parseValue(str)\
1134\009local fchar = str:sub(1, 1)\
1135\009if fchar == \"{\" then\
1136\009\009return parseObject(str)\
1137\009elseif fchar == \"[\" then\
1138\009\009return parseArray(str)\
1139\009elseif tonumber(fchar) ~= nil or numChars[fchar] then\
1140\009\009return parseNumber(str)\
1141\009elseif str:sub(1, 4) == \"true\" or str:sub(1, 5) == \"false\" then\
1142\009\009return parseBoolean(str)\
1143\009elseif fchar == \"\\\"\" then\
1144\009\009return parseString(str)\
1145\009elseif str:sub(1, 4) == \"null\" then\
1146\009\009return parseNull(str)\
1147\009end\
1148\009return nil\
1149end\
1150\
1151function decode(str)\
1152\009str = removeWhite(str)\
1153\009t = parseValue(str)\
1154\009return t\
1155end\
1156\
1157function decodeFromFile(path)\
1158\009local file = assert(fs.open(path, \"r\"))\
1159\009local decoded = decode(file.readAll())\
1160\009file.close()\
1161\009return decoded\
1162end",
1163 [ "BASE/.git/objects/c3/4e662a2cd9ed5bd7a21b32ea8c1909418db320" ] = "x\001+)JMU024e040031QHJ,N???K?g8?yf????????ju?|??g?KdE?%%?y??\012l?\031T??l??\025? x????'?\021??\0221p?}]??q????d\021??Z)?^\
1164U???W?????'?_??3???W)\007O??,Q?s?)????????\"?+?3?.?????y??E???E?j2\025\0028]???o???J'j'\028????\006\000?g[?",
1165 [ "BASE/programs/icons/base_settings" ] = "888888888\
1166887787788\
1167887787788\
1168887787788\
1169887787788",
1170 [ "BASE/.git/config" ] = "[core]\
1171\009repositoryformatversion = 0\
1172\009filemode = false\
1173\009bare = false\
1174\009logallrefupdates = true\
1175\009symlinks = false\
1176\009ignorecase = true\
1177[remote \"origin\"]\
1178\009url = http://root@dev.samjgunner.uk/misc-software/base-2.git\
1179\009fetch = +refs/heads/*:refs/remotes/origin/*\
1180[branch \"master\"]\
1181\009remote = origin\
1182\009merge = refs/heads/master",
1183 [ "BASE/programs/i" ] = "bNo = '1.2.1'\
1184\
1185function loadOpts()\
1186 if fs.exists('.sgunner2014/imaker/etc') then\
1187 local h = fs.open('.sgunner2014/imaker/etc', 'r')\
1188\009opts = textutils.unserialize(h.readAll())\
1189\009h.close()\
1190 else\
1191 fs.makeDir('.sgunner2014/imaker')\
1192\009local h = fs.open('.sgunner2014/imaker/etc', 'w')\
1193\009h.write('{auto = true}')\
1194\009h.close()\
1195\009opts = {\
1196\009 auto = true,\
1197\009}\
1198 end\
1199end\
1200\
1201function boot(arg)\
1202 term.setBackgroundColor(colors.white)\
1203 term.clear()\
1204 term.setTextColor(colors.black)\
1205 ctxt('Installer Maker - Version ' .. bNo, 9)\
1206 sleep(2)\
1207end\
1208\
1209function checkAndUpdate()\
1210 local newVer = http.get('http://www.pastebin.com/raw.php?i=LPKWiQZz')\
1211 local newVer = newVer.readAll()\
1212 if newVer ~= bNo then\
1213 local h = http.get('http://www.pastebin.com/raw.php?i=jVBbrQhp')\
1214\009local h = h.readAll()\
1215\009local f = fs.open('imakerUpdated', 'w')\
1216\009f.write(h)\
1217\009f.close()\
1218\009return true\
1219 end\
1220end\
1221\
1222function options()\
1223 optTerm = nil\
1224 repeat\
1225\009local beg = term.current()\
1226\009term.redirect(mainWin)\
1227\009term.setBackgroundColor(colors.white)\
1228\009term.clear()\
1229\009term.setTextColor(colors.black)\
1230\009ctxt('Auto-update', 4)\
1231\009ctxt('Update log', 5)\
1232\009term.redirect(beg)\
1233\009local _, button, x, y = os.pullEvent('mouse_click')\
1234\009if y<=2 then\
1235\009 handClick(1, x, y)\
1236\009else\
1237\009\009local res = handClick(3, x, y)\
1238\009\009if res == 1 then\
1239\009\009 term.redirect(mainWin)\
1240\009\009 local ans = popup('Do you want to receive automatic updates?')\
1241\009\009 term.redirect(beg)\
1242\009\009 if ans == true then\
1243\009\009\009opts.auto = true\
1244\009\009 elseif ans == false then\
1245\009\009\009opts.auto = false\
1246\009\009 end\
1247\009\009 local h = fs.open('.sgunner2014/imaker/etc', 'w')\
1248\009\009 h.write(textutils.serialize(opts))\
1249\009\009 h.close()\
1250\009\009elseif res == 2 then\
1251\009\009 term.redirect(mainWin)\
1252\009\009 term.setBackgroundColor(colors.white)\
1253\009\009 term.clear()\
1254\009\009 local upd8 = http.get('http://www.pastebin.com/raw.php?i=EwusSyQn')\
1255\009\009 local upd8 = upd8.readAll()\
1256\009\009 ctxt('Update Log:', 1)\
1257\009\009 term.setCursorPos(1, 2)\
1258\009\009 print(upd8)\
1259\009\009 ctxt('Click anywhere to exit', 17)\
1260\009\009 term.redirect(beg)\
1261\009\009 local _, button, x, y = os.pullEvent('mouse_click')\
1262\009\009end\
1263\009end\
1264 until optTerm == true\
1265end\
1266\
1267function popup(txt)\
1268 paintutils.drawLine(48, 9, 48, 13, colors.black)\
1269 paintutils.drawLine(5, 13, 48, 13, colors.black)\
1270 for i=8, 12 do\
1271 paintutils.drawLine(4, i, 47, i, colors.lightGray)\
1272 end\
1273 for i=9, 11 do\
1274 paintutils.drawLine(5, i, 46, i, colors.white)\
1275 end\
1276 ctxt(txt, 9)\
1277 paintutils.drawLine(5, 11, 25, 11, colors.green)\
1278 ptxt('Yes', 16, 11)\
1279 paintutils.drawLine(26, 11, 46, 11, colors.red)\
1280 ptxt('No', 35, 11)\
1281 local _, button, x, y = os.pullEvent('mouse_click')\
1282 local y = y-2\
1283 if button == 1 and x>=5 and x<=25 and y == 11 then\
1284 return true\
1285 elseif button == 1 and x>=26 and x<=46 and y == 11 then\
1286 return false\
1287 end\
1288end\
1289\
1290function diagBox(txt)\
1291 for i=8, 12 do\
1292 paintutils.drawLine(4, i, 47, i, colors.lightGray)\
1293 end\
1294 for i=9, 11 do\
1295 paintutils.drawLine(5, i, 46, i, colors.white)\
1296 end\
1297 paintutils.drawLine(48, 9, 48, 13, colors.black)\
1298 paintutils.drawLine(5, 13, 48, 13, colors.black)\
1299 term.setBackgroundColor(colors.white)\
1300 ctxt(txt, 9)\
1301 local beg = term.current()\
1302 local tmpWin = window.create(term.current(), 5, 11, 42, 1)\
1303 term.redirect(tmpWin)\
1304 term.setTextColor(colors.white)\
1305 term.setBackgroundColor(colors.gray)\
1306 term.clear()\
1307 term.setCursorPos(1, 1)\
1308 local tmpVal = read()\
1309 term.redirect(beg)\
1310 term.setTextColor(colors.black)\
1311 return tmpVal\
1312end\
1313\
1314function mClick()\
1315 _, button, x, y = os.pullEvent('mouse_click')\
1316end\
1317\
1318function mScroll()\
1319 _, dir, x, y = os.pullEvent('mouse_scroll')\
1320end\
1321\
1322function newInstaller()\
1323 local beg = term.current()\
1324 term.redirect(mainWin)\
1325 installTerm = nil\
1326 --repeat -- Secondary loop\
1327 local filePaths = {}\
1328 local tmpVal = false\
1329 local tmp = popup('Make a new installer?')\
1330 if tmp == true then\
1331 repeat\
1332 local tmpTxt = diagBox('Enter the path to the file to add')\
1333 if #tmpTxt > 1 then\
1334 table.insert(filePaths, tmpTxt)\
1335 end\
1336 local quit = popup('Do you want to add another file?')\
1337 if quit == false then\
1338 tmpVal = true\
1339 end\
1340 until tmpVal == true\
1341 \
1342 local tmp = nil\
1343 \
1344 for i=1, #filePaths do\
1345 if not fs.exists(filePaths[i]) then\
1346 tmp = false\
1347 end\
1348 end\
1349 \
1350 if tmp == nil then\
1351 local beg = term.current()\
1352 term.redirect(mainWin)\
1353 local tmpWin1 = window.create(term.current(), 1, 1, 51, 1)\
1354 local tmpWin2 = window.create(term.current(), 1, 2, 51, 15)\
1355 local tmpWin3 = window.create(term.current(), 1, 17, 51, 1)\
1356 \
1357 term.redirect(tmpWin3)\
1358 term.setBackgroundColor(colors.lightGray)\
1359 term.clear()\
1360 ctxt(' > Next step > ', 1)\
1361 term.redirect(beg)\
1362 \
1363 term.redirect(tmpWin1)\
1364 term.setBackgroundColor(colors.lightGray)\
1365 term.clear()\
1366 term.setTextColor(colors.white)\
1367 ctxt('Just to refresh, these are the files/folders you\\'ve added:', 1)\
1368 term.redirect(tmpWin2)\
1369 term.setBackgroundColor(colors.white)\
1370 term.clear()\
1371 term.setTextColor(colors.black)\
1372 \
1373 cPos = 1\
1374 \
1375 tmpTerm1 = nil\
1376 \
1377 term.setCursorPos(1, 1)\
1378 repeat\
1379 \
1380 term.setCursorPos(1, 1)\
1381 term.clear()\
1382 \
1383 for i=cPos, cPos+14 do\
1384 if filePaths[i] ~= nil then\
1385 print(filePaths[i])\
1386 end\
1387 end\
1388 local pid = parallel.waitForAny(mClick, mScroll)\
1389 if pid == 1 then\
1390 if button == 1 then\
1391 if x>=1 and x<=51 and y>2 and y<19 then\
1392 \
1393 y = y-1\
1394 elseif x>=1 and x<=51 and y==19 then\
1395 \
1396 local beg = term.current()\
1397 term.redirect(tmpWin2)\
1398 local ans = diagBox('Enter the installer path')\
1399 term.redirect(beg)\
1400 \
1401 local files = {}\
1402 \
1403 for i=1, #filePaths do\
1404\009\009\009 if not fs.isDir(filePaths[i]) then\
1405 local h = fs.open(filePaths[i], 'r')\
1406 local tmpCon = h.readAll()\
1407 h.close()\
1408 files[filePaths[i]] = tmpCon\
1409\009\009\009 else\
1410\009\009\009 \
1411\009\009\009\009local dirList = searchThroughDir(filePaths[i])\
1412\009\009\009\009for k, v in pairs(dirList) do\
1413\009\009\009\009 files[k] = v\
1414\009\009\009\009end\
1415\009\009\009\009\
1416\009\009\009 end\
1417 end\
1418 \
1419 if not fs.exists(fs.getDir(ans)) then\
1420 fs.makeDir(fs.getDir(ans))\
1421 end\
1422 \
1423 local h = fs.open(ans, 'w')\
1424 h.write('local tmpTbl = ' .. textutils.serialize(files))\
1425 h.writeLine('\\nfor k, v in pairs(tmpTbl) do')\
1426\009\009\009h.writeLine('if not fs.exists(fs.getDir(k)) then fs.makeDir(fs.getDir(k)) end')\
1427 h.writeLine('local h = fs.open(k, \\'w\\')')\
1428 h.writeLine('h.write(v)')\
1429 h.writeLine('h.close()')\
1430 h.writeLine('end')\
1431 h.writeLine('--Packaged using Sam Gunner\\'s installer maker - Version ' .. bNo)\
1432 h.close()\
1433 tmpTerm1 = true\
1434 \
1435 \
1436 elseif x==51 and y==1 then\
1437 fterm = true\
1438 tmpTerm1 = true\
1439 end\
1440 end\
1441 elseif pid == 2 then\
1442 if dir == -1 then\
1443 if cPos > 1 then\
1444 cPos = cPos-1\
1445 end\
1446 elseif dir == 1 then\
1447 if cPos+13 < (#filePaths) then\
1448 cPos = cPos+1\
1449 end\
1450 end\
1451 end\
1452 until tmpTerm1 == true\
1453 term.redirect(beg)\
1454 elseif tmp == false then\
1455 local ans = popup('Something went wrong. Close?')\
1456 if ans == true then\
1457 fterm = true\
1458 end\
1459 end\
1460 \
1461 end\
1462 \
1463 --until installTerm == true\
1464 installTerm = nil\
1465 term.redirect(beg)\
1466end\
1467\
1468function searchThroughDir(sDir)\
1469 local tmpTbl1 = {}\
1470 for k, v in ipairs(fs.list(sDir)) do\
1471 if fs.isDir(fs.combine(sDir, v)) then\
1472\009 local tmpTbl2 = searchThroughDir(fs.combine(sDir, v))\
1473\009 for k, v in pairs(tmpTbl2) do\
1474\009 tmpTbl1[k] = v\
1475\009 end\
1476\009else\
1477\009 local h = fs.open(fs.combine(sDir, v), 'r')\
1478\009 tmpTbl1[fs.combine(sDir, v)] = h.readAll()\
1479\009 h.close()\
1480\009end\
1481 end\
1482 return tmpTbl1\
1483end\
1484\
1485function handClick(m, x, y)\
1486 if m == 1 then\
1487 if x==51 and y==1 then\
1488\009 optTerm = true\
1489 fterm = true\
1490\009elseif x>=7 and x<=13 and y==2 then\
1491\009 options()\
1492\009elseif x>=1 and x<=4 then\
1493\009 optTerm = true\
1494 end\
1495 elseif m == 2 then\
1496 if y==5 then\
1497 newInstaller()\
1498 elseif y==12 then\
1499 fterm = true\
1500 end\
1501 elseif m == 3 then\
1502 if y==2 then\
1503\009 if x>=7 and x<=14 then\
1504\009 optTerm = true\
1505\009 end\
1506\009elseif y==1 then\
1507\009 if x==51 then\
1508\009 optTerm = true\
1509\009\009fterm = true\
1510\009 end\
1511\009else\
1512\009 local y=y-2\
1513\009 if x>=1 and x<=51 and y==4 then\
1514\009 return 1\
1515 elseif x>=1 and x<=51 and y==5 then\
1516\009 return 2\
1517\009 end\
1518\009end\
1519 end\
1520end\
1521\
1522function ctxt(txt, y)\
1523 local w, h = term.getSize()\
1524 local x = ((w/2)-(#txt/2))+1\
1525 term.setCursorPos(x, y)\
1526 write(txt)\
1527end\
1528\
1529function ptxt(txt, x, y)\
1530 term.setCursorPos(x, y)\
1531 write(txt)\
1532end\
1533\
1534function drawMain()\
1535 if mainWin == nil and topWin == nil then\
1536 mainWin = window.create(term.current(), 1, 3, 51, 17)\
1537 topWin = window.create(term.current(), 1, 1, 51, 2)\
1538 end\
1539 \
1540 local beg = term.current()\
1541 \
1542 term.redirect(topWin)\
1543 term.setBackgroundColor(colors.gray)\
1544 term.clear()\
1545 term.setTextColor(colors.white)\
1546 ctxt('Installer Maker - Version ' .. bNo, 1)\
1547 term.setTextColor(colors.red)\
1548 ptxt('x', 51, 1)\
1549 term.setTextColor(colors.white)\
1550 ptxt('Home Options', 1, 2)\
1551 term.redirect(beg)\
1552\
1553 term.redirect(mainWin)\
1554 term.setBackgroundColor(colors.white)\
1555 term.clear()\
1556 term.setTextColor(colors.black)\
1557 ctxt('New Installer', 5)\
1558 ctxt('Close', 12)\
1559 term.redirect(beg)\
1560 \
1561end\
1562\
1563function click()\
1564 _, tB, tX, tY = os.pullEvent('mouse_click')\
1565end\
1566\
1567function nread(char)\
1568 tmpTxt = read(char)\
1569end\
1570\
1571function mainLoop()\
1572 repeat\
1573 drawMain()\
1574 local event, button, x, y = os.pullEvent('mouse_click')\
1575 if x>=1 and x<=51 and y>2 then\
1576 handClick(2, x, y-2)\
1577 else\
1578 handClick(1, x, y)\
1579 end\
1580 until fterm == true\
1581end\
1582\
1583fterm = nil\
1584nUpdate = nil\
1585loadOpts()\
1586\
1587boot()\
1588mainLoop()\
1589fterm = nil\
1590\
1591term.setBackgroundColor(colors.black)\
1592term.clear()\
1593term.setCursorPos(1, 1)",
1594 [ "BASE/apis/notifications.lua" ] = "--[[\
1595\009Notifications API for BASE 2\
1596]]--\
1597\
1598last_id = 0\
1599notifications = {}\
1600local unreadNotifications = {}\
1601\
1602-- Notification object to represent a notification from an app\
1603local notification = {\
1604\009text = \"\",\
1605\009app_id = \"\",\
1606\009app_name = \"\",\
1607\009notification_id = \"\",\
1608\009setText = function(self, text)\
1609\009\009self.text = text\
1610\009end,\
1611\009setAppID = function(self, app_id)\
1612\009\009self.app_id = app_id\
1613\009end,\
1614\009setAppName = function(self, name)\
1615\009\009self.app_name = name\
1616\009end,\
1617\009setNotificationID = function(self, app_id)\
1618\009\009self.notification_id = app_id\
1619\009end,\
1620\009getAppID = function(self)\
1621\009\009return self.app_id\
1622\009end,\
1623\009getAppName = function(self)\
1624\009\009return self.app_name\
1625\009end,\
1626\009getText = function(self)\
1627\009\009return self.text\
1628\009end,\
1629\009getNotificationID = function(self)\
1630\009\009return self.notification_id\
1631\009end,\
1632\009new = function(self, o)\
1633\009\009o = o or {}\
1634\009\009setmetatable(o, self)\
1635\009\009self.__index = self\
1636\009\009return o\
1637\009end\
1638}\
1639\
1640-- Returns the next ID available\
1641function getNextID()\
1642\009last_id = last_id + 1\
1643\009return last_id\
1644end\
1645\
1646-- Creates new notification object and adds it to the noticications list\
1647function newNotification(appid, title, text)\
1648\009local obj321 = notification:new()\
1649\009obj321:setAppID(appid)\
1650\009obj321:setAppName(title)\
1651\009obj321:setText(text)\
1652\009obj321:setNotificationID(id)\
1653\009table.insert(notifications, obj321)\
1654\009local id = getNextID()\
1655\009return obj321:getText()\
1656end\
1657\
1658-- Returns all existing notifications\
1659function getNotifications()\
1660\009return notifications\
1661end\
1662\
1663-- Dismisses a notification\
1664function dismissNotification(notification_id)\
1665\009local notification = notifications[notification_id]\
1666\009table.remove(notifications, notification_id)\
1667\009base.kernel.bringToFront(notification.getAppID())\
1668end\
1669\
1670-- Removes a notification\
1671function removeNotification(notification_id)\
1672\009table.remove(notifications, notification_id)\
1673\009--notifications[notification_id] = nil\
1674end\
1675\
1676-- Returns true if a notification is present, false if not\
1677function notificationExists()\
1678\009if #notifications > 0 then\
1679\009\009return true\
1680\009else\
1681\009\009return false\
1682\009end\
1683end\
1684\
1685-- Returns all unread notifications\
1686function getUnreadNotifications()\
1687\009return unreadNotifications\
1688end\
1689\
1690-- Returns the number of unread notifications\
1691function getNumberOfUnread()\
1692\009return #unreadNotifications\
1693end\
1694\
1695-- Marks all notifications as read\
1696function readNotications()\
1697\009unreadNotifications = {}\
1698end\
1699\
1700-- Returns a specific notification\
1701function getNotification(notification_id)\
1702\009return notifications[notification_id]\
1703end",
1704 [ "BASE/files/images/genericIcon_small" ] = "0000f0000\
17050000f0000\
1706000000000\
17070000f0000\
1708000000000",
1709 [ "BASE/files/images/tskmgr_icon_small" ] = "885888888\
1710858588888\
1711588858885\
1712888885858\
1713888888588",
1714 [ "BASE/.git/objects/37/cbfe3143ecd15000c85bc754301a9b1d7e54e5" ] = "x\001K??OR044c??RP((??M,?\012I?(q???/R?U0627??\001??&f??\004\
1715??B???y)@\
17160q#S3????\020??!H$3?,??8\021?`?x-\0001?%?",
1717 [ "BASE/.git/sourcetreeconfig" ] = "<?xml version=\"1.0\"?>\
1718<RepositoryCustomSettings xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\
1719 <AutoRefresh>true</AutoRefresh>\
1720 <AutoRefreshRemotes>true</AutoRefreshRemotes>\
1721 <CommitTextLinks />\
1722 <DraftCommitMsg />\
1723 <IncomingSavedCount>0</IncomingSavedCount>\
1724 <LastCheckedRemotes>2017-09-06T00:56:37.2271355+01:00</LastCheckedRemotes>\
1725 <LastUsedView>Log</LastUsedView>\
1726 <LogBranchFilterIndex>0</LogBranchFilterIndex>\
1727 <OutgoingSavedCount>0</OutgoingSavedCount>\
1728 <RemoteProjectLinks />\
1729 <SidebarExpandedItems>\
1730 <string>File Status</string>\
1731 <string>Branches</string>\
1732 <string>Remotes</string>\
1733 </SidebarExpandedItems>\
1734 <SidebarWidth>140</SidebarWidth>\
1735 <SubtreeLinks />\
1736</RepositoryCustomSettings>",
1737 [ "BASE/.git/objects/56/8629664aa8934acc8d66d838614b1f46e75f2c" ] = "x\001?V]o\"7\020?+??[^?Ua???[?HI\027E+u???V?Udf<??=?=\001?}?=@ ??\008\025?????{???.\127z??7??/C???;??Z?????^=KG\"?5%?J?\015?I??r?P??\011r?Y;^n\008Ol?9I?gC\024>bWn\
1738I??x??\027\015S?ii??\019Zt\030?T\024\025?\026??0?ty?\
1739?~?N?ò?WFS#?\030?\005nmrQS+???9?v?D??m\0009?R?N??\127???{?t?\023\022.???C.?X\127b??\016??&s??|??????6v???????2???????XR??.\017_?#x???]?'???\028?BM?}???Q?m\004??x????sN,????A???\031?\030??,?(?hB?\003O\017?\009??E??ô\001f???^\0028\019?\007\024???\020C?????\005??6F?\000~vc_?\019??I:????????\001]?\001a=$W?{.?d?f?*\022y??%jy\016BmD?\001??#\022?\011??H?y*U-?\005???????''\012?\024?\007M&??[?N?70#?M?\001?(\022???W??IY??j\127Xo???%??0????[-\004?? ??[???r;?y?|?t?\029\025\018?C\127?k@?????5??\\hZHn\022\005?\024??X?6?Rzc?\005d\014\"{????\031?A\028??VuM?\0188?[\023ZGD?\029�??xt?$?<?HM?%?J???\011?q\027??\001??h?.?a?$?S0???\021??????bKy??\021b$$??\002\022g|vy.??-??[?QZ5\
1740??'\024????\025?l?\018\009&?M??\000\005??^?G?K?:[?]??\004?\016N?v!??6??\
1741$\026?KI^r$z8\024?>i\006??{?\127??`pL??\014,???9?h??5?/\008\
1742?9?\019;?\026?2??\018?|\006\
1743\0289?H???P5?\008???\005?W?\"?\015<? ?\
1744}\019D?A??? ?????\
1745?\011?<??X????\
1746<??0?rÿ??0?!?@y?S?\
1747?!?\011b??Bx?&??\001oX?|?\030?J?\"v??J?lM\027???\009t????Y?\020\
1748W?$??+d\009^z?\
1749\012?u ?E\030e^i?3????J??e^%????h???54?? \029a?a??D???\0097?\009m@itu???;??xtP????\005??\002^n???Y?\004\001??(r?o??aS?s=?\0167_?g/f\014?\001??_?#????=??4?x?(%&<F!?????zE?\011SP^@\014_??<\014???ãm\127q?W+8\022?p<?\030?4\008\029\
1750?\"???\000?|T?",
1751 [ "BASE/apis/system.lua" ] = "--[[\
1752 System 'API' for BASE. Holds various values and also includes some useful programs\
1753]]--\
1754\
1755version = \"2.1.5 (Development Version)\"\
1756systemVariables = {}\
1757updateAddress = \"http://computercraftcloud.com\" -- The root address for the OS to pull all updates and content from (NYI)\
1758\
1759-- Launch a program from a path and maximise it (maximising to be added in the future)\
1760function launchProgramForeground(path)\
1761 local _, id = base.kernel.newTaskFromPath(path, true)\
1762 return id\
1763end\
1764\
1765-- Check to see whether a system variable with a certain name exists.\
1766function setSystemVariable(var, value)\
1767\009systemVariables[var] = value\
1768\009base.io.saveTable(systemVariables, \"BASE/system/variables\")\
1769end\
1770\
1771-- Checks to see whether a value exists in a system variable.\
1772function isInSystemList(name, listName)\
1773\009if systemVariables[listName] ~= nil then\
1774\009\009local tbl = {}\
1775\009\009tbl = base.text.split(systemVariables[listName], \";\") -- Get the indidividual components of the system list\
1776\009\009for i = 1, #tbl do\
1777\009\009\009if tbl[i] == name then\
1778\009\009\009\009return true\
1779\009\009\009end\
1780\009\009end\
1781\009\009return false\
1782\009end\
1783end\
1784\
1785-- To add in a function that detects if the variables have already been set for the system.\
1786function init() -- Initialises the system API. Loads system variables.\
1787\009base.io.createTableFile(\"BASE/system/variables\")\
1788\009\
1789\009-- Now, set the variables (Will be changed in future to load from file if it exists.)\
1790\009setSystemVariable(\"mainColor\", colors.gray)\
1791\009setSystemVariable(\"secondaryColor\", colors.lightGray)\
1792\009setSystemVariable(\"thirdColor\", colors.white)\
1793\009setSystemVariable(\"primaryTextColor\", colors.black)\
1794\009setSystemVariable(\"inverseTextColor\", colors.white)\
1795\009setSystemVariable(\"ignore_global\", \".DS_Store;.gitignore;.git;.ignore;\") -- Contains a list of file names for the system to ignore when performing operations.\
1796end",
1797 [ "BASE/.git/objects/a0/0653dc8cb3d3d3282eaf64dfbc9a14941ac328" ] = "x\001?Vmo?6\016???W\028?aP0I??X?8@?\005A?,\
1798f\023?P\004\005%?%\"\020)??m????K\022w?\000'??r?{???X(S???\031~?)?}?\000|?Z??g?2?\021^\026\
1799W]?????\006+??Cr}\006o??>??\016-??Z???e#\029t?e?\014|??;????\001gZ\004\025?\006??0?????@?\001,???\026?l???\"\011R?.?:?????\\9p}? =?F{!?#\011?w??\008???E6?3?o??\003??1\027??O5Z#\019???Mo?2tlm<???#Z\012?c?\008??h??c\\&??Y6??z]??\\K?H? ???l???1\028A?k?+S\
1800\005???oa\0143\026?8??w?}???B8?]p?????s)LM7?%_C?w??C]?fzvd?P\016l-?(?+??8?M??w???\002m\139?8?x?}8?\021??9??!?%q*\008??T\
1801x\005Tr?B\0144?????h \017?\000?+-???[)\000\030'\030V?a\009so\009??D\018?\026-?\006???C?I?O?5????26)???7???!?+K??R?a?d\012??N?-\017??,?9??\005J?@!F?@1H?{/??9?;?1??2???\024]?V\012?#?????????\002??\022???dz?d?\020fG!?2d??+\014f?`fK??x?HQ?\008\026? ?lq??1?wD?D?J?EZHo??\030?S???????>?A??R?J??7\007?#?\001?(9?v\127S~?I\026?2???Bi?\004??,J??\020???#\005z\030???\011?ioXM\016I?\">?&?\003?????).\
1802ER<?\006?z?;:??8[Xr\\?H?!U?{\020<#?<[\014???E???>?T??~?????\028?+??^???\022?C??yz?.\007_???\
1803???\005??~oN\0025???v?\127|??9??\017??Js??\026??\021?r?\009?u??F?&+\019pzQ?b?GC?S(R?0?-??W?fM$$??P7?^*Y>M?B\014?\016\006?n??jT?\026Q?(`N\021????9p\027??A?<???chA??|?l]X9VT?|n?\021??????%xn?Nx%@vN?g???^p?{\024\027?Q\008l???__??\005(??bd??\030G?\000?]?'\015?g????v?\
1804;\0007?Idq?t?????T????X;P??[\002\021\028?\028?o.?8?\141f?e?%??\007?k???0wT?C{#\019???k?\022R?Ba\014?\
1805?O???/_?\
1806;??\009\002?n\017?S??PS>\028?%F<\
1807???%?:???<??\015MFH????\031??\008L",
1808 [ "BASE/.git/logs/refs/heads/master" ] = "0000000000000000000000000000000000000000 12513210bfaef59ba5e8e34960cce7aa217f56b4 Sam Gunner <sam> 1504474619 +0100\009commit (initial): Added operating system in its current state",
1809 [ "BASE/programs/icons/i" ] = "f00000000\
1810000000000\
1811f0fffff00\
1812f0f0f0f00\
1813f0f0f0f00",
1814 [ "BASE/.git/objects/77/453d2ad8653b36d02a4c12450fc834fc40cc82" ] = "x\001?Xmo?6\016???W\028?/2fk???\005?\003?I\026\020?`\009?\015YP?\018m\019?E??cg????\028I?R?d?\021ulIw??s?Pc??t????~??f??|?P?\008?_??R?4H\015?\003<?????D\027??????w?\023\015FNg???.\
1815\015\006?zt???bY?¤,r&?????\025\029\015?7d??j?`>??????'?2?k?ee????]2??G\015=?B???T?G??\024Q????zt/??R??#H?.?\019\026?hD\003r3Q???[?\003?\"???1?-?4%?\007^\\(+`e}2\
1816??w??A?<\025\029?\031?F?\
1817/@?>]?\004?{xF???J??,?!M?6?\005??^?~\009b'???!cET?I'#\026??V\0147?}??W?\
1818\027?;e\\\"\0287\015???J??:?v\007-? \028]\019e\017|??|?F??,????\019f?Z?>d????eY?j?(???MW3?D%?+?\025V?6],?:g??z?Y?N?2?0.?\\??l? ??/?.??+O??????{H}?L)?i\007??t?!???c\007??^|??Q\021????;\031?n??\006?\031?s?4Rb?^?v?C\006@???8??%?C?\004?C^?kZ??\023i??????Q:?\020?T?l?\019???=]&?/??Y?M\014\"?t?\003lTV?b\
1819?<8F\020? ??? ?\014h>\031s?E??d\015\
1820?*?M?k?v???2?\017\014\002i??`DU?\016r??Y+p9Hll,??5?9???\002?w?C???gY?d?0B\008??W???9V???\0031?\023\129??\025????c?2?h,]u?@\005\003/i\001!???XX\016S?.?b!?N?\023\\?\016?`/5(3??????/??Z?.? z???qo????`h'??i?}o\"R\019??2?\014??,?m??sz\030\019q??t\009??f??^\003??a\011?&6U?6<\016?K?\022?\026??\011??3????t?R??\009Y??3\023<?N?S%??\000\\?\006??0?^??9??34E?C??\011?=p??4\019F46??\0057???M6&?T?+??@?l\018???[K6????>?y;=\004??b?\000\028?\0309?D!gS\
1821\023'??\000=??1?P????\029??T#??x\\?N(?XX\019k??&?~???M?t&?;&?\021??<?\027??&q?)?9??mU?6???\008??I?\002?U\015?M\005?~??V?0?Q(?w?f?U??69?*??=\030??kt\027?c\024?-??\025f\030'?^\005?v??l\027??zZ?G4H??HxL¨\017\127n-???]H?mn???H?8?Vu\018?t?L\127?????\024\0175~??~?<??a??\002}????w??\017\022???\024yk?l\024\014?P?\006Z?(?l?D*K?\019\012????\
1822??;\008s/G?]:??!?U}?ti?6\024t?Puj???f??j?f?Wf??`?b??AM??H?\
1823t?\009???\
1824iU9??B?U3?\025??R\019^L?O\004\"??\020n??^)D\014\008#nQ<??C\026\030???\029?.?\001???G\127??\021\015\014\012??e?h???\01548l??\0056?+]?\019p0T\027^?F?\030?Cm??c1\028s?\021?m??\004??F'd????%?O|?%\004??\017?p?28\012$??[4Rt?????V?\
1825?\017\"Y??O#q??{???????F\024$?Wm3?\009F7??&*<???Gy3???\001???\000'?\008??[ W?\009-a+-x??9?\009BR?sr????\002?-????\007??\006??\007?Oe!s??,??&?an?\0185\019g\127??V\
1826?\017\014?~\
1827F\025CC??J?M???}??!\014?_{4\014/\018 ?:vv?\026?~??eCd\029\028?Y?0?hZisGz??<\030????a??????\017?+?a\024???\000\015\001??x??9??Y?\027e?ys???\031??_?9????v?Tah5?j???N??\007?r]`T)2??????L?lX\012\025?f?>?K]?T?-H%\024J\"s?\020^L=~5?Z\003?#???\008????\0195???\027\
1828??P",
1829 [ "BASE/.git/objects/82/355ac79b716e7d3fa58e47e66ca87dc72a5104" ] = "x\001+)JMU043b01\000\002???b\006??I?8;???;?8\004??g???N\004\"??_??0O???_?\022F?e????\020?)#\009?N??I-f??/??W?_v7?i?\020?\011&[L??!?\005E??E???\012?2????e\127???q??s????\000QR\\Y\\???ZY???m?^??S?{???\018F?O\000\000?`B\017",
1830 [ "BASE/apis/paintutils/overrides.lua" ] = "",
1831 [ "BASE/files/images/fileexplorer_icon_small" ] = "4444\
183211111111\
183311111111\
183411111111\
183511111111",
1836 [ "BASE/.git/objects/17/3a4d11b69b9faf472bfb25156c84a09680eb1d" ] = "x\001?Uao?0\016?W?+N|\
1837\018D\016h?1?E?4?????4UU?$\006?:v?8-???9!\004\008\029?U\004??????.?:?0?\012?\
1838\006OO\030????7??B-s`Y?=?\015\006??(Tl?V?\024???\009?[\022?\022i\0151??4@?5?_?F\023*?k??\031??\007?&?\028_??#3?E??\024\030k?0?q?5K,93~?\021I\031????N?7nr^\007\019C?*ma??\003\018}#\020?G}?????\020???\019La????\\???????*?E]?y?>s??0+??\0209??SX\031?\030\012\006???\020F`5?.?\031]????\024?\004????\011\009???H\023\004\
1839/?@?e\005\026\015???u???l?\003Ó61kdt????9\002G\018??\025q?U?!R,W??a?\030i\017\011(?\017f3*?+??ÊC?_B?\003??????\017Z\021}Y?`???V?\027f???/???C??\029?\027\
1840?9?m?i??$?Q?o??y?????!N>??}X\009???o)?????e\002D~gD??\024???\025J?\011????~?\"?9?s2tN?$??%W????%?;???\026??o???M?f?42i?)?\
1841?'?F??\031?#Y??A\
1842G??;u'??}%,??6????n\025l??@??2)?\029\007?pS\024S??\003\007\031\127???c??KC?\028+?[?j??ô5???\011c8\014_?i@EEI?a;?V[?p\011\"?$O\017?\019?v?r?Q??\028\030k?q+??*/??L??\\%\030???\024\
1843?\027?3?l???????\000'\008?\020?Nr????hW?z?U???%?\005???>???A\018?\021R~{ä?n??\026/?\020?k??a?????r??i??\031/F?TBd?V\005\000\024n\011?H&}??\\\127?????\025.\005????K???`??\\\007y\031\016N\029\0152??#?j??0?^???kj??A??j<<???? ??\004??\009?w??=k7\027&?\003???`",
1844 [ "BASE/.git/objects/87/40bcd87b6e61da4f132424fff78ac42abef2dd" ] = "x\001K??OR027bP??4\008P?A?q?U*???ih??\002V50c??Q???`???B??J?i@'??\006f\005\014+\001?\008@?",
1845 [ "BASE/files/images/default_background" ] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1846bbbbbb11111bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1847bbbbbb11111bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1848bbbbbb11111bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1849bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1850bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1851bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1852bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1853bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
1854bbbbbbbbbbbbbbbddddddddddddddddddbbbbbbbbbbbbbbbbbb\
1855bbbbbbbbbbbbdddccccccccccccccccccdddbbbbbbbbbbbbbbb\
1856bbbbbbbbbbddccccccccccccccccccccccccdddbbbbbbbbbbbb\
1857bbbbbbbbddccccccccccccccccccccccccccccddbbbbbbbbbbb\
1858bbbbbbdddcccccccccccccccccccccccccccccccdddbbbbbbbb\
1859bbbbdddcccccccccccccccccccccccccccccccccccdddbbbbbb\
1860bbbddcccccccccccccccccccccccccccccccccccccccddbbbbb\
1861bdddccccccccccccccccccccccccccccccccccccccccccddbbb\
1862ddccccccccccccccccccccccccccccccccccccccccccccccdbb\
1863dccccccccccccccccccccccccccccccccccccccccccccccccdd",
1864 [ "BASE/.git/objects/70/125c508b27c8c7e890c7f05bf18e887eaf6365" ] = "x\001uT]o?0\020??\021W?K?????\004??ih<!!m\018\015SANr?Xs??v?v????j???m??y|?3?2??????????'es.(?>6Q??66??????H??H??4\005\007zRpd?C:/\027?G?,M\147??\019>???D?\023??\"????xK?4\
1865+Z?I??k???o?e?K?\021???{\\?????5??D?ty\018?\\?H'?b?w?cM?E?\030?}??f.?9???u?\027?@?r?QaU\027?3a?hE!?\012?##u??\004?\021?WtX?g??6\
1866\028?\027\031???B?;vR^B?c?+?U??y?2??N???9)?\127?\001?5[t??$\021??Ps?K??\00135\
1867O??w?C\"?hw0?t??\
1868??y?x??9\017???J???%?)9?l??tN\023?y?\004??\005??D?\017???ex@7;?\028!\015D|w?I\
1869*\127b\031D??$??\014??\\??\003e??E??0?A\029i?c??\"?\014\007?8\
1870??\006;?h*F?=i?\017yD?t??gg\001?\022?\029???:??\003?2?id:?u??t\017?yd?i?X?7?\"?`\024?K????????N?/(?j??@???;?`c\016P`Iy?\014\019\"B\023z%?$f\006Z\023?j??X?\025,o/?pB??!=0?;?4N??P[p?n?\
1871o?n?x??5+\025?V=??\006?2Fx?y<\008\127=??vl?|???\127?b?z0?b\011??f?x\017t?6h?g?AP??\012j3???f?%\001?xd??bÙ??Ee?w?\021Z???!??????\019$??n???\127?\014?e?g\0089?U??f\005?\022?]?44??[??\023U_?{[\027?z\004??\029&w[>?=?? \025??\018????F??F?úG?!?U??H?\127-(Mi( ???|?@??F)??\031?$\025",
1872 [ "BASE/.git/objects/ab/2ccbbb888ffc308d6cc63397b6ef930cfdc3a9" ] = "x\001+)JMU045b040031QHI-?.?/`???}a???\030K??<????]?èJ?RK\018\025???\022\023??c?#??P?\005?\015?.??\027?.??(?(?(? ??$???y???-s?2??T??)UxtW?\029??$?8;)??!B??????wR?E?\024\015???Qx?\028\000?KC?",
1873 [ "BASE/.git/objects/7d/4f751c9e788f76dd61e56e943ad034b4346a5f" ] = "x\001+)JMU06f01\000\002??????b?==?~tX?`Kf??l,?[???\028\000\025?\014E",
1874 [ "BASE/system/defaults" ] = "{\
1875 primaryTextColor = 32768,\
1876 mainColor = 128,\
1877 secondaryColor = 256,\
1878 thirdColor = 1,\
1879 inverseTextColor = 1,\
1880}",
1881 [ "BASE/.git/objects/43/be26f1d5849d0e6902e47bbb4c7520e2dd2787" ] = "x\001]?Ak?0\016?{??\024?\
1882k??B/?!-KN?B{[? ?c[?VcFr?????#9]??\"$?y???;O\029|???]?\030\014\021?????\030??\024\024g?\\?3?l?\008:??????`B\0153c? MXD??\018?w??4?\004hN?B6??H??\005\016??<w<V?'k<\024\030#??/??oh[??\004\019?\030h(wU%??'\023aX?-??=?5fs(?[?h\0251TWY\022=?u?nJ??D?????M?jK?8?ur\009?\019\024????\029???\002l2\017???\009??\023??\027{??\004?0???o\019??j\
1883?W6??x\127\017?(`f?npB?Ã\024?wq????\008NJ?????A<? ?TH 0X?4M?\006x_x~?\001\025n??X???????[P1???l\021\
1884???RR?7\127\004??\023{?$??XJ?\005?????4'\025?\0165?\024j???\127?[F????R?XMze\001^'|NKr>jI?wqk??\018?I?MFHQ?????Vg\018\008??;{R?_?4??",
1885 [ "BASE/.git/objects/09/5fadeb784e62f198abbfc61d20b5453a22eba5" ] = "x\001K??OR01e??07?\000\002.\011 \005bq\0011T\004$\014\004\008\017\000=?\011\021",
1886 [ "BASE/.git/objects/24/16666d2b7ab286d9aea81f7b2e7deb59cf30b2" ] = "x\001?X?n\0277\016??+\006?H??p\0028?\003??\006P??\014P\004?QP+J\"?ZnI?m????3$?\"i?\024}??X??p8s????zFg?o?\127\024?oo?????5??????O)%?K?????$?U??2#???U??5?F/??\014?\018?\030??'atU??B?\\Z?,H/??>M??G?UkY8?.(?kU,?j]`m??Q????N_??\029?X?/UQH\003???da?p?44aS???^?ua???????????\009?U??(\024-\030???,??6???A??n??7??4U?x??~?<???\007rb?#g?s?xG?\020???,XY???\002\024HkS?Tdy\005?iQ\021\025{gI\000\007???1Z?l???$????\004\0163?8xMr?&ww?q???4\021P?\"A3ae??(KZ\024`/(??\009\005\011?[?I}.?~?eY\014y?8\025?:\0199??\0226?,?\136??Q?:\023N@??I=$\021?6J????*\005???<\031\030c?*?r??x\\?????\031'??{???U?=\011m??\017??$???!26M?i?(\011????0#?\003?P?\008>.?G\009ws;\002?|do2??????\0233??\019N?5,?+#3\023UAD-?ZR?\\.?Dv??9?sA??\001E2\024x\005V:^]z>CF\027??\024??\029?en?3;3?oS$???S8$?0?d}?W?1\028\022??0NB??L??????N?g?\003?????A???g?\019??\009j?M\
1887?1\020?\003?l\027????\006\028?28kl??I?MU!A??d?4Tx?%?>??\021????F<?]?Uw;???\009\003?\029z@\018?y;??\029?vu4???[?^`3??9L?\029?`\0073??Gi?? s???????d?d?@K?2t%?\\f??P?8??\000F\028??\029_????\005\029?Gu:58pa???C?????;?l??~??G?g9?\024??\026??:\
1888?\012.+?z:\009O?p???=?9+%!j? ?SYoX\009?2-\011????Bq?f???\127?*??\001a???s???\027?Np??>?[???5???S-\014??\005\027>p?E?6?\011\
1889?c\127Mf?\018???\"ZT?\019b??\024U?\014BY??;?9l????4?????yd\127?No?.;^?'?&??P?\025?\030?t\025??*\008c?\028LB??#L??&?xfT09?\
1890?a2???\015??\023\007(??????\016?Q*X???j6??~_<\0069?????\025r?s\030*;u!\028?\019???V???\019v6\029]s)\008?`??i?>???<?*\029?^?????\020??!+??E??^\024?~Br\021?\028chg??\024*\031¼?LZ?????M?\029?V?SaD?j?x`?h.??Q\127??/?ka:?2&??~Lå`?c[\024\030??\030'8g?rQ?{F??\\e?B??\008\007?Y?%'?>??\018\012?1?\030???k???*5:N?{??\012??_?8\014\000??E3N??@??I9|Y\008\030?\001?\
1891?^h?H???`o;?\015?\009Y<??%?d{~???\015??\015??\008?|@\008g#z\026?\006?k??U?_3\007x??=\0112?M?5n2\127f\008??N)???s????w??i?%??A\031???\004??d?_??\014?9?.?>\015\
1892??!*VH\024???n\030?1G.??U\018?b??&??{?9??\029\030<h\014\012????b?s?G??>l???`\027??IQ\011>c?O?gm\127\019??=^\015=\\????N\006????ZS?e?\127Zl????? ?\"\031??{-\031??3uw?;?Aw\000?u?d\027???????9n?\031?j??\009xXU$\004=(??\012g)\
1893??\011b6\
1894?\000??@?N?\023??\003??#?D\016*`a??\009?G????\012?????????D?`???&dW???g?\015\005\027???\017????\025\018\002n{?\007X?.??6?To\\??\009\011???\144?q????0?\029\029\
1895???K?8?N??$\011???\008?\031? ??5\007?\006?\009?????Y+?\023??w???\002???~??????_??/?h\000?",
1896 [ "BASE/core/boot/boot.lua" ] = "--[[\
1897 BASE Bootstrapper/bootloader\
1898\
1899 BASE: Copyright (C) 2016, Sam Gunner and James Hurcomb.\
1900 BASE is licensed under Creative Commons BY-NC-SA 4.0.\
1901\
1902 This file loads all important files that BASE requires, and performs any startup tasks\
1903 that are needed to be done.\
1904 When the bootloader has finished, it then hands over to the kernel.\
1905]]--\
1906\
1907-- Start variable declaration\
1908ignoreFilenames = { -- Filenames to ignore when automatically loading things.\
1909\009\".DS_Store\",\
1910}\
1911\
1912print(\"STARTING BASE BOOT PROCEDURE\")\
1913print(\"DEVELOPMENT BUILD\")\
1914_G.base = {}\
1915base.debug = {}\
1916base.debug.taskbarIsActive = false\
1917\
1918function table.contains(tbl, data)\
1919\009for k, v in pairs(tbl) do\
1920\009\009if v == data then\
1921\009\009\009return true\
1922\009\009end\
1923\009end\
1924\009return false\
1925end\
1926\
1927local tAPIsLoading = {}\
1928function loadAPIAs(_sPath, name)\
1929\009local sName = fs.getName( _sPath )\
1930\009if tAPIsLoading[sName] == true then\
1931\009printError( \"API \"..sName..\" is already being loaded\" )\
1932\009return false\
1933\009end\
1934\009tAPIsLoading[sName] = true\
1935\
1936\009local tEnv = {}\
1937\009setmetatable( tEnv, { __index = _G } )\
1938\009local fnAPI, err = loadfile( _sPath )\
1939\009if fnAPI then\
1940\009setfenv( fnAPI, tEnv )\
1941\009fnAPI()\
1942\009else\
1943\009printError( err )\
1944\009tAPIsLoading[sName] = nil\
1945\009return false\
1946\009end\
1947\
1948\009local tAPI = {}\
1949\009for k,v in pairs( tEnv ) do\
1950\009tAPI[k] = v\
1951\009end\
1952\
1953\009_G.base[name] = tAPI\
1954\009tAPIsLoading[sName] = nil\
1955\009return true\
1956end\
1957\
1958local function printDebug(process, text)\
1959\009term.setBackgroundColor(colors.gray)\
1960\009term.setTextColor(colors.white)\
1961\009write(\"[\" .. process .. \"]\")\
1962\009term.setBackgroundColor(colors.black)\
1963\009term.setTextColor(colors.white)\
1964\009print(\" \" .. text)\
1965end\
1966\
1967local function printLoadError(process, text)\
1968\009term.setBackgroundColor(colors.gray)\
1969\009term.setTextColor(colors.white)\
1970\009write(\"[\" .. process .. \"]\")\
1971\009term.setBackgroundColor(colors.red)\
1972\009term.setTextColor(colors.white)\
1973\009print(\" \" .. text)\
1974end\
1975\
1976local function printOkay(process, text)\
1977\009term.setBackgroundColor(colors.gray)\
1978\009term.setTextColor(colors.white)\
1979\009write(\"[\" .. process .. \"]\")\
1980\009term.setBackgroundColor(colors.black)\
1981\009term.setTextColor(colors.green)\
1982\009print(\" \" .. text)\
1983end\
1984\
1985local function checkIfFile(path)\
1986 if fs.exists(path) and not fs.isDir(path) then\
1987 \009return true\
1988 end\
1989end\
1990\
1991local folders = {\
1992\009\"BASE\",\
1993\009\"BASE/core\",\
1994\009\"BASE/apis\",\
1995\009\"BASE/files\",\
1996\009\"BASE/programs\",\
1997\009\"BASE/programs/special\",\
1998\009\"BASE/users\",\
1999\009\"BASE/system/program_files\",\
2000}\
2001\
2002local files = {\
2003\009\"BASE/apis/kernel\",\
2004\009\"BASE/apis/gui\",\
2005\009\"BASE/apis/io\",\
2006\009\"BASE/apis/system\",\
2007\009\"BASE/apis/text\",\
2008\009\"BASE/apis/window\",\
2009\009\"BASE/apis/app_names\", -- Aliases for apps so that they show up on the taskbar correctly.\
2010\009\"BASE/apis/baseforms\",\
2011\009\"BASE/apis/sha256\",\
2012\009\"BASE/core/user_login_menu.lua\"\
2013}\
2014\
2015-- End variable declaration and begin: file checking, loading.\
2016printDebug(\"Boot\", \"Started boot process successfully\")\
2017\
2018for i = 1, #folders do -- Check that essential folders are present\
2019\009if fs.isDir(folders[i]) then\
2020\009\009printDebug(\"File Check\", \"Found \" .. folders[i])\
2021\009else\
2022\009\009printLoadError(\"File Check\", \"Could not find (fo) \" .. folders[i])\
2023\009end\
2024end\
2025\
2026for i = 1, #files do -- Check that essential files are present\
2027\009if checkIfFile(files[i]) then\
2028\009\009printDebug(\"File Check\", \"Found \" .. files[i])\
2029\009else\
2030\009\009printLoadError(\"File Check\", \"Could not find (fi) \" .. files[i])\
2031\009end\
2032end\
2033\
2034term.setBackgroundColor(colors.black) -- Reset background color\
2035\
2036local apiList = fs.list(\"BASE/apis\") -- List all APIs in /apis and load all in there as base.<apiname>\
2037for i = 1, #apiList do\
2038\009if not table.contains(ignoreFilenames, apiList[i]) then\
2039\009\009local h = fs.open(fs.combine(\"BASE/apis\", apiList[i]), \"r\")\
2040\009\009local data = h.readAll()\
2041\009\009h.close()\
2042\009 \009loadAPIAs(fs.combine(\"BASE/apis\", apiList[i]), apiList[i])\
2043\009 \009printOkay(\"base.\" .. apiList[i], \"OK\")\
2044\009end\
2045end\
2046\
2047base.system.init()\
2048\
2049-- Load all images in /files/images\
2050local imgList = fs.list(\"BASE/files/images\")\
2051base.images = {}\
2052for i = 1, #imgList do\
2053\009if not table.contains(ignoreFilenames, imgList[i]) then\
2054\009\009local img = paintutils.loadImage(fs.combine(\"BASE/files/images\", imgList[i]))\
2055\009\009print(imgList[i])\
2056\009\009base.images[imgList[i]] = img\
2057\009end\
2058end\
2059base.images.icons = {}\
2060\
2061imgList = fs.list(\"BASE/programs/icons\")\
2062for i = 1, #imgList do\
2063\009if not table.contains(ignoreFilenames, imgList[i]) then\
2064\009\009local img = paintutils.loadImage(fs.combine(\"BASE/programs/icons\", imgList[i]))\
2065\009\009print(imgList[i])\
2066\009\009base.images.icons[imgList[i]] = img\
2067\009end\
2068end\
2069printDebug(\"base.images\", \"All loaded successfully\")\
2070\
2071printOkay(\"Boot Process\", \"OK\") -- Announces that the main boot process has finished successfully\
2072sleep(.5)\
2073\
2074shell.run(\"/BASE/core/user_login_temp.lua\")\
2075\
2076term.setBackgroundColor(colors.white)\
2077term.clear()\
2078term.setTextColor(colors.black)\
2079base.text.ctxt(\"Welcome to BASE 2!\", 8)\
2080sleep(2)\
2081\
2082local oldRead = read\
2083read = function(replacement)\
2084\009base.kernel.activateCursorBlink()\
2085\009local text = oldRead(replacement)\
2086\009base.kernel.deactivateCursorBlink()\
2087\009return text\
2088end\
2089\
2090local returnValue, errorMessage = base.kernel.main() -- Starts the BASE kernel boot process\
2091-- If base returns -1 here, it signifies that a serious error has occured within the kernel.\
2092if returnValue == -1 then -- Kernel error\
2093\009term.setBackgroundColor(colors.white)\
2094\009term.clear()\
2095\009term.setTextColor(colors.black)\
2096\009base.text.ctxt(\"Uh oh, look's like something's gone wrong\", 8)\
2097\009base.text.ctxt(\"Error message:\", 10)\
2098\009base.text.ctxt(errorMessage, 12)\
2099\009base.text.ctxt(\"Rebooting in 3...\", 18)\
2100\009sleep(1)\
2101\009base.text.ctxt(\"Rebooting in 2...\", 18)\
2102\009sleep(1)\
2103\009base.text.ctxt(\"Rebooting in 1...\", 18)\
2104\009sleep(1)\
2105\009os.reboot()\
2106elseif returnValue == 1 then -- Standard shutdown\
2107\009os.shutdown()\
2108elseif returnValue == 2 then -- Standard reboot\
2109\009os.reboot()\
2110end",
2111 [ "BASE/.git/HEAD" ] = "ref: refs/heads/master",
2112 [ "BASE/programs/special/taskbar" ] = "--[[\
2113\009BASE taskbar process. This handles any mouse events that are sent to the taskbar\
2114\009It also handle redrawing the taskbar, as well as displaying currently open items.\
2115]]--\
2116\
2117currentTaskbarPos = 1\
2118inverseBackgroundColor = colors.gray\
2119programBackgroundColor = colors.lightGray\
2120backgroundColor = colors.white\
2121toResume = \"\"\
2122log = base.log.new(\"/BASE/logs/taskbar.txt\")\
2123log:clear()\
2124\
2125-- Launch the notifications menu and present notifications to the user\
2126local function notificationMenu()\
2127\009local pos = 1\
2128\009local currentWin = term.current()\
2129\009local topWin = window.create(currentWin, 1, 1, 51, 3)\
2130\009local bottomWin = window.create(currentWin, 1, 4, 51, 15)\
2131\009local notifications\
2132\009local obj\
2133\009local ll\
2134\
2135\009local function drawMain()\
2136\009\009term.setTextColor(colors.white)\
2137\009\009term.redirect(topWin)\
2138\009\009base.gui.flash(colors.gray)\
2139\009\009base.gui.drawStandardHeader(\"Notification Center\")\
2140\009\009term.setTextColor(colors.lightGray)\
2141\009\009base.text.ptxt(\"<-\", 1, 1)\
2142\
2143\009\009term.redirect(bottomWin)\
2144\009\009base.gui.flash(colors.gray)\
2145\
2146\009\009notifications = base.notifications.getNotifications()\
2147\
2148\009\009for i = pos, pos + 5 do\
2149\009\009\009if #notifications >= i then\
2150\009\009\009\009term.setTextColor(colors.black)\
2151\
2152\009\009\009\009if i % 2 == 0 then\
2153\009\009\009\009\009paintutils.drawLine(2, i * 2 - 1, 50, i * 2 - 1, colors.lightGray)\
2154\009\009\009\009\009paintutils.drawLine(2, i * 2, 50, i * 2, colors.lightGray)\
2155\009\009\009\009else\
2156\009\009\009\009\009paintutils.drawLine(2, i * 2 - 1, 50, i * 2 - 1, colors.white)\
2157\009\009\009\009\009paintutils.drawLine(2, i * 2, 50, i * 2, colors.white)\
2158\009\009\009\009end\
2159\
2160\009\009\009\009base.text.ctxt(notifications[i]:getAppName(), i * 2 - 1)\
2161\009\009\009\009base.text.ctxt(notifications[i]:getText(), i * 2)\
2162\
2163\009\009\009\009term.setTextColor(colors.red)\
2164\009\009\009\009base.text.ptxt(\"x\", 50, i * 2 - 1)\
2165\009\009\009end\
2166\009\009end\
2167\
2168\009\009term.redirect(currentWin)\
2169\009end\
2170\
2171\009while true do\
2172\009\009drawMain()\
2173\009\009local evt, b, x, y = os.pullEvent(\"mouse_click\")\
2174\009\009if evt == \"mouse_click\" then\
2175\009\009\009local notification_id = math.ceil((y + 1) / 2 - pos - 1)\
2176\
2177\009\009\009if b == 1 and x == 51 and y == 1 then\
2178\009\009\009\009return 1\
2179\
2180\009\009\009elseif b == 1 and x >= 1 and x <= 51 and y == 19 then\
2181\009\009\009\009return 1\
2182\
2183\009\009\009elseif b == 1 and x == 50 then\
2184\009\009\009\009y = (y - 3)\
2185\009\009\009\009if y % 2 == 1 then\
2186\009\009\009\009\009base.notifications.removeNotification(notification_id)\
2187\009\009\009\009end\
2188\
2189\009\009\009elseif b == 1 and x >= 1 and x <= 2 and y == 1 then\
2190\009\009\009\009return\
2191\
2192\009\009\009elseif b == 1 and x ~= 50 and x >= 2 and x<= 50 then\
2193\009\009\009\009obj = base.notifications.getNotification(notification_id)\
2194\009\009\009\009if obj ~= nil and obj:getAppID() ~= \"\" then\
2195\009\009\009\009\009toResume = obj:getAppID()\
2196\009\009\009\009\009base.notifications.removeNotification(notification_id)\
2197\009\009\009\009\009return 1\
2198\009\009\009\009end\
2199\009\009\009end\
2200\009\009end\
2201\009end\
2202end\
2203\
2204-- Launch the start menu and present options to user\
2205local function startMenu()\
2206\009-- Local redraw all function\
2207\009local function drawMain()\
2208\009\009term.setBackgroundColor(colors.white)\
2209\009\009term.clear()\
2210\009\009term.setTextColor(base.system.systemVariables.inverseTextColor)\
2211\009\009paintutils.drawLine(1, 1, 51, 1, colors.gray)\
2212\009\009base.text.ctxt(\"What would you like to do?\", 1)\
2213\009\009term.setTextColor(colors.red)\
2214\009\009base.text.ptxt(\"x\", 51, 1)\
2215\009\009term.setTextColor(colors.black)\
2216\009\009\
2217\009\009for i = 3, 5 do\
2218\009\009\009paintutils.drawLine(3, i, 49, i, base.system.systemVariables.secondaryColor)\
2219\009\009end\
2220\009\009\
2221\009\009for i = 7, 9 do\
2222\009\009\009paintutils.drawLine(3, i, 49, i, base.system.systemVariables.secondaryColor)\
2223\009\009end\
2224\009\009\
2225\009\009for i = 11, 13 do\
2226\009\009\009paintutils.drawLine(3, i, 49, i, base.system.systemVariables.secondaryColor)\
2227\009\009end\
2228\009\009\
2229\009\009for i = 15, 17 do\
2230\009\009\009paintutils.drawLine(3, i, 23, i, base.system.systemVariables.secondaryColor)\
2231\009\009\009paintutils.drawLine(27, i, 49, i, base.system.systemVariables.secondaryColor)\
2232\009\009end\
2233\009\009\
2234\009\009base.text.ctxt(\"Reboot\", 4)\
2235\009\009base.text.ctxt(\"Shutdown\", 8)\
2236\009\009base.text.ctxt(\"Log out\", 12)\
2237\009\009base.text.ctxtAdvanced(\"Settings\", 3, 16, 23)\
2238\009\009base.text.ctxtAdvanced(\"Notifications\", 26, 16, 50)\
2239\009\009mainRedraw()\
2240\009\009term.setTextColor(colors.white)\
2241\009\009term.setBackgroundColor(colors.green)\
2242\009\009base.text.ptxt(\"\\31\", 2, 19)\
2243\009end\
2244\009\
2245\009while true do\
2246\009\009drawMain()\
2247\009\009local evt, b, x, y = coroutine.yield()\
2248\009\009if evt == \"mouse_click\" then\
2249\009\009\009\
2250\009\009\009if b == 1 and x >= 3 and x<= 49 and y>=2 and y<=4 then\
2251\009\009\009\009os.pullEvent()\
2252\009\009\009\009--[[local conf = base.gui.getBoolean(\"Are you sure you want to do that?\", \"Reboot?\")\
2253\009\009\009\009if conf then\
2254\009\009\009\009\009os.reboot()\
2255\009\009\009\009end]]--\
2256\009\009\009\009os.reboot()\
2257\009\009\009\009\
2258\009\009\009elseif b == 1 and x>= 3 and x<=49 and y>=7 and y<=9 then\
2259\009\009\009\009os.pullEvent()\
2260\009\009\009\009local conf = base.gui.getBoolean(\"Are you sure you want to do that?\", \"Shutdown?\")\
2261\009\009\009\009if conf then os.shutdown() end\
2262\009\009\009\009\
2263\009\009\009elseif b == 1 and x >= 3 and x <= 23 and y>=15 and y<=17 then\
2264\009\009\009\009base.debug.taskbarIsActive = false\
2265\009\009\009\009base.system.launchProgramForeground(\"BASE/programs/base_settings\")\
2266\009\009\009\009break\
2267\
2268\009\009\009elseif b == 1 and x >= 3 and x >= 27 and x <= 49 and y >= 15 and y <= 17 then\
2269\009\009\009\009local returnValue = notificationMenu()\
2270\009\009\009\009if returnValue == 1 then\
2271\009\009\009\009\009return\
2272\009\009\009\009end\
2273\009\009\009\009\
2274\009\009\009elseif (b == 1 and x >= 1 and x<=3 and y==19) or (x == 51 and y == 1)then\
2275\009\009\009\009base.debug.taskbarIsActive = false\
2276\009\009\009\009break\
2277\009\009\009end\
2278\009\009end\
2279\009end\
2280end\
2281\
2282-- Main redraw function for the whole of the taskbar\
2283function mainRedraw()\
2284\009term.setTextColor(colors.black)\
2285\009openApps = base.kernel.getOpenApps()\
2286\009paintutils.drawLine(1, 19, 51, 19, colors.white)\
2287\009if currentTaskbarPos > 1 then\
2288\009\009base.text.ptxt(\"\\27\", 4, 19)\
2289\009end\
2290\009if currentTaskbarPos + 2 < #openApps then\
2291\009\009base.text.ptxt(\"\\26\", 51, 19)\
2292\009end\
2293\009base.text.ptxt(\"\\25\", 5, 19)\
2294\009paintutils.drawLine(1, 19, 3, 19, colors.green)\
2295\
2296\009-- If a notification exists, then display an exclamation mark\
2297\009if base.notifications.notificationExists() then\
2298\009\009term.setTextColor(colors.red)\
2299\009\009base.text.ptxt(\"!\", 2, 19)\
2300\
2301\009--Otherwise, draw the usual symbol\
2302\009else\
2303\009\009term.setTextColor(colors.white)\
2304\009\009base.text.ptxt(\"\\30\", 2, 19)\
2305\009end\
2306\
2307\009if #openApps >= 1 then\
2308\009\009paintutils.drawLine(7, 19, 19, 19, colors.lightGray)\
2309\009\009term.setTextColor(colors.black)\
2310\009\009base.text.ptxt(string.sub(openApps[currentTaskbarPos].name, 1, 11), 7, 19)\
2311\009\009term.setTextColor(colors.red)\
2312\009\009base.text.ptxt(\"x\", 19, 19)\
2313\009end\
2314\
2315\009if #openApps >= 2 then\
2316\009\009paintutils.drawLine(22, 19, 34, 19, colors.lightGray)\
2317\009\009term.setTextColor(colors.black)\
2318\009\009base.text.ptxt(string.sub(openApps[currentTaskbarPos + 1].name, 1, 11), 22, 19)\
2319\009\009term.setTextColor(colors.red)\
2320\009\009base.text.ptxt(\"x\", 34, 19)\
2321\009end\
2322\
2323\009if #openApps >= 3 then\
2324\009\009paintutils.drawLine(37, 19, 49, 19, colors.lightGray)\
2325\009\009term.setTextColor(colors.black)\
2326\009\009base.text.ptxt(string.sub(openApps[currentTaskbarPos + 2].name, 1, 11), 37, 19)\
2327\009\009term.setTextColor(colors.red)\
2328\009\009base.text.ptxt(\"x\", 49, 19)\
2329\009end\
2330end\
2331\
2332-- Main cycle for the taskbar\
2333function mainSeq()\
2334\009local event, var1, var2, var3 = coroutine.yield()\
2335\009if event == \"mouse_click\" then\
2336\009\009if var1 == 1 and var2 == 5 then\
2337\009\009\009base.kernel.bringToFront(\"desktop\")\
2338\009\009\009base.debug.taskbarIsActive = true\
2339\009\009\009term.setTextColor(colors.white)\
2340\009\009\009paintutils.drawPixel(5, 19, colors.gray)\
2341\009\009\009base.text.ptxt(\"\\25\", 5, 19)\
2342\009\009\009sleep(.2)\
2343\009\009\009base.debug.taskbarIsActive = false\
2344\
2345\009\009elseif var1 == 1 and var2 >= 7 and var2 <= 17 then\
2346\009\009\009if openApps[currentTaskbarPos] ~= nil then\
2347\009\009\009\009base.debug.taskbarIsActive = true\
2348\009\009\009\009paintutils.drawLine(7, 19, 19, 19, colors.gray)\
2349\009\009\009\009term.setTextColor(colors.white)\
2350\009\009\009\009base.text.ptxt(string.sub(openApps[currentTaskbarPos].name, 1, 11), 7, 19)\
2351\009\009\009\009term.setTextColor(colors.red)\
2352\009\009\009\009base.text.ptxt(\"x\", 19, 19)\
2353\009\009\009\009sleep(.2)\
2354\009\009\009\009base.debug.taskbarIsActive = false\
2355\009\009\009\009if (not base.kernel.taskIsDead(openApps[currentTaskbarPos].id)) then -- Check that the app has not finished executing before resuming it\
2356\009\009\009\009\009base.kernel.bringToFront(openApps[currentTaskbarPos].id)\
2357\009\009\009\009else\
2358\009\009\009\009\009base.kernel.launchErrorReporter(\"'\" .. openApps[currentTaskbarPos].name .. \"' has crashed.\", openApps[currentTaskbarPos].id)\
2359\009\009\009\009\009return 1\
2360\009\009\009\009end\
2361\009\009\009end\
2362\
2363\009\009elseif var1 == 1 and var2 == 19 then\
2364\009\009\009if openApps[currentTaskbarPos] ~= nil then\
2365\009\009\009\009base.kernel.killTask(openApps[currentTaskbarPos].id)\
2366\009\009\009\009base.kernel.bringToFront(\"desktop\")\
2367\009\009\009end\
2368\
2369\009\009elseif var1 == 1 and var2 >= 22 and var2 <= 32 then\
2370\009\009\009if openApps[currentTaskbarPos + 1] ~= nil then\
2371\009\009\009\009base.debug.taskbarIsActive = true\
2372\009\009\009\009paintutils.drawLine(22, 19, 34, 19, colors.gray)\
2373\009\009\009\009term.setTextColor(colors.white)\
2374\009\009\009\009base.text.ptxt(string.sub(openApps[currentTaskbarPos + 1].name, 1, 11), 22, 19)\
2375\009\009\009\009term.setTextColor(colors.red)\
2376\009\009\009\009base.text.ptxt(\"x\", 34, 19)\
2377\009\009\009\009sleep(.2)\
2378\009\009\009\009base.debug.taskbarIsActive = false\
2379\009\009\009\009if (not base.kernel.taskIsDead(openApps[currentTaskbarPos + 1].id)) then -- Check that the app has not finished executing before resuming it\
2380\009\009\009\009\009base.kernel.bringToFront(openApps[currentTaskbarPos + 1].id)\
2381\009\009\009\009else\
2382\009\009\009\009\009base.kernel.launchErrorReporter(openApps[currentTaskbarPos + 1].name .. \" has crashed.\", openApps[currentTaskbarPos + 1].id)\
2383\009\009\009\009\009return 1\
2384\009\009\009\009end\
2385\009\009\009end\
2386\
2387\009\009elseif var1 == 1 and var2 == 34 then\
2388\009\009\009if openApps[currentTaskbarPos + 1] ~= nil then\
2389\009\009\009\009base.kernel.killTask(openApps[currentTaskbarPos + 1].id)\
2390\009\009\009\009base.kernel.bringToFront(\"desktop\")\
2391\009\009\009end\
2392\
2393\009\009elseif var1 == 1 and var2 >= 37 and var2 <= 47 then\
2394\009\009\009if openApps[currentTaskbarPos + 2] ~= nil then\
2395\009\009\009\009base.debug.taskbarIsActive = true\
2396\009\009\009\009paintutils.drawLine(37, 19, 49, 19, colors.gray)\
2397\009\009\009\009term.setTextColor(colors.white)\
2398\009\009\009\009base.text.ptxt(string.sub(openApps[currentTaskbarPos + 2].name, 1, 11), 37, 19)\
2399\009\009\009\009term.setTextColor(colors.red)\
2400\009\009\009\009base.text.ptxt(\"x\", 49, 19)\
2401\009\009\009\009sleep(.2)\
2402\009\009\009\009base.debug.taskbarIsActive = false\
2403\009\009\009\009if (not base.kernel.taskIsDead(openApps[currentTaskbarPos + 2].id)) then -- Check that the app has not finished executing before resuming it\
2404\009\009\009\009\009base.kernel.bringToFront(openApps[currentTaskbarPos + 2].id)\
2405\009\009\009\009else\
2406\009\009\009\009\009base.kernel.launchErrorReporter(openApps[currentTaskbarPos + 2].name .. \" has crashed.\", openApps[currentTaskbarPos + 2].id)\
2407\009\009\009\009\009return 1\
2408\009\009\009\009end\
2409\009\009\009end\
2410\
2411\009\009elseif var1 == 1 and var2 == 49 then\
2412\009\009\009if openApps[currentTaskbarPos + 2] ~= nil then\
2413\009\009\009\009base.kernel.killTask(openApps[currentTaskbarPos + 2].id)\
2414\009\009\009\009base.kernel.bringToFront(\"desktop\")\
2415\009\009\009end\
2416\
2417\009\009elseif var1 == 1 and var2 == 51 then\
2418\009\009\009if currentTaskbarPos + 2 < #openApps then\
2419\009\009\009\009base.debug.taskbarIsActive = true\
2420\009\009\009\009paintutils.drawPixel(51, 19, colors.gray)\
2421\009\009\009\009term.setTextColor(colors.white)\
2422\009\009\009\009base.text.ptxt(\"\\26\", 51, 19)\
2423\009\009\009\009sleep(.2)\
2424\009\009\009\009base.debug.taskbarIsActive = false\
2425\009\009\009\009currentTaskbarPos = currentTaskbarPos + 1\
2426\009\009\009end\
2427\
2428\009\009elseif var1 == 1 and var2 == 4 then\
2429\009\009\009if currentTaskbarPos > 1 then\
2430\009\009\009\009base.debug.taskbarIsActive = true\
2431\009\009\009\009paintutils.drawPixel(4, 19, colors.gray)\
2432\009\009\009\009term.setTextColor(colors.white)\
2433\009\009\009\009base.text.ptxt(\"\\27\", 4, 19)\
2434\009\009\009\009sleep(.2)\
2435\009\009\009\009base.debug.taskbarIsActive = false\
2436\009\009\009\009currentTaskbarPos = currentTaskbarPos - 1\
2437\009\009\009end\
2438\
2439\009\009elseif var1 == 1 and var2 >= 1 and var2 <= 3 and var3 == 19 then\
2440\009\009\009base.debug.taskbarIsActive = true\
2441\009\009\009startMenu()\
2442\009\009\009mainRedraw()\
2443\009\009\009base.debug.taskbarIsActive = false\
2444\009\009\009log:log(\"Attempting to maximise desktop\")\
2445\009\009\009if toResume ~= \"\" and base.kernel.taskExists(toResume) then\
2446\009\009\009\009local current = toResume\
2447\009\009\009\009toResume = \"\"\
2448\009\009\009\009base.kernel.bringToFront(current)\
2449\009\009\009else\
2450\009\009\009\009log:log(\"Attempting to maximise desktop\")\
2451\009\009\009\009base.kernel.bringToFront(\"desktop\")\
2452\009\009\009end\
2453\009\009\009\
2454\009\009elseif var1 == 2 then -- The taskbar has been right-clicked, now we need to launch a context menu from the GUI API\
2455\009\009\009base.debug.taskbarIsActive = true\
2456\009\009\009local opt = base.gui.dropdown(var2, var3 + 1, {\"Task Manager\", \"Console\"})\
2457\009\009\009if opt == 1 then\
2458\009\009\009\009base.kernel.newTaskFromPath(\"BASE/programs/task_manager\")\
2459\009\009\009elseif opt == 2 then\
2460\009\009\009\009base.kernel.newTaskFromPath(\"BASE/programs/console\")\
2461\009\009\009end\
2462\009\009\009base.debug.taskbarIsActive = false\
2463\009\009\009base.kernel.bringToFront(\"desktop\")\
2464\009\009end\
2465\009end\
2466end\
2467\
2468-- Main event loop\
2469function main()\
2470\009local ok, err\
2471\
2472\009while true do\
2473\009\009mainRedraw()\
2474\009\009mainSeq()\
2475\009end\
2476end\
2477\
2478local ok, err = pcall(main)\
2479if not ok then\
2480 --base.kernel.launchErrorReporter(\"Taskbar has crashed. Operating system needs to reboot\")\009\
2481 error(err)\
2482end",
2483 [ "BASE/.git/objects/6f/c0f7a16091d348a4ce7de9c2b088e611dd31c3" ] = "x\001??AO?0\012??v???HU?28???\"q?????f????@??I???;\007G??????5<>??[C\008N<BÛ??EwP??\008??92?d:??\016l?o?\007N??8?9\\\000M?$[??y?bYNl?2?2\012F1???7??]z\019?i\012i(+?W?,\016kEp??a??\
2484{`[?????h??x?dt\023\
2485?gd?P?kq?$I??71?dq!\030\022b??.\007?\004?ZY,??:?\011R~??I?\"?\127\009K??????j;????u???\"L<\014?f\019?\007?C??",
2486 [ "BASE/programs/update_centre" ] = "--[[\
2487 Update Centre for BASE.\
2488 A utility to check for and install official updates released by the dev team.\
2489\
2490 Copyright (C) Sam Gunner, 2016.\
2491 Licensed under Creative Commns BY-NC-SA 4.0\
2492]]--\
2493\
2494\
2495--[[\
2496function checkForUpdates()\
2497 local serverResponse = http.get(base.system.updateAdress, \"op=getUpdateDetails\")\
2498 if serverResponse ~= nil then\
2499 local data = serverResponse.readAll()\
2500 data = base.text.unserialise(data)\
2501 if data[1] ~= false then\
2502 if data.version >= base.system.systemVariables.version then -- The update is a more recent build of the OS.\
2503\
2504 end\
2505 end\
2506 end\
2507end\
2508\
2509]]--",
2510 [ "BASE/programs/icons/console" ] = "fffffffff\
2511f0fffffff\
2512ff0ffffff\
2513f0ff000ff\
2514fffffffff",
2515 [ "/startup" ] = "shell.run(\"BASE/core/boot/bootstrap.lua\")",
2516 [ "BASE/.git/objects/80/709a5555a9f44af46f462485e3f63da6092771" ] = "x\001?Zm??\017?????!\031$ö???k\017o??\027?^???z? \
2517\014????E?\012I??\022?o?3\028?\"%?Ip?\002?%?\028?\012g?y?fY1\019????????\020b*??(??`0?L???U?'?\\??i&??*+JY??/???\"\023qt,&\019???X????\022?89???d)^??\\?z??b-??N?r?Vu???\020I?\016?b?^?D}?Vc?T\"+?+???\029V]?????Z?\005&JQ`?4O2\026N????\022?JLHr??\030\011??^\016i)VeqU&?\031????:??$?\"M??mXo??@?KPJ???\">\017?\002\003B??4??u?U?L6???\012?E:\022?\030??y\001?T\017???\023??o\021??\024?\030?\031?js????\\F??\127???\025Q\012??Y????9x$>??n?v?\007?i\011\018?t,?\020???\027??oIV???q(\022??y\029\018\011??^????x?I?E????P??\026g\023\014?\002??1?9???????s??h?q??\028R_??:_x???5?dR*V?????(/?*?f?F\007\021k??\005?Na???iY?\014??R??\018?\\a??\014?1&??yYdY\008c?`??\005??v2????m?N? v?j~???T?X??JR?\029?\031]?3+1j?lQ???K??~3?j?\127?????b?X??eE?????\127?\008???\026?b?_h??K]? ?t*?4??*]H\012?fd??????es%\000??7/k?J\016?r??hv?Kg?)??(Oh?#R?\000JiVnX?W??b????F^O??vG??AW\003_{,?X?\023:\012?dY?A??yisZ????'??|V?et??????NmLN???t\007\018-\008(H\012??$&6>\005Q??\022E\001?f;' \00580???\0060zz?\"?\
2518??n??h??????t????b?\001f\020W_??r[\
2519Yn??\020\020!?\000?\016?\003???Z=?3???&0??u\009?%???gY:?$\016E\019A@????0B???EU'e-\023???\018?U\018l]VQZ=O?\016\023?b9???h\000<??\014?m^?(jW8?0MY???\"????Lc\016I???$F\012???\016???v\005|??\031??~?y?$!\031???e&k+??-/?o??\021??T????i???L*\004Q<\001_P~??5R\016s???V\003?1[\
2520h\012dd??\127I\000!\014\0236?\0147\007?Y\025?^H??r????\\?YH?????@MW\029\001M??\008D\020?J-?E ?vNF???q?v\014?1?????\030??????p\009r,\022Gj$Ql??yH8\011??C\
2521?z?;IiI?\022XF\\&?LFHv?P\017S?;cD???&\008??????1?t\017??\\??u??T????+?\011Z\031?D?u?\019PI?A\0024?M???\030???X?=e\024cA???&c'?S?bG?_N9\020?\029\009q\016x?\"?;?oVx\008u?\019\025\018?v??R`?:\002\005cM\029i\028`?y?\018?@\024|??-?2C?????,>?g\030\012\007GG?8?9???\005J???\006?.(?n?7??F??p?Gi???\023??B??\025??|?69\018=n\
2522???5T=\001??#?<?\011\021l??Xl?b?¢^_^?C¢gd?1??rx5?=????>????\020C6??,Z???(?\018?k????r-?\
2523??ll\005??????jw6=?'???K?AA??0?M??Jj?\018&?????Qr6u???\000IL?G\003^???<wwwQ??7k&?\026?\004\018y?q5???A??h?A?G,?_{????\002\028>??Y\002?w?9?\027\020????l'??zcV?F?Oo\016&G?G}\005[??\009???Gb???/5?E\026\030Q??U?^J\021 ?wA#?Q\008??]L?\015?c\016?P??FNMY?G|X??\001??F?O??(?lS?=??y??Z_??5?\027?3??~???9F?DU????M\005?\014?????L?a??1??g?J\023??*)Q~?,?$i??(??pN??X(\016q?????8i?H\029?\029.???O?\023T?@?f?\001???Lk??O???\011\002{v4n ???w??i??\019?f ;??Gm???{\015?i)U;?Z?M??,?\
2524?????Be??+??B?nk#1??\\?R?z??|/+\016E#1???EG}?\030??E*sm??7?b?M?M?@?.r\014\"0???V?,{?Zz??XW?7eV??\025??%\004>??`C???0\007\"j??!>???\003eq??}6?*??~+????#??\022H\014Vj\026??\
2525u?\014?\007?H??|\006\017?\020\019?P7?h?w??~?i?%m\002>??:??e?E?:?Y?\022nI?\014?6?\002??????`4h1?#????-\008N?>?;??\
2526\004?????\031??Hc?\
2527?;??\014??|d??/~wh?\015? 4?\011\011??{??^gt?\003??>??\012?Ma??/??}A?l? ??s\003?&eV?\026=T???6\008?n?9????jX?\009??S?(??k??C?i\
25284??z?\020S\006U?\018W????@E3s??S?d????\028\029N?7??$\027??6?B??\014iQ5????\009K\003\015'i?;?q\017???kEA?_\\#?B?'?c?K?e?|\028O\\?!???r???\021??h??5?3g?L?@;?\019e??X\004\027?!!???\
2529/\011o???v\018??\026A?????YG?v4#?{$?e?I?I???'?o?#Oi?\003\029#?-?S???$?t?\027?????(\025???7|?7'\028??R\002#?+\004??\008?????1\006f\030?T??y?V?`?H5g{y\031Q??\0271????!)-?l\\?K-???D$%?N&|??T?\031?a\028???V?????t?i-?w???\020?5??_\022????n8??t?\0313???cP\002\027????\008\001GC?Z8w&0+?/?u&M'W'?S]^;H?f?,\009??g???)\014?T\014\
2530?CcY*???\028\127n???:V\\`\007?_\004g?\015???;?s\011???;\029l$\023?1??!?\030\027O#ng\003?H\015?w?vn??c?\026?=\015???P??\009?AR?\\p?\005?m?? w????D??\001E???\
2531I?#z ?\006\007bW??!W?z??\019\154??\031?:?Tmv?k??\
2532W}H?\004c?n?0[??ycCb??-\030?????p\018??R\\?=\027?h?e?/?gc?e?\
2533\023??f?W\016Y?#\"\022Q??D>*0????\029\006?^9?????U1??c????R?????$?i?R?o?(\030\012??{JB]??Y??3K:U??6nZPD\022?e???\027|m?z\017?^?V???\016\000<(?\
2534_NA}??\011???d????\026?$?'?\005??\030?2B;/YT~C??o??j\000Y??v*??\030/\006\007?Kv????????:?5?G?\009??#W????i?#\0000 N?\012?:????\029\023?&\025??dZD??>?-??o?iS$\"pQ?ys?Vc?9$?&??H\015?????{????????8?_?????ya????V?\
2535?\020iw??\0036???*u_?&[???k???#????\001?Y?",
2536 [ "BASE/programs/icons/task_manager" ] = "885888888\
2537858588888\
2538588858885\
2539888885858\
2540888888588",
2541 [ "BASE/programs/special/desktop_beta" ] = "--[[\
2542\009BASE 2 Default Desktop. This can be easily replaced with a custom one if you wish, just follow the same format.\
2543\009Copyright (C) Sam Gunner, 2017\
2544\009Licensed under Creative Commons BY-NC-SA 4.0\
2545\
2546\009Planned features:\
2547\009- Context menus when you right click on certain areas of the desktop.\
2548\009- Multiple pages of apps that can be displayed.\
2549\009- \
2550]]--\
2551\
2552while true do\
2553\
2554\009--term.setBackgroundColor(base.system.systemVariables.secondaryColor)\
2555\009--term.clear()\
2556\009paintutils.drawImage(base.images.default_background, 1, 1)\
2557-- Get the programs into a list\
2558\
2559\009local tmpList = fs.list(\"BASE/programs\")\
2560\009local displayedList = {}\
2561\009local progList = {}\
2562\
2563\009for k, v in pairs(tmpList) do\
2564\009\009if not fs.isDir(fs.combine(\"BASE/programs\", v)) and v ~= \".DS_Store\" then\
2565\009\009\009progList[k] = v\
2566\009\009end\
2567\009end\
2568\
2569\009-- Giving locations of applications\
2570\009-- Each app ocation size is 10 (including gap) x 6 (Including gap)\
2571\009local locs = {\
2572\009\009{2, 1}, -- Row one\
2573\009\009{12, 1},\
2574\009\009{22, 1},\
2575\009\009{32, 1},\
2576\009\009{42, 1},\
2577\
2578\009\009{2, 7}, -- Row two\
2579\009\009{12, 7},\
2580\009\009{22, 7},\
2581\009\009{32, 7},\
2582\009\009{42, 7},\
2583\
2584\009\009{2, 13}, -- Row three\
2585\009\009{12, 13},\
2586\009\009{22, 13},\
2587\009\009{32, 13},\
2588\009\009{42, 13},\
2589\009}\
2590\
2591\009i = 1\
2592\009for k, v in pairs(progList) do\
2593\009\009if base.images.icons[v] ~= nil then -- Checking to make sure that the icon for the app exists\
2594\009\009\009paintutils.drawImage(base.images.icons[v], locs[i][1], locs[i][2]) -- Draw he image to the screen\
2595\009\009else -- The icon does not exists, diplay a generic one.\
2596\009\009\009paintutils.drawImage(base.images.genericIcon_small, locs[i][1], locs[i][2])\
2597\009\009end\
2598\009\009local tbl = {\
2599\009\009\009name = v,\
2600\009\009\009x = locs[i][1],\
2601\009\009\009y = locs[i][2],\
2602\009\009\009path = fs.combine(\"BASE/programs\", v),\
2603\009\009}\
2604\009\009table.insert(displayedList, tbl)\
2605\009\009i = i + 1\
2606\009end\
2607\
2608\009local h = fs.open(\"desktopDebug\", \"w\")\
2609\009h.write(textutils.serialise(displayedList))\
2610\009h.close()\
2611\
2612\009local evt, var1, var2, var3 = coroutine.yield() -- Queue an event to be processed by the kernel.\
2613\009-- With mouse_click: var1 = button, var2 = x, var3 = y.\
2614\009if evt == \"mouse_click\" then -- The event was a mouse click inside of the desktop\
2615\009\009for i = 1, #displayedList do\
2616\009\009\009if var2 >= displayedList[i].x and var2 <= displayedList[i].x + 8 and var3 >= displayedList[i].y and var3 <= displayedList[i].y + 4 then\
2617\009\009\009\009base.system.launchProgramForeground(displayedList[i].path) -- Launches app as new window and brings to front.\
2618\009\009\009end\
2619\009\009end\
2620\009end\
2621end",
2622 [ "BASE/.git/objects/1c/d99bbdc73dc9c0e7ed91afaf43ba307fa298c3" ] = "x\001+)JMU06c01\000\002?????????\"?6C?v?????s\015m?n9v?w?(\000;?\015?",
2623 [ "BASE/.git/logs/refs/remotes/origin/master" ] = "0000000000000000000000000000000000000000 12513210bfaef59ba5e8e34960cce7aa217f56b4 Sam Gunner <sam> 1504474645 +0100\009update by push",
2624 [ "BASE/apis/graphics/general/baseforms.lua" ] = "--[[\
2625\009BASE forms API for BASE 2\
2626]]--\
2627\
2628local views = {}\
2629local controllers = {}\
2630local currentScreen\
2631\
2632\
2633-- Loads the program into memory\
2634local function load(path)\
2635\009if (fs.exists(path) and fs.isDir(path)) then\
2636\009\009local defaultView = fs.combine(path, \"default.bfv\")\
2637\009\009local defaultController = fs.combine(path, \"default.bfc\")\
2638\009\009if (fs.exists(defaultView)) then\
2639\009\009\009local files = fs.list(path)\
2640\009\009\009for i = 1, #files do\
2641\009\009\009\009if (not fs.isDir(fs.combine(path, files[i]))) then\
2642\009\009\009\009\009local type = getType(files[i])\
2643\009\009\009\009\009local filename = getFilename(files[i])\
2644\
2645\009\009\009\009\009if type == \"view\" then\
2646\009\009\009\009\009\009views[filename] = loadfile(fs.combine(path, files[i]))\
2647\009\009\009\009\009elseif type == \"controller\" then\
2648\009\009\009\009\009\009controllers[filename] = loadfile(fs.combine(path, files[i]))\
2649\009\009\009\009\009end\
2650\009\009\009\009end\
2651\009\009\009end\
2652\
2653\009\009else\
2654\009\009\009error(\"Default screen not found\")\
2655\009\009end\
2656\
2657\009end\
2658end\
2659\
2660-- Splits the filename and returns the type of file\
2661local function getType(filename)\
2662\009local splits = string.split(filename, \".\")\
2663\009if #splits >= 2 then\
2664\009\009if splits[#splits] == \"bfv\" then\
2665\009\009\009return \"view\"\
2666\009\009elseif splits[#splits] == \"bfc\" then\
2667\009\009\009return \"controller\"\
2668\009\009else\
2669\009\009\009return false\
2670\009\009end\
2671\009else\
2672\009\009return false\
2673\009end\
2674end\
2675\
2676-- Gets the name of a file by removing the file extensions\
2677function getFilename(filename)\
2678\009return string.split(filename)[1]\
2679end",
2680 [ "BASE/core/boot/user_manager.lua" ] = "",
2681 [ "BASE/logs/taskbar.txt" ] = "",
2682 [ "BASE/programs/icons/explorer" ] = "1111104\
268311111104\
268411111104\
268511111104\
268611111104",
2687 [ "BASE/programs/special/desktop" ] = "while true do\
2688\009term.setBackgroundColor(colors.red)\
2689\009term.setTextColor(colors.white)\
2690\009term.clear()\
2691\009term.setCursorPos(1, 1)\
2692\009print(\"Reboot\")\
2693\009print(\"Explorer\")\
2694\009print(\"Imaker\")\
2695\009local _, b, x, y = os.pullEvent(\"mouse_click\")\
2696\009if y == 1 then\
2697\009\009os.reboot()\
2698\009elseif y == 2 then\
2699\009\009local ok, id = base.system.launchProgramForeground(\"BASE/programs/explorer\")\
2700\009elseif y == 3 then\
2701\009\009local ok, id = base.system.launchProgramForeground(\"BASE/programs/i\")\
2702\009end\
2703end",
2704 [ "BASE/programs/special/error_reporter" ] = "--[[\
2705 BASE error reporter\
2706 Program to be passed errors and present them to the user, with an option to report them to the main server\
2707]]\
2708\
2709local args = {...} -- Get hold of args\
2710\
2711-- This function redraws the main error screen\
2712function drawMain(error, taskID)\
2713 base.gui.flash(colors.white)\
2714 base.gui.alert(error, \"An error has occurred\", colors.black, colors.gray)\
2715\009base.kernel.killTask(taskID)\
2716end\
2717\
2718-- Check that the error has actually been specified before displaying it to the user (prevents another crash)\
2719if #args < 2 or type(args[1]) ~= \"string\" then-- or type(args[2]) ~= \"string\" then\
2720 --drawMain(\"Error reporter has crashed.\")\
2721else\
2722 drawMain(args[1], args[2])\
2723end\
2724\
2725local h = fs.open(\"/error_debug.txt\", \"w\")\
2726h.write(textutils.serialise(args))\
2727h.close()\
2728\
2729--os.pullEvent(\"mouse_click\")",
2730 [ "BASE/.git/objects/cb/09cca9be7d9b23c7dfe60a8547c3d244f975e9" ] = "x\001K??OR01e??077????\002b0\0002?\"?\012\000=?\011\015",
2731 [ "BASE/apis/utils.lua" ] = "--[[\
2732\009General utilities\
2733]]--\
2734\
2735function reverseArray(arr)\
2736\009local i = 1\
2737\009local j = #arr\
2738\
2739\009while i < j do\
2740\009\009arr[i], arr[j] = arr[j], arr[i]\
2741\009\009i = i + 1\
2742\009\009j = j - 1\
2743\009end\
2744\
2745\009return arr\
2746end",
2747 [ "BASE/.git/objects/fc/5a4f10f7e644fdb3aa2353949943187af9a8ca" ] = "x\001K??OR01eH?\002?T?4\016H?JM\003??\012 m``\000d??\000\000?\027\016?",
2748 [ "BASE/.git/objects/5b/34cdefdf7bedebb6118def7f767628848bbda3" ] = "x\001U?1\011?0\016???_q??\009??-\029?\021?M\028br6??\"???(.??\014???!?\001??9I?u????;??l??\003??D?0 X?\018\026?ha????{)??\018n\009?\012?\008??\014?\009?\031}v;?\031???e???a\031\009\008?r???U?\"D?Æ??\001Tf/(\025?W?%%$.?\026????k\024u?1c\018?h#\008$?\003p>K?",
2749 [ "BASE/apis/app_names.lua" ] = "--[[\
2750\009BASE App names.\
2751\009This file contains the paths of apps and names that should be displayed along with them.\
2752\009Don't edit this file, use the system API instead.\
2753]]--\
2754\
2755main = {\
2756\009[\"BASE/programs/explorer\"] = \"Explorer\",\
2757\009[\"BASE/programs/i\"] = \"Imaker\",\
2758\009[\"BASE/programs/base_settings\"] = \"Settings\",\
2759\009[\"BASE/programs/base_tour\"] = \"Tour\",\
2760\009[\"BASE/programs/base_info\"] = \"Information\",\
2761\009[\"BASE/programs/console\"] = \"Console\",\
2762\009[\"BASE/programs/update_centre\"] = \"Update Centre\",\
2763}",
2764 [ "BASE/.git/objects/bc/8ccef8883b2dc8066303d5033315bb23fd391e" ] = "x\001+)JMU02?d040031QH??IM?(??/J-??L??/?M??a?}??[o_z????O????p?.TKzj^jQf?'B??y?{k???\006y\031????8??u?P?????%?E%?\005??\0059??\025\012?\014{nT?%??\023VQ?????O0??SKJ2???\029·??D????s?j?.???Vs{\0075??8;7\029???\011n7?\018t!w????\\??\002\127?A\021??e???!\027??,???r??ZI???????-<\014\000\002?vG",
2765 [ "BASE/apis/window.lua" ] = "--[[\
2766\009BASE windowing API.\
2767\009To be deprecated soon.\
2768]]--\
2769\
2770-- Create a window with specified height and width.\
2771function new(width, height)\
2772\009local win = window.create(term.current(), 1, 1, width, height, false)\
2773\009return win\
2774end",
2775 [ "BASE/.git/objects/5b/a0db83b89452d06d9c4e42379d0289f910fcae" ] = "x\001K??OR05`??0?\000\003. \003??\002Q`?\005?\001?CX Q.\000x?\012\020",
2776 [ "BASE/apis/kernel.lua" ] = "--[[\
2777\009BASE Kernel, Version 1.0.15\
2778\009This was designed specifically for BASE 2, and so I cannot guarantee that it will work with any other OS.\
2779\009Copyright (C) 2016, Sam Gunner\
2780\009It is licensed under Creative Commons BY-NC-SA 4.0.\
2781\009This handles the 'multitasking' aspect of BASE, as well as redrawing the screen.\
2782\
2783\009Please note that there are likely to be a few bugs wihin the kernel, and I intend to patch these as soon as I can.\
2784\
2785\009This also functions as an API, and so it is stored in the API directory.\
2786\009Please bear in mind that if you choose to edit this file, it could have serious consequences.\
2787\
2788\009Kernel error codes:\
2789\0091 - Task with ID not found.\
2790\0092 - Screen not found\
2791\0093 - File not found\
2792\
2793\009Kernel task types:\
2794\009kill - remove task from the task list and terminate it.\
2795\009start - initilise a task and display it on the screen.\
2796]]--\
2797\
2798local cursorBlink = false\
2799width, height = term.getSize() -- Get the size of the screen (kernel will use this to create new screens)\
2800tasks = {} -- The holder for all the tasks that are currently being executed.\
2801toReplaceTasks = {}\
2802activeTask = \"desktop\" -- The task that is currently being shown on the screen.\
2803queuedTasks = {} -- Holder for any queued mini-tasks that teh kernel has to execute\
2804executingID = \"\" -- Holds the ID of the current task\
2805currentlyRunning = false\
2806eventData = {}\
2807taskbar = {\
2808\009filter = nil,\
2809}\
2810eventLog = {}\
2811minim = false\
2812local stats = {}\
2813local oldCursorPosFunction\
2814local resumeTaskBar = false\
2815\
2816-- Return the window object associated with the currently executing process.\
2817term.native = function()\
2818\009return tasks[executingID].window\
2819end\
2820\
2821local temp = loadfile(\"BASE/programs/special/taskbar\")\
2822taskbar.co = coroutine.create(temp)\
2823\
2824-- Generates a new 40 character long string to use as a unique identifier\
2825local function getNewID() \
2826 local str = \"\"\
2827 local alph = \"ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuwxyz1234567890\"\
2828 local tbl = base.text.explode(alph)\
2829 local tbl = base.text.shuffleArray(tbl)\
2830 for i = 1, 40 do\
2831 \009str = str .. tbl[math.random(1, 60)]\
2832 end\
2833 return str\
2834end\
2835\
2836-- Removes a task from the task list. Should not be used outside of the kernel, as it can cause serious stability issues.\
2837local function internalKill(taskToExecute)\
2838\009if taskToExecute.id ~= nil then\
2839\009\009tasks[taskToExecute.id] = nil\
2840\009\009return true, taskToExecute.id\
2841\009else\
2842\009\009return false, 1\
2843\009end\
2844end\
2845\
2846-- Replaces a task content with stuff\
2847local function internalReplaceTask(taskDetails)\
2848\009if taskDetails.id ~= nil and taskDetails.value ~= nil then\
2849\009\009tasks[taskDetails.id] = taskDetails.value\
2850\009end\
2851end\
2852\
2853-- Queues a replaceTask task\
2854local function replaceTask(task, key)\
2855\009local taskToAdd = {\
2856\009\009type = \"replace\",\
2857\009\009id = key,\
2858\009\009value = task,\
2859\009\009from = executingID\
2860\009}\
2861\009table.insert(queuedTasks, taskToAdd)\
2862end\
2863\
2864-- Initialises a task that's been spawned by a separate process. Should only be used within the kernel.\
2865local function startTask(execList)\
2866\009executingID = execList.id\
2867\009local beg = term.redirect(tasks[executingID].window)\
2868\
2869\009if tasks[executingID].nextArgs == nil then -- Make sure that it doesn't error out when the arguments are used\
2870\009\009tasks[executingID].nextArgs = {}\
2871\009end\
2872\
2873\009local _, filter = coroutine.resume(tasks[executingID].co, unpack(tasks[executingID].nextArgs)) -- resume the coroutine\
2874\009tasks[executingID].filter = filter\
2875\009tasks[executingID].nextArgs = nil\
2876\009term.redirect(beg)\
2877\009return true, executingID\
2878end\
2879\
2880-- Processes a queued task and executes the required action. Used to perform actions outside of a process' execution.\
2881local function handleTask(taskToExecute)\
2882\009if taskToExecute.type == \"kill\" then\
2883\009\009internalKill(taskToExecute)\
2884\009elseif taskToExecute.type == \"start\" then\
2885\009\009startTask(taskToExecute)\
2886\009elseif taskToExecute.type == \"replace\" then\
2887\009\009internalReplaceTask(taskToExecute)\
2888\009end\
2889end\
2890\
2891-- Creates a special process that won't be displayed on the taskbar. These are handled differently by the kernel compared to other tasks.\
2892local function createSpecialTask(path, id, position, name) -- Where position is a table with x and y values for start and stop\
2893\009if id == nil then\
2894\009\009id = getNewID()\
2895\009end\
2896\009if position == nil or position.x == nil or position.y == nil or position.xEnd == nil or position.yEnd == nil then\
2897\009\009position = {x = 1, y = 1, xEnd = 51, yEnd = 18}\
2898\009end\
2899\009local h = fs.open(path, \"r\")\
2900\009local data = h.readAll()\
2901\009h.close()\
2902\009local fileContents = loadstring(data)\
2903\
2904\009if name == nil then\
2905\009\009name = fs.getName(path)\
2906\009end\
2907\
2908\009local task = {\
2909\009\009name = name,\
2910\009\009id = id,\
2911\009\009permissions = \"root\",\
2912\009\009window = base.window.new(position.xEnd, position.yEnd),\
2913\009\009co = coroutine.create(fileContents),\
2914\009\009path = path,\
2915\009\009filter = nil,\
2916\009\009type = \"special\",\
2917\009}\
2918\009local beg = term.redirect(task.window)\
2919\009local succ, msg = coroutine.resume(task.co)\
2920\009if not succ then\
2921\009\009return false, msg\
2922\009else\
2923\009\009task.filter = msg\
2924\009\009term.redirect(beg)\
2925\009\009tasks[id] = task\
2926\009end\
2927\009return true, id\
2928end\
2929\
2930\
2931function activateCursorBlink()\
2932\009cursorBlink = true\
2933end\
2934\
2935function deactivateCursorBlink()\
2936\009cursorBlink = false\
2937end\
2938\
2939-- Run the kernel itself (Only to be executed once!)\
2940local function mainLoop()\
2941\009-- The startup sequence should go here. This should add windows and processes for the desktop, taskbar and login page.\
2942\009local currentWindow = term.current()\
2943\009local succ, desktopID = createSpecialTask(\"/BASE/programs/special/desktop_beta\", \"desktop\", {x = 1, y = 1, xEnd = 51, yEnd = 18}, \"Desktop\")\
2944\009if not succ then\
2945\009\009return -1, desktopID -- Return the code to the bootstrapper to signifiy there has been a kernel error.\
2946\009end\
2947\009bringToFront(\"desktop\") -- Start the OS with the desktop displayed.\
2948\009\
2949\009while true do\
2950\009\009local succ, oth = coroutine.resume(taskbar.co) -- Resume taskbar task so taskbar is drawn and rendered correctly\
2951\009\009if not succ then -- Check to see if the task executed sucessfully.\
2952\009\009\009error(\"Taskbar errored: \" .. oth)\
2953\009\009else\
2954\009\009\009taskbar.filter = oth\
2955\009\009end\
2956\009\009executingID = \"kernel\"\
2957\
2958\009\009for i = 1, #queuedTasks do\
2959\009\009\009local taskToDo = queuedTasks[i]\
2960\009\009\009handleTask(taskToDo)\
2961\009\009end\
2962\009\009\
2963\009\009queuedTasks = {} -- Reset tasks to do\
2964\
2965\009\009if resumeTaskBar then\
2966\009\009\009coroutine.resume(taskbar.co)\
2967\009\009\009resumeTaskBar = false\
2968\009\009end\
2969\
2970\009\009eventData = {os.pullEvent()}\
2971\
2972\009\009-- Now, check if the event needs to be handed to the taskbar\
2973\009\009if ((eventData[1] == \"mouse_click\" or eventData[1] == \"mouse_scroll\" or eventData[1] == \"mouse_drag\" or eventData[1] == \"mouse_up\") and eventData[4] == 19) or base.debug.taskbarIsActive == true then -- Check to see if it is a mouse event and that it hit the taskbar.\
2974\009\009\009local _, filter = coroutine.resume(taskbar.co, unpack(eventData))\
2975\009\009\009taskbar.filter = filter\
2976\009\009\009term.setCursorBlink(cursorBlink)\
2977\
2978\009\009-- The event did not need to be handed to the taskbar.\
2979\009\009else\
2980\009\009\009-- Now, check if the event needs to be passed to the currently active event\
2981\009\009\009if eventData[1] == \"mouse_click\" or eventData[1] == \"mouse_scroll\" or eventData[1] == \"mouse_drag\" or eventData[1] == \"mouse_up\" or eventData[1] == \"key\" or eventData[1] == \"key_up\" or eventData[1] == \"char\" or eventData[1] == \"paste\" then\
2982\009\009\009\009if tasks[activeTask].filter == nil or tasks[activeTask].filter == eventData[1] then\
2983\009\009\009\009\009executingID = activeTask\
2984\009\009\009\009\009local beg = term.redirect(tasks[activeTask].window) -- Redirect all output to the window of the app\
2985\009\009\009\009\009local succ, filter = coroutine.resume(tasks[activeTask].co, unpack(eventData))\
2986\009\009\009\009\009term.redirect(beg)\
2987\009\009\009\009\009if succ then\
2988\009\009\009\009\009\009tasks[activeTask].filter = filter\
2989\009\009\009\009\009else\
2990\009\009\009\009\009\009launchErrorReporter(filter)\
2991\009\009\009\009\009\009killTask(activeTask)\
2992\009\009\009\009\009\009bringToFront(\"desktop\")\
2993\009\009\009\009\009end\
2994\
2995\009\009\009\009\009if coroutine.status(tasks[activeTask].co) == \"dead\" then\
2996\009\009\009\009\009\009killTask(activeTask)\
2997\009\009\009\009\009\009bringToFront(\"desktop\")\
2998\009\009\009\009\009end\
2999\009\009\009\009end\
3000\009\009\009else\
3001\009\009\009\009for k, v in pairs(tasks) do\
3002\009\009\009\009\009if v.filter == nil or v.filter == eventData[1] then\
3003\009\009\009\009\009\009executingID = k\
3004\009\009\009\009\009\009local beg = term.redirect(v.window) -- Redirect all output to the window of the app\
3005\009\009\009\009\009\009local _, filter = coroutine.resume(v.co, unpack(eventData))\
3006\009\009\009\009\009\009term.redirect(beg)\
3007\009\009\009\009\009\009v.filter = filter\
3008\009\009\009\009\009\009\
3009\009\009\009\009\009\009replaceTask(v, k)\
3010\
3011\009\009\009\009\009\009if coroutine.status(v.co) == \"dead\" then\
3012\009\009\009\009\009\009\009killTask(k)\
3013\009\009\009\009\009\009\009bringToFront(\"desktop\")\
3014\009\009\009\009\009\009end\
3015\009\009\009\009\009end\
3016\009\009\009\009end\
3017\009\009\009end\
3018\009\009end\
3019\009end\
3020end\
3021\
3022-- Check if a task has been executed yet.\
3023function taskIsPresent(task)\
3024\009for i = 1, #queuedTasks do\
3025\009\009if queuedTasks[i] == task then\
3026\009\009\009return true\
3027\009\009end\
3028\009end\
3029\009return false\
3030end\
3031\
3032-- This gets the ID of the currently executing process and returns it\
3033function getCurrentID()\
3034\009return executingID\
3035end\
3036\
3037-- Creates a new process with standard permissions and arguments from a file.\
3038function newTaskFromPath(path, needsScreen, args)\
3039\009if fs.exists(path) and not fs.isDir(path) then\
3040\009\009local h = fs.open(path, \"r\")\
3041\009\009local data = h.readAll()\
3042\009\009h.close()\
3043\
3044\009\009local id = getNewID() -- Create a unique ID for the app\
3045\009\009fileContents = loadstring(data) -- Make a function with the data from the file.\
3046\009\009local newWind = base.window.new(width, height - 1) -- Create a new window for the process.\
3047\
3048\009\009if base.app_names.main[path] ~= nil then\
3049\009\009\009app_name = base.app_names.main[path]\
3050\009\009else\
3051\009\009\009app_name = fs.getName(path)\
3052\009\009end\
3053\
3054\009\009local task = { -- Task table to insert into tasks\
3055\009\009\009path = path,\
3056\009\009\009name = app_name,\
3057\009\009\009permissions = \"default\",\
3058\009\009\009window = newWind,\
3059\009\009\009co = coroutine.create(fileContents),\
3060\009\009\009id = id,\
3061\009\009\009filter = nil,\
3062\009\009\009type = \"app\",\
3063\009\009\009nextArgs = args,\
3064\009\009}\
3065\009\009tasks[id] = task -- Add new task to the task table.\
3066\
3067\009\009bringToFront(id) -- Bring the app to the front of the screen.\
3068\009\009local toDo = {\
3069\009\009\009id = id,\
3070\009\009\009type = \"start\",\
3071\009\009}\
3072\009\009table.insert(queuedTasks, toDo) -- Make sure that the kernel runs the task once to initialise it.\
3073\009\009return true, id\
3074\009else\
3075\009\009return false, 3\
3076\009end\
3077end\
3078\
3079-- Maximises a window; brings it to the user's focus.\
3080function bringToFront(taskID) -- Brings a process to the front of the screen\
3081\009if tasks[taskID] ~= nil then\
3082\009\009--tasks[activeTask].window.setVisible(true)\
3083\009\009tasks[taskID].window.setVisible(true) -- Bring new window into focus\
3084\009\009tasks[taskID].window.redraw()\
3085\009\009activeTask = taskID\
3086\009\009local toDo = {\
3087\009\009\009id = taskID,\
3088\009\009\009type = \"start\",\
3089\009\009}\
3090\009\009if not taskIsPresent(toDo) then\
3091\009\009\009table.insert(queuedTasks, toDo)\
3092\009\009end\
3093\009\009return true, taskID\
3094\009else\
3095\009\009error(\"Attempted to resume a task that doesn't exist\")\
3096\009end\
3097end\
3098\
3099-- Queue an internal task to remove a process from the active process list.\
3100function killTask(taskID) -- Queues a task to kill a process using a unique ID\
3101\009if taskID ~= nil then\
3102\009\009local taskToAdd = { -- Create the task table.\
3103\009\009\009['type'] = \"kill\",\
3104\009\009\009['id'] = taskID,\
3105\009\009\009['from'] = executingID,\
3106\009\009}\
3107\
3108\009\009table.insert(queuedTasks, taskToAdd)\
3109\009\009resumeTaskBar = true\
3110\009\009return true, taskID\
3111\009else\
3112\009\009return false\
3113\009end\
3114end\
3115\
3116-- Return a list of processes that should be shown on the taskbar. These are ones that the user will interact with.\
3117function getOpenApps()\
3118\009local toReturn = {}\
3119\009for k, v in pairs(tasks) do\
3120\009\009if v.type == \"app\" then\
3121\009\009\009local tmp = {}\
3122\009\009\009tmp.id = v.id\
3123\009\009\009tmp.name = v.name\
3124\009\009\009table.insert(toReturn, tmp)\
3125\009\009end\
3126\009end\
3127\009return toReturn\
3128end\
3129\
3130-- The main process for the kernel. This includes the main loop and handles everything.\
3131function main() \
3132\009if currentlyRunning then -- If it is currently running, then raise an error\
3133\009\009error(\"The kernel is already running!\")\
3134\
3135\009else -- Otherwise, run the main loop.\
3136\009\009currentlyRunning = true\
3137\009\009local ok, err = pcall(mainLoop)\
3138\009\009if not ok then\
3139\009\009\009return false, err\
3140\009\009else\
3141\009\009\009return\
3142\009\009end\
3143\009end\
3144end\
3145\
3146-- Returns a boolean representing whether the specicifed task has finished executing or not\
3147function taskIsDead(taskID)\
3148\009if tasks[taskID] ~= nil then\
3149\009\009local status = coroutine.status(tasks[taskID].co)\
3150\009\009if status == \"dead\" then\
3151\009\009\009return true\
3152\009\009else\
3153\009\009\009return false\
3154\009\009end\
3155\
3156\009else\
3157\009\009return true\
3158\009end\
3159end\
3160\
3161-- Launches a new instance of the error reporter to show an error message to the user\
3162function launchErrorReporter(error, taskID)\
3163\009newTaskFromPath(\"/BASE/programs/special/error_reporter\", true, {error, taskID})\
3164end\
3165\
3166-- Sets cursor pos\
3167function setCursorPos(x, y)\
3168\009if tasks[executingID] ~= nil then\
3169\009 tasks[executingID]['x'] = x\
3170\009 tasks[executingID]['y'] = y\
3171\009end\
3172end\
3173\
3174function setOldCursorPosFunction(func)\
3175\009oldCursorPosFunction = func\
3176end\
3177\
3178--Returns true if the task is dead, false if not\
3179function taskExists(taskID)\
3180\009if tasks[taskID] ~= nil then\
3181\009\009return true\
3182\009else\
3183\009\009return false\
3184\009end\
3185end\
3186\
3187local function legacyAppDetected()\
3188\009\
3189end",
3190 [ "BASE/.git/objects/4f/031e8efd79962bad1903f309a24f2f62d6a1c7" ] = "x\001K??OR01e?0??\000a.\016\009b\003\025`\026Y\004?\006\0007?\
3191?",
3192 [ "BASE/.git/COMMIT_EDITMSG" ] = "Added operating system in its current state",
3193 [ "BASE/.git/objects/64/af8c4a1905a709a7416b052babf0c60c66f9cf" ] = "x\001?S?j?0\016?s?b?.?\030z?\028R\008??B{+????\022?Gf$m???4!?>Y??f?<7?5????G]??/@?7?w?H???&?\028C\024\016\0307?[p\019?\
3194?z?\0158??n??Q`g?u????\022&v\026?G\015\028?R???z???X,?\026\030?7\004]$\029?#???\006#U\024\"S?\002??D?\003\011?_?~0z\016???)dZR?h\009(?8\030tdF\
3195v?\006?8\030P?-4s??\009?ja?V?K\031z\012\127\018?s?\\???[ ?v\
3196??:V\011?yB\018?\
3197??\\:X ?y?Q\025?%?i?(\003%g???bW?j??'\001?;?.?e?\127:???\005??H?\000\0178?A??\026\031???y??f?-?6?\127?A???f?Y?J;??dw\001??\005 ??\006????7?\022??????M*?B\
3198?E\008\028\017Z?????wes?Khb\008??pxY??\002kp~5Ek?\127%#????Om????Lw???\026?s?\015R???rH$?,?d5?))??ge??Q??{j?4~??V?\015I??[I}?????/?",
3199 [ "BASE/.git/objects/72/d1c84dfaa2a4410034cd217a09787e24f4bbd1" ] = "x\001?X[o#5\020?5?+\014?\003\019)?l?E?b?z\009Ka?Vm\023???rf????\014???\
3200?\127?;?L2I?t\023?\000/ml?s|???L*3??????d8??J?\014\015.?th?w??J??\004??R?9\127NGfuo?l?);??????\007t!????ZZ\018????R:????YN?V?rT?Bj'K?5d??«[\009???\014\127\031?>\026^\028????????k?*I??#QU??+c??>\0288?s??V?Q++? h\001\003??.????ya}?\"/??Ap`\018V????B??DRi?d}\127?K\
3201\018I\027\007?\\?&Z??,\007?<?k?j?ena\
3202D0?BZ-?<??\030\014?d8?\011??n?Ub\002CJYT??n?\0195???\031`?\014.{A\127\01886\027?\025i?o\019?7K?\022??}p??3??.Ozi~|qs?!2\029$?de??Yzqyp~y??e\019???K:;?=\026\031?9\031????x??????/??t????1?n^?\019?$A?w\009??K9?g??:\017??\029\020!?/h**'?dZk?\0248?m?\011??P?e~R\
3203?\020^??\030?D?\001??\018??>b??zj??\023/\002ip8?zV??B??%?R?I????y;?\012<E????B????)k?8?pz?\027w&?|@\028\008(\0219?k??2u?Lz^d\020\009\0094P?+?*P_???Z?n???Zc3Jq\021?y\030\008?<%$??P\004?=???\011?V?,}?h?E??\026????8\\='?Rz?\024??\015\006H??\027??{\011????/??N5?\027??\022G?\006W?????\011?R?f?0??!-,3???\000???,\027\007?[?U???z???\021?.?6?\025?tW\011\004??6?E?k???C?'L?!j?\004???:k?Q?\\\009??B:t\028/?z6N?e\014?\028?b1?\006}??T?}?\127?EV?w?.??u~7W?????\127?^????????kT?S?L*\\?!{?-M\127?pK4??r??4?/?le?o\027|?\016??????\026????\022sY,N?<t?\021z`\031\003\016?\
3204=O?U??\025F?6\024?.W?X?f?? \024?v\021j????J?¼w\\??R?30??Q\017?U?\018+?6g?:Kd\030\
3205h????d?D?a?\029.?,??r9j$??1$???7u?\027?\"?8?7RX?QefJ?U-?\001\015??\028\000J*???KL?`a?0??=?Tfg#??????u??m?v6??n???TV?R??\000*??8r?\024?\000\031!L\000AssG\000A<??T??M????W?9?\006H\025\003?=?WB\014L$?\127\030AYH\029?A?E?&boL\025KB?4 ?,FS?n??;?\006?ASKXe?\008?\
3206?i?/?a??8A?\025`??\017hX\024S?1?\
3207?\015?a\"??!?R?}?V\003*t?v??\030%???p??}???\014???;?G??J\
3208??\016Q65??D?%?ehH??33\016?\026?-??\031o%?e?\127j?jm?\008j-|b\008???=G?<M?\018??1??$??\021\026\016r\002A??+?\020V?g?p?o\002Lt??1\020]HS?0?\016?\029Y\002?\030 ?w??%??V??1?D??h?`?\029??GF????L?Qe??:???\
3209R\026?\027_?\016)?aF?Y\030?\
3210\018cX\012\001??AU1????2N?o4[6\014&\003?~???]?=?A?oi?H??\027\"?s?3+???*??\028O \0155?OpE4O21C??\000?t\028?%o4?U-g??K???%?\017?\003?v\011???\017?iX\030?\007\007?\000O\
3211?k?*?\022?8a?\031?sKG<??),??\018'lg\019{\0293?6'?;????C?+????A?mX@?????\027\005b????\029?>?????R?cw<?-\027??<?hw??!\020\019?g\016?E??l??aRj???\009\020\007\011??%2b{Fu??[?$??r??_??'?]??\003UQIaQ;-?\003`? ?`)#???o??~?\021z\008\006??O??Oa?7?F?}\020cSi?????j\025?r??????F:\005???\009?4\011n\008??} ??H??\005???i?x???\030??%?\014??\024?T??\020\004?L??-???>4EQ\003???o\021??3\009zmGk~<C6?k\014???[J\020??};m?z?Vz??c?v??fN\006?\001*c\022?;|?ZH?(<??#\0116f?DDw??Y??\003??H\" 2??s\016?=C??\009ipM\019\027P ??\020?d??\031\005?/r|.\000!?????\020????=?b\028&\017???G?Èm\002?t??%?f?V????.?+`\127\029?xe`???\000J.?\024",
3212 [ "BASE/.git/objects/58/10f848e95dcfdc6583144601c1e999f113af1e" ] = "x\001?Ymo?6\016?W?W\028?\015SP[??/@?\"?!@?\021m?}?B?\024[?,j???\024???HJ?l?n?,+`K?I?w?\031'???????~?Çn??????z1\009\021eJN??\001??cM?0?\018?)LW???\022$.E?k??aN?\018??H??\031?\\??9?X??{???Tx\021???Y=\
32135]?$?{\020?,\009W<eZ(?5?\021?L?\020?b?????~????-?o??1\
3214?qz)?\022/??b?d?F?d\"\021??|??L??.??}?:)?g??'?9i[?j\014b??~??E:?\027nt\030???\"-\000R\004??ADfy,S?$\009???\005^?\127???\025???n????0q\008\001????Nb??gb\012\127\014?_??B-\003-?-~|?!??7MD?j??????OB-\002????~\011U\028N ??\001[M?\0053P?\023y??\009z\019??\031?\008?\019{?\000???sl\023L????~g?$?dAW??\029<???e*??[?o?\021???df???f?/O\018?g?s\001??? #?\008b?O#_\024?{t????\001??T?Q?V\006S?D?Q}??=zzO[\
3215X\016????\004?=>???b?e 6\
3216e\008$o-?m?|'&R??c\022????y?G?*?????7rF???\007?????2L?\"??\"???4&\002???\030\
3217G<\127\009?zg|d??6Zu???\016i?\016k)\127?\006?{???b??h?\003_??w?BX)????A?2??G?=Z\025?\
32187\011ND??E\018\025??\011????c?L??4M???c\031???\014\1271g?3\006?U^?sX???l\01233?W??C?????z?#u?\021I?????#\012?\002$\025??8??'J\009????)?\019?\025]?\031\027\014?\003\024{\028????x\025\018?%?\029?Y\025?p?Z?\012?D?-?6yZ???d??}?T?k\019S\004~??g??\014p?!\"??hpRr\004??2R???\005.?8??{?\002\"?@J \012?f??9?\009?omt?Q*aC??qV??Em??_?\004???ce5Q\"\\?\005??d?ok?S?gc?j??\024?O\008\000?5??\029?ZC/?????\004?????(p?.?{\021?9?`#??COI^?\007??:Q?9\005?2?*???e\018?\011? \
3219,???Y?<?N???%??B?T$l+??\017V???g?+?[?\008????=?};\028?f&?;?3|\012?;????K<?!=?o+?[?{??,m?????\009?q[?a?=????B[fX;????~??v???o??i?\004??I(?\014?*3e?o??\020?F?2??\\!?\004???%?\031vd?1HÃ¥???\012?zd\008??T?????T?&\004?\0068?G?#???\003\004?\006?0Xjn???\021??>\028FN\0218??????a?????8X\030\028\0145?8]?2??\0296z???OvMe\026????PAQq???:j?H`y?VmMI0?WZ'$??\009\009?d?-9g9a;:??*?\012??^?2?Y??\001ma?\019+?O??[z??\026?m|-\018???\018??eAl????p??u::\017\"?\003????m\004??5]\004m\000\005??f0\006\"$\002\027A\0310?q,???8?\016?OJ?Uc(j??\021 ?\003?6j?s?{d????V?\028$?X\019?~p??\019 ?S??b9[??A??^?\031GGGF\024????\\L\023xBE??H?e??h??9]?i??\"\"q-????h\"`?\002?.??\028???&#?\022\001?0o???.c???JI?NdR?v|?;??`??? ?s??\012\031S\0212\011?K?Mz`+????:M??z;0\022q??C,?\004b?7>?\009??1??\014m\001U??????\011?D?;??X??\027??P~S?????[??????/??\003j?6?[Z?h?3???\127?????C\011\030????>????\029ZpK\022z/\022?'\009??\005W???a???`K?]Z???\009???`4?\\?\1270\\?)?\023Y?\006\024we??????N?\
3220????p?T[??\031?J????\022?+\021n?\025????Vnj2???X??qj?\019G>?C???x0?\001?5????F??VX??\015??x?r????\"??L$M+?\015,?,??s?r??\000\127Vq[;??9?u???\022:?U???k?????q0\019\028q??C?9i\016Q?\015\017q?L?@??W[EP??e?MH{J{???;??zF?o?X?\012?|z\016)??I?????\003nX??????3?P?y?p??????Q????>?\024\029.;??\001?H???????>v??{-???Q-k? r?#??|;??q??G]$\006\\?I???????f?\005?3????_2?BS??\006?A?c?S\016.???\127\0015?4?",
3221 [ "BASE/programs/base_info" ] = "--[[\
3222\009BASE 2 Information App.\
3223\009Includes updates and changes in the OS, as well as information about the operating system.\
3224]]--\
3225\
3226local update_url = \"http://samjgunner.uk/test.php\"\
3227base.gui.flash(colors.white)\
3228term.setTextColor(colors.black)\
3229base.text.ctxt(\"Obtaining Content...\", 10)\
3230local h = http.get(update_url)\
3231local content = h.readAll()\
3232h.close()\
3233content = base.json.decode(content)\
3234\
3235local function main()\
3236\009local subWindow = window.create(term.current(), 3, 3, 47, 15)\
3237\009local original = term.current()\
3238\009local page = 1\
3239\
3240\009local function drawMain()\
3241\009\009term.redirect(original)\
3242\009\009base.gui.flash(colors.white)\
3243\009\009term.setTextColor(colors.gray)\
3244\009\009paintutils.drawLine(1, 9, 1, 11, colors.lightGray)\
3245\009\009paintutils.drawLine(51, 9, 51, 11, colors.lightGray)\
3246\009\009base.text.ptxt(\"<\", 1, 10)\
3247\009\009base.text.ptxt(\">\", 51, 10)\
3248\009\009paintutils.drawLine(1, 1, 51, 1, colors.gray)\
3249\009\009term.setTextColor(colors.white)\
3250\009\009base.text.ctxt(\"Base Information\", 1)\
3251\009\009term.setTextColor(colors.red)\
3252\009\009base.text.ptxt(\"x\", 51, 1)\
3253\009\009\
3254\009\009term.redirect(subWindow)\
3255\009\009term.setCursorPos(1, 1)\
3256\009\009base.gui.flash(colors.white)\
3257\009\009term.setTextColor(colors.black)\
3258\009\009print(content[page])\
3259\009end\
3260\009\
3261\009while true do\
3262\009\009drawMain()\
3263\009\009local _, b, x, y = os.pullEvent(\"mouse_click\")\
3264\009\009if b == 1 then\
3265\009\009\009if x == 1 and y >= 9 and y <= 11 then\
3266\009\009\009\009if page > 1 then page = page - 1 end\
3267\009\009\009\
3268\009\009\009elseif x == 51 and y >= 9 and y <= 11 then\
3269\009\009\009\009if page < #content then page = page + 1 end\
3270\009\009\009\009\
3271\009\009\009elseif x == 51 and y == 1 then\
3272\009\009\009\009break\
3273\009\009\009end\
3274\009\009end\
3275\009end\
3276end\
3277\
3278main()",
3279 [ "BASE/.git/objects/06/15f0247613f4b7ce89560011c58cfc3e95bdc9" ] = "x\001K??OR05`??\001.\011\011ss\016? ?\002\000z\018\012\031",
3280 [ "BASE/.git/objects/66/9e243355ba054dee52f798760ea887daf3d144" ] = "x\001K??OR05`HII1\007\002\011$??\015\018?\000.\000??\
3281U",
3282 [ "BASE/.git/objects/46/5c4f5b6b0b4f2061ce53130619a6fcdb6c52c2" ] = "x\001?Z?n??\017??\021\
3283?a?,?.sq0\026 ?M6\011\012\018#v?\008?`?Z\018a?M?)K????b?\018/6v?!???(???????3??\\}??N~ws?~???)?VQ\028????\"??:6??K?\"ZE????&q?M?4Y????.\027^?v?\"?]?\004?;{?\031\030r??\003u??ß?\004???\\/???%??6??Tje3\021?YXL????R???|?G?\027\018?/Qb\002?h?<_\\??dyI??????N?\027??\"3&????5?J?W?v?>??A??d?3?]Ub??>_?Fg??b?\142s{P?(?h??1?U\012?f?U?C\028???~2?????'?Pn??v_7??????\005^4?@???#??9??T\018?d??M\029????q???\0182?R??U^n?$y?Z??@???T?\027???\0200??8???^`U\004Hp?v?B?6?p^\0027?\015?pA\002?Q??(?????Y???a????)~J\015To?8?tI?u???\
3284?JP?\007??@Mo\007j?K?a7???&?\017?mv\019*P?o\003?}t0q?v?Z? 3KZY???]?lvo?_V}?h\0149?P?\027?7Qnh?>?E?w?,RwY????\031?\016?6??ul?\\?2?~?H)?\018??A?????=??q?:!OY\021%??-g?????nM?\001o??ij\018????!\011?\022k?.?h?tU\002\002o??!?X\007\031^?3kQ^ ??a?_=)?N?w?ZDO?%????dI??\022\028\029AX8?\028???_??!i4\\?\004D???\017?\008hv??_}x?KSd6??\016?o??H?? j\002???)µ?\019k:\004Z??qD\004???W\02808l\000Sp?u?t\023?\127z?M??J? |9\006??Q\009?p?nM??\009\0303??|\\?3I3\008]?\025?????Xi\014? o????X?bc??p|?nn\030?X??t?X\008\017mun8/?<??f?9?\002?`bgH?O?\009\011|?8??>\026w??\007t??TX?\
3285????I??\002\031U?\026?\001P\004?{\"\020???Q??pc?j?\0196??*W??P=bY??\002;(?2?\012Nf?K?h\\O???%??*k?\020?pH^\003->???????)??xZ\000?)D??m?????a?k`?\000?\018\021*?S?I\021?*?R?1\018??/??O?\127??~????????{?6r@??x.\127?`2y?c?\"3??9\028}!?c?\001}?Ü?\0118?+\008?'x???\023TA\009w??\
3286????\025??c\018?>?\002I?<??%\127?L??\018??@??\002???\002w??\
3287?3~[?f?<??L?*??<I??(?/;D?\029IJ\025^?u??ä?x??/??\0181\030?\027?=?\026Z?mY\000?\023\023x??\004??w???j\014?K??T?:??\020N?t\000\014\008?\028?4??=?u???P???h:[???\031???\027,>\\????0-\015??X#??????sDr?6?)<\014?\030L?\020???%\012E-c\030?j??\008?+\024??6T3 ?????`s\127^R|W))?#!(U???\014>????`?7>+p?(W\031g????,)????\028??Gb\023nx?cc???\029\011?c\009;\007?I?\004\021V?sE\002?];5?}_????\
3288?f????\"=??\027????YpP?I\020N?N?i?2&;\006?\015??<?;i?\021x?4L\015?????R\006Q=??\023>??z\028Z??\004;ot??f?B\022?bVy??Q???QO\024?i??\022G???Q{?M???mncw?R}?h????]X\016??8\0010f?c???\006?\027?????\008%_??Xp??X ??t?????????\127\\>?da?R?????xBu???-??\023?~??Z?4??b???w\004?????(??M\022?9?\024?????p??R6???`\014?@c:?\025??J??*ZDp??9?E??P\008/}??l\0129?\017\021e?j?J?T??????0??9.~,???\\???+?*?[?\026G.???(?U?8?xT#?t\016??+?}?e(\025}\023?;\025?k:?0?\025?\001??\0159N?\025?DA?0(?8?P?\012?`\030?4???????l?\026??m'?\008?=S ?*;???\014x?J'????.%<?8??V\"Qg\004??\016?h???E???P?J?\004#?\022c?*\\???\021?K??\
3289???Pvyyr'?L?B?8j\030n4m5\017E&????2\012??T?H8p?R?4?p?DT??\001E?y?*?m???1=\
3290?0?i?g*zLO\003AZ?F\
3291?\002\030?V?????\018N\005??\"???\024\018>?w\006???\016\011??D\008M??Wt\024??r?F?????M?$\0083?7%? ???g???Q]x\133??C%\000R?/'?<+\026?O3?\\a???~???@?j? ?eg\001?\026?hT???t?\0078?s?\006\014?8x`???\015???-\
3292\016D??\002???J?Mn??[b???N\\mo;LG?Q'?v\019;?L\017?w\014\000R?p[(>??)?\019??'!j'?.?{P?????t?\028?K?8??3?\024hj??\016p??c?S?`?v\006\027??N\027\"M2]V??????+|\027[|?7. ?}&?]??\007\"??6?$???jp\031-??@m\012\021?r?\015?-/A??3~O6S??-?c?R7??F??_?\022?h??3?%X\003(?x???r?@?jLz\005A)??1?:y\031Y??c\"l???^??\011??=Mh??\026Z^J?ld??F,d?-?k??\006\019?>?}\029?_*{5\018\018|???HV4??:????qQ???????,?iD??\027\027??\020???\018??K??I\002????P?+??? \023/?\011??c?2??\008K\012????D?!???{???2\021\004\003?\022?([XJ7,\
3293?zg.\011Ba[???\021???G?A+q????$\006?a?_\000?M}?",
3294 [ "BASE/.git/objects/c8/114f11b0d20e664d996ab82f44f6d645e36a69" ] = "x\001??MK?0\016????b???'E?~??A?xH?\029??L]E???u]\004A<?$???'i\\h??p\127??????dys\014\020`y}Y??WUYV\021\\\005?\0016?C?bx???p\015?\016???\024L?\020??\017-???-S??D?V???[\022?A?j|??i?e1\031X??(Na??E?5\014z8?|X???=???M??????h?ssM??u!a^Of\027??f|?z?\009#\025GR????-???o?\011n?? K??\
3295?<?\017l?eta???@\
32963??BK\029a[\127?H?8?????:9????:]_g?:\030?\\?7??Ee7?|\
3297?e??G??V\018\"\008n\003??\028.`?\014k?^?\016??qHo??y?U?\011I???&?\028\007\020?.??b???m?ri??=?GK6xeM?\001f?\031??i6??m??5c?6?7?*???'??\001h",
3298 [ "BASE/core/user_login_temp.lua" ] = "--[[\
3299\009Base 2 Temporary Login Script\
3300]]--\
3301\
3302-- Generates a new salt for a user password\
3303local function generateSalt()\
3304\009local str = \"\"\
3305\009local alph = \"ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuwxyz1234567890\"\
3306\009local tbl = base.text.explode(alph)\
3307\009local tbl = base.text.shuffleArray(tbl)\
3308\009for i = 1, 10 do\
3309\009\009str = str .. tbl[math.random(1, 60)]\
3310\009end\
3311\009\
3312\009return str\
3313end\
3314\
3315-- Loads all user profiles stored in the user profile file\
3316local function loadUserProfiles()\
3317\009local tbl = base.io.loadTable(\"/BASE/system/users\")\
3318\009return tbl\
3319end\
3320\
3321-- This takes in a user name, password and existing table of users, hashes the password and adds it to the user profile file\
3322local function createNewUser(name, password, users)\
3323\009local salt = generateSalt()\
3324\009password = password .. salt -- Add salt to the password\
3325\
3326\009local newUser = {\
3327\009\009name = name,\
3328\009\009password = base.sha256.hash(password),\
3329\009\009color = colors.blue,\
3330\009\009salt = salt\
3331\009}\
3332\009\
3333\009table.insert(users, newUser)\
3334\009\
3335\009base.io.saveTable(users, \"/BASE/system/users\")\
3336\009return users\
3337end\
3338\
3339-- Deletes a user account from the user profile file\
3340local function deleteUser(id, users)\
3341\009if #users >= id then\
3342\009\009users[id] = nil\
3343\009end\
3344\009\
3345\009base.io.saveTable(users, \"/BASE/system/users\")\
3346\009\
3347\009return users\
3348end\
3349\
3350-- Checks credentials for user\
3351local function checkCredentials(user, pass, users)\
3352\009local userRec\
3353\009\
3354\009for i = 1, #users do\
3355\009\009if users[i].name == user then\
3356\009\009\009userRec = users[i]\
3357\009\009end\
3358\009end\
3359\009\
3360\009if userRec == nil then\
3361\009\009return false\
3362\009end\
3363\009\
3364\009pass = base.sha256.hash(pass .. userRec.salt)\
3365\009if pass == userRec.password then\
3366\009\009return true\
3367\009end\
3368\009\
3369\009return false\
3370end\
3371\
3372local function main()\
3373\009local users = loadUserProfiles()\
3374\009term.clear()\
3375\009term.setTextColor(colors.white)\
3376\009term.setCursorPos(1, 1)\
3377\
3378\009while true do\
3379\009\009print(\"Options available:\")\
3380\009\009print(\"1 - New Account\")\
3381\009\009print(\"2 - Login with an existing account\")\
3382\009\009print(\"3 - Shutdown PC\")\
3383\009\009write(\"Please enter your choice: \")\
3384\009\009local opt = read()\
3385\009\009if opt == \"1\" then\
3386\009\009\009write(\"Enter a new username: \")\
3387\009\009\009local username = read()\
3388\009\009\009write(\"Enter a password for this user: \")\
3389\009\009\009local pass = read(\"*\")\
3390\009\009\009if #username >= 1 and #pass >= 1 then\
3391\009\009\009\009users = createNewUser(username, pass, users)\
3392\009\009\009end\
3393\009\009\009\
3394\009\009elseif opt == \"2\" then\
3395\009\009\009write(\"Enter username: \")\
3396\009\009\009local username = read()\
3397\009\009\009write(\"Enter password: \")\
3398\009\009\009local password = read(\"*\")\
3399\009\009\009if checkCredentials(username, password, users) then\
3400\009\009\009\009base.system.currentUser = {\
3401\009\009\009\009\009name = username\
3402\009\009\009\009}\
3403\009\009\009\009break\
3404\009\009\009else\
3405\009\009\009\009print(\"Incorrect credentials\")\
3406\009\009\009end\
3407\009\009\009\
3408\009\009elseif opt == \"3\" then\
3409\009\009\009os.shutdown()\
3410\009\009end\
3411\009end\
3412end\
3413\
3414main()",
3415 [ "BASE/programs/store.lua" ] = "--[[\
3416 App store for CC\
3417 \
3418]]--\
3419\
3420local function main()\
3421 local mainWin = window.create(term.current(), 1, 3, 51, 16)\
3422 local topWin = window.create(term.current(), 1, 1, 51, 2)\
3423 local currentWin = term.current()\
3424 local topWinPage = 1\
3425 local topWinPosition = 1\
3426 \
3427 -- Redraws the login window with the currently-entered credentials\
3428 local function drawLoginWin(loginUsername, loginPasswordLength, registerUsername, registerPasswordLength)\
3429\009term.redirect(mainWin)\
3430\009\
3431\009base.gui.flash(colors.white)\
3432\009term.setTextColor(colors.black)\
3433\009base.text.ctxt(\"Please login to continue\", 2)\
3434\009term.redirect(currentWin)\
3435 end\
3436 \
3437 -- Draws the top bar with the current page highlighted\
3438 local function drawTopWin(page, position)\
3439\009term.redirect(topWin)\
3440\009base.gui.drawStandardHeader(\"Collect, built for BASE\")\
3441\009term.redirect(currentWin)\
3442 end\
3443 \
3444 while true do\
3445\009drawTopWin()\
3446\009drawLoginWin()\
3447\009local _, b, x, y = os.pullEvent(\"mouse_click\")\
3448\009if b == 1 and x == 51 and y == 1 then --Exit the app\
3449 return\
3450\009 \
3451\009elseif y >= 1 and y <= 2 then --Just a general click on the top bar, so we need to handle it and then redraw it\
3452\009 topWinHandle(x, y)\
3453\009 drawTopWin(topWinPage, topWinPosition)\
3454\009end\
3455 end\
3456end\
3457\
3458\
3459\
3460main()",
3461 [ "BASE/programs/console" ] = "--[[\
3462 BASE Console, version 1.0.0\
3463 This is intended for complicated tasks which\
3464 otherwise may not be possible with the GUI.\
3465 \
3466 Copyright (C) Sam Gunner, 2016.\
3467 Licensed under Creative Commons BY-NC-SA 4.0\
3468]]--\
3469\
3470local oldTermClear = term.clear\
3471local currentDir = \"/\"\
3472local clearedScreen = false\
3473\
3474term.clear = function() \
3475\009oldTermClear()\
3476\009clearedScreen = true\
3477end\
3478\
3479local functions = {\
3480\009clear = function()\
3481\009\009term.setBackgroundColor(colors.white)\
3482\009\009term.setTextColor(colors.black)\
3483\009\009term.clear()\
3484\009\009term.setCursorPos(1, 1)\
3485\009clearedScreen = false\
3486\009end,\
3487}\
3488\
3489-- Truncates an array\
3490function transformArray(arr, from, to)\
3491\009arrayToReturn = {}\
3492\009\
3493\009for i = from, to do\
3494\009\009arrayToReturn[i - from + 1] = arr[i]\
3495\009end\
3496\
3497\009return arrayToReturn\
3498end\
3499\
3500local input = \"\"\
3501local inputTable = {}\
3502os.pullEvent()\
3503\
3504function mainLoop()\
3505 \009functions.clear()\
3506\
3507\009while true do\
3508\009\009write(currentDir .. \"> \")\
3509\009\009input = read() -- Get raw command from user\
3510\009\009inputTable = base.text.split(input, \" \")\
3511\009\009if (functions[inputTable] ~= nil) then\
3512\009\009\009functions[inputTable](unpack(transformArray(inputTable, 2, #inputTable)))\
3513\
3514\009\009\009if clearedScreen then\
3515\009\009\009\009functions.clear()\
3516\009 \009\009end\
3517\
3518\009\009else\
3519\009\009\009print(\"Command '\" .. inputTable .. \"' not found.\")\
3520\009\009end\
3521\009end\
3522end\
3523\
3524base.gui.flash(colors.black)\
3525local ok, err = pcall(mainLoop)\
3526if not ok then\
3527 \009term.setTextColor(colors.red)\
3528 \009write(err)\
3529end\
3530term.clear = oldTermClear",
3531 [ "BASE/programs/base_settings" ] = "--[[\
3532 BASE settings app\
3533]]--\
3534\
3535function drawMain(tabNum)\
3536 term.setBackgroundColor(base.system.systemVariables.secondaryColor)\
3537 term.clear()\
3538 term.setTextColor(base.system.systemVariables.inverseTextColor)\
3539 paintutils.drawLine(1, 1, 51, 1, base.system.systemVariables.mainColor)\
3540 paintutils.drawLine(1, 2, 51, 2, base.system.systemVariables.mainColor)\
3541 base.text.ctxt(\"Settings\", 1)\
3542 base.text.ptxt(\"Personalisation\", 1, 2) -- From 1 to 15 (16)\
3543 base.text.ptxt(\"Account\", 18, 2) -- From 18 until 24\
3544 base.text.ptxt(\"About\", 26, 2) -- From 26 until 30\
3545 base.text.ptxt(\"Software Used\", 32, 2) -- From 32 to 44\
3546\
3547 term.setTextColor(colors.red)\
3548 base.text.ptxt(\"x\", 51, 1)\
3549 term.setTextColor(colors.black)\
3550 term.setBackgroundColor(colors.lightGray)\
3551\
3552 if tabNum == 1 then -- The personalisation tab is active\
3553 base.gui.halfButtonLargeLeft(4, \"Main Colour\", base.system.systemVariables.mainColor)\
3554 base.gui.halfButtonLargeRight(4, \"Secondary Colour\", base.system.systemVariables.secondaryColor)\
3555 base.gui.halfButtonLargeLeft(8, \"Third Colour\", base.system.systemVariables.thirdColor)\
3556 base.gui.halfButtonLargeRight(8, \"Primary Text Colour\", nil, base.system.systemVariables.primaryTextColor)\
3557\
3558 elseif tabNum == 2 then\
3559 base.gui.largeButton(4, \"Change Password (NYI)\", colors.red)\
3560\009base.gui.largeButton(8, \"Change Username (NYI)\", colors.blue)\
3561\009\
3562 elseif tabNum == 3 then\
3563 term.setTextColor(colors.black)\
3564 base.text.ctxt(\"About your installation of BASE\", 4)\
3565 base.text.ctxt(\"-------------------------------\", 5)\
3566 \
3567 base.text.ctxt(\"base.system.version\", 7)\
3568 base.text.ctxt(base.system.version, 8)\
3569 base.text.ctxt(\"base.system.currentUser.name\", 10)\
3570 base.text.ctxt(base.system.currentUser.name, 11)\
3571 base.text.ctxt(\"CC Version\", 13)\
3572 base.text.ctxt(os.version(), 14)\
3573\009\
3574 elseif tabNum == 4 then\
3575\009term.setTextColor(colors.black)\
3576\009base.text.ctxt(\"Third Party Software Used\", 4)\
3577\009base.text.ctxt(\"-------------------------\", 5)\
3578\009base.text.ctxt(\"SHA256 API by GravityScore\", 7)\
3579\009base.text.ctxt(\"JSON API by ElvishJerricco\", 8)\
3580\009base.text.ctxt(\"Framebuffer API by Lyqyd\", 9)\
3581 end\
3582end\
3583\
3584function mainLoop()\
3585 local pageNum = 1\
3586\
3587 while true do\
3588 drawMain(pageNum)\
3589 local _, button, x, y = os.pullEvent(\"mouse_click\")\
3590 if button == 1 then\
3591 if x == 51 and y == 1 then\
3592 return\
3593\
3594 elseif x>=1 and x<=15 and y==2 then --Personalisation\
3595 pageNum = 1\
3596\
3597 elseif x>=18 and x<=24 and y==2 then --Account\
3598 pageNum = 2\
3599\009\009\
3600\009 elseif x>=26 and x<=30 and y==2 then --About\
3601\009\009pageNum = 3\
3602\009\009\
3603\009 elseif x>=32 and x<=44 and y==2 then\
3604\009\009pageNum = 4\
3605 end\
3606 end\
3607 end\
3608end\
3609\
3610mainLoop()",
3611 [ "BASE/.git/logs/HEAD" ] = "0000000000000000000000000000000000000000 12513210bfaef59ba5e8e34960cce7aa217f56b4 Sam Gunner <sam> 1504474619 +0100\009commit (initial): Added operating system in its current state",
3612 [ "BASE/.git/objects/9e/20c43c97fa471d3832fb1da646aab257291c19" ] = "x\001+)JMU07c040031QH??/??)Md(?x???%?\012&g\021?8+?T??\008U???W?ZQ\018???W?`pv?~?!??~?tY???t?g??>\000\012?!?",
3613 [ "BASE/.git/objects/96/5bf9039e50bbff994d46b7976f713be76eac08" ] = "x\001mTQk?@\012??W???f??1??A?2(c,??\008y?8J}?|gt?f???}:;v?n?????I??+?^^]???B\000?????Y?)<!9e\
3614L???o?r\016\030??q\
3615\027KP?????^???]????WH;?\016j?\007c=?\016\026?Zi???\0210\002?\127}?\025?Oa?=???C\\$0?5?? ?py1?\028@\015?D?8S??\009\
3616B??\019?g]3k???}/??\
3617|b??e?\009?m)5X??#?FIp\
3618???e8\028??\008???????d0\007\008?g%!\026??H?P??{?????8\001\017??\019\017u9N\002xjQp?\006^???@?\007?YL\017E]6??V??G?\\za???\012o?s?=r?\0177???\012???9\":J???P??,??.??0M??\000o???GL=\021/B\012???4?uP?\016?},???![??-?????O?-?\006>??HDA7*?y\000??2?3?BA???\007?.\025?\011?\020??\016\017?\001?\\N??L?z??\012??\012s\025???.oZ??x????Z*?`m?6\024G?z??MD?n?\017???\017??>?O???\011LB?\007\022,?5?#??\030=??????\
3619?\014@?\006?@q%\029?'?;^/\031w?R?\028\002o \030(???%?^?Q:\009?e8f?_T??%\017?\025?1\014o\\\
3620??$\009?sA?7???\004???klWo\015#???u?n?]}???7Z?j??A?????\020\022??\021??0?D0??9??L???W?\031???A?C?`I'???=]Y?\023\030?\005",
3621 [ "BASE/apis/experimental/window_manager.lua" ] = "--[[\
3622 Experimental Window Manager for BASE\
3623]]--",
3624 [ "BASE/system/users" ] = "{\
3625 {\
3626 name = \"s\",\
3627 salt = \"Xufuhzsrcc\",\
3628 password = \"4062255bddcc262353980900082f2d82001725242ba51b56402b56b97c6f9465\",\
3629 color = 2048,\
3630 },\
3631 {\
3632 name = \"SGunner2017\",\
3633 salt = \"UEUceBJeyX\",\
3634 password = \"2da77ebe4397a6a50a4203fd7b432dce25a04b7ad4001ecc82dde39700a6acdf\",\
3635 color = 2048,\
3636 },\
3637 {\
3638 name = \"SGunner2015\",\
3639 salt = \"DwKnpOhhId\",\
3640 password = \"27dbe6cc8b846feb9430872e27af1497745c2b0779aaa8d92520f2f34e769c97\",\
3641 color = 2048,\
3642 },\
3643 {\
3644 name = \"SGunner2017\",\
3645 salt = \"47UYTwcefu\",\
3646 password = \"3a650b5141f67e41d84d7cf00d93d7fffd44c89b35815a37b527015adeb47778\",\
3647 color = 2048,\
3648 },\
3649 {\
3650 name = \"lauren\",\
3651 salt = \"GZzFDFIUsM\",\
3652 password = \"04b7f4cc3698937ac4e30a9c24ba751fac8fd705cfe42db66f8f16aa182dee0d\",\
3653 color = 2048,\
3654 },\
3655}",
3656 [ "BASE/.git/refs/heads/master" ] = "12513210bfaef59ba5e8e34960cce7aa217f56b4",
3657 [ "BASE/.git/objects/50/0945ece9d8bebc239ea722c87d90c05f592d2b" ] = "x\001K??OR01`H3\000\003.\008e??f?\006\002 \026\004?4\000 ?\012\016",
3658 [ "BASE/.git/objects/21/c882c388e8154ae277ebc684d4a9e9c6da4450" ] = "x\001K??OR047b??RP((??M,?\012I?(q???/R?U0627??\001??&f??\004\
3659??B???y)@\
36600q#S3????\020??!H$3=/?(5>\029hYb\014?T%=????\018???^zf\009D\026??r?????R??S?\029\0044?\022\000??8N",
3661 [ "BASE/.git/objects/a7/c2266321d9a3ecbaac6719220ca1d4dbcc490b" ] = "x\001]RMk?0\016????\006b?)!?-8????m\
3662a?l????d???w$'K?m?\027??y?\\?p???P?]\005<LF3?%?0???f?E\009?`f?,??\001????\005??????9?a???\014saI??H'2???`?\008&=?J\008?0??}:0V?%?z??{?W??????mO>_????6?f{\020wa\028}??c????\
3663n?????\018c?}?6????\016?Tiu)?.??0Q<R??4\005Q?\006\007?I=\017?:1??)1?j??H)]?\"L\027?X?>\019k??E????|/\027x?rf/????V???JR??b\014x?).??Y??/?Rm?U\006?`????\030?5h'!?jgXI?\023?i????x???v??y,3???K?Z??&h?A~?H?\006???3Ru)??T?\029?7???????^?\002?\
3664?n",
3665 [ "BASE/.git/objects/5d/eba64b2ebe67582ad48df5bbcafc0fb240dcdd" ] = "x\001K??OR01d0\001\002.C(??\000\000?)\009G",
3666 [ "BASE/.git/objects/86/1ed63ba298e1d3dd57815a07237b70fcee3feb" ] = "x\001?Z[s??\021??+v?\015$?$URRlgLgl?M?8?=R??v&\003?K\002\021\008?\000h????9gw??QR'\015??\"\008?=??U?^?'O\030????T?To2??'????6?\023Q??8\
3667\022?n???8V*Z?e>?7Q?\027?q??&??\127???D??Zg'???\006?\008u??\
3668?? V!0\003.??\027j?zYop|??\024?\023???\022Q???I??(???u?\028g:X<???\000K??<Ns??8?L\018???????\022??\031W;\002\009?,*t??9?\022??\"????e²???H)o????\015????1?/u{??E??V?Z\005???8??`~???m?x??i???|?\011A?[9?u???%?%?V\001???L???M??}??E\016?:S????H??YN???X?\011??\000???tPcz\030????d??f\017@!?V???\029pA5aQl?+\
3669jt????n?\027o???WQ2???,??p?U4{?????w??\029?l?\017???\002\014h??gF?y?}???????]?!C?^?y????]X|]\020???q?E??EB?Z:?<?t??\018?\023\008?t\002?;?/?\011??\002?J?\024?3??Aay??+r<r??6?tR@?G?;?(??\014???(??ou'\001??$?\000??HG?E?\007F[v\000?\127\006jr_T\002\127X???e?1\007\001pO???P]m?\"M??f??\016,??m\028??D????6???h~M???OgS?7?W\024`{???D\016`\
3670??#???\020E?e?n\025??351???K?x$\012\007\009!?????:U?t?vAR(?\003?^G?4o?uPDs%??\"?\027?E\015?\
3671N\024??\019?\012??\023@\024\005IW?_\006??\
3672?O\004\002?????}? ?\012(\027??@\\?a??\020?y?\011\127l?R??XXt@???v7?H????\005M?&K?#??m????\024????y!?D????t?%?{??\021??fy??MsrG?L\002?d\017\028???oA?N\011??w??`?T!?\022????e????5G\020n??R?\004?T?\008#.W????H\020\020?7\008%&\005/\016?_G??=Fz????\004;?&?e?@?ei\023?2?T4#|S?HA???PE????\012?8Z??7Y?'nIR?\004\0278?L\014a\003O??\011\031?????\005M?t?%\025??$??j?i??\01118???s2.HM?3??M??0?a?\019?x?@s???????BQ??????*AX?(\024\"???g?s?@??+??S\019+?@??&??\005??\011??L??0I?j??(X?Ho??'?_???=???r?Xi\002V??+??u?b?A?\000??E?\"??(?Q?1AWk ????M?M^X????o+#?&?E????\128?t-T%?2'\"#8x?~c\006\015\
3673\022\\?V9??{?r?z8?\005??\029$???\031\005???__??\026\025????`%??jd?*\022Tî?gT\007?]??\021\017\008?-????H?O5\026?\011=O?E??\017x?\
36748\0222?(?o?\"???3?853?}?nc?????P\001U??Z?\004;R?\030Kj\028?:\\\012?G??\000R\027&z?\018?H0H_EH??O?\014\022\011&A\024\016?\030?\014???? ?O\017\\?z\012???;!?J?\019???DAW\"??\017??^\"?4?a\
3675n2fGd%`0\"?h??????4)?FXR?]a2:\001?:_??N?\007\018D??\0308?l?dn????5\031?_????\006y???U??fF x$????Vm\029??\009P??j!?_?\015?k\002>\014?.??\127??e??#??\005\001?\030#@gC\012TY8?\011?\009\
3676?\
3677\015\006QucB[???R??%r?\012\"?x?-??-a??o0!P??7??2V\022T\0250q?\030\029`?)?O`?h4?.c\0163RB\127??M?D\031\023b[?\026?P@?????2?\023?lP???G??b?\023?r'TFM?D?(???:?p??Nq\\?Ld\012?9?\0068????\028 6?????u\016\022}3\015\018Z35?K\007a??*??^?AK? NQ?????Y\0253?\0146?\031)\020?3??N?P?rW?/?*??6n?e?n?\005??\0092?`??]\016\021\127K???/9y?LR-Q?-?r?>a?\015\030?5+\\Gf??s\020æ*~:;????)\023????'~,\019(c;?B*mkX?k??6?Y\027N?\
3678?A?q lZ??&]\030n\023\0096?n??QS\025 kQBu??BWIxqC\022T?!????^?hj2vd?#j?a6??????\021WjZ?(\008a\127\
3679?\003??s?\\\009\016??K\012G1_??\002???\028??????S?\021?\004)?\004\016?\012?p\005\029??\025_?\028|?);\022?\024????\016\019?U?\016?AH]?C?\009?\020u?Y?7?\003??\020?1???5???h??#?S?x??\017?5?c??\009?Q\000?J??\018s?A?J\016(o,_[]?t?v\00493~???\029]??\
3680/??+?\017w?<????V\011\018\030{?>&M\029Ê@K*??\018\
3681U\0018??k? ???IE?\018z\
3682%?6Z\005wS\
36830????cop\008?j??-??<?\016?[\024\028????!X???Q?R\023?Z}?gE\031{yY?+\018??\012?n\009;b??C?7??+?eE??\015\027{g.?#?6c??\026???\022??4?~??24M\0222C?R\0168\
36846+\021?\022N??F?\"\008L?@_?Z??q?%cx0???<?????_?\005?[??? U??R#?i1???#?\024??~RT?K?\
3685!)?t_\023?Z\023!??\014?\009j???j?^?qa??b a??\007->`e??p,???h$rU\026i'Z?)?ZD%l?\017?)????\026???y??)?$??\018#??\025?S\001?\003\\\
3686\015L???8\014?r?\023!???????????\015?4????gE8?P9?tDL???G?Is?cIW\018v??=0.??0D??O?`???f2.F,G>????<GZ?s$?$?D???roZ?\011????\031U*Nf?OP\025>?sS?G\026??g??\0230?\003C\015\149?g???\020ER???w/\030?w?9??Ac?\004;?\023+1??j?(d?&??r??2\008?+??\023????9?&?Vvb????ae\019??¨??\\W|~???8~\
3687[N??\005??|????Hh\020?^?\027?2g\006?\009?D\028/?????<???\014?q7??*8??????#??p\003???w'????\000?`\\\0128V??J\023H??\004(?7`m}???\024?_:????N?~??\018?\008??Y?\029\
3688??\023??k??[y??\007'R<\\?I\026??\"?\029?L???'?s;\"z?h???\026??\024\017???x???v?\000D?\031???\005\014??-\027\
3689??c?\027\012??@?\019?;?L??H?J?(q??H|?Y?\0087?V\031?\011??x?\\??\028Q^W?,XC07[\017M??h?i??$??#?\003?q?8#t\012?\030??\007?]\003\128?\127?\002?????`?\029zm???\019>???\001gqJ?<???V??^c??{?\027?T???Y?^???;\021?E:\002\028f\028^h/?\031\006?\020.F?6?\005?\008}?5p\006\027Rl\018???\004^S\020???z?\006\\?O?>???vv?I\
3690?=u?\024Np??\031:??x\005??NdAj??\002 \026?\030",
3691 [ "BASE/.git/objects/bf/9ea78d7ce46635524bc39b2fb2c705ae6bae51" ] = "x\001K??OR05`0\000?4\016???\002?\001\000k~\011i",
3692 [ "BASE/apis/text.lua" ] = "-- Advanced textutils.unserialise: also includes variables.\
3693function unserialise(s)\
3694 local func = load( \"return \" .. s, \"unserialize\", \"t\", _G )\
3695 if func then\
3696 local ok, result = pcall(func)\
3697 if ok then\
3698 return result\
3699 end\
3700 end\
3701 return nil\
3702end\
3703\
3704-- Write text in a certain place on the screen\
3705function ptxt(txt, x, y)\
3706\009term.setCursorPos(x, y)\
3707\009write(txt)\
3708end\
3709\
3710-- Alias for ptxt\
3711function pointWrite(txt, x, y)\
3712\009ptxt(txt, x, y)\
3713end\
3714\
3715-- Center text on the screen at a specific y value.\
3716function centerText(text, y)\
3717 local log = base.log.new(\"/path.txt\")\
3718 log:clear()\
3719 log:log(tostring(text))\
3720 local w, h = term.getSize()\
3721 local x = ((w/2) - (#text/2)) + 1\
3722 term.setCursorPos(x, y)\
3723 write(text)\
3724end\
3725\
3726-- Alias for centerText\
3727function ctxt(text, y)\
3728\009centerText(text, y)\
3729end\
3730\
3731-- More advanced version of ctxt; you can specify bounds to center it within.\
3732function ctxtAdvanced(txt, x, y, xF) -- Where x is the start of the zone and xF is the finishing point of the zone.\
3733\009local width = xF - x\
3734\009local xFin = x + ((width/2) - (#txt/2)) + 1\
3735\009term.setCursorPos(xFin, y)\
3736\009write(txt)\
3737end\
3738\
3739-- Shuffle the contents of an array.\
3740function shuffleArray(tbl)\
3741\009for i = 1, #tbl*2 do -- repeat this for twice the amount of elements in the table, to make sure everything is shuffled well\
3742\009\009local a = math.random(#tbl)\
3743\009\009local b = math.random(#tbl)\
3744\009\009tbl[a], tbl[b] = tbl[b], tbl[a]\
3745\009end\
3746\009return tbl\
3747end\
3748\
3749-- Turn a string into an array of characters.\
3750function explode(str)\
3751\009local tbl = {}\
3752\009local len = #str\
3753\009for i = 1, len do\
3754\009\009tbl[i] = string.sub(str, i, i)\
3755\009end\
3756\009return tbl\
3757end\
3758\
3759-- Split a string up by a certain character\
3760function split(text, charToDo)\
3761\009local reTbl = {}\
3762\009reTbl = string.match(text, \"([^\" .. charToDo .. \"]+)\")\
3763\009return reTbl\
3764end",
3765 [ "BASE/.git/objects/ba/69f5afcaf4bf5d4824c73977cec636dcca5f90" ] = "x\001+)JMU0?4d040031QHJ,N???K?gX?\022|?g???\026z?S??%2E?\006???????b\006q+_?m??w???*??`Z?kYd?%??E\012am?i^+&{??M?a??-??<^\007?(9??8?'?aZ?O?y\001????u?>=???y?\026\014????????\"???Y??+?x}?wSi}??v\025?z!TM\026C????Tk?\011Z>B??'L?8?i?Jf2??]?^4????Q???\005\127??61\000\002?L?\003\024\014??i??|\027}}???\030IN???\
3766\016??????\028??:?ww??1??9f<}???<\127\015??\026_?X?\029?????\014tc??\030/I???\029?Y?W\1278???<T]iAJbIj|rj^IQ*??Cj?7\023??&]R?g??g<?\001?W?X",
3767 [ "BASE/.git/objects/d4/19981ad2ca2a3bb220b543ac94d772f31f5714" ] = "x\001K??OR01a0\004\001\003\019.0M?\001\000\026?\009?",
3768 [ "BASE/apis/gui.lua" ] = "-- Draws a filled rectangle of specified dimensions and colour.\
3769function drawBox(xStart, yStart, xFin, yFin, backgroundCol)\
3770 for i = yStart, yFin do\
3771 paintutils.drawLine(xStart, i, xFin, i, backgroundCol)\
3772 end\
3773end\
3774\
3775-- Sets the screen a specific color\
3776function flash(color)\
3777 term.setBackgroundColor(color)\
3778 term.clear()\
3779end\
3780\
3781--Draws a box witha black line around it that makes it look like a shadow.\
3782function drawBoxWithShadow(xStart, yStart, xFin, yFin, backgroundCol, shadowCol)\
3783 local shadowCol = colors.black\
3784 \
3785 drawBox(xStart, yStart, xFin, yFin, backgroundCol)\
3786 paintutils.drawLine(xFin + 1, yStart + 1, xFin + 1, yFin + 1, shadowCol)\
3787 paintutils.drawLine(xStart + 1, yFin + 1, xFin + 1, yFin + 1, shadowCol)\
3788end\
3789\
3790-- Draws a basic popup window with specified title background color.\
3791function drawPopupSmall(titleBackCol)\
3792 if titleBackCol == nil then\
3793 local titleBackCol = colors.gray\
3794 end\
3795 drawBoxWithShadow(2, 8, 49, 12, colors.lightGray)\
3796 paintutils.drawLine(2, 8, 48, 8, titleBackCol)\
3797 paintutils.drawPixel(49, 8, colors.red)\
3798 term.setCursorPos(49, 8)\
3799 term.setTextColor(colors.white)\
3800 write(\"x\")\
3801end\
3802\
3803-- Brings up a simple alert window, with one option: \"Okay\" Designed to inform the user of something happening (Uses mouse_click)\
3804function alert(text, title, textCol, titleBackCol) \
3805\
3806 drawPopupSmall(colors.gray)\
3807 term.setBackgroundColor(colors.gray)\
3808 term.setTextColor(colors.white)\
3809 base.text.centerText(title, 8)\
3810 term.setTextColor(colors.black)\
3811 term.setBackgroundColor(colors.lightGray)\
3812 base.text.centerText(text, 10)\
3813 term.setTextColor(colors.white)\
3814 paintutils.drawLine(3, 12, 48, 12, colors.green)\
3815 base.text.centerText(\"Okay\", 12)\
3816 while true do\
3817\009local evt, b, x, y = os.pullEvent()\
3818\009if evt == \"mouse_click\" then\
3819\009\009if b == 1 then\
3820\009\009\009if x == 48 and y == 8 then\
3821\009\009\009\009paintutils.drawPixel(48, 8, colors.gray)\
3822\009\009\009\009base.text.ptxt(\"x\", 48, 8)\
3823\009\009\009\009sleep(.2) --Sleep for a bit to animate the button pressing\
3824\009\009\009elseif x>=3 and x<=48 and y == 12 then\
3825\009\009\009\009paintutils.drawLine(3, 12, 48, 12, colors.gray)\
3826\009\009\009\009base.text.ctxt(\"Okay\", 12)\
3827\009\009\009\009sleep(.2) --Sleep for a bit to animate the button pressing\
3828\009\009\009end\
3829\009\009\009return\
3830\009\009end\
3831\009end\
3832 end\
3833end\
3834\
3835-- Brings up a simple window asking the user if they want to do something. The two options are either \"yes\" or \"no\" (Uses mouse_click)\
3836function getBoolean(text, title, textCol, titleBackCol)\
3837 if titleBackCol == nil then\
3838 local titleBackCol = colors.gray\
3839 end\
3840 if textCol == nil then\
3841 local textCol = colors.black\
3842 end\
3843 drawPopupSmall(titleBackCol)\
3844 term.setBackgroundColor(titleBackCol)\
3845 base.text.ctxt(title, 8)\
3846 term.setBackgroundColor(colors.lightGray)\
3847 term.setTextColor(textCol)\
3848 base.text.centerText(text, 10)\
3849 drawBox(3, 12, 25, 12, colors.green)\
3850 base.text.ptxt(\"Yes\", 12, 12)\
3851 drawBox(26, 12, 48, 12, colors.red)\
3852 base.text.ptxt(\"No\", 37, 12)\
3853\009repeat\
3854 \009local _evt, b, x, y = os.pullEvent(\"mouse_click\")\
3855\009\009if _evt == \"mouse_click\" then\
3856\009\009\009if b == 1 then\
3857\009\009\009\009if x == 48 and y == 8 then\
3858\009\009\009\009\009paintutils.drawPixel(48, 8, colors.gray)\
3859\009\009\009\009\009base.text.ptxt(\"x\", 48, 8)\
3860\009\009\009\009\009sleep(.2)\
3861\009\009\009\009\009return false, \"x\"\
3862\009\009\009\009elseif x >= 3 and x<=25 and y == 12 then\
3863\009\009\009\009\009paintutils.drawLine(3, 12, 25, 12, colors.gray)\
3864\009\009\009\009\009base.text.ptxt(\"Yes\", 12, 12)\
3865\009\009\009\009\009sleep(.2)\
3866\009\009\009\009\009return true, \"yes\"\
3867\009\009\009\009elseif x >= 26 and x <= 48 and y == 12 then\
3868\009\009\009\009\009paintutils.drawLine(26, 12, 48, 12, colors.gray)\
3869\009\009\009\009\009base.text.ptxt(\"No\", 37, 12)\
3870\009\009\009\009\009sleep(.2)\
3871\009\009\009\009\009return false, \"no\"\
3872\009\009\009\009end\
3873\009\009\009end\
3874\009\009end\
3875\009until _evt == \"mouse_click\"\
3876\
3877end\
3878\
3879-- Draws a drop-down context menu with clickable options for the user\
3880-- Returns the option number clicked\
3881function dropdown(x, y, opts)\
3882 if y + #opts > 19 then\
3883\009opts = base.utils.reverseArray(opts)\
3884 term.setTextColor(colors.white)\
3885\009for i = 1, #opts do\
3886 paintutils.drawLine(x, y - i - 1, x + 13, y - i - 1, colors.gray)\
3887\009 base.text.ptxt(opts[#opts - i + 1], x, y - i - 1, x + 13, y - i - 1)\
3888\009end\
3889\
3890\009paintutils.drawLine(x + 14, y - 1, x + 14, y - #opts, colors.black)\
3891\009paintutils.drawLine(x + 1, y - 1, x + 14, y - 1, colors.black)\
3892\
3893\009while true do\
3894 local event, button, xP, yP = os.pullEvent('mouse_click')\
3895\009 if event == \"mouse_click\" then\
3896 return y - yP - 1\
3897\009 end\
3898\009end\
3899\
3900 else\
3901\
3902\009term.setTextColor(colors.white)\
3903\009for i=1, #opts do\
3904\009\009paintutils.drawLine(x, (y+i)-1, x+13, (y+i)-1, colors.gray)\
3905\009\009base.text.ptxt(opts[i], x, (y + i) - 1)\
3906\009end\
3907\009\
3908\009paintutils.drawLine(x + 14, y + 1, x + 14, y + #opts, colors.black)\
3909\009paintutils.drawLine(x + 1, y + #opts, x + 14, y + #opts, colors.black)\
3910\009while true do\
3911\009\009local event, button, xP, yP = os.pullEvent('mouse_click')\
3912\009\009if event == \"mouse_click\" then\
3913\009\009\009return (yP - y) + 1\
3914\009\009end\
3915\009end\
3916 end\
3917end\
3918\
3919function largeButton(y, text, mainCol, textCol)\
3920 if mainCol == nil then\
3921 mainCol = base.system.systemVariables.thirdColor\
3922 end\
3923 if textCol == nil then\
3924 textCol = base.system.systemVariables.primaryTextColor\
3925 end\
3926 for i = y, y + 2 do\
3927 paintutils.drawLine(3, i, 49, i, mainCol)\
3928 end\
3929 term.setTextColor(textCol)\
3930 base.text.ctxt(text, y + 1)\
3931end\
3932\
3933function halfButtonLargeLeft(y, text, mainCol, textCol) -- Where y is the y value where the button should *start*. text is the text that will be displayed on the button\
3934 if mainCol == nil then\
3935 mainCol = base.system.systemVariables.thirdColor\
3936 end\
3937 if textCol == nil then\
3938 textCol = base.system.systemVariables.primaryTextColor\
3939 end\
3940 for i = y, y + 2 do\
3941 paintutils.drawLine(3, i, 23, i, mainCol)\
3942 end\
3943 term.setTextColor(textCol)\
3944 base.text.ctxtAdvanced(text, 3, y + 1, 23) -- Centers the text upon the button\
3945end\
3946\
3947function halfButtonLargeRight(y, text, mainCol, textCol)\
3948 if mainCol == nil then\
3949 mainCol = base.system.systemVariables.thirdColor\
3950 end\
3951 if textCol == nil then\
3952 textCol = base.system.systemVariables.primaryTextColor\
3953 end\
3954 for i = y, y + 2 do\
3955 paintutils.drawLine(27, i, 49, i, mainCol)\
3956 end\
3957 term.setTextColor(textCol)\
3958 base.text.ctxtAdvanced(text, 27, y + 1, 49)\
3959end\
3960\
3961-- To be replaced with a more efficient method of coding this function in the future.\
3962function chooseColor() -- Gets the user to choose from a list of colours and then returns it\
3963 drawPopupSmall() -- Create the window\
3964 paintutils.drawLine(2, 10, 4, 10, colors.white)\
3965 paintutils.drawLine(5, 10, 7, 10, colors.orange)\
3966 paintutils.drawLine(8, 10, 10, 10, colors.magenta)\
3967 paintutils.drawLine(11, 10, 13, 10, colors.lightBlue)\
3968 paintutils.drawLine(14, 10, 16, 10, colors.yellow)\
3969 paintutils.drawLine(17, 10, 19, 10, colors.lime)\
3970 paintutils.drawLine(20, 10, 22, 10, colors.pink)\
3971 paintutils.drawLine(23, 10, 25, 10, colors.gray)\
3972 paintutils.drawLine(26, 10, 28, 10, colors.lightGray)\
3973 paintutils.drawLine(29, 10, 31, 10, colors.cyan)\
3974 paintutils.drawLine(32, 10, 34, 10, colors.purple)\
3975 paintutils.drawLine(35, 10, 37, 10, colors.blue)\
3976 paintutils.drawLine(38, 10, 40, 10, colors.brown)\
3977 paintutils.drawLine(41, 10, 43, 10, colors.green)\
3978 paintutils.drawLine(44, 10, 46, 10, colors.red)\
3979 paintutils.drawLine(47, 10, 49, 10, colors.black)\
3980\
3981 -- The colors have been drawn.\
3982 local _, b, x, y = os.pullEvent(\"mouse_click\")\
3983 if b == 1 then\
3984 if x>= 2 and x<=49 then -- It is within the bounds of the popup\
3985 if x>= 2 and x<=4 then\
3986 return colors.white\
3987 elseif x>=5 and x<=7 then\
3988 return colors.orange\
3989 elseif x>=8 and x<=10 then\
3990 return colors.magenta\
3991 elseif x>=11 and x<=13 then\
3992 return colors.lightBlue\
3993 elseif x>=14 and x<=16 then\
3994 return colors.yellow\
3995 elseif x>=17 and x<=19 then\
3996 return colors.lime\
3997 elseif x>=20 and x<=22 then\
3998 return colors.pink\
3999 elseif x>=23 and x<=25 then\
4000 return colors.gray\
4001 elseif x>=26 and x<=28 then\
4002 return colors.lightGray\
4003 elseif x>=29 and x<=31 then\
4004 return colors.cyan\
4005 elseif x>=32 and x<=34 then\
4006 return colors.purple\
4007 elseif x>=35 and x<=37 then\
4008 return colors.blue\
4009 elseif x>=38 and x<=40 then\
4010 return colors.brown\
4011 elseif x>=41 and x<=43 then\
4012 return colors.green\
4013 elseif x>=44 and x<=46 then\
4014 return colors.red\
4015 elseif x>=47 and x<=49 then\
4016 return colors.black\
4017 end\
4018 end\
4019 end\
4020end\
4021\
4022\
4023-- Shape drawing\
4024function rect(xStart, yStart, width, height, color, filled)\
4025 local xFin = xStart + width - 1\
4026 local yFin = yStart + height - 1\
4027\
4028 if color == nil then\
4029 color = colors.lightGray\
4030 end\
4031 if filled == nil then\
4032 filled = false\
4033 end\
4034\
4035 if not filled then\
4036 paintutils.drawLine(xStart, yStart, xFin, yStart, color)\
4037 paintutils.drawLine(xStart, yStart, xStart, yFin, color)\
4038 paintutils.drawLine(xStart, yFin, xFin, yFin, color)\
4039 paintutils.drawLine(xFin, yStart, xFin, yFin, color)\
4040 else\
4041 for i = yStart, yFin do\
4042 paintutils.drawLine(xStart, i, xFin, i, color)\
4043 end\
4044 end\
4045end\
4046\
4047-- This draws the standard header for all base apps\
4048function drawStandardHeader(title)\
4049 local w, h = term.getSize()\
4050 drawBox(1, 1, 51, 2, colors.gray)\
4051 term.setTextColor(colors.white)\
4052 base.text.ctxt(title, 1)\
4053 term.setTextColor(colors.red)\
4054 base.text.ptxt(\"x\", 51, 1)\
4055end",
4056 [ "BASE/.git/refs/remotes/origin/master" ] = "12513210bfaef59ba5e8e34960cce7aa217f56b4",
4057 [ "BASE/files/images/os_startup_splash" ] = " fffffff fffffff fffffff ffffffff\
4058 f f f f f f\
4059 f f fffffff f f\
4060 ffffff f f fffffff ffffffff\
4061 f f f f f f\
4062 f f f f f f\
4063 fffffff f f fffffff ffffffff",
4064 [ "BASE/programs/task_manager" ] = "--[[\
4065 Task Manager App for the BASE operating system\
4066 Allows for the control of apps and processes running on the system\
4067]]\
4068\
4069-- Begin functions\
4070\
4071-- This returns an array of strings, which represnt the names of tasks currently being executed by the kernel.\
4072local function getNamesOfTasks()\
4073 local tasks = base.kernel.getOpenApps()\
4074 return tasks\
4075end\
4076\
4077-- main: this runs the main loop for the program\
4078local function main()\
4079 local topWin = window.create(term.current(), 1, 1, 51, 2)\
4080 local bottomWin = window.create(term.current(), 1, 3, 51, 15)\
4081 local actionsWin = window.create(term.current(), 1, 18, 51, 1)\
4082 local nativeWin = term.current()\
4083 local pos = 1 -- The position of the scrollbar\
4084 base.notifications.newNotification(base.kernel.getCurrentID(), \"Task Manager\", \"Task manager launched\")\
4085\
4086 --drawMain: this draws the main screen of the program (a list of tasks currently being executed by the kernel)\
4087 local function drawMain()\
4088 local tasks = getNamesOfTasks()\
4089\009term.redirect(topWin)\
4090 base.gui.drawStandardHeader(\"BASE Task Manager\")\
4091\
4092\009term.redirect(bottomWin)\
4093 base.gui.flash(colors.white)\
4094\009term.setCursorPos(1, 1)\
4095\009term.setTextColor(colors.black)\
4096\009for i = 1, #tasks do\
4097\009 if i % 2 == 0 then\
4098\009\009paintutils.drawLine(1, i, 51, i, colors.white)\
4099\009\009term.setCursorPos(1, i)\
4100\009 else\
4101\009 paintutils.drawLine(1, i, 51, i, colors.lightGray)\
4102\009\009term.setCursorPos(1, i)\
4103\009 end\
4104 base.text.ptxt(i .. \" | \" .. tasks[i].name, 1, i)\
4105\009 base.text.ptxt(\"->\", 50, i)\
4106\009end\
4107\
4108\009term.redirect(actionsWin)\
4109\009base.gui.flash(colors.white)\
4110\009paintutils.drawLine(2, 1, 7, 1, colors.lightGray)\
4111\009term.setTextColor(colors.black)\
4112\009base.text.ptxt(\"Kill\", 3, 1)\
4113\
4114\009term.redirect(nativeWin)\
4115 end\
4116\
4117 while true do\
4118 drawMain()\
4119 \
4120 local _, button, xP, yP = os.pullEvent('mouse_click')\
4121 if button == 1 and xP == 51 and yP == 1 then --Exit the app\
4122 break\
4123 end\
4124 end\
4125end\
4126\
4127-- End of functions\
4128\
4129main()",
4130 [ "BASE/system/variables" ] = "{\
4131 primaryTextColor = 32768,\
4132 mainColor = 128,\
4133 secondaryColor = 256,\
4134 thirdColor = 1,\
4135 ignore_global = \".DS_Store;.gitignore;.git;.ignore;\",\
4136 inverseTextColor = 1,\
4137}",
4138 [ "BASE/programs/icons/base_info" ] = "888777888\
4139888888888\
4140888777888\
4141888777888\
4142888777888",
4143 [ "BASE/.git/objects/25/7973bbd13d8f2e8c4ae539de0565271832f3c8" ] = "x\001+)JMU044f040031QHIMK,?))f0???????\000?\019??C\012?f??<51\000\002????????????b\006????\030?=y?????;?2?_4?0?????$?\"?\019M?;^?z=*\127}?????n?\004\000\000G?4v",
4144 [ "BASE/apis/sha256.lua" ] = " --[[\
4145\009SHA-256 Lua API\
4146 ]]--\
4147 \
4148 \
4149-- \
4150-- Adaptation of the Secure Hashing Algorithm (SHA-244/256)\
4151-- Found Here: http://lua-users.org/wiki/SecureHashAlgorithm\
4152-- \
4153-- Using an adapted version of the bit library\
4154-- Found Here: https://bitbucket.org/Boolsheet/bslf/src/1ee664885805/bit.lua\
4155-- \
4156\
4157local MOD = 2^32\
4158local MODM = MOD-1\
4159\
4160local function memoize(f)\
4161\009local mt = {}\
4162\009local t = setmetatable({}, mt)\
4163\009function mt:__index(k)\
4164\009\009local v = f(k)\
4165\009\009t[k] = v\
4166\009\009return v\
4167\009end\
4168\009return t\
4169end\
4170\
4171local function make_bitop_uncached(t, m)\
4172\009local function bitop(a, b)\
4173\009\009local res,p = 0,1\
4174\009\009while a ~= 0 and b ~= 0 do\
4175\009\009\009local am, bm = a % m, b % m\
4176\009\009\009res = res + t[am][bm] * p\
4177\009\009\009a = (a - am) / m\
4178\009\009\009b = (b - bm) / m\
4179\009\009\009p = p*m\
4180\009\009end\
4181\009\009res = res + (a + b) * p\
4182\009\009return res\
4183\009end\
4184\009return bitop\
4185end\
4186\
4187local function make_bitop(t)\
4188\009local op1 = make_bitop_uncached(t,2^1)\
4189\009local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)\
4190\009return make_bitop_uncached(op2, 2 ^ (t.n or 1))\
4191end\
4192\
4193local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})\
4194\
4195local function bxor(a, b, c, ...)\
4196\009local z = nil\
4197\009if b then\
4198\009\009a = a % MOD\
4199\009\009b = b % MOD\
4200\009\009z = bxor1(a, b)\
4201\009\009if c then z = bxor(z, c, ...) end\
4202\009\009return z\
4203\009elseif a then return a % MOD\
4204\009else return 0 end\
4205end\
4206\
4207local function band(a, b, c, ...)\
4208\009local z\
4209\009if b then\
4210\009\009a = a % MOD\
4211\009\009b = b % MOD\
4212\009\009z = ((a + b) - bxor1(a,b)) / 2\
4213\009\009if c then z = bit32_band(z, c, ...) end\
4214\009\009return z\
4215\009elseif a then return a % MOD\
4216\009else return MODM end\
4217end\
4218\
4219local function bnot(x) return (-1 - x) % MOD end\
4220\
4221local function rshift1(a, disp)\
4222\009if disp < 0 then return lshift(a,-disp) end\
4223\009return math.floor(a % 2 ^ 32 / 2 ^ disp)\
4224end\
4225\
4226local function rshift(x, disp)\
4227\009if disp > 31 or disp < -31 then return 0 end\
4228\009return rshift1(x % MOD, disp)\
4229end\
4230\
4231local function lshift(a, disp)\
4232\009if disp < 0 then return rshift(a,-disp) end \
4233\009return (a * 2 ^ disp) % 2 ^ 32\
4234end\
4235\
4236local function rrotate(x, disp)\
4237 x = x % MOD\
4238 disp = disp % 32\
4239 local low = band(x, 2 ^ disp - 1)\
4240 return rshift(x, disp) + lshift(low, 32 - disp)\
4241end\
4242\
4243local k = {\
4244\0090x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\
4245\0090x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\
4246\0090xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\
4247\0090x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\
4248\0090xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\
4249\0090x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\
4250\0090x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\
4251\0090xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\
4252\0090x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\
4253\0090x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\
4254\0090xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\
4255\0090xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\
4256\0090x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\
4257\0090x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\
4258\0090x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\
4259\0090x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\
4260}\
4261\
4262local function str2hexa(s)\
4263\009return (string.gsub(s, \".\", function(c) return string.format(\"%02x\", string.byte(c)) end))\
4264end\
4265\
4266local function num2s(l, n)\
4267\009local s = \"\"\
4268\009for i = 1, n do\
4269\009\009local rem = l % 256\
4270\009\009s = string.char(rem) .. s\
4271\009\009l = (l - rem) / 256\
4272\009end\
4273\009return s\
4274end\
4275\
4276local function s232num(s, i)\
4277\009local n = 0\
4278\009for i = i, i + 3 do n = n*256 + string.byte(s, i) end\
4279\009return n\
4280end\
4281\
4282local function preproc(msg, len)\
4283\009local extra = 64 - ((len + 9) % 64)\
4284\009len = num2s(8 * len, 8)\
4285\009msg = msg .. \"\\128\" .. string.rep(\"\\0\", extra) .. len\
4286\009assert(#msg % 64 == 0)\
4287\009return msg\
4288end\
4289\
4290local function initH256(H)\
4291\009H[1] = 0x6a09e667\
4292\009H[2] = 0xbb67ae85\
4293\009H[3] = 0x3c6ef372\
4294\009H[4] = 0xa54ff53a\
4295\009H[5] = 0x510e527f\
4296\009H[6] = 0x9b05688c\
4297\009H[7] = 0x1f83d9ab\
4298\009H[8] = 0x5be0cd19\
4299\009return H\
4300end\
4301\
4302local function digestblock(msg, i, H)\
4303\009local w = {}\
4304\009for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end\
4305\009for j = 17, 64 do\
4306\009\009local v = w[j - 15]\
4307\009\009local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))\
4308\009\009v = w[j - 2]\
4309\009\009w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))\
4310\009end\
4311\
4312\009local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]\
4313\009for i = 1, 64 do\
4314\009\009local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))\
4315\009\009local maj = bxor(band(a, b), band(a, c), band(b, c))\
4316\009\009local t2 = s0 + maj\
4317\009\009local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))\
4318\009\009local ch = bxor (band(e, f), band(bnot(e), g))\
4319\009\009local t1 = h + s1 + ch + k[i] + w[i]\
4320\009\009h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2\
4321\009end\
4322\
4323\009H[1] = band(H[1] + a)\
4324\009H[2] = band(H[2] + b)\
4325\009H[3] = band(H[3] + c)\
4326\009H[4] = band(H[4] + d)\
4327\009H[5] = band(H[5] + e)\
4328\009H[6] = band(H[6] + f)\
4329\009H[7] = band(H[7] + g)\
4330\009H[8] = band(H[8] + h)\
4331end\
4332\
4333function hash(msg)\
4334\009msg = preproc(msg, #msg)\
4335\009local H = initH256({})\
4336\009for i = 1, #msg, 64 do digestblock(msg, i, H) end\
4337\009return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..\
4338\009\009num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))\
4339end",
4340 [ "BASE/core/boot/bootstrap.lua" ] = "--[[\
4341\009Bootstrapper for BASE 2\
4342\009Loads everything into memory and then hands control over to user manager\
4343]]--\
4344\
4345-- Load APIs\
4346shell.run(\"/BASE/core/boot/load_api.lua\")\
4347\
4348-- Initialise debug table\
4349base.debug = {}\
4350base.debug.taskbarIsActive = false\
4351\
4352-- Initialise system API\
4353base.system.init()\
4354\
4355-- Load User Content\
4356base.userContent = base.io.loadTable(\"/BASE/\")\
4357\
4358-- Load system images\
4359base.images = {}\
4360local imgList = fs.list(\"/BASE/files/images\")\
4361for i = 1, #imgList do\
4362\009local img = paintutils.loadImage(fs.combine(\"BASE/files/images\", imgList[i]))\
4363\009print(imgList[i])\
4364\009base.images[imgList[i]] = img\
4365end\
4366\
4367-- Load system icons\
4368base.images.icons = {}\
4369imgList = fs.list(\"/BASE/programs/icons\")\
4370for i = 1, #imgList do\
4371\009local img = paintutils.loadImage(fs.combine(\"BASE/programs/icons\", imgList[i]))\
4372\009base.images.icons[imgList[i]] = img\
4373end\
4374\
4375-- Run user manager and then start the kernel\
4376shell.run(\"/BASE/core/user_login_temp.lua\")\
4377\
4378-- Show splash screen\
4379term.setBackgroundColor(colors.white)\
4380term.clear()\
4381term.setTextColor(colors.black)\
4382base.text.ctxt(\"Welcome to BASE 2!\", 8)\
4383sleep(1)\
4384\
4385-- Replace function\
4386local oldRead = read\
4387read = function(replacement)\
4388\009base.kernel.activateCursorBlink()\
4389\009local text = oldRead(replacement)\
4390\009base.kernel.deactivateCursorBlink()\
4391\009return text\
4392end\
4393\
4394-- In case text API did not load correctly\
4395local function ctxt(text, y)\
4396\009local w, h = term.getSize()\
4397\009local x = (w / 2) - (#text / 2) + 1\
4398\009term.setCursorPos(x, y)\
4399\009write(text)\
4400end\
4401\
4402-- Displays simple error message\
4403local function displayError(err)\
4404\009term.setBackgroundColor(colors.lightGray)\
4405\009term.setTextColor(colors.white)\
4406\009term.clear()\
4407\009ctxt(\"BASE has encountered a serious error\", 6)\
4408\009ctxt(\"and needed to exit.\", 7)\
4409\009ctxt(\"Error message:\", 9)\
4410\009ctxt(err, 11)\
4411\009ctxt(\"BASE will shutdown in 5 seconds\", 13)\
4412\009sleep(5)\
4413end\
4414\
4415-- Run the kernel and catch any error message returned\
4416local returnValue, errorMessage = base.kernel.main() -- Starts the BASE kernel boot process\
4417if not returnValue then\
4418\009displayError(errorMessage)\
4419\009os.shutdown()\
4420else\
4421\009displayError(\"The kernel has exited with an unidentifiable error\")\
4422\009os.shutdown()\
4423end",
4424 [ "BASE/.git/objects/0e/ad44d11877da66999c1e7c3ed38ca96b2646ee" ] = "x\001K??OR01a0?\002.?\020?4 0?B????\000\000M?\012C",
4425 [ "BASE/.git/index" ] = "DIRC\000\000\000\002\000\000\000&Y?u?\026U??V?7?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\001?t??n?????28Po??\002\000\014apis/app_names\000\000\000\000Y?u?\026?tW\"`9\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\020\009$\022fm+z????\031{.}?Y?0?\000\014apis/baseforms\000\000\000\000Y?u?\027??Y?#?\"Fr?\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\"3F\\O[k\011O a?S\019\006\025???lR?\000\008apis/gui\000\000Y?u?\028.~(W\"`?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0030?\017O\017??\014fM?j?/D??E?ji\000\007apis/io\000\000\000Y?u?\029???Y??>\018\003\028?\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000+??Y?&\\?????k2?(???\022?\000\011apis/kernel\000\000\000\000\000\000\000Y?u?\030???W\"^?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\007\028??>????7\027?\006?u\018??.??\023\000\011apis/system\000\000\000\000\000\000\000Y?u?\0319*\000W#??\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\006?p\018\\P?'?????[?~?ce\000\009apis/text\000Y?u?\031???W\"_?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\000?[4???{??\017??\127vv(????\000\011apis/window\000\000\000\000\000\000\000Y?u? ?^pV?n\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\021vr??M???A\0004?!z\009x~$???\000\
4426core/boot.lua\000\000\000\000\000Y?u?!?:TY?pa\030??x\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\000u0?/V?B?N?-\005???\012???\000\017core/context_menu\000Y?u?#???V?{?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\000.]?K.?gX*?????\015?@??\000$files/images/fileexplorer_icon_small\000\000\000\000\000\000Y?u?$;\019?V??D\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0007????|?f5RKÛ/??\005?k?Q\000\030files/images/genericIcon_small\000\000\000\000Y?u?% \019\\V??\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\001\022?@??{na?O\019$$????*???\000\030files/images/os_startup_splash\000\000\000\000Y?u?%?\031\028V?{?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0000\014?D?\024w?f??\030|>??k&F?\000 files/images/settings_icon_small\000\000Y?u?&A?\020V?{?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0007[????R?m?NB7?\002??\016??\000\030files/images/tskmgr_icon_small\000\000\000\000Y?u?&?&?V?{?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0002O\003\030??y?+?\025\003?\009?O/b??\000\031files/images/unknown_icon_small\000\000\000Y?u?(9}\008Y???3?{\028\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\009??\006S????(.?d??\020?\026?(\000\018programs/base_info\000\000\000\000\000\000\000\000Y?u?(?\017,Y?\015\025\000??`\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\009\004\023:M\017????G+?%\021l?????\029\000\022programs/base_settings\000\000\000\000Y?u?(??\008Y?\015b8Q}?\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\
4427?V?)fJ??J?f?8aK\031F?_,\000\018programs/base_tour\000\000\000\000\000\000\000\000Y?u?)?~\020Y?\000?6]?h\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\005\008?[?\003?P???MF??oq;?n?\008\000\016programs/console\000\000Y?u?*?}?Y?c?#O?\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000(A?p?UU??J?oF$???=?\009'q\000\017programs/explorer\000Y?u?+\006?\004Y?c?\001??\012\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\019?wE=*?e;6?*L\018E\015?4?@?\000\
4428programs/f\000\000\000\000\000\000\000\000Y?u?+??tV?+\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000(??\030?;?????W?Z\007#{p????\000\
4429programs/i\000\000\000\000\000\000\000\000Y?u?.\002\003?V?.?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0002?\009??}?#???\
4430?G??D?u?\000\024programs/icons/base_info\000\000Y?u?.NF$V?/\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0007\006\021?$v\019???V\000\017??>???\000\028programs/icons/base_settings\000\000\000\000\000\000Y?u?/Q?@V?>\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0002\009_??xNb???\029 ?E:\"?\000\024programs/icons/base_tour\000\000Y?u?0\0246?W\023?\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0002?ZO\016??D???#S??C\024z???\000\022programs/icons/console\000\000\000\000Y?u?0l$\028V??D\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0001?\025?\026??*;? ?C???r?\031W\020\000\023programs/icons/explorer\000\000\000Y?u?0??\020V?-y\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\000-P\009E????#??\"?}??_Y-+\000\016programs/icons/i\000\000Y?u?2\015??V?+\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\001?o???`??H??}?°??\017?1?\000\024programs/special/desktop\000\000Y?u?2k?\016V??Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\009\012??k\023\021???A\009?U0?{???\000\029programs/special/desktop_beta\000\000\000\000\000Y?u?31??Y??x\001u?4\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\002?C?&???\014i\002?{?Lu ??'?\000\031programs/special/error_reporter\000\000\000Y?u?3?T?Y??#*?\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000 ;X\016?H?]??e?\020F\001???\019?\030\000\024programs/special/taskbar\000\000Y?u?,G??Y???\002s}\028\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\003?d??J\025\005?\009?Ak\005+???\012f??\000\021programs/task_manager\000\000\000\000\000Y?u?,?\011?V??9\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\002s??&c!??g\025\"\012????I\011\000\022programs/update_centre\000\000\000\000Y?u?5W=\004V??D\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\000z7??1C??P\000?[?T0\026?\029~T?\000\015system/defaults\000\000\000Y?u?6?`V?e\000\000\000\000\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\0002f?$3U?\005M?R??v\014?????D\000 system/program_files/base_tour/1\000\000Y?u?5??Z\001?\016&?_?\000\000\000\000\000\000\000\000\000\000??\000\000\000\000\000\000\000\000\000\000\000?!?È?\021J?w??????DP\000\016system/variables\000\000TREE\000\000\001X\00038 5\
4431?5Z?qn}???G?l?}?*Q\004apis\0008 0\
4432????\009?O\015g??@S?/\004???\020core\0002 0\
4433? ?<??G\02982?\029?F??W)\028\025files\0006 1\
4434}Ou\028?x?v?a?n?:?4?4j_images\0006 0\
4435?????;-?\006c\003?\0033\021?#?9\030system\0003 1\
4436%ys??=?.?J?9?\005e'\0242??program_files\0001 1\
4437\028???=?????C?0\127???base_tour\0001 0\
4438?1-?>?N.\011mµ\011???\
4439?\021programs\00019 2\
4440?i?????]H$?9w??6??_?icons\0006 0\
4441?Nf*,??[?\0272?\025\009A?? special\0004 0\
4442?,????0?l?3???\012?é?\008??\005????\022???b?{???",
4443}
4444for k, v in pairs(tmpTbl) do
4445if not fs.exists(fs.getDir(k)) then fs.makeDir(fs.getDir(k)) end
4446local h = fs.open(k, 'w')
4447h.write(v)
4448h.close()
4449end
4450--Packaged using Sam Gunner's installer maker - Version 1.2.1