Merge branch 'master' of github.com:espruino/BangleApps
commit
8cca43442b
|
|
@ -1 +1,3 @@
|
|||
0.01: New App!
|
||||
0.02: Increased Legibility, GUI rework
|
||||
0.03: 13 new chords
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ An app that simply describes finger placements on a Ukulele to form common chord
|
|||
|
||||
## Usage
|
||||
|
||||
Use the button to scroll through the available chords.
|
||||
Select a chord to view.
|
||||
Use the button to return to the chord selection menu.
|
||||
|
||||
## Creator
|
||||
|
||||
|
|
|
|||
246
apps/Uke/app.js
246
apps/Uke/app.js
|
|
@ -16,52 +16,12 @@ const cc = [
|
|||
|
||||
const dd = [
|
||||
"D",
|
||||
"22",
|
||||
"23",
|
||||
"22",
|
||||
"24",
|
||||
"x"
|
||||
];
|
||||
|
||||
const gg = [
|
||||
"G",
|
||||
"x",
|
||||
"21",
|
||||
"33",
|
||||
"22",
|
||||
];
|
||||
|
||||
const am = [
|
||||
"Am",
|
||||
"22",
|
||||
"x",
|
||||
"x",
|
||||
"x"
|
||||
];
|
||||
|
||||
const em = [
|
||||
"Em",
|
||||
"x",
|
||||
"43",
|
||||
"32",
|
||||
"21"
|
||||
];
|
||||
|
||||
const aa = [
|
||||
"A",
|
||||
"22",
|
||||
"11",
|
||||
"x",
|
||||
"x"
|
||||
];
|
||||
|
||||
const ff = [
|
||||
"F",
|
||||
"22",
|
||||
"x",
|
||||
"11",
|
||||
"x"
|
||||
];
|
||||
|
||||
var ee = [
|
||||
"E",
|
||||
"33",
|
||||
|
|
@ -70,14 +30,187 @@ var ee = [
|
|||
"11"
|
||||
];
|
||||
|
||||
const ff = [
|
||||
"F",
|
||||
"22",
|
||||
"x",
|
||||
"11",
|
||||
"x"
|
||||
];
|
||||
|
||||
const gg = [
|
||||
"G",
|
||||
"x",
|
||||
"21",
|
||||
"33",
|
||||
"22",
|
||||
];
|
||||
|
||||
const aa = [
|
||||
"A",
|
||||
"22",
|
||||
"11",
|
||||
"x",
|
||||
"x"
|
||||
];
|
||||
|
||||
const bb = [
|
||||
"B",
|
||||
"42",
|
||||
"43",
|
||||
"44",
|
||||
"21"
|
||||
];
|
||||
|
||||
const cm = [
|
||||
"Cm",
|
||||
"11",
|
||||
"x",
|
||||
"12",
|
||||
"34"
|
||||
];
|
||||
|
||||
const dm = [
|
||||
"Dm",
|
||||
"x",
|
||||
"22",
|
||||
"33",
|
||||
"11"
|
||||
];
|
||||
|
||||
const em = [
|
||||
"Em",
|
||||
"x",
|
||||
"43",
|
||||
"32",
|
||||
"21"
|
||||
];
|
||||
|
||||
const fm = [
|
||||
"Fm",
|
||||
"33",
|
||||
"11",
|
||||
"11",
|
||||
"11"
|
||||
];
|
||||
|
||||
const gm = [
|
||||
"Gm",
|
||||
"x",
|
||||
"22",
|
||||
"33",
|
||||
"11"
|
||||
];
|
||||
|
||||
const am = [
|
||||
"Am",
|
||||
"22",
|
||||
"23",
|
||||
"11",
|
||||
"x"
|
||||
];
|
||||
|
||||
const bm = [
|
||||
"Bm",
|
||||
"x",
|
||||
"43",
|
||||
"32",
|
||||
"21"
|
||||
];
|
||||
|
||||
const c7 = [
|
||||
"C7",
|
||||
"22",
|
||||
"33",
|
||||
"11",
|
||||
"x"
|
||||
];
|
||||
|
||||
const d7 = [
|
||||
"D7",
|
||||
"x",
|
||||
"22",
|
||||
"11",
|
||||
"23"
|
||||
];
|
||||
|
||||
const e7 = [
|
||||
"E7",
|
||||
"x",
|
||||
"11",
|
||||
"x",
|
||||
"x"
|
||||
];
|
||||
|
||||
const f7 = [
|
||||
"F7",
|
||||
"11",
|
||||
"22",
|
||||
"11",
|
||||
"11"
|
||||
];
|
||||
|
||||
const g7 = [
|
||||
"G7",
|
||||
"x",
|
||||
"x",
|
||||
"x",
|
||||
"11"
|
||||
];
|
||||
|
||||
const a7 = [
|
||||
"A7",
|
||||
"21",
|
||||
"21",
|
||||
"21",
|
||||
"32"
|
||||
];
|
||||
|
||||
const b7 = [
|
||||
"B7",
|
||||
"11",
|
||||
"22",
|
||||
"x",
|
||||
"23"
|
||||
];
|
||||
|
||||
|
||||
|
||||
var index = 0;
|
||||
var chords = [];
|
||||
var menu = {
|
||||
"" : { "title" : "Uke Chords" },
|
||||
"C" : function() { draw(cc); },
|
||||
"D" : function() { draw(dd); },
|
||||
"E" : function() { draw(ee); },
|
||||
"F" : function() { draw(ff); },
|
||||
"G" : function() { draw(gg); },
|
||||
"A" : function() { draw(aa); },
|
||||
"B" : function() { draw(bb); },
|
||||
"C7" : function() { draw(c7); },
|
||||
"D7" : function() { draw(d7); },
|
||||
"E7" : function() { draw(e7); },
|
||||
"F7" : function() { draw(f7); },
|
||||
"G7" : function() { draw(g7); },
|
||||
"A7" : function() { draw(a7); },
|
||||
"B7" : function() { draw(b7); },
|
||||
"Cm" : function() { draw(cm); },
|
||||
"Dm" : function() { draw(dm); },
|
||||
"Em" : function() { draw(em); },
|
||||
"Fm" : function() { draw(fm); },
|
||||
"Gm" : function() { draw(gm); },
|
||||
"Am" : function() { draw(am); },
|
||||
"Bm" : function() { draw(bm); },
|
||||
"About" : function() {
|
||||
E.showMessage(
|
||||
"Created By:\nNovaDawn999", {
|
||||
title:"About"
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function init() {
|
||||
g.setFontAlign(0,0); // center font
|
||||
g.setFont("6x8",2); // bitmap font, 8x magnified
|
||||
chords.push(cc, dd, gg, am, em, aa, ff, ee);
|
||||
}
|
||||
|
||||
function drawBase() {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
|
|
@ -87,18 +220,18 @@ function drawBase() {
|
|||
}
|
||||
|
||||
function drawChord(chord) {
|
||||
g.drawString(chord[0], g.getWidth() * 0.5 + 2, 18);
|
||||
g.drawString(chord[0], g.getWidth() * 0.5 - (chord[0].length * 5), 16);
|
||||
for (let i = 0; i < chord.length; i++) {
|
||||
if (i === 0 || chord[i][0] === "x") {
|
||||
continue;
|
||||
}
|
||||
if (chord[i][0] === "0") {
|
||||
g.drawString(chord[i][1], x + (i - 1) * stringInterval + 1, y + fretHeight * chord[i][0], true);
|
||||
g.drawCircle(x + (i - 1) * stringInterval -1, y + fretHeight * chord[i][0], 8);
|
||||
g.drawString(chord[i][1], x + (i - 1) * stringInterval - 5, y + fretHeight * chord[i][0] + 2, true);
|
||||
g.drawCircle(x + (i - 1) * stringInterval -1, y + fretHeight * chord[i][0], 10);
|
||||
}
|
||||
else {
|
||||
g.drawString(chord[i][1], x + (i - 1) * stringInterval + 1, y -fingerOffset + fretHeight * chord[i][0], true);
|
||||
g.drawCircle(x + (i - 1) * stringInterval -1, y -fingerOffset + fretHeight * chord[i][0], 8);
|
||||
g.drawString(chord[i][1], x + (i - 1) * stringInterval -5, y -fingerOffset + fretHeight * chord[i][0] + 2, true);
|
||||
g.drawCircle(x + (i - 1) * stringInterval -1, y -fingerOffset + fretHeight * chord[i][0], 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -107,22 +240,19 @@ function buttonPress() {
|
|||
setWatch(() => {
|
||||
buttonPress();
|
||||
}, BTN);
|
||||
index++;
|
||||
if (index >= chords.length) { index = 0; }
|
||||
draw();
|
||||
E.showMenu(menu);
|
||||
}
|
||||
|
||||
function draw() {
|
||||
function draw(chord) {
|
||||
g.clear();
|
||||
drawBase();
|
||||
drawChord(chords[index]);
|
||||
drawChord(chord);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function main() {
|
||||
init();
|
||||
draw();
|
||||
E.showMenu(menu);
|
||||
setWatch(() => {
|
||||
buttonPress();
|
||||
}, BTN);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ "id": "Uke",
|
||||
"name": "Uke Chords",
|
||||
"shortName":"Uke",
|
||||
"version":"0.01",
|
||||
"version":"0.03",
|
||||
"description": "Wrist mounted ukulele chords",
|
||||
"icon": "app.png",
|
||||
"tags": "uke, chords",
|
||||
|
|
|
|||
|
|
@ -66,3 +66,4 @@
|
|||
If settings.bootDebug is set, output timing for each section of .boot0
|
||||
0.56: Settings.log = 0,1,2,3 for off,display, log, both
|
||||
0.57: Handle the whitelist being disabled
|
||||
0.58: "Make Connectable" temporarily bypasses the whitelist
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ if (global.save) boot += `global.save = function() { throw new Error("You can't
|
|||
if (s.options) boot+=`Bangle.setOptions(${E.toJS(s.options)});\n`;
|
||||
if (s.brightness && s.brightness!=1) boot+=`Bangle.setLCDBrightness(${s.brightness});\n`;
|
||||
if (s.passkey!==undefined && s.passkey.length==6) boot+=`NRF.setSecurity({passkey:${E.toJS(s.passkey.toString())}, mitm:1, display:1});\n`;
|
||||
if (s.whitelist && !s.whitelist_disabled) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`;
|
||||
if (s.whitelist && !s.whitelist_disabled) boot+=`NRF.on('connect', function(addr) { if (!NRF.ignoreWhitelist && !(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`;
|
||||
if (s.rotate) boot+=`g.setRotation(${s.rotate&3},${s.rotate>>2});\n` // screen rotation
|
||||
// ================================================== FIXING OLDER FIRMWARES
|
||||
if (FWVERSION<215.068) // 2v15.68 and before had compass heading inverted.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "boot",
|
||||
"name": "Bootloader",
|
||||
"version": "0.57",
|
||||
"version": "0.58",
|
||||
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
||||
"icon": "bootloader.png",
|
||||
"type": "bootloader",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: More Chords, formatting, fret offset support.
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Guitar Chords
|
||||
|
||||
An app that simply describes finger placements on a Guitar to form common chords.
|
||||
|
||||
## Usage
|
||||
|
||||
Select a chord to view.
|
||||
Use the button to return to the chord selection menu.
|
||||
|
||||
## Creator
|
||||
|
||||
NovaDawn999
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwkCkQA/AGMkoQXVptEFytEogwUCoIYBLqlUGIIXTopHVknUoXULylNpouUIoKmUUi0hoMUailEiMSCR/d7pdECx8tC4IYBolULqAWC7qLSFwfdiKMRC4dEoK6RFwYWBppdW7vSLiPd6gXPConVgIWCYYYtM9vdosUqgXOFwndilBqoGDLh/eqtEioXR9xHCoIXDO5SKEpvU6kVppeQ73kqgwB7wuNOwosEXqSlB9xFNR49RpwXV6pICIxhIF73ePAIXTAAgXOJApePGBQXPGA4XPGAxeOGBAWQDAouRDAgWUAH4AZ"))
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
const stringInterval = 24;
|
||||
const stringLength = 138;
|
||||
const fretHeight = 35;
|
||||
const fingerOffset = 17;
|
||||
const xOffset = 26;
|
||||
const yOffset = 34;
|
||||
|
||||
const cc = [
|
||||
"C",
|
||||
"0X",
|
||||
"33",
|
||||
"22",
|
||||
"x",
|
||||
"11",
|
||||
"x",
|
||||
"0"
|
||||
];
|
||||
|
||||
const dd = [
|
||||
"D",
|
||||
"0X",
|
||||
"0X",
|
||||
"x",
|
||||
"21",
|
||||
"33",
|
||||
"22",
|
||||
"0"
|
||||
];
|
||||
|
||||
const gg = [
|
||||
"G",
|
||||
"32",
|
||||
"21",
|
||||
"x",
|
||||
"x",
|
||||
"x",
|
||||
"33",
|
||||
"0"
|
||||
];
|
||||
|
||||
const am = [
|
||||
"Am",
|
||||
"0x",
|
||||
"x",
|
||||
"23",
|
||||
"22",
|
||||
"11",
|
||||
"x",
|
||||
"0"
|
||||
];
|
||||
|
||||
const em = [
|
||||
"Em",
|
||||
"x",
|
||||
"22",
|
||||
"23",
|
||||
"x",
|
||||
"x",
|
||||
"x",
|
||||
"0"
|
||||
];
|
||||
|
||||
const aa = [
|
||||
"A",
|
||||
"0X",
|
||||
"x",
|
||||
"21",
|
||||
"22",
|
||||
"23",
|
||||
"x",
|
||||
"0"
|
||||
];
|
||||
|
||||
var ee = [
|
||||
"E",
|
||||
"x",
|
||||
"22",
|
||||
"23",
|
||||
"11",
|
||||
"x",
|
||||
"x",
|
||||
"0"
|
||||
];
|
||||
|
||||
var dm = [
|
||||
"Dm",
|
||||
"0x",
|
||||
"0x",
|
||||
"x",
|
||||
"22",
|
||||
"33",
|
||||
"11",
|
||||
"0"
|
||||
];
|
||||
|
||||
var ff = [
|
||||
"F",
|
||||
"0x",
|
||||
"0x",
|
||||
"33",
|
||||
"22",
|
||||
"11",
|
||||
"11",
|
||||
"0"
|
||||
];
|
||||
|
||||
var b7 = [
|
||||
"B7",
|
||||
"0x",
|
||||
"22",
|
||||
"11",
|
||||
"23",
|
||||
"x",
|
||||
"24",
|
||||
"0"
|
||||
];
|
||||
|
||||
var cadd9 = [
|
||||
"Cadd9",
|
||||
"0x",
|
||||
"32",
|
||||
"21",
|
||||
"x",
|
||||
"33",
|
||||
"34",
|
||||
"0"
|
||||
];
|
||||
|
||||
var dadd11 = [
|
||||
"Dadd11",
|
||||
"0x",
|
||||
"33",
|
||||
"22",
|
||||
"x",
|
||||
"11",
|
||||
"x",
|
||||
"3"
|
||||
];
|
||||
|
||||
var csus2 = [
|
||||
"Csus2",
|
||||
"0x",
|
||||
"33",
|
||||
"x",
|
||||
"x",
|
||||
"11",
|
||||
"0x",
|
||||
"0"
|
||||
];
|
||||
|
||||
var gadd9 = [
|
||||
"Gadd9",
|
||||
"32",
|
||||
"0x",
|
||||
"x",
|
||||
"21",
|
||||
"x",
|
||||
"33",
|
||||
"0"
|
||||
];
|
||||
|
||||
var aadd9 = [
|
||||
"Aadd9",
|
||||
"11",
|
||||
"33",
|
||||
"34",
|
||||
"22",
|
||||
"x",
|
||||
"x",
|
||||
"5"
|
||||
];
|
||||
|
||||
var fsharp7add11 = [
|
||||
"F#7add11",
|
||||
"21",
|
||||
"43",
|
||||
"44",
|
||||
"32",
|
||||
"x",
|
||||
"x",
|
||||
"0"
|
||||
];
|
||||
|
||||
var d9 = [
|
||||
"D9",
|
||||
"0x",
|
||||
"22",
|
||||
"11",
|
||||
"23",
|
||||
"23",
|
||||
"0x",
|
||||
"4"
|
||||
];
|
||||
|
||||
var g7 = [
|
||||
"G7",
|
||||
"33",
|
||||
"22",
|
||||
"x",
|
||||
"x",
|
||||
"34",
|
||||
"11",
|
||||
"0"
|
||||
];
|
||||
|
||||
var bflatd = [
|
||||
"Bb/D",
|
||||
"0x",
|
||||
"33",
|
||||
"11",
|
||||
"11",
|
||||
"11",
|
||||
"0x",
|
||||
"3"
|
||||
];
|
||||
|
||||
var e7sharp9 = [
|
||||
"E7#9",
|
||||
"0x",
|
||||
"22",
|
||||
"11",
|
||||
"23",
|
||||
"34",
|
||||
"0x",
|
||||
"6"
|
||||
];
|
||||
|
||||
var a11 = [
|
||||
"A11 3rd fret",
|
||||
"33",
|
||||
"0x",
|
||||
"34",
|
||||
"22",
|
||||
"11",
|
||||
"0x",
|
||||
"0"
|
||||
];
|
||||
|
||||
var a9 = [
|
||||
"A9",
|
||||
"32",
|
||||
"0x",
|
||||
"33",
|
||||
"21",
|
||||
"34",
|
||||
"0x",
|
||||
"3"
|
||||
];
|
||||
|
||||
|
||||
|
||||
var index = 0;
|
||||
var chords = [];
|
||||
var menu = {
|
||||
"" : {
|
||||
"title" : "Guitar Chords"
|
||||
},
|
||||
"C" : function() { draw(cc); },
|
||||
"D" : function() { draw(dd); },
|
||||
"E" : function() { draw(ee); },
|
||||
"Em" : function() { draw(em); },
|
||||
"A" : function() { draw(aa); },
|
||||
"Am" : function() { draw(am); },
|
||||
"F" : function() { draw(ff); },
|
||||
"G" : function() { draw(gg); },
|
||||
"Dm" : function() { draw(dm); },
|
||||
"B7" : function () { draw(b7); },
|
||||
"Cadd9" : function () { draw(cadd9); },
|
||||
"Dadd11" : function () { draw(dadd11); },
|
||||
"Csus2" : function () { draw(csus2); },
|
||||
"Gadd9" : function () { draw(gadd9); },
|
||||
"Aadd9" : function () { draw(aadd9); },
|
||||
"F#7add11" : function () { draw(fsharp7add11); },
|
||||
"D9" : function () { draw(d9); },
|
||||
"G7" : function () { draw(g7); },
|
||||
"Bb/D" : function () { draw(bflatd); },
|
||||
"E7#9" : function () { draw(e7sharp9); },
|
||||
"A11" : function () { draw(a11); },
|
||||
"A9" : function () { draw(a9); },
|
||||
"About" : function() {
|
||||
E.showMessage(
|
||||
"Created By:\nNovaDawn999", {
|
||||
title:"About"
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
function drawBase() {
|
||||
for (let i = 0; i < 6; i++) {
|
||||
g.drawLine(xOffset + i * stringInterval, yOffset, xOffset + i * stringInterval, yOffset + stringLength);
|
||||
g.fillRect(xOffset- 1, yOffset + i * fretHeight - 1, xOffset + stringInterval * 5 + 1, yOffset + i * fretHeight + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function drawChord(chord) {
|
||||
g.drawString(chord[0], g.getWidth() * 0.5 - (chord[0].length * 5), 16);
|
||||
for (let i = 0; i < chord.length - 1; i++) {
|
||||
if (i === 0 || chord[i][0] === "x") {
|
||||
continue;
|
||||
}
|
||||
if (chord[i][0] === "0") {
|
||||
g.drawString(chord[i][1], xOffset + (i - 1) * stringInterval - 5, yOffset + fretHeight * chord[i][0] + 2, true);
|
||||
g.drawCircle(xOffset + (i - 1) * stringInterval -1, yOffset + fretHeight * chord[i][0], 10);
|
||||
}
|
||||
else {
|
||||
g.drawString(chord[i][1], xOffset + (i - 1) * stringInterval -5, yOffset -fingerOffset + fretHeight * chord[i][0] + 2, true);
|
||||
g.drawCircle(xOffset + (i - 1) * stringInterval -1, yOffset -fingerOffset + fretHeight * chord[i][0], 10);
|
||||
}
|
||||
}
|
||||
if (chord[7] !== "0") {
|
||||
g.drawString(chord[7], 9, 50);
|
||||
}
|
||||
}
|
||||
|
||||
function buttonPress() {
|
||||
setWatch(() => {
|
||||
buttonPress();
|
||||
}, BTN);
|
||||
E.showMenu(menu);
|
||||
}
|
||||
|
||||
function draw(chord) {
|
||||
g.clear();
|
||||
drawBase();
|
||||
drawChord(chord);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function main() {
|
||||
E.showMenu(menu);
|
||||
setWatch(() => {
|
||||
buttonPress();
|
||||
}, BTN);
|
||||
}
|
||||
|
||||
main();
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -0,0 +1,14 @@
|
|||
{ "id": "guitar",
|
||||
"name": "Guitar Chords",
|
||||
"shortName":"Guitar",
|
||||
"version":"0.02",
|
||||
"description": "Wrist mounted guitar chords",
|
||||
"icon": "app.png",
|
||||
"tags": "guitar, chords",
|
||||
"supports" : ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"guitar.app.js","url":"app.js"},
|
||||
{"name":"guitar.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
||||
|
|
@ -5,3 +5,7 @@
|
|||
0.05: Tell clock widgets to hide
|
||||
0.06: Fix exception when showing missing hiragana 'WO'
|
||||
0.07: Fix regression in bitmap selection on some code paths
|
||||
0.08: Speedup next/prev and fix autogenerated hiragana bitmaps
|
||||
0.09: Optimize loading and rendering times, introduce transition animations
|
||||
0.10: Swipe up/down for Hiragana/Katakana, right/left for next/prev letter
|
||||
0.11: Sort by 'AIUEO' instead of 'AEIOU', draw Widgets every minute :?
|
||||
|
|
|
|||
|
|
@ -1,19 +1,25 @@
|
|||
# kanawatch
|
||||
|
||||
A simple watchface design with hiragana and katakana
|
||||
cards for learning.
|
||||
A simple watchface design perfect for learning hiragana and katakana.
|
||||
|
||||
## Changelog
|
||||
* Interact with the interface using swipes
|
||||
* Swipe up/down to switch between hiragana (H) and katakana (K)
|
||||
* Swipe right/left to display the next or previous letter
|
||||
* Tap to change accent color (always 24h, not configurable)
|
||||
* Non-intrustive transition animations
|
||||
* Low battery consumption
|
||||
|
||||
0.01: First release
|
||||
0.02: Improve battery life, sprite resolution, fix launcher issue and unaligned text bug
|
||||
0.03: Reduce code size, refresh once a minute and faster refresh
|
||||
0.04: Show a random kana every minute to improve learning
|
||||
## TODO
|
||||
|
||||
* Only render what needs to be repainted
|
||||
* Dont redraw the widgets if not necessary
|
||||
* Minigame to guess kata/hira phonem
|
||||
|
||||
## Author
|
||||
|
||||
Written by pancake in 2022, powered by insomnia
|
||||
Written by pancake in 2022, maintained during 2023 and powered by insomnia
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||
|
|
|
|||
|
|
@ -3,182 +3,214 @@ const stripe_pos = 40;
|
|||
const stripe2_pos = 110;
|
||||
const h = g.getHeight();
|
||||
const w = g.getWidth();
|
||||
const decompress = require("heatshrink").decompress;
|
||||
|
||||
/// /////////////////////////////////////////
|
||||
const katakana = {};
|
||||
const hiragana = {};
|
||||
|
||||
function benchStart() {
|
||||
return {
|
||||
now : +Date.now(),
|
||||
diff: function() {
|
||||
return (0+Date.now()) - this.now;
|
||||
}
|
||||
};
|
||||
}
|
||||
const startupTime = benchStart();
|
||||
function image(x,y,b) {
|
||||
return {
|
||||
bpp:1, width:x,height:y,
|
||||
buffer:require('heatshrink').decompress(atob(b))
|
||||
buffer: decompress(atob(b)),
|
||||
};
|
||||
}
|
||||
katakana['A'] = image(56, 51, "v//AAfwAon//AGF/wGT/gGM/A3F/BDEn/wJQoGCj4RB//gAxUB//AAwcDAwsH/+AAwcP/4tCAwMf/wGEn/8Awl/JYYGBKQkf/I9DAwJgBGwQGDGwRlBAwJsE+42DAwPzGwYGB+J7EQIIvDQIIFEAw5DEAwRDDgCIEAxCPBKIcAR4IhER4hnCLAg9BLAgoBAwgoBcQiCBMwj0BHogGBHogGBfoooEQQREFEIgGBAokAhAGFA=");
|
||||
katakana['I'] = image(54, 55, "AAkEAws+AokB/wGEg//Awk//gTE//gAwcPCYt/CYkDCYsfCYv//A0F4A0ECYg0BCYggBCYn/KwhBBGgl/EAgtBEAgMBEAZOBEAgMBEAYZB/+ABggTDBgQnDAoIaDJoIaDFgIABDQQFC74aBBgX8v4aBEwWBDQQgB/EHDQQ6BwEfGoX/+AJBDQMDWAKMBDQMPAQIaDiBFCPAgaDU4hrDDQiuDDX4acSAIaCA=");
|
||||
katakana['U'] = image(52, 55, "AAMP/gGE//ABlH/AAnvAon+Bk5EDv/vIgcHBkHPBgZwBBgn/Bi8B/+PBgcf/AMFw/wBgYEDgED/6qEv4MEKYK3F8AFDj7EED4LREv/4CQn/wASEFginBDAgfEDAIfDn67BC4YABH4QXBCQcHZoQkEEoYMCHAYlBFYZEBLwk/MgpQEAAw");
|
||||
katakana['E'] = image(58, 45, "h//AAfwgYGE/0AAwn/wE/AwngDgv4DjhDCv/wJQkf/gGEg//AwkB//AA4gc/Dn4cjbAv/34GF94GF/YGF/wcjwA=");
|
||||
katakana['O'] = image(57, 54, "AAcf+AGEh/8AwkH/wGEgf/AwkB/+AA4n/4AGEv/gAwk/GIsf/A4P/4AE+F/Awn4n4GE/kfAwn+h4cFg4GFwYGF4IGFKwYFBMQpxFAwJxEAwJxEAwJxEAwJxEK4JxEAwKqEMoQGE/o4En/8HAl//iqEAwKqEv/+VQgNBVQgNBcYgNBcYhLBcYhSCHAQKBAwI4CAwY4CD4IGBHASxBAYI4CAwY4CYwIGBHAQGBD4I4CBIJfCHASmDHAV/PYQ4Cj5QCHAUPLwQ4CgQGCOIgABOIgABHAIGEAAY=");
|
||||
katakana['KA'] = image(54, 54, "AAMP/AGEv/gAocB/+AAwcH/wTEj4arg//AAf+j4GE/F/AwnhAon/w4aZHAMP/hTEn/wKYn/4BTDgf/KYgQCDQYQCBIQQDBIQQCBIc/DQouCDQQuCEghJBEhITBH4RTBLoRTEBIJTGCAUPNwoTCDQQWBDoIuCj4TCJIX/CYQ/BZQInBH4U//0HwBTBGgPwXAXwh4PBXAXAv4PCZIIgBEYTJBn5SBDQXABAIzBCYJcCDQXwgbOCAwIDBQgI4CgEOJwIADkAGFA");
|
||||
katakana['KI'] = image(58, 55, "AAU+Awv/4AGEn/wAwkP/gGEgf/Dkk/CAc//4ABwAGBj4GC8ATBAAf4h4GE/woBAAmAAwvgFAYcIwAcD/BFDFARFD/kBIoYACv5FBAAcfRL94DgkfHgf/95EBD4RgDD4MHLwf8AogAd+CPFGwiJCS4XHJgSGB8CJEkCJJUwYABg5pDD4amTNwKmXYbgcDLoY=");
|
||||
katakana['KU'] = image(55, 55, "AAMHwAGEh/8Awkf/AGEv/wAwn/4AFDgf/EQkH/whF/4ACAwM/AoQQCBgY5BgIGDHIMHAwY5Bh4GD8AhEIAQFDIAIhBBIJACEIJpEj45CNIV/NgRpBDQIrBEoPgDQJlBEoQaDEoV/RwUP/wPBQ4Uf/gPBQ4QsBKAKSD8BvCSQXDDQYYBNYIaCGYIqBDQU//kPXoYYBj5QCEIPgj60DKoMcWga7FKoYABKogaDbojPBbojMDGob/ECYJBCbgYaDE4IaEPoIaDEAI1EbYQZECYgtBCZQGCLol/KwxxEAwJqEgIMFgIZEgA=");
|
||||
katakana['KE'] = image(60, 54, "AAMcAwsD/4HFn/wBxl/8AGEg/+BxkP/gOF//ABxcB/+AA4kf/BCGAAZOBv4HEIQIOGAwgOBh4OFGYIOFn4OFEgoOBAwvgh52BKgYDBOwJUDv5nBBwY6BAYM/BwIKBJgJjBBQSbCWoQVBRgK1D/4oDBwJJBWos/WIS1CgIVCJoRGBWowCCj61HYgpRCdIjEGLgTLEIwTLEfAv/GYqtBEghyBGYjoCAwwkDAwQVEYwYjEHQt/CopeBQgQOEIIgOBPgxeFgZ7FA");
|
||||
katakana['KO'] = image(49, 46, "v//AAYFF34FE74FE94FE+4FE/IFE/gFE/w0Dgf/AocB/+AAwf/4BHE8AFDn/wAocf/AFDh/8AocHGH4w6YZf7Aon9YYoFEejBhEAAIA=");
|
||||
katakana['SA'] = image(58, 53, "AAcD/wDBg4DC//AgEB/+AgE/+AKBv/ggEP/gGBj/4DgP/DnU//4A34CQ+DAIcEDAIcDDAQDDDAYDCDAYDD/4cDIgJADAAUfIAQACh4jCAAUHD4QACJwIfBAAQtBEYgGBI4QUDFQkP/4qEVYQvEAAIxCEIK5CBwV/AwsfAwocCAwYcCJogcBNIp3F");
|
||||
katakana['SI'] = image(56, 52, "gFwAwt+Awv/8AGF/gFDgP//4GGCocDAwIVDBoX/wAHCn4VFg4GB4AxEAwsfAworBEQYABv4GFj4DCjgrCBQYRFn/4JQfAIgIGD+F/JQcD/gGBMARQCOwcH/wNBCoUP/0PAwIrBj/8OwQGBn4fBGIIGCAQIlB+BcBAQKvDBIQRB8AfBIQUH4AXBP4RXBGgJmERoJsFAwv//yaFbYghBQIYaCeAi9FPQTZGdxKFCFASECFAZPBEIgNCJQaZEAwhDDAwRJDTAYGEQAiQBPIgAGA");
|
||||
katakana['SU'] = image(60, 51, "gH/AAYGBh4GD/AOG4AOF/gONDo+ABxAACgY7CAAd/+AGEg4OG//gAwkP/wGEgJCCAAcfKIQzEIQIzEIQozOj4zFEgIzFn4kHGYv/M4okIGYt/IQqXBFghuBHYs/bAY6DCwrJECod/HgYVB8ZLEcoMfLQYECCwYVB+BTBCwT7CCwYrBAYIKCCoQDC8BXBEIQSBNoQVBBYP4EAIoCOQPHCoYTB/xdBIwQ8B+6SET4N/dYn/4aCFFgKRFgC+EgPghivEAoI");
|
||||
katakana['SE'] = image(57, 53, "gEH/wGEgf/AwkB/+AA4n/4AGEv/gAwk/+AGEj/4AwkP/g4JjA4EBQQ4D/4DD4E/AwIuBv/vAoP/FwILCAAIuBv4GEBgn//wFEAwITEh//CgfwAwMfCIRGB/4BB/5xBAgJTBIQQGBwP/75CBAwOAD4JCBAwRmDDIKYBOIQGDOIQGDOIQbBAwSqBAwiqBAwiqBDYg4Cv4GCHAUfAwQ4Cg4GCHAUBbwbjnHAgADcYYADUYQxEEYq6CVwbDBdQi6CZQYqBAAZcCAwY1BEYi5DAAQ8CegfgA=");
|
||||
katakana['SO'] = image(52, 52, "gGAAol8AYUD/Ef4AGCn/3/wFCg/+v/wAwV/8//Bgk//AMD8f/FoQMBj/8Bgfg//gBgcPFoYMBFocP/kHFof/4AtDBgMDFoYMBFoYMBgIIBgADBwAtDj4dBHQQMCFoYqCHQQqCFoc/BIIPCCwQtDKYIpBB4IwDIAQwCh45CBIVAFgSmDFIaaDOIYfCVgYfBRYYfCTASTCUoY1BQgZPCD4l/D4kfH4g4BH4YYBH4gFBGQd//4yDBYIyDn4SEJQIlEBgRXEHAg+BFYZRGZYQADBYgAG");
|
||||
katakana['TA'] = image(55, 56, "AAMHwAGEh/8Awkf/AGEv/gAwn/4AFDgf/EQkH/4oF/4ACAwM/AoX+FAQGCHIMBCYY5BEIIAC+AhFIAIhDHIQFDF4IhBJQMHF4JDDNIUfHIRpCv5sCn/wDQJsCDwIaBEIIKBwEf/9gOAQaB/gbBFAIPB+YsC/AaB54RBFAIaBAIOAEoJvBOgPh/+DNAJWB+//DQPBQIZyBM4f4LQSQC8EPKAIpBFAMPPgKKCgEcYIZwBiAGDbohwEZ4bdEFILxFf4ghBXwLjEDQhLBCYoaEE4IaDdIQaDBgLBCDIRQENYYTIewRkEAwJCFHYicBOIkAEAhDBS4IAJ");
|
||||
katakana['TI'] = image(57, 54, "AAkGAwsfwAGE//gAocP//wBgn//gEBgIFBAAIeBAof/wAYBAwkHAof+gEDAwf4E4YAB4AGBv4TDAAM/AwoxDKQhABLQwiCAAV/MIglBMIglBHwRwDNARbF//3Awv7Awv9Awv+Awv/MQQAD34GF74GFKAUHOIYABSAJxGaYp4Uv54FP40/P4oGHQwQGKKgt/AwrUEMIQGEVYIGLg4bMFII+Fv5TGNAsPQgsHTIoAG");
|
||||
katakana['TU'] = image(54, 53, "AAMBwAGEj4FEgf8AYPwgFgn/4BIP/g+Av/ggEP/n/gP/4EAv/v/wQBFQP/z/4CAMAg/+DAMfEIICBDAN/FgN/8YYBBAIaBw4hDDQIVBAYMAn/wDAIhCCwIhDCwIBBwAIBHAIYBEIQYDBAIuBwAjBFQghCJgQhEAIIhDEYQPBh5HBM4IhDQQQhCwYeBCwMBCoSPB/0CIQQhBAQKWDvytBCYTBDv5tBZYYTCAAQTCAAYTFHAITEj4TF/4TEh4TFv4TEg//JgIMDMYIMEO4ImD/53BAAM/AwIsEEAgFBEAZNBIIgTCFocfJwo6BPgpHEgZAEgEOAogAGA==");
|
||||
katakana['TE'] = image(57, 51, "h//AAfwg4GE/kDAwn+gIGE/8AAwuAv4GE4E/Awngj4GFNWJNF/gGF/5UF/+/AwvfAwvvAwv3Awv7GJn8IQV/4BJEv59Fn/wAwkf/DJFEAYABg/+AwjJBAxbQBwAGFH4gGBH4gGIIwgGNG4IGEg//LYjyBAwiyBAxc/EQoGGFIJTLdYJvEgF+fIsYAwo=");
|
||||
katakana['TO'] = image(42, 54, "//AAgU/+AECh/8AgUD/4U/CgYPDn//wAUC/4VCCgIlDAgIKCCgIKCCgP//wUD//gCgQKCn/zBQQ+BDYP8CgMBEAQBBj4KBKYIKC54yBBQP7KYIKCG4QKB35YBBQIUCGQPjNAUD+BXDnB9Dgy8/CicAA=");
|
||||
katakana['MA'] = image(57, 50, "/4AE/l/A4s/AwvfAwoAN/YGF/oxGHokf/wGLh4GN/4GSg4GChgGDwARBAw3gAwv4Awo7BAwn/4ACBAwIKB+AGDgJtBAwcAUgOPAwYLB94GDgaFCAwTBDAwcfAwoyBAwgyBAwgyCAwgcBAwgyBNgL0ENgIADn6oHDijhFW4wcB4AGDKwPwBwl/fwzUJDgZOFgAGGngGFhADCA");
|
||||
katakana['MI'] = image(52, 53, "gPwAwkf/wFDgf///gAwU/AwIVCBgX//AME//8gEHAoQGCBgYGCv4GDFIMPBggoE4A2CCoIuCAweAAwc/BghYBMwswNw0PNwkBGAIbEG4gMCOoYMCOoQMDAwRnE4BYDKYQTEKYRuCKYY8GgCjDAAV+LAtgcTMDbYhTCHobICBwbBDBghZDZwmAZoYGCAogGBCYgiBEIidCBwQ2DS4QMCVYT2CSAb2DBoLpFn72EdJAA==");
|
||||
katakana['MU'] = image(59, 54, "AAMDwAHFv/AAwkf/gVF/4VG8AGEh4VHFgoVPFdZBdRogVBgP4CokBFogVBn/wTIkHEwYrCv4ODCoMP/wVDFIP/JYQVCBwgVBGYLICCoTIDCoQCBBwQhCn5RCCoR/DNoZCDDIRRDCoQODg4+CIQYvGCoZCCCoZRDAQV//4SBRAM//4ABwEfAgQAB/ARBAAkPAwvxAwv+Dgv/8YGF/gkD/xCB543DH4P5AoaBBewsAvgGFhgGFAAQ=");
|
||||
katakana['ME'] = image(55, 54, "AAcB8AGEgf/AwkP/wGEj/8Awk/+AGEv4iF//AFAuAAwcHFAsPFA34AYNwFAQvBgICCFAUHCAIoDDwQoDn4DBKIf/MYIoCDwIGB/5RBAwWDKIYGB456Dv//75RDAwP/JQQmBAwJ6Dj4GBOYYGCOYcP/5zEg//OYgGNDYw3BAwgvBAwaABAwgaBOARZC/wGDOoP8MQI1D+AGDFwPAAwJaBDAQNCJIc/AQJsBTYL3COQc/4ATBXoYdCSgU8J4SNCmCNCNQqoDAwQuBAwgFDFAITEAwK1DAAKZEAAIMFAA4=");
|
||||
katakana['MO'] = image(55, 49, "j//AAfAv4GFAon/wIGFgYFE/0HAwn8h4GE/AvF8A4Bv4DCAAQzBAocB/+AAwYxBCYkH/wGEh/8MIv4Awk/+AGEGyJfFAFP9AwpOBNuikeAwxfEHoLpFNoZACAwZABIgIACJYYABIAYGCIAYwCHIoABA=");
|
||||
katakana['NA'] = image(57, 55, "AAV/8AGEn/wAwkf/AGEh/8AwkH/wGEgf/AwkB/+AA4n/4A4rGoIAE/IGF/wGF/9/Awu/AwvfAwvvAwv3AwpQCOOqqEWLV/H4pGGn5GFAw0fJosfJooGGn4GGKgq6BLQoGEg4GFh4GFPoIpEDYIwFv5MFLQ4GFg6EFgaZFAAw");
|
||||
katakana['NI'] = image(56, 43, "h//AAf4A25+/AH4AuWggA5A=");
|
||||
katakana['NU'] = image(55, 51, "g//AAcAh4GFj4FD/0An4GD/kAv4GD/EADQnwgIGE8EDAwnAAwuAIIgvBAAcPF4IADn4vBAAd/8AGEFAIDBAQIsBFAMDCAIoDh4eBj4oCj4GBFAd/CIJRBgBZCAQIlD/+HQIIGD54oCNwZKDPQZPDOYRdDOYqmBOYi0BOYjCBBogGGYQSAEAwimDGATdDAwQTBH4JFBLIP8AwYTB+AqBAwITB4AGBE4bADBIJyBUIJ6CVgXgJAQzBg+BAoJkCgxcBCYRIEPArlEH4YGDO4ibBeQs+AokAsAGF");
|
||||
katakana['NE'] = image(61, 55, "AAX/4AGEg/+Bws/+AGEgP/wAHEh/8Cwt/8AGEgf/Bwsf/AMEAAYnBj4GDHwQOEDAMHA4hVBn4WFJIIADHwMPA4hgCAwZkFCQKCGBwpHBPQwOFFAJyGBwt/BwozBBwpwDGYiYEEgP+iAkF4IPDCoP8j7WCUAXhbwYVB/4RBU4n4QISfD54vBS4f+FASPD+AEB+AFB/IjBFIPnA4LzCGAfAeYIjBGAP4eYQCBwZuBeYUH/EfIwJRCAoIDBg6ACnCmDR4oqBDIKfEHgKuFS4g5CBwo8CWwqOCAAQ8DcYg8Vn48FAAo=");
|
||||
katakana['NO'] = image(47, 52, "AAcHAokP/gFDj/4Aod/+AFD//gAgUB//AAoUD/4oE/woJn4oLEQYoBwAoIh4oEj4oFJZ8HERU/EQhFEDgIiDH4JFDh4iEH4t/NAYcFHII/Dj4cEv4/DCwIcDCwIcDCwI5DCwhEBHIYQBKwf/GYYhBCwc/FoYKBFoYEBFoQKCE4RrBE4YFCHwQyBHAYnBJ4YFBcBN/AgcAPgYABA=");
|
||||
katakana['HA'] = image(62, 52, "AAP/wEH/gGCgf/gE/+AHCh4MB//AA4QMBCIQeD4ARCDwv4Dwt/8AeEgI4BDwkH/weFj4eEAgIeF8AeEAgQeEAgQeEAgQeEAgQeGMggeCMggeCQYiACQYYbCDwgbCIogbCIoZZDIoYTCMggTCEwn/CYJFDBYZFDBYYmDv4LBEwYDDg4aCh5JCDQYiDaIQWBNAQ5CMAYLDcgYmCCwgqCGIYTBFwL7EJIIWEAgPgh4WDNAPACwgMBCwiHB/wWEFwV/CwZVB/YWEDgPHXgYuBDwLbDKQPwh60CGwWAngGDgAFBkAHEsAFEAAQA==");
|
||||
katakana['HI'] = image(47, 51, "//AAgUB/+AAoUD/4QDg/+AocP/gFDj/4Aoc/+AFDv/gFw8BwIuDj+DFwf/FwcP/4uD///FwQKB/wuBJwIFBFwM/AoP8//PAgP/+IDCAAJdBAAXwg4FDEoQKCIIIgCLoQFBKYV//5qDB4aMuF1YFDFwIRDUIQAC+YFE8YFE44FEw4FEUgn+Aon8WwhKBXggA=");
|
||||
katakana['HU'] = image(49, 50, "/4AEv4FE34FE74FE94FE+4FE/YFE/oFE/w0Dg//AocD/+AAoUB//AI4ngAod/+AFDn4FEj/4Aon8AocPAokHHgg2BHhYFDHgJCLJBZCEAopIFAoxIEAoxOEApc/AojSBbwplEAoZxBAocPAojICBQhBCGYIFDBYRZCa4P/NYQuCPoYFBSoZGFZYsPAgYABA=");
|
||||
katakana['HE'] = image(61, 43, "AAMH8AHF/4HFh//wAOF/wOG/AHEv4eFg//DwoOBDwgOCDwk//YeEgf/x4eEn/8n4eDgP/4AeEj/8DAIeCBwPgLgkfDYIeECYQeDh4LBIwIeC//wDIIeCBYJdCDwV/BwIwBDwIOBCQYeBn4pCDwRIBIAQeCMIJPD/AOB4CED4BhBMwf/MISbD/kHPovwj4ODDwV/UYhYBKQJ2DRoIGDHQINEcARCCWYgGEDwIOFgb+FDwL2EDwQGFIQoeCBw0YA40AA==");
|
||||
katakana['HO'] = image(61, 54, "AAV/8AGEgf/Bwsf/AHF//AAwkH/wOFn/wAwkB/+AA4kP/g8Rg//AAngv4HFCYIAE/EfA4vAAwv+Eo3wn4HFwAGFJwZ5UgfAPIJzDn/x/+PEgR/BAoJzDP4N/8JzD//D/6KDFYI8BCwYrCCAItBPQOH/wWDCgIQBCwf/4P/wIWCCQIBDWgYBCZ4KJBE4LPDEYInBh5sBBgKLBNgQ0CJoIWB4ACCBgIiBBwP8EYU/TQLXBHQQECFAI8BCwIqB8DzCDYMPAgQbCMoI3BF4IRB44OBWwQUBv4TBJIV//InBHgQCBw4OBHgUH/EfNgKOCj0A3BsCQwNgeaSdCABA=");
|
||||
katakana['N'] = image(54, 50, "ggGFngFEgP+AwkPAws/AwkB/4GEh4GFn4Gaj///gNF/AGF4BEJAwITBgOAAwQTBh4GCnwJCCgVwLgRwMHAgTBHAgTGv4TEgYTFMIITEMAsHMBY0B+ClFCYiPFEAITEv//OIQMCTg3gBgggEDIIgDGYIgDMIJVDDAIABIIILCFoYYCJwZ0BHQgsBBgZnBBggnCKgYhBMIi3FgAFFgAA==");
|
||||
katakana['WA'] = image(51, 50, "/4Ay4A3E/AFCh4GBAoUBAoPgAwU///8AoUHBgOAD4nwAoUf//+AoUDGRYSBGQYSCGQd/94yDh/9GQZFB34yDn/zGQcPAgYSCG4YSBC4YSNv4SKJYJwDLwISEn5QDS4QSDDAJjDDAJ2DGIJ2DUYQ+DQYKcFFYYXBDASOCGIQFDGIQRCDwTaCG4YFBEgbHHN4hiFg6HEA=");
|
||||
katakana['WO'] = image(50, 52, "/4AE34FE94FE/YFE/wYYGocB/+AAwd/8AFDn/4AocP/gFDgf/KovADAnwDB43B45EE+IFE/F/KAkfBgmHAonhAonwDAn8h4MEN5X/N4l/N4k/KwkfRwgoBDwcHOohoBOoYFBEgY2BEgYFBEgYFBJIYXBFQYpBFQZ3CAoIWCKoQQCGwQLDHgR8CAoQdCAoQvCOYYFFn5gENgKREbYgAGA");
|
||||
katakana['RA'] = image(51, 50, "n//AAcHAongAon8j4GEwYFE+F/Aof+h4ME4IFE/BYr+4FE/wFE//fAon7BgpYE//vAon9CQo3Ev/gAocP/gFDgP/wASX+ASJgYSFXwJ2ECQivBDAoSEWIs//wFDbYIrDAoI+DAoIYDQ4IYCFIIABDALlDGIJhBewS/EJQQYCG4YkED4QFDD4JJF4AFDA");
|
||||
katakana['RI'] = image(43, 53, "AAf/7/4AgMf/f/AgMD/9/8AFBv/v/gEBh/9/+AgEB/+/+AKBn/3/wEBg/+//AFX4q3v4qDh/8FQQPBz4PDAYQvBEYQvCEYI/CGYRPBB4cfIYQpBB4cH/5TCDwJjD/4kCn4EBCgN/AgIUBDoP/FIJHBAAIyCDIYjBIYYaBQ4QaBJoZHDAAoA=");
|
||||
katakana['RU'] = image(61, 53, "AAUH/wHFn/wAgUB/+B/+AA4UP/gBBCgd/8ABBAwUD/4BBBwcf/ABBA4f/4ABBHQg8FHQI8/HksYHgwYBHgkPF4I8EvwlCHwOAg4gBEYI8CCIQjBHgITBCIP+HgU/CwIRBDAIgB4AMCAgMfEAIMBDAIOCBgQYCIwQMCPYJTBAQI8BBwUHEoN/8P/IYN/+AvBj4LBBwOAj/7BwZGB/4ABBwXAAQIODM4QOFHgIOC/4OBh4OCAYJGBv4OCn4OBHgJKBAYJkBIQISBaIYhCCwIOBSoTqBJQISBeYUHd4U+bYUwcAYAKA");
|
||||
katakana['RE'] = image(51, 51, "//AAocf/AFDgf/CQl/8AFDh/8AocB/+AAwc/+AFDg/+GX4ECgwyEgPgGQk+GQkP+IyDC4IyE//3GQc//gyDh//GQYYB8YyD//4GQc//wyDDAOBGQUH//gGQRvB/BlD/4DBGQU/CwIyCj4YBMoQkBBIIyBBAIYBGQIkBDAIDBGgIiD+AFBGoIyBv4eCGQIABJwQvBAAJnDEgTLCEgY8CIYLLDEgZVCAoZuBb4iaBfAj+EgE4AokAA");
|
||||
katakana['RO'] = image(50, 47, "/4AEn4FE94FE/YFE/wYF34YS4A1BgIYB+A8Cv/v/gFCj4YBAoUHDH4Y/DEbglDBQ8CAAYA==");
|
||||
katakana['YU'] = image(59, 46, "gP/AAX+A4M/A4fggEHAwf8BwIGD/4GBj4VFgYVGv4HDwEAh4GD+A+Eg46CAAf/4AGEj/4Coo6CCqJFBCot/KAIADh5QCQAhQBCrM/Myk/M3JQGh5QFMyIRBAH6NB");
|
||||
katakana['YO'] = image(50, 49, "v//AAefAonnAon5Aon+DDA1DgP/wA8E8AFDj/4AocHDFZjfDCJjxDD5WE/+/AonvAon7PgoYX/g3DAAQ");
|
||||
hiragana['A'] = image(52, 50, "gEB/wGEn/AAocD/gMcg//AAfgv4FD/wMYFIRNa54HDgYyCBgYsEBgX/+AGBHQYpBCQQaCh4JBJQPwgIdBBAP/wASB4H/j/8MIP8j5fBBIP/4P8gf+j/7/hVBj/jA4PH/C/Bn4RBv8Aj/3/Ef55FB/9/wI+D+/wj40BHwIWBL4QJB+BFBwAmB/4MBD4M/94MBD4JAB/4cBNYN/BgM//AsB/n/z4bBQgOHX4QVB/B3B/CQCAQTSC8BFCB4Q4CB4UAgIIBRQOAXojREn/gaIgAC");
|
||||
hiragana['I'] = image(58, 50, "v/gAgUggEf/AGCnkAg/+AwU/gEB/+AAwQZBDgcP/gcECQIcFCQIJCCol/4AGBgYLBj/wCokHCAIABFAIQCCon/DgQECn4cDCoItCAAI+BDggVCLoZeB+BgCCocPPQZUBwZdDJAQcEGAIcEGAIcEGQPDDghIBDggyBDggyBx4cBjxIC8aaCCAIyBLAMDM4IyBSARnC//HUIk/+IyBCASdBLAJKCGQOf/kDJQV/GQRKCJ4XgEYRPC/CoCDgOHNwl/8P/84jCDgM//5HCDgMHAwIjBgP8DwIsBQgYVBSQgVBaYZnCTIgtBbQhDCUAYkCfwYOCGIgAHA");
|
||||
hiragana['U'] = image(46, 50, "h//Aoc////8AFBAgIABgEDAofACwIAB/wWD//4CwgdBCIeAFQUfCwIADCwIAMj//+AEBv4tDAgQLBHAYFBAgf/8YFE54FECwRTB/wkCAoP7IAd/OgR2CKwcBQ4kH/hMEJYQcC4AWIh4WEn4tJg6EEj6EEVgIQDE4l/CAbABCAZqBBQgQDBQIQCXwIyCYYTIFeIhlCBQjxCLIQWBMgbdFvzYJ");
|
||||
hiragana['E'] = image(55, 50, "gF//4GE/4AB+AFBgIGC/+AgEDAwYNBg4FC/wGBh4GC/gGF/ArFFIQAD4BRVn42FLAIGEJQYGBLAhEBLAhEBLAf/8ArDBIIyEj5fCRYZYEEgJYEN4JNFDQouFDQKcBFwYGFMIIGDLQRJFAwgaBOYQuC8Y2DFwODAwcP/0HXAc//EPcQnAj5LCPAU/MwR4Cv5ECPAQ9CLoUBd4auE/guBVwf5PARaC+5qCAwXnJwSXB//HI4QGCw5ACAwUHNIn+gj/HAAg");
|
||||
hiragana['O'] = image(54, 50, "gEB/0AggGCg/4gE8AwUf8EA/gGCv+AB4QaDv/wDQn/CwIaCgP/4AaDgf/wAaCgPn/4PBAAXv/0HAwef/kfAoX+n/4v4GCAgPxCYfg/4jBAAWBGwQ1BgEDJoJQCJoJRBLYcPCAJrCgEcKAaGEHgSGDF4QPCJYYxCHoYMBn5YDBgoGBDIP8FQKiBDwabBFoIzCv/gEAJQCMwWfKAIbBh58BDQMH/l/4IaCh/xTgIaCn/P/BrD/8/4CGD/i3BDQfz/gaDv/P+AaCCAIaEHQQaDv/hGoV4h//g4VB8JnBa4ePZYRkBBwKNCbwPwCYR/C44CB4BtBfgSaD8ACBYQQWBAAYA==");
|
||||
hiragana['KA'] = image(55, 49, "gEH/AGEh/wAwkf8AGEn/AAwl/wEAhgGC/4CBngCBgP+AQP8AwMDAYIyDAYUPAwQ2CAwY2Cj/4gP/AAP4j/wgYGC/gGBg4GC/0/8EPAwsfCgd/4E/Awt/FIf/LgJmBE4IGCMwMf8JjBHwIPB4IDBgZmBv+DAYMHMwP/BQRfBOwIKCL4J2BOIQvBAgJxCGQIEBHAKPCCwIYDCwQBBQoRGBviIDIQJRC4AdCXAYdCKIcHboQ/CboY4BboghBboZKCFAYhBjAoDh/8nzME+CfBF4V/RgP/EgKVBwYGBFAMH/zIBFAQeBAwIoDboRRD4DrBJQUHAQJsDAAwA=");
|
||||
hiragana['KI'] = image(48, 50, "AAMB+AFDh4FL/AFDg4FIn//AAX4ArpHC/xNEAov/LQgFCDgYAlF4UfPx8/g/8CoQbBKgQhCAoMDFAkHAoeAh4FEDgQAB4E/FgIUBwE/HwQdBn/gAoM+AoPAAoMMAohFCAqIpCgI7C4BEBI4oICAoZfE4C9BAob2EAoISCaQgACA=");
|
||||
hiragana['KU'] = image(33, 45, "AAsB4ADC+ADC/wDBgf/wADMg//CYIDDh4DDD4UfAY/8AY34AZRDCh4DCg4DCgYbCgI/CgH/BgU/BgREBBgIQB8AMCFIRNDLoJ2Cv42DJwQdDFQIdDFQQdDFQIdDHYRkDgYhCgADDnwDChyzE");
|
||||
hiragana['KE'] = image(50, 49, "AAUB/0Ag/gAwN/wAICgEfBIIIBB4P4BAYPCh/wDAcD/gYE/4FBDAU/4AYEGIgOCDAQOBh//AAP+v+DAoX/7/AAof3+E/AoX9/gYD/9/gYFD/4YE/5QCGIJQDHYRvCJQU/N4JKCKAYYCKAQYWmAYEjwYEx6lDh/zUocDMgIYDv6cBKgUf/4yBBAMH/4eC4EBNQUfAQN/DYMPE4TjCAQQkCYgSJBDYLEBn7QCAQIbCE4UDDYP/PIV/CgLpD4EPP4UH+AkBAoIACCgIADh6LCAAMDAoYA==");
|
||||
hiragana['KO'] = image(52, 50, "h//AAX+gAFD//gBgn/BgvwBiWAAon4GwUBDIQACCQQFCn//4AFCg4lBCQc/DwYfBKQJdEDwYAB8CIihAFEgJJDIgQFEg5KEMgITEj/8D4hwED4JqEOIIfEv5eEg4fEFg0PHIwsEBigmFCYkOv65CJYPnbgn+ZgIAD8IMFewvgCYjRBE4IMDegQABIoUfAoK7HA==");
|
||||
hiragana['SA'] = image(51, 50, "AAMB/gFE/+AAwcf+AFDgf+DIl/4AFDg4fEgAfLgIfCj//AFQzCn/gLJYMELI5mEh6GGBgUHGAP4CAQ3COYILCBgUDIgYZBAoYmBn5REDwPgQQPgDAIVBj4fBJ4d+CQI1CgeAXhgSDKoYSEQQp1GQQpFBawXwD4IGBg42BaQngBgRlDBgmABgjzBRYZDCPIYvCv//MQoACA==");
|
||||
hiragana['SI'] = image(45, 50, "v/AAgUD/wKDj/wAof/wAECg/8BQc/8AbD/4bE/AbEFgcHFgk/FgcBFgkPDYhIgFgIKDFh8eFgn+FgcH/4sDv+/FgUD/osDn/vFgQ2BFgcf+YsD/+fFgUP/gsDv/HFgSKBLId/8IsCHgIXBSod/EIIKBwIhCv/4h4WBAQOAv/+IIP8AQIAC4AYBAAIkBn4KDJQIKDCwYpBCwRWCAoJhDAoK1DAAg=");
|
||||
hiragana['SU'] = image(52, 50, "AAUf8AFDgP+BjH/AYP/AAnvAon+BjJAUgf9BgZFB/4MDn4kEg4MFGIwMED4QME+E/+AyC/x0DFgPABwIMC/gMGDIn8gYMFv/4EwcP/+AKYf/BgRACBgYRB/4mCgF/AwJ6DBgoTCRohNDTZE/VAkP/gFDE4PAUQhGCI4YeEUIgYBD4gMBEpI4GgIFEAAo");
|
||||
hiragana['SE'] = image(56, 50, "AAcP/ADB//AAwP8AwkHA34FBAAn+A1JalmAGFvinFv4GF//PXghEBAwfBAwoNGEQP/+AGDn4GFh//8AGDg5PCgF/AYP/wAGEgj/CAwQADAw4mCAwZCCAAQ8BFQgGBAAQGBj4GFJQIGEJQIGEgYGFGIIGCIQQVDHQgACA");
|
||||
hiragana['SO'] = image(53, 50, "gP/AAXggEPAweAgF/AoX+gEDBgfwgEfCYoFD/EAg4MFAAQMCAAQwBBhQpBJQozBAAU/IAIACIYJUBAAV//gsJD4IsEn4sEOAn+NIn/+4FEAA39AwvvAwqQDAAP7UYhmCx5bDuBVB4BCDg5bEJ4JoEgJ1EEQKCESwIFEg5vEEA4TFh4TFv4TGYgiLBCYrFG/5dDd4YHCOQKkBDQjbDDQQwDWgR5DAwSGEEAgAEA==");
|
||||
hiragana['TA'] = image(52, 50, "gEP+AGE/4Mjgf/AAXAgE/AoX8BjUAgP+GYkf8AFDBhHnEIQMBEQQhBn/jFAWAgYMD/AMH/gMF4f/F4UH/kQGYd/KIIACg4VBBgmAQ4gMFUJcB/8DDQZgBv6iD/wuEn/gKIJGDEIl/4KCDC4KPE/+BBgYXBBgY5BAIImCj4MBTIKFB/wMBAAKSB8EPAwXnUYIMDCwLYD95RBEAIZCFQN/AwPBKISpBwEGQAgAGA==");
|
||||
hiragana['TI'] = image(51, 49, "gED/wGEv/AAocP/AFDgP/CQk/8AFDg/8Bgn/wAFDj/wBQYAqJ4M/LBZrMJYZ+Ch5aDv/f/4bCBQIABCoMDHAYTBv4+Ej4MEg4DB4IMCAoIcCwE/TwU/+ASBEQI8BVQJLCv/gS4cP/kBMgYWBjyoEgLbJEYYSCQQkHCQg2EHASCEv4SBgYOBOQ70BQoYrBEQIABFYR/DJASRED4YFCBgJDDA=");
|
||||
hiragana['TU'] = image(59, 45, "AAUP/4FFAAIGCAoX//EAg4GD//ACYYAB/kBAwgOBn4OFDgoOBAYX+BYP8j4GBwEAAgPDGwQ+C/F/BgIABCwOMLQl/+AGEg/+NIv/8BwF/gGEKwIqDAAM/HAYzDEhkfEgsDEgxJGh5JFHQPACqQrBCpkfCopXBCogcBCog5BK4jSCAwxtDDYK8EZIQcCAoQcDCYTjCJgQGCEYT0DIAYGGEgQGDEgRcEv5UEA=");
|
||||
hiragana['TE'] = image(57, 50, "/4AFv4GF34GF74GF94GF+4GF/YGF/oGF/w7Cn//4BCDAwOAAwpQEj4ZDAxP8AyUPAwwiFg4GMgZFFAw0BLQqlBNAkAv4GG8AGEn/wKgv4KhZGGHALeGH4oxNh4xFOJBjGEYt/VQwVFg//BwhOBAAI7Dv4GBHYYcBCwgcB/5CEDgQyFGYgrCUwkPKAwAC");
|
||||
hiragana['TO'] = image(46, 49, "gEH/AFDj/wAod/4AECgP/Cwn8C0cICwcDBoIWC/4NBCwMfEgV/4f/BoIWBv//LAMH/4AB8AWBAoWAgE/BQYlBDYUAh4FBHwQPEEIJQDFYJhCgYwCLQQqCDYQKDDYIKDn5xEEAYQB/x8JDYkDCAkPYIk/JoQWTAol/AocZQwR6B8aNCAAOPAgf+TIZqBAongT4QfCBYY9BW4R1BA=");
|
||||
hiragana['NA'] = image(55, 50, "AAd/wEAn4CBgH/BIXAgEB/wJEgf8AQIJCg/4AQIJBgEP+ACBBIMAj/gAQYsBEoIoCGwf/GwkB/8P/4AC4f+j4GDw/4n4GDj/wv4FC/0/8AMD/l/4IGD/H/wYGD+P/g4vELARtCMQRtDMQQKDL4YKCMQQKDMQQKDR4QKCTIYKCFYQ2bOoI2C4BgCGwWASAQ2BGQKJC8DNBBAIAB+DNBPYf4ZoKrDAgPwT4K7BAwRdBB4K3BVYIqCVYY6BAwKrB/0DVY3+v/hAwf8n4SBdIXwnxEBAwXgnBEBAwShBO4IbBSYSVCOYQAHA");
|
||||
hiragana['NI'] = image(57, 50, "AAMPwAGE//gAocf//wgFwgEH////kH/AZBAwP+gf+Bof/wP/gEDAwWAAIMBAwc/FgIGDj4sBv4GBE4P8HAIdBE4IqBAwYgBKAIGCKAYKBAwN/EYIGDn4jBAwZfBDAQfBLIPAAwZZBDgItENYN/CAIfBIAIGCLIRfDLIXwAwc/RQJmCHAPv/0PEoI4B+f/AwcH/P/w50D/l/wZ0CgP+j/BK4Q4Bg/gJoQ4BwIGBIwU/4EwAQI4CIYICCAYY/EJQMHHATcCbAQKEHARGBGgQqBCIc/D4IGDaITCDT4PAAQJfCQQRYDeQQGDSIIGEYYIGEE4IGEDgYFCcAQ+CGQZsCABAA=");
|
||||
hiragana['NU'] = image(58, 50, "gEP/AGEgf//wHE/4ABAwc/AwIPDh4OC8AGBg4GCEwUBAwX8Dod/EgoHC4AsF+BJFjAGDg4iEFgRfF/+AAwk/IwQjDFIgjDvAjDMYJlCgRHB4ABBFIUf/ABBFIXH/0HCoUf+BcBLwQpBCogpBCYIVDv+ACohNBn/wCoRxBCohNCMoIVBOIQVBAIJNCCAIVCEYIQBCoOAb4QtDCAQtC/gjCdIIXCN4QwBC4SVBDQIXBEYUP/gXBI4QEBHwPD/8ODgR/CwZNCCYN/8P/5/4GQOf+DtBKgXv/jtBKgX5/0PAwJxB/0/DAL8CvkDJYP/IYMMgFgg//fot/VYQACgYGFAAoA==");
|
||||
hiragana['NE'] = image(67, 45, "AAXwA43/4AHFn/8A4sPCA0B//+CAt///gA4kfCA0H/4QGA4IyFn4IBGQg5BIYsD//nCAt//F/CAkf/wzBCAYFBwH//BaE8ArBwBzFCAgNBLoQQCHIPADYIQD/6dBCAk/OQIQEHIQQEHIQkCCARaBO4YUCSYQQDHIQQFHIQQERQgQCLQQQEHIKBDCAPAn5fDCAP8gbNECAaJDCAbVECAPgvj+Gg72GdoqYFCAgHFKIoQDDA0AKIjODDA0ARYQAEhwHGAAIA==");
|
||||
hiragana['NO'] = image(54, 50, "h4GFn+AAocB/0IAwcH/F//4AB+Ef8IFC//A/+PAwcD/0fAoX8h/wDQk/4ITDAgMDAwcH/hGC/EAj/wIwXggF/4AGB/+AJIIFBGQJJCDQoWBDQf/wZlBDQIWBh41Dx5kE/0/Mgn4IgIGD8f8MgYaBL4IaEPQJrD/6RCGoRkCKAR/BKAgaBKAoaFNYoWCKIIaC8BKCDQWAIYQaCgJCCDQRyDDQRXDEoOBK4ahBW4K+CAgKcBDgLcBMwIwC/1/4JHBCYP5CoQwC4aND/atBRofDAgPgdQaSBHgX4hxXBHQXAhAOBAwKXCAAJlBbIIAH");
|
||||
hiragana['HA'] = image(50, 50, "AAMH/gFDgP/Bgl/4AFDj/wDBsH/4AD/oFE/9/AwoARJVXhAon4JQn+j4MEw4YLn4YEJTIfCAooYCAoX4DgQwCwBdEBgMDHoYMB//3Bgd/8AUC4A7BJQP//kHBwQGB4JYBFoX8KgMP/gGBz/+h//AIPjGAXA//wAoXwh/4DgX4gP8IgQnCF4QFBgOAEIKIEv6SCAA4A==");
|
||||
hiragana['HI'] = image(59, 50, "gP/AAOAA4U/AwPwAwUHAwP+CwYVC4AGCj4GB/AGCgYOCCod/AwPgGokH/g8GHQY8CHQYVCHQg8CwEfCAYEBgYQDAgV/JYYEBh5LDj/4GoJKEGoJLCAwP4JYZ9C/BLCNwSGDQgSGDOoaGDAwg6BEYQHDh//EomDAIP+ToaQBEIIvCKoJyCJgPH/yDCEIIVB4BNBMwIgB+CZCn/n4f+h5jBAQMw/+BOgKyCCoN/PIICBS4I0BCoQJBJQJqCBIP5NQfgD4KACn5tDGQSDEwADBTIJaBGQKZEDISvCToR8BeAQDBAQLbCb4RSCAAcHcQYACvwGFg45BAAj/DAAw=");
|
||||
hiragana['HU'] = image(55, 50, "gED/gGEg/4AwkP+EAhwGCj/ggF+AwU/4EB/wGCv+Ag4GD/4kBAwM//4AB84GBv4GC54GBAoX/x/+gIGDh/+gYFC/0P/kHAwX8AwMPAwX4j5cCGwJOBAwJIDj5jBv4QCAwIpBNoU/+AiBNoIGCJYJtBAwPhFwPANQXjAwOAgEEv+P/A2C/H+CoI2BTIIhBwY2Bh/xwH+UgUf+CwBUgSgBBYKkCn/gh/gToI1B4Ef4AvCBIM/4ZmCIAN/44oBSgKdCFAJ3CLAY0BUgQoBGgIGBEIUPAwSID+AGBQIZHBJQRECd4Q9DI4QvBJwQ2Cj4sBGATRBJwLcDFgTcDC4QGEEILqEAwIbDIARoCBgQAGA=");
|
||||
hiragana['HE'] = image(55, 50, "AAUf+AGEn/gAwl/4AECBQP/wAYC4EB/4YDwED/wYDwEH/gGCCIMP/AFBgIRBGwcDCIN/GwUH/EP/4bCDAP/AAI2C+4GCHwMfAoX/JgM/AwYjBv4GI8YGCFoN/wIGBgYCBFwIiBHYJfBNAPAn/8IwIGBwAaBh/wAwOD//4R4IfBg//+B2BDoJKB+AoBg/+JQPjOwMP/n/z/nQIMf/IOB76BBn/3/gVBMgN/94nBOQX/7/gAwKbBOwSOCHoJMCEIMH/v/CAJxBh/7/hcCF4X4KYLEC5/wj5KBEIOfGwJRCL4PzF4V/JIQvBCYJJCH4JxB4AGB/xCCFQIJDDoIMBBIRNBAQJdCIwKUCeAb5CPgQACSgIFDSgIFEAAg=");
|
||||
hiragana['HO'] = image(51, 50, "AAN+AokP+AFDgf+Bgl/4ASE/ASVv//AAX8h4FD/+BAonwn4FD/0HBgnAAogoBgP/HAk/8AFDg5LEgASM/gSFwADBFQIAC8E4Iof+/5FE5/wAof5/0fAwc/8YFD8f8PAYEB54MDJ4SRDJ4KRDj/gNYaoCLAYWBLAYWCLAQWCDYJvDgYSCCwV/NYQWBGQc/+AyDg4yBj4MBgYSBAQP4OwPwbIglBQAgpBBgZiBBgYYBBgY1CU4S0DFoIRCAAo=");
|
||||
hiragana['MA'] = image(55, 49, "gEP+AGEj/gAwk/4EAkAGCv+AgAPD/8AgYdCgP+EgkD/gdB/AGBg4DBv4GCj/w/wGCv////8AwQFB//4AwMBAwXwEQMDAwXgAwMHAwXAAwMPAwWAG4QvBLgQGBL4X/AwRfBKgIGCL4X8n/gLARUBn5YDMwM8NQaLBQYIoCAQSIDAQRZBRYaBDRYQhBFAIJCKIYyCDwKoBToZkBOAIJBPYKLCGwMH/h2CAwMfKoKKCI4PgSIYYB4afDJQMP/gpB+AhBMgIjB/AhC4EfAwIhCEoIGCwJdBaIIZBMgSkCjhMBgakBG4LICUgKDBAwQuBPgRKCjgGE4EQAwgEBAAIbBRAQACQgIDB");
|
||||
hiragana['MI'] = image(50, 50, "h+AAocD/gFDgP/CQl/4AFDn/gv//AAOP/E/AoXj/0HAoX4/+BAoX+DAuf+EfAoXn/gYD/P/gYEBG48f+AFDg5QMMYkf8BvE/BvE/wYE/4YEKAIYYgZSCDAMBJgQYCCgYDBFoYDBj4tCDAJlDDAMBGYYYBNYYYBn4xCg/4h6ECPgIHBPgfBDwaVBQgYvBToYYCFYauBaIIwB5/wcAfz/0PAoX8cAn/IgQFC55dBAoXxFILtC/grBGgL5BYIoAGA==");
|
||||
hiragana['MU'] = image(58, 50, "AAV/4AGEj/wAwkH/gGEgP/Aod+Dgv/wAcEj/gDgkH/AcEgP+Dgt/Dg3wn4mBHwYGBDAIyCAwP/8AGBAoQODh4GC/4sBgYGD/AcCAAO/IQQcC4IkCDgI7Bj5YBg//w/8EAIjCwIEBv/gMQPgLAMPFYP//h1BgZpC/4LCNwIxB4YoBFoIxB/AjBNIMH/v+n5UB/4qBn/fIoIJBv+PLYUPQwPhOIUD/gvBGYMH/3/BAX/457CBAP/84GBDgIlB/YGBCYJwB/qECDgKREwBCC34YBDgfvLYP+HIM/+YYCIwM/MoIYB/hGBMoQEBz4nBKQfDAwODGQXwKQQMB/P4j4GBAQP+ngtBUgIRBg6aBRwKiBwOAf4TNBAobjCAogAEA");
|
||||
hiragana['ME'] = image(57, 50, "gEP+AGEg/4AwkD/gGEgP+Dgv/Awt/wAGEn/Agf/BIUf8EP/40CHAMf/4tBAYP4AQImBCIP8n4GB4EH//+AwXgEwP/v4CB/EBAYIPBg4jBAwX8BYJFBCQRKDFYIGBJQJxBIgUfAQIrBAYMPCAIfBBQR8CAwR8DMAZ8Cv4GCGIQGDGIU/AwR8BAwKqCWoU/FoS1Cj4tCHASEBWogGBUAQKBAwItBHARpB8BlBBQKuCAQIKBO4SqCBQX8AwX4h/9/wGC/kP/n/DYSlCv+P/ArB4K+B4/4SIV+j/jWIX8n0P+JSBDoMOMwJWBAwOCMwM//ZOCMwI4C75nB/5bC45nBv+DAwPhTgXAb4PAoCfCQQifBYoYAHA");
|
||||
hiragana['MO'] = image(60, 50, "AAX//4GEv4HFj4GB/wGCg4GB//4AwMBAwX/4AcEDwcPAwYWBgYGDCwQVC54tCCoX8F4PgFYP4CYI+BgE//0P/gaB/ARB4F/4ApBwAVBg4OBj/8EgITB4AiB4InBBwQgBCAIOCPQPjD4MPJ4MH/0/+ALBwARB84kBBwQ0Bv/gBwc/+5bBj5tEHAR8Bn5lBBwInBBxY2CBwcDWIQOEGwIODJwIOFIoRKC4CNCBQP3AgKwCDIIOBKIQKB8/8IQJgBj4OB8E/MAfD/ytBEgX8J4KeBZwWDIgJCBCoP4ZgIzCAYIqBeYRQB8DnCK4gGBGoIDBwAyBF4IKCCQWBAwIVBEoPgF4RFBg/4F4Q2BAAQOBTwIADHoQADbIQAIA");
|
||||
hiragana['YA'] = image(54, 50, "gEf+AGEv/AAocB/4MEg/8DUv///Aj//wEDAwIcBAwMP//8BgIGBn//+IFBAwICB54GCDQQAC/0HAgXAn45BD4IDBn45Bv4MBAYPgGYJKCFAIbB8EAgf+DQRbEv/4LYYaBOQU/4EPCwIhCCYJrCgf8CYkP+BlBCYQaBv6GDOwQaECYIaEKwIaD4JWDgP+CYIaCg/4NQYTB8Z+BFwef+4aCMgN/74aCn/z/zXCIAOH/IaCh5CB44aBJoU+a4QyBwFwDQLGBCAOBX4adBGIJMBRIQaBUYI4CDQJnDFYJ7EDQKzCDQYECAA4");
|
||||
hiragana['YU'] = image(52, 49, "AAMf+AFDgP+Bgk/8AFDgYMM/gkD/4AC+EBAof/BkA5FhEAg45Cg/AgF/AQMBBIMP/4DB//gE4Xwn5dBn4GB74IBgY0Fv4FD8AfBAoYfB/gbBIAIiBg///A7B/+A/4rBCQIxBBAISB/ghBCQeBEoIMBCQI0BBgQSCDIYSB54MBgIlB+AMCj0H/0PBgIABHQQMBOgP4BgZBBBwTDCMYIMDKIIMRWQQmDAwUMYYqyBAoaxBN4IMEV4QMCcggMBWwbZCAweA");
|
||||
hiragana['YO'] = image(55, 50, "AAMHAwsP+AGEn/gAwl/4AFDgP/BgkD/whF/AGEj4oFEIsA/+AEIgoFg/8EIooFJQ3/JRcHJSgoGJQxEEg//FIkfAws/Cgv/AwUGJQX/HwMP8AoB74GBj/gh/+IoU/4BzBBQJBCJQIKBNQRzBv+AWoIIDJAP4SoMBIgIkBOYMDHoKTBAIIRBXgQBBB4IfBEIQYBFALgCCwMP/iVCJAXwJ4QfDcAX/4JRBSoRvBEIZ2DcAQGCFQIhBPoIYBcAQGBDAJqBCgQ6Bg7rIAAY=");
|
||||
hiragana['RA'] = image(48, 50, "gEP4AFDj//wAFE/gFE/4TCn4FBBgQFCBgQRC//gBgN/BYUP/EBAog3BGIIFCgH/BAIFCh4FEgQFEBoXwAqsfAoIuBAoROBEwIFBIwP+AoPnLIWALwZfBNQf/+AFE/AFBEIM/AoR6Bh/8OoIzBg4FBRgQFCL4UD/wlBAoikCAoM/W4QFBj5dCAoMGAohpDg4FEHYJ1EAog5DDgJWCb4Y/Cg7RDaARFCAoZFBAobiEeoruCAoQtCAoI+DAAgA=");
|
||||
hiragana['RI'] = image(40, 49, "ngEDn/AAg9/4Ef/AEBwF//4EBwP//4HBw4EB4F/x4EB8F/z4EB+H/n4EDAQIjBCwUPAgUAAgX+gEH/n//gEDHIMDAg3wAgP+AgvgAhBeBAhmAAiJ3BAhf8AgRUBAhBXBAAJtBAgSgCVgRcBAAJXCEwIEDj5SCBoJDCBAKSBBASSBXwKICAgQmCAgIcCv4SCAgI0DeAY=");
|
||||
hiragana['RU'] = image(51, 50, "gf/AAXAgF/AoX8gEPBgeAgIFD/EAn4MEg4FD8EACQoACn4lBAAUf/4FDDYOAAoQuBHwIACv/wDwgkEh/+DwoFDDw5ECDwRLDMwg5BLIZMBNgh/FGgIeB+AVB4AeBEYJmBBAJQBDgPBOocf/AoCVIU/Kwc/+5WDg/+Kwl/5/wh4mBh/4/A2CFgMOAoJDC8GBMgUHGAJQCCQKpCBgISBgf+SQMPCQN/4H/4YSBGIIwBCgMBDoTMCn/AEIROCLoKFEAIJvBTwZvCTAarFNIQFCXASyCYoYxBAoYAEA=");
|
||||
hiragana['RE'] = image(56, 50, "gEf8AGF+AGigP/wAGDg//GYQGBh//C4M/AYICB/AGDv///gGC+P/AwQKB+YGB/wNC+//w4GDBYMDAwn4AwQ3BFQIGF8AGF4AGFgAGEAYMDHwIGBAYIGDn5XBAwhlBAwd/Axh6CAwSPBAwMHAxEDAwqdBAwidDAw5IBOoQGDU4QGDUAIGE//fAwufCgrmCh4iCAwk4nwGE/EcAwbSBjAGFegReCUgIGJOYIUEQIYGCIYOAAwPgAwIAIA=");
|
||||
hiragana['RO'] = image(50, 50, "AAf4gEB/4AC8EAv4FC/kAj4MDwEHAofwDAgSBDAoACn/+AocfAokP/4FDE4OAApED//AAohJBAAI5BAocAIQIFEHghFCD4QFCBoU/KIQMBNQZ9BOAhOCQYYFE/B8CE4QFBM4JGB4YuDj/7AocD/xIE/+fP4c/84FDh/8QoZyBj5mE4aFDn5yEDAIFDGIIFDIgIXDDwKREv4eEv4eBiAFCDwMH+A8BIQLnEEgLnDSooqBQYQFCDgQ2DAoolCJAgAD");
|
||||
hiragana['WA'] = image(51, 50, "AAV/4AFDh/4AocB/4DBj/ggE/AQMD/0Ag/8DgWAgH/AQMP+ASB//AgISBAoIDC4Ef///+ASBh4FB/4SBgYFC+E/4IFC/8H/F///9//g/8f/3/x/+j/nAQPwv/j/H/wf+I4N/KAJlBv+P9/4MoMP/f9/xlBAIIqBwAUBn/vFwIdBg40BNIIOBIIR7B+BbC8B7BKoX4uAyCAwM+GQX5//f8IyCn/z/hHCK4N/4/8h/8/4EB/4lBF4P/z5wB8f+RYJjBPoPAFwO/BQP4IQX/wJkCTAUfVYf4gf4BgS4BbQRiCcgbSCAAILEcALkCAAM/DoYeCC4ZLBfoIeD/ASEDAhoBAoYlBDwcAg/ABggAEA=");
|
||||
hiragana['WO'] = image(50, 52, "/4AE34FE94FE/YFE/wYYGocB/+AAwd/8AFDn/4AocP/gFDgf/KovADAnwDB43B45EE+IFE/F/KAkfBgmHAonhAonwDAn8h4MEN5X/N4l/N4k/KwkfRwgoBDwcHOohoBOoYFBEgY2BEgYFBEgYFBJIYXBFQYpBFQZ3CAoIWCKoQQCGwQLDHgR8CAoQdCAoQvCOYYFFn5gENgKREbYgAGA"); // XXX there's no WO in hiragana, so we fill it with a copy of the katakana char
|
||||
hiragana['N'] = image(54, 50, "AAVgAYUP8EHwAGCv/Av4RD/8D/wFCgf8g/8DQf4j/4AwU/8E/+AaDwF//4VBgIfB/4GCD4MPAwcf+YFB/4jBn4FC/4jBAof/4AYC//n/+DBYeD/wZC/f/FgIrCGIQsCKYU/444CKYP/z4xCvxOBv+/8EBQQP4B4KFCCoJeCNIYPBQgQKBj53CAYSbBCYQDBHgJbCTYUDOQZHBM4QTBTYX/GQQxBP4Y8BDQRGBTYY4Eh5MDHgZTDAojdEbAYGEHgIGEv7/DHgIhFfAh1EEIg8GEIg8GTYYhDHhYAF");
|
||||
/// /////////////////////////////////////////
|
||||
|
||||
const katakana = {
|
||||
A: image(56, 51, "v//AAfwAon//AGF/wGT/gGM/A3F/BDEn/wJQoGCj4RB//gAxUB//AAwcDAwsH/+AAwcP/4tCAwMf/wGEn/8Awl/JYYGBKQkf/I9DAwJgBGwQGDGwRlBAwJsE+42DAwPzGwYGB+J7EQIIvDQIIFEAw5DEAwRDDgCIEAxCPBKIcAR4IhER4hnCLAg9BLAgoBAwgoBcQiCBMwj0BHogGBHogGBfoooEQQREFEIgGBAokAhAGFA="),
|
||||
I: image(54, 55, "AAkEAws+AokB/wGEg//Awk//gTE//gAwcPCYt/CYkDCYsfCYv//A0F4A0ECYg0BCYggBCYn/KwhBBGgl/EAgtBEAgMBEAZOBEAgMBEAYZB/+ABggTDBgQnDAoIaDJoIaDFgIABDQQFC74aBBgX8v4aBEwWBDQQgB/EHDQQ6BwEfGoX/+AJBDQMDWAKMBDQMPAQIaDiBFCPAgaDU4hrDDQiuDDX4acSAIaCA="),
|
||||
U: image(52, 55, "AAMP/gGE//ABlH/AAnvAon+Bk5EDv/vIgcHBkHPBgZwBBgn/Bi8B/+PBgcf/AMFw/wBgYEDgED/6qEv4MEKYK3F8AFDj7EED4LREv/4CQn/wASEFginBDAgfEDAIfDn67BC4YABH4QXBCQcHZoQkEEoYMCHAYlBFYZEBLwk/MgpQEAAw"),
|
||||
E: image(58, 45, "h//AAfwgYGE/0AAwn/wE/AwngDgv4DjhDCv/wJQkf/gGEg//AwkB//AA4gc/Dn4cjbAv/34GF94GF/YGF/wcjwA="),
|
||||
O: image(57, 54, "AAcf+AGEh/8AwkH/wGEgf/AwkB/+AA4n/4AGEv/gAwk/GIsf/A4P/4AE+F/Awn4n4GE/kfAwn+h4cFg4GFwYGF4IGFKwYFBMQpxFAwJxEAwJxEAwJxEAwJxEK4JxEAwKqEMoQGE/o4En/8HAl//iqEAwKqEv/+VQgNBVQgNBcYgNBcYhLBcYhSCHAQKBAwI4CAwY4CD4IGBHASxBAYI4CAwY4CYwIGBHAQGBD4I4CBIJfCHASmDHAV/PYQ4Cj5QCHAUPLwQ4CgQGCOIgABOIgABHAIGEAAY="),
|
||||
KA: image(54, 54, "AAMP/AGEv/gAocB/+AAwcH/wTEj4arg//AAf+j4GE/F/AwnhAon/w4aZHAMP/hTEn/wKYn/4BTDgf/KYgQCDQYQCBIQQDBIQQCBIc/DQouCDQQuCEghJBEhITBH4RTBLoRTEBIJTGCAUPNwoTCDQQWBDoIuCj4TCJIX/CYQ/BZQInBH4U//0HwBTBGgPwXAXwh4PBXAXAv4PCZIIgBEYTJBn5SBDQXABAIzBCYJcCDQXwgbOCAwIDBQgI4CgEOJwIADkAGFA"),
|
||||
KI: image(58, 55, "AAU+Awv/4AGEn/wAwkP/gGEgf/Dkk/CAc//4ABwAGBj4GC8ATBAAf4h4GE/woBAAmAAwvgFAYcIwAcD/BFDFARFD/kBIoYACv5FBAAcfRL94DgkfHgf/95EBD4RgDD4MHLwf8AogAd+CPFGwiJCS4XHJgSGB8CJEkCJJUwYABg5pDD4amTNwKmXYbgcDLoY="),
|
||||
KU: image(55, 55, "AAMHwAGEh/8Awkf/AGEv/wAwn/4AFDgf/EQkH/whF/4ACAwM/AoQQCBgY5BgIGDHIMHAwY5Bh4GD8AhEIAQFDIAIhBBIJACEIJpEj45CNIV/NgRpBDQIrBEoPgDQJlBEoQaDEoV/RwUP/wPBQ4Uf/gPBQ4QsBKAKSD8BvCSQXDDQYYBNYIaCGYIqBDQU//kPXoYYBj5QCEIPgj60DKoMcWga7FKoYABKogaDbojPBbojMDGob/ECYJBCbgYaDE4IaEPoIaDEAI1EbYQZECYgtBCZQGCLol/KwxxEAwJqEgIMFgIZEgA="),
|
||||
KE: image(60, 54, "AAMcAwsD/4HFn/wBxl/8AGEg/+BxkP/gOF//ABxcB/+AA4kf/BCGAAZOBv4HEIQIOGAwgOBh4OFGYIOFn4OFEgoOBAwvgh52BKgYDBOwJUDv5nBBwY6BAYM/BwIKBJgJjBBQSbCWoQVBRgK1D/4oDBwJJBWos/WIS1CgIVCJoRGBWowCCj61HYgpRCdIjEGLgTLEIwTLEfAv/GYqtBEghyBGYjoCAwwkDAwQVEYwYjEHQt/CopeBQgQOEIIgOBPgxeFgZ7FA"),
|
||||
KO: image(49, 46, "v//AAYFF34FE74FE94FE+4FE/IFE/gFE/w0Dgf/AocB/+AAwf/4BHE8AFDn/wAocf/AFDh/8AocHGH4w6YZf7Aon9YYoFEejBhEAAIA="),
|
||||
SA: image(58, 53, "AAcD/wDBg4DC//AgEB/+AgE/+AKBv/ggEP/gGBj/4DgP/DnU//4A34CQ+DAIcEDAIcDDAQDDDAYDCDAYDD/4cDIgJADAAUfIAQACh4jCAAUHD4QACJwIfBAAQtBEYgGBI4QUDFQkP/4qEVYQvEAAIxCEIK5CBwV/AwsfAwocCAwYcCJogcBNIp3F"),
|
||||
SI: image(56, 52, "gFwAwt+Awv/8AGF/gFDgP//4GGCocDAwIVDBoX/wAHCn4VFg4GB4AxEAwsfAworBEQYABv4GFj4DCjgrCBQYRFn/4JQfAIgIGD+F/JQcD/gGBMARQCOwcH/wNBCoUP/0PAwIrBj/8OwQGBn4fBGIIGCAQIlB+BcBAQKvDBIQRB8AfBIQUH4AXBP4RXBGgJmERoJsFAwv//yaFbYghBQIYaCeAi9FPQTZGdxKFCFASECFAZPBEIgNCJQaZEAwhDDAwRJDTAYGEQAiQBPIgAGA"),
|
||||
SU: image(60, 51, "gH/AAYGBh4GD/AOG4AOF/gONDo+ABxAACgY7CAAd/+AGEg4OG//gAwkP/wGEgJCCAAcfKIQzEIQIzEIQozOj4zFEgIzFn4kHGYv/M4okIGYt/IQqXBFghuBHYs/bAY6DCwrJECod/HgYVB8ZLEcoMfLQYECCwYVB+BTBCwT7CCwYrBAYIKCCoQDC8BXBEIQSBNoQVBBYP4EAIoCOQPHCoYTB/xdBIwQ8B+6SET4N/dYn/4aCFFgKRFgC+EgPghivEAoI"),
|
||||
SE: image(57, 53, "gEH/wGEgf/AwkB/+AA4n/4AGEv/gAwk/+AGEj/4AwkP/g4JjA4EBQQ4D/4DD4E/AwIuBv/vAoP/FwILCAAIuBv4GEBgn//wFEAwITEh//CgfwAwMfCIRGB/4BB/5xBAgJTBIQQGBwP/75CBAwOAD4JCBAwRmDDIKYBOIQGDOIQGDOIQbBAwSqBAwiqBAwiqBDYg4Cv4GCHAUfAwQ4Cg4GCHAUBbwbjnHAgADcYYADUYQxEEYq6CVwbDBdQi6CZQYqBAAZcCAwY1BEYi5DAAQ8CegfgA="),
|
||||
SO: image(52, 52, "gGAAol8AYUD/Ef4AGCn/3/wFCg/+v/wAwV/8//Bgk//AMD8f/FoQMBj/8Bgfg//gBgcPFoYMBFocP/kHFof/4AtDBgMDFoYMBFoYMBgIIBgADBwAtDj4dBHQQMCFoYqCHQQqCFoc/BIIPCCwQtDKYIpBB4IwDIAQwCh45CBIVAFgSmDFIaaDOIYfCVgYfBRYYfCTASTCUoY1BQgZPCD4l/D4kfH4g4BH4YYBH4gFBGQd//4yDBYIyDn4SEJQIlEBgRXEHAg+BFYZRGZYQADBYgAG"),
|
||||
TA: image(55, 56, "AAMHwAGEh/8Awkf/AGEv/gAwn/4AFDgf/EQkH/4oF/4ACAwM/AoX+FAQGCHIMBCYY5BEIIAC+AhFIAIhDHIQFDF4IhBJQMHF4JDDNIUfHIRpCv5sCn/wDQJsCDwIaBEIIKBwEf/9gOAQaB/gbBFAIPB+YsC/AaB54RBFAIaBAIOAEoJvBOgPh/+DNAJWB+//DQPBQIZyBM4f4LQSQC8EPKAIpBFAMPPgKKCgEcYIZwBiAGDbohwEZ4bdEFILxFf4ghBXwLjEDQhLBCYoaEE4IaDdIQaDBgLBCDIRQENYYTIewRkEAwJCFHYicBOIkAEAhDBS4IAJ"),
|
||||
TI: image(57, 54, "AAkGAwsfwAGE//gAocP//wBgn//gEBgIFBAAIeBAof/wAYBAwkHAof+gEDAwf4E4YAB4AGBv4TDAAM/AwoxDKQhABLQwiCAAV/MIglBMIglBHwRwDNARbF//3Awv7Awv9Awv+Awv/MQQAD34GF74GFKAUHOIYABSAJxGaYp4Uv54FP40/P4oGHQwQGKKgt/AwrUEMIQGEVYIGLg4bMFII+Fv5TGNAsPQgsHTIoAG"),
|
||||
TU: image(54, 53, "AAMBwAGEj4FEgf8AYPwgFgn/4BIP/g+Av/ggEP/n/gP/4EAv/v/wQBFQP/z/4CAMAg/+DAMfEIICBDAN/FgN/8YYBBAIaBw4hDDQIVBAYMAn/wDAIhCCwIhDCwIBBwAIBHAIYBEIQYDBAIuBwAjBFQghCJgQhEAIIhDEYQPBh5HBM4IhDQQQhCwYeBCwMBCoSPB/0CIQQhBAQKWDvytBCYTBDv5tBZYYTCAAQTCAAYTFHAITEj4TF/4TEh4TFv4TEg//JgIMDMYIMEO4ImD/53BAAM/AwIsEEAgFBEAZNBIIgTCFocfJwo6BPgpHEgZAEgEOAogAGA=="),
|
||||
TE: image(57, 51, "h//AAfwg4GE/kDAwn+gIGE/8AAwuAv4GE4E/Awngj4GFNWJNF/gGF/5UF/+/AwvfAwvvAwv3Awv7GJn8IQV/4BJEv59Fn/wAwkf/DJFEAYABg/+AwjJBAxbQBwAGFH4gGBH4gGIIwgGNG4IGEg//LYjyBAwiyBAxc/EQoGGFIJTLdYJvEgF+fIsYAwo="),
|
||||
TO: image(42, 54, "//AAgU/+AECh/8AgUD/4U/CgYPDn//wAUC/4VCCgIlDAgIKCCgIKCCgP//wUD//gCgQKCn/zBQQ+BDYP8CgMBEAQBBj4KBKYIKC54yBBQP7KYIKCG4QKB35YBBQIUCGQPjNAUD+BXDnB9Dgy8/CicAA="),
|
||||
MA: image(57, 50, "/4AE/l/A4s/AwvfAwoAN/YGF/oxGHokf/wGLh4GN/4GSg4GChgGDwARBAw3gAwv4Awo7BAwn/4ACBAwIKB+AGDgJtBAwcAUgOPAwYLB94GDgaFCAwTBDAwcfAwoyBAwgyBAwgyCAwgcBAwgyBNgL0ENgIADn6oHDijhFW4wcB4AGDKwPwBwl/fwzUJDgZOFgAGGngGFhADCA"),
|
||||
MI: image(52, 53, "gPwAwkf/wFDgf///gAwU/AwIVCBgX//AME//8gEHAoQGCBgYGCv4GDFIMPBggoE4A2CCoIuCAweAAwc/BghYBMwswNw0PNwkBGAIbEG4gMCOoYMCOoQMDAwRnE4BYDKYQTEKYRuCKYY8GgCjDAAV+LAtgcTMDbYhTCHobICBwbBDBghZDZwmAZoYGCAogGBCYgiBEIidCBwQ2DS4QMCVYT2CSAb2DBoLpFn72EdJAA=="),
|
||||
MU: image(59, 54, "AAMDwAHFv/AAwkf/gVF/4VG8AGEh4VHFgoVPFdZBdRogVBgP4CokBFogVBn/wTIkHEwYrCv4ODCoMP/wVDFIP/JYQVCBwgVBGYLICCoTIDCoQCBBwQhCn5RCCoR/DNoZCDDIRRDCoQODg4+CIQYvGCoZCCCoZRDAQV//4SBRAM//4ABwEfAgQAB/ARBAAkPAwvxAwv+Dgv/8YGF/gkD/xCB543DH4P5AoaBBewsAvgGFhgGFAAQ="),
|
||||
ME: image(55, 54, "AAcB8AGEgf/AwkP/wGEj/8Awk/+AGEv4iF//AFAuAAwcHFAsPFA34AYNwFAQvBgICCFAUHCAIoDDwQoDn4DBKIf/MYIoCDwIGB/5RBAwWDKIYGB456Dv//75RDAwP/JQQmBAwJ6Dj4GBOYYGCOYcP/5zEg//OYgGNDYw3BAwgvBAwaABAwgaBOARZC/wGDOoP8MQI1D+AGDFwPAAwJaBDAQNCJIc/AQJsBTYL3COQc/4ATBXoYdCSgU8J4SNCmCNCNQqoDAwQuBAwgFDFAITEAwK1DAAKZEAAIMFAA4="),
|
||||
MO: image(55, 49, "j//AAfAv4GFAon/wIGFgYFE/0HAwn8h4GE/AvF8A4Bv4DCAAQzBAocB/+AAwYxBCYkH/wGEh/8MIv4Awk/+AGEGyJfFAFP9AwpOBNuikeAwxfEHoLpFNoZACAwZABIgIACJYYABIAYGCIAYwCHIoABA="),
|
||||
NA: image(57, 55, "AAV/8AGEn/wAwkf/AGEh/8AwkH/wGEgf/AwkB/+AA4n/4A4rGoIAE/IGF/wGF/9/Awu/AwvfAwvvAwv3AwpQCOOqqEWLV/H4pGGn5GFAw0fJosfJooGGn4GGKgq6BLQoGEg4GFh4GFPoIpEDYIwFv5MFLQ4GFg6EFgaZFAAw"),
|
||||
NI: image(56, 43, "h//AAf4A25+/AH4AuWggA5A="),
|
||||
NU: image(55, 51, "g//AAcAh4GFj4FD/0An4GD/kAv4GD/EADQnwgIGE8EDAwnAAwuAIIgvBAAcPF4IADn4vBAAd/8AGEFAIDBAQIsBFAMDCAIoDh4eBj4oCj4GBFAd/CIJRBgBZCAQIlD/+HQIIGD54oCNwZKDPQZPDOYRdDOYqmBOYi0BOYjCBBogGGYQSAEAwimDGATdDAwQTBH4JFBLIP8AwYTB+AqBAwITB4AGBE4bADBIJyBUIJ6CVgXgJAQzBg+BAoJkCgxcBCYRIEPArlEH4YGDO4ibBeQs+AokAsAGF"),
|
||||
NE: image(61, 55, "AAX/4AGEg/+Bws/+AGEgP/wAHEh/8Cwt/8AGEgf/Bwsf/AMEAAYnBj4GDHwQOEDAMHA4hVBn4WFJIIADHwMPA4hgCAwZkFCQKCGBwpHBPQwOFFAJyGBwt/BwozBBwpwDGYiYEEgP+iAkF4IPDCoP8j7WCUAXhbwYVB/4RBU4n4QISfD54vBS4f+FASPD+AEB+AFB/IjBFIPnA4LzCGAfAeYIjBGAP4eYQCBwZuBeYUH/EfIwJRCAoIDBg6ACnCmDR4oqBDIKfEHgKuFS4g5CBwo8CWwqOCAAQ8DcYg8Vn48FAAo="),
|
||||
NO: image(47, 52, "AAcHAokP/gFDj/4Aod/+AFD//gAgUB//AAoUD/4oE/woJn4oLEQYoBwAoIh4oEj4oFJZ8HERU/EQhFEDgIiDH4JFDh4iEH4t/NAYcFHII/Dj4cEv4/DCwIcDCwIcDCwI5DCwhEBHIYQBKwf/GYYhBCwc/FoYKBFoYEBFoQKCE4RrBE4YFCHwQyBHAYnBJ4YFBcBN/AgcAPgYABA="),
|
||||
HA: image(62, 52, "AAP/wEH/gGCgf/gE/+AHCh4MB//AA4QMBCIQeD4ARCDwv4Dwt/8AeEgI4BDwkH/weFj4eEAgIeF8AeEAgQeEAgQeEAgQeEAgQeGMggeCMggeCQYiACQYYbCDwgbCIogbCIoZZDIoYTCMggTCEwn/CYJFDBYZFDBYYmDv4LBEwYDDg4aCh5JCDQYiDaIQWBNAQ5CMAYLDcgYmCCwgqCGIYTBFwL7EJIIWEAgPgh4WDNAPACwgMBCwiHB/wWEFwV/CwZVB/YWEDgPHXgYuBDwLbDKQPwh60CGwWAngGDgAFBkAHEsAFEAAQA=="),
|
||||
HI: image(47, 51, "//AAgUB/+AAoUD/4QDg/+AocP/gFDj/4Aoc/+AFDv/gFw8BwIuDj+DFwf/FwcP/4uD///FwQKB/wuBJwIFBFwM/AoP8//PAgP/+IDCAAJdBAAXwg4FDEoQKCIIIgCLoQFBKYV//5qDB4aMuF1YFDFwIRDUIQAC+YFE8YFE44FEw4FEUgn+Aon8WwhKBXggA="),
|
||||
HU: image(49, 50, "/4AEv4FE34FE74FE94FE+4FE/YFE/oFE/w0Dg//AocD/+AAoUB//AI4ngAod/+AFDn4FEj/4Aon8AocPAokHHgg2BHhYFDHgJCLJBZCEAopIFAoxIEAoxOEApc/AojSBbwplEAoZxBAocPAojICBQhBCGYIFDBYRZCa4P/NYQuCPoYFBSoZGFZYsPAgYABA="),
|
||||
HE: image(61, 43, "AAMH8AHF/4HFh//wAOF/wOG/AHEv4eFg//DwoOBDwgOCDwk//YeEgf/x4eEn/8n4eDgP/4AeEj/8DAIeCBwPgLgkfDYIeECYQeDh4LBIwIeC//wDIIeCBYJdCDwV/BwIwBDwIOBCQYeBn4pCDwRIBIAQeCMIJPD/AOB4CED4BhBMwf/MISbD/kHPovwj4ODDwV/UYhYBKQJ2DRoIGDHQINEcARCCWYgGEDwIOFgb+FDwL2EDwQGFIQoeCBw0YA40AA=="),
|
||||
HO: image(61, 54, "AAV/8AGEgf/Bwsf/AHF//AAwkH/wOFn/wAwkB/+AA4kP/g8Rg//AAngv4HFCYIAE/EfA4vAAwv+Eo3wn4HFwAGFJwZ5UgfAPIJzDn/x/+PEgR/BAoJzDP4N/8JzD//D/6KDFYI8BCwYrCCAItBPQOH/wWDCgIQBCwf/4P/wIWCCQIBDWgYBCZ4KJBE4LPDEYInBh5sBBgKLBNgQ0CJoIWB4ACCBgIiBBwP8EYU/TQLXBHQQECFAI8BCwIqB8DzCDYMPAgQbCMoI3BF4IRB44OBWwQUBv4TBJIV//InBHgQCBw4OBHgUH/EfNgKOCj0A3BsCQwNgeaSdCABA="),
|
||||
N: image(54, 50, "ggGFngFEgP+AwkPAws/AwkB/4GEh4GFn4Gaj///gNF/AGF4BEJAwITBgOAAwQTBh4GCnwJCCgVwLgRwMHAgTBHAgTGv4TEgYTFMIITEMAsHMBY0B+ClFCYiPFEAITEv//OIQMCTg3gBgggEDIIgDGYIgDMIJVDDAIABIIILCFoYYCJwZ0BHQgsBBgZnBBggnCKgYhBMIi3FgAFFgAA=="),
|
||||
WA: image(51, 50, "/4Ay4A3E/AFCh4GBAoUBAoPgAwU///8AoUHBgOAD4nwAoUf//+AoUDGRYSBGQYSCGQd/94yDh/9GQZFB34yDn/zGQcPAgYSCG4YSBC4YSNv4SKJYJwDLwISEn5QDS4QSDDAJjDDAJ2DGIJ2DUYQ+DQYKcFFYYXBDASOCGIQFDGIQRCDwTaCG4YFBEgbHHN4hiFg6HEA="),
|
||||
WO: image(50, 52, "/4AE34FE94FE/YFE/wYYGocB/+AAwd/8AFDn/4AocP/gFDgf/KovADAnwDB43B45EE+IFE/F/KAkfBgmHAonhAonwDAn8h4MEN5X/N4l/N4k/KwkfRwgoBDwcHOohoBOoYFBEgY2BEgYFBEgYFBJIYXBFQYpBFQZ3CAoIWCKoQQCGwQLDHgR8CAoQdCAoQvCOYYFFn5gENgKREbYgAGA"),
|
||||
RA: image(51, 50, "n//AAcHAongAon8j4GEwYFE+F/Aof+h4ME4IFE/BYr+4FE/wFE//fAon7BgpYE//vAon9CQo3Ev/gAocP/gFDgP/wASX+ASJgYSFXwJ2ECQivBDAoSEWIs//wFDbYIrDAoI+DAoIYDQ4IYCFIIABDALlDGIJhBewS/EJQQYCG4YkED4QFDD4JJF4AFDA"),
|
||||
RI: image(43, 53, "AAf/7/4AgMf/f/AgMD/9/8AFBv/v/gEBh/9/+AgEB/+/+AKBn/3/wEBg/+//AFX4q3v4qDh/8FQQPBz4PDAYQvBEYQvCEYI/CGYRPBB4cfIYQpBB4cH/5TCDwJjD/4kCn4EBCgN/AgIUBDoP/FIJHBAAIyCDIYjBIYYaBQ4QaBJoZHDAAoA="),
|
||||
RU: image(61, 53, "AAUH/wHFn/wAgUB/+B/+AA4UP/gBBCgd/8ABBAwUD/4BBBwcf/ABBA4f/4ABBHQg8FHQI8/HksYHgwYBHgkPF4I8EvwlCHwOAg4gBEYI8CCIQjBHgITBCIP+HgU/CwIRBDAIgB4AMCAgMfEAIMBDAIOCBgQYCIwQMCPYJTBAQI8BBwUHEoN/8P/IYN/+AvBj4LBBwOAj/7BwZGB/4ABBwXAAQIODM4QOFHgIOC/4OBh4OCAYJGBv4OCn4OBHgJKBAYJkBIQISBaIYhCCwIOBSoTqBJQISBeYUHd4U+bYUwcAYAKA"),
|
||||
RE: image(51, 51, "//AAocf/AFDgf/CQl/8AFDh/8AocB/+AAwc/+AFDg/+GX4ECgwyEgPgGQk+GQkP+IyDC4IyE//3GQc//gyDh//GQYYB8YyD//4GQc//wyDDAOBGQUH//gGQRvB/BlD/4DBGQU/CwIyCj4YBMoQkBBIIyBBAIYBGQIkBDAIDBGgIiD+AFBGoIyBv4eCGQIABJwQvBAAJnDEgTLCEgY8CIYLLDEgZVCAoZuBb4iaBfAj+EgE4AokAA"),
|
||||
RO: image(50, 47, "/4AEn4FE94FE/YFE/wYF34YS4A1BgIYB+A8Cv/v/gFCj4YBAoUHDH4Y/DEbglDBQ8CAAYA=="),
|
||||
YU: image(59, 46, "gP/AAX+A4M/A4fggEHAwf8BwIGD/4GBj4VFgYVGv4HDwEAh4GD+A+Eg46CAAf/4AGEj/4Coo6CCqJFBCot/KAIADh5QCQAhQBCrM/Myk/M3JQGh5QFMyIRBAH6NB"),
|
||||
YO: image(50, 49, "v//AAefAonnAon5Aon+DDA1DgP/wA8E8AFDj/4AocHDFZjfDCJjxDD5WE/+/AonvAon7PgoYX/g3DAAQ"),
|
||||
|
||||
};
|
||||
const hiragana = {
|
||||
|
||||
// hiragana
|
||||
|
||||
A: image(52, 50, "gEB/wGEn/AAocD/gMcg//AAfgv4FD/wMYFIRNa54HDgYyCBgYsEBgX/+AGBHQYpBCQQaCh4JBJQPwgIdBBAP/wASB4H/j/8MIP8j5fBBIP/4P8gf+j/7/hVBj/jA4PH/C/Bn4RBv8Aj/3/Ef55FB/9/wI+D+/wj40BHwIWBL4QJB+BFBwAmB/4MBD4M/94MBD4JAB/4cBNYN/BgM//AsB/n/z4bBQgOHX4QVB/B3B/CQCAQTSC8BFCB4Q4CB4UAgIIBRQOAXojREn/gaIgAC"),
|
||||
I:image(58, 50, "v/gAgUggEf/AGCnkAg/+AwU/gEB/+AAwQZBDgcP/gcECQIcFCQIJCCol/4AGBgYLBj/wCokHCAIABFAIQCCon/DgQECn4cDCoItCAAI+BDggVCLoZeB+BgCCocPPQZUBwZdDJAQcEGAIcEGAIcEGQPDDghIBDggyBDggyBx4cBjxIC8aaCCAIyBLAMDM4IyBSARnC//HUIk/+IyBCASdBLAJKCGQOf/kDJQV/GQRKCJ4XgEYRPC/CoCDgOHNwl/8P/84jCDgM//5HCDgMHAwIjBgP8DwIsBQgYVBSQgVBaYZnCTIgtBbQhDCUAYkCfwYOCGIgAHA"),
|
||||
U: image(46, 50, "h//Aoc////8AFBAgIABgEDAofACwIAB/wWD//4CwgdBCIeAFQUfCwIADCwIAMj//+AEBv4tDAgQLBHAYFBAgf/8YFE54FECwRTB/wkCAoP7IAd/OgR2CKwcBQ4kH/hMEJYQcC4AWIh4WEn4tJg6EEj6EEVgIQDE4l/CAbABCAZqBBQgQDBQIQCXwIyCYYTIFeIhlCBQjxCLIQWBMgbdFvzYJ"),
|
||||
E:image(55, 50, "gF//4GE/4AB+AFBgIGC/+AgEDAwYNBg4FC/wGBh4GC/gGF/ArFFIQAD4BRVn42FLAIGEJQYGBLAhEBLAhEBLAf/8ArDBIIyEj5fCRYZYEEgJYEN4JNFDQouFDQKcBFwYGFMIIGDLQRJFAwgaBOYQuC8Y2DFwODAwcP/0HXAc//EPcQnAj5LCPAU/MwR4Cv5ECPAQ9CLoUBd4auE/guBVwf5PARaC+5qCAwXnJwSXB//HI4QGCw5ACAwUHNIn+gj/HAAg"),
|
||||
O: image(54, 50, "gEB/0AggGCg/4gE8AwUf8EA/gGCv+AB4QaDv/wDQn/CwIaCgP/4AaDgf/wAaCgPn/4PBAAXv/0HAwef/kfAoX+n/4v4GCAgPxCYfg/4jBAAWBGwQ1BgEDJoJQCJoJRBLYcPCAJrCgEcKAaGEHgSGDF4QPCJYYxCHoYMBn5YDBgoGBDIP8FQKiBDwabBFoIzCv/gEAJQCMwWfKAIbBh58BDQMH/l/4IaCh/xTgIaCn/P/BrD/8/4CGD/i3BDQfz/gaDv/P+AaCCAIaEHQQaDv/hGoV4h//g4VB8JnBa4ePZYRkBBwKNCbwPwCYR/C44CB4BtBfgSaD8ACBYQQWBAAYA=="),
|
||||
|
||||
KA: image(55, 49, "gEH/AGEh/wAwkf8AGEn/AAwl/wEAhgGC/4CBngCBgP+AQP8AwMDAYIyDAYUPAwQ2CAwY2Cj/4gP/AAP4j/wgYGC/gGBg4GC/0/8EPAwsfCgd/4E/Awt/FIf/LgJmBE4IGCMwMf8JjBHwIPB4IDBgZmBv+DAYMHMwP/BQRfBOwIKCL4J2BOIQvBAgJxCGQIEBHAKPCCwIYDCwQBBQoRGBviIDIQJRC4AdCXAYdCKIcHboQ/CboY4BboghBboZKCFAYhBjAoDh/8nzME+CfBF4V/RgP/EgKVBwYGBFAMH/zIBFAQeBAwIoDboRRD4DrBJQUHAQJsDAAwA="),
|
||||
KI: image(48, 50, "AAMB+AFDh4FL/AFDg4FIn//AAX4ArpHC/xNEAov/LQgFCDgYAlF4UfPx8/g/8CoQbBKgQhCAoMDFAkHAoeAh4FEDgQAB4E/FgIUBwE/HwQdBn/gAoM+AoPAAoMMAohFCAqIpCgI7C4BEBI4oICAoZfE4C9BAob2EAoISCaQgACA="),
|
||||
KU: image(33, 45, "AAsB4ADC+ADC/wDBgf/wADMg//CYIDDh4DDD4UfAY/8AY34AZRDCh4DCg4DCgYbCgI/CgH/BgU/BgREBBgIQB8AMCFIRNDLoJ2Cv42DJwQdDFQIdDFQQdDFQIdDHYRkDgYhCgADDnwDChyzE"),
|
||||
KE: image(50, 49, "AAUB/0Ag/gAwN/wAICgEfBIIIBB4P4BAYPCh/wDAcD/gYE/4FBDAU/4AYEGIgOCDAQOBh//AAP+v+DAoX/7/AAof3+E/AoX9/gYD/9/gYFD/4YE/5QCGIJQDHYRvCJQU/N4JKCKAYYCKAQYWmAYEjwYEx6lDh/zUocDMgIYDv6cBKgUf/4yBBAMH/4eC4EBNQUfAQN/DYMPE4TjCAQQkCYgSJBDYLEBn7QCAQIbCE4UDDYP/PIV/CgLpD4EPP4UH+AkBAoIACCgIADh6LCAAMDAoYA=="),
|
||||
KO: image(52, 50, "h//AAX+gAFD//gBgn/BgvwBiWAAon4GwUBDIQACCQQFCn//4AFCg4lBCQc/DwYfBKQJdEDwYAB8CIihAFEgJJDIgQFEg5KEMgITEj/8D4hwED4JqEOIIfEv5eEg4fEFg0PHIwsEBigmFCYkOv65CJYPnbgn+ZgIAD8IMFewvgCYjRBE4IMDegQABIoUfAoK7HA=="),
|
||||
|
||||
SA:image(51, 50, "AAMB/gFE/+AAwcf+AFDgf+DIl/4AFDg4fEgAfLgIfCj//AFQzCn/gLJYMELI5mEh6GGBgUHGAP4CAQ3COYILCBgUDIgYZBAoYmBn5REDwPgQQPgDAIVBj4fBJ4d+CQI1CgeAXhgSDKoYSEQQp1GQQpFBawXwD4IGBg42BaQngBgRlDBgmABgjzBRYZDCPIYvCv//MQoACA=="),
|
||||
SI: image(45, 50, "v/AAgUD/wKDj/wAof/wAECg/8BQc/8AbD/4bE/AbEFgcHFgk/FgcBFgkPDYhIgFgIKDFh8eFgn+FgcH/4sDv+/FgUD/osDn/vFgQ2BFgcf+YsD/+fFgUP/gsDv/HFgSKBLId/8IsCHgIXBSod/EIIKBwIhCv/4h4WBAQOAv/+IIP8AQIAC4AYBAAIkBn4KDJQIKDCwYpBCwRWCAoJhDAoK1DAAg="),
|
||||
SU: image(52, 50, "AAUf8AFDgP+BjH/AYP/AAnvAon+BjJAUgf9BgZFB/4MDn4kEg4MFGIwMED4QME+E/+AyC/x0DFgPABwIMC/gMGDIn8gYMFv/4EwcP/+AKYf/BgRACBgYRB/4mCgF/AwJ6DBgoTCRohNDTZE/VAkP/gFDE4PAUQhGCI4YeEUIgYBD4gMBEpI4GgIFEAAo"),
|
||||
SE: image(56, 50, "AAcP/ADB//AAwP8AwkHA34FBAAn+A1JalmAGFvinFv4GF//PXghEBAwfBAwoNGEQP/+AGDn4GFh//8AGDg5PCgF/AYP/wAGEgj/CAwQADAw4mCAwZCCAAQ8BFQgGBAAQGBj4GFJQIGEJQIGEgYGFGIIGCIQQVDHQgACA"),
|
||||
SO: image(53, 50, "gP/AAXggEPAweAgF/AoX+gEDBgfwgEfCYoFD/EAg4MFAAQMCAAQwBBhQpBJQozBAAU/IAIACIYJUBAAV//gsJD4IsEn4sEOAn+NIn/+4FEAA39AwvvAwqQDAAP7UYhmCx5bDuBVB4BCDg5bEJ4JoEgJ1EEQKCESwIFEg5vEEA4TFh4TFv4TGYgiLBCYrFG/5dDd4YHCOQKkBDQjbDDQQwDWgR5DAwSGEEAgAEA=="),
|
||||
|
||||
TA: image(52, 50, "gEP+AGE/4Mjgf/AAXAgE/AoX8BjUAgP+GYkf8AFDBhHnEIQMBEQQhBn/jFAWAgYMD/AMH/gMF4f/F4UH/kQGYd/KIIACg4VBBgmAQ4gMFUJcB/8DDQZgBv6iD/wuEn/gKIJGDEIl/4KCDC4KPE/+BBgYXBBgY5BAIImCj4MBTIKFB/wMBAAKSB8EPAwXnUYIMDCwLYD95RBEAIZCFQN/AwPBKISpBwEGQAgAGA=="),
|
||||
TI: image(51, 49, "gED/wGEv/AAocP/AFDgP/CQk/8AFDg/8Bgn/wAFDj/wBQYAqJ4M/LBZrMJYZ+Ch5aDv/f/4bCBQIABCoMDHAYTBv4+Ej4MEg4DB4IMCAoIcCwE/TwU/+ASBEQI8BVQJLCv/gS4cP/kBMgYWBjyoEgLbJEYYSCQQkHCQg2EHASCEv4SBgYOBOQ70BQoYrBEQIABFYR/DJASRED4YFCBgJDDA="),
|
||||
TU: image(59, 45, "AAUP/4FFAAIGCAoX//EAg4GD//ACYYAB/kBAwgOBn4OFDgoOBAYX+BYP8j4GBwEAAgPDGwQ+C/F/BgIABCwOMLQl/+AGEg/+NIv/8BwF/gGEKwIqDAAM/HAYzDEhkfEgsDEgxJGh5JFHQPACqQrBCpkfCopXBCogcBCog5BK4jSCAwxtDDYK8EZIQcCAoQcDCYTjCJgQGCEYT0DIAYGGEgQGDEgRcEv5UEA="),
|
||||
TE: image(57, 50, "/4AFv4GF34GF74GF94GF+4GF/YGF/oGF/w7Cn//4BCDAwOAAwpQEj4ZDAxP8AyUPAwwiFg4GMgZFFAw0BLQqlBNAkAv4GG8AGEn/wKgv4KhZGGHALeGH4oxNh4xFOJBjGEYt/VQwVFg//BwhOBAAI7Dv4GBHYYcBCwgcB/5CEDgQyFGYgrCUwkPKAwAC"),
|
||||
TO: image(46, 49, "gEH/AFDj/wAod/4AECgP/Cwn8C0cICwcDBoIWC/4NBCwMfEgV/4f/BoIWBv//LAMH/4AB8AWBAoWAgE/BQYlBDYUAh4FBHwQPEEIJQDFYJhCgYwCLQQqCDYQKDDYIKDn5xEEAYQB/x8JDYkDCAkPYIk/JoQWTAol/AocZQwR6B8aNCAAOPAgf+TIZqBAongT4QfCBYY9BW4R1BA="),
|
||||
|
||||
NA: image(55, 49, "gEP+AGEj/gAwk/4EAkAGCv+AgAPD/8AgYdCgP+EgkD/gdB/AGBg4DBv4GCj/w/wGCv////8AwQFB//4AwMBAwXwEQMDAwXgAwMHAwXAAwMPAwWAG4QvBLgQGBL4X/AwRfBKgIGCL4X8n/gLARUBn5YDMwM8NQaLBQYIoCAQSIDAQRZBRYaBDRYQhBFAIJCKIYyCDwKoBToZkBOAIJBPYKLCGwMH/h2CAwMfKoKKCI4PgSIYYB4afDJQMP/gpB+AhBMgIjB/AhC4EfAwIhCEoIGCwJdBaIIZBMgSkCjhMBgakBG4LICUgKDBAwQuBPgRKCjgGE4EQAwgEBAAIbBRAQACQgIDB"),
|
||||
NI: image(50, 50, "h+AAocD/gFDgP/CQl/4AFDn/gv//AAOP/E/AoXj/0HAoX4/+BAoX+DAuf+EfAoXn/gYD/P/gYEBG48f+AFDg5QMMYkf8BvE/BvE/wYE/4YEKAIYYgZSCDAMBJgQYCCgYDBFoYDBj4tCDAJlDDAMBGYYYBNYYYBn4xCg/4h6ECPgIHBPgfBDwaVBQgYvBToYYCFYauBaIIwB5/wcAfz/0PAoX8cAn/IgQFC55dBAoXxFILtC/grBGgL5BYIoAGA=="),
|
||||
NU: image(58, 50, "AAV/4AGEj/wAwkH/gGEgP/Aod+Dgv/wAcEj/gDgkH/AcEgP+Dgt/Dg3wn4mBHwYGBDAIyCAwP/8AGBAoQODh4GC/4sBgYGD/AcCAAO/IQQcC4IkCDgI7Bj5YBg//w/8EAIjCwIEBv/gMQPgLAMPFYP//h1BgZpC/4LCNwIxB4YoBFoIxB/AjBNIMH/v+n5UB/4qBn/fIoIJBv+PLYUPQwPhOIUD/gvBGYMH/3/BAX/457CBAP/84GBDgIlB/YGBCYJwB/qECDgKREwBCC34YBDgfvLYP+HIM/+YYCIwM/MoIYB/hGBMoQEBz4nBKQfDAwODGQXwKQQMB/P4j4GBAQP+ngtBUgIRBg6aBRwKiBwOAf4TNBAobjCAogAEA"),
|
||||
NE: image(57, 50, "gEP+AGEg/4AwkD/gGEgP+Dgv/Awt/wAGEn/Agf/BIUf8EP/40CHAMf/4tBAYP4AQImBCIP8n4GB4EH//+AwXgEwP/v4CB/EBAYIPBg4jBAwX8BYJFBCQRKDFYIGBJQJxBIgUfAQIrBAYMPCAIfBBQR8CAwR8DMAZ8Cv4GCGIQGDGIU/AwR8BAwKqCWoU/FoS1Cj4tCHASEBWogGBUAQKBAwItBHARpB8BlBBQKuCAQIKBO4SqCBQX8AwX4h/9/wGC/kP/n/DYSlCv+P/ArB4K+B4/4SIV+j/jWIX8n0P+JSBDoMOMwJWBAwOCMwM//ZOCMwI4C75nB/5bC45nBv+DAwPhTgXAb4PAoCfCQQifBYoYAHA"),
|
||||
NO: image(60, 50, "AAX//4GEv4HFj4GB/wGCg4GB//4AwMBAwX/4AcEDwcPAwYWBgYGDCwQVC54tCCoX8F4PgFYP4CYI+BgE//0P/gaB/ARB4F/4ApBwAVBg4OBj/8EgITB4AiB4InBBwQgBCAIOCPQPjD4MPJ4MH/0/+ALBwARB84kBBwQ0Bv/gBwc/+5bBj5tEHAR8Bn5lBBwInBBxY2CBwcDWIQOEGwIODJwIOFIoRKC4CNCBQP3AgKwCDIIOBKIQKB8/8IQJgBj4OB8E/MAfD/ytBEgX8J4KeBZwWDIgJCBCoP4ZgIzCAYIqBeYRQB8DnCK4gGBGoIDBwAyBF4IKCCQWBAwIVBEoPgF4RFBg/4F4Q2BAAQOBTwIADHoQADbIQAIA"),
|
||||
|
||||
HA: image(55, 50, "AAd/wEAn4CBgH/BIXAgEB/wJEgf8AQIJCg/4AQIJBgEP+ACBBIMAj/gAQYsBEoIoCGwf/GwkB/8P/4AC4f+j4GDw/4n4GDj/wv4FC/0/8AMD/l/4IGD/H/wYGD+P/g4vELARtCMQRtDMQQKDL4YKCMQQKDMQQKDR4QKCTIYKCFYQ2bOoI2C4BgCGwWASAQ2BGQKJC8DNBBAIAB+DNBPYf4ZoKrDAgPwT4K7BAwRdBB4K3BVYIqCVYY6BAwKrB/0DVY3+v/hAwf8n4SBdIXwnxEBAwXgnBEBAwShBO4IbBSYSVCOYQAHA"),
|
||||
HI: image(57, 50, "AAMPwAGE//gAocf//wgFwgEH////kH/AZBAwP+gf+Bof/wP/gEDAwWAAIMBAwc/FgIGDj4sBv4GBE4P8HAIdBE4IqBAwYgBKAIGCKAYKBAwN/EYIGDn4jBAwZfBDAQfBLIPAAwZZBDgItENYN/CAIfBIAIGCLIRfDLIXwAwc/RQJmCHAPv/0PEoI4B+f/AwcH/P/w50D/l/wZ0CgP+j/BK4Q4Bg/gJoQ4BwIGBIwU/4EwAQI4CIYICCAYY/EJQMHHATcCbAQKEHARGBGgQqBCIc/D4IGDaITCDT4PAAQJfCQQRYDeQQGDSIIGEYYIGEE4IGEDgYFCcAQ+CGQZsCABAA="),
|
||||
HU: image(58, 50, "gEP/AGEgf//wHE/4ABAwc/AwIPDh4OC8AGBg4GCEwUBAwX8Dod/EgoHC4AsF+BJFjAGDg4iEFgRfF/+AAwk/IwQjDFIgjDvAjDMYJlCgRHB4ABBFIUf/ABBFIXH/0HCoUf+BcBLwQpBCogpBCYIVDv+ACohNBn/wCoRxBCohNCMoIVBOIQVBAIJNCCAIVCEYIQBCoOAb4QtDCAQtC/gjCdIIXCN4QwBC4SVBDQIXBEYUP/gXBI4QEBHwPD/8ODgR/CwZNCCYN/8P/5/4GQOf+DtBKgXv/jtBKgX5/0PAwJxB/0/DAL8CvkDJYP/IYMMgFgg//fot/VYQACgYGFAAoA=="),
|
||||
HE: image(67, 45, "AAXwA43/4AHFn/8A4sPCA0B//+CAt///gA4kfCA0H/4QGA4IyFn4IBGQg5BIYsD//nCAt//F/CAkf/wzBCAYFBwH//BaE8ArBwBzFCAgNBLoQQCHIPADYIQD/6dBCAk/OQIQEHIQQEHIQkCCARaBO4YUCSYQQDHIQQFHIQQERQgQCLQQQEHIKBDCAPAn5fDCAP8gbNECAaJDCAbVECAPgvj+Gg72GdoqYFCAgHFKIoQDDA0AKIjODDA0ARYQAEhwHGAAIA=="),
|
||||
HO: image(53, 49, "h4GFv4FEg/4kAGDn/D/4ACwP+j4FC/kf+IMD8H/w4GDEAM/AoQEB4IMD4f+g4FCEoPwGIXggH/wEAgP/IIP8KQX4B4PAKQXAgP+AoMDAYMPEAQkC/+DEIIkBEAJVD/8/8IFD/P/h4GD5/wv5IDv+DBgfz/gTEz/gCYf4KIIABGgRRBLIZVDNIJVDNIRVDNIRlBNIZlCKwIDC+EDGYJpCwClCNIQMCCYIwBBgX8GAIBBJwRIBPofwJAIeBLwKCBBwIiCx/4H4IVCv/BFYIFB/f+KYIMCx6RD94YBwLfDwYTBGYV8LgJICgI5CBgUCgaGBLYQACAwLVBgA"),
|
||||
|
||||
MA: image(50, 49, "AAMH/gFDgP/Bgl/4AFDj/wDBsH/4AD/oFE/9/AwoARJVXhAon4JQn+j4MEw4YLn4YEJTIfCAooYCAoX4DgQwCwBdEBgMDHoYMB//3Bgd/8AUC4A7BJQP//kHBwQGB4JYBFoX8KgMP/gGBz/+h//AIPjGAXA//wAoXwh/4DgX4gP8IgQnCF4QFBgOAEIKIEv6SCAAIA=="),
|
||||
MI: image(58, 49, "gP/AAOAA4V/AwPgAwUfAwP4AwUHAwP+DjAABgYcDDwYcDDwQcDDwQcFg/8gAXDDgMAn4XDv/Ah4XDj/wGgkPDgpQBDghPB+AcDMoXjDgQGCNwZsCNwYGEDgM/AwYcBPQQAC/kP/4IEw//MgIYC+f/wZHBCAP8//AGwMDEgKGBRAQVBz/4NYI2C44sBNYMP/PxFQI9BAQMY/+BFQKvCOoIsBEYKSCFQU/SQP8WYQCCGYIqCEwI0BFQQmBMgIDBJwOAfgXAAYItBRAJVCKIIVBAYN/FQIYBAYN/FoIrBTQSzCdgRfCAAg0BAAkfbwQACgY4BAAgGDA"),
|
||||
MU: image(55, 49, "gED/gGEg/4AwkP+EAhwGCj/ggF+AwU/4EB/wGCv+Ag4GD/4kBAwM//4AB84GBv4GC54GBAoX/x/+gIGDh/+gYFC/0P/kHAwX8AwMPAwX4j5cCGwJOBAwJIDj5jBv4QCAwIpBNoU/+AiBNoIGCJYJtBAwPhFwPANQXjAwOAgEEv+P/A2C/H+CoI2BTIIhBwY2Bh/xwH+UgUf+CwBUgSgBBYKkCn/gh/gToI1B4Ef4AvCBIM/4ZmCIAN/44oBSgKdCFAJ3CLAY0BUgQoBGgIGBEIUPAwSID+AGBQIZHBJQRECd4Q9DI4QvBJwQ2Cj4sBGATRBJwLcDFgTcDC4QGEEILqEAwIbDIARoCBgQ"),
|
||||
ME: image(55, 49, "AAUf+AGEn/gAwl/4AECBQP/wAYC4EB/4YDwED/wYDwEH/gGCCIMP/AFBgIRBGwcDCIN/GwUH/EP/4bCDAP/AAI2C+4GCHwMfAoX/JgM/AwYjBv4GI8YGCFoN/wIGBgYCBFwIiBHYJfBNAPAn/8IwIGBwAaBh/wAwOD//4R4IfBg//+B2BDoJKB+AoBg/+JQPjOwMP/n/z/nQIMf/IOB76BBn/3/gVBMgN/94nBOQX/7/gAwKbBOwSOCHoJMCEIMH/v/CAJxBh/7/hcCF4X4KYLEC5/wj5KBEIOfGwJRCL4PzF4V/JIQvBCYJJCH4JxB4AGB/xCCFQIJDDoIMBBIRNBAQJdCIwKUCeAb5CPgQACSgIFDSgIDC"),
|
||||
MO: image(50, 49, "AAN+Aokf8AFDh/4AocD/wSE/+AAod/4AeE+AFDg/8CAf/AAX8j4FD/8HAonBAonwDBY3OKwkBKxc/N5M/GwcHh42D3/DAofn/AFD/P+DAf+v/PBgeP+YFD8f+NAuAG4axBU4ZaCKAUBOAJQDOYIYE+AYEVYKFCDAaICDASICDAsPDAQxBgYYBj4rBAoOAYQPwPQPgE4JYDRQo6BAoglBPoQ0CAogMCAoYvBIwQA="),
|
||||
|
||||
|
||||
YA: image(53, 49, "AAVgAYUf4EPAoUB/8B/gGCg/4j/wAwU/4F/4ATDgf/BgUP/EPDQYRBn///wTBAQP//4OBCYMfAwP4CYPPAoP/8AnBAAeAh4FD/gMD/n/+ALD8H/z4EB/v/wf+CIUH/kP+4+CLoN/CYJhBCYmAgfwCYP7CYMeIwOcOoYiBBAOAPYXggZuCIwIrCTgQrCCYIMBFYP8gYZBC4Mf8B3CTQIPBQgYwBg4MDGAKYBGITABBgZnCL4QTCj5EFAAbUBAwgTBAoYTGYAITFcwQTPfQYTCTAITYMAQTDVgUAA="),
|
||||
YU: image(51, 49, "AAV/4AFDh/4AocB/4DBj/ggE/AQMD/0Ag/8DgWAgH/AQMP+ASB//AgISBAoIDC4Ef///+ASBh4FB/4SBgYFC+E/4IFC/8H/F///9//g/8f/3/x/+j/nAQPwv/j/H/wf+I4N/KAJlBv+P9/4MoMP/f9/xlBAIIqBwAUBn/vFwIdBg40BNIIOBIIR7B+BbC8B7BKoX4uAyCAwM+GQX5//f8IyCn/z/hHCK4N/4/8h/8/4EB/4lBF4P/z5wB8f+RYJjBPoPAFwO/BQP4IQX/wJkCTAUfVYf4gf4BgS4BbQRiCcgbSCAAILEcALkCAAM/DoYeCC4ZLBfoIeD/ASEDAhoBAoYlBDwcAg/AAoY"),
|
||||
YO: image(49, 49, "AAMP/AFDg/8AocD/wFDgP/DAn/wAFDv/AAoc/8AFDj/wGCH/AAIwDAAImCAoQmCv4FBEwU/AoImCj4FBEwUPAoJXCMO4wEM4IWDI4IwCKYQwCL4oFCDAQFDCQIXCNgQFDEoMP/iSC+EHEIJ5CAoSSCwYaBEwXhFoMf8Y4BEAJnBCYN/+Ef/AuBz41CLoPPUQd/4YFDj/AAocD4AuBPIXgDQJ/En6REA="),
|
||||
|
||||
RA: image(47, 49, "gEP4AFDn//Aod///wAoX///+AgMDAoP/DIMHAoX4AowjC//gh/4gIXCj4mBj4wBn/gEoP8GYI/CvAzBwAFBkAaBIgYTCAAUHGARcCJ4YrBFAJcD4AZDFAI/CFAMPJYQOBK4XwLgZdBJwIFDMIQFCQod/+AIBOIXzO4nnRIQRB55dDDYJdDHgQEBIgM/OgUD/0+Nof8jBtDOYk/OYgyDYgQhCPwLOCFoQ4DMwIcCPYSBCAATkECwKBDCwIVCFoQFCIgSNCHASNBGIQA=="),
|
||||
RI: image(39, 49, "ngEDv+AAgX/AYUD/wGB4EH/EH//wh/wn4EBj/h/4EBn/HAgV/z4EB+P+v4EB8YCB4F/8//E4N/54VBFgIWB4AEB346BgP/v/8AgP+//4IQP9//ggBABC4UPAgJRBj4qCgBKBC4IwBF4QrBDgQrB/5vBgYcDEwIcCEwI5BEwP3EIU/94hCv/fEIImBn4+BRYKWCg/8EwSLBTQU/CwScCUYSoDj4zCBoIzCHoIuDKARjBJYJUCQAR7DQAQbDEASABbgU/BATqE"),
|
||||
RU: image(51, 49, "gf/AAXAgF/AoX8gEPBgeAgIFD/EAn4MEg4FD8EACQoACn4lBAAUf/4FDDYOAAoQuBHwIACv/wDwgkEh/+DwoFDDw5ECDwRLDMwg5BLIZMBNgh/FGgIeB+AVB4AeBEYJmBBAJQBDgPBOocf/AoCVIU/Kwc/+5WDg/+Kwl/5/wh4mBh/4/A2CFgMOAoJDC8GBMgUHGAJQCCQKpCBgISBgf+SQMPCQN/4H/4YSBGIIwBCgMBDoTMCn/AEIROCLoKFEAIJvBTwZvCTAarFNIQFCXASyCYoYxBAoQ"),
|
||||
RE: image(55, 49, "gEf8AGEn4GFv/AAwn/wAFDgP/BgkD/wGEg/8DoIkCh/4gf/+A2C+EPAwV///gAQIGB///4ICB+AuB/+PAQPgg4DBn4GE/wSB//AEoIABwABBj4FB/hODA4PwJwYgB4BOCHwROCNoQDBJwJtCLoM/PwJdBPYN/AQMPEoQvDDQMBBIV/DwMDF4QhCg4QBEIIlBh4QBLIIlBWoRRBWol/F4eAIYIlBMwR7BEoQQBUIYvCNgIlBF4SBBEoLsBHgI2DSwP9GwaWB+ZmEj/HGwIvCj+PFgKWBjk+RgSWB/E4Lgn4sBcCIII+CGwTjDWoZFBSYYRBYYgDBYYa5CLgIGBAAI"),
|
||||
RO: image(50, 49, "AAf4gEB/4AC8EAv4FC/kAj4MDwEHAofwDAgSBDAoACn/+AocfAokP/4FDE4OAApED//AAohJBAAI5BAocAIQIFEHghFCD4QFCBoU/KIQMBNQZ9BOAhOCQYYFE/B8CE4QFBM4JGB4YuDj/7AocD/xIE/+fP4c/84FDh/8QoZyBj5mE4aFDn5yEDAIFDGIIFDIgIXDDwKREv4eEv4eBiAFCDwMH+A8BIQLnEEgLnDSooqBQYQFCDgQ2DAoolCJAQA="),
|
||||
WA: image(54, 49, "gEf+AGEv/AAocB/4MEg/8DUv///Aj//wEDAwIcBAwMP//8BgIGBn//+IFBAwICB54GCDQQAC/0HAgXAn45BD4IDBn45Bv4MBAYPgGYJKCFAIbB8EAgf+DQRbEv/4LYYaBOQU/4EPCwIhCCYJrCgf8CYkP+BlBCYQaBv6GDOwQaECYIaEKwIaD4JWDgP+CYIaCg/4NQYTB8Z+BFwef+4aCMgN/74aCn/z/zXCIAOH/IaCh5CB44aBJoU+a4QyBwFwDQLGBCAOBX4adBGIJMBRIQaBUYI4CDQJnDFYJ7EDQKzCDQYECgA="),
|
||||
WO: image(52, 49, "AAMf+AFDgP+Bgk/8AFDgYMM/gkD/4AC+EBAof/BkA5FhEAg45Cg/AgF/AQMBBIMP/4DB//gE4Xwn5dBn4GB74IBgY0Fv4FD8AfBAoYfB/gbBIAIiBg///A7B/+A/4rBCQIxBBAISB/ghBCQeBEoIMBCQI0BBgQSCDIYSB54MBgIlB+AMCj0H/0PBgIABHQQMBOgP4BgZBBBwTDCMYIMDKIIMRWQQmDAwUMYYqyBAoaxBN4IMEV4QMCcggMBWwbZCAweA"),
|
||||
N: image(54, 49, "AAMHAwsf8AGE/+AAocD/wTF+AGEv/ACZUP/ATKgP/CYv8Awk/IQgTBIQkHCYxCFCYxWTIQxWGFAhCBAwkPAwJCE/5KDCYQiBhhCBAwJlBn+Aj/+/49BDoP/8IDBgf8IQIDBKgUf/EPLAJUBv/gn/AFgKZCAIMHCIP4DQSXBAIIaC/+BCIIaBYwKZCLwIuBCYLRCFwIKBEYX/CYUfEYP4TIRACCYQ+BwZUBDwIYBOgITCRAQVCEIP//0BYISjB+CtDUYRNBAwQ5Bg7gDBQIA="),
|
||||
|
||||
};
|
||||
const keys = [
|
||||
"A","I","U","E","O",
|
||||
"HA","HI","HU","HE","HO",
|
||||
"KA","KI","KU","KE","KO",
|
||||
"MA","MI","MU","ME","MO",
|
||||
"NA","NI","NU","NE","NO",
|
||||
"RA","RI","RU","RE","RO",
|
||||
"SA","SI","SU","SE","SO",
|
||||
"TA","TI","TU","TE","TO",
|
||||
"WA","WO","YO","YU","N",
|
||||
];
|
||||
let kana = katakana.KA;
|
||||
let scroll = 0;
|
||||
|
||||
// const keys = Object.keys(katakana).sort();
|
||||
// console.log(keys);
|
||||
let hiramode = false;
|
||||
let curkana = 'KA';
|
||||
|
||||
console.log("StartupTime: "+startupTime.diff());
|
||||
|
||||
function next () {
|
||||
let found = false;
|
||||
for (const k of Object.keys(katakana).sort()) {
|
||||
if (found) {
|
||||
kana = hiramode ? hiragana[k] : katakana[k];
|
||||
curkana = k;
|
||||
return;
|
||||
}
|
||||
if (curkana === k) {
|
||||
found = true;
|
||||
}
|
||||
const off = keys.indexOf(curkana);
|
||||
if (off !== -1 && off + 1 < keys.length) {
|
||||
return keys[off + 1];
|
||||
}
|
||||
curkana = 'KA';
|
||||
updateWatch(ohhmm);
|
||||
return keys[0];
|
||||
}
|
||||
|
||||
function randKana() {
|
||||
try {
|
||||
const keys = Object.keys(katakana);
|
||||
const total = keys.length;
|
||||
let index = 0 | (Math.random() * total);
|
||||
let index = 0 | (Math.random() * keys.length);
|
||||
curkana = keys[index];
|
||||
} catch (e) {
|
||||
randKana();
|
||||
}
|
||||
}
|
||||
// const bench = benchStart();
|
||||
// console.log("-->" + bench.diff());
|
||||
|
||||
function prev () {
|
||||
let oldk = '';
|
||||
let count = 0;
|
||||
for (const k of Object.keys(katakana).sort()) {
|
||||
if (curkana === k) {
|
||||
if (count > 0) {
|
||||
curkana = oldk;
|
||||
return;
|
||||
}
|
||||
}
|
||||
oldk = k;
|
||||
count++;
|
||||
const off = keys.indexOf(curkana);
|
||||
if (off > 0) {
|
||||
return keys[off - 1];
|
||||
}
|
||||
return keys[keys.length - 1];
|
||||
}
|
||||
let color = 0;
|
||||
const colors = [
|
||||
() => g.setColor(0,1,0),
|
||||
() => g.setColor(1,1,0),
|
||||
() => g.setColor(0,1,1),
|
||||
() => g.setColor(1,1,1),
|
||||
// too dark
|
||||
() => g.setColor(0,0,1),
|
||||
() => g.setColor(0,0,0),
|
||||
() => g.setColor(1,0,0),
|
||||
];
|
||||
|
||||
function nextColor() {
|
||||
if (color + 1 >= colors.length) {
|
||||
color = 0;
|
||||
} else {
|
||||
color++;
|
||||
}
|
||||
}
|
||||
function prevColor() {
|
||||
if (color < 1) {
|
||||
color = colors.length - 1;
|
||||
} else {
|
||||
color--;
|
||||
}
|
||||
curkana = oldk;
|
||||
updateWatch(ohhmm);
|
||||
}
|
||||
|
||||
const kanacolors = {
|
||||
A: []
|
||||
};
|
||||
|
||||
|
||||
function updateWatch (hhmm) {
|
||||
function render(hhmm) {
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
g.setBgColor(0, 0, 0);
|
||||
g.setColor(0, 0, 0);
|
||||
var whitecolor = false;
|
||||
if (curkana.indexOf('A') != -1) {
|
||||
g.setColor(1, 0, 0);
|
||||
whitecolor = true;
|
||||
} else if (curkana.indexOf('I') != -1) {
|
||||
g.setColor(0, 1, 0);
|
||||
} else if (curkana.indexOf('U') != -1) {
|
||||
g.setColor(0, 0, 1);
|
||||
whitecolor = true;
|
||||
} else if (curkana.indexOf('E') != -1) {
|
||||
g.setColor(1, 1, 0);
|
||||
} else {
|
||||
g.setColor(0, 1, 1);
|
||||
}
|
||||
g.fillRect(0, 0, w, h);
|
||||
const whitecolor = color > 3;
|
||||
colors[color]();
|
||||
g.fillRect(0, 30, w, h);
|
||||
|
||||
g.setFont('Vector', 50);
|
||||
if (whitecolor) {
|
||||
|
|
@ -196,9 +228,9 @@ function updateWatch (hhmm) {
|
|||
}
|
||||
g.drawString(hhmm, x, y - 1);
|
||||
|
||||
drawKana(4 + (g.getWidth() / 6), 60);
|
||||
drawKana();
|
||||
drawMonthDay();
|
||||
Bangle.drawWidgets();
|
||||
// Bangle.drawWidgets(); // :? always draw?
|
||||
}
|
||||
|
||||
function drawMonthDay() {
|
||||
|
|
@ -219,21 +251,47 @@ function getPhoneme(k) {
|
|||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
var ohhmm = '';
|
||||
var ypos = 0;
|
||||
var xpos = 0;
|
||||
var zpos = 1;
|
||||
function drawKana (x, y) {
|
||||
if (!x) {
|
||||
x = 4 + (g.getWidth() / 6);
|
||||
}
|
||||
if (!y) {
|
||||
y = 40;
|
||||
}
|
||||
x += xpos;
|
||||
y += ypos;
|
||||
g.setColor(0, 0, 0);
|
||||
g.fillRect(0, 0, g.getWidth(), 6 * (h / 8) + 1);
|
||||
g.fillRect(0, 30, g.getWidth(), 6 * (h / 8) + 1);
|
||||
g.setColor(1, 1, 1);
|
||||
x -= ((zpos) - 1)*50;
|
||||
y -= (zpos - 1)*50;
|
||||
kana = hiramode ? hiragana[curkana] : katakana[curkana];
|
||||
g.drawImage(kana, x + 20, 40, { scale: 1.6 });
|
||||
if (guard) {
|
||||
g.setColor(0.8,0.8,0.8);
|
||||
}
|
||||
g.drawImage(kana, x + 20, y, { scale: 1.6 * zpos });
|
||||
g.setColor(1, 1, 1);
|
||||
g.setFont('Vector', 24);
|
||||
g.drawString(getPhoneme(curkana), 4, 32);
|
||||
g.drawString(hiramode ? 'H' : 'K', w - 20, 32);
|
||||
if (hiramode) {
|
||||
g.setColor(0.2,0.2,0.2)
|
||||
g.drawString('K', w - 20, 32);
|
||||
g.setColor(1, 1, 1);
|
||||
g.drawString('H', w - 20, 32+24);
|
||||
} else {
|
||||
g.setColor(1, 1, 1);
|
||||
g.drawString('K', w - 20, 32);
|
||||
g.setColor(0.2,0.2,0.2)
|
||||
g.drawString('H', w - 20, 32+24);
|
||||
}
|
||||
// g.drawString(hiramode ? 'H' : 'K', w - 20, 32);
|
||||
}
|
||||
|
||||
var ohhmm = '';
|
||||
|
||||
function tickWatch () {
|
||||
const now = Date();
|
||||
month = now.getMonth() + 1;
|
||||
|
|
@ -243,27 +301,127 @@ function tickWatch () {
|
|||
}
|
||||
const hhmm = zpad(now.getHours()) + ':' + zpad(now.getMinutes());
|
||||
if (hhmm !== ohhmm) {
|
||||
randKana();
|
||||
updateWatch(hhmm);
|
||||
ohhmm = hhmm;
|
||||
randKana();
|
||||
render(hhmm);
|
||||
}
|
||||
}
|
||||
let guard = false;
|
||||
function hiraPush(d,dx) {
|
||||
if (guard) {
|
||||
return;
|
||||
}
|
||||
xpos = 0;
|
||||
ypos = 0;
|
||||
zpos = 1;
|
||||
guard = true;
|
||||
var count = 2;
|
||||
function paint() {
|
||||
count--;
|
||||
if (count < 0) {
|
||||
guard = false;
|
||||
xpos = 0;
|
||||
ypos = 0;
|
||||
zpos = 1;
|
||||
render(ohhmm);
|
||||
return;
|
||||
}
|
||||
zpos -= 0.04;
|
||||
render(ohhmm);
|
||||
setTimeout(paint, 100);
|
||||
}
|
||||
setTimeout (paint, 5);
|
||||
}
|
||||
|
||||
function hiraSwipe(d,dx, dostuff) {
|
||||
if (guard) {
|
||||
return;
|
||||
}
|
||||
if (dx) {
|
||||
ypos = 0;
|
||||
} else {
|
||||
ypos = (d * 4);
|
||||
}
|
||||
xpos = 0;
|
||||
guard = true;
|
||||
var count = 2;
|
||||
function paint() {
|
||||
count--;
|
||||
if (count < 0) {
|
||||
if (dx) {
|
||||
curkana = d>0?prev():next();
|
||||
} else {
|
||||
if (dostuff) {
|
||||
hiramode = !hiramode;
|
||||
}
|
||||
}
|
||||
guard = false;
|
||||
xpos = 0;
|
||||
ypos = 0;
|
||||
render(ohhmm);
|
||||
return;
|
||||
}
|
||||
if (dx) {
|
||||
xpos += (8*d);
|
||||
} else {
|
||||
ypos -= (4*d);
|
||||
}
|
||||
render(ohhmm);
|
||||
setTimeout(paint, 5);
|
||||
}
|
||||
setTimeout (paint, 5);
|
||||
}
|
||||
|
||||
Bangle.on('touch', function (tap, top) {
|
||||
if (top.x < w / 4) {
|
||||
prev();
|
||||
} else if (top.x > (w - (w / 4))) {
|
||||
next();
|
||||
if (top.y < (h / 1.5)) {
|
||||
if (top.x > w /2) {
|
||||
//hiramode = !hiramode;
|
||||
if (hiramode) {
|
||||
hiraSwipe(1,0, hiramode);
|
||||
} else {
|
||||
hiraSwipe(-1,0, !hiramode);
|
||||
}
|
||||
} else {
|
||||
hiraSwipe(1,1,1);
|
||||
}
|
||||
} else if (top.x < w / 2) {
|
||||
nextColor();
|
||||
hiraPush();
|
||||
// curkana = prev();
|
||||
} else {
|
||||
hiramode = !hiramode;
|
||||
prevColor();
|
||||
hiraPush();
|
||||
// curkana = next();
|
||||
}
|
||||
kana = hiramode ? hiragana[curkana] : katakana[curkana];
|
||||
updateWatch(ohhmm);
|
||||
render(ohhmm);
|
||||
});
|
||||
Bangle.on('swipe', function (x,y) {
|
||||
if (x > 0) {
|
||||
// nextColor();
|
||||
hiraSwipe(1, 1);
|
||||
} else if (x < 0) {
|
||||
// prevColor();
|
||||
hiraSwipe(-1,1);
|
||||
} else if (y < 0) {
|
||||
hiraSwipe(1, 0, hiramode);
|
||||
} else if (y > 0) {
|
||||
hiraSwipe(-1, 0, !hiramode);
|
||||
}
|
||||
render(ohhmm);
|
||||
});
|
||||
|
||||
g.clear(true);
|
||||
// show launcher when button pressed
|
||||
Bangle.setUI('clock');
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
// redraw widgets every 10 minutes
|
||||
setInterval(function() {
|
||||
// maybe not always necessary
|
||||
Bangle.drawWidgets();
|
||||
}, 1000 * 60 * 10);
|
||||
tickWatch();
|
||||
setInterval(tickWatch, 1000 * 60);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "kanawatch",
|
||||
"name": "Kanawatch",
|
||||
"shortName": "Kanawatch",
|
||||
"version": "0.07",
|
||||
"version": "0.11",
|
||||
"type": "clock",
|
||||
"description": "Learn Hiragana and Katakana",
|
||||
"icon": "app.png",
|
||||
|
|
@ -26,6 +26,9 @@
|
|||
"screenshots": [
|
||||
{
|
||||
"url": "screenshot.png"
|
||||
},
|
||||
{
|
||||
"url": "screenshot2.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -3,3 +3,4 @@
|
|||
0.03: Use default Bangle formatter for booleans
|
||||
0.04: Allow moving the cursor
|
||||
0.05: Switch swipe directions for Caps Lock and moving cursor.
|
||||
0.06: Add ability to auto-lowercase after a capital letter insertion.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ Uses the multitap keypad logic originally from here: http://www.espruino.com/Mor
|
|||

|
||||

|
||||
|
||||
Written by: [Sir Indy](https://github.com/sir-indy) and [Thyttan](https://github.com/thyttan)
|
||||
Written by: [Sir Indy](https://github.com/sir-indy), [Thyttan](https://github.com/thyttan) and [bobrippling](https://github.com/bobrippling).
|
||||
|
||||
For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ exports.input = function(options) {
|
|||
if (settings.firstLaunch===undefined) { settings.firstLaunch = true; }
|
||||
if (settings.charTimeout===undefined) { settings.charTimeout = 500; }
|
||||
if (settings.showHelpBtn===undefined) { settings.showHelpBtn = true; }
|
||||
if (settings.autoLowercase===undefined) { settings.autoLowercase = true; }
|
||||
|
||||
var fontSize = "6x15";
|
||||
var Layout = require("Layout");
|
||||
|
|
@ -89,19 +90,21 @@ exports.input = function(options) {
|
|||
}
|
||||
|
||||
function newCharacter(ch) {
|
||||
displayText();
|
||||
displayText(false);
|
||||
if (ch && textIndex < text.length) textIndex ++;
|
||||
charCurrent = ch;
|
||||
charIndex = 0;
|
||||
}
|
||||
|
||||
function onKeyPad(key) {
|
||||
var retire = 0;
|
||||
deactivateTimeout(charTimeout);
|
||||
// work out which char was pressed
|
||||
if (key==charCurrent) {
|
||||
charIndex = (charIndex+1) % letters[charCurrent].length;
|
||||
text = text.slice(0, -1);
|
||||
} else {
|
||||
retire = charCurrent !== undefined;
|
||||
newCharacter(key);
|
||||
}
|
||||
var newLetter = letters[charCurrent][charIndex];
|
||||
|
|
@ -109,13 +112,22 @@ exports.input = function(options) {
|
|||
let post = text.slice(textIndex, text.length);
|
||||
|
||||
text = pre + (caps ? newLetter.toUpperCase() : newLetter.toLowerCase()) + post;
|
||||
|
||||
if(retire)
|
||||
retireCurrent();
|
||||
|
||||
// set a timeout
|
||||
charTimeout = setTimeout(function() {
|
||||
charTimeout = undefined;
|
||||
newCharacter();
|
||||
retireCurrent();
|
||||
}, settings.charTimeout);
|
||||
displayText(charTimeout);
|
||||
displayText(true);
|
||||
}
|
||||
|
||||
function retireCurrent(why) {
|
||||
if (caps && settings.autoLowercase)
|
||||
setCaps();
|
||||
}
|
||||
|
||||
var moveMode = false;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{ "id": "kbmulti",
|
||||
"name": "Multitap keyboard",
|
||||
"version":"0.05",
|
||||
"version":"0.06",
|
||||
"description": "A library for text input via multitap/T9 style keypad",
|
||||
"icon": "app.png",
|
||||
"type":"textinput",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
var settings = require('Storage').readJSON("kbmulti.settings.json", true) || {};
|
||||
if (settings.showHelpBtn===undefined) { settings.showHelpBtn = true; }
|
||||
if (settings.charTimeout===undefined) { settings.charTimeout = 500; }
|
||||
if (settings.autoLowercase===undefined) { settings.autoLowercase = true; }
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
|
@ -21,6 +22,10 @@
|
|||
format: v => v,
|
||||
onchange: v => updateSetting("charTimeout", v),
|
||||
},
|
||||
/*LANG*/'Lowercase after first uppercase': {
|
||||
value: !!settings().autoLowercase,
|
||||
onchange: v => updateSetting("autoLowercase", v)
|
||||
},
|
||||
/*LANG*/'Show help button?': {
|
||||
value: !!settings().showHelpBtn,
|
||||
onchange: v => updateSetting("showHelpBtn", v)
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@
|
|||
0.05: Keep drag-function in ram, hopefully improving performance and input reliability somewhat.
|
||||
0.06: Support input of numbers and uppercase characters.
|
||||
0.07: Support input of symbols.
|
||||
0.08: Redone patterns a,e,m,w,z.
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ on the left of the IDE, then do a stroke and copy out the Uint8Array line
|
|||
*/
|
||||
exports.getStrokes = function(mode, cb) {
|
||||
if (mode === exports.INPUT_MODE_ALPHA) {
|
||||
cb("a", new Uint8Array([58, 159, 58, 155, 62, 144, 69, 127, 77, 106, 86, 90, 94, 77, 101, 68, 108, 62, 114, 59, 121, 59, 133, 61, 146, 70, 158, 88, 169, 107, 176, 124, 180, 135, 183, 144, 185, 152]));
|
||||
cb("a", new Uint8Array([31, 157, 33, 149, 37, 131, 42, 112, 46, 97, 49, 83, 52, 72, 56, 64, 59, 59, 63, 53, 68, 48, 74, 47, 80, 47, 88, 50, 98, 63, 109, 94, 114, 115, 116, 130, 117, 141]));
|
||||
cb("b", new Uint8Array([51, 47, 51, 77, 56, 123, 60, 151, 65, 163, 68, 164, 68, 144, 67, 108, 67, 76, 72, 43, 104, 51, 121, 74, 110, 87, 109, 95, 131, 117, 131, 140, 109, 152, 88, 157]));
|
||||
cb("c", new Uint8Array([153, 62, 150, 62, 145, 62, 136, 62, 123, 62, 106, 65, 85, 70, 65, 75, 50, 82, 42, 93, 37, 106, 36, 119, 36, 130, 40, 140, 49, 147, 61, 153, 72, 156, 85, 157, 106, 158, 116, 158]));
|
||||
cb("d", new Uint8Array([57, 178, 57, 176, 55, 171, 52, 163, 50, 154, 49, 146, 47, 135, 45, 121, 44, 108, 44, 97, 44, 85, 44, 75, 44, 66, 44, 58, 44, 48, 44, 38, 46, 31, 48, 26, 58, 21, 75, 20, 99, 26, 120, 35, 136, 51, 144, 70, 144, 88, 137, 110, 124, 131, 106, 145, 88, 153]));
|
||||
cb("e", new Uint8Array([150, 72, 141, 69, 114, 68, 79, 69, 48, 77, 32, 81, 31, 85, 46, 91, 73, 95, 107, 100, 114, 103, 83, 117, 58, 134, 66, 143, 105, 148, 133, 148, 144, 148]));
|
||||
cb("e", new Uint8Array([107, 50, 101, 46, 94, 42, 85, 40, 75, 40, 65, 40, 58, 40, 51, 40, 47, 40, 44, 43, 45, 54, 52, 68, 63, 79, 70, 84, 70, 85, 59, 89, 52, 96, 45, 108, 39, 119, 37, 126, 37, 132, 37, 137, 41, 143, 48, 147, 60, 148, 69, 148, 78, 148, 84, 148, 89, 148]));
|
||||
cb("f", new Uint8Array([157, 52, 155, 52, 148, 52, 137, 52, 124, 52, 110, 52, 96, 52, 83, 52, 74, 52, 67, 52, 61, 52, 57, 52, 55, 52, 52, 52, 52, 54, 52, 58, 52, 64, 54, 75, 58, 97, 59, 117, 60, 130]));
|
||||
cb("g", new Uint8Array([160, 66, 153, 62, 129, 58, 90, 56, 58, 57, 38, 65, 31, 86, 43, 125, 69, 152, 116, 166, 145, 154, 146, 134, 112, 116, 85, 108, 97, 106, 140, 106, 164, 106]));
|
||||
cb("h", new Uint8Array([58, 50, 58, 55, 58, 64, 58, 80, 58, 102, 58, 122, 58, 139, 58, 153, 58, 164, 58, 171, 58, 177, 58, 179, 58, 181, 58, 180, 58, 173, 58, 163, 59, 154, 61, 138, 64, 114, 68, 95, 72, 84, 80, 79, 91, 79, 107, 82, 123, 93, 137, 111, 145, 130, 149, 147, 150, 154, 150, 159]));
|
||||
|
|
@ -22,7 +22,7 @@ exports.getStrokes = function(mode, cb) {
|
|||
cb("j", new Uint8Array([130, 57, 130, 61, 130, 73, 130, 91, 130, 113, 130, 133, 130, 147, 130, 156, 130, 161, 130, 164, 130, 166, 129, 168, 127, 168, 120, 168, 110, 168, 91, 167, 81, 167, 68, 167]));
|
||||
cb("k", new Uint8Array([149, 63, 147, 68, 143, 76, 136, 89, 126, 106, 114, 123, 100, 136, 86, 147, 72, 153, 57, 155, 45, 152, 36, 145, 29, 131, 26, 117, 26, 104, 27, 93, 30, 86, 35, 80, 45, 77, 62, 80, 88, 96, 113, 116, 130, 131, 140, 142, 145, 149, 148, 153]));
|
||||
cb("l", new Uint8Array([42, 55, 42, 59, 42, 69, 44, 87, 44, 107, 44, 128, 44, 143, 44, 156, 44, 163, 44, 167, 44, 169, 45, 170, 49, 170, 59, 169, 76, 167, 100, 164, 119, 162, 139, 160, 163, 159]));
|
||||
cb("m", new Uint8Array([49, 165, 48, 162, 46, 156, 44, 148, 42, 138, 42, 126, 42, 113, 43, 101, 45, 91, 47, 82, 49, 75, 51, 71, 54, 70, 57, 70, 61, 74, 69, 81, 75, 91, 84, 104, 94, 121, 101, 132, 103, 137, 106, 130, 110, 114, 116, 92, 125, 75, 134, 65, 139, 62, 144, 66, 148, 83, 151, 108, 155, 132, 157, 149]));
|
||||
cb("m", new Uint8Array([36, 139, 36, 120, 36, 99, 36, 79, 36, 61, 41, 45, 56, 43, 71, 46, 77, 66, 77, 93, 77, 97, 84, 69, 93, 51, 107, 47, 118, 53, 123, 79, 124, 115, 124, 140]));
|
||||
cb("n", new Uint8Array([50, 165, 50, 160, 50, 153, 50, 140, 50, 122, 50, 103, 50, 83, 50, 65, 50, 52, 50, 45, 50, 43, 52, 52, 57, 67, 66, 90, 78, 112, 93, 131, 104, 143, 116, 152, 127, 159, 135, 160, 141, 150, 148, 125, 154, 96, 158, 71, 161, 56, 162, 49]));
|
||||
cb("o", new Uint8Array([107, 58, 104, 58, 97, 61, 87, 68, 75, 77, 65, 88, 58, 103, 54, 116, 53, 126, 55, 135, 61, 143, 75, 149, 91, 150, 106, 148, 119, 141, 137, 125, 143, 115, 146, 104, 146, 89, 142, 78, 130, 70, 116, 65, 104, 62]));
|
||||
cb("p", new Uint8Array([29, 47, 29, 55, 29, 75, 29, 110, 29, 145, 29, 165, 29, 172, 29, 164, 30, 149, 37, 120, 50, 91, 61, 74, 72, 65, 85, 61, 103, 61, 118, 63, 126, 69, 129, 76, 130, 87, 126, 98, 112, 108, 97, 114, 87, 116]));
|
||||
|
|
@ -32,10 +32,10 @@ exports.getStrokes = function(mode, cb) {
|
|||
cb("t", new Uint8Array([45, 55, 48, 55, 55, 55, 72, 55, 96, 55, 120, 55, 136, 55, 147, 55, 152, 55, 155, 55, 157, 55, 158, 56, 158, 60, 156, 70, 154, 86, 151, 102, 150, 114, 148, 125, 148, 138, 148, 146]));
|
||||
cb("u", new Uint8Array([35, 52, 35, 59, 35, 73, 35, 90, 36, 114, 38, 133, 42, 146, 49, 153, 60, 157, 73, 158, 86, 156, 100, 152, 112, 144, 121, 131, 127, 114, 132, 97, 134, 85, 135, 73, 136, 61, 136, 56]));
|
||||
cb("v", new Uint8Array([36, 55, 37, 59, 40, 68, 45, 83, 51, 100, 58, 118, 64, 132, 69, 142, 71, 149, 73, 156, 76, 158, 77, 160, 77, 159, 80, 151, 82, 137, 84, 122, 86, 111, 90, 91, 91, 78, 91, 68, 91, 63, 92, 61, 97, 61, 111, 61, 132, 61, 150, 61, 162, 61]));
|
||||
cb("w", new Uint8Array([25, 46, 25, 82, 25, 119, 33, 143, 43, 153, 60, 147, 73, 118, 75, 91, 76, 88, 85, 109, 96, 134, 107, 143, 118, 137, 129, 112, 134, 81, 134, 64, 134, 55]));
|
||||
cb("w", new Uint8Array([35, 37, 35, 44, 35, 58, 35, 81, 35, 110, 35, 129, 39, 136, 45, 140, 51, 141, 60, 137, 70, 121, 76, 99, 78, 79, 78, 70, 78, 69, 83, 89, 89, 112, 93, 127, 97, 135, 102, 136, 108, 131, 115, 116, 119, 93, 122, 72, 123, 55, 123, 43]));
|
||||
cb("x", new Uint8Array([56, 63, 56, 67, 57, 74, 60, 89, 66, 109, 74, 129, 85, 145, 96, 158, 107, 164, 117, 167, 128, 164, 141, 155, 151, 140, 159, 122, 166, 105, 168, 89, 170, 81, 170, 73, 169, 66, 161, 63, 141, 68, 110, 83, 77, 110, 55, 134, 47, 145]));
|
||||
cb("y", new Uint8Array([30, 41, 30, 46, 30, 52, 30, 63, 30, 79, 33, 92, 38, 100, 47, 104, 54, 107, 66, 105, 79, 94, 88, 82, 92, 74, 94, 77, 96, 98, 96, 131, 94, 151, 91, 164, 85, 171, 75, 171, 71, 162, 74, 146, 84, 130, 95, 119, 106, 113]));
|
||||
cb("z", new Uint8Array([29, 62, 35, 62, 43, 62, 63, 62, 87, 62, 110, 62, 125, 62, 134, 62, 138, 62, 136, 63, 122, 68, 103, 77, 85, 91, 70, 107, 59, 120, 50, 132, 47, 138, 43, 143, 41, 148, 42, 151, 53, 155, 80, 157, 116, 158, 146, 158, 163, 158]));
|
||||
cb("z", new Uint8Array([39, 38, 45, 38, 53, 38, 62, 38, 72, 38, 82, 38, 89, 38, 96, 38, 99, 39, 95, 48, 82, 68, 70, 87, 60, 100, 50, 117, 42, 132, 42, 140, 45, 143, 53, 143, 67, 143, 81, 143]));
|
||||
cb("SHIFT", new Uint8Array([100, 160, 100, 50]));
|
||||
} else if (mode === exports.INPUT_MODE_NUM) {
|
||||
cb("0", new Uint8Array([82, 50, 76, 50, 67, 50, 59, 50, 50, 51, 43, 57, 38, 68, 34, 83, 33, 95, 33, 108, 34, 121, 42, 136, 57, 148, 72, 155, 85, 157, 98, 155, 110, 149, 120, 139, 128, 127, 134, 119, 137, 114, 138, 107, 138, 98, 138, 88, 138, 77, 137, 71, 134, 65, 128, 60, 123, 58]));
|
||||
|
|
@ -210,7 +210,7 @@ exports.input = function(options) {
|
|||
if (o.stroke!==undefined && o.xy.length >= 6 && isStrokeInside(R, o.xy)) {
|
||||
var ch = o.stroke;
|
||||
if (ch=="\b") text = text.slice(0,-1);
|
||||
else if (ch==="SHIFT") { shift=!shift; Bangle.drawWidgets(); }
|
||||
else if (ch==="SHIFT") { shift=!shift; WIDGETS.kbswipe.draw(); }
|
||||
else text += shift ? ch.toUpperCase() : ch;
|
||||
}
|
||||
lastDrag = undefined;
|
||||
|
|
@ -226,7 +226,7 @@ exports.input = function(options) {
|
|||
shift = false;
|
||||
setupStrokes();
|
||||
show();
|
||||
Bangle.drawWidgets();
|
||||
WIDGETS.kbswipe.draw();
|
||||
}
|
||||
|
||||
Bangle.on('stroke',strokeHandler);
|
||||
|
|
@ -239,7 +239,7 @@ exports.input = function(options) {
|
|||
area:"tl",
|
||||
width: 36, // 3 chars, 6*2 px/char
|
||||
draw: function() {
|
||||
g.reset();
|
||||
g.reset().clearRect(this.x, this.y, this.x + this.width-1, this.y + 23);
|
||||
g.setFont("6x8:2x3");
|
||||
g.setColor("#f00");
|
||||
if (input_mode === exports.INPUT_MODE_ALPHA) {
|
||||
|
|
@ -251,6 +251,7 @@ exports.input = function(options) {
|
|||
}
|
||||
}
|
||||
};
|
||||
Bangle.drawWidgets();
|
||||
|
||||
return new Promise((resolve,reject) => {
|
||||
Bangle.setUI({mode:"custom", drag:e=>{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{ "id": "kbswipe",
|
||||
"name": "Swipe keyboard",
|
||||
"version":"0.07",
|
||||
"version":"0.08",
|
||||
"description": "A library for text input via PalmOS style swipe gestures (beta!)",
|
||||
"icon": "app.png",
|
||||
"type":"textinput",
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ exports = { name : "en_GB", currencySym:"£",
|
|||
"%-m": "d.getMonth()+1",
|
||||
"%d": "('0'+d.getDate()).slice(-2)",
|
||||
"%-d": "d.getDate()",
|
||||
"%HH": "('0'+getHours(d)).slice(-2)",
|
||||
"%HH": "getHours(d)",
|
||||
"%MM": "('0'+d.getMinutes()).slice(-2)",
|
||||
"%SS": "('0'+d.getSeconds()).slice(-2)",
|
||||
"%A": `${js(locale.day)}.split(',')[d.getDay()]`,
|
||||
|
|
@ -191,9 +191,9 @@ function round(n, dp) {
|
|||
var is12;
|
||||
function getHours(d) {
|
||||
var h = d.getHours();
|
||||
if (is12===undefined) is12 = (require('Storage').readJSON('setting.json',1)||{})["12hour"];
|
||||
if (!is12) return h;
|
||||
return (h%12==0) ? 12 : h%12;
|
||||
if (is12 === undefined) is12 = (require('Storage').readJSON('setting.json', 1) || {})["12hour"];
|
||||
if (!is12) return ('0' + h).slice(-2);
|
||||
return ((h % 12 == 0) ? 12 : h % 12).toString();
|
||||
}
|
||||
exports = {
|
||||
name: ${js(locale.lang)},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* jshint esversion: 6 */
|
||||
const distanceUnits = { // how many meters per X?
|
||||
"m": 1,
|
||||
"ft": 0.3048,
|
||||
"yd": 0.9144,
|
||||
"mi": 1609.34,
|
||||
"km": 1000,
|
||||
|
|
@ -160,7 +161,7 @@ var locales = {
|
|||
currency_symbol: "$", currency_first: true,
|
||||
int_curr_symbol: "USD",
|
||||
speed: "mph",
|
||||
distance: { 0: "m", 1: "mi" },
|
||||
distance: { 0: "ft", 1: "mi" },
|
||||
temperature: "°F",
|
||||
ampm: { 0: "am", 1: "pm" },
|
||||
timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" },
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ function showMapMessage(msg) {
|
|||
if (msg.distance!==undefined)
|
||||
distance = require("locale").distance(msg.distance);
|
||||
if (msg.instr) {
|
||||
if (msg.instr.includes("towards")) {
|
||||
m = msg.instr.split("towards");
|
||||
if (msg.instr.includes("towards") || msg.instr.includes("toward")) {
|
||||
m = msg.instr.split(/towards|toward/);
|
||||
target = m[0].trim();
|
||||
street = m[1].trim();
|
||||
}else
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@
|
|||
0.10: Improvements to help notifications work with themes
|
||||
0.11: Fix regression that caused no notifications and corrupted background
|
||||
0.12: Add Bangle.js 2 support with Bangle.setLCDOverlay
|
||||
0.13: Add a default title background for the dark theme
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "notify",
|
||||
"name": "Notifications (default)",
|
||||
"shortName": "Notifications",
|
||||
"version": "0.12",
|
||||
"version": "0.13",
|
||||
"description": "Provides the default `notify` module used by applications to display notifications on the screen. This module is installed by default by client applications such as the Gadgetbridge app. Installing `Fullscreen Notifications` replaces this module with a version that displays the notifications using the full screen",
|
||||
"icon": "notify.png",
|
||||
"type": "notify",
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ exports.show = function(options) {
|
|||
b -= 2;h -= 2;
|
||||
// title bar
|
||||
if (options.title || options.src) {
|
||||
g.setColor(options.titleBgColor||0x39C7).fillRect(x,y, r,y+20);
|
||||
g.setColor("titleBgColor" in options ? options.titleBgColor : g.theme.dark ? 0x1 : 0x39C7).fillRect(x,y, r,y+20);
|
||||
const title = options.title||options.src;
|
||||
g.setColor(g.theme.fg).setFontAlign(-1, -1, 0).setFont("6x8", 2);
|
||||
g.drawString(title.trim().substring(0, 13), x+25,y+3);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ exports.show = function(options) {
|
|||
gg.clearRect(x,y, r,b);
|
||||
// title bar
|
||||
if (options.title || options.src) {
|
||||
gg.setColor(options.titleBgColor||0x39C7).fillRect(x,y, r,y+20);
|
||||
gg.setColor("titleBgColor" in options ? options.titleBgColor : g.theme.dark ? 0x1 : 0x39C7).fillRect(x,y, r,y+20);
|
||||
const title = options.title||options.src;
|
||||
gg.setColor(g.theme.fg).setFontAlign(-1, -1, 0).setFont("6x8", 2);
|
||||
gg.drawString(title.trim().substring(0, 13), x+25,y+3);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
0.01: New App!
|
||||
0.02: New Results menu item to show the formula and values used.
|
||||
0.03: Adds haptics to Input screen and long press "C" to go back.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Ohm's Law Calculator
|
||||
|
||||
This is a simple and intuitive Ohm's Law Calculator application designed for the Bangle.js 2 Smartwatch. The calculator focuses on providing an easy-to-navigate user interface with automatic calculation logic, allowing you to quickly and efficiently calculate electrical measurements, including Voltage, Current, Resistance, and Power.
|
||||
|
||||
## Usage Guide
|
||||
|
||||
* __Select the Electrical Measurement:__ On the main menu, select the electrical measurement that you wish to calculate (Voltage, Current, Resistance, or Power).
|
||||
* __Enter Known Values:__ You will then be prompted to enter the known values. The application will present a menu listing the remaining electrical measurements. Select one and you will be taken to a numeric input screen. Repeat this step for the second known value.
|
||||
* __View Results:__ Once the two known values have been entered, the application will automatically calculate and display the value of the selected electrical measurement. The Results menu will show the calculated value, the unit of measurement, and the formula used for calculation.
|
||||
* __Navigation:__ Whether you're deep in calculations or perusing the results, the power to navigate the app remains in your hands. While the 'Back' button is present in most scenarios, it isn't available in the Results menu and the Input screen. However, you can always return to the beginning by selecting 'Main Menu' from the Results menu. And if you're on the numeric Input screen, simply hold down the 'Clear' button to navigate back.
|
||||
|
||||
## Compatibility
|
||||
|
||||
This app was built and tested with Bangle.js 2.
|
||||
|
||||
## Feedback
|
||||
|
||||
If you have any issues or suggestions, please open an issue on this GitHub repository. Contributions to improve the application are also welcomed.
|
||||
|
||||
## Creator
|
||||
|
||||
[stweedo](https://github.com/stweedo)
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwxH+AH4AyQBIvmnM/AAk5F8pWBFwoABMDweGgEHF48HCAw2VE4MGDAgvCRIIACSoIvFgEGG4wuPKAYZCgENn8UgFVqsAik/hoNDC4ouUAAMOLAYoBF4Ok0gGEFwUOTJQuPAAM4DIIJCFAI2GRYM4ZRguNg7pIh0NhpXDAwIVIGBguFdwJlHABbTCgwwPCIgQB1V6dYSXGQ4zzCvWqIwhNBMBwvBvVPbokUKQQADg7BBSQUAp5FBDojANFAQmCAoTxCgEsmc0mkzlgxCMoQwBFwYFBFxgvBgAaCcYcUgEBmdfAA0zCoJiCegc4BIIvNeQwuCg4qEg8rAwowDdhwvLI4IuFLIIHFGAT4EF5rdEJAkHgImHF41fI4p2BAAYtIg8HhpGECwK7FXAQvHBQJIEikNEYIxGgE5UQh2FLw0rlYvHMAwAEnIvDGgIJDigABAwUAlhTGwAvBmgABnQMDlgfDDwRVDMAYvETocOAwSOFLwPVp6wEGAY8BC4MOBgYvMqukgENXwU0Lw3V5+kAALDFBoLaBhsA0lVF6U4F4rFBFgXP6uANoovVR5U6RQlP6ryGR6jvMnTqCYQJeGd6AwBBIYAFRIIiEeQheGr7FBDxE5FwZgCCQMHhqkBIwZTGYYYKGRwJ4DDIMNEYIoCF4YxEAAIWEMBAIBLxhIBAAYtFGYwXEnAmHF4JeFA4J4EAwIrLF5JICGAq9GE4J2EF6JsBI4UNhx5EYY67CFwcOhp3DGB0AFQTQCAoU4AwUsmYAClgHBg5EChwGCAoaNQE4N6p4wDMQIxCAAcHRYYoBp96DoouLgyjE1QZBPYQAEnDmEAAUNIoOqbYkGGBTsFCIL0GABhsCJoZgOFAkHFxEOAASZDNwYVFFxgwHdogJCii+DXoIGCgyXGFxwwHboIoG0mkAwgWBgBnDFyIwFVYQICQgIoBqtVF4TrBBoQXFFyAwDeAI4GnJmDnImGSYIuUJQbKMKxAXGAC4eBF44oeGBCJBAAiVBF0hgCAA4vlGI4tnADg="))
|
||||
|
|
@ -0,0 +1,373 @@
|
|||
let Layout = require("Layout");
|
||||
|
||||
// Definitions for units and formulas for electrical measurements.
|
||||
const UNITS = {
|
||||
"Voltage (V)": "Volts",
|
||||
"Current (I)": "Amps",
|
||||
"Resistance (R)": "Ohms",
|
||||
"Power (P)": "Watts",
|
||||
};
|
||||
|
||||
const FORMULAS = {
|
||||
'Voltage (V)': {
|
||||
'Current (I), Resistance (R)': { equation: "{0} * {1}", display: "V = I * R" },
|
||||
'Power (P), Current (I)': { equation: "{0} / {1}", display: "V = P / I" },
|
||||
'Power (P), Resistance (R)': { equation: "Math.sqrt({0} * {1})", display: "V = sqrt(P * R)" }
|
||||
},
|
||||
'Current (I)': {
|
||||
'Voltage (V), Resistance (R)': { equation: "{0} / {1}", display: "I = V / R" },
|
||||
'Power (P), Voltage (V)': { equation: "{0} / {1}", display: "I = P / V" },
|
||||
'Power (P), Resistance (R)': { equation: "Math.sqrt({0} / {1})", display: "I = sqrt(P / R)" }
|
||||
},
|
||||
'Resistance (R)': {
|
||||
'Voltage (V), Current (I)': { equation: "{0} / {1}", display: "R = V / I" },
|
||||
'Power (P), Current (I)': { equation: "{0} / (Math.pow({1}, 2))", display: "R = P / I^2" },
|
||||
'Power (P), Voltage (V)': { equation: "(Math.pow({1}, 2)) / {0}", display: "R = V^2 / P" }
|
||||
},
|
||||
'Power (P)': {
|
||||
'Voltage (V), Current (I)': { equation: "{0} * {1}", display: "P = V * I" },
|
||||
'Current (I), Resistance (R)': { equation: "(Math.pow({0}, 2)) * {1}", display: "P = I^2 * R" },
|
||||
'Voltage (V), Resistance (R)': { equation: "(Math.pow({0}, 2)) / {1}", display: "P = V^2 / R" }
|
||||
},
|
||||
};
|
||||
|
||||
// Screen positioning settings
|
||||
let btnSize = 23;
|
||||
let xCenter = g.getWidth() / 2;
|
||||
let yCenter = g.getHeight() / 2;
|
||||
|
||||
// Variables to hold state
|
||||
let lastStringWidth = 0;
|
||||
let halfStringWidth = lastStringWidth / 2;
|
||||
let calculatedVariable;
|
||||
let selectedVariable;
|
||||
let variableValues = {};
|
||||
let inputStr = "";
|
||||
let invalidInput = false;
|
||||
|
||||
// Function references
|
||||
let handleEnter;
|
||||
let showVariableSelectionMenu;
|
||||
let showInputMenu;
|
||||
let resultsMenu;
|
||||
let mainMenu;
|
||||
|
||||
// Setup the layout for input buttons
|
||||
let layout = new Layout({
|
||||
type: "v",
|
||||
c: [
|
||||
{ type: "txt", font: "6x8:3", label: "", id: "label" },
|
||||
{ type: "h", c: "123".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, fillx: 1, filly: 1 })) },
|
||||
{ type: "h", c: "456".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, fillx: 1, filly: 1 })) },
|
||||
{ type: "h", c: "789".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, fillx: 1, filly: 1 })) },
|
||||
{ type: "h", c: ".0C".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, cbl: i === "C" ? () => { showVariableSelectionMenu(); Bangle.buzz(20); } : undefined, fillx: 1, filly: 1 })) },
|
||||
{ type: "h", c: [{ type: "btn", font: "6x8:2", label: "Enter", cb: () => { handleEnter(); }, fillx: 1, filly: 1 }] }
|
||||
]
|
||||
}, { lazy: false });
|
||||
|
||||
// Clears area at the top of the screen where the text is displayed
|
||||
function clearTextArea() { // Except Back Button
|
||||
let x2 = g.getWidth();
|
||||
g.clearRect(0, 0, x2, btnSize);
|
||||
}
|
||||
|
||||
// Function to clear the entire screen, except for the Back button
|
||||
function clearScreen() {
|
||||
let x2 = g.getWidth();
|
||||
let y2 = g.getHeight();
|
||||
g.clearRect(btnSize, 0, x2, btnSize);
|
||||
g.clearRect(0, btnSize, x2, y2);
|
||||
}
|
||||
|
||||
// Function to set up and display the calculator input screen
|
||||
function showCalculatorInputScreen(variable) {
|
||||
selectedVariable = variable;
|
||||
layout.setUI();
|
||||
layout.render();
|
||||
}
|
||||
|
||||
// Function to set and display the current value of the input
|
||||
// Adjusts the font size to fit the screen width
|
||||
function setValue(newStr) {
|
||||
clearTextArea();
|
||||
inputStr = newStr;
|
||||
|
||||
// Here we check the width of the string and adjust the font size
|
||||
// Start with a standard font size and increase if the string is too wide
|
||||
let fontSize = "6x8:3"; // start with a standard size
|
||||
g.setFont(fontSize);
|
||||
|
||||
// If the string is too long to fit on the screen, adjust the font size
|
||||
while (g.stringWidth(inputStr) > g.getWidth() - 10 && fontSize !== "6x8:1") {
|
||||
fontSize = "6x8:" + (Number(fontSize.split(":")[1]) - 1).toString();
|
||||
g.setFont(fontSize);
|
||||
}
|
||||
|
||||
layout.label.label = inputStr;
|
||||
g.drawString(inputStr, layout.label.x, layout.label.y + 11);
|
||||
lastStringWidth = g.stringWidth(inputStr);
|
||||
}
|
||||
|
||||
// Function to handle the press of a button and append its value to the current input
|
||||
function handleButtonPress(value) {
|
||||
Bangle.buzz(20);
|
||||
if (invalidInput) {
|
||||
return; // Don't allow input if an invalid input error message is displayed
|
||||
}
|
||||
inputStr = value === 'C' ? '' : inputStr + value;
|
||||
setValue(inputStr);
|
||||
}
|
||||
|
||||
// Function to format the unit of measurement
|
||||
function formatUnit(unit, value) {
|
||||
return parseFloat(value) === 1 ? unit.slice(0, -1) : unit;
|
||||
}
|
||||
|
||||
// Calculates the value of the selected variable based on the entered values
|
||||
// Also handles rounding and trimming of long decimal numbers
|
||||
function calculateValue(calculatedVariable, variableValues) {
|
||||
let formulas = FORMULAS[calculatedVariable];
|
||||
let formulaKeys = Object.keys(formulas);
|
||||
for (let i = 0; i < formulaKeys.length; i++) {
|
||||
let formulaKey = formulaKeys[i];
|
||||
let variables = formulaKey.split(', ');
|
||||
if (variables.every(variable => variableValues.hasOwnProperty(variable))) {
|
||||
let formulaData = formulas[formulaKey];
|
||||
let formula = formulaData.equation;
|
||||
let formulaDisplay = formulaData.display;
|
||||
let formulaValues = variables.map(variable => variableValues[variable]);
|
||||
let calculatedValue = eval(formula.replace(/\{(\d+)\}/g, (_, index) => formulaValues[index]));
|
||||
|
||||
// Check if the number is an integer
|
||||
let isInteger = Math.floor(calculatedValue) === calculatedValue;
|
||||
|
||||
// Round and trim long decimal numbers
|
||||
if (!isInteger) {
|
||||
calculatedValue = calculatedValue.toFixed(3);
|
||||
calculatedValue = calculatedValue.replace(/\.0+$/, '').replace(/(\.\d*[1-9])0+$/, '$1');
|
||||
}
|
||||
|
||||
let result = Object.entries(variableValues).map(function (entry) {
|
||||
let variable = entry[0];
|
||||
let value = entry[1];
|
||||
return [variable, `${value} ${formatUnit(UNITS[variable], value.toString())}`];
|
||||
});
|
||||
result.push([calculatedVariable, `${calculatedValue} ${formatUnit(UNITS[calculatedVariable], calculatedValue.toString())}`]);
|
||||
return {
|
||||
formula: formulaDisplay.replace(/\{(\d+)\}/g, (_, index) => formulaValues[index]),
|
||||
value: calculatedValue,
|
||||
unit: formatUnit(UNITS[calculatedVariable], calculatedValue),
|
||||
result: result,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main function to initialize the application and setup the main menu
|
||||
(function () {
|
||||
mainMenu = {
|
||||
'': { 'title': 'Ohm\'s Law Calc' },
|
||||
'< Back': () => Bangle.showClock()
|
||||
};
|
||||
|
||||
Object.keys(UNITS).forEach(unit => {
|
||||
mainMenu[unit] = () => handleUnitSelection(unit);
|
||||
});
|
||||
|
||||
// Function to present the menu for selecting the variable
|
||||
// Filters out the calculated variable and already set variables from the menu
|
||||
showVariableSelectionMenu = function () {
|
||||
clearScreen();
|
||||
let variableSelectionMenu = {
|
||||
'': { 'title': 'Select Variable' },
|
||||
'< Back': () => {
|
||||
E.showMenu(mainMenu);
|
||||
variableValues = {};
|
||||
}
|
||||
};
|
||||
let variables = Object.keys(UNITS);
|
||||
let remainingVariables = variables.filter(v => v !== calculatedVariable && !variableValues[v]);
|
||||
remainingVariables.forEach(variable => {
|
||||
variableSelectionMenu[variable] = function () {
|
||||
showInputMenu(variable);
|
||||
};
|
||||
});
|
||||
E.showMenu(variableSelectionMenu);
|
||||
};
|
||||
|
||||
// Function to handle the input of variable values
|
||||
// It sets the current selected variable and displays the calculator input screen
|
||||
showInputMenu = function (variable) {
|
||||
setValue("");
|
||||
selectedVariable = variable;
|
||||
let inputMenu = {
|
||||
'': { 'title': variable },
|
||||
};
|
||||
E.showMenu(inputMenu);
|
||||
showCalculatorInputScreen(variable);
|
||||
};
|
||||
|
||||
// Function to handle the event of pressing 'Enter'
|
||||
// It checks if the input is valid, if so, it saves the value and
|
||||
// either calculates the result (if enough variables are present) or opens variable selection menu
|
||||
handleEnter = function () {
|
||||
// Check if the input is valid
|
||||
if (inputStr === "" || isNaN(inputStr) || (inputStr.match(/\./g) || []).length > 1) {
|
||||
// Show error message
|
||||
setValue("Invalid Input");
|
||||
invalidInput = true; // Prevent further input
|
||||
// Clear error message after 2 seconds
|
||||
setTimeout(() => {
|
||||
setValue('');
|
||||
invalidInput = false; // Allow input again
|
||||
}, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (calculatedVariable === null) {
|
||||
return;
|
||||
}
|
||||
variableValues[selectedVariable] = parseFloat(inputStr);
|
||||
if (Object.keys(variableValues).length === 2) {
|
||||
let result = calculateValue(calculatedVariable, variableValues);
|
||||
showResultsScreen(result);
|
||||
calculatedVariable = null;
|
||||
variableValues = {};
|
||||
} else {
|
||||
setValue("");
|
||||
showVariableSelectionMenu();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
// Function to handle the selection of a unit of electical measurement
|
||||
function handleUnitSelection(unit) {
|
||||
calculatedVariable = unit;
|
||||
showVariableSelectionMenu();
|
||||
}
|
||||
|
||||
// Function to display the results screen with the calculated value
|
||||
function drawValueScreen
|
||||
(result) {
|
||||
let drawPage = function () {
|
||||
clearScreen();
|
||||
let fontSize = g.getHeight() / 3;
|
||||
g.setFontVector(fontSize);
|
||||
|
||||
// Reduce the font size until both the value and unit fit on the screen
|
||||
while (g.stringWidth(result.value) > g.getWidth() - 10 || g.getFontHeight() > g.getHeight() / 2) {
|
||||
fontSize--;
|
||||
g.setFontVector(fontSize);
|
||||
}
|
||||
|
||||
let valueY = yCenter - g.getFontHeight() / 2;
|
||||
let unitY = yCenter + g.getFontHeight() / 2;
|
||||
let valueWidth = g.stringWidth(result.value);
|
||||
let unitWidth = g.stringWidth(result.unit);
|
||||
let valueX = (g.getWidth() - valueWidth) / 2;
|
||||
let unitX = (g.getWidth() - unitWidth) / 2;
|
||||
|
||||
g.drawString(result.value, valueX, valueY);
|
||||
g.drawString(result.unit, unitX, unitY);
|
||||
g.flip();
|
||||
};
|
||||
|
||||
// Shows the back button on the value screen
|
||||
return function () {
|
||||
clearScreen();
|
||||
let valueMenu = {
|
||||
'': { 'title': 'Results' },
|
||||
'< Back': function () {
|
||||
E.showMenu(resultsMenu);
|
||||
}
|
||||
};
|
||||
E.showMenu(valueMenu);
|
||||
drawPage();
|
||||
};
|
||||
}
|
||||
|
||||
// Function to display the results screen with the values from the result.result array
|
||||
function drawResultScreen(result) {
|
||||
let drawPage = function() {
|
||||
clearScreen();
|
||||
let fontSize = 30; // Initial font size
|
||||
let lineSpacing = 15; // Space between lines
|
||||
|
||||
// Define the vertical positions of the titles
|
||||
let titlePositions = [10, 72, 132];
|
||||
|
||||
for (let i = 0; i < result.result.length; i++) {
|
||||
let currentResult = result.result[i];
|
||||
let resultTitle = currentResult[0];
|
||||
let resultValue = currentResult[1];
|
||||
|
||||
// Draw title
|
||||
g.setFontVector(fontSize / 2); // Small font for title
|
||||
let titleX = (g.getWidth() - g.stringWidth(resultTitle)) / 2;
|
||||
let titleY = titlePositions[i]; // Get the vertical position for the title
|
||||
g.drawString(resultTitle, titleX, titleY); // Draw at the desired position
|
||||
|
||||
let underlineYPosition = titleY + g.getFontHeight() - 3;
|
||||
g.drawLine(titleX, underlineYPosition, titleX + g.stringWidth(resultTitle), underlineYPosition); // Draw underline
|
||||
|
||||
let valueX;
|
||||
let valueY = titleY + g.getFontHeight(); // Draw below the title
|
||||
|
||||
// Calculate the font size for value dynamically
|
||||
g.setFontVector(fontSize);
|
||||
while (g.stringWidth(resultValue) > g.getWidth() - 10) {
|
||||
fontSize--; // Reduce the font size by 1
|
||||
g.setFontVector(fontSize);
|
||||
}
|
||||
|
||||
valueY += g.getFontHeight() / 2 + 2;
|
||||
valueX = (g.getWidth() - g.stringWidth(resultValue)) / 2;
|
||||
g.drawString(resultValue, valueX, valueY); // Draw at the desired position
|
||||
|
||||
// Move down for the next entry
|
||||
let nextTitleY = (i + 1 < titlePositions.length) ? titlePositions[i + 1] : titleY + 1.5 * fontSize + lineSpacing;
|
||||
yPosition = nextTitleY;
|
||||
}
|
||||
g.flip();
|
||||
};
|
||||
|
||||
// Shows the back button on the result screen
|
||||
return function() {
|
||||
clearScreen();
|
||||
let resultMenu = {
|
||||
'': { 'title': 'Results' },
|
||||
'< Back': function() {
|
||||
E.showMenu(resultsMenu);
|
||||
}
|
||||
};
|
||||
E.showMenu(resultMenu);
|
||||
drawPage();
|
||||
};
|
||||
}
|
||||
|
||||
// Shows the results menu with the calculated results and options
|
||||
function showResultsScreen(result) {
|
||||
let backButton = function () {
|
||||
clearScreen();
|
||||
E.showMenu(resultsMenu);
|
||||
};
|
||||
g.clear();
|
||||
resultsMenu = {
|
||||
'': { 'title': 'Results' },
|
||||
'Main Menu': function () {
|
||||
E.showMenu(mainMenu);
|
||||
},
|
||||
};
|
||||
resultsMenu[result.value + ' ' + result.unit] = drawValueScreen(result);
|
||||
resultsMenu[result.formula] = drawResultScreen(result);
|
||||
resultsMenu['Exit'] = function () {
|
||||
Bangle.showClock();
|
||||
};
|
||||
E.showMenu(resultsMenu);
|
||||
}
|
||||
|
||||
clearTextArea();
|
||||
E.showMenu(mainMenu);
|
||||
|
||||
})();
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"id": "ohmcalc",
|
||||
"name": "Ohm's Law Calculator",
|
||||
"shortName": "Ohm's Law Calc",
|
||||
"version": "0.03",
|
||||
"description": "A smart and simple calculator for Ohm's Law calculations, designed specifically for Bangle.js 2 smartwatches. Handles voltage, current, resistance, and power calculations with smart logic to prevent invalid inputs.",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
"tags": "calculator, utilities, electric",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"storage": [{
|
||||
"name": "ohmcalc.app.js",
|
||||
"url": "app.js"
|
||||
},
|
||||
{
|
||||
"name": "ohmcalc.img",
|
||||
"url": "app-icon.js",
|
||||
"evaluate": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: Fixes colors not matching user input from color menu in some cases, 3 bands are now shown larger, various code improvements.
|
||||
|
|
@ -3,75 +3,19 @@
|
|||
// https://icons8.com/icon/ISAVBnskZod0/resistor
|
||||
|
||||
let colorData = {
|
||||
black: {
|
||||
value: 0,
|
||||
multiplier: Math.pow(10, 0),
|
||||
hex: '#000'
|
||||
},
|
||||
brown: {
|
||||
value: 1,
|
||||
multiplier: Math.pow(10, 1),
|
||||
tolerance: 1,
|
||||
hex: '#8B4513'
|
||||
},
|
||||
red: {
|
||||
value: 2,
|
||||
multiplier: Math.pow(10, 2),
|
||||
tolerance: 2,
|
||||
hex: '#f00'
|
||||
},
|
||||
orange: {
|
||||
value: 3,
|
||||
multiplier: Math.pow(10, 3),
|
||||
hex: '#FF9900'
|
||||
},
|
||||
yellow: {
|
||||
value: 4,
|
||||
multiplier: Math.pow(10, 4),
|
||||
hex: '#ff0'
|
||||
},
|
||||
green: {
|
||||
value: 5,
|
||||
multiplier: Math.pow(10, 5),
|
||||
tolerance: 0.5,
|
||||
hex: '#0f0'
|
||||
},
|
||||
blue: {
|
||||
value: 6,
|
||||
multiplier: Math.pow(10, 6),
|
||||
tolerance: 0.25,
|
||||
hex: '#00f'
|
||||
},
|
||||
violet: {
|
||||
value: 7,
|
||||
multiplier: Math.pow(10, 7),
|
||||
tolerance: 0.1,
|
||||
hex: '#f0f'
|
||||
},
|
||||
grey: {
|
||||
value: 8,
|
||||
multiplier: Math.pow(10, 8),
|
||||
tolerance: 0.05,
|
||||
hex: '#808080'
|
||||
},
|
||||
white: {
|
||||
value: 9,
|
||||
multiplier: Math.pow(10, 9),
|
||||
hex: '#fff'
|
||||
},
|
||||
gold: {
|
||||
multiplier: Math.pow(10, -1),
|
||||
tolerance: 5,
|
||||
hex: '#FFD700'
|
||||
},
|
||||
silver: {
|
||||
multiplier: Math.pow(10, -2),
|
||||
tolerance: 10,
|
||||
hex: '#C0C0C0'
|
||||
},
|
||||
none: {
|
||||
tolerance: 20
|
||||
},
|
||||
black: { value: 0, multiplier: 1, hex: '#000' },
|
||||
brown: { value: 1, multiplier: 10, tolerance: 1, hex: '#8B4513' },
|
||||
red: { value: 2, multiplier: 100, tolerance: 2, hex: '#f00' },
|
||||
orange: { value: 3, multiplier: 1000, hex: '#FF9900' },
|
||||
yellow: { value: 4, multiplier: 10000, hex: '#ff0' },
|
||||
green: { value: 5, multiplier: 100000, tolerance: 0.5, hex: '#0f0' },
|
||||
blue: { value: 6, multiplier: 1000000, tolerance: 0.25, hex: '#00f' },
|
||||
violet: { value: 7, multiplier: 10000000, tolerance: 0.1, hex: '#f0f' },
|
||||
grey: { value: 8, multiplier: 100000000, tolerance: 0.05, hex: '#808080' },
|
||||
white: { value: 9, multiplier: 1000000000, hex: '#fff' },
|
||||
gold: { multiplier: 0.1, tolerance: 5, hex: '#FFD700' },
|
||||
silver: { multiplier: 0.01, tolerance: 10, hex: '#C0C0C0' },
|
||||
none: { tolerance: 20 },
|
||||
};
|
||||
|
||||
function clearScreen() { // Except Back Button
|
||||
|
|
@ -91,38 +35,55 @@ function colorBandsToResistance(colorBands) {
|
|||
return [resistance, tolerance];
|
||||
}
|
||||
|
||||
function log10(val) {
|
||||
return Math.log(val) / Math.log(10);
|
||||
}
|
||||
|
||||
function resistanceToColorBands(resistance, tolerance) {
|
||||
let multiplier = Math.floor(log10(resistance));
|
||||
let firstDigit = Math.floor(resistance / Math.pow(10, multiplier));
|
||||
resistance -= firstDigit * Math.pow(10, multiplier);
|
||||
multiplier--; // for the next digit
|
||||
let secondDigit = Math.floor(resistance / Math.pow(10, multiplier));
|
||||
resistance -= secondDigit * Math.pow(10, multiplier);
|
||||
console.log("First Digit: " + firstDigit);
|
||||
console.log("Second Digit: " + secondDigit);
|
||||
console.log("Multiplier: " + multiplier);
|
||||
let firstBandEntry = Object.entries(colorData).find(function(entry) {
|
||||
let firstDigit, secondDigit, multiplier;
|
||||
if (resistance < 1) {
|
||||
// The resistance is less than 1, so we need to handle this case specially
|
||||
let count = 0;
|
||||
while (resistance < 1) {
|
||||
resistance *= 10;
|
||||
count++;
|
||||
}
|
||||
// Now, resistance is a whole number and count is how many times we had to multiply by 10
|
||||
let resistanceStr = resistance.toString();
|
||||
firstDigit = 0; // Set the first band color to be black
|
||||
secondDigit = Number(resistanceStr.charAt(0)); // Set the second band color to be the significant digit
|
||||
// Use count to determine the multiplier
|
||||
multiplier = count === 1 ? 0.1 : 0.01;
|
||||
} else {
|
||||
// Convert the resistance to a string so we can manipulate it easily
|
||||
let resistanceStr = resistance.toString();
|
||||
if (resistanceStr.length === 1) { // Check if resistance is a single digit
|
||||
firstDigit = 0;
|
||||
secondDigit = Number(resistanceStr.charAt(0));
|
||||
multiplier = 1; // Set multiplier to 1 for single digit resistance values
|
||||
} else {
|
||||
// Extract the first two digits from the resistance value
|
||||
firstDigit = Number(resistanceStr.charAt(0));
|
||||
secondDigit = Number(resistanceStr.charAt(1));
|
||||
// Calculate the multiplier by matching it directly with the length of digits
|
||||
multiplier = resistanceStr.length - 2 >= 0 ? Math.pow(10, resistanceStr.length - 2) : Math.pow(10, resistanceStr.length - 1);
|
||||
}
|
||||
}
|
||||
let firstBandEntry = Object.entries(colorData).find(function (entry) {
|
||||
return entry[1].value === firstDigit;
|
||||
});
|
||||
let firstBand = firstBandEntry ? firstBandEntry[1].hex : undefined;
|
||||
let secondBandEntry = Object.entries(colorData).find(function(entry) {
|
||||
let secondBandEntry = Object.entries(colorData).find(function (entry) {
|
||||
return entry[1].value === secondDigit;
|
||||
});
|
||||
let secondBand = secondBandEntry ? secondBandEntry[1].hex : undefined;
|
||||
let multiplierBandEntry = Object.entries(colorData).find(function(entry) {
|
||||
return entry[1].multiplier === Math.pow(10, multiplier);
|
||||
let multiplierBandEntry = Object.entries(colorData).find(function (entry) {
|
||||
return entry[1].multiplier === multiplier;
|
||||
});
|
||||
let multiplierBand = multiplierBandEntry ? multiplierBandEntry[1].hex : undefined;
|
||||
let toleranceBandEntry = Object.entries(colorData).find(function(entry) {
|
||||
let toleranceBandEntry = Object.entries(colorData).find(function (entry) {
|
||||
return entry[1].tolerance === tolerance;
|
||||
});
|
||||
let toleranceBand = toleranceBandEntry ? toleranceBandEntry[1].hex : undefined;
|
||||
console.log("Color bands: " + [firstBand, secondBand, multiplierBand, toleranceBand]);
|
||||
return [firstBand, secondBand, multiplierBand, toleranceBand];
|
||||
let bands = [firstBand, secondBand, multiplierBand];
|
||||
if (toleranceBand) bands.push(toleranceBand);
|
||||
return bands;
|
||||
}
|
||||
|
||||
function drawResistor(colorBands, tolerance) {
|
||||
|
|
@ -130,32 +91,27 @@ function drawResistor(colorBands, tolerance) {
|
|||
let resistorBodyWidth = 51;
|
||||
let resistorBodyHeight = 43;
|
||||
let resistorStartX = 52;
|
||||
var bandColors = colorBands;
|
||||
var numcolorBands = bandColors.length;
|
||||
var resistorStartY = ((g.getHeight() - resistorBodyHeight) / 2) + 48;
|
||||
let bandColors = colorBands;
|
||||
let numColorBands = bandColors.length;
|
||||
let resistorStartY = ((g.getHeight() - resistorBodyHeight) / 2) + 48;
|
||||
clearScreen();
|
||||
g.drawImage(img, 0, 112);
|
||||
var bandWidth = (resistorBodyWidth - (numcolorBands * 2 - 1)) / numcolorBands; // width of each band, accounting for the spacing
|
||||
var bandHeight = resistorBodyHeight; // height of each band
|
||||
var currentX = resistorStartX; // starting point for the first band
|
||||
let bandWidth = (resistorBodyWidth - (numColorBands * 2 - 1)) / numColorBands; // width of each band, accounting for the spacing
|
||||
let bandHeight = resistorBodyHeight; // height of each band
|
||||
let currentX = resistorStartX; // starting point for the first band
|
||||
// Define the tolerance values that will trigger the fourth band
|
||||
var validTolerances = [1, 2, 0.5, 0.25, 0.1, 0.05, 5, 10];
|
||||
|
||||
for (var i = 0; i < numcolorBands; i++) {
|
||||
let validTolerances = [1, 2, 0.5, 0.25, 0.1, 0.05, 5, 10];
|
||||
for (let i = 0; i < numColorBands; i++) {
|
||||
// Skip the fourth band and its outlines if the tolerance is not in the valid list
|
||||
if (i === 3 && !validTolerances.includes(tolerance)) continue;
|
||||
|
||||
var bandX = currentX; // calculate the x-coordinate of the band
|
||||
var bandY = resistorStartY; // y-coordinate of the band
|
||||
|
||||
let bandX = currentX; // calculate the x-coordinate of the band
|
||||
let bandY = resistorStartY; // y-coordinate of the band
|
||||
g.setColor(bandColors[i]); // set the color for the band
|
||||
g.fillRect(bandX, bandY, bandX + bandWidth, bandY + bandHeight);
|
||||
|
||||
// Draw band outlines
|
||||
g.setColor('#000'); // set the color for the outline
|
||||
g.drawLine(bandX, bandY, bandX, bandY + bandHeight); // left outline
|
||||
g.drawLine(bandX + bandWidth, bandY, bandX + bandWidth, bandY + bandHeight); // right outline
|
||||
|
||||
// if it's the fourth band, shift it over by an additional 12 pixels
|
||||
if (i === 2) {
|
||||
currentX = bandX + bandWidth + 5 + 12; // update the current X position for the next band, accounting for the spacing
|
||||
|
|
@ -170,14 +126,14 @@ function omega() {
|
|||
}
|
||||
|
||||
function formatResistance(resistance) {
|
||||
var units = ["", "k", "M", "G"];
|
||||
var unitIndex = 0;
|
||||
let units = ["", "k", "M", "G"];
|
||||
let unitIndex = 0;
|
||||
while (resistance >= 1000 && unitIndex < units.length - 1) {
|
||||
resistance /= 1000;
|
||||
unitIndex++;
|
||||
}
|
||||
// Convert to string and truncate unnecessary zeroes
|
||||
var resistanceStr = String(resistance);
|
||||
let resistanceStr = String(resistance);
|
||||
if (resistanceStr.length > 5) { // if length is more than 5 including decimal point
|
||||
resistanceStr = resistance.toFixed(2);
|
||||
}
|
||||
|
|
@ -188,49 +144,40 @@ function formatResistance(resistance) {
|
|||
}
|
||||
|
||||
function drawResistance(resistance, tolerance) {
|
||||
var x = g.getWidth() / 2;
|
||||
var y = 40;
|
||||
var formattedResistance = formatResistance(resistance);
|
||||
var resistanceStr = formattedResistance.value;
|
||||
var unit = formattedResistance.unit;
|
||||
let x = g.getWidth() / 2;
|
||||
let y = 40;
|
||||
let formattedResistance = formatResistance(resistance);
|
||||
let resistanceStr = formattedResistance.value;
|
||||
let unit = formattedResistance.unit;
|
||||
g.reset();
|
||||
|
||||
// draw resistance value
|
||||
g.setFontAlign(0, 0).setFont("Vector", 54);
|
||||
g.clearRect(0, y - 15, g.getWidth(), y + 25); // clear the background
|
||||
g.drawString(resistanceStr, x + 4, y);
|
||||
|
||||
// draw unit, symbol and tolerance
|
||||
// draw unit, symbol, and tolerance
|
||||
y += 46;
|
||||
g.setFontAlign(-1, 0).setFont("Vector", 27);
|
||||
|
||||
var toleranceShift = tolerance.toString().replace('.', '').length > 2 ? 8 : 0;
|
||||
var unitX = ((unit === "M" || unit === "G") ? 0 : 8) - toleranceShift;
|
||||
var omegaX = (unit ? 46 : 36) - toleranceShift; // Shift the Omega symbol to the left if there is no unit
|
||||
|
||||
let toleranceShift = tolerance.toString().replace('.', '').length > 2 ? 8 : 0;
|
||||
let unitX = ((unit === "M" || unit === "G") ? 0 : 8) - toleranceShift;
|
||||
let omegaX = (unit ? 46 : 36) - toleranceShift; // Shift the Omega symbol to the left if there is no unit
|
||||
g.drawString(unit.padStart(3), unitX, y);
|
||||
|
||||
// Draw the Ohm symbol to the right of the unit
|
||||
g.drawImage(omega(), omegaX, y - 13, {
|
||||
scale: 0.45
|
||||
});
|
||||
|
||||
g.drawImage(omega(), omegaX, y - 13, { scale: 0.45 });
|
||||
g.setFontAlign(1, 0).setFont("Vector", 27);
|
||||
|
||||
// Define the tolerance values that will trigger the fourth band
|
||||
var validTolerances = [1, 2, 0.5, 0.25, 0.1, 0.05, 5, 10];
|
||||
|
||||
let validTolerances = [1, 2, 0.5, 0.25, 0.1, 0.05, 5, 10];
|
||||
// Check if the tolerance is not in the valid list, and if it's not, set it to 20
|
||||
if (!validTolerances.includes(tolerance)) {
|
||||
tolerance = 20;
|
||||
}
|
||||
|
||||
var toleranceStr = "±" + tolerance + "%";
|
||||
var toleranceX = tolerance.toString().replace('.', '').length > 2 ? 10 : 14;
|
||||
let toleranceStr = "±" + tolerance + "%";
|
||||
let toleranceX = tolerance.toString().replace('.', '').length > 2 ? 10 : 14;
|
||||
g.drawString(toleranceStr.padEnd(4), 176 - toleranceX, y);
|
||||
}
|
||||
|
||||
(function() {
|
||||
(function () {
|
||||
let colorBands;
|
||||
let inputColorBands;
|
||||
let settings = {
|
||||
resistance: 0,
|
||||
tolerance: 0,
|
||||
|
|
@ -244,6 +191,8 @@ function drawResistance(resistance, tolerance) {
|
|||
colorBands: ["", "", "", ""]
|
||||
};
|
||||
settings = emptySettings;
|
||||
colorBands = null;
|
||||
inputColorBands = null;
|
||||
}
|
||||
|
||||
function showColorBandMenu(bandNumber) {
|
||||
|
|
@ -251,7 +200,7 @@ function drawResistance(resistance, tolerance) {
|
|||
'': {
|
||||
'title': `Band ${bandNumber}`
|
||||
},
|
||||
'< Back': function() {
|
||||
'< Back': function () {
|
||||
E.showMenu(colorEntryMenu);
|
||||
},
|
||||
};
|
||||
|
|
@ -260,24 +209,24 @@ function drawResistance(resistance, tolerance) {
|
|||
for (let color in colorData) {
|
||||
if (bandNumber === 1 || bandNumber === 2) {
|
||||
if (color !== 'none' && color !== 'gold' && color !== 'silver') {
|
||||
(function(color) {
|
||||
colorBandMenu[color.charAt(0).toUpperCase() + color.slice(1)] = function() {
|
||||
(function (color) {
|
||||
colorBandMenu[color.charAt(0).toUpperCase() + color.slice(1)] = function () {
|
||||
setBandColor(bandNumber, color);
|
||||
};
|
||||
})(color);
|
||||
}
|
||||
} else if (bandNumber === 3) {
|
||||
if (color !== 'none') {
|
||||
(function(color) {
|
||||
colorBandMenu[color.charAt(0).toUpperCase() + color.slice(1)] = function() {
|
||||
(function (color) {
|
||||
colorBandMenu[color.charAt(0).toUpperCase() + color.slice(1)] = function () {
|
||||
setBandColor(bandNumber, color);
|
||||
};
|
||||
})(color);
|
||||
}
|
||||
} else if (bandNumber === 4) {
|
||||
if (colorData[color].hasOwnProperty('tolerance')) {
|
||||
(function(color) {
|
||||
colorBandMenu[color.charAt(0).toUpperCase() + color.slice(1)] = function() {
|
||||
(function (color) {
|
||||
colorBandMenu[color.charAt(0).toUpperCase() + color.slice(1)] = function () {
|
||||
setBandColor(bandNumber, color);
|
||||
};
|
||||
})(color);
|
||||
|
|
@ -289,11 +238,8 @@ function drawResistance(resistance, tolerance) {
|
|||
|
||||
function setBandColor(bandNumber, color) {
|
||||
settings.colorBands[bandNumber - 1] = color; // arrays are 0-indexed
|
||||
console.log(`Band ${bandNumber} color set to ${color}`);
|
||||
|
||||
// Update the color band in the colorEntryMenu
|
||||
colorEntryMenu[`${bandNumber}:`].value = color;
|
||||
|
||||
showColorEntryMenu();
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +248,7 @@ function drawResistance(resistance, tolerance) {
|
|||
'': {
|
||||
'title': 'Band Color'
|
||||
},
|
||||
'< Back': function() {
|
||||
'< Back': function () {
|
||||
clearScreen();
|
||||
E.showMenu(mainMenu);
|
||||
},
|
||||
|
|
@ -338,9 +284,9 @@ function drawResistance(resistance, tolerance) {
|
|||
setTimeout(() => showColorBandMenu(4), 5);
|
||||
}
|
||||
},
|
||||
'Draw Resistor': function() {
|
||||
let colorBands = settings.colorBands;
|
||||
let values = colorBandsToResistance(colorBands);
|
||||
'Draw Resistor': function () {
|
||||
inputColorBands = settings.colorBands;
|
||||
let values = colorBandsToResistance(inputColorBands);
|
||||
settings.resistance = values[0];
|
||||
settings.tolerance = values[1];
|
||||
showDrawingMenu();
|
||||
|
|
@ -355,7 +301,7 @@ function drawResistance(resistance, tolerance) {
|
|||
'': {
|
||||
'title': 'Multiplier'
|
||||
},
|
||||
'< Back': function() {
|
||||
'< Back': function () {
|
||||
showResistanceEntryMenu();
|
||||
}
|
||||
};
|
||||
|
|
@ -367,9 +313,8 @@ function drawResistance(resistance, tolerance) {
|
|||
let formattedMultiplier = formatMultiplier(multiplierValue);
|
||||
multiplierMenu[`${formattedMultiplier}`] = () => {
|
||||
settings.multiplier = multiplierValue;
|
||||
console.log(`Multiplier changed to: ${settings.multiplier}`);
|
||||
// Update the value of 'Multiplier' in resistanceEntryMenu
|
||||
resistanceEntryMenu["Multiplier"] = function() {
|
||||
resistanceEntryMenu["Multiplier"] = function () {
|
||||
showMultiplierMenu();
|
||||
};
|
||||
showResistanceEntryMenu();
|
||||
|
|
@ -395,7 +340,7 @@ function drawResistance(resistance, tolerance) {
|
|||
'': {
|
||||
'title': 'Tolerance'
|
||||
},
|
||||
'< Back': function() {
|
||||
'< Back': function () {
|
||||
showResistanceEntryMenu();
|
||||
}
|
||||
};
|
||||
|
|
@ -406,22 +351,29 @@ function drawResistance(resistance, tolerance) {
|
|||
let tolerance = parseFloat(colorData[color].tolerance); // Parse the tolerance as a float
|
||||
toleranceMenu[`${tolerance}%`] = () => {
|
||||
settings.tolerance = tolerance;
|
||||
console.log(settings.tolerance);
|
||||
// Update the value of 'Tolerance (%)' in resistanceEntryMenu
|
||||
resistanceEntryMenu["Tolerance (%)"] = function() {
|
||||
resistanceEntryMenu["Tolerance (%)"] = function () {
|
||||
showToleranceMenu();
|
||||
};
|
||||
showResistanceEntryMenu();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
E.showMenu(toleranceMenu);
|
||||
}
|
||||
|
||||
function drawResistorAndResistance(resistance, tolerance, multipliedResistance) {
|
||||
console.log('Draw Resistor clicked');
|
||||
let colorBands = resistanceToColorBands(multipliedResistance || resistance, tolerance);
|
||||
function drawResistorAndResistance(resistance, tolerance) {
|
||||
if (inputColorBands) {
|
||||
colorBands = inputColorBands.map(color => {
|
||||
if (colorData.hasOwnProperty(color)) {
|
||||
return colorData[color].hex;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
colorBands = resistanceToColorBands(resistance, tolerance);
|
||||
}
|
||||
drawResistor(colorBands, tolerance);
|
||||
drawResistance(resistance, tolerance);
|
||||
resetSettings();
|
||||
|
|
@ -431,7 +383,7 @@ function drawResistance(resistance, tolerance) {
|
|||
'': {
|
||||
'title': 'Resistance'
|
||||
},
|
||||
'< Back': function() {
|
||||
'< Back': function () {
|
||||
clearScreen();
|
||||
E.showMenu(mainMenu);
|
||||
},
|
||||
|
|
@ -441,15 +393,15 @@ function drawResistance(resistance, tolerance) {
|
|||
max: 99,
|
||||
wrap: true,
|
||||
format: v => '',
|
||||
onchange: v => {}
|
||||
onchange: v => { }
|
||||
},
|
||||
'Multiplier': function() {
|
||||
'Multiplier': function () {
|
||||
showMultiplierMenu();
|
||||
},
|
||||
'Tolerance (%)': function() {
|
||||
'Tolerance (%)': function () {
|
||||
showToleranceMenu();
|
||||
},
|
||||
'Draw Resistor': function() {
|
||||
'Draw Resistor': function () {
|
||||
showDrawingMenu();
|
||||
}
|
||||
};
|
||||
|
|
@ -469,25 +421,21 @@ function drawResistance(resistance, tolerance) {
|
|||
};
|
||||
resistanceEntryMenu['Ohms'].onchange = v => {
|
||||
settings.resistance = v || 0;
|
||||
console.log('Resistance changed to: ', settings.resistance);
|
||||
};
|
||||
|
||||
E.showMenu(resistanceEntryMenu);
|
||||
}
|
||||
|
||||
function showDrawingMenu() {
|
||||
let drawingMenu = {
|
||||
'': {
|
||||
'title': 'Resistor Drawing'
|
||||
'title': ''
|
||||
},
|
||||
'< Back': function() {
|
||||
'< Back': function () {
|
||||
clearScreen();
|
||||
E.showMenu(mainMenu);
|
||||
},
|
||||
};
|
||||
|
||||
E.showMenu(drawingMenu);
|
||||
|
||||
let resistance = settings.resistance * (settings.multiplier || 1);
|
||||
let tolerance = settings.tolerance;
|
||||
drawResistorAndResistance(resistance, tolerance);
|
||||
|
|
@ -498,14 +446,14 @@ function drawResistance(resistance, tolerance) {
|
|||
'title': 'Resistor Calc'
|
||||
},
|
||||
'< Back': () => Bangle.showClock(), // return to the clock app
|
||||
'Resistance': function() {
|
||||
'Resistance': function () {
|
||||
resetSettings();
|
||||
showResistanceEntryMenu();
|
||||
},
|
||||
'Colors': function() {
|
||||
'Colors': function () {
|
||||
resetSettings();
|
||||
showColorEntryMenu();
|
||||
},
|
||||
};
|
||||
E.showMenu(mainMenu);
|
||||
})();
|
||||
})();
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Resistor Calculator",
|
||||
"shortName": "Resistor Calc",
|
||||
"icon": "rescalc.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"screenshots": [
|
||||
{"url": "screenshot.png"},
|
||||
{"url": "screenshot-1.png"},
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@
|
|||
0.13: Revert #1578 (stop duplicate entries) as with 2v12 menus it causes other boxes to be wiped (fix #1643)
|
||||
0.14: Fix Bangle.js 1 issue where after the 'overwrite track' menu, the start/stop button stopped working
|
||||
0.15: Keep run state between runs (allowing you to exit and restart the app)
|
||||
0.16: Added ability to resume a run that was stopped previously (fix #1907)
|
||||
0.16: Added ability to resume a run that was stopped previously (fix #1907)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@
|
|||
0.12: Fix for recorder not stopping at end of run. Bug introduced in 0.11
|
||||
0.13: Revert #1578 (stop duplicate entries) as with 2v12 menus it causes other boxes to be wiped (fix #1643)
|
||||
0.14: Fix Bangle.js 1 issue where after the 'overwrite track' menu, the start/stop button stopped working
|
||||
0.15: Diverge from the standard "Run" app. Swipe to intensity interface a la Karvonen (curtesy of FTeacher at https://github.com/f-teacher)
|
||||
Keep run state between runs (allowing you to exit and restart the app)
|
||||
0.16: Don't clear zone 2b indicator segment when updating HRM reading.
|
||||
Write to correct settings file, fixing settings not working.
|
||||
0.17: Fix typo in variable name preventing starting a run.
|
||||
0.18: Tweak HRM min/max defaults. Extend min/max intervals in settings. Fix
|
||||
another typo.
|
||||
0.15: Keep run state between runs (allowing you to exit and restart the app)
|
||||
0.16: Added ability to resume a run that was stopped previously (fix #1907)
|
||||
0.17: Diverge from the standard "Run" app. Swipe to intensity interface a la Karvonen (curtesy of FTeacher at https://github.com/f-teacher)
|
||||
0.18: Don't clear zone 2b indicator segment when updating HRM reading.
|
||||
Write to correct settings file, fixing settings not working.
|
||||
0.19: Fix typo in variable name preventing starting a run
|
||||
0.20: Tweak HRM min/max defaults. Extend min/max intervals in settings. Fix
|
||||
another typo.
|
||||
0.21: Rebase on "Run" app ver. 0.16.
|
||||
|
|
|
|||
|
|
@ -61,36 +61,47 @@ function setStatus(running) {
|
|||
|
||||
// Called to start/stop running
|
||||
function onStartStop() {
|
||||
let running = !exs.state.active;
|
||||
let prepPromises = [];
|
||||
var running = !exs.state.active;
|
||||
var shouldResume = false;
|
||||
var promise = Promise.resolve();
|
||||
|
||||
if (running && exs.state.duration > 10000) { // if more than 10 seconds of duration, ask if we should resume?
|
||||
promise = promise.
|
||||
then(() => {
|
||||
isMenuDisplayed = true;
|
||||
return E.showPrompt("Resume run?",{title:"Run"});
|
||||
}).then(r => {
|
||||
isMenuDisplayed=false;shouldResume=r;
|
||||
});
|
||||
}
|
||||
|
||||
// start/stop recording
|
||||
// Do this first in case recorder needs to prompt for
|
||||
// an overwrite before we start tracking exstats
|
||||
if (settings.record && WIDGETS["recorder"]) {
|
||||
if (running) {
|
||||
isMenuDisplayed = true;
|
||||
prepPromises.push(
|
||||
WIDGETS["recorder"].setRecording(true).then(() => {
|
||||
promise = promise.
|
||||
then(() => WIDGETS["recorder"].setRecording(true, { force : shouldResume?"append":undefined })).
|
||||
then(() => {
|
||||
isMenuDisplayed = false;
|
||||
layout.setUI(); // grab our input handling again
|
||||
layout.forgetLazyState();
|
||||
layout.render();
|
||||
})
|
||||
);
|
||||
});
|
||||
} else {
|
||||
prepPromises.push(
|
||||
WIDGETS["recorder"].setRecording(false)
|
||||
promise = promise.then(
|
||||
() => WIDGETS["recorder"].setRecording(false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!prepPromises.length) // fix for Promise.all bug in 2v12
|
||||
prepPromises.push(Promise.resolve());
|
||||
|
||||
Promise.all(prepPromises)
|
||||
.then(() => {
|
||||
promise = promise.then(() => {
|
||||
if (running) {
|
||||
exs.start();
|
||||
if (shouldResume)
|
||||
exs.resume()
|
||||
else
|
||||
exs.start();
|
||||
} else {
|
||||
exs.stop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "runplus",
|
||||
"name": "Run+",
|
||||
"version": "0.18",
|
||||
"version": "0.21",
|
||||
"description": "Displays distance, time, steps, cadence, pace and more for runners. Based on the Run app, but extended with additional screen for heart rate interval training.",
|
||||
"icon": "app.png",
|
||||
"tags": "run,running,fitness,outdoors,gps,karvonen,karvonnen",
|
||||
|
|
|
|||
|
|
@ -66,4 +66,5 @@ of 'Select Clock'
|
|||
0.58: On/Off settings items now use checkboxes
|
||||
0.59: Preserve BLE whitelist even when disabled
|
||||
0.60: Moved LCD calibration to top of menu, and use 12 taps (not 8)
|
||||
LCD calibration will now error if the calibration is obviously wrong
|
||||
LCD calibration will now error if the calibration is obviously wrong
|
||||
0.61: Permit temporary bypass of the BLE whitelist
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "setting",
|
||||
"name": "Settings",
|
||||
"version": "0.60",
|
||||
"version": "0.61",
|
||||
"description": "A menu for setting up Bangle.js",
|
||||
"icon": "settings.png",
|
||||
"tags": "tool,system",
|
||||
|
|
|
|||
|
|
@ -658,6 +658,7 @@ function showUtilMenu() {
|
|||
function makeConnectable() {
|
||||
try { NRF.wake(); } catch (e) { }
|
||||
Bluetooth.setConsole(1);
|
||||
NRF.ignoreWhitelist = 1;
|
||||
var name = "Bangle.js " + NRF.getAddress().substr(-5).replace(":", "");
|
||||
E.showPrompt(name + /*LANG*/"\nStay Connectable?", { title: /*LANG*/"Connectable" }).then(r => {
|
||||
if (settings.ble != r) {
|
||||
|
|
@ -665,6 +666,7 @@ function makeConnectable() {
|
|||
updateSettings();
|
||||
}
|
||||
if (!r) try { NRF.sleep(); } catch (e) { }
|
||||
delete NRF.ignoreWhitelist;
|
||||
showMainMenu();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
0.01: New App!
|
||||
0.02: New 'Settings Menu' to choose your favorite color and switch between light or dark themes
|
||||
0.03: New 'Leading Zero' and 'Date Suffix' options in 'Settings Menu'
|
||||
0.04: Updated settings menu to better maintain app settings and system settings
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ let color = appSettings.color !== undefined ? appSettings.color : "#0ff";
|
|||
let enableLeadingZero = appSettings.enableLeadingZero !== undefined ? appSettings.enableLeadingZero : false;
|
||||
let enableSuffix = appSettings.enableSuffix !== undefined ? appSettings.enableSuffix : true;
|
||||
|
||||
// Draw the time and date
|
||||
(function () {
|
||||
let drawTimeout;
|
||||
|
||||
|
|
@ -46,30 +45,17 @@ let enableSuffix = appSettings.enableSuffix !== undefined ? appSettings.enableSu
|
|||
var y = g.getHeight() / 2;
|
||||
g.reset().clearRect(Bangle.appRect);
|
||||
var date = new Date();
|
||||
var hour = date.getHours();
|
||||
var minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
var locale = require("locale");
|
||||
var timeStr = locale.time(date, 1);
|
||||
|
||||
// Handle 12-hour format
|
||||
if (is12Hour) {
|
||||
hour = hour % 12 || 12; // Convert 0 to 12 for 12-hour format
|
||||
} else {
|
||||
// If the leading zero option is enabled and hour is less than 10, add leading zero
|
||||
if (enableLeadingZero && hour < 10) {
|
||||
hour = '0' + hour;
|
||||
}
|
||||
}
|
||||
|
||||
var timeStr = hour + ':' + minutes;
|
||||
|
||||
// Handle midnight in 12-hour format specifically
|
||||
if (is12Hour && hour === 0) {
|
||||
timeStr = '12' + timeStr.substring(2);
|
||||
// If 24-hour format and leading zero should be removed
|
||||
if (!is12Hour && !enableLeadingZero && timeStr.charAt(0) === '0') {
|
||||
timeStr = timeStr.substr(1);
|
||||
}
|
||||
|
||||
g.setFontAlign(0, 0).setFont("LondrinaSolid").setColor(color).drawString(timeStr, x - 1, y);
|
||||
g.reset().setFontAlign(0, 0).setFont("LondrinaShadow").drawString(timeStr, x - 1, y);
|
||||
|
||||
var locale = require("locale");
|
||||
var dayOfMonth = date.getDate();
|
||||
var month = locale.month(date, 1).slice(0, 1).toUpperCase() + locale.month(date, 1).slice(1).toLowerCase();
|
||||
var year = date.getFullYear();
|
||||
|
|
@ -110,4 +96,4 @@ let enableSuffix = appSettings.enableSuffix !== undefined ? appSettings.enableSu
|
|||
Bangle.loadWidgets();
|
||||
draw();
|
||||
setTimeout(Bangle.drawWidgets, 0);
|
||||
})();
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "shadowclk",
|
||||
"name": "Shadow Clock",
|
||||
"version": "0.03",
|
||||
"version": "0.04",
|
||||
"description": "A simple clock using the Londrina font in color with a shadowed outline. Based on the Anton Clock.",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{
|
||||
|
|
@ -32,4 +32,4 @@
|
|||
"data": [{
|
||||
"name": "shadowclk.json"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,18 @@
|
|||
theme: 'light',
|
||||
enableSuffix: true,
|
||||
enableLeadingZero: false,
|
||||
enable12Hour: false // default time mode
|
||||
enable12Hour: false
|
||||
}, require('Storage').readJSON("shadowclk.json", true) || {});
|
||||
|
||||
// Check if shadowclk is the selected clock
|
||||
if (sysSettings.clock === "shadowclk.app.js") {
|
||||
// Sync app settings with system settings
|
||||
appSettings.theme = sysSettings.theme.dark ? 'dark' : 'light';
|
||||
if (sysSettings['12hour'] !== undefined) {
|
||||
appSettings.enable12Hour = sysSettings['12hour'];
|
||||
}
|
||||
}
|
||||
|
||||
// Colors from 'Light BW' and 'Dark BW' themes
|
||||
function createThemeColors(mode) {
|
||||
let cl = x => g.setColor(x).getColor();
|
||||
|
|
@ -37,9 +46,10 @@
|
|||
// Switch theme and save to storage
|
||||
function switchTheme(mode) {
|
||||
if (mode === g.theme.dark) return;
|
||||
let s = require('Storage').readJSON("setting.json", 1) || {};
|
||||
s.theme = createThemeColors(mode);
|
||||
require('Storage').writeJSON("setting.json", s);
|
||||
sysSettings.theme = createThemeColors(mode);
|
||||
if (sysSettings.clock === "shadowclk.app.js") {
|
||||
require('Storage').writeJSON("setting.json", sysSettings);
|
||||
}
|
||||
updateTheme(mode);
|
||||
}
|
||||
|
||||
|
|
@ -85,8 +95,10 @@
|
|||
}
|
||||
|
||||
function writeTimeModeSetting() {
|
||||
sysSettings['12hour'] = appSettings.enable12Hour;
|
||||
require('Storage').writeJSON("setting.json", sysSettings);
|
||||
if (sysSettings.clock === "shadowclk.app.js") {
|
||||
sysSettings['12hour'] = appSettings.enable12Hour;
|
||||
require('Storage').writeJSON("setting.json", sysSettings);
|
||||
}
|
||||
}
|
||||
|
||||
function showMenu() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
0.01: New App!
|
||||
0.02: Add "from Consec."-setting
|
||||
0.03: Correct how to ignore last triggered alarm
|
||||
0.04: Make "disable alarm" possible on next day; correct alarm filtering; improve settings
|
||||
0.04: Make "disable alarm" possible on next day; correct alarm filtering; improve settings
|
||||
0.05: Correct hide function + replace all `var` with `let`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Sleep Log Alarm
|
||||
|
||||
This widget searches for active alarms and raises an own alarm event up to the defined time earlier, if in light sleep or awake phase. Optional the earlier alarm will only be triggered if comming from or in consecutive sleep. The settings of the earlier alarm can be adjusted and it is possible to filter the targeting alarms by time and message. By default the time of the targeting alarm is displayed inside the widget which can be adjusted, too.
|
||||
This widget searches for active alarms and raises an own alarm event up to the defined time earlier, if in light sleep or awake phase. Optional the earlier alarm will only be triggered if comming from or in consecutive sleep. The settings of the earlier alarm can be adjusted and it is possible to filter the targeting alarms by time and message. The widget is only displayed if an active alarm is detected. The time of the targeting alarm is displayed inside the widget, too. The time or the complete widget can be hidden in the options.
|
||||
|
||||
_This widget does not detect sleep on its own and can not create alarms. It requires the [sleeplog](/apps/?id=sleeplog) app and any alarm app that uses [sched](/apps/?id=sched) to be installed._
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ _This widget does not detect sleep on its own and can not create alarms. It requ
|
|||
- __msg includes__ | include only alarms including this string in msg
|
||||
__""__ / ...
|
||||
- __Widget__ submenu
|
||||
- __hide__ | completely hide the widget
|
||||
- __hide always__ | completely hide the widget
|
||||
_on_ / __off__
|
||||
- __show time__ | show the time of the targeting alarm
|
||||
__on__ / _off_
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// load library
|
||||
var sched = require("sched");
|
||||
let sched = require("sched");
|
||||
|
||||
// find next active alarm in range
|
||||
function getNextAlarm(allAlarms, fo, withId) {
|
||||
|
|
@ -10,7 +10,7 @@ function getNextAlarm(allAlarms, fo, withId) {
|
|||
// return next active alarms in range, filter for
|
||||
// active && not timer && not own alarm &&
|
||||
// after from && before to && includes msg
|
||||
var ret = allAlarms.filter(
|
||||
let ret = allAlarms.filter(
|
||||
a => a.on && !a.timer && a.id !== "sleeplog" &&
|
||||
a.t >= fo.from && a.t < fo.to && (!fo.msg || a.msg.includes(fo.msg))
|
||||
).map(a => { // add time to alarm
|
||||
|
|
@ -21,7 +21,7 @@ function getNextAlarm(allAlarms, fo, withId) {
|
|||
).sort((a, b) => a.tTo - b.tTo);
|
||||
// prevent triggering for an already triggered alarm again if available
|
||||
if (fo.lastDate) {
|
||||
var toLast = fo.lastDate - new Date().valueOf() + 1000;
|
||||
let toLast = fo.lastDate - new Date().valueOf() + 1000;
|
||||
if (toLast > 0) ret = ret.filter(a => a.tTo > toLast);
|
||||
}
|
||||
// return first entry
|
||||
|
|
@ -59,7 +59,7 @@ exports = {
|
|||
if (typeof (global.sleeplog || {}).trigger !== "object") return;
|
||||
|
||||
// read settings to calculate alarm range
|
||||
var settings = exports.getSettings();
|
||||
let settings = exports.getSettings();
|
||||
|
||||
// set the alarm time
|
||||
this.time = getNextAlarm(sched.getAlarms(), settings.filter).t;
|
||||
|
|
@ -68,7 +68,7 @@ exports = {
|
|||
if (!this.time) return;
|
||||
|
||||
// set widget width if not hidden
|
||||
if (!this.hidden) this.width = 8;
|
||||
if (!settings.wid.hide) this.width = 8;
|
||||
|
||||
// insert sleeplogalarm conditions and function
|
||||
sleeplog.trigger.sleeplogalarm = {
|
||||
|
|
@ -87,22 +87,22 @@ exports = {
|
|||
// trigger function
|
||||
trigger: function() {
|
||||
// read settings
|
||||
var settings = exports.getSettings();
|
||||
let settings = exports.getSettings();
|
||||
|
||||
// read all alarms
|
||||
var allAlarms = sched.getAlarms();
|
||||
let allAlarms = sched.getAlarms();
|
||||
|
||||
// find first active alarm
|
||||
var alarm = getNextAlarm(sched.getAlarms(), settings.filter, settings.disableOnAlarm);
|
||||
let alarm = getNextAlarm(sched.getAlarms(), settings.filter, settings.disableOnAlarm);
|
||||
|
||||
// return if no alarm is found
|
||||
if (!alarm) return;
|
||||
|
||||
// get now
|
||||
var now = new Date();
|
||||
let now = new Date();
|
||||
|
||||
// get date of the alarm
|
||||
var aDate = new Date(now + alarm.tTo);
|
||||
let aDate = new Date(now + alarm.tTo);
|
||||
|
||||
// disable earlier triggered alarm if set
|
||||
if (settings.disableOnAlarm) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"id":"sleeplogalarm",
|
||||
"name":"Sleep Log Alarm",
|
||||
"shortName": "SleepLogAlarm",
|
||||
"version": "0.04",
|
||||
"version": "0.05",
|
||||
"description": "Enhance your morning and let your alarms wake you up when you are in light sleep.",
|
||||
"icon": "app.png",
|
||||
"type": "widget",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
(function(back) {
|
||||
// read settings
|
||||
var settings = require("sleeplogalarm").getSettings();
|
||||
let settings = require("sleeplogalarm").getSettings();
|
||||
|
||||
// write change to storage
|
||||
function writeSetting() {
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
// show widget menu
|
||||
function showFilterMenu() {
|
||||
// set menu
|
||||
var filterMenu = {
|
||||
let filterMenu = {
|
||||
"": {
|
||||
title: "Filter Alarm"
|
||||
},
|
||||
|
|
@ -64,22 +64,22 @@
|
|||
})
|
||||
}
|
||||
};
|
||||
var menu = E.showMenu(filterMenu);
|
||||
let menu = E.showMenu(filterMenu);
|
||||
}
|
||||
|
||||
// show widget menu
|
||||
function showWidMenu() {
|
||||
// define color values and names
|
||||
var colName = ["red", "yellow", "green", "cyan", "blue", "magenta", "black", "white"];
|
||||
var colVal = [63488, 65504, 2016, 2047, 31, 63519, 0, 65535];
|
||||
let colName = ["red", "yellow", "green", "cyan", "blue", "magenta", "black", "white"];
|
||||
let colVal = [63488, 65504, 2016, 2047, 31, 63519, 0, 65535];
|
||||
|
||||
// set menu
|
||||
var widgetMenu = {
|
||||
let widgetMenu = {
|
||||
"": {
|
||||
title: "Widget Settings"
|
||||
},
|
||||
/*LANG*/"< Back": () => showMain(9),
|
||||
/*LANG*/"hide": {
|
||||
/*LANG*/"hide always": {
|
||||
value: settings.wid.hide,
|
||||
onchange: v => {
|
||||
settings.wid.hide = v;
|
||||
|
|
@ -105,13 +105,13 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
var menu = E.showMenu(widgetMenu);
|
||||
let menu = E.showMenu(widgetMenu);
|
||||
}
|
||||
|
||||
// show main menu
|
||||
function showMain(selected) {
|
||||
// set menu
|
||||
var mainMenu = {
|
||||
let mainMenu = {
|
||||
"": {
|
||||
title: "Sleep Log Alarm",
|
||||
selected: selected
|
||||
|
|
@ -184,7 +184,7 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
var menu = E.showMenu(mainMenu);
|
||||
let menu = E.showMenu(mainMenu);
|
||||
}
|
||||
|
||||
// draw main menu
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// check if enabled in settings
|
||||
if ((require("Storage").readJSON("sleeplogalarm.settings.json", true) || {enabled: true}).enabled) {
|
||||
// read settings
|
||||
settings = require("sleeplogalarm").getSettings(); // is undefined if used with var
|
||||
let settings = require("sleeplogalarm").getSettings();
|
||||
|
||||
// insert neccessary settings into widget
|
||||
WIDGETS.sleeplogalarm = {
|
||||
|
|
@ -10,10 +10,13 @@ if ((require("Storage").readJSON("sleeplogalarm.settings.json", true) || {enable
|
|||
time: 0,
|
||||
earlier: settings.earlier,
|
||||
draw: function () {
|
||||
// draw zzz
|
||||
g.reset().setColor(settings.wid.color).drawImage(atob("BwoBD8SSSP4EEEDg"), this.x + 1, this.y);
|
||||
// call function to draw the time of alarm if a alarm is found
|
||||
if (this.time) this.drawTime(this.time + 1);
|
||||
// draw if width is set
|
||||
if (this.width) {
|
||||
// draw zzz
|
||||
g.reset().setColor(settings.wid.color).drawImage(atob("BwoBD8SSSP4EEEDg"), this.x + 1, this.y);
|
||||
// call function to draw the time of alarm if a alarm is found
|
||||
if (this.time) this.drawTime(this.time + 1);
|
||||
}
|
||||
},
|
||||
drawTime: () => {},
|
||||
reload: require("sleeplogalarm").widReload
|
||||
|
|
|
|||
Loading…
Reference in New Issue