From 501c7e79cfe6916154a48a8b086ef589e682c893 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 2 Mar 2022 16:55:38 +0800 Subject: [PATCH 001/253] Update app.js Support some invalid base32 characters. --- apps/authentiwatch/app.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 73b8bdeea..69890c90c 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -32,9 +32,12 @@ if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ function b32decode(seedstr) { // RFC4648 - var i, buf = 0, bitcount = 0, retstr = ""; - for (i in seedstr) { - var c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".indexOf(seedstr.charAt(i).toUpperCase(), 0); + var buf = 0, bitcount = 0, retstr = ""; + for (var c of seedstr.toUpperCase()) { + if (c=='0')c='O'; + if (c=='1')c='I'; + if (c=='8')c='B'; + c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".indexOf(c); if (c != -1) { buf <<= 5; buf |= c; @@ -47,7 +50,7 @@ function b32decode(seedstr) { } } var retbuf = new Uint8Array(retstr.length); - for (i in retstr) { + for (var i in retstr) { retbuf[i] = retstr.charCodeAt(i); } return retbuf; From cb0aec47a43919235df08c4e2472c5dd64df5183 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 2 Mar 2022 16:57:48 +0800 Subject: [PATCH 002/253] Update app.js Add language translation tags --- apps/authentiwatch/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 69890c90c..e9d00a265 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -8,9 +8,9 @@ const algos = { "SHA256":{sha:crypto.SHA256,retsz:32,blksz:64 }, "SHA1" :{sha:crypto.SHA1 ,retsz:20,blksz:64 }, }; -const calculating = "Calculating"; -const notokens = "No tokens"; -const notsupported = "Not supported"; +const calculating = /*LANG*/"Calculating"; +const notokens = /*LANG*/"No tokens"; +const notsupported = /*LANG*/"Not supported"; // sample settings: // {tokens:[{"algorithm":"SHA1","digits":6,"period":30,"issuer":"","account":"","secret":"Bbb","label":"Aaa"}],misc:{}} From fe8345ed15e5a1202dd4f2a027ede2705969f849 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 2 Mar 2022 22:44:13 +0800 Subject: [PATCH 003/253] Update interface.html Refactoring --- apps/authentiwatch/interface.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 5ee32fd8e..bfc0e55d1 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -54,9 +54,9 @@ var tokens = settings.tokens; */ function base32clean(val, nows) { var ret = val.replaceAll(/\s+/g, ' '); - ret = ret.replaceAll(/0/g, 'O'); - ret = ret.replaceAll(/1/g, 'I'); - ret = ret.replaceAll(/8/g, 'B'); + ret = ret.replaceAll('0', 'O'); + ret = ret.replaceAll('1', 'I'); + ret = ret.replaceAll('8', 'B'); ret = ret.replaceAll(/[^A-Za-z2-7 ]/g, ''); if (nows) { ret = ret.replaceAll(/\s+/g, ''); @@ -81,9 +81,9 @@ function b32encode(str) { function b32decode(seedstr) { // RFC4648 - var i, buf = 0, bitcount = 0, ret = ''; - for (i in seedstr) { - var c = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.indexOf(seedstr.charAt(i).toUpperCase(), 0); + var buf = 0, bitcount = 0, ret = ''; + for (var c of seedstr.toUpperCase()) { + c = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.indexOf(c); if (c != -1) { buf <<= 5; buf |= c; @@ -487,7 +487,7 @@ function startScan(handler,cancel) { document.body.className = 'scanning'; navigator.mediaDevices .getUserMedia({video:{facingMode:'environment'}}) - .then(function(stream){ + .then(stream => { scanning=true; video.setAttribute('playsinline',true); video.srcObject = stream; From 7810dd2cfc01145b58998886b13ce78893219852 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Mon, 7 Mar 2022 23:33:23 +0800 Subject: [PATCH 004/253] Update app.js Bangle 2: Improve drag responsiveness and exit on button press --- apps/authentiwatch/app.js | 48 +++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index e9d00a265..b8181e4a2 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -34,9 +34,9 @@ function b32decode(seedstr) { // RFC4648 var buf = 0, bitcount = 0, retstr = ""; for (var c of seedstr.toUpperCase()) { - if (c=='0')c='O'; - if (c=='1')c='I'; - if (c=='8')c='B'; + if (c == '0') c = 'O'; + if (c == '1') c = 'I'; + if (c == '8') c = 'B'; c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".indexOf(c); if (c != -1) { buf <<= 5; @@ -166,11 +166,7 @@ function drawToken(id, r) { } while (g.stringWidth(state.otp) > (r.w - adj)); g.drawString(state.otp, (x1 + adj + x2) / 2, y1 + tokenextraheight, false); } - // shaded lines top and bottom - g.setColor(0.5, 0.5, 0.5) - .drawLine(x1, y1, x2, y1) - .drawLine(x1, y2, x2, y2) - .setClipRect(0, 0, g.getWidth(), g.getHeight()); + g.setClipRect(0, 0, g.getWidth(), g.getHeight()); } function draw() { @@ -212,7 +208,7 @@ function draw() { if (id == state.curtoken && (tokens[id].period <= 0 || state.nextTime != 0)) { drewcur = true; } - id += 1; + id++; y += tokenheight; } if (drewcur) { @@ -273,11 +269,33 @@ function onTouch(zone, e) { } function onDrag(e) { - if (e.x > g.getWidth() || e.y > g.getHeight()) return; - if (e.dx == 0 && e.dy == 0) return; - var newy = Math.min(state.listy - e.dy, tokens.length * tokenheight - Bangle.appRect.h); - state.listy = Math.max(0, newy); - draw(); + if (e.b != 0 && e.x < g.getWidth() && e.y < g.getHeight() && e.dy != 0) { + var y = Math.max(0, Math.min(state.listy - e.dy, tokens.length * tokenheight - Bangle.appRect.h)); + if (state.listy != y) { + var id, dy = state.listy - y; + state.listy = y; + g.setClipRect(Bangle.appRect.x,Bangle.appRect.y,Bangle.appRect.x2,Bangle.appRect.y2) + .scroll(0, dy); + if (dy > 0) { + id = Math.floor((state.listy + dy) / tokenheight); + y = id * tokenheight + Bangle.appRect.y - state.listy; + do { + drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:tokenheight}); + id--; + y -= tokenheight; + } while (y > 0); + } + if (dy < 0) { + id = Math.floor((state.listy + dy + Bangle.appRect.h) / tokenheight); + y = id * tokenheight + Bangle.appRect.y - state.listy; + while (y < Bangle.appRect.y2) { + drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:tokenheight}); + id++; + y += tokenheight; + } + } + } + } } function onSwipe(e) { @@ -332,6 +350,8 @@ if (typeof BTN2 == 'number') { setWatch(function(){bangle1Btn(-1);}, BTN1, {edge:"rising" , debounce:50, repeat:true}); setWatch(function(){exitApp(); }, BTN2, {edge:"falling", debounce:50}); setWatch(function(){bangle1Btn( 1);}, BTN3, {edge:"rising" , debounce:50, repeat:true}); +} else { + setWatch(function(){exitApp(); }, BTN1, {edge:"falling", debounce:50}); } Bangle.loadWidgets(); From 929920fcb6708a715b0961e830c03cca7ef8a358 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Mon, 7 Mar 2022 23:33:53 +0800 Subject: [PATCH 005/253] Update ChangeLog 0.07 --- apps/authentiwatch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/ChangeLog b/apps/authentiwatch/ChangeLog index bb2945db4..655916170 100644 --- a/apps/authentiwatch/ChangeLog +++ b/apps/authentiwatch/ChangeLog @@ -4,3 +4,4 @@ 0.04: Fix tapping at very bottom of list, exit on inactivity 0.05: Add support for bulk importing and exporting tokens 0.06: Add spaces to codes for improved readability (thanks @BartS23) +0.07: Bangle 2: Improve drag responsiveness and exit on button press From 51744f842df0484bab0b72bc3bcbe8f089e8c8e3 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Mon, 7 Mar 2022 23:34:18 +0800 Subject: [PATCH 006/253] Update metadata.json 0.07 --- apps/authentiwatch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/metadata.json b/apps/authentiwatch/metadata.json index b4ed34a12..36e1ea34d 100644 --- a/apps/authentiwatch/metadata.json +++ b/apps/authentiwatch/metadata.json @@ -4,7 +4,7 @@ "shortName": "AuthWatch", "icon": "app.png", "screenshots": [{"url":"screenshot1.png"},{"url":"screenshot2.png"},{"url":"screenshot3.png"},{"url":"screenshot4.png"}], - "version": "0.06", + "version": "0.07", "description": "Google Authenticator compatible tool.", "tags": "tool", "interface": "interface.html", From 915ad6394795ea25e28d05480095ad23247836ec Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Tue, 8 Mar 2022 15:58:46 +0800 Subject: [PATCH 007/253] Update interface.html Use push instead of concat. --- apps/authentiwatch/interface.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index bfc0e55d1..7d567d34f 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -405,7 +405,7 @@ class proto3decoder { constructor(str) { this.buf = []; for (let i in str) { - this.buf = this.buf.concat(str.charCodeAt(i)); + this.buf.push(str.charCodeAt(i)); } } getVarint() { From d7def5d5e1c95fcd456a406ef8bda3da183e9f34 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Tue, 8 Mar 2022 21:52:57 +0800 Subject: [PATCH 008/253] Update app.js Cache font size calculations --- apps/authentiwatch/app.js | 45 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index b8181e4a2..8a8aeb962 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -18,18 +18,6 @@ var settings = require("Storage").readJSON("authentiwatch.json", true) || {token if (settings.data ) tokens = settings.data ; /* v0.02 settings */ if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ -// QR Code Text -// -// Example: -// -// otpauth://totp/${url}:AA_${algorithm}_${digits}dig_${period}s@${url}?algorithm=${algorithm}&digits=${digits}&issuer=${url}&period=${period}&secret=${secret} -// -// ${algorithm} : one of SHA1 / SHA256 / SHA512 -// ${digits} : one of 6 / 8 -// ${period} : one of 30 / 60 -// ${url} : a domain name "example.com" -// ${secret} : the seed code - function b32decode(seedstr) { // RFC4648 var buf = 0, bitcount = 0, retstr = ""; @@ -75,6 +63,10 @@ function do_hmac(key, message, algo) { var v = new DataView(ret, ret[ret.length - 1] & 0x0F, 4); return v.getUint32(0) & 0x7FFFFFFF; } +function formatOtp(otp, digits) { + var re = (digits % 3 == 0 || (digits % 3 >= digits % 4 && digits % 4 != 0)) ? "" : "."; + return otp.replace(new RegExp("(..." + re + ")", "g"), "$1 ").trim(); +} function hotp(d, token, dohmac) { var tick; if (token.period > 0) { @@ -98,8 +90,7 @@ function hotp(d, token, dohmac) { ret = "0" + ret; } // add a space after every 3rd or 4th digit - var re = (token.digits % 3 == 0 || (token.digits % 3 >= token.digits % 4 && token.digits % 4 != 0)) ? "" : "."; - ret = ret.replace(new RegExp("(..." + re + ")", "g"), "$1 ").trim(); + ret = formatOtp(ret, token.digits); } catch(err) { ret = notsupported; } @@ -107,6 +98,7 @@ function hotp(d, token, dohmac) { return {hotp:ret, next:((token.period > 0) ? ((tick + 1) * token.period * 1000) : d.getTime() + 30000)}; } +var fontsz_cache = {}; var state = { listy: 0, prevcur:0, @@ -117,12 +109,25 @@ var state = { hide:0 }; +function size_font(id, txt, w) { + var sz = fontsz_cache[id]; + if (sz) { + g.setFont("Vector", sz); + } else { + sz = tokendigitsheight; + do { + g.setFont("Vector", sz--); + } while (g.stringWidth(txt) > w); + fontsz_cache[id] = sz + 1; + } +} + function drawToken(id, r) { var x1 = r.x; var y1 = r.y; var x2 = r.x + r.w - 1; var y2 = r.y + r.h - 1; - var adj, lbl, sz; + var adj, lbl; g.setClipRect(Math.max(x1, Bangle.appRect.x ), Math.max(y1, Bangle.appRect.y ), Math.min(x2, Bangle.appRect.x2), Math.min(y2, Bangle.appRect.y2)); lbl = tokens[id].label.substr(0, 10); @@ -137,10 +142,7 @@ function drawToken(id, r) { } else { g.setColor(g.theme.fg) .setBgColor(g.theme.bg); - sz = tokendigitsheight; - do { - g.setFont("Vector", sz--); - } while (g.stringWidth(lbl) > r.w); + size_font("l" + id, lbl, r.w); // center in box g.setFontAlign(0, 0, 0); adj = (y1 + y2) / 2; @@ -160,10 +162,7 @@ function drawToken(id, r) { adj = 12; } // digits just below label - sz = tokendigitsheight; - do { - g.setFont("Vector", sz--); - } while (g.stringWidth(state.otp) > (r.w - adj)); + size_font("d" + id, state.otp, r.w - adj); g.drawString(state.otp, (x1 + adj + x2) / 2, y1 + tokenextraheight, false); } g.setClipRect(0, 0, g.getWidth(), g.getHeight()); From ebdea05bff9df19ea85ed7a636967b27f740a21f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 9 Mar 2022 21:53:24 +0800 Subject: [PATCH 009/253] Update app.js Improve code style --- apps/authentiwatch/app.js | 93 ++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 8a8aeb962..fb130969f 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -1,6 +1,6 @@ -const tokenextraheight = 16; -var tokendigitsheight = 30; -var tokenheight = tokendigitsheight + tokenextraheight; +const TOKEN_EXTRA_HEIGHT = 16; +var TOKEN_DIGITS_HEIGHT = 30; +var TOKEN_HEIGHT = TOKEN_DIGITS_HEIGHT + TOKEN_EXTRA_HEIGHT; // Hash functions const crypto = require("crypto"); const algos = { @@ -8,9 +8,9 @@ const algos = { "SHA256":{sha:crypto.SHA256,retsz:32,blksz:64 }, "SHA1" :{sha:crypto.SHA1 ,retsz:20,blksz:64 }, }; -const calculating = /*LANG*/"Calculating"; -const notokens = /*LANG*/"No tokens"; -const notsupported = /*LANG*/"Not supported"; +const CALCULATING = /*LANG*/"Calculating"; +const NO_TOKENS = /*LANG*/"No tokens"; +const NOT_SUPPORTED = /*LANG*/"Not supported"; // sample settings: // {tokens:[{"algorithm":"SHA1","digits":6,"period":30,"issuer":"","account":"","secret":"Bbb","label":"Aaa"}],misc:{}} @@ -43,7 +43,8 @@ function b32decode(seedstr) { } return retbuf; } -function do_hmac(key, message, algo) { + +function doHmac(key, message, algo) { var a = algos[algo]; // RFC2104 if (key.length > a.blksz) { @@ -63,11 +64,13 @@ function do_hmac(key, message, algo) { var v = new DataView(ret, ret[ret.length - 1] & 0x0F, 4); return v.getUint32(0) & 0x7FFFFFFF; } + function formatOtp(otp, digits) { var re = (digits % 3 == 0 || (digits % 3 >= digits % 4 && digits % 4 != 0)) ? "" : "."; return otp.replace(new RegExp("(..." + re + ")", "g"), "$1 ").trim(); } -function hotp(d, token, dohmac) { + +function hotp(d, token, calcHmac) { var tick; if (token.period > 0) { // RFC6238 - timed @@ -81,10 +84,10 @@ function hotp(d, token, dohmac) { var v = new DataView(msg.buffer); v.setUint32(0, tick >> 16 >> 16); v.setUint32(4, tick & 0xFFFFFFFF); - var ret = calculating; - if (dohmac) { + var ret = CALCULATING; + if (calcHmac) { try { - var hash = do_hmac(b32decode(token.secret), msg, token.algorithm.toUpperCase()); + var hash = doHmac(b32decode(token.secret), msg, token.algorithm.toUpperCase()); ret = "" + hash % Math.pow(10, token.digits); while (ret.length < token.digits) { ret = "0" + ret; @@ -92,13 +95,13 @@ function hotp(d, token, dohmac) { // add a space after every 3rd or 4th digit ret = formatOtp(ret, token.digits); } catch(err) { - ret = notsupported; + ret = NOT_SUPPORTED; } } return {hotp:ret, next:((token.period > 0) ? ((tick + 1) * token.period * 1000) : d.getTime() + 30000)}; } -var fontsz_cache = {}; +var fontszCache = {}; var state = { listy: 0, prevcur:0, @@ -109,16 +112,16 @@ var state = { hide:0 }; -function size_font(id, txt, w) { - var sz = fontsz_cache[id]; +function sizeFont(id, txt, w) { + var sz = fontszCache[id]; if (sz) { g.setFont("Vector", sz); } else { - sz = tokendigitsheight; + sz = TOKEN_DIGITS_HEIGHT; do { g.setFont("Vector", sz--); } while (g.stringWidth(txt) > w); - fontsz_cache[id] = sz + 1; + fontszCache[id] = sz + 1; } } @@ -135,14 +138,14 @@ function drawToken(id, r) { // current token g.setColor(g.theme.fgH) .setBgColor(g.theme.bgH) - .setFont("Vector", tokenextraheight) + .setFont("Vector", TOKEN_EXTRA_HEIGHT) // center just below top line .setFontAlign(0, -1, 0); adj = y1; } else { g.setColor(g.theme.fg) .setBgColor(g.theme.bg); - size_font("l" + id, lbl, r.w); + sizeFont("l" + id, lbl, r.w); // center in box g.setFontAlign(0, 0, 0); adj = (y1 + y2) / 2; @@ -162,8 +165,8 @@ function drawToken(id, r) { adj = 12; } // digits just below label - size_font("d" + id, state.otp, r.w - adj); - g.drawString(state.otp, (x1 + adj + x2) / 2, y1 + tokenextraheight, false); + sizeFont("d" + id, state.otp, r.w - adj); + g.drawString(state.otp, (x1 + adj + x2) / 2, y1 + TOKEN_EXTRA_HEIGHT, false); } g.setClipRect(0, 0, g.getWidth(), g.getHeight()); } @@ -174,7 +177,7 @@ function draw() { var d = new Date(); if (state.curtoken != -1) { var t = tokens[state.curtoken]; - if (state.otp == calculating) { + if (state.otp == CALCULATING) { state.otp = hotp(d, t, true).hotp; } if (d.getTime() > state.nextTime) { @@ -200,20 +203,20 @@ function draw() { } if (tokens.length > 0) { var drewcur = false; - var id = Math.floor(state.listy / tokenheight); - var y = id * tokenheight + Bangle.appRect.y - state.listy; + var id = Math.floor(state.listy / TOKEN_HEIGHT); + var y = id * TOKEN_HEIGHT + Bangle.appRect.y - state.listy; while (id < tokens.length && y < Bangle.appRect.y2) { - drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:tokenheight}); + drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:TOKEN_HEIGHT}); if (id == state.curtoken && (tokens[id].period <= 0 || state.nextTime != 0)) { drewcur = true; } id++; - y += tokenheight; + y += TOKEN_HEIGHT; } if (drewcur) { // the current token has been drawn - schedule a redraw if (tokens[state.curtoken].period > 0) { - timerdly = (state.otp == calculating) ? 1 : 1000; // timed + timerdly = (state.otp == CALCULATING) ? 1 : 1000; // timed } else { timerdly = state.nexttime - d.getTime(); // counter } @@ -230,9 +233,9 @@ function draw() { state.nexttime = 0; } } else { - g.setFont("Vector", tokendigitsheight) + g.setFont("Vector", TOKEN_DIGITS_HEIGHT) .setFontAlign(0, 0, 0) - .drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2, Bangle.appRect.y + Bangle.appRect.h / 2, false); + .drawString(NO_TOKENS, Bangle.appRect.x + Bangle.appRect.w / 2, Bangle.appRect.y + Bangle.appRect.h / 2, false); } if (state.drawtimer) { clearTimeout(state.drawtimer); @@ -242,18 +245,18 @@ function draw() { function onTouch(zone, e) { if (e) { - var id = Math.floor((state.listy + (e.y - Bangle.appRect.y)) / tokenheight); + var id = Math.floor((state.listy + (e.y - Bangle.appRect.y)) / TOKEN_HEIGHT); if (id == state.curtoken || tokens.length == 0 || id >= tokens.length) { id = -1; } if (state.curtoken != id) { if (id != -1) { - var y = id * tokenheight - state.listy; + var y = id * TOKEN_HEIGHT - state.listy; if (y < 0) { state.listy += y; y = 0; } - y += tokenheight; + y += TOKEN_HEIGHT; if (y > Bangle.appRect.h) { state.listy += (y - Bangle.appRect.h); } @@ -269,28 +272,28 @@ function onTouch(zone, e) { function onDrag(e) { if (e.b != 0 && e.x < g.getWidth() && e.y < g.getHeight() && e.dy != 0) { - var y = Math.max(0, Math.min(state.listy - e.dy, tokens.length * tokenheight - Bangle.appRect.h)); + var y = Math.max(0, Math.min(state.listy - e.dy, tokens.length * TOKEN_HEIGHT - Bangle.appRect.h)); if (state.listy != y) { var id, dy = state.listy - y; state.listy = y; g.setClipRect(Bangle.appRect.x,Bangle.appRect.y,Bangle.appRect.x2,Bangle.appRect.y2) .scroll(0, dy); if (dy > 0) { - id = Math.floor((state.listy + dy) / tokenheight); - y = id * tokenheight + Bangle.appRect.y - state.listy; + id = Math.floor((state.listy + dy) / TOKEN_HEIGHT); + y = id * TOKEN_HEIGHT + Bangle.appRect.y - state.listy; do { - drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:tokenheight}); + drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:TOKEN_HEIGHT}); id--; - y -= tokenheight; + y -= TOKEN_HEIGHT; } while (y > 0); } if (dy < 0) { - id = Math.floor((state.listy + dy + Bangle.appRect.h) / tokenheight); - y = id * tokenheight + Bangle.appRect.y - state.listy; + id = Math.floor((state.listy + dy + Bangle.appRect.h) / TOKEN_HEIGHT); + y = id * TOKEN_HEIGHT + Bangle.appRect.y - state.listy; while (y < Bangle.appRect.y2) { - drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:tokenheight}); + drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:TOKEN_HEIGHT}); id++; - y += tokenheight; + y += TOKEN_HEIGHT; } } } @@ -324,12 +327,12 @@ function bangle1Btn(e) { } state.curtoken = Math.max(state.curtoken, 0); state.curtoken = Math.min(state.curtoken, tokens.length - 1); - state.listy = state.curtoken * tokenheight; - state.listy -= (Bangle.appRect.h - tokenheight) / 2; - state.listy = Math.min(state.listy, tokens.length * tokenheight - Bangle.appRect.h); + state.listy = state.curtoken * TOKEN_HEIGHT; + state.listy -= (Bangle.appRect.h - TOKEN_HEIGHT) / 2; + state.listy = Math.min(state.listy, tokens.length * TOKEN_HEIGHT - Bangle.appRect.h); state.listy = Math.max(state.listy, 0); var fakee = {}; - fakee.y = state.curtoken * tokenheight - state.listy + Bangle.appRect.y; + fakee.y = state.curtoken * TOKEN_HEIGHT - state.listy + Bangle.appRect.y; state.curtoken = -1; state.nextTime = 0; onTouch(0, fakee); From f96ba8d6a5df56459ebbcf2249c925c3deae72a3 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 9 Mar 2022 21:56:52 +0800 Subject: [PATCH 010/253] Add files via upload Update screenshots --- apps/authentiwatch/screenshot1.png | Bin 2708 -> 1595 bytes apps/authentiwatch/screenshot2.png | Bin 2914 -> 1835 bytes apps/authentiwatch/screenshot3.png | Bin 2656 -> 1425 bytes apps/authentiwatch/screenshot4.png | Bin 2951 -> 1721 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/authentiwatch/screenshot1.png b/apps/authentiwatch/screenshot1.png index c7ca744b497c2098743be85b15d16878f7196a54..c3ac0e3b7e98b4db240c3928901179496a6ff69c 100644 GIT binary patch literal 1595 zcmaKsdpOez7{_NO4E6JzM09N9q@u)fEt)YWlWQiE#7K_he#>EwOIy>CYY5@NVXe$8 zA(q<`!Xmjdw~mxZiOpr~=v@9ePfve*-}iYw|GdxhdEV!nXlHXq2C4`Jfj}}?3(UEl zUHLT<;GGE{2$9@b;-Oe;bMd#LlF~{FBm{@EgCqkjoI^k$8~E3V>?7t(>_CV&+8PZ4 zF;k=j1ThdutP_htUiCUT^3bf;ePvt>O!RJe{)X0WQTjuM8@ zV_UiLF5Z(mI>!@&)T|=*8)RZrzG4a&QG2 zRP9mAW^TP<(+5{QYipjb)h|8FIqL;cBG;NdA=XuI5<@-@*AjY5$TTTo#~W{l}5^z;N31HlrE47D=RQ7G|7_@n_U~ z8}da@Y4msd_Tw_!>z(mQhu064@^^qdC@v zWH2FPoknSn%tp&l)a=A_W_vMZZ+jmW5e0u>H#SFEwQM&PNO9f3FJ|qLdDyI~T@JFp zt_)Fv?*uvhO+Gd{jStIX^WY{DPeiUS$D!($yGSS|t~gg(Y`6A)t$^jL{i= z9U5$6X#4T|;Z)@<&r$}!N?YfqAWa!;JApDjGWcAI`w3yX zfCR+^Ly;qs^Agz#s%K+kN%!WLbG3X zP<@yNtDT@M)NXw+O^)uK8bn{&R8=~id|0kHgJ>%#;5y%^;5!LKU#%Az@LFq~FL>7V z;5K-z`uGb`iK4Pahqn7m!={_M48r(U;T8U?vh@>gFD@XiDUPSipPw9YnLO7E{p^m` z6J(alfiu>eD6grLkn&O#n`(OF%ml}59Nk5L_ zs%^0D`cME`HT&j48+c#j{J=#-GE(JKLpTDL27B6QYsnAPRoW)N;M9t<$~8=1JH&(j zi>lkwkQs8vkm+uhc5#N1q89m|2Klb#|GMT0aevISEeUFd(P|@^36)>8-T<-GF&xMF zJ&h!SIwNLj0jUx!aO+p19Od%tUM!wJ-6rD{y|il^)}AfU__I2+V_&jG#xnNZA=}74LRqH5R3_^nq3n{K98|K5veg+h zB1<{SE{Z9GETcIk%W=}{e1AW@*Y$q5@BfG2eO>pL`~Sc0w6pe>0tg8N0008kR%T8I z+VpS1c@8?Qo#k^NAlb>%1ZW(VTmb-ty|tOK3&n?Bc8Of2cIalwuU}PUQx9EyNQV;k z#lYOΞ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 diff --git a/apps/authentiwatch/screenshot2.png b/apps/authentiwatch/screenshot2.png index 8156dd3e8a8070e3b57b93163f8cd44ca5e90e85..26bafdbb2db394b8652c4197ce828c4463281351 100644 GIT binary patch literal 1835 zcmb7FdpHvc8y}X2aTX=!wsmw?a*0|lCzlyQ>>@)#R?cyV$)!<3)@)Dh z005xs=IZ1n<3Iihki0CzMq-s@v^~zv(|P->f)W_Ie{e?9B$JfRyPk{%05GtBLQXR& z|D8+(hN3)C06<-aiiEfg08ngkb3%D1j4c*jOTTXeb|wx>rTxfS7f04!Y8N>|Sfp*+ zw%;g(`_@VYnPOM0)XGYcO2qkgycCy-_aEdPjFVka5feOLVG)=mU3AX7`XR?21r(GBw#e+P!MI^JFrqq zV;Bgj>FYYDx=d3-?W=$67!>8_00}p|z|aFZ-lCwrKL$F#nL1PEl{&rEEzXJzjmp#9 z!w6QP;9#r9R|icz`*xsv668^FcrwMwu8sopz^y3G!4y!e+kfe3f{b$T*5;4i^|ec6 zQ(kN%%F!9m9SD;U*i*P7B=SOxikh4}@W0`8TIC|i^9xeSu^50`-2G`oQOm+%0s%6H zZ~IYC{u+=9R{&xt!O6_Djybq80um4PmtNfXCJ1jEZi?rspA#^Ao;L=}(!y;fOc+g< zNT(uSucaO5a0&*dSo{Fe!d9cHW&&87=i?li!BRzTcKJrH64vh>>~S&47k_Q-f&jUHgS6Q{3ragojiD_`&{+# z!RBrVvY#opegx@Ju7>B2k`@zpHSSg(y+ewx#PZ;r=fv`y1qXcV?_7!D{ggGZI=ex_pak;dm7N9Y&oc59K)o&;7!$}RRY^L zV^+K}gdwMS=l6;r9NkAl7w3iN_{WD2ww;7jpE6Ein?~C2KkaYzZt*a|Kl2A|&d#2+ z&vSg@Q6V-bbw&;U+s62EL37qoS-0RpicYXTq5^3d#>d472J>lc{3g4xr#?VIlwFH= zP)ci{v!~-{c`f|C$*)wTVI*L{Cg1Z^oL zhF9iyEEaeq1#wQ@5L){W_uCUKFQI8u%7KE~%ddciv0`jRY7}_#G{I>ZQl?cRTFP*L z|LYI7*8Ve7#W*E)PG29WE}6Ujg|=!QmQrW?DZ=-@J&R0%4SiX|Y|5=M56s!+M@KWD zd56f30{@!gmEwHH;UEuv**ZhSBRJE`%SI;z-}KDMpr12L3^HQ%Nd*n(NRS3z&j4Kb zw`-D3Fn!bTrGXCJ$`)I0XC0>>kUqL@j@vvDJ!%(uJ}a$QCn@ zc$lzKH5(w&Fd|Mveo68h4tc!S>G&J>+3^=p;_3~y^=>H@>NK_(F(E|0=nc+qh0BET zB_jh+rtz}vwj55TH4UKf-DHpvYU!$OunJo7->(11{_jOe5uIh0u9#GBa-Vb{^WoA7 zAZnod#F_q)n6G2U;TsYG;7*r$&)nrJ%OrH2PmdGPHP zNTPixL?lX0&p_{_e+VJ?wKdsft$;&SPjbzJAa`!nA1W*etMXAV9ii)!qU3gTA3sO5y1bFQ>UQRmfl9qi7r}$`P1^aC&FZRXECmT6 zWKP9A9&?d+{YOSz>*`@&#z~hD%%7&RODWiR;x;ZEj+695ZklG8e}@$G9bZtq~GV)1NPy<|+^+d@RJo1z`)d7>&YDCs|9F;0mG%f1@G%^BnL I&@q_uFAa7*R{#J2 literal 2914 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 Z(A4{6$wZuM;{MYNIM|-BskI8c@jt}ERJ#BG diff --git a/apps/authentiwatch/screenshot3.png b/apps/authentiwatch/screenshot3.png index 6d14e0b965efa1b522d034bc0fee2f8415a950d5..80f2fb172b55fdfc19ac61f2c7878d718ebdc1fb 100644 GIT binary patch delta 1418 zcmV;51$Fx16p;&%8Gix*001D>a|r+d00(qQO+^Rh0|^WmIF(|)#sB~S32;bRa{vHN zAOHYPAORMAnce^Z00d`2O+f$vv5yP`~99@h|ufxBRi2H zlzHw;3uFjoyD!{-@2gi@gNgQ{^fY6a3}K>fo**DhXnwhULyLfz($54H^8^7grJo6` z2LToc2nEMXP%$^GILlCQ%mjsU!!~yRcAE^LX8mOA=7tpkp=Qkrg>pj^0imXsA%sDa zAeIyM#vw$C`VhoK9w`E1AtuuBD+kai*d}ZO z2VoiFI2)QIkwNewgB*}eq6#w0p@@v+)N7!8yit?+y7u9v@E6bP5Cdgq`_1nb__1!% zKY!#6tVP&XSC+Gky9O%G`!u<`sIjHlDH#w073Y1L40JnHG%VT15ChJhq%v6wze*Ez z^)f`Ky#85P{DC6%>UHg#MaNWX^y@00A$BA4yB}qST7{{^XNbG$v2*^J?RZ>Kd_WB7 z)O;i?CdL2!z5VmoE({d@;x|BF&Uzn*oFJ!yJ6?(aD494 zvH8-C2A{h212y`s`DF;LtFybOYWY0)FvBAreWVyv>Ygh$-}PzYumMqhTgtIjBt3G=;zJiRTwpYbZwy0e7A%8mm zjhSvfA_L;?J|-p{gdH*@6=JI&k1L8FL#zfS-<8&|80n10q9BeAC{BNIHhNdnLP8wfYQI@6S}t z5IzO&wW`%m*4FowG($XCk{y4hYJY}+k@yVJeELnoT>2qmGDNB~Z*0Y9h~@mIhezgy z{z`fqSiL^@Warkr`t5i@-|wWHWiI*d~(Yq{xWJ2u=WLp%3B!DmAEtrZ55q&;$_} zrHF+9g7jiW5uy}_{^%J6(UB4q4T1wNGk@THIOnXj&)RG64`=OlvRqvp_MlWy008W9 zay;rLo^}5eLQ>pon-~1V1H9noa2Ti=#C-q&l#0{QL#Gn_R!aViD@axbGwgQBL|? z*{>Hpk)`GZyMPS%luh(fbR18qHNmxO&1BR)le;)Kd9FPo2*NF6s?^+>!1WKk4NH1J ztRRSC*sV4l{Isbyb%N(}xc_bVZ+wqC*4u6H1U2vGm!}$~haR2@Vt(tROw+AMC;wH# z(`>(Ise<_NLQqo?3zBuCc8rd)geP3|vjTGejQpc(o4%)+}F6okB)K^7@=Q9B;ydVgJ;##sp_Q z+C|}A%}h^_x)FGuz$3L?pb;h5(B^86V43Fy>A$gou*UR#(;*>OJ%JmWcN57=?!raa@Loz7Lf<(eCv=}_w6XIy!gHTrSL*^tDBVfCO+ zu9m7)R!FP9=kW>NM+vojqKV}CFFjajW|O(0m`eo4pHZ2+KC*X#2sQPJFN9$|7U=}+ zYzha6k`d01?1P9V@0^%iAx7{5VB^oDg&jQ<2_d2bPR7#VO&`nrr*doqHG>FD?F1IL ze7LSqw!%X~zT&L6z52O4lB3j)8GO?D7E(C- zB5|TIsa0O!#Zh_dmU0EsP%U(E1&t*Tb)5Wc`7!{M%_}Kj=-DzmZv+>kB@oe>%f+Kq z5L&JzyiM1&WgZD$s_;Xh>Bid1#G@dD)3hdjabp5WdN0WuD6{}QY59Ny!T(Ej>Or1l z0$2HiPMrz~o%3s=b^Vy$TKK2k(EtnCE^A?=ld1py+sOlL|3{*>TO^ls$Oqq?pKcyLUrEK2R^l2KW+b`IA|Fzlnad|g&k5*j*lJSFft49 zEi9vI#ST$dfI@L5mTMKZaCc08tUqFg259+W#S1{s*ReAsCoU&)0CoxZdVf)Vzgel$ z9k=3qKzc+fVZ#lk4#MT?v z&i*RBKKz-NO<^cOsA5rz8$iA1KhebRdJ-Z7am?(kE*~(?-WkQ*>izMUbH^v~DY{Z* z>;fHwD&8XCjxxbACKJ^pZ!kN?)hRl7z+$SA&`^Q1iT7r-CM;--S#2j+GV=`U=0>ao z+k#avM^v;_Ip=MSFfsq~rh)7j|7!v_2lfG1-Cvp;vyTW0dK`P@=qxNB8(iZR)C6qG z*5^s-F3gO(TLj)0+sXCGbd*7=5F}0Pi^ATmSAwgt4t=%m$9!?-k1SRnVBb?Pl%mt8 zm7XXhe_gKx?60XN^7Gj;{F-hQDHJqFqxKcLKG)O(RjIPeu zz@HsT49%XFq$97i&q_EqH_d2Ph9Corw673(@l#$#$140@lkNgZKRoj^S5)VjUpnD# z4!Q(|3>-#8JI{}ta%PTrdNrUSpAnJSPx1mY+PFbFFtK6dJO(G{+%%Wg_&=1-5nrM% zleg!uHu%@BSuj^OmeyoDyodYajrsSsUeu0NwcchMq(=zyo0jy7fTi{NU~PCy#Y*C@ zI=sXV11}_K6rNOChK$A=Q)!2p)Tz>{_l6*Qj*!*`*G|hZ^^2}AF!BZsQj!$AAU=Ha z81IQmTy$hA zt@6@6dWr#gLDaDWhw5rLVcjg?X0E?6cpbOc_gAYNHL5&(;4%N6Z&35QLe=u-^3*d6 zdF6KVlS?-wv6Hi`wsm*XYMeWoX>-1KPnr2;FQ%M(rD01|5boR0PraA&$`xyfgH%{u z@Qt2?ibuW^10F4*-9li~UCOMNX!~UFB!=Ei4$qG9fpC_&*&i1F6f>%;2DNxO)1P$7 zRf!ne;q@U(MZ24{N%+97Lg9M~yb#!>X8`3K*?o}#o%=-}7cDbx`olvw6s%->e!ur*0yDt|aaU@d=8+S)lUk~3q! zU4D9hW;4(-Ho$t+Fm@^L+8Y(`=@s)6qTvkUqUJ1;wP}5%a}SS}*{HV7X13x*06gnl zJn0xv-nN2TrvVXdRXwb{*<3%DB3$(y4It^={npPmq&O<`H+1MtOEYFo{^x>3w17Ak z+5ZK3f8)-rb&a#9E<==u0^YZxM&mz!k#=TE0UP9>V2|URSMuinA|ZsDvR`a z0y`jbMFH(IiGvIxy5*$xZJA2@uReGwj#V$MTu)CB>Zr3k?o49>eJba=pNV5NV<6y6 zJp}h0&(!)s3>%-7buUm9O#EfBZMD5F-(J$CbI^KzO_q{`=^@697`2W0M;p!`C70EU zQ`IBx;Gq>bIVI~RRh@Tp_Jpf7=t2)%#2}(WMDn99O!-33RygD{`8T|AFKl^zE_KMl zNka|r+d00(qQO+^Rh0|^WlF6J&5SO5S332;bRa{vHN zAOHYPAORMAnce^Z00d`2O+f$vv5yP zwG7x`CkQMd1)dIpL;^yW0UL}2!T2Hz&U-2wFSHaI`hWad{rqyaUux^C9f`HGM{C@) zo#%mK8elDmv2w0!t!VqksnbhMYH>{UE~jO`S{4l~x{Q6L-!JF zZvUXttjxY@7|w&SCQQ4GJH}A$BZ{+y^NCI;JytdNH)fZvJHQXgnJgFlgS|#K2P4FhWG!UBS|01P$YJU zLKz@JK8INI*2G#3`_B7wc5fb6PZhFjq)JUokoalGahca_LowObpRB>i%5?{RvMmm9$)f6*7j=OyzK(*O_o& zom#bAN`bBFl@}Ox!iL1l-ye#HCSbs!G4@fy=CAVo|5?1h(6-R~<=PAMedPXT3xB1; zYB_{W{A{lV*+KH~7XP#<#wH#u2$MZnK(|I1j8noQW?XpkP<`1Z}3aOFM2EFW6haombm^g;`9xVGr zW-7zsJBua1xOM4`m*Iq+6G1m?bALE{{g-WHA1})|M58xt>wP$(4ff@750zA6h=9xd zNy~M0Kzkpt7@{Y0)z1tkwBf1cIzrMRj$W!fE%|Ul8=hLOdY*Ze57zt+-ff2>>|-qm z^ANBBLBIwC0UHP^0RR91000000KlIp>v!|Ps_QG;3gfyU=`ue>*oHqh7k}WFvl(kP zDb9;qbKiE1`3K*uehHp}xZ1{O!T`4}quRPf*O0wG&WL{uu~2PqL|~6kmr>XQ4IhUn z4snx@!uqv!Gs&IqY~a>r_+&^hIOvH*l#*1_wu?4!Yh!ZnsXS_@M*9gSG03ewi3QO! zqotihHMcGVjUleiWPgtL*MF={64mQykkuiMy6U6uTrY`IZoLTV5Dz9u!yl2=AwUU# zhj>3Rdj}5arC)-NLxdW6!y12wn2t9+JklG2KMZa$M78-p3OL;Wanz?YCJL33TrF&H zm3ulwu_Cb0sISJeHBieoNqVjm$}^lt8U1z94m>-rES^N9q@g?`ihnl8jG>ygrwQ*T zIZA%IZWq}erZ|E~$5VH6g&1W-rn+|_l*!BT9BFIN)9_EShsiyt49>$EyQ|3F8OTBW zola6but<7D-U|r;0000000000000000000009U!Z6>Q*rgldwfzSkg2W7D2e1>V|q z-Lp&m!LKl=;`M#+Y%Rl&h~raqR}fjgZ4WwedzFv4;RxTif&TyuY=GPy0O1V)0000< KMNUMnLSTZ>#1y{( literal 2951 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 From c43c61eb8130a9b160d68eb0b79217ea3f873c8a Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 12:43:29 -0600 Subject: [PATCH 011/253] Create node.js.yml --- .github/workflows/node.js.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/node.js.yml diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 000000000..278de90bf --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,31 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12.x, 14.x, 16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm ci + - run: npm run build --if-present + - run: npm test From 8f4680d9bf9074be7d42dfbdc91f24b6a6a21df1 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 13:19:49 -0600 Subject: [PATCH 012/253] Inital commit for MTG Watchface --- apps/mtgwatchface/app-icon.js | 6 ++ apps/mtgwatchface/app.js | 126 ++++++++++++++++++++++++++++++++ apps/mtgwatchface/metadata.json | 36 +++++++++ 3 files changed, 168 insertions(+) create mode 100644 apps/mtgwatchface/app-icon.js create mode 100644 apps/mtgwatchface/app.js create mode 100644 apps/mtgwatchface/metadata.json diff --git a/apps/mtgwatchface/app-icon.js b/apps/mtgwatchface/app-icon.js new file mode 100644 index 000000000..3ca872eee --- /dev/null +++ b/apps/mtgwatchface/app-icon.js @@ -0,0 +1,6 @@ +{ + width : 48, height : 48, bpp : 2, + transparent : -1, + palette : new Uint16Array([65535,0,23275,42260]), + buffer : require("heatshrink").decompress(atob("AB8P9Wq3kD////gKCgeVqoAB2QHBhgLCkoKCqtaBYoWDAAIjEgXVBQdWHIkliojE0ALDqv1BYdlqgKCgNVpIvEqvABYMJqtfBYtABYM1BIoABsALBHIgADrgLBKIgADHgRpFAAVXKQQAIBYe6BAdsIYKkBH4U5QQcCMAILBwAGCIgYIBBwQbCqtwIgQLCSQZ0D6oLHFAJ0BwAfBBY4jBA4Nr4ENBYO8gEOHAR3DrNlNYr5Drt1copcCqttvIECrA4COoVtbQVWHQM61WqGIILDtWq1k8DIUFvuJQYUAnALEucJBYcInkCgWggt63Nch06wALBhM77kFU4UJidwBYMBlEsBYcOgFABYcYBYkDEYUBnNcBYOVBYMBHYQDB0EKqvVzkOhYLChsDoELBYPch029gLBh3NCANVi0chXuyALBNwILBysAjhrDBIMgAgPrgEsQYabC1WoA4IGD1gPCABIfBnnA0ewA4MDmADB1ks2/jwv4kHagQyC8sQ3OzhsHlERgUIBYP+ld8+fOmm3iXC5ALBhkAFAQAB4AGFABA")) + } \ No newline at end of file diff --git a/apps/mtgwatchface/app.js b/apps/mtgwatchface/app.js new file mode 100644 index 000000000..f3dc6b188 --- /dev/null +++ b/apps/mtgwatchface/app.js @@ -0,0 +1,126 @@ +var blueImg = require("heatshrink").decompress(atob("2WywYgdpMkyQCFMG0EHwxE4hI+KAQmQIN4+NAQkgIFkCIKQCBpBBqiRBUAQOAINA+UAQhBwyARZIMoUhILwWPgiGpFLEJQ05BFwAaTiSGlEwocWQwlIIPcAgShZEZwfZQwlAIPYghgAggQwofahJBgQwpB8QwuQDi8BDoeAPSlIBZMSQwQOKL6JBUgFJkBoOIK0EULDgBLJYmCyRCWILB3BC5hQBFIJBYLiwXBoCtPd6kSIIQpMLhYOMgQpWC4dIIKpcCa5yGCE6RBCcCxcCyDyjhJBYLga2OFgSwRTYcgIKpcSgjITCij4YbQTIREwWAISpBDyBWSE58SEyKeKyVAOMKYUFhBxRgBWRNCaeIIgTdTkAQMhIRBpBBVTwazQfCZTQTxbjUWx8EVSYAEgJBEUKR0PVSgpHUKrIOa6CeML6sJTZrsUTw4CDLiqbKKAVAIKqeCIIZuLAA8CXJcBEwRBVEwSGENxTIVSRoALII0kwDIfEYRBVTwYCEUKzIId4TUJABhBHWBLINoCtKIKqqCIgrmUZBRNLABpBHkmAZDwjCIKrgCIgxiUPRKPKMqCGHcy44GNYSnUMoZEHUi44FaJQANgJBJECrIIaJIAOIJOSpAgXNY4gVdIREIeQzIWFIQgYIhDyFAB4aCA4ggCD6kCIJTpZFI2QMS4CJEKh9HhKMGAB4XCIhRCVPosBEANIUi4CKESg7GgikWC4RBKMqrICkAFCiSkWIJgjWgQXBwAFEZwYAQLIRBLEakAhIaBoAFEDqhBNZCzsCAoQdWLIREMeQaqUI4gdTgJBOeQaqVI4yhUIhryCACTCEDoOQDaZBPeQYmUYQLyCL6abCZEcCQAaJEcagCOQikBQAaJDACKbCZEkEC4SJCUKRcCQyBCUd4RuDLirIlC4OQNwVIDKRBSEyatDpDLDTyjImC4MgZYaeTIKOQIKcCC4OADSkJIKTIVFITLCoAYRIKawBISZZCggaBC6IUCZE5ZCDQQXRiRBTVqcAgQaEwAXWZEkBDQgXRIKprSeQ1ILKzIleQieRIK1JIKSwFTyJBWZCawFTaoCTQiUEC4dITarImNwkgCp8JIK8kISTgVILDISgIXUbojInFglIbqjInFgkgbqjInC4mACh0JILKwQgEBLKhBZZCUELKYUEAS2QISESC4cgCibIoC4mACiYCWNx8AgIXECh0JHzDITeoibPQbECZCb1ETZ5BXyCzDZCAaEwBWSASdALgbIPKwYCBKyYCSYQRHEABsEDohWTASTCBZCYaCWwRWTASTvCeqMCCITdQIK4mCF4TIPhIRBTYQUNEwYCUEwTIDY5wRBpC2CKyBEVcYzIOCIMgiQUBKx6GWDYQsCyQtNWYWACh5oDASh9DUIVIIRo+DCh5oDASihGkAtMgIRBoDLDKx4CUNAgICyCzPZYhWOIipoDFgR0CWZzdDKx5EVNAYsCOgKzOSoIUPKwREVDgYIDFphTCSoKJDKxpBVpAcDBAR0BABYXECh0BIK1JkAcCgQICOgIALC4YyCL4gAHghBWkmAUIz1PC4RfFChZEVPoT4CeqDCCTYRfDChSGZAob1PLIrdMILCMJFhj7FTRhBeFh8gfYoULa4REdFhzdBfYgVLa4RBcyAsLHYwFBpDdOATlAFZUBBwybOIL1JNxzOGTZYOCILkgNxyMGZBcJZD2AFZUSBw0ELJpBeySELBw7IOLIRBboCwNBwoIILJACbQhYOIZFopKHBK5CwAYKILopLHBLIsFBUCBwOQaJ4AEgJBcNZZ6KZFZrNpC5KLhSeCILMgIRQOLZFStOBZDINghBayBBKGpjIpExzUMZEtIExUJKBjINcYYCWNBpQLZFAzKBwUgBzDIZVRUEKBrIDyDIiEZz7LZAbXOASh0Za6YCToBlNBxZTQBwRBSU5cJBxoRRBwRESEBUBBxoADggjCB5ZBefB4ADgQjCB5ZBSGRZxPXI6VPILKkDwBCPGQYULSoZBZiSzOGRFAdhxBYFiAAEgIpDCJhBMNyFIIKDdETZxBJF5xTQC7MEIIuQCx0Ja577LwAYTeUIAHiRxCoBCjILBcaVtL4DIMMEEwWQDi5BCpMgIMZoZUIZfYVRdADrESQwZB8gEBQ0JBDpAgfQzggggEJQzxBhgEEEbodEkBCdgAjDQzBBkgBBDEyyhFkhBfgECEwmSoBcXIMIpIwAWOgJBpQw4sNCiiGgF5QRRQ04CRIMwABghBWkBBoAAMJIP4ACiRBRpBAsAARBQoBBvAAMBIJmAIGJEMYTo=")) +var redImg = require("heatshrink").decompress(atob("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")); +var greenImg = { + width : 142, height : 145, bpp : 1, + transparent : 1, + palette : new Uint16Array([2016,65535]), + buffer : require("heatshrink").decompress(atob("/4AF/kAv4JGAA4aBn4QN+ARQHwQRNEQRHOwARPNAJ0JAAvgCAUBK58AgYQL/ARDg4RL4ARDgkAh40NEpg0EAAQjJGggRMCA0Aj6/Gg40HbA3+Q4KeDAAjGFBwMDaYYAEIZrGIIZCOIPA58JCBRqFGhZqFGhZqFCBcDCAf8CJZYEVpDVIVpBYHaYJYP+ARMEYZ7MEYgQMCIZ7MfIhGNfIZGNUAaNMfIaNNLAf4LCDUMLAhGQRppGDGhsDGiCNCPZ0fPZ4RDYRpqDCBsAv40PPgQQOYYIiGh6OJRgyCC+DVFYI0DFQMDCIsfAwoZBZIMPBQs/Gg0PSgM/bwrBHnx1CDgkBGg0AvBGBDgsHYI0BIwSGFj7OKIwosBAAccXghjFC4kHF4cDTAsDC4iTERo0OfwpeDTA04dgoMDZoxGERAkDNIpGFgJYDh7MGRpMwAwt8CJJXFahAAIg5NFABUfFQoAK/4QPQ4gAMZIwAFXok/ZwcAhAvFDol+BYl4MgodECwl/AokDdgkBCwYKBDgl/MgkGUgn/UocB/4pEKQgRBfAYpBZBQjEg46ECI7JPh63RIwbJZVZQRMLBMQAws+Aws/DAVgBQrnGSoUDFo1ASgrdChxMLCAKnCvhdLCIQnBQwcPCAr4BAAK5Bv7fDv6LFh4RC/4nBBgQbBCIoQDG4YbDCIhoCAAbxDv4RFK4YAC/gJBgZyDGhJqCDYQQDDAQRHHQppFAAR8BBIX4cYgRG4CWDUoZGHEYJoBFAZ7IAAxqDPYylJSgQAKSYTlEABJYDIxpYDPY5YJCBixDYQ4AFWIbCHI35G/I0oQCgF/Gh8BERnALBxoDAAMHEJxqMIgY1NVwYRMEQw2KEQyQJ/gQICI6/DAAyLLAAi0GK5CiI+ARJfY3we4oACj7VOERB+KYhPwgcAhDWN4EcgF4fRuA/EDOAP8RgxYEg/gj/gGRRYCj/Av4TBCJaQBEAITBCJfn/xTB4IQLGwQgMAAf5DRAA=")) +} +var whiteImg = require("heatshrink").decompress(atob("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")); +var blackImg = { + width : 152, height : 144, bpp : 1, + transparent : 1, + palette : new Uint16Array([0,65535]), + buffer : require("heatshrink").decompress(atob("/4AGwAKBg4LHAAoeEh4RL8AyNEhAABj4RJ/ASGgYSJ4BsPG5AABn4RH/gSIJhHwCRCaIQQxfLXIQAGgJwQORISvJY/4OJISH8CERwASJVQ3+gC9JjwmF/EAuASImByFEYN4JRB7Bv7hFCREHAQM/cIs8VRMAj4SDAwISLh5wEM4ISKOQYSCj4SKX4f8FgROBfBiWBNAL3JAAKFCXQUDXxISEcAZPCABCYCCQZyLTARHLTAwSPg7PDCSAROXwYSPXwJ/LCS7RBCSN/eoQShn/4CUcfCSXwCUcPCSXgCSEHCWZHDgfAC4bfMCQn//wRGgf//4SFg4IBDAY3DBIYSDn4IBTowJCJgMBwA3CAAJCCAAYJCDgISCgIICIQQACBIf4CQZTCAAIsCKggvCCQQIDL4pdCCQoIDKoQACj4ICR4ISCBAYSFOASiFCQiFEv5oHDYYSFBAYSJPYISUUAiOECSRUECQazECRLkDCVbaDCRDsECSo6BCRwQBCQyEDCRKqICQoHBHQMPew4SE/zEBCQLHEM4YSEFwISCEwigDCQngCQgTCJQarEPIUBCoIAPgYSSNQYADgUAsASHIooABgwSIg7JDCRyaBCR5/BCRFwBI0fW4gSMeYJyGhwSKL4wSJaoQSHvAIFgLoECQqhGfgY5FCRBwBAARzECRF/CQYmEjwSGVAIAEJoYSGGwgADwASHNwYSOGwwSGgISDXIISQCJASDnwSDJRISEgYSCgYSMn4SDZgYSKw4SR/4SQbQISVLxt4OKIABnASRAAQS/CRb2NCX4S/CTkACRsMCR9ACQUCCRtgCQUGCX4SGuASChwSN+ASVjwSPEYM+CRv4CQV+CSP+CSEHCR38gEP/4SggIOBCSUfCRvAgP/gE/CRvgCQOAAwUAAwIAI/EDAwgSL/4SFwAGFAAvnKQsHAwgA==")) +} +var backgrounds = [blackImg, blueImg, redImg, greenImg, whiteImg] +var manaColors = ["#000000","#0000ff","#ff0000","#00ff00","#ffff00"] +var bgIndex = 0; +g.width = g.getWidth(); +g.height = g.getHeight(); + +//console.log(backgrounds.length); + +//var Layout = require("Layout"); +//var layout = new Layout(); + +Graphics.prototype.setFontTreasurehuntDOYwE_20 = function(scale) { + // Actual height 20 (19 - 0) + this.setFontCustom(atob("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C////4AP////gA/7/q+ADwB8A8APQLwDwAvS/APAC//8A4AP//0DAAv/f0sAAvg//gAAED/8AAAAL/gAAAAL4AAAAAEAAAAAAAAAAC//8AAAv//8AAL///8AA//7/wAH4AF/AAtAAB9ADwAAD4APAAALgA8AAAtADwAAC0APQAAPAAvAAA0AA8AALAADgAA0AAEAAAAAAAAAAAAHgAFbwAv///+AD////4AP////wA/v+q/AD8EAH8APwAAfgA+AAB+AD8AAD4APwAAPgA/gAA8AC/QAHgAP/kB9AAv/+/wAA///9AAB///QAAAf/0AAAAEQAAAAAAAAAAAH/4AAAD//8AAAv//8AAH///4AA/r//wAH0fB/AAsB4B+ADwHQD8APAcALwA8BwAeADwDACwAPAcAPAA+BwA8AD8LQHQALwtA8AAOBgCQAAQAAAAAHVURWQAv///+AC////4AP////gA//+q+AD4BwC8APQDADgA8AMANADwAwAAAPQHQAAA/AcAAAD8AQAAAPwAAAAA8AAAAABgAAAAAAAAAAAAAf//QAAD///QAAv///AAH/qv+AAvAAL8ADwAAPwANAAAvAB0BQA8ALQPADwAtA8APAC0DwA4ALwOAHgAPw9A8AA/D//gAC0P/8AABAr5AAAAAAAAAH/r5rgAf///9AB////0AL+///gAYAOQeAAAA0AUAAADQAAAAANAAAAAA4AAAKADwAQA+7/rvAD////4AL////gAv+v6+ACgAAAsAAAAAAQAAAAAAAB1BUAoAH//+/gAf///+AC////4APqv+vgAQAAAKAAAAAAEAAAAAAAKQAAAAP/AAAAb3//v+v+P/////w/////9D/+v/5AFAAEAAAAAAAAAAPVaVSgA////+AC////4AP////QA////+ACUf9V4AAD/4DgAAv/0EAAH9/wAAB/i/0AAP4D/wAD+AL/gAPgAL/AA8AAL+ACAAAH8AAAAAL4AAAAAPwAAAAAfAAAAAAsAAAAAAwAAAAADAAAAAAIAAAAAAADgFBQYAP7///wA////+AD////4APuvv/wAUAQAfAAAAAA4AAAAADgAAAAAOAAAAAA9AAAAAD8AAAAAeQAAAACwAAAAAFAAL///0AA/+lbwAP/AALQA/wAAIAD9AAAAAPwAAAAA/AAAAAD9AAAAAH9AAAAAD+AAAAAH/UBQAAH///gAB////AAf///4AD//6vQAv+oAEAD/QAAAAP8AAAAAvQAAAAC0AAAAAPgAABAAfgAAsAA/QALwAB/Qb/AAB///8AAB///gAAB//8AAABqUAAAAAAAAD+pZuq/v/////k/////kD/+AAAAO/8AAAAS/8AAAAD/wAAAAH/wAAAAP/AAAAAv9AAAABv4AAAQA/0AADAD/wAANAH/AAA0AL9AADkVf9AAP///9AA////8AD5ABWQAEAAAAAAAAAAAAAAH//8AAA///4AAP+r/wAB9AH/AALgAH8AB4AAH0ALAAALgA8AAAfADwAAA8APQAADgA/QAAMAC/QAGwAL/lC9AAf//vwAA///9AAB//+QAAB//wAAAAWQAAAAAAAAAIAAAAAH1WpVVB7//////P/////4/+///+DVRfVUAMAA8AAAwADwAADQAPAAAPAA4AAA/gHAAAD/74AAAP//AAAAf/8AAAAb+AAAAAFQAAAAAAAAAAAAD//8AAA///4AAL///wAA9QL/AALgAH9AB8AAH0ALQAALgAsAAAfADwAEA8APAA8DgA/AD4NAC/AL2wAH/UP9AAf//v0AA////wAB////AAB//x8AAAagA0AAAAADQAAAAAJAAAAAAACwAAAPAPVWqr4Av////AC////0AH///8AAf/7/AAB9QAQAAHAAAAAAcABgAAB8APAAAH4B/QAAf5v/QAA////AAD//f+gAD/0v/wAHpAv/wAAAAL/0AAAAL/gAAAAH/AAAAAH8AAAAALwAAAAAPAAAAAAcAAAAAA0AAAAABQAAAAAAAP/AHwAC/+AvQAP/8C9AC2/0D0APA/gPgA8C/AvADwL8B8APA/wHgA8D/QtADwP/rwAPgv//AAvA//wAB0D/+AAAAH/QAAAABUAAAAAAAAALgAAAAA8AAAAADwAAAAAPAAAAAA8AAAAADwAAAAAPQAARQA//7//AD////8AP////gA////+AD1WQD8APAAAHwA8AAAOADwAAAQAPAAAAAA+AAAAAD8AAAAAPwAAAAA9AAAAADgAAAAAEAAAAAA4L/5AAD2//8AAP///+AA////8AD/mv/wAPkAH/AAsAAH8AAAAAL4AAAAAPwAAAAA/AAAAAD8AAAAALQAAAAAtADAAADwAOQAJPAA////8AD////4AP////0A//v//w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"), 32, atob("BgYHDQsQEwQKCAgLBgkGDA4GCwoPCwwMCwwGBgwJCwoNGREQExEQEREICBcOHRUTERUaEBYXFh0TERIKCwcKCgYSDg0PDQ0NDgcGEg0XERAPEhINExERFw4ODwYFBgoK"), 20+(scale<<8)+(2<<16)); + return this; +} + +Graphics.prototype.setFontTreasurehuntDOYwE_40_N = function(scale) { + // Actual height 40 (39 - 0) + this.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAA8AAAAABwAAAAAHAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAB4AAAAAfwAAAAB/AAAAA/4AAAAH+AAAAB/gAAAAf4AAAAH+AAAAB/gAAAA/4AAAAP+AAAAB/wAAAA/8AAAAf/AAAAD/gAAAAf4AAAAA+AAAAADwAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAP/wAAAB//wAAAf//wAAD///AAAf8H+AAB+AH8AAPgAHwAB4AAPgAHAAAeAA4AAB4ADgAAHgAOAAAOAA4AAB4ADgAAHgAPAAAeAA+AADwAD8AAeAAH4AD4AAf4APgAA/8H8AAD///gAAD//8AAAH//gAAAH/4AAAAAYAAAAAAAAAAAAAAAAAAAAAAAAYAABAADgAAeAAf///4AD////gAP///+AA////4ABwAADgAAAAAGAAAAAAAAAAAAAAABwAAGAAPgAA4AB8AAHgAHwAA8AA8AAHwADgAA/AAMAAP8AB4AB/4AHgAf3gAPAH8eAA8B/B4AD4P4HgAP/+AeAA//wB4AB/8AHgAD/AAPAAPgAB8AAAAAPwAAAAB+AAAAAHgAAAAAAAAAAAAAAAAAAAAABgAAPwAOAMA/AB4DwAcAHAeAA4AOD4ADgA4/AAMADn8AAwAP/wADAA/3AAcAD8cADwAPh4AeAB4HgH4AHAfB/gAAA//8AAAB//gAAAD/8AAAAH/AAAAAEAAAAAAAAAAAAAAAAAAA4AAAAADgAAAAAeAAAAAD4AAAAAPgAAAAB+AAAAAP4AAAAB/gAAAAHOAAAAA44AAAAHjgAAAA8OAGAAPg4AYAD8Dh/gAP///+AB////wAH////gAP///+AA4BwA4AAAHAAgAAAMAAAAAB4AAAAAHgAAAAAeAAAAAB4AAAAAPAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAAcAPAAADwAMAAA+AAwAAP4ADAAD/AAOAA/8AA4AD/wADAAP3AAMAA8cABwADhwAfAAOHgD4AA4fAfgADh//8AAfD//gAB8P/8AAHwf/gAAeB/4AABwD/AAAAAAAAAAAAAAAAAAAf/AAAAH//AAAA//+AAAP//4AAB/5/gAAP8A/AAB/wB8AAf3ADwAD8cAPAAfDwA4AB4PADgAPA8AeAB4DwDwAPAHgPAB4Afj4APAB//AB4AD/8APgAH/AA8AAP4ADgAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAPAAAAAB4AADgAPAAA+AB8AAP4AHwAD/gAfAAf4AB8AH+AADwA/gAAPAP4AAA8D+AAADw/wAAAPP8AAAA9/AAAAD/4AAAAP+AAAAA/gAAAAD4AAAAAfAAAAAAwAAAAACAAAAAAAAAAAAAAAAAAAAAAH8AAAAA/4AAAAP/wAADh//AAA/Pw+AAH+8B4AA//AHgAH/8AeAAcHgA4ADgeADgAOB4AOAB4HwB4AHg/gPgAfn/x8AB/9//gAD/3/8AAP+P/gAAPwf4AAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAACAAfgAAcAH/gADwA//AAeAD/8ADwAf/4AeADwHgDwAeAeAfABwA4D4APADgfAA4AOD4ADgA4/AAPADn4AA+AN/AAD4A/4AAP8f+AAA///wAAB//8AAAH//gAAAH/4AAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAHAeAAAA+D4AAAB4PwAAAHg/AAAAcB4AAAAAAAAAAAAAA"), 46, atob("CxgcCxcUHhUXFxYXCw=="), 40+(scale<<8)+(1<<16)); + return this; +} + + +function draw() { + g.clear(); + drawBackground(); + drawDate(); + drawTime(); + drawBattery(); +} +function drawDate() { + days = ["Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"] + months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + var d = new Date(); + var dateString = `${days[d.getDay()]} ${months[d.getMonth()]} ${d.getDate()}`; + g.setFontTreasurehuntDOYwE_20(1); + var sm = g.stringMetrics(dateString); + g.setColor(0,0,0).drawString(dateString, (g.width - sm.width) / 2, g.height - sm.height - 3); +} + +function drawTime(){ + var top = 100; pad = 6; bh=48; bw=62; linew=3 + var boxH = {x:pad,y:top,x2:pad+bw,y2:top+bh}; + var boxM = {x:g.width-pad-bw,y:top,x2:g.width-pad,y2:top+bh}; + var innerH = {x:boxH.x+linew, y:boxH.y+linew, x2:boxH.x2-linew, y2:boxH.y2-linew} + var innerM = {x:boxM.x+linew, y:boxM.y+linew, x2:boxM.x2-linew, y2:boxM.y2-linew} + g.setColor(manaColors[bgIndex]).fillRect(boxH).fillRect(boxM).clearRect(innerH).clearRect(innerM); + + //Draw the hour and minute + g.setFontTreasurehuntDOYwE_40_N(1); + var d = new Date(); + var h = `00${d.getHours()}`.slice(-2); + var m = `00${d.getMinutes()}`.slice(-2); + + var yOffset = 1; xOffset=2; + var mH = g.stringMetrics(h); + var mM = g.stringMetrics(m); + var xH = (bw - mH.width)/2 + boxH.x+xOffset; + var yH = (bh - mH.height)/2 +boxH.y+yOffset; + console.log `Hours: ${h}, x: ${xH}, y:${yH}`; + var xM = (bw - mM.width)/2 + boxM.x+xOffset; + var yM = (bh - mM.height)/2 +boxM.y+yOffset; + g.setColor(0,0,0).drawString (h, xH, yH).drawString(m, xM, yM); +} + +function drawBattery(){ + var pad = 6; top=pad; bh=10; bw=40; linew=1; + var box = {x:g.width-pad-bw,y:top,x2:g.width-pad,y2:top+bh}; + var innerB = {x:box.x+linew, y:box.y+linew, x2:box.x2-linew, y2:box.y2-linew} + var batteryFill={x:box.x+linew, y:box.y+linew, x2:(box.x-linew)+bw*E.getBattery()/100, y2:box.y2-linew} + g.setColor(manaColors[bgIndex]).fillRect(box).clearRect(innerB).setColor(0,1,0).fillRect(batteryFill); +} + +function drawBluetooth(){ + +} + +function drawBackground() { + var metrics = g.imageMetrics(backgrounds[bgIndex]); + g.drawImage(backgrounds[bgIndex], (g.width-metrics.width)/2, 5); +} + +function nextBackground() { + bgIndex++; + if (bgIndex > backgrounds.length - 1) bgIndex = 0; + if (bgIndex < 0) bgIndex = backgrounds.length - 1; +} +function prevBackground() { + bgIndex--; + if (bgIndex > backgrounds.length - 1) bgIndex = 0; + if (bgIndex < 0) bgIndex = backgrounds.length - 1; +} + +Bangle.on("touch", function (button, xy) { + if (button == 1) { + prevBackground(); + } else { + nextBackground(); + } + draw(); +}); + +draw(); +Bangle.setLocked(false); +Bangle.setLCDPower(true); +Bangle.setUI("clock"); + +var redrawTimerId = setInterval(function(){ + draw(); +}, 60000); diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json new file mode 100644 index 000000000..dcc58ea6c --- /dev/null +++ b/apps/mtgwatchface/metadata.json @@ -0,0 +1,36 @@ +{ + "id": "appid", + "name": "Readable name", + "shortName": "Short name", + "version": "0v01", + "description": "Magic the Gathering themed watch face. Embrace the inner wizzard ", + "icon": "icon.png", + "screenshots": [ + { + "url": "screenshot.png" + } + ], + "tags": "", + "supports": [ + "BANGLEJS2" + ], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + { + "name": "mtgwatchface.app.js", + "url": "app.js", + "supports": [ + "BANGLEJS2" + ] + }, + { + "name": "mtgwatchface.img", + "url": "app-icon.js", + "evaluate":true, + "supports": [ + "BANGLEJS2" + ] + } + ] +} \ No newline at end of file From a9b072ccb4bd9567c15f87b7d7627373668cbae6 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 13:29:47 -0600 Subject: [PATCH 013/253] Delete node.js.yml --- .github/workflows/node.js.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/node.js.yml diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml deleted file mode 100644 index 278de90bf..000000000 --- a/.github/workflows/node.js.yml +++ /dev/null @@ -1,31 +0,0 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: Node.js CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [12.x, 14.x, 16.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm ci - - run: npm run build --if-present - - run: npm test From 1e0a8f2411748f2afd59155dfc75249d3ac8c972 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 13:33:24 -0600 Subject: [PATCH 014/253] Update metadata for MTG Watchface --- apps/mtgwatchface/metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index dcc58ea6c..b3ec2d3f1 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -1,7 +1,7 @@ { - "id": "appid", - "name": "Readable name", - "shortName": "Short name", + "id": "mtgwatchface", + "name": "MTG Watchface", + "shortName": "Magic the Gathering Watch Face", "version": "0v01", "description": "Magic the Gathering themed watch face. Embrace the inner wizzard ", "icon": "icon.png", From 3f684d138dcc0886996996c8c40e25ae31af68eb Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 13:43:05 -0600 Subject: [PATCH 015/253] Add screenhshot for MTG Watchface --- apps/mtgwatchface/black.png | Bin 0 -> 3427 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/mtgwatchface/black.png diff --git a/apps/mtgwatchface/black.png b/apps/mtgwatchface/black.png new file mode 100644 index 0000000000000000000000000000000000000000..a348053a5e3adaacfc20f35ec577e39525312f50 GIT binary patch literal 3427 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 Date: Sun, 13 Mar 2022 13:46:17 -0600 Subject: [PATCH 016/253] Update metadata --- apps/mtgwatchface/metadata.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index b3ec2d3f1..268a39669 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -6,9 +6,7 @@ "description": "Magic the Gathering themed watch face. Embrace the inner wizzard ", "icon": "icon.png", "screenshots": [ - { - "url": "screenshot.png" - } + {"url": "black.png"} ], "tags": "", "supports": [ From d629f79e8dcfca30a976d5ad325b9c714d4f3571 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 13:50:36 -0600 Subject: [PATCH 017/253] Add icon --- apps/mtgwatchface/icon.png | Bin 0 -> 2240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/mtgwatchface/icon.png diff --git a/apps/mtgwatchface/icon.png b/apps/mtgwatchface/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9fb2cd3e7b99f37ca2da0e93b7bc18745ac391 GIT binary patch literal 2240 zcmV;x2tW6UP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2vtc$K~!i%-I{l3 z6;BYyCmMV2-H6ybMiCVoiY>ONs7OQwODtdn(J1;yu*8A}Y+#EbiXd2mVu)g|v0wu+ zu_czMu||X4>~FvG_TIaDxA&U)5r4mr4B6dxw>Pu5J3F&yn2^wam_jk&?c2BX=+Ps} z%*^Eai4!OIuZ}u(>QI|DZKzSBM%1odJE~NvlKO?{QsyPf&&pRd-&CtsjUpo>iC{n| zNTtQrty@LUo;^i)csK?jXen2&oESQEs5o-u2=^Hw{{>1~S{nZi+JLWLzlwSD=84j! zOKX)1Rr>euFRJ8KQBU!YVL;GRXu*O7w0iYwRV!qoiPB=zRK-8iXlZ(YBT=QLI=oe#qUscSVgFHEa+66KUMIF)JSz7spd+ z;>3v}J3Cux;2WO?+`fHVNRMH8SYl$LNJ>hwwEd|>MMa6?#fw|o>eZ_!GBPrhCeAn- zfRXoB9)i)w=)}at*nTT)DOs|lNKH*u8tHK~V91am+D;+Tmy4xKmx|=%gvTD7Wn1pWrWg7(H@fQ%^J8;!Wt4TUHWj3wS{#&(brM*5YD~qo)uo$ps&mQefJ$m#I_wU~q z1qB7_N)KpDPfr(JyLQ#y>m+c$6DCX$A3l6gJz4qv`?uDWuUofHUE#uFz?wB{Y&SqL zM4gnFSJ58TH zoy*?+7`%M>l4Rb&%3r;DRkga(0g9Z(+cQkzXaFXFI z*RerOn>LLG3>ZL@CQWj;>o|S-G)dPesK&VfKLo2l!duy1_#t6bFuPVC>kj{JIdgtXQ#vWP(A%h7F^sQ>XGGmGQc| zvT%^zhU(U>OEPJqjEoGbT)8rbHkfKrQBmqDI{~=|tPeRN^y9}5u46hG-va&(%9bt5 zf7h>HPwm^cXQP}5$N;#j=g*&0)22FrLe-qX zV69!dme+$X0y3aWmo9Yk=1t1Z&gT38(+EMC8BDS0=x9~*FmBv9RdRu8A?LWNIfH-= z&H@AG3r7QF@=S8;c266SoSaOzZr!qlxCZ`Wci=RiF*rCn0f~u;Bx5OlHl|TbObi`A zew=^v#?b(T$b$zDW|s)IZ{JSKmMtThHu7}Q0oUgZLS}#+Rt94{sye=X`$kQgG+{+Q ze*DP$$BP#)=;FnT{PvB0Y`_)i+^CryJ9cnjC%1LgVh87!2(~(Q>}YY9h;DHdl9!jK zt`s67BEsfIgTd@Z-9w3(&T#m_K6$X%;eEe@R@K76QJ zy}%nVbN%{tKE9L53kOnCDgG{Id?A6if!9K?hfhri@(d3q-<;dq;1d-30Jyhi&6?ad zzH;Io9OxQA4P;$7Jbv}+m1-5N2ZB2Yg1w(Vf2v()vPkg*PbLNcuBcAab1KcBBrjS$A-LE$xc_HkY2(^nIqJIG32;w;Cv3=YC O0000 Date: Sun, 13 Mar 2022 14:01:53 -0600 Subject: [PATCH 018/253] Update metadata --- apps/mtgwatchface/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index 268a39669..79ae3fb7d 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -8,13 +8,14 @@ "screenshots": [ {"url": "black.png"} ], - "tags": "", + "tags": "clock", + "type": "clock", "supports": [ "BANGLEJS2" ], "readme": "README.md", "allow_emulator": true, - "storage": [ + "storage": [ { "name": "mtgwatchface.app.js", "url": "app.js", From 58fd4af88a6a792fe4b593aac4e0a0592b01e367 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 16:29:35 -0600 Subject: [PATCH 019/253] Changed background images --- apps/mtgwatchface/app.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/mtgwatchface/app.js b/apps/mtgwatchface/app.js index f3dc6b188..a90e9ba01 100644 --- a/apps/mtgwatchface/app.js +++ b/apps/mtgwatchface/app.js @@ -1,12 +1,27 @@ -var blueImg = require("heatshrink").decompress(atob("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")) -var redImg = require("heatshrink").decompress(atob("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")); +var blueImg = { + width : 93, height : 145, bpp : 2, + transparent : 1, + palette : new Uint16Array([31,65535,65535,59167]), + buffer : require("heatshrink").decompress(atob("qoAlgoWVgIWVKqwWXioWVOasAOarJWgEMLikAhZcUgEK4IWToEK2AWV1hcToEO1ZcTCwOqLiYWCLiYWCLiZbCLiYWClRcSCwS5TCwUCLiQWCgBcSCwZcSqECCwJcSCwZcSCwZcSCwOqCwJcRqEDCwRcRCwhcRCwXALiVUCwhcQCwpcQqkACwZcQCwpcQCwPqwAWCLh4WGLiAWFLiAWB2AWCLiBWBCwhcPCwxcPgE60AWDLh9ACwpcBgIWO1gWElWACxsKCwsO0BFMoEOCwsD1CiMqEO1AWEX4JcMCxE6LhlQgWrCwpcNqkDCwxcNCwOqCwpcNCxM6f5dUgGq4AWFf5o8BCwz/NCwOACwz/MBoOwCwyiMoBqBCwyiBIpQWB0AWGG4PACxUKCxAJBaJNQh2sCw7wBIpIWB1AWHRYR0IqkC1YWIHAIuIfoIWJeIMAFw79CCxKVBFxAWBfo50DFxD9BCxLyCUY9AP4IWJP4T9QAAfqFw9QcxKjDFw7mKFxbPBcxIuKZ5guKCx0OHgK4GCxgOBwDSEoDPLAAUK1kBXArPKAAeq4AuDXALPLAAU6Fwi4OAAMD1R0DXBwuDUYa4PAAMCaQhjBCx0AlQuDUJ7SDOgShQaQSjCUKDSDIoNUUJ8CUYiKBUJ+gUYRFBgChPlYwBOgSKQFYJ0COYKKPUAJ0B0EFRQJMBABhxB4D6BgNUgSKOIQInBlWAipzQnQQBhxFBOYLOP1RtBIoJzQgWqIocQOZ8A1SLBIoMEOaL9BIoRzQlWqaIMq4FAAQJzPH4JZChQcBc5pcCgYCBLh4WBLgS2CLhyhBXIS2CLh86OYSiBLiEDaARcSgEPCARcCMQQAQLgQCCACD/CL4QAQLgMBL4QARLgL/QLgsQUR5cGgRFSCYMBUoYAQ1cAqE6IqRwBqjoQOYewipFTOYMFIqZBBgJFBRaMDOYNVIoLRR1QWBqDRSFIMVqkDIqPqwEVIqcq2EFIoMOXSCdBCwNUMIQWP0EBqtVoC6QnS4BCwNQgSnBCx6hBAAJ5CCyZ0BUZwWFOgIuOlQWEOgMKFxvqCwqjCFxnq0AWEOgMKRhcD1SxBCwlQFwK7KhwWHFwIKB4CIJBYQWFFwPqIxPqCxAuDPwJDHEIL8CFww6B3hwFFgIgBCw67BHYWvCof61RxCgoWHXYKXBAAO//4ECMoUVCw4uCh4SCAAarCCxJ1BC4xKCLRBGEAAJDC/4GCLRCNFAA4VLC5IsMC5BZLO5AVLoAA==")) +} +var redImg = { + width : 130, height : 144, bpp : 1, + transparent : 1, + palette : new Uint16Array([63488,65535]), + buffer : require("heatshrink").decompress(atob("/4AD8EAh4HEAA38C4UHB5QeBAAQhKwA5Ev4PI/APEgYxK+AQDj5SOgJjLEIYgH/hbDKgQgHJ4JbCKgYgGBQKNDIJIaCII0/Lg4pC/y1IBISMD4CkIc4owDYoprCHIQPDKIopCDAS0EKIjwCIAT2EKIhwCFAQlCCQRwGB4JlCAgJ5C/ZwEBQIkCGgIgBgf+OYRgBF4QEBB4IZCv/PHQZPCYwgJBh/zLQZ4DwAPCCgMBGATRF/ydDGAWPMAbqFGAnhCoXAZIowE/gLBwHweITsHv43B8F8bIowF4LLBv+HaAQcBOwTWBgP4v/8n/jFQUHFgLfBLYV+FgM//AqDK4KCCfgWDDgRgC/EPBYP+VgY+BBgPfRgYLBn+fIAMALo4OBFYPjIAUPK4SMFFYJcBAgXgTwwKBIAMPEoV4TwzoBIAODIAUeGBMPVYIEBg+AVowKC/EOGoTPHGAMB/8BwAPBniYCAAZsCOoY1BCwIAFDYLRCAAIjBZIJRGv7VBAAVgUQxRBUwkAjBxGAAYwDgwnBB5AwEwBxGKgoACOIwwHRAQAIQoQACOIwwIOI7XFAAJxKa4QACB5RREIBQgEOJTUFB5RiEWRJiFWRP9cohAJ/gqBUgRAJ/0f+LlDIBH+g/4v5RCIBH+gP4n/gIBcAv0PMIRAJFQMDeoZAIFQPAWYbCIFQPwv6BCh57DAgYKBvEfKAUDBQQWBMwQKBjxyBGATJFv6MCg+BSIZACbIYaCgfgv7SFB4YAD/EfaQoPHn0H+CRECoQAEj+BKAoPHSIN+KAh2CAAkD+EfKAg1CAAv8g5KCKAI1DAAl/gKhEa4ZQF4EgKAaWDAAkPHIjyBB48HFIhQBSA6LBEoiAIHQIJDMAJwIv4JDEoJwIn5AEMBJKBMBpKFYIJgHB4JADAoLRHLQJADYJIJBHQbBJBII6DOAJQHB4Q6DAoKhGDIQ6DOAJQHB4I6DOAPIWA46ESwPGUBBQDQAPhSIxwCJQQFB8FAMBChCAoPwmBQIMARmB+EMIBBgDCgMDYJl//EBSJH+EoY0BuAgGn4PDh4PBnjCHB4cHB4MPB40AgQUDB4MHIAwAFQgMBQ4QAMM4YALn4POj/gB5pzCABh4EABSpBwAQN/5AOagJwO/4PPWRiAB/6yNB4JxNB4JxNv4PBOJaPBAALjLh4PCOJQOEOJQ9CAASiIHoYwLgYPGMI4PHGA4PHGA4/HGBBfFSRJ/FAATDHB470HII70Kn6zOB4qzIgEfWZoPHQQ4vGKJKTHEA6CHEAzTIEAxOGMQ7iIaosHBhA")) +} var greenImg = { width : 142, height : 145, bpp : 1, transparent : 1, palette : new Uint16Array([2016,65535]), buffer : require("heatshrink").decompress(atob("/4AF/kAv4JGAA4aBn4QN+ARQHwQRNEQRHOwARPNAJ0JAAvgCAUBK58AgYQL/ARDg4RL4ARDgkAh40NEpg0EAAQjJGggRMCA0Aj6/Gg40HbA3+Q4KeDAAjGFBwMDaYYAEIZrGIIZCOIPA58JCBRqFGhZqFGhZqFCBcDCAf8CJZYEVpDVIVpBYHaYJYP+ARMEYZ7MEYgQMCIZ7MfIhGNfIZGNUAaNMfIaNNLAf4LCDUMLAhGQRppGDGhsDGiCNCPZ0fPZ4RDYRpqDCBsAv40PPgQQOYYIiGh6OJRgyCC+DVFYI0DFQMDCIsfAwoZBZIMPBQs/Gg0PSgM/bwrBHnx1CDgkBGg0AvBGBDgsHYI0BIwSGFj7OKIwosBAAccXghjFC4kHF4cDTAsDC4iTERo0OfwpeDTA04dgoMDZoxGERAkDNIpGFgJYDh7MGRpMwAwt8CJJXFahAAIg5NFABUfFQoAK/4QPQ4gAMZIwAFXok/ZwcAhAvFDol+BYl4MgodECwl/AokDdgkBCwYKBDgl/MgkGUgn/UocB/4pEKQgRBfAYpBZBQjEg46ECI7JPh63RIwbJZVZQRMLBMQAws+Aws/DAVgBQrnGSoUDFo1ASgrdChxMLCAKnCvhdLCIQnBQwcPCAr4BAAK5Bv7fDv6LFh4RC/4nBBgQbBCIoQDG4YbDCIhoCAAbxDv4RFK4YAC/gJBgZyDGhJqCDYQQDDAQRHHQppFAAR8BBIX4cYgRG4CWDUoZGHEYJoBFAZ7IAAxqDPYylJSgQAKSYTlEABJYDIxpYDPY5YJCBixDYQ4AFWIbCHI35G/I0oQCgF/Gh8BERnALBxoDAAMHEJxqMIgY1NVwYRMEQw2KEQyQJ/gQICI6/DAAyLLAAi0GK5CiI+ARJfY3we4oACj7VOERB+KYhPwgcAhDWN4EcgF4fRuA/EDOAP8RgxYEg/gj/gGRRYCj/Av4TBCJaQBEAITBCJfn/xTB4IQLGwQgMAAf5DRAA=")) } -var whiteImg = require("heatshrink").decompress(atob("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")); +var whiteImg = { + width : 153, height : 145, bpp : 2, + transparent : 0, + palette : new Uint16Array([65535,65535,65504,65505]), + buffer : require("heatshrink").decompress(atob("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")) +} var blackImg = { width : 152, height : 144, bpp : 1, transparent : 1, From cc1f0f6d378dedb083f60370b9913a8acca296b4 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sun, 13 Mar 2022 23:51:22 -0600 Subject: [PATCH 020/253] Added Bluetooth v1 --- apps/mtgwatchface/app.js | 22 +++++++++++++++++++++- apps/mtgwatchface/metadata.json | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/mtgwatchface/app.js b/apps/mtgwatchface/app.js index a90e9ba01..4f5587ad1 100644 --- a/apps/mtgwatchface/app.js +++ b/apps/mtgwatchface/app.js @@ -51,6 +51,16 @@ Graphics.prototype.setFontTreasurehuntDOYwE_40_N = function(scale) { return this; } +//Bluetooth on +var btOnImg = { + width : 15, height : 22, bpp : 3, + transparent : 2, + buffer : E.toArrayBuffer(atob("/////H//////A/////4A/////4BH////4JI////4JJH///4J5I///4BP5I///BJ/5A//BJPP5A/4JJ5P5H4J/PL/JHBJf/5JI4JJ/7JJIBP75/ZJAJZPJ/JIBJJ5/JJHBJP/JJA4JJ/JJI/4JPJJI//4BJJA////AAH//A==")) +} +var btOffImg = { + width : 15, height : 22, bpp : 1, + buffer : E.toArrayBuffer(atob("AAAAwAcAGgBEAQgEEBgQIDCAIQAiACgAUABgAMABgAKACQARAEGDAPgA")) +} function draw() { g.clear(); @@ -58,6 +68,7 @@ function draw() { drawDate(); drawTime(); drawBattery(); + drawBluetooth(); } function drawDate() { days = ["Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"] @@ -103,7 +114,13 @@ function drawBattery(){ } function drawBluetooth(){ - + var img; + if (NRF.getSecurityStatus().connected) { + img=btOnImg; + } else { + img=btOffImg; + } + g.reset().drawImage(img,3,3); } function drawBackground() { @@ -136,6 +153,9 @@ Bangle.setLocked(false); Bangle.setLCDPower(true); Bangle.setUI("clock"); +NRF.on('connect', draw); +NRF.on('disconnect', draw); + var redrawTimerId = setInterval(function(){ draw(); }, 60000); diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index 79ae3fb7d..3e1a9df29 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -2,7 +2,7 @@ "id": "mtgwatchface", "name": "MTG Watchface", "shortName": "Magic the Gathering Watch Face", - "version": "0v01", + "version": "1v01", "description": "Magic the Gathering themed watch face. Embrace the inner wizzard ", "icon": "icon.png", "screenshots": [ From faea4564f0a5409d1cc2021d3696ecac873b8516 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Tue, 15 Mar 2022 15:29:32 -0600 Subject: [PATCH 021/253] Added charger indicator --- apps/mtgwatchface/app.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/apps/mtgwatchface/app.js b/apps/mtgwatchface/app.js index 4f5587ad1..d54247033 100644 --- a/apps/mtgwatchface/app.js +++ b/apps/mtgwatchface/app.js @@ -62,6 +62,14 @@ var btOffImg = { buffer : E.toArrayBuffer(atob("AAAAwAcAGgBEAQgEEBgQIDCAIQAiACgAUABgAMABgAKACQARAEGDAPgA")) } +//Charging symbol +var chrgOn = { + width : 8, height : 15, bpp : 2, + transparent : 0, + palette : new Uint16Array([65535,65504,63488,64928]), + buffer : E.toArrayBuffer(atob("qterVKlcrVClcLVAlVfVVA1cDVANQA3ADQAPAAwA")) +} + function draw() { g.clear(); drawBackground(); @@ -69,6 +77,7 @@ function draw() { drawTime(); drawBattery(); drawBluetooth(); + drawBatteryStatus(); } function drawDate() { days = ["Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"] @@ -122,6 +131,17 @@ function drawBluetooth(){ } g.reset().drawImage(img,3,3); } +function drawBatteryStatus(){ + var left = g.width - (20+6+4); + var img; + if (Bangle.isCharging()) { + console.log("Charger connected"); + img=chrgOn; + g.reset().drawImage(img,left, 4); + } else { + console.log("Charger not connected"); + } +} function drawBackground() { var metrics = g.imageMetrics(backgrounds[bgIndex]); @@ -155,6 +175,7 @@ Bangle.setUI("clock"); NRF.on('connect', draw); NRF.on('disconnect', draw); +Bangle.on("charging", draw); var redrawTimerId = setInterval(function(){ draw(); From 79fb0a37a473638f4bad85ad31f6540958c16933 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Tue, 15 Mar 2022 15:32:58 -0600 Subject: [PATCH 022/253] Version up to 1v02 --- apps/mtgwatchface/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index 3e1a9df29..a24ca52c8 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -2,7 +2,7 @@ "id": "mtgwatchface", "name": "MTG Watchface", "shortName": "Magic the Gathering Watch Face", - "version": "1v01", + "version": "1v02", "description": "Magic the Gathering themed watch face. Embrace the inner wizzard ", "icon": "icon.png", "screenshots": [ From 90a946e99861fce41c447a98beebbf4e52051492 Mon Sep 17 00:00:00 2001 From: Hilmar Strauch <56518493+HilmarSt@users.noreply.github.com> Date: Thu, 17 Mar 2022 09:17:31 +0100 Subject: [PATCH 023/253] Update app-icon.js --- apps/bikespeedo/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bikespeedo/app-icon.js b/apps/bikespeedo/app-icon.js index c34f52cfb..411d644fd 100644 --- a/apps/bikespeedo/app-icon.js +++ b/apps/bikespeedo/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwxH+64A/AC+sF1uBgAwsq1W1krGEmswIFDlcAFoMrqyGjlcrGAQDB1guBBQJghKYZZCMYhqBlYugFAesgAuFYgQIHAE2sYMZDfwIABbgIuowMAqwABb4wAjFVQAEqyMrF4cAlYABqwypR4RgBwIyplYnF1hnBGIo8BAAQvhGIj6C1hpBgChBGCqGBqwdCRQQnCB4gJBGAgtWc4WBPoi9JH4ILBGYQATPoRHJRYoACwLFBLi4tGLIyLEA5QuPCoYpEMhBBBGDIuFgArIYQIUHA4b+GABLUBAwoQIXorDGI5RNGCB9WRQ0AJwwHGDxChOH4oDCRI4/GXpAaB1gyLEwlWKgTrBT46ALCogQKZoryFCwzgGBgz/NZpaQHHBCdEF5hKBBxWBUwoGBgEAEoIyHHYesBg7aBJQ7SBBAIvEIIJCBD4IFBgBIGEAcAUA8rGAIWHS4QvDCAJAHG4JfRCgKCFeAovCdRIiBDYq/NABi0Cfo5IEBgjUGACZ6BqwcGwLxBFYRsEHIKBIJwLkBNoIHDF468GYgIBBXY4EDE4IHDYwSwCN4IGBCIp5CJYtWgBZBHAgFEMoRjEE4QDCLYJUEUoaCBPYoQCgA4FGozxFLYwfEQgqrGexIYFBoxbDS4YHCIAYVEEAZcCYwwvGfoQHEcwQHHIg9WIAS9BIoYYESoowIABQuBUgg1DVwwACEpIwBChDLFDQ5JLlZnHJAajBQwgLEO4LDBHKAhBFxQxFCIIACAwadLHgJJBAAUrQJxYFAAbKPCwRGCCqAAm")) +require("heatshrink").decompress(atob("mEwgP/ABO/AokfAgf+r4FD3lPBQcZw4FC/nD+4FC/Pn+YFCBIP7GQ4aDEIMDAol/ApQRFuAFEv0/BoQXBx0HAoPgh/nn40C4fwEoP+n/4/BWC/weBBYP5BAM/C4Pz7/7z+f//n7/z5/f//vA4Pv5//AIPv8/n//d//Ou5yBDIOfu58Bz42B+Z8Bz/8AoPgv+/AoP7w0f3IFBnc/5+bL4Oyv/nEYP/+X/mYFC+n8mff8ln+v4vfd7tfsvzvfN7tPtv2vPn6H35vg/f36vX7vj/fz9vvznH+Z3B/0+5/3/l//iDBMwMf+KEBOAPBUoOCj///CNBUQQAEA=")) From 1523a15b8e9c271ee85da212fe66e5f3768874ce Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 20 Mar 2022 17:36:34 +0800 Subject: [PATCH 024/253] Update app.js Rewrite UI code and drawing --- apps/authentiwatch/app.js | 440 +++++++++++++++++++++----------------- 1 file changed, 248 insertions(+), 192 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index fb130969f..2734a064a 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -1,3 +1,4 @@ +const COUNTER_TRIANGLE_SIZE = 10; const TOKEN_EXTRA_HEIGHT = 16; var TOKEN_DIGITS_HEIGHT = 30; var TOKEN_HEIGHT = TOKEN_DIGITS_HEIGHT + TOKEN_EXTRA_HEIGHT; @@ -44,8 +45,8 @@ function b32decode(seedstr) { return retbuf; } -function doHmac(key, message, algo) { - var a = algos[algo]; +function hmac(key, message, algo) { + var a = algos[algo.toUpperCase()]; // RFC2104 if (key.length > a.blksz) { key = a.sha(key); @@ -66,50 +67,52 @@ function doHmac(key, message, algo) { } function formatOtp(otp, digits) { + // add 0 padding + var ret = "" + otp % Math.pow(10, digits); + while (ret.length < digits) { + ret = "0" + ret; + } + // add a space after every 3rd or 4th digit var re = (digits % 3 == 0 || (digits % 3 >= digits % 4 && digits % 4 != 0)) ? "" : "."; - return otp.replace(new RegExp("(..." + re + ")", "g"), "$1 ").trim(); + return ret.replace(new RegExp("(..." + re + ")", "g"), "$1 ").trim(); } -function hotp(d, token, calcHmac) { - var tick; +function hotp(token) { + var d = Date.now(); + var tick, next; if (token.period > 0) { // RFC6238 - timed - var seconds = Math.floor(d.getTime() / 1000); + var seconds = Math.floor(d / 1000); tick = Math.floor(seconds / token.period); + next = (tick + 1) * token.period * 1000; } else { // RFC4226 - counter tick = -token.period; + next = d + 30000; } var msg = new Uint8Array(8); var v = new DataView(msg.buffer); v.setUint32(0, tick >> 16 >> 16); v.setUint32(4, tick & 0xFFFFFFFF); - var ret = CALCULATING; - if (calcHmac) { - try { - var hash = doHmac(b32decode(token.secret), msg, token.algorithm.toUpperCase()); - ret = "" + hash % Math.pow(10, token.digits); - while (ret.length < token.digits) { - ret = "0" + ret; - } - // add a space after every 3rd or 4th digit - ret = formatOtp(ret, token.digits); - } catch(err) { - ret = NOT_SUPPORTED; - } + var ret; + try { + ret = hmac(b32decode(token.secret), msg, token.algorithm); + ret = formatOtp(ret, token.digits); + } catch(err) { + ret = NOT_SUPPORTED; } - return {hotp:ret, next:((token.period > 0) ? ((tick + 1) * token.period * 1000) : d.getTime() + 30000)}; + return {hotp:ret, next:next}; } +// Tokens are displayed in three states: +// 1. Unselected (state.id==-1) +// 2. Selected, inactive (no code) (state.id!=-1,state.hotp.hotp=="") +// 3. Selected, active (code showing) (state.id!=-1,state.hotp.hotp!="") var fontszCache = {}; var state = { - listy: 0, - prevcur:0, - curtoken:-1, - nextTime:0, - otp:"", - rem:0, - hide:0 + listy:0, // list scroll position + id:-1, // current token ID + hotp:{hotp:"",next:0} }; function sizeFont(id, txt, w) { @@ -125,117 +128,42 @@ function sizeFont(id, txt, w) { } } -function drawToken(id, r) { - var x1 = r.x; - var y1 = r.y; - var x2 = r.x + r.w - 1; - var y2 = r.y + r.h - 1; - var adj, lbl; - g.setClipRect(Math.max(x1, Bangle.appRect.x ), Math.max(y1, Bangle.appRect.y ), - Math.min(x2, Bangle.appRect.x2), Math.min(y2, Bangle.appRect.y2)); - lbl = tokens[id].label.substr(0, 10); - if (id == state.curtoken) { - // current token - g.setColor(g.theme.fgH) - .setBgColor(g.theme.bgH) - .setFont("Vector", TOKEN_EXTRA_HEIGHT) - // center just below top line - .setFontAlign(0, -1, 0); - adj = y1; - } else { - g.setColor(g.theme.fg) - .setBgColor(g.theme.bg); - sizeFont("l" + id, lbl, r.w); - // center in box - g.setFontAlign(0, 0, 0); - adj = (y1 + y2) / 2; - } - g.clearRect(x1, y1, x2, y2) - .drawString(lbl, (x1 + x2) / 2, adj, false); - if (id == state.curtoken) { - if (tokens[id].period > 0) { - // timed - draw progress bar - let xr = Math.floor(Bangle.appRect.w * state.rem / tokens[id].period); - g.fillRect(x1, y2 - 4, xr, y2 - 1); - adj = 0; - } else { - // counter - draw triangle as swipe hint - let yc = (y1 + y2) / 2; - g.fillPoly([0, yc, 10, yc - 10, 10, yc + 10, 0, yc]); - adj = 12; - } - // digits just below label - sizeFont("d" + id, state.otp, r.w - adj); - g.drawString(state.otp, (x1 + adj + x2) / 2, y1 + TOKEN_EXTRA_HEIGHT, false); - } - g.setClipRect(0, 0, g.getWidth(), g.getHeight()); -} +tokenY = id => id * TOKEN_HEIGHT + AR.y - state.listy; +half = n => Math.floor(n / 2); -function draw() { - var timerfn = exitApp; - var timerdly = 10000; - var d = new Date(); - if (state.curtoken != -1) { - var t = tokens[state.curtoken]; - if (state.otp == CALCULATING) { - state.otp = hotp(d, t, true).hotp; - } - if (d.getTime() > state.nextTime) { - if (state.hide == 0) { - // auto-hide the current token - if (state.curtoken != -1) { - state.prevcur = state.curtoken; - state.curtoken = -1; +function timerCalc() { + let timerfn = exitApp; + let timerdly = 10000; + let id = state.id; + if (id != -1) { + if (state.hotp.hotp != "") { + if (tokens[id].period > 0) { + // timed HOTP + if (state.hotp.next < Date.now()) { + if (state.cnt > 0) { + --state.cnt; + state.hotp = hotp(tokens[id]); + } else { + state.hotp.hotp = ""; + } + timerdly = 1; + timerfn = updateCurrentToken; + } else { + timerdly = 1000; + timerfn = updateProgressBar; } - state.nextTime = 0; } else { - // time to generate a new token - var r = hotp(d, t, state.otp != ""); - state.nextTime = r.next; - state.otp = r.hotp; - if (t.period <= 0) { - state.hide = 1; + // counter HOTP + if (state.cnt > 0) { + --state.cnt; + timerdly = 30000; + } else { + state.hotp.hotp = ""; + timerdly = 1; } - state.hide--; + timerfn = updateCurrentToken; } } - state.rem = Math.max(0, Math.floor((state.nextTime - d.getTime()) / 1000)); - } - if (tokens.length > 0) { - var drewcur = false; - var id = Math.floor(state.listy / TOKEN_HEIGHT); - var y = id * TOKEN_HEIGHT + Bangle.appRect.y - state.listy; - while (id < tokens.length && y < Bangle.appRect.y2) { - drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:TOKEN_HEIGHT}); - if (id == state.curtoken && (tokens[id].period <= 0 || state.nextTime != 0)) { - drewcur = true; - } - id++; - y += TOKEN_HEIGHT; - } - if (drewcur) { - // the current token has been drawn - schedule a redraw - if (tokens[state.curtoken].period > 0) { - timerdly = (state.otp == CALCULATING) ? 1 : 1000; // timed - } else { - timerdly = state.nexttime - d.getTime(); // counter - } - timerfn = draw; - if (tokens[state.curtoken].period <= 0) { - state.hide = 0; - } - } else { - // de-select the current token if it is scrolled out of view - if (state.curtoken != -1) { - state.prevcur = state.curtoken; - state.curtoken = -1; - } - state.nexttime = 0; - } - } else { - g.setFont("Vector", TOKEN_DIGITS_HEIGHT) - .setFontAlign(0, 0, 0) - .drawString(NO_TOKENS, Bangle.appRect.x + Bangle.appRect.w / 2, Bangle.appRect.y + Bangle.appRect.h / 2, false); } if (state.drawtimer) { clearTimeout(state.drawtimer); @@ -243,101 +171,230 @@ function draw() { state.drawtimer = setTimeout(timerfn, timerdly); } -function onTouch(zone, e) { - if (e) { - var id = Math.floor((state.listy + (e.y - Bangle.appRect.y)) / TOKEN_HEIGHT); - if (id == state.curtoken || tokens.length == 0 || id >= tokens.length) { - id = -1; - } - if (state.curtoken != id) { - if (id != -1) { - var y = id * TOKEN_HEIGHT - state.listy; - if (y < 0) { - state.listy += y; - y = 0; +function updateCurrentToken() { + drawToken(state.id); + timerCalc(); +} + +function updateProgressBar() { + drawProgressBar(); + timerCalc(); +} + +function drawProgressBar() { + let id = state.id; + if (id != -1) { + if (tokens[id].period > 0) { + let rem = Math.floor((state.hotp.next - Date.now()) / 1000); + if (rem >= 0) { + let y1 = tokenY(id); + let y2 = y1 + TOKEN_HEIGHT - 1; + if (y2 >= AR.y && y1 <= AR.y2) { + // token visible + if ((y2 - 3) <= AR.y2) + { + // progress bar visible + y2 = Math.min(y2, AR.y2); + rem = Math.min(rem, tokens[id].period); + let xr = Math.floor(AR.w * rem / tokens[id].period) + AR.x; + g.setColor(g.theme.fgH) + .setBgColor(g.theme.bgH) + .fillRect(AR.x, y2 - 3, xr, y2) + .clearRect(xr + 1, y2 - 3, AR.x2, y2); + } + } else { + // token not visible + state.id = -1; } - y += TOKEN_HEIGHT; - if (y > Bangle.appRect.h) { - state.listy += (y - Bangle.appRect.h); - } - state.otp = ""; } - state.nextTime = 0; - state.curtoken = id; - state.hide = 2; } } - draw(); +} + +// id = token ID number (0...) +function drawToken(id) { + var x1 = AR.x; + var y1 = tokenY(id); + var x2 = AR.x2; + var y2 = y1 + TOKEN_HEIGHT - 1; + var adj, lbl; + g.setClipRect(x1, Math.max(y1, AR.y), x2, Math.min(y2, AR.y2)); + lbl = tokens[id].label.substr(0, 10); + if (id === state.id) { + g.setColor(g.theme.fgH) + .setBgColor(g.theme.bgH); + } else { + g.setColor(g.theme.fg) + .setBgColor(g.theme.bg); + } + if (id == state.id && state.hotp.hotp != "") { + // small label centered just below top line + g.setFont("Vector", TOKEN_EXTRA_HEIGHT) + .setFontAlign(0, -1, 0); + adj = y1; + } else { + // large label centered in box + sizeFont("l" + id, lbl, AR.w); + g.setFontAlign(0, 0, 0); + adj = half(y1 + y2); + } + g.clearRect(x1, y1, x2, y2) + .drawString(lbl, half(x1 + x2), adj, false); + if (id == state.id && state.hotp.hotp != "") { + adj = 0; + if (tokens[id].period <= 0) { + // counter - draw triangle as swipe hint + let yc = half(y1 + y2); + adj = COUNTER_TRIANGLE_SIZE; + g.fillPoly([AR.x, yc, AR.x + adj, yc - adj, AR.x + adj, yc + adj]); + adj += 2; + } + // digits just below label + x1 = half(x1 + adj + x2); + y1 += TOKEN_EXTRA_HEIGHT; + if (state.hotp.hotp == CALCULATING) { + sizeFont("c", CALCULATING, AR.w - adj); + g.drawString(CALCULATING, x1, y1, false) + .flip(); + state.hotp = hotp(tokens[id]); + g.clearRect(AR.x + adj, y1, AR.x2, y2); + } + sizeFont("d" + id, state.hotp.hotp, AR.w - adj); + g.drawString(state.hotp.hotp, x1, y1, false); + if (tokens[id].period > 0) { + drawProgressBar(); + } + } + g.setClipRect(0, 0, g.getWidth(), g.getHeight()); +} + +function startupDraw() { + if (tokens.length > 0) { + let id = 0; + let y = tokenY(id); + while (id < tokens.length && y < AR.y2) { + if ((y + TOKEN_HEIGHT) > AR.y) { + drawToken(id); + } + id++; + y += TOKEN_HEIGHT; + } + } else { + let x = AR.x + half(AR.w); + let y = AR.y + half(AR.h); + g.setFont("Vector", TOKEN_DIGITS_HEIGHT) + .setFontAlign(0, 0, 0) + .drawString(NO_TOKENS, x, y, false); + } + timerCalc(); } function onDrag(e) { - if (e.b != 0 && e.x < g.getWidth() && e.y < g.getHeight() && e.dy != 0) { - var y = Math.max(0, Math.min(state.listy - e.dy, tokens.length * TOKEN_HEIGHT - Bangle.appRect.h)); + state.cnt = 1; + if (e.b != 0 && e.dy != 0) { + var y = E.clip(state.listy - e.dy, 0, tokens.length * TOKEN_HEIGHT - AR.h); if (state.listy != y) { var id, dy = state.listy - y; state.listy = y; - g.setClipRect(Bangle.appRect.x,Bangle.appRect.y,Bangle.appRect.x2,Bangle.appRect.y2) + g.setClipRect(AR.x, AR.y, AR.x2, AR.y2) .scroll(0, dy); if (dy > 0) { id = Math.floor((state.listy + dy) / TOKEN_HEIGHT); - y = id * TOKEN_HEIGHT + Bangle.appRect.y - state.listy; + y = tokenY(id + 1); do { - drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:TOKEN_HEIGHT}); + drawToken(id); id--; y -= TOKEN_HEIGHT; - } while (y > 0); + } while (y > AR.y); } if (dy < 0) { - id = Math.floor((state.listy + dy + Bangle.appRect.h) / TOKEN_HEIGHT); - y = id * TOKEN_HEIGHT + Bangle.appRect.y - state.listy; - while (y < Bangle.appRect.y2) { - drawToken(id, {x:Bangle.appRect.x, y:y, w:Bangle.appRect.w, h:TOKEN_HEIGHT}); + id = Math.floor((state.listy + dy + AR.h) / TOKEN_HEIGHT); + y = tokenY(id); + while (y < AR.y2) { + drawToken(id); id++; y += TOKEN_HEIGHT; } } } } + if (e.b == 0) { + timerCalc(); + } +} + +function changeId(id) { + if (id != state.id) { + state.hotp.hotp = CALCULATING; + let pid = state.id; + state.id = id; + if (pid != -1) { + drawToken(pid); + } + if (id != -1) { + drawToken( id); + } + timerCalc(); + } +} + +function onTouch(zone, e) { + state.cnt = 1; + if (e) { + var id = Math.floor((state.listy + e.y - AR.y) / TOKEN_HEIGHT); + if (id == state.id || tokens.length == 0 || id >= tokens.length) { + id = -1; + } + if (state.id != id) { + if (id != -1) { + // scroll token into view if necessary + var fakee = {b:1,x:0,y:0,dx:0,dy:0}; + var y = id * TOKEN_HEIGHT - state.listy; + if (y < 0) { + fakee.dy -= y; + y = 0; + } + y += TOKEN_HEIGHT; + if (y > AR.h) { + fakee.dy -= (y - AR.h); + } + onDrag(fakee); + } + changeId(id); + } + } } function onSwipe(e) { + state.cnt = 1; + let id = state.id; if (e == 1) { exitApp(); } - if (e == -1 && state.curtoken != -1 && tokens[state.curtoken].period <= 0) { - tokens[state.curtoken].period--; + if (e == -1 && id != -1 && tokens[id].period <= 0) { + tokens[id].period--; let newsettings={tokens:tokens,misc:settings.misc}; require("Storage").writeJSON("authentiwatch.json", newsettings); - state.nextTime = 0; - state.otp = ""; - state.hide = 2; + state.hotp.hotp = CALCULATING; + drawToken(id); } - draw(); } function bangle1Btn(e) { + state.cnt = 1; if (tokens.length > 0) { - if (state.curtoken == -1) { - state.curtoken = state.prevcur; - } else { - switch (e) { - case -1: state.curtoken--; break; - case 1: state.curtoken++; break; - } + var id = state.id; + switch (e) { + case -1: id--; break; + case 1: id++; break; } - state.curtoken = Math.max(state.curtoken, 0); - state.curtoken = Math.min(state.curtoken, tokens.length - 1); - state.listy = state.curtoken * TOKEN_HEIGHT; - state.listy -= (Bangle.appRect.h - TOKEN_HEIGHT) / 2; - state.listy = Math.min(state.listy, tokens.length * TOKEN_HEIGHT - Bangle.appRect.h); - state.listy = Math.max(state.listy, 0); - var fakee = {}; - fakee.y = state.curtoken * TOKEN_HEIGHT - state.listy + Bangle.appRect.y; - state.curtoken = -1; - state.nextTime = 0; - onTouch(0, fakee); + id = E.clip(id, 0, tokens.length - 1); + var fakee = {b:1,x:0,y:0,dx:0}; + fakee.dy = state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, tokens.length * TOKEN_HEIGHT - AR.h); + onDrag(fakee); + changeId(id); } else { - draw(); // resets idle timer + timerCalc(); } } @@ -356,8 +413,7 @@ if (typeof BTN2 == 'number') { setWatch(function(){exitApp(); }, BTN1, {edge:"falling", debounce:50}); } Bangle.loadWidgets(); - -// Clear the screen once, at startup -g.clear(); -draw(); +const AR = Bangle.appRect; +g.clear(); // Clear the screen once, at startup +startupDraw(); Bangle.drawWidgets(); From ed36b7286e2b8ff5505a504df0e429c898233f99 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 20 Mar 2022 23:11:18 +0800 Subject: [PATCH 025/253] Update app.js Workaround Bangle1 issues --- apps/authentiwatch/app.js | 97 ++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 2734a064a..8e25e5ef2 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -135,34 +135,32 @@ function timerCalc() { let timerfn = exitApp; let timerdly = 10000; let id = state.id; - if (id != -1) { - if (state.hotp.hotp != "") { - if (tokens[id].period > 0) { - // timed HOTP - if (state.hotp.next < Date.now()) { - if (state.cnt > 0) { - --state.cnt; - state.hotp = hotp(tokens[id]); - } else { - state.hotp.hotp = ""; - } - timerdly = 1; - timerfn = updateCurrentToken; - } else { - timerdly = 1000; - timerfn = updateProgressBar; - } - } else { - // counter HOTP + if (id != -1 && state.hotp.hotp != "") { + if (tokens[id].period > 0) { + // timed HOTP + if (state.hotp.next < Date.now()) { if (state.cnt > 0) { --state.cnt; - timerdly = 30000; + state.hotp = hotp(tokens[id]); } else { state.hotp.hotp = ""; - timerdly = 1; } + timerdly = 1; timerfn = updateCurrentToken; + } else { + timerdly = 1000; + timerfn = updateProgressBar; } + } else { + // counter HOTP + if (state.cnt > 0) { + --state.cnt; + timerdly = 30000; + } else { + state.hotp.hotp = ""; + timerdly = 1; + } + timerfn = updateCurrentToken; } } if (state.drawtimer) { @@ -183,29 +181,27 @@ function updateProgressBar() { function drawProgressBar() { let id = state.id; - if (id != -1) { - if (tokens[id].period > 0) { - let rem = Math.floor((state.hotp.next - Date.now()) / 1000); - if (rem >= 0) { - let y1 = tokenY(id); - let y2 = y1 + TOKEN_HEIGHT - 1; - if (y2 >= AR.y && y1 <= AR.y2) { - // token visible - if ((y2 - 3) <= AR.y2) - { - // progress bar visible - y2 = Math.min(y2, AR.y2); - rem = Math.min(rem, tokens[id].period); - let xr = Math.floor(AR.w * rem / tokens[id].period) + AR.x; - g.setColor(g.theme.fgH) - .setBgColor(g.theme.bgH) - .fillRect(AR.x, y2 - 3, xr, y2) - .clearRect(xr + 1, y2 - 3, AR.x2, y2); - } - } else { - // token not visible - state.id = -1; + if (id != -1 && tokens[id].period > 0) { + let rem = Math.floor((state.hotp.next - Date.now()) / 1000); + if (rem >= 0) { + let y1 = tokenY(id); + let y2 = y1 + TOKEN_HEIGHT - 1; + if (y2 >= AR.y && y1 <= AR.y2) { + // token visible + if ((y2 - 3) <= AR.y2) + { + // progress bar visible + y2 = Math.min(y2, AR.y2); + rem = Math.min(rem, tokens[id].period); + let xr = Math.floor(AR.w * rem / tokens[id].period) + AR.x; + g.setColor(g.theme.fgH) + .setBgColor(g.theme.bgH) + .fillRect(AR.x, y2 - 3, xr, y2) + .clearRect(xr + 1, y2 - 3, AR.x2, y2); } + } else { + // token not visible + state.id = -1; } } } @@ -265,10 +261,10 @@ function drawToken(id) { drawProgressBar(); } } - g.setClipRect(0, 0, g.getWidth(), g.getHeight()); + g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1); } -function startupDraw() { +function drawAll() { if (tokens.length > 0) { let id = 0; let y = tokenY(id); @@ -391,8 +387,13 @@ function bangle1Btn(e) { id = E.clip(id, 0, tokens.length - 1); var fakee = {b:1,x:0,y:0,dx:0}; fakee.dy = state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, tokens.length * TOKEN_HEIGHT - AR.h); - onDrag(fakee); - changeId(id); + //onDrag(fakee); + //changeId(id); + // onDrag() (specifically g.scroll()) doesn't appear to work with the Bangle1 + state.id = id; + state.hotp.hotp = CALCULATING; + state.listy -= fakee.dy; + drawAll(); } else { timerCalc(); } @@ -415,5 +416,5 @@ if (typeof BTN2 == 'number') { Bangle.loadWidgets(); const AR = Bangle.appRect; g.clear(); // Clear the screen once, at startup -startupDraw(); +drawAll(); Bangle.drawWidgets(); From 33cb21482c21223df3e071a0f9756516ed5f52dd Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 21 Mar 2022 21:38:29 +0100 Subject: [PATCH 026/253] Create readme.md --- apps/glbasic/readme.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/glbasic/readme.md diff --git a/apps/glbasic/readme.md b/apps/glbasic/readme.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/apps/glbasic/readme.md @@ -0,0 +1 @@ + From 7ddcfd7565f9920e5f3fed1b5b37a97c74ec5253 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 21 Mar 2022 21:39:02 +0100 Subject: [PATCH 027/253] Add files via upload --- apps/glbasic/GLBasic-Watchface-Bangle.JS2.js | 114 +++++++++++++++++++ apps/glbasic/glbasic.icon.js | 1 + apps/glbasic/glbasic_screenshot.png | Bin 0 -> 1809 bytes apps/glbasic/icon48.png | Bin 0 -> 1365 bytes apps/glbasic/metadata.json | 18 +++ 5 files changed, 133 insertions(+) create mode 100644 apps/glbasic/GLBasic-Watchface-Bangle.JS2.js create mode 100644 apps/glbasic/glbasic.icon.js create mode 100644 apps/glbasic/glbasic_screenshot.png create mode 100644 apps/glbasic/icon48.png create mode 100644 apps/glbasic/metadata.json diff --git a/apps/glbasic/GLBasic-Watchface-Bangle.JS2.js b/apps/glbasic/GLBasic-Watchface-Bangle.JS2.js new file mode 100644 index 000000000..d51d02a10 --- /dev/null +++ b/apps/glbasic/GLBasic-Watchface-Bangle.JS2.js @@ -0,0 +1,114 @@ + +Graphics.prototype.setFontLECO1976Regular42 = function(scale) { + // Actual height 42 (41 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60+(scale<<8)+(1<<16)); +}; + +Graphics.prototype.setFontLECO1976Regular22 = function(scale) { + // Actual height 22 (21 - 0) +g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22+(scale<<8)+(1<<16)); +}; + + +require("Font7x11Numeric7Seg").add(Graphics); + + +var temperature = 13; + +//the following 2 sections are used from waveclk to schedule minutely updates +// timeout used to update every minute +var drawTimeout; + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function drawBackground() { + g.setBgColor(0,0,0); + g.setColor(1,1,1); + g.clear(); +} + +function digit(num){ + return String.fromCharCode(num + 48); +} +function timeString(h, m){ + return digit(h/10) + digit(h%10) + ":" + digit(m/10) + digit(m%10); +} +function dayString(w){ + return digit(w/10) + digit(w%10); +} + +function getSteps() { + if (WIDGETS.wpedom !== undefined) { + return WIDGETS.wpedom.getSteps(); + } + return '????'; +} + + + +function draw(){ + drawBackground(); + var date = new Date(); + var h = date.getHours(), m = date.getMinutes(); + var d = date.getDate(), w = date.getDay(); + + g.setBgColor(0,0,0); + g.setColor(1,1,1); + + + // g.setFont('Vector', 30); + // g.setFont("7x11Numeric7Seg", 5); + g.setFontLECO1976Regular42(); + g.setFontAlign(0, -1); + g.drawString(timeString(h, m), g.getWidth()/2,28); + g.drawString(dayString(w), g.getWidth()*3/4,88); + g.setColor(0,1,0); + g.fillRect(0,76,g.getWidth(), 80); + g.reset(); + + // Steps + g.setFontLECO1976Regular22(); + g.setFontAlign(-1, -1); + g.drawString(getSteps(), 8, 88); + + // g.drawString(temperature, 4, 108); + + + // widget redraw + Bangle.drawWidgets(); + queueDraw(); +} + + +//////////////////////////////////////////////////// +// Bangle.setBarometerPower(true); + +Bangle.loadWidgets(); +draw(); + + +// Bangle.on('pressure', function(e){ +// temperature = e.temperature; +// draw(); +// }); + +//the following section is also from waveclk +Bangle.on('lcdPower',on=>{ + if (on) { + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); + +Bangle.setUI("clock"); + +Bangle.drawWidgets(); \ No newline at end of file diff --git a/apps/glbasic/glbasic.icon.js b/apps/glbasic/glbasic.icon.js new file mode 100644 index 000000000..0c3280635 --- /dev/null +++ b/apps/glbasic/glbasic.icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4UA///ssp4XthFCBwUBqoABqAaGBZcFBZdX1W1qgLHrwLKqv/6oLJAAILHioLJn5qBAAYLEBQoLeHQQABv4LjGAgLYq2qAAOlBbBHFBdPAKcQLdWcb7jAAoLcn4LKgEVHQVUBQsAgoLLq//6oLIr2q2oXJBZQvCqALGgILTA=")) diff --git a/apps/glbasic/glbasic_screenshot.png b/apps/glbasic/glbasic_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e6e5ff9f714ffdca28588be6cd6e87376f12cce9 GIT binary patch literal 1809 zcmds&`!|$%9LLAggNM+JX z$6zpuF8dt4(J1(~AQ^OTZl4Z9gVafHhCQa~8F3zikr{At+VSS^u+ zRTmX$Jc_o-yeFk<_Nw`DMvt@M?ehb7Cx2@1JF5vrx{7#68Iw1*M~-Zy73qP2+ew;l zaB8w`+UZCjpD%_AHU;ACM2&rnc`y}NYFYQT9am4mtAqK{|=d zdE>aKc^355KK4vD(Wr7(`!sFm28G(ZSCE+R#Sc65;nuQu~eBq3fCkLf?ePWX)BAi zDeJdeb1O<~)jC%#R}G^VwCCb2JQc98C;hX66rOnqjc_o#Va2a`G zQ^EP(&l`?j6T4Z@{=Q*ej%XV*h;go^ZYhUmr}s5{YRP^1s+U!clq0LPScpZlP_Bg+ zy31&ir^ZBd!;6QOT4L+H2Y+9guqxL7sL-Gi-Q%~wR9(Ag z)I9k0W&rql*@Fm3wh;lUAO$+rxiHR^T*abqIR(Kd4%`)NI>zw4f1yjiX1e6dj;9g3 zm~19{om3VdLNP)sJP?D}*GH^t;SN@v`%#~c-&TfpsJ+q++qw8V`)nwOs~E;@z7Ilnfo;wMrh@ea@80m@ zw73u#xRIcnfjEKKH7&7086_Q2=f!s9VSvM6ZBu!r8k2MF@WrmUyswJY_kszl@l`2a_EBJBI=vO*#@=m z(viI-w*ovd@Th6%BeE2z^zhnnB5I#XOMMwRG6#FCb@Vd0;R6$>O0s%;Rf*YH<)hQ3tr=g|jfS_!I z6a%i(b~f9yw^#y6 z8aa@`^{q-CZ0bE!>^5U3Qd-QQ`{!pM-B*MQyQRQXTjHE1iDGuuO%FAWA78v%#4f{uHkR48&=R(DU|9i5r$V1{zloT?{-g0#DbauG%AMI0d$oe9w!tOwqX z{WR}PH#$vXPF{^1S#Zqp5gUMP;%SaAKve=pTo1abh|)*|RhL0bRKakN^Mx literal 0 HcmV?d00001 diff --git a/apps/glbasic/icon48.png b/apps/glbasic/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..368e08750d5ede99497d54b310fe9b91e03d9c10 GIT binary patch literal 1365 zcmV-b1*-aqP)Px)4@pEpRA@upn$J%oWf;f5@65Ech+x zv{2{Lr1SoGKJW9q@AEwGGXxf&j*gBFO6h${sg)5nRaJf3O2^bb#OfezZEaUYQ5<26 zhgpeNqlqU<|a5!MM+tXy)-`__( z9#8#$LlA_fU@-V^J`k4nfTAcL1GvSlA&<$o1wnW%7!2OaV+?Bo$g<3Zznss+0AlfY z{JrJnjL8}`p4TwIc*HA2YF(Z&`TV|N3A zz$du?84BR>cxDJ8uUk3qa}k8M36YTEp zVrM5|vZwa&)vv9sO$dJk(C_#AZ`$UZ?XIgKO%tB)k~ zeOsM?$OPbWxe^*+jQ#2LdS5(s4KNT?RZs-3hq1m%@Nml*fG*HbV6|8N+4QG#d;Sbsoppz&lSeLBj3C!9cC9YdJ} zgjOVc_*FUp_XC8G&!(rRuMH0mI|MRySs0P!{IVQ$id*?;AX)$vDvuA$b@u1 zkaUa|#*v-02h4zE(?HQ2+5ZCIsS1i;M#9*O7@ow(6eEcYp%ok6|03NF6iov>l&Ekr zd~>M?YqU0q$(nx@?Wa7n*j z*EFq$Qd)@X_31z$&}T~Wqeg}RnFecZZM`K3LTMB@G65)x@)3aBW^T8$tmZbQ^wp)M zrTe+8cxqcq8c-DFO#r+!bgan7E0wm?91_5}EAq9pv^*zC(r>9{)}f&xw70jXm02ey zCNMfWn!0$4s;a({&*~>qSE~akin0peS-pR@Lign4Bp$&|E$>&@`<(6bhZ)rv|btUl9c1rWOBiEEs&!V)H@V+` XI5?_a++oDw00000NkvXXu0mjfkw}hY literal 0 HcmV?d00001 diff --git a/apps/glbasic/metadata.json b/apps/glbasic/metadata.json new file mode 100644 index 000000000..03559823a --- /dev/null +++ b/apps/glbasic/metadata.json @@ -0,0 +1,18 @@ +{ + "id": "glbasic", + "name": "GLBasic Clock", + "shortName": "GLBasic", + "version": "0.01", + "description": "A clock with large numbers", + "dependencies": {"widpedom":"app"}, + "readme": "README.md", + "icon": "icon48.png", + "screenshots": [{"url":glbasic_screenshot.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS", "BANGLEJS2"], + "storage": [ + {"name":"glbasic.app.js","url":"glbasic.app.js"}, + {"name":"glbasic.img","url":"glbasic.icon.js","evaluate":true} + ] +} \ No newline at end of file From a699247ad1ca640bff3a2845baaef6363f3204a2 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 21 Mar 2022 22:02:55 +0100 Subject: [PATCH 028/253] Typos Typos --- apps/glbasic/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/glbasic/metadata.json b/apps/glbasic/metadata.json index 03559823a..f4fe042db 100644 --- a/apps/glbasic/metadata.json +++ b/apps/glbasic/metadata.json @@ -7,7 +7,7 @@ "dependencies": {"widpedom":"app"}, "readme": "README.md", "icon": "icon48.png", - "screenshots": [{"url":glbasic_screenshot.png"}], + "screenshots": [{"url":"glbasic_screenshot.png"}], "type": "clock", "tags": "clock", "supports": ["BANGLEJS", "BANGLEJS2"], @@ -15,4 +15,4 @@ {"name":"glbasic.app.js","url":"glbasic.app.js"}, {"name":"glbasic.img","url":"glbasic.icon.js","evaluate":true} ] -} \ No newline at end of file +} From 5beec202f964c2eb54ee60c3d08b6b31f13a0c5b Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 21 Mar 2022 22:04:25 +0100 Subject: [PATCH 029/253] Add files via upload --- apps/glbasic/glbasic.app.js | 114 ++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 apps/glbasic/glbasic.app.js diff --git a/apps/glbasic/glbasic.app.js b/apps/glbasic/glbasic.app.js new file mode 100644 index 000000000..d51d02a10 --- /dev/null +++ b/apps/glbasic/glbasic.app.js @@ -0,0 +1,114 @@ + +Graphics.prototype.setFontLECO1976Regular42 = function(scale) { + // Actual height 42 (41 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60+(scale<<8)+(1<<16)); +}; + +Graphics.prototype.setFontLECO1976Regular22 = function(scale) { + // Actual height 22 (21 - 0) +g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22+(scale<<8)+(1<<16)); +}; + + +require("Font7x11Numeric7Seg").add(Graphics); + + +var temperature = 13; + +//the following 2 sections are used from waveclk to schedule minutely updates +// timeout used to update every minute +var drawTimeout; + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function drawBackground() { + g.setBgColor(0,0,0); + g.setColor(1,1,1); + g.clear(); +} + +function digit(num){ + return String.fromCharCode(num + 48); +} +function timeString(h, m){ + return digit(h/10) + digit(h%10) + ":" + digit(m/10) + digit(m%10); +} +function dayString(w){ + return digit(w/10) + digit(w%10); +} + +function getSteps() { + if (WIDGETS.wpedom !== undefined) { + return WIDGETS.wpedom.getSteps(); + } + return '????'; +} + + + +function draw(){ + drawBackground(); + var date = new Date(); + var h = date.getHours(), m = date.getMinutes(); + var d = date.getDate(), w = date.getDay(); + + g.setBgColor(0,0,0); + g.setColor(1,1,1); + + + // g.setFont('Vector', 30); + // g.setFont("7x11Numeric7Seg", 5); + g.setFontLECO1976Regular42(); + g.setFontAlign(0, -1); + g.drawString(timeString(h, m), g.getWidth()/2,28); + g.drawString(dayString(w), g.getWidth()*3/4,88); + g.setColor(0,1,0); + g.fillRect(0,76,g.getWidth(), 80); + g.reset(); + + // Steps + g.setFontLECO1976Regular22(); + g.setFontAlign(-1, -1); + g.drawString(getSteps(), 8, 88); + + // g.drawString(temperature, 4, 108); + + + // widget redraw + Bangle.drawWidgets(); + queueDraw(); +} + + +//////////////////////////////////////////////////// +// Bangle.setBarometerPower(true); + +Bangle.loadWidgets(); +draw(); + + +// Bangle.on('pressure', function(e){ +// temperature = e.temperature; +// draw(); +// }); + +//the following section is also from waveclk +Bangle.on('lcdPower',on=>{ + if (on) { + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); + +Bangle.setUI("clock"); + +Bangle.drawWidgets(); \ No newline at end of file From a23e4ecd38f135228663f7cbea43bf4904ae82c3 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 21 Mar 2022 22:06:03 +0100 Subject: [PATCH 030/253] Update metadata.json --- apps/glbasic/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/glbasic/metadata.json b/apps/glbasic/metadata.json index f4fe042db..589ea6004 100644 --- a/apps/glbasic/metadata.json +++ b/apps/glbasic/metadata.json @@ -5,7 +5,7 @@ "version": "0.01", "description": "A clock with large numbers", "dependencies": {"widpedom":"app"}, - "readme": "README.md", + "readme": "readme.md", "icon": "icon48.png", "screenshots": [{"url":"glbasic_screenshot.png"}], "type": "clock", From e7f3c0f00e23b8ee9f732bb85ccc5a7cb147d3a7 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 22 Mar 2022 06:41:32 +0100 Subject: [PATCH 031/253] Added Calendar --- apps/glbasic/glbasic.app.js | 145 ++++++++++++++++++++++++++++-------- 1 file changed, 116 insertions(+), 29 deletions(-) diff --git a/apps/glbasic/glbasic.app.js b/apps/glbasic/glbasic.app.js index d51d02a10..b2b6f45ed 100644 --- a/apps/glbasic/glbasic.app.js +++ b/apps/glbasic/glbasic.app.js @@ -1,20 +1,17 @@ - Graphics.prototype.setFontLECO1976Regular42 = function(scale) { // Actual height 42 (41 - 0) - g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60+(scale<<8)+(1<<16)); + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60 + (scale << 8) + (1 << 16)); }; Graphics.prototype.setFontLECO1976Regular22 = function(scale) { // Actual height 22 (21 - 0) -g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22+(scale<<8)+(1<<16)); + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22 + (scale << 8) + (1 << 16)); }; require("Font7x11Numeric7Seg").add(Graphics); -var temperature = 13; - //the following 2 sections are used from waveclk to schedule minutely updates // timeout used to update every minute var drawTimeout; @@ -29,19 +26,21 @@ function queueDraw() { } function drawBackground() { - g.setBgColor(0,0,0); - g.setColor(1,1,1); + g.setBgColor(0, 0, 0); + g.setColor(1, 1, 1); g.clear(); } -function digit(num){ +function digit(num) { return String.fromCharCode(num + 48); } -function timeString(h, m){ - return digit(h/10) + digit(h%10) + ":" + digit(m/10) + digit(m%10); + +function timeString(h, m) { + return digit(h / 10) + digit(h % 10) + ":" + digit(m / 10) + digit(m % 10); } -function dayString(w){ - return digit(w/10) + digit(w%10); + +function dayString(w) { + return digit(w / 10) + digit(w % 10); } function getSteps() { @@ -51,36 +50,124 @@ function getSteps() { return '????'; } +/** + * draws calender week view (-1,0,1) for given date + */ +function drawCal() { + d = /*this.date ? this.date : */ new Date(); + + const DAY_NAME_FONT_SIZE = 10; + const CAL_Y = g.getHeight() - 44; // Bangle.appRect.y+this.DATE_FONT_SIZE()+10+this.TIME_FONT_SIZE()+3; + const CAL_AREA_H = 44; // g.getHeight()-CAL_Y+24; //+24: top widgtes only + const CELL_W = g.getWidth() / 7; //cell width + const CELL_H = (CAL_AREA_H - DAY_NAME_FONT_SIZE) / 3; //cell heigth + const DAY_NUM_FONT_SIZE = Math.min(CELL_H + 3, 15); //size down, max 15 + + const wdStrt = 1; + + const ABR_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + const IS_SUNDAY = [1, 0, 0, 0, 0, 1, 1]; // what days are sunday? + const nrgb = ["#000", "#FFF", "#F00", "#0F0", "#00F", "#FF0"]; //fg, r ,g , b + const suClr = 5; // sunday color fg + const tdyMrkClr = 3; // today bk + const tdyNumClr = 0; // today fg + + g.setFont("Vector", DAY_NAME_FONT_SIZE+3); + g.setColor(nrgb[1]); + g.setFontAlign(-1, -1); + // g.clearRect(Bangle.appRect.x, CAL_Y, Bangle.appRect.x2, CAL_Y+CAL_AREA_H); + + //draw grid & Headline + const dNames = ABR_DAY.map((a) => a.length <= 2 ? a : a.substr(0, 2)); //force shrt 2 + for (var dNo = 0; dNo < dNames.length; dNo++) { + const dIdx = wdStrt >= 0 ? ((wdStrt + dNo) % 7) : ((dNo + d.getDay() + 4) % 7); + const dName = dNames[dIdx]; + // if(dNo>0) { g.drawLine(dNo*CELL_W, CAL_Y, dNo*CELL_W, CAL_Y+CAL_AREA_H-1);} -function draw(){ + var colTx = 0; + var colBk = 1; + if (IS_SUNDAY[dIdx]) { + colBk = suClr; + } + + g.setColor(nrgb[colBk]); + g.fillRect(dNo * CELL_W, CAL_Y, dNo * CELL_W + CELL_W, CAL_Y + DAY_NAME_FONT_SIZE-1); + g.setColor(nrgb[colTx]); + g.drawString(dName, dNo * CELL_W + (CELL_W - g.stringWidth(dName)) / 2 + 2, CAL_Y-1); + // g.setColor(nrgb[clTxt]); + } + g.setColor(nrgb[1]); + var nextY = CAL_Y + DAY_NAME_FONT_SIZE; + + // horizontal lines + // for(i=0; i<3; i++){ const y=nextY+i*CELL_H; g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); } + + g.setFont("Vector", DAY_NUM_FONT_SIZE); + + g.setFont("7x11Numeric7Seg", 1); + + //write days + const tdyDate = d.getDate(); + const days = wdStrt >= 0 ? 7 + ((7 + d.getDay() - wdStrt) % 7) : 10; //start day (week before=7 days + days in this week realtive to week start) or fixed 7+3 days + var rD = new Date(d.getTime()); + rD.setDate(rD.getDate() - days); + var rDate = rD.getDate(); + for (var y = 0; y < 3; y++) { + for (var x = 0; x < dNames.length; x++) { + if (rDate === tdyDate) { //today + g.setColor(nrgb[tdyMrkClr]); //today marker color or fg color + + // rectangle + g.fillRect(x * CELL_W, nextY + CELL_H-1, x * CELL_W + CELL_W, nextY + CELL_H + CELL_H - 1); + g.setColor(nrgb[tdyNumClr]); //today color or fg color + + // simulate "bold" + g.drawString(rDate, 1+ x * CELL_W + ((CELL_W - g.stringWidth(rDate)) / 2) + 2, nextY + ((CELL_H - DAY_NUM_FONT_SIZE + 2) / 2) + (CELL_H * y)); + + } else if (IS_SUNDAY[rD.getDay()]) { //sundays + g.setColor(nrgb[suClr]); + } else { //default + g.setColor(nrgb[1]); + } + g.drawString(rDate, x * CELL_W + ((CELL_W - g.stringWidth(rDate)) / 2) + 2, nextY + ((CELL_H - DAY_NUM_FONT_SIZE + 2) / 2) + (CELL_H * y)); + rD.setDate(rDate + 1); + rDate = rD.getDate(); + } + } +} + + +function draw() { drawBackground(); var date = new Date(); - var h = date.getHours(), m = date.getMinutes(); - var d = date.getDate(), w = date.getDay(); + var h = date.getHours(), + m = date.getMinutes(); + var d = date.getDate(), + w = date.getDay(); // d=1..31; w=0..6 + + g.setBgColor(0, 0, 0); + g.setColor(1, 1, 1); + - g.setBgColor(0,0,0); - g.setColor(1,1,1); - - // g.setFont('Vector', 30); // g.setFont("7x11Numeric7Seg", 5); g.setFontLECO1976Regular42(); g.setFontAlign(0, -1); - g.drawString(timeString(h, m), g.getWidth()/2,28); - g.drawString(dayString(w), g.getWidth()*3/4,88); - g.setColor(0,1,0); - g.fillRect(0,76,g.getWidth(), 80); + g.drawString(timeString(h, m), g.getWidth() / 2, 28); + g.drawString(dayString(d), g.getWidth() * 3 / 4, 88); + g.setColor(0, 1, 0); + g.fillRect(0, 76, g.getWidth(), 80); g.reset(); - + // Steps g.setFontLECO1976Regular22(); g.setFontAlign(-1, -1); g.drawString(getSteps(), 8, 88); - // g.drawString(temperature, 4, 108); - - + drawCal(); + + // widget redraw Bangle.drawWidgets(); queueDraw(); @@ -100,7 +187,7 @@ draw(); // }); //the following section is also from waveclk -Bangle.on('lcdPower',on=>{ +Bangle.on('lcdPower', on => { if (on) { draw(); // draw immediately, queue redraw } else { // stop draw timer @@ -111,4 +198,4 @@ Bangle.on('lcdPower',on=>{ Bangle.setUI("clock"); -Bangle.drawWidgets(); \ No newline at end of file +Bangle.drawWidgets(); From 9df926f062d49c6087bc462061e2ca7edb4ac33a Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 22 Mar 2022 06:42:31 +0100 Subject: [PATCH 032/253] Version --- apps/glbasic/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/glbasic/metadata.json b/apps/glbasic/metadata.json index 589ea6004..9d8f5ec7b 100644 --- a/apps/glbasic/metadata.json +++ b/apps/glbasic/metadata.json @@ -2,7 +2,7 @@ "id": "glbasic", "name": "GLBasic Clock", "shortName": "GLBasic", - "version": "0.01", + "version": "0.2", "description": "A clock with large numbers", "dependencies": {"widpedom":"app"}, "readme": "readme.md", From 200e6fcc1dab2d087a825e824d0ea4b065c3abe8 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 22 Mar 2022 07:42:40 +0100 Subject: [PATCH 033/253] Update widget.js Buzz on connection loss. --- apps/widbt/widget.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index c7ef8c0ad..a6c15a97f 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -5,8 +5,11 @@ WIDGETS["bluetooth"]={area:"tr",width:15,draw:function() { else g.setColor(g.theme.dark ? "#666" : "#999"); g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="),2+this.x,2+this.y); -},changed:function() { +},connect:function() { + WIDGETS["bluetooth"].draw(); +},dicconnect:function() { + Bangle.buzz(1000,1); // buzz on connection loss WIDGETS["bluetooth"].draw(); }}; -NRF.on('connect',WIDGETS["bluetooth"].changed); -NRF.on('disconnect',WIDGETS["bluetooth"].changed); +NRF.on('connect',WIDGETS["bluetooth"].connect); +NRF.on('disconnect',WIDGETS["bluetooth"].disconnect); From 0743af578641b5886b2fef52bb769d5cef2f83dc Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 22 Mar 2022 07:45:00 +0100 Subject: [PATCH 034/253] Update metadata.json --- apps/widbt/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt/metadata.json b/apps/widbt/metadata.json index e2d5082a5..78a61496c 100644 --- a/apps/widbt/metadata.json +++ b/apps/widbt/metadata.json @@ -1,7 +1,7 @@ { "id": "widbt", "name": "Bluetooth Widget", - "version": "0.08", + "version": "0.09", "description": "Show the current Bluetooth connection status in the top right of the clock", "icon": "widget.png", "type": "widget", From aa118dc3fa40501193874727235f9c86e4c7bedb Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 22 Mar 2022 07:46:04 +0100 Subject: [PATCH 035/253] Update ChangeLog 0.09 --- apps/widbt/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widbt/ChangeLog b/apps/widbt/ChangeLog index 4c2132122..3b9024ee4 100644 --- a/apps/widbt/ChangeLog +++ b/apps/widbt/ChangeLog @@ -5,3 +5,4 @@ 0.06: Tweaking colors for dark/light themes and low bpp screens 0.07: Memory usage improvements 0.08: Disable LCD on, on bluetooth status change +0.09: Vibrate on connection loss From 9886125fbd796feabfea5beef484487c67324e63 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Tue, 22 Mar 2022 23:16:17 +0800 Subject: [PATCH 036/253] Update app.js Refactoring and extra range checks. --- apps/authentiwatch/app.js | 117 ++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 67 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 8e25e5ef2..b2608a5dc 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -2,6 +2,7 @@ const COUNTER_TRIANGLE_SIZE = 10; const TOKEN_EXTRA_HEIGHT = 16; var TOKEN_DIGITS_HEIGHT = 30; var TOKEN_HEIGHT = TOKEN_DIGITS_HEIGHT + TOKEN_EXTRA_HEIGHT; +const SETTINGS = "authentiwatch.json"; // Hash functions const crypto = require("crypto"); const algos = { @@ -15,7 +16,7 @@ const NOT_SUPPORTED = /*LANG*/"Not supported"; // sample settings: // {tokens:[{"algorithm":"SHA1","digits":6,"period":30,"issuer":"","account":"","secret":"Bbb","label":"Aaa"}],misc:{}} -var settings = require("Storage").readJSON("authentiwatch.json", true) || {tokens:[],misc:{}}; +var settings = require("Storage").readJSON(SETTINGS, true) || {tokens:[],misc:{}}; if (settings.data ) tokens = settings.data ; /* v0.02 settings */ if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ @@ -134,14 +135,13 @@ half = n => Math.floor(n / 2); function timerCalc() { let timerfn = exitApp; let timerdly = 10000; - let id = state.id; - if (id != -1 && state.hotp.hotp != "") { - if (tokens[id].period > 0) { + if (state.id != -1 && state.hotp.hotp != "") { + if (tokens[state.id].period > 0) { // timed HOTP if (state.hotp.next < Date.now()) { if (state.cnt > 0) { - --state.cnt; - state.hotp = hotp(tokens[id]); + state.cnt--; + state.hotp = hotp(tokens[state.id]); } else { state.hotp.hotp = ""; } @@ -154,7 +154,7 @@ function timerCalc() { } else { // counter HOTP if (state.cnt > 0) { - --state.cnt; + state.cnt--; timerdly = 30000; } else { state.hotp.hotp = ""; @@ -215,7 +215,7 @@ function drawToken(id) { var y2 = y1 + TOKEN_HEIGHT - 1; var adj, lbl; g.setClipRect(x1, Math.max(y1, AR.y), x2, Math.min(y2, AR.y2)); - lbl = tokens[id].label.substr(0, 10); + lbl = (id >= 0 && id < tokens.length) ? tokens[id].label.substr(0, 10) : ""; if (id === state.id) { g.setColor(g.theme.fgH) .setBgColor(g.theme.bgH); @@ -264,31 +264,24 @@ function drawToken(id) { g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1); } -function drawAll() { - if (tokens.length > 0) { - let id = 0; - let y = tokenY(id); - while (id < tokens.length && y < AR.y2) { - if ((y + TOKEN_HEIGHT) > AR.y) { - drawToken(id); - } - id++; - y += TOKEN_HEIGHT; +function changeId(id) { + if (id != state.id) { + state.hotp.hotp = CALCULATING; + let pid = state.id; + state.id = id; + if (pid != -1) { + drawToken(pid); + } + if (id != -1) { + drawToken( id); } - } else { - let x = AR.x + half(AR.w); - let y = AR.y + half(AR.h); - g.setFont("Vector", TOKEN_DIGITS_HEIGHT) - .setFontAlign(0, 0, 0) - .drawString(NO_TOKENS, x, y, false); } - timerCalc(); } function onDrag(e) { state.cnt = 1; if (e.b != 0 && e.dy != 0) { - var y = E.clip(state.listy - e.dy, 0, tokens.length * TOKEN_HEIGHT - AR.h); + var y = E.clip(state.listy - E.clip(e.dy, -AR.h, AR.h), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h)); if (state.listy != y) { var id, dy = state.listy - y; state.listy = y; @@ -319,21 +312,6 @@ function onDrag(e) { } } -function changeId(id) { - if (id != state.id) { - state.hotp.hotp = CALCULATING; - let pid = state.id; - state.id = id; - if (pid != -1) { - drawToken(pid); - } - if (id != -1) { - drawToken( id); - } - timerCalc(); - } -} - function onTouch(zone, e) { state.cnt = 1; if (e) { @@ -344,36 +322,39 @@ function onTouch(zone, e) { if (state.id != id) { if (id != -1) { // scroll token into view if necessary - var fakee = {b:1,x:0,y:0,dx:0,dy:0}; + var dy = 0; var y = id * TOKEN_HEIGHT - state.listy; if (y < 0) { - fakee.dy -= y; + dy -= y; y = 0; } y += TOKEN_HEIGHT; if (y > AR.h) { - fakee.dy -= (y - AR.h); + dy -= (y - AR.h); } - onDrag(fakee); + onDrag({b:1, dy:dy}); } changeId(id); } } + timerCalc(); } function onSwipe(e) { state.cnt = 1; - let id = state.id; - if (e == 1) { + switch (e) { + case 1: exitApp(); + break; + case -1: + if (state.id != -1 && tokens[state.id].period <= 0) { + tokens[state.id].period--; + require("Storage").writeJSON(SETTINGS, {tokens:tokens, misc:settings.misc}); + state.hotp.hotp = CALCULATING; + drawToken(state.id); + } } - if (e == -1 && id != -1 && tokens[id].period <= 0) { - tokens[id].period--; - let newsettings={tokens:tokens,misc:settings.misc}; - require("Storage").writeJSON("authentiwatch.json", newsettings); - state.hotp.hotp = CALCULATING; - drawToken(id); - } + timerCalc(); } function bangle1Btn(e) { @@ -385,18 +366,11 @@ function bangle1Btn(e) { case 1: id++; break; } id = E.clip(id, 0, tokens.length - 1); - var fakee = {b:1,x:0,y:0,dx:0}; - fakee.dy = state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, tokens.length * TOKEN_HEIGHT - AR.h); - //onDrag(fakee); - //changeId(id); - // onDrag() (specifically g.scroll()) doesn't appear to work with the Bangle1 - state.id = id; - state.hotp.hotp = CALCULATING; - state.listy -= fakee.dy; - drawAll(); - } else { - timerCalc(); + var dy = state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h)); + onDrag({b:1, dy:dy}); + changeId(id); } + timerCalc(); } function exitApp() { @@ -415,6 +389,15 @@ if (typeof BTN2 == 'number') { } Bangle.loadWidgets(); const AR = Bangle.appRect; -g.clear(); // Clear the screen once, at startup -drawAll(); +// draw the initial display +g.clear(); +if (tokens.length > 0) { + state.listy = AR.h; + onDrag({b:1, dy:AR.h}); +} else { + g.setFont("Vector", TOKEN_DIGITS_HEIGHT) + .setFontAlign(0, 0, 0) + .drawString(NO_TOKENS, AR.x + half(AR.w), AR.y + half(AR.h), false); +} +timerCalc(); Bangle.drawWidgets(); From 1d7c090c21a10aad2dbc64ebb9c95de05d432bdb Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Tue, 22 Mar 2022 23:26:50 +0800 Subject: [PATCH 037/253] Update app.js Update progress bar on Bangle1 button presses. Clean up timer before exiting. --- apps/authentiwatch/app.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index b2608a5dc..58d712451 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -369,11 +369,15 @@ function bangle1Btn(e) { var dy = state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h)); onDrag({b:1, dy:dy}); changeId(id); + drawProgressBar(); } timerCalc(); } function exitApp() { + if (state.drawtimer) { + clearTimeout(state.drawtimer); + } Bangle.showLauncher(); } From 94207739c08a368b7f76c38eb9f3879757a77f94 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 23 Mar 2022 14:22:17 +0800 Subject: [PATCH 038/253] Update app.js Refactoring --- apps/authentiwatch/app.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 58d712451..aae570e13 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -16,7 +16,7 @@ const NOT_SUPPORTED = /*LANG*/"Not supported"; // sample settings: // {tokens:[{"algorithm":"SHA1","digits":6,"period":30,"issuer":"","account":"","secret":"Bbb","label":"Aaa"}],misc:{}} -var settings = require("Storage").readJSON(SETTINGS, true) || {tokens:[],misc:{}}; +var settings = require("Storage").readJSON(SETTINGS, true) || {tokens:[], misc:{}}; if (settings.data ) tokens = settings.data ; /* v0.02 settings */ if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ @@ -106,9 +106,9 @@ function hotp(token) { } // Tokens are displayed in three states: -// 1. Unselected (state.id==-1) -// 2. Selected, inactive (no code) (state.id!=-1,state.hotp.hotp=="") -// 3. Selected, active (code showing) (state.id!=-1,state.hotp.hotp!="") +// 1. Unselected (state.id<0) +// 2. Selected, inactive (no code) (state.id>=0,state.hotp.hotp=="") +// 3. Selected, active (code showing) (state.id>=0,state.hotp.hotp!="") var fontszCache = {}; var state = { listy:0, // list scroll position @@ -135,7 +135,7 @@ half = n => Math.floor(n / 2); function timerCalc() { let timerfn = exitApp; let timerdly = 10000; - if (state.id != -1 && state.hotp.hotp != "") { + if (state.id >= 0 && state.hotp.hotp != "") { if (tokens[state.id].period > 0) { // timed HOTP if (state.hotp.next < Date.now()) { @@ -181,7 +181,7 @@ function updateProgressBar() { function drawProgressBar() { let id = state.id; - if (id != -1 && tokens[id].period > 0) { + if (id >= 0 && tokens[id].period > 0) { let rem = Math.floor((state.hotp.next - Date.now()) / 1000); if (rem >= 0) { let y1 = tokenY(id); @@ -269,10 +269,10 @@ function changeId(id) { state.hotp.hotp = CALCULATING; let pid = state.id; state.id = id; - if (pid != -1) { + if (pid >= 0) { drawToken(pid); } - if (id != -1) { + if (id >= 0) { drawToken( id); } } @@ -320,7 +320,7 @@ function onTouch(zone, e) { id = -1; } if (state.id != id) { - if (id != -1) { + if (id >= 0) { // scroll token into view if necessary var dy = 0; var y = id * TOKEN_HEIGHT - state.listy; @@ -347,7 +347,7 @@ function onSwipe(e) { exitApp(); break; case -1: - if (state.id != -1 && tokens[state.id].period <= 0) { + if (state.id >= 0 && tokens[state.id].period <= 0) { tokens[state.id].period--; require("Storage").writeJSON(SETTINGS, {tokens:tokens, misc:settings.misc}); state.hotp.hotp = CALCULATING; From e76535fece1bad8660c986c228f663f1faff0817 Mon Sep 17 00:00:00 2001 From: Brendan Hubble Date: Wed, 23 Mar 2022 18:44:01 +1100 Subject: [PATCH 039/253] touchtimer: ADD 5 second count down buzzer - This is a configurable option (Default is off) for the timer to buzz each second when there are 5 seconds left. --- apps/touchtimer/ChangeLog | 1 + apps/touchtimer/app.js | 8 ++++++++ apps/touchtimer/metadata.json | 2 +- apps/touchtimer/settings.js | 8 ++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/touchtimer/ChangeLog b/apps/touchtimer/ChangeLog index fbabe6cb7..0969a3da4 100644 --- a/apps/touchtimer/ChangeLog +++ b/apps/touchtimer/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial creation of the touch timer app 0.02: Add settings menu 0.03: Add ability to repeat last timer +0.04: Add 5 second count down buzzer diff --git a/apps/touchtimer/app.js b/apps/touchtimer/app.js index 61d3a08fd..c2f2fb5e9 100644 --- a/apps/touchtimer/app.js +++ b/apps/touchtimer/app.js @@ -126,6 +126,14 @@ var main = () => { timerIntervalId = setInterval(() => { timerCountDown.draw(); + // Buzz lightly when there are less then 5 seconds left + if (settings.countDownBuzz) { + var remainingSeconds = timerCountDown.getAdjustedTime().seconds; + if (remainingSeconds <= 5 && remainingSeconds > 0) { + Bangle.buzz(); + } + } + if (timerCountDown.isFinished()) { buttonStartPause.value = "FINISHED!"; buttonStartPause.draw(); diff --git a/apps/touchtimer/metadata.json b/apps/touchtimer/metadata.json index 50c5f03dd..0f2b9f491 100644 --- a/apps/touchtimer/metadata.json +++ b/apps/touchtimer/metadata.json @@ -2,7 +2,7 @@ "id": "touchtimer", "name": "Touch Timer", "shortName": "Touch Timer", - "version": "0.03", + "version": "0.04", "description": "Quickly and easily create a timer with touch-only input. The time can be easily set with a number pad.", "icon": "app.png", "tags": "tools", diff --git a/apps/touchtimer/settings.js b/apps/touchtimer/settings.js index 885670f57..79424f250 100644 --- a/apps/touchtimer/settings.js +++ b/apps/touchtimer/settings.js @@ -31,6 +31,14 @@ writeSettings(settings); }, }, + "CountDown Buzz": { + value: !!settings.countDownBuzz, + format: value => value?"On":"Off", + onchange: (value) => { + settings.countDownBuzz = value; + writeSettings(settings); + }, + }, "Pause Between": { value: settings.pauseBetween, min: 1, From b26d3416092f8ad12fa790b012a3336a93e8a18a Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 23 Mar 2022 16:13:57 +0800 Subject: [PATCH 040/253] Update app.js Refactoring --- apps/authentiwatch/app.js | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index aae570e13..5ea8dd476 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -182,7 +182,7 @@ function updateProgressBar() { function drawProgressBar() { let id = state.id; if (id >= 0 && tokens[id].period > 0) { - let rem = Math.floor((state.hotp.next - Date.now()) / 1000); + let rem = Math.min(tokens[id].period, Math.floor((state.hotp.next - Date.now()) / 1000)); if (rem >= 0) { let y1 = tokenY(id); let y2 = y1 + TOKEN_HEIGHT - 1; @@ -192,7 +192,6 @@ function drawProgressBar() { { // progress bar visible y2 = Math.min(y2, AR.y2); - rem = Math.min(rem, tokens[id].period); let xr = Math.floor(AR.w * rem / tokens[id].period) + AR.x; g.setColor(g.theme.fgH) .setBgColor(g.theme.bgH) @@ -209,13 +208,13 @@ function drawProgressBar() { // id = token ID number (0...) function drawToken(id) { - var x1 = AR.x; - var y1 = tokenY(id); - var x2 = AR.x2; - var y2 = y1 + TOKEN_HEIGHT - 1; - var adj, lbl; + let x1 = AR.x; + let y1 = tokenY(id); + let x2 = AR.x2; + let y2 = y1 + TOKEN_HEIGHT - 1; + let lbl = (id >= 0 && id < tokens.length) ? tokens[id].label.substr(0, 10) : ""; + let adj; g.setClipRect(x1, Math.max(y1, AR.y), x2, Math.min(y2, AR.y2)); - lbl = (id >= 0 && id < tokens.length) ? tokens[id].label.substr(0, 10) : ""; if (id === state.id) { g.setColor(g.theme.fgH) .setBgColor(g.theme.bgH); @@ -281,9 +280,9 @@ function changeId(id) { function onDrag(e) { state.cnt = 1; if (e.b != 0 && e.dy != 0) { - var y = E.clip(state.listy - E.clip(e.dy, -AR.h, AR.h), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h)); + let y = E.clip(state.listy - E.clip(e.dy, -AR.h, AR.h), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h)); if (state.listy != y) { - var id, dy = state.listy - y; + let id, dy = state.listy - y; state.listy = y; g.setClipRect(AR.x, AR.y, AR.x2, AR.y2) .scroll(0, dy); @@ -315,15 +314,15 @@ function onDrag(e) { function onTouch(zone, e) { state.cnt = 1; if (e) { - var id = Math.floor((state.listy + e.y - AR.y) / TOKEN_HEIGHT); + let id = Math.floor((state.listy + e.y - AR.y) / TOKEN_HEIGHT); if (id == state.id || tokens.length == 0 || id >= tokens.length) { id = -1; } if (state.id != id) { if (id >= 0) { // scroll token into view if necessary - var dy = 0; - var y = id * TOKEN_HEIGHT - state.listy; + let dy = 0; + let y = id * TOKEN_HEIGHT - state.listy; if (y < 0) { dy -= y; y = 0; @@ -357,17 +356,16 @@ function onSwipe(e) { timerCalc(); } -function bangle1Btn(e) { +function bangleBtn(e) { state.cnt = 1; if (tokens.length > 0) { - var id = state.id; + let id = state.id; switch (e) { case -1: id--; break; case 1: id++; break; } id = E.clip(id, 0, tokens.length - 1); - var dy = state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h)); - onDrag({b:1, dy:dy}); + onDrag({b:1, dy:state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h))}); changeId(id); drawProgressBar(); } @@ -384,12 +382,14 @@ function exitApp() { Bangle.on('touch', onTouch); Bangle.on('drag' , onDrag ); Bangle.on('swipe', onSwipe); -if (typeof BTN2 == 'number') { - setWatch(function(){bangle1Btn(-1);}, BTN1, {edge:"rising" , debounce:50, repeat:true}); - setWatch(function(){exitApp(); }, BTN2, {edge:"falling", debounce:50}); - setWatch(function(){bangle1Btn( 1);}, BTN3, {edge:"rising" , debounce:50, repeat:true}); -} else { - setWatch(function(){exitApp(); }, BTN1, {edge:"falling", debounce:50}); +if (typeof BTN1 == 'number') { + if (typeof BTN2 == 'number' && typeof BTN3 == 'number') { + setWatch(()=>bangleBtn(-1), BTN1, {edge:"rising" , debounce:50, repeat:true}); + setWatch(()=>exitApp() , BTN2, {edge:"falling", debounce:50}); + setWatch(()=>bangleBtn( 1), BTN3, {edge:"rising" , debounce:50, repeat:true}); + } else { + setWatch(()=>exitApp() , BTN1, {edge:"falling", debounce:50}); + } } Bangle.loadWidgets(); const AR = Bangle.appRect; From bf30b35ac07fc3bde3299e0dd5dc6dc2886c9d82 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 23 Mar 2022 16:18:21 +0800 Subject: [PATCH 041/253] Update app.js Fix progress bar drawing. --- apps/authentiwatch/app.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 5ea8dd476..69e4a1ae1 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -188,15 +188,16 @@ function drawProgressBar() { let y2 = y1 + TOKEN_HEIGHT - 1; if (y2 >= AR.y && y1 <= AR.y2) { // token visible - if ((y2 - 3) <= AR.y2) + y1 = y2 - 3; + if (y1 <= AR.y2) { // progress bar visible y2 = Math.min(y2, AR.y2); let xr = Math.floor(AR.w * rem / tokens[id].period) + AR.x; g.setColor(g.theme.fgH) .setBgColor(g.theme.bgH) - .fillRect(AR.x, y2 - 3, xr, y2) - .clearRect(xr + 1, y2 - 3, AR.x2, y2); + .fillRect(AR.x, y1, xr, y2) + .clearRect(xr + 1, y1, AR.x2, y2); } } else { // token not visible From c7242674f27f4be0d0ab2576a855169a2d6ba6fe Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 23 Mar 2022 09:20:59 +0100 Subject: [PATCH 042/253] Update widget.js Typos --- apps/widbt/widget.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index a6c15a97f..246b8d65b 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -1,15 +1,23 @@ -WIDGETS["bluetooth"]={area:"tr",width:15,draw:function() { - g.reset(); - if (NRF.getSecurityStatus().connected) - g.setColor((g.getBPP()>8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); - else - g.setColor(g.theme.dark ? "#666" : "#999"); - g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="),2+this.x,2+this.y); -},connect:function() { - WIDGETS["bluetooth"].draw(); -},dicconnect:function() { - Bangle.buzz(1000,1); // buzz on connection loss - WIDGETS["bluetooth"].draw(); -}}; -NRF.on('connect',WIDGETS["bluetooth"].connect); -NRF.on('disconnect',WIDGETS["bluetooth"].disconnect); +WIDGETS.bluetooth = { + area: "tr", + width: 15, + draw: function() { + g.reset(); + if (NRF.getSecurityStatus().connected) { + g.setColor((g.getBPP() > 8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); + } else { + g.setColor(g.theme.dark ? "#666" : "#999"); + } + g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y); + }, + connect: function() { + WIDGETS.bluetooth.draw(); + }, + diconnect: function() { + Bangle.buzz(1000, 1); // buzz on connection loss + WIDGETS.bluetooth.draw(); + } +}; + +NRF.on('connect', WIDGETS.bluetooth.connect); +NRF.on('disconnect', WIDGETS.bluetooth.diconnect); From 8d7cf2dde6f2e40801abcda5d8dcd9df5cf9ad97 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 23 Mar 2022 09:21:48 +0100 Subject: [PATCH 043/253] Update ChangeLog bug fix --- apps/widbt/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widbt/ChangeLog b/apps/widbt/ChangeLog index 3b9024ee4..04bff2b1a 100644 --- a/apps/widbt/ChangeLog +++ b/apps/widbt/ChangeLog @@ -6,3 +6,4 @@ 0.07: Memory usage improvements 0.08: Disable LCD on, on bluetooth status change 0.09: Vibrate on connection loss +0.10: Bug fix From ef6fcc92f0423954d444b9d26948b9b142474f92 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 23 Mar 2022 09:22:10 +0100 Subject: [PATCH 044/253] Update metadata.json version update --- apps/widbt/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt/metadata.json b/apps/widbt/metadata.json index 78a61496c..29d960f33 100644 --- a/apps/widbt/metadata.json +++ b/apps/widbt/metadata.json @@ -1,7 +1,7 @@ { "id": "widbt", "name": "Bluetooth Widget", - "version": "0.09", + "version": "0.10", "description": "Show the current Bluetooth connection status in the top right of the clock", "icon": "widget.png", "type": "widget", From 47332eba50f743ccfb7e85439cc41f5321bf910f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 23 Mar 2022 16:26:48 +0800 Subject: [PATCH 045/253] Update app.js Simplify. --- apps/authentiwatch/app.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 69e4a1ae1..3920ebddd 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -360,12 +360,7 @@ function onSwipe(e) { function bangleBtn(e) { state.cnt = 1; if (tokens.length > 0) { - let id = state.id; - switch (e) { - case -1: id--; break; - case 1: id++; break; - } - id = E.clip(id, 0, tokens.length - 1); + let id = E.clip(state.id + e, 0, tokens.length - 1); onDrag({b:1, dy:state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h))}); changeId(id); drawProgressBar(); From 05b75d2241844d4858992b46335f1d141b680f1a Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 23 Mar 2022 16:30:24 +0800 Subject: [PATCH 046/253] Update app.js Fix missing break. --- apps/authentiwatch/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 3920ebddd..3a452b6e9 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -353,6 +353,7 @@ function onSwipe(e) { state.hotp.hotp = CALCULATING; drawToken(state.id); } + break; } timerCalc(); } From b3cc125a3f733b8f8a9cd591d537f947ca2488b1 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 23 Mar 2022 16:36:42 +0800 Subject: [PATCH 047/253] Update app.js Use let instead of var. --- apps/authentiwatch/app.js | 41 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 3a452b6e9..5198254af 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -22,8 +22,8 @@ if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ function b32decode(seedstr) { // RFC4648 - var buf = 0, bitcount = 0, retstr = ""; - for (var c of seedstr.toUpperCase()) { + let buf = 0, bitcount = 0, retstr = ""; + for (let c of seedstr.toUpperCase()) { if (c == '0') c = 'O'; if (c == '1') c = 'I'; if (c == '8') c = 'B'; @@ -39,63 +39,62 @@ function b32decode(seedstr) { } } } - var retbuf = new Uint8Array(retstr.length); - for (var i in retstr) { + let retbuf = new Uint8Array(retstr.length); + for (let i in retstr) { retbuf[i] = retstr.charCodeAt(i); } return retbuf; } function hmac(key, message, algo) { - var a = algos[algo.toUpperCase()]; + let a = algos[algo.toUpperCase()]; // RFC2104 if (key.length > a.blksz) { key = a.sha(key); } - var istr = new Uint8Array(a.blksz + message.length); - var ostr = new Uint8Array(a.blksz + a.retsz); - for (var i = 0; i < a.blksz; ++i) { - var c = (i < key.length) ? key[i] : 0; + let istr = new Uint8Array(a.blksz + message.length); + let ostr = new Uint8Array(a.blksz + a.retsz); + for (let i = 0; i < a.blksz; ++i) { + let c = (i < key.length) ? key[i] : 0; istr[i] = c ^ 0x36; ostr[i] = c ^ 0x5C; } istr.set(message, a.blksz); ostr.set(a.sha(istr), a.blksz); - var ret = a.sha(ostr); + let ret = a.sha(ostr); // RFC4226 dynamic truncation - var v = new DataView(ret, ret[ret.length - 1] & 0x0F, 4); + let v = new DataView(ret, ret[ret.length - 1] & 0x0F, 4); return v.getUint32(0) & 0x7FFFFFFF; } function formatOtp(otp, digits) { // add 0 padding - var ret = "" + otp % Math.pow(10, digits); + let ret = "" + otp % Math.pow(10, digits); while (ret.length < digits) { ret = "0" + ret; } // add a space after every 3rd or 4th digit - var re = (digits % 3 == 0 || (digits % 3 >= digits % 4 && digits % 4 != 0)) ? "" : "."; + let re = (digits % 3 == 0 || (digits % 3 >= digits % 4 && digits % 4 != 0)) ? "" : "."; return ret.replace(new RegExp("(..." + re + ")", "g"), "$1 ").trim(); } function hotp(token) { - var d = Date.now(); - var tick, next; + let d = Date.now(); + let tick, next; if (token.period > 0) { // RFC6238 - timed - var seconds = Math.floor(d / 1000); - tick = Math.floor(seconds / token.period); + tick = Math.floor(Math.floor(d / 1000) / token.period); next = (tick + 1) * token.period * 1000; } else { // RFC4226 - counter tick = -token.period; next = d + 30000; } - var msg = new Uint8Array(8); - var v = new DataView(msg.buffer); + let msg = new Uint8Array(8); + let v = new DataView(msg.buffer); v.setUint32(0, tick >> 16 >> 16); v.setUint32(4, tick & 0xFFFFFFFF); - var ret; + let ret; try { ret = hmac(b32decode(token.secret), msg, token.algorithm); ret = formatOtp(ret, token.digits); @@ -117,7 +116,7 @@ var state = { }; function sizeFont(id, txt, w) { - var sz = fontszCache[id]; + let sz = fontszCache[id]; if (sz) { g.setFont("Vector", sz); } else { From b8e495d422b824b173df487240bf6f1265cd01ba Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 23 Mar 2022 09:40:36 +0100 Subject: [PATCH 048/253] Add files via upload updated screenshot --- apps/glbasic/glbasic_screenshot.png | Bin 1809 -> 2678 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/glbasic/glbasic_screenshot.png b/apps/glbasic/glbasic_screenshot.png index e6e5ff9f714ffdca28588be6cd6e87376f12cce9..151ee38b922b4a10c35d81e44a2ecdcae1556759 100644 GIT binary patch literal 2678 zcmbVOdo^Y8N5!3cyX*dY*Sddvzk7ez=d<_P>$CRW>zm?WXDNb_!2ke6 zPMx%H;#=mwju4uE*SAc2^9>@@$+LYo>(%|;?T)&lb zO9tv>{B!MwZ+f~fTk%2X;8U~n*V-n6zdwX4FwqEJMV9hHumF%2YbFDzMMvRx6k%sz zEdaq@X7Pel=}`{^__H;7hbT;7HX*^&@C_k($cGvr03zqVh!eqccmxA@BQwg8ATh31 z5^!t#EO}rjilPZ%N)DZikVgMMiJuDdewfXku8fH>HSgQ5k;y?mat);%)B(6%7i?=D zKAGl89;5AO_4Ne!{W$1myl`TUo*?%j4Db>*1Uw|5B(DnG)G7ugfJwraohT~ZYV07; z8rlsd_!`?Hn9gc!0{B{0CWnH}O|_xgQq}n_S2}~7ZhaLqsor~kAESrzo0C5B&pJ=+He9IM zu&j@hB$cDK)d~JeB)$fUGvpl1gHRC#fsCwoRYqVmfi$7W=m{tHMWiGDofwSYEK$fK z-;H9)|A)g8B!TZw&M;cef6h9eaUGjcl}rYp#Q)avUP6XbGn_?W*N2aIV^ zn+I9`o~hBN{|nU2iQR4arF4MgOmnxFWt6(DE#*^0aqo2@<=IF9 z;HIdg`jH>E(%9W_6k)e-hmx;vArcVnqlno5K?Zx0lT&E?Ng^(uAx7OOvYf zmhyw7j$gfDWU88=r0M5b6DKL@K9smi!Y{R#1>D^4zX()6=2%gYhJ~`S-21cnfd5Yb zO(`rf$YuXIHWlbDUTLTU$W_`*1e|X!M0juk2_YioV~}iq;mEX)_W>0YS{A{&0L28Q zG*uuC&AvIn+X(|L_+nwoUJ%9hsIN{-9+s7zg;#Q8mKWkWDMKWu-o)a5Nl5BZ^KVtR z%XYvFDf7JwpaD((qBp(=pm-s3nK*v=SwxW*0T>YR#^uKWnyO;|JctI!f-{G+^TavI z_V$7Ar!E_AwOrSi*8fTt@Ec~~(h;o0X53m0rnmYEB1BM#VpI3i#RkcJ_L9tWokDVP zV$HdpKixfJ#^Y@oY7Bn=%P9sPeDc%PZVYEdxH^#2v5?8p5FF7vl!%dBZ#_^b z-W~9CXsR?!TPA0-&n`~%Z zg$?453pBD0(5KqyR>}W z*rZYP`s!9kNBKyPK7DIfeswsjJL$sSvvqOxeQ0*;p*11xW2U>fE`t3*YNY|wUx|TG zsDnp=_L$2+UM=1RQ$+68-dK->LcLgx?Y~6y96}eNd5A0a5G6VnS@bH_AZ_SU^FG&?D_k<0EnuIjUj)YOmMWx_brE-fFgUCY5oFpVqri~z_ZICKy&*B32#@AUc6cxU~ubmgiQ$Dv8R)!@RCGu@fdL!;Icx}DvRZPbIrLODt_GfWhm zH#Q;r3&yLCyo!J;b$w2&+`MUZ&%^mbvgxKq(@nC>V~yqe=II) zTBRBW-E{`RlN3d-S4qMl(-KFUHXa#&VuFFV+}0(iG3*Z|?(AlAxz(rdLwhR@2bPI0 zz3MuP=TEZm(u$tScI%iQd{C`b2hCmT-Je;G>PSJt8G9pl`Us1Q1%yOsg}-teS}JV| zqpqn|@7w%Uv?Vq`)aJIJ;lXIrx!4W}bMOvf?j! zsqxV5xeM)u-3i2Q>MQXan%4d~7`raL+9hM#P(79Xp>EX&869r?abhbp zqR>NulOI+V(exwcq`iCo&`1rfpdvP@b{Yj8;mYp408Yni8Xxrk!e4#3(B`-M5mc}h z2yG|Xda~jZWL=6P99|CjGp^l~T&B#IZZ?Qji;%;d_sA9PzS4F6@7)Ghl(Vs)Y@3%D zoBT!H8GXrV1#77^Aq8m;m7u;^l%h<$2^QY=4Y$;=)o8mQwqa1Of|~I=g8ja&B-{L} zQ{{~_+Sit@G|ASS^lUP-fs~IC_6VHN z$6zpuF8dt4(J1(~AQ^OTZl4Z9gVafHhCQa~8F3zikr{At+VSS^u+ zRTmX$Jc_o-yeFk<_Nw`DMvt@M?ehb7Cx2@1JF5vrx{7#68Iw1*M~-Zy73qP2+ew;l zaB8w`+UZCjpD%_AHU;ACM2&rnc`y}NYFYQT9am4mtAqK{|=d zdE>aKc^355KK4vD(Wr7(`!sFm28G(ZSCE+R#Sc65;nuQu~eBq3fCkLf?ePWX)BAi zDeJdeb1O<~)jC%#R}G^VwCCb2JQc98C;hX66rOnqjc_o#Va2a`G zQ^EP(&l`?j6T4Z@{=Q*ej%XV*h;go^ZYhUmr}s5{YRP^1s+U!clq0LPScpZlP_Bg+ zy31&ir^ZBd!;6QOT4L+H2Y+9guqxL7sL-Gi-Q%~wR9(Ag z)I9k0W&rql*@Fm3wh;lUAO$+rxiHR^T*abqIR(Kd4%`)NI>zw4f1yjiX1e6dj;9g3 zm~19{om3VdLNP)sJP?D}*GH^t;SN@v`%#~c-&TfpsJ+q++qw8V`)nwOs~E;@z7Ilnfo;wMrh@ea@80m@ zw73u#xRIcnfjEKKH7&7086_Q2=f!s9VSvM6ZBu!r8k2MF@WrmUyswJY_kszl@l`2a_EBJBI=vO*#@=m z(viI-w*ovd@Th6%BeE2z^zhnnB5I#XOMMwRG6#FCb@Vd0;R6$>O0s%;Rf*YH<)hQ3tr=g|jfS_!I z6a%i(b~f9yw^#y6 z8aa@`^{q-CZ0bE!>^5U3Qd-QQ`{!pM-B*MQyQRQXTjHE1iDGuuO%FAWA78v%#4f{uHkR48&=R(DU|9i5r$V1{zloT?{-g0#DbauG%AMI0d$oe9w!tOwqX z{WR}PH#$vXPF{^1S#Zqp5gUMP;%SaAKve=pTo1abh|)*|RhL0bRKakN^Mx From 6158d76f176315b014498e997a93a6ad1a267b30 Mon Sep 17 00:00:00 2001 From: Micha <97034053+foostuff@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:37:44 +0100 Subject: [PATCH 050/253] configurable drag gestures --- apps/clockcal/app.js | 172 ++++++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 77 deletions(-) diff --git a/apps/clockcal/app.js b/apps/clockcal/app.js index 86fa0815a..5e8c7f796 100644 --- a/apps/clockcal/app.js +++ b/apps/clockcal/app.js @@ -4,12 +4,13 @@ var s = Object.assign({ CAL_ROWS: 4, //number of calendar rows.(weeks) Shouldn't exceed 5 when using widgets. BUZZ_ON_BT: true, //2x slow buzz on disconnect, 2x fast buzz on connect. Will be extra widget eventually MODE24: true, //24h mode vs 12h mode - FIRSTDAYOFFSET: 6, //First day of the week: 0-6: Sun, Sat, Fri, Thu, Wed, Tue, Mon + FIRSTDAY: 6, //First day of the week: mo, tu, we, th, fr, sa, su REDSUN: true, // Use red color for sunday? REDSAT: true, // Use red color for saturday? - DRAGENABLED: true, - DRAGMUSIC: true, - DRAGMESSAGES: true + DRAGDOWN: "[AI:messg]", + DRAGRIGHT: "[AI:music]", + DRAGLEFT: "[ignore]", + DRAGUP: "[calend.]" }, require('Storage').readJSON("clockcal.json", true) || {}); const h = g.getHeight(); @@ -27,13 +28,13 @@ var monthOffset = 0; */ function drawFullCalendar(monthOffset) { addMonths = function (_d, _am) { - var ay = 0, m = _d.getMonth(), y = _d.getFullYear(); - while ((m + _am) > 11) { ay++; _am -= 12; } - while ((m + _am) < 0) { ay--; _am += 12; } - n = new Date(_d.getTime()); - n.setMonth(m + _am); - n.setFullYear(y + ay); - return n; + var ay = 0, m = _d.getMonth(), y = _d.getFullYear(); + while ((m + _am) > 11) { ay++; _am -= 12; } + while ((m + _am) < 0) { ay--; _am += 12; } + n = new Date(_d.getTime()); + n.setMonth(m + _am); + n.setFullYear(y + ay); + return n; }; monthOffset = (typeof monthOffset == "undefined") ? 0 : monthOffset; state = "calendar"; @@ -45,22 +46,22 @@ function drawFullCalendar(monthOffset) { if (typeof minuteInterval !== "undefined") clearTimeout(minuteInterval); d = addMonths(Date(), monthOffset); tdy = Date().getDate() + "." + Date().getMonth(); - newmonth=false; + newmonth = false; c_y = 0; g.reset(); g.setBgColor(0); g.clear(); - var prevmonth = addMonths(d, -1) + var prevmonth = addMonths(d, -1); const today = prevmonth.getDate(); var rD = new Date(prevmonth.getTime()); rD.setDate(rD.getDate() - (today - 1)); - const dow = (s.FIRSTDAYOFFSET + rD.getDay()) % 7; + const dow = (s.FIRSTDAY + rD.getDay()) % 7; rD.setDate(rD.getDate() - dow); var rDate = rD.getDate(); bottomrightY = c_y - 3; - clrsun=s.REDSUN?'#f00':'#fff'; - clrsat=s.REDSUN?'#f00':'#fff'; - var fg=[clrsun,'#fff','#fff','#fff','#fff','#fff',clrsat]; + clrsun = s.REDSUN ? '#f00' : '#fff'; + clrsat = s.REDSUN ? '#f00' : '#fff'; + var fg = [clrsun, '#fff', '#fff', '#fff', '#fff', '#fff', clrsat]; for (var y = 1; y <= 11; y++) { bottomrightY += CELL_H; bottomrightX = -2; @@ -69,14 +70,14 @@ function drawFullCalendar(monthOffset) { rMonth = rD.getMonth(); rDate = rD.getDate(); if (tdy == rDate + "." + rMonth) { - caldrawToday(rDate); + caldrawToday(rDate); } else if (rDate == 1) { - caldrawFirst(rDate); + caldrawFirst(rDate); } else { - caldrawNormal(rDate,fg[rD.getDay()]); + caldrawNormal(rDate, fg[rD.getDay()]); } if (newmonth && x == 7) { - caldrawMonth(rDate,monthclr[rMonth % 6],months[rMonth],rD); + caldrawMonth(rDate, monthclr[rMonth % 6], months[rMonth], rD); } rD.setDate(rDate + 1); } @@ -84,7 +85,7 @@ function drawFullCalendar(monthOffset) { delete addMonths; if (DEBUG) console.log("Calendar performance (ms):" + (Date().getTime() - start)); } -function caldrawMonth(rDate,c,m,rD) { +function caldrawMonth(rDate, c, m, rD) { g.setColor(c); g.setFont("Vector", 18); g.setFontAlign(-1, 1, 1); @@ -93,29 +94,29 @@ function caldrawMonth(rDate,c,m,rD) { newmonth = false; } function caldrawToday(rDate) { - g.setFont("Vector", 16); - g.setFontAlign(1, 1); - g.setColor('#0f0'); - g.fillRect(bottomrightX - CELL2_W + 1, bottomrightY - CELL_H - 1, bottomrightX, bottomrightY - 2); - g.setColor('#000'); - g.drawString(rDate, bottomrightX, bottomrightY); + g.setFont("Vector", 16); + g.setFontAlign(1, 1); + g.setColor('#0f0'); + g.fillRect(bottomrightX - CELL2_W + 1, bottomrightY - CELL_H - 1, bottomrightX, bottomrightY - 2); + g.setColor('#000'); + g.drawString(rDate, bottomrightX, bottomrightY); } function caldrawFirst(rDate) { - g.flip(); - g.setFont("Vector", 16); - g.setFontAlign(1, 1); - bottomrightY += 3; - newmonth = true; - g.setColor('#0ff'); - g.fillRect(bottomrightX - CELL2_W + 1, bottomrightY - CELL_H - 1, bottomrightX, bottomrightY - 2); - g.setColor('#000'); - g.drawString(rDate, bottomrightX, bottomrightY); + g.flip(); + g.setFont("Vector", 16); + g.setFontAlign(1, 1); + bottomrightY += 3; + newmonth = true; + g.setColor('#0ff'); + g.fillRect(bottomrightX - CELL2_W + 1, bottomrightY - CELL_H - 1, bottomrightX, bottomrightY - 2); + g.setColor('#000'); + g.drawString(rDate, bottomrightX, bottomrightY); } -function caldrawNormal(rDate,c) { - g.setFont("Vector", 16); - g.setFontAlign(1, 1); - g.setColor(c); - g.drawString(rDate, bottomrightX, bottomrightY);//100 +function caldrawNormal(rDate, c) { + g.setFont("Vector", 16); + g.setFontAlign(1, 1); + g.setColor(c); + g.drawString(rDate, bottomrightX, bottomrightY);//100 } function drawMinutes() { if (DEBUG) console.log("|-->minutes"); @@ -163,7 +164,7 @@ function drawWatch() { g.clear(); drawMinutes(); if (!dimSeconds) drawSeconds(); - const dow = (s.FIRSTDAYOFFSET + d.getDay()) % 7; //MO=0, SU=6 + const dow = (s.FIRSTDAY + d.getDay()) % 7; //MO=0, SU=6 const today = d.getDate(); var rD = new Date(d.getTime()); rD.setDate(rD.getDate() - dow); @@ -205,27 +206,52 @@ function BTevent() { setTimeout(function () { Bangle.buzz(interval); }, interval * 3); } } - +function action(a) { + g.reset(); + if (typeof secondInterval !== "undefined") clearTimeout(secondInterval); + if (DEBUG) console.log("action:" + a); + switch (a) { + case "[ignore]": + break; + case "[calend.]": + drawFullCalendar(); + break; + case "[AI:music]": + l = require("Storage").list(RegExp("music.*app.js")); + if (l.length > 0) { + load(l[0]); + } else E.showAlert("Music app not found", "Not found").then(drawWatch); + break; + case "[AI:messg]": + l = require("Storage").list(RegExp("message.*app.js")); + if (l.length > 0) { + load(l[0]); + } else E.showAlert("Message app not found", "Not found").then(drawWatch); + break; + default: + l = require("Storage").list(RegExp(a + ".app.js")); + if (l.length > 0) { + load(l[0]); + } else E.showAlert(a + ": App not found", "Not found").then(drawWatch); + break; + } +} function input(dir) { - if (s.DRAGENABLED) { - Bangle.buzz(100,1); - console.log("swipe:"+dir); + Bangle.buzz(100, 1); + if (DEBUG) console.log("swipe:" + dir); switch (dir) { case "r": if (state == "calendar") { drawWatch(); } else { - if (s.DRAGMUSIC) { - l=require("Storage").list(RegExp("music.*app")); - if (l.length > 0) { - load(l[0]); - } else Bangle.buzz(3000,1);//not found - } + action(s.DRAGRIGHT); } break; case "l": if (state == "calendar") { drawWatch(); + } else { + action(s.DRAGLEFT); } break; case "d": @@ -233,21 +259,15 @@ function input(dir) { monthOffset--; drawFullCalendar(monthOffset); } else { - if (s.DRAGMESSAGES) { - l=require("Storage").list(RegExp("message.*app")); - if (l.length > 0) { - load(l[0]); - } else Bangle.buzz(3000,1);//not found - } + action(s.DRAGDOWN); } break; case "u": - if (state == "watch") { - state = "calendar"; - drawFullCalendar(0); - } else if (state == "calendar") { + if (state == "calendar") { monthOffset++; drawFullCalendar(monthOffset); + } else { + action(s.DRAGUP); } break; default: @@ -255,26 +275,24 @@ function input(dir) { drawWatch(); } break; + } - } } let drag; Bangle.on("drag", e => { - if (s.DRAGENABLED) { - if (!drag) { - drag = { x: e.x, y: e.y }; - } else if (!e.b) { - const dx = e.x - drag.x, dy = e.y - drag.y; - var dir = "t"; - if (Math.abs(dx) > Math.abs(dy) + 10) { - dir = (dx > 0) ? "r" : "l"; - } else if (Math.abs(dy) > Math.abs(dx) + 10) { - dir = (dy > 0) ? "d" : "u"; - } - drag = null; - input(dir); + if (!drag) { + drag = { x: e.x, y: e.y }; + } else if (!e.b) { + const dx = e.x - drag.x, dy = e.y - drag.y; + var dir = "t"; + if (Math.abs(dx) > Math.abs(dy) + 20) { + dir = (dx > 0) ? "r" : "l"; + } else if (Math.abs(dy) > Math.abs(dx) + 20) { + dir = (dy > 0) ? "d" : "u"; } + drag = null; + input(dir); } }); From d0426a2093caf025b0fdf3b4ae930bca83b9ee75 Mon Sep 17 00:00:00 2001 From: Micha <97034053+foostuff@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:38:42 +0100 Subject: [PATCH 051/253] Configurable drag gestures --- apps/clockcal/settings.js | 65 +++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/apps/clockcal/settings.js b/apps/clockcal/settings.js index c4ec764c9..abedad99b 100644 --- a/apps/clockcal/settings.js +++ b/apps/clockcal/settings.js @@ -1,19 +1,22 @@ (function (back) { var FILE = "clockcal.json"; - - settings = Object.assign({ + defaults={ CAL_ROWS: 4, //number of calendar rows.(weeks) Shouldn't exceed 5 when using widgets. BUZZ_ON_BT: true, //2x slow buzz on disconnect, 2x fast buzz on connect. Will be extra widget eventually MODE24: true, //24h mode vs 12h mode FIRSTDAY: 6, //First day of the week: mo, tu, we, th, fr, sa, su REDSUN: true, // Use red color for sunday? REDSAT: true, // Use red color for saturday? - DRAGENABLED: true, //Enable drag gestures (bigger calendar etc) - DRAGMUSIC: true, //Enable drag down for music (looks for "music*app") - DRAGMESSAGES: true //Enable drag right for messages (looks for "message*app") - }, require('Storage').readJSON(FILE, true) || {}); - + DRAGDOWN: "[AI:messg]", + DRAGRIGHT: "[AI:music]", + DRAGLEFT: "[ignore]", + DRAGUP: "[calend.]" + }; + settings = Object.assign(defaults, require('Storage').readJSON(FILE, true) || {}); + actions = ["[ignore]","[calend.]","[AI:music]","[AI:messg]"]; + require("Storage").list(RegExp(".app.js")).forEach(element => actions.push(element.replace(".app.js",""))); + function writeSettings() { require('Storage').writeJSON(FILE, settings); } @@ -70,27 +73,39 @@ writeSettings(); } }, - 'Swipes (big cal.)?': { - value: settings.DRAGENABLED, - format: v => v ? "On" : "Off", + 'Drag Up ': { + min:0, max:actions.length-1, + value: actions.indexOf(settings.DRAGUP), + format: v => actions[v], onchange: v => { - settings.DRAGENABLED = v; + settings.DRAGUP = actions[v]; writeSettings(); } }, - 'Swipes (music)?': { - value: settings.DRAGMUSIC, - format: v => v ? "On" : "Off", + 'Drag Right': { + min:0, max:actions.length-1, + value: actions.indexOf(settings.DRAGRIGHT), + format: v => actions[v], onchange: v => { - settings.DRAGMUSIC = v; + settings.DRAGRIGHT = actions[v]; writeSettings(); } }, - 'Swipes (messg)?': { - value: settings.DRAGMESSAGES, - format: v => v ? "On" : "Off", + 'Drag Down': { + min:0, max:actions.length-1, + value: actions.indexOf(settings.DRAGDOWN), + format: v => actions[v], onchange: v => { - settings.DRAGMESSAGES = v; + settings.DRGDOWN = actions[v]; + writeSettings(); + } + }, + 'Drag Left': { + min:0, max:actions.length-1, + value: actions.indexOf(settings.DRAGLEFT), + format: v => actions[v], + onchange: v => { + settings.DRAGLEFT = actions[v]; writeSettings(); } }, @@ -100,17 +115,7 @@ format: v => ["No", "Yes"][v], onchange: v => { if (v == 1) { - settings = { - CAL_ROWS: 4, //number of calendar rows.(weeks) Shouldn't exceed 5 when using widgets. - BUZZ_ON_BT: true, //2x slow buzz on disconnect, 2x fast buzz on connect. - MODE24: true, //24h mode vs 12h mode - FIRSTDAY: 6, //First day of the week: mo, tu, we, th, fr, sa, su - REDSUN: true, // Use red color for sunday? - REDSAT: true, // Use red color for saturday? - DRAGENABLED: true, - DRAGMUSIC: true, - DRAGMESSAGES: true - }; + settings = defaults; writeSettings(); load(); } From abf684449780be69a38ad881f9f7c61ed9894a42 Mon Sep 17 00:00:00 2001 From: Micha <97034053+foostuff@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:40:31 +0100 Subject: [PATCH 052/253] increment version --- apps/clockcal/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/clockcal/metadata.json b/apps/clockcal/metadata.json index a42e1ad2e..dde32f746 100644 --- a/apps/clockcal/metadata.json +++ b/apps/clockcal/metadata.json @@ -1,7 +1,7 @@ { "id": "clockcal", "name": "Clock & Calendar", - "version": "0.2", + "version": "0.3", "description": "Clock with Calendar", "readme":"README.md", "icon": "app.png", From 00d74ceef61fb3596b8468db3219b7e6598962d5 Mon Sep 17 00:00:00 2001 From: Micha <97034053+foostuff@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:46:03 +0100 Subject: [PATCH 053/253] Update ChangeLog --- apps/clockcal/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/clockcal/ChangeLog b/apps/clockcal/ChangeLog index 299b1ec69..f73c6ed97 100644 --- a/apps/clockcal/ChangeLog +++ b/apps/clockcal/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial upload 0.2: Added scrollable calendar and swipe gestures +0.3: Configurable drag gestures From d6c8f634c7689662dea624ab07f91ee2469d1bd3 Mon Sep 17 00:00:00 2001 From: Micha <97034053+foostuff@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:56:17 +0100 Subject: [PATCH 054/253] Update README.md --- apps/clockcal/README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/apps/clockcal/README.md b/apps/clockcal/README.md index da6887177..d30205be0 100644 --- a/apps/clockcal/README.md +++ b/apps/clockcal/README.md @@ -9,25 +9,24 @@ I know that it seems redundant because there already **is** a *time&cal*-app, bu |![unlocked screen](screenshot2.png)|unlocked: smaller clock, but with seconds| |![big calendar](screenshot3.png)|swipe up for big calendar, (up down to scroll, left/right to exit)| - - - ## Configurable Features - Number of calendar rows (weeks) - Buzz on connect/disconnect (I know, this should be an extra widget, but for now, it is included) -- Clock Mode (24h/12h). Doesn't have an am/pm indicator. It's only there because it was easy. +- Clock Mode (24h/12h). (No am/pm indicator) - First day of the week -- Red Saturday -- Red Sunday -- Swipes (to disable all gestures) -- Swipes: music (swipe down) -- Spipes: messages (swipe right) +- Red Saturday/Sunday +- Swipe/Drag gestures to launch features or apps. ## Auto detects your message/music apps: -- swiping down will search your files for an app with the string "music" in its filename and launch it -- swiping right will search your files for an app with the string "message" in its filename and launch it. -- Configurable apps coming soon. +- swiping down will search your files for an app with the string "message" in its filename and launch it. (configurable) +- swiping right will search your files for an app with the string "music" in its filename and launch it. (configurable) ## Feedback The clock works for me in a 24h/MondayFirst/WeekendFree environment but is not well-tested with other settings. So if something isn't working, please tell me: https://github.com/foostuff/BangleApps/issues + +## Planned features: + - Internal lightweight music control, because switching apps has a loading time. + - Clean up settings + - Maybe am/pm indicator for 12h-users + - Step count (optional) From 00ad2a12780da264d897ddd1c39d06074211cb97 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 23 Mar 2022 22:24:14 +0800 Subject: [PATCH 055/253] Update app.js Define some constants. Add RFC comments. --- apps/authentiwatch/app.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 5198254af..6e2951b9f 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -2,6 +2,8 @@ const COUNTER_TRIANGLE_SIZE = 10; const TOKEN_EXTRA_HEIGHT = 16; var TOKEN_DIGITS_HEIGHT = 30; var TOKEN_HEIGHT = TOKEN_DIGITS_HEIGHT + TOKEN_EXTRA_HEIGHT; +const PROGRESSBAR_HEIGHT = 3; +const IDLE_REPEATS = 1; // when idle, the number of extra timed periods to show before hiding const SETTINGS = "authentiwatch.json"; // Hash functions const crypto = require("crypto"); @@ -21,7 +23,7 @@ if (settings.data ) tokens = settings.data ; /* v0.02 settings */ if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ function b32decode(seedstr) { - // RFC4648 + // RFC4648 Base16/32/64 Data Encodings let buf = 0, bitcount = 0, retstr = ""; for (let c of seedstr.toUpperCase()) { if (c == '0') c = 'O'; @@ -48,7 +50,7 @@ function b32decode(seedstr) { function hmac(key, message, algo) { let a = algos[algo.toUpperCase()]; - // RFC2104 + // RFC2104 HMAC if (key.length > a.blksz) { key = a.sha(key); } @@ -62,7 +64,7 @@ function hmac(key, message, algo) { istr.set(message, a.blksz); ostr.set(a.sha(istr), a.blksz); let ret = a.sha(ostr); - // RFC4226 dynamic truncation + // RFC4226 HOTP (dynamic truncation) let v = new DataView(ret, ret[ret.length - 1] & 0x0F, 4); return v.getUint32(0) & 0x7FFFFFFF; } @@ -187,7 +189,7 @@ function drawProgressBar() { let y2 = y1 + TOKEN_HEIGHT - 1; if (y2 >= AR.y && y1 <= AR.y2) { // token visible - y1 = y2 - 3; + y1 = y2 - PROGRESSBAR_HEIGHT; if (y1 <= AR.y2) { // progress bar visible @@ -278,7 +280,7 @@ function changeId(id) { } function onDrag(e) { - state.cnt = 1; + state.cnt = IDLE_REPEATS; if (e.b != 0 && e.dy != 0) { let y = E.clip(state.listy - E.clip(e.dy, -AR.h, AR.h), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h)); if (state.listy != y) { @@ -312,7 +314,7 @@ function onDrag(e) { } function onTouch(zone, e) { - state.cnt = 1; + state.cnt = IDLE_REPEATS; if (e) { let id = Math.floor((state.listy + e.y - AR.y) / TOKEN_HEIGHT); if (id == state.id || tokens.length == 0 || id >= tokens.length) { @@ -340,7 +342,7 @@ function onTouch(zone, e) { } function onSwipe(e) { - state.cnt = 1; + state.cnt = IDLE_REPEATS; switch (e) { case 1: exitApp(); @@ -358,7 +360,7 @@ function onSwipe(e) { } function bangleBtn(e) { - state.cnt = 1; + state.cnt = IDLE_REPEATS; if (tokens.length > 0) { let id = E.clip(state.id + e, 0, tokens.length - 1); onDrag({b:1, dy:state.listy - E.clip(id * TOKEN_HEIGHT - half(AR.h - TOKEN_HEIGHT), 0, Math.max(0, tokens.length * TOKEN_HEIGHT - AR.h))}); From 287cbf6eea1376f02e1d5472a1c9b9956c953205 Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 23 Mar 2022 14:56:07 -0400 Subject: [PATCH 056/253] New app 2047++ --- apps/2047++/2047++.app.js | 129 ++++++++++++++++++++++++++++++++++++++ apps/2047++/README.md | 6 ++ apps/2047++/app-icon.js | 1 + apps/2047++/app.png | Bin 0 -> 759 bytes apps/2047++/metadata.json | 14 +++++ 5 files changed, 150 insertions(+) create mode 100644 apps/2047++/2047++.app.js create mode 100644 apps/2047++/README.md create mode 100644 apps/2047++/app-icon.js create mode 100644 apps/2047++/app.png create mode 100644 apps/2047++/metadata.json diff --git a/apps/2047++/2047++.app.js b/apps/2047++/2047++.app.js new file mode 100644 index 000000000..b508d8f07 --- /dev/null +++ b/apps/2047++/2047++.app.js @@ -0,0 +1,129 @@ + + +class TwoK { + constructor() { + this.b = Array(4).fill().map(() => Array(4).fill(0)); + this.score = 0; + this.cmap = {0: "#caa", 2:"#ccc", 4: "#bcc", 8: "#ba6", 16: "#e61", 32: "#d20", 64: "#d00", 128: "#da0", 256: "#ec0", 512: "#dd0"}; + } + drawBRect(x1, y1, x2, y2, th, c, cf) { + g.setColor(c); + for (i=0; i 4) g.setColor(1, 1, 1); + else g.setColor(0, 0, 0); + g.setFont("Vector", bh*(b>8 ? (b>64 ? (b>512 ? 0.32 : 0.4) : 0.6) : 0.7)); + if (b>0) g.drawString(b.toString(), xo+(x+0.5)*bw+1, yo+(y+0.5)*bh); + } + } + shift(d) { // +/-1: shift x, +/- 2: shift y + var crc = E.CRC32(this.b.toString()); + if (d==-1) { // shift x left + for (y=0; y<4; ++y) { + for (x=2; x>=0; x--) + if (this.b[y][x]==0) { + for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1]; + this.b[y][3] = 0; moved = true; + } + for (x=0; x<3; ++x) + if (this.b[y][x]==this.b[y][x+1]) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y][x+1]; + for (j=x+1; j<3; ++j) this.b[y][j] = this.b[y][j+1]; + this.b[y][3] = 0; moved = true; + } + } + } + else if (d==1) { // shift x right + for (y=0; y<4; ++y) { + for (x=1; x<4; x++) + if (this.b[y][x]==0) { + for (i=x; i>0; i--) this.b[y][i] = this.b[y][i-1]; + this.b[y][0] = 0; + } + for (x=3; x>0; --x) + if (this.b[y][x]==this.b[y][x-1]) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y][x-1] ; + for (j=x-1; j>0; j--) this.b[y][j] = this.b[y][j-1]; + this.b[y][0] = 0; + } + } + } + else if (d==-2) { // shift y down + for (x=0; x<4; ++x) { + for (y=1; y<4; y++) + if (this.b[y][x]==0) { + for (i=y; i>0; i--) this.b[i][x] = this.b[i-1][x]; + this.b[0][x] = 0; + } + for (y=3; y>0; y--) + if (this.b[y][x]==this.b[y-1][x] || this.b[y][x]==0) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y-1][x]; + for (j=y-1; j>0; j--) this.b[j][x] = this.b[j-1][x]; + this.b[0][x] = 0; + } + } + } + else if (d==2) { // shift y up + for (x=0; x<4; ++x) { + for (y=2; y>=0; y--) + if (this.b[y][x]==0) { + for (i=y; i<3; i++) this.b[i][x] = this.b[i+1][x]; + this.b[3][x] = 0; + } + for (y=0; y<3; ++y) + if (this.b[y][x]==this.b[y+1][x] || this.b[y][x]==0) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y+1][x]; + for (j=y+1; j<3; ++j) this.b[j][x] = this.b[j+1][x]; + this.b[3][x] = 0; + } + } + } + return (E.CRC32(this.b.toString())!=crc); + } + addDigit() { + var d = Math.random()>0.9 ? 4 : 2; + var id = Math.floor(Math.random()*16); + while (this.b[Math.floor(id/4)][id%4] > 0) id = Math.floor(Math.random()*16); + this.b[Math.floor(id/4)][id%4] = d; + } +} + +function dragHandler(e) { + if (e.b && (Math.abs(e.dx)>7 || Math.abs(e.dy)>7)) { + var res = false; + if (Math.abs(e.dx)>Math.abs(e.dy)) { + if (e.dx>0) res = twok.shift(1); + if (e.dx<0) res = twok.shift(-1); + } + else { + if (e.dy>0) res = twok.shift(-2); + if (e.dy<0) res = twok.shift(2); + } + if (res) twok.addDigit(); + twok.render(); + } +} + +var twok = new TwoK(); +twok.addDigit(); twok.addDigit(); +twok.render(); +Bangle.on("drag", dragHandler); diff --git a/apps/2047++/README.md b/apps/2047++/README.md new file mode 100644 index 000000000..5b70423e4 --- /dev/null +++ b/apps/2047++/README.md @@ -0,0 +1,6 @@ + +# Game of 2047++ + +Tile shifting game inspired by the well known 2048 game. Also very similar to another Bangle game, Game1024. + +Attempt to combine equal numbers by swiping left, right, up or down. diff --git a/apps/2047++/app-icon.js b/apps/2047++/app-icon.js new file mode 100644 index 000000000..4086d1879 --- /dev/null +++ b/apps/2047++/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A31gAeFtoxPF9wujGBYQG1YAWF6ur5gAYGIovOFzIABF6ReaMAwv/F/4v/F7ejv9/0Yvq1Eylksv4vqvIuBF9ZeDF9ZeBqovr1AsB0YvrLwXMF9ReDF9ZeBq1/v4vBqowKF7lWFYIAFF/7vXAAa/qF+jxB0YvsABov/F/4v/F6WsF7YgEF5xgaLwgvPGIQAWDwwvQADwvJGEguKF+AxhFpoA/AH4A/AFI=")) \ No newline at end of file diff --git a/apps/2047++/app.png b/apps/2047++/app.png new file mode 100644 index 0000000000000000000000000000000000000000..d1fb4a5e5cbadce3da7b36806d4907f680f8f1bb GIT binary patch literal 759 zcmVYCuD-J|F04S(qype>Ll^oVPK(#&(MEqX}dr+-4N41U&D6G<#pk8p=ry~PL z8P~wDv0Fxk@G(D*-Esf`5DS+uaYFpJB+Wpns^Zb}E7&tzFF7%tm102J6nd69|4+P3 zr1VfMt5{y0fI>`0^KD2mu=F8{y6M673*Til--d7lyX64hte$~F4EL^Xh;F_M;RY5n zQPi8Q(T|*z{|6UpV5c0w+w9;*9}v8ZE@h%j4t73gCg!Qfe`}$Ac#sB~}C%=m9 zQmlcEAIAXzTR($HE?;WPt>nU3$%Ta*5c>_tUp2cB`Ud77yzh$Lczg#y>rX6t^Z|D> zcQA?REP&Q#P6pBq$e1?!8Tl#X8W=W?3|OSe*3omHjttb47#RG02|5f6e$ zObTJ!ml%i%20ylab9U#WUDz$7W@n({nZhq+5~`IO*5Pi07qm053E*;P(4-Kmo@>1; z>;uNw7hc?M3Z*1!=?Nlw%8PRi7>4l#z$>YW4#!KwFcx?T+e^N5I_>#$tusSJ+zSuc p5YZ-MEM*wRg54#bi;K&M^BdjW!v$Q*XjK3J002ovPDHLkV1lLySIGbX literal 0 HcmV?d00001 diff --git a/apps/2047++/metadata.json b/apps/2047++/metadata.json new file mode 100644 index 000000000..f887d95d9 --- /dev/null +++ b/apps/2047++/metadata.json @@ -0,0 +1,14 @@ +{ "id": "2047++", + "name": "2047++", + "shortName":"2047++", + "icon": "app.png", + "version":"0.01", + "description": "Bangle version of a tile shifting game", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "tags": "game", + "storage": [ + {"name":"2047++.app.js","url":"2047++.app.js"}, + {"name":"2047++.img","url":"app-icon.js","evaluate":true} + ] +} From 1e10f4a25eb1c7a48513694b71fa1b0aee623217 Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 23 Mar 2022 14:59:23 -0400 Subject: [PATCH 057/253] Change name of new app --- apps/2047++/2047++.app.js | 129 -------------------------------------- apps/2047++/README.md | 6 -- apps/2047++/app-icon.js | 1 - apps/2047++/app.png | Bin 759 -> 0 bytes apps/2047++/metadata.json | 14 ----- 5 files changed, 150 deletions(-) delete mode 100644 apps/2047++/2047++.app.js delete mode 100644 apps/2047++/README.md delete mode 100644 apps/2047++/app-icon.js delete mode 100644 apps/2047++/app.png delete mode 100644 apps/2047++/metadata.json diff --git a/apps/2047++/2047++.app.js b/apps/2047++/2047++.app.js deleted file mode 100644 index b508d8f07..000000000 --- a/apps/2047++/2047++.app.js +++ /dev/null @@ -1,129 +0,0 @@ - - -class TwoK { - constructor() { - this.b = Array(4).fill().map(() => Array(4).fill(0)); - this.score = 0; - this.cmap = {0: "#caa", 2:"#ccc", 4: "#bcc", 8: "#ba6", 16: "#e61", 32: "#d20", 64: "#d00", 128: "#da0", 256: "#ec0", 512: "#dd0"}; - } - drawBRect(x1, y1, x2, y2, th, c, cf) { - g.setColor(c); - for (i=0; i 4) g.setColor(1, 1, 1); - else g.setColor(0, 0, 0); - g.setFont("Vector", bh*(b>8 ? (b>64 ? (b>512 ? 0.32 : 0.4) : 0.6) : 0.7)); - if (b>0) g.drawString(b.toString(), xo+(x+0.5)*bw+1, yo+(y+0.5)*bh); - } - } - shift(d) { // +/-1: shift x, +/- 2: shift y - var crc = E.CRC32(this.b.toString()); - if (d==-1) { // shift x left - for (y=0; y<4; ++y) { - for (x=2; x>=0; x--) - if (this.b[y][x]==0) { - for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1]; - this.b[y][3] = 0; moved = true; - } - for (x=0; x<3; ++x) - if (this.b[y][x]==this.b[y][x+1]) { - this.score += 2*this.b[y][x]; - this.b[y][x] += this.b[y][x+1]; - for (j=x+1; j<3; ++j) this.b[y][j] = this.b[y][j+1]; - this.b[y][3] = 0; moved = true; - } - } - } - else if (d==1) { // shift x right - for (y=0; y<4; ++y) { - for (x=1; x<4; x++) - if (this.b[y][x]==0) { - for (i=x; i>0; i--) this.b[y][i] = this.b[y][i-1]; - this.b[y][0] = 0; - } - for (x=3; x>0; --x) - if (this.b[y][x]==this.b[y][x-1]) { - this.score += 2*this.b[y][x]; - this.b[y][x] += this.b[y][x-1] ; - for (j=x-1; j>0; j--) this.b[y][j] = this.b[y][j-1]; - this.b[y][0] = 0; - } - } - } - else if (d==-2) { // shift y down - for (x=0; x<4; ++x) { - for (y=1; y<4; y++) - if (this.b[y][x]==0) { - for (i=y; i>0; i--) this.b[i][x] = this.b[i-1][x]; - this.b[0][x] = 0; - } - for (y=3; y>0; y--) - if (this.b[y][x]==this.b[y-1][x] || this.b[y][x]==0) { - this.score += 2*this.b[y][x]; - this.b[y][x] += this.b[y-1][x]; - for (j=y-1; j>0; j--) this.b[j][x] = this.b[j-1][x]; - this.b[0][x] = 0; - } - } - } - else if (d==2) { // shift y up - for (x=0; x<4; ++x) { - for (y=2; y>=0; y--) - if (this.b[y][x]==0) { - for (i=y; i<3; i++) this.b[i][x] = this.b[i+1][x]; - this.b[3][x] = 0; - } - for (y=0; y<3; ++y) - if (this.b[y][x]==this.b[y+1][x] || this.b[y][x]==0) { - this.score += 2*this.b[y][x]; - this.b[y][x] += this.b[y+1][x]; - for (j=y+1; j<3; ++j) this.b[j][x] = this.b[j+1][x]; - this.b[3][x] = 0; - } - } - } - return (E.CRC32(this.b.toString())!=crc); - } - addDigit() { - var d = Math.random()>0.9 ? 4 : 2; - var id = Math.floor(Math.random()*16); - while (this.b[Math.floor(id/4)][id%4] > 0) id = Math.floor(Math.random()*16); - this.b[Math.floor(id/4)][id%4] = d; - } -} - -function dragHandler(e) { - if (e.b && (Math.abs(e.dx)>7 || Math.abs(e.dy)>7)) { - var res = false; - if (Math.abs(e.dx)>Math.abs(e.dy)) { - if (e.dx>0) res = twok.shift(1); - if (e.dx<0) res = twok.shift(-1); - } - else { - if (e.dy>0) res = twok.shift(-2); - if (e.dy<0) res = twok.shift(2); - } - if (res) twok.addDigit(); - twok.render(); - } -} - -var twok = new TwoK(); -twok.addDigit(); twok.addDigit(); -twok.render(); -Bangle.on("drag", dragHandler); diff --git a/apps/2047++/README.md b/apps/2047++/README.md deleted file mode 100644 index 5b70423e4..000000000 --- a/apps/2047++/README.md +++ /dev/null @@ -1,6 +0,0 @@ - -# Game of 2047++ - -Tile shifting game inspired by the well known 2048 game. Also very similar to another Bangle game, Game1024. - -Attempt to combine equal numbers by swiping left, right, up or down. diff --git a/apps/2047++/app-icon.js b/apps/2047++/app-icon.js deleted file mode 100644 index 4086d1879..000000000 --- a/apps/2047++/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A31gAeFtoxPF9wujGBYQG1YAWF6ur5gAYGIovOFzIABF6ReaMAwv/F/4v/F7ejv9/0Yvq1Eylksv4vqvIuBF9ZeDF9ZeBqovr1AsB0YvrLwXMF9ReDF9ZeBq1/v4vBqowKF7lWFYIAFF/7vXAAa/qF+jxB0YvsABov/F/4v/F6WsF7YgEF5xgaLwgvPGIQAWDwwvQADwvJGEguKF+AxhFpoA/AH4A/AFI=")) \ No newline at end of file diff --git a/apps/2047++/app.png b/apps/2047++/app.png deleted file mode 100644 index d1fb4a5e5cbadce3da7b36806d4907f680f8f1bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 759 zcmVYCuD-J|F04S(qype>Ll^oVPK(#&(MEqX}dr+-4N41U&D6G<#pk8p=ry~PL z8P~wDv0Fxk@G(D*-Esf`5DS+uaYFpJB+Wpns^Zb}E7&tzFF7%tm102J6nd69|4+P3 zr1VfMt5{y0fI>`0^KD2mu=F8{y6M673*Til--d7lyX64hte$~F4EL^Xh;F_M;RY5n zQPi8Q(T|*z{|6UpV5c0w+w9;*9}v8ZE@h%j4t73gCg!Qfe`}$Ac#sB~}C%=m9 zQmlcEAIAXzTR($HE?;WPt>nU3$%Ta*5c>_tUp2cB`Ud77yzh$Lczg#y>rX6t^Z|D> zcQA?REP&Q#P6pBq$e1?!8Tl#X8W=W?3|OSe*3omHjttb47#RG02|5f6e$ zObTJ!ml%i%20ylab9U#WUDz$7W@n({nZhq+5~`IO*5Pi07qm053E*;P(4-Kmo@>1; z>;uNw7hc?M3Z*1!=?Nlw%8PRi7>4l#z$>YW4#!KwFcx?T+e^N5I_>#$tusSJ+zSuc p5YZ-MEM*wRg54#bi;K&M^BdjW!v$Q*XjK3J002ovPDHLkV1lLySIGbX diff --git a/apps/2047++/metadata.json b/apps/2047++/metadata.json deleted file mode 100644 index f887d95d9..000000000 --- a/apps/2047++/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ "id": "2047++", - "name": "2047++", - "shortName":"2047++", - "icon": "app.png", - "version":"0.01", - "description": "Bangle version of a tile shifting game", - "supports" : ["BANGLEJS2"], - "readme": "README.md", - "tags": "game", - "storage": [ - {"name":"2047++.app.js","url":"2047++.app.js"}, - {"name":"2047++.img","url":"app-icon.js","evaluate":true} - ] -} From 80246d2398a93311aaa131886f873b54da705a66 Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 23 Mar 2022 15:00:54 -0400 Subject: [PATCH 058/253] New app 2047pp --- apps/2047pp/2047pp.app.js | 129 ++++++++++++++++++++++++++++++++++++++ apps/2047pp/README.md | 6 ++ apps/2047pp/app-icon.js | 1 + apps/2047pp/app.png | Bin 0 -> 759 bytes apps/2047pp/metadata.json | 14 +++++ 5 files changed, 150 insertions(+) create mode 100644 apps/2047pp/2047pp.app.js create mode 100644 apps/2047pp/README.md create mode 100644 apps/2047pp/app-icon.js create mode 100644 apps/2047pp/app.png create mode 100644 apps/2047pp/metadata.json diff --git a/apps/2047pp/2047pp.app.js b/apps/2047pp/2047pp.app.js new file mode 100644 index 000000000..b508d8f07 --- /dev/null +++ b/apps/2047pp/2047pp.app.js @@ -0,0 +1,129 @@ + + +class TwoK { + constructor() { + this.b = Array(4).fill().map(() => Array(4).fill(0)); + this.score = 0; + this.cmap = {0: "#caa", 2:"#ccc", 4: "#bcc", 8: "#ba6", 16: "#e61", 32: "#d20", 64: "#d00", 128: "#da0", 256: "#ec0", 512: "#dd0"}; + } + drawBRect(x1, y1, x2, y2, th, c, cf) { + g.setColor(c); + for (i=0; i 4) g.setColor(1, 1, 1); + else g.setColor(0, 0, 0); + g.setFont("Vector", bh*(b>8 ? (b>64 ? (b>512 ? 0.32 : 0.4) : 0.6) : 0.7)); + if (b>0) g.drawString(b.toString(), xo+(x+0.5)*bw+1, yo+(y+0.5)*bh); + } + } + shift(d) { // +/-1: shift x, +/- 2: shift y + var crc = E.CRC32(this.b.toString()); + if (d==-1) { // shift x left + for (y=0; y<4; ++y) { + for (x=2; x>=0; x--) + if (this.b[y][x]==0) { + for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1]; + this.b[y][3] = 0; moved = true; + } + for (x=0; x<3; ++x) + if (this.b[y][x]==this.b[y][x+1]) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y][x+1]; + for (j=x+1; j<3; ++j) this.b[y][j] = this.b[y][j+1]; + this.b[y][3] = 0; moved = true; + } + } + } + else if (d==1) { // shift x right + for (y=0; y<4; ++y) { + for (x=1; x<4; x++) + if (this.b[y][x]==0) { + for (i=x; i>0; i--) this.b[y][i] = this.b[y][i-1]; + this.b[y][0] = 0; + } + for (x=3; x>0; --x) + if (this.b[y][x]==this.b[y][x-1]) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y][x-1] ; + for (j=x-1; j>0; j--) this.b[y][j] = this.b[y][j-1]; + this.b[y][0] = 0; + } + } + } + else if (d==-2) { // shift y down + for (x=0; x<4; ++x) { + for (y=1; y<4; y++) + if (this.b[y][x]==0) { + for (i=y; i>0; i--) this.b[i][x] = this.b[i-1][x]; + this.b[0][x] = 0; + } + for (y=3; y>0; y--) + if (this.b[y][x]==this.b[y-1][x] || this.b[y][x]==0) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y-1][x]; + for (j=y-1; j>0; j--) this.b[j][x] = this.b[j-1][x]; + this.b[0][x] = 0; + } + } + } + else if (d==2) { // shift y up + for (x=0; x<4; ++x) { + for (y=2; y>=0; y--) + if (this.b[y][x]==0) { + for (i=y; i<3; i++) this.b[i][x] = this.b[i+1][x]; + this.b[3][x] = 0; + } + for (y=0; y<3; ++y) + if (this.b[y][x]==this.b[y+1][x] || this.b[y][x]==0) { + this.score += 2*this.b[y][x]; + this.b[y][x] += this.b[y+1][x]; + for (j=y+1; j<3; ++j) this.b[j][x] = this.b[j+1][x]; + this.b[3][x] = 0; + } + } + } + return (E.CRC32(this.b.toString())!=crc); + } + addDigit() { + var d = Math.random()>0.9 ? 4 : 2; + var id = Math.floor(Math.random()*16); + while (this.b[Math.floor(id/4)][id%4] > 0) id = Math.floor(Math.random()*16); + this.b[Math.floor(id/4)][id%4] = d; + } +} + +function dragHandler(e) { + if (e.b && (Math.abs(e.dx)>7 || Math.abs(e.dy)>7)) { + var res = false; + if (Math.abs(e.dx)>Math.abs(e.dy)) { + if (e.dx>0) res = twok.shift(1); + if (e.dx<0) res = twok.shift(-1); + } + else { + if (e.dy>0) res = twok.shift(-2); + if (e.dy<0) res = twok.shift(2); + } + if (res) twok.addDigit(); + twok.render(); + } +} + +var twok = new TwoK(); +twok.addDigit(); twok.addDigit(); +twok.render(); +Bangle.on("drag", dragHandler); diff --git a/apps/2047pp/README.md b/apps/2047pp/README.md new file mode 100644 index 000000000..e685946c1 --- /dev/null +++ b/apps/2047pp/README.md @@ -0,0 +1,6 @@ + +# Game of 2047pp (2047++) + +Tile shifting game inspired by the well known 2048 game. Also very similar to another Bangle game, Game1024. + +Attempt to combine equal numbers by swiping left, right, up or down. diff --git a/apps/2047pp/app-icon.js b/apps/2047pp/app-icon.js new file mode 100644 index 000000000..4086d1879 --- /dev/null +++ b/apps/2047pp/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A31gAeFtoxPF9wujGBYQG1YAWF6ur5gAYGIovOFzIABF6ReaMAwv/F/4v/F7ejv9/0Yvq1Eylksv4vqvIuBF9ZeDF9ZeBqovr1AsB0YvrLwXMF9ReDF9ZeBq1/v4vBqowKF7lWFYIAFF/7vXAAa/qF+jxB0YvsABov/F/4v/F6WsF7YgEF5xgaLwgvPGIQAWDwwvQADwvJGEguKF+AxhFpoA/AH4A/AFI=")) \ No newline at end of file diff --git a/apps/2047pp/app.png b/apps/2047pp/app.png new file mode 100644 index 0000000000000000000000000000000000000000..d1fb4a5e5cbadce3da7b36806d4907f680f8f1bb GIT binary patch literal 759 zcmVYCuD-J|F04S(qype>Ll^oVPK(#&(MEqX}dr+-4N41U&D6G<#pk8p=ry~PL z8P~wDv0Fxk@G(D*-Esf`5DS+uaYFpJB+Wpns^Zb}E7&tzFF7%tm102J6nd69|4+P3 zr1VfMt5{y0fI>`0^KD2mu=F8{y6M673*Til--d7lyX64hte$~F4EL^Xh;F_M;RY5n zQPi8Q(T|*z{|6UpV5c0w+w9;*9}v8ZE@h%j4t73gCg!Qfe`}$Ac#sB~}C%=m9 zQmlcEAIAXzTR($HE?;WPt>nU3$%Ta*5c>_tUp2cB`Ud77yzh$Lczg#y>rX6t^Z|D> zcQA?REP&Q#P6pBq$e1?!8Tl#X8W=W?3|OSe*3omHjttb47#RG02|5f6e$ zObTJ!ml%i%20ylab9U#WUDz$7W@n({nZhq+5~`IO*5Pi07qm053E*;P(4-Kmo@>1; z>;uNw7hc?M3Z*1!=?Nlw%8PRi7>4l#z$>YW4#!KwFcx?T+e^N5I_>#$tusSJ+zSuc p5YZ-MEM*wRg54#bi;K&M^BdjW!v$Q*XjK3J002ovPDHLkV1lLySIGbX literal 0 HcmV?d00001 diff --git a/apps/2047pp/metadata.json b/apps/2047pp/metadata.json new file mode 100644 index 000000000..7c120efec --- /dev/null +++ b/apps/2047pp/metadata.json @@ -0,0 +1,14 @@ +{ "id": "2047pp", + "name": "2047pp", + "shortName":"2047pp", + "icon": "app.png", + "version":"0.01", + "description": "Bangle version of a tile shifting game", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "tags": "game", + "storage": [ + {"name":"2047pp.app.js","url":"2047pp.app.js"}, + {"name":"2047pp.img","url":"app-icon.js","evaluate":true} + ] +} From 0342b131249937c8a692f0a500748d264b3ab05e Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 23 Mar 2022 15:38:16 -0400 Subject: [PATCH 059/253] Support Bangles 1&2 --- apps/2047pp/2047pp.app.js | 31 +++++++++++++++++++++---------- apps/2047pp/README.md | 3 ++- apps/2047pp/metadata.json | 2 +- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/apps/2047pp/2047pp.app.js b/apps/2047pp/2047pp.app.js index b508d8f07..9b2283036 100644 --- a/apps/2047pp/2047pp.app.js +++ b/apps/2047pp/2047pp.app.js @@ -1,15 +1,13 @@ - - class TwoK { constructor() { this.b = Array(4).fill().map(() => Array(4).fill(0)); this.score = 0; this.cmap = {0: "#caa", 2:"#ccc", 4: "#bcc", 8: "#ba6", 16: "#e61", 32: "#d20", 64: "#d00", 128: "#da0", 256: "#ec0", 512: "#dd0"}; } - drawBRect(x1, y1, x2, y2, th, c, cf) { + drawBRect(x1, y1, x2, y2, th, c, cf, fill) { g.setColor(c); for (i=0; i 4) g.setColor(1, 1, 1); else g.setColor(0, 0, 0); g.setFont("Vector", bh*(b>8 ? (b>64 ? (b>512 ? 0.32 : 0.4) : 0.6) : 0.7)); @@ -38,14 +36,14 @@ class TwoK { for (x=2; x>=0; x--) if (this.b[y][x]==0) { for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1]; - this.b[y][3] = 0; moved = true; + this.b[y][3] = 0; } for (x=0; x<3; ++x) if (this.b[y][x]==this.b[y][x+1]) { this.score += 2*this.b[y][x]; this.b[y][x] += this.b[y][x+1]; for (j=x+1; j<3; ++j) this.b[y][j] = this.b[y][j+1]; - this.b[y][3] = 0; moved = true; + this.b[y][3] = 0; } } } @@ -123,7 +121,20 @@ function dragHandler(e) { } } +function swipeHandler() { + +} + +function buttonHandler() { + +} + var twok = new TwoK(); twok.addDigit(); twok.addDigit(); twok.render(); -Bangle.on("drag", dragHandler); +if (process.env.HWVERSION==2) Bangle.on("drag", dragHandler); +else if (process.env.HWVERSION==1) { + Bangle.on("swipe", (e) => { res = twok.shift(e); if (res) twok.addDigit(); twok.render(); }); + setWatch(() => { res = twok.shift(2); if (res) twok.addDigit(); twok.render(); }, BTN1, {repeat: true}); + setWatch(() => { res = twok.shift(-2); if (res) twok.addDigit(); twok.render(); }, BTN3, {repeat: true}); +} diff --git a/apps/2047pp/README.md b/apps/2047pp/README.md index e685946c1..8228892fd 100644 --- a/apps/2047pp/README.md +++ b/apps/2047pp/README.md @@ -3,4 +3,5 @@ Tile shifting game inspired by the well known 2048 game. Also very similar to another Bangle game, Game1024. -Attempt to combine equal numbers by swiping left, right, up or down. +Attempt to combine equal numbers by swiping left, right, up or down (on Bangle 2) or swiping left/right and using +the top/bottom button (Bangle 1). diff --git a/apps/2047pp/metadata.json b/apps/2047pp/metadata.json index 7c120efec..0241e9933 100644 --- a/apps/2047pp/metadata.json +++ b/apps/2047pp/metadata.json @@ -4,7 +4,7 @@ "icon": "app.png", "version":"0.01", "description": "Bangle version of a tile shifting game", - "supports" : ["BANGLEJS2"], + "supports" : ["BANGLEJS1","BANGLEJS2"], "readme": "README.md", "tags": "game", "storage": [ From 0c24bd397aeb82f5d3d1af2794e95942e9039c5f Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 23 Mar 2022 15:40:28 -0400 Subject: [PATCH 060/253] Use correct string for supported devices --- apps/2047pp/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/2047pp/metadata.json b/apps/2047pp/metadata.json index 0241e9933..0a362c583 100644 --- a/apps/2047pp/metadata.json +++ b/apps/2047pp/metadata.json @@ -4,7 +4,7 @@ "icon": "app.png", "version":"0.01", "description": "Bangle version of a tile shifting game", - "supports" : ["BANGLEJS1","BANGLEJS2"], + "supports" : ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "tags": "game", "storage": [ From 60c3a3249459c7219ed28b8b1c8d6b9f7cd98fe8 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Wed, 23 Mar 2022 21:52:26 +0100 Subject: [PATCH 061/253] waypointer Bangle.js 2 compatibility --- apps/waypointer/ChangeLog | 2 ++ apps/waypointer/README.md | 2 +- apps/waypointer/app.js | 55 ++++++++++++++++++----------------- apps/waypointer/metadata.json | 4 +-- 4 files changed, 34 insertions(+), 29 deletions(-) create mode 100644 apps/waypointer/ChangeLog diff --git a/apps/waypointer/ChangeLog b/apps/waypointer/ChangeLog new file mode 100644 index 000000000..1b584f7dd --- /dev/null +++ b/apps/waypointer/ChangeLog @@ -0,0 +1,2 @@ +0.01: New app! +0.02: Make Bangle.js 2 compatible diff --git a/apps/waypointer/README.md b/apps/waypointer/README.md index e98fdbb7e..c0b4c5125 100644 --- a/apps/waypointer/README.md +++ b/apps/waypointer/README.md @@ -24,7 +24,7 @@ need to travel in to reach the selected waypoint. The blue text is the name of the current waypoint. NONE means that there is no waypoint set and so bearing and distance will remain at 0. To select a waypoint, press BTN2 (middle) and wait for the blue text to turn -white. Then use BTN1 and BTN3 to select a waypoint. The waypoint +white. Then use BTN1 and BTN3 (swipe up/down on Bangle.js 2) to select a waypoint. The waypoint choice is fixed by pressing BTN2 again. In the screen shot below a waypoint giving the location of Stone Henge has been selected. diff --git a/apps/waypointer/app.js b/apps/waypointer/app.js index d3aab7c50..615fbbc36 100644 --- a/apps/waypointer/app.js +++ b/apps/waypointer/app.js @@ -1,24 +1,25 @@ -var pal_by = new Uint16Array([0x0000,0xFFC0],0,1); // black, yellow -var pal_bw = new Uint16Array([0x0000,0xffff],0,1); // black, white -var pal_bb = new Uint16Array([0x0000,0x07ff],0,1); // black, blue +const scale = g.getWidth()/240; +var pal_by = new Uint16Array([g.getBgColor(),0xFFC0],0,1); // black, yellow +var pal_bw = new Uint16Array([g.getBgColor(),g.getColor()],0,1); // black, white +var pal_bb = new Uint16Array([g.getBgColor(),0x07ff],0,1); // black, blue // having 3 2 color pallette keeps the memory requirement lower -var buf1 = Graphics.createArrayBuffer(160,160,1, {msb:true}); -var buf2 = Graphics.createArrayBuffer(80,40,1, {msb:true}); +var buf1 = Graphics.createArrayBuffer(160*scale,160*scale,1, {msb:true}); +var buf2 = Graphics.createArrayBuffer(g.getWidth()/3,40*scale,1, {msb:true}); var arrow_img = require("heatshrink").decompress(atob("lEowIPMjAEDngEDvwED/4DCgP/wAEBgf/4AEBg//8AEBh//+AEBj///AEBn///gEBv///wmCAAImCAAIoBFggE/AkaaEABo=")); function flip1(x,y) { - g.drawImage({width:160,height:160,bpp:1,buffer:buf1.buffer, palette:pal_by},x,y); + g.drawImage({width:160*scale,height:160*scale,bpp:1,buffer:buf1.buffer, palette:pal_by},x,y); buf1.clear(); } function flip2_bw(x,y) { - g.drawImage({width:80,height:40,bpp:1,buffer:buf2.buffer, palette:pal_bw},x,y); + g.drawImage({width:g.getWidth()/3,height:40*scale,bpp:1,buffer:buf2.buffer, palette:pal_bw},x,y); buf2.clear(); } function flip2_bb(x,y) { - g.drawImage({width:80,height:40,bpp:1,buffer:buf2.buffer, palette:pal_bb},x,y); + g.drawImage({width:g.getWidth()/3,height:40*scale,bpp:1,buffer:buf2.buffer, palette:pal_bb},x,y); buf2.clear(); } @@ -51,12 +52,12 @@ function drawCompass(course) { previous.course = course; buf1.setColor(1); - buf1.fillCircle(80,80,79,79); + buf1.fillCircle(buf1.getWidth()/2,buf1.getHeight()/2,79*scale); buf1.setColor(0); - buf1.fillCircle(80,80,69,69); + buf1.fillCircle(buf1.getWidth()/2,buf1.getHeight()/2,69*scale); buf1.setColor(1); - buf1.drawImage(arrow_img, 80, 80, {scale:3, rotate:radians(course)} ); - flip1(40, 30); + buf1.drawImage(arrow_img, buf1.getWidth()/2, buf1.getHeight()/2, {scale:3*scale, rotate:radians(course)} ); + flip1(40*scale, Bangle.appRect.y+6*scale); } /***** COMPASS CODE ***********/ @@ -138,7 +139,7 @@ function distance(a,b){ function drawN(){ - buf2.setFont("Vector",24); + buf2.setFont("Vector",24*scale); var bs = wp_bearing.toString(); bs = wp_bearing<10?"00"+bs : wp_bearing<100 ?"0"+bs : bs; var dst = loc.distance(dist); @@ -147,12 +148,12 @@ function drawN(){ // show distance on the left if (previous.dst !== dst) { - previous.dst = dst + previous.dst = dst; buf2.setColor(1); buf2.setFontAlign(-1,-1); - buf2.setFont("Vector", 20); + buf2.setFont("Vector", 20*scale); buf2.drawString(dst,0,0); - flip2_bw(0, 200); + flip2_bw(0, g.getHeight()-40*scale); } // bearing, place in middle at bottom of compass @@ -160,9 +161,9 @@ function drawN(){ previous.bs = bs; buf2.setColor(1); buf2.setFontAlign(0, -1); - buf2.setFont("Vector",38); - buf2.drawString(bs,40,0); - flip2_bw(80, 200); + buf2.setFont("Vector",38*scale); + buf2.drawString(bs,40*scale,0); + flip2_bw(g.getWidth()/3, g.getHeight()-40*scale); } // waypoint name on right @@ -170,13 +171,13 @@ function drawN(){ previous.selected = selected; buf2.setColor(1); buf2.setFontAlign(1,-1); // right, bottom - buf2.setFont("Vector", 20); - buf2.drawString(wp.name, 80, 0); + buf2.setFont("Vector", 20*scale); + buf2.drawString(wp.name, 80*scale, 0); if (selected) - flip2_bw(160, 200); + flip2_bw(g.getWidth()/3*2, g.getHeight()-40*scale); else - flip2_bb(160, 200); + flip2_bb(g.getWidth()/3*2, g.getHeight()-40*scale); } } @@ -229,9 +230,11 @@ function startdraw(){ } function setButtons(){ - setWatch(nextwp.bind(null,-1), BTN1, {repeat:true,edge:"falling"}); - setWatch(doselect, BTN2, {repeat:true,edge:"falling"}); - setWatch(nextwp.bind(null,1), BTN3, {repeat:true,edge:"falling"}); + Bangle.setUI("updown", d=>{ + if (d<0) { nextwp(-1); } + else if (d>0) { nextwp(1); } + else { doselect(); } + }); } Bangle.on('lcdPower',function(on) { diff --git a/apps/waypointer/metadata.json b/apps/waypointer/metadata.json index cb477107b..111259bbc 100644 --- a/apps/waypointer/metadata.json +++ b/apps/waypointer/metadata.json @@ -1,11 +1,11 @@ { "id": "waypointer", "name": "Way Pointer", - "version": "0.01", + "version": "0.02", "description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation", "icon": "waypointer.png", "tags": "tool,outdoors,gps", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "interface": "waypoints.html", "storage": [ From fd8cc60283512c3aa649f525a4d01482af79e531 Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 23 Mar 2022 17:24:42 -0400 Subject: [PATCH 062/253] Make border thicknesses more consistent; add screenshot; allow running in emulator. --- apps/2047pp/2047pp.app.js | 8 ++++---- apps/2047pp/2047pp_screenshot.png | Bin 0 -> 4541 bytes apps/2047pp/README.md | 2 ++ apps/2047pp/metadata.json | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 apps/2047pp/2047pp_screenshot.png diff --git a/apps/2047pp/2047pp.app.js b/apps/2047pp/2047pp.app.js index 9b2283036..58738d04a 100644 --- a/apps/2047pp/2047pp.app.js +++ b/apps/2047pp/2047pp.app.js @@ -18,11 +18,11 @@ class TwoK { bw = Math.floor(w/4); g.clearRect(0, 0, g.getWidth()-1, yo).setFontAlign(0, 0, 0); g.setFont("Vector", 16).setColor("#fff").drawString("Score:"+this.score.toString(), g.getWidth()/2, 8); - this.drawBRect(xo-2, yo-2, xo+w+2, yo+h, 2, "#a88", "#caa", false); + this.drawBRect(xo-3, yo-3, xo+w+2, yo+h+2, 4, "#a88", "#caa", false); for (y=0; y<4; ++y) for (x=0; x<4; ++x) { b = this.b[y][x]; - this.drawBRect(xo+x*bw, yo+y*bh-2, xo+(x+1)*bh, yo+(y+1)*bh-2, 4, "#a88", this.cmap[b], true); + this.drawBRect(xo+x*bw, yo+y*bh-1, xo+(x+1)*bh-1, yo+(y+1)*bh-2, 4, "#a88", this.cmap[b], true); if (b > 4) g.setColor(1, 1, 1); else g.setColor(0, 0, 0); g.setFont("Vector", bh*(b>8 ? (b>64 ? (b>512 ? 0.32 : 0.4) : 0.6) : 0.7)); @@ -35,7 +35,7 @@ class TwoK { for (y=0; y<4; ++y) { for (x=2; x>=0; x--) if (this.b[y][x]==0) { - for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1]; + for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1]; this.b[y][3] = 0; } for (x=0; x<3; ++x) @@ -133,7 +133,7 @@ var twok = new TwoK(); twok.addDigit(); twok.addDigit(); twok.render(); if (process.env.HWVERSION==2) Bangle.on("drag", dragHandler); -else if (process.env.HWVERSION==1) { +if (process.env.HWVERSION==1) { Bangle.on("swipe", (e) => { res = twok.shift(e); if (res) twok.addDigit(); twok.render(); }); setWatch(() => { res = twok.shift(2); if (res) twok.addDigit(); twok.render(); }, BTN1, {repeat: true}); setWatch(() => { res = twok.shift(-2); if (res) twok.addDigit(); twok.render(); }, BTN3, {repeat: true}); diff --git a/apps/2047pp/2047pp_screenshot.png b/apps/2047pp/2047pp_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..8c407fb6fe4b78d2f60c30651c60f8513b5c658d GIT binary patch literal 4541 zcmb7IeLR!v|G)0dHnvO;jF41Ehnc7j<{^iv6cR%7w1%Pxqhd_8IW4K^(L)KTwDOR7 zikP~kA}SAgs>WFdQN%op%J1f!*ZKYN{pb7rW4rHN_x1T)*XMJ6-tW)*Uc94&jXYiz z4*-zgxnrv{a+NN8WUeIRz-D5Dw-l)7IVsiw%R9=Da08V82n~HFK1fT@J?grx`!HyioMg5>d)+R z)=tU^O%<$7YFRznr?2Dctv@_G{IjCxcSTE{HCc+{4)%T>oPTT)G$45L!$t7%MLxUM z$?UZLv8I}-miAbHx__&i2#@BnW$#&?7oSgTZjay$ji z@{!9^I_h)9+xxNlzCh8VFmL%OZaO4+dgngih@*7>ozy>27Z!52DG9&xFqXTm z+We!2wEg|N_nIEDBk8jnM*MMMVU zx~KeGk+_4bkuvp+oi0|ri|bZ|yH7-q_)I1>p40}gQchO;ixw@-lrCqZ%w&b+Z-3g= zI=o)$9Db+!h+y`bYQw~Q{-GHDRk8gF;HA@Mcc!hYtMvYaN1@=Z(9>b)(65tAi!{Lf z#wvx&wqt)D-V9=j?*~ZMA)eRmzqC=Dhx(6!H1LGOE_e4)q2ecQ!D(}I`}czK6iTy# z;ts^>Di*I!hkylZY`_!`3=Fv_oEzXO+%T_5M6Cgt4uTr;+{{e*yT}*q0fG6Vs_&D> zGFL@Td})Zg@KPHvcK9iwfEhU?ZmDi45bdaM=P=L4#Ni{vE#$FF<5(EPxG{Uzu8ukk zmcU?$^{tAQ_YMQl24G~Hpyx4&(Q}@1s=p-gJ^$M3EpZJpDFBm41Cmt(N5w7mo)e0* zW&0T3lVd;ncPD0iSR>kAWEg!`h=;hCjcTVoqRz>%<+~3J0I?8!@^t3|*zA|*VRpKq zPCy{RFl}1a(iWV_wl#bx8Nt5~bn;EXMRH3GSjiYX;7IBF8cEuH493a#$7{;c`Tjz`VP(zrvYANgF03ql9M0W~v4&Z;Pn4Iy zv14v)z(4DPSE{LoENjg+Pe@wo``xKBiTsr3TJruGa!{E{3;F&4?sq@0SKD*&Zj*hM zYmVxR4lMnvX=PK6uhppA8VPLmRM{w~Z`UzqsTs&4lN3XdvcSph>�s2LAZhiWN(X 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 literal 0 HcmV?d00001 diff --git a/apps/2047pp/README.md b/apps/2047pp/README.md index 8228892fd..cac3323a6 100644 --- a/apps/2047pp/README.md +++ b/apps/2047pp/README.md @@ -5,3 +5,5 @@ Tile shifting game inspired by the well known 2048 game. Also very similar to an Attempt to combine equal numbers by swiping left, right, up or down (on Bangle 2) or swiping left/right and using the top/bottom button (Bangle 1). + +![Screenshot](./2047pp_screenshot.png) diff --git a/apps/2047pp/metadata.json b/apps/2047pp/metadata.json index 0a362c583..f0fd6c1e3 100644 --- a/apps/2047pp/metadata.json +++ b/apps/2047pp/metadata.json @@ -5,6 +5,7 @@ "version":"0.01", "description": "Bangle version of a tile shifting game", "supports" : ["BANGLEJS","BANGLEJS2"], + "allow_emulator": true, "readme": "README.md", "tags": "game", "storage": [ From dd27b11eb87b5087e668549ab59b908260c10545 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 24 Mar 2022 09:43:32 +0800 Subject: [PATCH 063/253] Update app.js Fix automatic font sizing. --- apps/authentiwatch/app.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 6e2951b9f..05d94fc46 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -119,15 +119,14 @@ var state = { function sizeFont(id, txt, w) { let sz = fontszCache[id]; - if (sz) { - g.setFont("Vector", sz); - } else { + if (!sz) { sz = TOKEN_DIGITS_HEIGHT; do { g.setFont("Vector", sz--); } while (g.stringWidth(txt) > w); - fontszCache[id] = sz + 1; + fontszCache[id] = ++sz; } + g.setFont("Vector", sz); } tokenY = id => id * TOKEN_HEIGHT + AR.y - state.listy; From ae74a508384a9f92ed3acc7bf776106a251fcd58 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Wed, 23 Mar 2022 22:54:32 +0100 Subject: [PATCH 064/253] [Wave Clock] Show the day of the week --- apps/waveclk/ChangeLog | 1 + apps/waveclk/app.js | 4 ++++ apps/waveclk/metadata.json | 2 +- apps/waveclk/screenshot.png | Bin 2884 -> 6237 bytes 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/waveclk/ChangeLog b/apps/waveclk/ChangeLog index 8c2a33143..f1fb77c59 100644 --- a/apps/waveclk/ChangeLog +++ b/apps/waveclk/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! 0.02: Load widgets after setUI so widclk knows when to hide +0.03: Show the day of the week diff --git a/apps/waveclk/app.js b/apps/waveclk/app.js index f1c67ce2f..18b28500b 100644 --- a/apps/waveclk/app.js +++ b/apps/waveclk/app.js @@ -41,6 +41,7 @@ function draw() { var date = new Date(); var timeStr = require("locale").time(date,1); var dateStr = require("locale").date(date).toUpperCase(); + var dowStr = require("locale").dow(date).toUpperCase(); // draw time g.setFontAlign(0,0).setFont("ZCOOL"); g.drawString(timeStr,x,y); @@ -48,6 +49,9 @@ function draw() { y += 35; g.setFontAlign(0,0,1).setFont("6x8"); g.drawString(dateStr,g.getWidth()-8,g.getHeight()/2); + // draw the day of the week + g.setFontAlign(0,0,3).setFont("6x8"); + g.drawString(dowStr,8,g.getHeight()/2); // queue draw in one minute queueDraw(); } diff --git a/apps/waveclk/metadata.json b/apps/waveclk/metadata.json index a8d270da2..9ba2798ff 100644 --- a/apps/waveclk/metadata.json +++ b/apps/waveclk/metadata.json @@ -1,7 +1,7 @@ { "id": "waveclk", "name": "Wave Clock", - "version": "0.02", + "version": "0.03", "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/)", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], diff --git a/apps/waveclk/screenshot.png b/apps/waveclk/screenshot.png index 7f05ce68880935db0de4aaf840077e9b30413db7..161ef96ef0194e95c23821555e073a21607dfc83 100644 GIT binary patch literal 6237 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 Hu0mjfXH(f- literal 2884 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 iR539+GBi3hI4dwQIxsMs^94u%0000 Date: Thu, 24 Mar 2022 15:52:19 +0000 Subject: [PATCH 065/253] first hack at support for running the App Loader inside Gadgetbridge --- gadgetbridge.js | 162 ++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 1 + 2 files changed, 163 insertions(+) create mode 100644 gadgetbridge.js diff --git a/gadgetbridge.js b/gadgetbridge.js new file mode 100644 index 000000000..679fffc60 --- /dev/null +++ b/gadgetbridge.js @@ -0,0 +1,162 @@ +/* Detects if we're running under Gadgetbridge in a WebView, and if +so it overwrites the 'Puck' library with a special one that calls back +into Gadgetbridge to handle watch communications */ + +/*// test code +Android = { + bangleTx : function(data) { + console.log("TX : "+JSON.stringify(data)); + } +};*/ + +if (typeof Android!=="undefined") { + console.log("Running under Gadgetbridge, overwrite Puck library"); + + var isBusy = false; + var queue = []; + var connection = { + cb : function(data) {}, + write : function(data, writecb) { + Android.bangleTx(data); + Puck.writeProgress(data.length, data.length); + if (writecb) setTimeout(writecb,10); + }, + close : function() {}, + received : "", + hadData : false + } + + function bangleRx(data) { +// document.getElementById("status").innerText = "RX:"+data; + connection.received += data; + connection.hadData = true; + if (connection.cb) connection.cb(data); + } + + function log(level, s) { + if (Puck.log) Puck.log(level, s); + } + + function handleQueue() { + if (!queue.length) return; + var q = queue.shift(); + log(3,"Executing "+JSON.stringify(q)+" from queue"); + if (q.type == "write") Puck.write(q.data, q.callback, q.callbackNewline); + else log(1,"Unknown queue item "+JSON.stringify(q)); + } + + /* convenience function... Write data, call the callback with data: + callbackNewline = false => if no new data received for ~0.2 sec + callbackNewline = true => after a newline */ + function write(data, callback, callbackNewline) { + let result; + /// If there wasn't a callback function, then promisify + if (typeof callback !== 'function') { + callbackNewline = callback; + + result = new Promise((resolve, reject) => callback = (value, err) => { + if (err) reject(err); + else resolve(value); + }); + } + + if (isBusy) { + log(3, "Busy - adding Puck.write to queue"); + queue.push({type:"write", data:data, callback:callback, callbackNewline:callbackNewline}); + return result; + } + + var cbTimeout; + function onWritten() { + if (callbackNewline) { + connection.cb = function(d) { + var newLineIdx = connection.received.indexOf("\n"); + if (newLineIdx>=0) { + var l = connection.received.substr(0,newLineIdx); + connection.received = connection.received.substr(newLineIdx+1); + connection.cb = undefined; + if (cbTimeout) clearTimeout(cbTimeout); + cbTimeout = undefined; + if (callback) + callback(l); + isBusy = false; + handleQueue(); + } + }; + } + // wait for any received data if we have a callback... + var maxTime = 300; // 30 sec - Max time we wait in total, even if getting data + var dataWaitTime = callbackNewline ? 100/*10 sec if waiting for newline*/ : 3/*300ms*/; + var maxDataTime = dataWaitTime; // max time we wait after having received data + cbTimeout = setTimeout(function timeout() { + cbTimeout = undefined; + if (maxTime) maxTime--; + if (maxDataTime) maxDataTime--; + if (connection.hadData) maxDataTime=dataWaitTime; + if (maxDataTime && maxTime) { + cbTimeout = setTimeout(timeout, 100); + } else { + connection.cb = undefined; + if (callback) + callback(connection.received); + isBusy = false; + handleQueue(); + connection.received = ""; + } + connection.hadData = false; + }, 100); + } + + if (!connection.txInProgress) connection.received = ""; + isBusy = true; + connection.write(data, onWritten); + return result + } + + // ---------------------------------------------------------- + + Puck = { + /// Are we writing debug information? 0 is no, 1 is some, 2 is more, 3 is all. + debug : Puck.debug, + /// Should we use flow control? Default is true + flowControl : true, + /// Used internally to write log information - you can replace this with your own function + log : function(level, s) { if (level <= this.debug) console.log(" "+s)}, + /// Called with the current send progress or undefined when done - you can replace this with your own function + writeProgress : Puck.writeProgress, + connect : function(callback) { + setTimeout(callback, 10); + }, + write : write, + eval : function(expr, cb) { + const response = write('\x10Bluetooth.println(JSON.stringify(' + expr + '))\n', true) + .then(function (d) { + try { + return JSON.parse(d); + } catch (e) { + log(1, "Unable to decode " + JSON.stringify(d) + ", got " + e.toString()); + return Promise.reject(d); + } + }); + if (cb) { + return void response.then(cb, (err) => cb(null, err)); + } else { + return response; + } + }, + isConnected : function() { return true; }, + getConnection : function() { return connection; }, + close : function() { + if (connection) + connection.close(); + }, + }; + // no need for header + document.getElementsByTagName("header")[0].style="display:none"; + // force connection attempt automatically + setTimeout(function() { + getInstalledApps(true).catch(err => { + showToast("Device connection failed, "+err,"error"); + }); + }, 100); +} diff --git a/index.html b/index.html index a418b48eb..bd8ddea5a 100644 --- a/index.html +++ b/index.html @@ -179,5 +179,6 @@ + From 0a347ee03166662d5dbed0eb3d7ba292079dd15f Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 24 Mar 2022 16:16:25 +0000 Subject: [PATCH 066/253] boot 0.46: Fix no clock found error on Bangle.js 2 --- apps/boot/ChangeLog | 1 + apps/boot/bootloader.js | 2 +- apps/boot/metadata.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index ef437fe3b..87b5f7def 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -49,3 +49,4 @@ 0.43: Fix Gadgetbridge handling with Programmable:off 0.44: Write .boot0 without ever having it all in RAM (fix Bangle.js 1 issues with BTHRM) 0.45: Fix 0.44 regression (auto-add semi-colon between each boot code chunk) +0.46: Fix no clock found error on Bangle.js 2 diff --git a/apps/boot/bootloader.js b/apps/boot/bootloader.js index 3cf885ac9..45e271f30 100644 --- a/apps/boot/bootloader.js +++ b/apps/boot/bootloader.js @@ -14,6 +14,6 @@ if (!clockApp) { if (clockApp) clockApp = require("Storage").read(clockApp.src); } -if (!clockApp) clockApp=`E.showMessage("No Clock Found");setWatch(()=>{Bangle.showLauncher();}, BTN2, {repeat:false,edge:"falling"});`; +if (!clockApp) clockApp=`E.showMessage("No Clock Found");setWatch(()=>{Bangle.showLauncher();}, global.BTN2||BTN, {repeat:false,edge:"falling"});`; eval(clockApp); delete clockApp; diff --git a/apps/boot/metadata.json b/apps/boot/metadata.json index c21ab6833..11884576f 100644 --- a/apps/boot/metadata.json +++ b/apps/boot/metadata.json @@ -1,7 +1,7 @@ { "id": "boot", "name": "Bootloader", - "version": "0.45", + "version": "0.46", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "icon": "bootloader.png", "type": "bootloader", From 6dbe7dfee1ddc3a661c509fc298b36063f033a28 Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Fri, 25 Mar 2022 00:31:38 +0100 Subject: [PATCH 067/253] Bug: Fixed issue #1609 added a message popup state handler to control unwanted screen redraw --- apps/game1024/app.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/apps/game1024/app.js b/apps/game1024/app.js index 9f6081376..133630634 100644 --- a/apps/game1024/app.js +++ b/apps/game1024/app.js @@ -144,6 +144,13 @@ const buttons = { }, add: function(btn) { this.all.push(btn); + }, + isPopUpActive: false, + activatePopUp: function() { + this.isPopUpActive = true; + }, + deActivatePopUp: function() { + this.isPopUpActive = false; } }; /** @@ -253,7 +260,6 @@ const dragThreshold = 10; const clickThreshold = 3; let allSquares = []; -// let buttons = []; class Button { constructor(name, x0, y0, width, height, text, bg, fg, cb, enabled) { @@ -483,6 +489,7 @@ function initGame() { Bangle.drawWidgets(); } function drawPopUp(message,cb) { + buttons.activatePopUp(); g.setColor('#FFFFFF'); let rDims = Bangle.appRect; g.fillPoly([rDims.x+10, rDims.y+20, @@ -505,6 +512,7 @@ function drawPopUp(message,cb) { g.drawString(message, rDims.x+20, rDims.y+20); buttons.add(btnYes); buttons.add(btnNo); + } function handlePopUpClicks(btn) { const name = btn.name; @@ -512,6 +520,7 @@ function handlePopUpClicks(btn) { buttons.all.pop(); // remove the yes button buttons.all.forEach(b => {b.enable();}); // enable the remaining buttons again debug(() => console.log("Button name =", name)); + buttons.deActivatePopUp(); switch (name) { case 'yes': resetGame(); @@ -568,14 +577,13 @@ function handleclick(e) { // Handle a drag event (moving the stones around) function handledrag(e) { - /*debug(Math.abs(e.dx) > Math.abs(e.dy) ? - (e.dx > 0 ? e => console.log('To the right') : e => console.log('To the left') ) : - (e.dy > 0 ? e => console.log('Move down') : e => console.log('Move up') )); - */ - // [move.right, move.left, move.up, move.down] - runGame((Math.abs(e.dx) > Math.abs(e.dy) ? - (e.dx > 0 ? mover.direction.right : mover.direction.left ) : - (e.dy > 0 ? mover.direction.down : mover.direction.up ))); + // Stop moving things around when the popup message is active + // Bangleapps issue #1609 + if (!(buttons.isPopUpActive)) { + runGame((Math.abs(e.dx) > Math.abs(e.dy) ? + (e.dx > 0 ? mover.direction.right : mover.direction.left ) : + (e.dy > 0 ? mover.direction.down : mover.direction.up ))); + } } // Evaluate "drag" events from the UI and call handlers for drags or clicks // The UI sends a drag as a series of events indicating partial movements From a46051a88ec208a12edf48cf4ee7a3a2824a1dfc Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Fri, 25 Mar 2022 00:38:17 +0100 Subject: [PATCH 068/253] v0.06 added to metadata and changelog --- apps/game1024/ChangeLog | 3 ++- apps/game1024/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/game1024/ChangeLog b/apps/game1024/ChangeLog index ffb1f94bc..8759fb428 100644 --- a/apps/game1024/ChangeLog +++ b/apps/game1024/ChangeLog @@ -2,4 +2,5 @@ 0.02: Temporary intermediate version 0.03: Basic colors 0.04: Bug fix score reset after Game Over, new icon -0.05: Chevron marker on the randomly added square \ No newline at end of file +0.05: Chevron marker on the randomly added square +0.06: Fixed issue 1609 added a message popup state handler to control unwanted screen redraw \ No newline at end of file diff --git a/apps/game1024/metadata.json b/apps/game1024/metadata.json index 557d77b89..73d7607f3 100644 --- a/apps/game1024/metadata.json +++ b/apps/game1024/metadata.json @@ -1,7 +1,7 @@ { "id": "game1024", "name": "1024 Game", "shortName" : "1024 Game", - "version": "0.05", + "version": "0.06", "icon": "game1024.png", "screenshots": [ {"url":"screenshot.png" } ], "readme":"README.md", From f8d64ab7dd51ce9e391b27001b364226d2021f94 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:19:24 -0500 Subject: [PATCH 069/253] Create app.js --- apps/gsat/app.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 apps/gsat/app.js diff --git a/apps/gsat/app.js b/apps/gsat/app.js new file mode 100644 index 000000000..3a7d443fe --- /dev/null +++ b/apps/gsat/app.js @@ -0,0 +1,38 @@ +// Clear screen +g.clear(); + +const secsinmin = 60; +const quickfixperiod = 900; +var seconds = 1200; + +function countSecs() { + if (seconds != 0) {seconds -=1;} + console.log(seconds); +} +function drawTime() { + g.clear(); + g.setFontAlign(0,0); + g.setFont('Vector', 12); + g.drawString('Geek Squad Appointment Timer', 125, 20); + if (seconds == 0) { + g.setFont('Vector', 35); + g.drawString('Appointment', 125, 100); + g.drawString('finished!', 125, 150); + Bangle.buzz(); + return; + } + min = seconds / secsinmin; + if (seconds < quickfixperiod) { + g.setFont('Vector', 20); + g.drawString('Quick Fix', 125, 50); + g.drawString('Period Passed!', 125, 75); + } + g.setFont('Vector', 50); + g.drawString(Math.ceil(min), 125, 125); + g.setFont('Vector', 25); + g.drawString('minutes', 125, 165); + g.drawString('remaining', 125, 195); +} +drawTime(); +setInterval(countSecs, 1000); +setInterval(drawTime, 60000); From 840cecf976d2444edcae2c7466fc8a3c798594c3 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:22:45 -0500 Subject: [PATCH 070/253] Create metadata.json --- apps/gsat/metadata.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 apps/gsat/metadata.json diff --git a/apps/gsat/metadata.json b/apps/gsat/metadata.json new file mode 100644 index 000000000..cda1f7096 --- /dev/null +++ b/apps/gsat/metadata.json @@ -0,0 +1,14 @@ +{ + "id": "gsat", + "name": "Geek Squad Appointment Timer", + "shortName": "gsat", + "version": "0.01", + "description": "Starts a 20 minute timer for appointments at Geek Squad.", + "icon": "app.png", + "tags": "tool", + "readme": "README.md", + "supports": ["BANGLEJS"], + "storage": [ + {"name":"gsat.app.js","url":"app.js"}, + ] +} From 027048302aa4ba67c68d7bffd1f4960048f2e687 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:23:20 -0500 Subject: [PATCH 071/253] Add app png --- apps/gsat/icons8-clock-48.png | Bin 0 -> 929 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/gsat/icons8-clock-48.png diff --git a/apps/gsat/icons8-clock-48.png b/apps/gsat/icons8-clock-48.png new file mode 100644 index 0000000000000000000000000000000000000000..cf057046be6eca51564a213bc3e7307271464009 GIT binary patch literal 929 zcmV;S177@zP)hL^4Q9~j~`7LX9JB(!Q` zf!g{&{RcFW&Q~mny+EQd5wRkG(GU|*v#i00#krWf=gz{s+-Te{nPTqF`ObG{=bo84 z7wV|v|Hht3JPkk}FaUG|9Y7m!Ao=|p@Bx?yW`SwoCGazne{UQEt^-TJmSbB2t^w^e zR}HiRcY*JgVs~m~;0|!8R^p4mY6RiBtpaENr0^Uv>(vCT0r!Cspcg0r`;t~jo{azx zfb|`CCKF##(F8oL;_xjnl#FrV8%ADg6Xz30z8#UnEWQMc5jI;nU_9Z{{Eq{QD8L7t!&STXpy9ZFm@kj^1Fem7{l-O!eBYr8>b)d^b3W}9W~#A6U*g95Oi>^=c4 z)~Zv`8K;EXvhfK3pp)!7am&FTkR7(HNX8sFd;lS+^%_N}!U1DH{Ly|K9>B#6_hueBM`PvzgXPMrIx>vGBiU)6Z4 zEpn3sb9fkCLB-z-YcKpmwJ#|r9RWl zC5~dFfRx^~zcZo4lLpcS%$dU%U1Vo|3%C)3JcraOHF*iC9^?bK^S~v{rNu|U-T>|j zG$FN0?PUAC7)9=|wrEE3yiS#A@zILA+sGlcN|VDaIFIb+1>`8+h@2|>kwB-& z?yx%JM4NdN29eBAO@MFvNQ4*G7A;7*Pj7ZUZ3CJ0gS8T$MjKKwTeK9b&o&dl(GUSK zKeKitb( Date: Thu, 24 Mar 2022 20:23:55 -0500 Subject: [PATCH 072/253] Delete icons8-clock-48.png --- apps/gsat/icons8-clock-48.png | Bin 929 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/gsat/icons8-clock-48.png diff --git a/apps/gsat/icons8-clock-48.png b/apps/gsat/icons8-clock-48.png deleted file mode 100644 index cf057046be6eca51564a213bc3e7307271464009..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 929 zcmV;S177@zP)hL^4Q9~j~`7LX9JB(!Q` zf!g{&{RcFW&Q~mny+EQd5wRkG(GU|*v#i00#krWf=gz{s+-Te{nPTqF`ObG{=bo84 z7wV|v|Hht3JPkk}FaUG|9Y7m!Ao=|p@Bx?yW`SwoCGazne{UQEt^-TJmSbB2t^w^e zR}HiRcY*JgVs~m~;0|!8R^p4mY6RiBtpaENr0^Uv>(vCT0r!Cspcg0r`;t~jo{azx zfb|`CCKF##(F8oL;_xjnl#FrV8%ADg6Xz30z8#UnEWQMc5jI;nU_9Z{{Eq{QD8L7t!&STXpy9ZFm@kj^1Fem7{l-O!eBYr8>b)d^b3W}9W~#A6U*g95Oi>^=c4 z)~Zv`8K;EXvhfK3pp)!7am&FTkR7(HNX8sFd;lS+^%_N}!U1DH{Ly|K9>B#6_hueBM`PvzgXPMrIx>vGBiU)6Z4 zEpn3sb9fkCLB-z-YcKpmwJ#|r9RWl zC5~dFfRx^~zcZo4lLpcS%$dU%U1Vo|3%C)3JcraOHF*iC9^?bK^S~v{rNu|U-T>|j zG$FN0?PUAC7)9=|wrEE3yiS#A@zILA+sGlcN|VDaIFIb+1>`8+h@2|>kwB-& z?yx%JM4NdN29eBAO@MFvNQ4*G7A;7*Pj7ZUZ3CJ0gS8T$MjKKwTeK9b&o&dl(GUSK zKeKitb( Date: Thu, 24 Mar 2022 20:24:22 -0500 Subject: [PATCH 073/253] Add files via upload --- apps/gsat/app.png | Bin 0 -> 929 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/gsat/app.png diff --git a/apps/gsat/app.png b/apps/gsat/app.png new file mode 100644 index 0000000000000000000000000000000000000000..cf057046be6eca51564a213bc3e7307271464009 GIT binary patch literal 929 zcmV;S177@zP)hL^4Q9~j~`7LX9JB(!Q` zf!g{&{RcFW&Q~mny+EQd5wRkG(GU|*v#i00#krWf=gz{s+-Te{nPTqF`ObG{=bo84 z7wV|v|Hht3JPkk}FaUG|9Y7m!Ao=|p@Bx?yW`SwoCGazne{UQEt^-TJmSbB2t^w^e zR}HiRcY*JgVs~m~;0|!8R^p4mY6RiBtpaENr0^Uv>(vCT0r!Cspcg0r`;t~jo{azx zfb|`CCKF##(F8oL;_xjnl#FrV8%ADg6Xz30z8#UnEWQMc5jI;nU_9Z{{Eq{QD8L7t!&STXpy9ZFm@kj^1Fem7{l-O!eBYr8>b)d^b3W}9W~#A6U*g95Oi>^=c4 z)~Zv`8K;EXvhfK3pp)!7am&FTkR7(HNX8sFd;lS+^%_N}!U1DH{Ly|K9>B#6_hueBM`PvzgXPMrIx>vGBiU)6Z4 zEpn3sb9fkCLB-z-YcKpmwJ#|r9RWl zC5~dFfRx^~zcZo4lLpcS%$dU%U1Vo|3%C)3JcraOHF*iC9^?bK^S~v{rNu|U-T>|j zG$FN0?PUAC7)9=|wrEE3yiS#A@zILA+sGlcN|VDaIFIb+1>`8+h@2|>kwB-& z?yx%JM4NdN29eBAO@MFvNQ4*G7A;7*Pj7ZUZ3CJ0gS8T$MjKKwTeK9b&o&dl(GUSK zKeKitb( Date: Thu, 24 Mar 2022 20:25:34 -0500 Subject: [PATCH 074/253] Create README.md --- apps/gsat/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 apps/gsat/README.md diff --git a/apps/gsat/README.md b/apps/gsat/README.md new file mode 100644 index 000000000..faf986947 --- /dev/null +++ b/apps/gsat/README.md @@ -0,0 +1,3 @@ +# Geek Squad Appointment Timer + +An app dedicated to setting a 20 minute timer for Geek Squad Appointments. From b0f530107d33d849fe0f83b2e7fc0a0e9e7d11bf Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:26:21 -0500 Subject: [PATCH 075/253] Create ChangeLog --- apps/gsat/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/gsat/ChangeLog diff --git a/apps/gsat/ChangeLog b/apps/gsat/ChangeLog new file mode 100644 index 000000000..48156d0d4 --- /dev/null +++ b/apps/gsat/ChangeLog @@ -0,0 +1 @@ +0.01: Added Source Code From 62b2d94e9363257c5c321ae7aa80da8c7dc62034 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:27:52 -0500 Subject: [PATCH 076/253] Update metadata.json --- apps/gsat/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/gsat/metadata.json b/apps/gsat/metadata.json index cda1f7096..678e1eb19 100644 --- a/apps/gsat/metadata.json +++ b/apps/gsat/metadata.json @@ -9,6 +9,6 @@ "readme": "README.md", "supports": ["BANGLEJS"], "storage": [ - {"name":"gsat.app.js","url":"app.js"}, + {"name":"gsat.app.js","url":"app.js"} ] } From 8f3f229c5519812dbc0ccd2c7e0e9b6ab411d006 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:31:26 -0500 Subject: [PATCH 077/253] Create app-icon.js --- apps/gsat/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/gsat/app-icon.js diff --git a/apps/gsat/app-icon.js b/apps/gsat/app-icon.js new file mode 100644 index 000000000..06f93e2ef --- /dev/null +++ b/apps/gsat/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwIdah/wAof//4ECgYFB4AFBg4FB8AFBj/wh/4AoM/wEB/gFBvwCEBAU/AQP4gfAj8AgPwAoMPwED8AFBg/AAYIBDA4ngg4TB4EBApkPKgJSBJQIFTMgIFCJIIFDKoIFEvgFBGoMAnw7DP4IFEh+BAoItBg+DNIQwBMIaeCKoKxCPoIzCEgKVHUIqtFXIrFFaIrdFdIwAV")) From b50f0d7a565994688ced0d52b1ecb64b249e19a9 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:31:55 -0500 Subject: [PATCH 078/253] Update metadata.json --- apps/gsat/metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/gsat/metadata.json b/apps/gsat/metadata.json index 678e1eb19..0e81c0513 100644 --- a/apps/gsat/metadata.json +++ b/apps/gsat/metadata.json @@ -9,6 +9,7 @@ "readme": "README.md", "supports": ["BANGLEJS"], "storage": [ - {"name":"gsat.app.js","url":"app.js"} + {"name":"gsat.app.js","url":"app.js"}, + {"name":"gsat.img","url":"app-icon.js","evaluate":true} ] } From 9af8213b92312c846ce4e521c51af803f280c2f0 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:38:20 -0500 Subject: [PATCH 079/253] Update README.md --- apps/gsat/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/gsat/README.md b/apps/gsat/README.md index faf986947..17880e287 100644 --- a/apps/gsat/README.md +++ b/apps/gsat/README.md @@ -1,3 +1,4 @@ # Geek Squad Appointment Timer An app dedicated to setting a 20 minute timer for Geek Squad Appointments. +![screenshot](https://user-images.githubusercontent.com/37220586/160037582-71b46f82-aa7c-47cf-a42a-5e4bb72705c4.png) From e7ee68d5642d6b8c0a7d06406328f2a8350eab2b Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:42:15 -0500 Subject: [PATCH 080/253] Update README.md --- apps/gsat/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/gsat/README.md b/apps/gsat/README.md index 17880e287..faf986947 100644 --- a/apps/gsat/README.md +++ b/apps/gsat/README.md @@ -1,4 +1,3 @@ # Geek Squad Appointment Timer An app dedicated to setting a 20 minute timer for Geek Squad Appointments. -![screenshot](https://user-images.githubusercontent.com/37220586/160037582-71b46f82-aa7c-47cf-a42a-5e4bb72705c4.png) From 451ecd7226339b676f954588703502a7617f9af2 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:42:36 -0500 Subject: [PATCH 081/253] Add files via upload --- apps/gsat/screenshot.png | Bin 0 -> 4250 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/gsat/screenshot.png diff --git a/apps/gsat/screenshot.png b/apps/gsat/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..032319bf674745ec454e9a16645aff39ba44d93f GIT binary patch literal 4250 zcmcgvc{r478-E)~$w2&EzMl74fA{bH-S>0P0&XZQC?N;{ zfUvRA2`d1Av~u1z8zG#QnA@-6oX;k-(P<0-h`i#y>tcTvkpzG(rp709t*_&z`kJD8 z%69O#xyNl_t>lp(3yAN__-LTUcZ+h}gV;{Iau3jbS2QX0+ea36#((DNnuGa5FgKP+ z2P*0QM-y8|!WgH866_izTAn*eFOcL?;!tee1kW$xT8BZ01q;v=S5-2(}=@ewRv$;=v0KZ2D~A!%RFGL^F6+@|D|6D zem7(SJzeUzJh(nFrTZl^%|`uLACy5Vp;hTl4=Y+aJ#SLc1g>FNF0PJ8nmtO=Jt zWd&R_(&PQ-VlYY(+C3w`nEg5IsJ@tdRkfg1w7bH2qVqgUDx1k#aJbE!@<{jz|9l;A z&R7yS_7L8vV_Kf#87gC0Y&9P~8TDw2x-#AtTcW|DG*qb$kjklhN4oN<OouWH0!;mRvv?SfSej4$9MND)~YZwD#&Y3`y@ELnL zhX58Q%??it&zC`8tm9#r{@H0914*R7Govzr+R3E}DswlW&eWql{%}q2 ztGM~njV1@TTeDStA;60?DV}>5Xqm{AyK*&4C^P?j@ySp&lH&EA z_y#$oLszg0wGA%vRdb0N9Ss4wdfjrQ$S*ZnvodT~g38T(f@z?C!AoQqUx$CB*pB7( zzcBOH^St3@ML~qt%RRJtra*k?UTd{dSlmot1ep2l>;)r$K3A*sV&B++(D};(iaVN` zZiD7NDD5F#JFl3_|#s@?rM#qn%BBBkMVnGOouFlZRkLf%hho^p6JgJdL3 zdD~@OKFHXumoE+i_+z$>PG_E^*Z3ZIf}3`^K7Q;-!xorg09)KCd5_&)5X?Aqfqm!G+x%S34wt)F-Ovw+nasXq-p)7*aZFV23>#r9p_pJ7 z`j#L$?4(*!vjt!0az3?Z2H}2nA!8=1Y{1-N@Jieh-X1Sn8Qq9eF`3Bn>(tT0 z%@g)a=hPf;zE;W*yXE+I`1C#8`~JRdt&I1ZfSdF+t_s_kioNgVGy;jM0aMR0S3C+j zMGq;0T#Py-93$7X`H00DzWilYl$jc6jWtLFf_HCUWaqaW+7BA~7)JLG8u$zaCmBPU zFFn5RG62 zsCVu=p4k;Q#G^)s@mUP<%vSQyc|<-$lMpR;oR5RL0&glv5FmwYK}>IszxqMu$Nkj9CJ zL_w?uF8H`yiRU}hS0@LaK{2*-!q5F)@}#uaC4)}45KoT*86$86X%I(<2w0D-EWBdk zDS1LM~N$;SCO2`rO(TmvMqNsXc`gHPupnIMzJ+ zpBj@(#pMrHgv&56i<6UbxXH|r8R9jygZCs9lrHb|+p*d=9~-U6-YnsM&O4^ew( zlgbr|T@MmU8@)g!g5W3JhSvFYU+}|^^&tqy3a;4D*gdLxZd2~z0A5Dnh9V$@nVZYT zJ`caPuZkCNCj0pZuPIIMOb@O;4Z;NIwWayo7*C%y1UI6KGSY&pmBD2H$d@;p_D^u_ hYr6cOT2SsQkk>x|=EPt9I9VS6jP>Csa*v~K{RJk1|9$`f literal 0 HcmV?d00001 From 9eff57362b1ff350b4bb320ae2f406c8c887ab76 Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:43:08 -0500 Subject: [PATCH 082/253] Update metadata.json --- apps/gsat/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/gsat/metadata.json b/apps/gsat/metadata.json index 0e81c0513..bdc8fee32 100644 --- a/apps/gsat/metadata.json +++ b/apps/gsat/metadata.json @@ -8,6 +8,7 @@ "tags": "tool", "readme": "README.md", "supports": ["BANGLEJS"], + "screenshots": [{"url":"screenshot.png"}] "storage": [ {"name":"gsat.app.js","url":"app.js"}, {"name":"gsat.img","url":"app-icon.js","evaluate":true} From db88e1800d1dec7d707d5a72697bc85d214ec4eb Mon Sep 17 00:00:00 2001 From: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:44:12 -0500 Subject: [PATCH 083/253] Update metadata.json --- apps/gsat/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/gsat/metadata.json b/apps/gsat/metadata.json index bdc8fee32..878d213e4 100644 --- a/apps/gsat/metadata.json +++ b/apps/gsat/metadata.json @@ -8,7 +8,7 @@ "tags": "tool", "readme": "README.md", "supports": ["BANGLEJS"], - "screenshots": [{"url":"screenshot.png"}] + "screenshots": [{"url":"screenshot.png"}], "storage": [ {"name":"gsat.app.js","url":"app.js"}, {"name":"gsat.img","url":"app-icon.js","evaluate":true} From 9a0c31c56d41912074ba41ca034baeb7cdf17b12 Mon Sep 17 00:00:00 2001 From: Salim Blume Date: Thu, 24 Mar 2022 22:19:11 -0500 Subject: [PATCH 084/253] Fix run notifications bugs and improve accuracy --- apps/recorder/ChangeLog | 1 + apps/recorder/metadata.json | 2 +- apps/recorder/widget.js | 3 +-- apps/run/ChangeLog | 1 + apps/run/app.js | 4 ++-- apps/run/metadata.json | 2 +- apps/run/settings.js | 12 ++++++------ modules/exstats.js | 12 +++++++----- 8 files changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/recorder/ChangeLog b/apps/recorder/ChangeLog index 90937e160..e9877808c 100644 --- a/apps/recorder/ChangeLog +++ b/apps/recorder/ChangeLog @@ -17,3 +17,4 @@ 0.11: Fix KML and GPX export when there is no GPS data 0.12: Fix 'Back' label positioning on track/graph display, make translateable 0.13: Fix for when widget is used before app +0.14: Remove unneeded variable assignment \ No newline at end of file diff --git a/apps/recorder/metadata.json b/apps/recorder/metadata.json index e2400603d..d715af38d 100644 --- a/apps/recorder/metadata.json +++ b/apps/recorder/metadata.json @@ -2,7 +2,7 @@ "id": "recorder", "name": "Recorder", "shortName": "Recorder", - "version": "0.13", + "version": "0.14", "description": "Record GPS position, heart rate and more in the background, then download to your PC.", "icon": "app.png", "tags": "tool,outdoors,gps,widget", diff --git a/apps/recorder/widget.js b/apps/recorder/widget.js index 221bc6c1a..4a105754b 100644 --- a/apps/recorder/widget.js +++ b/apps/recorder/widget.js @@ -248,7 +248,7 @@ } var buttons={Yes:"yes",No:"no"}; if (newFileName) buttons["New"] = "new"; - var prompt = E.showPrompt("Overwrite\nLog " + settings.file.match(/\d+/)[0] + "?",{title:"Recorder",buttons:buttons}).then(selection=>{ + return E.showPrompt("Overwrite\nLog " + settings.file.match(/\d+/)[0] + "?",{title:"Recorder",buttons:buttons}).then(selection=>{ if (selection==="no") return false; // just cancel if (selection==="yes") { require("Storage").open(settings.file,"r").erase(); @@ -259,7 +259,6 @@ } return WIDGETS["recorder"].setRecording(1); }); - return prompt; } settings.recording = isOn; updateSettings(settings); diff --git a/apps/run/ChangeLog b/apps/run/ChangeLog index 401a68de9..46fdb7e7e 100644 --- a/apps/run/ChangeLog +++ b/apps/run/ChangeLog @@ -9,3 +9,4 @@ 0.08: Added support for notifications from exstats. Support all stats from exstats 0.09: Fix broken start/stop if recording not enabled (fix #1561) 0.10: Don't allow the same setting to be chosen for 2 boxes (fix #1578) +0.11: Notifications fixes \ No newline at end of file diff --git a/apps/run/app.js b/apps/run/app.js index d066c8b1f..fb8158e58 100644 --- a/apps/run/app.js +++ b/apps/run/app.js @@ -59,7 +59,7 @@ function onStartStop() { layout.render(); }) ); - } else { + } else if (!settings.record && WIDGETS["recorder"]) { prepPromises.push( WIDGETS["recorder"].setRecording(false) ); @@ -124,7 +124,7 @@ function configureNotification(stat) { } Object.keys(settings.notify).forEach((statType) => { - if (settings.notify[statType].increment > 0) { + if (settings.notify[statType].increment > 0 && exs.stats[statType]) { configureNotification(exs.stats[statType]); } }); diff --git a/apps/run/metadata.json b/apps/run/metadata.json index 51239d297..09e5a3bed 100644 --- a/apps/run/metadata.json +++ b/apps/run/metadata.json @@ -1,6 +1,6 @@ { "id": "run", "name": "Run", - "version":"0.10", + "version":"0.11", "description": "Displays distance, time, steps, cadence, pace and more for runners.", "icon": "app.png", "tags": "run,running,fitness,outdoors,gps", diff --git a/apps/run/settings.js b/apps/run/settings.js index 949f7a235..6a7d169c4 100644 --- a/apps/run/settings.js +++ b/apps/run/settings.js @@ -90,8 +90,8 @@ [[300, 1],[300, 0],[300, 1],[300, 0],[300, 1]], ]; notificationsMenu[/*LANG*/"Dist Pattern"] = { - value: Math.max(0,vibPatterns.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.dist.notifications))), - min: 0, max: vibPatterns.length, + value: Math.max(0,vibTimes.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.dist.notifications))), + min: 0, max: vibTimes.length, format: v => vibPatterns[v]||/*LANG*/"Off", onchange: v => { settings.notify.dist.notifications = vibTimes[v]; @@ -100,8 +100,8 @@ } } notificationsMenu[/*LANG*/"Step Pattern"] = { - value: Math.max(0,vibPatterns.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.step.notifications))), - min: 0, max: vibPatterns.length, + value: Math.max(0,vibTimes.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.step.notifications))), + min: 0, max: vibTimes.length, format: v => vibPatterns[v]||/*LANG*/"Off", onchange: v => { settings.notify.step.notifications = vibTimes[v]; @@ -110,8 +110,8 @@ } } notificationsMenu[/*LANG*/"Time Pattern"] = { - value: Math.max(0,vibPatterns.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.time.notifications))), - min: 0, max: vibPatterns.length, + value: Math.max(0,vibTimes.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.time.notifications))), + min: 0, max: vibTimes.length, format: v => vibPatterns[v]||/*LANG*/"Off", onchange: v => { settings.notify.time.notifications = vibTimes[v]; diff --git a/modules/exstats.js b/modules/exstats.js index b106622d0..ec0a838a7 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -139,9 +139,9 @@ Bangle.on("GPS", function(fix) { if (stats["pacea"]) stats["pacea"].emit("changed",stats["pacea"]); if (stats["pacec"]) stats["pacec"].emit("changed",stats["pacec"]); if (stats["speed"]) stats["speed"].emit("changed",stats["speed"]); - if (state.notify.dist.increment > 0 && state.notify.dist.next <= stats["dist"]) { + if (state.notify.dist.increment > 0 && state.notify.dist.next <= state.distance) { stats["dist"].emit("notify",stats["dist"]); - state.notify.dist.next = stats["dist"] + state.notify.dist.increment; + state.notify.dist.next = state.notify.dist.next + state.notify.dist.increment; } }); @@ -152,7 +152,7 @@ Bangle.on("step", function(steps) { state.lastStepCount = steps; if (state.notify.step.increment > 0 && state.notify.step.next <= steps) { stats["step"].emit("notify",stats["step"]); - state.notify.step.next = steps + state.notify.step.increment; + state.notify.step.next = state.notify.step.next + state.notify.step.increment; } }); Bangle.on("HRM", function(h) { @@ -285,7 +285,7 @@ exports.getStats = function(statIDs, options) { } if (state.notify.time.increment > 0 && state.notify.time.next <= now) { stats["time"].emit("notify",stats["time"]); - state.notify.time.next = now + state.notify.time.increment; + state.notify.time.next = state.notify.time.next + state.notify.time.increment; } }, 1000); function reset() { @@ -299,6 +299,8 @@ exports.getStats = function(statIDs, options) { state.curSpeed = 0; state.BPM = 0; state.BPMage = 0; + state.thisGPS = {}; + state.lastGPS = {}; state.notify = options.notify; if (options.notify.dist.increment > 0) { state.notify.dist.next = state.distance + options.notify.dist.increment; @@ -338,7 +340,7 @@ exports.appendMenuItems = function(menu, settings, saveSettings) { } exports.appendNotifyMenuItems = function(menu, settings, saveSettings) { var distNames = ['Off', "1000m","1 mile","1/2 Mthn", "Marathon",]; - var distAmts = [0, 1000,1609,21098,42195]; + var distAmts = [0, 1000, 1609, 21098, 42195]; menu['Ntfy Dist'] = { min: 0, max: distNames.length-1, value: Math.max(distAmts.indexOf(settings.notify.dist.increment),0), From 5e5ba0cc69b97835c535e578415cc993e7a4687a Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Fri, 25 Mar 2022 19:01:34 +0100 Subject: [PATCH 085/253] calendar: Add one to previous month --- apps/calendar/ChangeLog | 1 + apps/calendar/calendar.js | 2 +- apps/calendar/metadata.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/calendar/ChangeLog b/apps/calendar/ChangeLog index beba4ed95..cc8bb6306 100644 --- a/apps/calendar/ChangeLog +++ b/apps/calendar/ChangeLog @@ -4,3 +4,4 @@ 0.04: Add setting to switch color schemes. On Bangle 2 non-dithering colors will be used by default. Use localized names for months and days of the week (Language app needed). 0.05: Update calendar weekend colors for start on Sunday 0.06: Use larger font for dates +0.07: Fix off-by-one-error on previous month diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js index 62702e349..3f4315811 100644 --- a/apps/calendar/calendar.js +++ b/apps/calendar/calendar.js @@ -171,7 +171,7 @@ function drawCalendar(date) { let days = []; let nextMonthDay = 1; let thisMonthDay = 51; - let prevMonthDay = monthMaxDayMap[month > 0 ? month - 1 : 11] - dowNorm; + let prevMonthDay = monthMaxDayMap[month > 0 ? month - 1 : 11] - dowNorm + 1; for (let i = 0; i < colN * (rowN - 1) + 1; i++) { if (i < dowNorm) { days.push(prevMonthDay); diff --git a/apps/calendar/metadata.json b/apps/calendar/metadata.json index 5531c03c3..62d2513ae 100644 --- a/apps/calendar/metadata.json +++ b/apps/calendar/metadata.json @@ -1,7 +1,7 @@ { "id": "calendar", "name": "Calendar", - "version": "0.06", + "version": "0.07", "description": "Simple calendar", "icon": "calendar.png", "screenshots": [{"url":"screenshot_calendar.png"}], From 80f8b727d9bbcc0b8e6c29b519860f06bc15f38d Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 17:56:26 -0700 Subject: [PATCH 086/253] Create boot.js --- apps/quicklaunch/boot.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 apps/quicklaunch/boot.js diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js new file mode 100644 index 000000000..f7fded6df --- /dev/null +++ b/apps/quicklaunch/boot.js @@ -0,0 +1,11 @@ +(function() { + var sui = Bangle.setUI; + Bangle.setUI = function(mode, cb) { + sui(mode,cb); + if(!mode) return; + if ("object"==typeof mode) mode = mode.mode; + if (!mode.startsWith("clock")) return; + Bangle.swipeHandler = dir => { if (dir<0) Bangle.showLauncher(); }; + Bangle.on("swipe", Bangle.swipeHandler); + }; +})(); From 65f81fbde963bcfb51777cb4291de97c825fb477 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:07:44 -0700 Subject: [PATCH 087/253] Create app-icon.js --- apps/quicklaunch/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/quicklaunch/app-icon.js diff --git a/apps/quicklaunch/app-icon.js b/apps/quicklaunch/app-icon.js new file mode 100644 index 000000000..659d0d925 --- /dev/null +++ b/apps/quicklaunch/app-icon.js @@ -0,0 +1 @@ +E.toArrayBuffer(atob("AAAAAAAHAAAAH8AACDBgwBAnMGA/7b/wP+if8BBokGAIKLDAACigAAAIgAAACPgAAAjIAAAIjgAACA+AAHgIgADIAPAAiADYAIAAiADAAAgAQAAIAEAACABAAAgAYAAYACAAGAAwABAAEAAQABgAMAAMACAAB//gAAP/wAAAAAA=")) From a20a159dc97a16cd1cc1a365b345c50e3b7687f3 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:10:55 -0700 Subject: [PATCH 088/253] Create metadata.json --- apps/quicklaunch/metadata.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 apps/quicklaunch/metadata.json diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json new file mode 100644 index 000000000..8c624a6d3 --- /dev/null +++ b/apps/quicklaunch/metadata.json @@ -0,0 +1,12 @@ +{ "id": "quicklaunch", + "name": "Quick Launch", + "shortName":"Quick Launch", + "icon": "app.png", + "version":"0.01", + "description": "", + "tags": "", + "storage": [ + {"name":"quicklaunch.app.js","url":"quicklaunch.js"}, + {"name":"quicklaunch.img","url":"app-icon.js","evaluate":true} + ] +} From fbf762a825e61de868b5947b0189da8bd4a77cfd Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:15:27 -0700 Subject: [PATCH 089/253] Update metadata.json --- apps/quicklaunch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index 8c624a6d3..6a001dc56 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -6,7 +6,7 @@ "description": "", "tags": "", "storage": [ - {"name":"quicklaunch.app.js","url":"quicklaunch.js"}, + {"name":"quicklaunch.app.js","url":"app.js"}, {"name":"quicklaunch.img","url":"app-icon.js","evaluate":true} ] } From 34b99993d73aa6ec2c7f136fe31881912bdc463b Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:16:08 -0700 Subject: [PATCH 090/253] Update metadata.json --- apps/quicklaunch/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index 6a001dc56..dd58c6408 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -7,6 +7,7 @@ "tags": "", "storage": [ {"name":"quicklaunch.app.js","url":"app.js"}, + {"name":"quicklaunch.boot.js","url":"boot.js"}, {"name":"quicklaunch.img","url":"app-icon.js","evaluate":true} ] } From e1d6505b240e17aecb9198eb887881db4ad5ad51 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:22:57 -0700 Subject: [PATCH 091/253] Update metadata.json --- apps/quicklaunch/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index dd58c6408..a08e75ed9 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -1,13 +1,14 @@ { "id": "quicklaunch", "name": "Quick Launch", - "shortName":"Quick Launch", "icon": "app.png", "version":"0.01", "description": "", - "tags": "", + "tags": "tools, system", + "supports": ["BANGLEJS2"], "storage": [ {"name":"quicklaunch.app.js","url":"app.js"}, {"name":"quicklaunch.boot.js","url":"boot.js"}, {"name":"quicklaunch.img","url":"app-icon.js","evaluate":true} + ] } From fca2852e8896f4b39aeb723036fa286c92e01130 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:24:48 -0700 Subject: [PATCH 092/253] Create app.js --- apps/quicklaunch/app.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 apps/quicklaunch/app.js diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js new file mode 100644 index 000000000..ae684f005 --- /dev/null +++ b/apps/quicklaunch/app.js @@ -0,0 +1,26 @@ +var s = require("Storage"); +let settings = Object.assign({ showClocks: true }, s.readJSON("launch.json", true) || {}); + +var apps = s.list(/\.info$/).map(app=>{var a=s.readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || (app.type=="clock" && settings.showClocks) || !app.type)); +apps.sort((a,b)=>{ + var n=(0|a.sortorder)-(0|b.sortorder); + if (n) return n; // do sortorder first + if (a.nameb.name) return 1; + return 0; +}); + +// First menu +var mainmenu = { + "" : { "title" : "-- Main Menu --" }, +}; + +apps.forEach((app)=>{ + mainmenu[app.name] = function() { + E.showMessage(/*LANG*/"Loading..."); + load(app.src); + }; +}); + +// Actually display the menu +E.showMenu(mainmenu); From 90a0c0e927637127503116f80588afb307290171 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:28:33 -0700 Subject: [PATCH 093/253] Update metadata.json --- apps/quicklaunch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index a08e75ed9..261b33327 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -1,6 +1,6 @@ { "id": "quicklaunch", "name": "Quick Launch", - "icon": "app.png", + "icon": "quicklaunch.img", "version":"0.01", "description": "", "tags": "tools, system", From 00a7971c88a231d5011b56278cacff42b1e37fa9 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:32:43 -0700 Subject: [PATCH 094/253] Add files via upload --- apps/quicklaunch/app.png | Bin 0 -> 321 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/quicklaunch/app.png diff --git a/apps/quicklaunch/app.png b/apps/quicklaunch/app.png new file mode 100644 index 0000000000000000000000000000000000000000..3d1d0fdd245c75ffe952bfd214f70f372811b45f GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^ia@Ny!2~4Zgw&@2DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMpx`x67sn6}@3(yy#hMK`od5oxfA5;wrig%r zRo^zewX4YRXgb~hG2-FxxEp(0cXQTQM(y$cuA)09Q-C&(s6+rPOeWgFv` zz$=*z^z5U<~{GYcP2uO-+n*NoIz0BLf3=YrchFr6Z@QU(q&v-MMv= Q7SM+bp00i_>zopr0E3W$NB{r; literal 0 HcmV?d00001 From 77e3c27c507b10136686280ffb1b6fa38c3f0cbd Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:33:34 -0700 Subject: [PATCH 095/253] Update metadata.json --- apps/quicklaunch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index 261b33327..a08e75ed9 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -1,6 +1,6 @@ { "id": "quicklaunch", "name": "Quick Launch", - "icon": "quicklaunch.img", + "icon": "app.png", "version":"0.01", "description": "", "tags": "tools, system", From 1b2c2545cf6f10cea59671e592c71d4b39627dc4 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Fri, 25 Mar 2022 23:57:12 -0600 Subject: [PATCH 096/253] Update metadata.json --- apps/mtgwatchface/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index a24ca52c8..f0be4b206 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -3,7 +3,7 @@ "name": "MTG Watchface", "shortName": "Magic the Gathering Watch Face", "version": "1v02", - "description": "Magic the Gathering themed watch face. Embrace the inner wizzard ", + "description": "Magic the Gathering themed watch face. Embrace the inner wizzard. Dispay any of the different types of mana on your watch. Which color are you devoted to today? ", "icon": "icon.png", "screenshots": [ {"url": "black.png"} @@ -32,4 +32,4 @@ ] } ] -} \ No newline at end of file +} From 665f603a70fa48040d2c9f05004cfad017bf8f2d Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Fri, 25 Mar 2022 23:58:10 -0600 Subject: [PATCH 097/253] Create README --- apps/mtgwatchface/README | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 apps/mtgwatchface/README diff --git a/apps/mtgwatchface/README b/apps/mtgwatchface/README new file mode 100644 index 000000000..36c0c9efb --- /dev/null +++ b/apps/mtgwatchface/README @@ -0,0 +1,5 @@ +## Magic the Gathering Watch Face +Magic the Gathering themed watch face. Embrace the inner wizzard. Dispay any of the different types of mana on your watch. Which color are you devoted to today? + +### Touch Enabled +Simply touch the screen on the sides to switch the mana colors From 73774bbe070ed98bb70bb6a450cfb603ca0ac952 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Sat, 26 Mar 2022 00:01:40 -0600 Subject: [PATCH 098/253] Rename README to README.md --- apps/mtgwatchface/{README => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/mtgwatchface/{README => README.md} (100%) diff --git a/apps/mtgwatchface/README b/apps/mtgwatchface/README.md similarity index 100% rename from apps/mtgwatchface/README rename to apps/mtgwatchface/README.md From 6ea588646e16b7cd728a378f4513041304136b2e Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 23:45:53 -0700 Subject: [PATCH 099/253] Update boot.js --- apps/quicklaunch/boot.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index f7fded6df..1aa696f39 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -1,11 +1,25 @@ (function() { + var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); + + if (!settings.leftapp) { + settings["leftapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } + if (!settings.rightapp) { + settings["rightapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } + var sui = Bangle.setUI; Bangle.setUI = function(mode, cb) { sui(mode,cb); if(!mode) return; if ("object"==typeof mode) mode = mode.mode; if (!mode.startsWith("clock")) return; - Bangle.swipeHandler = dir => { if (dir<0) Bangle.showLauncher(); }; + Bangle.swipeHandler = dir => { + if (dir<0) load(settings.leftapp.src); + else load(settings.rightapp.src); + }; Bangle.on("swipe", Bangle.swipeHandler); }; })(); From dbc3da8a1a977aef0b976e0952ed4fcbf6c189b1 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Fri, 25 Mar 2022 23:53:20 -0700 Subject: [PATCH 100/253] Update app.js --- apps/quicklaunch/app.js | 68 +++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index ae684f005..8976cd20d 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -1,7 +1,15 @@ -var s = require("Storage"); -let settings = Object.assign({ showClocks: true }, s.readJSON("launch.json", true) || {}); +var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); -var apps = s.list(/\.info$/).map(app=>{var a=s.readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || (app.type=="clock" && settings.showClocks) || !app.type)); +if (!settings.leftapp) { + settings["leftapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); +} +if (!settings.rightapp) { + settings["rightapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); +} + +var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || (app.type=="clock" && Object.assign(require("Storage").readJSON("launch.json", true) || {}).showClocks) || !app.type)); apps.sort((a,b)=>{ var n=(0|a.sortorder)-(0|b.sortorder); if (n) return n; // do sortorder first @@ -10,17 +18,57 @@ apps.sort((a,b)=>{ return 0; }); +function save(key, value) { + settings[key] = value; + require("Storage").write("quicklaunch.json",settings); +} + // First menu -var mainmenu = { - "" : { "title" : "-- Main Menu --" }, +function showMainMenu() { + var mainmenu = { + "" : { "title" : "Quick Launch" } + }; + + mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(ltappmenu); }; + mainmenu["Right: "+settings.rightapp.name] = function() { E.showMenu(rtappmenu); }; + mainmenu["Launch left "+settings.leftapp.name] = function() { load(settings.leftapp.src); }; + mainmenu["Launch right "+settings.rightapp.name] = function() { load(settings.rightapp.src); }; + + return E.showMenu(mainmenu); +} + + +var ltappmenu = { + "" : { "title" : "Left Swipe" }, + "< Back" : showMainMenu }; -apps.forEach((app)=>{ - mainmenu[app.name] = function() { - E.showMessage(/*LANG*/"Loading..."); - load(app.src); +ltappmenu["(none)"] = function() { + save("leftapp", {"name":"(none)"}); + showMainMenu(); +}; +apps.forEach((a)=>{ + ltappmenu[a.name] = function() { + save("leftapp", a); + showMainMenu(); + }; +}); + +var rtappmenu = { + "" : { "title" : "Right Swipe" }, + "< Back" : showMainMenu +}; + +rtappmenu["(none)"] = function() { + save("rightapp", {"name":"(none)"}); + showMainMenu(); +}; +apps.forEach((b)=>{ + rtappmenu[b.name] = function() { + save("rightapp", b); + showMainMenu(); }; }); // Actually display the menu -E.showMenu(mainmenu); +showMainMenu(); From d3f41a367c93b7b697f944314eb821093c84dd54 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:07:11 -0700 Subject: [PATCH 102/253] Update metadata.json --- apps/quicklaunch/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index a08e75ed9..deadb8fc2 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -9,6 +9,6 @@ {"name":"quicklaunch.app.js","url":"app.js"}, {"name":"quicklaunch.boot.js","url":"boot.js"}, {"name":"quicklaunch.img","url":"app-icon.js","evaluate":true} - - ] + ], + "data": [{"name":"quicklaunch.json"}] } From 13a1d46144979cc3b34f9463403f76295c42860b Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:08:43 -0700 Subject: [PATCH 103/253] Update app.js --- apps/quicklaunch/app.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index 8976cd20d..c5b7fe0d7 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -31,8 +31,6 @@ function showMainMenu() { mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(ltappmenu); }; mainmenu["Right: "+settings.rightapp.name] = function() { E.showMenu(rtappmenu); }; - mainmenu["Launch left "+settings.leftapp.name] = function() { load(settings.leftapp.src); }; - mainmenu["Launch right "+settings.rightapp.name] = function() { load(settings.rightapp.src); }; return E.showMenu(mainmenu); } From 4242633f606d6f4d12fd6065849b760cdc4fcf60 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:19:38 -0700 Subject: [PATCH 104/253] Delete app-icon.js --- apps/quicklaunch/app-icon.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 apps/quicklaunch/app-icon.js diff --git a/apps/quicklaunch/app-icon.js b/apps/quicklaunch/app-icon.js deleted file mode 100644 index 659d0d925..000000000 --- a/apps/quicklaunch/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -E.toArrayBuffer(atob("AAAAAAAHAAAAH8AACDBgwBAnMGA/7b/wP+if8BBokGAIKLDAACigAAAIgAAACPgAAAjIAAAIjgAACA+AAHgIgADIAPAAiADYAIAAiADAAAgAQAAIAEAACABAAAgAYAAYACAAGAAwABAAEAAQABgAMAAMACAAB//gAAP/wAAAAAA=")) From c661309138b9fedc0da1437c4b27f51207ee276c Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:19:58 -0700 Subject: [PATCH 105/253] Delete app.js --- apps/quicklaunch/app.js | 72 ----------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 apps/quicklaunch/app.js diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js deleted file mode 100644 index c5b7fe0d7..000000000 --- a/apps/quicklaunch/app.js +++ /dev/null @@ -1,72 +0,0 @@ -var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); - -if (!settings.leftapp) { - settings["leftapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); -} -if (!settings.rightapp) { - settings["rightapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); -} - -var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || (app.type=="clock" && Object.assign(require("Storage").readJSON("launch.json", true) || {}).showClocks) || !app.type)); -apps.sort((a,b)=>{ - var n=(0|a.sortorder)-(0|b.sortorder); - if (n) return n; // do sortorder first - if (a.nameb.name) return 1; - return 0; -}); - -function save(key, value) { - settings[key] = value; - require("Storage").write("quicklaunch.json",settings); -} - -// First menu -function showMainMenu() { - var mainmenu = { - "" : { "title" : "Quick Launch" } - }; - - mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(ltappmenu); }; - mainmenu["Right: "+settings.rightapp.name] = function() { E.showMenu(rtappmenu); }; - - return E.showMenu(mainmenu); -} - - -var ltappmenu = { - "" : { "title" : "Left Swipe" }, - "< Back" : showMainMenu -}; - -ltappmenu["(none)"] = function() { - save("leftapp", {"name":"(none)"}); - showMainMenu(); -}; -apps.forEach((a)=>{ - ltappmenu[a.name] = function() { - save("leftapp", a); - showMainMenu(); - }; -}); - -var rtappmenu = { - "" : { "title" : "Right Swipe" }, - "< Back" : showMainMenu -}; - -rtappmenu["(none)"] = function() { - save("rightapp", {"name":"(none)"}); - showMainMenu(); -}; -apps.forEach((b)=>{ - rtappmenu[b.name] = function() { - save("rightapp", b); - showMainMenu(); - }; -}); - -// Actually display the menu -showMainMenu(); From 711394cfc1db6a522e2811efb42e0d2d960184a9 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:20:09 -0700 Subject: [PATCH 106/253] Delete app.png --- apps/quicklaunch/app.png | Bin 321 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/quicklaunch/app.png diff --git a/apps/quicklaunch/app.png b/apps/quicklaunch/app.png deleted file mode 100644 index 3d1d0fdd245c75ffe952bfd214f70f372811b45f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^ia@Ny!2~4Zgw&@2DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMpx`x67sn6}@3(yy#hMK`od5oxfA5;wrig%r zRo^zewX4YRXgb~hG2-FxxEp(0cXQTQM(y$cuA)09Q-C&(s6+rPOeWgFv` zz$=*z^z5U<~{GYcP2uO-+n*NoIz0BLf3=YrchFr6Z@QU(q&v-MMv= Q7SM+bp00i_>zopr0E3W$NB{r; From a50f8b433f4b426c0c75ad23ddf4e38d2f2d5037 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:20:18 -0700 Subject: [PATCH 107/253] Delete boot.js --- apps/quicklaunch/boot.js | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 apps/quicklaunch/boot.js diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js deleted file mode 100644 index 1aa696f39..000000000 --- a/apps/quicklaunch/boot.js +++ /dev/null @@ -1,25 +0,0 @@ -(function() { - var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); - - if (!settings.leftapp) { - settings["leftapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } - if (!settings.rightapp) { - settings["rightapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } - - var sui = Bangle.setUI; - Bangle.setUI = function(mode, cb) { - sui(mode,cb); - if(!mode) return; - if ("object"==typeof mode) mode = mode.mode; - if (!mode.startsWith("clock")) return; - Bangle.swipeHandler = dir => { - if (dir<0) load(settings.leftapp.src); - else load(settings.rightapp.src); - }; - Bangle.on("swipe", Bangle.swipeHandler); - }; -})(); From 5056826d2d94fb9eae0b2f143ec74f91a132527d Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:20:25 -0700 Subject: [PATCH 108/253] Delete metadata.json --- apps/quicklaunch/metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 apps/quicklaunch/metadata.json diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json deleted file mode 100644 index deadb8fc2..000000000 --- a/apps/quicklaunch/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ "id": "quicklaunch", - "name": "Quick Launch", - "icon": "app.png", - "version":"0.01", - "description": "", - "tags": "tools, system", - "supports": ["BANGLEJS2"], - "storage": [ - {"name":"quicklaunch.app.js","url":"app.js"}, - {"name":"quicklaunch.boot.js","url":"boot.js"}, - {"name":"quicklaunch.img","url":"app-icon.js","evaluate":true} - ], - "data": [{"name":"quicklaunch.json"}] -} From 92878dc159104ff70cbd1da4d0d6f594dfc8fc8f Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:23:20 -0700 Subject: [PATCH 109/253] Create app.js --- apps/quicklaunch/app.js | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 apps/quicklaunch/app.js diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js new file mode 100644 index 000000000..c5b7fe0d7 --- /dev/null +++ b/apps/quicklaunch/app.js @@ -0,0 +1,72 @@ +var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); + +if (!settings.leftapp) { + settings["leftapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); +} +if (!settings.rightapp) { + settings["rightapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); +} + +var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || (app.type=="clock" && Object.assign(require("Storage").readJSON("launch.json", true) || {}).showClocks) || !app.type)); +apps.sort((a,b)=>{ + var n=(0|a.sortorder)-(0|b.sortorder); + if (n) return n; // do sortorder first + if (a.nameb.name) return 1; + return 0; +}); + +function save(key, value) { + settings[key] = value; + require("Storage").write("quicklaunch.json",settings); +} + +// First menu +function showMainMenu() { + var mainmenu = { + "" : { "title" : "Quick Launch" } + }; + + mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(ltappmenu); }; + mainmenu["Right: "+settings.rightapp.name] = function() { E.showMenu(rtappmenu); }; + + return E.showMenu(mainmenu); +} + + +var ltappmenu = { + "" : { "title" : "Left Swipe" }, + "< Back" : showMainMenu +}; + +ltappmenu["(none)"] = function() { + save("leftapp", {"name":"(none)"}); + showMainMenu(); +}; +apps.forEach((a)=>{ + ltappmenu[a.name] = function() { + save("leftapp", a); + showMainMenu(); + }; +}); + +var rtappmenu = { + "" : { "title" : "Right Swipe" }, + "< Back" : showMainMenu +}; + +rtappmenu["(none)"] = function() { + save("rightapp", {"name":"(none)"}); + showMainMenu(); +}; +apps.forEach((b)=>{ + rtappmenu[b.name] = function() { + save("rightapp", b); + showMainMenu(); + }; +}); + +// Actually display the menu +showMainMenu(); From 9ab343db9dd21cb9f82e6c79840cf2e1cb317ff2 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:25:50 -0700 Subject: [PATCH 110/253] Create app-icon.js --- apps/quicklaunch/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/quicklaunch/app-icon.js diff --git a/apps/quicklaunch/app-icon.js b/apps/quicklaunch/app-icon.js new file mode 100644 index 000000000..659d0d925 --- /dev/null +++ b/apps/quicklaunch/app-icon.js @@ -0,0 +1 @@ +E.toArrayBuffer(atob("AAAAAAAHAAAAH8AACDBgwBAnMGA/7b/wP+if8BBokGAIKLDAACigAAAIgAAACPgAAAjIAAAIjgAACA+AAHgIgADIAPAAiADYAIAAiADAAAgAQAAIAEAACABAAAgAYAAYACAAGAAwABAAEAAQABgAMAAMACAAB//gAAP/wAAAAAA=")) From b05bc9e2918f9b2d6dcac0174d7158d991c3e482 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:26:32 -0700 Subject: [PATCH 111/253] Create boot.js --- apps/quicklaunch/boot.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 apps/quicklaunch/boot.js diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js new file mode 100644 index 000000000..1aa696f39 --- /dev/null +++ b/apps/quicklaunch/boot.js @@ -0,0 +1,25 @@ +(function() { + var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); + + if (!settings.leftapp) { + settings["leftapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } + if (!settings.rightapp) { + settings["rightapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } + + var sui = Bangle.setUI; + Bangle.setUI = function(mode, cb) { + sui(mode,cb); + if(!mode) return; + if ("object"==typeof mode) mode = mode.mode; + if (!mode.startsWith("clock")) return; + Bangle.swipeHandler = dir => { + if (dir<0) load(settings.leftapp.src); + else load(settings.rightapp.src); + }; + Bangle.on("swipe", Bangle.swipeHandler); + }; +})(); From 62aebd710212ccdf630a3e45302bd1119fd46c6f Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:27:04 -0700 Subject: [PATCH 112/253] Create metadata.json --- apps/quicklaunch/metadata.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 apps/quicklaunch/metadata.json diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json new file mode 100644 index 000000000..deadb8fc2 --- /dev/null +++ b/apps/quicklaunch/metadata.json @@ -0,0 +1,14 @@ +{ "id": "quicklaunch", + "name": "Quick Launch", + "icon": "app.png", + "version":"0.01", + "description": "", + "tags": "tools, system", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"quicklaunch.app.js","url":"app.js"}, + {"name":"quicklaunch.boot.js","url":"boot.js"}, + {"name":"quicklaunch.img","url":"app-icon.js","evaluate":true} + ], + "data": [{"name":"quicklaunch.json"}] +} From 7dfeb8fc61e5c47658affc55c7f31a08d8be65ee Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:27:21 -0700 Subject: [PATCH 113/253] Add files via upload --- apps/quicklaunch/app.png | Bin 0 -> 321 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/quicklaunch/app.png diff --git a/apps/quicklaunch/app.png b/apps/quicklaunch/app.png new file mode 100644 index 0000000000000000000000000000000000000000..3d1d0fdd245c75ffe952bfd214f70f372811b45f GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^ia@Ny!2~4Zgw&@2DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMpx`x67sn6}@3(yy#hMK`od5oxfA5;wrig%r zRo^zewX4YRXgb~hG2-FxxEp(0cXQTQM(y$cuA)09Q-C&(s6+rPOeWgFv` zz$=*z^z5U<~{GYcP2uO-+n*NoIz0BLf3=YrchFr6Z@QU(q&v-MMv= Q7SM+bp00i_>zopr0E3W$NB{r; literal 0 HcmV?d00001 From ba669d2cabbfe7f3ed9837e9ee4623f6d3de0948 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:33:37 -0700 Subject: [PATCH 114/253] Update app.js --- apps/quicklaunch/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index c5b7fe0d7..3f3263c3e 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -27,6 +27,7 @@ function save(key, value) { function showMainMenu() { var mainmenu = { "" : { "title" : "Quick Launch" } + "< Back" : ()=>{load(); }; mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(ltappmenu); }; From 86fe688d44374bcfb4528908dfc9b6992a793603 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 00:43:01 -0700 Subject: [PATCH 115/253] Update app.js --- apps/quicklaunch/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index 3f3263c3e..e0f4827a9 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -26,8 +26,8 @@ function save(key, value) { // First menu function showMainMenu() { var mainmenu = { - "" : { "title" : "Quick Launch" } - "< Back" : ()=>{load(); + "" : { "title" : "Quick Launch" }, + "< Back" : ()=>{load();} }; mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(ltappmenu); }; From 1a53e4b64e98e47f9187b42e94a74c978d989de5 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 01:02:35 -0700 Subject: [PATCH 116/253] Update app-icon.js --- apps/quicklaunch/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/app-icon.js b/apps/quicklaunch/app-icon.js index 659d0d925..2c7750df5 100644 --- a/apps/quicklaunch/app-icon.js +++ b/apps/quicklaunch/app-icon.js @@ -1 +1 @@ -E.toArrayBuffer(atob("AAAAAAAHAAAAH8AACDBgwBAnMGA/7b/wP+if8BBokGAIKLDAACigAAAIgAAACPgAAAjIAAAIjgAACA+AAHgIgADIAPAAiADYAIAAiADAAAgAQAAIAEAACABAAAgAYAAYACAAGAAwABAAEAAQABgAMAAMACAAB//gAAP/wAAAAAA=")) +E.toArrayBuffer(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAP////AAAAAAAAAAAADwAAD/AAAP8AAA/wAAAAAA8AAADwD/8A/wAAD/AAAAAP/////w/w/w//////8AAAAP/////w8ADwD/////8AAAAA8AAA/w8ADwDwAAD/AAAAAADwAADw8ADw/wAA/wAAAAAAAAAADw8ADw8AAAAAAAAAAAAAAAAA8ADwAAAAAAAAAAAAAAAAAA8AD///AAAAAAAAAAAAAAAA8AD/APAAAAAAAAAAAAAAAA8ADwAP/wAAAAAAAAAAAAAA8AAAAP//8AAAAAAAAAAA//8AAAAPAA8AAAAAAAAAAP8A8AAAAAAA//8AAAAAAAAPAA8AAAAAAA/w/wAAAAAAAPAAAAAAAAAA8ADwAAAAAAAP8AAAAAAAAAAADwAAAAAAAA8AAAAAAAAAAADwAAAAAAAA8AAAAAAAAAAADwAAAAAAAA8AAAAAAAAAAADwAAAAAAAA/wAAAAAAAAAA/wAAAAAAAADwAAAAAAAAAA/wAAAAAAAAD/AAAAAAAAAA8AAAAAAAAAAPAAAAAAAAAA8AAAAAAAAAAP8AAAAAAAAP8AAAAAAAAAAA/wAAAAAAAPAAAAAAAAAAAAD/////////AAAAAAAAAAAAAP///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) From e998b36e96459ae798bb1ed6b4dae525c31ffdb5 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 01:09:06 -0700 Subject: [PATCH 117/253] Update app-icon.js --- apps/quicklaunch/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/app-icon.js b/apps/quicklaunch/app-icon.js index 2c7750df5..14ae94823 100644 --- a/apps/quicklaunch/app-icon.js +++ b/apps/quicklaunch/app-icon.js @@ -1 +1 @@ -E.toArrayBuffer(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAP////AAAAAAAAAAAADwAAD/AAAP8AAA/wAAAAAA8AAADwD/8A/wAAD/AAAAAP/////w/w/w//////8AAAAP/////w8ADwD/////8AAAAA8AAA/w8ADwDwAAD/AAAAAADwAADw8ADw/wAA/wAAAAAAAAAADw8ADw8AAAAAAAAAAAAAAAAA8ADwAAAAAAAAAAAAAAAAAA8AD///AAAAAAAAAAAAAAAA8AD/APAAAAAAAAAAAAAAAA8ADwAP/wAAAAAAAAAAAAAA8AAAAP//8AAAAAAAAAAA//8AAAAPAA8AAAAAAAAAAP8A8AAAAAAA//8AAAAAAAAPAA8AAAAAAA/w/wAAAAAAAPAAAAAAAAAA8ADwAAAAAAAP8AAAAAAAAAAADwAAAAAAAA8AAAAAAAAAAADwAAAAAAAA8AAAAAAAAAAADwAAAAAAAA8AAAAAAAAAAADwAAAAAAAA/wAAAAAAAAAA/wAAAAAAAADwAAAAAAAAAA/wAAAAAAAAD/AAAAAAAAAA8AAAAAAAAAAPAAAAAAAAAA8AAAAAAAAAAP8AAAAAAAAP8AAAAAAAAAAA/wAAAAAAAPAAAAAAAAAAAAD/////////AAAAAAAAAAAAAP///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) +require("heatshrink").decompress(atob("kMigILIgPAAYMD/ADBwcGhkAwM5wcA/+2//Av/Rn/giFoyFggkUrFggEKlAkCiApCx+AAYNGoADBkU4AYMQj4DBvEICANkAoIPBgE2B4MAiMAH4MAwECAYNALYUgBIISCHYMYAoQWBAIMEgAYBAIMBwEDDQNgDwUf/4eBg4DCAA4")) From 1a8febf9ee9b3aa70af0edf40654ecdc126620b1 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 01:15:00 -0700 Subject: [PATCH 118/253] Update app-icon.js --- apps/quicklaunch/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/app-icon.js b/apps/quicklaunch/app-icon.js index 14ae94823..1e100f6c3 100644 --- a/apps/quicklaunch/app-icon.js +++ b/apps/quicklaunch/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("kMigILIgPAAYMD/ADBwcGhkAwM5wcA/+2//Av/Rn/giFoyFggkUrFggEKlAkCiApCx+AAYNGoADBkU4AYMQj4DBvEICANkAoIPBgE2B4MAiMAH4MAwECAYNALYUgBIISCHYMYAoQWBAIMEgAYBAIMBwEDDQNgDwUf/4eBg4DCAA4")) +require("heatshrink").decompress(atob("ABEB4ADBgf4AYODg0MgGBnODgH/23/4F/6M/8EQtGQsEEilYsEAhUoEgUQFIWPwADBo1AAYMinADBiEfAYN4hAQBsgFBB4MAmwPBgERgA/BgGAgQDBoEBAYMgBIISCHYMYAoQWBAIMEgAYBAIMBwEDDQNgDwUf/4eBg4DCAA4A==")) From ecd6215eb537dde64ae3570a644b643688f3b0bb Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 01:21:07 -0700 Subject: [PATCH 119/253] Update metadata.json --- apps/quicklaunch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index deadb8fc2..09017f0f0 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -2,7 +2,7 @@ "name": "Quick Launch", "icon": "app.png", "version":"0.01", - "description": "", + "description": "Swipe left or right on your clock face to launch any two apps of your choice.", "tags": "tools, system", "supports": ["BANGLEJS2"], "storage": [ From 6b6125a619157efc819f4c4d60a56ca409365e2f Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 01:21:39 -0700 Subject: [PATCH 120/253] Create ChangeLog --- apps/quicklaunch/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/quicklaunch/ChangeLog diff --git a/apps/quicklaunch/ChangeLog b/apps/quicklaunch/ChangeLog new file mode 100644 index 000000000..4022f485c --- /dev/null +++ b/apps/quicklaunch/ChangeLog @@ -0,0 +1 @@ +0.01: First version! From 9d8e8ed20837bf2cd2ea48ea16b32c6bf9337997 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 01:24:27 -0700 Subject: [PATCH 121/253] Update ChangeLog --- apps/quicklaunch/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/ChangeLog b/apps/quicklaunch/ChangeLog index 4022f485c..ec66c5568 100644 --- a/apps/quicklaunch/ChangeLog +++ b/apps/quicklaunch/ChangeLog @@ -1 +1 @@ -0.01: First version! +0.01: Initial version From 16f3a81d14d93df0094aeae6e8d26d4f39c19c3b Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 01:36:25 -0700 Subject: [PATCH 123/253] Update app-icon.js --- apps/quicklaunch/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/app-icon.js b/apps/quicklaunch/app-icon.js index 1e100f6c3..14ae94823 100644 --- a/apps/quicklaunch/app-icon.js +++ b/apps/quicklaunch/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("ABEB4ADBgf4AYODg0MgGBnODgH/23/4F/6M/8EQtGQsEEilYsEAhUoEgUQFIWPwADBo1AAYMinADBiEfAYN4hAQBsgFBB4MAmwPBgERgA/BgGAgQDBoEBAYMgBIISCHYMYAoQWBAIMEgAYBAIMBwEDDQNgDwUf/4eBg4DCAA4A==")) +require("heatshrink").decompress(atob("kMigILIgPAAYMD/ADBwcGhkAwM5wcA/+2//Av/Rn/giFoyFggkUrFggEKlAkCiApCx+AAYNGoADBkU4AYMQj4DBvEICANkAoIPBgE2B4MAiMAH4MAwECAYNALYUgBIISCHYMYAoQWBAIMEgAYBAIMBwEDDQNgDwUf/4eBg4DCAA4")) From f57d4d965c7b1195145e8c4e38510aef332fd68e Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 09:22:18 -0700 Subject: [PATCH 124/253] Update app.js --- apps/quicklaunch/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index e0f4827a9..226a0433f 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -9,7 +9,8 @@ if (!settings.rightapp) { require("Storage").write("quicklaunch.json",settings); } -var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || (app.type=="clock" && Object.assign(require("Storage").readJSON("launch.json", true) || {}).showClocks) || !app.type)); +var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="launch" || (app.type=="clock" && Object.assign(require("Storage").readJSON("launch.json", true) || {}).showClocks) || !app.type)); + apps.sort((a,b)=>{ var n=(0|a.sortorder)-(0|b.sortorder); if (n) return n; // do sortorder first From 970c102822eee27aed0b360334c92bc162334357 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 09:30:44 -0700 Subject: [PATCH 125/253] Update boot.js --- apps/quicklaunch/boot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 1aa696f39..deb6b86cb 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -17,8 +17,8 @@ if ("object"==typeof mode) mode = mode.mode; if (!mode.startsWith("clock")) return; Bangle.swipeHandler = dir => { - if (dir<0) load(settings.leftapp.src); - else load(settings.rightapp.src); + if (dir<0) && (settings.leftapp.src) load(settings.leftapp.src); + if (dir>0) && (settings.rightapp.src) load(settings.rightapp.src); }; Bangle.on("swipe", Bangle.swipeHandler); }; From 7ff995e3ec79af1eefbe5cc3070928f26b3b2656 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 09:41:52 -0700 Subject: [PATCH 126/253] Update boot.js --- apps/quicklaunch/boot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index deb6b86cb..dfc427d5c 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -17,8 +17,8 @@ if ("object"==typeof mode) mode = mode.mode; if (!mode.startsWith("clock")) return; Bangle.swipeHandler = dir => { - if (dir<0) && (settings.leftapp.src) load(settings.leftapp.src); - if (dir>0) && (settings.rightapp.src) load(settings.rightapp.src); + if ((dir<0) && (settings.leftapp.src)) load(settings.leftapp.src); + if ((dir>0) && (settings.rightapp.src)) load(settings.rightapp.src); }; Bangle.on("swipe", Bangle.swipeHandler); }; From 1f81238c12bdd2c739e567803ae91c7b92e7245d Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 09:47:46 -0700 Subject: [PATCH 127/253] Update boot.js --- apps/quicklaunch/boot.js | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index dfc427d5c..c3e213d0c 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -1,25 +1,25 @@ (function() { - var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); + var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); - if (!settings.leftapp) { - settings["leftapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } - if (!settings.rightapp) { - settings["rightapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } + if (!settings.leftapp) { + settings["leftapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } + if (!settings.rightapp) { + settings["rightapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } - var sui = Bangle.setUI; - Bangle.setUI = function(mode, cb) { - sui(mode,cb); - if(!mode) return; - if ("object"==typeof mode) mode = mode.mode; - if (!mode.startsWith("clock")) return; - Bangle.swipeHandler = dir => { - if ((dir<0) && (settings.leftapp.src)) load(settings.leftapp.src); - if ((dir>0) && (settings.rightapp.src)) load(settings.rightapp.src); - }; - Bangle.on("swipe", Bangle.swipeHandler); + var sui = Bangle.setUI; + Bangle.setUI = function(mode, cb) { + sui(mode,cb); + if(!mode) return; + if ("object"==typeof mode) mode = mode.mode; + if (!mode.startsWith("clock")) return; + Bangle.swipeHandler = dir => { + if ((dir<0) && (settings.leftapp.src)) load(settings.leftapp.src); + if ((dir>0) && (settings.rightapp.src)) load(settings.rightapp.src); }; + Bangle.on("swipe", Bangle.swipeHandler); + }; })(); From a20ea2df714887a9ac350b3ec668dc511b9ef6b5 Mon Sep 17 00:00:00 2001 From: Francois Lancelot <16709438+francoislanc@users.noreply.github.com> Date: Sat, 26 Mar 2022 18:40:11 +0100 Subject: [PATCH 128/253] Add UI for the TodoList app --- apps/todolist/README.md | 64 +++++++++++----- apps/todolist/interface.html | 135 ++++++++++++++++++++++++++++++++++ apps/todolist/metadata.json | 1 + apps/todolist/screenshot4.png | Bin 0 -> 74049 bytes 4 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 apps/todolist/interface.html create mode 100644 apps/todolist/screenshot4.png diff --git a/apps/todolist/README.md b/apps/todolist/README.md index 27c7cfb63..0e1beb74a 100644 --- a/apps/todolist/README.md +++ b/apps/todolist/README.md @@ -2,39 +2,63 @@ Todo List ======== This is a simple Todo List application. +The content is loaded from a JSON file. +A task can be marked as completed or uncompleted. ![](screenshot2.png) -The content is loaded from a JSON file. -You can mark a task as completed. +Once installed, the list can be modified via the `Download data from app` icon in the [Bangle.js App Store](https://banglejs.com/apps/) (TodoList app). + +![](screenshot4.png) + JSON file content example: ```javascript [ { - name: "Pro", - children: [ + "name": "Pro", + "children": [ { - name: "Read doc", - done: true, - children: [], + "name": "Read doc", + "done": true, + "children": [] } - ], + ] }, { - name: "Pers", - children: [ + "name": "Pers", + "children": [ { - name: "Grocery", - children: [ - { name: "Milk", done: false, children: [] }, - { name: "Eggs", done: false, children: [] }, - { name: "Cheese", done: false, children: [] }, - ], + "name": "Grocery", + "children": [ + { + "name": "Milk", + "done": false, + "children": [] + }, + { + "name": "Eggs", + "done": false, + "children": [] + }, + { + "name": "Cheese", + "done": false, + "children": [] + } + ] }, - { name: "Workout", done: false, children: [] }, - { name: "Learn Rust", done: false, children: [] }, - ], - }, + { + "name": "Workout", + "done": false, + "children": [] + }, + { + "name": "Learn Rust", + "done": false, + "children": [] + } + ] + } ] ``` \ No newline at end of file diff --git a/apps/todolist/interface.html b/apps/todolist/interface.html new file mode 100644 index 000000000..5b9cb038e --- /dev/null +++ b/apps/todolist/interface.html @@ -0,0 +1,135 @@ + + + + + + + +
+ + + + + +

+
+    
+    
+  
+
diff --git a/apps/todolist/metadata.json b/apps/todolist/metadata.json
index 0833a86bd..a8eb6118b 100644
--- a/apps/todolist/metadata.json
+++ b/apps/todolist/metadata.json
@@ -10,6 +10,7 @@
   "tags": "tool,todo",
   "supports": ["BANGLEJS", "BANGLEJS2"],
   "readme": "README.md",
+  "interface": "interface.html",
   "storage": [
     { "name": "todolist.app.js", "url": "app.js" },
     { "name": "todolist.img", "url": "app-icon.js", "evaluate": true }
diff --git a/apps/todolist/screenshot4.png b/apps/todolist/screenshot4.png
new file mode 100644
index 0000000000000000000000000000000000000000..43db1b0e6e2c55ffe7506f204035e1a6207d9e93
GIT binary patch
literal 74049
zcmeFYgO_DV(=S}EQ&yL4+qSxFtIM|4UAApkb$8jeZQHhaYv!3}X4d8IJ!kE;
zb4SK6BQr8GBO~@Xq4KigaL`!LKtMonk`f|{KtLespBD!J;*(MzmmCBH1Z!I*9mqo_|b0j{DB|8@}$j%utk+ZQyP9`n8YW%yzIVXVz}JmX2OiMik$6dUd;2M%;mx;;>vIT!FAu-Rq04>8
zKh&nSV2pTxV(bx3uZ>&1Lehad*)K_^L4ZP_+x8MbLO~{esH;JP2DsIMm{MQSfsZS1
z=Yz6ILRp2-gXW0sITS7dnXUSJh!N6bUz>RaEvk&7hXPMJ`Eh(F-@PVO?LAM(=9m02
zLRjyAj~rsa^F8$m*YtklkvaIWY4wz_bktH{R!D?N63=z{LnG~j_R0NP5TDIXK5#k&
zO!U1nsKJ3;l#&5;+s58Rx-@Sd(HHS5(HRn`5U__d^wo1Vh1{^`8Q42S=V>*DA|#R!
z9_64<8fORS%Arz_dttP_IpJMgZZk)I?1WXN*!N%I!{o;1cL2<0FI$Y$v@Y`Fw(
z3Q~_H5e0~^00~fau5%Y?4TwD8PA{l-_&4()RthbSdMr$qPzFMt0NyJtzB(!1brMLH
zK;$9*dXwFyeyh73#r{W|kNk^Fk6)Tuq8Q&{Y%ZsnBrItVB5{a;i03K*q4Vw1%ni=3
z2hMbx&)?mvhMb4A76lKf9EA(eKpwU)=^Ns}a`^q#;FqS6j~>h_goDR+S0les@Mt5S
z4OoUf!eMYAq|ii`{D^8_SqbzG%!W!`@hLwuU6Klm%?E+1I&kz_VJ{z>&C7cdy739ms_$unG
zfHDh#`-4dV4J(i=cW27ViAghnP9QmN&y2JgvP@Ji2Yu?q4DuQItPiLt>d0_Eg}J|X
zQJp3!%Gf~B3Qg57(I8PBZXS?*qf!cb($BXok`cvhXWHmbd})*sEZ1+kC3SiCNY{$S
zAE?)dzs>uo1`??+ZAbEm%n`sCVAcIah%q;!(%&w{4lAorwws$MwnVO$)T5^+MQoH%
zmYj~zhUA=>4P_-XI<$=hc_?OA;+niKuCV|_krNlovDSl5p6Z=QZkOzetdCka%@99_E7R*<}P0tTVK+)oMhgv{J!Ea
zC2PV=f@ea*@$oU*G2ijkG0`38@!s*v+{90QS$!=OnTG
zrAa@tqgs$Jwg`S8DRnUoIQiR)#$Nn%QZs55ON1>=cs=rLMzf!Mp~v@hJ@@yS~kro
z{Wu*Wbw8z?jn`(`Sd1Np0VTDJ&63HpYtpb1!#%>GpHeKksmeW|Y1Qkud%AmeV3}xj
zA5XY9+5;_RlJp48$XpU_60fR>YJQoCx{B6X6`2-uS>U{7*@R|CLsgw*oral`>CNhV
zXOf|ok(RaRM3f1-8T(TC^m!WZRF-+RWyjQeHR$o?5rI>QUE^*Dmj`DU4m(#pH&TXI
zMz3t5EPLk9ahe061B-)Tx@Wp6x*P3dZQaO9tXRHpeIYf(?ady|`%N~kZQP2cM!SRV
z#Mt8P_KtQtO)8B#j>S#EO%pB^uD)kmhlH1lyY?gT=bX!qxu)R<==8SqKh+}Dk{c3T
zgB~C*(xr7wa2%m-G7!4R7ftIY6tbh+b=$$)A-z9t9q&i(R?Z&063!^PO3w1}UbG$^
z-x{7>!5Bc8KSvvZ%%6)7%awyFV!`
zl)ueBmxxcnPfZ{8PaPf(PW=|!2(OAl8kp_#QLyfnMS#z_)BrUIH;gp`V52l+vq4G`b@;Mi22=7
z!EM4V?opee@IX1{3g@_^_EjVHj`e^XuCI^ZR6r}#0GWmCt}IW2;Go3VV&+vU_DI?8
zy@>-8yV3pSVryM%@+-l+g->#)UZvtC%?Q7x@%)X|$EnJaPPc$TYNb{$S{ZuVcgNvkk*%yZl4=Xb@jizxbrYG3`w%pZ(naSvG@HM4NSAN>O^4eDvtFew&23&%8hG
z#u3lzctT^Ox?h^KlvIO0dY*y8XS$$0yt>-dG3J=r;IOWDqjbPd$DqMr+O?D2?fZ*v
zo+1ftL;JA7?uN)K)=XjL+e6<8nlJ5EvNnY?EiLt1Ye2(p_XM#o-A9wJ`TTUfvF->P
zEjb-JeMc3MU0-?PGIh8rpDwG1%9%y~aon75S!(0HSE~5ZeqBP{bsg^B)ZX1m={&98
zgL|9Z+g;dZm^XF=JI(r~53%n~qKsg=1zWlm-P)^pxY!*fn#vj5dRr-0S(2LT8D_)5^?FR(9qTx&*2B>S
z^%}zc$U_H5jQwVRSBXDua7wU+Pu;t7kHPa+oMwTGrnOvVWqCedS$i8{b#CEQ#nmNJ
zGBI~_8h#l^k*n2`{qPm|z)N~qnnyb6*cy4Y9FI-vqQk>(O8kOsU$zA|uJiM1Y9%xI
zMD;jZ<_*8=ZR^ET5X>lyGkP1{e7#3K-uu{1LyxttbzO2R{hZ!?)9NDMueZm!t;*0YP&j3%-hr07*UIrier6t*2(?B^r?U78XOEB<&
zyi+|$#78;xC3^S}bRgEt7v6SkpS4vm{STK#A3-0P#ozr?KoZx$B`q(L@}V>%YcfNk
zf!@$tg1#SGi#4&Tz?a7EzP@_Kz8}ff4C;&AY~hK#B|;&Uri;kWq|E#%uhDy|5*kC
z`U;HwcUcjb;x8T$AfRA#Ah5r9G(Ycud}2PYPxN1R(6}HV$j>L_&nqAYN%i)
zmpMM`fCQCf)aSC_4!aM<5_H(myU>Nkx*&&){jnTv^>o
zT}GPA(AJvHz{vKSF`b*W-5>1$@wjn)7Ojn)3<%t;t!x~*+<1xpe`@~e=zowZj>Zncw$`6OC%%8?>M!uWEB`0(
zPmvn`h-Bkn`nSk`)%*+j#}K#_jU8>Roc~avijBDw-zV&UBmYm7#y>DVMi!R8K>w!x
zPlWpaiugD6e&MeX-5J|SrV@KQw3xx<7%
z8UBL?Nt*w&jlW0%Dc_;h2_b$>QT~exPE!W@x3KTX07hWcN+DR~e5HT7@QKod{8zh(
z-$1DJ12Ia(ioyP&qE^+0&?l=j$op
z3u>iHKvs~--!fgeK@1EGs%e44e7I(QexDO;_VI-TwP5%|BY(D^GXqdwn3eDm{DDCT
z^Rp40w&mjH$>?U^YpcFSyBJzMGBR@dK6^vE0epQ*Xt|aP3%|#fnx=x==hQ{qv1}{x
zzgqf%OS<{Mo<@;Gqd|6LZeHzl?=Ge>&wxg`F_56Khod=sxeok*CT;`4XFBLCB0Gkfl4#spj
zd}QM%#1aQ%6OQa$g)9{Qe143_ba=Io-~DNtl{{Jsi*iu^{BBLMy1f^IHW9RGBrNQ&
ztf~rCfJ7`<&yv@_B?paTUsZ*Sf>I;=)1yuI$)<~Fsk%_TKMI$ax7pQ}tjvb`ItZfT
z(*^;yBHtAK0)knSdCPXCd~5hVwCBqvVt*EAQt2o)Td8q<*`EE!1ae6Q2t%1f9TfAl
zeb?&5-g9E=%&rtM18LU=vc0I{qj<%#JhzNFA5NJg;s)+7a>pVi2El32qJ(;*E$4@Y
zecxI{#Ke^7O#@;s?Zlgn3|=FBLLQNCL;FrMGX7cwKfL{b_7Ij;M8(Ag2b=o=+WF#<@qyv(
zv3azjh~-g92U)&9X9B6a&uj78%gbfoZyq~D;vfY&!;mQ}&?LjY%LA+E*q2E*A9R+-
zwOEvAINocB0W1SH_f%&TPDEozz2Sq!)NB0a=F22BAIe*4vc7MA>rptYdFdD43_ge<
zDG!~Un;nLk;3dsR$f981aPq%0*l`J#JW3;qe!pRq=#?@W+!T~aK3q7HUe~}|wW4;~
zw;D`5v2DfFtfp|kjqUiVD#lg*L>R;6SIpgd{$B%<2U(H(PONb1nxEU-boFdWO2{Wj
zCe0y=l}EHY_aQTIIFledr@e#|tle2HtnUv2pK!;?g6CgE#q{<124**lpO>PdjZ2s>
z^(qe*pHI1DiZEcefP@%`6GX1l4M$OqgA~7i6S?)2?~SRH*bhoSbe5Q}p++crEPf~3
zC)0q-bChALkuV0L&{QmXK9KQIA|yJQx}q^bFrvm>9e8|y2p}^^T%pB3tKN1qC3KXz
zCPO6cF&Yl7mQ-l--&Gdi_g%$CL|lC2JMdd!tr1+FOst?k1eOv(8mjX>h2p0uwfYNpg_8Or(b
zM#|mN(3A>;Mkm(z#AKpekA!17nnH<*xGxrkLAcgj$d-6P4s`0(;BzJ~tjLE!&Ze%1VPQQ`X%oV`#+O|`t;@sy;M{*?RC!T(DC;mrQp
zpOMY%+J1MQ&3WSZvFIQD82a(EIQvYm-pf6nU;2Q>hb)t0uESU=loP>PdB(X#PhEYN
zf3KD~LN6$HWN7G4&u$8pUvlTWz4)`~M3&)e#>5tRuw$5hww;rH}VB
zMoP%Qqx##Gt_Xf_<1mH66Zdx+MdSHsbsVKYvaYsizTz4LMHnnmAkG=mv@rTIP;1JK
zY*xG=i%n!D_xy#5&1RX#w)HCL%ID#XedK3xhSmMc!-Zwgjcg{9lCH-QDyRAN72;&~
z-kzH7z}=Uo_vewlQ)W4KAMpqbG6f*leN45TMs(O6T*>n{1paP&Ot5VJVdG?N0v&@K
z+2pik)Dar1xQ3z*f*ZOP^(cOyX_ry`TlOUn1^L~W?f%GgnbzP4Y;sV>Qc2hICDY;W
zK5qq;C4;+V;?d_!=Q*GS&COrqkmD;8dVNxk7RMgA0&xb5665RNl&zBXnLbyx5ww0pl`IOfVzbGd|mpDUmdLSh%}
z^f-}OB*XPen7ZHm5`abzyF+Y*Q_CML%^}E_e%1aZIRV3ZD#Mm9F;qO0A~=daKsWsr
zkJa8U0)ty3X*`=WmVxYmWei_`M$~n-w
zl$Xawro)Wd^Awp)YaGq)Kqc$)GLJQ-X%^w{f(WOsfQ+Y$xvts|44t{IlUB&R%$k)4
zeM4Q+)3y8gx`Y2gZaHta@8=wXVQ@NDZ|eN}?}OPX2Jnh$@!cVzxEv3%pYpBTv(_;1
zsXqz|iV^aBt+ce=E-1FkfWsuuEggC##pxs}da?nfXT{P(`W|{O4tjDzx+7kBDITKN
zF9II>dBRLwZnz#hovEa_BFEY9q@=y+hA)ib)QDFk;0(>#0)eAOGp4Jsh9A;E3(;`t
zv9V+wEq7?8k#|+CZ|9!Z2aq2@sCzJs^PX+mPD68*UCTy73ON2MSYU0|zI!W)5$FFb
zr!$gHz7|O~GXtmL`!!kojd2O?P3r}KIzoCofEM{#*gY4VgG5!(i
z2r0*gSZPUV0_P1{iesAxmyel%oVcME{7b60L~}&8FPj{&?LL=v_aQ@#{I5%m9EFs7
z_vu}fN{>^O>rthT*l_w5F%zF>KG+R4Oy4i7W+ZxA2fDsJ;60Di`2VM_I|CsE_jq6ti%24$t8!O;UtOrx!yx|JFJP2+)**&g@q85<<%
zneKk_d&!B3l%^Rzr4nafpDyAj^y}9lh#yO}l8Iecy*naSeRCul&SSK34UR5*Fe(O#
zqj_odeD2`x%@WR8nIG{yZb==_azF>t%5FeGpBSPUTj{?~)|xA2S*>T-Ue^LM12=K;
zvKr$>8#bc_UMs7p41uHTQHtX@x3<2l2Mcl2XUTOH+ff`&DWr=H-2D8hWAxO0XHrBs
z5&MJd??LL*6Mu(qSHe}cBl9WuXSJWEOdxyRpw%`SU#iPaqSHF(|JKd8zkCRa@Sx{B
z2KWAkz%`A7@308=u}wPefeOpwIj-%iIRU({nN9feGQs-+Qsa9`IPfgTcV<=dF}JXh
z_IOog{$cIgIFo@gbgk!hwf9~#{${+X{;Iy-h45qKQ75FXDWxHyl<+;Ime5D8q3bHOZEuH`Z6cSc23$G0q%j?VM0bdyzr}l3c*>vcx
zC0EER7RX7}qjKx(W%IU*Ex)2ObH@ak%|nDO?I9Y%@r}b;$05ZumZK)O97Kq~BQVi`
zbGbH7S2O((8wogz%b@wverV;z5>WBmF-bOOa<{145QVTtME5zNeE=
zq?F4R_Hsv`J_$?Rb)?9k;qDG@P^wTed&8i%hHMP#U-NYD2Er}Vxr|0h466{gr5C>=
z4Fu3*5OL&g*zCReqWy?|YI{sjre3AY8|
zR_V+m5L!r+Hv~iV$l-_PU%9s2&X3vcT~d8j1$?_LgHmPVd8^&Wn16<$3yy~nuFv$v
z&f@dm+2nNo+jn+m$>@K^s-A3AV{QM6<(I{Co))!Ux=ZN)UR$5>{0}xj$@e)3oVJ3$
zH}_B1^qC0wO+3pI@ozXm4u~qY-EG{zXk0>{>47Nu8HT@Qe@8a+{|xM{JEx@nMLPt1
zhW}hbGClta<#XUZ!~Hs7ar%E^#;-ZVpW*#6fE6zPU!D1X9sJBq{NJQOE}72j7w$OR
z&so+a+DuM5R+2i
zxVY!a_d!;cl;{?9)GM%A|4J+=VYp(oQDZsQfJ*V$y?HLQw5ZK+H%Tfe6vdW7J3;3j
z*QkLu-Z$+-MiCa&6%j4-E}pK8Hsvk(jn4UesLXjicwTf_|8|wPKANHNz2jSGINZ#0
zmA^`lKYGTqM~9I~|KM!4v1Egdg3QD=yjWRRVyCWD4hk3zKUO=#(__9@)9Ez`=lh}=
zCH+FVZAF=2raA)^zoDThU%Cn%Ui4t1+P!f8`D_Io_OGd`{Xs&=U@4AcY;INO7c}7c
z&@ku@Y0svw>n{|t&$prMSdJF8Y*r<4hS6iO#QmNHQ_<)=*~BqtS^+{@%LN4tPn$aq
zlF|_|j^k%@w=_X)sF5;Ir@UZ7RQgK|;_xu4s&gZY3bE4-z6HuEY-tT+ZIJ0nMy81R
z-eDnt_>w^ervlyh0@Q+Ezp;&WLl`g_nZ8+s=ZKz-NN0G1EweJtmUU{K-Z6kG!CVUF0`emU
zTAi%J4e@DHbd#0|AHmRCCVw^ubhkSjB=Kyc#=f@J*y{ZCGUfd+ZFmQV?X7vIihRw!v0~-MI=nnvSRW0=H*s$$>+B%-4E(RZQ%;u(cHF?q?Ie1?BPatD@3b^78UN
zh-%9XTF7+K0#9I>_}S2n>W0>XG{)p4BCE5wc?D2kUZa4a%
zaC7Wk7d#wvwQ%M1`(O~X+KlqbTWqgW_>Jki`B%sV{P>CQrs>pLy6Hi*?9u73VE0;5
z13}i7mOW`aU_5Mn(eYhpm1D_c(RbJx5O3~0kwr45D>mCzq2QkLhM(I#?2kzp^&jN3
z2eu6xGJSBYdM})~UjdaQySpL(ZEyOPr2`gL<1d?DG|C&2-ie<&pVy)^-8&
z_!BJ;W&EDwHfQcFpE^%EIBQ>Po>;PzIatkFMF)L3A93MtB!q`Ic>~Y>7-HmUerta4
z-DbDzE*hi#DDlpTOkAnzI>4{Enh46xzAxB{8o{0SUO%_B^&0DL0yW(5HhWvLmReXn
zSbeb$tXf#ra$U4OZ{a0~%MnH?d(pOhDJz_~vDrVrWQ*W6Z6J$i!&qd3f3M1J==dSE
zkMkQgIJ(TBo}2C&hOge>jP23m(muW;2WFq)QG1fH2O_(Az{PTBBdZL~vf;eaX8*qR
zMO(_Cl;7s_b?+ZKTCE2GYdsQ!I{ghc$?BZvsM#(nEs(GJhf}VV=`=H6zRy!zkrG(B
zy^mA${VKqv)~VR}FVD6J303mF4q@Giw)$_sIN9`v7t?OXYWbT~iGaMg2ZFXx9s2!e
z8~Npc`4fxgx^4>;oe5TG#~EA$??Z+?v+vZDwU#RuKVuYs1JcobK^^xCY4F*e)j0y3
zk!v*^O=Hdx9tu;w8s^8MaPfd5-r-dK8@N!Mg1l%F1=nZTRH
zki7}fiI(TE0T8isb5JTQ&nb$C9k(
zD{j*G&s~#tq-=(g#5C#)1ksJoXa=z^_#}b0JIn2@7#17tV`F5;iGMS{TY#WV^qGbSDdQ_w>
ztuBT7f>Lu3d*X<0jq#Cmf0uEto#+o%(>6K9mOx2uo@>;Sn{%%vo>b58ru>{s#K}6T
zG$-?Od8N*@NpnF6dr8i<5SAtGvB4Il#U`l=1g33A{DX$W@(94A`%6Xm+Af|x;`Qeo
z8ZzGMS`V{7CCSd{J4%?&U~U9`*($o89EvZZCcM|%CN4`CAaTA>w@ul2Gya~&5f>wj
z%<(*cFMj!4fmZ3AbV!v}rin@Wv7hssfcM&u(-H0$oQdFNT!@gpOc|%9OBL^<4wa=z
zz@?jy*c0U6o$BmdM|6S{BsLVZGv7Zn9=;4u
za)pBaqdy1+eO&K6k$*LnDqp;KI4^KxB#re@La|4txZ422qC5yLJSpAg+~3xvFKq|k
zN1ZbL=6IB9(AjKsX(%}GDSdB)ZWTR4d_QuWErBLHdC$cTj0IbEDPjQ4XVrdjq%70%
z#=vyw&VSXNNX|l`OUT~A=m;;g1x=N0T8SAhm>PrfivWSIMhE!W|R>
zjQOGd)gTj1f__2Sh=HH@vjFztK?O#KD^l;>aQd*_u?2_SoGS%&f%+-CTIV`<8<*3N
zBXO}XtM%RZjdwm_2!yW;?o7rav)VZBS8>qp-X2w7(4Q`8N9}sDelpRFj31;-1f@5P
z{Z5Y$o#~rCBX`TT4)I=hn<$Za>7(~db*wQdXE+mcV!7FNU1s(4)w$AQibyYY$H#s`
z0>gpiW@ZVirqSC@#I`x5LLqZWX61h;sOczAq^ZsQk~H@jzf9VL93s248xD+#5m8ZT
zL%_+#W%2G1aL6BSg5uH%2a}DkE_@#7R#0(s7g(mPW+}9H_nr#e!s!VxII*Dm2jti<
zqj4c{u?3pH!B*Lsg++p6kL9u3@!n?CNJx4v5RV3YCXU~koGlPEs$ic4c}Bx!I!X}Tg^B}g
z)>c7VU;I%o;z6mQ@lEIg#iHGdRV!OpqVjwt3zR1Ax14&>lkGkrUkiYsaeEAS~x`do1Vwx^(ZiG9`Euv4w1I)ojNiZ
z%|Z7cnQ2(H7OmS}Zx@2z;n}Zvo{1d4GPPR}4_eJlUTVV~LuSJD9E9EZFQ}{TCu=Tw
z?al>TO2-TLTl(H^Ek(wr`>g3jWlV}D(e=jgzB1tj8G4)G?$`7t!#Wte3?EZ3L}?|+%$p}!q)^r|nxHFTTj=ChUM-g7hY_)`1&SY=*G
z7h^i}CdyF{$uq!#J0G<K_2*&b0zw_=*0hb{jZ6Lm(R*zvk>
z<7s#rcGg4$!A3%3eL%q0lxeAvc5wI>X84{{ab7Lr?_T(783y>p7a47yO-;Fc*{tC<
zaJ!D?;u3`Cp}>oD$~VVZ1k@Oq_2RF9vq@M9EDj|nKN+7ca&WpR=1pmr4#Yrn!+cgO
z&R0Bqbt({#;v-XdeuxfYSTL(avMN~2v2TpNHxS23rN|%X9qK0KBaW#;b%dd~orrqa
zgo=%e#WdyGY;vSFT3_{eL^o?9DwIkFXuxq7T&W(9wAeT%Sy8t=TA0KEnwTVn2Gblyw|d-%u?f5OQQSblUKu@vCgn%Vh~V+K&5%QO3?T#}u?-FlAu)Ne
z+)oi+>&Br5CJ4hvGGoD>qoa9bdVc#l!hS9GbZwa(frCk$-`~6a{!|E!OUVtiPn;0t
zOvD$6n>_K#x>g~;g#)rBkAr(cz*-{NC~khFFe&X(sPzEgd=DT2B*co@eS;L)3L=aU
zm@w=Wqy?=r_*qg+o{f942g5p`Y9B(lXPDUGB&z4%C&y9`hEf2ukfpq<;s$h
zi(+8o-FPjAAf`KRFv4!cKdeoKF(6qKR?C|n&RHlu67@a{5{7AJzqX2Df(Tl4E4b}+
zG7m*%__P#xc*?xW=Z9Z9uY?^j~#c;7WCxg>KsIR&lsf8QD9j2)ENHKEQO9c@l@7+9$sJ5p_)w&^vp?lo
zYAcf-)N0`?;pTiN>`o=|Hrz=Q4AvNPr&9`Ew&@>#4^N{=1P$~H%{eV&yu8AcOgX(
zk!+N+95P&d3gf)=GiLGX-Dz0aUhnR?uP0MpGu4Vpx53=Zdm%k7x%s=5v4cTyiPsb2
zj=5wN>{t<@;-rK0zH=yP@FhB%<6OUCZBJ#T%p=`0*`>VbE3|jF#33d4S%$xu*u1R?
zu#7ujzi6qA)GZK3-C~&0TNurj&@IjnxgU7Z58$MKC;U!B9xc%Ukrpe*Pn%$xO_u=f
zc)a(4Hxg$b?9^jtl!{}gA2!wf1#Na{hT@@MM^Q$5R~$`_rydwYr;db_+eKj%wCR28
z-UpHGWcPk$UMT0Lt0*5PD685)xK{MMgB{%+F8;(u!k;0Q>|wnI8dubR^)=nfi4ICE
zCg+mT)~0IJ;Rd2Y
z5xtvX(ML*_g5toA@LZ|lcq0P3J4Ri8im42_-0A_s9F_@~*bGt9vZFH)5o|Q#vd#hXtgO2351Blx2eff9
z07DDFPv0j?`Xyhhup^O*#_4cRU1SN<-}lkor)l_Y4&&~WCG2f7?@XTkgUl1~$q0Ol
zG~}5H)Chc&D&t(-pgp^?nzQxZp}7s82e)7Y3zR}iVekMypSS$o^%scYR(Dc|1zc?V
zDuwb^E}5duzJ1@1k;H)y9g->r^^YB$w#cHVhKACZtKh!e_glXhM9anbSr3C~bqaR9
z4$1dt3Hnr)pO9Ik9XKv-zasFnsSx;EHM4y3v~8Nof~7f0;pnjx_Ma#yf5snVuaG>f
zD}o4)ArVY7ee1L-x&1L8d*|90=J52Q=U7;PK`-Q1?#?f~XT@uXno}R|qL0&jKGg$C
z_)E9E>6?G+C3HaV*3e{s-$;6e+Tf%?EQaDK9Lf(mxB86a(nMc0Z;0cKqenZA?9H!C?+p@r
z5=6|DTQ94VM(28~x0jCdqzB{SMYmqzah)x59;oEJZFA)1%NXLS{>L#cl48-MTk{R}
zM}cNOj#SK!l*%3NHhs(wCDi0NOGb2F2Fjt)|6;Fa>S)esaDPc-%m)gZ7IhnmN~A6y
z41(q#ZiQmTvp{pmIm2Y6S_UBTdh`x9Y*@uUY)tsG{nm}*ro*il;N6{DIGz-A7B`I{
z>oYst@HUMf&1?bh0f#ySFi#@7GtMHBs_Co^0Mu$a)`;+ZQXmN_mstX4!!F?x;Ns>Y
zCha`;O|^1Rf3x9^HUMsh2EZrjSn~}1O~71CmX@v#N5l4%5)1&_9oxUGoSFxTU%A|^
zVo>CygXI@=RQFgg#!y&AA#pQ^98J)-$~<5qg7bI#)1Omi58ocHjm9&+5$9yOyEK2<
zRRFT%BHA~dL(nx7IxcXnP&cC@+N+uHcDU>s5;J6UG6M;~icSzjahnv>xr8{0FAP7~
zWA8ZgA7?@8?=QTbPfwpTP|mG64QeeKKB%FJSs)sunnj$43Km4CElp6Gi0ElM1f`W_
ziFghtP`76CJACRmBwbjWMFk-ZiksxT&LSlh9Zo+KKoj`Bc{wVIZk#LZ7_?{A2H2~g
zYwwONOCuFEXcCV$O9f~p^o2|9fzGD?`UPP|J-zp;=NxbRn}g*PY}aL72tTNrc?#Gy
zSYD6zqBYWimg2`{DnUnk6MZeF?0^hg>ZFy=n{)0}&$Hw65%1n)&(3cC(VfH69%kc!
z4x@-N@kM(JCRWH-h6|hPc|dN|Nc5xv(AhjMPNsX=XqtvuEqo!V?jkkXU>-QC!@E19
z!&F}z+`&?fLh<@a#ETw+AfF6fTPvgq>9kD1~pKyb+DsYJUUVgCTu>U
zF4&n!ym%upMvD@$sIOwYtMp4B3VMZMRyFJjd}M#vLO7)2w&1sI6JS=e4RE
zz>cnyL3VTC7I|qw=Q54J>c1=0Mfck@UadBo`V2ar*%DQ+9%HJeYA-Qb^-wd(Ksm3d;`$O8$7DJkx}80q#vscd2s=7
ziVT-@wo)>^&!DnUu5hSc9YOX34hOr;X6@T<%>?xBTQt^gZig%T`{&zDi>HMSDf{T|
z-J@a)f{FN2x&e&T44^^B!J)eJk{%
z4bz&V??Xv!k_Q_JL5@IN^KO{D<%<20Qh}YC^bKz|kvuP6w040*rrGysSh!liS)V7>*c1%9
zaP)bB!;(P#Wau)ZwhRVN@tlQ3SN_w;C>|zxQ%6#6W*nhaw5Nw1|JZCBCNHDds+;W?
zg6y^?Jx^m)7KWVx*W}w;KcaE*Ziz2`{5z9%Z*HFYW~aMvC7=_G)&WE=iUe!kFC?qf&1kv
zdHVg`AaQ(-XoSd1JS44KIf;;`YyXqhuI&c~7$Mv0VhR!V@#i~E0PqhTB7MdUs}T+s
zVPI-Z+}GV9%&{_3RSqawOFKXt!W6Nr3VnpynPFz-jD;;y1mN^MN
zZti&i-^MsyvXX3AjC5)GWIw$9j9I2G$R(3ZX=hO=Y~d59FWsrjjhcF0n^uFms^3F?_Yp!Ub(Gi!{4QOn
zRg+$GhJ*QdAnGi&4tR@DtT{Ki1jER|%it`LB}^`lpiGK0XEkq7!OGNBtr&51iAr)&
zaV(=$uiG_Pfb2aAS3h~gT@uKoz&rcF7!24R5sb4Qht(NM(_V>w*SpE>M6BFUHXhq{
zVHu^|SL7a1bnO@u4n@G{!E2^7cgp0^bSm#_Dr>%Oc`FlyaFMQA3xg8`aJczWE~6=a
z{WlB$5L}!YB&1`J;B88}FwQ
zqRplOL(|5Im5iqbr#)s~vVxDyfB^E07@Jd9j#t?($D!@7L&7>Q7bv2W`_73^H!Z{;
zrH-HP7CiW(ks6a_-!_rq#JAlg{7oW+6|mW6b7WOUnoPwF78$kMpMF6*I~G>u^PB>d
zc^WhBShoYmb`neQsoQNk+e+BYjZ8NCfHnDp99P&=1#+LeZbsNb@BDi@tdi9Smc*vS
zY#tfNqp4MuCHPM9<#?$fglu?&CZr<2vjRY-v}ZrEKX_p21)%zS2}nsb*FD)M%nA`O
zlPN6c=TZ*L`@+7)Tds3swccp(-P~g24^a=CYB!UZC7(ReR5}pJ1;%uEm~sny=y_v0
z`7Wpm6K4Tv%_3GEEURAMU5BohS9l2{M2SCGIzswJRP#v;2kkq7q$z}OO}x|H8pVU6
zLgK)0ju~;ZLeb0VidLod{`kWPx2%3LK;3F^(MDcgA5;uG4-#KJc!|>oR@8V?hOv+3
z@HfNQyMXjk5sWZsRtB>1`u?NXK~F+AE5E8iO1^BhN6i7tdO-V?S4*E1=drhZgE)2-B~2DYP#}jyGsp`W*CVs>6A&
z5b>I09%w+UsTw5HAkHx{(~xIAYP*@6v~OG<5Bo}UbUQB-hT8^OB4bXpW0ql2C^wP?
z&c&KF7{*L#*DRpXCo&!vI%RyNt&aLzQ_A|o$VtSQ+C&zMhb*Iko`*e5EvDq8{N(s>
z)s1>%&U9(rKNH?{@mvclC
z;8G5-zN34ud{duAPKUSBucO`HASdFDMm>$6O;H>VeFh_=Mv>!y;M_MIU|K~pkU}(2
z_M7LzIw4Jvxj?A7)w1Mz-wfM{3Eg@-A;O*t{n_)cw(Jlt+}Q!tG$=a2
zX8Mq6x%*VGgi|?Oh=D`m(wm|`dV;F#L$HM%Sh7srxNORNTM9cxcWm))qFa~Dt6N8z
zOe6g%L+H;eHo4O%W~m6=(j>GgmxCee3pi<&oyIy
z#3)?ti&bxy%~u@aLGuQrSdKsIUZi|$e|v6+vH-4^$TqAN+@djp?h+`k`V!2m+bh=$
z+||{N2@aRIOnI1u{>;7}s`c|^C*JQqTX5M#R?0KFUwjZqUlWV|t!6z-4WwU13E)hGC`?f{K
zMzO|-ayp8DeE|`Zk3SV^r2o(xp)Tyz%7@ykW#vcLrdKS*;Y1lJohVFL#0H907>d!A
z#KXo0D*PF<p5&R!&ru2b)5sU(7%-+B5~bILq53U!X@cRuXNhC{75s(7%(b
ze0_=1e%^*{!s>->n|8TCP>P0tTcsCv%1Ue!;^#yUllSQBBjO+&1xNY_N@1k^|OnsVhU5FHALtf#z;P+#^mX4U22BUzYh;+nI=Eh)v1vbRcNmg0f`
zK3bN_^(@EK)l>IIO403(c<_HLNx7vja9BV6NWWO@_9x2oPl&Vj%;Qwr{v;WoAE<2tLjmTI
z4*>vz%w^ksp{`)Up%xih6|%a_h|X&R&Jc(>>6n+N1lVLA()9<%J>lgC10lLHU7JCJ
z+SBpL7H_Nfj%yks86{f_fLZPUsiw)e*>^+P9xGkgwHleJyQ-|NViIk|+;6q#Y&p@s
zT%)Eehf>MHZ6aoaK7PTe4GAFzGrcX&@g_sA^Cb>u5wUWRDE6JDj5MoyR!0xtYs%UN
z$3BgkWLlnIr#PDT6yxZeV(z`R=NB08t9A&IL(3Ex(MXT|J%|{(7_b{)IqSuHtscgA#V!4@eP8_Z$vINIA
z^dlgnz`j5)1uO~@$KEA_vWWmg3!mP8N__mS0W&4Uu9j>zs#BUFxNdPHiO4iFJt(^n
z4Axez=1XCi*H5I;-evEEh)?m{&)jvg`fRnPNn=m2dm^CZGBSx`_!6u__f!S*ySGg6KEwa8zdI^#B;C>x8?kmZ+Fb9;Au0JOYpP)98mwz5@5}d=
z1%YQ)D(k)!bG8mU}R0;T%8{Rg!5p0KBZxH#Q=
zqg0$cU(OfnpBq_rHzK%{
zNO?U4NSca%)hQogO;;T`t$gptjNUnwkb%#V{+xIb+8@ck;Cr3Z?LdT3M(OqiHw5-d
zeao3?2p`YnoSwb~01$5K#B#IWeSN*z!EQqp>Jfd-Qtzw!fpj%+lB|ZF|H%r_R#gw%
z`x$M}&X>sqZo^xZNvCb9;+0d8!!cGviOF8WUx3dEcqmpN1UkvT2tMRoPheK5ma$(3
z_teYlu+9AYxM-!P24dzg=t)dj^K198Y;ce`8BsWvyUhnzMkFjq%>2|s{;>>Z8G`K?5cFZKaTQ%M8-Q`p(kfx#gfBr)c@
z9CP}tGE%8{u&;I$exM7jwu!lhbaA=S$8`6>i1_YlSaBbQsJZNex2UeX
zYRd->xDP{wvrhdEBTF{=0E|BA?0QdwBCzc86dD)WtO-e72Oe3&>J4>Y2k;IB#WVs%
z7*DE(OkgV#dwpnx_%hXrLI`xilNGf0E(co~KuM$+@vvWJ?@VuxJ+|gP*?+AV8gcjo}~>f6GEa|JUPA{orM~{
zyu3(gw1}B_X+aYqNMfd?5vgj=Bh*S%w{Sc#(#KaddY~~cI4~I2;(#H*sG?R;>aAZ6
z3Jy_Y=sO*c*O{{j?c3QmAx&`BHF_E6wmprQFfVV9)p`&|IXPykC%Ec`zRVxgo9K_^
zMi=+@l<@*d9GJ)Ca%<%%f(f#3sr_64`50`1n}?tLNj?Q%9tBH))P+0kPGpm~G!$qd
z;uZ&OUz{jh?3FdF0x+SZ&rLYbAGDzC!%Wb3wTtd?k;ymO#_KV;R-jUu7B0(IWMP

SZRIpy4NN(f#ec?V6n)wbNieSKoKvmmb3Y=GrJc`(t@KO+neEJ zZ;yYJy7vQ6y$fMo+=M&)5#h5ilsf6VN8Sf!(Va0SR1#6LREO`E>`7bCyC|egdv$J( zblA7q@GfgKGmeFk2?hEE-@=37J1{#t(4l2Je!XMi7_od$r@kvv)omZUG(+SktitZYNeq` zEfooYr~jV`K_=7f(&f*C)FjOo#xyVmxC3M_K8_CHO|n{r9_y1U`J1m{atGw5&zh8l zYDdLigu_@?eb;S2nrp@tP*yIl{JJxyOjHz{+@z`= z468|ze!;vLL4u^a2wcTtDtz!L7SHVlkCts0aWKAAY(=o2y!C?R_G$jnEZfdmEo{V< z@+dJBK?YRk*jvHKSj`SH!pVYaw~Zw;?8K;%qpH38-?KR9`JcH zD3O+~qzx4R7!5P zimnK1dry7&w2$Lss=CT4(V1{S)b*y8cEnaF#H>I6dyh$5v+9l`O}vSCq|n~|(m|a! zOxb9HQu5@!7dMXOQQUk|a=@uxv)oRtEZSG3kbH*EnjzJK9qo>4Q9b0Ur(~sRXD-abxeVab4||0JIhYdXs5TxIySpE@veBG52?b>S$d%+Gt-cE+Vnw)u8HOf@dZi zkb)R0$WIP3R$+5(&G0=8&PZT!GCVX?osQ>($_3ktL|!jbSaWpT@JHcj%6k!I!LEjb z@GbRsqwLf{>6}g43sR0D3;{wUhmGqai5Qvm2_3JL44!cJDHHCF?bB(#Wg2+Fbrp+E@EW7#$Z`4VfS)Vl)!DH& zsVXA}uisdDJ=f%cIm19~yQiLP7J@O`Tz`j@q3}zf>k7A*3+#CkPAy!~u(%r8O|7KP zM!Qbxr)=-g7}KB)c~!2TK1SDra$-HjcLz{2oDP~E_a9u#`(DBcn%T99XGW-1X!M)b z<4xj( zCy({+58*dhut0;9jTWY@%#ZQxe+pLQx7eE&i!knF{1MvP+|^Z6i{CFW1%16q4U<|T zUpOkQ(S|U$#QScA&o{4Zu!3$u`)D;A>EG);KYxqqVbgW3670OmCVWB3KB|=^ntJ8w z?cAgi&81>|n%cy~zgmIj#+V$Gi0QNJf2-T0=kY;Qa(aDAXCf`oNk=gdnq;%zHeFOS zM_YJZ#UF(Agqe?y{cJ%NV4Hq(6e0nqt4d@$ZxYaD0<|zZRWY8aO9pNxxlAVFe|EYY z-(+fqWBw#(Yy#(dYYcr1dwknQH7NSyjG2Hi(eSNFUvcrj$=wGWDiSr328!bXJeG8H)p!yB1OV9h$vekfJ*ycvZA zii^WsFo|W2HkAYfg?gnWq^ppUJ={!~w8=pBDbJa+j4fNwRa6U8^-#?%dw)#9z~H5Z zwF|n_2@Omq##8OwFJ!2x&I85coTk6-dZ5<(*zGWN{<+nbU*B-Tdd>r!DfYgoZ>26ra<=K5h6@_m51yLU7q%;$A0z)b9-e z7dLOnh%SCZQzOj~#y)jRHpT9;-7UGt1UX_R#O)25C}XJ*G>NR_^a{#h+F*e#v=aw{ z^*4{2_`OQ^+o^<}_6~9J5uQ&&wvK_#M3kMw$fTtt0Tq4adc*4ioL< zjKAu41f=hc)iqstE2F7Sx}5W$h{QPgP%Kl<){yGBUoCg2^-{stF8O>vqF)#l3~?tE z@8Sc87%mH(6IZ|-9vr#jwfCiLtC_GH3eg40BH{^=jb%iQ9d^i>5R?%}?>T-rar1kB z82vCSRCb!N0*AtW(QUOK(_rNuy6DA^C}c%Xvs%sBIK6ayVK^bRn($-Kpe4<&>sb!w zxm2fUb#6)iTKJiFop~kVa(U=nn8dei0e=c#LnZ;?dbslA1?QG4kNa5NP-LytBhM5) zK!miZdg2P-0bPr$&fsNN3g(+{LQwSH`1qC)h~U~4rVC4)Y5O+kei+2|vNy?C?Ic&P zX=-m`LmA7`!S(1M^(Rm}$%!j91i0N;+1rqIHH^5-%y{UKE+rU$w|K3KQMFhC2LzWp ztj#AmuZ~v=6mmX0dBt^-{h+-DA<9hoYjx^6Nv{U?%HqdeY=d2Wccu+1!zG9%o|%S- zyO1(T70H1~t;^*D$I)jAG4z)tu2mQrs4bZHF;lX-zy?_U=1y;W-)R$u%$wemJ*&m3 z45vUrK5&wX4;zry5VQJx?g+`~Cts*u?1W%XkahXgWuEN0@vr-x2gKCs9wty}xPGzQ zse{w7ldq|Q+JMT$0QhQS?;g8qE{|3x&D)m!r!H}URj4eZ9DU>5?&xp5T!A4%frxGw z%l6ZmNC}A1=`1_DoU_&0*+(cGgV$DWZW(XoCs7dVyC2Du=QjNLrb@xXRW+nmnptU8kGIAb`<_y_uBmguy*9+txjOnVTx zz_<#2gvlUHvj;I_1o&8y8($l5f89a#DAYIM;TfC=qSlCI-pP}ccAlx$f7I^m7M_0G z#O6ldk12av920`3Tg4n6rJN3WejM^BmME&GwqHq>4+~f(OZOcFYEKj_J1v zxRJiQ5gOwB+j^!pTuvr2K6ZTONwfCMlRTz)_wLcX5~qm05L}lG02;B%bs5`nCl1(w zCNSvG5Qf7P(?#xoW7w1 z>vt@fBjC2NrbWd#hxCk0ZQ;T=Zf~+W>{KO5Z=8O62ziwL#PhLRzE-P2hl$^*jKHhm z@nG?Ff?`T!E{m?jSIeKLg+&vsRdID;=W$fXrm!WQ6jmLEkAd!k(F) zc3oGi(6H^U#c_ah5ZnR_a9e*Mb&dN`RxpTOCM ztz<}Qo@K{#>r#90_ZyZw~0bx(_{kk$c z2TE*8kn1{?zyVfRHi`vBmbBmg&z`W=dM8;8s#NaCRyxSF7BZrSevSa%R+4@nI~_Ly zsdjj$hJk0c?X1kqZ;T-6GQ3r*b=GmcZlD1)9uK7rRQ<)MxH z(D6lRjq{T#2(;;jE8TQW6%ZlM!|gEPJLHRj$YwtD0V9a0s&aC?N}yl$xS>xSKrFeh zOV{HChM?u-wx%xGb$eaFg#+3dd3yEJ^tPyWp)J4tg;uFrM3w^q(qq(XRGkqC&?;i9 zh)s?;oaz-p|2`Dz_Zz8_mHQjFLcs~wsEV{X1r7IdbXqm9qbxxCHw^St2{fHr5B!wc z#UhM_k#tHBluFGRF%4qX70N8N1Mtg|_6Q!O>m^&p!3`0|+^STVHXY0j5VHV3YrmRu z(QB#EfA`ihr2%b?$2j|_agpbo3r>N@3!YRUtx8my3+Pn7Tmo5sb>?Za{vDH)ey z7bjd>J-h?KPI>DJuuV~sP)OUECi;c6-oq1yd|AYv?E-7Z+@boXMX zpV_x#KPMIBBW!ml6bh-xupKk1C7#r(>v(NUsv``EPRORwymuf`uN%sXNzotV6dm8u zf}&qu8rBm-TS`r#M}+?k$hxPtPBL%(u+ zzU{_C!Bf8oL80shg>9$0RmZsL0;dY=KKGWuXzKb%C|- z1MismEZc}DATG()%pu4V4T{UBvzdXO+~3GVbjLHY{nEX7slc>)r`kfCw8|9)s@ZRE zpdYZny6LHb+B8QAg#YS=NLYi_qtSA@JT7=ArQ40zeM3R>AzjzIec_M z*{mIkak|!w`TgbX5}QAe#Ht~^?MV*wj6{zWTPTYbu4thWkEqr4n{}yA)i(_>A=k{tel90UbE&U-ljKuJpbHr>;*x)Oxqbtc z&qzMZiu{Xm{;jgvpMjWU3UdpszjXY6tv>*v#&y{L0UG~*aE8SRgaTn)Xa-r>zrXYP z)0tA&4A*}JKtz!Pq3#o4{g<0S0Q!p)8E8dTnQk>est3FApMRdx2YskB!Q_*l!qQzj zjf?;F=$tk&WEBEpA@CpYb)6^>5}G(Mtq0DOlB!F>UqOx1xwxqD_N}0B(Go zCn1X~juQj6ugq=FY0o_Ojf3EY1h}@6_UimDmO$8(17P)}+}fH4_{Xv#5DmDdd0&5b z+S==|fme{fqxWu&*Sb^l{HrDXdA)T~)Aw$D#d4vu-3Iv5O5ldevbJcY=KAaWgw5-s zA^#y@a@jE08L(=IW2$+yZ0B+UzpB7-GHGLteZI4BXZj4!5Q#g z%gEKee_ZHUxxTUNZRrKitQ~|keO-3!9_;q9!d@V#WG>^KG(7p`<2I2ldf_AKbH;g+ zXust2OEaUe_U)84qt<@uhX9)L+~80-R9{2fgJWYnj=1L-mIUb;iPLRIJ4DAdR)Do&I@h7ASInkYTzxbi=X z%$5G358*2z(w2TrN0!P&hjFrKGRu62h;6g#$DaN zL^2?xRjY`YA!$l+p844mI9EJDI$Z$?B}h~>^yq$=Y=qNBP2H;$NEsIdiN{3Zr%}{mph2qeE^#?E<*LK9`=JdXp{h+(5k~XMneSnsZdS^@ zP{?@+rNQD(`HEdv{7ZKSM8FV%B5l)vf6YgvO)9#BPIn{qU*e9dZ}_P0N%NGm^=z6s z{*y6Rbm$dxD=-;rOKgO?TOJ1c2Ue=CRkRba{ zGdWP;=994S@t;-#(Eoo-i2gt)+C8vVILh+v0o}ss-#IuJ)hmQj(@OG}Wa%3iOb!xt zWrs@nm+b}E|4)Gf7&U)oEbL3#o~I`d_uIXL-Q)wEpRy)nFkbasaU#=A{~3RkC*l(4 z2JshlNO)Wd1iqW9U7L~E!$Y;SX>c*u7^D_Ip?3A3*_;=K z*0gWaK_R7SnAj!Q5&!%nA`GZ!o}Wl}crCJXafqA}NR;qD3kAjM&#Tatqo=H;MdkkZ zh>U|nvfS=jj7~krD!lWrN^nW(O=4?)f`#^Z>tA$uj8`4K==CMCZM)5IYhQ=|IOX@B zf&T7NG7x+mEvOjs{m%9%Ihm|E0zYnUt^yeg3(JBIJM$mOvcP~H#{jqZI8_BzRdP$m zYoi%P6jEwxVFQDldGylWM%|D9(i5c%>ct>ceM!R#jEeGsKCs!;oQ{g>nAps*|F_N8 ztX{A?OpsB!VS$hLqTP_Wso`zTl}B;s|M7WxK=UvJqiJ1GwmBD7X9Eb2;YYGA;kGZ( zeJ+ytmjm!CVQ80)^{&lgYe{8gVr6GK$;sm0P}<|Cy^QBKV#C2`MiJ-`QOW;0MHg~V z&uOv__`TdDh+jBib!`yX=e-sP|wNL?bu>={F4i7+u{20UWB6q}n!$3(v z!IC%+F)A%_|A+mL!hg-b3m-_tWt}j%^Mh_UY$mU{=9AGGJPRwrf0pWlKd($zc<4pw z#s&pnS%`?3|Nk?bNI&Cj5fPE$Dk5*=rxV-ZZPHOAN1Znn>xA39e^nnSnGmRFoL|2& zPEmEsUO{P|=Asdn_a^;s3bo#QXlK@YZM6^<^M8i&dv4p|RpfM1J2*KkcA=UN&iO|G zzN)miOuL!?jUi6y!0sqOMul?8s2Lg8UzQzP{$(tU>pB`?me zP9+E0iUQQ_KoLLGn$sD$RusAMe@y~tb>eUd>umqX1028vFu-3)2So2n|6?6XB)`sm39uEW=e_g8rmT&z>6F0L}mA>zVebFp@H2=d=ffz_(@=l+OS8{7@(~29XKdK`h z7j3$U@ytIP=&E2=b6zzb$h}gf)~z>?bCr^kl39|+tzBoiZ)av^twVf%e*R~xeJzlo zHK|QSb#Z7wnq#1WS+U{5u z%i7|LrqBjsdyNnDT3@i@w@%8(D*db#I6lUOQ;?=@jL2&km}Y3+S^43eYJxYT$>&?Z z!oretSW;55``Y*(a&t1y7y>&=O|^G$phGIl`<_y!-6+`c;*pVN_lwlwoSrVu{Td^w zex%IK=-Oz<^g++Ga`~Fah51f!=V9T5UQ#4Kx7xz&VkC`zJ@G5lNK^VhuKg4p?2Z$J znukZq1A$W^$Iw8J?3?fB@9y9G`UhHU#4-5@&(L5DQ9&v6PBOB9I;f6t;TrbO` zX>aP7^v`wBi~CC^g5VCTFjcAd z)y?dr0AdMK3eA294-kMa#ZysMk^pg09sTHp`G5;7X)-L0@ZcUrEd%tzqQlv`c`&0< zB@%~<#2@Mzk5v9Pysiq;s`|oT^^Z&D#kGc$kNW5=_=POyRYtS8l+^s>-y!d2eB9si zRY{T4-90>7cy3Rr6<|}#9Va;?3S@XiwzszrnKSi8m0;@gJUAG4hT$XTV#&NEkRrC7 zYwjaR|6FhX3Iin(O}LCIX6PP^C`M!|@ZRCDri?Mv zN$?zlYD)c6VYD+S+l!YU9lsc7PI*R;}(!Fal2aRtHt{TS|n{v3cy? z7<0kM>}31g=eC=}X=$6LqsE^wQDb+JO`X+Q7rQm}N-tT|Hj)4^BC z(a&sTBW78LLA}+FkB<&(toNgw81EWAFHsKf>FmQqkZ0ulZ%qq*S34>7O!imHH9oH% zy_*k)(SCLu${FtGdt?yymzNIr?e`KJeBM$?Zcw(3>vv*Dv+SBd)WTnU|BB`G8VUX2 zIgQ|j^?hFM4UDR1k>OiJDF4oBTA3W^^1{$g zm1o*p{fmd}lSA(6_tt6pjMo?0mjiQOLBSusw=tG4ww=#JgJQ3~O*=MrHW%y=S2qKx zfTZinHm-I`XVJhgi2VoM7~UgU0RKW}qVAN_YY>JmtG>ez_;gCLrUr(%&v;*(c%tp`G>aQyH8L3u z2gEgE@J-C38u)rc?gqcBc5vQ3_mTp6{Mdl(&#oJp5oad;0;K&@xcT|_tZeFY-yhrR zs{jtc4@ou_iF7l5`QV4g$J9{^`B_(d3|n_0Yn``8tSz! zjPG<%a%a;3Dc>Hzs4y&5-lE$pc zMcQN#;t@>eRaWlEy+!n$FT|1SI7a8E^A0Bfz)wl~4mmS+(N*gG8W7>+z~HDK!UK3l zJq|^&#^POeR3ZF}73#DHZ&pl6uI$(X1-uq>P*^-pdAk^>;wmZylrgFPj{JBXv}nWo zv5SYQe?n7#VC0;MQUx{d($dfi$5%kGQY+TqCsYK@8~`_o6=(r#JH$c~HocM`c(<@WqK^gwb{%YFJow zLPoOrfbQ3?81Bc(7`t1jt- zq3S^?7SYqS7U$TpNGFm=#x}H5uP8n&Hn;Czy6GaLVcpi=9^0H}c*iMA@hpt6S_)j^ zXS!%)gL8dbOzsgL%_O{Pe55}7!!=kH3w0U`s$y4&<0W+m@+#$6YVLH3`h6)@@%f6y zDv++@#q{dF^JUnq787VI2P4d~{A*uLW7Nj$M8r@x>4JiWhQ!k<qDxG2|P*I_p&Tw##Sv!bM9wwF5*0V#v1Wgi_G$(ojg?ZdkOd>u{~TQp}T ziM=yLJ>53gNrBy4^KsJs+Y1VqA}$?7{#yOSh@9R!IIH!>l0pFkiU`AzSI_DDDR>)# z6Sx~aTrt!pGdE677Uk87=4HXwZ1)2FsZ-Zdj1xh z#;`{-cJngua0UxOYa%53SBBQbC!N&{RxO)rrsHNIy}gq&{b?9 z;CZ$bwgUvQRQ%{zUcP$&-=z=z4Z-g>8NkA{Yn}uOWsaIW80y~2YI}H2z*E_hCtz;{ zt$MK()a5&swg;d+7E#>xpq!Q4v4)fEI}GP;=Dow+`s~4KTcht{S+e<57TrKh<~K;d zI}}_>h=+)LuoPAanrPs;eg3m?@rFXQn%UiGT_XN%4xh%N?!E1$G#3ct_M-ECav{#f zXM4=SxM9VMU$wH?qET)nU%W&l1p#T?tGc`s`;D0$@k0#1Tmg6;%OhvYPzi0#Lqi)> zLgiK>w~Wlxv!`j59TwP1Q0o5qi_Efsh%NTDs1O2oX`SBjscvC(bQjFA~7S{eC|qi66jKka)Pm9G$DIHjCdB z*bd)hSW&jy`9u=6nZA5eV$<<@{kTKHU*xMRmG;8s^SZ}gsa$H^dbb_38yaX)(=L?S zU@e`_ShLmzjsbfoqv_0_{Ry2$jYbpME1EpR`y*EJa*--G{zqd^C^SdxaAdj$Um5%Z zN}UFkCV;<~5kZ+HI#ru|J}7*b;w zLQ)Yhl~7m3#opWA^a|K|dc^{nK}z!bfm~UhkY}-VqBAa`iX643=PplVLJ(v^{}E{c z7jp(1?%I7o-!D>$rpxe!D}t@#15LhHIysm<#SKQq2u-zRK{WJ2f-4LAYPJX@JsWwW zM%F1<6EtGnM)udCXBcEOYHSQmcyw~pTf_cN9lQ`tI}brr2b9l-u^{L_6%hBJmI#Z$ zCm^Dz!zgOpZyBuMgy}HNmPVt=O&rxV=_@}Afc}2ur0DNVyZoqKOAO4JloTc zBU-DMk1VLBc)T=AfdtMl&vVU{xHx3$m;n7?4eK`u-`bp~YfqyM383<2m7o;4p@^Xo zT8Rj{!_70wCd5Y7v~f9qJE5djtY>pE+gP~a(tXC?LaO5YYxpHne&}T-FLyDQ)hBUT zPllWUx0nPpA!2{YQw%i~pj@m2$*q_HHWo)Xuk222to@g;{htLssW1vM;{2@$KwUun zt@!p5j0FGrDE31kR0MSRG8Hw*J)4cPr@nx(x9};(?-oiTpr~rfm*oVCh6P1j1v=!A z!oS}-2<1;jUghLlY_&|P&3-cn$K;(Ud8Ok#XwUmgEhd6;q5)J!lhb5Yazk3ud82^l zDDj+_x>awOk(UT6p&SApqfV>gj;PMf8%Rk`D!s^P-gzrvxu#UVxxA%0^AsMdyDGO1 zyu+lgPeO6LIr_&Bq?+tQ_x+)q?YVBAKkM)VtRxa4!6%OOGuc`1D*|s=HUBG>aJ+dE?<)^mi!qVX$RW!TWW{owNR5wpqGIwXE?#hPcE@tW~z`*wQ|5OSUzhCLgPp8Dna@z4}H%M#kazr%BD# z5Z{8sf`Xv_H|7cLkoJvg$HWUyu+I0(Ldq)VRTrMOUB{k#_G_!_*V=}fL95jUxW%`F zuU3g4(?w#@pVmj#VJv?u_iz3FiBiM_I+`;)G}QNLk}tU4ask^u*YvIZr6*Rc)+K%1 zVM;kD5{=oz`BU&`B+JS`*}!lX-U?j^E;NF#;8|?#m3BbOB!=F?aGD?w$3QWMb+>7k<-zN*A`VrcO~{N zUJV&Hbxv(pJ+n(q=CNcX$`kTlSJjJE9=96TW&CWF>#fiElg7}32L3#cakKWbRqvbO zqx3nqB{U4`f9!}4rtpL)>2-3ftf_T;oloF@EaRE5{ zOVHSuq>+lmWNR#C%h==9saM{bnWN)1gKxLcSUNX?=a+{=kiNpSUpQwg_@*^`yZeO1 zJX!@%_uG|6%+!xp-`73Mg}1>M$gK!{kRQ?FU_KJqXLmP}=;=vGbi9FM26=EKWNzbYLI~ zNB>uoZk6REK8uwc0Y(}>;=BAm@el_s@HMF4)%uX0O_ zvE*m=1bWRdw!!)yb3n?9wt#exEiL~F-IL8I`p@8_+(WM6<(C&_t=yKlcx%m z#tiZdzXaM;&sB#5>gjgaBvaUgP)z37|G5-g5YXu59Viwh^%N-d2+0kf_p9(o0sD#b z>3grffdTi{qHW>yLH_4$%e1NTPYIQ3LC2T#)n=DWUOZ1Id6-CfD`beimFt0n86MD% z{ia{7RGMyn5@GT_IofJ_#QsPQb3SPdRa4i;txlxZb(d@5QycxRv9zmZVB4}1Rn~8H zP_fqZobh~dF>9OSaeMr5waVyryv#n;VaaUkbNgd*c%r)x8pRGEJh>gbb-!7e?1+Sq z9<8eDDOqsEmeO{zVBKY``i4W`b(0L$DUPI$Go62ZIbi|zoC4m=ewe+=(tiq z3JsDSe#@QGCzjI1+gZ_fU`qZw>WIemr!wrW$pOYc#}E6pjpHS)gh=ARVhHB*8RWit z^{N;37o}pvhwW0^sG=#Bdb8rngo=b&M4D}@#p6!9X_UsD?Fc#s`+6hniwOD-RzAU% zgz($~Y3!})5P-jiO@UOh%h0_4f`KtrEP2Os zV&hiVlgI-dFEl)^I^lpDUK*M)CHLX){!JGFg8LmVj;L%FG#gJiDc$Zi8SX z(=+P2ndX}ob$pamcW}X zQdQVuxM6y&a*>%G4YT`pAeuRDt90HASlH&!#0cZ8lZ=-C)ie`GMu4g2ex|BC)1wN( zD!cRkI<1dVxn})DBNXRt(a=m*hcTHMr^E<~{amp(^|yWQP0ROsfXDoNOpzwWs*z++ zrVn1_vhm1dpqYGdi*eBTNxonySFxjIEqNkeDdr60=|(1*IXonJ=ImXzn+0Eaqamc2 z+EFb^n*9>_pAl@T5z3K*C!m4efj{wCdVLFxDl3chV%&KUEasTzr}nrajY7g}pfgNU z7~h zV}BF&-HomP%GYU(i)`;ub0WQR>7GjmkQAXEj`jDvX9@jwRz1DbbpZuu_T`svo`4~k zF1&(J7$P*V_ z)AGGC3#CGPxGjYO_gbU)ew_dHS+mi-~fWm0o+l{ySZ>tr2#~%P&b_34Cl=U`aEwB-bKo#=q^L(&=KhL zY%)95)zuDPq|krf8a(r2cx(r0(t7 z`GCwRbKU}}QaEw8_fc1m7X}Vm1n3IJQIk~4SFs}Bb|qgfWN3kks(F>-rJ+Bl~Gxd7|H6 zo=LTw+}VHezc9Tp>X)nzd^Uh6QsxHn7mU6=*(55#gcazlo#=CYf5w;PyT-oD3-6a? z`D$_O^NV}?>$1T7Wj74UiI(SOvVvt2TuaTx%cn`i6V2`P`2;bia7# z+&;>VizxAklH7}j58uRsu^7$0cVH$5)&3|)4H)Qdua2G%rQvD;*<;fQ>I!vkLauHm zm)YXi2CDC1zN@e^8rn{`>+5}AYDohsc$7w?*TS^#d%sFcvl@)a>>cUIa-pdRUj=>R z2$3jNbdOdGjC8w}Y2sAWv^S`(StV+^EF4B+F$XeKKW7_!QKhqRM?-Ek;xGHG4y`8U z;=9=K8IX8qq)X%IRv<(9y11rRTh6*I!laat1IZSfT-q_UQm3Xlo-3w(mYr{yUbiM;>3M1W&gNYD zEhivcyIe95M)Z}M=8K3(m>%cSjFMU>47H|O+Edz*y`VANh*IEr%KPGty2AkyBMxyu zB|}8|@Cd=5MacnbD!l({1*TJ7D2e#Zjt&0>l>*Cxbvm;>axsqQ%4Q#0nsm`+0b8aQ zTjzo;_;(%a)CO&CJd@0N-}5`ESDC_g?|SFe(%E3_R+zLtYwx?`JUlH|efx%qZ7plh zm0;^ajy;%BMP?$9r@_B+RsqoXs1M)^`s<-2U@VIMdNm?aDc(b!=)3gdcH8iDwi)oz zR1}1+8lr*iDIqTe_u+!%G2HXb^kr$bbcJC#LD92-KuI)oSG#Coe$G7v#tUJLcd-%} zHk@!~lhj1jKQ<^1%oWij5}j2!K*CF4#Ks{03ah^gW<5xDf0gHq_^TZ8`=@~NX90g@ zv<WFl@);?7lnfz1}e+gYI~R8elT)wQRyVq6}xe;2%i6^ zqX!TWm@)?si56mdfeA9BzZ0t89l(?^z2Q`$m!78Kmg%&k123`>5*0;b zU4o7HE0P6v^?(GDqBZhRbIK>hY&tH|+F;FKa$32RnC3MFGHh%W(Eqo;@B@2^{6MQ_ z?54lKmA}~k=^*z#E8=2>dQxbTW{x9OCzwnv?(a}WybA#usA~g>1@LDcZuX+05G}5} zIui&q99>DNdI?B$f8OqwiJa9%wG+XtLRBuD_Uqc=x=k?58QN1Qu_#+Y!@eGSc`QHguvt%f+z(C8rm^9aYk$K&|{c6q@RK zYkF-+tumS>eqlK`t<9N&sZvlHC;oe2z%s%I;4&$6d_j}vQZAx~EbZ^#nvtaI0`5jA zsv}hDk$)z06O#z2Ex{PY#MBJph{v4Y6kwhWj9=2p0E5VKk4V5|+%~B*pT`CI z<^ExB86hR5ylNwPt9THmh@bzmeJGteysvfl5Z_;42<5vbpg|{@9D9M z3n}Uue}wIl{ol%Cn3kzANn;`*`TLlr+q}(TjGiCLoG4>~)N=e?dU+uFt-EgKDn`Zp z3G3XVwA9rj*&r%{e+*(%_4mTdR7wWLpPyFD`=QhDdzqgy{nK!d3^;Mk8wj3%+I-#&0h-y%MSk_@Kg$rG3akl{y7PNfWUqni zv>Hut#x;%L^Ee26znjO0%X@o0KL|hUw0-TElp)A7tyv+IeY>%ERz-THERi`&e2Zs2 z%z@ruOsJR9T)+1=*L(t8m|fI(Z^!?hk!WyGCx^<8IA6 zPLAPzFY|G16>XIrR$iIud>pGrOXEzDOUTtbsf}&V`xTXKD>K&oprBOyok6%N;Lets zf*u`Ye@%lxGStO;Yy!0I@+VEn?h)luM(+VDBNG$slWrLA3{D&@tYl-`JWxxH??1!M zeaHJ&oKK{wfkBRV=YihsasA#($zGlBJBU;=*GFKb>863*c?H&LscLvt$Hj#WIrdI} zqvKUvhVR2!ECd=)1HSD(ObhTFMZfM9pK6(!u?B^7Yr_~&QGpKrCswSA$ThMOK-HCtR1K4@%9<5xh)i)jt3MEA~Lu|30PdirH8hE*H>pd53Za9m{eclao zhC93mWsY23z4-S{udPOgSq#(ztzARrd`E`c8O%qN6!)UjTX%mA>LhVlr?_(2q=%Nb zp1VVl0NOD~Y}(OW*Laa9J0G~vX>~M=*iRqANAzZ``C%@ZPE_9SiHK6LImR_}eH zR#nonv8j+)X>jJA;M!3-U8>$8P`7RmIZi}(IH7x0Ot^H0+n(L@{&7&)ofKKi;7No^vzk@;acA6Rm6TXNgod@ zok4frrM2`8s4aKy_;zE&M5=PkS3p2u%S}^IsLy8!dPUa>`Z!<-8Zc$Q5@-|Hn!8j? zXh1kIuG+`W(^3DCGPG#Xl!ElKXA}DkY@Ef%Q)bjZk>?F6#EotYoJyzBWF#SpR;eJN z-+H^bUv6GrUY~;swfT5ZH~8nhzSVT_&hc@+LSF3kr`bpkW#t;l$o=+%1$PuQv@rE* z^9&&Mj~3kpx=u_AQRc)ml_m^{%w}Y<*pZTzR{YIwj;IWd4SdT~`bu;3lhI90n&U+p z$iVGoiw(&S!R!uZu;*=zYvn0JE#~fGjE;Fz07xN(E4Lk8@G8=0H8LBlBmJX=y5$aq z)?jkD_ONHm!2{NQX)}A#bo7ehj%A;r%EB4nSJP9GW+h^uE1Z4wSd@S)L^szA-6+xe za8XD|Tz$YF3cz;a-Oju1R7x~zEQS5UXu#?$q(OEPD?dy0T`yC4y7VXNP(~dK z*>&>G-Kl>vc8J#~(7KqPgR~kc3ROzIhFhM`mEv=_c-ZKFy}nF;U#H#d28*DJBM2eG z1%gav4g8%@_^hG>5%&s2&AjP#jxMgTjLBMHR-oE)!r&rwHT~9okehki6=KoVo0-1l z#yFW{dFiAakYv0chJ>v4Hk_-%E!4Bul&@*P!PLgi+r z$o-gY9|3Zv)f}tK+41I4#~4GV=dIJL2k%R~5u;*!rcUI&tHtNTg>%AN?p+i4O9ey^ zsccI$>2|^n5E|+G=Ca4kHiJU>Z%z@Z4FeY#<)QQ#`r}!;$ux*JlWOxfxeL5|zFvQj z7<#K##e;}*J>+JyJ8s5_XHGHRdbEOV5Dk}}yoW#Loid2Wr$GV?oM0Rnkbn-zaMN?Upz&;vfX2VLyTmkA*l`vDH>R1I`^)P z#2A?-h|^?&eDT8S_`H_ywMNIc8nfGK389Nq25<=H$)R3Hko!nxr&`@nMaFcsMWmT_ zXIx;vWZ#(Dd3@ALlT7rF-+8SM8v4fsNpa0s=-v;l_s9E7kF*Z^i~=CeDC61OM~=-O z_A2Gygd}LFDFFool4A#w^a8KO znXSiPapqiH&bQbCRjuw~Q^3}IJt^cFP3k+M+W9-AlEw|RWLq~KkB3e+)g}iH&Z=F% zmG+V-WG6&g4KNxHFo9VkL~H#_L(D|`0I?zCR!v2Jp-Cs_0Y;xCxLc;>j-KcyFi>P) zo#lA<5WQnmi7PEa{e9Kr;K^fW-_(zVSwE;KG4B3IBc)1XsW5^|nnX4mbMf)77hMl$ zcMF(Ber$^_!Y<+OP4m(DOb)n{UAxS#wC@(&l3hqDDk_hTDbrRO z^d3JSw%kL#U?~)Y{_&|&rcEJok$m#|j;z4-m`n>?9E57E7ky&LxeT4kCEpoyVP~L0 zXRmD+=hy@zPy*w z+xfY$*tAVTvE;H#(63Xc+OZ)t{vkhtYBk#Fn3umM_pcX#Fm`+ZDvu0zTiGx)T4~EM z7VpiOML(L{Lb`ybp^?!F0CsiUtiu)FobSG9(XrLsRnGNV=McH7F`F2jBeeOO-t#{c z)zAA%G6lDFuAx#|4TT;uoYSh+PmR-!k*!aPD1kmGXD8@AvUtW)V-9@}2yK4#kjOjN z(c_R2j2;@nCdJ#4`fXfs=z^e;JEbvY_4+QfR4P%`ihIF5WhW}eDHRcq%~ic-dkeKF zT$GkK6~d4HL^A#;ujg_LeaP+Myi|gl%jw`ED4>_L=$N}=w%@M~o%`|DE4emhbukFK z?-U@=xDmSVi48Sfhf2Of#pky@l>&W9l_t761+f$B$HfP*tN9cro0?9X0;Na+7x7`Z1i=}U#8^7|YLR=sG z5o%oH!MPRJwY7D^3F`GLu@j)wfR|H86(0A^XyX*?<6=|LGLI=g5I)(EN;SXcl~2SX zD3%`2SWR13C948Vx_PhnEI{g&gg6D;`p}^rcR9C)A#c6MB(C>F`~yf;YS4zMYL>se zPVlm$m7FLP^Sq`=cid$&XumL=zwsuGvU`oVbB%#bgg`cg>Ybf3_)W=+uUgAO;DjJ_ zyXvk(NYr4fS|!O=4c1ztYlCB6Dcpu+O-e(3azN}*Dp{GtjFY^9Z~a-9Omcu&%i||5 zn-s%bX%-IQT*E1=c^@tJ=#OJkkDu>*%(^z|SO)=1kvhFB)#`CH3^>&CtDU4nBR5;F zYOx3<4S;;Ouv`sy)j9dTe$OZ-Kn%GyWVe6SaRU~T|=@zRjxfPP)o?M_bBFTDT1sApSnupf87_v2HW;iFQou%SX%7IPJ=@AL)HP>h69BNK()ooofCQG|3 zqn@XyznUe5)DZBrE$*jO0XPCb{q{V_uo<*T-VZm72y;GK4(q7A8qL`3{&tMrvSEuX43StGcQm>GOcJ9o&H<#rQhbeXx! z)d}qR&+Hfjb{=FC=K7uBIIH^mY47g(Y*cGZIlq%SaLUmU3NQv_YtXSzzQ#oAVkCC- z4+wNsq1S$Uh0lF*bZ;zbN0;|qIImn8q-hmz@C8TRo%HsH> zk0_XE?&bIw&m4zGP!e#{M-{t6tWruS_CR~$KtrbwejBO2grBv~(LFMQei>X%coG|_ z{9Q)Z1E-WcH;K??BKL+U*H@bW>L7;$5P4Y~XtoKsXWDk>Q{T}KEw=ZOvWcwT#rYkM zjN#j1qAKQ#j#K*;kSB^W)_Sl&;~>y^(G6LU9*k>p$u-8DaVUSvb9*y&2lYBT$Z zUTZ!3)AQS-AMQ&A_v45Cg$hev_y_fZNxAV{)x3LM*`ND{9G-Bk{6Z+hPVoKRHv*pm zv4=IaOKZ3Pkd_`NEc4iU7sV%v1azXjKGj;zP)x?=*kwy2ABw~^Iv-+LbbA2w=l0vS z`36TCiaU-Mb2Wzo-AGo3u%{7rWW5v}Jsa@=))R9(U>CdOmOS0uh^k=^+>t@A#YwEp z`j||7%e8Iykjog5Cm_6lW@f*VNzOPB9~8(4JptC@nmH_}wguIA(hO>dMN{S0+dp8@ z$Z@LIT89I05YWiO#O^FulXbP!x%j|mGLT5;n~Av2lw*I+#tvMZ}C5L*A z=>dTsXC;Gr(=>a>?!msBMPPVaUWqG5fvB?pO8p4LVIE5yeNKFD z578OJnudb+yJOpvGZoO?gvT)!?wS&|y@v-<&b6d8!tcBvAVHeV5Vr54wicU4b7FVm=>fDvxw3+BbGQScl-M z`{4`$25~FW=JAr09-ljCweT70A&_6*ec=~I0704%^7$)FG=PY78lipN_izu9ZY+KlOUfLQrq~9w1~;g73SE^n3mBG^XP~`* zkUw@6*g>KGhBaCX6!oue9=q#IPkGNAYu@$iB7$T>ReO zi-WnH`Y9P-jt6j3$Nna9B!4LC*iR|y+3SV+9F35#Wa`WpWu2i?V_7nRU+*DuZQ+>3$)hY z%-%TBCL1D;w7x9F$-lVegU}~l)tH}F*Eh9Syx0>1s~a?h9J6O)jKhyU%kfRnqQ! z!}T-;71hO%urb6pY(3Wj!NFp=IH$C0(~VOcwDp;@%BZ5YN^%Zr48H(SezhkADn=Kl zx9CGfW03d7jEd>_5e8Ww#CMMR`m3K~3?um?93RAIP1MVL#fi>%RZdJ*n+y{;&`a|@ z5~s8#F}@NxH(fp~Bd%B}+gH04>7ft(KRzNw4vs}0L?F@2{obPe+eiQreDuajha{fmL+=;juY`|8Cl;SuCe%L@Y}m~np2wO8&ei0KM(WVtnFnV00TBuo8e-%;WpV46*+(E>B`Xl_lP{8b zM*7&tMyGw&7a7DEb^|BI@}cqY&+g|K#y*>Gk5oc=3JW+n)kunNBwkfjIqXGIi6b6( z)bNB$%*KTY8Aw%%_Obhlq-HCULcvHpp7y~82$8aHr5$*xr`06IkXuRcNub+h58?Xy zPq}U)UnobBDio==aG5SzCU8zXn20q3_1$}M@j};04|A&VhakfVU=|H%^}#6D&gnl@|IElVR&KSRSc)=&+$|Ew;E140qW~K`wV0frNsAPIpX- z0J5WVM$ehn@pZTysSgrT&Z#*EIS7<1{JqzY%kjw`&lsBSU?xkJ!Zd6ikO92F7pF8N zMi5$*jf2FrfBN04^Oen@kkIbbdycCXt^-j`2dEnB1s{`C&zJkNHSfGE+DNXvZmv~; zLjRRXnj_4j*QFrY{!HM{pBUWdt-&o7m6fe# zO2iGiY){kz*QE!(PPo_|FJRJk-M11F5sKH|7WDvX+N}wD6adu>j?;0)498{bY99iJ z!yG4eqf(iNyWIl)^Gkvuz3DQ&xFzY(ifOi_h7%#Eee8^P4qJ|@Wu{ct zjr*)&ue_K<7CrGOWKuV*Y?6XXh~pk$w{Z$wjxu16m!BgCk<*|eb6=s1zt9nMa3D+d z-gd0And;*1?(AHxW?K}frBCUvBuL}^`O|Q%=pFjeI;Bl0oI~=eRBrp7>V1x5wapX+ zspz85n9P3oe3*l#>vhY=ftJ#aedjR#l-X)YDOPWDb814*Ewh&`r|-_N1kPLikXKhF z7|t)W2#)illUB}6#=hSon=>keFUl{4O39i6N_W3D)DRpg*)Q$@o3Y3?I_E#`2+e_-CP;N9Rcj?@C(< zzeGge6;Hl;U5zdwM{P}Do8_^U0-CF_>VA$q|M?i5V)cm{1zhX4yB6RK#y)0-mMU$S zmn?<;43+5~sqk(!HzQw;lu%0;Wx;EcN44rB@lD#8jKB69@T2WZv{e$@N6*VlWvR{d zB^X4!Os{4p+fGab+t{;O<$=Vy)5k!r@V?TJWK=etL(fS(uCCYR)QFswu&m5d{F>m- zt@ND z)$Bu@RZ`=2+;Vwx<{f_-zWZLuDPwVUk7`xP`0@|A6r{Gtoq}PiRfm1r5}fpNgnwx0 z-7voffpCGy2)N>N+I5v7M?o8LC-gA-4dkvOAy$bp?u%<`V%L_ELJPm)VHEUYh0q&p z92_4*TSaF^m{;AGKY~8miXfv!p}+C2IFS*GZ(BgFbkp_SI%9imU zPiHt=jFgGSEP3AZ+qeD3f*_{*%=3oC^j@Zg}?&q+SOWOxpTXiHM~f*n9&YrI@IRLM8?s-BtJrNWw$t5?MQ1eeMxXt`@I@XqF5wE8$a9DsJAf zaf#x077W|C6-Xe*At%6A?m(@*X&jTT?l(F*R{n8?1V`GUs8p6TBNu0JRal~5sqb*H z5|)Ac@nrHW)`z^6b7$Vx+3H;>tXq42 z{5FNL(Y-ajQsuin?A_TQjYHuzij;Tu7fZRxQe2kg*Eot~Wl}-yVrIk&Xa?*vT zMQgz!Ar7Jm?sLZBJ1lRV`q?WT{V1|~nYYrSAK!Oh6o;3_bZu*E5QX17>x-ou6Sa}G z$czy6bF`aU*t2O|BOEW*!1f+WvKh71*zn=|oku7IK7)=WYBIl#I&k0VF`X+&1ZBFT zv^?@clr}%)TE07K2-79Et4O)ez-7+=?7Vb~vYE#BjL7>0$LnF8ZQfxzT2wq&>ki#sznL76x**dL5T_Yh+H#H5B9=tteMcqD zZuB~qLC0*TVl|Wfm3`+9tI0NJPs7xeEM{Jq4PiCEndx*o1WD$q?T}~WN+?51muMDW zXDr>EWa54_d|Rn^k_}Xj*pJ6@?j&X_l6MI%H#68ryQM8_Mrxhc^Px)yJt0!7pD7+R z&>GT)5oLHzNu>7{5wdu3!byQCcF?Oi!jSlDAbC;v|Jtz-Y`ee_Dn4 z=0Hn-3)V)HZ~g|=hO7vp<$hH#jDQP^DC`CUsF*R)DZRsTLgPqCWSqqZ<#BglyZx{Y&x6QfuGp78ox1gKG`_FK?bFsC z%Ny!Y(ed;<^uCh2fZ)Qe%=LVu+}0Ts;y|m@kSMQW<+L}9#bhkmZG)bhC6HoX_rMny zw6$a0U~-!cd45Q4F`O<%G(!o>u$j94%>E@k^PMU)n4|a45noMULCgQ>E+1bm=-MW%#h4x6g(iD3Q zElU#?tw&3(gS!TG8RTzBaZ3J^KH9}PT|EoRvSCGLf+uDi7U9$)s*?HN|hgXtm8+D>*j)YuBI+6D|T}ZGKe${^Wf|GJ* z6ebpGg}AIAFJ9EHx|zzit&iPv7gb1F!6qte+h=hhFwWWo3SVUjGX>S^ZkNGR;8$|4 z@zPXDZ;oxoba(BivMv)v9~D*II&-)!041=(F^kEd=IfdmkS6y;5Y75er*t;xt6zd0 zGFfuCVc5PQ?Mh79n>Ljfdc{%)def0$Oqj%tB$?A7#*f%sA3)Pkbeq-+yNV;ay>pV} zO@#C2FAy3lELxJiFyyj^t~7<4YtsR&pMs#tooe7Ahyn4xAcgB z9Hq!QC))6@g`ThhrC@+;a*?jP)R z(%I+NFb}BZsLanMdywx7_L%c|STDW1<|P6Lj&8~dsAI5&Pa(28FfERLr1LEOLyBMi z0MNsJ)yB$hB7w=?aTcu2<5}7cn+^-*TF5l?!R*5WjF*Rex=xz4cz%SLYSGzTU<-~V zzo=?H^*BA}YX99x|DvXP^KTE685J?B>fS&-{RHV>ciMCa*X-ySk; zUp%)WJn?28?3%OCmuCz_!t-%G-AK?>Z;`T(n{dbDyBT9RnvQ1Zh3HpXWOS=Eu|X@r z;e>3r0b|B#JF$T8mtI9{k4F;p0R+;I3&Tk{$Oux(nC7h0tmkTn3q!0jwxgEX&IC0j z-^Q7nPIfF@&Z{4BqY`6MNMSi1u^GT;)JWOciJ7dWjfCzxiABXS0rP&5e4#JvYb{Mzj{3g3-$Jt;F~i7gZq)l^TGYO<84tJ z5{(WYo3c!?V!|7fG!`9eYb5afjz)HFPJ;dcH~3st?n_d1=w7mA>2&$zx4ODlO-E;> zuUroo^ut5i7Mp{?O7SMeqK^)hQiut5mi>?5do`#e17XIf6N9U$ereDC>mrvd(>8*uihg4Fz z)n$&kwqD8^U!r1sCL}0HRd|Ofetg#G3=Z)DL^8U)-+EMAyt0B`q$_OFv#*^g$Q7$6 zt9o+>Vb}t)RYY&;WZxHSkNiT07=t{ue4NfZrb0oJ8Twn1$LIjos@|beN*o)@$zE+k zL~06(x1|;H5uweGj4y>MzrLWLSgBolZ2b<6Fq|(ZSY@+>N|&g}wEBI{wLXEz9SK-_ zzJpo~`dwiyZ%r;V$4eAoH&fW)tRkZo`g3&LFZMdG_$c){E6BSjfnw!={k#es6mIL$ z;PNBE}H&Lnh7m2L_CiP;cOKLL3FO9XdHdYNQMFI z{6%Y@DzSn-?l|Y@`PHP$QP0#nukRQR+q2LJSagDMgV=g~lU5=fuf~Gmn5<~1Iblkh zuU{;BJSwb}8dCQ>%C(U`T7Y;3jBiT$0pxPT;e5_*<9h1jbq;oxLY}m~YcIgL=M7}R z>+IoLvdhvJX@^G*6b#h-oWT}};lqO6>~`KUxZwWQV8b#RY`A z$=Jkd^OcZ3`asfNc=3V?h*cVLO4ZX6(Dw8S}^FuAG-FzGRw~0%#dD3(WWeS^X z@3!tjZ3orzvNWa!8FOCwMoV+xJRjnLtzBT9ha27)&M=b zs+3m_*BZymZzKjhmY%3gH&`AaEG*jlrC*mN(dSp}`2-~{1yFd$w|Z;St$mh}^h)*- zlM5Q2ZJkYTMe?H1Olp#rjNfGH(-LO{*5-#~=g>^99dL=hvdwuhvAXtAqy=KS(Ihfj zW>A9TC47jQ@Y?at(NMBfZN#wO7-WN#=-jv?r#bF0Kz1*7 zf5Bp&uGNhm6}tgKQKSF>%U3OLRs1(b(tY;}X&5kVxlqbi^T=7bCc^?Dw^A6eOZu zvG^F83BRe(jH@wSR~Et9S8D}NI*}Tl8|Z$5V-u^@??JWO@yiK7@RepNG#ZpPF?Ypt zXvtq*);!ypL99h;84*b;8l$A_rHXFh9FCC?HZ=2%6_4X7s;I0C@1!MpuWZlwJ0N}G z$9aLV;-Ju_uGaJ(ZcB05EHBL`I65!kW7_E4j3`X8Vb9UL$cnJof{y6>qPTl=tJO47GEDrDjiZQn7bsHYE*aq@R0Jk)*{ zh+=imP$^ar&ak_^NwWEPdW2dLwWAttCuE$F6N0`SCRN11_+d8VYbb3u)bI933o+1b zCTgN4&FpAUthKh9f4gU_c~{!Dp_+8C&>&DOX5f7T4dA+gSG)uaNPDi+^=54Xc;>|7e(M@q(+JnNuju zH+UxIcq|r^LIk#kHewJ<;fRX$*Ak}hp1N*Y&n9p?Tf<2nebyNI! zsdowd9#^)!%H^8k=XKSlb>p!6h=ICOXW{wP-dLp3y1uB*QdrNRkseKzM@CcxfA!#b zL^?OSLD}9tCdGqMPT|9H;nlAif=pHnXyPc1VxJCKb4(_j!k%|W8hCZ(%ViyPZt94! zBIB}J?>IV44X~7gjq@#AUem0e_^E%D-Wd~A?%Ss3rF;^9ME1nO4J5Jzx>#oD-9vd? zJ-o4;11ky5%Wg%{Pm1S|-}F#}<+AwN_DpcWS;t`ed!nc6CxYSp***Plx9``$5E>Dx8ynck%v3}H9 z9M4vUIR5-!XOE(uGr=xdR>+$|kg!n7cjq2Ld1~pM-dLDP{Y+N}XM0S7o!2F8!F|1v z_RQ5K%VT_aXGA_=;`^;#uv`r<&=@XKFuwuqn-eC*#>9}XTIRuJuy^#(?=s4Qw=hJ($=2uJHqR_sVsLdWu=QW)53X=3Q zPa;R)Y~HctFEkk49v+3V2$(CgMGstbz(c#tAXOeR4#a~wgLnvx>UE7c{!^5@w&6@Axe7!e$0&A8{yx13Q^wiR)w=m9H ztOH#$tV*jIQKe?MHgjb|>XWf!?i!N>dB+F3eGR+zdArS4-2^}jkn3LdvPLIyQ`VD9 zk)TF1TT*MMoDbZVTWdY>ovmQp>LH6n*T=lpY#Kjh@*t}Gyn7+fAKF^7^~t!j&vmeV;|Z@Jyvc!PcLP>d<3z49{S>LqKSfpHO8|*yY%*`8aduE-o^{^wJ3C|M zpicOk(meUS01B`6mS+|{y?uSc%GyYf=MKE~6goK6M*lQi5G|Dal$R$i0gTwMP_csM z=aV6cXcbD~=%vwPVfFs?*1d#*SFv-^l9Q9$@}4xiT8h^(G+Hq>G&IJP#IzeM!-uPc z|I<}JVt7h5Ty!{v^EFt7MEut_l1fAe606_+)QMY7bw6nTN=}1r?N}dLim|LL^Y$WbU;3JpVDMoCacKZq59Y0|7cEu}>Q@b}m-+fU8U3K;uZ0t37E+ zRWCP(U^j>{8(EnH#TfI?hnIDpR>%=}+}FrgwZK>K{gqtwqKAyKjMEC6AVsqcTpdS8CMS7K@YXd&oFNJvP>go;)mU^aTZ&=r@#@o&AN z9icyM!?VosM{0Wd8eemh>VFT5NqCkrPjj?Cz1HD9Z`~KI?m1n0@_4%mA@&~z6 z)Q41Z3K_Q2%0wybczi#@@^>)_LMkci$|+v2v?x3Mb+fqh=a0cqy}j6Pzd=kw!N(6n z;SelS8|#8YL_CjH>9YPqasW((oFJ9Nb+@b1)k|2d=Y6?Ed4mDdIzwWVHLw>^wK;h_ zPqFDt;ohU+4By`=xPvPE7Tt&`Q#@DIQAfnvb%a;S%2f>elW11+S_j+x!=ITaTSf*x z2;B$%BAbBq5<@O0$>%^!y7Dhr^Att->rwLMv1ldwOJ4U6^a*}}qvMGC-{u6Iz`~#2 z!l_WUbTzi~uUr-wzIE|*aX_9&{-gId&Hd?j>t~>~fsDfY@6Epap_shx`xm6Xd_o4O zt3EoiWyWnGirFA4!l*N+(N0F&rfh=0TPG^1*kZbA_}^xa*@zmJt)qqhz` zR0=f~oB7{Y1B3aQ1mGpT;glr(dqBMQkq00dYG~&F$wy!N2tJ{&7zDXbEX?0O{8VsP z;n9tit3xyPDbhPRE@QOs|4#kK4&ZOCcA?bn;{&K!9fALwrgSJM>gLu_&q4?9LIN&l z;&<-=#f6G!vHA=0S0t7Ho4nR2a@lRqGElYogKvPT^XNp~LtxU;`qWZebY7A_r?)5; zj>dofV?p%%GswOJu$TH$bX47j${AN9k;vlZD^{x+b5?|E$i3lqL+Zc(IdHgfK*nh6 zs$uBq=>Li_6__B7K4Pj3Mn3{1->hURbSco1Cc2kmn*dj|gu z0Wc7sP>%3?jFw_yUEvTA1Z2OAInp#)a{lK_K32T|zNF$aQ@2p3?nFhvG}!aA9yY$_ zHuihMedqp*e@ianEkuhPrLrzi0=yy$e|VYZea=%8{G*V5jy2h>S1c$zoa6h}H2(iy z0zV!cv*3&lmwZZs?Dur-V{#C=LDFE1~powPys1MklYerhVbhJ@b9_Qicu zYF_+h)c(bD!y*`aem&F}3&PhBGp?Lcri7X*QU1%JEQ%Ao9KyWvx? z=j~hDRWcWpK>r;Uq)dI!DrUQ()aIMeXt%UCjV;|cn=ZR)jsFXq5ajEYKa| z{5y*a%_>tbB!B|yAE)DjcD_6H?t71V4X9OqsR+QvUZ-2Lo$=k$`t^$yJ#z#7^~eFn z37%MXn@;tjY%|&|?y(<%eu?{?ie>SmPci@9$6TP;A01O}!Eu8)!ZmsIw5obbsKXf1_~J@4bhU7n`+&#Dw| zWq?*rWpA>06Re{w_w3a#D(deuZ(XYO(4%bJ9P^C?Ol3tyR8&;Nvzaw&PU@X>I=o&y zwB7&g=&vY8GzhT^xq1^j)h_E3Q-D!%+*-R_8VMIy9+`o$_J7ujETorF+bC6==8WOl zb)0s0Zg|qsY$fSPwk;_X^mU9hXc)V<_ka70_i3;u-C`1=d^k>3mcd+sPf%MVufWCM z=no8*2i#T4HYFPyvRkXJscH}oK#-5%uo*Vd{O{S3CDLjG6?-sfjX(eVISLxdDz!Ix zhBbBX+Q*3579!UF*(bm~JrWSK8t3Saf(`rcE%1H)?v0%)QTD<}{)S!l*cVp;;ypbB zZ4K3UWsj{-@@Il}YcQtOTn$I;5<<7g-{=as4p3LORz&R2RBTQ-FGY5GlG?zoHmpwB zq>2LGWhZ$r@4MhOyB{T|9siD!&sUWE@g1RBqhS<6!idMla|$x@{dO*fm)&DBJmG+q zeG--6`GEd^_EWD=x;z3cf_Q+ki_0tE+-Z098|?fk7Fuq*CX&=o^S=pKq=xh&F8dZQ zjcpzj5+;Rs^T0dps(4jwN6v_Sa zKsfu#5W0^d`@d(r8r)S(tDRtxP7D26yY~VA3Gl1bhBVMvk7+b+7Y=X|=!8 z_W%Eo*Y3{)m2ZG74XZku7n>M=jUl!D_s)6ql|QCZcY6?tgM;G-z`~SO#AhF>7k*zz z`@$9InK?Njotz}E6`vP+4l&Isee-6pa#!ZR=AFaZ50PFfqBA)q=&_KNE-9mO$pa6G zRxtdD7U1!5=Ke$;Y$oHuuCr~Xen%h(P-sKP6&F=4$Wghzx!)>TTC_+5 zq?ON`?iW9cd@6+V++2`zQCI~IlV(o_t2EV!KPM29XnHRkEdmKCDf$rK>6=NAmIbW< zhh4;q1OqoQiGJ~beu+7Oe7Vu%*;?`CN&V$UrL8nKQm+Nm%n4Y9&H~zJz+$&jMWb|} z*2IQHq~($GYxHFTNw9nL(a3EnKLD;YB55qL$;b_{K6-IT-nKjI2%kLMQ|v|%a2@YR z$QYz`Sja+Di$>7w*sk)Qac;tJ9|P{ICpV2F4N3^8<&nDgT~ZX0?)Ywp2T1^d%V4ZY zMa3&=Aa};?-29M5rlx7E-hNZ}AejS=K^Z)+DVfHB&Sc!bTpxo)@+Zr{6i@HH)&)u* zk}5qJ{{Z0)8|6aWO7zUEEF{SNJtXffg4O+R@pSn^xQc)$DlaSymQFi>c}yAYA|oQQ z)VeKK2Y!*=G+&c4e28qMclHoF@bgV!A{2c8Ub1}ntr=e#%wDAk3^a6>+bNdI`N#_U zVH3m$jxWA3MJj9K3OBFmDPWN2`9^=LKxEVI)d7Cr758?Ra~rm!@QVRlk-0M->T#~I zPWqWysBcUZcW9#M%z(xnKH$zKamFiY^fyERNoT$tWFINf4QPPrONwK{a)oj>^pF02 zZn&kZ7wE$N0a?n$PERd9YzG;nu?@v%8g*T-M z$aS3UJtA*hrBXSib_Tys7SEx)(YfXIbXz-Y*)+Hhlmcu7T}>C863W5(SJTbz$Q074 zA>sPhFOZM~(xTlmf!4{Q*LtsFTws&OWBI%X5oro!r2ri(H4>Z6VhCVXD#p{sF1Ayk zRg|l8Hq-REaRZ(Pv0fiy^b6^O&X2iWPu8fD=sG7R;Ibd#aiN5k21kpv^GC2B5%>{; z%Xwb}ILL*zp!EAD_v4veL&~Nj^7B6=+ntDQ4TFmdy5Nhg=A09`DPL@A$zN`1+6nj!^GQY^wD^O0SQitG6pj z83?Y@bMtSOK<&$aJV1jvawC_|^Z`oraEzW`(h`)&+Yj3)aR@k#wG*6Iy3ga?I%d=CuQ5dM@Bz|e9tX(+dH+Beja z^*DnatU4Xawsec{IRu99Qz_{zUCUbuujPHq`<@!8EoZ~Lb=;Y(ajrAZs8n;OYL@-2 zwT}8qyY~*#T^bICHdajLf0udwSD?Er*C8}EcECBHjP-( ze|HHXHq+p<6UjGY^9tt>8R3cbxW!MmM6NLHhaN&6_3{A&%1yTq-5c7cUe^=O0Gm|7 zsPN<&n)!HZKL^55o2U+dKpYHad^H-{moKt{smY`<=2L~_`t>#0O7-3+fiJxOq+xF% zuD4<}POm-~Oyz%wfTaA(Wic)52TWZyW(cH6Y%T64~K zx)++NjyUTAB%9`$7ZNu(_Y4=@_x*i@YEj0kP6zY*sKf@L@w>H;cxz@;8CfQ`5d?%* zy9e%sXWUmu3KaW($fE8yDO^9IV`C2zxYrqEE(uLsfX1_t3(wh>LTZ~}Nvv0n%kJ&N zXWLYDI%!5%W_b`JA?oYYu&|fWqNRXx;5a*vYY3Mrb1*wtu;E9?O{%n(ySvbQJbSrN zf`zSjRa$OyzoY`$1ovUo1yd)=R@2ykMvXXEF*k`@e zg%Xpzu*;@4LGD8^UvE;b!D5ZoXHkz*$>fJy3Gw;OC}_k*x9G1wIo|a|C#f*PEQ+}N zu8u!SqW*{i?5-0|om>{LTGOR?bfh7Hly>}b+0{3pYVbzkZH0=H1>KSK4 zfgkFp_z+KIhTZok$=C^*{(1rAv50uzAa=>b`!2XgAFnwRt;`ENey@JKu1$c~q(gw) z7}5wrpl2VFEGQiF0I9yLjvxZxL+ug~Zl_RV_(e-{NViv)E=Fz)BqnZuNV%|>P6wMY zNZz&TudTi_I$=IO<-|D#>`y2(9o0u+s&&nhx$=?!IU3QmN7)ftHUvC%I=< zH!%otLerOhsdCE7Q1(Pij*sQiG7<4uSGP@4yBiNByUy7z1)DrNE_*|G7woBIgyLb; z+)eM&&lYcBfto%D=6qnZhNOg`WAnD38=a?gRBt(V~eIG3$7_NB78rG1pk2qxh+ zczgFa$A#SbCWJoXaSQ=P{*ylzoWHgpc8)rVoUEL{o)#5krhc2Y9PI~mOgW6c|6}T_ z1FCwSx0MhOX+b(9C8g`qCEeZKc|jVaySqz5y1ToPPU-G$@I8Fg@9+Ja%QAo^{+En4f{ZWA_SgT zG+&CfJiA~o59i^Pk+4E*E!E~5^;eW0%+-b2Q6TtvVPRhr+2F$}htEmE}qP)G~NuLzcQ&9?}$mn(O_`$SDqU0|a?%VRul zZ1k`V)(qazt347pNg&gk`$@#1hUbikEnT_Opzgt~TEB4}wL3$~PeY;OHR!(64sPtH z5npEU31KZcwO8DuRCPatc)efDal!|l^tkun4##(oyMDD8{)uj+{Uk(rt%+{uBgJQ# ztHsum>)E^bEs2-G5<>ZYyMP16tB4wUTrK2Vcc04bHa^M5lR_0=!^cG9K&RtYJw-_$*l97{}9IlZfaF858qcOLv|~ zU8$JO{NjXOi8t$rV|IS=8A!RoDGu9O zv3>E?X{+k5#_GQ2JMApbjAd9dl!{=b?qA?pbCYH6FP2sVew7TBQAvgtIlO55Cb{bV zcH(Ckh{j_^GHMvuEX5HI$1OMlfH=S#1nf-56D_eXBqSs{dlR0Yju4a0H_O(8uewzh zho}fvoSvM`_ym@0o@A^B@8HBv1s9ay?MT&BY}Hl!r*hU>AC8*{>VCOYsa?%x>AN!5 zQL?aL;ILYD{Bryy46Za$B!|8>I9dU3rj`&^+kk{q(w^^j^aKU%vl}cs_O+M){xNVusCN(_%irFK7T~<+ zjhVh6cLKAdQyc*edJMV*9QsO#kv%UzbJ%10vHaTKh%PM|FlT}mPoU1qqVIZ8Y~zCs z3P>)*&?eBXQGBI+x-7-zA~?5gd{zs|^L$BVH0(yOkvIGeC)d>=t@DVutO@~zlDNlB zHB^>~ncaP}VDSs=jD2|tKfSP62iK0{kCfBu0rcug^RJg@ zf(hBybv8)vBt}}Xw9L>Q_wj#kjcc20$tWMwYIq^`h|7j7nSF?Ef3S!>kPqBu9QrU1 zaT9hJ4&PB0BMg4K3xU$XcV4nHZN&*tqUoH1fWq)2t<|k1-}yHW#ZVf%x_ZCgQ8D5g z2BkM1t~on;ynk~A$JZ3^wQtyMhA5dtqkZcgl)rn$DCi$hd)dVjw5;EcHs|a~ikA>= zhYbhUrwEA?Ngk|xkH=%nkDz$=tk7H->BwztE3D2%frKHwY9x)3uobimk``U$bY_TB zLL#Gzkonfe15w~ntGW;=g=1OiUOVKFax+L-Qj&dsF_eGjz|L$+@L9`rk0KEo{si3f zv>|%nwZx+ay=$7L-)lH8-k;hq0&+Y^<-PH(b>OuVdn;!GR!-08O{Z#=&V_Rs{a`uo zH2{zm?g*aw1gb+!>MK+SKz_MDB+lRdx8-^LhXH_i z)4Nlb8@(8-+-cZy2N~H* zv0vI76)M)qV{W0(bWMj~Y!-wRq*%^A@~pA5K~_%le5yeV{&}`tADvod33j*Gaf7x3 z+a7J&$1@$W%a!t(>mLs7eO>HJSuDNStA&hw$KjQP=!zRLFma`riY+D8&gqKa5Z=3hgB#QzY}Y=9lfdMN>lk z@l=`Lp#*i}Vq-UpDxqj&^UDSyV#DEHzj)|&cHl2*K7t?rxinxtWVnG(8|;%7ga7X* z|M|LATnL7NCtMO#SykA%GBWBtgNMNh9@G3keo#RRVp>k;j4Yu!Tym^stpw6ZHmQ|% z?`Sv!SM#=z%~jnmZd|Wp>CHt$3!b}XB3GIRQTX*D)2VRPyLyr%I_ZbG=eyDz&{0g~ zpB0gDe>pb{+lrd0jyBceW#R)|bqxn8G2T`w$3Mr`gtqJylz(7Om~M4v$B0|9UZ(fF zNq;i)gkGj;1CqL0<-@szDD#)$y?pzJXx^G6pB`6STQ>J?YVIdMct@i}%Cb8tIXPIG z`ysk?w$T0vMec*2+a5^0?x-7vfF@J9iR6Q-(#}pJ@N=rerJBWfZEI@m8dth>=V#{T zt7Gcsr(+92p(91-xy5aY-CIZ)z0dC38sAg7k0=(MLnhtVmEXEQ?(r9|l&ennl%?Mt zhWysOO1|1Dv9fgf{cLiX^TBc~`Qa1BQ%!X{e7*xv75;awZ|PtaaJ+IIk$40k4n`M6 z^hWll`*ZR7C->66IsW2)TcorFPfde=>tFtA9jR|GM=Byb2p|&D`B*OOD5A{JrTspf zS15ci0yyV8!4oR1CHtP+y@KX3)Nkh=oopMv9vn9E;0d~G>$mmMQbcCbgEejfkuRd zLfME8`M$WT{`9^Omz$0$<@DZ*F_2W*{HI&HC7C4?iY2=3C-k_8J}#Aul%6wGW_ zX~C~cyLFCQH9)&@S{(++m-D1+vBI!8xa(Dpokg94pOyZc3aP z#3aj#pKD)}E^M{%%7*qXABpof;n`W0OY2a~rao&855HS*JdRK!OE3I(C0_NpFYal{ zFVVGqXj1%2U?rh)F(&%o2vP+y7vQL`kfp@P&$>?@H`Z96NxA?f_H96YPaAfk7lKSn~cl`@qfX1&G$qx#2+gSYj z`5h*gkz|K@lXe*mj&s?^S`(~$4Leq?l>0nvrOjcDOF=P2qtT=Q@{E*V)|Hfiz)`%j zA?uJ>nj_hu2A1|aPpRvx_<36i~+pUUztTf{VM^IopWABPp1>C+x&;o6?B z^D8^F{bl?L+do81RK_5!TYlkzcSgIm60Sv#7Cgjonc>a7 zwV!W@ocM3ghy&I-x?=sHiXQp%wD?4))riIs3c`sOp`r zCc^EGw@}TIjm=}Tue(%M4{bZ>RatOz5u>HiHNL%BaZE64Lkh~RwOlM9Y9~n!d_J8s zt+&0kAsxOZ2vjOUZu)xQFTFFSm>qJoxm}Tfgz2`m1q*ws{B!^w5DE-q4^%)kz>WRI zQX!@ay#}%1sqp0B8=-MR@6t0_W4u{54(8$oC4{tm!9AZ!W#G=Sn;K0Wes|ea5HrHq=e~&)!n~~1 z*(8fct=WnV=;?VUy9=AXe)gz$T6Op$KB+|p@1nV+9Yj$(>;=6)erurao{X1o`jtaU z8;l)*O(Ic-Zdx;6=d8Ura?zEzp38j$-@JJ=jPf9T;HT+4D z2}ZV@ouuI3(dM2~yYv&Un-BF`5`*pz0rkGTd4tCbUJDDPkkPDI=xEfn1dR zf4L~{6`>3bw32LHybuz+FMyJ)SB>%XVPU`B$l?nAN{vggoM&3>ANRQ`y^5=a*^9~& zZf#8}yQeEsf@66J-_cQuII9a?&Zcg3c0JBB%v5W7nG2=>ue6qiNGg@>$9aV%diC*y z2=UClrQn-4Pz49L$#Vp&+D*KO7tl9dCVoEx3_7R%N+o5t8HCa<-U8b1bRDK@it|Ov zNNQ17rQIJL3JUb1$^L{a{FxId1z*ACVlDwL+EegNj#fSS8MK+A>p}flL=CD#33*8k9uF=wsu5hsD6y+r#S5l$4yT)HLOH=3p?9LN6;Ek}blzQ120l zCKkTxTJH&&o&NUG#zbQHM-vy!7G_da=rp2gBouONKK$b2ijhR*SY~ zNUDB!NR0&3c;xxpc6eBOUVn+1B1v5Y`N;44#g8QU-wWPU^lw-q_se)dnnI|`aafM) z1P@BvyXA2?G-K^|8!vaHIW9q@-}Gd?;}}tZyOM9YDSsbE9~UqG&)|1LzB!d2_V2IJ zET5Qe6*4DYcE5i-A6hXHMeF{34`x1Ya)ou7c*~6l8XN5E6F?|3WdzhlPA{)3jv(Vw zV#LeZl6-PKe}{bI*PEc&Wm$eX`iJ+8soYNT~HSfK~9I|w(Z0W#ecwLu~w5# zr&b0%T~6*U=GP@JJughvjkm2Jzsnyu!ZJ0M;S3~8$nQ?{#STJ56|T;dl?z!*)Om$CYd^Hy6%6$#oaaY|wGtq`W-wWCvDB-mvcHvs`mjzH`Q><@kmIltxedN%o0m}{9czOgy3 zccP@CB9E%pE9jWc>#^A{%Vdq8M;36Ang=;fzu6&1OthLumIw5_0)0wrp_5EuszBu1 zK6xC~SvQRt1NtGNGBi}LS9qzx^`Bu?bJ*;ZQlN^6h$doL2Jr~Tte6TBwNd&nj$~ji zV8%K+BIVG0JoGunDU$#pMp$as^*r+@LRO))1o;P-!!n0l zzn%m8#VArRJr7~eJSFWfrCCp#?8RPJrzZg_q6<4l(O366w^y?ZzN?-;sej1*L98fI zye??U4Fbyp3Eo`mU{O7vr@7(g2cX>Xl@VME^;CQ)D%YvazpzPd&`Jx4Xq1XeSmYIX&;{ETu z3l;|OBYMZ~xTOHU1|QrYC=pvj6k@;WgZ@?w-0jlX>e1|Tbftux`(cL<4q6KCLUG_& z;l}80!&WDUJWG))(bRuWibe%;SUI`qvQ88kDYk|5&eI;n`fX94zxf|F+Rve~LVAcj z7eg|_^+JXfF4Lx$f6d%~`9Ft~lFR==cF4C8uz~IO5$)nN|AJp%-f2=oaCxeewX1s1OV=MX9V})~O9tW=N%Ywggu7mY~+VZT0W@xl}{jx?Ofk zq&DpV{gXQ0G>`2B=W)X{Nzey$L2crj%6Dn9$)=Tm-q zjiR#EYzul!5TG-V66f;ybfaPH>JZ{oItZr}{4dKb=!OCozL{0JrOa<-&v>|IaB!5i zOz0Ec-x2Y`D%e4+cTn~r7|@|x54USke^6%S*lrV4C96$R z>zD!wzOuiu{zj;NbA1`Wce_j$8hO+LSbG2&nrV$5rxBjoq0zkw3e>3Iy6O(LMo(jfi z-)}XoE^i&E(d-USlkFcKl#B0)QABM2-*b6MNeLkUJCQ;{)AHDR^^$}SCtkpDr?Vpc zFrJJx1eO_!`hRAkzz@M7s4|+82d$LG!I#MPOcaXePH?{a%NIZWymH4bJ8u2o6j0It zCL-17upqy+#`oop`2Sm|S|~v{w!Im1>39sa`vuYMp3wjM{vcqd*qx7{>TVfi>Ph__ zJTEB;VayWMnq&;wKhr{nKu`GwTO91}`Q72)D}7&n2T_E&3^ecgzb96}1-2Iw-UN{M z9l)J0kvtr{osb9^DYq_qs_Ek23aqXhn?)TZ)fo!{!xn+rMgRMjRX5~F(c>K-Gc1b* z>F~NXTAu-UrS2Cfe$*kQ784b-w0qc>msTNZrR|Fim0h^n#5Q-J`6MEiBM#eh|RJJ{zqvhq^Q?-ipUYY7S zKn=_M^?s?^0LnBc}CdCfW7UJ(jMszXh zbK3;FTWUv1P4;C^hGpe6qb}&HrzUg(AOpLIQ=V zR`C#?Ic}yd)Jx*pFJ9KL6B~b`Y|+u$Xl1L^*Or!bu9kdoxvG(3C197Vy4N2^?FnYL zxivqN)0>8+htZ#|8O^8N6#ruisbakTuxY_nhrJrq)YWpuNVXhX<~I@?m`I+MNq#;a z6y`_>+6Um#on4NI!}`XB-oaRQP2ojwO?Yn7&;b)z3%zgTBbeh?_QKdmE#VYv2>y9P zA>sp_WgmBI_w3ZHa9E1GCj#vf9pdm9GT-C5r7|wa3AXMR*XvIM3q`vWd!F+}<0HbYO6d*r=gl2viTRxkl?S(L=i3Etq=ZS!b*AG8 zlw$X->&lc#+EnvJ&w(Uki$Myp^J1X8{F?#o-UISO_hC7YJw!>xr7nV(6kED8vav^N>w-5P-q(zm_HBVEr7n^q57gfe%ADLmDTzmF7K1*Zxi86g3> zX#~jDEqh&F+Pgi^_top(!VbEUo6Qtwo%eQkuW#IC=OG|BCpLb*OLaA1jIw*B09UFuj>u3L^kwdb&e+;36JY7V^JF# zCG*EpI~d1W{i#YZdHHD&z&jqWNXqbyH@p7Ec@iB!vl@E+QSwC23j`===!vl}rKl4? zFTtKecJSxB3X$6;JG4 zR~A^%Si;pf{``CWxKA5+ht|pX-s1NDw!r>b4~5b7UZMGR;hl!9swarSltC&T6!gPd zQW;5aG$uXW3!n+D4N{f1qe*l7`JB7+`JlbGX&{V$$Yos-3c6`J0i3uEH5sZViQ=X5?X85smxo)??HhtQJs#_WbJl3plex13+H!5Hq~fjH zp7?}lRL>)F)yKFoP(Nav%c$H{6|ORZ)6uS}0cyKJS^%TC8+BTL~WU z+Qn2PAtvsswDznvJZXj82YUJ%jysFKlGXAYqAHWD`dOY@@^-}S?mTXA24gV)1z)GM znm_kce2;bu^naki*CL8HSvN(jHt~A)?5~N;A7NOF%BMyOO*hC|6F~2~>pw6s#aJFd z#cGg5-}p*ON~(UZ!Lnr6)!#&OcGl~@B`8IVlJr1~ty9wpO@72iFoCA9N(6(8;n(mLO7T-qrA-SAqobDol zU^-pxqBt7x!EYJ~#_9via%Yy%Z5XW8UWo6eM7Q;C=#H!XA51yV1{z;YJ(;b80v6{M zy9p2j5D7ZV5B!Nq=K9BM!?2n8`|y?5VJ)58y?l`XO?RNM8#7E80jI!xdywT)=0G-C zgP?{E!-LuV^U+b#7b3cBq>+cg?+r@h4|Q@}0R!gqeDfP+o;l&`ISKwmZ1trJjRJK8 zJ?q)qrB{24AI7em5F@x5{6P*ScV|)Nav4hrJU)R9y<}C2k2k9xmzje z;IS}1P$%D}k|)d(x`IAw!(dccb{@poh|4W1{>%V(p%N!K&2`wVBx&N{9sjzZ-O<0Ig5z5 zp2<%{ApxzQ1S&7e$(0Jvd&)R`7ry43igS#HY1PtSIXRP#^p`WChSw|uKkvxXuGgc8yB z=8vt1?1RcGhh7kBQA!N!CaoyRHOHbn@s$HC zPOy;#$GD|f46nf4$z{I5DEe*}Mg=a@ne46QV6MmRF1-zMF3HZa4>Khz#gzxuorCdY zT41=`Fp-S(bKJbvvr=qYhZ-xG4t4cc`LT{-i_Cx^+4Di7cVBt==f|^$F*8`{{6ik( zFn!q}Q_|duk~bk$ub=3856W6X-5;)HSr#z8eBUCmP5@fr+M3vdM?B@gcDsT^Er~gu z#}84*@7#RITO5;wD>)Eh3AIFL%V0M#f_%8?$V;PlIvhx_eMn2l5el)1lU$@v_;i@s zgBcK34N)Oq*Xp$DHNGDPftx>htMNCVi46xbyos}WYdiH8YBO{1YJ}=5Z^hTL=9N`W zCN@Z1!(l|7wVOmi%Pok23?tdIYAfmm_w)M=vbMa15m&8>Ps<{Ebs4NbU?^OTl*%-u z@Ua(gLej5cOw`|a%z^7&`gQCNCh&-be}!1LKH-P_))M9%rW33aFBP6j=c1H0#qR{g z*18;cP&!^VH<$YPLD%&qTthcK)h9Dv^eG=vBjs(yG(Z6H|978fCmul4@v zm8Yrqu&~muMT$t>Im`!V8Emo)de>Ek|IHJ_GoZtVPElP3bG-<;#)L)BarB5YT?-yg zbl!|&j#l+=%8?lhwUnMOGsqxhyt8t2$*a<|MbeovCD=kpa3wQ~RGbYjUZ@Yz`&0SN z(bIeE8C0%D$1G<)e;CRb{~~??f$3H3`yHZB*(L_C1Cz-8u68EO* zvce)l2t)e0ZT;Nq^y(VuUzt+wIK~b1lEYbcGV-=Wq8l9o=U@l02-R7kYz|z=qwlj+ zsH|mGmTG=P#-I6i-xdr~c%Z*;jRHWO#c7%E*JRGFt~obCT;q*~m>*fKJA*xEC%MkM znP=b0E|UEmd{6rA&EF4{X@qZGKF)EyAsdH-h4rFlx^~=Dfv$e_!B0el z>3H~^W9+eIdVCKFan2Ar4BBq0vgTk8CZ@roHD?`Cgw%|OCd(#g4ptSh|WxIB9mDL8A+&ZsV@{fuUl2GNs^klv@rCW_bA4|6Q=jNg;s3n6G+k? zw>U_K`a*{0v*o@tcI8T`5J1$SB`&F_d?QF;>q=e#D zdr`p61VwNmNUJ5Do`;P6L@rnM;;?V+3}3>3HXR%t?QA+}k$$iYgRz9>=db3xlKd_4 zUP*2JzqB|mOgiyx;F799IGv@M9ZEA6It* zN<3E2eN;li9v^!lGlopSciRY8T^~a%ZGT?hrf#rF!ZU?anG(VokGOcCW8BP|koTkQ zl6(F8_7&k7Qf?shNwZO zUB$LR!)8K2JM6UM@K~i6*T`cbGMhW}-hoM_{%2}AiJESM27+IuakPMGvyRX-k?Bk5 z>$NWiL=J|H7mwxBl>G}-k?=|$tku1Q?;gimk z`?7Ua1+|>}Rqmd1h(r7-cs|l8un4#Sd0Pzm^C*m7@zs10^sUycJXR`lL*Asp@M1d|r z0Gh{8C&wX|1{+9NDCMYr4^Xmr4PSsihGk|`upe1wi}=zP6n^x3CDD!l;P9O=-e-=B z3nf2HTDaF96e$G5*R!M*Sr?~v?o~8++H(~Jjcj2@aWh7y7awM7D|;7j2A&&>zlPA{ zJ7!U^a44t z98`}m)Wb2b&&kqgFClhOX*sB8zW;m5pa`)3&<)1Gt>XSx`y;B+@@AAHqGLC90|ZRr2V@Za+>+I=6sj zCJj{c-q!dBj`F%-){V^;^h+wg+ZK;z=-1Y#s@UnImYlN#Un4Tuf(ShB5k7tTlsU_# z-z~{nn8452_FK(9zM3vt`cHf^C=GyXLu2K`7{gskj~~}y`lNcXP|2ueTA!{(LNjhj zT5#Ef=69N}J2bTNGqNA`@jak`T2x9-o;io)oO9fpyUwz+{ezPN<+W4hgtbT~N;tX~7$#zZ0m4Fw70%-P^JCr6N(VbYa@dH6!QRz4$N5`to-DTYLu3_ZPp64!(1vvgX zBwWTBLZ*rjafcJ{xbwym{TPkq6?M~;)hpX(&PciT&rKC>eEYOJR2w4z5v2SZco#~v z9f7I1YRi9vp#=f>^M`b2FYGIyI}4@z~#u z*j0gpIp^9Q*I1)!eo#DfcR4)~^NFP?+L&o(SEn|O7?91g6F6mD0eu9Xu?w4goB`y? zA&aB)h@RB}{wrR$Tb*N3QBqnY=3gLsoarpGVl`sc>1eZLtC zZAO}0_5s?LqW~EqF813y6s1TUWuFzv+1rmBd=dic%S;M$jT^77@~pvVs!*HoSg6{u zvy)w2@qPrGURg&bCZngRn~^X9jLuG}u0=Iz4<{{X&Lm=&k=YoK%S^*_*+Oj2wUs|V zf~J(pN*FlSu6G}?9vMuqQ7^C0{gq{)H1^QBt~-`I@ZUJ(e{E2|NU}7HnGGuAvZRY2 zEfZN>bpZ;J*Z2hrn~T`{z^flZ9v&Ww?%^Wz-oM|Cz(p-ey;nBl#DKhCeXf6D7ruXrAT5le2*4t!qglXP2n0@AO*w=Ag zt*XCs9gxEf4HxFsA>4-!$n-pA9b zOW{+TvqbG4jOW1A6w#Tf?sx#?us(tij4bmyE4FeTY@C_0{A-xiX4!41Im{D}cpvG1K!mcP&#~g@m@k4`MuJ zGIhBxfA%UR@oVG9aV@L|&9#N4Og_jZk6BC?`l_b$b|$ka=A`pVe=?Ju&8Nu8}&279RigIu>bVo@a)AX*iu(s^+rHoHzrc4<>+jWO2h=@3F zJ&%7t0aFOU;S!h0(wg09y=!}Zy~OCk@S@-rLc8yEyFp%VcBK|~#Fo}}x;}(yyTM2j zul6yu*%%<^d+#ysP&TCk9tz9x7yFwoYj?~jb;nFb`rGXQq51=_zQ`}@p*|^1IBGRk z;w)D0Z(_3_)=ie{Md~WgQl6w_)kj}*VDb#;fiCmj2x!4U$RW*7?FDLU>0Op!C0sWY z)jpXN|7<#}6fc1Y^o>lRnvjpN6`iehGCLQ%y_@D|J->GQt%-&U!VCd`2nxCnNHB=4 zcF5C621Z+vyo=UAS*&sF3*9gY82JE0wN(?H0kR zbOIcv^HW^?RXoaRuA)B>1`}Ir<_%s0M84C>^(!`vw)aFGR|*ZCMxc2-T8 zn8w*Y2;(hqov>FdMsl=-=F>-jm*0&}4h1#UyQTb&Z+#$!k|04B1_5d9?6cY%gx|UO zG5w#0&E>moX06Us5wJl}cpTL=H2{0CbU!sCVsClIn7Q`iBn-o(nHR zm7L#F8+LVzAA7kCGYn0+lhs0+W2jurg!v>g71B|~ZZr^E{CC@(33|D34M>j}GAoN@ zG4~vKP`8DB2P-3j|E!nQ4k6*%z(z#MT-N^mYkEQt{^#Y&Z$8mTciMw*l0IpuP^1|I zG8ndB#z}xvG}^UTu|+oB4Em4*XcST;RHv`eG&$;sY~xOZ)@#A@Olr1?sdgAOPiEhC z5~HH!!1;5KSH0DH)mwb>UGL|mCBZ%k&JlFMMY3H(EZUObNfFxq9o*`2xeqhu*ZWyn z;ZZq%uQ9#OfvbN-4}Ynu)!j8~meLlrX0-^PYYSU;uqrkw^=jzHrz|Lc8l)}bj*cx= zr;7X_Ar;ynY;@^atK#}$uS+<1j`&Z_>ydG>IFjWzSwyVLA5g7g+qX3LGKe<6yi3>j zCR?4{7j9|%IfGx>o08brw6z|+{Ojy=4rYY8h-D8}vA3sVU(l@0{qrJgM#@FSv6!?p zWSQC~dI-1Dneiy`|B5uk#CgdY65{7P6WeGJpb;^hu%1=V%FLich_9c^DF#RLXmE-< z`X-Bj9tI9&@Td2=F6-^~>J-TI;pLM4Fp(Scf| zm|m4OQ^;IAWpHWzvH;VEw}IqQNYQZ1IJ2r zAIWvuHkv;c?`Y0Di$fq%+c`D)>?W!(6M;DHkr8`(CPDclgIDN4Uvx5(RJQW^HLe<$ zt9>t=Qi9;)Ums-x$f99pi}Gug0(YlSXw)2f59C)mz6a^=F>~dg?c*>i&f{+F$>sMl zBgmeACWpsCq&BFxKIGCr!Ia+jd=8s;x~nm*jy~l;b=O*@A#8oPCSP*=jb|dVNMYkD zCw*Ln0At1pqZjdm$*|s6oBB-yf~;%K*+Blqc(Edb~rrIyIzBU8}aTgqzI*xG5ztJ zt~h0l;0PYoKtFBwh@60H{fX~EW-C8<7ku`8=B@Siajf+Z>*)*j2>2mvC`usSRZ8;D zvY3qr_l6%WEHrDYxnXLtWm*E=F53>tn?)8GKzH5p{R4($3it~(5t%{vz0Hj2F%BDn zvSy6(mI*DUU2kscMxQ9t3Upbr!f^Cg<5&r+Wg$@o#q`Z4b9th5z(f(aZSb;|-^KXF z%M7Sn=sywt4Zz~Q!9PKtRCl~H3?h)(jQan`WM<(=JpClG5wBJ#X~dkiv>}dgw#2$@ z4(BJ3Y)89rd>SWxG?8BKvtfMXASheih`@M1sNGc;ICx=`J=#aZGF$Xj1!m+|HpoId z|Lnjv9A8|93d8*2P8O$fN`tCJoO5wab88;5Cnag$!=~ANbvlZCuLjf{4PZ!LVPzIM zF&jeHI&r7Dxg-VzLWMJaS-RKOsZKE?@l;#^)o??D-C;L;D5K?1%K#&6M~At zgzKapK$g|}IlaMUwCm!>aEELveZ(MUFT;+5y;bS#a~vl}n6}yQMFpD;&Xsuh$n|jc z2(C5vPURsxJYs2x&Xl64TK5@rNG$lF&$c&R$4H%&%eX^%xgD2nsz@DXGOx9`o1`w~ zp@T2K2>xHBNcmD3NZQnM&o_c(eLt30?ErG@qyA!l^EPC1Z#!o`K77{JBEYA0W@r1_ zCOO9~byk*>O$$bIraa-KVsg*T-k?i1wLwC5M?(n)+-9#K8s3O|QU~3c z`2R#!g(N`Y5O)b&xG(NAvFF2t<8PCOarPx@`Vw=d_Ox;dZB;QkkLJ=AMOmZ$gs5yZBEBTVs(;8hED zS+Jvg<9|@m3;B#61>miq?|)@$qj!N$aTbT!nf-|Ie@|irhGvAVcnZ3f!3DJ0gDn?x zrXHTuYAud!2!2q`IqXIMJ8*u70-OH#yQjM%73;=K~Lf#y{Yv+ck|5 zI8;#oJx~cVzJY8nR27mKY041=`v}Q6-kyvl`pRo-{%SwMQ~#R(OUYAeG$SPtbqD0$$kIAYjZ4xO8MyBBzY%^DEEHQE%@sYsS8 zIVxFM;g1a2<+zj_m%z_J{P>$X`0`$n0Y>(A#S=+dx_G4$W={zzez`U4t)pt=|Jc&} zFBN=5Rz6^ytQ}QmOVr@fG~&~Vp|Xv**_B=|NczH$Nr%T8%X*T3*24E2*XyKBE9viV zHLBY6P|#5|khDFYxo52Be1SrnBF$e#yf@$B|Cu@EOKy(-j1gDjwGcAhtSW!nhijkA zE;agpmb!xi*gPm6eFD|Bl6r}Oqp}>;R*}d$hDq%2;$yxn{-OVZqeu{C_!N%eym93J z>eKk!_n-`-nlzmSV-)~TQNWj!R59#)59ZG63C8BAoQTbyP3nrQhH~yuleJ?cus=)n2RUvcJpr{JFs0; zT1*&_a;~>vRYfMpmrBlsYlv8tj(=4*_#~ww^UGySU!{DNv5*SJbPp@>^PY3_!!k_& z;HVPBevUKzmsgs>0AwH^uS!Bnmfndb-4@6vVBK|%*QC(g&_*tuPV%fww5?Mt#>gls z%I+hGDk7dh+eaKB$!BL5OcOEMcWvEx#(^8ocuZit%49|7$<~d>?yo!ht|Lz}YXAN= z2(8{~7r9uwO;nT0!Hg@$=Z{~GO?~kJqlF7wm#3dSK$qh~LorKOe1nWRx~I>%w6y+G zbvH(5T^fCWvcy59+m!QLak}ErBH4e+_xxIok)*lzpvp z9a{EkCAl9UW=*3qOk1^@%oPwhcg|!PhHO)g4DSN10w6ts%^yg!SQn!_EU-oI*>Lf6 z@iw5T$(A4qrAn8U!>Jx;=Wu#sb=z$7>iTR(b@T7OGbGe`WT6q@`y_V-mnal6uI_TL zjw*@g$R{lP##se1OV{Tfps{v7yFaXL9fc{;s2Awc(PT0(FxYPH(w8gy2XsR~LZZx6 z!!@^r!MK{KVTa?1%d8*mM&+y$m1J`8&DC1MJep1OFMhSO(DUQcqxo z<|0nqUk68l0{9@(P6aN;tqFltNcfM4kAyps0(#z%AznZw%je@YxZU|Cq;R~Tu3%

NEyB!hXPj5<a5YPW(CMgY`U!0mpuHS6?vChD})!j8#v z%$Gt)508B;AiH)t4psfux?s=_U6fop(;sQ1Cfn13oOt7%%gw&`_t>fzUI{-AYwrSr zy3Ny1zQl(!<-wS~Yj(PulX3Dq!ge0y5Ra!fDa3Ujv%w;yt12Yuu+$&-y0kd@Iz)oF zq{N9(*ew?pZyk>?hFyQ-#ijWX1!!OkD~cR&jg68yq5g#ihF_ooEX`?}0zaVxpx1aP znRS34vtrs2P|yZ2g0N|d1(a|H1gva>RQuJN;7%mm5y3_^ok%>--YFtW->6_T3w>Yj z6cM0?@_0V@gIF#588^ZJP0DvIR#5!>{HH%5ZwhpadWKln`sh|f@}<W)HGSAUZ3lGUGM9R9@4^4 zg!kJvMX0+yUsr?oWeA+87V;Tb9X1b(F%YYGO>YkMk}yX%tV;|RqH?=S9p#Ha3P(cc zhRCvbzT{X_`=lHHMi zh~PHlaa-z(33BfnVN=Nz5FdHO%-2pYbBW{IiWqvMs<|$sl}O(Zt-l>#d}=>G0^eF< zo6!qc-l%j)HZukX4DQ+*BN297TD}bND}y7}K);grYm|76p8G66n0RmDQJ)@;29g`} znn|GhL&ukAB*8~HN$+AreCJlxvPwGry!4cus!`&#D>Ly^V`JddX&5G%IF`zA@|)1# zT3`XNlWCkZ)d$WUdZ^(&0NA0JvW9Kp?ah@a)wpcX#DccSD&A->suXpodmbS)kad=e zM&AcXTp~u1bylx`fzO&h7YPX_&y{+Z%$-|2_E0rB)m}x6!mldci{U);{uTo8X@3-3 z=)nTmuwnL|f=ICuaC67X5=4h6Wv#xBG=@d_0^9E-ZCMzn*vB^+jP9JNE7zWH8k*3~ zU%#p}QS+w&Sd&@Z)uNAq9A%ZE(X0@p;o#o(xW8We--Xh*#1Ed0B=mh-{|Io!dsoD~ z--1xo_P$*vt#TyO2&(4?^42dJ^#iSQ{p92%`K^&V#425vB!~=*c%B>G1m*;EM|#fs zlntNcnRb{0?E1g16hK;oGqbYdgEDo-u!4-gEz2_M#34a+vIk=FH(uv$~@R=FA? zFyfLrH?XZgipjB2xRiO_ep|=D)j#=foSw%m$Ei=;~@5%K5$1o_b^U@Srsl|S$gE|6j-y}vRX6srYzS$T5lAC zdoyL^?Yf7_`G=XnAKMcI+F_x^jO_}&^mFp^DE+Q;q92u+H9n`_u8$5Zlh8rWlbz+H zv6-7wEN!zks`%&VogMQ*YKV!Lvc8inj+v0QXcfPERU&AlPS_@?g>LWbD`6^3kUod3 zYWt#zH3UCp;I_tSOO3NaeU6-sb88-G3h7jsu_tGoye~{pGEKGX{v?F?q1k|K-w72x zI+&zS;3gQ15)du{2-Ab#U4WhD@JabMo&h=xwcVV-yr|S=8S=EBE%yKC3wK z+rZDAb{0xoc=8rXa#$walhhEGl#1RJUle(d!+YmQ*Bv!-O|A0-Muy@=4^2|7&lS1!+j5v4f zQQn;KO_D%UzRsZ=Qk-W3G&ior9ZB%*p(*$a%d>r7O(5hJ{aCljFrF_-;aAPMU|GsS zzYHWW18Ng_?-X*sY`jV$KV=vg9X$&K-8L!dNN~U*7f$ATZntyG4j+PAQeWFHk6;G4 zhwyYQY|w00y8q&t8b6?fCaL4?@LV0gwM7`Pb57FWq)$hfisaz&tvNCgGG?K zutPfqX|Wk%byD9quWN&5dmevLW~Trs&*O%JSe1$g5cK24cYM5FAZq}Z`o${x0@XP) z#e$67r>g^PItdkqy;&8Df|2!as*fF~PakhE=ByZuHfg(ZGx9QXX}Tw%mM87bbHZPF z;>Uhv9x#oNhhvutun|0)n#GRi*V`{U)7=ftI&W_(PkJC&{xGiUyUT$s;=dzShx~Ib zDEqnHigm&&i3&lo4qDxV7N9|v3k4N!EA~t(rThRAn5pFYBU^SlGNL-HM&?a+VPE}? zJVG8_UcEyi$gwR2<&{$*+4M`l4MD#S5qB$j%I5K14NF=v0y}t>wJNuV45VySP6~?P zWxSQdlo!Munto|5w)|9$#3(%_`!Y1DKpw{9osV_Tkh!~!>3^7w%w(@c1lY~fmdGVC z`Zg%@Gr_0Id-mW~dGJj*zZ2alEZBwA+?^kmXm&#>%8AXepcmvV^XjB4)sgSUs@Pc0 zLxZ5Mk#KNls4e$>i)_BJ$=C0QEsdkO_Fa5N1?~E9QvQVB7bZ1J2!^5h1Q^#}@josW zb>+(C-tS*|;IhsXi2cxPh*=%`Az|ZAI8r-u_qrTJHBMG$OJQJq`eKEBH{$+a06 z3xTq3SryrNg-ssI7=s-Q+rYxF41f;ky9H8S(iDmH_ver%3AvT<_avaf*b&HJ`) zQTDQ2;%9oUuu$j*QunH-74^0+#K~F((R(V0G2f?%mrE}`4wZ4)x<+&chA+8^)`o~$ zEU8d~04WaC^E%GPg0A39S)SUbY|r7>A_g(DVSID%ATS=f$X1qDH#mkNuSvrbNmyGYM5iz&erc5tlE{l~p!=|Ey_; z$<}yzvt;bAmjy$a2JqV6rH?ar5n7-o>T?e*Gxt6r!cD1N7e$EPCVV5)TFnn_{+lJM>t|uZ_Ru)oQHQ$#0 z$v48!4KmTDFmkVHq#zvs7X-*rTF_{soh@v`15?`{N9g9tM8PkSY)$?vD*%H{_heVY z?{dhm5EuVl>iIwGQ9m^9;EenS{|W-XKU3tZBo2RqkT3og#rXDVvK Date: Sat, 26 Mar 2022 12:10:59 -0700 Subject: [PATCH 129/253] Update app.js --- apps/quicklaunch/app.js | 80 +++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index 226a0433f..d6c9d0820 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -1,14 +1,5 @@ var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); -if (!settings.leftapp) { - settings["leftapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); -} -if (!settings.rightapp) { - settings["rightapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); -} - var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="launch" || (app.type=="clock" && Object.assign(require("Storage").readJSON("launch.json", true) || {}).showClocks) || !app.type)); apps.sort((a,b)=>{ @@ -31,41 +22,92 @@ function showMainMenu() { "< Back" : ()=>{load();} }; - mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(ltappmenu); }; - mainmenu["Right: "+settings.rightapp.name] = function() { E.showMenu(rtappmenu); }; + mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(leftmenu); }; + mainmenu["Right: "+settings.rightapp.name] = function() { E.showMenu(rightmenu); }; + mainmenu["Up: "+settings.upapp.name] = function() { E.showMenu(upmenu); }; + mainmenu["Down: "+settings.downapp.name] = function() { E.showMenu(downmenu); }; + mainmenu["Tap: "+settings.tapapp.name] = function() { E.showMenu(tapmenu); }; return E.showMenu(mainmenu); } -var ltappmenu = { +var leftmenu = { "" : { "title" : "Left Swipe" }, "< Back" : showMainMenu }; -ltappmenu["(none)"] = function() { +leftmenu["(none)"] = function() { save("leftapp", {"name":"(none)"}); showMainMenu(); }; apps.forEach((a)=>{ - ltappmenu[a.name] = function() { + leftmenu[a.name] = function() { save("leftapp", a); showMainMenu(); }; }); -var rtappmenu = { +var rightmenu = { "" : { "title" : "Right Swipe" }, "< Back" : showMainMenu }; -rtappmenu["(none)"] = function() { +rightmenu["(none)"] = function() { save("rightapp", {"name":"(none)"}); showMainMenu(); }; -apps.forEach((b)=>{ - rtappmenu[b.name] = function() { - save("rightapp", b); +apps.forEach((a)=>{ + rightmenu[a.name] = function() { + save("rightapp", a); + showMainMenu(); + }; +}); + +var upmenu = { + "" : { "title" : "Up Swipe" }, + "< Back" : showMainMenu +}; + +upmenu["(none)"] = function() { + save("upapp", {"name":"(none)"}); + showMainMenu(); +}; +apps.forEach((a)=>{ + upmenu[a.name] = function() { + save("upapp", a); + showMainMenu(); + }; +}); + +var downmenu = { + "" : { "title" : "Down Swipe" }, + "< Back" : showMainMenu +}; + +downmenu["(none)"] = function() { + save("downapp", {"name":"(none)"}); + showMainMenu(); +}; +apps.forEach((a)=>{ + downmenu[a.name] = function() { + save("downapp", a); + showMainMenu(); + }; +}); + +var tapmenu = { + "" : { "title" : "Tap" }, + "< Back" : showMainMenu +}; + +tapmenu["(none)"] = function() { + save("tapapp", {"name":"(none)"}); + showMainMenu(); +}; +apps.forEach((a)=>{ + tapmenu[a.name] = function() { + save("tapapp", a); showMainMenu(); }; }); From ea4187c00ea08fd36e22fed20d188cfa909e8ef2 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 12:11:26 -0700 Subject: [PATCH 130/253] Update boot.js --- apps/quicklaunch/boot.js | 43 +++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index c3e213d0c..33c1048b3 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -9,6 +9,18 @@ settings["rightapp"] = {"name":"(none)"}; require("Storage").write("quicklaunch.json",settings); } + if (!settings.upapp) { + settings["upapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } + if (!settings.downapp) { + settings["downapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } + if (!settings.tapapp) { + settings["tapapp"] = {"name":"(none)"}; + require("Storage").write("quicklaunch.json",settings); + } var sui = Bangle.setUI; Bangle.setUI = function(mode, cb) { @@ -16,10 +28,31 @@ if(!mode) return; if ("object"==typeof mode) mode = mode.mode; if (!mode.startsWith("clock")) return; - Bangle.swipeHandler = dir => { - if ((dir<0) && (settings.leftapp.src)) load(settings.leftapp.src); - if ((dir>0) && (settings.rightapp.src)) load(settings.rightapp.src); - }; - Bangle.on("swipe", Bangle.swipeHandler); + + function tap() { + if (settings.tapapp.src) load (settings.tapapp.src); + } + + let drag; + let e; + + Bangle.on("touch",tap); + Bangle.on("drag", e => { + if (!drag) { // start dragging + drag = {x: e.x, y: e.y}; + } else if (!e.b) { // released + const dx = e.x-drag.x, dy = e.y-drag.y; + drag = null; + if ((Math.abs(dx)>Math.abs(dy)+10) && (settings.leftapp.src)) { + // horizontal + load(dx>0 ? settings.rightapp.src : settings.leftapp.src); + } + else if (Math.abs(dy)>Math.abs(dx)+10) { + // vertical + load(dy>0 ? settings.downapp.src : settings.upapp.src); + } + } + }); + }; })(); From 26b4c43d4a195304ccee6b697b35b0fe96ca133a Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 12:34:00 -0700 Subject: [PATCH 131/253] Update boot.js --- apps/quicklaunch/boot.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 33c1048b3..4faf925e8 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -43,13 +43,13 @@ } else if (!e.b) { // released const dx = e.x-drag.x, dy = e.y-drag.y; drag = null; - if ((Math.abs(dx)>Math.abs(dy)+10) && (settings.leftapp.src)) { - // horizontal - load(dx>0 ? settings.rightapp.src : settings.leftapp.src); + if (Math.abs(dx)>Math.abs(dy)+10) { + if ((settings.leftapp.src) && dx<0) load(settings.leftapp.src); + if ((settings.rightapp.src) && dx>0) load(settings.rightapp.src); } else if (Math.abs(dy)>Math.abs(dx)+10) { - // vertical - load(dy>0 ? settings.downapp.src : settings.upapp.src); + if ((settings.upapp.src) && dy<0) load(settings.upapp.src); + if ((settings.downapp.src) && dy>0) load(settings.downapp.src); } } }); From 2a764c64ad70b8a8144909add9b6bdbcd28decc9 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 12:41:31 -0700 Subject: [PATCH 132/253] Update metadata.json --- apps/quicklaunch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index 09017f0f0..6411d1a5f 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -2,7 +2,7 @@ "name": "Quick Launch", "icon": "app.png", "version":"0.01", - "description": "Swipe left or right on your clock face to launch any two apps of your choice.", + "description": "Tap or swipe left/right/up/down on your clock face to launch up to five apps of your choice.", "tags": "tools, system", "supports": ["BANGLEJS2"], "storage": [ From bae7606df35b384476caa58dd6775088bb6718f2 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 13:06:48 -0700 Subject: [PATCH 133/253] Update app.js --- apps/quicklaunch/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index d6c9d0820..d919675f0 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -1,6 +1,6 @@ var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); -var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="launch" || (app.type=="clock" && Object.assign(require("Storage").readJSON("launch.json", true) || {}).showClocks) || !app.type)); +var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="launch" || app.type=="clock" || !app.type)); apps.sort((a,b)=>{ var n=(0|a.sortorder)-(0|b.sortorder); From 3ffc4425760b8e1e9394675085a32e33884a4428 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 14:03:39 -0700 Subject: [PATCH 134/253] Update boot.js --- apps/quicklaunch/boot.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 4faf925e8..89a24aa02 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -1,6 +1,6 @@ (function() { var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); - + if (!settings.leftapp) { settings["leftapp"] = {"name":"(none)"}; require("Storage").write("quicklaunch.json",settings); @@ -30,7 +30,8 @@ if (!mode.startsWith("clock")) return; function tap() { - if (settings.tapapp.src) load (settings.tapapp.src); + var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); + if ((settings.tapapp.src) && apps.some(e => e.src === settings.tapapp.src)) load (settings.tapapp.src); } let drag; @@ -43,13 +44,14 @@ } else if (!e.b) { // released const dx = e.x-drag.x, dy = e.y-drag.y; drag = null; + var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); if (Math.abs(dx)>Math.abs(dy)+10) { - if ((settings.leftapp.src) && dx<0) load(settings.leftapp.src); - if ((settings.rightapp.src) && dx>0) load(settings.rightapp.src); + if ((settings.leftapp.src) && apps.some(e => e.src === settings.leftapp.src) && dx<0) load(settings.leftapp.src); + if ((settings.rightapp.src) && apps.some(e => e.src === settings.rightapp.src) && dx>0) load(settings.rightapp.src); } else if (Math.abs(dy)>Math.abs(dx)+10) { - if ((settings.upapp.src) && dy<0) load(settings.upapp.src); - if ((settings.downapp.src) && dy>0) load(settings.downapp.src); + if ((settings.upapp.src) && apps.some(e => e.src === settings.upapp.src) && dy<0) load(settings.upapp.src); + if ((settings.downapp.src) && apps.some(e => e.src === settings.downapp.src) && dy>0) load(settings.downapp.src); } } }); From 506746a4d47b09eeb1ac9c8372a9303f6e64d139 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 14:17:51 -0700 Subject: [PATCH 135/253] Update boot.js --- apps/quicklaunch/boot.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 89a24aa02..22ec670de 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -1,5 +1,7 @@ (function() { var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); + + //populate empty app list if (!settings.leftapp) { settings["leftapp"] = {"name":"(none)"}; @@ -22,6 +24,7 @@ require("Storage").write("quicklaunch.json",settings); } + //activate on clock faces var sui = Bangle.setUI; Bangle.setUI = function(mode, cb) { sui(mode,cb); @@ -30,6 +33,7 @@ if (!mode.startsWith("clock")) return; function tap() { + //tap, check if source exists var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); if ((settings.tapapp.src) && apps.some(e => e.src === settings.tapapp.src)) load (settings.tapapp.src); } @@ -44,11 +48,14 @@ } else if (!e.b) { // released const dx = e.x-drag.x, dy = e.y-drag.y; drag = null; + //check if source exists var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); + //horizontal swipes if (Math.abs(dx)>Math.abs(dy)+10) { if ((settings.leftapp.src) && apps.some(e => e.src === settings.leftapp.src) && dx<0) load(settings.leftapp.src); if ((settings.rightapp.src) && apps.some(e => e.src === settings.rightapp.src) && dx>0) load(settings.rightapp.src); } + //vertical swipes else if (Math.abs(dy)>Math.abs(dx)+10) { if ((settings.upapp.src) && apps.some(e => e.src === settings.upapp.src) && dy<0) load(settings.upapp.src); if ((settings.downapp.src) && apps.some(e => e.src === settings.downapp.src) && dy>0) load(settings.downapp.src); From 46d82b45c21197f77ebf2e15d528aaaec1f11fb7 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sat, 26 Mar 2022 14:20:10 -0700 Subject: [PATCH 136/253] Update app.js --- apps/quicklaunch/app.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/quicklaunch/app.js b/apps/quicklaunch/app.js index d919675f0..f2b749e3e 100644 --- a/apps/quicklaunch/app.js +++ b/apps/quicklaunch/app.js @@ -15,13 +15,14 @@ function save(key, value) { require("Storage").write("quicklaunch.json",settings); } -// First menu +// Quick Launch menu function showMainMenu() { var mainmenu = { "" : { "title" : "Quick Launch" }, "< Back" : ()=>{load();} }; + //List all selected apps mainmenu["Left: "+settings.leftapp.name] = function() { E.showMenu(leftmenu); }; mainmenu["Right: "+settings.rightapp.name] = function() { E.showMenu(rightmenu); }; mainmenu["Up: "+settings.upapp.name] = function() { E.showMenu(upmenu); }; @@ -31,7 +32,7 @@ function showMainMenu() { return E.showMenu(mainmenu); } - +//Left swipe menu var leftmenu = { "" : { "title" : "Left Swipe" }, "< Back" : showMainMenu @@ -48,6 +49,7 @@ apps.forEach((a)=>{ }; }); +//Right swipe menu var rightmenu = { "" : { "title" : "Right Swipe" }, "< Back" : showMainMenu @@ -64,6 +66,7 @@ apps.forEach((a)=>{ }; }); +//Up swipe menu var upmenu = { "" : { "title" : "Up Swipe" }, "< Back" : showMainMenu @@ -80,6 +83,7 @@ apps.forEach((a)=>{ }; }); +//Down swipe menu var downmenu = { "" : { "title" : "Down Swipe" }, "< Back" : showMainMenu @@ -96,6 +100,7 @@ apps.forEach((a)=>{ }; }); +//Tap menu var tapmenu = { "" : { "title" : "Tap" }, "< Back" : showMainMenu @@ -112,5 +117,4 @@ apps.forEach((a)=>{ }; }); -// Actually display the menu showMainMenu(); From 4c90ea57d75e9dea0588a654d06e489fb85a8aec Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 27 Mar 2022 09:02:15 +0800 Subject: [PATCH 137/253] Update interface.html Use Bangle styling for buttons. Move main token list UI button to above the tokens. --- apps/authentiwatch/interface.html | 39 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 7d567d34f..13d46ac03 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -226,15 +226,15 @@ function editToken(id) { markup += selectMarkup('algorithm', otpAlgos, tokens[id].algorithm); markup += ''; markup += ''; - markup += ''; + markup += ''; markup += ''; - markup += ''; - markup += ''; + markup += ''; + markup += ''; if (tokens[id].isnew) { - markup += ''; + markup += ''; } else { - markup += ''; - markup += ''; + markup += ''; + markup += ''; } document.getElementById('edit').innerHTML = markup; document.body.className = 'editing'; @@ -304,9 +304,19 @@ function updateTokens() { return ''; }; const tokenButton = function(fn, id, label, dir) { - return ''; + return ''; }; - var markup = '
'; + var markup = ''; + markup += '
'; + markup += ''; + markup += ''; + markup += ''; + markup += ''; + markup += '
'; + markup += ''; + markup += ''; + markup += '
'; + markup += ''; /* any tokens marked new are cancelled new additions and must be removed */ @@ -331,15 +341,6 @@ function updateTokens() { markup += ''; } markup += '
'; markup += tokenSelect('all'); markup += 'TokenOrder
'; - markup += '
'; - markup += ''; - markup += ''; - markup += ''; - markup += ''; - markup += '
'; - markup += ''; - markup += ''; - markup += '
'; document.getElementById('tokens').innerHTML = markup; document.body.className = 'select'; } @@ -604,7 +605,7 @@ function qrBack() {
- +
@@ -613,7 +614,7 @@ function qrBack() {
- +
From ecc3f5ff66e0df4c9539795570022c747e5941e5 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 27 Mar 2022 09:12:55 +0800 Subject: [PATCH 138/253] Update interface.html Space out buttons. --- apps/authentiwatch/interface.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 13d46ac03..e80180a45 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -229,11 +229,14 @@ function editToken(id) { markup += ''; markup += '
'; markup += ''; + markup += ' '; markup += ''; + markup += ' '; if (tokens[id].isnew) { markup += ''; } else { markup += ''; + markup += ' '; markup += ''; } document.getElementById('edit').innerHTML = markup; @@ -309,11 +312,15 @@ function updateTokens() { var markup = ''; markup += '

'; markup += ''; markup += '
'; From 638bc7fb3ed540c9a6a3260d99f3972239de9c1f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 27 Mar 2022 09:22:39 +0800 Subject: [PATCH 139/253] Update interface.html Change button styling to non-primary. --- apps/authentiwatch/interface.html | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index e80180a45..011549df2 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -226,18 +226,18 @@ function editToken(id) { markup += selectMarkup('algorithm', otpAlgos, tokens[id].algorithm); markup += '
'; - markup += ''; + markup += ''; markup += '
'; - markup += ''; + markup += ''; markup += ' '; - markup += ''; + markup += ''; markup += ' '; if (tokens[id].isnew) { - markup += ''; + markup += ''; } else { - markup += ''; + markup += ''; markup += ' '; - markup += ''; + markup += ''; } document.getElementById('edit').innerHTML = markup; document.body.className = 'editing'; @@ -307,21 +307,21 @@ function updateTokens() { return ''; }; const tokenButton = function(fn, id, label, dir) { - return ''; + return ''; }; var markup = ''; markup += '
'; - markup += ''; + markup += ''; markup += ' '; - markup += ''; + markup += ''; markup += ' '; - markup += ''; + markup += ''; markup += ' '; - markup += ''; + markup += ''; markup += '
'; - markup += ''; + markup += ''; markup += ' '; - markup += ''; + markup += ''; markup += '
'; markup += '
'; markup += tokenSelect('all'); @@ -612,7 +612,7 @@ function qrBack() {
- +
@@ -621,7 +621,7 @@ function qrBack() {
- +
From 2b32bc37e26ab5965482ece5a1e3372389b2ffe6 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 27 Mar 2022 09:27:01 +0800 Subject: [PATCH 140/253] Update interface.html Change token row background colours. --- apps/authentiwatch/interface.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 011549df2..d7cd59f1a 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -12,8 +12,8 @@ body.select div.select,body.export div.export{display:block} body.select div.export,body.export div.select{display:none} body.select div#tokens,body.editing div#edit,body.scanning div#scan,body.showqr div#showqr,body.export div#tokens{display:block} #tokens th,#tokens td{padding:5px} -#tokens tr:nth-child(odd){background-color:#ccc} -#tokens tr:nth-child(even){background-color:#eee} +#tokens tr:nth-child(odd){background-color:#f1f1fc} +#tokens tr:nth-child(even){background-color:#fff} #qr-canvas{margin:auto;width:calc(100%-20px);max-width:400px} #advbtn,#scan,#tokenqr table{text-align:center} #edittoken tbody#adv{display:none} From 178b011c34c70ebcbf160fa986f7fd58324b8896 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 27 Mar 2022 10:30:34 +0800 Subject: [PATCH 141/253] Fix #1583. Fix timers doubling (plus a bit) when they expire. Timer reset restores to configured time, not to the default. Added surise/sunset times (hidden by default). --- apps/timerclk/ChangeLog | 1 + apps/timerclk/README.md | 1 + apps/timerclk/alarm.info | 1 - apps/timerclk/app.js | 34 ++++++++++++++++++++++++++++++++++ apps/timerclk/boot.js | 19 +++++-------------- apps/timerclk/lib.js | 2 ++ apps/timerclk/metadata.json | 5 +---- apps/timerclk/settings.js | 28 ++++++++++++++++++++++++++++ apps/timerclk/stopwatch.info | 1 - apps/timerclk/timer.alert.js | 17 +++-------------- apps/timerclk/timer.info | 1 - apps/timerclk/timer.js | 8 +++++--- 12 files changed, 80 insertions(+), 38 deletions(-) delete mode 100644 apps/timerclk/alarm.info delete mode 100644 apps/timerclk/stopwatch.info delete mode 100644 apps/timerclk/timer.info diff --git a/apps/timerclk/ChangeLog b/apps/timerclk/ChangeLog index 5560f00bc..e17baa27c 100644 --- a/apps/timerclk/ChangeLog +++ b/apps/timerclk/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: Add sunrise/sunset. Fix timer bugs. diff --git a/apps/timerclk/README.md b/apps/timerclk/README.md index fd6d2b16b..c27a8f6f8 100644 --- a/apps/timerclk/README.md +++ b/apps/timerclk/README.md @@ -11,6 +11,7 @@ A clock based on the Anton Clock with stopwatches, timers and alarms based on th * alarms * multiple stopwatches, timers and alarms * stopwatches and timers keep running in the background +* optional time of sunrise/sunset using the My Location app - hidden by default ## Images diff --git a/apps/timerclk/alarm.info b/apps/timerclk/alarm.info deleted file mode 100644 index 1289f8cef..000000000 --- a/apps/timerclk/alarm.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"timerclk","name":"tclk Alarm","src":"timerclk.alarm.js","icon":"timerclk.img","version":"0.01","tags":"","files":"","sortorder":10} diff --git a/apps/timerclk/app.js b/apps/timerclk/app.js index eeb3ac4cd..c750fcfde 100644 --- a/apps/timerclk/app.js +++ b/apps/timerclk/app.js @@ -3,6 +3,23 @@ Graphics.prototype.setFontAnton = function(scale) { g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAA/gAAAAAAAAAAP/gAAAAAAAAAH//gAAAAAAAAB///gAAAAAAAAf///gAAAAAAAP////gAAAAAAD/////gAAAAAA//////gAAAAAP//////gAAAAH///////gAAAB////////gAAAf////////gAAP/////////gAD//////////AA//////////gAA/////////4AAA////////+AAAA////////gAAAA///////wAAAAA//////8AAAAAA//////AAAAAAA/////gAAAAAAA////4AAAAAAAA///+AAAAAAAAA///gAAAAAAAAA//wAAAAAAAAAA/8AAAAAAAAAAA/AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////AAAAAB///////8AAAAH////////AAAAf////////wAAA/////////4AAB/////////8AAD/////////+AAH//////////AAP//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wA//8AAAAAB//4A//wAAAAAAf/4A//gAAAAAAP/4A//gAAAAAAP/4A//gAAAAAAP/4A//wAAAAAAf/4A///////////4Af//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH//////////AAD/////////+AAB/////////8AAA/////////4AAAP////////gAAAD///////+AAAAAf//////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAP/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/AAAAAAAAAAA//AAAAAAAAAAA/+AAAAAAAAAAB/8AAAAAAAAAAD//////////gAH//////////gAP//////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAAB/gAAD//4AAAAf/gAAP//4AAAB//gAA///4AAAH//gAB///4AAAf//gAD///4AAA///gAH///4AAD///gAP///4AAH///gAP///4AAP///gAf///4AAf///gAf///4AB////gAf///4AD////gA////4AH////gA////4Af////gA////4A/////gA//wAAB/////gA//gAAH/////gA//gAAP/////gA//gAA///8//gA//gAD///w//gA//wA////g//gA////////A//gA///////8A//gA///////4A//gAf//////wA//gAf//////gA//gAf/////+AA//gAP/////8AA//gAP/////4AA//gAH/////gAA//gAD/////AAA//gAB////8AAA//gAA////wAAA//gAAP///AAAA//gAAD//8AAAA//gAAAP+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/+AAAAAD/wAAB//8AAAAP/wAAB///AAAA//wAAB///wAAB//wAAB///4AAD//wAAB///8AAH//wAAB///+AAP//wAAB///+AAP//wAAB////AAf//wAAB////AAf//wAAB////gAf//wAAB////gA///wAAB////gA///wAAB////gA///w//AAf//wA//4A//AAA//wA//gA//AAAf/wA//gB//gAAf/wA//gB//gAAf/wA//gD//wAA//wA//wH//8AB//wA///////////gA///////////gA///////////gA///////////gAf//////////AAf//////////AAP//////////AAP/////////+AAH/////////8AAH///+/////4AAD///+f////wAAA///8P////gAAAf//4H///+AAAAH//gB///wAAAAAP4AAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAAAAAAAAAA//wAAAAAAAAAP//wAAAAAAAAB///wAAAAAAAAf///wAAAAAAAH////wAAAAAAA/////wAAAAAAP/////wAAAAAB//////wAAAAAf//////wAAAAH///////wAAAA////////wAAAP////////wAAA///////H/wAAA//////wH/wAAA/////8AH/wAAA/////AAH/wAAA////gAAH/wAAA///4AAAH/wAAA//+AAAAH/wAAA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAH/4AAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8AAA/////+B///AAA/////+B///wAA/////+B///4AA/////+B///8AA/////+B///8AA/////+B///+AA/////+B////AA/////+B////AA/////+B////AA/////+B////gA/////+B////gA/////+B////gA/////+A////gA//gP/gAAB//wA//gf/AAAA//wA//gf/AAAAf/wA//g//AAAAf/wA//g//AAAA//wA//g//gAAA//wA//g//+AAP//wA//g////////gA//g////////gA//g////////gA//g////////gA//g////////AA//gf///////AA//gf//////+AA//gP//////+AA//gH//////8AA//gD//////4AA//gB//////wAA//gA//////AAAAAAAH////8AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////gAAAAB///////+AAAAH////////gAAAf////////4AAB/////////8AAD/////////+AAH//////////AAH//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wAf//////////4A//wAD/4AAf/4A//gAH/wAAP/4A//gAH/wAAP/4A//gAP/wAAP/4A//gAP/4AAf/4A//wAP/+AD//4A///wP//////4Af//4P//////wAf//4P//////wAf//4P//////wAf//4P//////wAP//4P//////gAP//4H//////gAH//4H//////AAH//4D/////+AAD//4D/////8AAB//4B/////4AAA//4A/////wAAAP/4AP////AAAAB/4AD///4AAAAAAAAAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAADgA//gAAAAAAP/gA//gAAAAAH//gA//gAAAAB///gA//gAAAAP///gA//gAAAD////gA//gAAAf////gA//gAAB/////gA//gAAP/////gA//gAB//////gA//gAH//////gA//gA///////gA//gD///////gA//gf///////gA//h////////gA//n////////gA//////////gAA/////////AAAA////////wAAAA///////4AAAAA///////AAAAAA//////4AAAAAA//////AAAAAAA/////4AAAAAAA/////AAAAAAAA////8AAAAAAAA////gAAAAAAAA///+AAAAAAAAA///4AAAAAAAAA///AAAAAAAAAA//4AAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//gB///wAAAAP//4H///+AAAA///8P////gAAB///+f////4AAD///+/////8AAH/////////+AAH//////////AAP//////////gAP//////////gAf//////////gAf//////////wAf//////////wAf//////////wA///////////wA//4D//wAB//4A//wB//gAA//4A//gA//gAAf/4A//gA//AAAf/4A//gA//gAAf/4A//wB//gAA//4A///P//8AH//4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////gAP//////////gAP//////////AAH//////////AAD/////////+AAD///+/////8AAB///8f////wAAAf//4P////AAAAH//wD///8AAAAA/+AAf//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAAAAAAAAB///+AA/+AAAAP////gA//wAAAf////wA//4AAB/////4A//8AAD/////8A//+AAD/////+A///AAH/////+A///AAP//////A///gAP//////A///gAf//////A///wAf//////A///wAf//////A///wAf//////A///wA///////AB//4A//4AD//AAP/4A//gAB//AAP/4A//gAA//AAP/4A//gAA/+AAP/4A//gAB/8AAP/4A//wAB/8AAf/4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH/////////+AAD/////////8AAB/////////4AAAf////////wAAAP////////AAAAB///////4AAAAAD/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAB/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("EiAnGicnJycnJycnEw=="), 78+(scale<<8)+(1<<16)); }; +var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js"); +const LOCATION_FILE = "mylocation.json"; +let location; +var sunRise = "--:--"; +var sunSet = "--:--"; +var sunIcons = "\0" + atob("DwyBAAAAAAAAAAgAOAD4A/gP+D/4//gAAAAA") + "\0" + atob("FQyDAAAAAAAAAAAAAAAABAAAAAAABAAIABAAAAABAAABAAAAAAABJAAAAABAAJJJIABAABAJJJJIBAAAAJJJJJIAAAAJJJJJJIAAJBJJJJJJBIAAJJJJJJIAAAAAAAAAAAAA") + "\0" + atob("DwyBAAAAAAAAA//j/4P+A/gD4AOAAgAAAAAA"); + +function loadLocation() { + location = require('Storage').readJSON(LOCATION_FILE, true) || {lat:51.5072,lon:0.1276,location:"London"}; +} + +function updateSunRiseSunSet(location) { + var times = SunCalc.getTimes(new Date(), location.lat, location.lon); + sunRise = require("locale").time(times.sunrise, 1); + sunSet = require("locale").time(times.sunset, 1); +} + var timerclk = require("timerclk.lib.js"); var settings = require('Storage').readJSON("timerclk.json", true) || {}; settings = Object.assign({ @@ -12,11 +29,14 @@ settings = Object.assign({ "dateFontSize":2, "dowFont":"6x8", "dowFontSize":2, + "srssFont":"6x8", + "srssFontSize":2, "specialFont":"6x8", "specialFontSize":2, "shortDate":true, "showStopwatches":true, "showTimers":true, + "showSrss":false, }, settings.clock||{}); var stopwatches = [], timers = []; @@ -77,7 +97,12 @@ function drawSpecial() { queueDraw(drawSpecialTimeout, interval, drawSpecial); } +var drawCount=0; + function draw() { + if (drawCount++ % 60 == 0) { + updateSunRiseSunSet(location); + } var x = g.getWidth()/2; var y = g.getHeight()/2; g.reset(); @@ -85,6 +110,7 @@ function draw() { var timeStr = require("locale").time(date,1); var dateStr = require("locale").date(date,settings.shortDate).toUpperCase(); var dowStr = require("locale").dow(date).toUpperCase(); + var srssStr = sunRise + sunIcons + sunSet; // draw time if (settings.timeFont == "Anton") { @@ -105,6 +131,13 @@ function draw() { g.setFontAlign(0,0).setFont(settings.dowFont, settings.dowFontSize); y += g.stringMetrics(dowStr).height/2; g.drawString(dowStr,x,y); + if (settings.showSrss) { + // draw sun rise sun set + y += g.stringMetrics(dowStr).height/2; + g.setFontAlign(0,0).setFont(settings.srssFont, settings.srssFontSize); + y += g.stringMetrics(srssStr).height/2; + g.drawString(srssStr,x,y); + } // queue draw in one minute queueDraw(drawTimeout, 60000, draw); } @@ -147,5 +180,6 @@ Bangle.setUI("clock"); // Show launcher when middle button pressed g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); +loadLocation(); draw(); if (stopwatches || timers) drawSpecial(); diff --git a/apps/timerclk/boot.js b/apps/timerclk/boot.js index 9a09f68f3..b6eb05c14 100644 --- a/apps/timerclk/boot.js +++ b/apps/timerclk/boot.js @@ -1,26 +1,17 @@ var timerclkTimerTimeout; var timerclkAlarmTimeout; function timerclkCheckTimers() { + var expiresIn=require("timerclk.lib.js").timerExpiresIn; if (timerclkTimerTimeout) clearTimeout(timerclkTimerTimeout); var timers = require('Storage').readJSON('timerclk.timer.json',1)||[]; timers = timers.filter(e=>e.start); if (timers.length) { - timers = timers.sort((a,b)=>{ - var at = a.timeAdd; - if (a.start) at += Date.now()-a.start; - at = a.period-at; - var bt = b.timeAdd; - if (b.start) bt += Date.now()-b.start; - bt = b.period-bt; - return at-bt; - }); + timers = timers.sort((a,b)=>expiresIn(a)-expiresIn(b)); if (!require('Storage').read("timerclk.timer.alert.js")) { console.log("No timer app!"); } else { - var time = timers[0].timeAdd; - if (timers[0].start) time += Date.now()-timers[0].start; - time = timers[0].time - time; - if (time<1000) t=1000; + var time = expiresIn(timers[0]); + if (time<1000) time=1000; if (timerclkTimerTimeout) clearTimeout(timerclkTimerTimeout); timerclkTimerTimeout = setTimeout(() => load("timerclk.timer.alert.js"),time); } @@ -38,7 +29,7 @@ function timerclkCheckAlarms() { } else { var time = alarms[0].time-currentTime; if (alarms[0].last == new Date().getDate() || time < 0) time += 86400000; - if (time<1000) t=1000; + if (time<1000) time=1000; if (timerclkAlarmTimeout) clearTimeout(timerclkAlarmTimeout); timerclkAlarmTimeout = setTimeout(() => load("timerclk.alarm.alert.js"),time); } diff --git a/apps/timerclk/lib.js b/apps/timerclk/lib.js index 718962fe0..dd3893fa1 100644 --- a/apps/timerclk/lib.js +++ b/apps/timerclk/lib.js @@ -125,3 +125,5 @@ exports.registerControls = function(o) { }); } }; + +exports.timerExpiresIn=t=>t.time-(Date.now()-t.start); diff --git a/apps/timerclk/metadata.json b/apps/timerclk/metadata.json index 6b415c0fc..ce8870ab0 100644 --- a/apps/timerclk/metadata.json +++ b/apps/timerclk/metadata.json @@ -2,7 +2,7 @@ "id": "timerclk", "name": "Timer Clock", "shortName":"Timer Clock", - "version":"0.01", + "version":"0.02", "description": "A clock with stopwatches, timers and alarms build in.", "icon": "app-icon.png", "type": "clock", @@ -29,9 +29,6 @@ {"name":"timerclk.timer.alert.js","url":"timer.alert.js"}, {"name":"timerclk.alarm.js","url":"alarm.js"}, {"name":"timerclk.alarm.alert.js","url":"alarm.alert.js"}, - {"name":"timerclk.stopwatch.info","url":"stopwatch.info"}, - {"name":"timerclk.timer.info","url":"timer.info"}, - {"name":"timerclk.alarm.info","url":"alarm.info"} ], "data": [{"name":"timerclk.json"},{"name":"timerclk.stopwatch.json"},{"name":"timerclk.timer.json"},{"name":"timerclk.alarm.json"}], "sortorder": 0 diff --git a/apps/timerclk/settings.js b/apps/timerclk/settings.js index 556dded98..992985f52 100644 --- a/apps/timerclk/settings.js +++ b/apps/timerclk/settings.js @@ -12,9 +12,12 @@ "dowFontSize":2, "specialFont":"6x8", "specialFontSize":2, + "srssFont":"6x8", + "srssFontSize":2, "shortDate":true, "showStopwatches":true, "showTimers":true, + "showSrss":false, }, settings.clock||{}); settings.stopwatch = Object.assign({ "font":"Vector", @@ -108,6 +111,23 @@ writeSettings(); } }, + "sun font":{ + value: 0|g.getFonts().indexOf(settings.clock.srssFont), + format: v => g.getFonts()[v], + min: 0, max: g.getFonts().length-1, + onchange: v => { + settings.clock.srssFont = g.getFonts()[v]; + writeSettings(); + } + }, + "sun size":{ + value: 0|settings.clock.srssFontSize, + min: 0, + onchange: v => { + settings.clock.srssFontSize = v; + writeSettings(); + } + }, "short date": { value: !!settings.clock.shortDate, format: BOOL_FORMAT, @@ -132,6 +152,14 @@ writeSettings(); } }, + "sun times": { + value: !!settings.clock.showSrss, + format: v=>v?/*LANG*/"Show":/*LANG*/"Hide", + onchange: v => { + settings.clock.showSrss = v; + writeSettings(); + } + }, }; var stopwatchMenu = { diff --git a/apps/timerclk/stopwatch.info b/apps/timerclk/stopwatch.info deleted file mode 100644 index 72ad418b1..000000000 --- a/apps/timerclk/stopwatch.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"timerclk","name":"tclk Stopwatch","src":"timerclk.stopwatch.js","icon":"timerclk.img","version":"0.01","tags":"","files":"","sortorder":10} diff --git a/apps/timerclk/timer.alert.js b/apps/timerclk/timer.alert.js index f51ea6767..96352097d 100644 --- a/apps/timerclk/timer.alert.js +++ b/apps/timerclk/timer.alert.js @@ -14,10 +14,7 @@ function showTimer(timer) { buttons : {/*LANG*/"Ok":true} }).then(function(ok) { buzzCount = 0; - if (ok) { - timer.time += Date.now() - timer.start; - timer.start = null; - } + timer.start = null; require("Storage").write("timerclk.timer.json",JSON.stringify(timers)); load(); }); @@ -45,16 +42,8 @@ console.log("checking for timers..."); var timers = require("Storage").readJSON("timerclk.timer.json",1)||[]; var active = timers.filter(e=>e.start); if (active.length) { - // if there's an timer, show it - active = active.sort((a,b)=>{ - var at = a.time; - if (a.start) at += Date.now()-a.start; - at = a.period-at; - var bt = b.time; - if (b.start) bt += Date.now()-b.start; - bt = b.period-bt; - return at-bt; - }); + // if there's an active timer, show it + active = active.sort((a,b)=>timerclk.timerExpiresIn(a)-timerclk.timerExpiresIn(b)); showTimer(active[0]); } else { // otherwise just go back to default app diff --git a/apps/timerclk/timer.info b/apps/timerclk/timer.info deleted file mode 100644 index 39a338693..000000000 --- a/apps/timerclk/timer.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"timerclk","name":"tclk Timer","src":"timerclk.timer.js","icon":"timerclk.img","version":"0.01","tags":"","files":"","sortorder":10} diff --git a/apps/timerclk/timer.js b/apps/timerclk/timer.js index 060c07813..25052e6ae 100644 --- a/apps/timerclk/timer.js +++ b/apps/timerclk/timer.js @@ -34,18 +34,20 @@ function update() { } function play() { if (all[current].start) { // running - all[current].timeAdd += Date.now() - all[current].start; + all[current].timeAdd = Date.now() - all[current].start; all[current].start = null; update(); } else { // paused - all[current].start = Date.now(); + all[current].start = Date.now() - all[current].timeAdd; + all[current].timeAdd = 0; update(); } require("Storage").write("timerclk.timer.json",JSON.stringify(all)); timerclkCheckTimers(); } function reset() { - all[current] = defaultElement.clone(); + all[current].start = null; + all[current].timeAdd = 0; update(); require("Storage").write("timerclk.timer.json",JSON.stringify(all)); timerclkCheckTimers(); From 2a530646c1cc87297ef39e4692e37b9ac918522a Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 27 Mar 2022 10:40:26 +0800 Subject: [PATCH 142/253] Fix metadata. --- apps/timerclk/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/timerclk/metadata.json b/apps/timerclk/metadata.json index ce8870ab0..7c6c7c9b3 100644 --- a/apps/timerclk/metadata.json +++ b/apps/timerclk/metadata.json @@ -28,7 +28,7 @@ {"name":"timerclk.timer.js","url":"timer.js"}, {"name":"timerclk.timer.alert.js","url":"timer.alert.js"}, {"name":"timerclk.alarm.js","url":"alarm.js"}, - {"name":"timerclk.alarm.alert.js","url":"alarm.alert.js"}, + {"name":"timerclk.alarm.alert.js","url":"alarm.alert.js"} ], "data": [{"name":"timerclk.json"},{"name":"timerclk.stopwatch.json"},{"name":"timerclk.timer.json"},{"name":"timerclk.alarm.json"}], "sortorder": 0 From 6330ec0b93a67b4cfc96062370d3653af9360acf Mon Sep 17 00:00:00 2001 From: Hilmar Strauch <56518493+HilmarSt@users.noreply.github.com> Date: Sun, 27 Mar 2022 09:33:57 +0200 Subject: [PATCH 143/253] Add files via upload --- apps/bikespeedo/settings.js | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 apps/bikespeedo/settings.js diff --git a/apps/bikespeedo/settings.js b/apps/bikespeedo/settings.js new file mode 100644 index 000000000..a3921f4a3 --- /dev/null +++ b/apps/bikespeedo/settings.js @@ -0,0 +1,48 @@ +(function(back) { + + let settings = require('Storage').readJSON('bikespeedo.json',1)||{}; + + function writeSettings() { + require('Storage').write('bikespeedo.json',settings); + } + + const appMenu = { + '': {'title': 'Bike Speedometer'}, + '< Back': back, + '< Load Bike Speedometer': ()=>{load('bikespeedo.app.js');}, + 'Barometer Altitude adjustment' : function() { E.showMenu(altdiffMenu); }, + 'Kalman Filters' : function() { E.showMenu(kalMenu); } + }; + + const altdiffMenu = { + '': { 'title': 'Altitude adjustment' }, + '< Back': function() { E.showMenu(appMenu); }, + 'Altitude delta': { + value: settings.altDiff || 100, + min: -200, + max: 200, + step: 10, + onchange: v => { + settings.altDiff = v; + writeSettings(); } + } + }; + + const kalMenu = { + '': {'title': 'Kalman Filters'}, + '< Back': function() { E.showMenu(appMenu); }, + 'Speed' : { + value : settings.spdFilt, + format : v => v?"On":"Off", + onchange : () => { settings.spdFilt = !settings.spdFilt; writeSettings(); } + }, + 'Altitude' : { + value : settings.altFilt, + format : v => v?"On":"Off", + onchange : () => { settings.altFilt = !settings.altFilt; writeSettings(); } + } + }; + + E.showMenu(appMenu); + +}); From 354d6e283202908b5356d82ff7950b05a8f94436 Mon Sep 17 00:00:00 2001 From: Hilmar Strauch <56518493+HilmarSt@users.noreply.github.com> Date: Sun, 27 Mar 2022 09:36:06 +0200 Subject: [PATCH 144/253] Update metadata.json --- apps/bikespeedo/metadata.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/bikespeedo/metadata.json b/apps/bikespeedo/metadata.json index 7dea28649..a627f19f8 100644 --- a/apps/bikespeedo/metadata.json +++ b/apps/bikespeedo/metadata.json @@ -2,7 +2,7 @@ "id": "bikespeedo", "name": "Bike Speedometer (beta)", "shortName": "Bike Speedomet.", - "version": "0.01", + "version": "0.02", "description": "Shows GPS speed, GPS heading, Compass heading, GPS altitude and Barometer altitude from internal sources", "icon": "app.png", "screenshots": [{"url":"Screenshot.png"}], @@ -13,6 +13,8 @@ "allow_emulator": true, "storage": [ {"name":"bikespeedo.app.js","url":"app.js"}, - {"name":"bikespeedo.img","url":"app-icon.js","evaluate":true} - ] + {"name":"bikespeedo.img","url":"app-icon.js","evaluate":true}, + {"name":"bikespeedo.settings.js","url":"settings.js"} + ], + "data": [{"name":"bikespeedo.json"}] } From 746bbe7a10c3c3d631f9c8e6bb03b7a3f5647b48 Mon Sep 17 00:00:00 2001 From: Hilmar Strauch <56518493+HilmarSt@users.noreply.github.com> Date: Sun, 27 Mar 2022 09:38:13 +0200 Subject: [PATCH 145/253] Update ChangeLog --- apps/bikespeedo/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bikespeedo/ChangeLog b/apps/bikespeedo/ChangeLog index 5fb78710b..2a3023750 100644 --- a/apps/bikespeedo/ChangeLog +++ b/apps/bikespeedo/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: Barometer altitude adjustment setting From 0c29915231aec60f0a00d1e2b21a28ab93c61771 Mon Sep 17 00:00:00 2001 From: The Dod Date: Sun, 27 Mar 2022 14:11:49 +0300 Subject: [PATCH 146/253] `mkFourTwentyTz.js` now handles new CSV format Also make a fresh `fourTwentyTz.js` from latest timezonedb.com CSV zip. --- apps/ftclock/.gitignore | 7 ++- apps/ftclock/ChangeLog | 1 + apps/ftclock/fourTwentyTz.js | 42 ++++++------- apps/ftclock/metadata.json | 2 +- apps/ftclock/mkFourTwentyTz.js | 104 +++++++++++++++------------------ 5 files changed, 75 insertions(+), 81 deletions(-) diff --git a/apps/ftclock/.gitignore b/apps/ftclock/.gitignore index b384cf1f2..304792757 100644 --- a/apps/ftclock/.gitignore +++ b/apps/ftclock/.gitignore @@ -1,4 +1,5 @@ -timezonedb.csv.zip +TimeZoneDB.csv.zip country.csv -zone.csv -timezone.csv +time_zone.csv +database.sql +readme.txt diff --git a/apps/ftclock/ChangeLog b/apps/ftclock/ChangeLog index c944dd9ac..83ec21ee6 100644 --- a/apps/ftclock/ChangeLog +++ b/apps/ftclock/ChangeLog @@ -1,2 +1,3 @@ 0.01: first release 0.02: RAM efficient version of `fourTwentyTz.js` (as suggested by @gfwilliams). +0.03: `mkFourTwentyTz.js` now handles new timezonedb.com CSV format diff --git a/apps/ftclock/fourTwentyTz.js b/apps/ftclock/fourTwentyTz.js index 5fa6cdab7..7ef7418f6 100644 --- a/apps/ftclock/fourTwentyTz.js +++ b/apps/ftclock/fourTwentyTz.js @@ -1,33 +1,33 @@ // Generated by mkFourTwentyTz.js -// Wed Jan 12 2022 19:35:36 GMT+0200 (Israel Standard Time) -// Data source: https://timezonedb.com/files/timezonedb.csv.zip +// Sun Mar 27 2022 14:10:08 GMT+0300 (Israel Daylight Time) +// Data source: https://timezonedb.com/files/TimeZoneDB.csv.zip exports.offsets = [1380,1320,1260,1200,1140,1080,1020,960,900,840,780,720,660,600,540,480,420,360,300,240,180,120,60,0]; exports.timezones = function(offs) { switch (offs) { - case 1380: return ["Cape Verde, Cabo Verde","Scoresbysund, Greenland","Azores, Portugal"]; - case 1320: return ["Noronha, Brazil","South Georgia, South Georgia and the South Sandwich Islands"]; - case 1260: return ["Palmer, Antarctica","Rothera, Antarctica","Buenos Aires, Argentina","Cordoba, Argentina","Salta, Argentina","Jujuy, Argentina","Tucuman, Argentina","Catamarca, Argentina","La Rioja, Argentina","San Juan, Argentina","Mendoza, Argentina","San Luis, Argentina","Rio Gallegos, Argentina","Ushuaia, Argentina","Belem, Brazil","Fortaleza, Brazil","Recife, Brazil","Araguaina, Brazil","Maceio, Brazil","Bahia, Brazil","Sao Paulo, Brazil","Santarem, Brazil","Santiago, Chile","Punta Arenas, Chile","Stanley, Falkland Islands (Malvinas)","Cayenne, French Guiana","Nuuk, Greenland","Miquelon, Saint Pierre and Miquelon","Asuncion, Paraguay","Paramaribo, Suriname","Montevideo, Uruguay"]; - case 1200: return ["Antigua, Antigua and Barbuda","Anguilla, Anguilla","Aruba, Aruba","Barbados, Barbados","St Barthelemy, Saint Barthélemy","Bermuda, Bermuda","La Paz, Bolivia (Plurinational State of)","Kralendijk, Bonaire, Sint Eustatius and Saba","Campo Grande, Brazil","Cuiaba, Brazil","Porto Velho, Brazil","Boa Vista, Brazil","Manaus, Brazil","Halifax, Canada","Glace Bay, Canada","Moncton, Canada","Goose Bay, Canada","Blanc-Sablon, Canada","Curacao, Curaçao","Dominica, Dominica","Santo Domingo, Dominican Republic","Grenada, Grenada","Thule, Greenland","Guadeloupe, Guadeloupe","Guyana, Guyana","St Kitts, Saint Kitts and Nevis","St Lucia, Saint Lucia","Marigot, Saint Martin (French part)","Martinique, Martinique","Montserrat, Montserrat","Puerto Rico, Puerto Rico","Lower Princes, Sint Maarten (Dutch part)","Port of_Spain, Trinidad and Tobago","St Vincent, Saint Vincent and the Grenadines","Caracas, Venezuela (Bolivarian Republic of)","Tortola, Virgin Islands (British)","St Thomas, Virgin Islands (U.S.)"]; - case 1140: return ["Eirunepe, Brazil","Rio Branco, Brazil","Nassau, Bahamas","Toronto, Canada","Nipigon, Canada","Thunder Bay, Canada","Iqaluit, Canada","Pangnirtung, Canada","Atikokan, Canada","Easter, Chile","Bogota, Colombia","Havana, Cuba","Guayaquil, Ecuador","Port-au-Prince, Haiti","Jamaica, Jamaica","Cayman, Cayman Islands","Cancun, Mexico","Panama, Panama","Lima, Peru","Grand Turk, Turks and Caicos Islands","New York, United States of America","Detroit, United States of America","Louisville, Kentucky","Monticello, Kentucky","Indianapolis, Indiana","Vincennes, Indiana","Winamac, Indiana","Marengo, Indiana","Petersburg, Indiana","Vevay, Indiana"]; - case 1080: return ["Belize, Belize","Winnipeg, Canada","Rainy River, Canada","Resolute, Canada","Rankin Inlet, Canada","Regina, Canada","Swift Current, Canada","Costa Rica, Costa Rica","Galapagos, Ecuador","Guatemala, Guatemala","Tegucigalpa, Honduras","Mexico City, Mexico","Merida, Mexico","Monterrey, Mexico","Matamoros, Mexico","Bahia Banderas, Mexico","Managua, Nicaragua","El Salvador, El Salvador","Chicago, United States of America","Tell City, Indiana","Knox, Indiana","Menominee, United States of America","Center, North Dakota","New_Salem, North Dakota","Beulah, North Dakota"]; - case 1020: return ["Edmonton, Canada","Cambridge Bay, Canada","Yellowknife, Canada","Inuvik, Canada","Creston, Canada","Dawson Creek, Canada","Fort Nelson, Canada","Whitehorse, Canada","Dawson, Canada","Mazatlan, Mexico","Chihuahua, Mexico","Ojinaga, Mexico","Hermosillo, Mexico","Denver, United States of America","Boise, United States of America","Phoenix, United States of America"]; - case 960: return ["Vancouver, Canada","Tijuana, Mexico","Pitcairn, Pitcairn","Los Angeles, United States of America"]; - case 900: return ["Gambier, French Polynesia","Anchorage, United States of America","Juneau, United States of America","Sitka, United States of America","Metlakatla, United States of America","Yakutat, United States of America","Nome, United States of America"]; - case 840: return ["Rarotonga, Cook Islands","Kiritimati, Kiribati","Tahiti, French Polynesia","Adak, United States of America","Honolulu, United States of America"]; - case 780: return ["McMurdo, Antarctica","Pago Pago, American Samoa","Fiji, Fiji","Kanton, Kiribati","Niue, Niue","Auckland, New Zealand","Fakaofo, Tokelau","Tongatapu, Tonga","Midway, United States Minor Outlying Islands","Apia, Samoa"]; - case 720: return ["Tarawa, Kiribati","Majuro, Marshall Islands","Kwajalein, Marshall Islands","Norfolk, Norfolk Island","Nauru, Nauru","Kamchatka, Russian Federation","Anadyr, Russian Federation","Funafuti, Tuvalu","Wake, United States Minor Outlying Islands","Wallis, Wallis and Futuna"]; - case 660: return ["Casey, Antarctica","Lord Howe, Australia","Macquarie, Australia","Hobart, Australia","Melbourne, Australia","Sydney, Australia","Pohnpei, Micronesia (Federated States of)","Kosrae, Micronesia (Federated States of)","Noumea, New Caledonia","Bougainville, Papua New Guinea","Magadan, Russian Federation","Sakhalin, Russian Federation","Srednekolymsk, Russian Federation","Guadalcanal, Solomon Islands","Efate, Vanuatu"]; - case 600: return ["DumontDUrville, Antarctica","Brisbane, Australia","Lindeman, Australia","Chuuk, Micronesia (Federated States of)","Guam, Guam","Saipan, Northern Mariana Islands","Port Moresby, Papua New Guinea","Vladivostok, Russian Federation","Ust-Nera, Russian Federation"]; - case 540: return ["Jayapura, Indonesia","Tokyo, Japan","Pyongyang, Korea (Democratic People's Republic of)","Seoul, Korea, Republic of","Palau, Palau","Chita, Russian Federation","Yakutsk, Russian Federation","Khandyga, Russian Federation","Dili, Timor-Leste"]; + case 1380: return ["Cape Verde, Cape Verde"]; + case 1320: return ["Noronha, Brazil","Nuuk, Greenland","South Georgia, South Georgia and the South Sandwich Islands","Miquelon, Saint Pierre and Miquelon"]; + case 1260: return ["Palmer, Antarctica","Rothera, Antarctica","Buenos Aires, Argentina","Cordoba, Argentina","Salta, Argentina","Jujuy, Argentina","Tucuman, Argentina","Catamarca, Argentina","La Rioja, Argentina","San Juan, Argentina","Mendoza, Argentina","San Luis, Argentina","Rio Gallegos, Argentina","Ushuaia, Argentina","Bermuda, Bermuda","Belem, Brazil","Fortaleza, Brazil","Recife, Brazil","Araguaina, Brazil","Maceio, Brazil","Bahia, Brazil","Sao Paulo, Brazil","Santarem, Brazil","Halifax, Canada","Glace Bay, Canada","Moncton, Canada","Goose Bay, Canada","Santiago, Chile","Punta Arenas, Chile","Stanley, Falkland Islands (Malvinas)","Cayenne, French Guiana","Thule, Greenland","Paramaribo, Suriname","Montevideo, Uruguay"]; + case 1200: return ["Antigua, Antigua and Barbuda","Anguilla, Anguilla","Aruba, Aruba","Barbados, Barbados","St Barthelemy, Saint Barthélemy","La Paz, Bolivia, Plurinational State of","Kralendijk, Bonaire, Sint Eustatius and Saba","Campo Grande, Brazil","Cuiaba, Brazil","Porto Velho, Brazil","Boa Vista, Brazil","Manaus, Brazil","Nassau, Bahamas","Blanc-Sablon, Canada","Toronto, Canada","Nipigon, Canada","Thunder Bay, Canada","Iqaluit, Canada","Pangnirtung, Canada","Havana, Cuba","Curacao, Curaçao","Dominica, Dominica","Santo Domingo, Dominican Republic","Grenada, Grenada","Guadeloupe, Guadeloupe","Guyana, Guyana","Port-au-Prince, Haiti","St Kitts, Saint Kitts and Nevis","St Lucia, Saint Lucia","Marigot, Saint Martin (French part)","Martinique, Martinique","Montserrat, Montserrat","Puerto Rico, Puerto Rico","Asuncion, Paraguay","Lower Princes, Sint Maarten (Dutch part)","Grand Turk, Turks and Caicos Islands","Port of_Spain, Trinidad and Tobago","New York, United States","Detroit, United States","Louisville, Kentucky","Monticello, Kentucky","Indianapolis, Indiana","Vincennes, Indiana","Winamac, Indiana","Marengo, Indiana","Petersburg, Indiana","Vevay, Indiana","St Vincent, Saint Vincent and the Grenadines","Caracas, Venezuela, Bolivarian Republic of","Tortola, Virgin Islands, British","St Thomas, Virgin Islands, U.S."]; + case 1140: return ["Eirunepe, Brazil","Rio Branco, Brazil","Atikokan, Canada","Winnipeg, Canada","Rainy River, Canada","Resolute, Canada","Rankin Inlet, Canada","Easter, Chile","Bogota, Colombia","Guayaquil, Ecuador","Jamaica, Jamaica","Cayman, Cayman Islands","Cancun, Mexico","Matamoros, Mexico","Panama, Panama","Lima, Peru","Chicago, United States","Tell City, Indiana","Knox, Indiana","Menominee, United States","Center, North Dakota","New_Salem, North Dakota","Beulah, North Dakota"]; + case 1080: return ["Belize, Belize","Regina, Canada","Swift Current, Canada","Edmonton, Canada","Cambridge Bay, Canada","Yellowknife, Canada","Inuvik, Canada","Costa Rica, Costa Rica","Galapagos, Ecuador","Guatemala, Guatemala","Tegucigalpa, Honduras","Mexico City, Mexico","Merida, Mexico","Monterrey, Mexico","Ojinaga, Mexico","Bahia Banderas, Mexico","Managua, Nicaragua","El Salvador, El Salvador","Denver, United States","Boise, United States"]; + case 1020: return ["Creston, Canada","Dawson Creek, Canada","Fort Nelson, Canada","Whitehorse, Canada","Dawson, Canada","Vancouver, Canada","Mazatlan, Mexico","Chihuahua, Mexico","Hermosillo, Mexico","Tijuana, Mexico","Phoenix, United States","Los Angeles, United States"]; + case 960: return ["Pitcairn, Pitcairn","Anchorage, United States","Juneau, United States","Sitka, United States","Metlakatla, United States","Yakutat, United States","Nome, United States"]; + case 900: return ["Gambier, French Polynesia","Adak, United States"]; + case 840: return ["Rarotonga, Cook Islands","Kiritimati, Kiribati","Tahiti, French Polynesia","Honolulu, United States"]; + case 780: return ["McMurdo, Antarctica","Pago Pago, American Samoa","Kanton, Kiribati","Niue, Niue","Auckland, New Zealand","Fakaofo, Tokelau","Tongatapu, Tonga","Midway, United States Minor Outlying Islands","Apia, Samoa"]; + case 720: return ["Fiji, Fiji","Tarawa, Kiribati","Majuro, Marshall Islands","Kwajalein, Marshall Islands","Norfolk, Norfolk Island","Nauru, Nauru","Kamchatka, Russian Federation","Anadyr, Russian Federation","Funafuti, Tuvalu","Wake, United States Minor Outlying Islands","Wallis, Wallis and Futuna"]; + case 660: return ["Casey, Antarctica","Lord Howe, Australia","Macquarie, Australia","Hobart, Australia","Melbourne, Australia","Sydney, Australia","Pohnpei, Micronesia, Federated States of","Kosrae, Micronesia, Federated States of","Noumea, New Caledonia","Bougainville, Papua New Guinea","Magadan, Russian Federation","Sakhalin, Russian Federation","Srednekolymsk, Russian Federation","Guadalcanal, Solomon Islands","Efate, Vanuatu"]; + case 600: return ["DumontDUrville, Antarctica","Brisbane, Australia","Lindeman, Australia","Chuuk, Micronesia, Federated States of","Guam, Guam","Saipan, Northern Mariana Islands","Port Moresby, Papua New Guinea","Vladivostok, Russian Federation","Ust-Nera, Russian Federation"]; + case 540: return ["Jayapura, Indonesia","Tokyo, Japan","Pyongyang, Korea, Democratic People's Republic of","Seoul, Korea, Republic of","Palau, Palau","Chita, Russian Federation","Yakutsk, Russian Federation","Khandyga, Russian Federation","Dili, Timor-Leste"]; case 480: return ["Perth, Australia","Brunei, Brunei Darussalam","Shanghai, China","Hong Kong, Hong Kong","Makassar, Indonesia","Ulaanbaatar, Mongolia","Choibalsan, Mongolia","Macau, Macao","Kuala Lumpur, Malaysia","Kuching, Malaysia","Manila, Philippines","Irkutsk, Russian Federation","Singapore, Singapore","Taipei, Taiwan, Province of China"]; case 420: return ["Davis, Antarctica","Christmas, Christmas Island","Jakarta, Indonesia","Pontianak, Indonesia","Phnom Penh, Cambodia","Vientiane, Lao People's Democratic Republic","Hovd, Mongolia","Novosibirsk, Russian Federation","Barnaul, Russian Federation","Tomsk, Russian Federation","Novokuznetsk, Russian Federation","Krasnoyarsk, Russian Federation","Bangkok, Thailand","Ho Chi_Minh, Viet Nam"]; case 360: return ["Vostok, Antarctica","Dhaka, Bangladesh","Thimphu, Bhutan","Urumqi, China","Chagos, British Indian Ocean Territory","Bishkek, Kyrgyzstan","Almaty, Kazakhstan","Qostanay, Kazakhstan","Omsk, Russian Federation"]; case 300: return ["Mawson, Antarctica","Qyzylorda, Kazakhstan","Aqtobe, Kazakhstan","Aqtau, Kazakhstan","Atyrau, Kazakhstan","Oral, Kazakhstan","Maldives, Maldives","Karachi, Pakistan","Yekaterinburg, Russian Federation","Kerguelen, French Southern Territories","Dushanbe, Tajikistan","Ashgabat, Turkmenistan","Samarkand, Uzbekistan","Tashkent, Uzbekistan"]; case 240: return ["Dubai, United Arab Emirates","Yerevan, Armenia","Baku, Azerbaijan","Tbilisi, Georgia","Mauritius, Mauritius","Muscat, Oman","Reunion, Réunion","Astrakhan, Russian Federation","Saratov, Russian Federation","Ulyanovsk, Russian Federation","Samara, Russian Federation","Mahe, Seychelles"]; - case 180: return ["Syowa, Antarctica","Bahrain, Bahrain","Minsk, Belarus","Djibouti, Djibouti","Asmara, Eritrea","Addis Ababa, Ethiopia","Baghdad, Iraq","Nairobi, Kenya","Comoro, Comoros","Kuwait, Kuwait","Antananarivo, Madagascar","Qatar, Qatar","Moscow, Russian Federation","Simferopol, Ukraine","Kirov, Russian Federation","Volgograd, Russian Federation","Riyadh, Saudi Arabia","Mogadishu, Somalia","Istanbul, Turkey","Dar es_Salaam, Tanzania, United Republic of","Kampala, Uganda","Aden, Yemen","Mayotte, Mayotte"]; - case 120: return ["Mariehamn, Åland Islands","Sofia, Bulgaria","Bujumbura, Burundi","Gaborone, Botswana","Lubumbashi, Congo, Democratic Republic of the","Nicosia, Cyprus","Famagusta, Cyprus","Tallinn, Estonia","Cairo, Egypt","Helsinki, Finland","Athens, Greece","Jerusalem, Israel","Amman, Jordan","Beirut, Lebanon","Maseru, Lesotho","Vilnius, Lithuania","Riga, Latvia","Tripoli, Libya","Chisinau, Moldova, Republic of","Blantyre, Malawi","Maputo, Mozambique","Windhoek, Namibia","Gaza, Palestine, State of","Hebron, Palestine, State of","Bucharest, Romania","Kaliningrad, Russian Federation","Kigali, Rwanda","Khartoum, Sudan","Juba, South Sudan","Damascus, Syrian Arab Republic","Mbabane, Eswatini","Kiev, Ukraine","Uzhgorod, Ukraine","Zaporozhye, Ukraine","Johannesburg, South Africa","Lusaka, Zambia","Harare, Zimbabwe"]; - case 60: return ["Andorra, Andorra","Tirane, Albania","Luanda, Angola","Vienna, Austria","Sarajevo, Bosnia and Herzegovina","Brussels, Belgium","Porto-Novo, Benin","Kinshasa, Congo, Democratic Republic of the","Bangui, Central African Republic","Brazzaville, Congo","Zurich, Switzerland","Douala, Cameroon","Prague, Czechia","Berlin, Germany","Busingen, Germany","Copenhagen, Denmark","Algiers, Algeria","El Aaiun, Western Sahara","Madrid, Spain","Ceuta, Spain","Paris, France","Libreville, Gabon","Gibraltar, Gibraltar","Malabo, Equatorial Guinea","Zagreb, Croatia","Budapest, Hungary","Rome, Italy","Vaduz, Liechtenstein","Luxembourg, Luxembourg","Casablanca, Morocco","Monaco, Monaco","Podgorica, Montenegro","Skopje, North Macedonia","Malta, Malta","Niamey, Niger","Lagos, Nigeria","Amsterdam, Netherlands","Oslo, Norway","Warsaw, Poland","Belgrade, Serbia","Stockholm, Sweden","Ljubljana, Slovenia","Longyearbyen, Svalbard and Jan Mayen","Bratislava, Slovakia","San Marino, San Marino","Ndjamena, Chad","Tunis, Tunisia","Vatican, Holy See"]; - case 0: return ["Troll, Antarctica","Ouagadougou, Burkina Faso","Abidjan, Côte d'Ivoire","Canary, Spain","Faroe, Faroe Islands","London, United Kingdom of Great Britain and Northern Ireland","Guernsey, Guernsey","Accra, Ghana","Danmarkshavn, Greenland","Banjul, Gambia","Conakry, Guinea","Bissau, Guinea-Bissau","Dublin, Ireland","Isle of_Man, Isle of Man","Reykjavik, Iceland","Jersey, Jersey","Monrovia, Liberia","Bamako, Mali","Nouakchott, Mauritania","Lisbon, Portugal","Madeira, Portugal","St Helena, Saint Helena, Ascension and Tristan da Cunha","Freetown, Sierra Leone","Dakar, Senegal","Sao Tome, Sao Tome and Principe","Lome, Togo"]; + case 180: return ["Syowa, Antarctica","Mariehamn, Åland Islands","Sofia, Bulgaria","Bahrain, Bahrain","Minsk, Belarus","Nicosia, Cyprus","Famagusta, Cyprus","Djibouti, Djibouti","Tallinn, Estonia","Asmara, Eritrea","Addis Ababa, Ethiopia","Helsinki, Finland","Athens, Greece","Jerusalem, Israel","Baghdad, Iraq","Amman, Jordan","Nairobi, Kenya","Comoro, Comoros","Kuwait, Kuwait","Beirut, Lebanon","Vilnius, Lithuania","Riga, Latvia","Chisinau, Moldova, Republic of","Antananarivo, Madagascar","Gaza, Palestine, State of","Hebron, Palestine, State of","Qatar, Qatar","Bucharest, Romania","Moscow, Russian Federation","Simferopol, Ukraine","Kirov, Russian Federation","Volgograd, Russian Federation","Riyadh, Saudi Arabia","Mogadishu, Somalia","Damascus, Syrian Arab Republic","Istanbul, Turkey","Dar es_Salaam, Tanzania, United Republic of","Kiev, Ukraine","Uzhgorod, Ukraine","Zaporozhye, Ukraine","Kampala, Uganda","Aden, Yemen","Mayotte, Mayotte"]; + case 120: return ["Andorra, Andorra","Tirane, Albania","Troll, Antarctica","Vienna, Austria","Sarajevo, Bosnia and Herzegovina","Brussels, Belgium","Bujumbura, Burundi","Gaborone, Botswana","Lubumbashi, Congo, the Democratic Republic of the","Zurich, Switzerland","Prague, Czech Republic","Berlin, Germany","Busingen, Germany","Copenhagen, Denmark","Cairo, Egypt","Madrid, Spain","Ceuta, Spain","Paris, France","Gibraltar, Gibraltar","Zagreb, Croatia","Budapest, Hungary","Rome, Italy","Vaduz, Liechtenstein","Maseru, Lesotho","Luxembourg, Luxembourg","Tripoli, Libya","Monaco, Monaco","Podgorica, Montenegro","Skopje, Macedonia, the Former Yugoslav Republic of","Malta, Malta","Blantyre, Malawi","Maputo, Mozambique","Windhoek, Namibia","Amsterdam, Netherlands","Oslo, Norway","Warsaw, Poland","Belgrade, Serbia","Kaliningrad, Russian Federation","Kigali, Rwanda","Khartoum, Sudan","Stockholm, Sweden","Ljubljana, Slovenia","Longyearbyen, Svalbard and Jan Mayen","Bratislava, Slovakia","San Marino, San Marino","Juba, South Sudan","Mbabane, Swaziland","Vatican, Holy See (Vatican City State)","Johannesburg, South Africa","Lusaka, Zambia","Harare, Zimbabwe"]; + case 60: return ["Luanda, Angola","Porto-Novo, Benin","Kinshasa, Congo, the Democratic Republic of the","Bangui, Central African Republic","Brazzaville, Congo","Douala, Cameroon","Algiers, Algeria","Canary, Spain","Faroe, Faroe Islands","Libreville, Gabon","London, United Kingdom","Guernsey, Guernsey","Malabo, Equatorial Guinea","Dublin, Ireland","Isle of_Man, Isle of Man","Jersey, Jersey","Niamey, Niger","Lagos, Nigeria","Lisbon, Portugal","Madeira, Portugal","Ndjamena, Chad","Tunis, Tunisia"]; + case 0: return ["Ouagadougou, Burkina Faso","Abidjan, Côte d'Ivoire","El Aaiun, Western Sahara","Accra, Ghana","Danmarkshavn, Greenland","Scoresbysund, Greenland","Banjul, Gambia","Conakry, Guinea","Bissau, Guinea-Bissau","Reykjavik, Iceland","Monrovia, Liberia","Casablanca, Morocco","Bamako, Mali","Nouakchott, Mauritania","Azores, Portugal","St Helena, Saint Helena, Ascension and Tristan da Cunha","Freetown, Sierra Leone","Dakar, Senegal","Sao Tome, Sao Tome and Principe","Lome, Togo"]; default: return ["Houston, we have a bug."]; } }; diff --git a/apps/ftclock/metadata.json b/apps/ftclock/metadata.json index 3cbf5ce66..876feb1bb 100644 --- a/apps/ftclock/metadata.json +++ b/apps/ftclock/metadata.json @@ -1,7 +1,7 @@ { "id": "ftclock", "name": "Four Twenty Clock", - "version": "0.02", + "version": "0.03", "description": "A clock that tells when and where it's going to be 4:20 next", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}, {"url":"screenshot1.png"}], diff --git a/apps/ftclock/mkFourTwentyTz.js b/apps/ftclock/mkFourTwentyTz.js index 4571c15f7..4e7829aa3 100644 --- a/apps/ftclock/mkFourTwentyTz.js +++ b/apps/ftclock/mkFourTwentyTz.js @@ -4,7 +4,7 @@ let csv = require('csv'); let countries = {}, zones = {}, offsdict = {}, - now = Date.now(); // we need this to find zone's current DST state + now = Date.now()/1000; // we need this to find zone's current DST state function handleWrite(err,bytes) { if (err) { @@ -19,10 +19,10 @@ fs.createReadStream(__dirname+'/country.csv') countries[r[0]] = r[1]; }) .on('end', () => { - fs.createReadStream(__dirname+'/zone.csv') + fs.createReadStream(__dirname+'/time_zone.csv') .pipe(csv.parse()) .on('data', (r) => { - let parts = r[2].replace('_',' ').split('/'); + let parts = r[0].replace('_',' ').split('/'); let city = parts[parts.length-1]; let country =''; if (parts.length>2) { // e.g. America/North_Dakota/New_Salem @@ -30,59 +30,51 @@ fs.createReadStream(__dirname+'/country.csv') } else { country = countries[r[1]]; // e.g. United States } - zones[parseInt(r[0])] = {"name": `${city}, ${country}`}; + zone = zones[r[0]] || { "name": `${city}, ${country}` }; + let starttime = parseInt(r[3] || "0"), // Bugger. They're feeding us blanks for UTC now + offs = parseInt(r[4]); + if (offs<0) { + offs += 60*60*24; + } + if (starttime { - fs.createReadStream(__dirname+'/timezone.csv') - .pipe(csv.parse()) - .on('data', (r) => { - code = parseInt(r[0]); - if (!(code in zones)) return; - starttime = parseInt(r[2] || "0"); // Bugger. They're feeding us blanks for UTC now - offs = parseInt(r[3]); - if (offs<0) { - offs += 60*60*24; - } - zone = zones[code]; - if (starttime { - for (z in zones) { - zone = zones[z]; - if (zone.offs%60) continue; // One a dem funky timezones. Ignore. - zonelist = offsdict[zone.offs] || []; - zonelist.push(zone.name); - offsdict[zone.offs] = zonelist; - } - offsets = []; - for (o in offsdict) { - offsets.unshift(parseInt(o)); - } - fs.open("fourTwentyTz.js","w", (err, fd) => { - if (err) { - console.log("Can't open output file"); - return; - } - fs.write(fd, "// Generated by mkFourTwentyTz.js\n", handleWrite); - fs.write(fd, `// ${Date()}\n`, handleWrite); - fs.write(fd, "// Data source: https://timezonedb.com/files/timezonedb.csv.zip\n", handleWrite); - fs.write(fd, "exports.offsets = ", handleWrite); - fs.write(fd, JSON.stringify(offsets), handleWrite); - fs.write(fd, ";\n", handleWrite); - fs.write(fd, "exports.timezones = function(offs) {\n", handleWrite); - fs.write(fd, " switch (offs) {\n", handleWrite); - for (i=0; i { + if (err) { + console.log("Can't open output file"); + return; + } + fs.write(fd, "// Generated by mkFourTwentyTz.js\n", handleWrite); + fs.write(fd, `// ${Date()}\n`, handleWrite); + fs.write(fd, "// Data source: https://timezonedb.com/files/TimeZoneDB.csv.zip\n", handleWrite); + fs.write(fd, "exports.offsets = ", handleWrite); + fs.write(fd, JSON.stringify(offsets), handleWrite); + fs.write(fd, ";\n", handleWrite); + fs.write(fd, "exports.timezones = function(offs) {\n", handleWrite); + fs.write(fd, " switch (offs) {\n", handleWrite); + for (i=0; i Date: Sun, 27 Mar 2022 13:27:17 +0200 Subject: [PATCH 147/253] Update app.js --- apps/bikespeedo/app.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/apps/bikespeedo/app.js b/apps/bikespeedo/app.js index 0c5680c9d..edb23fc78 100644 --- a/apps/bikespeedo/app.js +++ b/apps/bikespeedo/app.js @@ -460,9 +460,11 @@ function updateClock() { } +// =Main Prog + +// Read settings. +let cfg = require('Storage').readJSON('bikespeedo.json',1)||{}; -//### -let cfg = {}; cfg.spd = 1; // Multiplier for speed unit conversions. 0 = use the locale values for speed cfg.spd_unit = 'km/h'; // Displayed speed unit cfg.alt = 1; // Multiplier for altitude unit conversions. (feet:'0.3048') @@ -472,8 +474,12 @@ cfg.dist_unit = 'km'; // Displayed distnce units cfg.modeA = 1; cfg.primSpd = 1; // 1 = Spd in primary, 0 = Spd in secondary -cfg.spdFilt = false; -cfg.altFilt = false; +cfg.altDiff = cfg.altDiff==undefined?100:cfg.altDiff; +cfg.spdFilt = cfg.spdFilt==undefined?true:cfg.spdFilt; +cfg.altFilt = cfg.altFilt==undefined?false:cfg.altFilt; +console.log("cfg.altDiff: " + cfg.altDiff); +console.log("cfg.spdFilt: " + cfg.spdFilt); +console.log("cfg.altFilt: " + cfg.altFilt); if ( cfg.spdFilt ) var spdFilter = new KalmanFilter({R: 0.1 , Q: 1 }); if ( cfg.altFilt ) var altFilter = new KalmanFilter({R: 0.01, Q: 2 }); @@ -489,7 +495,9 @@ function onGPSraw(nmea) { } } if(BANGLEJS2) Bangle.on('GPS-raw', onGPSraw); -function onPressure(dat) { altiBaro = dat.altitude.toFixed(0); } +function onPressure(dat) { + altiBaro = Number(dat.altitude.toFixed(0)) + Number(cfg.altDiff); +} Bangle.setBarometerPower(1); // needs some time... g.clearRect(0,screenYstart,screenW,screenH); @@ -520,10 +528,10 @@ function Compass_tiltfixread(O,S){ return psi; } var Compass_heading = 0; -function Compass_newHeading(m,h){ +function Compass_newHeading(m,h){ var s = Math.abs(m - h); var delta = (m>h)?1:-1; - if (s>=180){s=360-s; delta = -delta;} + if (s>=180){s=360-s; delta = -delta;} if (s<2) return h; var hd = h + delta*(1 + Math.round(s/5)); if (hd<0) hd+=360; From c43124360f30c73e5c4501b5abfeb037d6893027 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sun, 27 Mar 2022 11:23:23 -0700 Subject: [PATCH 148/253] Update boot.js --- apps/quicklaunch/boot.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 22ec670de..4389e6a84 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -1,5 +1,8 @@ (function() { var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); + + //list all sources + var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); //populate empty app list @@ -33,7 +36,7 @@ if (!mode.startsWith("clock")) return; function tap() { - //tap, check if source exists + //tap, check if source exists, launch var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); if ((settings.tapapp.src) && apps.some(e => e.src === settings.tapapp.src)) load (settings.tapapp.src); } @@ -48,14 +51,12 @@ } else if (!e.b) { // released const dx = e.x-drag.x, dy = e.y-drag.y; drag = null; - //check if source exists - var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); - //horizontal swipes + //horizontal swipes, check if source exists, launch if (Math.abs(dx)>Math.abs(dy)+10) { if ((settings.leftapp.src) && apps.some(e => e.src === settings.leftapp.src) && dx<0) load(settings.leftapp.src); if ((settings.rightapp.src) && apps.some(e => e.src === settings.rightapp.src) && dx>0) load(settings.rightapp.src); } - //vertical swipes + //vertical swipes, check if source exists, launch else if (Math.abs(dy)>Math.abs(dx)+10) { if ((settings.upapp.src) && apps.some(e => e.src === settings.upapp.src) && dy<0) load(settings.upapp.src); if ((settings.downapp.src) && apps.some(e => e.src === settings.downapp.src) && dy>0) load(settings.downapp.src); From 252f58d1ec429636fc5b4dd3ce40280e252e7629 Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sun, 27 Mar 2022 11:31:58 -0700 Subject: [PATCH 149/253] Update boot.js --- apps/quicklaunch/boot.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 4389e6a84..3670c4776 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -37,7 +37,6 @@ function tap() { //tap, check if source exists, launch - var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); if ((settings.tapapp.src) && apps.some(e => e.src === settings.tapapp.src)) load (settings.tapapp.src); } From aa99d5cea83b5fb9caba5890ef6b05cdf87be0fe Mon Sep 17 00:00:00 2001 From: Salim Blume Date: Sun, 27 Mar 2022 15:42:13 -0500 Subject: [PATCH 150/253] Reverting fix that was actually a bug --- apps/run/ChangeLog | 3 ++- apps/run/app.js | 4 ++-- apps/run/metadata.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/run/ChangeLog b/apps/run/ChangeLog index 46fdb7e7e..9f1a547b1 100644 --- a/apps/run/ChangeLog +++ b/apps/run/ChangeLog @@ -9,4 +9,5 @@ 0.08: Added support for notifications from exstats. Support all stats from exstats 0.09: Fix broken start/stop if recording not enabled (fix #1561) 0.10: Don't allow the same setting to be chosen for 2 boxes (fix #1578) -0.11: Notifications fixes \ No newline at end of file +0.11: Notifications fixes +0.12: Fix for recorder not stopping at end of run. Bug introduced in 0.11 \ No newline at end of file diff --git a/apps/run/app.js b/apps/run/app.js index fb8158e58..19dcd7e88 100644 --- a/apps/run/app.js +++ b/apps/run/app.js @@ -59,7 +59,7 @@ function onStartStop() { layout.render(); }) ); - } else if (!settings.record && WIDGETS["recorder"]) { + } else { prepPromises.push( WIDGETS["recorder"].setRecording(false) ); @@ -68,7 +68,7 @@ function onStartStop() { if (!prepPromises.length) // fix for Promise.all bug in 2v12 prepPromises.push(Promise.resolve()); - + Promise.all(prepPromises) .then(() => { if (running) { diff --git a/apps/run/metadata.json b/apps/run/metadata.json index 09e5a3bed..b1b5617be 100644 --- a/apps/run/metadata.json +++ b/apps/run/metadata.json @@ -1,6 +1,6 @@ { "id": "run", "name": "Run", - "version":"0.11", + "version":"0.12", "description": "Displays distance, time, steps, cadence, pace and more for runners.", "icon": "app.png", "tags": "run,running,fitness,outdoors,gps", From e96e181eded86393f2b26c9a2b67071ddc764831 Mon Sep 17 00:00:00 2001 From: BartS23 <10829389+BartS23@users.noreply.github.com> Date: Sun, 27 Mar 2022 23:29:46 +0200 Subject: [PATCH 151/253] Fix exception on Dist/Step/Time pattern selection --- apps/run/settings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/run/settings.js b/apps/run/settings.js index 6a7d169c4..240df9f07 100644 --- a/apps/run/settings.js +++ b/apps/run/settings.js @@ -91,7 +91,7 @@ ]; notificationsMenu[/*LANG*/"Dist Pattern"] = { value: Math.max(0,vibTimes.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.dist.notifications))), - min: 0, max: vibTimes.length, + min: 0, max: vibTimes.length - 1, format: v => vibPatterns[v]||/*LANG*/"Off", onchange: v => { settings.notify.dist.notifications = vibTimes[v]; @@ -101,7 +101,7 @@ } notificationsMenu[/*LANG*/"Step Pattern"] = { value: Math.max(0,vibTimes.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.step.notifications))), - min: 0, max: vibTimes.length, + min: 0, max: vibTimes.length - 1, format: v => vibPatterns[v]||/*LANG*/"Off", onchange: v => { settings.notify.step.notifications = vibTimes[v]; @@ -111,7 +111,7 @@ } notificationsMenu[/*LANG*/"Time Pattern"] = { value: Math.max(0,vibTimes.findIndex((p) => JSON.stringify(p) === JSON.stringify(settings.notify.time.notifications))), - min: 0, max: vibTimes.length, + min: 0, max: vibTimes.length - 1, format: v => vibPatterns[v]||/*LANG*/"Off", onchange: v => { settings.notify.time.notifications = vibTimes[v]; From 02fca7a4c881cdb8ad3019fb4adbe9be4412c673 Mon Sep 17 00:00:00 2001 From: BartS23 <10829389+BartS23@users.noreply.github.com> Date: Mon, 28 Mar 2022 00:04:01 +0200 Subject: [PATCH 152/253] Fix.speed could be NaN then curSpeed during the entire run is NaN --- modules/exstats.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exstats.js b/modules/exstats.js index ec0a838a7..b22f3f5d3 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -135,7 +135,7 @@ Bangle.on("GPS", function(fix) { if (stats["dist"]) stats["dist"].emit("changed",stats["dist"]); var duration = Date.now() - state.startTime; // in ms state.avrSpeed = state.distance * 1000 / duration; // meters/sec - state.curSpeed = state.curSpeed*0.8 + fix.speed*0.2/3.6; // meters/sec + if (!isNaN(fix.speed)) state.curSpeed = state.curSpeed*0.8 + fix.speed*0.2/3.6; // meters/sec if (stats["pacea"]) stats["pacea"].emit("changed",stats["pacea"]); if (stats["pacec"]) stats["pacec"].emit("changed",stats["pacec"]); if (stats["speed"]) stats["speed"].emit("changed",stats["speed"]); From bacc9e80af40ec2940fd9fb901647e682a998728 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 08:24:12 +0200 Subject: [PATCH 153/253] Update widget.js -Avoid too many notifications on connection loss. -Change non-connected icon color. --- apps/widbt/widget.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 246b8d65b..96656324e 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -1,12 +1,14 @@ WIDGETS.bluetooth = { area: "tr", width: 15, + warningEnabled: 1, draw: function() { g.reset(); if (NRF.getSecurityStatus().connected) { g.setColor((g.getBPP() > 8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); } else { - g.setColor(g.theme.dark ? "#666" : "#999"); + // g.setColor(g.theme.dark ? "#666" : "#999"); + g.setColor("#f00"); // red is easier to distinguish from blue } g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y); }, @@ -14,7 +16,11 @@ WIDGETS.bluetooth = { WIDGETS.bluetooth.draw(); }, diconnect: function() { - Bangle.buzz(1000, 1); // buzz on connection loss + if(warningEnabled == 1){ + Bangle.buzz(700, 1); // buzz on connection loss + warningEnabled = 0; + setTimeout('WIDGETS.bluetooth.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. + } WIDGETS.bluetooth.draw(); } }; From 9ad0704cd26a7c1ab56c8ce5573d0b724247c5c4 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 08:24:40 +0200 Subject: [PATCH 154/253] Update metadata.json Version update. --- apps/widbt/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt/metadata.json b/apps/widbt/metadata.json index 29d960f33..6e705584e 100644 --- a/apps/widbt/metadata.json +++ b/apps/widbt/metadata.json @@ -1,7 +1,7 @@ { "id": "widbt", "name": "Bluetooth Widget", - "version": "0.10", + "version": "0.11", "description": "Show the current Bluetooth connection status in the top right of the clock", "icon": "widget.png", "type": "widget", From c8bc3f7254f0aa32ff80a6c176c1c8715401d7b0 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 08:25:36 +0200 Subject: [PATCH 155/253] Update ChangeLog 0.11: Avoid too many notifications. Change disconnected colour to red. --- apps/widbt/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widbt/ChangeLog b/apps/widbt/ChangeLog index 04bff2b1a..b5a50210e 100644 --- a/apps/widbt/ChangeLog +++ b/apps/widbt/ChangeLog @@ -7,3 +7,4 @@ 0.08: Disable LCD on, on bluetooth status change 0.09: Vibrate on connection loss 0.10: Bug fix +0.11: Avoid too many notifications. Change disconnected colour to red. From c34ade140c8f3c7b36c1082d5bed16c1c74c0a73 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 28 Mar 2022 10:30:26 +0100 Subject: [PATCH 156/253] messages 0.27: Add 'mark all read' option to popup menu (fix #1624) --- apps/messages/ChangeLog | 1 + apps/messages/app.js | 5 +++++ apps/messages/metadata.json | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index c39e7d6fe..91d2bb0bf 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -39,3 +39,4 @@ 0.24: Remove left-over debug statement 0.25: Fix widget memory usage issues if message received and watch repeatedly calls Bangle.drawWidgets (fix #1550) 0.26: Setting to auto-open music +0.27: Add 'mark all read' option to popup menu (fix #1624) diff --git a/apps/messages/app.js b/apps/messages/app.js index 403f9b5d8..655fc7122 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -302,6 +302,11 @@ function showMessageSettings(msg) { saveMessages(); checkMessages({clockIfNoMsg:0,clockIfAllRead:0,showMsgIfUnread:0,openMusic:0}); }, + /*LANG*/"Mark all read" : () => { + MESSAGES.forEach(msg => msg.new = false); + saveMessages(); + checkMessages({clockIfNoMsg:0,clockIfAllRead:0,showMsgIfUnread:0,openMusic:0}); + }, /*LANG*/"Delete all messages" : () => { E.showPrompt(/*LANG*/"Are you sure?", {title:/*LANG*/"Delete All Messages"}).then(isYes => { if (isYes) { diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index a3d3f4179..4fb5a4045 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.26", + "version": "0.27", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 105e5279b2a88b651b3efd526ef0665dd00518a6 Mon Sep 17 00:00:00 2001 From: Hilmar Strauch <56518493+HilmarSt@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:27:04 +0200 Subject: [PATCH 157/253] Update metadata.json --- apps/bikespeedo/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bikespeedo/metadata.json b/apps/bikespeedo/metadata.json index a627f19f8..c3de0487c 100644 --- a/apps/bikespeedo/metadata.json +++ b/apps/bikespeedo/metadata.json @@ -1,7 +1,7 @@ { "id": "bikespeedo", "name": "Bike Speedometer (beta)", - "shortName": "Bike Speedomet.", + "shortName": "Bike Speedometer", "version": "0.02", "description": "Shows GPS speed, GPS heading, Compass heading, GPS altitude and Barometer altitude from internal sources", "icon": "app.png", From a7cb978e040266a42c9b15cfe5dfc03a4350c4e6 Mon Sep 17 00:00:00 2001 From: Hilmar Strauch <56518493+HilmarSt@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:49:25 +0200 Subject: [PATCH 158/253] Update README.md --- apps/bikespeedo/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/bikespeedo/README.md b/apps/bikespeedo/README.md index 7d271a022..e4ce5ea5c 100644 --- a/apps/bikespeedo/README.md +++ b/apps/bikespeedo/README.md @@ -6,6 +6,10 @@ #### If "CALIB!" is shown on the display or the compass heading differs too much from GPS heading, compass calibration should be done with the ["Navigation Compass" App](https://banglejs.com/apps/?id=magnav) +Permanently diverging Barometer Altitude values can be compensated in the settings menu. + +Please report bugs to https://github.com/espruino/BangleApps/issues/new?assignees=&labels=bug&template=bangle-bug-report-custom-form.yaml&title=%5BBike+Speedometer%5D+Short+description+of+bug + **Credits:**
Bike Speedometer App by github.com/HilmarSt
Big parts of the software are based on github.com/espruino/BangleApps/tree/master/apps/speedalt
From 74ca4151cd404be0db074ee722e058a91f5fc1f8 Mon Sep 17 00:00:00 2001 From: Hilmar Strauch <56518493+HilmarSt@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:51:45 +0200 Subject: [PATCH 159/253] Update app.js --- apps/bikespeedo/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/bikespeedo/app.js b/apps/bikespeedo/app.js index edb23fc78..a62a429e5 100644 --- a/apps/bikespeedo/app.js +++ b/apps/bikespeedo/app.js @@ -477,9 +477,9 @@ cfg.primSpd = 1; // 1 = Spd in primary, 0 = Spd in secondary cfg.altDiff = cfg.altDiff==undefined?100:cfg.altDiff; cfg.spdFilt = cfg.spdFilt==undefined?true:cfg.spdFilt; cfg.altFilt = cfg.altFilt==undefined?false:cfg.altFilt; -console.log("cfg.altDiff: " + cfg.altDiff); -console.log("cfg.spdFilt: " + cfg.spdFilt); -console.log("cfg.altFilt: " + cfg.altFilt); +// console.log("cfg.altDiff: " + cfg.altDiff); +// console.log("cfg.spdFilt: " + cfg.spdFilt); +// console.log("cfg.altFilt: " + cfg.altFilt); if ( cfg.spdFilt ) var spdFilter = new KalmanFilter({R: 0.1 , Q: 1 }); if ( cfg.altFilt ) var altFilter = new KalmanFilter({R: 0.01, Q: 2 }); From ae972f71c5f74e889c9e2618e2bae69500f728f0 Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Mon, 28 Mar 2022 07:03:59 -0600 Subject: [PATCH 160/253] Update metadata.json --- apps/mtgwatchface/metadata.json | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index f0be4b206..22bdcee1e 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -18,18 +18,12 @@ "storage": [ { "name": "mtgwatchface.app.js", - "url": "app.js", - "supports": [ - "BANGLEJS2" - ] + "url": "app.js" }, { "name": "mtgwatchface.img", "url": "app-icon.js", - "evaluate":true, - "supports": [ - "BANGLEJS2" - ] + "evaluate":true } ] } From a4acab8316754df93a02c541c1badf76080cd68a Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Mon, 28 Mar 2022 07:11:26 -0600 Subject: [PATCH 161/253] Update app-icon.js --- apps/mtgwatchface/app-icon.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/mtgwatchface/app-icon.js b/apps/mtgwatchface/app-icon.js index 3ca872eee..ebeeb7840 100644 --- a/apps/mtgwatchface/app-icon.js +++ b/apps/mtgwatchface/app-icon.js @@ -1,6 +1 @@ -{ - width : 48, height : 48, bpp : 2, - transparent : -1, - palette : new Uint16Array([65535,0,23275,42260]), - buffer : require("heatshrink").decompress(atob("AB8P9Wq3kD////gKCgeVqoAB2QHBhgLCkoKCqtaBYoWDAAIjEgXVBQdWHIkliojE0ALDqv1BYdlqgKCgNVpIvEqvABYMJqtfBYtABYM1BIoABsALBHIgADrgLBKIgADHgRpFAAVXKQQAIBYe6BAdsIYKkBH4U5QQcCMAILBwAGCIgYIBBwQbCqtwIgQLCSQZ0D6oLHFAJ0BwAfBBY4jBA4Nr4ENBYO8gEOHAR3DrNlNYr5Drt1copcCqttvIECrA4COoVtbQVWHQM61WqGIILDtWq1k8DIUFvuJQYUAnALEucJBYcInkCgWggt63Nch06wALBhM77kFU4UJidwBYMBlEsBYcOgFABYcYBYkDEYUBnNcBYOVBYMBHYQDB0EKqvVzkOhYLChsDoELBYPch029gLBh3NCANVi0chXuyALBNwILBysAjhrDBIMgAgPrgEsQYabC1WoA4IGD1gPCABIfBnnA0ewA4MDmADB1ks2/jwv4kHagQyC8sQ3OzhsHlERgUIBYP+ld8+fOmm3iXC5ALBhkAFAQAB4AGFABA")) - } \ No newline at end of file +var img = E.toArrayBuffer(atob("MDCDAf/////////////////////////////////+AAAP/////////////////wAAAAAAAB+v////x//////+AAAAAAAAAAAv///////////wAAAAAAAAAAAhxxxxx/////+OAAAAAAAAAAAP//////////wAAAAAAAAAABxx/////////wAOAAAAAAAAAAAAB////////wABwAAAAAAAAAAAAB//////wAAAOAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAAAAP////wAAAAAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAP///wAAAOOAAAAAAAAAP+AAAP///wABx///wAAAAAB////wAB//+AAB////+AAAAAP////wAP///wAB/////wAAAB/////wAB//+AAP/////wAAAB/////+AB///wAP/////wAAAB/////wAB//+AAP/////wAAAB/////+AB///wABxx//wAAAABx///xwAB///wAAAAAAAAAAAAAAAAAAAP////wAAAAAAAABwAAAAAAAB/////+AAAAAAAOBwAAAAAAAP///////wAAAABwBwAAAAABx////wAAAAAAAAAOB+AAAAAAAAAP/x///////wBwBwAB///////x/////////wB+P+AP///////x/x/x//x//wBxxwAB/x/xx//x///+Px+P/wAAAAAP/wOPwP/x/x/wPx/x/wAAAAAB/x//x//x///+OB+P/wAAAAAP/+P+B//x/x/wPwAB/wAAAAAB/x/+B//x///+P/wP/wAAOAAP/+P+P//x/x/wP/x//xwAAAAB/x/xxx/x///+P+P//xwAOAOP/+OOAP/x/x///x///xwAP/+B///////x////+P///x+B//+P///////x/xxxxxxxxx/////xxxxxxxxx//////////////////////////xx///xx/x/x///////x/////wP+P+B+P/wPx+P+OP+OP////xwAPxwB//x/xxx+B//xx////+OOPwP///+OBwAOOP+Px/////x///////x////x///x///////////////////////////w==")) From 3f4a45b59f2bfcd9a358de9c9ca665d85ad0e9ff Mon Sep 17 00:00:00 2001 From: Brant Peery Date: Mon, 28 Mar 2022 11:26:14 -0600 Subject: [PATCH 162/253] Update version --- apps/mtgwatchface/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mtgwatchface/metadata.json b/apps/mtgwatchface/metadata.json index 22bdcee1e..fd81ce10f 100644 --- a/apps/mtgwatchface/metadata.json +++ b/apps/mtgwatchface/metadata.json @@ -2,7 +2,7 @@ "id": "mtgwatchface", "name": "MTG Watchface", "shortName": "Magic the Gathering Watch Face", - "version": "1v02", + "version": "1v03", "description": "Magic the Gathering themed watch face. Embrace the inner wizzard. Dispay any of the different types of mana on your watch. Which color are you devoted to today? ", "icon": "icon.png", "screenshots": [ From 464643db38fb264ab0f0766fe6183e2dd5b12ebd Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 21:40:10 +0200 Subject: [PATCH 163/253] Update widget.js --- apps/widbt/widget.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 96656324e..b9035e9bb 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -15,10 +15,11 @@ WIDGETS.bluetooth = { connect: function() { WIDGETS.bluetooth.draw(); }, - diconnect: function() { + disconnect: function() { if(warningEnabled == 1){ Bangle.buzz(700, 1); // buzz on connection loss - warningEnabled = 0; + E.showMessage("Connection\nlost.","Bluetooth"); + WIDGETS.bluetooth.warningEnabled = 0; setTimeout('WIDGETS.bluetooth.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. } WIDGETS.bluetooth.draw(); @@ -26,4 +27,4 @@ WIDGETS.bluetooth = { }; NRF.on('connect', WIDGETS.bluetooth.connect); -NRF.on('disconnect', WIDGETS.bluetooth.diconnect); +NRF.on('disconnect', WIDGETS.bluetooth.disconnect); From cd1294af40f8365e0fa62b6828a29c8c6ac2b988 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 21:53:55 +0200 Subject: [PATCH 164/253] Update widget.js --- apps/widbt/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index b9035e9bb..58b4d4b4a 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -16,7 +16,7 @@ WIDGETS.bluetooth = { WIDGETS.bluetooth.draw(); }, disconnect: function() { - if(warningEnabled == 1){ + if(WIDGETS.bluetooth.warningEnabled == 1){ Bangle.buzz(700, 1); // buzz on connection loss E.showMessage("Connection\nlost.","Bluetooth"); WIDGETS.bluetooth.warningEnabled = 0; From a06c782edeb56ed540f8baf6b160b7f01e24d42f Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 21:57:52 +0200 Subject: [PATCH 165/253] Update settings.js -Option to unlock the watch, when a message arrives, so the buttons can directly be touched. --- apps/messages/settings.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/messages/settings.js b/apps/messages/settings.js index 99843602b..1e9605360 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -4,6 +4,7 @@ if (settings.vibrate===undefined) settings.vibrate="."; if (settings.repeat===undefined) settings.repeat=4; if (settings.unreadTimeout===undefined) settings.unreadTimeout=60; + if( settings.unlockWatch===undefined) settings.unlockWatch = false; settings.openMusic=!!settings.openMusic; settings.maxUnreadTimeout=240; return settings; @@ -49,6 +50,11 @@ format: v => v?/*LANG*/'Yes':/*LANG*/'No', onchange: v => updateSetting("openMusic", v) }, + /*LANG*/'Unlock Watch': { + value: !!settings().unlockWatch, + format: v => v?/*LANG*/'Yes':/*LANG*/'No', + onchange: v => updateSetting("unlockWatch", v) + }, }; E.showMenu(mainmenu); }) From af7f67205378c374d87fa0ab5bf890a81fed0ebf Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:08:16 +0200 Subject: [PATCH 166/253] Update lib.js Unlock the watch, to get touch access, if the user want that. --- apps/messages/lib.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index 0f514a73d..3e6dd2426 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -58,6 +58,7 @@ exports.pushMessage = function(event) { var loadMessages = Bangle.CLOCK || event.important; // first, buzz var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; + var unlockWatch = (require('Storage').readJSON('setting.json',1)||{}).unlockWatch; if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages) WIDGETS.messages.buzz(); // after a delay load the app, to ensure we have all the messages @@ -65,7 +66,12 @@ exports.pushMessage = function(event) { exports.messageTimeout = setTimeout(function() { exports.messageTimeout = undefined; // if we're in a clock or it's important, go straight to messages app - if (loadMessages) return load("messages.app.js"); + if (loadMessages){ + if(unlockWatch){ + Bangle.setLocked(false); + } + return load("messages.app.js"); + } if (!quiet && (!global.WIDGETS || !WIDGETS.messages)) return Bangle.buzz(); // no widgets - just buzz to let someone know WIDGETS.messages.show(); }, 500); From 29f93c01655b9026df946a1e4699bd4719696472 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:10:29 +0200 Subject: [PATCH 167/253] Update README.md --- apps/messages/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/messages/README.md b/apps/messages/README.md index 655c549b9..780d8e50b 100644 --- a/apps/messages/README.md +++ b/apps/messages/README.md @@ -20,6 +20,7 @@ to the clock where a ringing bell will be shown in the Widget bar. is chosen if there isn't much message text, but this specifies the smallest the font should get before it starts getting clipped. * `Auto-Open Music` - Should the app automatically open when the phone starts playing music? +* `Unlock Watch` - Should the app unlock the watch when a new message arrives, so you can touch the buttons at the bottom of the app? ## New Messages From 148e571769bd9cd5e2add8884e26f634a24c1fa6 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:12:19 +0200 Subject: [PATCH 168/253] Update ChangeLog 0.27: Option to auto-unlock the watch when a new message arrives --- apps/messages/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index c39e7d6fe..e263227e5 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -39,3 +39,4 @@ 0.24: Remove left-over debug statement 0.25: Fix widget memory usage issues if message received and watch repeatedly calls Bangle.drawWidgets (fix #1550) 0.26: Setting to auto-open music +0.27: Option to auto-unlock the watch when a new message arrives From febcdf4f536360fab3b6fba853a19eefc887c9f1 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:15:41 +0200 Subject: [PATCH 169/253] Update metadata.json --- apps/messages/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index a3d3f4179..4fb5a4045 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.26", + "version": "0.27", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 14e8a93c81840788ee1e7264cb85356abdfc6d77 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:28:39 +0200 Subject: [PATCH 170/253] Update lib.js --- apps/messages/lib.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index 3e6dd2426..ba632cb46 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -58,18 +58,19 @@ exports.pushMessage = function(event) { var loadMessages = Bangle.CLOCK || event.important; // first, buzz var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; - var unlockWatch = (require('Storage').readJSON('setting.json',1)||{}).unlockWatch; - if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages) + var unlockWatch = !!((require('Storage').readJSON("messages.settings.json", true) || {}).unlockWatch; + if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages){ WIDGETS.messages.buzz(); + if(unlockWatch){ + Bangle.setLocked(false); + } + } // after a delay load the app, to ensure we have all the messages if (exports.messageTimeout) clearTimeout(exports.messageTimeout); exports.messageTimeout = setTimeout(function() { exports.messageTimeout = undefined; // if we're in a clock or it's important, go straight to messages app if (loadMessages){ - if(unlockWatch){ - Bangle.setLocked(false); - } return load("messages.app.js"); } if (!quiet && (!global.WIDGETS || !WIDGETS.messages)) return Bangle.buzz(); // no widgets - just buzz to let someone know From b5010b41098e862d0f53f42d4c0c1ee32f12683c Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:33:52 +0200 Subject: [PATCH 171/253] Update lib.js --- apps/messages/lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index ba632cb46..f7489c276 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -58,7 +58,7 @@ exports.pushMessage = function(event) { var loadMessages = Bangle.CLOCK || event.important; // first, buzz var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; - var unlockWatch = !!((require('Storage').readJSON("messages.settings.json", true) || {}).unlockWatch; + var unlockWatch = !!((require('Storage').readJSON("messages.settings.json", true) || {}).unlockWatch); if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages){ WIDGETS.messages.buzz(); if(unlockWatch){ From a011858cab9218642bf43344dd3d389b83c203c1 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:43:46 +0200 Subject: [PATCH 172/253] Update lib.js --- apps/messages/lib.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index f7489c276..30ffe0a95 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -57,11 +57,11 @@ exports.pushMessage = function(event) { // otherwise load messages/show widget var loadMessages = Bangle.CLOCK || event.important; // first, buzz - var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; - var unlockWatch = !!((require('Storage').readJSON("messages.settings.json", true) || {}).unlockWatch); + var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; + var unlockWatch = (require('Storage').readJSON('setting.json',1)||{}).unlockWatch; if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages){ WIDGETS.messages.buzz(); - if(unlockWatch){ + if(!!unlockWatch){ Bangle.setLocked(false); } } From cf53626c5957e7eb08f9080964b28560b11b0fbd Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 22:45:41 +0200 Subject: [PATCH 173/253] Update lib.js --- apps/messages/lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index 30ffe0a95..fa607b268 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -61,7 +61,7 @@ exports.pushMessage = function(event) { var unlockWatch = (require('Storage').readJSON('setting.json',1)||{}).unlockWatch; if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages){ WIDGETS.messages.buzz(); - if(!!unlockWatch){ + if(unlockWatch != false){ Bangle.setLocked(false); } } From 284da20f01b3425b6238c558de8761433ddb01aa Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Mon, 28 Mar 2022 23:14:00 +0200 Subject: [PATCH 174/253] Update ChangeLog --- apps/messages/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 91d2bb0bf..7815cc3d1 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -40,3 +40,4 @@ 0.25: Fix widget memory usage issues if message received and watch repeatedly calls Bangle.drawWidgets (fix #1550) 0.26: Setting to auto-open music 0.27: Add 'mark all read' option to popup menu (fix #1624) + Option to auto-unlock the watch when a new message arrives From deb18b0ef5cc8138f17a00a356daa38f64fb67db Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 29 Mar 2022 07:15:05 +0200 Subject: [PATCH 175/253] Update widget.js Reload the clock after the "connection lost" message was shown. --- apps/widbt/widget.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 58b4d4b4a..5d752b575 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -18,7 +18,10 @@ WIDGETS.bluetooth = { disconnect: function() { if(WIDGETS.bluetooth.warningEnabled == 1){ Bangle.buzz(700, 1); // buzz on connection loss - E.showMessage("Connection\nlost.","Bluetooth"); + + E.showMessage(/*LANG*/"Connection\nlost.","Bluetooth"); + setInterval(()=>{load();}, 3000); // clear message + WIDGETS.bluetooth.warningEnabled = 0; setTimeout('WIDGETS.bluetooth.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. } From be3d00e9746528d82564d9d4f3be78d4e216d01b Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 29 Mar 2022 07:25:56 +0200 Subject: [PATCH 176/253] Update widget.js --- apps/widbt/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 5d752b575..6fa7f3b7a 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -19,7 +19,7 @@ WIDGETS.bluetooth = { if(WIDGETS.bluetooth.warningEnabled == 1){ Bangle.buzz(700, 1); // buzz on connection loss - E.showMessage(/*LANG*/"Connection\nlost.","Bluetooth"); + E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth'); setInterval(()=>{load();}, 3000); // clear message WIDGETS.bluetooth.warningEnabled = 0; From 5ff8ab62a2c7344eb5abaf6b0f4b92f68915b9c0 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 29 Mar 2022 07:44:41 +0200 Subject: [PATCH 177/253] Update settings.js --- apps/messages/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messages/settings.js b/apps/messages/settings.js index 1e9605360..589d603da 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -4,7 +4,7 @@ if (settings.vibrate===undefined) settings.vibrate="."; if (settings.repeat===undefined) settings.repeat=4; if (settings.unreadTimeout===undefined) settings.unreadTimeout=60; - if( settings.unlockWatch===undefined) settings.unlockWatch = false; + settings.unlockWatch=!!settings.unlockWatch; settings.openMusic=!!settings.openMusic; settings.maxUnreadTimeout=240; return settings; From 30c946ceaa6d767874c74c5b5321c9790dd51b4c Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 29 Mar 2022 07:54:18 +0200 Subject: [PATCH 178/253] Update lib.js --- apps/messages/lib.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index fa607b268..d7c95570b 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -63,6 +63,7 @@ exports.pushMessage = function(event) { WIDGETS.messages.buzz(); if(unlockWatch != false){ Bangle.setLocked(false); + Bangle.setLCDPower(1); // turn screen on } } // after a delay load the app, to ensure we have all the messages From 599f20aca93934e7b84e06d957ca42000033cd28 Mon Sep 17 00:00:00 2001 From: Brendan Hubble Date: Tue, 29 Mar 2022 18:59:05 +1100 Subject: [PATCH 179/253] touchtimer: FIX countdown buzz to be in last 5 seconds - The countdown buzz was happening on each minute and not only on the last 5 seconds --- apps/touchtimer/ChangeLog | 1 + apps/touchtimer/app.js | 7 ++++++- apps/touchtimer/metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/touchtimer/ChangeLog b/apps/touchtimer/ChangeLog index 0969a3da4..f81907152 100644 --- a/apps/touchtimer/ChangeLog +++ b/apps/touchtimer/ChangeLog @@ -2,3 +2,4 @@ 0.02: Add settings menu 0.03: Add ability to repeat last timer 0.04: Add 5 second count down buzzer +0.05: Fix 5 second count down buzzer to be only in the final 5 seconds diff --git a/apps/touchtimer/app.js b/apps/touchtimer/app.js index c2f2fb5e9..18c07feef 100644 --- a/apps/touchtimer/app.js +++ b/apps/touchtimer/app.js @@ -129,7 +129,12 @@ var main = () => { // Buzz lightly when there are less then 5 seconds left if (settings.countDownBuzz) { var remainingSeconds = timerCountDown.getAdjustedTime().seconds; - if (remainingSeconds <= 5 && remainingSeconds > 0) { + var remainingMinutes = timerCountDown.getAdjustedTime().minutes; + var remainingHours = timerCountDown.getAdjustedTime().hours; + if ( remainingSeconds <= 5 + && remainingSeconds > 0 + && remainingMinutes <= 0 + && remainingHours <= 0) { Bangle.buzz(); } } diff --git a/apps/touchtimer/metadata.json b/apps/touchtimer/metadata.json index 0f2b9f491..9261f3619 100644 --- a/apps/touchtimer/metadata.json +++ b/apps/touchtimer/metadata.json @@ -2,7 +2,7 @@ "id": "touchtimer", "name": "Touch Timer", "shortName": "Touch Timer", - "version": "0.04", + "version": "0.05", "description": "Quickly and easily create a timer with touch-only input. The time can be easily set with a number pad.", "icon": "app.png", "tags": "tools", From 011388e442ec0f7093724062c540ec106160dfdb Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 29 Mar 2022 09:17:28 +0100 Subject: [PATCH 180/253] icon tweak --- apps/mtgwatchface/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mtgwatchface/app-icon.js b/apps/mtgwatchface/app-icon.js index ebeeb7840..61ba9e656 100644 --- a/apps/mtgwatchface/app-icon.js +++ b/apps/mtgwatchface/app-icon.js @@ -1 +1 @@ -var img = E.toArrayBuffer(atob("MDCDAf/////////////////////////////////+AAAP/////////////////wAAAAAAAB+v////x//////+AAAAAAAAAAAv///////////wAAAAAAAAAAAhxxxxx/////+OAAAAAAAAAAAP//////////wAAAAAAAAAABxx/////////wAOAAAAAAAAAAAAB////////wABwAAAAAAAAAAAAB//////wAAAOAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAAAAP////wAAAAAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAP///wAAAOOAAAAAAAAAP+AAAP///wABx///wAAAAAB////wAB//+AAB////+AAAAAP////wAP///wAB/////wAAAB/////wAB//+AAP/////wAAAB/////+AB///wAP/////wAAAB/////wAB//+AAP/////wAAAB/////+AB///wABxx//wAAAABx///xwAB///wAAAAAAAAAAAAAAAAAAAP////wAAAAAAAABwAAAAAAAB/////+AAAAAAAOBwAAAAAAAP///////wAAAABwBwAAAAABx////wAAAAAAAAAOB+AAAAAAAAAP/x///////wBwBwAB///////x/////////wB+P+AP///////x/x/x//x//wBxxwAB/x/xx//x///+Px+P/wAAAAAP/wOPwP/x/x/wPx/x/wAAAAAB/x//x//x///+OB+P/wAAAAAP/+P+B//x/x/wPwAB/wAAAAAB/x/+B//x///+P/wP/wAAOAAP/+P+P//x/x/wP/x//xwAAAAB/x/xxx/x///+P+P//xwAOAOP/+OOAP/x/x///x///xwAP/+B///////x////+P///x+B//+P///////x/xxxxxxxxx/////xxxxxxxxx//////////////////////////xx///xx/x/x///////x/////wP+P+B+P/wPx+P+OP+OP////xwAPxwB//x/xxx+B//xx////+OOPwP///+OBwAOOP+Px/////x///////x////x///x///////////////////////////w==")) +E.toArrayBuffer(atob("MDCDAf/////////////////////////////////+AAAP/////////////////wAAAAAAAB+v////x//////+AAAAAAAAAAAv///////////wAAAAAAAAAAAhxxxxx/////+OAAAAAAAAAAAP//////////wAAAAAAAAAABxx/////////wAOAAAAAAAAAAAAB////////wABwAAAAAAAAAAAAB//////wAAAOAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAAAAP////wAAAAAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAP///wAAAOOAAAAAAAAAP+AAAP///wABx///wAAAAAB////wAB//+AAB////+AAAAAP////wAP///wAB/////wAAAB/////wAB//+AAP/////wAAAB/////+AB///wAP/////wAAAB/////wAB//+AAP/////wAAAB/////+AB///wABxx//wAAAABx///xwAB///wAAAAAAAAAAAAAAAAAAAP////wAAAAAAAABwAAAAAAAB/////+AAAAAAAOBwAAAAAAAP///////wAAAABwBwAAAAABx////wAAAAAAAAAOB+AAAAAAAAAP/x///////wBwBwAB///////x/////////wB+P+AP///////x/x/x//x//wBxxwAB/x/xx//x///+Px+P/wAAAAAP/wOPwP/x/x/wPx/x/wAAAAAB/x//x//x///+OB+P/wAAAAAP/+P+B//x/x/wPwAB/wAAAAAB/x/+B//x///+P/wP/wAAOAAP/+P+P//x/x/wP/x//xwAAAAB/x/xxx/x///+P+P//xwAOAOP/+OOAP/x/x///x///xwAP/+B///////x////+P///x+B//+P///////x/xxxxxxxxx/////xxxxxxxxx//////////////////////////xx///xx/x/x///////x/////wP+P+B+P/wPx+P+OP+OP////xwAPxwB//x/xxx+B//xx////+OOPwP///+OBwAOOP+Px/////x///////x////x///x///////////////////////////w==")) From 6389b27d41577544a09719c96aad2f9d0138874d Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 10:51:29 +0100 Subject: [PATCH 181/253] Update pebble.app.js First stab at adding theme selection --- apps/pebble/pebble.app.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 106e09b82..d4e9110b7 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -12,7 +12,7 @@ const SETTINGS_FILE = "pebble.json"; let settings; function loadSettings() { - settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green'}; + settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green', 'theme':'System'}; } var img = require("heatshrink").decompress(atob("oFAwkEogA/AH4A/AH4A/AH4A/AE8AAAoeXoAfeDQUBmcyD7A+Dh///8QD649CiAfaHwUvD4sEHy0DDYIfEICg+Cn4fHICY+DD4nxcgojOHwgfEIAYfRCIQaDD4ZAFD5r7DH4//kAfRCIZ/GAAnwD5p9DX44fTHgYSBf4ofVDAQEBl4fFUAgfOXoQzBgIfFBAIfPP4RAEAoYAB+cRiK/SG4h/WIBAfXIA7CBAAswD55AHn6fUIBMCD65AHl4gCmcziAfQQJqfQQJpiDgk0IDXxQLRAEECaBM+QgRYRYgUIA0CD4ggSQJiDCiAKBICszAAswD55AHABKBVD7BAFABIqBD5pAFABPxD55AOD6BADiIAJQAyxLABwf/gaAPAH4A/AH4ARA==")); @@ -107,6 +107,17 @@ function getSteps() { return '????'; } +function set_colors() { + if (settings.theme == 'Light') { + pass + } else if (settings.theme == 'Dark') { + pass + } else { + let color_bg = g.theme.bg + let color_fg = g.theme.fg + } +} + g.clear(); Bangle.loadWidgets(); /* @@ -116,6 +127,7 @@ Bangle.loadWidgets(); */ for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} loadSettings(); +set_colors(); setInterval(draw, 15000); // refresh every 15s draw(); Bangle.setUI("clock"); From dcd39418a58495809f02f644e8595c7a74207486 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 29 Mar 2022 10:58:48 +0100 Subject: [PATCH 182/253] quick removal of GPS clear from #1619 --- modules/exstats.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/exstats.js b/modules/exstats.js index b22f3f5d3..056dc9f0f 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -299,8 +299,6 @@ exports.getStats = function(statIDs, options) { state.curSpeed = 0; state.BPM = 0; state.BPMage = 0; - state.thisGPS = {}; - state.lastGPS = {}; state.notify = options.notify; if (options.notify.dist.increment > 0) { state.notify.dist.next = state.distance + options.notify.dist.increment; From aba96398f17366634a5a84332b0e4dc462dbd486 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 11:06:29 +0100 Subject: [PATCH 183/253] Update metadata.json Switched on allow emulator --- apps/pebble/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pebble/metadata.json b/apps/pebble/metadata.json index 4295d7507..68f7d1465 100644 --- a/apps/pebble/metadata.json +++ b/apps/pebble/metadata.json @@ -11,6 +11,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS", "BANGLEJS2"], + "allow_emulator": true, "storage": [ {"name":"pebble.app.js","url":"pebble.app.js"}, {"name":"pebble.settings.js","url":"pebble.settings.js"}, From 24689a7684dca116e1b8ffee8ed719726b9ca520 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 12:39:55 +0100 Subject: [PATCH 184/253] Update pebble.settings.js --- apps/pebble/pebble.settings.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/pebble/pebble.settings.js b/apps/pebble/pebble.settings.js index ff408907d..95eecc7e3 100644 --- a/apps/pebble/pebble.settings.js +++ b/apps/pebble/pebble.settings.js @@ -2,7 +2,7 @@ const SETTINGS_FILE = "pebble.json"; // initialize with default settings... - let s = {'bg': '#0f0', 'color': 'Green'} + let s = {'bg': '#0f0', 'color': 'Green', 'theme':'System'} // ...and overwrite them with any saved values // This way saved values are preserved if a new version adds more settings @@ -20,6 +20,7 @@ var color_options = ['Green','Orange','Cyan','Purple','Red','Blue']; var bg_code = ['#0f0','#ff0','#0ff','#f0f','#f00','#00f']; + var theme_options = ['System', 'Light', 'Dark']; E.showMenu({ '': { 'title': 'Pebble Clock' }, @@ -33,6 +34,14 @@ s.bg = bg_code[v]; save(); }, + 'Theme': { + value: 0 | theme_options.indexOf(s.theme), + min: 0, max: theme_options.length - 1, + format: v => theme_options[v], + onchange: v => { + s.theme = theme_options[v]; + save(); + }, } }); }) From 358e8d18c804bb27e1d8307aba7b3a58692101fd Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 12:45:08 +0100 Subject: [PATCH 185/253] Update pebble.app.js --- apps/pebble/pebble.app.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index d4e9110b7..159bc2bf8 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -30,6 +30,8 @@ function draw() { let da = date.toString().split(" "); let timeStr = da[4].substr(0,5); const t = 6; + print('Theme'); + print(theme); // turn the warning on once we have dipped below 30% if (E.getBattery() < 30) @@ -44,7 +46,7 @@ function draw() { g.fillRect(0, 0, w, h2 - t); // contrast bar - g.setColor(g.theme.fg); + g.setColor(theme.fg); g.fillRect(0, h2 - t, w, h2); // day and steps @@ -65,11 +67,11 @@ function draw() { g.setFontLECO1976Regular42(); g.setFontAlign(0, -1); - g.setColor(!batteryWarning ? g.theme.fg : '#fff'); + g.setColor(!batteryWarning ? theme.fg : '#fff'); g.drawString(timeStr, w/2, h2 + 8); // contrast bar - g.setColor(g.theme.fg); + g.setColor(theme.fg); g.fillRect(0, h3, w, h3 + t); // the bottom @@ -83,11 +85,11 @@ function draw() { // at x,y width:wi thicknes:th function drawCalendar(x,y,wi,th,str) { - g.setColor(g.theme.fg); + g.setColor(theme.fg); g.fillRect(x, y, x + wi, y + wi); - g.setColor(g.theme.bg); + g.setColor(theme.bg); g.fillRect(x + th, y + th, x + wi - th, y + wi - th); - g.setColor(g.theme.fg); + g.setColor(theme.fg); let hook_t = 6; // first calendar hook, one third in @@ -107,15 +109,13 @@ function getSteps() { return '????'; } -function set_colors() { - if (settings.theme == 'Light') { - pass - } else if (settings.theme == 'Dark') { - pass - } else { - let color_bg = g.theme.bg - let color_fg = g.theme.fg - } +function loadThemeColors(style) { + if (style === "Dark") + theme = {fg: g.toColor(1,1,1), bg: g.toColor(0,0,0)}; + else if (style === "Light") + theme = {fg: g.toColor(0,0,0), bg: g.toColor(1,1,1)}; + else + theme = {fg: g.theme.fg, bg: g.theme.bg}; } g.clear(); @@ -127,7 +127,7 @@ Bangle.loadWidgets(); */ for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} loadSettings(); -set_colors(); +loadThemeColors(settings.theme); setInterval(draw, 15000); // refresh every 15s draw(); Bangle.setUI("clock"); From 4658fb9743aa138d1cd6f7145f0ae2de25e05bbc Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 12:46:07 +0100 Subject: [PATCH 186/253] Update README.md --- apps/pebble/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pebble/README.md b/apps/pebble/README.md index 4b0233781..15d2bd58c 100644 --- a/apps/pebble/README.md +++ b/apps/pebble/README.md @@ -4,7 +4,7 @@ * Designed specifically for Bangle 2 * A choice of 6 different background colous through its setting menu. Goto Settings, App/Widget settings, Pebble. -* Supports the Light and Dark themes +* Supports the Light and Dark themes (or set theme independently) * Uses pedometer widget to get latest step count * Dependant apps are installed when Pebble installs * Uses the whole screen, widgets are made invisible but still run in the background From f867c68340df0d3d2cc51ba58251c9684e2a5c1a Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 12:55:42 +0100 Subject: [PATCH 187/253] Update pebble.app.js --- apps/pebble/pebble.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 159bc2bf8..36bdf8c31 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -62,7 +62,7 @@ function draw() { // time // white on red for battery warning - g.setColor(!batteryWarning ? g.theme.bg : '#f00'); + g.setColor(!batteryWarning ? theme.bg : '#f00'); g.fillRect(0, h2, w, h3); g.setFontLECO1976Regular42(); From 2330f1f4642ec4912c35352c41db19d64743d3a8 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:00:21 +0100 Subject: [PATCH 188/253] Update ChangeLog --- apps/pebble/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pebble/ChangeLog b/apps/pebble/ChangeLog index 0cba5a2b2..c2705b790 100644 --- a/apps/pebble/ChangeLog +++ b/apps/pebble/ChangeLog @@ -5,3 +5,4 @@ 0.05: Fix typo in settings - Purple 0.06: Added dependancy on Pedometer Widget 0.07: Fixed icon and ong file to 48x48 +0.08: Added theme options From 3d9a49a5fba15fa1275d9b6d8d9f927444ea2bad Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:00:36 +0100 Subject: [PATCH 189/253] Update metadata.json --- apps/pebble/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pebble/metadata.json b/apps/pebble/metadata.json index 68f7d1465..eb049e78e 100644 --- a/apps/pebble/metadata.json +++ b/apps/pebble/metadata.json @@ -2,7 +2,7 @@ "id": "pebble", "name": "Pebble Clock", "shortName": "Pebble", - "version": "0.07", + "version": "0.08", "description": "A pebble style clock to keep the rebellion going", "dependencies": {"widpedom":"app"}, "readme": "README.md", From e3db453b44691cd7e84643a7eb612beb92fd06f3 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:00:55 +0100 Subject: [PATCH 190/253] Update pebble.settings.js --- apps/pebble/pebble.settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pebble/pebble.settings.js b/apps/pebble/pebble.settings.js index 95eecc7e3..4e235791b 100644 --- a/apps/pebble/pebble.settings.js +++ b/apps/pebble/pebble.settings.js @@ -41,7 +41,7 @@ onchange: v => { s.theme = theme_options[v]; save(); - }, + } } }); }) From 62b3336e6aac21cbd75b978204f63a844936bb10 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:10:48 +0100 Subject: [PATCH 191/253] Update pebble.settings.js --- apps/pebble/pebble.settings.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/pebble/pebble.settings.js b/apps/pebble/pebble.settings.js index 4e235791b..58715750d 100644 --- a/apps/pebble/pebble.settings.js +++ b/apps/pebble/pebble.settings.js @@ -33,7 +33,8 @@ s.color = color_options[v]; s.bg = bg_code[v]; save(); - }, + } + }, 'Theme': { value: 0 | theme_options.indexOf(s.theme), min: 0, max: theme_options.length - 1, From d8b49af3c844d3dcedee49dd52cf1e839db1850f Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:28:32 +0100 Subject: [PATCH 192/253] Update pebble.app.js Removed print statements from debugging --- apps/pebble/pebble.app.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 36bdf8c31..bbe2596ab 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -30,8 +30,6 @@ function draw() { let da = date.toString().split(" "); let timeStr = da[4].substr(0,5); const t = 6; - print('Theme'); - print(theme); // turn the warning on once we have dipped below 30% if (E.getBattery() < 30) From 8df137b21ddfa41cebd26f628b4b6413c34c593b Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Tue, 29 Mar 2022 14:32:33 +0200 Subject: [PATCH 193/253] widget 'widbt_notify' New Widget 'widbt_notify' is a bluetooth widget, that vibrates, when the connection gets lost. --- apps/widbt_notify/ChangeLog | 10 ++++++++++ apps/widbt_notify/metadata.json | 13 +++++++++++++ apps/widbt_notify/widget.js | 33 ++++++++++++++++++++++++++++++++ apps/widbt_notify/widget.png | Bin 0 -> 1119 bytes 4 files changed, 56 insertions(+) create mode 100644 apps/widbt_notify/ChangeLog create mode 100644 apps/widbt_notify/metadata.json create mode 100644 apps/widbt_notify/widget.js create mode 100644 apps/widbt_notify/widget.png diff --git a/apps/widbt_notify/ChangeLog b/apps/widbt_notify/ChangeLog new file mode 100644 index 000000000..b5a50210e --- /dev/null +++ b/apps/widbt_notify/ChangeLog @@ -0,0 +1,10 @@ +0.02: Tweaks for variable size widget system +0.03: Ensure redrawing works with variable size widget system +0.04: Fix automatic update of Bluetooth connection status +0.05: Make Bluetooth widget thinner, and when on a bright theme use light grey for disabled color +0.06: Tweaking colors for dark/light themes and low bpp screens +0.07: Memory usage improvements +0.08: Disable LCD on, on bluetooth status change +0.09: Vibrate on connection loss +0.10: Bug fix +0.11: Avoid too many notifications. Change disconnected colour to red. diff --git a/apps/widbt_notify/metadata.json b/apps/widbt_notify/metadata.json new file mode 100644 index 000000000..0b795c2c8 --- /dev/null +++ b/apps/widbt_notify/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "widbt_notify", + "name": "Bluetooth Widget with Notification", + "version": "0.11", + "description": "Show the current Bluetooth connection status in the top right of the clock and vibrate when disconnected.", + "icon": "widget.png", + "type": "widget", + "tags": "widget,bluetooth", + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"widbt_notify.wid.js","url":"widget.js"} + ] +} diff --git a/apps/widbt_notify/widget.js b/apps/widbt_notify/widget.js new file mode 100644 index 000000000..04f91a698 --- /dev/null +++ b/apps/widbt_notify/widget.js @@ -0,0 +1,33 @@ +WIDGETS.bluetooth_notify = { + area: "tr", + width: 15, + warningEnabled: 1, + draw: function() { + g.reset(); + if (NRF.getSecurityStatus().connected) { + g.setColor((g.getBPP() > 8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); + } else { + // g.setColor(g.theme.dark ? "#666" : "#999"); + g.setColor("#f00"); // red is easier to distinguish from blue + } + g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y); + }, + connect: function() { + WIDGETS.bluetooth_notify.draw(); + }, + disconnect: function() { + if(WIDGETS.bluetooth_notify.warningEnabled == 1){ + Bangle.buzz(700, 1); // buzz on connection loss + + E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth'); + setInterval(()=>{load();}, 3000); // clear message + + WIDGETS.bluetooth_notify.warningEnabled = 0; + setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. + } + WIDGETS.bluetooth_notify.draw(); + } +}; + +NRF.on('connect', WIDGETS.bluetooth_notify.connect); +NRF.on('disconnect', WIDGETS.bluetooth_notify.disconnect); diff --git a/apps/widbt_notify/widget.png b/apps/widbt_notify/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..1a884a62c1029ae43243f8f58ef9dc3a3327e437 GIT binary patch literal 1119 zcmV-l1fctgP)cE5(396`@Dz$wLqIPzYppJ*B(brZX|I zHChYW;Hm1lL~9feUi^283bm!!Ka0DG`v(zZvk8h?W%2@c?XT zES*ZPJU3a{7h{cB0RRrPTh=dGr*a^!0&xQX?DMczGEQwQ4)Y`c0EQJR_Oa?r)W%5x z0HhI_x1HK2pc0j7k^sKW*iQXQ=2YX6D9n-q_%qO+(!1;R%(3!ggBm9SkZ!j|fYm^E zR%O?(qZ5_=gLo$b@WZ#`wXJ`4=)@t~Y>Yv)Y!7y;OB zeO8rs?l*_RK!7NCKLhRU0}||esEhzCyx)O;I=Y5XtC(@B$NTljy45^tT?SHJ10ruX zOS$(<@@!=?P@`0+S)vnkL!=bB)DOg{Q*}L+GO)XAK;&$g@DSo22n#XlR9!)?07D(! zDxz;SOSunBbNCAVm!5U2c~9jVx@WU3=u3)pJ!ur3cu;sm-)NQ!pM}i;0{{TnZpA^Z ztASvff%b#?JdoF$<=hv8)Q159pyx{LBoBD4SyIzhb(HlW;>}!J+1=AqCDO_A6&XN}=e)0!pcibn z_HtD9d_@BAknp}zDCb9=>MK#y^fmCZ_8GoYkv>KTT7e$nHy?0mXP*UpX*>1PgVgRc z3#Fdn#d~2}5mATky^{qxZ#%U!Ve5AonQN!;&C-!_@cJGbKmk6^xYakqWbkDSU>e?6 zF9=onXw<2mHO=A62q0{DUp*iYB(+@Ja7a-n2aQU$C-1do)^M)j_l7Z`m-DHf;N2WNgeIsEr6@kFmJ z8_YbwGn3bL?QPY+LOBr_TDRcEMmfJ|;s=HR0IQ!ry9xAti1(G5Y&@#1^&${_&Hfi+ z9c`2jUpMuHhg{we{KebpwXs3NLqaRiAr)b6sg!$n>kZxDN)lj0k<-mm?qZatNdeqJ z)Lky+8&Ml40dUjvB)_tlzY&Ld+&A&{bh~wEWib~^c!+ZagoS&X-t=l^d_A@r#J2*U lKABp3ezkHW*6{xc{R@3@kib`1LqGrk002ovPDHLkV1l684mkh- literal 0 HcmV?d00001 From e60586f13824bbf0c2f9cfba5ed41931581f4ed5 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:58:05 +0100 Subject: [PATCH 194/253] Update pebble.app.js Move day and steps color into loadThemeColors function. Added test lock icon --- apps/pebble/pebble.app.js | 46 +++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index bbe2596ab..b6aab30d7 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -12,7 +12,7 @@ const SETTINGS_FILE = "pebble.json"; let settings; function loadSettings() { - settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green', 'theme':'System'}; + settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green', 'theme':'System', 'showlock':'false'}; } var img = require("heatshrink").decompress(atob("oFAwkEogA/AH4A/AH4A/AH4A/AE8AAAoeXoAfeDQUBmcyD7A+Dh///8QD649CiAfaHwUvD4sEHy0DDYIfEICg+Cn4fHICY+DD4nxcgojOHwgfEIAYfRCIQaDD4ZAFD5r7DH4//kAfRCIZ/GAAnwD5p9DX44fTHgYSBf4ofVDAQEBl4fFUAgfOXoQzBgIfFBAIfPP4RAEAoYAB+cRiK/SG4h/WIBAfXIA7CBAAswD55AHn6fUIBMCD65AHl4gCmcziAfQQJqfQQJpiDgk0IDXxQLRAEECaBM+QgRYRYgUIA0CD4ggSQJiDCiAKBICszAAswD55AHABKBVD7BAFABIqBD5pAFABPxD55AOD6BADiIAJQAyxLABwf/gaAPAH4A/AH4ARA==")); @@ -48,11 +48,11 @@ function draw() { g.fillRect(0, h2 - t, w, h2); // day and steps - if (settings.color == 'Blue' || settings.color == 'Red') - g.setColor('#fff'); // white on blue or red best contrast - else - g.setColor('#000'); // otherwise black regardless of theme - + //if (settings.color == 'Blue' || settings.color == 'Red') + // g.setColor('#fff'); // white on blue or red best contrast + //else + // g.setColor('#000'); // otherwise black regardless of theme + g.setColor(theme.day); g.setFontLECO1976Regular22(); g.setFontAlign(0, -1); g.drawString(da[0].toUpperCase(), w/4, ha); // day of week @@ -107,15 +107,33 @@ function getSteps() { return '????'; } -function loadThemeColors(style) { - if (style === "Dark") - theme = {fg: g.toColor(1,1,1), bg: g.toColor(0,0,0)}; - else if (style === "Light") - theme = {fg: g.toColor(0,0,0), bg: g.toColor(1,1,1)}; - else - theme = {fg: g.theme.fg, bg: g.theme.bg}; +function loadThemeColors() { + theme = {fg: g.theme.fg, bg: g.theme.bg, day: g.toColor(0,0,0)}; + if (settings.theme === "Dark") { + theme.fg = g.toColor(1,1,1); + theme.bg = g.toColor(0,0,0); + } + else if (settings.theme === "Light") { + theme.fg = g.toColor(0,0,0); + theme.bg = g.toColor(1,1,1); + } + // day and steps + if (settings.color == 'Blue' || settings.color == 'Red') + theme.day = g.toColor(1,1,1); // white on blue or red best contrast } +function drawLock(){ + if(Bangle.isLocked()){ + g.drawImage(atob("DhABH+D/wwMMDDAwwMf/v//4f+H/h/8//P/z///f/g=="), 1, 4); + } else { + g.clearRect(0, 0, 20, 20); + } +} + +Bangle.on('lock', function(isLocked) { + drawLock(); +}); + g.clear(); Bangle.loadWidgets(); /* @@ -125,7 +143,7 @@ Bangle.loadWidgets(); */ for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} loadSettings(); -loadThemeColors(settings.theme); +loadThemeColors(); setInterval(draw, 15000); // refresh every 15s draw(); Bangle.setUI("clock"); From 7c697cf74939b4988879e78b9d14838a44994286 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 14:06:58 +0100 Subject: [PATCH 195/253] Update pebble.app.js --- apps/pebble/pebble.app.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index b6aab30d7..b6576671c 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -79,6 +79,8 @@ function draw() { g.setColor(settings.bg); g.drawImage(img, w/2 + ((w/2) - 64)/2, 1, { scale: 1 }); drawCalendar(((w/2) - 42)/2, 14, 42, 4, da[2]); + + drawLock(); } // at x,y width:wi thicknes:th @@ -124,9 +126,11 @@ function loadThemeColors() { function drawLock(){ if(Bangle.isLocked()){ + g.setColor(theme.day); g.drawImage(atob("DhABH+D/wwMMDDAwwMf/v//4f+H/h/8//P/z///f/g=="), 1, 4); } else { - g.clearRect(0, 0, 20, 20); + g.setColor(settings.bg); + g.drawRect(0, 0, 20, 20); } } From 181db378678b2d51c216df462440b4f0f076bf3d Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 14:17:13 +0100 Subject: [PATCH 196/253] Update pebble.app.js --- apps/pebble/pebble.app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index b6576671c..e583f1706 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -130,11 +130,11 @@ function drawLock(){ g.drawImage(atob("DhABH+D/wwMMDDAwwMf/v//4f+H/h/8//P/z///f/g=="), 1, 4); } else { g.setColor(settings.bg); - g.drawRect(0, 0, 20, 20); + g.fillRect(0, 0, 20, 20); } } -Bangle.on('lock', function(isLocked) { +Bangle.on('lock', function(on) { drawLock(); }); From c8e90b1f926d432ce17bc07d8d8115d1e2c47363 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 15:21:21 +0100 Subject: [PATCH 197/253] Update pebble.app.js --- apps/pebble/pebble.app.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index e583f1706..28e32354a 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -125,12 +125,15 @@ function loadThemeColors() { } function drawLock(){ - if(Bangle.isLocked()){ - g.setColor(theme.day); - g.drawImage(atob("DhABH+D/wwMMDDAwwMf/v//4f+H/h/8//P/z///f/g=="), 1, 4); - } else { - g.setColor(settings.bg); - g.fillRect(0, 0, 20, 20); + if (settings.showlock == 'true') { + if (Bangle.isLocked()){ + g.setColor(theme.day); + g.setBgColor(settings.bg); + g.drawImage(atob("DhABH+D/wwMMDDAwwMf/v//4f+H/h/8//P/z///f/g=="), 1, 4); + } else { + g.setColor(settings.bg); + g.fillRect(0, 0, 20, 20); + } } } From abdd91b6f1bc84a3fdeb9d77f988aeaf2e5c9814 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 15:24:13 +0100 Subject: [PATCH 198/253] Update pebble.settings.js --- apps/pebble/pebble.settings.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/pebble/pebble.settings.js b/apps/pebble/pebble.settings.js index 58715750d..3fbf72118 100644 --- a/apps/pebble/pebble.settings.js +++ b/apps/pebble/pebble.settings.js @@ -2,7 +2,7 @@ const SETTINGS_FILE = "pebble.json"; // initialize with default settings... - let s = {'bg': '#0f0', 'color': 'Green', 'theme':'System'} + let s = {'bg': '#0f0', 'color': 'Green', 'theme':'System', 'showlock':'false'} // ...and overwrite them with any saved values // This way saved values are preserved if a new version adds more settings @@ -21,6 +21,7 @@ var color_options = ['Green','Orange','Cyan','Purple','Red','Blue']; var bg_code = ['#0f0','#ff0','#0ff','#f0f','#f00','#00f']; var theme_options = ['System', 'Light', 'Dark']; + var lock_options = ['false', 'true']; E.showMenu({ '': { 'title': 'Pebble Clock' }, @@ -43,6 +44,15 @@ s.theme = theme_options[v]; save(); } + }, + 'Show Lock': { + value: 0 | lock_options.indexOf(s.showlock), + min: 0, max: lock_options.length - 1, + format: v => lock_options[v], + onchange: v => { + s.showlock = lock_options[v]; + save(); + } } }); }) From 4d6773c022c08cbbb337ef4e6eac03a859270ddc Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 15:27:34 +0100 Subject: [PATCH 199/253] Update pebble.settings.js --- apps/pebble/pebble.settings.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/apps/pebble/pebble.settings.js b/apps/pebble/pebble.settings.js index 3fbf72118..8a5fba63b 100644 --- a/apps/pebble/pebble.settings.js +++ b/apps/pebble/pebble.settings.js @@ -2,7 +2,7 @@ const SETTINGS_FILE = "pebble.json"; // initialize with default settings... - let s = {'bg': '#0f0', 'color': 'Green', 'theme':'System', 'showlock':'false'} + let s = {'bg': '#0f0', 'color': 'Green', 'theme':'System', 'showlock':false} // ...and overwrite them with any saved values // This way saved values are preserved if a new version adds more settings @@ -21,7 +21,6 @@ var color_options = ['Green','Orange','Cyan','Purple','Red','Blue']; var bg_code = ['#0f0','#ff0','#0ff','#f0f','#f00','#00f']; var theme_options = ['System', 'Light', 'Dark']; - var lock_options = ['false', 'true']; E.showMenu({ '': { 'title': 'Pebble Clock' }, @@ -46,13 +45,12 @@ } }, 'Show Lock': { - value: 0 | lock_options.indexOf(s.showlock), - min: 0, max: lock_options.length - 1, - format: v => lock_options[v], - onchange: v => { - s.showlock = lock_options[v]; + value: settings.showlock, + format: () => (settings.showlock ? 'Yes' : 'No'), + onchange: () => { + settings.showlock = !settings.showlock; save(); } - } + }, }); }) From 01a868155ebc5dd59eec5b52e70d5875b21b43b6 Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 15:28:42 +0100 Subject: [PATCH 200/253] Update pebble.app.js --- apps/pebble/pebble.app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 28e32354a..80243c890 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -12,7 +12,7 @@ const SETTINGS_FILE = "pebble.json"; let settings; function loadSettings() { - settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green', 'theme':'System', 'showlock':'false'}; + settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green', 'theme':'System', 'showlock':false}; } var img = require("heatshrink").decompress(atob("oFAwkEogA/AH4A/AH4A/AH4A/AE8AAAoeXoAfeDQUBmcyD7A+Dh///8QD649CiAfaHwUvD4sEHy0DDYIfEICg+Cn4fHICY+DD4nxcgojOHwgfEIAYfRCIQaDD4ZAFD5r7DH4//kAfRCIZ/GAAnwD5p9DX44fTHgYSBf4ofVDAQEBl4fFUAgfOXoQzBgIfFBAIfPP4RAEAoYAB+cRiK/SG4h/WIBAfXIA7CBAAswD55AHn6fUIBMCD65AHl4gCmcziAfQQJqfQQJpiDgk0IDXxQLRAEECaBM+QgRYRYgUIA0CD4ggSQJiDCiAKBICszAAswD55AHABKBVD7BAFABIqBD5pAFABPxD55AOD6BADiIAJQAyxLABwf/gaAPAH4A/AH4ARA==")); @@ -125,7 +125,7 @@ function loadThemeColors() { } function drawLock(){ - if (settings.showlock == 'true') { + if (settings.showlock) { if (Bangle.isLocked()){ g.setColor(theme.day); g.setBgColor(settings.bg); From b7ba1314b293af0ae61a60c536a4bf1bc73f8bbc Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 15:30:22 +0100 Subject: [PATCH 201/253] Update README.md --- apps/pebble/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pebble/README.md b/apps/pebble/README.md index 15d2bd58c..953db0ba7 100644 --- a/apps/pebble/README.md +++ b/apps/pebble/README.md @@ -9,6 +9,7 @@ * Dependant apps are installed when Pebble installs * Uses the whole screen, widgets are made invisible but still run in the background * When battery is less than 30% main screen goes Red +* Optionally show a lock symbol when screen is locked (default off, enable in Settings) ![](pebble_screenshot.png) ![](pebble_screenshot2.png) From 6ff39e55843ff96cbafdc1837e90a937e0d8524a Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Tue, 29 Mar 2022 15:30:45 +0100 Subject: [PATCH 202/253] Update ChangeLog --- apps/pebble/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pebble/ChangeLog b/apps/pebble/ChangeLog index c2705b790..01f653f48 100644 --- a/apps/pebble/ChangeLog +++ b/apps/pebble/ChangeLog @@ -5,4 +5,4 @@ 0.05: Fix typo in settings - Purple 0.06: Added dependancy on Pedometer Widget 0.07: Fixed icon and ong file to 48x48 -0.08: Added theme options +0.08: Added theme options and optional lock symbol From e0d457fd56fe6e485043c11663487b1d705f1759 Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Tue, 29 Mar 2022 23:34:01 +0200 Subject: [PATCH 203/253] Changed basic mover algorithme in favor of speed --- apps/game1024/app.js | 95 +++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 54 deletions(-) diff --git a/apps/game1024/app.js b/apps/game1024/app.js index 133630634..b0e8d74f7 100644 --- a/apps/game1024/app.js +++ b/apps/game1024/app.js @@ -164,16 +164,16 @@ const buttons = { const mover = { direction: { up: {name: 'up', step: 1, innerBegin: 0, innerEnd: rows-1, outerBegin: 0, outerEnd: cols-1, iter: rows -1, - sqIndex: function (m,n) {return m*(cols) + n;}, sqNextIndex: function (m,n) {return m < rows -1 ? (m+1)*(cols) + n : -1;} + sqIndex: function (i,o) {return i*(cols) + o;}, sqNextIndex: function (i,o) {return i < rows -1 ? (i+1)*(cols) + o : -1;} }, down: {name: 'down', step:-1, innerBegin: rows-1, innerEnd: 0, outerBegin: cols-1, outerEnd: 0, iter: rows -1, - sqIndex: function (m,n) {return m*(cols) + n;}, sqNextIndex: function (m,n) {return m > 0 ? (m-1)*(cols) + n : -1;} + sqIndex: function (i,o) {return i*(cols) + o;}, sqNextIndex: function (i,o) {return i > 0 ? (i-1)*(cols) + o : -1;} }, left: {name: 'left', step: 1, innerBegin: 0, innerEnd: cols-1, outerBegin: 0, outerEnd: rows-1, iter: cols -1, - sqIndex: function (m,n) {return n*(rows) + m;}, sqNextIndex: function (m,n) {return m < cols -1 ? n*(rows) + m +1 : -1;} + sqIndex: function (i,o) {return o*(rows) + i;}, sqNextIndex: function (i,o) {return i < cols -1 ? o*(rows) + i +1 : -1;} }, right: {name: 'right', step:-1, innerBegin: cols-1, innerEnd: 0, outerBegin: rows-1, outerEnd: 0, iter: cols -1, - sqIndex: function (m,n) {return n*(rows) + m;}, sqNextIndex: function (m,n) {return m > 0 ? n*(rows) + m -1: -1;} + sqIndex: function (i,o) {return o*(rows) + i;}, sqNextIndex: function (i,o) {return i > 0 ? o*(rows) + i -1: -1;} } }, anyLeft: function() { @@ -207,49 +207,39 @@ const mover = { }); return canContinue; }, - nonEmptyCells: function (dir) { - debug(() => console.log("Move: ", dir.name)); + moveAndMerge: function (dir) { const step = dir.step; // outer loop for all colums/rows - for (let n = dir.outerBegin; step*n <= step*dir.outerEnd; n=n+step) { - // let rowStr = '| '; - - // Move a number of iteration with the squares to move them all to one side - for (let iter = 0; iter < dir.iter; iter++) { - - // lets move squares one position in a row or column, counting backwards starting from the and where the squares will end up - for (let m = dir.innerBegin; step*m <= step*dir.innerEnd; m=m+step) { - // get the array of squares index for current cell - const idx = dir.sqIndex(m,n); - const nextIdx = dir.sqNextIndex(m,n); - - if (allSquares[idx].expVal == 0 && nextIdx >= 0) { - allSquares[idx].setExpVal(allSquares[nextIdx].expVal); - allSquares[nextIdx].setExpVal(0); - } - } - } - } - }, - // add up the conjacent squares with identical values en set next square to empty in the process - mergeEqlCells: function(dir) { - const step = dir.step; - // outer loop for all colums/rows - for (let n = dir.outerBegin; step*n <= step*dir.outerEnd; n=n+step) { - // lets move squares one position in a row or column, counting backwards starting from the and where the squares will end up + for (let o = dir.outerBegin; step*o <= step*dir.outerEnd; o=o+step) { + + let allVals = allSquares.map(sq=>{return sq.getExpVal()}); + let allLineVals = []; for (let m = dir.innerBegin; step*m <= step*dir.innerEnd; m=m+step) { - const idx = dir.sqIndex(m,n); - const nextIdx = dir.sqNextIndex(m,n); - - if ((allSquares[idx].expVal > 0) && nextIdx >= 0) { - if (allSquares[idx].expVal == allSquares[nextIdx].expVal) { - let expVal = allSquares[idx].expVal; - allSquares[idx].setExpVal(++expVal); - allSquares[idx].addToScore(); - allSquares[nextIdx].setExpVal(0); - } - } + allLineVals.push(allVals[dir.sqIndex(m,o)]); } + + let sortedLineVals = allLineVals.filter((val)=>{return val>0;}); + let zeroLineVals = allLineVals.filter((val)=>{return val==0;}); + // merge the equally valued adjacent cells + let r=0; + while (r{return val>0;}); + sortedLineVals.filter((val)=>{return val==0;}).forEach((zero)=>{mergedLineVals.push(zero);}); + zeroLineVals.forEach((zero)=>{mergedLineVals.push(zero);}); + + let i = 0; + for (let m = dir.innerBegin; step*m <= step*dir.innerEnd; m=m+step) { + let idx = dir.sqIndex(m,o); + allSquares[idx].setExpVal(mergedLineVals[i++]); + } + debug(()=>console.log("new allSquares values:", allSquares.map(sq=>{return sq.expVal}))); } } }; @@ -301,7 +291,7 @@ class Button { } class Cell { - constructor(x0, y0, width, idx, cb) { + constructor(x0, y0, width, idx) { this.x0 = x0; this.y0 = y0; this.x1 = x0 + width; @@ -309,7 +299,7 @@ class Cell { this.expVal = 0; this.previousExpVals=[]; this.idx = idx; - this.cb = cb; + // this.cb = cb; this.isRndm = false; this.ax = x0; this.ay = Math.floor(0.2*width+y0); @@ -345,6 +335,9 @@ class Cell { .drawString(char, strX, strY); } } + getExpVal() { + return this.expVal; + } setExpVal(val) { this.expVal = val; } @@ -364,10 +357,6 @@ class Cell { removeUndo() { this.previousExpVals=[0]; } - addToScore() {if (typeof this.cb === 'function') { - this.cb(this.expVal); - } - } setRndmFalse() { this.isRndm = false; } @@ -416,7 +405,7 @@ function createGrid () { for (let c = 0; c < cols; c++) { let x0 = borderWidth + c*(borderWidth + sqWidth) - (rows/2)*(2*borderWidth + sqWidth) + middle.x + Math.floor(sqWidth/3); let y0 = borderWidth + r*(borderWidth + sqWidth) - (cols/2)*(2*borderWidth + sqWidth) + middle.y + Math.floor(sqWidth/3); - let cell = new Cell(x0, y0, sqWidth, c + r*cols, addToScore); + let cell = new Cell(x0, y0, sqWidth, c + r*cols); allSquares.push(cell); } } @@ -454,7 +443,7 @@ function addRandomNumber() { let randomIdx = Math.floor( emptySquaresIdxs.length * Math.random() ); allSquares[emptySquaresIdxs[randomIdx]].setExpVal(makeRandomNumber()); allSquares[emptySquaresIdxs[randomIdx]].setRndmTrue(); - } + } } function drawGrid() { allSquares.forEach(sq => { @@ -651,9 +640,7 @@ dragger.attach(); function runGame(dir){ addToUndo(); updUndoLvlIndex(); - mover.nonEmptyCells(dir); - mover.mergeEqlCells(dir); - mover.nonEmptyCells(dir); + mover.moveAndMerge(dir); allSquares.forEach(sq => {sq.setRndmFalse();}); addRandomNumber(); drawGrid(); From d7bf20ebc7e71eff0e5afb868440c9421343535f Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Tue, 29 Mar 2022 23:38:19 +0200 Subject: [PATCH 204/253] v0.07 efficiency improvements --- apps/game1024/ChangeLog | 3 ++- apps/game1024/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/game1024/ChangeLog b/apps/game1024/ChangeLog index 8759fb428..6ec8a15fc 100644 --- a/apps/game1024/ChangeLog +++ b/apps/game1024/ChangeLog @@ -3,4 +3,5 @@ 0.03: Basic colors 0.04: Bug fix score reset after Game Over, new icon 0.05: Chevron marker on the randomly added square -0.06: Fixed issue 1609 added a message popup state handler to control unwanted screen redraw \ No newline at end of file +0.06: Fixed issue 1609 added a message popup state handler to control unwanted screen redraw +0.07: Optimized the mover algorithm for efficiency (work in progress) \ No newline at end of file diff --git a/apps/game1024/metadata.json b/apps/game1024/metadata.json index 73d7607f3..14e64347a 100644 --- a/apps/game1024/metadata.json +++ b/apps/game1024/metadata.json @@ -1,7 +1,7 @@ { "id": "game1024", "name": "1024 Game", "shortName" : "1024 Game", - "version": "0.06", + "version": "0.07", "icon": "game1024.png", "screenshots": [ {"url":"screenshot.png" } ], "readme":"README.md", From 9c86c483980ff76427675fec0050c437a5779b90 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 07:17:52 +0200 Subject: [PATCH 205/253] Update widget.js --- apps/widbt_notify/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt_notify/widget.js b/apps/widbt_notify/widget.js index 04f91a698..f1e4d372f 100644 --- a/apps/widbt_notify/widget.js +++ b/apps/widbt_notify/widget.js @@ -20,7 +20,7 @@ WIDGETS.bluetooth_notify = { Bangle.buzz(700, 1); // buzz on connection loss E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth'); - setInterval(()=>{load();}, 3000); // clear message + // setInterval(()=>{load();}, 3000); // clear message - this will reload the widget, resetting 'warningEnabled'. WIDGETS.bluetooth_notify.warningEnabled = 0; setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. From a59579476b914f03cb397c0cedb5f51d25476cfc Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 07:19:58 +0200 Subject: [PATCH 206/253] Revert "Update widget.js" This reverts commit be3d00e9746528d82564d9d4f3be78d4e216d01b. --- apps/widbt/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 6fa7f3b7a..5d752b575 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -19,7 +19,7 @@ WIDGETS.bluetooth = { if(WIDGETS.bluetooth.warningEnabled == 1){ Bangle.buzz(700, 1); // buzz on connection loss - E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth'); + E.showMessage(/*LANG*/"Connection\nlost.","Bluetooth"); setInterval(()=>{load();}, 3000); // clear message WIDGETS.bluetooth.warningEnabled = 0; From 3986899c8b305b5dbff421d0cb43d65602e9d338 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 07:20:11 +0200 Subject: [PATCH 207/253] Revert "Update widget.js" This reverts commit deb18b0ef5cc8138f17a00a356daa38f64fb67db. --- apps/widbt/widget.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 5d752b575..58b4d4b4a 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -18,10 +18,7 @@ WIDGETS.bluetooth = { disconnect: function() { if(WIDGETS.bluetooth.warningEnabled == 1){ Bangle.buzz(700, 1); // buzz on connection loss - - E.showMessage(/*LANG*/"Connection\nlost.","Bluetooth"); - setInterval(()=>{load();}, 3000); // clear message - + E.showMessage("Connection\nlost.","Bluetooth"); WIDGETS.bluetooth.warningEnabled = 0; setTimeout('WIDGETS.bluetooth.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. } From 85a0c4100d954793ec5581840da16e07a64c5500 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 07:25:49 +0200 Subject: [PATCH 208/253] Restored widbt I restored the widbt code and made a separate widget widbt_notify. --- apps/widbt/ChangeLog | 3 --- apps/widbt/metadata.json | 2 +- apps/widbt/widget.js | 42 ++++++++++++---------------------------- 3 files changed, 13 insertions(+), 34 deletions(-) diff --git a/apps/widbt/ChangeLog b/apps/widbt/ChangeLog index b5a50210e..4c2132122 100644 --- a/apps/widbt/ChangeLog +++ b/apps/widbt/ChangeLog @@ -5,6 +5,3 @@ 0.06: Tweaking colors for dark/light themes and low bpp screens 0.07: Memory usage improvements 0.08: Disable LCD on, on bluetooth status change -0.09: Vibrate on connection loss -0.10: Bug fix -0.11: Avoid too many notifications. Change disconnected colour to red. diff --git a/apps/widbt/metadata.json b/apps/widbt/metadata.json index 6e705584e..e2d5082a5 100644 --- a/apps/widbt/metadata.json +++ b/apps/widbt/metadata.json @@ -1,7 +1,7 @@ { "id": "widbt", "name": "Bluetooth Widget", - "version": "0.11", + "version": "0.08", "description": "Show the current Bluetooth connection status in the top right of the clock", "icon": "widget.png", "type": "widget", diff --git a/apps/widbt/widget.js b/apps/widbt/widget.js index 58b4d4b4a..c7ef8c0ad 100644 --- a/apps/widbt/widget.js +++ b/apps/widbt/widget.js @@ -1,30 +1,12 @@ -WIDGETS.bluetooth = { - area: "tr", - width: 15, - warningEnabled: 1, - draw: function() { - g.reset(); - if (NRF.getSecurityStatus().connected) { - g.setColor((g.getBPP() > 8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); - } else { - // g.setColor(g.theme.dark ? "#666" : "#999"); - g.setColor("#f00"); // red is easier to distinguish from blue - } - g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y); - }, - connect: function() { - WIDGETS.bluetooth.draw(); - }, - disconnect: function() { - if(WIDGETS.bluetooth.warningEnabled == 1){ - Bangle.buzz(700, 1); // buzz on connection loss - E.showMessage("Connection\nlost.","Bluetooth"); - WIDGETS.bluetooth.warningEnabled = 0; - setTimeout('WIDGETS.bluetooth.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. - } - WIDGETS.bluetooth.draw(); - } -}; - -NRF.on('connect', WIDGETS.bluetooth.connect); -NRF.on('disconnect', WIDGETS.bluetooth.disconnect); +WIDGETS["bluetooth"]={area:"tr",width:15,draw:function() { + g.reset(); + if (NRF.getSecurityStatus().connected) + g.setColor((g.getBPP()>8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); + else + g.setColor(g.theme.dark ? "#666" : "#999"); + g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="),2+this.x,2+this.y); +},changed:function() { + WIDGETS["bluetooth"].draw(); +}}; +NRF.on('connect',WIDGETS["bluetooth"].changed); +NRF.on('disconnect',WIDGETS["bluetooth"].changed); From b5e66340045b3d6f6c32c3d912921917f69ef731 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 10:42:00 +0200 Subject: [PATCH 209/253] bugfix settings.json Read settings from the wron file. --- apps/messages/lib.js | 2 +- apps/widbt_notify/widget.js | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index d7c95570b..c517fde73 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -58,7 +58,7 @@ exports.pushMessage = function(event) { var loadMessages = Bangle.CLOCK || event.important; // first, buzz var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; - var unlockWatch = (require('Storage').readJSON('setting.json',1)||{}).unlockWatch; + var unlockWatch = (require('Storage').readJSON('messages.setting.json',1)||{}).unlockWatch; if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages){ WIDGETS.messages.buzz(); if(unlockWatch != false){ diff --git a/apps/widbt_notify/widget.js b/apps/widbt_notify/widget.js index f1e4d372f..d6bad5dc9 100644 --- a/apps/widbt_notify/widget.js +++ b/apps/widbt_notify/widget.js @@ -17,13 +17,16 @@ WIDGETS.bluetooth_notify = { }, disconnect: function() { if(WIDGETS.bluetooth_notify.warningEnabled == 1){ - Bangle.buzz(700, 1); // buzz on connection loss - E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth'); // setInterval(()=>{load();}, 3000); // clear message - this will reload the widget, resetting 'warningEnabled'. WIDGETS.bluetooth_notify.warningEnabled = 0; setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. + + var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; + if(!quiet){ + Bangle.buzz(700, 1); // buzz on connection loss + } } WIDGETS.bluetooth_notify.draw(); } From 15a6d07e067a5d8378f795e5a81b6896bd0bd8b0 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 30 Mar 2022 11:10:15 +0100 Subject: [PATCH 210/253] 0.47: Add polyfill for setUI with an object as an argument (fix regression for 2v12 devices after Layout module changed) --- apps/boot/ChangeLog | 1 + apps/boot/bootupdate.js | 60 ++++++++++------------------------------- apps/boot/metadata.json | 2 +- 3 files changed, 16 insertions(+), 47 deletions(-) diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 87b5f7def..e3f492d3b 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -50,3 +50,4 @@ 0.44: Write .boot0 without ever having it all in RAM (fix Bangle.js 1 issues with BTHRM) 0.45: Fix 0.44 regression (auto-add semi-colon between each boot code chunk) 0.46: Fix no clock found error on Bangle.js 2 +0.47: Add polyfill for setUI with an object as an argument (fix regression for 2v12 devices after Layout module changed) diff --git a/apps/boot/bootupdate.js b/apps/boot/bootupdate.js index c2ed5458d..46391d874 100644 --- a/apps/boot/bootupdate.js +++ b/apps/boot/bootupdate.js @@ -97,52 +97,20 @@ delete g.theme; // deleting stops us getting confused by our own decl. builtins if (!g.theme) { boot += `g.theme={fg:-1,bg:0,fg2:-1,bg2:7,fgH:-1,bgH:0x02F7,dark:true};\n`; } -delete Bangle.setUI; // deleting stops us getting confused by our own decl. builtins can't be deleted -if (!Bangle.setUI) { // assume this is just for F18 - Q3 should already have it - boot += `Bangle.setUI=function(mode, cb) { -if (Bangle.btnWatches) { - Bangle.btnWatches.forEach(clearWatch); - delete Bangle.btnWatches; -} -if (Bangle.swipeHandler) { - Bangle.removeListener("swipe", Bangle.swipeHandler); - delete Bangle.swipeHandler; -} -if (Bangle.touchHandler) { - Bangle.removeListener("touch", Bangle.touchHandler); - delete Bangle.touchHandler; -} -if (!mode) return; -else if (mode=="updown") { - Bangle.btnWatches = [ - setWatch(function() { cb(-1); }, BTN1, {repeat:1}), - setWatch(function() { cb(1); }, BTN3, {repeat:1}), - setWatch(function() { cb(); }, BTN2, {repeat:1}) - ]; -} else if (mode=="leftright") { - Bangle.btnWatches = [ - setWatch(function() { cb(-1); }, BTN1, {repeat:1}), - setWatch(function() { cb(1); }, BTN3, {repeat:1}), - setWatch(function() { cb(); }, BTN2, {repeat:1}) - ]; - Bangle.swipeHandler = d => {cb(d);}; - Bangle.on("swipe", Bangle.swipeHandler); - Bangle.touchHandler = d => {cb();}; - Bangle.on("touch", Bangle.touchHandler); -} else if (mode=="clock") { - Bangle.CLOCK=1; - Bangle.btnWatches = [ - setWatch(Bangle.showLauncher, BTN2, {repeat:1,edge:"falling"}) - ]; -} else if (mode=="clockupdown") { - Bangle.CLOCK=1; - Bangle.btnWatches = [ - setWatch(function() { cb(-1); }, BTN1, {repeat:1}), - setWatch(function() { cb(1); }, BTN3, {repeat:1}), - setWatch(Bangle.showLauncher, BTN2, {repeat:1,edge:"falling"}) - ]; -} else - throw new Error("Unknown UI mode"); +try { + Bangle.setUI({}); // In 2v12.xx we added the option for mode to be an object - for 2v12 and earlier, add a fix if it fails with an object supplied +} catch(e) { + boot += `Bangle._setUI = Bangle.setUI; +Bangle.setUI=function(mode, cb) { + if (Bangle.uiRemove) { + Bangle.uiRemove(); + delete Bangle.uiRemove; + } + if ("object"==typeof mode) { + // TODO: handle mode.back? + mode = mode.mode; + } + Bangle._setUI(mode, cb); };\n`; } delete E.showScroller; // deleting stops us getting confused by our own decl. builtins can't be deleted diff --git a/apps/boot/metadata.json b/apps/boot/metadata.json index 11884576f..d1bf2edde 100644 --- a/apps/boot/metadata.json +++ b/apps/boot/metadata.json @@ -1,7 +1,7 @@ { "id": "boot", "name": "Bootloader", - "version": "0.46", + "version": "0.47", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "icon": "bootloader.png", "type": "bootloader", From a09df566f259955024bd2e7e6441edad9afe3dd2 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 30 Mar 2022 14:36:52 +0100 Subject: [PATCH 211/253] ignore backup files of length 0, fix #1593 --- backup.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backup.js b/backup.js index 75e236049..8a894666e 100644 --- a/backup.js +++ b/backup.js @@ -79,7 +79,9 @@ function bangleUpload() { .then(() => file.async("string")) .then(data => { console.log("decoded", path); - if (path.startsWith(BACKUP_STORAGEFILE_DIR)) { + if (data.length==0) { // https://github.com/espruino/BangleApps/issues/1593 + console.log("Can't restore files of length 0, ignoring "+path); + } else if (path.startsWith(BACKUP_STORAGEFILE_DIR)) { path = path.substr(BACKUP_STORAGEFILE_DIR.length+1); cmds += AppInfo.getStorageFileUploadCommands(path, data)+"\n"; } else if (!path.includes("/")) { From 48efab699d1e4aed4313b033d2707b2e491e85e9 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 30 Mar 2022 15:11:14 +0100 Subject: [PATCH 212/253] Show distance more accurately in conjunction with new locale app (fix #1523) Also slightly more memory efficient locale module --- apps/gpsrec/ChangeLog | 3 ++- apps/gpsrec/app.js | 2 +- apps/gpsrec/metadata.json | 2 +- apps/locale/ChangeLog | 4 +++- apps/locale/locale.html | 26 +++++++++++++------------- apps/locale/metadata.json | 2 +- apps/recorder/ChangeLog | 3 ++- apps/recorder/app.js | 2 +- apps/recorder/metadata.json | 2 +- modules/exstats.js | 4 ++-- 10 files changed, 27 insertions(+), 23 deletions(-) diff --git a/apps/gpsrec/ChangeLog b/apps/gpsrec/ChangeLog index 365405846..f923739f0 100644 --- a/apps/gpsrec/ChangeLog +++ b/apps/gpsrec/ChangeLog @@ -28,4 +28,5 @@ 0.24: Better support for Bangle.js 2, avoid widget area for Graphs, smooth graphs more 0.25: Fix issue where if Bangle.js 2 got a GPS fix but no reported time, errors could be caused by the widget (fix #935) 0.26: Multiple bugfixes -0.27: Map drawing with light theme (fix #1023) +0.27: Map drawing with light theme (fix #1023) +0.28: Show distance more accurately in conjunction with new locale app (fix #1523) diff --git a/apps/gpsrec/app.js b/apps/gpsrec/app.js index 833a816ea..527eb780d 100644 --- a/apps/gpsrec/app.js +++ b/apps/gpsrec/app.js @@ -248,7 +248,7 @@ function plotTrack(info) { g.fillCircle(ox,oy,5); if (info.qOSTM) g.setColor(0, 0, 0); else g.setColor(g.theme.fg); - g.drawString(require("locale").distance(dist),g.getWidth() / 2, g.getHeight() - 20); + g.drawString(require("locale").distance(dist,2),g.getWidth() / 2, g.getHeight() - 20); g.setFont("6x8",2); g.setFontAlign(0,0,3); g.drawString("Back",g.getWidth() - 10, g.getHeight()/2); diff --git a/apps/gpsrec/metadata.json b/apps/gpsrec/metadata.json index 088b8c741..8f4736066 100644 --- a/apps/gpsrec/metadata.json +++ b/apps/gpsrec/metadata.json @@ -1,7 +1,7 @@ { "id": "gpsrec", "name": "GPS Recorder", - "version": "0.27", + "version": "0.28", "description": "Application that allows you to record a GPS track. Can run in background", "icon": "app.png", "tags": "tool,outdoors,gps,widget", diff --git a/apps/locale/ChangeLog b/apps/locale/ChangeLog index 2dbb4febb..3354a57c1 100644 --- a/apps/locale/ChangeLog +++ b/apps/locale/ChangeLog @@ -15,4 +15,6 @@ 0.13: Now use shorter de_DE date format to more closely match other languages for size 0.14: Added some first translations for Messages in nl_NL 0.15: Fixed sv_SE formatting, long date does not work well for Bangle.js2 - Added Swedish localisation with English text \ No newline at end of file + Added Swedish localisation with English text +0.16: Remove global variables that used RAM + Add second 'dp' argument for decimal places in distance/speed/temp (fix #1523) diff --git a/apps/locale/locale.html b/apps/locale/locale.html index b23225d5f..b58b4a297 100644 --- a/apps/locale/locale.html +++ b/apps/locale/locale.html @@ -158,10 +158,10 @@ exports = { name : "en_GB", currencySym:"£", "%HH": "('0'+getHours(d)).slice(-2)", "%MM": "('0'+d.getMinutes()).slice(-2)", "%SS": "('0'+d.getSeconds()).slice(-2)", - "%A": "day.split(',')[d.getDay()]", - "%a": "day.split(',')[d.getDay() + 7]", - "%B": "month.split(',')[d.getMonth()]", - "%b": "month.split(',')[d.getMonth() + 12]", + "%A": `${js(locale.day)}.split(',')[d.getDay()]`, + "%a": `${js(locale.abday)}.split(',')[d.getDay()]`, + "%B": `${js(locale.month)}.split(',')[d.getMonth()]`, + "%b": `${js(locale.abmonth)}.split(',')[d.getMonth() + 12]`, "%p": `d.getHours()<12?${js(locale.ampm[0].toUpperCase())}:${js(locale.ampm[1].toUpperCase())}`, "%P": `d.getHours()<12?${js(locale.ampm[0].toLowerCase())}:${js(locale.ampm[1].toLowerCase())}` }; @@ -182,10 +182,10 @@ exports = { name : "en_GB", currencySym:"£", var temperature = locale.temperature=='°F' ? '(t*9/5)+32' : 't'; var localeModule = ` -var day = ${js(locale.day + ',' + locale.abday)}; -var month = ${js(locale.month + ',' + locale.abmonth)}; -function round(n) { - return n < 10 ? Math.round(n * 10) / 10 : Math.round(n); +function round(n, dp) { + if (dp===undefined) dp=0; + var p = Math.min(dp,dp - Math.floor(Math.log(n)/Math.log(10))); + return n.toFixed(p); } var is12; function getHours(d) { @@ -197,8 +197,8 @@ function getHours(d) { exports = { name: ${js(locale.lang)}, currencySym: ${js(locale.currency_symbol)}, - dow: (d,short) => day.split(',')[d.getDay() + (short ? 7 : 0)], - month: (d,short) => month.split(',')[d.getMonth() + (short ? 12 : 0)], + dow: (d,short) => ${js(locale.day + ',' + locale.abday)}.split(',')[d.getDay() + (short ? 7 : 0)], + month: (d,short) => ${js(locale.month + ',' + locale.abmonth)}.split(',')[d.getMonth() + (short ? 12 : 0)], number: (n, dec) => { if (dec == null) dec = 2; var w = n.toFixed(dec), @@ -215,9 +215,9 @@ exports = { return s.substr(0, i + 3) + r + (d ? '${locale.decimal_point}' + d: ''); }, currency: n => ${currency}, - distance: n => n < ${distanceUnits[locale.distance[1]]} ? round(${unitConv(distanceUnits[locale.distance[0]])}) + ${js(locale.distance[0])} : round(${unitConv(distanceUnits[locale.distance[1]])}) + ${js(locale.distance[1])}, - speed: n => round(${unitConv(speedUnits[locale.speed])}) + ${js(locale.speed)}, - temp: t => Math.round(${temperature}) + ${js(locale.temperature)}, + distance: (n,dp) => n < ${distanceUnits[locale.distance[1]]} ? round(${unitConv(distanceUnits[locale.distance[0]])},dp) + ${js(locale.distance[0])} : round(${unitConv(distanceUnits[locale.distance[1]])},dp) + ${js(locale.distance[1])}, + speed: (n,dp) => round(${unitConv(speedUnits[locale.speed])},dp) + ${js(locale.speed)}, + temp: (t,dp) => round(${temperature},dp) + ${js(locale.temperature)}, translate: s => ${locale.trans?`{var t=${js(locale.trans)};s=''+s;return t[s]||t[s.toLowerCase()]||s;}`:`s`}, date: (d,short) => short ? \`${dateS}\` : \`${dateN}\`, time: (d,short) => short ? \`${timeS}\` : \`${timeN}\`, diff --git a/apps/locale/metadata.json b/apps/locale/metadata.json index c8908c7a7..20f1f72b8 100644 --- a/apps/locale/metadata.json +++ b/apps/locale/metadata.json @@ -1,7 +1,7 @@ { "id": "locale", "name": "Languages", - "version": "0.15", + "version": "0.16", "description": "Translations for different countries", "icon": "locale.png", "type": "locale", diff --git a/apps/recorder/ChangeLog b/apps/recorder/ChangeLog index e9877808c..877b1354a 100644 --- a/apps/recorder/ChangeLog +++ b/apps/recorder/ChangeLog @@ -17,4 +17,5 @@ 0.11: Fix KML and GPX export when there is no GPS data 0.12: Fix 'Back' label positioning on track/graph display, make translateable 0.13: Fix for when widget is used before app -0.14: Remove unneeded variable assignment \ No newline at end of file +0.14: Remove unneeded variable assignment +0.15: Show distance more accurately in conjunction with new locale app (fix #1523) diff --git a/apps/recorder/app.js b/apps/recorder/app.js index 99252e0e2..fb3dfab4f 100644 --- a/apps/recorder/app.js +++ b/apps/recorder/app.js @@ -307,7 +307,7 @@ function viewTrack(filename, info) { g.fillCircle(ox,oy,5); if (info.qOSTM) g.setColor("#000"); else g.setColor(g.theme.fg); - g.drawString(require("locale").distance(dist),g.getWidth() / 2, g.getHeight() - 20); + g.drawString(require("locale").distance(dist,2),g.getWidth() / 2, g.getHeight() - 20); g.setFont("6x8",2); g.setFontAlign(0,0,3); var isBTN3 = "BTN3" in global; diff --git a/apps/recorder/metadata.json b/apps/recorder/metadata.json index d715af38d..4146e92be 100644 --- a/apps/recorder/metadata.json +++ b/apps/recorder/metadata.json @@ -2,7 +2,7 @@ "id": "recorder", "name": "Recorder", "shortName": "Recorder", - "version": "0.14", + "version": "0.15", "description": "Record GPS position, heart rate and more in the background, then download to your PC.", "icon": "app.png", "tags": "tool,outdoors,gps,widget", diff --git a/modules/exstats.js b/modules/exstats.js index 056dc9f0f..5d7cf0c2b 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -212,7 +212,7 @@ exports.getStats = function(statIDs, options) { stats["dist"]={ title : "Dist", getValue : function() { return state.distance; }, - getString : function() { return require("locale").distance(state.distance); }, + getString : function() { return require("locale").distance(state.distance,2); }, }; } if (statIDs.includes("step")) { @@ -251,7 +251,7 @@ exports.getStats = function(statIDs, options) { stats["speed"]={ title : "Speed", getValue : function() { return state.curSpeed*3.6; }, // in kph - getString : function() { return require("locale").speed(state.curSpeed*3.6); }, + getString : function() { return require("locale").speed(state.curSpeed*3.6,2); }, }; } if (statIDs.includes("caden")) { From 00f1de401acba484ee4e3429e57f9a494718aa82 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 30 Mar 2022 15:55:31 +0100 Subject: [PATCH 213/253] Add 'reinstall apps' button --- index.html | 7 ++++--- loader.js | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index bd8ddea5a..7a94f684a 100644 --- a/index.html +++ b/index.html @@ -128,9 +128,10 @@

Utilities

- + + -

+

Settings

@@ -179,6 +180,6 @@ - + diff --git a/loader.js b/loader.js index 82d6172cb..c4553940b 100644 --- a/loader.js +++ b/loader.js @@ -155,6 +155,29 @@ window.addEventListener('load', (event) => { }); }); + // Button to install all default apps in one go + document.getElementById("reinstallall").addEventListener("click",event=>{ + var promise = showPrompt("Reinstall","Really re-install all apps?").then(() => { + getInstalledApps().then(installedapps => { + console.log(installedapps); + var promise = Promise.resolve(); + installedapps.forEach(app => { + if (app.custom) + return console.log(`Ignoring ${app.id} as customised`); + var oldApp = app; + app = appJSON.find(a => a.id==oldApp.id); + if (!app) + return console.log(`Ignoring ${oldApp.id} as not found`); + promise = promise.then(() => updateApp(app)); + }); + return promise; + }).catch(err=>{ + Progress.hide({sticky:true}); + showToast("App re-install failed, "+err,"error"); + }); + }); + }); + // Button to install all default apps in one go document.getElementById("installdefault").addEventListener("click",event=>{ getInstalledApps().then(() => { From c95067521210fbc31a7d1d4beed7c6ef76c5db05 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 30 Mar 2022 15:56:35 +0100 Subject: [PATCH 214/253] fix upload progress bar regression --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 27c7db603..7b189b5aa 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 27c7db6035832837ca3909ea52939f60803df72f +Subproject commit 7b189b5aa85e6d85c8e0fd8b6db16f3d69387de0 From 7c97c138b182decfed7b33e7a178d81039ba260a Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 30 Mar 2022 16:10:32 +0100 Subject: [PATCH 215/253] Disable App Loader "Update App Button" for customizable apps. (fix https://github.com/espruino/BangleApps/issues/1383) --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 7b189b5aa..e9097fa68 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 7b189b5aa85e6d85c8e0fd8b6db16f3d69387de0 +Subproject commit e9097fa680182069a5814c3e566a0bcbcb5e72a1 From 5254f20bb660d0ae2737ad720c1b9dbb5d18beed Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 17:43:46 +0200 Subject: [PATCH 216/253] Redrawing the current clock, if a 'draw()' function exists. --- apps/widbt_notify/widget.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/widbt_notify/widget.js b/apps/widbt_notify/widget.js index d6bad5dc9..0c0a53bba 100644 --- a/apps/widbt_notify/widget.js +++ b/apps/widbt_notify/widget.js @@ -12,16 +12,26 @@ WIDGETS.bluetooth_notify = { } g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y); }, + + redrawCurrentApp: function(){ + if(typeof(draw)=='function'){ + draw(); + }else{ + load(); // fallback. This might reset some variables + } + }, + connect: function() { WIDGETS.bluetooth_notify.draw(); }, + disconnect: function() { if(WIDGETS.bluetooth_notify.warningEnabled == 1){ E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth'); - // setInterval(()=>{load();}, 3000); // clear message - this will reload the widget, resetting 'warningEnabled'. + setInterval(WIDGETS.bluetooth_notify.redrawCurrentApp()=>{;}, 3000); // clear message WIDGETS.bluetooth_notify.warningEnabled = 0; - setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // re-notify only after 30 seconds. + setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // don't buzz for the next 30 seconds. var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; if(!quiet){ From 50e38126fba23c3893e3b62036f4be87b132b24c Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 17:45:58 +0200 Subject: [PATCH 217/253] typos --- apps/widbt_notify/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widbt_notify/widget.js b/apps/widbt_notify/widget.js index 0c0a53bba..47765f3d0 100644 --- a/apps/widbt_notify/widget.js +++ b/apps/widbt_notify/widget.js @@ -28,7 +28,7 @@ WIDGETS.bluetooth_notify = { disconnect: function() { if(WIDGETS.bluetooth_notify.warningEnabled == 1){ E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth'); - setInterval(WIDGETS.bluetooth_notify.redrawCurrentApp()=>{;}, 3000); // clear message + setInterval(()=>{WIDGETS.bluetooth_notify.redrawCurrentApp();}, 3000); // clear message - this will reload the widget, resetting 'warningEnabled'. WIDGETS.bluetooth_notify.warningEnabled = 0; setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // don't buzz for the next 30 seconds. From 2e05c57259eb4dae4568912c4a84c3bb818a3354 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Wed, 30 Mar 2022 18:03:54 +0200 Subject: [PATCH 218/253] typo fixed --- apps/messages/lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messages/lib.js b/apps/messages/lib.js index c517fde73..7d49d4c64 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -58,7 +58,7 @@ exports.pushMessage = function(event) { var loadMessages = Bangle.CLOCK || event.important; // first, buzz var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet; - var unlockWatch = (require('Storage').readJSON('messages.setting.json',1)||{}).unlockWatch; + var unlockWatch = (require('Storage').readJSON('messages.settings.json',1)||{}).unlockWatch; if (!quiet && loadMessages && global.WIDGETS && WIDGETS.messages){ WIDGETS.messages.buzz(); if(unlockWatch != false){ From d356735bf2f50e7b7ccce8c9193c9639256c391f Mon Sep 17 00:00:00 2001 From: sir-indy <53864146+sir-indy@users.noreply.github.com> Date: Wed, 30 Mar 2022 20:52:13 +0100 Subject: [PATCH 219/253] Update pebble.app.js --- apps/pebble/pebble.app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 80243c890..062592e47 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -10,6 +10,7 @@ Graphics.prototype.setFontLECO1976Regular22 = function(scale) { const SETTINGS_FILE = "pebble.json"; let settings; +let theme; function loadSettings() { settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green', 'theme':'System', 'showlock':false}; From 1642dbc93a937a8f73f05f4fa3b9c824c6bafb36 Mon Sep 17 00:00:00 2001 From: KungPhoo Date: Thu, 31 Mar 2022 07:37:43 +0200 Subject: [PATCH 220/253] reset graphics before drawing --- apps/glbasic/glbasic.app.js | 237 ++++++++++++++++++------------------ 1 file changed, 119 insertions(+), 118 deletions(-) diff --git a/apps/glbasic/glbasic.app.js b/apps/glbasic/glbasic.app.js index b2b6f45ed..ff7837ada 100644 --- a/apps/glbasic/glbasic.app.js +++ b/apps/glbasic/glbasic.app.js @@ -1,176 +1,177 @@ -Graphics.prototype.setFontLECO1976Regular42 = function(scale) { - // Actual height 42 (41 - 0) - g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60 + (scale << 8) + (1 << 16)); +Graphics.prototype.setFontLECO1976Regular42 = function (scale) { + // Actual height 42 (41 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60 + (scale << 8) + (1 << 16)); }; -Graphics.prototype.setFontLECO1976Regular22 = function(scale) { - // Actual height 22 (21 - 0) - g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22 + (scale << 8) + (1 << 16)); +Graphics.prototype.setFontLECO1976Regular22 = function (scale) { + // Actual height 22 (21 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22 + (scale << 8) + (1 << 16)); }; require("Font7x11Numeric7Seg").add(Graphics); -//the following 2 sections are used from waveclk to schedule minutely updates +// the following 2 sections are used from waveclk to schedule minutely updates // timeout used to update every minute var drawTimeout; // schedule a draw for the next minute function queueDraw() { - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = setTimeout(function() { - drawTimeout = undefined; - draw(); - }, 60000 - (Date.now() % 60000)); + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function () { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); } function drawBackground() { - g.setBgColor(0, 0, 0); - g.setColor(1, 1, 1); - g.clear(); + g.setBgColor(0, 0, 0); + g.setColor(1, 1, 1); + g.clear(); } function digit(num) { - return String.fromCharCode(num + 48); + return String.fromCharCode(num + 48); } function timeString(h, m) { - return digit(h / 10) + digit(h % 10) + ":" + digit(m / 10) + digit(m % 10); + return digit(h / 10) + digit(h % 10) + ":" + digit(m / 10) + digit(m % 10); } function dayString(w) { - return digit(w / 10) + digit(w % 10); + return digit(w / 10) + digit(w % 10); } function getSteps() { - if (WIDGETS.wpedom !== undefined) { - return WIDGETS.wpedom.getSteps(); - } - return '????'; + if (WIDGETS.wpedom !== undefined) { + return WIDGETS.wpedom.getSteps(); + } + return '????'; } /** * draws calender week view (-1,0,1) for given date */ function drawCal() { - d = /*this.date ? this.date : */ new Date(); + d = /*this.date ? this.date : */ new Date(); - const DAY_NAME_FONT_SIZE = 10; - const CAL_Y = g.getHeight() - 44; // Bangle.appRect.y+this.DATE_FONT_SIZE()+10+this.TIME_FONT_SIZE()+3; - const CAL_AREA_H = 44; // g.getHeight()-CAL_Y+24; //+24: top widgtes only - const CELL_W = g.getWidth() / 7; //cell width - const CELL_H = (CAL_AREA_H - DAY_NAME_FONT_SIZE) / 3; //cell heigth - const DAY_NUM_FONT_SIZE = Math.min(CELL_H + 3, 15); //size down, max 15 + const DAY_NAME_FONT_SIZE = 10; + const CAL_Y = g.getHeight() - 44; // Bangle.appRect.y+this.DATE_FONT_SIZE()+10+this.TIME_FONT_SIZE()+3; + const CAL_AREA_H = 44; // g.getHeight()-CAL_Y+24; //+24: top widgtes only + const CELL_W = g.getWidth() / 7; //cell width + const CELL_H = (CAL_AREA_H - DAY_NAME_FONT_SIZE) / 3; //cell heigth + const DAY_NUM_FONT_SIZE = Math.min(CELL_H + 3, 15); //size down, max 15 - const wdStrt = 1; + const wdStrt = 1; - const ABR_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - const IS_SUNDAY = [1, 0, 0, 0, 0, 1, 1]; // what days are sunday? - const nrgb = ["#000", "#FFF", "#F00", "#0F0", "#00F", "#FF0"]; //fg, r ,g , b - const suClr = 5; // sunday color fg - const tdyMrkClr = 3; // today bk - const tdyNumClr = 0; // today fg + const ABR_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + const IS_SUNDAY = [1, 0, 0, 0, 0, 1, 1]; // what days are sunday? + const nrgb = ["#000", "#FFF", "#F00", "#0F0", "#00F", "#FF0"]; //fg, r ,g , b + const suClr = 5; // sunday color fg + const tdyMrkClr = 3; // today bk + const tdyNumClr = 0; // today fg - g.setFont("Vector", DAY_NAME_FONT_SIZE+3); - g.setColor(nrgb[1]); - g.setFontAlign(-1, -1); - // g.clearRect(Bangle.appRect.x, CAL_Y, Bangle.appRect.x2, CAL_Y+CAL_AREA_H); + g.setFont("Vector", DAY_NAME_FONT_SIZE + 3); + g.setColor(nrgb[1]); + g.setFontAlign(-1, -1); + // g.clearRect(Bangle.appRect.x, CAL_Y, Bangle.appRect.x2, CAL_Y+CAL_AREA_H); - //draw grid & Headline - const dNames = ABR_DAY.map((a) => a.length <= 2 ? a : a.substr(0, 2)); //force shrt 2 - for (var dNo = 0; dNo < dNames.length; dNo++) { - const dIdx = wdStrt >= 0 ? ((wdStrt + dNo) % 7) : ((dNo + d.getDay() + 4) % 7); - const dName = dNames[dIdx]; - // if(dNo>0) { g.drawLine(dNo*CELL_W, CAL_Y, dNo*CELL_W, CAL_Y+CAL_AREA_H-1);} + //draw grid & Headline + const dNames = ABR_DAY.map((a) => a.length <= 2 ? a : a.substr(0, 2)); //force shrt 2 + for (var dNo = 0; dNo < dNames.length; dNo++) { + const dIdx = wdStrt >= 0 ? ((wdStrt + dNo) % 7) : ((dNo + d.getDay() + 4) % 7); + const dName = dNames[dIdx]; + // if(dNo>0) { g.drawLine(dNo*CELL_W, CAL_Y, dNo*CELL_W, CAL_Y+CAL_AREA_H-1);} - var colTx = 0; - var colBk = 1; - if (IS_SUNDAY[dIdx]) { - colBk = suClr; + var colTx = 0; + var colBk = 1; + if (IS_SUNDAY[dIdx]) { + colBk = suClr; + } + + g.setColor(nrgb[colBk]); + g.fillRect(dNo * CELL_W, CAL_Y, dNo * CELL_W + CELL_W, CAL_Y + DAY_NAME_FONT_SIZE - 1); + g.setColor(nrgb[colTx]); + g.drawString(dName, dNo * CELL_W + (CELL_W - g.stringWidth(dName)) / 2 + 2, CAL_Y - 1); + // g.setColor(nrgb[clTxt]); } + g.setColor(nrgb[1]); + var nextY = CAL_Y + DAY_NAME_FONT_SIZE; - g.setColor(nrgb[colBk]); - g.fillRect(dNo * CELL_W, CAL_Y, dNo * CELL_W + CELL_W, CAL_Y + DAY_NAME_FONT_SIZE-1); - g.setColor(nrgb[colTx]); - g.drawString(dName, dNo * CELL_W + (CELL_W - g.stringWidth(dName)) / 2 + 2, CAL_Y-1); - // g.setColor(nrgb[clTxt]); - } - g.setColor(nrgb[1]); - var nextY = CAL_Y + DAY_NAME_FONT_SIZE; + // horizontal lines + // for(i=0; i<3; i++){ const y=nextY+i*CELL_H; g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); } - // horizontal lines - // for(i=0; i<3; i++){ const y=nextY+i*CELL_H; g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); } + g.setFont("Vector", DAY_NUM_FONT_SIZE); - g.setFont("Vector", DAY_NUM_FONT_SIZE); + g.setFont("7x11Numeric7Seg", 1); - g.setFont("7x11Numeric7Seg", 1); - - //write days - const tdyDate = d.getDate(); - const days = wdStrt >= 0 ? 7 + ((7 + d.getDay() - wdStrt) % 7) : 10; //start day (week before=7 days + days in this week realtive to week start) or fixed 7+3 days - var rD = new Date(d.getTime()); - rD.setDate(rD.getDate() - days); - var rDate = rD.getDate(); - for (var y = 0; y < 3; y++) { - for (var x = 0; x < dNames.length; x++) { - if (rDate === tdyDate) { //today - g.setColor(nrgb[tdyMrkClr]); //today marker color or fg color + //write days + const tdyDate = d.getDate(); + const days = wdStrt >= 0 ? 7 + ((7 + d.getDay() - wdStrt) % 7) : 10; //start day (week before=7 days + days in this week realtive to week start) or fixed 7+3 days + var rD = new Date(d.getTime()); + rD.setDate(rD.getDate() - days); + var rDate = rD.getDate(); + for (var y = 0; y < 3; y++) { + for (var x = 0; x < dNames.length; x++) { + if (rDate === tdyDate) { //today + g.setColor(nrgb[tdyMrkClr]); //today marker color or fg color - // rectangle - g.fillRect(x * CELL_W, nextY + CELL_H-1, x * CELL_W + CELL_W, nextY + CELL_H + CELL_H - 1); - g.setColor(nrgb[tdyNumClr]); //today color or fg color + // rectangle + g.fillRect(x * CELL_W, nextY + CELL_H - 1, x * CELL_W + CELL_W, nextY + CELL_H + CELL_H - 1); + g.setColor(nrgb[tdyNumClr]); //today color or fg color - // simulate "bold" - g.drawString(rDate, 1+ x * CELL_W + ((CELL_W - g.stringWidth(rDate)) / 2) + 2, nextY + ((CELL_H - DAY_NUM_FONT_SIZE + 2) / 2) + (CELL_H * y)); + // simulate "bold" + g.drawString(rDate, 1 + x * CELL_W + ((CELL_W - g.stringWidth(rDate)) / 2) + 2, nextY + ((CELL_H - DAY_NUM_FONT_SIZE + 2) / 2) + (CELL_H * y)); - } else if (IS_SUNDAY[rD.getDay()]) { //sundays - g.setColor(nrgb[suClr]); - } else { //default - g.setColor(nrgb[1]); - } - g.drawString(rDate, x * CELL_W + ((CELL_W - g.stringWidth(rDate)) / 2) + 2, nextY + ((CELL_H - DAY_NUM_FONT_SIZE + 2) / 2) + (CELL_H * y)); - rD.setDate(rDate + 1); - rDate = rD.getDate(); + } else if (IS_SUNDAY[rD.getDay()]) { //sundays + g.setColor(nrgb[suClr]); + } else { //default + g.setColor(nrgb[1]); + } + g.drawString(rDate, x * CELL_W + ((CELL_W - g.stringWidth(rDate)) / 2) + 2, nextY + ((CELL_H - DAY_NUM_FONT_SIZE + 2) / 2) + (CELL_H * y)); + rD.setDate(rDate + 1); + rDate = rD.getDate(); + } } - } } function draw() { - drawBackground(); - var date = new Date(); - var h = date.getHours(), - m = date.getMinutes(); - var d = date.getDate(), - w = date.getDay(); // d=1..31; w=0..6 + g.reset(); + drawBackground(); + var date = new Date(); + var h = date.getHours(), + m = date.getMinutes(); + var d = date.getDate(), + w = date.getDay(); // d=1..31; w=0..6 - g.setBgColor(0, 0, 0); - g.setColor(1, 1, 1); + g.setBgColor(0, 0, 0); + g.setColor(1, 1, 1); - // g.setFont('Vector', 30); - // g.setFont("7x11Numeric7Seg", 5); - g.setFontLECO1976Regular42(); - g.setFontAlign(0, -1); - g.drawString(timeString(h, m), g.getWidth() / 2, 28); - g.drawString(dayString(d), g.getWidth() * 3 / 4, 88); - g.setColor(0, 1, 0); - g.fillRect(0, 76, g.getWidth(), 80); - g.reset(); + // g.setFont('Vector', 30); + // g.setFont("7x11Numeric7Seg", 5); + g.setFontLECO1976Regular42(); + g.setFontAlign(0, -1); + g.drawString(timeString(h, m), g.getWidth() / 2, 28); + g.drawString(dayString(d), g.getWidth() * 3 / 4, 88); + g.setColor(0, 1, 0); + g.fillRect(0, 76, g.getWidth(), 80); + g.reset(); - // Steps - g.setFontLECO1976Regular22(); - g.setFontAlign(-1, -1); - g.drawString(getSteps(), 8, 88); + // Steps + g.setFontLECO1976Regular22(); + g.setFontAlign(-1, -1); + g.drawString(getSteps(), 8, 88); - drawCal(); + drawCal(); - // widget redraw - Bangle.drawWidgets(); - queueDraw(); + // widget redraw + Bangle.drawWidgets(); + queueDraw(); } @@ -188,12 +189,12 @@ draw(); //the following section is also from waveclk Bangle.on('lcdPower', on => { - if (on) { - draw(); // draw immediately, queue redraw - } else { // stop draw timer - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = undefined; - } + if (on) { + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } }); Bangle.setUI("clock"); From aff76fe2c012e509b4264a69f20b7c60f483c3e3 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 31 Mar 2022 11:39:59 +0100 Subject: [PATCH 221/253] 0.17: Fix regression where long month names were 'undefined' (fix #1641)Fix issue where long month names included 'undefined' (fix #1641) --- apps/locale/ChangeLog | 1 + apps/locale/locale.html | 2 +- apps/locale/metadata.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/locale/ChangeLog b/apps/locale/ChangeLog index 3354a57c1..d21cb1a56 100644 --- a/apps/locale/ChangeLog +++ b/apps/locale/ChangeLog @@ -18,3 +18,4 @@ Added Swedish localisation with English text 0.16: Remove global variables that used RAM Add second 'dp' argument for decimal places in distance/speed/temp (fix #1523) +0.17: Fix regression where long month names were 'undefined' (fix #1641) diff --git a/apps/locale/locale.html b/apps/locale/locale.html index b58b4a297..bac938ffa 100644 --- a/apps/locale/locale.html +++ b/apps/locale/locale.html @@ -161,7 +161,7 @@ exports = { name : "en_GB", currencySym:"£", "%A": `${js(locale.day)}.split(',')[d.getDay()]`, "%a": `${js(locale.abday)}.split(',')[d.getDay()]`, "%B": `${js(locale.month)}.split(',')[d.getMonth()]`, - "%b": `${js(locale.abmonth)}.split(',')[d.getMonth() + 12]`, + "%b": `${js(locale.abmonth)}.split(',')[d.getMonth()]`, "%p": `d.getHours()<12?${js(locale.ampm[0].toUpperCase())}:${js(locale.ampm[1].toUpperCase())}`, "%P": `d.getHours()<12?${js(locale.ampm[0].toLowerCase())}:${js(locale.ampm[1].toLowerCase())}` }; diff --git a/apps/locale/metadata.json b/apps/locale/metadata.json index 20f1f72b8..54ad64e80 100644 --- a/apps/locale/metadata.json +++ b/apps/locale/metadata.json @@ -1,7 +1,7 @@ { "id": "locale", "name": "Languages", - "version": "0.16", + "version": "0.17", "description": "Translations for different countries", "icon": "locale.png", "type": "locale", From ee739ec447358c86dcac3bfb0987380270299633 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 31 Mar 2022 13:47:35 +0100 Subject: [PATCH 222/253] minor tweaks --- apps/glbasic/ChangeLog | 2 ++ apps/glbasic/metadata.json | 3 +-- apps/glbasic/readme.md | 1 - apps/messages/ChangeLog | 2 +- apps/messages/metadata.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 apps/glbasic/ChangeLog delete mode 100644 apps/glbasic/readme.md diff --git a/apps/glbasic/ChangeLog b/apps/glbasic/ChangeLog new file mode 100644 index 000000000..89aee01f8 --- /dev/null +++ b/apps/glbasic/ChangeLog @@ -0,0 +1,2 @@ +0.20: New App! + diff --git a/apps/glbasic/metadata.json b/apps/glbasic/metadata.json index 9d8f5ec7b..7c79097da 100644 --- a/apps/glbasic/metadata.json +++ b/apps/glbasic/metadata.json @@ -2,10 +2,9 @@ "id": "glbasic", "name": "GLBasic Clock", "shortName": "GLBasic", - "version": "0.2", + "version": "0.20", "description": "A clock with large numbers", "dependencies": {"widpedom":"app"}, - "readme": "readme.md", "icon": "icon48.png", "screenshots": [{"url":"glbasic_screenshot.png"}], "type": "clock", diff --git a/apps/glbasic/readme.md b/apps/glbasic/readme.md deleted file mode 100644 index 8b1378917..000000000 --- a/apps/glbasic/readme.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 7815cc3d1..416cb1694 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -40,4 +40,4 @@ 0.25: Fix widget memory usage issues if message received and watch repeatedly calls Bangle.drawWidgets (fix #1550) 0.26: Setting to auto-open music 0.27: Add 'mark all read' option to popup menu (fix #1624) - Option to auto-unlock the watch when a new message arrives +0.28: Option to auto-unlock the watch when a new message arrives diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index 4fb5a4045..6f35f39b0 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.27", + "version": "0.28", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 60af0ea6a59fbb59155d08be996eeff964593df9 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 31 Mar 2022 15:40:29 +0100 Subject: [PATCH 223/253] Naming - fix #1640 --- apps/doztime/metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/doztime/metadata.json b/apps/doztime/metadata.json index 6933487ab..a05bf1470 100644 --- a/apps/doztime/metadata.json +++ b/apps/doztime/metadata.json @@ -1,9 +1,9 @@ { "id": "doztime", - "name": "Dozenal Time", - "shortName": "Dozenal Time", + "name": "Dozenal Digital Time", + "shortName": "Dozenal Digital", "version": "0.05", - "description": "A dozenal Holocene calendar and dozenal diurnal clock", + "description": "A dozenal Holocene calendar and dozenal diurnal digital clock", "icon": "app.png", "type": "clock", "tags": "clock", From 605a1fb96d39c44fbd42cb5b0fce6afc1d3ab0f9 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 31 Mar 2022 15:41:22 +0100 Subject: [PATCH 224/253] version sync --- apps/smclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/smclock/metadata.json b/apps/smclock/metadata.json index 55668adcc..ca40193a2 100644 --- a/apps/smclock/metadata.json +++ b/apps/smclock/metadata.json @@ -4,7 +4,7 @@ "shortName": "MonoClock", "icon": "app.png", "screenshots": [{ "url": "screenshot0.png" }, {"url": "screenshot1.png" }], - "version": "0.04", + "version": "0.06", "description": "A simple watchface based on my stylised monogram.", "type": "clock", "tags": "clock", From 7fc1747a3fe59909002dae1ac4e8add6c0d12b57 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 31 Mar 2022 15:52:17 +0100 Subject: [PATCH 225/253] 0.13: Revert #1578 (stop duplicate entries) as with 2v12 menus it causes other boxes to be wiped (fix #1643) --- apps/run/ChangeLog | 3 ++- apps/run/metadata.json | 2 +- apps/run/settings.js | 5 ----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/apps/run/ChangeLog b/apps/run/ChangeLog index 9f1a547b1..de070dbd8 100644 --- a/apps/run/ChangeLog +++ b/apps/run/ChangeLog @@ -10,4 +10,5 @@ 0.09: Fix broken start/stop if recording not enabled (fix #1561) 0.10: Don't allow the same setting to be chosen for 2 boxes (fix #1578) 0.11: Notifications fixes -0.12: Fix for recorder not stopping at end of run. Bug introduced in 0.11 \ No newline at end of file +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) diff --git a/apps/run/metadata.json b/apps/run/metadata.json index b1b5617be..afa52b2f7 100644 --- a/apps/run/metadata.json +++ b/apps/run/metadata.json @@ -1,6 +1,6 @@ { "id": "run", "name": "Run", - "version":"0.12", + "version":"0.13", "description": "Displays distance, time, steps, cadence, pace and more for runners.", "icon": "app.png", "tags": "run,running,fitness,outdoors,gps", diff --git a/apps/run/settings.js b/apps/run/settings.js index 240df9f07..c3bb31a0d 100644 --- a/apps/run/settings.js +++ b/apps/run/settings.js @@ -42,11 +42,6 @@ value: Math.max(statsIDs.indexOf(settings[boxID]),0), format: v => statsList[v].name, onchange: v => { - for (var i=1;i<=6;i++) - if (settings["B"+i]==statsIDs[v]) { - settings["B"+i]=""; - boxMenu["Box "+i].value=0; - } settings[boxID] = statsIDs[v]; saveSettings(); }, From 5d76a5cd465522fe0b6e04442e879908c2abe8d4 Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Thu, 31 Mar 2022 23:56:02 +0200 Subject: [PATCH 226/253] v0.08: Bug fix at end of the game with victorious splash and glorious orchestra --- apps/game1024/ChangeLog | 3 ++- apps/game1024/app.js | 31 +++++++++++++++++++++++++++---- apps/game1024/metadata.json | 2 +- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/apps/game1024/ChangeLog b/apps/game1024/ChangeLog index 6ec8a15fc..c917bb90c 100644 --- a/apps/game1024/ChangeLog +++ b/apps/game1024/ChangeLog @@ -4,4 +4,5 @@ 0.04: Bug fix score reset after Game Over, new icon 0.05: Chevron marker on the randomly added square 0.06: Fixed issue 1609 added a message popup state handler to control unwanted screen redraw -0.07: Optimized the mover algorithm for efficiency (work in progress) \ No newline at end of file +0.07: Optimized the mover algorithm for efficiency (work in progress) +0.08: Bug fix at end of the game with victorious splash and glorious orchestra \ No newline at end of file diff --git a/apps/game1024/app.js b/apps/game1024/app.js index b0e8d74f7..13430ff2d 100644 --- a/apps/game1024/app.js +++ b/apps/game1024/app.js @@ -162,6 +162,7 @@ const buttons = { */ const mover = { + gameWon: false, direction: { up: {name: 'up', step: 1, innerBegin: 0, innerEnd: rows-1, outerBegin: 0, outerEnd: cols-1, iter: rows -1, sqIndex: function (i,o) {return i*(cols) + o;}, sqNextIndex: function (i,o) {return i < rows -1 ? (i+1)*(cols) + o : -1;} @@ -397,7 +398,7 @@ function addToUndo() { } function addToScore (val) { scores.add(val); - if (val == 10) messageYouWin(); + if (val == 10) mover.gameWon = true; } function createGrid () { let cn =0; @@ -421,15 +422,30 @@ function messageGameOver () { .drawString("O V E R !", middle.x+12, middle.y+25); } function messageYouWin () { - g.setColor("#1a0d00") + const c = (g.theme.dark) ? {"fg": "#FFFFFF", "bg": "#808080"} : {"fg": "#FF0000", "bg": "#000000"}; + g.setColor(c.bg) .setFont12x20(2) .setFontAlign(0,0,0) .drawString("YOU HAVE", middle.x+18, middle.y-24) .drawString("W O N ! !", middle.x+18, middle.y+24); - g.setColor("#FF0808") + g.setColor(c.fg) .drawString("YOU HAVE", middle.x+17, middle.y-25) .drawString("W O N ! !", middle.x+17, middle.y+25); - Bangle.buzz(200, 1); + for (let r=0;r<4;r++){ + Bangle.buzz(200,0.2) + .then((result) => { + Bangle.buzz(200,0.5) + .then((result)=>{ + Bangle.buzz(200,0.8) + .then((result)=>{ + Bangle.buzz(200,1) + .then((result)=>{ + Bangle.buzz(500,0); + }) + }) + }) + }) + } } function makeRandomNumber () { return Math.ceil(2*Math.random()); @@ -527,6 +543,7 @@ function handlePopUpClicks(btn) { function resetGame() { g.clear(); scores.reset(); + mover.gameWon=false; allSquares.forEach(sq => {sq.setExpVal(0);sq.removeUndo();sq.setRndmFalse();}); addRandomNumber(); addRandomNumber(); @@ -653,6 +670,12 @@ function runGame(dir){ debug(() => console.log("G A M E O V E R !!")); snapshot.reset(); messageGameOver(); + } else { + if (mover.gameWon) { + debug(() => console.log("Y O U H A V E W O N !!")); + snapshot.reset(); + messageYouWin(); + } } } diff --git a/apps/game1024/metadata.json b/apps/game1024/metadata.json index 14e64347a..dd350d2b9 100644 --- a/apps/game1024/metadata.json +++ b/apps/game1024/metadata.json @@ -1,7 +1,7 @@ { "id": "game1024", "name": "1024 Game", "shortName" : "1024 Game", - "version": "0.07", + "version": "0.08", "icon": "game1024.png", "screenshots": [ {"url":"screenshot.png" } ], "readme":"README.md", From 172df0dc2732550d42e1fd118922cd7b44d0f189 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 1 Apr 2022 09:54:25 +0100 Subject: [PATCH 227/253] messages 0.29: Fix message list overwrites on Bangle.js 1 (fix #1642) --- apps/messages/ChangeLog | 1 + apps/messages/app.js | 1 + apps/messages/metadata.json | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 416cb1694..ec5a85a8b 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -41,3 +41,4 @@ 0.26: Setting to auto-open music 0.27: Add 'mark all read' option to popup menu (fix #1624) 0.28: Option to auto-unlock the watch when a new message arrives +0.29: Fix message list overwrites on Bangle.js 1 (fix #1642) diff --git a/apps/messages/app.js b/apps/messages/app.js index 655fc7122..6d37b5192 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -457,6 +457,7 @@ function checkMessages(options) { var msg = MESSAGES[idx-1]; if (msg && msg.new) g.setBgColor(g.theme.bgH).setColor(g.theme.fgH); else g.setColor(g.theme.fg); + g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); if (idx==0) msg = {id:"back", title:"< Back"}; if (!msg) return; var x = r.x+2, title = msg.title, body = msg.body; diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index 6f35f39b0..edc072714 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.28", + "version": "0.29", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 0fdb4db1d91fe33531148a2e0811c290a4cca377 Mon Sep 17 00:00:00 2001 From: Robert Kaiser Date: Sat, 2 Apr 2022 02:57:24 +0200 Subject: [PATCH 228/253] add stardate clock --- apps/stardateclock/ChangeLog | 1 + apps/stardateclock/README.md | 23 ++ apps/stardateclock/app-icon.js | 1 + apps/stardateclock/app.js | 362 +++++++++++++++++++++++++++++ apps/stardateclock/app.png | Bin 0 -> 594 bytes apps/stardateclock/metadata.json | 23 ++ apps/stardateclock/screenshot1.png | Bin 0 -> 3431 bytes apps/stardateclock/screenshot2.png | Bin 0 -> 2354 bytes apps/stardateclock/screenshot3.png | Bin 0 -> 4017 bytes apps/stardateclock/screenshot4.png | Bin 0 -> 5287 bytes 10 files changed, 410 insertions(+) create mode 100644 apps/stardateclock/ChangeLog create mode 100644 apps/stardateclock/README.md create mode 100644 apps/stardateclock/app-icon.js create mode 100644 apps/stardateclock/app.js create mode 100644 apps/stardateclock/app.png create mode 100644 apps/stardateclock/metadata.json create mode 100644 apps/stardateclock/screenshot1.png create mode 100644 apps/stardateclock/screenshot2.png create mode 100644 apps/stardateclock/screenshot3.png create mode 100644 apps/stardateclock/screenshot4.png diff --git a/apps/stardateclock/ChangeLog b/apps/stardateclock/ChangeLog new file mode 100644 index 000000000..7ebdc317a --- /dev/null +++ b/apps/stardateclock/ChangeLog @@ -0,0 +1 @@ +1.0: Initial release on the app repository for Bangle.js 1 and 2 diff --git a/apps/stardateclock/README.md b/apps/stardateclock/README.md new file mode 100644 index 000000000..2b5da3a41 --- /dev/null +++ b/apps/stardateclock/README.md @@ -0,0 +1,23 @@ +# Stardate Clock + +A clock face displaying a stardate along with a "standard" digital/analog clock +in LCARS design. + +That design has been made popular by various Star Trek shows. Credits for the +original LCARS designs go to Michael Okuda, copyrights are owned by Paramount Global, +usage of that type of design is permitted freely for non-profit use cases. +The Bangle.js version has been created by Robert Kaiser . + +The stardate concept used leans on the shows released from the late 80s onward +by using 1000 units per Earth year, but to apply this more cleanly, this split +is applied exactly. Also, to give more relationship to the shows and +incidentally make values look similar to those depicted there, the zero point +is set to the first airing of the original 'Star Trek' series in the US on +Thursday, September 8, 1966, at 8:30 p.m. Eastern Time. + +The clock face supports Bangle.js 1 and 2 with some compromises (e.g. the +colors will look best on Bangle.js 1, the font sizes will look best on +Bangle.js 2). + +Any tap on the diaply while unlocked switches the "standard" Earth-style clock +between digital and analog display. diff --git a/apps/stardateclock/app-icon.js b/apps/stardateclock/app-icon.js new file mode 100644 index 000000000..d38013a98 --- /dev/null +++ b/apps/stardateclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgkiAA0gDRwX/C/4X/C5MO9wBDgnkAIMAAQQXKAItehwECAQIXK8gBEIQIeDC5YAF8EAAIIECC48hE4oYCAogXIkQvHDIgCBiQXHiCPFAIaaCgECJBChDAIsOU4RIJbJwwIDIVEABIYBMJAXOAC8SmYAHmHdABJfBCxAXNCpEyRxoWVgETC46+OkYXHRpxGWC5EwBQMBkQDBiK4DKQMBiAXKNQMggQ2CgI7CkcgC5UjicwkYXCgUxmakBC5kCmERC4MiAoMjgMTC50AC4KYCkcAgYXRPgJFBC6YABgYEBC6iQBC6cRgMgL6ikBR4IXOiR3EX4IXPAgTXDBgIXNgUiiClCAAMikIKBC5YAMC64AXogAGoAX/C6w")) \ No newline at end of file diff --git a/apps/stardateclock/app.js b/apps/stardateclock/app.js new file mode 100644 index 000000000..70f1070fc --- /dev/null +++ b/apps/stardateclock/app.js @@ -0,0 +1,362 @@ +// Stardate clock face, by KaiRo.at, 2021-2022 + +var redrawClock = true; +var clockface = "digital"; + +// note: Bangle.js 1 has 240x240x16, 2 has 176x176x3 screen +var bpp = g.getBPP ? g.getBPP() : 16; + +// Load fonts +Graphics.prototype.setFontAntonio27 = function(scale) { + // Actual height 23 (23 - 1) + g.setFontCustom(atob("AAAAAAGAAAAwAAAGAAAAwAAAGAAAAwAAAAAAAAAAAAAAAAAADAAAA4AAAHAAAAAAAAAAAAAAAAAAAAAA4AAB/AAD/4AH/4AP/wAf/gAD/AAAeAAAAAAAAAAAAA///AP//+D///4eAAPDgAA4cAAHD///4P//+A///gAAAAAAAAAAAAAAYAAAHAAAA4AAAOAAAD///4f///D///4AAAAAAAAAAAAAAAAAAAAAAA/gD4P8B/D/g/4cAfzDgP4Yf/8DD/+AYP/ADAGAAAAAAAAAAAAHwD8B+AfwfwD/DgMA4cDgHDgeA4f///B/3/wH8P8AAAAAAAAAAAAOAAAPwAAP+AAP/wAf8OAf4BwD///4f///D///4AABwAAAGAAAAAAAAAAAAAAD/4Pwf/h/D/4P4cMAHDjgA4cf//Dh//4cH/8AAAAAAAAAAAAAAH//8B///wf///Dg4A4cHAHDg4A4f3//B+f/wHh/8AAAAAAAAAAAAAAcAAADgAA4cAD/DgH/4cH//Dv/4Af/gAD/gAAfAAADgAAAAAAAAAAAAH4f8B///wf///Dg8A4cDAHDg8A4f///B///wH8/8AAAAAAAAAAAAAAH/h4B/+Pwf/5/DgHA4cA4HDgHA4f///B///wH//8AAAAAAAAAAAAAAAAAAAHgeAA8DwAHgeAAAAAAAAAA"), 45, atob("CQcKDAsMDAwMDAwMDAc="), 27+(scale<<8)+(1<<16)); +}; +Graphics.prototype.setFontAntonio42 = function(scale) { + // Actual height 36 (36 - 1) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAAAHgAAAAAHgAAAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAfgAAAAH/gAAAB//gAAAf//gAAH//4AAB//+AAAf//gAAH//4AAAf/+AAAAf/gAAAAf4AAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAA////gAH////+AP/////Af/////gf/////gfAAAAPgeAAAAHgeAAAAHgfAAAAPgf/////gf/////gP/////AH////+AB////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAAAB4AAAAAB4AAAAADwAAAAAHwAAAAAP/////gf/////gf/////gf/////gf/////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAPgH/8AD/gP/8AP/gP/8A//gf/8B//gfAAH/ngeAAf+HgeAB/4HgfAH/gHgf//+AHgP//4AHgH//wAHgD/+AAHgAPgAAAAAAAAAAAAAAAAAAAAAAAAAA+AAfwAH+AAf+AP+AAf/AP+AAf/Af+AAf/gfADwAPgeADwAHgeADwAHgfAH4APgf///h/gf/////AP/+///AH/+f/+AB/4H/4AAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAA/gAAAAH/gAAAB//gAAAP//gAAB//HgAAf/wHgAD/8AHgAf/AAHgAf/////gf/////gf/////gf/////gf/////gAAAAHgAAAAAHgAAAAAHAAAAAAAAAAAAAAAAAAAAAAAf//gP8Af//gP+Af//gP/Af//gP/gf/+AAfgeB8AAHgeB4AAHgeB8AAHgeB////geB////geA////AeAf//+AAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf///gAD////8AH/////AP/////Af/////gfAPgAfgeAPAAHgeAPAAHgeAPAAHgf+PgAPgf+P///gP+H///AH+H//+AB+B//8AAAAD8AAAAAAAAAAAAAAAAAAAAAAAeAAAAAAeAAAAAAeAAAAPgeAAAP/geAAD//geAA///geAH///geB///+AeP//4AAe//8AAAf//AAAAf/wAAAAf+AAAAAfwAAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAB/wH/4AH/8f/+AP/////Af/////gf/////geAH4APgeADgAHgeADgAHgeAHwAHgf/////gf/////gP/////AH/8//+AB/wH/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//gPgAH//4P+AP//8P/Af//+P/AfwB+P/geAAeAPgeAAeAHgeAAeAHgfAAeAPgf/////gP/////AP/////AH////8AA////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4APgAAH4AfgAAH4AfgAAH4AfgAAH4AfgAAD4APgAAAAAAAAAAAAAAA="), 45, atob("DgsPEhESEhISEhISEgo="), 42+(scale<<8)+(1<<16)); +}; +const fontName = "Antonio27"; +const fontNameLarge = "Antonio42"; +const fontSize = 1; +const fontSizeLarge = 1; +const fontHeightLarge = 42 * fontSizeLarge; + +// LCARS dimensions +if (g.getWidth() < 200) { // Bangle.js 2 + const baseUnit1 = 3; + const baseUnit2 = 2; + const baseUnit3 = 7; +} +else { + const baseUnit1 = 5; + const baseUnit2 = 3; + const baseUnit3 = 10; +} +const widgetsHeight = 24; +const sbarWid = baseUnit3 * 5; +const hbarHt = baseUnit1; +const outRad = baseUnit1 * 5; +const inRad = outRad - hbarHt; +const gap = baseUnit2; +const divisionPos = baseUnit3 * 8; +const sbarGapPos = baseUnit3 * 15; +const lowerTop = divisionPos+gap+1; + +// Star Trek famously premiered on Thursday, September 8, 1966, at 8:30 p.m. +// See http://www.startrek.com/article/what-if-the-original-star-trek-had-debuted-on-friday-nights +const gSDBase = new Date("September 8, 1966 20:30:00 EST"); +const sdatePosBottom = divisionPos - hbarHt - 1; +const sdatePosRight = g.getWidth() - baseUnit2; +const sdateDecimals = 1; +const secondsPerYear = 86400 * 365.2425; +const sdateDecFactor = Math.pow(10, sdateDecimals); + +const clockAreaLeft = sbarWid + inRad / 2; +const clockAreaTop = lowerTop + hbarHt + inRad / 2; +const clockWid = g.getWidth() - clockAreaLeft; +const clockHt = g.getHeight() - clockAreaTop; + +const ctimePosTop = clockAreaTop + baseUnit1 * 5; +const ctimePosCenter = clockAreaLeft + clockWid / 2; +const cdatePosTop = ctimePosTop + fontHeightLarge; +const cdatePosCenter = clockAreaLeft + clockWid / 2; + +const clockCtrX = Math.floor(clockAreaLeft + clockWid / 2); +const clockCtrY = Math.floor(clockAreaTop + clockHt / 2); +const analogRad = Math.floor(Math.min(clockWid, clockHt) / 2); + +const analogMainLineLength = baseUnit1 * 2; +const analogSubLineLength = baseUnit1; + +const analogHourHandLength = analogRad / 2; +const analogMinuteHandLength = analogRad - analogMainLineLength / 2; + +const colorBg = "#000000"; +const colorTime = "#9C9CFF"; +const colorDate = "#A09090"; +const colorStardate = "#FFCF00"; +// On low-bpp devices (Bangle.js 2), use basic colors for analog clock. +const colorHours = bpp > 3 ? "#9C9CFF" : "#00FF00"; +const colorSeconds = bpp > 3 ? "#E7ADE7" : "#FFFF00"; +const colorHands = bpp > 3 ? "#A09090" : "#00FFFF"; +const colorLCARSGray = "#A09090"; +const colorLCARSOrange = "#FF9F00"; +const colorLCARSPink = "#E7ADE7"; +const colorLCARSPurple = "#A06060"; +const colorLCARSBrown = "#C09070"; +// More colors: teal #008484, yellow FFCF00, purple #6050B0 + +var lastSDateString; +var lastTimeStringToMin; +var lastTimeStringSec; +var lastDateString; +var lastAnalogDate; + +function updateStardate() { + var curDate = new Date(); + + // Note that the millisecond division and the 1000-unit multiplier cancel each other out. + var sdateval = (curDate - gSDBase) / secondsPerYear; + + var sdatestring = (Math.floor(sdateval * sdateDecFactor) / sdateDecFactor).toFixed(sdateDecimals); + + // Reset the state of the graphics library. + g.reset(); + g.setBgColor(colorBg); + // Set Font + g.setFont(fontName, fontSize); + if (lastSDateString) { + // Clear the area where we want to draw the time. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(sdatePosRight - g.stringWidth(lastSDateString) - 1, + sdatePosBottom - g.getFontHeight(), + sdatePosRight, + sdatePosBottom); + } + // Draw the current stardate. + g.setColor(colorStardate); + g.setFontAlign(1, 1, 0); // Align following string to bottom right. + g.drawString(sdatestring, sdatePosRight, sdatePosBottom); + lastSDateString = sdatestring; + + // Schedule next when an update to the last decimal is due. + var mstonextUpdate = (Math.ceil(sdateval * sdateDecFactor) / sdateDecFactor - sdateval) * secondsPerYear; + if (redrawClock) { + setTimeout(updateStardate, mstonextUpdate); + } +} + +function updateConventionalTime() { + var curDate = new Date(); + + if (clockface == "digital") { + drawDigitalClock(curDate); + } + else { + drawAnalogClock(curDate); + } + + // Schedule next when an update to the last second is due. + var mstonextUpdate = Math.ceil(curDate / 1000) * 1000 - curDate; + if (redrawClock) { + setTimeout(updateConventionalTime, mstonextUpdate); + } +} + +function drawDigitalClock(curDate) { + var timestringToMin = ("0" + curDate.getHours()).substr(-2) + ":" + + ("0" + curDate.getMinutes()).substr(-2) + ":"; + var timestringSec = ("0" + curDate.getSeconds()).substr(-2); + var datestring = "" + curDate.getFullYear() + "-" + + ("0" + (curDate.getMonth() + 1)).substr(-2) + "-" + + ("0" + curDate.getDate()).substr(-2); + + // Reset the state of the graphics library. + g.reset(); + g.setBgColor(colorBg); + // Set Font + g.setFont(fontNameLarge, fontSizeLarge); + var ctimePosLeft = ctimePosCenter - g.stringWidth("12:34:56") / 2; + if (ctimePosLeft + g.stringWidth("00:00:00") > g.getWidth()) { + ctimePosLeft = g.getWidth() - g.stringWidth("00:00:00"); + } + g.setColor(colorTime); + if (timestringToMin != lastTimeStringToMin) { + if (lastTimeStringToMin) { + // Clear the area where we want to draw the time. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(ctimePosLeft, + ctimePosTop, + ctimePosLeft + g.stringWidth(lastTimeStringToMin) + 1, + ctimePosTop + g.getFontHeight()); + } + // Draw the current time. + g.drawString(timestringToMin, ctimePosLeft, ctimePosTop); + lastTimeStringToMin = timestringToMin; + } + var ctimePosLeftSec = ctimePosLeft + g.stringWidth(timestringToMin); + if (lastTimeStringSec) { + // Clear the area where we want to draw the seconds. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(ctimePosLeftSec, + ctimePosTop, + ctimePosLeftSec + g.stringWidth(lastTimeStringSec) + 1, + ctimePosTop + g.getFontHeight()); + } + // Draw the current seconds. + g.drawString(timestringSec, ctimePosLeftSec, ctimePosTop); + lastTimeStringSec = timestringSec; + + if (datestring != lastDateString) { + // Set Font + g.setFont(fontName, fontSize); + var cdatePosLeft = cdatePosCenter - g.stringWidth("1234-56-78") / 2; + if (lastDateString) { + // Clear the area where we want to draw the time. + //g.setBgColor("#FF6600"); // for debugging + g.clearRect(cdatePosLeft, + cdatePosTop, + cdatePosLeft + g.stringWidth(lastDateString) + 1, + cdatePosTop + g.getFontHeight()); + } + // Draw the current date. + g.setColor(colorDate); + //g.setFontAlign(0, -1, 0); // Align following string to bottom right. + g.drawString(datestring, cdatePosLeft, cdatePosTop); + lastDateString = datestring; + } +} + +function drawLine(x1, y1, x2, y2, color) { + g.setColor(color); + // On high-bpp devices, use anti-aliasing. Low-bpp (Bangle.js 2) doesn't clear nicely with AA. + if (bpp > 3 && g.drawLineAA) { + g.drawLineAA(x1, y1, x2, y2); + } + else { + g.drawLine(x1, y1, x2, y2); + } +} + +function clearLine(x1, y1, x2, y2) { + drawLine(x1, y1, x2, y2, colorBg); +} + +function drawAnalogClock(curDate) { + // Reset the state of the graphics library. + g.reset(); + g.setBgColor(colorBg); + // Init variables for drawing any seconds we have not drawn. + // If minute changed, we'll set for the full wheel below. + var firstDrawSecond = lastAnalogDate ? lastAnalogDate.getSeconds() + 1 : curDate.getSeconds(); + var lastDrawSecond = curDate.getSeconds(); + if (!lastAnalogDate || curDate.getMinutes() != lastAnalogDate.getMinutes()) { + // Draw the main hour lines. + //g.setColor("#9C9CFF"); + //g.drawCircle(clockCtrX, clockCtrY, analogRad); + for (let i = 0; i < 60; i = i + 15) { + let edgeX = clockCtrX + analogRad * Math.sin(i * Math.PI / 30); + let edgeY = clockCtrY - analogRad * Math.cos(i * Math.PI / 30); + let innerX = clockCtrX + (analogRad - analogMainLineLength) * Math.sin(i * Math.PI / 30); + let innerY = clockCtrY - (analogRad - analogMainLineLength) * Math.cos(i * Math.PI / 30); + drawLine(edgeX, edgeY, innerX, innerY, colorHours); + } + // Set for drawing the full second wheel. + firstDrawSecond = 0; + lastDrawSecond = 59; + } + // Draw the second wheel, or the parts of it that we haven't done yet. + for (let i = firstDrawSecond; i <= lastDrawSecond; i++) { + let edgeX = clockCtrX + analogRad * Math.sin(i * Math.PI / 30); + let edgeY = clockCtrY - analogRad * Math.cos(i * Math.PI / 30); + let innerX = clockCtrX + (analogRad - analogSubLineLength) * Math.sin(i * Math.PI / 30); + let innerY = clockCtrY - (analogRad - analogSubLineLength) * Math.cos(i * Math.PI / 30); + if (i <= curDate.getSeconds()) { + drawLine(edgeX, edgeY, innerX, innerY, colorSeconds); + } + else if (i % 5 == 0) { + drawLine(edgeX, edgeY, innerX, innerY, colorHours); + } + else { + clearLine(edgeX, edgeY, innerX, innerY); + } + } + if (lastAnalogDate) { + // Clear previous hands. + if (curDate.getMinutes() != lastAnalogDate.getMinutes()) { + // Clear hour hand. + let HhAngle = (lastAnalogDate.getHours() + lastAnalogDate.getMinutes() / 60) * Math.PI / 6; + let HhEdgeX = clockCtrX + analogHourHandLength * Math.sin(HhAngle); + let HhEdgeY = clockCtrY - analogHourHandLength * Math.cos(HhAngle); + clearLine(HhEdgeX, HhEdgeY, clockCtrX, clockCtrY); + // Clear minute hand. + let MhEdgeX = clockCtrX + analogMinuteHandLength * Math.sin(lastAnalogDate.getMinutes() * Math.PI / 30); + let MhEdgeY = clockCtrY - analogMinuteHandLength * Math.cos(lastAnalogDate.getMinutes() * Math.PI / 30); + clearLine(MhEdgeX, MhEdgeY, clockCtrX, clockCtrY); + } + } + if (!lastAnalogDate || curDate.getMinutes() != lastAnalogDate.getMinutes()) { + // Draw hour hand. + let HhAngle = (curDate.getHours() + curDate.getMinutes() / 60) * Math.PI / 6; + let HhEdgeX = clockCtrX + analogHourHandLength * Math.sin(HhAngle); + let HhEdgeY = clockCtrY - analogHourHandLength * Math.cos(HhAngle); + drawLine(HhEdgeX, HhEdgeY, clockCtrX, clockCtrY, colorHands); + // Draw minute hand. + let MhEdgeX = clockCtrX + analogMinuteHandLength * Math.sin(curDate.getMinutes() * Math.PI / 30); + let MhEdgeY = clockCtrY - analogMinuteHandLength * Math.cos(curDate.getMinutes() * Math.PI / 30); + drawLine(MhEdgeX, MhEdgeY, clockCtrX, clockCtrY, colorHands); + } + lastAnalogDate = curDate; +} + +function switchClockface() { + if (clockface == "digital") { + clockface = "analog"; + } + else { + clockface = "digital"; + } + // Clear whole lower area. + g.clearRect(clockAreaLeft,clockAreaTop,g.getWidth(),g.getHeight()); + lastTimeStringToMin = undefined; + lastTimeStringSec = undefined; + lastDateString = undefined; + lastAnalogDate = undefined; +} + +// Clear the screen once, at startup. +g.setBgColor(colorBg); +g.clear(); +// Draw LCARS borders. +// Upper section: rounded corner. +g.setColor(colorLCARSGray); +g.fillCircle(outRad, divisionPos - outRad, outRad); +g.fillRect(outRad, divisionPos - outRad, sbarWid + inRad, divisionPos); +g.fillRect(outRad, divisionPos - hbarHt, sbarWid + outRad, divisionPos); // div bar stub +g.fillRect(0, 0, sbarWid, divisionPos - outRad); // side bar +g.setColor(colorBg); // blocked out areas of corner +g.fillCircle(sbarWid + inRad + 1, divisionPos - hbarHt - inRad - 1, inRad); +g.fillRect(sbarWid + 1, divisionPos - outRad * 2, sbarWid + outRad, divisionPos - hbarHt - inRad); +// upper division bar +g.setColor(colorLCARSPurple); +g.fillRect(sbarWid + outRad + gap + 1, divisionPos - hbarHt, g.getWidth(), divisionPos); +// Lower section: rounded corner. +g.setColor(colorLCARSPink); +g.fillCircle(outRad, lowerTop + outRad, outRad); +g.fillRect(outRad, lowerTop, sbarWid + inRad, lowerTop + outRad); +g.fillRect(outRad, lowerTop, sbarWid + outRad, lowerTop + hbarHt); // div bar stub +g.fillRect(0, lowerTop + outRad, sbarWid, sbarGapPos); // side bar +g.setColor(colorBg); // blocked out areas of corner +g.fillCircle(sbarWid + inRad + 1, lowerTop + hbarHt + inRad + 1, inRad); +g.fillRect(sbarWid + 1, lowerTop + hbarHt + inRad, sbarWid + outRad, lowerTop + outRad * 2); +// lower division bar +g.setColor(colorLCARSOrange); +g.fillRect(sbarWid + outRad + gap + 1, lowerTop, g.getWidth(), lowerTop + hbarHt); +// second color of side bar +g.setColor(colorLCARSBrown); +g.fillRect(0, sbarGapPos + gap + 1, sbarWid, g.getHeight()); +// Draw immediately at first. +updateStardate(); +updateConventionalTime(); +// Make sure widgets can be shown. +//g.setColor("#FF0000"); g.fillRect(0, 0, g.getWidth(), widgetsHeight); // debug +Bangle.loadWidgets(); +Bangle.drawWidgets(); +// Show launcher on button press as usual for a clock face +Bangle.setUI("clock", Bangle.showLauncher); +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower', on => { + if (on) { + redrawClock = true; + // Draw immediately to kick things off. + updateStardate(); + updateConventionalTime(); + } + else { + redrawClock = false; + } +}); +Bangle.on('touch', button => { + // button == 1 is left, 2 is right + switchClockface(); +}); diff --git a/apps/stardateclock/app.png b/apps/stardateclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..86426721b8492f302a1609de5246bed582b59689 GIT binary patch literal 594 zcmV-Y04Po1Q`WL9dB_KkEu?x$?kx_MMGC zmt+N$Qo#(x=+0(sSP$8=0N_9TPG2j(XcjWYpau}JAh|s$00-iBmPxNJXl@694uAy! zB1*3`OyXe}kgBA1S%D*p2sNXW>6X0jd)QL}07R5D@S-I&j$^Vf zou;W66N!}UQ!?LE5jyAj&08(YY8X8TRegFN4KjZA7!5QnDZAYe*g4P;R zN=PXeL_tK*S|e1xTYR$u0D#No0su2n#LSv4zS)mej4_KIF~-b+@gd6TJjPd)ZaP=< zTI+?~&uplt)_esjku@fZDYt3>tYzH=|B9xoK3e2WTr~in_mxs0qJK?XbqTq~G{$V& zkBAbP{j`Z=d_}3ue$vD-z9J{9_=AbR^Sr9dj2dVitH#JW{=>Px#07*qoM6N<$g0k`Wr2qf` literal 0 HcmV?d00001 diff --git a/apps/stardateclock/metadata.json b/apps/stardateclock/metadata.json new file mode 100644 index 000000000..8be981038 --- /dev/null +++ b/apps/stardateclock/metadata.json @@ -0,0 +1,23 @@ +{ + "id": "stardateclock", + "name":"Stardate Clock", + "shortName":"Stardate Clock", + "description": "A clock displaying a stardate along with a 'standard' digital/analog clock in LCARS design", + "version":"1.0", + "icon": "app.png", + "type":"clock", + "tags": "clock", + "supports": ["BANGLEJS", "BANGLEJS2"], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + {"name": "stardateclock.app.js","url": "app.js"}, + {"name": "stardateclock.img","url": "app-icon.js","evaluate": true} + ], + "screenshots": [ + {"url": "screenshot1.png"}, + {"url": "screenshot2.png"}, + {"url": "screenshot3.png"}, + {"url": "screenshot4.png"} + ] +} diff --git a/apps/stardateclock/screenshot1.png b/apps/stardateclock/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..98bd0cea3f25eccbdeced27f9b765b45ae467d72 GIT binary patch literal 3431 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 literal 0 HcmV?d00001 diff --git a/apps/stardateclock/screenshot2.png b/apps/stardateclock/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..8a70c3f522117d08bc8c9671bdd6a01eba2a4a5f GIT binary patch literal 2354 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 Nz~0)~s?L&}{7+|NPYwV8 literal 0 HcmV?d00001 diff --git a/apps/stardateclock/screenshot3.png b/apps/stardateclock/screenshot3.png new file mode 100644 index 0000000000000000000000000000000000000000..7acb91d0a6a0abce308ccf2adbf0e81a5f4edabf GIT binary patch literal 4017 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 literal 0 HcmV?d00001 From 6435c684fdedac4f8c4b554bed145940590f82d2 Mon Sep 17 00:00:00 2001 From: Danny <31635744+DDDanny@users.noreply.github.com> Date: Sat, 2 Apr 2022 11:51:59 +0200 Subject: [PATCH 229/253] replaced substr(ing) by slice --- apps/antonclk/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/antonclk/app.js b/apps/antonclk/app.js index 7b40d8eb5..6197d66aa 100644 --- a/apps/antonclk/app.js +++ b/apps/antonclk/app.js @@ -99,7 +99,7 @@ function updateState() { } function isoStr(date) { - return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).substr(-2) + "-" + ("0" + date.getDate()).substr(-2); + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).substr(-2); } var calWeekBuffer = [false,false,false]; //buffer tz, date, week no (once calculated until other tz or date is requested) @@ -140,7 +140,7 @@ function draw() { g.setFontAlign(0, 0).setFont("Anton").drawString(timeStr, x, y); // draw time if (secondsScreen) { y += 65; - var secStr = (secondsWithColon ? ":" : "") + ("0" + date.getSeconds()).substr(-2); + var secStr = (secondsWithColon ? ":" : "") + ("0" + date.getSeconds()).slice(-2); if (doColor()) g.setColor(0, 0, 1); g.setFont("AntonSmall"); @@ -193,7 +193,7 @@ function draw() { if (calWeek || weekDay) { var dowcwStr = ""; if (calWeek) - dowcwStr = " #" + ("0" + ISO8601calWeek(date)).substring(-2); + dowcwStr = " #" + ("0" + ISO8601calWeek(date)).slice(-2); if (weekDay) dowcwStr = require("locale").dow(date, calWeek ? 1 : 0) + dowcwStr; //weekDay e.g. Monday or weekDayShort # e.g. Mon #01 else //week #01 From 42c6f3b1b96404e0ef99fbc36453b3eb310a54b5 Mon Sep 17 00:00:00 2001 From: Danny <31635744+DDDanny@users.noreply.github.com> Date: Sat, 2 Apr 2022 11:52:53 +0200 Subject: [PATCH 230/253] replaced substr by slice --- apps/antonclk/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/antonclk/app.js b/apps/antonclk/app.js index 6197d66aa..4b1e71bda 100644 --- a/apps/antonclk/app.js +++ b/apps/antonclk/app.js @@ -99,7 +99,7 @@ function updateState() { } function isoStr(date) { - return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).substr(-2); + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2); } var calWeekBuffer = [false,false,false]; //buffer tz, date, week no (once calculated until other tz or date is requested) From 290dcfec3b306ea9c704cb39919c8a27171a2a2b Mon Sep 17 00:00:00 2001 From: Danny <31635744+DDDanny@users.noreply.github.com> Date: Sat, 2 Apr 2022 12:05:33 +0200 Subject: [PATCH 231/253] changed to v0.08 --- apps/antonclk/ChangeLog | 3 ++- apps/antonclk/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/antonclk/ChangeLog b/apps/antonclk/ChangeLog index ac49dcbd7..73a63f7c7 100644 --- a/apps/antonclk/ChangeLog +++ b/apps/antonclk/ChangeLog @@ -8,4 +8,5 @@ 0.06: fixes #1271 - wrong settings name when weekday name and calendar weeknumber are on then display is # week is buffered until date or timezone changes -0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users) \ No newline at end of file +0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users) +0.08: fixed calendar weeknumber not shortened to two digits \ No newline at end of file diff --git a/apps/antonclk/metadata.json b/apps/antonclk/metadata.json index 4d26dd0c7..c58ee2a1b 100644 --- a/apps/antonclk/metadata.json +++ b/apps/antonclk/metadata.json @@ -1,7 +1,7 @@ { "id": "antonclk", "name": "Anton Clock", - "version": "0.07", + "version": "0.08", "description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.", "readme":"README.md", "icon": "app.png", From 6b55faae979849359138854bc858c2c530eef37e Mon Sep 17 00:00:00 2001 From: xxpasixx <62435140+xxpasixx@users.noreply.github.com> Date: Sat, 2 Apr 2022 13:49:14 +0200 Subject: [PATCH 232/253] Add new Icons Add new Icons (Youtube, Twitch, MS TODO, Teams, Snapchat, Signal, Post & DHL, Nina, Lieferando, Kalender, Discord, Corona Warn, Bibel) --- apps/messages/ChangeLog | 1 + apps/messages/app.js | 44 ++++++++++++++++++++++++++++--------- apps/messages/metadata.json | 2 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index ec5a85a8b..092a38eb6 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -42,3 +42,4 @@ 0.27: Add 'mark all read' option to popup menu (fix #1624) 0.28: Option to auto-unlock the watch when a new message arrives 0.29: Fix message list overwrites on Bangle.js 1 (fix #1642) +0.30: Add new Icons (Youtube, Twitch, MS TODO, Teams, Snapchat, Signal, Post & DHL, Nina, Lieferando, Kalender, Discord, Corona Warn, Bibel) diff --git a/apps/messages/app.js b/apps/messages/app.js index 6d37b5192..821813108 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -82,31 +82,45 @@ function getNegImage() { return atob("FhaBADAAMeAB78AP/4B/fwP4/h/B/P4D//AH/4AP/AAf4AB/gAP/AB/+AP/8B/P4P4fx/A/v4B//AD94AHjAAMA="); } /* -* icons should be 24x24px with 1bpp colors and transparancy +* icons should be 24x24px with 1bpp colors and 'Transparency to Color' +* http://www.espruino.com/Image+Converter */ function getMessageImage(msg) { if (msg.img) return atob(msg.img); var s = (msg.src||"").toLowerCase(); - if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA="); + if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA="); + if (s=="bibel") return atob("GBgBAAAAA//wD//4D//4H//4H/f4H/f4H+P4H4D4H4D4H/f4H/f4H/f4H/f4H/f4H//4H//4H//4GAAAEAAAEAAACAAAB//4AAAA"); if (s=="calendar") return atob("GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgAGB//+B//+B//+B9m2B//+B//+Btm2B//+B//+Btm+B//+B//+A//8AAAAAAAAAAAAA=="); + if (s=="corona-warn") return atob("GBgBAAAAABwAAP+AAf/gA//wB/PwD/PgDzvAHzuAP8EAP8AAPAAAPMAAP8AAH8AAHzsADzuAB/PAB/PgA//wAP/gAH+AAAwAAAAA"); + if (s=="discord") return atob("GBgBAAAAAAAAAAAAAIEABwDgDP8wH//4H//4P//8P//8P//8Pjx8fhh+fzz+f//+f//+e//ePH48HwD4AgBAAAAAAAAAAAAAAAAA"); if (s=="facebook") return getFBIcon(); + if (s=="gmail") return getNotificationImage(); + if (s=="google home") return atob("GBiCAAAAAAAAAAAAAAAAAAAAAoAAAAAACqAAAAAAKqwAAAAAqroAAAACquqAAAAKq+qgAAAqr/qoAACqv/6qAAKq//+qgA6r///qsAqr///6sAqv///6sAqv///6sAqv///6sA6v///6sA6v///qsA6qqqqqsA6qqqqqsA6qqqqqsAP7///vwAAAAAAAAAAAAAAAAA=="); if (s=="hangouts") return atob("FBaBAAH4AH/gD/8B//g//8P//H5n58Y+fGPnxj5+d+fmfj//4//8H//B//gH/4A/8AA+AAHAABgAAAA="); if (s=="home assistant") return atob("FhaBAAAAAADAAAeAAD8AAf4AD/3AfP8D7fwft/D/P8ec572zbzbNsOEhw+AfD8D8P4fw/z/D/P8P8/w/z/AAAAA="); if (s=="instagram") return atob("GBiBAAAAAAAAAAAAAAAAAAP/wAYAYAwAMAgAkAh+EAjDEAiBEAiBEAiBEAiBEAjDEAh+EAgAEAwAMAYAYAP/wAAAAAAAAAAAAAAAAA=="); - if (s=="gmail") return getNotificationImage(); - if (s=="google home") return atob("GBiCAAAAAAAAAAAAAAAAAAAAAoAAAAAACqAAAAAAKqwAAAAAqroAAAACquqAAAAKq+qgAAAqr/qoAACqv/6qAAKq//+qgA6r///qsAqr///6sAqv///6sAqv///6sAqv///6sA6v///6sA6v///qsA6qqqqqsA6qqqqqsA6qqqqqsAP7///vwAAAAAAAAAAAAAAAAA=="); + if (s=="kalender") return atob("GBgBBgBgBQCgff++RQCiRgBiQAACf//+QAACQAACR//iRJkiRIEiR//iRNsiRIEiRJkiR//iRIEiRIEiR//iQAACQAACf//+AAAA"); + if (s=="lieferando") return atob("GBgBABgAAH5wAP9wAf/4A//4B//4D//4H//4P/88fV8+fV4//V4//Vw/HVw4HVw4HBg4HBg4HBg4HDg4Hjw4Hj84Hj44Hj44Hj44"); if (s=="mail") return getNotificationImage(); if (s=="messenger") return getFBIcon(); - if (s=="outlook mail") return getNotificationImage(); + if (s=="nina") return atob("GBgBAAAABAAQCAAICAAIEAAEEgAkJAgSJBwSKRxKSj4pUn8lVP+VVP+VUgAlSgApKQBKJAASJAASEgAkEAAECAAICAAIBAAQAAAA"); + if (s=="outlook mail") return atob("HBwBAAAAAAAAAAAIAAAfwAAP/gAB/+AAP/5/A//v/D/+/8P/7/g+Pv8Dye/gPd74w5znHDnOB8Oc4Pw8nv/Dwe/8Pj7/w//v/D/+/8P/7/gf/gAA/+AAAfwAAACAAAAAAAAAAAA="); if (s=="phone") return atob("FxeBABgAAPgAAfAAB/AAD+AAH+AAP8AAP4AAfgAA/AAA+AAA+AAA+AAB+AAB+AAB+OAB//AB//gB//gA//AA/8AAf4AAPAA="); + if (s=="post & dhl") return atob("GBgBAPgAE/5wMwZ8NgN8NgP4NgP4HgP4HgPwDwfgD//AB/+AAf8AAAAABs7AHcdgG4MwAAAAGESAFESAEkSAEnyAEkSAFESAGETw"); + if (s=="signal") return atob("GBgBAAAAAGwAAQGAAhggCP8QE//AB//oJ//kL//wD//0D//wT//wD//wL//0J//kB//oA//ICf8ABfxgBYBAADoABMAABAAAAAAA"); if (s=="skype") return atob("GhoBB8AAB//AA//+Af//wH//+D///w/8D+P8Afz/DD8/j4/H4fP5/A/+f4B/n/gP5//B+fj8fj4/H8+DB/PwA/x/A/8P///B///gP//4B//8AD/+AAA+AA=="); if (s=="slack") return atob("GBiBAAAAAAAAAABAAAHvAAHvAADvAAAPAB/PMB/veD/veB/mcAAAABzH8B3v+B3v+B3n8AHgAAHuAAHvAAHvAADGAAAAAAAAAAAAAA=="); if (s=="sms message") return getNotificationImage(); - if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); - if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA"); + if (s=="snapchat") return atob("GBgBAAAAAAAAAH4AAf+AAf+AA//AA//AA//AA//AA//AH//4D//wB//gA//AB//gD//wH//4f//+P//8D//wAf+AAH4AAAAAAAAA"); + if (s=="teams") return atob("GBgBAAAAAAAAAAQAAB4AAD8IAA8cP/M+f/scf/gIeDgAfvvefvvffvvffvvffvvff/vff/veP/PeAA/cAH/AAD+AAD8AAAQAAAAA"); if (s=="telegram") return atob("GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA=="); + if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); + if (s=="to do") return atob("GBgBAAAAAAAAAAAwAAB4AAD8AAH+AAP/DAf/Hg//Px/+f7/8///4///wf//gP//AH/+AD/8AB/4AA/wAAfgAAPAAAGAAAAAAAAAA"); + if (s=="twitch") return atob("GBgBH//+P//+P//+eAAGeAAGeAAGeDGGeDOGeDOGeDOGeDOGeDOGeDOGeAAOeAAOeAAcf4/4f5/wf7/gf//Af/+AA/AAA+AAAcAA"); + if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA"); if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA=="); if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql"); + if (s=="youtube") return atob("GBgBAAAAAAAAAAAAAAAAAf8AH//4P//4P//8P//8P5/8P4/8f4P8f4P8P4/8P5/8P//8P//8P//4H//4Af8AAAAAAAAAAAAAAAAA"); if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A="); if (msg.id=="back") return getBackImage(); return getNotificationImage(); @@ -115,28 +129,38 @@ function getMessageImageCol(msg,def) { return { // generic colors, using B2-safe colors "alarm": "#fff", - "calendar": "#f00", "mail": "#ff0", "music": "#f0f", "phone": "#0f0", "sms message": "#0ff", // brands, according to https://www.schemecolor.com/?s (picking one for multicolored logos) // all dithered on B2, but we only use the color for the icons. (Could maybe pick the closest 3-bit color for B2?) + "bibel": "#54342c", + "discord": "#738adb", "facebook": "#4267b2", "gmail": "#ea4335", "google home": "#fbbc05", - "home assistant": "#fff", // ha-blue is #41bdf5, but that's the background "hangouts": "#1ba261", + "home assistant": "#fff", // ha-blue is #41bdf5, but that's the background "instagram": "#dd2a7b", + "liferando": "#ee5c00", "messenger": "#0078ff", + "nina": "#e57004", "outlook mail": "#0072c6", + "post & dhl": "#f2c101", + "signal": "#00f", "skype": "#00aff0", "slack": "#e51670", - "threema": "#000", + "snapchat": "#ff0", + "teams": "#464eb8", "telegram": "#0088cc", + "threema": "#000", + "to do": "#3999e5", + "twitch": "#6441A4", "twitter": "#1da1f2", "whatsapp": "#4fce5d", "wordfeud": "#e7d3c7", + "youtube": "#f00", }[(msg.src||"").toLowerCase()]||(def !== undefined?def:g.theme.fg); } diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index edc072714..dfeedaef7 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.29", + "version": "0.30", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 2aac234b42b827de1fb976a11dca3029ec65b9cb Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 2 Apr 2022 14:25:41 +0100 Subject: [PATCH 233/253] Daisy 0.06 changed Steps to STEPS, enahnced contrast when using light theme --- apps/daisy/ChangeLog | 1 + apps/daisy/README.md | 3 ++- apps/daisy/app.js | 25 ++++++++++++++++--------- apps/daisy/metadata.json | 4 ++-- apps/daisy/screenshot_daisy2.jpg | Bin 4775 -> 0 bytes apps/daisy/screenshot_daisy2.png | Bin 0 -> 1246 bytes apps/daisy/screenshot_daisy3.png | Bin 0 -> 3265 bytes 7 files changed, 21 insertions(+), 12 deletions(-) delete mode 100644 apps/daisy/screenshot_daisy2.jpg create mode 100644 apps/daisy/screenshot_daisy2.png create mode 100644 apps/daisy/screenshot_daisy3.png diff --git a/apps/daisy/ChangeLog b/apps/daisy/ChangeLog index 26396b75c..d1778dde9 100644 --- a/apps/daisy/ChangeLog +++ b/apps/daisy/ChangeLog @@ -3,3 +3,4 @@ 0.03: fix metadata.json to allow setting as clock 0.04: added heart rate which is switched on when cycled to it through up/down touch on rhs 0.05: changed text to uppercase, just looks better, removed colons on text +0.06: better contrast for light theme, use fg color of dithered ring color diff --git a/apps/daisy/README.md b/apps/daisy/README.md index 12a55ddfd..491ed697f 100644 --- a/apps/daisy/README.md +++ b/apps/daisy/README.md @@ -28,5 +28,6 @@ See [#1248](https://github.com/espruino/BangleApps/issues/1248) ## Screenshots ![](screenshot_daisy1.png) +![](screenshot_daisy3.png) -It is worth looking at the real thing though as the screenshot does not do it justice. +It is worth looking at the real thing though as the screenshots do not do it justice. diff --git a/apps/daisy/app.js b/apps/daisy/app.js index cf0287616..7c513726f 100644 --- a/apps/daisy/app.js +++ b/apps/daisy/app.js @@ -41,10 +41,17 @@ Graphics.prototype.setFontRoboto20 = function(scale) { }; function assignPalettes() { - // palette for 0-40% - pal1 = new Uint16Array([g.theme.bg, g.toColor(settings.gy), g.toColor(settings.fg), g.toColor("#00f")]); - // palette for 50-100% - pal2 = new Uint16Array([g.theme.bg, g.toColor(settings.fg), g.toColor(settings.gy), g.toColor("#00f")]); + if (g.theme.dark) { + // palette for 0-40% + pal1 = new Uint16Array([g.theme.bg, g.toColor(settings.gy), g.toColor(settings.fg), g.toColor("#00f")]); + // palette for 50-100% + pal2 = new Uint16Array([g.theme.bg, g.toColor(settings.fg), g.toColor(settings.gy), g.toColor("#00f")]); + } else { + // palette for 0-40% + pal1 = new Uint16Array([g.theme.bg, g.theme.fg, g.toColor(settings.fg), g.toColor("#00f")]); + // palette for 50-100% + pal2 = new Uint16Array([g.theme.bg, g.toColor(settings.fg), g.theme.fg, g.toColor("#00f")]); + } } function setSmallFont20() { @@ -109,10 +116,10 @@ function updateSunRiseSunSet(now, lat, lon, line){ const infoData = { ID_DATE: { calc: () => {var d = (new Date()).toString().split(" "); return d[2] + ' ' + d[1] + ' ' + d[3];} }, ID_DAY: { calc: () => {var d = require("locale").dow(new Date()).toLowerCase(); return d[0].toUpperCase() + d.substring(1);} }, - ID_SR: { calc: () => 'Sunrise ' + sunRise }, - ID_SS: { calc: () => 'Sunset ' + sunSet }, - ID_STEP: { calc: () => 'Steps ' + getSteps() }, - ID_BATT: { calc: () => 'Battery ' + E.getBattery() + '%' }, + ID_SR: { calc: () => 'SUNRISE ' + sunRise }, + ID_SS: { calc: () => 'SUNSET ' + sunSet }, + ID_STEP: { calc: () => 'STEPS ' + getSteps() }, + ID_BATT: { calc: () => 'BATTERY ' + E.getBattery() + '%' }, ID_HRM: { calc: () => hrmCurrent } }; @@ -225,7 +232,7 @@ function drawSteps() { setSmallFont(); g.setFontAlign(0,0); g.setColor(g.theme.fg); - g.drawString('Steps ' + getSteps(), w/2, (3*h/4) - 4); + g.drawString('STEPS ' + getSteps(), w/2, (3*h/4) - 4); drawingSteps = false; } diff --git a/apps/daisy/metadata.json b/apps/daisy/metadata.json index 15a24592c..6225db055 100644 --- a/apps/daisy/metadata.json +++ b/apps/daisy/metadata.json @@ -1,13 +1,13 @@ { "id": "daisy", "name": "Daisy", - "version":"0.05", + "version":"0.06", "dependencies": {"mylocation":"app"}, "description": "A clock based on the Pastel clock with large ring guage for steps", "icon": "app.png", "type": "clock", "tags": "clock", "supports" : ["BANGLEJS2"], - "screenshots": [{"url":"screenshot_daisy2.jpg"}], + "screenshots": [{"url":"screenshot_daisy2.png"}], "readme": "README.md", "storage": [ {"name":"daisy.app.js","url":"app.js"}, diff --git a/apps/daisy/screenshot_daisy2.jpg b/apps/daisy/screenshot_daisy2.jpg deleted file mode 100644 index fec6a4c7b82c9dd40f3993017eb3edaa1a457b1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4775 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 diff --git a/apps/daisy/screenshot_daisy2.png b/apps/daisy/screenshot_daisy2.png new file mode 100644 index 0000000000000000000000000000000000000000..3636f376652628060fe0dedd8b4d631bfc44c7f5 GIT binary patch literal 1246 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 Date: Sat, 2 Apr 2022 14:43:10 +0100 Subject: [PATCH 234/253] Daisy 0.06 changed Steps to STEPS, enhanced contrast when using light theme --- apps/daisy/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daisy/metadata.json b/apps/daisy/metadata.json index 6225db055..85cefeaf2 100644 --- a/apps/daisy/metadata.json +++ b/apps/daisy/metadata.json @@ -7,7 +7,7 @@ "type": "clock", "tags": "clock", "supports" : ["BANGLEJS2"], - "screenshots": [{"url":"screenshot_daisy2.png"}], + "screenshots": [{"url":"screenshot_daisy3.png"}], "readme": "README.md", "storage": [ {"name":"daisy.app.js","url":"app.js"}, From b28478f1d9f087f67923d731181994885f03f96d Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 2 Apr 2022 14:56:54 +0100 Subject: [PATCH 235/253] Daisy 0.06 changed Steps to STEPS, enhanced contrast when using light theme --- apps/daisy/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daisy/metadata.json b/apps/daisy/metadata.json index 85cefeaf2..5073db603 100644 --- a/apps/daisy/metadata.json +++ b/apps/daisy/metadata.json @@ -2,7 +2,7 @@ "name": "Daisy", "version":"0.06", "dependencies": {"mylocation":"app"}, - "description": "A clock based on the Pastel clock with large ring guage for steps", + "description": "A beautiful digital clock with large ring guage, idle timer and a cyclic information line that includes, day, date, steps, battery, sunrise and sunset times", "icon": "app.png", "type": "clock", "tags": "clock", From 43a052374c4542019785e34fea17d66f45bd43bc Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 2 Apr 2022 15:00:27 +0100 Subject: [PATCH 236/253] Daisy 0.06 changed Steps to STEPS, enhanced contrast when using light theme --- apps/daisy/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daisy/ChangeLog b/apps/daisy/ChangeLog index d1778dde9..d5844c62b 100644 --- a/apps/daisy/ChangeLog +++ b/apps/daisy/ChangeLog @@ -3,4 +3,4 @@ 0.03: fix metadata.json to allow setting as clock 0.04: added heart rate which is switched on when cycled to it through up/down touch on rhs 0.05: changed text to uppercase, just looks better, removed colons on text -0.06: better contrast for light theme, use fg color of dithered ring color +0.06: better contrast for light theme, use fg color instead of dithered for ring From 6fe1a7e1d94e881ff921de94704099a64b033796 Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 15:59:39 -0400 Subject: [PATCH 237/253] New app 'bee', add game statistics to 'bordle' app. --- apps/bee/README.md | 34 + apps/bee/app-icon.js | 1 + apps/bee/app.png | Bin 0 -> 2145 bytes apps/bee/bee.app.js | 192 + apps/bee/bee_lindex.json | 1 + apps/bee/bee_screenshot.png | Bin 0 -> 1338 bytes apps/bee/bee_words_2of12 | 74578 ++++++++++++++++++++++++++++++++++ apps/bee/metadata.json | 16 + apps/bordle/bordle.app.js | 46 +- 9 files changed, 74861 insertions(+), 7 deletions(-) create mode 100644 apps/bee/README.md create mode 100644 apps/bee/app-icon.js create mode 100644 apps/bee/app.png create mode 100644 apps/bee/bee.app.js create mode 100644 apps/bee/bee_lindex.json create mode 100644 apps/bee/bee_screenshot.png create mode 100644 apps/bee/bee_words_2of12 create mode 100644 apps/bee/metadata.json diff --git a/apps/bee/README.md b/apps/bee/README.md new file mode 100644 index 000000000..1beece1af --- /dev/null +++ b/apps/bee/README.md @@ -0,0 +1,34 @@ + +# Spelling bee game + +Word finding game inspired by the NYT spelling bee. Find as many words with 4 or more letters (must include the +letter at the center of the 'hive'). + + +Usage: + - tap on letters to type out word + - swipe left to delete last letter + - swipe right to enter; the word will turn blue while is being checked against the internal dictionary; once + checked, it will turn red if the word is invalid, does not contain the central letter or has been guessed before or + green if it is a valid word; in the latter case, points will be awarded + - swipe down to shuffle the 6 outer letters + - swipe up to view a list of already guessed words; tap on any of them to return to the regular game. + + +Scoring: +The number of correctly guessed words is displayed on the bottom left, the score on the bottom right. A single point +is awarded for a 4 letter word, or the number of letters if longer. A pangram is a word that contains all 7 letters at +least once and yields an additional 7 points. Each game contains at least one pangram. + + +Technical remarks: +The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words'). The dictionary is fairly +large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat +slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory). +In order to make checking for the validity of a guessed word faster, an index file ('bee_lindex.json') is installed with +the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to +replace the dictionary file with a different version (e.g. a different language) the index file has to be regenerated. The easiest +way to do so is to delete (via the Web IDE or the fileman app on the watch) the file 'bee_lindex.json' - it will be regenerated (and saved, +i.e. it only happens once) on app startup automatically, a process that takes roughly 30 seconds. + +![Screenshot](./bee_screenshot.png) diff --git a/apps/bee/app-icon.js b/apps/bee/app-icon.js new file mode 100644 index 000000000..f3bf5dbb2 --- /dev/null +++ b/apps/bee/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AE2JAAIKHnc7DyNPp4vRGAwuBGB4sBAAQvSGIovPFqYvHGAYvDGBYsGGhwvGGIQvEGBQnDMYhkNGBAvOvQABqyRTF5GJr4wLFwQACX6IwLsowJLYMrldVGAQvTsoADGBITD0YvDldPF6n+F4gyGGAdP5nMF4KKBGDJZDGI7EBcoOiGAK7DGAQvYRogxEr1Pp9VMAiSBBILBWeJIxCromBMAQwDAAZfTGBQyCxOCGAIvBGIV/F7AwMAAOIp95GAYACFqoyQMAIwGF7QADEQd5FgIADqvGF8DnEAAIvFGIWjF8CFE0QwHAAQudAAK0EGBQuecw3GqpemYIxiCGIa8cF4wwHdTwvJp9/F82jGA9VMQovf5jkHGIwvg4wvIAAgvg5miF9wwNF8QABF9QwF0YuoF4oxCqoulGBAAB42i0QvjGBPMF0gwIFswwHF1IA/AH4A/AH4AL")) diff --git a/apps/bee/app.png b/apps/bee/app.png new file mode 100644 index 0000000000000000000000000000000000000000..ed16c44b17415aba02d261f0a2b607713201f147 GIT binary patch literal 2145 zcmV-n2%h(eP)Wa%1m3q4yG15t;Mn9*n%jcZND%+5bH=Cs(m=LHV;Hh0tzBfAWDSr2!Vt=xJm9g z_ng%aF-XGA&5gNEXFB=MoDXO3|61$6_C9CtwKoi77{eF_!0oTA`M-!Ou{xir32y*y z0A2`NzSTd!PTHgKO8yj@FD`#Z<(aa(lYW7Sepx|F=FRiBb~fFlDz_utBtw%;8DNNx^Hbwc-cdR{?~gkR7GCxTn!pPboq@NJ1K(|gB9JS!giYDM7AG0apI(9 zMQ#I*09B&;ftq|^y4Hs;R_tyWR005NYr3{7a(ygL#8q~kayfaf&*Gyr7{2h-ckW1U z?Q8SYlKYn;y0&k7IBfAr-QhOZ3QdS6xG!S=1Aw^3BS0h;$72Yy#+u}(8@)$F$ad|( zFZ=SJT)a3H(I=XkTlo7s?^3p{hPtCCP*wbXANiL~ZnR``*4pFmfFRtt2@p^L41)S1^Bml6i(En>g^sR_05myP>&=^uaX>mE!>~N+-aop}? zE=d-yA8!)$o;UY-A}znUr?{xhvgK`Hb#_|Q4*{|=(;1VMah}+4x{199Kk0cbT~)ep zL_!h(C@_-lye!>lEXXjN$!P|cBnzYbf+{qGTn;uX4IvlHffS!Gcf3hfP(U@5_2xr! zTqxOjVAOtqtkkm@;v&G+Gp3P~opnCWk@}NFA`U>hVSB%oump}k#5BZb7-9xILVA+H zxDshx#@b5N79?T+XLwJuRP&2iRPeZ386v!_1s~007f8m^EV> zb7sw8!nm243YkG+(kO!|874umaJ=2+=-Ro~wMjBU4%V+x3$%x43`sLg}x&~E2&VS_b z?b_ws2#oL7p+L|pqy>b4M`*WQ%(3~TU3xif`?eW7K2EBickSs+L(~|Tb&8pJ2T4zE zLshUMKJ3Wn<(crFVNklIYFB40O#|)&eewK0O}0YTdVxCzV`n=MX+FmORd+FCN^AMU zch{9f7bq9r5@bbOJqidZ%@zxOxksxq@V?G6o0&0TU|&T(66%>KZ`| zQvjT<5W63p2f!71t(D6b)Xj~mLHLo(4gc{gO&}T`xcTZke*ehcH6D+f)6@3i-*Weq z?MS~IF%Z*4BVW`U8L9UBEAFiwJ37sp*xQpXmm93##uGDPr>F%bMZa?*^7Qm6?I$u) zt<0YGsT0qQ-tvCdNylX*uG`C|Gi;9kXH}MW$No|8`8*sQHPW^NJ~dF@e(XhOXFPEe zG6Rcln7u?rp9Q!wzqR70chwbN*njv~u;sD!d0us8z>Nv$^tf*R3tM;8#}j+VGjMlt z(KvxO5xf8m&4ILe*PM=cJnHM=q@~z_{M?SS+xMhJ6bZ!kDC=LUta&xw_;K$8{X3AA z2*I9rRZ^eYIO)T_yn;#XV^%FaAQ_|Vz5RRBzb1{eA0ABnA$>yKXW8aPgp|HY?!Wcu zj=5Jh7e=$&eK4i=FO}I%#~PC|ElUg)4jQ7bOe(K=Z6&zTZ2H5H5_o*k^luzG8vIv3 z-JMJBtUGXZL2ImXz{U0CNJ*&S%W4?XC$wT=ZLZ(z9_^<)Y29mI%iml+W?RhoVn^N3 z;>C~>F#YbBTZ>Pf?w240H&=|ku5@id)rm8KBhfjM6SX}~4DBa&<=p&hPhFLk64@P# z*4XTuy?ou&am&|Tw!Qp=jOwni`9+bY8jN8&Acpi0Xr=FaAa9&$^`0($y1;Q&qTNtL zgY7Z&xXvvFE_Bd$#B=<-ajJ(_fA zV0!-;@=mOk{#sx%z~SQ~4nDqqa?o+4-*USTj&G=_9uIu!yVN0XWQd%f{z*BZ{I$#W zC8dsxRL5njtY-+~ArT2UyZ~4|uPMoq%yp%Ei|(0U|E_6h^p&R@Exv$p(Y?@Mk&t3e zEB(&{Kfb74vA2DcQN6irj5M|R^7Mk6W)JeCBqo9Kk(n6QN5CbqXs6EjKWhzn zyIR}Kvcd-&A528-gdJ$KJW!0GTL51y8n6a$_*XKAm}lL1kMM|4O0dcyv4Is)-$>VGLs!|7Z9w XLWm}&-3OsD00000NkvXXu0mjfj8ZL+ literal 0 HcmV?d00001 diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js new file mode 100644 index 000000000..4989296e0 --- /dev/null +++ b/apps/bee/bee.app.js @@ -0,0 +1,192 @@ + +const S = require("Storage"); +var letters = []; +var letterIdx = []; + +var centers = []; + +var word = ''; + +var foundWords = []; +var score = 0; + +var intervalID = -1; + +function prepareLetterIdx () { + "compile" + var li = [0]; + if (S.read("bee_lindex.json")!==undefined) li = S.readJSON("bee_lindex.json"); // check for cached index + else { + for (var i=1; i<26; ++i) { + var prefix = String.fromCharCode(97+i%26); + console.log(prefix); + li.push(words.indexOf("\n"+prefix, li[i-1])+1); + } + li.push(words.length); + S.writeJSON("bee_lindex.json", li); + } + for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]); +} + +function findWord (w) { + "compile" + var ci = w.charCodeAt(0)-97; + var f = letterIdx[ci].indexOf(w); + if (f>=0 && letterIdx[ci][f+w.length]=="\n") return true; + return false; +} + +function isPangram(w) { + var ltrs = ''; + for (var i=0; i=0) return false; // already found + if (findWord(w)) { + foundWords.push(w); + if (w.length==4) score++; + else score += w.length; + if (isPangram(w)) score += 7; + return true; + } + return false; +} + +function getHexPoly(cx, cy, r, a) { + var p = []; + for (var i=0; i<6; ++i) p.push(cx+r*Math.sin((i+a)/3*Math.PI), cy+r*Math.cos((i+a)/3*Math.PI)); + return p; +} + +function drawHive() { + w = g.getWidth(); + h = g.getHeight(); + const R = w/3.3; + centers = getHexPoly(w/2, h/2+10, R, 0); + centers.push(w/2, h/2+10); + g.clear(); + g.setFont("Vector", w/7).setFontAlign(0, 0, 0); + g.setColor(g.theme.fg); + for (var i=0; i<6; ++i) { + g.drawPoly(getHexPoly(centers[2*i], centers[2*i+1], 0.9*R/Math.sqrt(3), 0.5), {closed:true}); + g.drawString(String.fromCharCode(65+letters[i+1]), centers[2*i]+2, centers[2*i+1]+2); + } + g.setColor(1, 1, 0).fillPoly(getHexPoly(w/2, h/2+10, 0.9*R/Math.sqrt(3), 0.5)); + g.setColor(0).drawString(String.fromCharCode(65+letters[0]), w/2+2, h/2+10+2); +} + +function shuffleLetters(qAll) { + for (var i=letters.length-1; i > 0; i--) { + var j = (1-qAll) + Math.floor(Math.random()*(i+qAll)); + var temp = letters[i]; + letters[i] = letters[j]; + letters[j] = temp; + } +} + +function pickLetters() { + var ltrs = ""; + while (ltrs.length!==7) { + ltrs = []; + var j = Math.floor(26*Math.random()); + var i = Math.floor((letterIdx[j].length-10)*Math.random()); + while (letterIdx[j][i]!="\n" && i0) { + word = word.slice(0, -1); + drawWord(g.theme.fg); + } + if (d==1 && word.length>=4) { + drawWord("#00f"); + drawWord((checkWord(word.toLowerCase()) ? "#0f0" : "#f00")); + if (intervalID===-1) intervalID = setInterval(wordFound, 800); + } + if (e===1) { + shuffleLetters(0); + drawHive(); + drawScore(); + drawWord(g.theme.fg); + } + if (e===-1 && foundWords.length>0) showWordList(); +} + +function showWordList() { + Bangle.removeListener("touch", touchHandler); + Bangle.removeListener("swipe", swipeHandler); + E.showScroller({ + h : 20, c : foundWords.length, + draw : (idx, r) => { + g.clearRect(r.x,r.y,r.x+r.w-1,r.y+r.h-1); + g.setFont("6x8:2").drawString(foundWords[idx].toUpperCase(),r.x+10,r.y+4); + }, + select : (idx) => { + setInterval(()=> { + E.showScroller(); + drawHive(); + drawScore(); + Bangle.on("touch", touchHandler); + Bangle.on("swipe", swipeHandler); + clearInterval(); + }, 100); + } + }); +} + +prepareLetterIdx(); +pickLetters(); +drawHive(); +drawScore(); +Bangle.on("touch", touchHandler); +Bangle.on("swipe", swipeHandler); diff --git a/apps/bee/bee_lindex.json b/apps/bee/bee_lindex.json new file mode 100644 index 000000000..e4fa13037 --- /dev/null +++ b/apps/bee/bee_lindex.json @@ -0,0 +1 @@ +[0,41048,80445,152390,198606,228714,257919,279071,303726,337982,343582,348026,367246,404452,419780,438696,496250,499697,544600,624304,659085,680996,691270,708186,708341,709916,710883] \ No newline at end of file diff --git a/apps/bee/bee_screenshot.png b/apps/bee/bee_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..cd173b9978f4c906fb63e4957e41793a70da8350 GIT binary patch literal 1338 zcmV-A1;zS_P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00009 zP)t-s00030|NsC00A6}Z?f?J)0b)x>L;?Q-E#3eC00(qQO+^Rh1Of{l24Xi!e*gdk zE=fc|R9M5+nK7>1AP|OOWj9;7cEfy7MH_Z5 z=U_Dk|F3DbK8(yj&uTJI}*LlcS)t}I_#fTL;fk? zs7P=>ssZ%HsSeW>sSc-BB!y{qMGQ(vmi-<~8%e#IST=*5pZQ6h z!{{cguL!65;I*(XPjxu$g8{Z2UI?7J1zj~RWMbV?1deiqw*t(4Y7~aqf$)Oy2DFUu zQir+vIXp2q+m2lbD`Z$%XNFQa!c&A_qQ87aHfUGCbbJWhU2<;;-s>>&DGJwDev*4n@bd)5Wy+p&G zQ|>*%&u;Y9pM#fX_oa2?(u#CxtxK&)3e)V07$fU5eeA9LVNWq!yPfY#3|{NIRRQBZ zs6@FB76FxyzAWyJ8&l5Y+8u4+ZB)4(XWAXjYp_K-hubh zxjTd16k8kc!YT{!*m~H`@)kyfeQ9H*Bul^Iw2n$(+Lq&C0(`xRO*TytAhf z&Ee8FtO(Z_l}{wDBo-D)WxvgI30^XDJ_nzF5&I2s0{&02e=r6B001R)MObuXVRU6W zV{&C-bY%cCFfuYNFf=VNGE^}&Ix{djFg7hPG&(RaZ!PlY0000bbVXQnWMOn=I&E)c wX=Zr0 && b==2) inp = inp.slice(0,-1); + if (keyStateIdx==6 && b==5) { + wordle.drawStats(); + return; + } layout.input.label = inp; } layout = getKeyLayout(inp); @@ -82,6 +87,7 @@ class Wordle { this.word = this.words.slice(i, i+5).toUpperCase(); } console.log(this.word); + this.stats = require("Storage").readJSON("bordlestats.json") || {'1':0, '2':0, '3':0, '4':0, '5':0, '6':0, 'p':0, 'w':0, 's':0, 'ms':0}; } render(clear) { h = g.getHeight(); @@ -109,7 +115,7 @@ class Wordle { layout = getKeyLayout(""); wordle.render(true); }); - return 3; + return 1; } this.guesses.push(w); this.nGuesses++; @@ -130,13 +136,39 @@ class Wordle { this.guessColors[this.nGuesses].push(col); } if (correct==5) { - E.showAlert("The word is\n"+this.word, "You won in "+(this.nGuesses+1)+" guesses!").then(function(){load();}); - return 1; - } - if (this.nGuesses==5) { - E.showAlert("The word was\n"+this.word, "You lost!").then(function(){load();}); + E.showAlert("The word is\n"+this.word, "You won in "+(this.nGuesses+1)+" guesses!").then(function(){ + wordle.stats['p']++; wordle.stats['w']++; wordle.stats['s']++; wordle.stats[wordle.nGuesses+1]++; + if (wordle.stats['s']>wordle.stats['ms']) wordle.stats['ms'] = wordle.stats['s']; + require("Storage").writeJSON("bordlestats.json", wordle.stats); + wordle.drawStats(); + }); return 2; } + if (this.nGuesses==5) { + E.showAlert("The word was\n"+this.word, "You lost!").then(function(){ + wordle.stats['p']++; wordle.stats['s'] = 0; + require("Storage").writeJSON("bordlestats.json", wordle.stats); + wordle.drawStats(); + }); + return 3; + } + } + drawStats() { + E.showMessage(" ", "Statistics"); + var max = 1; + for (i=1; i<=6; ++i) if (max20 ? 25 : 25+tw, 52+(i-0.5)*(h-52)/6); + } + g.setFontVector((h-40)/9).setColor("#fff").drawString("P:"+this.stats["p"]+" W:"+this.stats["w"]+" S:"+this.stats["s"]+" M:"+this.stats["ms"], 4, 34); + Bangle.setUI(); + Bangle.on("touch", (e) => { load(); }); } } From 5b93e7f6e54f6c2154b63d08cc8b631cf8df77db Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 16:08:21 -0400 Subject: [PATCH 238/253] Edits of README.md, fix small filename bug in app. --- apps/bee/README.md | 12 +++++++----- apps/bee/bee.app.js | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/bee/README.md b/apps/bee/README.md index 1beece1af..f065d45a6 100644 --- a/apps/bee/README.md +++ b/apps/bee/README.md @@ -5,7 +5,8 @@ Word finding game inspired by the NYT spelling bee. Find as many words with 4 or letter at the center of the 'hive'). -Usage: +## Usage + - tap on letters to type out word - swipe left to delete last letter - swipe right to enter; the word will turn blue while is being checked against the internal dictionary; once @@ -15,15 +16,16 @@ Usage: - swipe up to view a list of already guessed words; tap on any of them to return to the regular game. -Scoring: +## Scoring + The number of correctly guessed words is displayed on the bottom left, the score on the bottom right. A single point is awarded for a 4 letter word, or the number of letters if longer. A pangram is a word that contains all 7 letters at least once and yields an additional 7 points. Each game contains at least one pangram. -Technical remarks: -The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words'). The dictionary is fairly -large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat +## Technical remarks +The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words', using the '2of12inf' word list). +The dictionary is fairly large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory). In order to make checking for the validity of a guessed word faster, an index file ('bee_lindex.json') is installed with the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index 4989296e0..7be7c83ce 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -22,7 +22,7 @@ function prepareLetterIdx () { console.log(prefix); li.push(words.indexOf("\n"+prefix, li[i-1])+1); } - li.push(words.length); + li.push(require("Storage").read('bee.words').length); S.writeJSON("bee_lindex.json", li); } for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]); From c19b876820f0516e577843788910b73569c8ea12 Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 17:23:42 -0400 Subject: [PATCH 239/253] Fix some typos. --- apps/bee/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/bee/README.md b/apps/bee/README.md index f065d45a6..c6461fb8e 100644 --- a/apps/bee/README.md +++ b/apps/bee/README.md @@ -2,16 +2,16 @@ # Spelling bee game Word finding game inspired by the NYT spelling bee. Find as many words with 4 or more letters (must include the -letter at the center of the 'hive'). +letter at the center of the 'hive') as you can. ## Usage - tap on letters to type out word - swipe left to delete last letter - - swipe right to enter; the word will turn blue while is being checked against the internal dictionary; once + - swipe right to enter; the word will turn blue while it is being checked against the internal dictionary; once checked, it will turn red if the word is invalid, does not contain the central letter or has been guessed before or - green if it is a valid word; in the latter case, points will be awarded + will turn green if it is a valid word; in the latter case, points will be awarded - swipe down to shuffle the 6 outer letters - swipe up to view a list of already guessed words; tap on any of them to return to the regular game. @@ -27,7 +27,7 @@ least once and yields an additional 7 points. Each game contains at least one pa The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words', using the '2of12inf' word list). The dictionary is fairly large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory). -In order to make checking for the validity of a guessed word faster, an index file ('bee_lindex.json') is installed with +In order to make checking the validity of a guessed word faster an index file ('bee_lindex.json') is installed with the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to replace the dictionary file with a different version (e.g. a different language) the index file has to be regenerated. The easiest way to do so is to delete (via the Web IDE or the fileman app on the watch) the file 'bee_lindex.json' - it will be regenerated (and saved, From 2d042ee380227e7dfe281170346a258e48e8d7a4 Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 2 Apr 2022 17:34:18 -0400 Subject: [PATCH 240/253] Restore word display on return from word list view. --- apps/bee/bee.app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index 7be7c83ce..f0ae5badd 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -22,7 +22,7 @@ function prepareLetterIdx () { console.log(prefix); li.push(words.indexOf("\n"+prefix, li[i-1])+1); } - li.push(require("Storage").read('bee.words').length); + li.push(S.read('bee.words').length); S.writeJSON("bee_lindex.json", li); } for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]); @@ -176,6 +176,7 @@ function showWordList() { E.showScroller(); drawHive(); drawScore(); + drawWord(g.theme.fg); Bangle.on("touch", touchHandler); Bangle.on("swipe", swipeHandler); clearInterval(); From fff5ddef67ace7522d9a9a2dc7ae9d53fb666837 Mon Sep 17 00:00:00 2001 From: Salim Blume Date: Sat, 2 Apr 2022 20:54:23 -0500 Subject: [PATCH 241/253] Add maxbpm as a tracked stat in exstats. --- modules/exstats.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/exstats.js b/modules/exstats.js index 5d7cf0c2b..830398a51 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -15,6 +15,7 @@ print(ExStats.getList()); {name: "Distance", id:"dist"}, {name: "Steps", id:"step"}, {name: "Heart (BPM)", id:"bpm"}, + {name: "Max BPM", id:"maxbpm"}, {name: "Pace (avr)", id:"pacea"}, {name: "Pace (current)", id:"pacec"}, {name: "Cadence", id:"caden"}, @@ -72,6 +73,7 @@ var state = { // cadence // steps per minute adjusted if <1 minute // BPM // beats per minute // BPMage // how many seconds was BPM set? + // maxBPM // The highest BPM reached while active // Notifies: 0 for disabled, otherwise how often to notify in meters, seconds, or steps notify: { dist: { @@ -159,6 +161,10 @@ Bangle.on("HRM", function(h) { if (h.confidence>=60) { state.BPM = h.bpm; state.BPMage = 0; + if (state.maxBPM < h.bpm) { + state.maxBPM = h.bpm; + if (stats["maxbpm"]) stats["maxbpm"].emit("changed",stats["maxbpm"]); + } if (stats["bpm"]) stats["bpm"].emit("changed",stats["bpm"]); } }); @@ -170,6 +176,7 @@ exports.getList = function() { {name: "Distance", id:"dist"}, {name: "Steps", id:"step"}, {name: "Heart (BPM)", id:"bpm"}, + {name: "Max BPM", id:"maxbpm"}, {name: "Pace (avg)", id:"pacea"}, {name: "Pace (curr)", id:"pacec"}, {name: "Speed", id:"speed"}, @@ -230,6 +237,14 @@ exports.getStats = function(statIDs, options) { getString : function() { return state.BPM||"--" }, }; } + if (statIDs.includes("bpm")) { + needHRM = true; + stats["maxbpm"]={ + title : "Max BPM", + getValue : function() { return state.maxBPM; }, + getString : function() { return state.maxBPM||"--" }, + }; + } if (statIDs.includes("pacea")) { needGPS = true; stats["pacea"]={ @@ -299,6 +314,7 @@ exports.getStats = function(statIDs, options) { state.curSpeed = 0; state.BPM = 0; state.BPMage = 0; + state.maxBPM = 0; state.notify = options.notify; if (options.notify.dist.increment > 0) { state.notify.dist.next = state.distance + options.notify.dist.increment; From 9f10a3bdfecd63d8e36fc19d46dbb2b0c91ea899 Mon Sep 17 00:00:00 2001 From: Salim Blume Date: Sat, 2 Apr 2022 20:58:49 -0500 Subject: [PATCH 242/253] Update run README for max BPM --- apps/run/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/run/README.md b/apps/run/README.md index 89750eb7d..7f645b518 100644 --- a/apps/run/README.md +++ b/apps/run/README.md @@ -14,7 +14,8 @@ the red `STOP` in the bottom right turns to a green `RUN`. shown will increase, even if you are standing still. * `TIME` - the elapsed time for your run * `PACE` - the number of minutes it takes you to run a given distance, configured in settings (default 1km) **based on your run so far** -* `HEART` - Your heart rate +* `HEART (BPM)` - Your current heart rate +* `Max BPM` - Your maximum heart rate reached during the run * `STEPS` - Steps since you started exercising * `CADENCE` - Steps per second based on your step rate *over the last minute* * `GPS` - this is green if you have a GPS lock. GPS is turned on automatically @@ -35,7 +36,7 @@ Under `Settings` -> `App` -> `Run` you can change settings for this app. record GPS/HRM/etc data every time you start a run? * `Pace` is the distance that pace should be shown over - 1km, 1 mile, 1/2 Marathon or 1 Marathon * `Boxes` leads to a submenu where you can configure what is shown in each of the 6 boxes on the display. - Available stats are "Time", "Distance", "Steps", "Heart (BPM)", "Pace (avg)", "Pace (curr)", "Speed", and "Cadence". + Available stats are "Time", "Distance", "Steps", "Heart (BPM)", "Max BPM", "Pace (avg)", "Pace (curr)", "Speed", and "Cadence". Any box set to "-" will display no information. * Box 1 is the top left (defaults to "Distance") * Box 2 is the top right (defaults to "Time") From 7322013f103bac0de4d219a6cafe5d6c07c5efb9 Mon Sep 17 00:00:00 2001 From: Salim Blume Date: Sat, 2 Apr 2022 21:00:45 -0500 Subject: [PATCH 243/253] Fix for when to include maxbpm --- modules/exstats.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exstats.js b/modules/exstats.js index 830398a51..63d94ec7b 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -237,7 +237,7 @@ exports.getStats = function(statIDs, options) { getString : function() { return state.BPM||"--" }, }; } - if (statIDs.includes("bpm")) { + if (statIDs.includes("maxbpm")) { needHRM = true; stats["maxbpm"]={ title : "Max BPM", From 164683fce5e077af0482290f785becf5c4f57d8d Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Sun, 3 Apr 2022 15:51:01 +0200 Subject: [PATCH 244/253] v0.09 added settings menu, removed symbols button, added highscore reset, clockmode optional --- apps/game1024/ChangeLog | 3 +- apps/game1024/app.js | 69 ++++++++++++++++++------------------ apps/game1024/metadata.json | 3 +- apps/game1024/settings.js | 70 +++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 apps/game1024/settings.js diff --git a/apps/game1024/ChangeLog b/apps/game1024/ChangeLog index c917bb90c..29838413e 100644 --- a/apps/game1024/ChangeLog +++ b/apps/game1024/ChangeLog @@ -5,4 +5,5 @@ 0.05: Chevron marker on the randomly added square 0.06: Fixed issue 1609 added a message popup state handler to control unwanted screen redraw 0.07: Optimized the mover algorithm for efficiency (work in progress) -0.08: Bug fix at end of the game with victorious splash and glorious orchestra \ No newline at end of file +0.08: Bug fix at end of the game with victorious splash and glorious orchestra +0.09: Added settings menu, removed symbol selection button (*), added highscore reset \ No newline at end of file diff --git a/apps/game1024/app.js b/apps/game1024/app.js index 13430ff2d..a70db76c8 100644 --- a/apps/game1024/app.js +++ b/apps/game1024/app.js @@ -1,7 +1,21 @@ -const debugMode = 'off'; // valid values are: off, test, production, development +let settings = Object.assign({ + // default values + maxUndoLevels: 4, + charIndex: 0, + clockMode: true, + debugMode: false, +}, require('Storage').readJSON("game1024.settings.json", true) || {}); + +const clockMode = settings.clockMode!==undefined ? settings.clockMode : true; +const debugMode = settings.debugMode!==undefined ? settings.debugMode : false; // #settings -- valid values are: true or false +const maxUndoLevels = settings.maxUndoLevels!==undefined ? settings.maxUndoLevels : 4; // #settings +const charIndex = settings.charIndex!==undefined ? settings.charIndex : 0; // #settings -- plain numbers on the grid + +delete settings; // remove unneeded settings from memory + const middle = {x:Math.floor(g.getWidth()/2)-20, y: Math.floor(g.getHeight()/2)}; -const rows = 4, cols = 4; -const borderWidth = 6; +const rows = 4, cols = 4; // #settings +const borderWidth = 6; const sqWidth = (Math.floor(Bangle.appRect.w - 48) / rows) - borderWidth; const cellColors = [{bg:'#00FFFF', fg: '#000000'}, {bg:'#FF00FF', fg: '#000000'}, {bg:'#808000', fg: '#FFFFFF'}, {bg:'#0000FF', fg: '#FFFFFF'}, {bg:'#008000', fg: '#FFFFFF'}, @@ -13,12 +27,8 @@ const cellChars = [ ['0','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], ['0','I', 'II', 'III', 'IV', 'V', 'VI', 'VII','VIII', 'IX', 'X'] ]; -// const numInitialCells = 2; -const maxUndoLevels = 4; -const noExceptions = true; -let charIndex = 0; // plain numbers on the grid -const themeBg = g.theme.bg; +const themeBg = g.theme.bg; const scores = { currentScore: 0, @@ -78,12 +88,12 @@ const snapshot = { updCounter: function() { this.counter = ++this.counter > this.interval ? 0 : this.counter; }, - dump: {gridsize: rows * cols, expVals: [], score: 0, highScore: 0, charIndex: charIndex}, + dump: {gridsize: rows * cols, expVals: [], score: 0, highScore: 0}, write: function() { require("Storage").writeJSON(this.snFileName, this.dump); }, read: function () { - let sn = require("Storage").readJSON(this.snFileName, noExceptions); + let sn = require("Storage").readJSON(this.snFileName, true); if ((typeof sn == "undefined") || (sn.gridsize !== rows * cols)) { require("Storage").writeJSON(this.snFileName, this.dump); return false; @@ -101,7 +111,6 @@ const snapshot = { }); this.dump.score = scores.currentScore; this.dump.highScore = scores.highScore; - this.dump.charIndex = charIndex; }, make: function () { this.updCounter(); @@ -118,7 +127,7 @@ const snapshot = { }); scores.currentScore = this.dump.score ? this.dump.score : 0; scores.highScore = this.dump.highScore ? this.dump.highScore : 0 ; - charIndex = this.dump.charIndex ? this.dump.charIndex : 0 ; + if (this.dump.hasOwnProperty('charIndex')) delete this.dump.charIndex; // depricated in v0.09 } }, reset: function () { @@ -129,12 +138,11 @@ const snapshot = { } this.dump.score = 0; this.dump.highScore = scores.highScore; - this.dump.charIndex = charIndex; this.write(); debug(() => console.log("reset D U M P E D!", this.dump)); } }; -const btnAtribs = {x: 134, w: 42, h: 42, fg:'#C0C0C0', bg:'#800000'}; +const btnAtribs = {x: 134, w: 42, h: 50, fg:'#C0C0C0', bg:'#800000'}; const buttons = { all: [], draw: function () { @@ -314,7 +322,7 @@ class Cell { } drawBg() { debug(()=>console.log("Drawbg!!")); - if (this.isRndm == true) { + if (this.isRndm) { debug(()=>console.log('Random: (ax)', this.ax)); g.setColor(this.getColor(this.expVal).bg) .fillRect(this.x0, this.y0, this.x1, this.y1) @@ -365,7 +373,7 @@ class Cell { this.isRndm = true; } drawRndmIndicator(){ - if (this.isRndm == true) { + if (this.isRndm) { debug(()=>console.log('Random: (ax)', this.ax)); g.setColor(this.getColor(0).bg) .fillPoly(this.ax,this.ay,this.bx,this.by,this.cx,this.cy); @@ -374,8 +382,9 @@ class Cell { } function undoGame() { - g.clear(); + if (scores.lastScores.length > 0) { + g.clear(); allSquares.forEach(sq => { sq.popFromUndo(); sq.drawBg(); @@ -386,9 +395,9 @@ function undoGame() { buttons.draw(); updUndoLvlIndex(); snapshot.make(); - } - Bangle.loadWidgets(); + Bangle.loadWidgets(); Bangle.drawWidgets(); + } } function addToUndo() { allSquares.forEach(sq => { @@ -487,8 +496,8 @@ function initGame() { drawGrid(); scores.draw(); buttons.draw(); - // Clock mode allows short-press on button to exit - Bangle.setUI("clock"); + // #settings Clock mode allows short-press on button to exit + if(clockMode) Bangle.setUI("clock"); // Load widgets Bangle.loadWidgets(); Bangle.drawWidgets(); @@ -560,14 +569,8 @@ function resetGame() { * @param {function} func function to call like console.log() */ const debug = (func) => { - switch (debugMode) { - case "development": - if (typeof func === 'function') { - func(); - } - break; - case "off": - default: break; + if (debugMode) { + if (typeof func === 'function') func(); } }; @@ -690,13 +693,9 @@ function updUndoLvlIndex() { .drawString(scores.lastScores.length, x, y); } } -function incrCharIndex() { - charIndex++; - if (charIndex >= cellChars.length) charIndex = 0; - drawGrid(); -} + buttons.add(new Button('undo', btnAtribs.x, 25, btnAtribs.w, btnAtribs.h, 'U', btnAtribs.fg, btnAtribs.bg, undoGame, true)); -buttons.add(new Button('chars', btnAtribs.x, 71, btnAtribs.w, 31, '*', btnAtribs.fg, btnAtribs.bg, function(){incrCharIndex();}, true)); + buttons.add(new Button('restart', btnAtribs.x, 106, btnAtribs.w, btnAtribs.h, 'R', btnAtribs.fg, btnAtribs.bg, function(){drawPopUp('Do you want\nto restart?',handlePopUpClicks);}, true)); initGame(); diff --git a/apps/game1024/metadata.json b/apps/game1024/metadata.json index dd350d2b9..e2c4bdb3e 100644 --- a/apps/game1024/metadata.json +++ b/apps/game1024/metadata.json @@ -1,7 +1,7 @@ { "id": "game1024", "name": "1024 Game", "shortName" : "1024 Game", - "version": "0.08", + "version": "0.09", "icon": "game1024.png", "screenshots": [ {"url":"screenshot.png" } ], "readme":"README.md", @@ -12,6 +12,7 @@ "supports" : ["BANGLEJS2"], "storage": [ {"name":"game1024.app.js","url":"app.js"}, + {"name":"game1024.settings.js","url":"settings.js"}, {"name":"game1024.img","url":"app-icon.js","evaluate":true} ] } diff --git a/apps/game1024/settings.js b/apps/game1024/settings.js new file mode 100644 index 000000000..c8e393663 --- /dev/null +++ b/apps/game1024/settings.js @@ -0,0 +1,70 @@ +(function(back) { + var FILE = "game1024.settings.json"; + var scoreFile = "game1024.json"; + // Load settings + var settings = Object.assign({ + maxUndoLevels: 5, + charIndex: 0, + clockMode: true, + debugMode: false, + }, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + var symbols = ["1 2 3 ...", "A B C ...", "I II III..."]; + var settingsMenu = { + "" : { "title" : "1024 Game" }, + "< Back" : () => back(), + "Symbols": { + value: 0|settings.charIndex, + min:0,max:symbols.length-1, + format: v=>symbols[v], + onchange: v=> { settings.charIndex=v; writeSettings();} + } + , + "Undo levels:": { + value: 0|settings.maxUndoLevels, // 0| converts undefined to 0 + min: 0, max: 9, + onchange: v => { + settings.maxUndoLevels = v; + writeSettings(); + } + }, + "Exit press:": { + value: !settings.debugMode, // ! converts undefined to true + format: v => v?"short":"long", + onchange: v => { + settings.debugMode = v; + writeSettings(); + }, + }, + "Debug mode:": { + value: !!settings.debugMode, // !! converts undefined to false + format: v => v?"On":"Off", + onchange: v => { + settings.debugMode = v; + writeSettings(); + } + }, + "Reset Highscore": () => { + E.showPrompt('Reset Highscore?').then((v) => { + let delay = 50; + if (v) { + delay = 500; + let sF = require("Storage").readJSON(scoreFile, true); + if (typeof sF !== "undefined") { + E.showMessage('Resetting'); + sF.highScore = 0; + require("Storage").writeJSON(scoreFile, sF); + } else { + E.showMessage('No highscore!'); + } + } + setTimeout(() => E.showMenu(settingsMenu), delay); + }); + } + } + // Show the menu + E.showMenu(settingsMenu); + }) \ No newline at end of file From d0c9de691929cdb1182f9174d66f9e3a9ce046c1 Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Sun, 3 Apr 2022 16:55:16 +0200 Subject: [PATCH 245/253] bug fix undoGame levels --- apps/game1024/app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/game1024/app.js b/apps/game1024/app.js index a70db76c8..a82db4352 100644 --- a/apps/game1024/app.js +++ b/apps/game1024/app.js @@ -383,7 +383,7 @@ class Cell { function undoGame() { - if (scores.lastScores.length > 0) { + if (scores.lastScores.length) { g.clear(); allSquares.forEach(sq => { sq.popFromUndo(); @@ -396,7 +396,7 @@ function undoGame() { updUndoLvlIndex(); snapshot.make(); Bangle.loadWidgets(); - Bangle.drawWidgets(); + Bangle.drawWidgets(); } } function addToUndo() { @@ -516,8 +516,8 @@ function drawPopUp(message,cb) { rDims.x+10, rDims.y2-40 ]); buttons.all.forEach(btn => {btn.disable();}); - const btnYes = new Button('yes', rDims.x+16, rDims.y2-80, 54, btnAtribs.h, 'YES', btnAtribs.fg, btnAtribs.bg, cb, true); - const btnNo = new Button('no', rDims.x2-80, rDims.y2-80, 54, btnAtribs.h, 'NO', btnAtribs.fg, btnAtribs.bg, cb, true); + const btnYes = new Button('yes', rDims.x+16, rDims.y2-88, 54, btnAtribs.h, 'YES', btnAtribs.fg, btnAtribs.bg, cb, true); + const btnNo = new Button('no', rDims.x2-80, rDims.y2-88, 54, btnAtribs.h, 'NO', btnAtribs.fg, btnAtribs.bg, cb, true); btnYes.draw(); btnNo.draw(); g.setColor('#000000'); From 84db9a14fd0d5a48d8954dfaa2586588c80bdd91 Mon Sep 17 00:00:00 2001 From: marko Date: Sun, 3 Apr 2022 21:40:58 -0400 Subject: [PATCH 246/253] Mark pangrams green in word list. --- apps/bee/bee.app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index f0ae5badd..d06177ab3 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -168,8 +168,8 @@ function showWordList() { E.showScroller({ h : 20, c : foundWords.length, draw : (idx, r) => { - g.clearRect(r.x,r.y,r.x+r.w-1,r.y+r.h-1); - g.setFont("6x8:2").drawString(foundWords[idx].toUpperCase(),r.x+10,r.y+4); + g.clearRect(r.x,r.y,r.x+r.w-1,r.y+r.h-1).setFont("6x8:2"); + g.setColor(isPangram(foundWords[idx])?'#0f0':g.theme.fg).drawString(foundWords[idx].toUpperCase(),r.x+10,r.y+4); }, select : (idx) => { setInterval(()=> { From 96d77312568d9567230908a278eeedb3d5597411 Mon Sep 17 00:00:00 2001 From: marko Date: Sun, 3 Apr 2022 22:52:07 -0400 Subject: [PATCH 247/253] variable 'words' no longer defined --- apps/bee/bee.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js index d06177ab3..a12ca7820 100644 --- a/apps/bee/bee.app.js +++ b/apps/bee/bee.app.js @@ -20,7 +20,7 @@ function prepareLetterIdx () { for (var i=1; i<26; ++i) { var prefix = String.fromCharCode(97+i%26); console.log(prefix); - li.push(words.indexOf("\n"+prefix, li[i-1])+1); + li.push(S.read('bee.words').indexOf("\n"+prefix, li[i-1])+1); } li.push(S.read('bee.words').length); S.writeJSON("bee_lindex.json", li); From 4d352b791504607801a743ec156c175706ba4ad0 Mon Sep 17 00:00:00 2001 From: Romek Date: Mon, 4 Apr 2022 09:43:48 +0200 Subject: [PATCH 248/253] Add README.md to metadata.json if exists --- apps/aclock/metadata.json | 1 + apps/berlinc/metadata.json | 1 + apps/calculator/metadata.json | 1 + apps/cliock/metadata.json | 1 + apps/ffcniftyb/metadata.json | 1 + apps/floralclk/metadata.json | 1 + apps/hcclock/metadata.json | 1 + apps/impwclock/metadata.json | 1 + apps/intclock/metadata.json | 1 + apps/intervals/metadata.json | 1 + apps/ios/metadata.json | 1 + apps/numerals/metadata.json | 1 + apps/pipboy/metadata.json | 1 + apps/promenu/metadata.json | 1 + apps/score/metadata.json | 1 + apps/showimg/metadata.json | 1 + apps/sunclock/metadata.json | 1 + apps/supmariodark/metadata.json | 1 + apps/touchmenu/metadata.json | 1 + apps/waveclk/metadata.json | 1 + 20 files changed, 20 insertions(+) diff --git a/apps/aclock/metadata.json b/apps/aclock/metadata.json index c483a4e8c..5e4b4b680 100644 --- a/apps/aclock/metadata.json +++ b/apps/aclock/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"aclock.app.js","url":"clock-analog.js"}, diff --git a/apps/berlinc/metadata.json b/apps/berlinc/metadata.json index 49601cbd3..85c42fc47 100644 --- a/apps/berlinc/metadata.json +++ b/apps/berlinc/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "screenshots": [{"url":"berlin-clock-screenshot.png"}], "storage": [ diff --git a/apps/calculator/metadata.json b/apps/calculator/metadata.json index 3d1310859..e78e4d54f 100644 --- a/apps/calculator/metadata.json +++ b/apps/calculator/metadata.json @@ -8,6 +8,7 @@ "screenshots": [{"url":"screenshot_calculator.png"}], "tags": "app,tool", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"calculator.app.js","url":"app.js"}, {"name":"calculator.img","url":"calculator-icon.js","evaluate":true} diff --git a/apps/cliock/metadata.json b/apps/cliock/metadata.json index c5d3fa49e..2df48892e 100644 --- a/apps/cliock/metadata.json +++ b/apps/cliock/metadata.json @@ -9,6 +9,7 @@ "type": "clock", "tags": "clock,cli,command,bash,shell", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"cliock.app.js","url":"app.js"}, diff --git a/apps/ffcniftyb/metadata.json b/apps/ffcniftyb/metadata.json index e4e099a51..73f93ed36 100644 --- a/apps/ffcniftyb/metadata.json +++ b/apps/ffcniftyb/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"ffcniftyb.app.js","url":"app.js"}, diff --git a/apps/floralclk/metadata.json b/apps/floralclk/metadata.json index d4848b0d8..33ab6b8ae 100644 --- a/apps/floralclk/metadata.json +++ b/apps/floralclk/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"floralclk.app.js","url":"app.js"}, diff --git a/apps/hcclock/metadata.json b/apps/hcclock/metadata.json index e372a0a2c..0d4cbe0cd 100644 --- a/apps/hcclock/metadata.json +++ b/apps/hcclock/metadata.json @@ -8,6 +8,7 @@ "tags": "clock", "screenshots": [{"url":"bangle1-high-contrast-clock-screenshot.png"}], "supports": ["BANGLEJS"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"hcclock.app.js","url":"hcclock.app.js"}, diff --git a/apps/impwclock/metadata.json b/apps/impwclock/metadata.json index 120fbe795..733dbb957 100644 --- a/apps/impwclock/metadata.json +++ b/apps/impwclock/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "screenshots": [{"url":"bangle1-impercise-word-clock-screenshot.png"}], "allow_emulator": true, "storage": [ diff --git a/apps/intclock/metadata.json b/apps/intclock/metadata.json index fff4c58b0..13f596392 100644 --- a/apps/intclock/metadata.json +++ b/apps/intclock/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"intclock.app.js","url":"app.js"}, diff --git a/apps/intervals/metadata.json b/apps/intervals/metadata.json index bc054a539..32c18ae70 100644 --- a/apps/intervals/metadata.json +++ b/apps/intervals/metadata.json @@ -7,6 +7,7 @@ "icon": "intervals.png", "tags": "", "supports": ["BANGLEJS"], + "readme": "README.md", "storage": [ {"name":"intervals.app.js","url":"intervals.app.js"}, {"name":"intervals.img","url":"intervals-icon.js","evaluate":true} diff --git a/apps/ios/metadata.json b/apps/ios/metadata.json index 0083c66b0..eb75a6dbc 100644 --- a/apps/ios/metadata.json +++ b/apps/ios/metadata.json @@ -7,6 +7,7 @@ "tags": "tool,system,ios,apple,messages,notifications", "dependencies": {"messages":"app"}, "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"ios.app.js","url":"app.js"}, {"name":"ios.img","url":"app-icon.js","evaluate":true}, diff --git a/apps/numerals/metadata.json b/apps/numerals/metadata.json index dcb86da9a..6ba850d86 100644 --- a/apps/numerals/metadata.json +++ b/apps/numerals/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "numerals,clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "screenshots": [{"url":"bangle1-numerals-screenshot.png"}], "storage": [ diff --git a/apps/pipboy/metadata.json b/apps/pipboy/metadata.json index 34a6cb0ac..3dfb94c4a 100644 --- a/apps/pipboy/metadata.json +++ b/apps/pipboy/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "readme": "README.md", "allow_emulator": true, "screenshots": [{"url":"bangle1-pipboy-themed-clock-screenshot.png"}], "storage": [ diff --git a/apps/promenu/metadata.json b/apps/promenu/metadata.json index d70f36b0a..443809004 100644 --- a/apps/promenu/metadata.json +++ b/apps/promenu/metadata.json @@ -7,6 +7,7 @@ "type": "boot", "tags": "system", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "screenshots": [{"url":"pro-menu-screenshot.png"}], "storage": [ {"name":"promenu.boot.js","url":"boot.js","supports": ["BANGLEJS"]}, diff --git a/apps/score/metadata.json b/apps/score/metadata.json index fd72e197d..b593d7388 100644 --- a/apps/score/metadata.json +++ b/apps/score/metadata.json @@ -8,6 +8,7 @@ "type": "app", "tags": "", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"score.app.js","url":"score.app.js"}, {"name":"score.settings.js","url":"score.settings.js"}, diff --git a/apps/showimg/metadata.json b/apps/showimg/metadata.json index d5e44c0ee..e4dbc5738 100644 --- a/apps/showimg/metadata.json +++ b/apps/showimg/metadata.json @@ -7,6 +7,7 @@ "icon": "app.png", "tags": "tool", "supports" : ["BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"showimg.app.js","url":"app.js"}, {"name":"showimg.img","url":"app-icon.js","evaluate":true} diff --git a/apps/sunclock/metadata.json b/apps/sunclock/metadata.json index a39343992..617d76821 100644 --- a/apps/sunclock/metadata.json +++ b/apps/sunclock/metadata.json @@ -7,6 +7,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"sunclock.app.js","url":"app.js"}, diff --git a/apps/supmariodark/metadata.json b/apps/supmariodark/metadata.json index b56b19735..e5d0861ae 100644 --- a/apps/supmariodark/metadata.json +++ b/apps/supmariodark/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "readme": "README.md", "storage": [ {"name":"supmariodark.app.js","url":"supmariodark.js"}, {"name":"supmariodark.img","url":"supmariodark-icon.js","evaluate":true}, diff --git a/apps/touchmenu/metadata.json b/apps/touchmenu/metadata.json index 825989d99..5335e9fd6 100644 --- a/apps/touchmenu/metadata.json +++ b/apps/touchmenu/metadata.json @@ -8,6 +8,7 @@ "type": "bootloader", "tags": "tool", "supports": ["BANGLEJS2"], + "readme": "README.md", "storage": [ {"name":"touchmenu.boot.js","url":"touchmenu.boot.js"} ] diff --git a/apps/waveclk/metadata.json b/apps/waveclk/metadata.json index 9ba2798ff..0e9163157 100644 --- a/apps/waveclk/metadata.json +++ b/apps/waveclk/metadata.json @@ -8,6 +8,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", "allow_emulator": true, "storage": [ {"name":"waveclk.app.js","url":"app.js"}, From dc1bb3ea35b1d76e4d3a50c086ba7ad90b1b9923 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 4 Apr 2022 09:37:12 +0100 Subject: [PATCH 249/253] bump app version --- apps/bordle/ChangeLog | 2 ++ apps/bordle/metadata.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 apps/bordle/ChangeLog diff --git a/apps/bordle/ChangeLog b/apps/bordle/ChangeLog new file mode 100644 index 000000000..f45509a34 --- /dev/null +++ b/apps/bordle/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App +0.02: app keeps track of statistics now diff --git a/apps/bordle/metadata.json b/apps/bordle/metadata.json index e70effed5..37ef5c855 100644 --- a/apps/bordle/metadata.json +++ b/apps/bordle/metadata.json @@ -2,7 +2,7 @@ "name": "Bordle", "shortName":"Bordle", "icon": "app.png", - "version":"0.01", + "version":"0.02", "description": "Bangle version of a popular word search game", "supports" : ["BANGLEJS2"], "readme": "README.md", From 6948926572c5699cb47f2599866be5f8731ab19a Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Mon, 4 Apr 2022 17:45:06 +0200 Subject: [PATCH 250/253] v0.09 Updated the readme and screenshots --- apps/game1024/README.md | 24 +++++++++++++----- .../game1024_sc_dump_app_settings.png | Bin 0 -> 3623 bytes apps/game1024/game1024_sc_dump_dark.png | Bin 4404 -> 0 bytes apps/game1024/game1024_sc_dump_dark_v0.09.png | Bin 0 -> 3853 bytes apps/game1024/game1024_sc_dump_light.png | Bin 4054 -> 0 bytes .../game1024/game1024_sc_dump_light.v0.09.png | Bin 0 -> 3729 bytes apps/game1024/screenshot.png | Bin 6079 -> 3504 bytes 7 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 apps/game1024/game1024_sc_dump_app_settings.png delete mode 100644 apps/game1024/game1024_sc_dump_dark.png create mode 100644 apps/game1024/game1024_sc_dump_dark_v0.09.png delete mode 100644 apps/game1024/game1024_sc_dump_light.png create mode 100644 apps/game1024/game1024_sc_dump_light.v0.09.png diff --git a/apps/game1024/README.md b/apps/game1024/README.md index 500453145..f72a7ffef 100644 --- a/apps/game1024/README.md +++ b/apps/game1024/README.md @@ -1,7 +1,7 @@ # Play the game of 1024 -Move the tiles by swiping to the lefthand, righthand or up- and downward side of the watch. +Move the tiles by swiping left, righth, up- or downward over the watchface. When two tiles with the same number are squashed together they will add up as exponentials: @@ -21,16 +21,28 @@ Use the side **BTN** to exit the game, score and tile positions will be saved. ## Buttons on the screen - - Button **U**: Undo the last move. There are currently a maximum of 4 undo levels. The level is indicated with a small number in the lower righthand corner of the Undo button - - Button **\***: Change the text on the tile to number, capitals or Roman numbers - - Button **R**: Reset the game. The Higscore will be remembered. You will be prompted first. + - Button **U**: Undo the last move. There are currently a maximum of 9 undo levels. The level is indicated with a small number in the lower righthand corner of the Undo button + - You can set the maximum undo level in the Apps settings menu. + + - Button **R**: Reset the game. The Higscore will be remembered. You will be prompted first. + - The highscore value can be reset in the Apps settings menu. + + Apps setting: ![Screenshot of the apps settings menu](./game1024_sc_dump_app_settings.png) + + - Stuff you can change in de 1024 Game settings: + - Symbols on the cells: numerical, alphabetical or Roman + - Undo levels [0-9] + - Exit: how to exit the game: long or short press + - Debug mode: on or off. This will log all kinds of stuff in the console of the Web IDE + - Reset Highsccore: Tired of looking at the old highscore? Now you can set it to 0 again. ### Credits Game 1024 is based on Saming's 2048 and Misho M. Petkovic 1024game.org and conceptually similar to Threes by Asher Vollmer. In Dark theme with numbers: -![Screenshot from the Banglejs 2 watch with the game in dark theme](./game1024_sc_dump_dark.png) +![Screenshot from the Banglejs 2 watch with the game in dark theme](./game1024_sc_dump_dark_v0.09.png) In Light theme with characters: -![Screenshot from the Banglejs 2 watch with the game in light theme](./game1024_sc_dump_light.png) \ No newline at end of file +![Screenshot from the Banglejs 2 watch with the game in light theme](./game1024_sc_dump_light.v0.09.png) + diff --git a/apps/game1024/game1024_sc_dump_app_settings.png b/apps/game1024/game1024_sc_dump_app_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..6c50898b371cda94ac6cab8edef79999b79d1d3b GIT binary patch literal 3623 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 literal 0 HcmV?d00001 diff --git a/apps/game1024/game1024_sc_dump_light.png b/apps/game1024/game1024_sc_dump_light.png deleted file mode 100644 index 06ada65ac44865e01178d2684c8212e40fd33aed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4054 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 literal 6079 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 From 0268fd3592c350e732490d7d05ddefed76e8e710 Mon Sep 17 00:00:00 2001 From: chiefdaft Date: Mon, 4 Apr 2022 17:51:11 +0200 Subject: [PATCH 251/253] Corrected a few typos --- apps/game1024/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/game1024/README.md b/apps/game1024/README.md index f72a7ffef..a25683b68 100644 --- a/apps/game1024/README.md +++ b/apps/game1024/README.md @@ -1,7 +1,7 @@ # Play the game of 1024 -Move the tiles by swiping left, righth, up- or downward over the watchface. +Move the tiles by swiping left, right, up- or downward over the watchface. When two tiles with the same number are squashed together they will add up as exponentials: @@ -24,7 +24,7 @@ Use the side **BTN** to exit the game, score and tile positions will be saved. - Button **U**: Undo the last move. There are currently a maximum of 9 undo levels. The level is indicated with a small number in the lower righthand corner of the Undo button - You can set the maximum undo level in the Apps settings menu. - - Button **R**: Reset the game. The Higscore will be remembered. You will be prompted first. + - Button **R**: Reset the game. The Highscore will be remembered. You will be prompted first. - The highscore value can be reset in the Apps settings menu. Apps setting: ![Screenshot of the apps settings menu](./game1024_sc_dump_app_settings.png) From d4d6d48471eba1e4a633ec0a91576f29e4e3c538 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 5 Apr 2022 16:48:56 +0100 Subject: [PATCH 252/253] better example app --- apps/_example_app/app.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/_example_app/app.js b/apps/_example_app/app.js index af367779a..06c254a36 100644 --- a/apps/_example_app/app.js +++ b/apps/_example_app/app.js @@ -1,12 +1,34 @@ // place your const, vars, functions or classes here -// special function to handle display switch on -Bangle.on('lcdPower', (on) => { - if (on) { - // call your app function here - // If you clear the screen, do Bangle.drawWidgets(); +// clear the screen +g.clear(); + +var n = 0; + +// redraw the screen +function draw() { + g.reset().clearRect(Bangle.appRect); + g.setFont("6x8").setFontAlign(0,0).drawString("Up / Down",g.getWidth()/2,g.getHeight()/2 - 20); + g.setFont("Vector",60).setFontAlign(0,0).drawString(n,g.getWidth()/2,g.getHeight()/2 + 30); +} + +// Respond to user input +Bangle.setUI({mode: "updown"}, function(dir) { + if (dir<0) { + n--; + draw(); + } else if (dir>0) { + n++; + draw(); + } else { + n = 0; + draw(); } }); -g.clear(); -// call your app function here +// First draw... +draw(); + +// Load widgets +Bangle.loadWidgets(); +Bangle.drawWidgets(); From 0d696558a633e13f7eacdfe49f3c378c3f1bffd5 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 5 Apr 2022 16:49:19 +0100 Subject: [PATCH 253/253] Adding apps for keyboards on bangle.js 2 --- apps/kbswipe/ChangeLog | 1 + apps/kbswipe/README.md | 36 ++++++++++ apps/kbswipe/app.png | Bin 0 -> 2042 bytes apps/kbswipe/lib.js | 110 ++++++++++++++++++++++++++++++ apps/kbswipe/metadata.json | 14 ++++ apps/kbswipe/screenshot.png | Bin 0 -> 3823 bytes apps/kbtouch/ChangeLog | 1 + apps/kbtouch/README.md | 37 ++++++++++ apps/kbtouch/app.png | Bin 0 -> 506 bytes apps/kbtouch/lib.js | 132 ++++++++++++++++++++++++++++++++++++ apps/kbtouch/metadata.json | 14 ++++ apps/kbtouch/screenshot.png | Bin 0 -> 3208 bytes 12 files changed, 345 insertions(+) create mode 100644 apps/kbswipe/ChangeLog create mode 100644 apps/kbswipe/README.md create mode 100644 apps/kbswipe/app.png create mode 100644 apps/kbswipe/lib.js create mode 100644 apps/kbswipe/metadata.json create mode 100644 apps/kbswipe/screenshot.png create mode 100644 apps/kbtouch/ChangeLog create mode 100644 apps/kbtouch/README.md create mode 100644 apps/kbtouch/app.png create mode 100644 apps/kbtouch/lib.js create mode 100644 apps/kbtouch/metadata.json create mode 100644 apps/kbtouch/screenshot.png diff --git a/apps/kbswipe/ChangeLog b/apps/kbswipe/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/kbswipe/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/kbswipe/README.md b/apps/kbswipe/README.md new file mode 100644 index 000000000..1a402a9f3 --- /dev/null +++ b/apps/kbswipe/README.md @@ -0,0 +1,36 @@ +# Swipe Keyboard + +A library that provides the ability to input text by swiping PalmOS Graffiti-style characters onto the screen. + +To get a legend of available characters, just tap the screen. + + +## Usage + +In your app's metadata, add: + +``` + "dependencies": {"textinput":"type"}, +``` + +From inside your app, call: + +``` +Bangle.loadWidgets(); +Bangle.drawWidgets(); +require("textinput").input({text:"Foo"}).then(result => { + console.log("Text input", E.toJS(result)); +}); +``` + +The first argument to `input` is an object containing the following: + +* `text` - initial text to edit + +(in the future, the ability to restrict usage of newline/etc may be added) + +## Make your own + +You can create your own keyboard input apps. Just ensure that they have +`"type":"textinput",` in their metadata and provide a library called `textinput` +that exports an `input` method. diff --git a/apps/kbswipe/app.png b/apps/kbswipe/app.png new file mode 100644 index 0000000000000000000000000000000000000000..9564a4068b6b7d0beb52a26a6aa48cfb72b18047 GIT binary patch literal 2042 zcmV1GM#J7}(A_PPt(XlbpFmbg(FzwXU zP?I`MGuCw4WYUh)m?n+Xshyg3G}9&-r!$>trjwc$h|0sDfUFN<6R{S71rc`_1kq?j z1s}YAw}0TSfQzsK``cK)f8F!D=bm$Z-{1Y+d(XXB&XRg~ILuqW$%U&dner859?swEvr2Lk$31tPL6a(2vl zdreiTuj27(4@g?JaQj394 zyt938F!YgM0Ui?MS4l}pCQl6jQ1TPJe)-;5Fn=B*-5oG6Fo1ap@$NbinK2aG-k=u& zf@}e<0e`Vtt(|vi_dd`*6vqLk-uwmx^x#ve{>dL^^m0^?m$3=hG*F|$yvz;225+62 zQ!VKz`u(-^K;K{B{|=)B=pBIG7$rdO0QANv0eT0ZH%1B2I{>{gN`T%0=#5bV^bWv< zu^}P11;s>P`Sn@aIS|6bL)~R1{B%i*<>cgCA1S|nL%_oMiG+uR;&9dj zj8*VQM7W^^VNS6$AshpaiK4R8plnYi&Z$aIPuGU(*KY_g8jZa5`Y(7h{db%@|7G9m zDJW8bR0S9{;qcLltLBuI<)EEVO3IW_-eznsFUihs@y4&;5C9N5V;bB4^aqL$mT=_r zQXI}YE?n&Qs9+qZMIehrx_5WSbOkDNip7Dbf1}C2o?H-@Gf*$_D*^z zO8{tTY2~!TiNjfsqplviy$)yn8QR*~JT(^}0woa$t4oene3q2_z2~f-e$vpNKffcO zFCKjG0TSZlNQjSfKhrdgvrXr*JDk{^bvT^$*d29u{5lGrFd4*}wEX)EtvNd`db02L z1bBkMU|{;RDNLU>g>OCiP51Nb*Kbg3cd*}jh&_9YP)Y$3Y0^601zzxI%SSQ$1R)_~ zh>v@e*M7E+pTF{Q&#JVg-%0bh)qY+or=n8uD0}Al0Sq}D_p|VDU*48 zUc&Ia!4NTM0=f*HW^UamNtheQ+82M|u8Rl{BO*M^Ei0w4JL<3=Dxs+OP_Om;jOkPP z&0D|3Wb%(S*r20OFxgd}J!|IOR1py(Bf^M`2;)aT;H$J%588o<5EC6mOmvj@(fI&_9*UKa4|D-k*s6JN`(J5jY`V4H{`z9j zJz#%sMx!~!vJF@dusb)O-MRS$1_m&F+B712zxLnyQ_VQL)E? zalk}wU3u$?n>X92wL92bSWL;0ql^g-COjz~QomBYH1*6`TeIrrjn#4zOfsJ7O2 z-CkpJ+G}i|+fUhct$BXc*7}BX`3M?FG!O{T+ORKvq!c9*)K1s<6vOhjs zn44iys2|dO5tG)|YrOIHW{w>{F=Bq3FJHbbi1K*%*rz#ZQC`-EqEr&l1klmZLHg!* zsH{3UBL2R*bh)Qk?@7n!NqNDZtWr~#=?Q@b=$^60LzO2z zU3Mk%^FMZqK`j9;09?6pmCakW(b?HGY(C0PRHA9_L!oo~axxsA^mN;n*_V@5jj)Pa z`9)>bNeYYa7^LqR$IHsyWr4l@>FK&JRhXM;Rl=`b^451hSS`bZ-8uQ&U3R-P{@Gs) zx+mt28r$LU=$JBtGVCbWlbJPei@_l#D&ey(>FPlEThX4(%;BX#GZdep0UsMA8{cdXhusI(wQihd5MGmCn4+Q9n zQ3CW1KyQo^pmzYG$>|ZZtyJwmI=WATix$LwRC2UjDI{)S?ZHD(6^rK2`A0$C-4~bt Y10aN}YH-iLtpET307*qoM6N<$f~{lh@Bjb+ literal 0 HcmV?d00001 diff --git a/apps/kbswipe/lib.js b/apps/kbswipe/lib.js new file mode 100644 index 000000000..51f92f510 --- /dev/null +++ b/apps/kbswipe/lib.js @@ -0,0 +1,110 @@ +/* To make your own strokes, type: + +Bangle.on('stroke',print) + +on the left of the IDE, then do a stroke and copy out the Uint8Array line +*/ +exports.getStrokes = function(cb) { + 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("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("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])); + cb("i", new Uint8Array([89, 48, 89, 49, 89, 51, 89, 55, 89, 60, 89, 68, 89, 78, 89, 91, 89, 103, 89, 114, 89, 124, 89, 132, 89, 138, 89, 144, 89, 148, 89, 151, 89, 154, 89, 156, 89, 157, 89, 158])); + 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("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([52, 59, 52, 64, 54, 73, 58, 88, 61, 104, 65, 119, 67, 130, 69, 138, 71, 145, 71, 147, 71, 148, 71, 143, 70, 133, 68, 120, 67, 108, 67, 97, 67, 89, 68, 79, 72, 67, 83, 60, 99, 58, 118, 58, 136, 63, 146, 70, 148, 77, 145, 84, 136, 91, 121, 95, 106, 97, 93, 97, 82, 97])); + cb("q", new Uint8Array([95, 59, 93, 59, 88, 59, 79, 59, 68, 61, 57, 67, 50, 77, 48, 89, 48, 103, 50, 117, 55, 130, 65, 140, 76, 145, 85, 146, 94, 144, 101, 140, 105, 136, 106, 127, 106, 113, 100, 98, 92, 86, 86, 79, 84, 75, 84, 72, 91, 69, 106, 67, 126, 67, 144, 67, 158, 67, 168, 67, 173, 67, 177, 67])); + cb("r", new Uint8Array([53, 49, 53, 62, 53, 91, 53, 127, 53, 146, 53, 147, 53, 128, 53, 94, 53, 69, 62, 44, 82, 42, 94, 50, 92, 68, 82, 85, 77, 93, 80, 102, 95, 119, 114, 134, 129, 145, 137, 150])); + cb("s", new Uint8Array([159, 72, 157, 70, 155, 68, 151, 66, 145, 63, 134, 60, 121, 58, 108, 56, 96, 55, 83, 55, 73, 55, 64, 56, 57, 60, 52, 65, 49, 71, 49, 76, 50, 81, 55, 87, 71, 94, 94, 100, 116, 104, 131, 108, 141, 114, 145, 124, 142, 135, 124, 146, 97, 153, 70, 157, 52, 158])); + 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([33, 58, 34, 81, 39, 127, 44, 151, 48, 161, 52, 162, 57, 154, 61, 136, 65, 115, 70, 95, 76, 95, 93, 121, 110, 146, 119, 151, 130, 129, 138, 84, 140, 56, 140, 45])); + 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([42, 56, 42, 70, 48, 97, 62, 109, 85, 106, 109, 90, 126, 65, 134, 47, 137, 45, 137, 75, 127, 125, 98, 141, 70, 133, 65, 126, 92, 137, 132, 156, 149, 166])); + 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("\b", new Uint8Array([183, 103, 182, 103, 180, 103, 176, 103, 169, 103, 159, 103, 147, 103, 133, 103, 116, 103, 101, 103, 85, 103, 73, 103, 61, 103, 52, 103, 38, 103, 34, 103, 29, 103, 27, 103, 26, 103, 25, 103, 24, 103])); + cb(" ", new Uint8Array([39, 118, 40, 118, 41, 118, 44, 118, 47, 118, 52, 118, 58, 118, 66, 118, 74, 118, 84, 118, 94, 118, 104, 117, 114, 116, 123, 116, 130, 116, 144, 116, 149, 116, 154, 116, 158, 116, 161, 116, 163, 116])); +}; + +exports.input = function(options) { + options = options||{}; + var text = options.text; + if ("string"!=typeof text) text=""; + +Bangle.strokes = {}; +exports.getStrokes( (id,s) => Bangle.strokes[id] = Unistroke.new(s) ); + + var flashToggle = false; + const R = Bangle.appRect; + + function draw(noclear) { + g.reset(); + if (!noclear) g.clearRect(R); + var l = g.setFont("6x8:4").wrapString(text+(flashToggle?"_":" "), R.w-8); + if (l.length>4) l=l.slice(-4); + g.drawString(l.join("\n"),R.x+4,R.y+4); + } + + function show() { + g.reset(); + g.clearRect(R).setColor("#f00"); + var n=0; + exports.getStrokes((id,s) => { + var x = n%6; + var y = (n-x)/6; + s = g.transformVertices(s, {scale:0.16, x:R.x+x*30-4, y:R.y+y*30-4}); + g.fillRect(s[0]-1,s[1]-2,s[0]+1,s[1]+1); + g.drawPoly(s); + n++; + }); + + } + + function strokeHandler(o) { + //print(o); + if (!flashInterval) + flashInterval = setInterval(() => { + flashToggle = !flashToggle; + draw(); + }, 1000); + if (o.stroke!==undefined) { + var ch = o.stroke; + if (ch=="\b") text = text.slice(0,-1); + else text += ch; + } + flashToggle = true; + draw(); + } + Bangle.on('stroke',strokeHandler); + g.reset().clearRect(R); + show(); + draw(true); + var flashInterval; + + return new Promise((resolve,reject) => { + var l;//last event + Bangle.setUI({mode:"custom", drag:e=>{ + if (l) g.reset().setColor("#f00").drawLine(l.x,l.y,e.x,e.y); + l = e.b ? e : 0; + },touch:() => { + if (flashInterval) clearInterval(flashInterval); + flashInterval = undefined; + show(); + }, back:()=>{ + Bangle.removeListener("stroke", strokeHandler); + clearInterval(flashInterval); + Bangle.setUI(); + g.clearRect(Bangle.appRect); + resolve(text); + }}); + }); +}; diff --git a/apps/kbswipe/metadata.json b/apps/kbswipe/metadata.json new file mode 100644 index 000000000..635841e62 --- /dev/null +++ b/apps/kbswipe/metadata.json @@ -0,0 +1,14 @@ +{ "id": "kbswipe", + "name": "Swipe keyboard", + "version":"0.01", + "description": "A library for text input via PalmOS style swipe gestures (beta!)", + "icon": "app.png", + "type":"textinput", + "tags": "keyboard", + "supports" : ["BANGLEJS2"], + "screenshots": [{"url":"screenshot.png"}], + "readme": "README.md", + "storage": [ + {"name":"textinput","url":"lib.js"} + ] +} diff --git a/apps/kbswipe/screenshot.png b/apps/kbswipe/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..11788ad8793bfd0b93113f038a1d08bcaa67860b GIT binary patch literal 3823 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 Q`d|Tb6RRr}WB2&~0e-$dDgXcg literal 0 HcmV?d00001 diff --git a/apps/kbtouch/ChangeLog b/apps/kbtouch/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/kbtouch/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/kbtouch/README.md b/apps/kbtouch/README.md new file mode 100644 index 000000000..513ba9239 --- /dev/null +++ b/apps/kbtouch/README.md @@ -0,0 +1,37 @@ +# Touch Keyboard + +A library that provides an on-screen keyboard for text input. + +## Usage + +In your app's metadata, add: + +``` + "dependencies": {"textinput":"type"}, +``` + +From inside your app, call: + +``` +Bangle.loadWidgets(); +Bangle.drawWidgets(); +require("textinput").input({text:"Foo"}).then(result => { + console.log("Text input", E.toJS(result)); +}); +``` + +The first argument to `input` is an object containing the following: + +* `text` - initial text to edit + +(in the future, the ability to restrict usage of newline/etc may be added) + +## Make your own + +You can create your own keyboard input apps. Just ensure that they have +`"type":"textinput",` in their metadata and provide a library called `textinput` +that exports an `input` method. + +## To-do + +Make this Bangle.js 1 compatible (use left/right touch and up/down buttons) diff --git a/apps/kbtouch/app.png b/apps/kbtouch/app.png new file mode 100644 index 0000000000000000000000000000000000000000..19aec3c05b794809eae76077da580c604f981c42 GIT binary patch literal 506 zcmV&(fVX&)lQkODWP$9~zxmoIHO8{0cs!=+0aVFEEh#Mnrn((KgzLy9_SD2DG(jJL z3I|bZO2&XUKHDM4D1e5Nj#`(pC+T~t5!-mw=rtjwp?QeAhgX1$@V)Pie4-Gx(<@u9h&#<}y zF?fK0uBMk4iY^|k$Ef}R5M|re1l#|CCV=Os>T_EIY#V3*c&N&?T9lDwa%>^I;HB#ld_5-jY=EeDzG8vfqF+kTfoZ wlBVcqp}4rSP|^YlrR)v36mmEm4o6w@0yuf5j`FMk(f|Me07*qoM6N<$g18aoQvd(} literal 0 HcmV?d00001 diff --git a/apps/kbtouch/lib.js b/apps/kbtouch/lib.js new file mode 100644 index 000000000..3dfdce00c --- /dev/null +++ b/apps/kbtouch/lib.js @@ -0,0 +1,132 @@ +exports.input = function(options) { + options = options||{}; + var text = options.text; + if ("string"!=typeof text) text=""; + + // Key Maps for Keyboard +var KEYMAPLOWER = [ + "`1234567890-=\b", + "\2qwertyuiop[]\n", + "\2asdfghjkl;'#\n", + " \\zxcvbnm,./ ", + ]; +var KEYMAPUPPER = [ + "¬!\"£$%^&*()_+\b", + "\2QWERTYUIOP{}\n", + "\2ASDFGHJKL:@~\n", + " |ZXCVBNM<>? ", + ]; +var KEYIMGL = Graphics.createImage(` + + + # + ### + ##### + # + # + # + # + # + # + # + # + # + # + # + # + # +`);KEYIMGL.transparent=0; +var KEYIMGR = Graphics.createImage(` + + + # + ## +##### + ## + # + + + +### + # + # + # + # + # +##### + ### + # + +#`);KEYIMGR.transparent=0; +/* If a char in the keymap is >=128, +subtract 128 and look in this array for +multi-character key codes*/ +var KEYEXTRA = [ + String.fromCharCode(27,91,68), // 0x80 left + String.fromCharCode(27,91,67), // 0x81 right + String.fromCharCode(27,91,65), // 0x82 up + String.fromCharCode(27,91,66), // 0x83 down + String.fromCharCode(27,91,53,126), // 0x84 page up + String.fromCharCode(27,91,54,126), // 0x85 page down +]; +// state +const R = Bangle.appRect; +var kbx = 0, kby = 0, kbdx = 0, kbdy = 0, kbShift = false, flashToggle = false; +const PX=12, PY=16, DRAGSCALE=24; +var xoff = 3, yoff = g.getHeight()-PY*4; + +function draw() { + var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER; + //g.drawImage(KEYIMG,0,yoff); + g.reset().setFont("6x8:2"); + g.clearRect(R); + if (kbx>=0) + g.setColor(g.theme.bgH).fillRect(xoff+kbx*PX,yoff+kby*PY, xoff+(kbx+1)*PX-1,yoff+(kby+1)*PY-1).setColor(g.theme.fg); + g.drawImage(KEYIMGL,xoff,yoff+PY,{scale:2}); + g.drawImage(KEYIMGR,xoff+PX*13,yoff,{scale:2}); + g.drawString(map[0],xoff,yoff); + g.drawString(map[1],xoff,yoff+PY); + g.drawString(map[2],xoff,yoff+PY*2); + g.drawString(map[3],xoff,yoff+PY*3); + var l = g.setFont("6x8:4").wrapString(text+(flashToggle?"_":" "), R.w-8); + if (l.length>2) l=l.slice(-2); + g.drawString(l.join("\n"),R.x+4,R.y+4); + + g.flip(); +} + g.reset().clearRect(R); + draw(); + var flashInterval = setInterval(() => { + flashToggle = !flashToggle; + draw(); + }, 1000); + + return new Promise((resolve,reject) => { + + Bangle.setUI({mode:"custom", drag:e=>{ + kbdx += e.dx; + kbdy += e.dy; + var dx = Math.round(kbdx/DRAGSCALE), dy = Math.round(kbdy/DRAGSCALE); + kbdx -= dx*DRAGSCALE; + kbdy -= dy*DRAGSCALE; + if (dx || dy) { + kbx = (kbx+dx+15)%15; + kby = (kby+dy+4)%4; + draw(); + } + },touch:()=>{ + var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER; + var ch = map[kby][kbx]; + if (ch=="\2") kbShift=!kbShift; + else if (ch=="\b") text = text.slice(0,-1); + else text += ch; + Bangle.buzz(20); + draw(); + },back:()=>{ + clearInterval(flashInterval); + Bangle.setUI(); + g.clearRect(Bangle.appRect); + resolve(text); + }}); + }); +}; diff --git a/apps/kbtouch/metadata.json b/apps/kbtouch/metadata.json new file mode 100644 index 000000000..da8b6c3c6 --- /dev/null +++ b/apps/kbtouch/metadata.json @@ -0,0 +1,14 @@ +{ "id": "kbtouch", + "name": "Touch keyboard", + "version":"0.01", + "description": "A library for text input via onscreen keyboard", + "icon": "app.png", + "type":"textinput", + "tags": "keyboard", + "supports" : ["BANGLEJS2"], + "screenshots": [{"url":"screenshot.png"}], + "readme": "README.md", + "storage": [ + {"name":"textinput","url":"lib.js"} + ] +} diff --git a/apps/kbtouch/screenshot.png b/apps/kbtouch/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..3aa772ddaa2b3d21bb49a23cb3a4132c4eb23b6b GIT binary patch literal 3208 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 W?Um+=5q0~u035S-##P$}T>USMPwCeH literal 0 HcmV?d00001