581 line
		
	
	
		
			14 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			581 line
		
	
	
		
			14 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
pico-8 cartridge // http://www.pico-8.com
 | 
						||
version 32
 | 
						||
__lua__
 | 
						||
-- utils / globals
 | 
						||
local none = {}
 | 
						||
 | 
						||
--have to do this before i make
 | 
						||
--any functions
 | 
						||
local wraps = {}
 | 
						||
for k,v in pairs(_ENV) do
 | 
						||
	if type(v)=="function" then
 | 
						||
		wraps[#wraps + 1]={k=k, v=v,}
 | 
						||
	end
 | 
						||
end
 | 
						||
 | 
						||
function is_sym(s)
 | 
						||
	return type(s) == "string"
 | 
						||
		and sub(s,1,1) != ";"
 | 
						||
end
 | 
						||
 | 
						||
function is_num(n)
 | 
						||
	return type(n) == "number"
 | 
						||
end
 | 
						||
 | 
						||
function is_fun(f)
 | 
						||
	return type(f) == "function"
 | 
						||
end
 | 
						||
 | 
						||
function is_tab(t)
 | 
						||
	return type(t) == "table"
 | 
						||
	 and t != none
 | 
						||
end
 | 
						||
 | 
						||
function is_str(s)
 | 
						||
	return type(s) == "string"
 | 
						||
		and sub(s,1,1) == ";"
 | 
						||
end
 | 
						||
 | 
						||
function is_bool(b)
 | 
						||
	return type(b) == "boolean"
 | 
						||
end
 | 
						||
 | 
						||
--todo:
 | 
						||
--can this be made faster ?
 | 
						||
function rest(t)
 | 
						||
	local function r_1(fst, ...)
 | 
						||
		return {...}
 | 
						||
	end
 | 
						||
	return r_1(unpack(t))
 | 
						||
end
 | 
						||
 | 
						||
function deep_copy(v)
 | 
						||
	if not is_tab(v) then
 | 
						||
		return v
 | 
						||
	end
 | 
						||
 | 
						||
	local c = {}
 | 
						||
	for key = 1, #v do
 | 
						||
	--for key in pairs(v) do
 | 
						||
		c[key] = deep_copy(v[key])
 | 
						||
	end
 | 
						||
	return c
 | 
						||
end
 | 
						||
 | 
						||
--todo: this is limitted to 2
 | 
						||
--args, it's kinda missleading
 | 
						||
--ig, tho i doubt anyone else
 | 
						||
--will be using this func
 | 
						||
 | 
						||
--todo: see if this needs to /
 | 
						||
--can be spead up
 | 
						||
function bind(func, ...)
 | 
						||
	local args = {...}
 | 
						||
 | 
						||
	local function copy(t)
 | 
						||
		return pack(unpack(t))
 | 
						||
	end
 | 
						||
 | 
						||
	return function(a, b)
 | 
						||
		local args_2 = copy(args)
 | 
						||
		args_2[#args + 1] = a
 | 
						||
		args_2[#args + 2] = b
 | 
						||
		return func(unpack(args_2))
 | 
						||
	end
 | 
						||
end
 | 
						||
 | 
						||
function list_tostr(l, s)
 | 
						||
	if l == none then
 | 
						||
		return s .. "none"
 | 
						||
	end
 | 
						||
	if type(l)=="table" then
 | 
						||
		s = s .. "("
 | 
						||
		for i = 1, #l do
 | 
						||
			if(i > 1) s = s .. " "
 | 
						||
			s = list_tostr(l[i], s)
 | 
						||
		end
 | 
						||
		s = s .. ")"
 | 
						||
		return s
 | 
						||
	end
 | 
						||
	if is_str(l) then
 | 
						||
		return
 | 
						||
			s.."\""..sub(l,2).."\""
 | 
						||
	end
 | 
						||
	return s .. tostr(l)
 | 
						||
end
 | 
						||
 | 
						||
function chr_size(c)
 | 
						||
	return ord(c) < 128 and 4 or 8
 | 
						||
end
 | 
						||
 | 
						||
function replace(s, a, b)
 | 
						||
	local r = ""
 | 
						||
	for i = 1, #s do
 | 
						||
		local c = sub(s, i, i)
 | 
						||
		if c == a then
 | 
						||
			c = b
 | 
						||
		end
 | 
						||
		r = r .. c
 | 
						||
	end
 | 
						||
	return r
 | 
						||
end
 | 
						||
 | 
						||
-->8
 | 
						||
-- tokenizer
 | 
						||
 | 
						||
--[[ todo:
 | 
						||
generisize token_str + com ?
 | 
						||
--]]
 | 
						||
 | 
						||
--::tok,rst,type
 | 
						||
--[[
 | 
						||
"pun" = puncuation
 | 
						||
"ws" = whitespace
 | 
						||
"sym" = symbol
 | 
						||
"num" = number
 | 
						||
"end" = end of input
 | 
						||
"str" = string
 | 
						||
"com" = comment
 | 
						||
--]]
 | 
						||
function token_str(s, hk)
 | 
						||
	for i = 2, #s do
 | 
						||
		if(hk) hk(sub(s,i,i))
 | 
						||
		if sub(s,i,i) == "\"" then
 | 
						||
			return sub(s, 1, i),
 | 
						||
				sub(s,i + 1), "str"
 | 
						||
		end
 | 
						||
	end
 | 
						||
	return s, "", "str" --no end
 | 
						||
end
 | 
						||
 | 
						||
function token_com(s, hk)
 | 
						||
	for i = 2, #s do
 | 
						||
		if(hk) hk(sub(s,i,i))
 | 
						||
		if sub(s,i,i) == "\n" then
 | 
						||
			return sub(s, 1, i),
 | 
						||
				sub(s,i + 1), "com"
 | 
						||
		end
 | 
						||
	end
 | 
						||
	return s, "", "com" --eof
 | 
						||
end
 | 
						||
 | 
						||
function token_1(s, hk)
 | 
						||
	local fst,rst = sub(s,1,1),
 | 
						||
		sub(s,2)
 | 
						||
 | 
						||
	if(hk) hk(fst)
 | 
						||
 | 
						||
	if(s=="")return "","","end"
 | 
						||
 | 
						||
	if fst == "\"" then
 | 
						||
		return token_str(s, hk)
 | 
						||
	end
 | 
						||
	if fst == ";" then
 | 
						||
		return token_com(s, hk)
 | 
						||
	end
 | 
						||
	
 | 
						||
	if fst == " "
 | 
						||
	or fst == "\n"
 | 
						||
	or fst == "\t" then
 | 
						||
		local t,r,tp = token_1(rst,hk)
 | 
						||
		if tp == "ws" then
 | 
						||
			return fst..t, r, "ws"
 | 
						||
		end
 | 
						||
		return fst, rst, "ws"
 | 
						||
	end
 | 
						||
 | 
						||
	if fst == "("
 | 
						||
	or fst == ")"
 | 
						||
	or fst == "'"
 | 
						||
	or fst == "`"
 | 
						||
	or fst == ","
 | 
						||
	or fst == "@" then
 | 
						||
		return fst, rst, "pun"
 | 
						||
	end
 | 
						||
	
 | 
						||
	local t,r,tp = token_1(rst,hk)
 | 
						||
	if tp == "sym" then
 | 
						||
		return fst..t, r, "sym"
 | 
						||
	end
 | 
						||
	return fst,rst,"sym"
 | 
						||
end
 | 
						||
 | 
						||
function token(s, hk)
 | 
						||
	local t,r,tp = token_1(s, hk)
 | 
						||
	
 | 
						||
	if tonum(t) != nil then
 | 
						||
		return tonum(t),r,"num"
 | 
						||
	end
 | 
						||
	
 | 
						||
	return t,r,tp
 | 
						||
end
 | 
						||
 | 
						||
-->8
 | 
						||
-- parser
 | 
						||
 | 
						||
--[[ todo:
 | 
						||
collect line numbers ?
 | 
						||
--]]
 | 
						||
 | 
						||
function parse(src)
 | 
						||
	local t, rst, tp = token(src)
 | 
						||
 | 
						||
	if tp=="ws"
 | 
						||
	or tp=="com" then
 | 
						||
	 return parse(rst) end
 | 
						||
	
 | 
						||
	if t == "'" then
 | 
						||
		t, rst, tp = parse(rst)
 | 
						||
		return {"quote",t}, rst, tp
 | 
						||
	end
 | 
						||
	if t == "`" then
 | 
						||
		t, rst, tp = parse(rst)
 | 
						||
		return {"backquote",t}, rst, tp
 | 
						||
	end
 | 
						||
	if t == "," then
 | 
						||
		t, rst, tp = parse(rst)
 | 
						||
		return {"comma",t}, rst, tp
 | 
						||
	end
 | 
						||
	
 | 
						||
	if tp == "str" then
 | 
						||
		return ";" .. sub(t,2,#t-1),
 | 
						||
			rst, tp
 | 
						||
	end
 | 
						||
	
 | 
						||
	if t == "(" then
 | 
						||
		local list = {}
 | 
						||
		while true do
 | 
						||
			t, rst, tp = parse(rst)
 | 
						||
			if(t == ")") break
 | 
						||
			if tp == "end" then
 | 
						||
				print("err, unclosed paren")
 | 
						||
				break
 | 
						||
			end
 | 
						||
			add(list, t)
 | 
						||
		end
 | 
						||
		return list, rst, tp
 | 
						||
	end
 | 
						||
	
 | 
						||
	return t, rst, tp
 | 
						||
end
 | 
						||
 | 
						||
-->8
 | 
						||
-- env
 | 
						||
#include env.lua
 | 
						||
 | 
						||
-->8
 | 
						||
-- lib
 | 
						||
#include lib.lua
 | 
						||
 | 
						||
 | 
						||
-->8
 | 
						||
-- eval
 | 
						||
#include eval.lua
 | 
						||
 | 
						||
eval(parse([[
 | 
						||
(do
 | 
						||
 (def! push (\ (l a)
 | 
						||
	 (join l (list a))))
 | 
						||
 | 
						||
 (def! bq-fold (\ (acc ast)
 | 
						||
  (push acc
 | 
						||
   (if (tab? ast)
 | 
						||
    (if (= ([] ast 1) 'comma)
 | 
						||
     ([] ast 2)
 | 
						||
     (fold bq-fold '(list) ast))
 | 
						||
    (list 'quote ast)))))
 | 
						||
 | 
						||
	(defmacro! backquote (\ (ast)
 | 
						||
	 (fold bq-fold '(list) ast))))
 | 
						||
]]), lib, function(val)
 | 
						||
	--
 | 
						||
end)
 | 
						||
 | 
						||
-->8
 | 
						||
cls()
 | 
						||
lisp_src = [[
 | 
						||
 | 
						||
;; edit example
 | 
						||
(?! 69 "steamed hams") ;comment
 | 
						||
(do
 | 
						||
 | 
						||
 (def! add-or-sub (\ (func)
 | 
						||
  (func 10 18)))
 | 
						||
 | 
						||
 (add-or-sub (\ (a b)
 | 
						||
  (?! a b)
 | 
						||
  (= a b))))
 | 
						||
 | 
						||
(do
 | 
						||
	(def! add-or-sub (\ (func)
 | 
						||
	 (func 10 18)))
 | 
						||
 | 
						||
 (add-or-sub (\ (a b)
 | 
						||
  (?! a b)
 | 
						||
 | 
						||
  (= a b))))
 | 
						||
 | 
						||
(do
 | 
						||
 | 
						||
 (def! farts (list 69 420 666))
 | 
						||
 
 | 
						||
 (def! combo (\ (acc l)
 | 
						||
  (?! "combo:" acc l)
 | 
						||
  (+ acc l)))
 | 
						||
 | 
						||
 (fold combo 0 farts))
 | 
						||
 | 
						||
(do 
 | 
						||
	(def! thing 1)
 | 
						||
 (def! adder (\ (num)
 | 
						||
 | 
						||
  ; unamed second function
 | 
						||
 	(\ (a)
 | 
						||
 	
 | 
						||
 	 ; unamed third function
 | 
						||
 	 (\ (b)
 | 
						||
 	  (+ a b num)))
 | 
						||
  ))
 | 
						||
 
 | 
						||
 (def! crap (adder 4))
 | 
						||
 (def! dung (crap 2))
 | 
						||
 (dung 1)
 | 
						||
 ;((adder 4) 2) -> dung
 | 
						||
 
 | 
						||
 (dung 63))
 | 
						||
 | 
						||
(do
 | 
						||
 (def! cownter (let ((c 0))
 | 
						||
  (\ (a)
 | 
						||
   (set! c (+ c a))
 | 
						||
   (?! c))))
 | 
						||
 | 
						||
 (cownter 1)
 | 
						||
 (cownter 5)
 | 
						||
 (cownter 2))
 | 
						||
 | 
						||
(do
 | 
						||
 | 
						||
 (def! uwu (\ (x y)
 | 
						||
  (set! x (- 0 x))
 | 
						||
  (set! y (- 0 y))
 | 
						||
  (camera x y)
 | 
						||
  
 | 
						||
 
 | 
						||
  (color 5)
 | 
						||
  (line 10 98 10 88)
 | 
						||
  (line 10 98 50 98)
 | 
						||
  (line 50 88 50 98)
 | 
						||
  (line 50 88 40 88)
 | 
						||
  (line 20 88 10 88)
 | 
						||
  (line 20 88 20 60)
 | 
						||
  (line 40 88 40 60)
 | 
						||
  (line 40 60 20 60)
 | 
						||
  (line 40 70 20 70)
 | 
						||
  (line 30 65 30 60)))
 | 
						||
 
 | 
						||
 (cls 1)
 | 
						||
 (uwu 50 0)
 | 
						||
 (uwu 0 0)
 | 
						||
 (uwu 25 -48))
 | 
						||
 
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
(do
 | 
						||
 (defmacro! bee
 | 
						||
	 (let ((bees 0)) (\ (val)
 | 
						||
		 (set! bees (+ 1 bees))
 | 
						||
		 `(?! ,bees ,val))))
 | 
						||
	
 | 
						||
	(def! a 6)
 | 
						||
	(def! b "trees")
 | 
						||
	
 | 
						||
	(bee b)
 | 
						||
	(bee "yeet")
 | 
						||
	(bee ((\() "yeet")))
 | 
						||
	(bee "tank")
 | 
						||
	(bee "yank")
 | 
						||
	(bee "gank"))
 | 
						||
 | 
						||
 | 
						||
(def! draw (let ()
 | 
						||
	(def! l (\ (c)
 | 
						||
		(def! x (rnd 128))
 | 
						||
		(def! y (rnd 128))
 | 
						||
		(def! u (rnd 128))
 | 
						||
		(def! v (rnd 128))
 | 
						||
		(line x y u v c)
 | 
						||
		(spr 1 (- x 4) (- y 4))
 | 
						||
		(circ u v 4)))
 | 
						||
	(def! jump 0)
 | 
						||
	(\ ()
 | 
						||
		(call/cc (\ (c)
 | 
						||
			(set! jump c)))
 | 
						||
	 (cls 15)
 | 
						||
	 (cursor 1 1)
 | 
						||
	 (color 0)
 | 
						||
	 (?! (stat 0))
 | 
						||
	 (map 0 0)
 | 
						||
	 (if (< 0 (btn))
 | 
						||
	  (?! "hi"))
 | 
						||
	 (l 1) (l 0)
 | 
						||
	 (l 1) (l 0)
 | 
						||
	 (l 1) (l 0)
 | 
						||
	 (l 1) (l 0))))
 | 
						||
]]
 | 
						||
lisp_src = replace(lisp_src,
 | 
						||
	"\t", " ")
 | 
						||
list,rst = parse(lisp_src)
 | 
						||
 | 
						||
print(list_tostr(list, ""))
 | 
						||
 | 
						||
local enviro = {
 | 
						||
	__p = lib,
 | 
						||
	__t = {},
 | 
						||
	["true"] = true,
 | 
						||
	["false"] = false,
 | 
						||
	["none"] = none,
 | 
						||
}
 | 
						||
 | 
						||
local err = eval(list, enviro,
 | 
						||
	function(v)
 | 
						||
		print(list_tostr(v, "-> "))
 | 
						||
	end)
 | 
						||
if(err) print("err: " .. tostr(err))
 | 
						||
 | 
						||
-->8
 | 
						||
-- edit
 | 
						||
 | 
						||
--[[
 | 
						||
todo:
 | 
						||
--]]
 | 
						||
 | 
						||
function draw_line(s, y)
 | 
						||
	if y > 128 or y < -6 then
 | 
						||
		return
 | 
						||
	end
 | 
						||
 | 
						||
 local x = 0
 | 
						||
	local cols = {
 | 
						||
	 str=3, com=13, num=12, sym=6,
 | 
						||
	 bound=14, lib=11,
 | 
						||
	}
 | 
						||
 | 
						||
 local t, rst, tp = token(s)
 | 
						||
	while tp != "end" do
 | 
						||
	 color(7)
 | 
						||
		if cols[tp] then
 | 
						||
			color(cols[tp])
 | 
						||
		end
 | 
						||
		if lib[t] then
 | 
						||
	  color(cols.lib)
 | 
						||
	 end
 | 
						||
		if enviro[t] then
 | 
						||
	  color(cols.bound)
 | 
						||
	 end
 | 
						||
 | 
						||
		x = print(t, x, y)
 | 
						||
		t, rst, tp = token(rst)
 | 
						||
	end
 | 
						||
end
 | 
						||
 | 
						||
function draw_code(y)
 | 
						||
	cls(0)
 | 
						||
	
 | 
						||
	local src=split(lisp_src, "\n")
 | 
						||
 | 
						||
	for	i = 1, #src do
 | 
						||
 	draw_line(src[i], y+ i * 6 - 6)
 | 
						||
  --print(src[i])
 | 
						||
 end
 | 
						||
end
 | 
						||
 | 
						||
-->8
 | 
						||
-- draw
 | 
						||
 | 
						||
if enviro.draw then
 | 
						||
 function _draw()
 | 
						||
	 local err = enviro.draw({},
 | 
						||
		 enviro, function(v)end)
 | 
						||
		if err then
 | 
						||
			color(7)
 | 
						||
		 ?err
 | 
						||
		 stop()
 | 
						||
		end
 | 
						||
 end
 | 
						||
else
 | 
						||
	local scroll = 0
 | 
						||
	function _draw()
 | 
						||
		draw_code(scroll)
 | 
						||
		if(btn(⬆️))scroll += 6
 | 
						||
		if(btn(⬇️))scroll -= 6
 | 
						||
	end
 | 
						||
end
 | 
						||
 | 
						||
__gfx__
 | 
						||
00000000008888000033330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000002200000000220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00700700002200000000220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00077000088aa8000036633000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00077000a88aa8a00636633600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00700700a88aa8a00636633600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000088888000033333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000080080000003003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
03333330333330003333330300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333333333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333333333333332233300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
03332223332223233333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
03333332333233333333232300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333333332333333233300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33332333323333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333233322333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
03333323333333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
03333333333333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33233333333222332333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333223333333333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
32323233233333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333333322323333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33323333333332233333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
00333333333333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333333333333322333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333333333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333332332333333323300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
32323322223333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33223333323333233233333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
33333333333333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
03332333333333333333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
30333303330033300333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
__map__
 | 
						||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000002021220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000003031320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000004041420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000000000202121212200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
						||
0000000000404141414200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 |