14 Commits
179 changed files with 375 additions and 10393 deletions
-3
View File
@@ -1,3 +0,0 @@
[*.lua]
indent_style = space
indent_size = 2
+14
View File
@@ -0,0 +1,14 @@
const fs = require("fs")
const luamin = require('lua-format')
const Code = fs.readFileSync(process.argv[2],"utf-8")
const Settings = {
RenameVariables: true,
RenameGlobals: false,
SolveMath: true,
Indentation: '\t'
}
const Beautified = luamin.Beautify(Code, Settings)
const Minified = luamin.Minify(Code, Settings)
fs.writeFileSync(process.argv[2],"utf-8")
+55
View File
@@ -0,0 +1,55 @@
name: Minify all Lua files to minified branch
on:
push:
branches:
- main
jobs:
minify:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout main branch
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
- name: Get latest commit info
id: commit
run: |
COMMIT_MSG=$(git log -1 --pretty=%s)
echo "message=${COMMIT_MSG}" >> $GITHUB_OUTPUT
- name: Set up Node.js
uses: actions/setup-node@v4
- name: Install luamin
run: npm install -g luamin
- name: Switch to minified branch
run: git checkout minified
- name: Copy files from main
run: |
git checkout main -- .
git reset HEAD
- name: Minify all Lua files
run: |
for file in $(find . -name "*.lua" -not -path "./.git/*"); do
echo $file
cat "$file" | luamin -c > "$file"
done
- name: Commit and push to minified branch
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "${{ steps.commit.outputs.message }} (minified)"
git push origin minified
-5
View File
@@ -1,5 +0,0 @@
.stfolder
.idea
home/*
halyde/logs/*
*.kate-swp
+6 -97
View File
@@ -1,101 +1,10 @@
{
"$schema": "https://raw.githubusercontent.com/LuaLS/lua-language-server/master/locale/en-us/setting.lua",
"runtime": {
"version": "Lua 5.3",
"special": {},
"unicodeName": false,
"nonstandardSymbol": []
},
"workspace": {
"checkThirdParty": false,
"maxPreload": 5000,
"preloadFileSize": 500
},
"diagnostics": {
"disable": [
"undefined-global",
"lowercase-global",
"missing-fields"
"diagnostics.globals": [
"checkArg",
"computer",
"component"
],
"globals": [
"_G",
"_VERSION",
"assert",
"error",
"getmetatable",
"ipairs",
"load",
"next",
"pairs",
"pcall",
"rawequal",
"rawget",
"rawlen",
"rawset",
"select",
"setmetatable",
"tonumber",
"tostring",
"type",
"xpcall",
"checkArg",
"bit32",
"coroutine",
"debug",
"math",
"os",
"string",
"table",
"component",
"computer",
"unicode",
"utf8"
"diagnostics.disable": [
"lowercase-global"
]
},
"completion": {
"enable": true,
"callSnippet": "Both",
"keywordSnippet": "Both",
"displayContext": 6
},
"hover": {
"enable": true,
"viewString": true,
"viewStringMax": 1000,
"viewNumber": true,
"fieldInfer": 3000,
"previewFields": 50,
"enumsLimit": 5
},
"semantic": {
"enable": true,
"variable": true,
"annotation": true,
"keyword": false
},
"format": {
"enable": true,
"defaultConfig": {
"indent_style": "space",
"indent_size": "2",
"tab_width": "2"
}
},
"spell": {
"dict": []
},
"telemetry": {
"enable": false
},
"IntelliSense": {
"traceLocalSet": false,
"traceReturn": false,
"traceBeSetted": false,
"traceFieldInject": false
},
"type": {
"castNumberToInteger": false,
"weakUnionCheck": false,
"weakNilCheck": false
}
}
View File
@@ -1,4 +1,3 @@
local agregistry = {
["halyde"] = "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/",
["edit"] = "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/",
@@ -9,10 +8,7 @@ local agregistry = {
["hextra"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["utape"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["libctif"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["ctif-viewer"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/",
["libsha256"] = "https://raw.githubusercontent.com/tema5002/ag-packages/refs/heads/main/",
["sha256sum"] = "https://raw.githubusercontent.com/tema5002/ag-packages/refs/heads/main/",
["base64"] = "https://raw.githubusercontent.com/mcplayer3/AgPackages/refs/heads/main/"
["ctif-viewer"] = "https://raw.githubusercontent.com/Ponali/ArgentumPackages/refs/heads/master/"
}
return agregistry
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
local a=import("component")local b=import("computer")local c={...}local d=false;local e=table.find(c,"-f")or table.find(c,"--force")if e then table.remove(c,e)d=true end;local function e(b)local function c(b)for c,d in a.list()do if a.slot(c)==b then return c end end end;if b=="hdd1"or b=="#1"then return c(5)end;if b=="hdd2"or b=="#2"then return c(6)end;if b=="floppy"or b=="#3"then return c(7)end;if#b<3 then return nil,"Abbreviated ID must atleast have 3 characters"end;return a.get(b)end;local function f(b,c)return a.invoke(b,"exists",c)and not a.invoke(b,"isDirectory",c)end;if type(c[1])=="string"then local e,g=e(c[1])if not e then print("\x1b[91mCould not get component ID from '"..c[1].."'.")if type(g)=="string"then print("\x1b[91m"..g)end;return end;if not d then if componentlib.additions[e]then return print("\x1b[91mThis component is virtual and cannot be booted from directly.\nID: "..e)end;local a=a.type(e)if a~="filesystem"and a~="drive"then return print("\x1b[91mThis component is not a storage medium.\nID: "..e)end;if a=="filesystem"and not f(e,"/init.lua")then return print("\x1b[91mThis storage medium doesn't have an \"init.lua\" file.\nID: "..e)end end;b.setBootAddress(e)if b.getBootAddress()~=e then return print("\x1b[91mFailed to set the boot address.")end;b.shutdown(true)else shell.run("help boot")end
+1
View File
@@ -0,0 +1 @@
local a={...}local b=import("filesystem")if not a or not a[1]then shell.run("help cat")return end;for a,a in ipairs(a)do if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if not b.exists(a)then print("\27[91mFile does not exist.")end;local a=b.open(a,"r")local b;repeat b=a:read(math.huge or math.maxinteger)termlib.write(b)until not b end
+1
View File
@@ -0,0 +1 @@
local a=...local b=import("filesystem")if not a then return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if b.exists(a)and b.isDirectory(a)then shell.workingDirectory=b.canonical(a)else print("\27[91mNo such directory.")end
+1
View File
@@ -0,0 +1 @@
clear()
+1
View File
@@ -0,0 +1 @@
local a,b=...local c=import("filesystem")if not a or not b then shell.run("help cp")return end;if a:sub(1,1)~="/"then a=c.concat(shell.workingDirectory,a)end;if b:sub(1,1)~="/"then b=c.concat(shell.workingDirectory,b)end;if a==b then print("\27[91mSource and destination are the same.")return end;if not c.exists(a)then print("\27[91mSource file does not exist.")return end;if c.exists(b)and not(table.find({...},"-o")or table.find({...},"--overwrite"))then print("\27[91mDestination file already exists. Run this command again with -o to overwrite it.")return end;c.copy(a,b)
+1
View File
@@ -0,0 +1 @@
local a=...local b=import("component")local c=import("filesystem")if not b.list("internet")()then print("\27[91mThis program requires an internet card to run.")return end;if not a then print("Please enter a URL to download from.")shell.run("help download")return end;if a:sub(-1,-1)=="/"then a=a:sub(1,-2)end;local b=b.internet;local d,e,f=nil,"",nil;local b,g=pcall(function()d=b.request(a)d:finishConnect()end)if not b then print("\27[91mDownload failed: "..g)end;local b=d:response()if b and b~=200 then print("\27[91mDownload failed: "..tostring(b))end;repeat f=d.read(math.huge)e=e..(f or"")until not f;local b;local d=false;repeat b=read(nil,"File save location: ",c.concat(shell.workingDirectory,a:match("/([^/]+)$")))if c.isDirectory(b)then print("\27[91mThe specified location is a directory.")elseif c.exists(b)then local a=read(nil,"\27[91mThere is already a file at the specified directory. Overwrite it? [Y/n]")if a:lower()~="n"then d=true end else d=true end until d;local a=c.open(b,"w")a:write(e)a:close()print("File downloaded successfully.")
+1
View File
@@ -0,0 +1 @@
local a={...}local b=a[1]table.remove(a,1)for a,a in pairs(a)do b=b.." "..a end;print(b)
+1
View File
@@ -0,0 +1 @@
local a=...local b=import("filesystem")local c=import("event")local d=import("component")local e=import("unicode")local d=d.gpu;local f,g=d.getResolution()local h,i=1,1;local j,k=1,1;local l=true;local m=false;local n=d.allocateBuffer()local o=5;local p=" "local function q(a,b,c)termlib.cursorPosX=a;termlib.cursorPosY=b;termlib.write(c,false)end;local r,s,t,u,v;if a then if a:sub(1,1)=="/"then s=a else s=shell.workingDirectory..a end;t,u,v=b.open(s,"r"),"",nil;if b.exists(s)then r=s;repeat v=t:read(math.huge)u=u..(v or"")until not v;v={}if u:gmatch("(.-)\n")()then for a in u:gmatch("(.-)\n")do local a=a:gsub("\r","")table.insert(v,a)end else v={u}end else s=shell.workingDirectory..a;r="[NEW FILE]"v={""}end else s=""r="[NEW FILE]"v={""}end;local function a()d.setActiveBuffer(n)clear()local a=math.min(j,e.wlen(v[k+i-1])-h+2)if a<1 then h=h+a-1;j=1;a=math.min(j,e.wlen(v[k+i-1])-h+2)end;for a=i,g+i-3 do d.set(1,a-i+1,(v[a]or""):sub(h))end;q(1,g-1,"\27[107m\27[30m"..r..string.rep(" ",f))q(1,g,"\27[107m\27[30m^X\27[0m Exit \27[107m\27[30m^S\27[0m Save"..string.rep(" ",f))local b=d.get(a,k)if l then d.setForeground(0)d.setBackground(16777215)end;d.set(a,k,b)d.bitblt()d.setActiveBuffer(0)end;local n,q=false,false;local function t()k=k-1;q=true;l=true;if k<1 then n=true;i=i-1;k=1 end;if i<1 then n=false;i=1 end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function u()k=k+1;q=true;l=true;if k+i-1>#v then n=false;k=#v-i+1 end;if k>g-2 then n=true;i=i+1;k=g-2 end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function w()q=true;l=true;if j>1 then if j<=e.wlen(v[k+i-1])-h+2 then j=j-1 elseif e.wlen(v[k+i-1])-h+1>1 then j=e.wlen(v[k+i-1])-h+1 end elseif h>1 then h=h-1;n=true end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function x()q=true;l=true;if j<=e.wlen(v[k+i-1])-h+1 then j=j+1 end;if j>f then j=f;h=h+1;n=true end end;local function y(a)n,q=false,false;if a[1]=="key_down"then local b=a[4]local b=keyboard.keys[b]if keyboard.ctrlDown then return false,false,b end;if b=="down"and k<#v then u()end;if b=="up"then t()end;if b=="left"then w()end;if b=="right"then x()end;if b=="enter"then m=true;n=true;l=true;table.insert(v,k+1,v[k+i-1]:sub(j))v[k+i-1]=v[k+i-1]:sub(1,j-1)j=1;k=k+1;h=1;if k>g-2 then i=i+1;k=g-2 end end;if b=="back"then m=true;q=true;l=true;if j==1 and k+i-1>1 then k=k-1;if k<1 then i=i-1;k=1 end;if i<1 then i=1 end;j=e.wlen(v[k+i-1])-h+2;if j>f then h=j-f+1;j=f end;v[k+i-1]=v[k+i-1]..v[k+1]table.remove(v,k+1)n=true else v[k+i-1]=v[k+i-1]:sub(1,j+h-3)..v[k+i-1]:sub(j+h-1)j=math.min(j-1,e.wlen(v[k+i-1])+1)if j<1 then j=1;h=h-1;n=true else d.set(1,k,v[k+i-1]:sub(h).." ")end end end;if b=="tab"then m=true;q=true;l=true;v[k+i-1]=v[k+i-1]:sub(1,j+h-2)..p..v[k+i-1]:sub(j+h-1)j=j+e.wlen(p)if j>f then h=h+j-f;j=f;n=true else d.set(1,k,v[k+i-1]:sub(h))end end;if a[3]>=32 and a[3]<=126 then m=true;q=true;l=true;v[k+i-1]=v[k+i-1]:sub(1,j+h-2)..e.char(a[3])..v[k+i-1]:sub(j+h-1)j=math.min(j,e.wlen(v[k+i-1]))+1;if j>f then j=f;h=h+1;n=true else d.set(1,k,v[k+i-1]:sub(h))end end elseif a[1]=="scroll"then if a[5]==1 then for a=1,o do t()end elseif a[5]==-1 and k<#v then for a=1,o do u()end end end;return n,q end;local function n()d.setBackground(16777215)d.setForeground(0)d.set(1,g-1,string.rep(" ",f))termlib.cursorPosX=1;termlib.cursorPosY=g-1;local a=read(nil,"\27[107m\27[30mSave location: ",s)d.setBackground(16777215)d.setForeground(0)if b.exists(a)then d.set(1,g-1,string.rep(" ",f))local a=read(nil,"\27[107m\27[30mFile already exists. Overwrite it? [Y/n] ")if a:lower()=="n"then d.setBackground(16777215)d.setForeground(0)d.set(1,g-1,r..string.rep(" ",f))return end end;local a,b=b.open(a,"w")if a then if table.concat(v,"\n"):sub(-1,-1)=="\n"then a:write(table.concat(v,"\n"))else a:write(table.concat(v,"\n").."\n")end;a:close()d.set(1,g-1,r..string.rep(" ",f))else d.set(1,g-1,"ERROR: "..b:gsub("\n","")..string.rep(" ",f))end;m=false end;a()while true do local b={c.pull(0.5)}local f,o,p=false,false,nil;local q,r=math.min(j,e.wlen(v[k+i-1])-h+2),k;if b and b[1]then l=true;f,o,p=y(b)if p=="x"then if m then termlib.cursorPosX=1;termlib.cursorPosY=g-1;local a=read(nil,"\27[107m\27[30mWould you like to save changes? [Y/n] ")if a:lower()~="n"then n()end end;d.freeAllBuffers()clear()return end;if p=="s"then n()end;repeat b={c.pull("key_down",0)}if b and b[1]then y(b)end until not b or not b[1]else l=not l;o=true end;if o then local a=d.get(q,r)d.set(q,r,a)local a=math.min(j,e.wlen(v[k+i-1])-h+2)if a<1 then h=h+a-1;j=1;a=math.min(j,e.wlen(v[k+i-1])-h+2)end;local b=d.get(a,k)if l then d.setBackground(16777215)d.setForeground(0)end;d.set(a,k,b)if l then d.setForeground(16777215)d.setBackground(0)end end;if f then a()end end
+1
View File
@@ -0,0 +1 @@
local a=import("component")local b=import("computer")local function c(a)termlib.cursorPosX=35;termlib.write(a.."\n",false)end;termlib.write(_OSLOGO,false)termlib.cursorPosY=termlib.cursorPosY-17;c("\27[92mOS\27[0m: ".._OSVERSION)c("\27[92mArchitecture\27[0m: ".._VERSION)local d=0;for a,a in a.list()do d=d+1 end;c("\27[92mComponents\27[0m: "..tostring(d))c("\27[92mCoroutines\27[0m: "..tostring(#cormgr.corList))c("\27[92mBattery\27[0m: "..tostring(math.floor(b.energy()/b.maxEnergy()*1000+0.5)/10).."%")local d=b.totalMemory()local e=b.totalMemory()-b.freeMemory()local f;if convert(d,"B","GiB")>=1 then f=tostring(math.floor(convert(d,"B","GiB")*100+0.5)/100).." GiB"elseif convert(d,"B","MiB")>=1 then f=tostring(math.floor(convert(d,"B","MiB")*100+0.5)/100).." MiB"elseif convert(d,"B","KiB")>=1 then f=tostring(math.floor(convert(d,"B","KiB")*100+0.5)/100).." KiB"else f=tostring(d).." B"end;local d;if convert(e,"B","GiB")>=1 then d=tostring(math.floor(convert(e,"B","GiB")*100+0.5)/100).." GiB"elseif convert(e,"B","MiB")>=1 then d=tostring(math.floor(convert(e,"B","MiB")*100+0.5)/100).." MiB"elseif convert(e,"B","KiB")>=1 then d=tostring(math.floor(convert(e,"B","KiB")*100+0.5)/100).." KiB"else d=tostring(e).." B"end;c("\27[92mMemory\27[0m: "..d.." / "..f)local d=a.invoke(b.getBootAddress(),"spaceTotal")local b=a.invoke(b.getBootAddress(),"spaceUsed")local e;if convert(d,"B","GiB")>=1 then e=tostring(math.floor(convert(d,"B","GiB")*100+0.5)/100).." GiB"elseif convert(d,"B","MiB")>=1 then e=tostring(math.floor(convert(d,"B","MiB")*100+0.5)/100).." MiB"elseif convert(d,"B","KiB")>=1 then e=tostring(math.floor(convert(d,"B","KiB")*100+0.5)/100).." KiB"else e=tostring(d).." B"end;local d;if convert(b,"B","GiB")>=1 then d=tostring(math.floor(convert(b,"B","GiB")*100+0.5)/100).." GiB"elseif convert(b,"B","MiB")>=1 then d=tostring(math.floor(convert(b,"B","MiB")*100+0.5)/100).." MiB"elseif convert(b,"B","KiB")>=1 then d=tostring(math.floor(convert(b,"B","KiB")*100+0.5)/100).." KiB"else d=tostring(b).." B"end;c("\27[92mDisk\27[0m: "..d.." / "..e)local a,b=a.invoke(a.list("gpu")(),"getResolution")c("\27[92mResolution\27[0m: "..tostring(a).."x"..tostring(b).."\n")c("\27[40m \27[41m \27[42m \27[43m \27[44m \27[45m \27[46m \27[47m ")c("\27[100m \27[101m \27[102m \27[103m \27[104m \27[105m \27[106m \27[107m ")termlib.cursorPosY=termlib.cursorPosY+5
+1
View File
@@ -0,0 +1 @@
local a=import("filesystem")local b={...}local c=b[1]b=nil;if not c then local a,b,c=a.open("/halyde/apps/helpdb/default.txt","r"),"",nil;repeat c=a:read(math.huge or math.maxinteger)b=b..(c or"")until not c;print(b)return end;if shell.aliases[c]then c=shell.aliases[c]end;if a.exists("/halyde/apps/helpdb/"..c..".txt")then local a,b,d=a.open("/halyde/apps/helpdb/"..c..".txt","r"),"",nil;repeat d=a:read(math.huge or math.maxinteger)b=b..(d or"")until not d;print(b)local a=table.copy(shell.aliases)if table.find(a,c)then local b=table.find(a,c)local d="Aliases:\n "..b;a[b]=nil;while table.find(a,c)do b=table.find(a,c)d=d..", "..b;a[b]=nil end;print(d)end else print("Could not find help file for: "..c..".")end
+18
View File
@@ -0,0 +1,18 @@
Usage: argentum [COMMAND] [PACKAGES]
Uses the Argentum package manager.
COMMAND Specifies the operation for Ag to do.
install Installs packages.
remove Removes packages.
update Updates packages.
list Lists all available packages.
search Searches all available packages.
info Shows information on a specific package.
PACKAGES* Packages to apply operations to.
Examples:
ag install hal-draw Installs the hal-draw package.
ag list Lists all packages.
ag info hal-draw Shows information about hal-draw.
ag update hal-draw Updates the hal-draw package if it's not at the newest version.
ag update Updates all packages.
+15
View File
@@ -0,0 +1,15 @@
Usage: boot [ADDRESS] [FLAGS]
Restarts and automatically boots into any storage medium. Meant to be used for systems using a Lua BIOS EEPROM.
ADDRESS The storage medium to boot to.
hdd1 The first hard drive inserted in the computer.
hdd2 The second hard drive inserted in the computer.
floppy The floppy disk that is inserted in the computer.
The ID of the component, abbreviated. Must have three or more characters.
FLAGS Specifies extra options when executing the command.
-f, --force Forces booting into the storage medium.
Examples:
boot hdd1 Boot into the first hard drive inserted in the computer.
boot hdd2 Boot into the second hard drive inserted in the computer.
boot floppy Boot into the floppy disk inserted in the comuter.
+8
View File
@@ -0,0 +1,8 @@
Usage: cat [FILES]...
Concatenates and prints a file.
FILES Specifies the paths to the files to print.
Examples:
cat /init.lua Concatenates and prints init.lua in the root directory.
cat help.lua cat.lua Concatenates and prints help.lua and cat.lua in the current working directory.
+10
View File
@@ -0,0 +1,10 @@
Usage: cd [PATH]
Sets the shell working directory.
PATH Specifies the path to set the shell working directory to.
Examples:
cd /home/ Sets the shell working directory to /home/.
cd halyde Sets the shell working directory to a directory named "halyde" in the current working directory.
cd .. Sets the shell working directory back one directory.
.. Equivalent of "cd ..".
+5
View File
@@ -0,0 +1,5 @@
Usage: clear
Clears the screen.
Examples:
clear Clears the screen.
+11
View File
@@ -0,0 +1,11 @@
Usage: cp [FLAGS] [SOURCE] [DESTINATION]
Copies a file.
FLAGS Specifies extra options when executing the command.
-o, --overwrite Allows any file that might be at the destination to be overwritten.
SOURCE Specifies the file to be copied.
DESTINATION Specifies the path to copy the file to.
Examples:
cp /home/a.txt /b.txt Copies the file at /home/a.txt to /b.txt.
cp -o c.lua d.txt Copies the file c.lua to another file called d.txt in the shell working directory, overwriting any file that might be there.
+25
View File
@@ -0,0 +1,25 @@
All default Halyde shell commands:
argentum Uses the Argentum package manager.
cat Concatenates and prints a file.
cd Changes directory.
clear Clears the screen.
cp Copies a file.
download Downloads a file from the internet.
echo Prints a message.
edit Opens the text editor.
fetch Displays system information.
help Shows this.
ls Lists files.
lscor Lists coroutines.
lua Starts the Lua shell.
mkdir Makes a directory.
mv Moves/renames a file.
reboot Reboots the computer.
rm Deletes a file.
shutdown Shuts down the computer.
You can get additional information on any app or command by running:
help [COMMAND]
In the help documentation, an asterisk (*) next to an argument means it is optional.
This is excluding flags, which are all optional.
+7
View File
@@ -0,0 +1,7 @@
Usage: download [URL]
Downloads a file from the internet.
URL Specifies the URL from which to download the file from.
Examples:
download https://github.com/ Downloads github.com.
+8
View File
@@ -0,0 +1,8 @@
Usage: echo [TEXT]...
Concatenates and prints text to the terminal.
TEXT Text to print.
Examples:
echo test Prints "test" to the terminal.
echo Hello World! Prints "Hello World!" to the terminal.
+8
View File
@@ -0,0 +1,8 @@
Usage: edit [PATH]
Opens a file with the text editor, or a new blank file if not specified.
PATH* Specifies the file to be opened.
Examples:
edit Opens a new blank file in the text editor.
edit /LICENSE Opens /LICENSE in the text editor.
+5
View File
@@ -0,0 +1,5 @@
Usage: fetch
Displays system information including OS version, Lua version, memory, etc.
Examples:
fetch Displays system information.
+8
View File
@@ -0,0 +1,8 @@
Usage: help [COMMAND]
Displays info on the command specified, or a list of commands if one is not specified.
COMMAND* Command to display information on.
Examples:
help Displays a list of all default commands available.
help cp Displays information about the cp command.
+16
View File
@@ -0,0 +1,16 @@
Usage: label [ADDRESS] [LABEL]
Get or set a label of a component that supports labelling.
ADDRESS The component to use for getting or setting the label.
eeprom The computer's EEPROM.
halyde The drive where the Halyde installation resides in.
slotN The slot number of the drive, in top-to-bottom order (range 7-9)
#N The slot number of the drive, in drive space (range 1-3)
The ID of the component, abbreviated. Must have three or more characters.
LABEL* The label to set the component to. If not found, the current label will be printed out.
Examples:
label #3 Get the label of the third drive in the computer.
label eeprom Get the label of the EEPROM inserted in the computer.
label slot8 Storage Set the drive at slot 8 to have the label "Storage"
label halyde Halyde Set the label of the Halyde installation to "Halyde"
+10
View File
@@ -0,0 +1,10 @@
Usage: ls [PATH]
Lists all files and directories in the specified path, or in the shell working directory if the path isn't specified.
Directories are shown in yellow, executable files are shown in green, and other files are shown in white.
PATH* Path to the folder to list files and directories from.
Examples:
ls Lists all files and directories from the current shell working directory.
ls /halyde Lists all files and directories from /halyde.
ls apps Lists all files and directories from the apps directory in the shell working directory.
+5
View File
@@ -0,0 +1,5 @@
Usage: lscor
Lists every active coroutine by ID and name.
Examples:
lscor Lists every active coroutine by ID and name.
+27
View File
@@ -0,0 +1,27 @@
Usage: lsdrv [FLAGS]
Shows all drives that are inserted into the computer.
FLAGS Specifies extra options when executing the command.
-a, --all Shows every column and every component. Acts the same as '-o all -s all'.
-o, --output [COLS] Specifies the columns to output in the output table.
Possible columns are: "slot", "capacity", "managed", "readOnly", "id", "mount", "bootable", and "label".
If the list of columns start with a "+", the default columns will appear first.
Default columns are slots, capacity, the entire ID, the mount point, and the drive label.
-s, --show [EXPR] Only list drives when the expression returns 'true'.
-S, --sort [EXPR] Sort the output by an expression that returns a number.
The higher the number, the lower the drive is displayed, and vice-versa.
EXPR An expression in Lua, for filtering or sorting output.
If this expression contains spaces, make sure to put quotation marks on them!
Built-in variables are: "component", "computer", "type", "id", "readonly", "capacity", "managed", "eeprom", "halyde", "tmp", "proxy", "slot", and "all" (true).
Examples:
lsblk Show regular drives, with the default columns.
lsblk -a Show all storage components, with every column.
lsblk -o +bootable Show drives, with an added "bootable" category.
lsblk -o slot,label -s halyde Show the slot and the label of the drive where Halyde is installed.
lsblk -o mount,capacity,label -s "not halyde" Show the mount points, capacities and labels of all drives other than Halyde.
lsblk -s type=='filesystem' Only show managed drives.
lsblk -s slot==1 Show all drives that aren't physical (Virtual components, tmpfs)
lsblk -S capacity Sort the drives by capacity, in ascending order.
lsblk -S -capacity Sort the drives by capacity, in descending order.
lsblk -o +managed -S managed Show managed drives first, then unmanaged drives second, with an extra "managed" column.
+5
View File
@@ -0,0 +1,5 @@
Usage: lua
Starts the Lua shell, where you can type commands to interpret them in real time.
Examples:
lua Starts the Lua shell.
+2
View File
@@ -0,0 +1,2 @@
Usage: maindrv
Shows the entire ID of the drive where Halyde is installed to.
+7
View File
@@ -0,0 +1,7 @@
Usage: mkdir [PATH]
Makes a directory.
PATH Specifies the path to create the directory in.
Examples:
mkdir a Creates a directory named a in the current shell working directory.
+11
View File
@@ -0,0 +1,11 @@
Usage: mv [FLAGS] [SOURCE] [DESTINATION]
Moves/renames a file.
FLAGS Specifies extra options when executing the command.
-o, --overwrite Allows any file that might be at the destination to be overwritten.
SOURCE Specifies the file to be moved/renamed.
DESTINATION Specifies the path/filename to move/rename the file to.
Examples:
mv /home/a.txt /b.txt Moves the file at /home/a.txt to /b.txt.
mv -o c.lua d.txt Renames the file c.lua to another file called d.txt in the shell working directory, overwriting any file that might be there.
+5
View File
@@ -0,0 +1,5 @@
Usage: reboot
Reboots the computer.
Examples:
reboot Reboots the computer.
+7
View File
@@ -0,0 +1,7 @@
Usage: rm [PATH]
Removes files and directories.
PATH Specifies the file to be moved/renamed.
Examples:
rm a.txt Removes a.txt in the current shell working directory.
+5
View File
@@ -0,0 +1,5 @@
Usage: shutdown
Shuts down the computer.
Examples:
shutdown Shuts down the computer.
+1
View File
@@ -0,0 +1 @@
local a=import("component")local b=import("computer")local c={...}if not c then return print("\x1b[91mCannot get arguments.")end;if not c[1]then return shell.run("help label")end;local d=c[1]local e;local function f(b)if b>=5 and b<=8 then b=b-1 end;for c,d in a.list()do if a.slot(c)==b then e=a.proxy(c)end end end;if d=="eeprom"then e=a.eeprom elseif d=="halyde"then e=a.proxy(b.getBootAddress())elseif d:sub(1,4)=="slot"and tonumber(d:sub(5))then local a=tonumber(d:sub(5))-1;f(a)elseif d:sub(1,1)=="#"and tonumber(d:sub(2))then local a=tonumber(d:sub(2))+5;f(a)elseif#d>=3 then local b=a.get(d)if not b then return print("\x1b[91mCould not find entire component ID from \""..d.."\".")end;e=a.proxy(b)else print("\x1b[91mAddress must have atleast 3 characters")return shell.run("help label")end;if not e then return print("\x1b[91mCould not find component from \""..d.."\".")end;local a=e.address;local function b(a)return a:sub(1,8).."\x1b[37m"..a:sub(9).."\x1b[39m"end;local function d(c)print("This \x1b[92m"..(e.type or"unknown").."\x1b[39m component doesn't support "..c.." labels.\nID: "..b(a))end;local function f(b,c)print("\x1b[91mAn error occured while "..b.." the label of this component.\nComponent: "..(a or"unknown id").." ("..((e or{}).type or"unknown type")..")\n\n"..c)end;local function g(a)local b="No label defined"if a then b="\""..a.."\""end;return b end;if type(c[2])~="string"then if not e.getLabel then return d("getting")end;local c;local d,h=pcall(function()c=e.getLabel()end)if d then print("Label of "..b(a)..((e.type and e.type~="filesystem")and" ("..e.type..")"or"")..":\n \x1b[92m"..g(c).."\x1b[39m")else f("getting",h)end else if not e.setLabel then return d("setting")end;local d=""for a=2,#c do d=d..tostring(c[a])if a<#c then d=d.." "end end;local c;local d,h=pcall(function()c=e.setLabel(d)end)if d then print("Successfully set label of "..b(a)..(e.type and" ("..e.type..")"or"").." to:\n \x1b[92m"..g(c).."\x1b[39m")else f("setting",h)end end
+1
View File
@@ -0,0 +1 @@
local a={...}local b=a[1]a=nil;local a=import("filesystem")local c=import("unicode")local d=0;local e=2;local f={}local g={}if b then if b:sub(1,1)~="/"then b=a.concat(shell.workingDirectory,b)end else b=shell.workingDirectory end;local h=a.list(b)if h then for a,a in pairs(h)do if a:sub(-1,-1)=="/"then table.insert(f,a)a=a:sub(1,-2)else table.insert(g,a)end;if c.wlen(a)>d then d=c.wlen(a)end end;table.sort(f)table.sort(g)h={}for a,a in ipairs(f)do table.insert(h,a)end;for a,a in ipairs(g)do table.insert(h,a)end;f,g=nil,nil;for f,f in ipairs(h)do local g=false;local h;if f:sub(-1,-1)=="/"then g=true;h="\27[93m"..f:sub(1,-2)elseif f:find(".")and f:match("[^.]+$")=="lua"then h="\27[92m"..f end;h=(h or f)..string.rep(" ",d-c.wlen(f)+e)if g then print(h.." \27[0m[DIR]")else local a=a.size(a.concat(b,f))local b;if convert(a,"B","GiB")>=1 then b=tostring(math.floor(convert(a,"B","GiB")*100+0.5)/100).." GiB"elseif convert(a,"B","MiB")>=1 then b=tostring(math.floor(convert(a,"B","MiB")*100+0.5)/100).." MiB"elseif convert(a,"B","KiB")>=1 then b=tostring(math.floor(convert(a,"B","KiB")*100+0.5)/100).." KiB"else b=tostring(a).." B"end;print(h.."\27[0m"..b)end end end
+1
View File
@@ -0,0 +1 @@
print("\27[93m"..tostring(#cormgr.corList).."\27[0m coroutines active")for a=1,#cormgr.corList do if a==#cormgr.corList then print("\27[93m└ "..a.."\27[0m - "..cormgr.labelList[a].." \27[0m")else print("\27[93m├ "..a.."\27[0m - "..cormgr.labelList[a].." \27[0m")end end
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
print("\27[44m".._VERSION.."\27[0m shell")print('Type "exit" to exit.')termlib.readHistory["lua"]={""}local a=import("filesystem")local b=""local a=a.list("halyde/lib")for a,a in pairs(a)do if a:match("(.+)%.lua")then b=b.."local "..a:match("(.+)%.lua")..' = import("'..a:match("(.+)%.lua")..'")\n'end end;while true do local a=read("lua","\27[44mlua>\27[0m ")if a=="exit"then return else local function c()local a=load(b.."return "..a,"=stdin")or load(b..a,"=stdin")local a={assert(a)()}if a and(type(a[1])~="nil"or type(a[2])~="nil")then print(table.unpack(a))end end;local a,b=xpcall(c,function(a)return a.."\n\n"..debug.traceback()end)if not a then print("\27[91m"..b)end end end
+1
View File
@@ -0,0 +1 @@
local a=import("computer")if type(a)~="table"then return print("\x1b[91mComputer library returned '"..type(a).."' type\x1b[39m")end;local a=a.getBootAddress()print(a)
+1
View File
@@ -0,0 +1 @@
local a=...local b=import("filesystem")if not a then shell.run("help mkdir")return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if b.exists(a)then print("\27[91mAn object already exists at the specified path.")end;b.makeDirectory(a)
+1
View File
@@ -0,0 +1 @@
local a,b=...local c=import("filesystem")if not a or not b then shell.run("help mv")return end;if a:sub(1,1)~="/"then a=c.concat(shell.workingDirectory,a)end;if b:sub(1,1)~="/"then b=c.concat(shell.workingDirectory,b)end;if a==b then print("\27[91mSource and destination are the same.")end;if not c.exists(a)then print("\27[91mSource file does not exist.")end;if c.exists(b)and not(table.find({...},"-o")or table.find({...},"--overwrite"))then print("\27[91mDestination file already exists. Run this command again with -o to overwrite it.")return end;c.rename(a,b)
+1
View File
@@ -0,0 +1 @@
import("computer").shutdown(true)
+1
View File
@@ -0,0 +1 @@
local a=...local b=import("filesystem")if not a then shell.run("help rm")return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if not b.exists(a)then print("\27[91mFile does not exist.")return end;b.remove(a)
+1
View File
@@ -0,0 +1 @@
local a=import("raster")a.init()local b=import("event")local c=0;local d=0;local e=1;local f=1;local g=8421504;local h=0;while b.pull("key_down",0)==nil do h=h+1;a.set(c,d,g)c=c+e;d=d+f;if c>a.displayWidth then c=a.displayWidth;e=-math.abs(e)g=math.random(0,16777215)end;if c<1 then c=1;e=math.abs(e)g=math.random(0,16777215)end;if d>a.displayHeight-6 then d=a.displayHeight-6;f=-math.abs(f)g=math.random(0,16777215)end;if d<1 then d=1;f=math.abs(f)g=math.random(0,16777215)end;if h>10 and h%15>0 then while true do local b=0;local c,d=math.random(1,a.displayWidth),math.random(1,a.displayHeight-6)if a.get(c,d)~=0 then a.set(c,d,0)break end;b=b+1;if b>20 then break end end end;if h%10==0 then a.update()coroutine.yield()end end;a.free()termlib.cursorPosY=1
+1
View File
@@ -0,0 +1 @@
local a=import("component")local b=import("computer")local c=import("raster")local d=import("event")local a,e=a.invoke(a.list("gpu")(),"getResolution")a,e=a*2,e*4;local a=a/2;local e=e/2;local f=10;local g=0;local h=16777215;local i=0.1;local j={{-f,-f,-f},{f,-f,-f},{f,f,-f},{-f,f,-f},{-f,-f,f},{f,-f,f},{f,f,f},{-f,f,f}}local k={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}}local l=256;local m=300;local n,o,p=0,0,0;local function q(a,b,c)local d,e=math.cos(n),math.sin(n)local f=b*d-c*e;local b=b*e+c*d;local c,d=math.cos(o),math.sin(o)local e=a*c+b*d;local a=-a*d+b*c;local b,c=math.cos(p),math.sin(p)local d=e*b-f*c;local b=e*c+f*b;return d,b,a end;local function r(b,c,d)local d=l/(d+m)local a=b*d+a;local b=c*d+e;return a,b end;local function a()local a=b.uptime()*20;g=a*0.05;f=(math.sin(g)+1)*25;j={{-f,-f,-f},{f,-f,-f},{f,f,-f},{-f,f,-f},{-f,-f,f},{f,-f,f},{f,f,f},{-f,f,f}}c.clear()n=a*i;o=a*i*0.7;p=a*i*0.5;local a={}for b,c in ipairs(j)do local c,d,e=q(c[1],c[2],c[3])local c,d=r(c,d,e)a[b]={c,d}end;for b,b in ipairs(k)do local d=a[b[1]+1]local a=a[b[2]+1]c.drawLine(d[1],d[2],a[1],a[2],h)end;c.update()end;function main()c.init()while true do a()coroutine.yield()if d.pull("key_down",0)then c.free()break end end;return a end;return main()
+1
View File
@@ -0,0 +1 @@
import("computer").shutdown()
+1
View File
@@ -0,0 +1 @@
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
+1
View File
@@ -0,0 +1 @@
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
+1
View File
@@ -0,0 +1 @@
["/halyde/core/fullkb.lua","/halyde/core/evmgr.lua","/halyde/core/drvload.lua","/halyde/core/shell.lua"]
+1
View File
@@ -0,0 +1 @@
local a=...local b=a("/halyde/lib/filesystem.lua")(a)_G._OSVERSION="Halyde 2.8.1"_G._OSLOGO=""local c,d=b.open("/halyde/config/oslogo.ans","r"),nil;repeat d=c:read(math.huge)_OSLOGO=_OSLOGO..(d or"")until not d;_G.package={["preloaded"]={}}a("/halyde/core/datatools.lua")()function _G.import(a,...)local c=table.pack(...)if package.preloaded[a]then return package.preloaded[a]end;local d;if b.exists(a)then d=a elseif b.exists("/halyde/lib/"..a..".lua")then d="/halyde/lib/"..a..".lua"elseif shell and shell.workingDirectory and b.exists(shell.workingDirectory..a)then d=shell.workingDirectory..a end;assert(d,"module not found\npossible locations:\n/halyde/lib/"..a..".lua")local a,b,e=b.open(d),"",nil;repeat e=a:read(math.huge or math.maxinteger)b=b..(e or"")until not e;a:close()return(assert(load(b,"="..d))(table.unpack(c)))end;local function a(a)local b,c,d=assert(b.open("/halyde/lib/"..a..".lua","r")),"",nil;repeat d=b:read(math.huge or math.maxinteger)c=c..(d or"")until not d;package.preloaded[a]=assert(load(c,"="..a))()_G[a]=nil end;a("component")a("computer")a("filesystem")local a=import("component")local b=a.gpu;local a=a.list("screen")()b.bind(a)b.setResolution(b.maxResolution())local a=import("filesystem")if not a.exists("/halyde/config/shell.json")then a.copy("/halyde/config/generate/shell.json","/halyde/config/shell.json")end;if not a.exists("/halyde/config/startupapps.json")then a.copy("/halyde/config/generate/startupapps.json","/halyde/config/startupapps.json")end;a=nil;import("/halyde/core/cormgr.lua")
+1
View File
@@ -0,0 +1 @@
_G.cormgr={}_G.cormgr.corList={}_G.cormgr.labelList={}local a=import("component")local b=import("filesystem")local c=import("json")local a=a.gpu;function _G.cormgr.loadCoroutine(b,...)local c={...}local function d()local b,c=xpcall(function(...)import(...)end,function(a)return a.."\n \n"..debug.traceback()end,b,table.unpack(c))if not b then if print then a.freeAllBuffers()print("\n\27[91m"..c)else error(c)end end end;cormgr.addCoroutine(d,string.match(tostring(b),"([^/]+)%.lua$"))end;function _G.cormgr.addCoroutine(a,b)local a=coroutine.create(a)table.insert(cormgr.corList,a)table.insert(cormgr.labelList,b)return a end;function _G.cormgr.removeCoroutine(a)local a=table.find(cormgr.labelList,cor)table.remove(cormgr.corList,a)table.remove(cormgr.labelList,a)end;function handleError(a)if a==nil then error("unknown error")else error(tostring(a).."\n \n"..debug.traceback())end end;local function a()for a=1,#_G.cormgr.corList do if cormgr.corList[a]then local b,c=coroutine.resume(cormgr.corList[a])if cormgr.corList[a]then if not b then handleError(c)end;if coroutine.status(cormgr.corList[a])=="dead"then table.remove(cormgr.corList,a)table.remove(cormgr.labelList,a)a=a-1 end end end end end;local b,d,e=b.open("/halyde/config/startupapps.json","r"),"",nil;repeat e=b:read(math.huge or math.maxinteger)d=d..(e or"")until not e;b:close()for b,b in ipairs(c.decode(d))do if b~=""then _G.cormgr.loadCoroutine(b)a()end end;while true do a()if#_G.cormgr.corList==0 then computer.shutdown()end end
+1
View File
@@ -0,0 +1 @@
local a={["bytes"]={["B"]=1,["KB"]=1000,["MB"]=1000000,["GB"]=1000000000},["bibytes"]={["B"]=1,["KiB"]=1024,["MiB"]=1048576,["GiB"]=1073741824}}function table.find(a,b)for a,c in pairs(a)do if c==b then return a end end end;function table.copy(a)local b=type(a)local c;if b=='table'then c={}for a,b in next,a,nil do c[table.copy(a)]=table.copy(b)end;setmetatable(c,table.copy(getmetatable(a)))else c=a end;return c end;function convert(b,c,d)for a,a in pairs(a)do if a[d]then return b/a[d]*a[c]end end;return false,"unit does not exist"end
+1
View File
@@ -0,0 +1 @@
local a=import("filesystem")local b="/halyde/drivers"local c=a.list(b)local d={}local function e(f)local a=import(a.concat(b,f))table.remove(c,table.find(c,f))if a.dependencies then for a,a in pairs(a.dependencies)do if table.find(c,a)then e(a)elseif table.find(c,a..".lua")then e(a..".lua")else for b,c in pairs(d)do if c==a then e(b)end end end end end;if a.onStartup then a.onStartup()end end;for c,c in pairs(c)do local a=import(a.concat(b,c))if a.type then d[c]=a.type end end;for a,a in pairs(c)do if a:sub(-1,-1)~="/"then e(a)end end
+1
View File
@@ -0,0 +1 @@
_G.evmgr={}_G.evmgr.eventQueue={}local a=10;local b=import("computer")keyboard.ctrlDown=false;keyboard.altDown=false;keyboard.shiftDown=false;while true do local c;repeat c={b.uptime(),b.pullSignal(0)}if c and c[2]then table.insert(evmgr.eventQueue,c)if keyboard then if c[2]=="key_down"then local a=c[5]local a=keyboard.keys[a]if a=="lcontrol"then keyboard.ctrlDown=true elseif a=="lmenu"then keyboard.altDown=true elseif a=="lshift"then keyboard.shiftDown=true elseif a=="c"and keyboard.ctrlDown and keyboard.altDown then if print then print("\n\27[91mCoroutine "..tostring(#cormgr.corList).." killed.")end;cormgr.corList[#cormgr.corList]=nil end elseif c[2]=="key_up"then local a=c[5]local a=keyboard.keys[a]if a=="lcontrol"then keyboard.ctrlDown=false elseif a=="lmenu"then keyboard.altDown=false elseif a=="lshift"then keyboard.shiftDown=true end end end;while#evmgr.eventQueue>a do table.remove(evmgr.eventQueue,1)end end until not c or not c[1]coroutine.yield()end
+1
View File
@@ -0,0 +1 @@
_G.keyboard={["keys"]={}}keyboard.keys["1"]=2;keyboard.keys["2"]=3;keyboard.keys["3"]=4;keyboard.keys["4"]=5;keyboard.keys["5"]=6;keyboard.keys["6"]=7;keyboard.keys["7"]=8;keyboard.keys["8"]=9;keyboard.keys["9"]=10;keyboard.keys["0"]=11;keyboard.keys.a=30;keyboard.keys.b=48;keyboard.keys.c=46;keyboard.keys.d=32;keyboard.keys.e=18;keyboard.keys.f=33;keyboard.keys.g=34;keyboard.keys.h=35;keyboard.keys.i=23;keyboard.keys.j=36;keyboard.keys.k=37;keyboard.keys.l=38;keyboard.keys.m=50;keyboard.keys.n=49;keyboard.keys.o=24;keyboard.keys.p=25;keyboard.keys.q=16;keyboard.keys.r=19;keyboard.keys.s=31;keyboard.keys.t=20;keyboard.keys.u=22;keyboard.keys.v=47;keyboard.keys.w=17;keyboard.keys.x=45;keyboard.keys.y=21;keyboard.keys.z=44;keyboard.keys.apostrophe=40;keyboard.keys.at=145;keyboard.keys.back=14;keyboard.keys.backslash=43;keyboard.keys.capital=58;keyboard.keys.colon=146;keyboard.keys.comma=51;keyboard.keys.enter=28;keyboard.keys.equals=13;keyboard.keys.grave=41;keyboard.keys.lbracket=26;keyboard.keys.lcontrol=29;keyboard.keys.lmenu=56;keyboard.keys.lshift=42;keyboard.keys.minus=12;keyboard.keys.numlock=69;keyboard.keys.pause=197;keyboard.keys.period=52;keyboard.keys.rbracket=27;keyboard.keys.rcontrol=157;keyboard.keys.rmenu=184;keyboard.keys.rshift=54;keyboard.keys.scroll=70;keyboard.keys.semicolon=39;keyboard.keys.slash=53;keyboard.keys.space=57;keyboard.keys.stop=149;keyboard.keys.tab=15;keyboard.keys.underline=147;keyboard.keys.up=200;keyboard.keys.down=208;keyboard.keys.left=203;keyboard.keys.right=205;keyboard.keys.home=199;keyboard.keys["end"]=207;keyboard.keys.pageUp=201;keyboard.keys.pageDown=209;keyboard.keys.insert=210;keyboard.keys.delete=211;keyboard.keys.f1=59;keyboard.keys.f2=60;keyboard.keys.f3=61;keyboard.keys.f4=62;keyboard.keys.f5=63;keyboard.keys.f6=64;keyboard.keys.f7=65;keyboard.keys.f8=66;keyboard.keys.f9=67;keyboard.keys.f10=68;keyboard.keys.f11=87;keyboard.keys.f12=88;keyboard.keys.f13=100;keyboard.keys.f14=101;keyboard.keys.f15=102;keyboard.keys.f16=103;keyboard.keys.f17=104;keyboard.keys.f18=105;keyboard.keys.f19=113;keyboard.keys.kana=112;keyboard.keys.kanji=148;keyboard.keys.convert=121;keyboard.keys.noconvert=123;keyboard.keys.yen=125;keyboard.keys.circumflex=144;keyboard.keys.ax=150;keyboard.keys.numpad0=82;keyboard.keys.numpad1=79;keyboard.keys.numpad2=80;keyboard.keys.numpad3=81;keyboard.keys.numpad4=75;keyboard.keys.numpad5=76;keyboard.keys.numpad6=77;keyboard.keys.numpad7=71;keyboard.keys.numpad8=72;keyboard.keys.numpad9=73;keyboard.keys.numpadmul=55;keyboard.keys.numpaddiv=181;keyboard.keys.numpadsub=74;keyboard.keys.numpadadd=78;keyboard.keys.numpaddecimal=83;keyboard.keys.numpadcomma=179;keyboard.keys.numpadenter=156;keyboard.keys.numpadequals=141;setmetatable(keyboard.keys,{__index=function(a,b)if type(b)~="number"then return end;for a,c in pairs(a)do if c==b then return a end end end})
+1
View File
@@ -0,0 +1 @@
local a=import("filesystem")local b=import("json")local c,d,e=a.open("/halyde/config/shell.json","r"),"",nil;repeat e=c:read(math.huge)d=d..(e or"")until not e;c:close()local b=b.decode(d)import("/halyde/core/termlib.lua")local c=import("event")local c=import("component")local c=c.gpu;_G.shell={}_G.shell.workingDirectory=b["defaultWorkingDirectory"]_G.shell.aliases=b["aliases"]local function d(a,...)cormgr.loadCoroutine(a,...)local a=#cormgr.corList;local b=cormgr.corList[#cormgr.corList]repeat coroutine.yield()until cormgr.corList[a]~=b end;function _G.shell.run(c)checkArg(1,c,"string")if shell.aliases[c:match("[^ ]+")]then local a,a=c:find("[^ ]+")c=shell.aliases[c:match("[^ ]+")]..c:sub(a+1)end;local c,e,f,g=c:gmatch("[^ ]+"),nil,{},c;while true do e=c()if not e then break end;if e:find('"')then local a=g:find('"')local b=e:sub(1,e:find('"')-1)if b and b~=""then table.insert(f,b)end;g=g:sub(a+1)if g:find('"')then table.insert(f,g:sub(1,g:find('"')-1))g=g:sub(g:find('"')+1)c=g:gmatch('[^ ]+')else print("\27[91mmalformed shell command")return end else table.insert(f,e)end end;local b=table.copy(b.path)table.insert(b,shell.workingDirectory)if not f[1]then return end;if a.exists(f[1])and not a.isDirectory(f[1])then local a=f[1]table.remove(f,1)d(a,table.unpack(f))return end;for b,b in pairs(b)do if a.exists(b..f[1])and not a.isDirectory(b..f[1])then local a=a.concat(b,f[1])table.remove(f,1)d(a,table.unpack(f))return else local c=a.list(b)or{}for c,c in pairs(c)do if f[1]==c:match("(.+)%.[^%.]+$")and not a.isDirectory(b..c)then table.remove(f,1)d(b..c,table.unpack(f))return end end end end;print("No such file or command: "..f[1])end;print(b["startupMessage"]:format(_OSVERSION,b.splashMessages[math.random(1,#b.splashMessages)]))while true do coroutine.yield()if shell.workingDirectory:sub(-1,-1)~="/"then shell.workingDirectory=shell.workingDirectory.."/"end;local a=read("shell",b.prompt:format(shell.workingDirectory))shell.run(a)c.freeAllBuffers()end
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
local a;local b;if table.copy then a=table.copy(component)b=table.copy(component)else a={}b=component end;_G.componentlib={["additions"]={},["removals"]={}}a.virtual={}function a.virtual.add(a,b,c)checkArg(1,a,"string")checkArg(2,b,"string")checkArg(3,c,"table")c["address"]=a;componentlib.additions[a]={["componentType"]=b,["proxy"]=c}if componentlib.removals[a]then componentlib.removals[a]=nil end end;function a.virtual.remove(a)checkArg(1,a,"string")if componentlib.additions[a]then componentlib.additions[a]=nil else table.insert(componentlib.removals,a)end end;function a.list(a)checkArg(1,a,"string","nil")local b=table.copy(b.list(a))for c,d in pairs(componentlib.additions)do if d.componentType==a or not a then b[c]=d.componentType end end;for a,a in pairs(componentlib.removals)do b[a]=nil end;local a,c;setmetatable(b,{__call=function(b)a,c=next(b,a)return a,c end})return b end;function a.proxy(a)if componentlib.additions[a]then return componentlib.additions[a].proxy else return b.proxy(a)end end;function a.invoke(a,c,...)if componentlib.additions[a]then return componentlib.additions[a].proxy[c](...)else return b.invoke(a,c,...)end end;function a.get(b)checkArg(1,b,"string")if#b<3 then return nil,"abbreviated address must be at least 3 characters long"end;for a,c in a.list()do if a:find("^"..b)then return(a)end end;return nil,"full address not found"end;setmetatable(a,{["__index"]=function(b,b)if a.list(b)()then return a.proxy(a.list(b)())else return a[b]end end})return a
+1
View File
@@ -0,0 +1 @@
local a=table.copy(computer)local b=table.copy(computer)function a.pullSignal(a)local c=b.uptime()local d;repeat d={b.pullSignal(0)}coroutine.yield()until d or a and b.uptime()>=c+a;return table.unpack(d)end;return a
+1
View File
@@ -0,0 +1 @@
local a=import("computer")local b={}local c=0.1;function b.pull(...)local b={...}local d,e={},nil;for a,a in pairs(b)do if type(a)=="number"and not e then e=a else table.insert(d,tostring(a))end end;local b=a.uptime()while true do for a=1,#evmgr.eventQueue do local e=false;if d[1]then for d,d in pairs(d)do if evmgr.eventQueue[a][2]==d and evmgr.eventQueue[a][1]>=b-c then e=true end end else if evmgr.eventQueue[a][1]>=b-c then e=true end end;if e then local b=table.copy(evmgr.eventQueue[a])table.remove(evmgr.eventQueue,a)table.remove(b,1)return table.unpack(b)end end;if e and a.uptime()>=b+e then return nil end;coroutine.yield()end end;return b
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
local a={_version="0.1.2"}local b;local c={["\\"]="\\",["\""]="\"",["\b"]="b",["\f"]="f",["\n"]="n",["\r"]="r",["\t"]="t"}local d={["/"]="/"}for a,b in pairs(c)do d[b]=a end;local function e(a)return"\\"..(c[a]or string.format("u%04x",a:byte()))end;local function c(a)return"null"end;local function f(a,c)local d={}c=c or{}if c[a]then error("circular reference")end;c[a]=true;if rawget(a,1)~=nil or next(a)==nil then local e=0;for a in pairs(a)do if type(a)~="number"then error("invalid table: mixed or invalid key types")end;e=e+1 end;if e~=#a then error("invalid table: sparse array")end;for a,a in ipairs(a)do table.insert(d,b(a,c))end;c[a]=nil;return"["..table.concat(d,",").."]"else for a,e in pairs(a)do if type(a)~="string"then error("invalid table: mixed or invalid key types")end;table.insert(d,b(a,c)..":"..b(e,c))end;c[a]=nil;return"{"..table.concat(d,",").."}"end end;local function g(a)return'"'..a:gsub('[%z\1-\31\\"]',e)..'"'end;local function e(a)if a~=a or a<=-math.huge or a>=math.huge then error("unexpected number value '"..tostring(a).."'")end;return string.format("%.14g",a)end;local c={["nil"]=c,["table"]=f,["string"]=g,["number"]=e,["boolean"]=tostring}b=function(a,b)local d=type(a)local c=c[d]if c then return c(a,b)end;error("unexpected type '"..d.."'")end;function a.encode(a)return b(a)end;local b;local function c(...)local a={}for b=1,select("#",...)do a[select(b,...)]=true end;return a end;local e=c(" ","\t","\r","\n")local f=c(" ","\t","\r","\n","]","}",",")local g=c("\\","/",'"',"b","f","n","r","t","u")local c=c("true","false","null")local h={["true"]=true,["false"]=false,["null"]=nil}local function i(a,b,c,d)for b=b,#a do if c[a:sub(b,b)]~=d then return b end end;return#a+1 end;local function j(a,b,c)local d=1;local e=1;for b=1,b-1 do e=e+1;if a:sub(b,b)=="\n"then d=d+1;e=1 end end;error(string.format("%s at line %d col %d",c,d,e))end;local function k(a)local b=math.floor;if a<=127 then return string.char(a)elseif a<=2047 then return string.char(b(a/64)+192,a%64+128)elseif a<=65535 then return string.char(b(a/4096)+224,b(a%4096/64)+128,a%64+128)elseif a<=1114111 then return string.char(b(a/262144)+240,b(a%262144/4096)+128,b(a%4096/64)+128,a%64+128)end;error(string.format("invalid unicode codepoint '%x'",a))end;local function l(a)local b=tonumber(a:sub(1,4),16)local a=tonumber(a:sub(7,10),16)if a then return k((b-55296)*1024+a-56320+65536)else return k(b)end end;local function k(a,b)local c=""local e=b+1;local f=e;while e<=#a do local b=a:byte(e)if b<32 then j(a,e,"control character in string")elseif b==92 then c=c..a:sub(f,e-1)e=e+1;local b=a:sub(e,e)if b=="u"then local a=a:match("^[dD][89aAbB]%x%x\\u%x%x%x%x",e+1)or a:match("^%x%x%x%x",e+1)or j(a,e-1,"invalid unicode escape in string")c=c..l(a)e=e+#a else if not g[b]then j(a,e-1,"invalid escape char '"..b.."' in string")end;c=c..d[b]end;f=e+1 elseif b==34 then c=c..a:sub(f,e-1)return c,e+1 end;e=e+1 end;j(a,b,"expected closing quote for string")end;local function d(a,b)local c=i(a,b,f)local d=a:sub(b,c-1)local e=tonumber(d)if not e then j(a,b,"invalid number '"..d.."'")end;return e,c end;local function g(a,b)local d=i(a,b,f)local e=a:sub(b,d-1)if not c[e]then j(a,b,"invalid literal '"..e.."'")end;return h[e],d end;local function c(a,c)local d={}local f=1;c=c+1;while 1 do local g;c=i(a,c,e,true)if a:sub(c,c)=="]"then c=c+1;break end;g,c=b(a,c)d[f]=g;f=f+1;c=i(a,c,e,true)local b=a:sub(c,c)c=c+1;if b=="]"then break end;if b~=","then j(a,c,"expected ']' or ','")end end;return d,c end;local function f(a,c)local d={}c=c+1;while 1 do local f,g;c=i(a,c,e,true)if a:sub(c,c)=="}"then c=c+1;break end;if a:sub(c,c)~='"'then j(a,c,"expected string for key")end;f,c=b(a,c)c=i(a,c,e,true)if a:sub(c,c)~=":"then j(a,c,"expected ':' after key")end;c=i(a,c+1,e,true)g,c=b(a,c)d[f]=g;c=i(a,c,e,true)local b=a:sub(c,c)c=c+1;if b=="}"then break end;if b~=","then j(a,c,"expected '}' or ','")end end;return d,c end;local c={['"']=k,["0"]=d,["1"]=d,["2"]=d,["3"]=d,["4"]=d,["5"]=d,["6"]=d,["7"]=d,["8"]=d,["9"]=d,["-"]=d,["t"]=g,["f"]=g,["n"]=g,["["]=c,["{"]=f}b=function(a,b)local d=a:sub(b,b)local c=c[d]if c then return c(a,b)end;j(a,b,"unexpected character '"..d.."'")end;function a.decode(a)if type(a)~="string"then error("expected argument of type string, got "..type(a))end;local b,c=b(a,i(a,1,e,true))c=i(a,c,e,true)if c<=#a then j(a,c,"trailing garbage")end;return b end;return a
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
local a={}function a.string(a)return'"'..a:gsub("[%z\1-\31\34\92\127-\159]",function(a)local a=a:byte()if a==7 then return"\\a"end;if a==8 then return"\\b"end;if a==9 then return"\\t"end;if a==10 then return"\\n"end;if a==11 then return"\\v"end;if a==12 then return"\\f"end;if a==13 then return"\\r"end;if a==34 then return"\\\""end;if a==92 then return"\\\\"end;return string.format("\\x%02x",a)end)..'"'end;function a.table(b,c,d)d=table.copy(d or{})table.insert(d,b)local e=0;local f=true;local g=""local h=true;for b,i in pairs(b)do if not h then g=g..",\n"end;h=false;g=g.." "if type(b)=="string"then if b:match("^[%a_][%w_]*$")then g=g..b.."="else g=g..'['..a.string(b)..']='end else g=g.."["..tostring(b).."]="end;if type(b)~="number"then f=false end;local a,b=pcall(function()local b=""if type(i)=="table"then if#d>4 or table.find(d,i)then b="..."else b=a.table(i,c,d)end elseif type(i)=="string"then local c={}for a in(i.."\n"):gmatch("([^\n]*)\n")do table.insert(c,a)end;if#c[#c]==0 then c[#c]=nil;c[#c]=c[#c].."\n"end;for b=1,#c do if b<#c then c[b]=a.string(c[b].."\n")else c[b]=a.string(c[b])end end;b=table.concat(c," ..\n ")else b=tostring(i)end;local a={}for b in(b.."\n"):gmatch("([^\n]*)\n")do table.insert(a,b)end;g=g..table.concat(a,"\n ")a=nil;e=e+1 end)if not a then if c then g=g.."\x1b[91m"end;g=g.."["..tostring(b).."]"if c then g=g.."\x1b[39m"end end;coroutine.yield()end;local h=getmetatable(b)local i={}if type(h)=="table"then for a,b in pairs(h)do f=false;table.insert(i,a)end end;if#i>0 then g=g.."\n "if c then g=g.."\x1b[92m"end;if table.find(i,"__tostring")then g=g.."tostring: "..a.string(tostring(b)).."\n "table.remove(i,table.find(i,"__tostring"))end;g=g..table.concat(i,", ")if c then g=g.."\x1b[39m"end end;if e==0 then return"{}"end;if f then local e={}for b,b in pairs(b)do if#e>=5 and#d>1 then table.insert(e,"...")break end;if type(b)=="table"then table.insert(e,a.table(b,c,d))elseif type(b)=="string"then table.insert(e,a.string(b))else table.insert(e,tostring(b))end end;return"{"..table.concat(e,", ").."}"end;return"{\n"..g.."\n}"end;return a
+1
View File
@@ -0,0 +1 @@
local a;local b;if table.copy then a=table.copy(unicode)b=table.copy(unicode)else a={}b=unicode end;function a.readCodePoint(a)checkArg(1,a,"function")local function b(a,b,...)for c,c in ipairs({...})do if not(c and c>=a and c<b)then return false end end;return true end;local c=a()if c==nil then return end;if c<128 then return c elseif c<192 then return nil elseif c<224 then local a=a()if a==nil then return nil end;if b(128,192,a)then local a=((c&31)<<6)|(a&63)return a end elseif c<240 then local a,d=a(),a()if a==nil and d==nil then return nil end;if b(128,192,a,d)then local a=((c&15)<<12)|((a&63)<<6)|(d&63)return a end elseif c<248 then local a,d,e=a(),a(),a()if a==nil and d==nil and e==nil then return nil end;if b(128,192,a,d,e)then local a=((c&7)<<18)|((a&63)<<12)|((d&63)<<6)|(e&63)return a end end;return nil end;function a.readChar(c)checkArg(1,c,"function")return b.char(a.readCodePoint(c))end;function a.codepoint(a)checkArg(1,a,"string")local b=1;return unicode.readCodePoint(function()local a=a:byte(b)b=b+1;return a end),b-1 end;function a.iterate(c)checkArg(1,c,"string","function")if type(c)=="string"then local a,b=c,0;c=function()b=b+1;return a:byte(b)end end;return function()local a=a.readCodePoint(c)if a==nil then return nil end;return b.char(a),a end end;a.char=b.char;a.charWidth=b.charWidth;a.isWide=b.isWide;a.len=b.len;a.lower=b.lower;a.reverse=b.reverse;a.sub=b.sub;a.upper=b.upper;a.wlen=b.wlen;a.wtrunc=b.wtrunc;return a
+1
View File
@@ -0,0 +1 @@
local a=component.proxy(component.list("gpu")())local b,c=a.getResolution()local function d(a)checkArg(1,a,"string")local b=component.invoke(computer.getBootAddress(),"open",a,"r")local c=""repeat local a=component.invoke(computer.getBootAddress(),"read",b,math.huge or math.maxinteger)c=c..(a or"")until not a;component.invoke(computer.getBootAddress(),"close",b)return assert(load(c,"="..a))end;local function e(a)return(a.."\n \n"..debug.traceback())end;function loadthething()d("/halyde/core/boot.lua")(d)end;a.setBackground(0)a.fill(1,1,b,c," ")local d,e=xpcall(loadthething,e)if not d then if import then local a=import("computer")end;a.setBackground(0)a.fill(1,1,b,c," ")a.setBackground(8388608)a.setForeground(16777215)a.set(2,2,"A critical error has occurred.")local b=4;e=e:gsub("\t"," ")for c in string.gmatch((e~=nil and tostring(e))or"unknown error","([^\n]*)\n?")do a.set(2,b,c)b=b+1 end;if computer~=nil then a.set(2,b+1,"Press any key to restart.")local a;repeat a=computer.pullSignal()until a=="key_down"computer.shutdown(true)end;while true do coroutine.yield()end end
-9
View File
@@ -1,9 +0,0 @@
{
"halyde": "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/",
"argentum": "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/",
"edit": "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/",
"package1": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/",
"package2": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/",
"vpkg": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/",
"grouper": "https://raw.githubusercontent.com/WahPlus/ArgentumPackages/refs/heads/main/"
}
-520
View File
@@ -1,520 +0,0 @@
local cliparse = require("cliparse")
local fs = require("filesystem")
local component = require("component")
local json = require("json")
local function getFile(path)
checkArg(1, path, "string")
if path:sub(1, 7) == "http://" or path:sub(1, 8) == "https://" then
if not component.list("internet")() then
return false, "Internet card required but not found."
end
local handle, data, tmpdata = component.internet.request(path), "", nil
local success, errorMessage = pcall(function()
handle:finishConnect()
end)
if not success then
return false, errorMessage
end
local code, message = handle:response()
if code and code ~= 200 then
return false, ("%d %s"):format(code, message)
end
repeat
tmpdata = handle.read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
return true, data
elseif path:sub(1, 1) == "/" then
if not fs.exists(path) then
return false, "No such file or directory: " .. path
end
if fs.isDirectory(path) then
return false, "Expected file, found directory: " .. path
end
local handle, data, tmpdata = fs.open(path, "r", false), "", nil
if not handle then
return false, data
end
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
return true, data
else
return false, "Unsupported path: " .. path
end
end
cliparse.config({
["x"] = 0,
["exclude-deps"] = 0,
["u"] = 0,
["update-registry"] = 0,
["f"] = 0,
["force"] = 0,
["c"] = 0,
["clean"] = 0,
["s"] = 1,
["source"] = 1,
["C"] = 0,
["cascade"] = 0,
})
local parsed, errorMessage = cliparse.parse(...)
if not parsed then
print(("\27[91m%s\n\27[0mExiting."):format(errorMessage))
return
end
local command = parsed.args[1]
if not command then
print("\27[91mNo command specified.\n\27[0mExiting.")
return
end
if
not (
command == "install"
or command == "remove"
or command == "update"
or command == "list"
or command == "repo-list"
or command == "repo-add"
or command == "repo-remove"
or command == "info"
)
then
print(("\27[91mInvalid command: %s\n\27[0mExiting."):format(command))
return
end
local packages = parsed.args
table.remove(packages, 1)
-- Remove the command from the actual package list
-- local result, data, failure
do
local function check(condition, message)
if not condition then
print(message)
failure = true
end
end
if parsed.flags.u or parsed.flags["update-registry"] then
terminal.write("Updating registry...")
result, data = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/Pre-Alpha-3.0.0/ag2/registry.json")
check(result, "\27[91mFailed to get registry: " .. data .. "\27[0m")
local handle, errorMessage = fs.open("/ag2/registry.json", "w")
check(handle, "\27[91mFailed to open write handle to registry: " .. errorMessage .. "\27[0m")
local success, errorMessage = handle:write(data)
check(success, "\27[91mFailed to write to registry: " .. errorMessage .. "\27[0m")
handle:close()
else
result, data = getFile("/ag2/registry.json")
check(result, "\27[91mFailed to get registry: " .. data .. "\27[0m")
end
end
local success, registry = pcall(function()
return json.decode(data)
end)
if not success then
print(("\27[91mFailed to parse registry: %s\n\27[0mExiting."):format(registry))
return
end
local function getServersidePackageConfig(source, package)
local success, data = getFile(fs.concat(source, "/ag2.json"))
if not success then
return false, ("\27[91mFailed to get package config (ag2.json) of package '%s': " .. data .. "\27[0m"):format(package)
end
local success, packageConfig = pcall(function()
return json.decode(data)
end)
if not success then
return false, ("\27[91mFailed to parse package config (ag2.json) of package '%s': " .. packageConfig .. "\27[0m"):format(package)
end
if not packageConfig[package] then
return false, ("\27[91mRepository package config (ag2.json) does not contain package '%s'.\27[0m"):format(package)
end
return packageConfig[package]
end
-- Check if everything is valid
failure = false
local dependencyCounter = 0
local previousI = 1 -- See 190
::RESETLOOP::
if command == "install" then
for i = previousI, #packages do
if not packages[i] then
-- When packages are removed, the last packages can end up reading as nil
goto SKIP
end
local otherPackages = table.copy(packages)
table.remove(otherPackages, i)
-- This is to check if the package can be found in the others, or in other words, checking for duplicates
if table.find(otherPackages, packages[i]) then
print(("\27[93mDuplicate package specified (%s), skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
goto SKIP
end
local source
if parsed.s or parsed.source then
source = parsed.s or parsed.source
else
source = registry[packages[i]]
end
if not source then
print("\27[91mCould not find package in registry and no source provided: " .. packages[i] .. "\27[0m")
failure = true
goto SKIP
end
local packageConfig, errorMessage = getServersidePackageConfig(source, packages[i])
if not packageConfig then
failure = true
print(errorMessage)
goto SKIP
end
if packageConfig.type == "group" then
table.remove(packages, i)
for _, package in ipairs(packageConfig.packages) do
table.insert(packages, package)
end
previousI = i
goto RESETLOOP
-- Apparently "for i = 1, n" loops don't change when n changes. So when the table gets extended, packages near the end won't get picked up.
-- This is why it is needed to restart the loop.
elseif packageConfig.type == "virtual-package" then
print(("Installing virtual package %s"):format(packages[i]))
local pkgAskText = ("Select a package by typing in its number: 1) %s"):format(packageConfig.packages[1])
-- This is all a silly workaround to place commas correctly
for i = 2, #packageConfig.packages do
pkgAskText = pkgAskText .. (", %d) %s"):format(i, packageConfig.packages[i])
end
print(pkgAskText)
::RETRY::
local packageSel = terminal.read()
if not tonumber(packageSel) or tonumber(packageSel) % 1 ~= 0 then
-- Is there really no better way to check for an int..?
print("\27[93mNon-integer received - try again\27[0m")
goto RETRY
end
if tonumber(packageSel) < 1 or tonumber(packageSel) > #packageConfig.packages then
print("\27[93mInteger out of range - try again\27[0m")
end
packages[i] = packageConfig.packages[tonumber(packageSel)]
i = i - 1
goto SKIP
end
if fs.exists(("/ag2/pkg/%s.json"):format(packages[i])) then
print(("\27[93mPackage %s is already installed, skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
goto SKIP
end
if packageConfig.dependencies then
for _, dependency in ipairs(packageConfig.dependencies) do
table.insert(packages, i + 1, dependency)
dependencyCounter = dependencyCounter + 1
end
end
-- TODO: Add checks for conflicting packages
::SKIP::
end
elseif command == "remove" then
::JUMPBACK::
local doJumpBack = false
for i = 1, #packages do
if not fs.exists(("/ag2/pkg/%s.json"):format(packages[i])) then
if parsed.s or parsed.source then
source = parsed.s or parsed.source
else
source = registry[package]
end
if source then
local packageConfig = getServersidePackageConfig(source, packages[i])
if packageConfig then
if packageConfig.type == "virtual-package" or packageConfig.type == "group" then
table.remove(packages, i)
for _, groupPackage in ipairs(packageConfig.packages) do
table.insert(packages, groupPackage)
goto GOAHEAD
end
end
end
end
print(("\27[93mPackage %s is not installed, skipping\27[0m"):format(packages[i]))
table.remove(packages, i)
i = i - 1
::GOAHEAD::
end
end
-- I was originally gonna add this in the dependency cascade section, but realized it could shorten the normal dependency check code a bit
local dependencyList = {}
for _, packageConfig in ipairs(fs.list("/ag2/pkg/")) do
local package = packageConfig:sub(1, -6)
-- I'm not adding error handling here because if this fails then fuck you for touching the files by hand and good luck figuring this shit out
local _, data = getFile(("/ag2/pkg/%s.json"):format(package))
data = json.decode(data)
dependencyList[package] = data.dependencies
end
for _, package in ipairs(packages) do
if dependencyList[package] then
-- Check if all the deps are no longer needed and if they're auto-installed and stuff
for _, dependency in pairs(dependencyList[package]) do
if fs.exists(("/ag2/pkg/%s.json"):format(dependency)) then
local _, data = getFile(("/ag2/pkg/%s.json"):format(dependency))
data = json.decode(data)
if data.autoInstalled
and not table.find(packages, dependency) -- Just to prevent dependency loops and issues when re-checking the packages after jumpback
then
dependencyCounter = dependencyCounter + 1
table.insert(packages, dependency)
end
else
-- It could still be a group or a vpackage, and checking that is the job of the loop 2 loops back
table.insert(packages, dependency)
doJumpBack = true
end
end
end
end
-- Check for cascading dependencies
for packageName, dependencies in pairs(dependencyList) do
if not table.find(packages, packageName) then
for _, dependency in ipairs(dependencies) do
if table.find(packages, dependency) then
if parsed.flags.cascade or parsed.flags.C then
table.insert(packages, packageName)
dependencyCounter = dependencyCounter + 1
doJumpBack = true
-- Listen, I'm so sorry for this abhorrent bullshit code, but the newly added packages have to get checked one way or another and hopefully this is readable enough.
else
-- The Pyramids of Giza were built entirely out of silver. No they weren't...
print(("\27[93mPackage %s is depended on by %s, cannot uninstall without --cascade\27[0m"):format(dependency, packageName))
failure = true
end
end
end
end
end
if doJumpBack then
goto JUMPBACK
-- IT'S NOT SPAGHETTI SHUT UP SHUT UP SHU
end
end
-- TODO: Add checks for the other commands
if #packages == 0 then
print("\27[93mNo packages selected.\n\27[0mExiting.")
return
end
if failure then
print("Exiting.")
return
end
if command == "install" then
if dependencyCounter == 1 then
print("\27[93m1 dependency pulled in.\27[0m")
elseif dependencyCounter >= 2 then
print(("\27[93m%d dependencies pulled in.\27[0m"):format(dependencyCounter))
end
print("Packages that will be installed:")
print(table.concat(packages, ", "))
local answer = terminal.read({prefix = "\nContinue? [Y/n] "})
if answer:lower() == "n" then
print("Exiting.")
return
end
for _, package in ipairs(packages) do
local source
if parsed.s or parsed.source then
source = parsed.s or parsed.source
else
source = registry[package]
end
print(("Installing %s..."):format(package))
local _, data = getFile(fs.concat(source, "/ag2.json"))
local packageConfig = json.decode(data)[package]
if packageConfig.directories then
for _, directory in ipairs(packageConfig.directories) do
print((" Creating directory %s..."):format(directory))
fs.makeDirectory(directory)
end
end
if packageConfig.files then
for _, file in ipairs(packageConfig.files) do
::RETRY::
print((" Downloading file %s..."):format(file))
local success, data = getFile(fs.concat(source, file))
if not success then
print(("\27[91mFailed to get file '%s' of package '%s': " .. data .. "\27[0m"):format(file, package))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
else
goto RETRY
end
end
if fs.exists(file) then
print(("\27[93mFile '%s' already exists.\27[0m"):format(file))
local answer = terminal.read({prefix = "Abort, Overwrite, Skip? [a/O/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
end
end
local handle, errorMessage = fs.open(file, "w")
if not handle then
print(("\27[91mFailed to open write handle to file '%s': " .. errorMessage .. "\27[0m"):format(file))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
else
goto RETRY
end
end
local success, errorMessage = handle:write(data)
if not success then
handle:close()
print(("\27[91mFailed to write to file '%s': " .. errorMessage .. "\27[0m"):format(file))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file %s.\27[0m"):format(file))
goto SKIP
else
goto RETRY
end
end
handle:close()
::SKIP::
end
end
print(" Writing tracking file...")
if not fs.exists("/ag2/pkg/") then
fs.makeDirectory("/ag2/pkg/")
-- Technically this would break if /ag2/pkg/ was a file, but... why would it be a file?
end
-- TODO: Make functions for reading from and writing to a file with error handling since this is really repetitive
::RETRY::
local handle, errorMessage = fs.open(("/ag2/pkg/%s.json"):format(package), "w")
if not handle then
print(("\27[91mFailed to open write handle to file '/ag2/pkg/%s.json': " .. errorMessage .. "\27[0m"):format(package))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file /ag2/pkg/%s.json.\27[0m"):format(package))
goto SKIP
else
goto RETRY
end
end
local packageData = {
name = package,
version = packageConfig.version,
autoInstalled = false,
-- TODO: Make the above actually work
dependencies = packageConfig.dependencies,
conflicts = packageConfig.conflicts,
files = packageConfig.files,
directories = packageConfig.directories,
config = packageConfig.config
}
local trackingFile = json.encode(packageData)
local success, errorMessage = handle:write(trackingFile)
if not success then
handle:close()
print(("\27[91mFailed to write to file '/ag2/pkg/%s.json': " .. errorMessage .. "\27[0m"):format(package))
local answer = terminal.read({prefix = "Abort, Retry, Skip? [a/R/s]"})
if answer:lower() == "a" then
print("Exiting.")
return
elseif answer:lower() == "s" then
print((" \27[93mSkipped file /ag2/pkg/%s.json.\27[0m"):format(package))
goto SKIP
else
goto RETRY
end
else
handle:close()
end
::SKIP::
end
elseif command == "remove" then
if dependencyCounter == 1 then
print("\27[93m1 orphaned dependency will be removed.\27[0m")
elseif dependencyCounter >= 2 then
print(("\27[93m%d orphaned dependencies will be removed.\27[0m"):format(dependencyCounter))
end
print("Packages that will be removed:")
print(table.concat(packages, ", "))
local answer = terminal.read({prefix = "\nContinue? [Y/n] "})
if answer:lower() == "n" then
print("Exiting.")
return
end
for _, package in ipairs(packages) do
-- See line 263
local _, data = getFile(("/ag2/pkg/%s.json"):format(package))
data = json.decode(data)
if data.files then
for _, file in ipairs(data.files) do
print((" Removing file %s..."):format(file))
fs.remove(file) -- I cannot think of how this could fail. If you can, please add error handling here
end
end
if data.directories then
for _, directory in ipairs(data.directories) do
if fs.isDirectory(directory) then
if next(fs.list(directory)) == nil then
-- Apparently THAT's the best way to check if a table is empty in Lua. Alright I guess.
print((" Removing directory %s..."):format(directory))
fs.remove(directory)
else
print((" Directory %s specified by package %s still has something in it, skipping"):format(directory))
end
end
end
end
print(" Removing tracking file...")
fs.remove(("/ag2/pkg/%s.json"):format(package)) -- See line 500
end
end
print("Operation completed successfully.")
-688
View File
@@ -1,688 +0,0 @@
local packages = {...}
local command = table.remove(packages,1)
local shell = require("shell")
local fs = require("filesystem")
local component = require("component")
local agReg = require("/argentum/registry.cfg")
if not command then
shell.run("help argentum")
return
end
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.\27[0m")
return
end
local internet = component.internet
local source
if table.find(packages, "-s") then
source = table.remove(packages, table.find(packages, "-s") + 1)
table.remove(packages, table.find(packages, "-s"))
print("Using " .. source .. " as package source")
elseif table.find(packages, "--source") then
source = table.remove(packages, table.find(packages, "--source") + 1)
table.remove(packages, table.find(packages, "--source"))
print("Using " .. source .. " as package source")
else
print("Using main registry as package source")
end
if source and source:sub(1, 1) == "/" and source:sub(-1, -1) ~= "/" then
source = source .. "/"
end
local packageList = table.copy(packages)
local function getFile(path)
if path:sub(1,1) == "/" then
if not fs.exists(path) then
return false, "file does not exist"
end
local handle, data, tmpdata = fs.open(path, "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
return data
else
local request, data, tmpdata = nil, "", nil
local status, errorMessage = pcall(function()
request = internet.request(path)
request:finishConnect()
end)
if not status then
return false, errorMessage
end
local responseCode = request:response()
if responseCode and responseCode ~= 200 then
return false, responseCode
end
repeat
tmpdata = request.read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
return data
end
end
local i = 1
local function getAgConfig(package, source)
source = source or agReg[package]
local data, errorMessage = getFile(source .. "argentum.cfg")
if not data or data == "" then
print("\27[91mCould not fetch Ag config: " .. (errorMessage or "returned nil data") .. "\27[0m")
return false
end
local func, errorMessage = load(data, "=argentum.cfg", "bt", {})
if not func then
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.\27[0m")
return false
end
local agcfg
local status, errorMessage = pcall(function()
agcfg = func()
end)
if not status then
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.\27[0m")
return false
end
if not agcfg[package] or not agcfg[package].maindir or not agcfg[package].directories or not agcfg[package].files or not agcfg[package].version then
local response = "\27[91mAg config of " .. package .. " is improperly configured.\nPlease contact the package owner.\27[0m"
end
return agcfg
end
local function doChecks(package)
if not agReg[package] and not source then
print("\27[91mPackage " .. package .. " does not exist.\27[0m")
return false
end
if fs.exists("/argentum/store/" .. package) then
print("\27[91mPackage " .. package .. " is already installed.\27[0m")
return false
end
agcfg = getAgConfig(package, source)
if not agcfg then
return false
end
if agcfg[package].dependencies then
for _, dependency in ipairs(agcfg[package].dependencies) do
if not agReg[dependency] and not agcfg[dependency] then
local response = terminal.read({prefix = "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]\27[0m"})
if response:lower() ~= "s" then
fs.remove("/argentum/store/" .. package)
return false
end
end
end
for _, dependency in pairs(agcfg[package].dependencies) do
print(package .. " depends on " .. dependency)
if not table.find(packages, dependency) and doChecks(dependency) then
table.insert(packages, table.find(packages, package), dependency)
table.insert(packageList, dependency)
i = i + 1
end
end
end
return true
end
local function lpad(str, len, char)
str=tostring(str)
if char == nil then char = ' ' end
return string.rep(char, len - #str) .. str
end
local width, height = terminal.getResolution()
local function progress(package, progress)
terminal.write("\x1b[s")
local info = string.format("%s %s%%", package, lpad(math.floor(progress * 100), 2))
info = info .. string.rep(" ", width - #info)
local progX = math.floor(progress * width)
terminal.write("\x1b[42m\x1b[30m" .. info:sub(1, progX) .. "\x1b[40m\x1b[37m" .. info:sub(progX + 1) .. "\x1b[0m")
terminal.write("\x1b[u")
end
local function clearProgress()
terminal.write("\x1b[s")
terminal.write("\r\x1b[40m" .. string.rep(" ", width) .. "\x1b[0m\r")
terminal.write("\x1b[u")
end
local function installPackage(package, overwriteFlag)
if not overwriteFlag then
overwriteFlag = false
end
if not overwriteFlag then print("Installing " .. package .. "...") end
local agcfg = getAgConfig(package, source)
if not agcfg then
return false
end
local source = source or agReg[package]
local packageStore = "V" .. agcfg[package].version
if agcfg[package].dependencies then
for _, dependency in ipairs(agcfg[package].dependencies) do
if not agReg[dependency] and not agcfg[dependency] then
local response = terminal.read({prefix = "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]\27[0m"})
if response:lower() ~= "s" then
fs.remove("/argentum/store/" .. package)
return false
end
end
end
for _, dependency in pairs(agcfg[package].dependencies) do
if agReg[dependency] or agcfg[dependency] then
--installPackage(dependency)
packageStore = packageStore .. "\nD" .. dependency
end
end
end
if agcfg[package].directories then
for _, directory in pairs(agcfg[package].directories) do
if directory:sub(-1, -1) ~= "/" then
directory = directory .. "/"
end
packageStore = "A" .. directory .. "\n" .. packageStore
if not fs.exists(directory) then
fs.makeDirectory(directory)
end
end
end
for idx, file in ipairs(agcfg[package].files) do
clearProgress()
::retry::
print(" Downloading " .. file .. "...")
progress(package,idx/#agcfg[package].files)
local data, errorMessage = getFile(source .. agcfg[package].maindir .. file)
if not data then
clearProgress()
local response = terminal.read({prefix = "\27[91mCould not fetch " .. file .. ": " .. errorMessage .. "\n\27[0m[a - Abort/R - Retry/s - Skip]"})
if response:lower() == "a" then
fs.remove("/argentum/store/" .. package)
return false
elseif response:lower() == "s" then
goto skip
else
goto retry
end
end
if fs.exists(file) and not overwriteFlag then
if not fs.exists("/argentum/store/" .. package .. "/files/" .. file:match("(.*/)")) then
fs.makeDirectory("/argentum/store/" .. package .. "/files/" .. file:match("(.*/)"))
end
fs.copy(file, "/argentum/store/" .. package .. "/files/" .. file)
packageStore = packageStore .. "\nM" .. file
else
packageStore = packageStore .. "\nA" .. file
end
local handle, err = fs.open(file, "w")
handle:write(data)
handle:close()
::skip::
end
clearProgress()
fs.makeDirectory("/argentum/store/" .. package)
local handle = fs.open("/argentum/store/" .. package .. "/package.cfg", "w")
handle:write(packageStore)
handle:close()
return true
end
local function removePackage(package)
print("Removing " .. package .. "...")
if not fs.exists("/argentum/store/" .. package .. "/package.cfg") then
print("\27[91mLocal Ag config of " .. package .. " does not exist.\27[0m")
return false
end
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
data = data .. "\n"
local idx = 0
for line in data:gmatch("(.-)\n") do
idx=idx+1
if line:sub(1, 1) == "A" then
clearProgress()
::retry::
print(" Removing " .. line:sub(2) .. "...")
if line:sub(-1, -1) == "/" and fs.list(line:sub(2))[1] then
print(" There are still files in " .. line:sub(2) .. ". Skipping.")
else
progress(package,idx/select(2,data:gsub("\n","\n")))
local result, errorMessage = fs.remove(line:sub(2))
if not result then
clearProgress()
local response = terminal.read({prefix = "\27[91mFailed to remove " .. line:sub(2) .. ": " .. errorMessage .. "\n\27[0m[a - Abort/r - Retry/S - Skip]"})
if response:lower() == "a" then
return false
elseif response:lower() == "r" then
goto retry
end
end
end
elseif line:sub(1, 1) == "M" then
clearProgress()
::retry::
print(" Reverting " .. line:sub(2) .. "...")
progress(package,idx/select(2,data:gsub("\n","\n")))
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/files/" .. line:sub(2), "r"), "", nil
if not handle then
clearProgress()
local response = terminal.read({prefix = "\27[91mFailed to revert " .. line:sub(2) .. ": " .. data .. "\n\27[0m[a - Abort/R - Retry/s - Skip]"}) -- this is pretty stupid but i think the error message would get pushed to data
if response:lower() == "a" then
return false
elseif response:lower() == "s" then
goto skip
else
goto retry
end
end
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local handle = fs.open(line:sub(2), "w")
handle:write(data)
handle:close()
::skip::
end
end
clearProgress()
fs.remove("/argentum/store/" .. package .. "/")
return true
end
local function updatePackage(package)
print("Updating " .. package .. "...")
local agcfg = getAgConfig(package, source)
if not agcfg then
return false
end
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local oldFiles = {}
for line in (data .. "\n"):gmatch("(.-)\n") do
if line:sub(1, 1) == "A" or line:sub(1, 1) == "M" then
if agcfg[package].directories then
if not table.find(agcfg[package].files, line:sub(2)) and not table.find(agcfg[package].directories, line:sub(2, -2)) then
table.insert(oldFiles, line:sub(2))
end
else
if not table.find(agcfg[package].files, line:sub(2)) then
table.insert(oldFiles, line:sub(2))
end
end
end
end
for _, oldFile in pairs(oldFiles) do
print(" Removing " .. oldFile .. "...")
end
return installPackage(package, true)
end
local fails = {}
if command == "install" then
if not packages or not packages[1] then
print("Please specify packages to install.")
return
end
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
while true do
if not doChecks(packages[i]) then
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
end
i = i + 1
if i > #packages then
break
end
end
local answer
if #fails == 0 then
print("Packages that will be installed: " .. table.concat(packageList, ", "))
if terminal.read({prefix = "Would you like to proceed? [Y/n] "}):lower() == "n" then
return
end
elseif #packageList == 0 then
print("None of the packages can be installed.")
return
else
print("Some packages cannot be installed.")
print("Packages that will be installed: " .. table.concat(packageList, ", "))
print("Packages that cannot be installed: " .. table.concat(fails, ", "))
if terminal.read({prefix = "Would you like to proceed? [y/N] "}):lower() ~= "y" then
return
end
end
for _, failedPackage in pairs(fails) do
table.remove(packages, table.find(packages, failedPackage))
end
fails = {}
for _, package in ipairs(packages) do
if not installPackage(package) then
table.insert(fails, package)
table.remove(packageList, table.find(packageList, package))
end
end
if #fails == 0 then
print("Installation completed successfully.")
print("Packages installed: " .. table.concat(packageList, ", "))
elseif #packageList == 0 then
print("All packages failed to install.")
print("Packages that could not be installed: " .. table.concat(fails, ", "))
else
print("Some packages failed to install.")
print("Packages installed: " .. table.concat(packageList, ", "))
print("Packages that could not be installed: " .. table.concat(fails, ", "))
end
elseif command == "remove" then
if not packages or not packages[1] then
print("Please specify packages to remove.")
return
end
while true do
if not fs.exists("/argentum/store/" .. packages[i]) then
print("\27[91mPackage " .. packages[i] .. " is not installed.\27[0m")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
elseif packages[i] == "halyde" then -- yes, this stuff is hard-coded.
print("\27[91mFor obvious reasons, you can't uninstall Halyde.\27[0m")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
elseif packages[i] == "argentum" then
print("\27[91mFor obvious reasons, you can't uninstall Argentum.\27[0m")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
end
i = i + 1
if i > #packages then
break
end
end
-- do dependency checks
local packagesInstalled = fs.list("/argentum/store")
for _, currentPackage in pairs(packagesInstalled) do
if currentPackage:sub(-1, -1) == "/" and fs.exists("/argentum/store/" .. currentPackage .. "package.cfg") then
local handle, data, tmpdata = fs.open("/argentum/store/" .. currentPackage .. "package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
for line in (data.."\n"):gmatch("(.-)\n") do
for i = 1, #packages do
if line == "D" .. packages[i] then
print(packages[i] .. " depends on " .. currentPackage:sub(1, -2))
if not table.find(packages, currentPackage:sub(1, -2)) then
table.insert(packages, table.find(packages, packages[i]), currentPackage:sub(1, -2))
table.insert(packageList, currentPackage:sub(1, -2))
i = i + 1
end
end
end
end
end
end
local answer
if #fails == 0 then
print("Packages that will be removed: " .. table.concat(packageList, ", "))
if terminal.read({prefix = "Would you like to proceed? [Y/n] "}):lower() == "n" then
return
end
elseif #packageList == 0 then
print("None of the packages can be removed.")
return
else
print("Some packages cannot be removed.")
print("Packages that will be removed: " .. table.concat(packageList, ", "))
print("Packages that cannot be removed: " .. table.concat(fails, ", "))
if terminal.read({prefix = "Would you like to proceed? [y/N] "}):lower() ~= "y" then
return
end
end
for _, failedPackage in pairs(fails) do
table.remove(packages, table.find(packages, failedPackage))
end
fails = {}
for _, package in ipairs(packages) do
if not removePackage(package) then
table.insert(fails, package)
table.remove(packageList, table.find(packageList, package))
end
end
if #fails == 0 then
print("Removal completed successfully.")
print("Packages removed: " .. table.concat(packageList, ", "))
elseif #packageList == 0 then
print("All packages failed to be removed.")
print("Packages that could not be removed: " .. table.concat(fails, ", "))
else
print("Some packages failed to be removed.")
print("Packages removed: " .. table.concat(packageList, ", "))
print("Packages that could not be removed: " .. table.concat(fails, ", "))
end
elseif command == "update" then
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
if not packages[1] then
local packagesInstalled = fs.list("/argentum/store/")
for _, currentPackage in pairs(packagesInstalled) do
if currentPackage:sub(-1, -1) == "/" and fs.exists("/argentum/store/" .. currentPackage .. "package.cfg") then
table.insert(packages, currentPackage:sub(1, -2))
table.insert(packageList, currentPackage:sub(1, -2))
end
end
end
while true do
local nonexistent = false -- I couldn't figure out a better way to do this, so I have to use a flag if the package doesn't exist
if not fs.exists("/argentum/store/" .. packages[i]) then
print("\27[91mPackage " .. packages[i] .. " is not installed.")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
nonexistent = true
end
if not nonexistent then
-- Check if up to date
local agcfg = getAgConfig(packages[i], source)
if not agcfg then
return false
end
local handle, data, tmpdata = fs.open("/argentum/store/" .. packages[i] .. "/package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local version = "0.0.0"
for line in (data.."\n"):gmatch("(.-)\n") do
if line:sub(1, 1) == "V" then
version = line:sub(2)
break
end
end
if agcfg[packages[i]].version == version then
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
else
print(packages[i].." is out of date [\x1b[93m"..version.."\x1b[0m < \x1b[92m"..agcfg[packages[i]].version.."\x1b[0m")
end
end
i = i + 1
if i > #packages then
break
end
end
local answer
if #packageList == 0 then
if #fails == 0 then
print("All packages are up to date.")
return
else
print("None of the packages can be updated.")
return
end
elseif #fails == 0 then
print("Packages that will be updated: " .. table.concat(packageList, ", "))
if terminal.read({prefix = "Would you like to proceed? [Y/n] "}):lower() == "n" then
return
end
else
print("Some packages cannot be updated.")
print("Packages that will be updated: " .. table.concat(packageList, ", "))
print("Packages that cannot be updated: " .. table.concat(fails, ", "))
if terminal.read({prefix = "Would you like to proceed? [y/N] "}):lower() ~= "y" then
return
end
end
for _, failedPackage in pairs(fails) do
table.remove(packages, table.find(packages, failedPackage))
end
fails = {}
for _, package in pairs(packages) do
-- Previous up-to-date check
--local agcfg = getAgConfig(package, source)
--if not agcfg then
-- return false
--end
--local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
--repeat
-- tmpdata = handle:read(math.huge)
-- data = data .. (tmpdata or "")
--until not tmpdata
--handle:close()
--local version = "0.0.0"
--for line in (data.."\n"):gmatch("(.-)\n") do
-- if line:sub(1, 1) == "V" then
-- version = line:sub(2)
-- break
-- end
--end
--if agcfg[package].version == version then
-- print(package .. " is up to date")
-- goto skip
--end
if not updatePackage(package) then
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
goto skip
end
::skip::
end
if #fails == 0 then
print("Update completed successfully.")
print("Packages updated: " .. table.concat(packageList, ", "))
elseif #packageList == 0 then
print("All packages failed to update.")
print("Packages that could not update: " .. table.concat(fails, ", "))
else
print("Some packages failed to update.")
print("Packages updated: " .. table.concat(packageList, ", "))
print("Packages that could not update: " .. table.concat(fails, ", "))
end
elseif command == "info" then
if not packages[1] then
print("Please specify a package to show information about.")
return
end
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
if not agReg[packages[1]] and not source then
print("\27[91mPackage " .. packages[1] .. " does not exist.")
return
end
local agcfg = getAgConfig(packages[1], source)
if not agcfg then
return false
end
print("\27[93m" .. packages[1] .. "\27[0m v" .. agcfg[packages[1]].version .. "\n " .. (agcfg[packages[1]].description or "No description."):gsub("\n", " \n"))
elseif command == "search" then
if not packages[1] then
print("Please specify a search term.")
return
end
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = require("/argentum/registry.cfg")
local searchResults = {}
for packageName, _ in pairs(agReg) do
if packageName:find(packages[1], 1, true) then
table.insert(searchResults, packageName)
end
end
if not searchResults[1] then
print("No search results found for " .. packages[1] .. ".")
return
end
table.sort(searchResults)
print("Search results: \n " .. table.concat(searchResults, "\n "))
elseif command == "list" then
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil") .. "\27[0m")
end
agReg = require("/argentum/registry.cfg")
local sortedPackages = {}
for packageName, _ in pairs(agReg) do
table.insert(sortedPackages, packageName)
end
table.sort(sortedPackages)
print("List of available Ag packages: \n " .. table.concat(sortedPackages, "\n "))
else
shell.run("help ag")
end
-334
View File
@@ -1,334 +0,0 @@
local fs = require("filesystem")
local shell = require("shell")
local gpu = require("component").gpu
local event = require("event")
local computer = require("computer")
local ocelot = require("component").ocelot
local resX, resY = gpu.getResolution()
local textBuffer = gpu.allocateBuffer(resX, resY - 1)
local args = {...}
local file = args[1]
if not file then
print("\x1b[91mEnter a file name.")
return
end
if fs.isDirectory(file) then
print("\x1b[91mThe specified file is a directory.")
return
end
if file:sub(1, 1) ~= "/" then
file = fs.concat(shell.getWorkingDirectory(), file)
end
local data = ""
if fs.exists(file) then
local handle = fs.open(file)
local tmpdata
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
end
local lines = {}
for line in data:gmatch("[^\r\n]+") do
table.insert(lines, line)
end
local function renderText(xOffset, yOffset)
gpu.setActiveBuffer(textBuffer)
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
gpu.fill(1, 1, resX, resY - 1, " ")
for i = yOffset + 1, #lines do
gpu.set(1, i - yOffset, lines[i]:sub(xOffset + 1))
end
gpu.setActiveBuffer(0)
gpu.bitblt(0, 1, 1, resX, resY - 1, textBuffer, 1, 1)
end
local function addLine(pos)
if pos <= #lines then
for i = #lines, pos, -1 do
lines[i + 1] = lines[i]
end
lines[pos] = ""
else
table.insert(lines, "")
end
end
local function removeLine(pos)
length = #lines
for i = pos + 1, length do
lines[i - 1] = lines[i]
end
lines[length] = nil
end
local function save()
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
gpu.set(1, resY, "Enter a location to save:")
local savepath = file or ""
local saveCursorX = 27 + #savepath
local ready = false
local eventArgs = {}
gpu.fill(27, resY, resX - 27, 1, " ")
gpu.set(27, resY, savepath)
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
gpu.set(saveCursorX, resY, " ")
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
repeat
local shouldRender = false
coroutine.yield()
eventArgs = {event.pull("key_down", 0)}
if keyboard.keys[eventArgs[4]] == "enter" then
ready = true
end
if keyboard.keys[eventArgs[4]] == "back" then
savepath = string.sub(savepath, 1, #savepath - 1)
if saveCursorX > 27 then
saveCursorX = saveCursorX - 1
end
shouldRender = true
end
if not keyboard.keys.special[eventArgs[4]] and keyboard.keys[eventArgs[4]] then
savepath = savepath .. (string.char(eventArgs[3]) or "")
saveCursorX = saveCursorX + 1
shouldRender = true
end
if shouldRender then
gpu.fill(27, resY, resX - 27, 1, " ")
gpu.set(27, resY, savepath)
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
gpu.set(saveCursorX, resY, " ")
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
end
until ready
gpu.fill(1, resY, resX, 1, " ")
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
gpu.set(1, resY, "^X")
gpu.set(10, resY, "^S")
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
gpu.set(4, resY, "Exit")
gpu.set(13, resY, "Save")
local text = table.concat(lines, "\n")
local handle = fs.open(savepath, "w")
handle:write(text)
handle:close()
file = savepath
end
-- Initialize screen
renderText(0, 0)
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
gpu.set(1, resY, "^X")
gpu.set(10, resY, "^S")
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
gpu.set(4, resY, "Exit")
gpu.set(13, resY, "Save")
local scrollX = 0
local scrollY = 0
local cursorX = 1 -- Absolute position, not accounting for scrolling
local cursorY = 1
local cursorWhite = true
local oldTime = computer.uptime()
while true do
local renderBufferFlag = false -- Flag to render the whole text buffer
-- Handle events
local previousCursorX -- Used for blackening the previous cursor location when the cursor is moved
local previousCursorY
coroutine.yield()
local eventArgs = {}
repeat
eventArgs = {event.pull("key_down", 0)}
-- The logical solution here for flashing the cursor would be to set the timeout to 0.5, and, if the timeout is reached, change the color.
-- However, that makes scrolling freeze the screen up completely.
-- Thus, for flashing the cursor, a timer is needed.
if computer.uptime() >= oldTime + 0.5 then
oldTime = computer.uptime()
cursorWhite = not cursorWhite
end
if next(eventArgs) ~= nil then
cursorWhite = true
oldTime = computer.uptime()
end
if eventArgs[1] == "key_down" then
-- Mouse events might be added later, that's why this if statement is here
if keyboard.getCtrlDown() then
-- Special commands
if keyboard.keys[eventArgs[4]] == "x" then
goto exit
end
if keyboard.keys[eventArgs[4]] == "s" then
save()
end
else
if keyboard.keys[eventArgs[4]] == "up" and cursorY > 1 then
if cursorY - scrollY <= 1 then
renderBufferFlag = true
scrollY = scrollY - 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorY = cursorY - 1
-- The cursor absolute position still has to be moved, even if on-screen it won't move
if cursorX > string.len(lines[cursorY]) + 1 then -- cursor snapping, +1 to be 1 char in front of end of line
cursorX = string.len(lines[cursorY]) + 1
end
end
if keyboard.keys[eventArgs[4]] == "down" then
if cursorY - scrollY >= resY - 1 then
renderBufferFlag = true
scrollY = scrollY + 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorY = cursorY + 1
if cursorX > string.len(lines[cursorY]) + 1 then
cursorX = string.len(lines[cursorY]) + 1
end
end
if keyboard.keys[eventArgs[4]] == "left" and cursorX > 1 then
if cursorX - scrollX <= 1 then
renderBufferFlag = true
scrollX = scrollX - 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorX = cursorX - 1
end
if keyboard.keys[eventArgs[4]] == "right" and cursorX < string.len(lines[cursorY]) + 1 then
if cursorX - scrollX >= resX then
renderBufferFlag = true
scrollX = scrollX + 1
else
if not previousCursorX and not previousCursorY then
previousCursorX = cursorX
previousCursorY = cursorY
end
end
cursorX = cursorX + 1
end
if not keyboard.keys.special[eventArgs[4]] then
local line = lines[cursorY] or ""
line = string.sub(line, 1, cursorX - 1) .. string.char(eventArgs[3]) .. string.sub(line, cursorX, -1)
lines[cursorY] = line
cursorX = cursorX + 1
renderBufferFlag = true
end
if keyboard.keys[eventArgs[4]] == "back" then
local line = lines[cursorY]
local prevline = lines[cursorY - 1]
if cursorX > 1 then
line = string.sub(line, 1, cursorX - 2) .. string.sub(line, cursorX, -1) -- remove 1 char
elseif prevline then
prevline = prevline .. line -- copy line up to the next before removing it
ocelot.log(prevline)
line = nil
end
if line then
lines[cursorY] = line
else
removeLine(cursorY)
end
lines[cursorY - 1] = prevline
if not line then
cursorY = cursorY - 1 -- this can only trigger if the line is not the first
end
if cursorX > 1 then
cursorX = cursorX - 1
end
renderBufferFlag = true
end
if keyboard.keys[eventArgs[4]] == "enter" then
addLine(cursorY + 1)
cursorY = cursorY + 1
cursorX = 1
renderBufferFlag = true
end
end
end
until next(eventArgs) == nil
local displayedCursorX = cursorX - scrollX
local displayedCursorY = cursorY - scrollY
local previousDisplayedCursorX -- What a mouthful
local previousDisplayedCursorY
if previousCursorX and previousCursorY then
previousDisplayedCursorX = previousCursorX - scrollX
previousDisplayedCursorY = previousCursorY - scrollY
end
if renderBufferFlag then
renderText(scrollX, scrollY)
if cursorWhite then
-- If the cursor is black, then there's no need to do anything because there is no cursor after calling renderText().
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
local letter = gpu.get(displayedCursorX, displayedCursorY)
gpu.set(displayedCursorX, displayedCursorY, letter)
-- TODO: Account for scrolling
end
else
if cursorWhite then
if previousCursorX or previousCursorY then
-- Remove old cursor
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
local letter = gpu.get(previousDisplayedCursorX, previousDisplayedCursorY)
gpu.set(previousDisplayedCursorX, previousDisplayedCursorY, letter)
end
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
local letter = gpu.get(displayedCursorX, displayedCursorY)
gpu.set(displayedCursorX, displayedCursorY, letter)
else
-- If renderText() hasn't been called, the cursor may still be white and need to be turned black.
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
local letter = gpu.get(displayedCursorX, displayedCursorY)
gpu.set(displayedCursorX, displayedCursorY, letter)
end
end
end
-- Cleanup
::exit::
gpu.freeBuffer(textBuffer)
gpu.setActiveBuffer(0)
terminal.clear()
-19
View File
@@ -1,19 +0,0 @@
local computer = require("computer")
local cliparse = require("cliparse")
cliparse.config({
["f"] = 1,
["frequency"] = 1,
["t"] = 1,
["time"] = 1,
})
local parsed, err = cliparse.parse(...)
if not parsed then
return print("\x1b[91m" .. err .. "\x1b[0m")
end
local freq =
tonumber(parsed.flags.f and parsed.flags.f[1] or parsed.flags.frequency and parsed.flags.frequency[1] or "440")
local time = tonumber(parsed.flags.t and parsed.flags.t[1] or parsed.flags.time and parsed.flags.time[1] or "0.1")
computer.beep(freq, time)
-585
View File
@@ -1,585 +0,0 @@
local raster = require("raster")
local event = require("event")
local color_table = {
0xAAAAAA, 0x666666, 0xFF0000, 0xFF0000, 0xFFDDDD, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF,
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000,
0xAA00AA, 0x660066, 0xFF0000, 0xFF0000, 0xFFDDDD, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF,
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000
}
local ball_bitplanes = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0007, 0xff80, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0xffff, 0xfc00, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x00f8, 0x007f, 0xffff, 0xff80, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0fe6, 0x03ff, 0xffff, 0xfff0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0xfd1b, 0x980f, 0xffff, 0xfffc, 0x0000, 0x0000,
0x0000, 0x0000, 0x000f, 0xc14e, 0xb410, 0xffff, 0xffff, 0x8000, 0x0000,
0x0000, 0x0000, 0x00fc, 0x927a, 0xe92a, 0x7fff, 0xffff, 0xf000, 0x0000,
0x0000, 0x0000, 0x00c5, 0x09db, 0xa26f, 0x6fff, 0xffff, 0xfe00, 0x0000,
0x0000, 0x0000, 0x01d0, 0x46ee, 0xc4d2, 0x0fff, 0xffff, 0xff80, 0x0000,
0x0000, 0x0000, 0x0bba, 0x3bbd, 0x99b2, 0xd5bf, 0xffff, 0xffc0, 0x0000,
0x0000, 0x0000, 0x0d76, 0x5ef6, 0x3324, 0xd57f, 0xffff, 0xffe0, 0x0000,
0x0000, 0x0000, 0x5dec, 0x8fdc, 0x4665, 0xd55f, 0xffff, 0xfff0, 0x0000,
0x0000, 0x0000, 0xab99, 0x18f8, 0x8ccd, 0x9455, 0xffff, 0xfff8, 0x0000,
0x0000, 0x0002, 0xd772, 0x3103, 0x19c9, 0x96aa, 0xffff, 0xfffc, 0x0000,
0x0000, 0x000d, 0xaecc, 0x6238, 0x3199, 0x96aa, 0x6fff, 0xfffe, 0x0000,
0x0000, 0x001a, 0xbd98, 0xc673, 0x8399, 0xb695, 0x97ff, 0xffff, 0x8000,
0x0000, 0x006d, 0x7331, 0x8c73, 0x1b39, 0xb255, 0xbbff, 0xffff, 0xc000,
0x0000, 0x00d2, 0xe663, 0x18e7, 0x30f3, 0x324a, 0x9dff, 0xffff, 0xe000,
0x0000, 0x0fa5, 0xccc3, 0x31ce, 0x31c3, 0x324b, 0xebff, 0xffff, 0xf000,
0x0000, 0x1917, 0xb986, 0x23ce, 0x618c, 0x336d, 0x71ff, 0xffff, 0xf800,
0x0000, 0x1ade, 0x670c, 0x639c, 0x639c, 0xc325, 0xa8ff, 0xffff, 0xfc00,
0x0000, 0x32a3, 0xce18, 0xc73c, 0xc319, 0xcf26, 0xf37f, 0xffff, 0xfe00,
0x0000, 0x35a6, 0x7c31, 0x8e38, 0xc719, 0xccf2, 0xd5df, 0xffff, 0xff00,
0x0000, 0x6946, 0xc463, 0x1e71, 0x8739, 0x8ccf, 0x7a6f, 0xffff, 0xff00,
0x0000, 0xcacc, 0xc707, 0x1c71, 0x8e31, 0x9ccc, 0x6d37, 0xffff, 0xff80,
0x0000, 0xd69d, 0x8e7e, 0x38e3, 0x0e33, 0x98cc, 0xcd4b, 0xffff, 0xff80,
0x0001, 0x9599, 0x8e73, 0xb9e3, 0x1c73, 0x98cc, 0xc9b7, 0xffff, 0xffc0,
0x0001, 0xad33, 0x1ce3, 0x81c6, 0x1c63, 0x98cc, 0xc92b, 0xffff, 0xffc0,
0x0003, 0x4b33, 0x1ce7, 0x0dc6, 0x3c63, 0x18cc, 0xc92b, 0xffff, 0xffe0,
0x0003, 0x5666, 0x39c7, 0x1c4c, 0x38e7, 0x18cc, 0xccaa, 0x3fff, 0xffe0,
0x0006, 0x96e6, 0x39ce, 0x1872, 0x78c7, 0x19cc, 0xc495, 0x3fff, 0xfff0,
0x000d, 0x2ccc, 0x738e, 0x38f3, 0xb0c7, 0x19cc, 0xc495, 0x1fff, 0xfff0,
0x000d, 0x5dcc, 0x739c, 0x30e7, 0x89c7, 0x39ce, 0xc495, 0x1fff, 0xfff0,
0x001a, 0x5b98, 0xe71c, 0x71e7, 0x0f8e, 0x31ce, 0x64d4, 0xffff, 0xfff8,
0x001a, 0xbb18, 0xe738, 0x71cf, 0x1e4e, 0x31ce, 0x64ca, 0x8fff, 0xfff8,
0x0008, 0xb731, 0xce38, 0xe1ce, 0x1c71, 0x31ce, 0x664a, 0x8fff, 0xfffc,
0x000a, 0xf631, 0xce78, 0xe38e, 0x3cf1, 0xf1ce, 0x664a, 0x77ff, 0xfffc,
0x000a, 0x9e63, 0x9c71, 0xc39e, 0x3ce3, 0xc9ce, 0x6649, 0x47ff, 0xfffe,
0x000a, 0x9063, 0x9cf1, 0xc71c, 0x38e3, 0x8ece, 0x6261, 0x5fff, 0xfffe,
0x0004, 0x9327, 0x38e3, 0x873c, 0x78e3, 0x9e36, 0x6265, 0x1bff, 0xffff,
0x0015, 0x933f, 0x39e3, 0x8e38, 0x79e3, 0x9c30, 0x6264, 0x23ff, 0xffff,
0x0015, 0x3339, 0xb1c7, 0x8e38, 0xf1c7, 0x9c71, 0x9324, 0xafff, 0xffff,
0x0015, 0x2639, 0x83c7, 0x0c78, 0xf1c7, 0x1c61, 0x9f30, 0x8dff, 0xffff,
0x0015, 0x2671, 0x8d8f, 0x1c70, 0xe3c7, 0x3c63, 0x9cf2, 0x91ff, 0xffff,
0x0015, 0x2673, 0x8c76, 0x1871, 0xe38f, 0x3863, 0x1cce, 0x16ff, 0xffff,
0x0009, 0x2673, 0x1c71, 0x38f1, 0xe38e, 0x38e3, 0x38cd, 0xc6ff, 0xffff,
0x000b, 0x2673, 0x1861, 0xf0e1, 0xc78e, 0x78c3, 0x39cd, 0xbbff, 0xffff,
0x000b, 0x6663, 0x18e3, 0xc9e3, 0xc70e, 0x70c7, 0x399d, 0xb47f, 0xffff,
0x000b, 0x6c67, 0x18e3, 0x8ec3, 0xc71e, 0x71c6, 0x3999, 0xb4ff, 0xffff,
0x004b, 0x6ce7, 0x38e3, 0x9e27, 0x871c, 0x71c6, 0x3199, 0x34ff, 0xffff,
0x002b, 0x6ce7, 0x30c3, 0x9c38, 0x4f1c, 0xf1c6, 0x339b, 0x2cff, 0xfffe,
0x0012, 0x6ce6, 0x31c7, 0x9c78, 0x761c, 0xe186, 0x739b, 0x6aff, 0xfffe,
0x0016, 0x4cc6, 0x31c7, 0x1c70, 0xf13c, 0xe38e, 0x739b, 0x69ff, 0xfffe,
0x0096, 0xccce, 0x3187, 0x3c70, 0xe1d8, 0xe38c, 0x733b, 0x69ff, 0xfffe,
0x00e6, 0xd8ce, 0x718f, 0x3871, 0xe3c1, 0xe38c, 0x6333, 0x69ff, 0xfffe,
0x0068, 0xd9ce, 0x618e, 0x38f1, 0xc386, 0xc30c, 0x6732, 0x69ff, 0xfffe,
0x0071, 0x198e, 0x638e, 0x78e1, 0xc78e, 0x271c, 0x6732, 0x59ff, 0xfffe,
0x0074, 0x219c, 0x630e, 0x70e3, 0xc70c, 0x3898, 0xe732, 0x55ff, 0xfffe,
0x0034, 0xa61c, 0xe31e, 0x71e3, 0x871c, 0x78f8, 0xc732, 0x55ff, 0xfffe,
0x0038, 0x866c, 0xc31c, 0x71c7, 0x8f18, 0x71e4, 0xce72, 0x55ff, 0xfffe,
0x003a, 0x9263, 0xc71c, 0xf1c7, 0x0e38, 0xf1c7, 0x0e66, 0xd5ff, 0xfffe,
0x001a, 0x1323, 0x261c, 0xe3c7, 0x1e38, 0xe3ce, 0x7664, 0xd5ff, 0xfffe,
0x001c, 0x5323, 0x393c, 0xe38f, 0x1c70, 0xe38e, 0x71e4, 0xb3ff, 0xfffc,
0x0015, 0x4323, 0x39d8, 0xe38e, 0x1c71, 0xc79c, 0xe304, 0xabff, 0xfffc,
0x0015, 0x0933, 0x39c1, 0xe38e, 0x3ce1, 0xc71c, 0xe33b, 0xabff, 0xfff8,
0x000f, 0x2933, 0x39c6, 0xc79e, 0x38e3, 0x8f39, 0xc636, 0x6bff, 0xfff8,
0x000a, 0xa933, 0x39c6, 0x3b1c, 0x39c3, 0x8e39, 0xc676, 0x97ff, 0xfff0,
0x000a, 0xa993, 0x39c6, 0x383c, 0x79c7, 0x0e73, 0x8c6c, 0xafff, 0xfff0,
0x0007, 0x9591, 0x39ce, 0x30d8, 0x73c7, 0x1c73, 0x8ccd, 0x2fff, 0xffe0,
0x0005, 0x5491, 0xb9cc, 0x71c4, 0xf386, 0x1ce7, 0x19db, 0x5fff, 0xffe0,
0x0005, 0x5491, 0x99cc, 0x7187, 0x678e, 0x38e7, 0x1992, 0x9fff, 0xffe0,
0x0002, 0xd491, 0x998c, 0x718e, 0x1b0c, 0x39ce, 0x33b4, 0xbfff, 0xffc0,
0x0001, 0x2a99, 0x998c, 0x638e, 0x389c, 0x71ce, 0x3325, 0x7fff, 0xffc0,
0x0000, 0x9249, 0x998c, 0x631c, 0x31f8, 0x739c, 0x6669, 0x7fff, 0xff80,
0x0000, 0x4849, 0x998c, 0xe31c, 0x71c4, 0xe39c, 0x665a, 0xffff, 0xff80,
0x0000, 0x26b9, 0x998c, 0xe718, 0x63cf, 0x0738, 0xccd4, 0xffff, 0xff00,
0x0000, 0x095f, 0x999c, 0xc638, 0xe38e, 0x3f38, 0xd8b5, 0xffff, 0xff00,
0x0000, 0x065b, 0x1998, 0xc630, 0xc71c, 0x71b1, 0x9969, 0xffff, 0xfe00,
0x0000, 0x032f, 0x6198, 0xce71, 0xc73c, 0xe301, 0xb153, 0xffff, 0xfe00,
0x0000, 0x01d5, 0xa619, 0xcc61, 0x8e38, 0xc61c, 0x32d7, 0xffff, 0xfc00,
0x0000, 0x02e7, 0xb279, 0x8c63, 0x9c71, 0xcc39, 0x82a7, 0xffff, 0xf800,
0x0000, 0x0112, 0xd367, 0x9cc3, 0x1ce3, 0x9873, 0x3baf, 0xffff, 0xe000,
0x0000, 0x0085, 0x5b26, 0x78c7, 0x39e7, 0x30e6, 0x748f, 0xffff, 0xc000,
0x0000, 0x004b, 0xe926, 0x6186, 0x39ce, 0x619d, 0xe96f, 0xffff, 0x8000,
0x0000, 0x001c, 0xad26, 0x664e, 0x739c, 0x6333, 0xa6df, 0xffff, 0x0000,
0x0000, 0x000e, 0xd5a6, 0xcefc, 0x6718, 0xc667, 0x4b7f, 0xfffe, 0x0000,
0x0000, 0x0004, 0xd4b6, 0xcce3, 0xe739, 0x8cce, 0xb6ff, 0xfff8, 0x0000,
0x0000, 0x000d, 0x2ab4, 0xcdc6, 0x3e73, 0x19bd, 0x6bff, 0xfff0, 0x0000,
0x0000, 0x0003, 0x6a94, 0xd9cc, 0x63e6, 0x3374, 0xb7ff, 0xffe0, 0x0000,
0x0000, 0x0000, 0xd954, 0xdb98, 0xc60c, 0x4eeb, 0x5fff, 0xffc0, 0x0000,
0x0000, 0x0000, 0x36d5, 0xd331, 0x1860, 0x99d6, 0x7fff, 0xff00, 0x0000,
0x0000, 0x0000, 0x0d85, 0x9662, 0x31ce, 0xf7ba, 0xffff, 0xfe00, 0x0000,
0x0000, 0x0000, 0x0313, 0xa6cc, 0x473b, 0x1eb3, 0xffff, 0xf800, 0x0000,
0x0000, 0x0000, 0x00c1, 0x4d99, 0x9cec, 0x42e7, 0xffff, 0xe000, 0x0000,
0x0000, 0x0000, 0x0030, 0x7722, 0x7362, 0x087f, 0xffff, 0x8000, 0x0000,
0x0000, 0x0000, 0x000c, 0xa185, 0xcb90, 0x81ff, 0xfffc, 0x0000, 0x0000,
0x0000, 0x0000, 0x0003, 0x0fef, 0x2e49, 0x1fff, 0xfff0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0803, 0x7281, 0xffff, 0xff80, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0038, 0x481f, 0xffff, 0xfe00, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xf100, 0x007f, 0xf800, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x00fe, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0f7b, 0xfc00, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0xf7ec, 0x3ff0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000f, 0x7e70, 0xc4ff, 0x8000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x00f7, 0xe383, 0x0fcd, 0xa000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x057e, 0x0e1c, 0x3f8f, 0x9800, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x1a60, 0x78f0, 0xff1c, 0xde00, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x2cc3, 0xc3c1, 0xfe3c, 0xeb80, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0xd187, 0xdf07, 0xfc38, 0xe7e0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0001, 0x660f, 0xf01f, 0xf879, 0xe798, 0x0000, 0x0000, 0x0000,
0x0000, 0x0006, 0xcc1f, 0xe0ff, 0xf0f1, 0xe798, 0x0000, 0x0000, 0x0000,
0x0000, 0x001b, 0x187f, 0xc1ff, 0xe1f1, 0xe7cd, 0x0000, 0x0000, 0x0000,
0x0000, 0x002e, 0x30ff, 0x83c1, 0xc1e1, 0xe7cc, 0xa000, 0x0000, 0x0000,
0x0000, 0x00dc, 0xc1ff, 0x0783, 0xe3e1, 0xc7e6, 0xd000, 0x0000, 0x0000,
0x0000, 0x0171, 0x83fe, 0x0f83, 0xe3c1, 0xc3e6, 0x5800, 0x0000, 0x0000,
0x0000, 0x06e3, 0x07fc, 0x1f07, 0xc0c3, 0xc3f3, 0x2c00, 0x0000, 0x0000,
0x0000, 0x0bc6, 0x0ffc, 0x3e0f, 0xc1f3, 0xc3f3, 0x3500, 0x0000, 0x0000,
0x0000, 0x1198, 0x3ff8, 0x3c0f, 0x81ff, 0xc3f1, 0x9a80, 0x0000, 0x0000,
0x0000, 0x13e0, 0x7ff0, 0x7c1f, 0x83ff, 0x03f9, 0xcd40, 0x0000, 0x0000,
0x0000, 0x23c3, 0xffe0, 0xf83f, 0x03fe, 0x0ff8, 0xc5a0, 0x0000, 0x0000,
0x0000, 0x27c7, 0x9fc1, 0xf03f, 0x07fe, 0x0f3c, 0xe6c0, 0x0000, 0x0000,
0x0000, 0x4f87, 0x0783, 0xe07e, 0x07fe, 0x0f0c, 0x6360, 0x0000, 0x0000,
0x0000, 0x8f0f, 0x07c7, 0xe07e, 0x0ffe, 0x1f0f, 0x71b0, 0x0000, 0x0000,
0x0000, 0x9f1e, 0x0f8f, 0xc0fc, 0x0ffc, 0x1f0f, 0x0198, 0x0000, 0x0000,
0x0001, 0x1e1e, 0x0f83, 0xc1fc, 0x1ffc, 0x1f0f, 0x0fda, 0x0000, 0x0000,
0x0001, 0x3e3c, 0x1f03, 0xf1f8, 0x1ffc, 0x1f0f, 0x0fcd, 0x0000, 0x0000,
0x0002, 0x7c3c, 0x1f07, 0xfff8, 0x3ffc, 0x1f0f, 0x0fcc, 0x8000, 0x0000,
0x0002, 0x7878, 0x3e07, 0xffb0, 0x3ff8, 0x1f0f, 0x0fcc, 0x8000, 0x0000,
0x0004, 0xf8f8, 0x3e0f, 0xff82, 0x7ff8, 0x1e0f, 0x07e6, 0x8000, 0x0000,
0x0009, 0xf0f0, 0x7c0f, 0xff03, 0xfff8, 0x1e0f, 0x07e6, 0x4000, 0x0000,
0x0009, 0xe1f0, 0x7c1f, 0xff07, 0xf7f8, 0x3e0f, 0x07e6, 0x4000, 0x0000,
0x0013, 0xe3e0, 0xf81f, 0xfe07, 0xf1f0, 0x3e0f, 0x87e7, 0x4000, 0x0000,
0x0013, 0xc3e0, 0xf83f, 0xfe0f, 0xe070, 0x3e0f, 0x87f3, 0x2000, 0x0000,
0x002f, 0xc7c1, 0xf03f, 0xfe0f, 0xe07e, 0x3e0f, 0x87f3, 0x2000, 0x0000,
0x002c, 0x87c1, 0xf07f, 0xfc0f, 0xc0fe, 0x3e0f, 0x87f3, 0xa800, 0x0000,
0x002c, 0xef83, 0xe07f, 0xfc1f, 0xc0fc, 0x0e0f, 0x87f1, 0x9000, 0x0000,
0x002c, 0xe383, 0xe0ff, 0xf81f, 0xc0fc, 0x0f0f, 0x83f9, 0x9000, 0x0000,
0x0028, 0xe3e7, 0xc0ff, 0xf83f, 0x80fc, 0x1fff, 0x83f9, 0xd400, 0x0000,
0x0059, 0xe3ff, 0xc1ff, 0xf03f, 0x81fc, 0x1fff, 0x83f8, 0xcc00, 0x0000,
0x0059, 0xc3fe, 0x01ff, 0xf03f, 0x01f8, 0x1ffe, 0x13f8, 0xc800, 0x0000,
0x0059, 0xc7fe, 0x03ff, 0xf07f, 0x01f8, 0x1ffe, 0x1ffc, 0xea00, 0x0000,
0x0059, 0xc7fe, 0x0fff, 0xe07f, 0x03f8, 0x3ffc, 0x1f3c, 0xe600, 0x0000,
0x0059, 0xc7fc, 0x0f87, 0xe07e, 0x03f0, 0x3ffc, 0x1f0c, 0x6500, 0x0000,
0x0051, 0xc7fc, 0x1f81, 0xc0fe, 0x03f0, 0x3ffc, 0x3f0e, 0x7500, 0x0000,
0x0053, 0xc7fc, 0x1f81, 0xc0fe, 0x07f0, 0x7ffc, 0x3e0e, 0x3200, 0x0000,
0x0053, 0x87fc, 0x1f03, 0xf1fc, 0x07f0, 0x7ff8, 0x3e1e, 0x3e80, 0x0000,
0x0053, 0x8ff8, 0x1f03, 0xf0fc, 0x07e0, 0x7ff8, 0x3e1e, 0x3e00, 0x0000,
0x0093, 0x8ff8, 0x3f03, 0xe038, 0x07e0, 0x7ff8, 0x3e1e, 0x3e00, 0x0000,
0x00b3, 0x8ff8, 0x3f03, 0xe03f, 0xcfe0, 0xfff8, 0x3c1c, 0x3e00, 0x0000,
0x00a3, 0x8ff8, 0x3e07, 0xe07f, 0xffe0, 0xfff8, 0x7c1c, 0x7c00, 0x0000,
0x00a7, 0x8ff8, 0x3e07, 0xe07f, 0xfec0, 0xfff0, 0x7c1c, 0x7d00, 0x0000,
0x00a7, 0x0ff0, 0x3e07, 0xc07f, 0xfe00, 0xfff0, 0x7c3c, 0x7c00, 0x0000,
0x00b7, 0x1ff0, 0x7e0f, 0xc07f, 0xfc01, 0xfff0, 0x7c3c, 0x7c00, 0x0000,
0x00ff, 0x1ff0, 0x7e0f, 0xc0ff, 0xfc07, 0xfff0, 0x783c, 0x7c00, 0x0000,
0x005e, 0x1ff0, 0x7c0f, 0x80ff, 0xf80f, 0xdfe0, 0x783c, 0x7c00, 0x0000,
0x005f, 0x3fe0, 0x7c0f, 0x80ff, 0xf80f, 0xc0e0, 0xf83c, 0x7800, 0x0000,
0x003f, 0x3860, 0xfc1f, 0x81ff, 0xf81f, 0x80e0, 0xf83c, 0x7800, 0x0000,
0x002f, 0x1870, 0xfc1f, 0x81ff, 0xf01f, 0x81f8, 0xf07c, 0x7800, 0x0000,
0x002f, 0x1c7c, 0xf81f, 0x01ff, 0xf03f, 0x01f8, 0x3078, 0xf800, 0x0000,
0x001f, 0x9c3c, 0x381f, 0x03ff, 0xe03f, 0x03f0, 0x7878, 0xf800, 0x0000,
0x0017, 0x9c3c, 0x3f3f, 0x03ff, 0xe07f, 0x03f0, 0x7ff8, 0xf800, 0x0000,
0x001f, 0x8c3c, 0x3fff, 0x03ff, 0xe07e, 0x07e0, 0xfff8, 0xf000, 0x0000,
0x001f, 0xce3c, 0x3ffe, 0x03ff, 0xc0fe, 0x07e0, 0xffc3, 0xf000, 0x0000,
0x000b, 0xce3c, 0x3ff8, 0x07ff, 0xc0fc, 0x0fc1, 0xffc7, 0xb000, 0x0000,
0x000f, 0xce3c, 0x3ff8, 0x3fff, 0xc1fc, 0x0fc1, 0xff87, 0x1800, 0x0000,
0x000f, 0xce1c, 0x3ff8, 0x3fff, 0x81f8, 0x0f83, 0xff8f, 0x3000, 0x0000,
0x0005, 0xe61e, 0x3ff0, 0x3f1f, 0x83f8, 0x1f83, 0xff0e, 0x3000, 0x0000,
0x0007, 0xe71e, 0x3ff0, 0x7e07, 0x03f8, 0x1f07, 0xfe1c, 0x6000, 0x0000,
0x0007, 0xe71e, 0x1ff0, 0x7e07, 0x87f0, 0x3f07, 0xfe1c, 0xe000, 0x0000,
0x0003, 0xe71e, 0x1ff0, 0x7e0f, 0xe3f0, 0x3e0f, 0xfc38, 0xc000, 0x0000,
0x0002, 0xf31e, 0x1ff0, 0x7c0f, 0xc0e0, 0x7e0f, 0xfc39, 0x8000, 0x0000,
0x0001, 0x5b8e, 0x1ff0, 0x7c1f, 0xc1e0, 0x7c1f, 0xf871, 0x8000, 0x0000,
0x0000, 0xad8e, 0x1ff0, 0xfc1f, 0x81fc, 0xfc1f, 0xf863, 0x0000, 0x0000,
0x0000, 0x54fe, 0x1ff0, 0xf81f, 0x83ff, 0xf83f, 0xf0e7, 0x0000, 0x0000,
0x0000, 0x2278, 0x1fe0, 0xf83f, 0x03ff, 0xc03f, 0xe0c6, 0x0000, 0x0000,
0x0000, 0x137c, 0x1fe0, 0xf83f, 0x07ff, 0x81ff, 0xe18e, 0x0000, 0x0000,
0x0000, 0x09bc, 0x7fe0, 0xf07e, 0x07ff, 0x03ff, 0xc19c, 0x0000, 0x0000,
0x0000, 0x049e, 0x3861, 0xf07e, 0x0fff, 0x07e0, 0xc318, 0x0000, 0x0000,
0x0000, 0x054e, 0x3c61, 0xf07c, 0x1ffe, 0x0fc1, 0xe338, 0x0000, 0x0000,
0x0000, 0x02a7, 0x1c79, 0xe0fc, 0x1ffc, 0x1f83, 0xc230, 0x0000, 0x0000,
0x0000, 0x0157, 0x9c38, 0x60f8, 0x3ff8, 0x3f07, 0x87f0, 0x0000, 0x0000,
0x0000, 0x00a3, 0x8e38, 0x79f8, 0x3ff0, 0x7e1e, 0x0f80, 0x0000, 0x0000,
0x0000, 0x0049, 0xce38, 0x7fb0, 0x7fe0, 0x7c3c, 0x3f00, 0x0000, 0x0000,
0x0000, 0x0024, 0xe638, 0xff00, 0x7fe0, 0xf878, 0x7c00, 0x0000, 0x0000,
0x0000, 0x0012, 0xe738, 0xff03, 0xffc1, 0xf0f0, 0xf800, 0x0000, 0x0000,
0x0000, 0x000c, 0x7338, 0xfe07, 0xcf83, 0xe1c1, 0xf000, 0x0000, 0x0000,
0x0000, 0x0003, 0x7318, 0xfe0f, 0x8307, 0xc387, 0xc000, 0x0000, 0x0000,
0x0000, 0x0000, 0xdd98, 0xfc1f, 0x07cf, 0x8f0f, 0x8000, 0x0000, 0x0000,
0x0000, 0x0000, 0x3799, 0xfc3e, 0x1f87, 0x1e1f, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0db9, 0xf87c, 0x3e0f, 0xf83c, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x033b, 0xf8f0, 0x783f, 0xe0f8, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x00cd, 0x91e1, 0xe0ff, 0x83f0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0032, 0xbbc3, 0x83fc, 0x0c40, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000c, 0xb1c6, 0x0fe0, 0xe100, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0003, 0x4ff0, 0x3f8e, 0x1000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0802, 0xfcf1, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0038, 0x6f90, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xfd00, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x00ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0fbc, 0xf800, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0xf9f0, 0x3ff0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000f, 0x8f80, 0xfb1f, 0x8000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x00f8, 0xfc03, 0xf1ce, 0xa000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0687, 0xf01f, 0xc3f1, 0xd800, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x1c7f, 0x80ff, 0x07e0, 0xea00, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x30fc, 0x03fe, 0x1fc0, 0xf2c0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0xe1f8, 0x5ff8, 0x3fc0, 0xf9b0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0001, 0x87f0, 0xffe0, 0x7f81, 0xf9ec, 0x0000, 0x0000, 0x0000,
0x0000, 0x0007, 0x0fe1, 0xff00, 0xff01, 0xf8e3, 0x0000, 0x0000, 0x0000,
0x0000, 0x001c, 0x1f83, 0xfe03, 0xfe01, 0xf8f1, 0xc000, 0x0000, 0x0000,
0x0000, 0x0030, 0x3f0f, 0xfc01, 0xfe01, 0xf8f0, 0xf000, 0x0000, 0x0000,
0x0000, 0x00e0, 0xfe1f, 0xf803, 0xfc01, 0xf8f8, 0xf800, 0x0000, 0x0000,
0x0000, 0x0181, 0xfc3f, 0xf003, 0xfc01, 0xfc78, 0x6c00, 0x0000, 0x0000,
0x0000, 0x0703, 0xf87f, 0xe007, 0xff03, 0xfc7c, 0x3600, 0x0000, 0x0000,
0x0000, 0x0c07, 0xf0ff, 0xc00f, 0xfe03, 0xfc7c, 0x3a00, 0x0000, 0x0000,
0x0000, 0x1e1f, 0xc1ff, 0xc00f, 0xfe0f, 0xfc7e, 0x1d00, 0x0000, 0x0000,
0x0000, 0x1cff, 0x87ff, 0x801f, 0xfc1f, 0xfc3e, 0x0e80, 0x0000, 0x0000,
0x0000, 0x3cfc, 0x0fff, 0x003f, 0xfc1f, 0xf03f, 0x0640, 0x0000, 0x0000,
0x0000, 0x39f8, 0x1ffe, 0x003f, 0xf81f, 0xf03f, 0x0760, 0x0000, 0x0000,
0x0000, 0x71f8, 0x07fc, 0x007f, 0xf83f, 0xf00f, 0x83b0, 0x0000, 0x0000,
0x0000, 0xf3f0, 0x07f8, 0x007f, 0xf03f, 0xe00f, 0x81d8, 0x0000, 0x0000,
0x0000, 0xe7e0, 0x0ff0, 0x00ff, 0xf03f, 0xe00f, 0xf1ec, 0x0000, 0x0000,
0x0001, 0xe7e0, 0x0ffc, 0x01ff, 0xe07f, 0xe00f, 0xf1e4, 0x0000, 0x0000,
0x0001, 0xcfc0, 0x1ffc, 0x01ff, 0xe07f, 0xe00f, 0xf1f2, 0x0000, 0x0000,
0x0003, 0x8fc0, 0x1ff8, 0x0fff, 0xc07f, 0xe00f, 0xf1f1, 0x0000, 0x0000,
0x0003, 0x9f80, 0x3ff8, 0x1fff, 0xc0ff, 0xe00f, 0xf0f0, 0xc000, 0x0000,
0x0007, 0x1f00, 0x3ff0, 0x1ffd, 0x80ff, 0xe00f, 0xf8f8, 0xc000, 0x0000,
0x000e, 0x3f00, 0x7ff0, 0x3ffc, 0x00ff, 0xe00f, 0xf8f8, 0x6000, 0x0000,
0x000e, 0x7e00, 0x7fe0, 0x3ff8, 0x01ff, 0xc00f, 0xf8f8, 0x6000, 0x0000,
0x001c, 0x7c00, 0xffe0, 0x7ff8, 0x01ff, 0xc00f, 0xf8f8, 0x6000, 0x0000,
0x001c, 0xfc00, 0xffc0, 0x7ff0, 0x007f, 0xc00f, 0xf8fc, 0x3000, 0x0000,
0x0030, 0xf801, 0xffc0, 0xfff0, 0x007f, 0xc00f, 0xf87c, 0x3000, 0x0000,
0x0030, 0xf801, 0xff80, 0xfff0, 0x00ff, 0xc00f, 0xf87c, 0x3000, 0x0000,
0x0030, 0xf003, 0xff81, 0xffe0, 0x00ff, 0xf00f, 0xf87e, 0x1800, 0x0000,
0x0030, 0xfc03, 0xff01, 0xffe0, 0x00ff, 0xf00f, 0xfc7e, 0x1800, 0x0000,
0x0030, 0xfc27, 0xff03, 0xffc0, 0x00ff, 0xe03f, 0xfc7e, 0x1800, 0x0000,
0x0061, 0xfc3f, 0xfe03, 0xffc0, 0x01ff, 0xe03f, 0xfc7f, 0x0800, 0x0000,
0x0061, 0xfc3f, 0xfe07, 0xffc0, 0x01ff, 0xe07f, 0xec3f, 0x0c00, 0x0000,
0x0061, 0xf83f, 0xfc07, 0xff80, 0x01ff, 0xe07f, 0xe03f, 0x0c00, 0x0000,
0x0061, 0xf87f, 0xf00f, 0xff80, 0x03ff, 0xc07f, 0xe03f, 0x0400, 0x0000,
0x0061, 0xf87f, 0xf007, 0xff80, 0x03ff, 0xc07f, 0xe00f, 0x8600, 0x0000,
0x0061, 0xf87f, 0xe001, 0xff00, 0x03ff, 0xc0ff, 0xc00f, 0x8600, 0x0000,
0x0063, 0xf87f, 0xe001, 0xff00, 0x07ff, 0x80ff, 0xc00f, 0xc300, 0x0000,
0x0063, 0xf87f, 0xe003, 0xfe00, 0x07ff, 0x80ff, 0xc01f, 0xc700, 0x0000,
0x0063, 0xf07f, 0xe003, 0xff00, 0x07ff, 0x81ff, 0xc01f, 0xc700, 0x0000,
0x00e3, 0xf0ff, 0xc003, 0xffc0, 0x07ff, 0x81ff, 0xc01f, 0xc700, 0x0000,
0x00c3, 0xf0ff, 0xc003, 0xffc0, 0x4fff, 0x01ff, 0xc01f, 0xcf00, 0x0000,
0x00c3, 0xf0ff, 0xc007, 0xff80, 0x7fff, 0x01ff, 0x801f, 0x8f00, 0x0000,
0x00c7, 0xf0ff, 0xc007, 0xff80, 0xffff, 0x03ff, 0x801f, 0x8e00, 0x0000,
0x00c7, 0xf0ff, 0xc007, 0xff80, 0xffff, 0x03ff, 0x803f, 0x8e00, 0x0000,
0x00c7, 0xe0ff, 0x800f, 0xff81, 0xfffe, 0x03ff, 0x803f, 0x8e00, 0x0000,
0x00cf, 0xe1ff, 0x800f, 0xff01, 0xfff8, 0x03ff, 0x803f, 0x8e00, 0x0000,
0x0067, 0xe1ff, 0x800f, 0xff01, 0xfff0, 0x07ff, 0x803f, 0x9e00, 0x0000,
0x0067, 0xc1ff, 0x800f, 0xff03, 0xfff0, 0x00ff, 0x003f, 0x9e00, 0x0000,
0x0027, 0xc07f, 0x001f, 0xfe03, 0xffe0, 0x00ff, 0x003f, 0x9e00, 0x0000,
0x0033, 0xe07f, 0x001f, 0xfe07, 0xffe0, 0x01ff, 0x007f, 0x9e00, 0x0000,
0x0033, 0xe07f, 0x001f, 0xfe07, 0xffc0, 0x01ff, 0xc07f, 0x1e00, 0x0000,
0x0013, 0xe03f, 0xc01f, 0xfc07, 0xffc0, 0x03ff, 0x807f, 0x1e00, 0x0000,
0x0019, 0xe03f, 0xc13f, 0xfc0f, 0xff80, 0x03ff, 0x81ff, 0x3c00, 0x0000,
0x0019, 0xf03f, 0xc1ff, 0xfc0f, 0xff80, 0x07ff, 0x03ff, 0x3c00, 0x0000,
0x0019, 0xf03f, 0xc1ff, 0xfc0f, 0xff00, 0x07ff, 0x03fc, 0x3c00, 0x0000,
0x000d, 0xf03f, 0xc1ff, 0xf81f, 0xff00, 0x0ffe, 0x07f8, 0x3c00, 0x0000,
0x000c, 0xf03f, 0xc1ff, 0xc01f, 0xfe00, 0x0ffe, 0x07f8, 0x1c00, 0x0000,
0x000c, 0xf01f, 0xc1ff, 0xc03f, 0xfe00, 0x0ffc, 0x0ff0, 0x3800, 0x0000,
0x0006, 0xf81f, 0xc1ff, 0xc01f, 0xfc00, 0x1ffc, 0x0ff0, 0x3800, 0x0000,
0x0006, 0x781f, 0xc1ff, 0x8007, 0xfc00, 0x1ff8, 0x1fe0, 0x7000, 0x0000,
0x0006, 0x781f, 0xe1ff, 0x8007, 0xf800, 0x3ff8, 0x1fe0, 0xf000, 0x0000,
0x0003, 0x781f, 0xe1ff, 0x800f, 0xfc00, 0x3ff0, 0x3fc0, 0xe000, 0x0000,
0x0003, 0x3c1f, 0xe1ff, 0x800f, 0xff00, 0x7ff0, 0x3fc1, 0xc000, 0x0000,
0x0001, 0x9c0f, 0xe1ff, 0x801f, 0xfe00, 0x7fe0, 0x7f81, 0xc000, 0x0000,
0x0000, 0xce0f, 0xe1ff, 0x001f, 0xfe04, 0xffe0, 0x7f83, 0x8000, 0x0000,
0x0000, 0x673f, 0xe1ff, 0x001f, 0xfc0f, 0xffc0, 0xff07, 0x8000, 0x0000,
0x0000, 0x339f, 0xe1ff, 0x003f, 0xfc0f, 0xffc0, 0xff07, 0x0000, 0x0000,
0x0000, 0x1b9f, 0xe1ff, 0x003f, 0xf81f, 0xfe01, 0xfe0f, 0x0000, 0x0000,
0x0000, 0x0dcf, 0x81ff, 0x007f, 0xf83f, 0xfc01, 0xfe1e, 0x0000, 0x0000,
0x0000, 0x06e7, 0xc07e, 0x007f, 0xf03f, 0xf800, 0xfc1c, 0x0000, 0x0000,
0x0000, 0x0677, 0xc07e, 0x007f, 0xe07f, 0xf001, 0xfc3c, 0x0000, 0x0000,
0x0000, 0x033b, 0xe07e, 0x00ff, 0xe0ff, 0xe003, 0xfc38, 0x0000, 0x0000,
0x0000, 0x0199, 0xe03f, 0x80ff, 0xc1ff, 0xc007, 0xf8f8, 0x0000, 0x0000,
0x0000, 0x00cd, 0xf03f, 0x81ff, 0xc1ff, 0x801f, 0xf1f0, 0x0000, 0x0000,
0x0000, 0x006e, 0xf03f, 0x87ff, 0x83ff, 0x803f, 0xc7e0, 0x0000, 0x0000,
0x0000, 0x0037, 0xf83f, 0x0fff, 0x87ff, 0x007f, 0x8f80, 0x0000, 0x0000,
0x0000, 0x001b, 0x783f, 0x0ffc, 0x07fe, 0x00ff, 0x3f00, 0x0000, 0x0000,
0x0000, 0x000f, 0xbc3f, 0x0ff8, 0x0ffc, 0x01fe, 0x7c00, 0x0000, 0x0000,
0x0000, 0x0003, 0xbc1f, 0x1ff0, 0x03f8, 0x03f8, 0xf800, 0x0000, 0x0000,
0x0000, 0x0000, 0xee1f, 0x1fe0, 0x07f0, 0x0ff3, 0xe000, 0x0000, 0x0000,
0x0000, 0x0000, 0x3b1e, 0x1fc0, 0x1ff8, 0x1fe7, 0x8000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0ede, 0x1f80, 0x3ff0, 0xffdf, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x03ac, 0x3f00, 0x7fc3, 0xff3c, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x00ee, 0x1e01, 0xff0f, 0xfcf8, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0039, 0x3c03, 0xfc7f, 0xf060, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000e, 0x3e07, 0xf3ff, 0x0100, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0003, 0x77ff, 0xcff0, 0x1000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x09fc, 0x7f01, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0008, 0x7010, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0500, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x000f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x003f, 0xfc00, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01ff, 0xc7f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0fff, 0x030f, 0x8000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0xfffc, 0x01f0, 0xe000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0707, 0xffe0, 0x03f9, 0xe800, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x1f9f, 0xff00, 0x07ff, 0xf200, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x3f03, 0xfc00, 0x1fff, 0x0c80, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0xfe00, 0x6000, 0x3fff, 0x0020, 0x0000, 0x0000, 0x0000,
0x0000, 0x0001, 0xf800, 0xfc00, 0x7ffe, 0x01c8, 0x0000, 0x0000, 0x0000,
0x0000, 0x0007, 0xf001, 0xff80, 0xfffe, 0x00fe, 0x0000, 0x0000, 0x0000,
0x0000, 0x001f, 0xe003, 0xffe3, 0xfffe, 0x00fe, 0x0000, 0x0000, 0x0000,
0x0000, 0x003f, 0xc00f, 0xffff, 0xfffe, 0x00ff, 0x3000, 0x0000, 0x0000,
0x0000, 0x00ff, 0x001f, 0xfffc, 0x1ffe, 0x00ff, 0x1800, 0x0000, 0x0000,
0x0000, 0x01fe, 0x003f, 0xfffc, 0x03fe, 0x007f, 0x8c00, 0x0000, 0x0000,
0x0000, 0x07fc, 0x007f, 0xfff8, 0x003c, 0x007f, 0xc600, 0x0000, 0x0000,
0x0000, 0x03f8, 0x00ff, 0xfff0, 0x000c, 0x007f, 0xc300, 0x0000, 0x0000,
0x0000, 0x0060, 0x01ff, 0xfff0, 0x000f, 0x007f, 0xe180, 0x0000, 0x0000,
0x0000, 0x00f0, 0x07ff, 0xffe0, 0x001f, 0xf03f, 0xf0c0, 0x0000, 0x0000,
0x0000, 0x00ff, 0x0fff, 0xffc0, 0x001f, 0xfc3f, 0xf860, 0x0000, 0x0000,
0x0000, 0x01ff, 0xffff, 0xffc0, 0x001f, 0xffff, 0xf860, 0x0000, 0x0000,
0x0000, 0x01ff, 0xfbff, 0xff80, 0x003f, 0xfff3, 0xfc30, 0x0000, 0x0000,
0x0000, 0x03ff, 0xf83f, 0xff80, 0x003f, 0xfff0, 0xfe18, 0x0000, 0x0000,
0x0000, 0x07ff, 0xf00f, 0xff00, 0x003f, 0xfff0, 0x0e0c, 0x0000, 0x0000,
0x0000, 0x07ff, 0xf000, 0x3e00, 0x007f, 0xfff0, 0x0106, 0x0000, 0x0000,
0x0000, 0x0fff, 0xe000, 0x0e00, 0x007f, 0xfff0, 0x01e3, 0x0000, 0x0000,
0x0000, 0x0fff, 0xe000, 0x0e00, 0x007f, 0xfff0, 0x01ff, 0x8000, 0x0000,
0x0000, 0x1fff, 0xc000, 0x1fc0, 0x00ff, 0xfff0, 0x00ff, 0x0000, 0x0000,
0x0000, 0x1fff, 0xc000, 0x1ffe, 0x00ff, 0xfff0, 0x00ff, 0x0000, 0x0000,
0x0000, 0x3fff, 0x8000, 0x3fff, 0xc0ff, 0xfff0, 0x00ff, 0x8000, 0x0000,
0x0000, 0x7fff, 0x8000, 0x3fff, 0xf9ff, 0xfff0, 0x00ff, 0x8000, 0x0000,
0x0000, 0x7fff, 0x0000, 0x7fff, 0xffff, 0xfff0, 0x00ff, 0x8000, 0x0000,
0x0000, 0xffff, 0x0000, 0x7fff, 0xffbf, 0xfff0, 0x00ff, 0xc000, 0x0000,
0x003c, 0xfffe, 0x0000, 0xffff, 0xff80, 0xfff0, 0x007f, 0xc000, 0x0000,
0x003f, 0x7ffe, 0x0000, 0xffff, 0xff00, 0x3ff0, 0x007f, 0xc000, 0x0000,
0x003f, 0x0ffc, 0x0001, 0xffff, 0xff00, 0x07f0, 0x007f, 0xe000, 0x0000,
0x003f, 0x03fc, 0x0001, 0xffff, 0xff00, 0x00f0, 0x007f, 0xe000, 0x0000,
0x003f, 0x0038, 0x0003, 0xffff, 0xff00, 0x0038, 0x007f, 0xe000, 0x0000,
0x007e, 0x0038, 0x0003, 0xffff, 0xfe00, 0x003e, 0x007f, 0xf000, 0x0000,
0x007e, 0x003f, 0xc007, 0xffff, 0xfe00, 0x007f, 0xf03f, 0xf000, 0x0000,
0x007e, 0x003f, 0xf007, 0xffff, 0xfe00, 0x007f, 0xfc3f, 0xf000, 0x0000,
0x007e, 0x007f, 0xfe0f, 0xffff, 0xfc00, 0x007f, 0xffff, 0xf800, 0x0000,
0x007e, 0x007f, 0xffff, 0xffff, 0xfc00, 0x007f, 0xfff3, 0xf800, 0x0000,
0x007e, 0x007f, 0xfffe, 0xffff, 0xfc00, 0x00ff, 0xfff0, 0x7800, 0x0000,
0x007c, 0x007f, 0xfffe, 0x3fff, 0xf800, 0x00ff, 0xfff0, 0x0c00, 0x0000,
0x007c, 0x007f, 0xfffc, 0x07ff, 0xf800, 0x00ff, 0xffe0, 0x0700, 0x0000,
0x007c, 0x007f, 0xfffc, 0x00ff, 0xf800, 0x01ff, 0xffe0, 0x0780, 0x0000,
0x00fc, 0x00ff, 0xfffc, 0x001f, 0xf800, 0x01ff, 0xffe0, 0x0780, 0x0000,
0x00fc, 0x00ff, 0xfffc, 0x0000, 0x7000, 0x01ff, 0xffe0, 0x0f80, 0x0000,
0x00fc, 0x00ff, 0xfff8, 0x0000, 0x7800, 0x01ff, 0xffe0, 0x0f00, 0x0000,
0x00f8, 0x00ff, 0xfff8, 0x0000, 0xff00, 0x03ff, 0xffe0, 0x0f00, 0x0000,
0x0078, 0x00ff, 0xfff8, 0x0000, 0xffe0, 0x03ff, 0xffc0, 0x0f00, 0x0000,
0x0008, 0x00ff, 0xfff0, 0x0001, 0xfff8, 0x03ff, 0xffc0, 0x0f00, 0x0000,
0x000e, 0x01ff, 0xfff0, 0x0001, 0xffff, 0x03ff, 0xffc0, 0x0f00, 0x0000,
0x0007, 0xc1ff, 0xfff0, 0x0001, 0xffff, 0xe7ff, 0xffc0, 0x1f00, 0x0000,
0x0007, 0xf9ff, 0xfff0, 0x0003, 0xffff, 0xff7f, 0xffc0, 0x1e00, 0x0000,
0x0007, 0xffff, 0xffe0, 0x0003, 0xffff, 0xff1f, 0xffc0, 0x1e00, 0x0000,
0x0003, 0xff8f, 0xffe0, 0x0007, 0xffff, 0xfe03, 0xff80, 0x1e00, 0x0000,
0x0003, 0xff80, 0xffe0, 0x0007, 0xffff, 0xfe00, 0x3f80, 0x1e00, 0x0000,
0x0003, 0xffc0, 0x1fe0, 0x0007, 0xffff, 0xfc00, 0x0780, 0x1e00, 0x0000,
0x0001, 0xffc0, 0x01c0, 0x000f, 0xffff, 0xfc00, 0x0180, 0x3e00, 0x0000,
0x0001, 0xffc0, 0x01e0, 0x000f, 0xffff, 0xf800, 0x03e0, 0x3c00, 0x0000,
0x0001, 0xffc0, 0x01f8, 0x000f, 0xffff, 0xf800, 0x03ff, 0x3c00, 0x0000,
0x0001, 0xffc0, 0x01ff, 0x001f, 0xffff, 0xf000, 0x07ff, 0xfc00, 0x0000,
0x0000, 0xffc0, 0x01ff, 0xfc1f, 0xffff, 0xf000, 0x07ff, 0xe000, 0x0000,
0x0000, 0xffe0, 0x01ff, 0xff3f, 0xffff, 0xf000, 0x0fff, 0xc000, 0x0000,
0x0000, 0xffe0, 0x01ff, 0xffff, 0xffff, 0xe000, 0x0fff, 0xc000, 0x0000,
0x0000, 0x7fe0, 0x01ff, 0xfffb, 0xffff, 0xe000, 0x1fff, 0x8000, 0x0000,
0x0000, 0x7fe0, 0x01ff, 0xfff8, 0x7fff, 0xc000, 0x1fff, 0x0000, 0x0000,
0x0000, 0x7fe0, 0x01ff, 0xfff0, 0x03ff, 0xc000, 0x3fff, 0x0000, 0x0000,
0x0003, 0xbfe0, 0x01ff, 0xfff0, 0x007f, 0x8000, 0x3ffe, 0x0000, 0x0000,
0x0001, 0xe7f0, 0x01ff, 0xffe0, 0x001f, 0x8000, 0x7ffe, 0x0000, 0x0000,
0x0000, 0xf1f0, 0x01ff, 0xffe0, 0x0007, 0x0000, 0x7ffc, 0x0000, 0x0000,
0x0000, 0x7830, 0x01ff, 0xffe0, 0x000f, 0xe000, 0xfff8, 0x0000, 0x0000,
0x0000, 0x3c1e, 0x01ff, 0xffc0, 0x000f, 0xf800, 0xfff8, 0x0000, 0x0000,
0x0000, 0x1c1f, 0x81ff, 0xffc0, 0x001f, 0xffc1, 0xfff0, 0x0000, 0x0000,
0x0000, 0x0e0f, 0xf9ff, 0xff80, 0x003f, 0xfff1, 0xffe0, 0x0000, 0x0000,
0x0000, 0x0707, 0xffff, 0xff80, 0x003f, 0xffff, 0xffe0, 0x0000, 0x0000,
0x0000, 0x0787, 0xff9f, 0xff80, 0x007f, 0xfffe, 0x1fc0, 0x0000, 0x0000,
0x0000, 0x03c3, 0xff81, 0xff00, 0x00ff, 0xfffc, 0x01c0, 0x0000, 0x0000,
0x0000, 0x01e1, 0xffc0, 0x1f00, 0x01ff, 0xfff8, 0x00c0, 0x0000, 0x0000,
0x0000, 0x00f1, 0xffc0, 0x0600, 0x01ff, 0xffe0, 0x01f0, 0x0000, 0x0000,
0x0000, 0x0070, 0xffc0, 0x07c0, 0x03ff, 0xffc0, 0x07e0, 0x0000, 0x0000,
0x0000, 0x0038, 0xffc0, 0x0ff0, 0x07ff, 0xff80, 0x0f80, 0x0000, 0x0000,
0x0000, 0x001c, 0x7fc0, 0x0fff, 0x07ff, 0xff00, 0x3f00, 0x0000, 0x0000,
0x0000, 0x0000, 0x3fc0, 0x0fff, 0xffff, 0xfe00, 0x7c00, 0x0000, 0x0000,
0x0000, 0x0000, 0x7fe0, 0x1fff, 0xfcff, 0xfc00, 0xf800, 0x0000, 0x0000,
0x0000, 0x0000, 0x13e0, 0x1fff, 0xf83f, 0xf003, 0xe000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0460, 0x1fff, 0xe007, 0xe007, 0x8000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0110, 0x1fff, 0xc000, 0xc01f, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x004e, 0x3fff, 0x8003, 0xf03c, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0017, 0xfffe, 0x000f, 0xfff8, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0005, 0xc3fc, 0x007f, 0xff80, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0001, 0xc038, 0x03ff, 0xfe00, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x87f8, 0x0fff, 0xe000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x07ff, 0x7ffe, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0007, 0x8fe0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000
}
--local SCREEN_W = 336
--local SCREEN_H = 216
local SCREEN_W = 320
local SCREEN_H = 200
local function l(x1, y1, x2, y2, c)
raster.drawLine(x1-8, y1-8, x2-8, y2-8, c)
end
local function g(x, y)
return raster.get(x-8, y-8)
end
local function s(x, y, c)
raster.set(x-8, y-8, c)
end
local BALL_W = 144
local BALL_H = 100
local ONE_PLANE_LEN = BALL_W * BALL_H / 16
local function ball()
local color_cycle = 2
local pos = { x = 0.0, y = 0.0 }
local scroll = { x = -1, y = -1 }
local pixel_index = {}
local is_shadow = {}
local this = {}
function this.pos()
return -pos.x + 77, -pos.y
end
function this.step()
pos.x = pos.x + scroll.x
if pos.x <= -95 or pos.x >= 95 then scroll.x = -scroll.x end
local adj = scroll.y
if pos.y > -10.0 then adj = adj * 1.0
elseif pos.y > -30.0 then adj = adj * 2.0
elseif pos.y > -60.0 then adj = adj * 3.0
else adj = adj * 4.0 end
pos.y = pos.y + adj
if pos.y <= -100 or pos.y >= 0 then scroll.y = -scroll.y end
end
local function orderbits(value)
local result = 0
for i = 0, 15 do
if (value >> i) & 1 == 1 then
result = result | (1 << (15 - i))
end
end
return result
end
function this.decode()
for y = 0, BALL_H - 1 do
for x = 0, BALL_W - 1 do
local pos = y * BALL_W + x
local offset = pos // 16
local bitpos = pos % 16
local value = 0
for plane = 0, 3 do
local word = orderbits(ball_bitplanes[offset + plane * ONE_PLANE_LEN + 1])
if (word & (1 << bitpos)) ~= 0 then
value = value | (1 << plane)
end
end
if (value == 1) then
is_shadow[pos + 1] = true
pixel_index[pos + 1] = 0
else
is_shadow[pos + 1] = false
pixel_index[pos + 1] = value
end
end
end
end
function this.cycle_palette()
if scroll.x > 0 then color_cycle = color_cycle - 1
else color_cycle = color_cycle + 1 end
if color_cycle == -1 then color_cycle = 13
elseif color_cycle == 14 then color_cycle = 0 end
for i = 0, 6 do
if color_cycle + i < 14 then
color_table[color_cycle + i + 3] = 0xFFFFFF
color_table[color_cycle + i + 19] = 0xFFFFFF
else
color_table[color_cycle + i - 11] = 0xFFFFFF
color_table[color_cycle + i + 5] = 0xFFFFFF
end
end
for i = 7, 13 do
if color_cycle + i < 14 then
color_table[color_cycle + i + 3] = 0xFF0000
color_table[color_cycle + i + 19] = 0xFF0000
else
color_table[color_cycle + i - 11] = 0xFF0000
color_table[color_cycle + i + 5] = 0xFF0000
end
end
if scroll.x > -1 then
color_table[color_cycle + 3] = 0xFFDDDD
color_table[color_cycle + 19] = 0xFFDDDD
elseif color_cycle + 6 < 14 then
color_table[color_cycle + 9] = 0xFFDDDD
color_table[color_cycle + 25] = 0xFFDDDD
else
color_table[color_cycle - 5] = 0xFFDDDD
color_table[color_cycle + 11] = 0xFFDDDD
end
end
function this.draw(x, y, shadow)
for oy = 0, BALL_H - 1 do
for ox = 0, BALL_W - 1 do
local pos = oy * BALL_W + ox + 1
if shadow then
if is_shadow[pos] then
local c = g(ox+x, oy+y)
if c == 0xAAAAAA then s(ox+x, oy+y, 0x666666) end
end
else
local idx = pixel_index[pos]
if idx ~= 0 then
local c = color_table[idx + 1]
s(ox+x, oy+y, c)
end
end
end
end
end
return this
end
function draw_background()
raster.clear()
local lc = color_table[17]
local k = 20
for j = 48, 300, 16 do
l(j, 0, j, 192, lc)
l(j, 192, k, 215, lc)
k = k + 20
end
for j = 0, 200, 16 do
l(48, j, 288, j, lc)
end
l(45, 194, 291, 194, lc)
l(41, 197, 295, 197, lc)
l(37, 201, 300, 201, lc)
l(30, 207, 308, 207, lc)
l(20, 215, 319, 215, lc)
end
local b = ball()
b.decode()
raster.init(SCREEN_W/2, SCREEN_H/4, color_table[1])
local i = 0
while true do
i = i + 1
draw_background()
b.cycle_palette()
b.step()
local x, y = b.pos()
b.draw(x, y, true)
b.draw(x, y)
raster.update()
if event.pull("key_down", 0.01) then
break
end
end
raster.free()
terminal.clear()
-60
View File
@@ -1,60 +0,0 @@
local component = require("component")
local computer = require("computer")
local args = {...}
local force = false
local forceArgIdx = table.find(args,"-f") or table.find(args,"--force")
if forceArgIdx then
table.remove(args,forceArgIdx)
force = true
end
local function getComponentID(str)
local function fromSlot(slot)
for i,v in component.list() do
if component.slot(i)==slot then
return i
end
end
end
if str=="hdd1" or str=="#1" then return fromSlot(5) end
if str=="hdd2" or str=="#2" then return fromSlot(6) end
if str=="floppy" or str=="#3" then return fromSlot(7) end
if #str<3 then return nil,"Abbreviated ID must atleast have 3 characters" end
return component.get(str)
end
local function fileExists(compID,file)
return component.invoke(compID,"exists",file) and not component.invoke(compID,"isDirectory",file)
end
if type(args[1])=="string" then
local compID,err = getComponentID(args[1])
if not compID then
print("\x1b[91mCould not get component ID from '"..args[1].."'.")
if type(err)=="string" then print("\x1b[91m"..err.."\x1b[0m") end
return
end
if not force then
if component.virtual.check(compID) then
return print("\x1b[91mThis component is virtual and cannot be booted from directly.\nID: "..compID.."\x1b[0m")
end
local type = component.type(compID)
if type~="filesystem" and type~="drive" then
return print("\x1b[91mThis component is not a storage medium.\nID: "..compID.."\x1b[0m")
end
if type=="filesystem" and not fileExists(compID,"/init.lua") then
return print("\x1b[91mThis storage medium doesn't have an \"init.lua\" file.\nID: "..compID.."\x1b[0m")
end
end
computer.setBootAddress(compID)
if computer.getBootAddress()~=compID then
return print("\x1b[91mFailed to set the boot address.\x1b[0m")
end
computer.shutdown(true)
else
require("shell").run("help boot")
end
-30
View File
@@ -1,30 +0,0 @@
local fs = require("filesystem")
local shell = require("shell")
local args = {...}
if not args[1] then
return shell.run("help cat")
end
for _, file in pairs(args) do
file = shell.resolvePath(file)
local handle = fs.open(file, "r")
if handle == nil then
terminal.write("\27[91mCan't open " .. file .. "\27[0m\n")
goto continue
end
local enddata
while true do
local data = handle:read(math.huge or math.maxinteger)
if data == nil then break end
terminal.write(data)
enddata = data
end
handle:close()
if string.sub(enddata, -1, -1) ~= "\n" then
print("")
end
::continue::
end
-26
View File
@@ -1,26 +0,0 @@
local args = {...}
if args[2] then
terminal.write("\27[91mToo many arguments.\27[0m")
end
if not args[1] then
return
end
local fs = require("filesystem")
local shell = require("shell")
local directory = shell.resolvePath(args[1])
if not fs.exists(directory) then
terminal.write("\27[91mError: " .. directory .. ": No such file or directory\27[0m\n")
return
end
if not fs.isDirectory(directory) then
terminal.write("\27[91mError: " .. directory .. ": Not a directory\27[0m\n")
return
end
shell.setWorkingDirectory(fs.canonical(directory))
-3
View File
@@ -1,3 +0,0 @@
terminal.clear()
-- truly so much going on here
-- meow
-70
View File
@@ -1,70 +0,0 @@
local fs = require("filesystem")
local shell = require("shell")
local args = {...}
if not args[1] then
return shell.run("help cp")
end
if not args[2] then
terminal.write("\27[91mError: No destination\27[0m\n")
return
end
local dest = shell.resolvePath(args[#args])
if fs.isFile(dest) then
if #args ~= 2 then
terminal.write("\27[91mError: Destination is not a directory\27[0m\n")
return
end
local src = shell.resolvePath(args[1])
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
return
end
if fs.isDirectory(src) then
terminal.write("\27[91mError: Cannot write directory " .. src .. " to file " .. dest .. "\27[0m\n")
return
end
fs.copy(src, dest)
elseif fs.isDirectory(dest) then
for i = 1, #args - 1 do
local src = shell.resolvePath(args[i])
if src == dest then
terminal.write("\27[91mError: Source and destination are the same\27[0m\n")
goto continue
end
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
goto continue
end
fs.copy(src, fs.concat(dest, fs.basename(src)))
::continue::
end
elseif not fs.exists(dest) then
if #args ~= 2 then
terminal.write("\27[91mError: " .. dest .. ": No such file or directory\27[0m\n")
return
end
local src = shell.resolvePath(args[1])
if not fs.exists(src) then
terminal.write("\27[91mError: " .. src .. ": No such file or directory\27[0m\n")
return
end
local destp = fs.parent(dest)
if not fs.exists(destp) then
terminal.write("\27[91mError: " .. destp .. ": No such file or directory\27[0m\n")
return
end
if not fs.isDirectory(destp) then
terminal.write("\27[91mError: " .. destp .. ": Not a directory\27[0m\n")
return
end
fs.copy(src, dest)
else
terminal.write("\27[91mUnknown error\27[0m\n")
end
-57
View File
@@ -1,57 +0,0 @@
local url = ...
local component = require("component")
local fs = require("filesystem")
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.\27[0m")
return
end
if not url then
print("Please enter a URL to download from.")
require("shell").run("help download")
return
end
if url:sub(-1, -1) == "/" then
url = url:sub(1, -2)
end
local internet = component.internet
local request, data, tmpdata = nil, "", nil
local status, errorMessage = pcall(function()
request = internet.request(url)
request:finishConnect()
end)
if not status then
print("\27[91mDownload failed: " .. errorMessage .. "\27[0m")
end
local responseCode = request:response()
if responseCode and responseCode ~= 200 then
print("\27[91mDownload failed: " .. tostring(responseCode) .. "\27[0m")
end
repeat
tmpdata = request.read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
local saveLocation
local saveLocationOK = false
repeat
saveLocation = terminal.read(nil, "File save location: ", fs.concat(require("shell").getWorkingDirectory(), url:match("/([^/]+)$")))
if fs.isDirectory(saveLocation) then
print("\27[91mThe specified location is a directory.\27[0m")
elseif fs.exists(saveLocation) then
local answer = terminal.read({prefix = "\27[91mThere is already a file at the specified directory. Overwrite it? [Y/n]\27[0m"})
if answer:lower() ~= "n" then
saveLocationOK = true
end
else
saveLocationOK = true
end
until saveLocationOK
local handle = fs.open(saveLocation, "w")
handle:write(data)
handle:close()
print("File downloaded successfully.")
-7
View File
@@ -1,7 +0,0 @@
local args = {...}
local concatText = args[1]
table.remove(args, 1)
for _, item in pairs(args) do
concatText = concatText .. " " .. item
end
print(concatText)
-348
View File
@@ -1,348 +0,0 @@
local file = ...
local fs = require("filesystem")
local event = require("event")
local component = require("component")
local unicode = require("unicode")
local workingDirectory = require("shell").getWorkingDirectory()
local gpu = component.gpu
local width, height = gpu.getResolution()
local scrollPosX, scrollPosY = 1, 1
local cursorPosX, cursorPosY = 1, 1
local cursorWhite = true
local changesMade = false
local renderBuffer = gpu.allocateBuffer()
local scrollSpeed = 5
local tab = " "
--local ocelot = component.ocelot
local function rawset(x, y, text)
terminal.write("\x1b[".. tostring(y) .. ";" .. tostring(x) .. "H" .. text)
end
local filestring, filepath, handle, data, tmpdata
if file then
if file:sub(1, 1) == "/" then
filepath = file
else
filepath = workingDirectory .. file
end
handle, data, tmpdata = fs.open(filepath, "r"), "", nil
if fs.exists(filepath) then
filestring = filepath
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
tmpdata = {}
if data:gmatch("(.-)\n")() then
for line in data:gmatch("(.-)\n") do
local newLine = line:gsub("\r", "") -- this took me SO LONG TO FIGURE OUT AAAAAAAA I HATE CRLF I HATE CRLF I HATE CRLF
table.insert(tmpdata, newLine)
end
else
tmpdata = {data}
end
else
filepath = workingDirectory .. file
filestring = "[NEW FILE]"
tmpdata = {""}
end
else
filepath = ""
filestring = "[NEW FILE]"
tmpdata = {""}
end
local function render()
gpu.setActiveBuffer(renderBuffer)
terminal.clear()
--ocelot.log(tostring(scrollPosY))
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
if realCursorX < 1 then
scrollPosX = scrollPosX + realCursorX - 1
cursorPosX = 1
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
end
for i = scrollPosY, height + scrollPosY - 3 do
gpu.set(1, i - scrollPosY + 1, (tmpdata[i] or ""):sub(scrollPosX))
end
rawset(1, height - 1, "\27[107m\27[30m" .. filestring .. string.rep(" ", width))
rawset(1, height, "\27[107m\27[30m^X\27[0m Exit \27[107m\27[30m^S\27[0m Save" .. string.rep(" ", width))
local char = gpu.get(realCursorX, cursorPosY)
if cursorWhite then
gpu.setForeground(0)
gpu.setBackground(0xFFFFFF)
end
gpu.set(realCursorX, cursorPosY, char)
gpu.bitblt()
gpu.setActiveBuffer(0)
end
local renderFlag, cursorRenderFlag = false, false
local function scrollUp()
cursorPosY = cursorPosY - 1
cursorRenderFlag = true
cursorWhite = true
if cursorPosY < 1 then
renderFlag = true
scrollPosY = scrollPosY - 1
cursorPosY = 1
end
if scrollPosY < 1 then
renderFlag = false
scrollPosY = 1
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollDown()
cursorPosY = cursorPosY + 1
cursorRenderFlag = true
cursorWhite = true
if cursorPosY + scrollPosY - 1 > #tmpdata then
renderFlag = false
cursorPosY = #tmpdata - scrollPosY + 1
end
if cursorPosY > height - 2 then
renderFlag = true
scrollPosY = scrollPosY + 1
cursorPosY = height - 2
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollLeft()
cursorRenderFlag = true
cursorWhite = true
if cursorPosX > 1 then
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2 then
cursorPosX = cursorPosX - 1
elseif unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 > 1 then
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1
end
elseif scrollPosX > 1 then
scrollPosX = scrollPosX - 1
renderFlag = true
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollRight()
cursorRenderFlag = true
cursorWhite = true
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 then
cursorPosX = cursorPosX + 1
end
if cursorPosX > width then
cursorPosX = width
scrollPosX = scrollPosX + 1
renderFlag = true
end
end
local function processEvent(args)
renderFlag, cursorRenderFlag = false, false
if args[1] == "key_down" then
local keycode = args[4]
local key = keyboard.keys[keycode]
if keyboard.getCtrlDown() then
return false, false, key
end
if key == "down" and cursorPosY < #tmpdata then
scrollDown()
end
if key == "up" then
scrollUp()
end
if key == "left" then
scrollLeft()
end
if key == "right" then
scrollRight()
end
if key == "enter" then
changesMade = true
renderFlag = true
cursorWhite = true
table.insert(tmpdata, cursorPosY + 1, tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX))
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX - 1)
cursorPosX = 1
cursorPosY = cursorPosY + 1
scrollPosX = 1
if cursorPosY > height - 2 then
scrollPosY = scrollPosY + 1
cursorPosY = height - 2
end
end
if key == "back" then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
if cursorPosX == 1 and cursorPosY + scrollPosY - 1 > 1 then
cursorPosY = cursorPosY - 1
if cursorPosY < 1 then
scrollPosY = scrollPosY - 1
cursorPosY = 1
end
if scrollPosY < 1 then
scrollPosY = 1
end
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2
if cursorPosX > width then
scrollPosX = cursorPosX - width + 1
cursorPosX = width
end
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1] .. tmpdata[cursorPosY + 1]
table.remove(tmpdata, cursorPosY + 1)
renderFlag = true
else
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 3) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = math.min(cursorPosX - 1, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) + 1)
if cursorPosX < 1 then
cursorPosX = 1
scrollPosX = scrollPosX - 1
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX) .. " ")
end
end
end
if key == "tab" then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. tab .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = cursorPosX + unicode.wlen(tab)
if cursorPosX > width then
scrollPosX = scrollPosX + cursorPosX - width
cursorPosX = width
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
end
end
if args[3] >= 32 and args[3] <= 126 then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. unicode.char(args[3]) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1])) + 1
--ocelot.log(tostring(cursorPosX))
if cursorPosX > width then
cursorPosX = width
scrollPosX = scrollPosX + 1
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
end
end
elseif args[1] == "scroll" then
if args[5] == 1 then
for i = 1, scrollSpeed do
scrollUp()
end
elseif args[5] == -1 and cursorPosY < #tmpdata then
for i = 1, scrollSpeed do
scrollDown()
end
end
end
return renderFlag, cursorRenderFlag
end
local function save()
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
gpu.set(1, height - 1, string.rep(" ", width))
rawset(1, height - 1)
local savepath = terminal.read({prefix = "\27[107m\27[30mSave location: ", defaultText = filepath})
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
if fs.exists(savepath) then
gpu.set(1, height - 1, string.rep(" ", width))
local answer = terminal.read({prefix = "\27[107m\27[30mFile already exists. Overwrite it? [Y/n] "})
if answer:lower() == "n" then
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
return
end
end
local handle, errorMessage = fs.open(savepath, "w")
if handle then
if table.concat(tmpdata, "\n"):sub(-1, -1) == "\n" then
handle:write(table.concat(tmpdata, "\n"))
else
handle:write(table.concat(tmpdata, "\n") .. "\n") -- add a newline at the end to follow POSIX standards
end
handle:close()
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
else
gpu.set(1, height - 1, "ERROR: " .. errorMessage:gsub("\n", "") .. string.rep(" ", width))
end
changesMade = false
end
render()
while true do
local args = {event.pull(0.5)}
local renderFlag, cursorRenderFlag, specialKey = false, false, nil
local previousCursorX, previousCursorY = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2), cursorPosY
if args and args[1] then
cursorWhite = true
renderFlag, cursorRenderFlag, specialKey = processEvent(args)
if specialKey == "x" then
if changesMade then
rawset(1, height - 1)
local response = terminal.read({prefix = "\27[107m\27[30mWould you like to save changes? [Y/n] "})
if response:lower() ~= "n" then
save()
end
end
gpu.freeAllBuffers()
terminal.clear()
return
end
if specialKey == "s" then
save()
end
repeat
args = {event.pull("key_down", 0)}
if args and args[1] then
processEvent(args)
end
until not args or not args[1]
else
cursorWhite = not cursorWhite
cursorRenderFlag = true
end
if cursorRenderFlag then
local char = gpu.get(previousCursorX, previousCursorY)
gpu.set(previousCursorX, previousCursorY, char)
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
if realCursorX < 1 then
scrollPosX = scrollPosX + realCursorX - 1
cursorPosX = 1
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
end
local char = gpu.get(realCursorX, cursorPosY)
if cursorWhite then
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
end
gpu.set(realCursorX, cursorPosY, char)
if cursorWhite then
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0)
end
end
if renderFlag then
render()
end
end
-66
View File
@@ -1,66 +0,0 @@
local component = require("component")
local computer = require("computer")
local filesystem = require("filesystem")
local function convert(value, fromUnit, toUnit)
local units = {B = 1, KiB = 1024, MiB = 1024^2, GiB = 1024^3}
return value * units[fromUnit] / units[toUnit]
end
local function printstat(text)
terminal.write("\27[35G" .. text .. "\n")
end
local logo = ""
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat
tmpdata = handle:read(math.huge)
logo = logo .. (tmpdata or "")
until not tmpdata
handle:close()
terminal.write(logo)
terminal.write("\27[17A")
printstat("\27[92mOS\27[0m: " .. _OSVERSION)
printstat("\27[92mArchitecture\27[0m: " .. _VERSION)
local componentCounter = 0
for _ in component.list() do
componentCounter = componentCounter + 1
end
printstat("\27[92mComponents\27[0m: " .. tostring(componentCounter))
printstat("\27[92mCoroutines\27[0m: " .. tostring(#tsched.getTasks()))
printstat("\27[92mBattery\27[0m: " .. tostring(math.floor(computer.energy() / computer.maxEnergy() * 1000 + 0.5) / 10) .. "%")
local totalMemory = computer.totalMemory()
local usedMemory = computer.totalMemory() - computer.freeMemory()
local function formatBytes(bytes)
if convert(bytes, "B", "GiB") >= 1 then
return tostring(math.floor(convert(bytes, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(bytes, "B", "MiB") >= 1 then
return tostring(math.floor(convert(bytes, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(bytes, "B", "KiB") >= 1 then
return tostring(math.floor(convert(bytes, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
return tostring(bytes) .. " B"
end
end
printstat("\27[92mMemory\27[0m: " .. formatBytes(usedMemory) .. " / " .. formatBytes(totalMemory))
local totalDisk = component.invoke(computer.getBootAddress(), "spaceTotal")
local usedDisk = component.invoke(computer.getBootAddress(), "spaceUsed")
printstat("\27[92mDisk\27[0m: " .. formatBytes(usedDisk) .. " / " .. formatBytes(totalDisk))
local gpuComponent = component.list("gpu")()
local width, height = component.invoke(gpuComponent, "getResolution")
printstat("\27[92mResolution\27[0m: " .. tostring(width) .. "x" .. tostring(height) .. "\n")
printstat("\27[40m \27[41m \27[42m \27[43m \27[44m \27[45m \27[46m \27[47m ")
printstat("\27[100m \27[101m \27[102m \27[103m \27[104m \27[105m \27[106m \27[107m ")
terminal.write("\27[5B\27[0m")
-268
View File
@@ -1,268 +0,0 @@
local fs = require("filesystem")
local shell = require("shell")
local arg = ... or "default"
local what = arg
local aliases = shell.getAliases()
if aliases[what] then
what = aliases[what]
end
local path = "/halyde/apps/helpdb/" .. what
if not fs.exists(path) then
print("Could not find help file for: " .. arg .. ".")
return
end
if path == "/halyde/apps/helpdb/default" then
return shell.run("cat " .. path) -- smh
end
local handle = fs.open(path, "r")
local data = {
command = "",
usage = "",
description = "",
args = {},
examples = {}
}
while true do
local line = ""
while true do
local char = handle:read(1)
if not char then
if line == "" then
line = nil
break
end
break
end
if char == "\n" then
break
end
if char == "\r" then
local next_char = handle:read(1)
if next_char and next_char == "\n" then
break
elseif next_char then
local pos = file:seek("cur")
if pos then
file:seek("set", pos - 1)
end
break
end
break
end
line = line .. char
end
if line == nil then
break
end
line = line:match("^%s*(.-)%s*$")
if line then
local key, value = line:match("^(%w+)%s+(.*)$")
if not key then goto continue end
if key:lower() == "command" then
data.command = value
end
if key:lower() == "usage" then
data.usage = value
end
if key:lower() == "description" then
data.description = value
end
if key:lower():match("^arg%d+$") then
local num = key:lower():match("^arg(%d+)$")
if not data.args[tonumber(num)] then data.args[tonumber(num)] = {} end
data.args[tonumber(num)].name = value
end
if key:lower():match("^arg%d+description$") then
local num = key:lower():match("^arg(%d+)description$")
if not data.args[tonumber(num)] then data.args[tonumber(num)] = {} end
data.args[tonumber(num)].description = value
end
if key:lower():match("^arg%d+sub%d+$") then
local main_num, sub_num = key:lower():match("^arg(%d+)sub(%d+)$")
if main_num and sub_num then
if not data.args[tonumber(main_num)] then data.args[tonumber(main_num)] = {} end
if not data.args[tonumber(main_num)].subflags then data.args[tonumber(main_num)].subflags = {} end
if not data.args[tonumber(main_num)].subflags[tonumber(sub_num)] then
data.args[tonumber(main_num)].subflags[tonumber(sub_num)] = {}
end
data.args[tonumber(main_num)].subflags[tonumber(sub_num)].name = value
end
end
if key:lower():match("^arg%d+sub%d+description$") then
local main_num, sub_num = key:lower():match("^arg(%d+)sub(%d+)description$")
if main_num and sub_num then
if not data.args[tonumber(main_num)] then data.args[tonumber(main_num)] = {} end
if not data.args[tonumber(main_num)].subflags then data.args[tonumber(main_num)].subflags = {} end
if not data.args[tonumber(main_num)].subflags[tonumber(sub_num)] then
data.args[tonumber(main_num)].subflags[tonumber(sub_num)] = {}
end
data.args[tonumber(main_num)].subflags[tonumber(sub_num)].description = value
end
end
if key:lower():match("^example%d+$") then
local num = key:lower():match("^example(%d+)$")
if not data.examples[tonumber(num)] then data.examples[tonumber(num)] = {} end
data.examples[tonumber(num)].name = value
end
if key:lower():match("^example%d+description$") then
local num = key:lower():match("^example(%d+)description$")
if not data.examples[tonumber(num)] then data.examples[tonumber(num)] = {} end
data.examples[tonumber(num)].description = value
end
::continue::
end
end
handle:close()
--print(require("serialize")(data, "\t"))
-- Halyde terminal doesn't support bold (CSI 1 m) but who cares
if data.command then
terminal.write("\27[1mUsage: \27[0m\n")
terminal.write(" \27[96m" .. data.command)
if data.usage then
terminal.write("\27[93m " .. data.usage)
end
terminal.write("\27[0m\n\n")
end
local width, height = terminal.getResolution()
local function wrap_text(text, indent)
if not text then return "" end
local words = {}
for word in text:gmatch("%S+") do
table.insert(words, word)
end
local lines = {}
local current_line = ""
for i, word in ipairs(words) do
if #current_line + #word + 1 <= width * 0.66 - indent then
if current_line == "" then
current_line = word
else
current_line = current_line .. " " .. word
end
else
table.insert(lines, current_line)
current_line = word
end
end
if current_line ~= "" then
table.insert(lines, current_line)
end
local result = {}
for i, line in ipairs(lines) do
if i == 1 then
table.insert(result, line)
else
table.insert(result, string.rep(" ", indent) .. line)
end
end
return table.concat(result, "\n")
end
if data.description then
terminal.write("\27[1mDescription:\27[0m\n")
terminal.write(" " .. wrap_text(data.description, 2))
terminal.write("\n\n")
end
if #data.args > 0 then
terminal.write("\27[1mArguments:\27[0m\n")
local max_len = 0
for _, flag in ipairs(data.args) do
if flag.name then
max_len = math.max(max_len, #flag.name)
end
for _, subf in ipairs(flag.subflags or {}) do
if subf.name then
max_len = math.max(max_len, #subf.name + 2)
end
end
end
for _, flag in ipairs(data.args) do
terminal.write(" \27[93m" .. (flag.name or "") .. "\27[0m" .. string.rep(" ", max_len - (flag.name and #flag.name or 0) + 2) .. wrap_text(flag.description, 4 + max_len) .. "\n")
for _, subf in ipairs(flag.subflags or {}) do
terminal.write(" \27[92m" .. (subf.name or "") .. "\27[0m" .. string.rep(" ", max_len - (subf.name and #subf.name or 0)) .. wrap_text(subf.description, 4 + max_len) .. "\n")
end
end
terminal.write("\n")
end
local function formatExampleName(name, utility)
if not name then return name end
local contains = false
if name:find(utility, 1, true) then
contains = true
else
for alias, cmd in pairs(aliases) do
if cmd == utility and name:find(alias, 1, true) then
contains = true
break
end
end
end
if not contains then
return "\27[92m" .. name
end
local formatted = name
formatted = formatted:gsub("(" .. utility .. ")", "\27[96m%1\27[92m")
for alias, cmd in pairs(aliases) do
if cmd == utility then
formatted = formatted:gsub("(" .. alias .. ")", "\27[96m%1\27[92m")
end
end
return formatted
end
if #data.examples > 0 then
terminal.write("\27[1mExamples:\27[0m\n")
local max_len = 0
for _, flag in ipairs(data.examples) do
max_len = math.max(max_len, #flag.name)
end
for _, flag in ipairs(data.examples) do
terminal.write(" " .. formatExampleName(flag.name, arg) .. "\27[0m" .. string.rep(" ", max_len - #flag.name + 2) .. wrap_text(flag.description, 4 + max_len) .. "\n")
end
terminal.write("\n")
end
local first = true
for k, v in pairs(aliases) do
if v == arg then
if first then
terminal.write("\27[1mAliases:\27[0m\n ")
end
terminal.write("\27[96m" .. k)
if not first then
terminal.write("\27[0m, ")
end
first = false
end
end
if not first then
terminal.writec(0xa)
end
-47
View File
@@ -1,47 +0,0 @@
COMMAND ag2
USAGE [COMMAND] [PACKAGES] [FLAGS]
DESCRIPTION Uses the Argentum 2 package manager.
ARG1 COMMAND
ARG1SUB1 install
ARG1SUB2 remove
ARG1SUB3 update
ARG1SUB4 list
ARG1SUB5 repo-list
ARG1SUB6 repo-add
ARG1SUB7 repo-remove
ARG1SUB8 info
ARG2 PACKAGES
ARG3 FLAGS
ARG3SUB1 -x, --exclude-deps
ARG3SUB2 -u, --update-repos
ARG3SUB3 -f, --force
ARG3SUB4 -c, --clean
ARG3SUB5 -s, --source [URL]
ARG3SUB6 -C, --cascade
ARG1DESCRIPTION Specifies the operation for Argentum 2 to do.
ARG1SUB1DESCRIPTION Installs packages.
ARG1SUB2DESCRIPTION Removes packages.
ARG1SUB3DESCRIPTION Updates packages.
ARG1SUB4DESCRIPTION Lists all available packages.
ARG1SUB5DESCRIPTION Lists all installed repositories.
ARG1SUB6DESCRIPTION Adds a custom repository.
ARG1SUB7DESCRIPTION Removes a repository.
ARG1SUB8DESCRIPTION Shows a packages version, description and other relevant information.
ARG2DESCRIPTION Packages to apply operations to.
ARG3DESCRIPTION These flags are available and can be inserted anywhere
ARG3SUB1DESCRIPTION Ignore dependencies. WARNING: Using this can and will leave you with broken packages. Use it at your own risk and only when truly necessary.
ARG3SUB2DESCRIPTION Update the list of repositories.
ARG3SUB3DESCRIPTION Force the operation, even if there are conflicts or unresolvable dependencies. WARNING: Using this can and will leave you with broken packages. Use it at your own risk and only when truly necessary.
ARG3SUB4DESCRIPTION Clean up now-unnecessary packages (previous dependencies).
ARG3SUB5DESCRIPTION Use a custom source for the operation.
ARG3SUB6DESCRIPTION When removing a package that other packages depend on, remove those packages too instead of aborting.
EXAMPLE1 ag2 install halyde
EXAMPLE2 ag2 list
EXAMPLE3 ag2 info halyde
EXAMPLE4 ag2 remove -x edit
EXAMPLE5 ag2 remove -c hal-draw
EXAMPLE1DESCRIPTION Installs the halyde package.
EXAMPLE2DESCRIPTION Lists all packages.
EXAMPLE3DESCRIPTION Shows information about the halyde package.
EXAMPLE4DESCRIPTION Removes edit, but does not remove any packages that depend on it.
EXAMPLE5DESCRIPTION Removes hal-draw and any dependencies that are no longer needed.
-29
View File
@@ -1,29 +0,0 @@
COMMAND argentum
USAGE [COMMAND] [PACKAGES]
DESCRIPTION Uses the Argentum package manager.
ARG1 COMMAND
ARG1SUB1 install
ARG1SUB2 remove
ARG1SUB3 update
ARG1SUB4 list
ARG1SUB5 search
ARG1SUB6 info
ARG2 PACKAGES
ARG1DESCRIPTION Specifies the operation for Ag to do.
ARG1SUB1DESCRIPTION Installs packages.
ARG1SUB2DESCRIPTION Removes packages.
ARG1SUB3DESCRIPTION Updates packages.
ARG1SUB4DESCRIPTION Lists all available packages.
ARG1SUB5DESCRIPTION Searches all available packages.
ARG1SUB6DESCRIPTION Shows information on a specific package.
ARG2DESCRIPTION Packages to apply operations to.
EXAMPLE1 ag install hal-draw
EXAMPLE2 ag list
EXAMPLE3 ag info hal-draw
EXAMPLE4 ag update hal-draw
EXAMPLE5 ag update hal-draw
EXAMPLE1DESCRIPTION Installs the hal-draw package.
EXAMPLE2DESCRIPTION Lists all packages.
EXAMPLE3DESCRIPTION Shows information about hal-draw.
EXAMPLE4DESCRIPTION Updates the hal-draw package if it's not at the newest version.
EXAMPLE5DESCRIPTION Updates all packages.
-8
View File
@@ -1,8 +0,0 @@
COMMAND beep
USAGE [FLAGS]
DESCRIPTION Make the computer beep.
ARG1 FLAGS
ARG1SUB1 -f, --frequency
ARG1SUB2 -t, --time
ARG1SUB1DESCRIPTION Specifies the frequency, in Hz. Defaults to 440Hz.
ARG1SUB2DESCRIPTION Specifies how long, in seconds, the computer should beep. Defaults to 0.1s.

Some files were not shown because too many files have changed in this diff Show More