"""SaiCore Tool Palette, Extra Palette, Erase Palette, Background Palette, Cursors, and misc icons."""
import os
from PIL import Image, ImageDraw, ImageFont
BASE = os.path.join(os.path.dirname(__file__), "..", "resources", "images")
DARK = (250, 250, 249) # cream-white for dark bg
INDIGO = (220, 38, 38) # red-600
INDIGO_LT = (248, 113, 113) # red-400
WHITE = (255, 255, 255)
RED = (239, 68, 68)
GREEN = (16, 185, 129)
AMBER = (245, 158, 11)
GRAY = (82, 82, 91)
LIGHT_GRAY = (229, 231, 235)
T = (0, 0, 0, 0)
def font(sz):
for n in ['C:/Windows/Fonts/segoeuib.ttf', 'C:/Windows/Fonts/arialbd.ttf']:
try: return ImageFont.truetype(n, sz)
except: pass
return ImageFont.load_default()
def new(sz=42):
img = Image.new('RGBA', (sz, sz), T)
return img, ImageDraw.Draw(img)
def save(path, img):
img.save(path, 'PNG')
print(f" {os.path.basename(path)}")
def svg(path, body, w=42, h=42):
with open(path, 'w', encoding='utf-8') as f:
f.write(f'\n\n')
print(f" {os.path.basename(path)}")
def hx(c): return f'#{c[0]:02x}{c[1]:02x}{c[2]:02x}'
def gen_tool_palette():
print("=== Tool Palette ===")
d = os.path.join(BASE, "toolPalette")
sz = 42
# Compass
img, dr = new(sz)
dr.line([21,8,12,34], fill=DARK, width=2)
dr.line([21,8,30,34], fill=DARK, width=2)
dr.ellipse([18,5,24,11], outline=DARK, width=2)
dr.ellipse([9,31,15,37], fill=DARK)
dr.line([12,34,30,34], fill=DARK, width=1)
save(os.path.join(d, "compassTool.png"), img)
svg(os.path.join(d, "compassTool.svg"), '')
# Ruler
img, dr = new(sz)
dr.polygon([(6,28),(34,6),(36,10),(8,32)], fill=DARK)
for i in range(5):
x1, y1 = 10+i*5, 30-i*4
dr.line([(x1,y1),(x1+2,y1-3)], fill=WHITE, width=1)
save(os.path.join(d, "rulerTool.png"), img)
# Protractor
img, dr = new(sz)
dr.arc([6,6,36,36], 0, 180, fill=DARK, width=2)
dr.line([6,21,36,21], fill=DARK, width=2)
dr.arc([12,12,30,30], 0, 180, fill=DARK, width=1)
save(os.path.join(d, "protractorTool.png"), img)
# Triangle
img, dr = new(sz)
dr.polygon([(6,34),(34,34),(6,6)], outline=DARK, width=2)
save(os.path.join(d, "triangleTool.png"), img)
# Axes
img, dr = new(sz)
dr.line([21,6,21,36], fill=DARK, width=2)
dr.line([6,21,36,21], fill=DARK, width=2)
dr.polygon([(21,6),(18,10),(24,10)], fill=DARK)
dr.polygon([(36,21),(32,18),(32,24)], fill=DARK)
save(os.path.join(d, "axesTool.png"), img)
# Aristo (L-shape)
img, dr = new(sz)
dr.polygon([(6,6),(6,34),(34,34)], outline=DARK, width=2)
save(os.path.join(d, "aristoTool.png"), img)
# Magnifier
img, dr = new(sz)
dr.ellipse([8,8,28,28], outline=DARK, width=3)
dr.line([26,26,36,36], fill=DARK, width=3)
save(os.path.join(d, "magnifierTool.png"), img)
# Cache
img, dr = new(sz)
dr.rounded_rectangle([8,8,34,34], radius=4, outline=DARK, width=2)
dr.line([8,8,34,34], fill=DARK, width=1)
save(os.path.join(d, "cacheTool.png"), img)
# Mask
img, dr = new(sz)
dr.rounded_rectangle([8,8,34,34], radius=4, fill=DARK)
dr.rounded_rectangle([14,14,28,28], radius=2, fill=T[:3]+(0,))
save(os.path.join(d, "maskTool.png"), img)
# Podcast
svg(os.path.join(d, "podcast.svg"), '')
svg(os.path.join(d, "podcastOn.svg"), '')
def gen_extra_palette():
print("=== Extra Palette ===")
d = os.path.join(BASE, "extraPalette")
sz = 42
for name, suffix, color, fill_c in [
("blackout","",DARK,None),("blackoutOn","",INDIGO,None),
("compass","",DARK,None),("compassOn","",INDIGO,None),
("keyboard","",DARK,None),("keyboardOn","",INDIGO,None),
("mask","",DARK,None),("maskOn","",INDIGO,None),
("oEmbed","",DARK,None),
("podcast","",DARK,None),("podcastOn","",INDIGO,None),
("protractor","",DARK,None),("protractorOn","",INDIGO,None),
("ruler","",DARK,None),("rulerOn","",INDIGO,None),
("trapFlash","",DARK,None),
("webTrap","",DARK,None),("webTrapEnabled","",INDIGO,None),
]:
img, dr = new(sz)
if "blackout" in name:
dr.rounded_rectangle([8,8,34,34], radius=4, fill=color)
elif "compass" in name:
dr.line([21,8,12,34], fill=color, width=2)
dr.line([21,8,30,34], fill=color, width=2)
dr.ellipse([18,5,24,11], outline=color, width=2)
elif "keyboard" in name:
dr.rounded_rectangle([6,14,36,28], radius=2, outline=color, width=2)
for i in range(5):
for j in range(2):
dr.rectangle([10+j*5+i*5, 16, 13+j*5+i*5, 19], fill=color)
elif "mask" in name:
dr.rounded_rectangle([8,8,34,34], radius=4, fill=color)
elif "podcast" in name:
dr.ellipse([9,9,33,33], outline=color, width=2)
dr.ellipse([17,17,25,25], fill=color)
elif "protractor" in name:
dr.arc([6,6,36,36], 0, 180, fill=color, width=2)
dr.line([6,21,36,21], fill=color, width=2)
elif "ruler" in name:
dr.polygon([(6,28),(34,6),(36,10),(8,32)], fill=color)
elif "oEmbed" in name:
dr.rounded_rectangle([8,14,34,28], radius=2, outline=color, width=2)
dr.polygon([(18,18),(18,24),(24,21)], fill=color)
elif "trapFlash" in name:
dr.ellipse([8,8,34,34], outline=color, width=2)
dr.line([8,8,34,34], fill=color, width=1)
elif "webTrap" in name:
dr.ellipse([8,8,34,34], outline=color, width=2)
dr.line([8,8,34,34], fill=color, width=1)
dr.line([21,8,21,34], fill=color, width=1)
dr.line([8,21,34,21], fill=color, width=1)
save(os.path.join(d, f"{name}{suffix}.png"), img)
def gen_erase_palette():
print("=== Erase Palette ===")
d = os.path.join(BASE, "erasePalette")
for name, color in [("eraseAll",DARK),("eraseAnnotation",DARK),("eraseBackground",DARK),("eraseItem",DARK)]:
svg(os.path.join(d, f"{name}.svg"), f'')
# eraseAll - X with circle
svg(os.path.join(d, "eraseAll.svg"), '')
# eraseAnnotation - eraser with lines
svg(os.path.join(d, "eraseAnnotation.svg"), '')
# eraseBackground - grid with X
svg(os.path.join(d, "eraseBackground.svg"), '')
# eraseItem - box with X
svg(os.path.join(d, "eraseItem.svg"), '')
def gen_background_palette():
print("=== Background Palette ===")
d = os.path.join(BASE, "backgroundPalette")
bgs = [
("background1", "plain"), ("background2", "grid"), ("background3", "lines"),
("background4", "dots"), ("background5", "cross"), ("background6", "ruler"),
("background7", "dark"), ("background8", "light"),
]
for name, bg_type in bgs:
for suffix, color in [("", DARK), ("On", INDIGO)]:
c = hx(color)
if bg_type == "plain":
body = f''
elif bg_type == "grid":
body = f''
elif bg_type == "lines":
body = f''
elif bg_type == "dots":
body = f'' + ''.join(f'' for x in range(12,36,6) for y in range(12,36,6))
elif bg_type == "cross":
body = f'' + ''.join(f'' for x in range(12,36,6) for y in range(12,36,6))
elif bg_type == "ruler":
body = f'' + ''.join(f'' for x in range(12,36,3))
elif bg_type == "dark":
body = f''
elif bg_type == "light":
body = f''
svg(os.path.join(d, f"{name}{suffix}.svg"), body)
# Reset grid size
svg(os.path.join(d, "resetDefaultGridSize.svg"), '')
def gen_cursors():
print("=== Cursors ===")
d = os.path.join(BASE, "cursors")
sz = 32
for name, fn in [
("drawCompass", lambda dr: (dr.line([16,4,8,28], fill=DARK, width=2), dr.line([16,4,24,28], fill=DARK, width=2), dr.ellipse([13,1,19,7], outline=DARK, width=2))),
("drawRulerLine", lambda dr: (dr.line([4,28,28,4], fill=DARK, width=2), dr.ellipse([2,26,8,32], fill=DARK), dr.ellipse([26,2,32,8], fill=DARK))),
("eraser", lambda dr: dr.rounded_rectangle([6,10,26,22], radius=3, fill=DARK)),
("laser", lambda dr: (dr.ellipse([12,12,20,20], fill=RED), dr.line([16,16,28,28], fill=RED, width=2))),
("marker", lambda dr: (dr.line([6,26,26,6], fill=DARK, width=5), dr.rounded_rectangle([23,4,29,10], radius=2, fill=DARK))),
("play", lambda dr: dr.polygon([(8,6),(8,26),(26,16)], fill=DARK)),
("resize", lambda dr: (dr.line([4,16,28,16], fill=DARK, width=2), dr.polygon([(4,16),(8,12),(8,20)], fill=DARK), dr.polygon([(28,16),(24,12),(24,20)], fill=DARK))),
("rotate", lambda dr: (dr.arc([6,6,26,26], 0, 270, fill=DARK, width=2), dr.polygon([(26,6),(22,6),(26,10)], fill=DARK))),
("zoomIn", lambda dr: (dr.ellipse([6,6,22,22], outline=DARK, width=2), dr.line([20,20,28,28], fill=DARK, width=2), dr.line([10,14,18,14], fill=DARK, width=2), dr.line([14,10,14,18], fill=DARK, width=2))),
("zoomOut", lambda dr: (dr.ellipse([6,6,22,22], outline=DARK, width=2), dr.line([20,20,28,28], fill=DARK, width=2), dr.line([10,14,18,14], fill=DARK, width=2))),
]:
img, dr = new(sz)
fn(dr)
save(os.path.join(d, f"{name}.png"), img)
def gen_misc():
print("=== Misc Icons ===")
sz = 42
# Main SVG icons
d = BASE
for name, body in [
("close", ''),
("closeDisabled", ''),
("closeTool", ''),
("color", ''),
("circle", ''),
("duplicate", ''),
("duplicateDisabled", ''),
("eyeClosed", ''),
("eyeOpened", ''),
("flash", ''),
("font", 'A'),
("frozen", ''),
("unfrozen", ''),
("groupItems", ''),
("ungroupItems", ''),
("home", ''),
("locked", ''),
("unlocked", ''),
("menu", ''),
("menuDisabled", ''),
("minus", ''),
("plus", ''),
("pin", ''),
("unpin", ''),
("play", ''),
("pause", ''),
("stop", ''),
("reload", ''),
("rotate", ''),
("rotateProtractor", ''),
("roundeRrectangle", ''),
("save", ''),
("setAsBackground", ''),
("soundOff", ''),
("soundOn", ''),
("hflipTool", ''),
("vflipTool", ''),
("moveDown", ''),
("moveDownDisabled", ''),
("moveUp", ''),
("moveUpDisabled", ''),
("moveTool", ''),
("resetAngle", ''),
("resetTool", ''),
("resizeTool", ''),
("resizeBottom", ''),
("resizeLeft", ''),
("resizeRight", ''),
("resizeTop", ''),
("resizeButton", ''),
("resizeCompass", ''),
("resizeRuler", ''),
("numbersTool", '123'),
("angleMarker", ''),
("centerAligned", ''),
("leftAligned", ''),
("rightAligned", ''),
("notAligned", ''),
("z_layer_up", ''),
("z_layer_down", ''),
("increase", ''),
("decrease", ''),
("resize", ''),
("rotate", ''),
("addItemToCurrentPage", ''),
("addItemToLibrary", ''),
("addItemToNewPage", ''),
("addToFavorites", ''),
("removeFromFavorites", ''),
("folder", ''),
("myFolder", ''),
]:
svg(os.path.join(d, f"{name}.svg"), body)
# PNG-only misc icons
for name, fn in [
("addToFavorites", lambda dr: dr.polygon([(21,6),(26,16),(37,17),(28,25),(31,36),(21,30),(11,36),(14,25),(5,17),(16,16)], outline=DARK, width=2)),
("removeFromFavorites", lambda dr: dr.polygon([(21,6),(26,16),(37,17),(28,25),(31,36),(21,30),(11,36),(14,25),(5,17),(16,16)], fill=INDIGO)),
("asc", lambda dr: (dr.line([8,30,34,30], fill=DARK, width=2), dr.line([8,20,34,20], fill=DARK, width=2), dr.line([8,10,34,10], fill=DARK, width=2), dr.polygon([(21,4),(16,10),(26,10)], fill=DARK))),
("desc", lambda dr: (dr.line([8,30,34,30], fill=DARK, width=2), dr.line([8,20,34,20], fill=DARK, width=2), dr.line([8,10,34,10], fill=DARK, width=2), dr.polygon([(21,36),(16,30),(26,30)], fill=DARK))),
("cache_circle", lambda dr: dr.ellipse([6,6,36,36], outline=DARK, width=2)),
("cache_close", lambda dr: (dr.ellipse([6,6,36,36], outline=DARK, width=2), dr.line([14,14,28,28], fill=RED, width=2), dr.line([28,14,14,28], fill=RED, width=2))),
("cache_open", lambda dr: (dr.ellipse([6,6,36,36], outline=DARK, width=2), dr.line([14,14,28,28], fill=GREEN, width=2))),
("cache_square", lambda dr: dr.rounded_rectangle([8,8,34,34], radius=2, outline=DARK, width=2)),
("collapse-all", lambda dr: (dr.line([6,10,36,10], fill=DARK, width=2), dr.polygon([(10,6),(6,10),(10,14)], fill=DARK), dr.line([6,21,36,21], fill=DARK, width=2), dr.polygon([(10,17),(6,21),(10,25)], fill=DARK), dr.line([6,32,36,32], fill=DARK, width=2), dr.polygon([(10,28),(6,32),(10,36)], fill=DARK))),
("expand-all", lambda dr: (dr.line([6,10,36,10], fill=DARK, width=2), dr.polygon([(6,6),(10,10),(6,14)], fill=DARK), dr.line([6,21,36,21], fill=DARK, width=2), dr.polygon([(6,17),(10,21),(6,25)], fill=DARK), dr.line([6,32,36,32], fill=DARK, width=2), dr.polygon([(6,28),(10,32),(6,36)], fill=DARK))),
("currentDocument", lambda dr: (dr.rounded_rectangle([8,6,34,36], radius=2, outline=DARK, width=2), dr.line([12,12,30,12], fill=DARK, width=1), dr.line([12,16,30,16], fill=DARK, width=1), dr.line([12,20,24,20], fill=DARK, width=1))),
("defaultWidgetIcon", lambda dr: (dr.rounded_rectangle([8,8,34,34], radius=4, outline=DARK, width=2), dr.ellipse([16,16,26,26], fill=INDIGO))),
("download_close", lambda dr: (dr.line([8,8,34,34], fill=RED, width=2), dr.line([34,8,8,34], fill=RED, width=2))),
("download_open", lambda dr: (dr.line([8,21,34,21], fill=GREEN, width=2), dr.polygon([(14,16),(14,26),(8,21)], fill=GREEN), dr.polygon([(28,16),(28,26),(34,21)], fill=GREEN))),
("edit-mode", lambda dr: (dr.line([8,34,28,14], fill=DARK, width=3), dr.ellipse([25,11,33,19], outline=DARK, width=2))),
("favorites", lambda dr: dr.polygon([(21,6),(26,16),(37,17),(28,25),(31,36),(21,30),(11,36),(14,25),(5,17),(16,16)], outline=DARK, width=2)),
("folder", lambda dr: (dr.rounded_rectangle([6,12,36,34], radius=3, fill=(220,38,38,40), outline=DARK, width=2), dr.polygon([(6,12),(16,12),(20,8),(28,8)], fill=DARK, outline=DARK, width=1), dr.rounded_rectangle([6,10,28,14], radius=2, fill=(220,38,38,60), outline=DARK, width=1))),
("library_close", lambda dr: (dr.rounded_rectangle([6,6,36,36], radius=4, outline=DARK, width=2), dr.line([14,14,28,28], fill=RED, width=2))),
("library_open", lambda dr: (dr.rounded_rectangle([6,6,36,36], radius=4, outline=DARK, width=2), dr.line([14,21,28,21], fill=GREEN, width=2))),
("myContent", lambda dr: (dr.rounded_rectangle([6,8,36,34], radius=2, outline=DARK, width=2), dr.line([6,16,36,16], fill=DARK, width=1))),
("myFolder", lambda dr: (dr.rounded_rectangle([6,12,36,34], radius=3, fill=(220,38,38,40), outline=DARK, width=2), dr.polygon([(6,12),(16,12),(20,8),(28,8)], fill=DARK, outline=DARK, width=1), dr.rounded_rectangle([6,10,28,14], radius=2, fill=(220,38,38,60), outline=DARK, width=1))),
("navig_arrow", lambda dr: dr.polygon([(8,8),(34,21),(8,34)], fill=DARK)),
("online", lambda dr: (dr.ellipse([8,8,34,34], outline=GREEN, width=2), dr.line([14,21,19,26], fill=GREEN, width=3), dr.line([19,26,30,15], fill=GREEN, width=3))),
("pages_close", lambda dr: (dr.rounded_rectangle([6,6,36,36], radius=4, outline=DARK, width=2), dr.line([14,14,28,28], fill=DARK, width=2), dr.line([28,14,14,28], fill=DARK, width=2))),
("pages_open", lambda dr: (dr.rounded_rectangle([6,6,36,36], radius=4, outline=DARK, width=2), dr.line([14,18,28,18], fill=DARK, width=2), dr.line([14,24,28,24], fill=DARK, width=2))),
("paletteLibrary", lambda dr: (dr.rounded_rectangle([6,6,36,36], radius=4, outline=DARK, width=2), dr.line([6,16,36,16], fill=DARK, width=1), dr.line([16,6,16,36], fill=DARK, width=1))),
("paletteNavigator", lambda dr: (dr.rounded_rectangle([6,6,36,36], radius=4, outline=DARK, width=2), dr.ellipse([14,14,28,28], outline=INDIGO, width=2))),
("save", lambda dr: (dr.rounded_rectangle([8,6,34,36], radius=2, outline=DARK, width=2), dr.rectangle([14,6,28,14], fill=DARK), dr.rectangle([14,22,28,34], outline=DARK, width=1))),
("shape", lambda dr: (dr.ellipse([6,6,24,24], outline=DARK, width=2), dr.polygon([(20,18),(36,18),(28,36)], outline=DARK, width=2))),
("tab_mask", lambda dr: dr.rounded_rectangle([2,8,40,34], radius=2, outline=DARK, width=2)),
("tools", lambda dr: (dr.line([8,34,24,18], fill=DARK, width=3), dr.ellipse([22,14,32,24], outline=DARK, width=2))),
("trash", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2), dr.line([16,4,26,4], fill=DARK, width=2))),
("trash-delete-document", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2), dr.rounded_rectangle([16,14,26,30], radius=2, outline=RED, width=1))),
("trash-delete-folder", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2), dr.rounded_rectangle([14,14,28,28], radius=2, fill=(220,38,38,40), outline=RED, width=1), dr.polygon([(14,14),(20,14),(22,10),(26,10)], fill=RED), dr.line([16,18,26,26], fill=RED, width=2), dr.line([26,18,16,26], fill=RED, width=2))),
("trash-document-page", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2), dr.line([16,14,26,14], fill=RED, width=1), dr.line([16,20,26,20], fill=RED, width=1))),
("trash-document", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2), dr.rounded_rectangle([16,14,26,30], radius=2, outline=DARK, width=1))),
("trash-empty", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2))),
("trash-folder", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2), dr.rounded_rectangle([14,14,28,28], radius=2, fill=(220,38,38,40), outline=RED, width=1), dr.polygon([(14,14),(20,14),(22,10),(26,10)], fill=RED))),
("trash-my-documents", lambda dr: (dr.line([6,8,36,8], fill=DARK, width=2), dr.rounded_rectangle([10,8,32,36], radius=2, outline=DARK, width=2), dr.ellipse([16,14,22,20], outline=DARK, width=1), dr.ellipse([24,14,30,20], outline=DARK, width=1))),
("up_arrow", lambda dr: dr.polygon([(21,6),(8,30),(34,30)], fill=DARK)),
("down_arrow", lambda dr: dr.polygon([(21,36),(8,12),(34,12)], fill=DARK)),
("left_arrow", lambda dr: dr.polygon([(6,21),(30,8),(30,34)], fill=DARK)),
("right_arrow", lambda dr: dr.polygon([(36,21),(12,8),(12,34)], fill=DARK)),
("edit-mode", lambda dr: (dr.line([8,34,28,14], fill=DARK, width=3), dr.ellipse([25,11,33,19], outline=DARK, width=2))),
("banner", lambda dr: dr.rounded_rectangle([0,0,42,42], radius=0, fill=INDIGO)),
("banner_linear", lambda dr: dr.rounded_rectangle([0,0,42,42], radius=0, fill=INDIGO)),
]:
img, dr = new(sz)
fn(dr)
save(os.path.join(d, f"{name}.png"), img)
# Ch.SaiCore.SaiCore.svg
svg(os.path.join(d, "ch.SaiCore.SaiCore.svg"), 'S')
def gen_libpalette():
print("=== Lib Palette ===")
d = os.path.join(BASE, "libpalette")
if not os.path.exists(d): os.makedirs(d)
# Check what's there and regenerate
for f in os.listdir(d):
path = os.path.join(d, f)
if f.endswith('.png'):
try:
img = Image.open(path)
img = img.convert('RGBA')
# Recolor: replace green/colored with red, dark pixels with cream
pixels = img.load()
for y in range(img.height):
for x in range(img.width):
r, g, b, a = pixels[x, y]
if a > 0 and g > r and g > b:
pixels[x, y] = (INDIGO[0], INDIGO[1], INDIGO[2], a)
elif a > 0 and r == g == b and r < 128:
pixels[x, y] = (DARK[0], DARK[1], DARK[2], a)
elif a > 0 and r > 100 and g < 100 and b < 100:
pixels[x, y] = (INDIGO[0], INDIGO[1], INDIGO[2], a)
img.save(path, 'PNG')
print(f" recolored: {f}")
except: pass
def gen_print():
print("=== Print ===")
d = os.path.join(BASE, "print")
if not os.path.exists(d): os.makedirs(d)
for f in os.listdir(d):
path = os.path.join(d, f)
if f.endswith('.png'):
try:
img = Image.open(path).convert('RGBA')
pixels = img.load()
for y in range(img.height):
for x in range(img.width):
r, g, b, a = pixels[x, y]
if a > 0 and g > r and g > b:
pixels[x, y] = (INDIGO[0], INDIGO[1], INDIGO[2], a)
img.save(path, 'PNG')
print(f" recolored: {f}")
except: pass
def run():
gen_tool_palette()
gen_extra_palette()
gen_erase_palette()
gen_background_palette()
gen_cursors()
gen_misc()
gen_libpalette()
gen_print()
if __name__ == "__main__":
run()