From 57268095307e723bb11983818ddb387fc35378b4 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 17:53:50 +0200 Subject: [PATCH 001/183] Create app.js --- apps/pongclock/app.js | 309 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 apps/pongclock/app.js diff --git a/apps/pongclock/app.js b/apps/pongclock/app.js new file mode 100644 index 000000000..8efe0eca5 --- /dev/null +++ b/apps/pongclock/app.js @@ -0,0 +1,309 @@ +class Ball { + constructor(collision) { + this.collision = collision; + this.w = 4; + this.h = this.w; + this.y = height / 2 - this.h / 2; + this.x = width / 2 - this.w / 2; + this.oldX = this.x; + this.oldY = this.y; + this.velX = 6; + this.velY = 3.5 + Math.random(); + } + + reset() { + this.y = height / 2 - this.h / 2; + this.x = width / 2 - this.w / 2; + this.velX = 6; + this.velY = 3.5 + Math.random(); + } + + checkCollision(that, isLeft) { + let test = false; + if (isLeft) { + test = this.x <= that.w + this.w && this.y > that.y && this.y < that.y + that.h; + } + else { + test = this.x >= that.x + this.w && this.y > that.y && this.y < that.y + that.h; + } + if (test) { + this.velX = -this.velX; + this.valY = (3.5 + Math.random()) * this.valY / Math.abs(this.valY); + + if (isLeft) { + right.follow = this; + left.follow = null; + } else { + left.follow = this; + right.follow = null; + } + } + } + + move() { + if (this.velX > 0) { + this.checkCollision(right, false); + } else { + this.checkCollision(left, true); + } + + this.x += this.velX; + this.y += this.velY; + + if (this.y <= this.h) { + this.y = this.h; + this.velY = -this.velY; + } + + if (this.y >= height - this.h) { + this.y = height - this.h; + this.velY = -this.velY; + } + + if(this.x >= width) { + left.scored(); + restart(); + } else if(this.x < 0) { + right.scored(); + restart(); + } + + } +} + +class Paddle { + constructor(side) { + this.side = side; + this.w = 4;//15; + this.h = 30;//80; + this.y = height / 2 - this.h/2; + this.follow = null; + this.target = height / 2 - this.h/2; + this.score = 99; + this.hasLost = false; + } + + reset() { + this.follow = null; + this.hasLost = false; + this.target = height / 2 - this.h/2; + this.y = height / 2 - this.h/2; + this.move(); + } + + scored() { + let d = new Date(); + let value = 0; + if (this.side == "left") { + value = d.getHours(); + } else { + value = d.getMinutes(); + } + if (this.score < value) { + this.score++; + } + else { + this.score = value; + } + } + + move() { + + if (this.follow && ! this.hasLost) { + var dy = this.follow.y - this.y - this.h / 2; + this.y += dy / 2; + } + else { + this.y += (this.target - this.y) / 10; + } + if (this.y < 0) { + this.y = 0; + } + if (this.y > height - this.h) { + this.y = height - this.h; + } + } +} + +var updateTimeout = null; +function update() { + var d = new Date(); + var lastStep = Date.now(); + left.move(); + right.move(); + if(d.getHours() != left.score) { + right.follow = null; + right.hasLost = true; + } + if(d.getMinutes() != right.score) { + left.follow = null; + left.hasLost = true; + } + + ball.move(); + redraw(); + var nextStep = 40 - (Date.now() - lastStep); + //console.log(nextStep); + updateTimeout = setTimeout(update, nextStep > 0 ? nextStep : 0); + return lastStep; +} + +function redraw() { + let fontHeight = width / 3.6; + let fontTop = top + height / 11; + let topHeight = top + height; + g.reset(); + + if (settings.isInvers) { + g.setColor(g.theme.bg); + g.setBgColor(g.theme.fg); + } + + g.clearRect(0, top + left.oldY, left.w, top + left.oldY + left.h); + g.clearRect(width - right.w, top + right.oldY, width, top + right.oldY + right.h); + g.clearRect(width / 2 - fontHeight * 1.4, fontTop, width / 2 + fontHeight * 1.4, fontTop + fontHeight); + g.clearRect(ball.oldX - ball.w, top + ball.oldY - ball.h, ball.oldX + ball.w, top + ball.oldY + ball.h); + + g.drawLine(width / 2, top, width / 2, topHeight); + g.fillRect(0, top + left.y, left.w, top + left.y + left.h); + left.oldY = left.y; + g.fillRect(width - right.w, top + right.y, width, top + right.y + right.h); + right.oldY = right.y; + g.fillCircle(ball.x, top + ball.y, ball.w); + ball.oldX = ball.x; + ball.oldY = ball.y; + + g.setFontVector(fontHeight); + /* + g.setFontAlign(0, -1); + g.drawString(("0" + left.score).substr(-2)+ " " + ("0" + right.score).substr(-2), width / 2, fontTop); + */ + /**/ + g.setFontAlign(1, -1); + g.drawString(("0" + left.score).substr(-2), 5 * width / 11, fontTop); + g.setFontAlign(-1, -1); + g.drawString(("0" + right.score).substr(-2), 6 * width / 11, fontTop); + /**/ +} + +function restart() { + g.reset(); + if (settings.isInvers) { + g.setColor(g.theme.bg); + g.setBgColor(g.theme.fg); + } + g.clearRect(0, top, width, top + height); + ball.reset(); + left.reset(); + right.reset(); + right.follow = ball; + left.move(); + right.move(); + if (settings.withWidgets) { + Bangle.drawWidgets(); + } +} + +function stop() { + if (updateTimeout) { + clearTimeout(updateTimeout); + } + updateTimeout = null; + if (pauseTimeout) { + clearTimeout(pauseTimeout); + } + pauseTimeout = null; +} + +var pauseTimeout = null; +function pause() { + stop(); + left.scored(); + right.scored(); + redraw(); + pauseTimeout = setTimeout(pause, Date.now() % 60000); +} + +const SETTINGS_FILE = "pongclock.json"; +var settings = Object.assign({ + // default values + withWidgets: true, + isInvers: false, + playLocked: true, +}, require('Storage').readJSON(SETTINGS_FILE, true) || {}); +require('Storage').writeJSON(SETTINGS_FILE, settings); + +var height = g.getHeight(), + width = g.getWidth(); +var top = 0; + +Bangle.setUI("clock"); + +g.reset(); +g.clearRect(0, top, width, height); + +if (settings.withWidgets) { + Bangle.loadWidgets(); + Bangle.drawWidgets(); + //console.log(WIDGETS); + if (global.WIDGETS) { + let bottom = 0; + for (var i in WIDGETS) { + var w = WIDGETS[i]; + if (w.area) { + if (w.area.indexOf("t") >= 0) { + top = 25; + } + if (w.area.indexOf("b") >= 0) { + bottom = 25; + } + } + } + height -= top + bottom; + } +} + +if (settings.isInvers) { + g.setColor(g.theme.bg); + g.setBgColor(g.theme.fg); +} +g.clearRect(0, top, width, top + height); + +var left = new Paddle("left"); +var right = new Paddle("right"); +var ball = new Ball(true); + +left.x = 20; +right.x = width - 20; + +left.scored(); +right.scored(); + +Bangle.on("lock", (on) => { + //console.log(on); + if (!settings.playLocked) { + if (on) { + pause(); + } else { + stop(); + update(); + } + } +}); + +restart(); +if (!settings.playLocked && Bangle.isLocked()) { + pause(); +} else { + update(); +} + +/* +require("Storage").write("pongclock.info",{ + "id":"pongclock", + "name":"Pong Clock", + "type":"clock", + "src":"pongclock.app.js", + "icon":"pongclock.img" +}); +*/ From 0e45f63f4005e74cc7526f95e2a1718a8e411dfc Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 17:59:55 +0200 Subject: [PATCH 002/183] Add files via upload --- apps/pongclock/pongclock.img | Bin 0 -> 1156 bytes apps/pongclock/pongclock.png | Bin 0 -> 933 bytes apps/pongclock/settings.js | 44 +++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 apps/pongclock/pongclock.img create mode 100644 apps/pongclock/pongclock.png create mode 100644 apps/pongclock/settings.js diff --git a/apps/pongclock/pongclock.img b/apps/pongclock/pongclock.img new file mode 100644 index 0000000000000000000000000000000000000000..e0045eff79314697cb8fe35138277dd0de433bc6 GIT binary patch literal 1156 zcmcJNQEtN^5JVR{|3>NoAie;oIRKaIft~mO+nI&fSg!w4BrD5fn4JJQ|J-CBy6kmd zeS~|FIW||+9AD~P(P(waoWEEPs(#X13znU#iH22uc#bQ5oO1`BaYG;BSLy%hW>&UNWPw3kNy2f@>t7EWdFER5bVG z&5e2n(S^Y8Rl8P2eYsG z1ffabKcYrr^Z%Q}gM*T7bd#<;i2j>z?}wod&9;Px#1ZP1_K>z@;j|==^1poj6O;Ai!MF0Q*|Ns9C3=AC|9V;s*Vk25RodFx=H}*fbaZ!jcLoLqtE=<#^L>4N zetv%5-rgoACR9{Z)YQ~=c6JyT7;bKEFE1~>y}j}A@qvMXgoK3a>+1sp1FfyC2L}fe z6BA};WVGd00H4iL_t(YOWl-bR}(=LK;K1@SSXg*3y3{puc#=X z7%O7$9cu#r|D*HXya}vHVD}t7$K(BwS9b60yxBdG&H$d}3v5jo2_D;yQ7oENzO z7n3l?CA)Z8SGq#g3de?4#<`k~^%_jXrc$Hknb8s^_3=@d@*Nr1;fAM15=LM;2{*%` z*12VUxy_xsF^eQ&fO}R2;l3Vf5@uSaOzf|8Uk@V7hb`rRZ1_6RbSVcd}A*sJs=~zg?CmdL5RE; z8Rmm`Gr}x<{1k{=`aGx9`7$S8VLV>Q3g2wOCErrOX80ca*7IP(kJxS(e#U-A$g back(), + 'Widgets?': { + value: !!settings.withWidgets, // !! converts undefined to false + format: v => v?"Show":"Hide", + onchange: v => { + settings.withWidgets = v; + writeSettings(); + } + }, + 'Inverted?': { + value: !!settings.isInvers, // !! converts undefined to false + format: v => v?"Yes":"No", + onchange: v => { + settings.withWidgets = v; + writeSettings(); + } + }, + 'On Lock?': { + value: !!settings.isInvers, // !! converts undefined to false + format: v => v?"Play":"Pause", + onchange: v => { + settings.withWidgets = v; + writeSettings(); + } + } + }); +})/*(load)/**/ \ No newline at end of file From a21898b7164306af1e152df4101e69ead1fc7eb1 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:02:50 +0200 Subject: [PATCH 003/183] Create ChangeLog --- apps/pongclock/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/pongclock/ChangeLog diff --git a/apps/pongclock/ChangeLog b/apps/pongclock/ChangeLog new file mode 100644 index 000000000..e8c8518ae --- /dev/null +++ b/apps/pongclock/ChangeLog @@ -0,0 +1 @@ +0.1: First release From 36eea36a53431aaeb7db7442344148bfc23e17be Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:06:17 +0200 Subject: [PATCH 004/183] Create metadata.json --- apps/pongclock/metadata.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 apps/pongclock/metadata.json diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json new file mode 100644 index 000000000..13f8ff4f1 --- /dev/null +++ b/apps/pongclock/metadata.json @@ -0,0 +1,12 @@ +{ "id": "pongclock", + "name": "Pong Clock", + "shortName":"Pong Clock", + "icon": "pongclock.png", + "version":"0.1", + "description": "A clock playing Pong", + "tags": "", + "storage": [ + {"name":"pongclock.app.js","url":"app.js"}, + {"name":"pongclock.img","url":"pongclock-img.js","evaluate":true} + ] +} From 425c00cee195c712772b5c4e1d935ffd8d97567d Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:10:16 +0200 Subject: [PATCH 005/183] Create pongclock-icon.js --- apps/pongclock/pongclock-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/pongclock/pongclock-icon.js diff --git a/apps/pongclock/pongclock-icon.js b/apps/pongclock/pongclock-icon.js new file mode 100644 index 000000000..00002a018 --- /dev/null +++ b/apps/pongclock/pongclock-icon.js @@ -0,0 +1 @@ +atob("MDCEBP//////////////AA//////////////////////////////AA//////////////////////////////AA//////////////////////////////AA//////////////////////////P///Ii//////////P////////zEAP/MQAC///////xAf//8xAAL/////8gAAP/AAAAL//////wAv//MAAAAv////8gEAPzAD8QD/Ii//8wA///IAPxAf////8S8APyAf8wD/AA//8gD///EB/yAP//////8APxAP8wD/AA//8AH///AB/yAf//////8AP///8gD/AA//MAP//////xAf//////8AP///8QH/AA//IA///////wAv//////8AP///MAP/AA//EB8AL///8gD///////8AP///EB//AA//AC8AL///8AL///////8AP//yAD//AA/zAD8AL///IA////////8AP//wAf//AA/xAP8AL//zAC////////8AP/8gA///Ii/wAf8AL//xAP///wAP//8AP/MAH/////8wABEAEf8wAv///wAP//8AP/EA//////8wAAAAAf8QD////wAP//8APzAB////Ii/yIiIAEvIAL////wAP//8APyAAAAD/AA////8AL/EAAAAP/wAP//8APyAAAAD/AA////8AL/EAAAAP/wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////Ii///////////////wAP///////////////////////////wAAAP///////////////////////////wAP//////////////Ii/////////////wAP//////8yP/////AA/////////////wAP//////EAAf////AA/////////////wAP/////zAAAD////AA/////////////wAP/////yAAAC////AA/////////////wAP/////zAAAD////AA/////////////wAP//////EAAf////AA/////////////wAP//////8yP/////AA/////////////wAP//////////////AA/////////////wAP//////////////Ii/////////////wAP/////////////////////////////wAP//////////////////////////////////////////////Ii//////////////////////////////AA//////////////////////////////AA//////////////////////////////AA//////////////////////////////AA///////////////w==") From 6db2bbcdb37f0eba036c92318c1b5948f4e43d18 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:10:54 +0200 Subject: [PATCH 006/183] Update metadata.json --- apps/pongclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index 13f8ff4f1..a9e0240e6 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -7,6 +7,6 @@ "tags": "", "storage": [ {"name":"pongclock.app.js","url":"app.js"}, - {"name":"pongclock.img","url":"pongclock-img.js","evaluate":true} + {"name":"pongclock.img","url":"pongclock-icon.js","evaluate":true} ] } From 2b4ca3a2f7cc9e5577cc331afb6871cf0a204fdb Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:24:13 +0200 Subject: [PATCH 007/183] Create README.md --- apps/pongclock/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 apps/pongclock/README.md diff --git a/apps/pongclock/README.md b/apps/pongclock/README.md new file mode 100644 index 000000000..47883c56f --- /dev/null +++ b/apps/pongclock/README.md @@ -0,0 +1,2 @@ +**Pong Clock** +A clock that plays pong while the counter displays the time. From e7b4ecb3ccb7c7a2e96a4721e14f396b6fa2688f Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:29:35 +0200 Subject: [PATCH 008/183] Update metadata.json --- apps/pongclock/metadata.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index a9e0240e6..3f35fddb0 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -5,8 +5,13 @@ "version":"0.1", "description": "A clock playing Pong", "tags": "", + "readme":"README.md", "storage": [ {"name":"pongclock.app.js","url":"app.js"}, - {"name":"pongclock.img","url":"pongclock-icon.js","evaluate":true} + {"name":"pongclock.img","url":"pongclock-icon.js","evaluate":true}, + {"name":"pongclock.settings.js","url":"settings.js"} + ], + "data": [ + {"name":"pongclock.json"} ] } From fc0f758073240a97c8ffd9f244f13d23f1036a81 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:31:26 +0200 Subject: [PATCH 009/183] Update metadata.json --- apps/pongclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index 3f35fddb0..7ffb3e6dc 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -5,6 +5,7 @@ "version":"0.1", "description": "A clock playing Pong", "tags": "", + "supports": ["BANGLEJS2", "BANGLEJS2"], "readme":"README.md", "storage": [ {"name":"pongclock.app.js","url":"app.js"}, From 63f22684a1df68753d4725a585f6c70ae6bc052f Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 18:32:42 +0200 Subject: [PATCH 010/183] Update metadata.json --- apps/pongclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index 7ffb3e6dc..9ce9fe291 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -5,7 +5,7 @@ "version":"0.1", "description": "A clock playing Pong", "tags": "", - "supports": ["BANGLEJS2", "BANGLEJS2"], + "supports": ["BANGLEJS", "BANGLEJS2"], "readme":"README.md", "storage": [ {"name":"pongclock.app.js","url":"app.js"}, From 9014dc0f4f63c6814bd22b9200f10188b27b7080 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:18:58 +0200 Subject: [PATCH 011/183] Update README.md --- apps/pongclock/README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/pongclock/README.md b/apps/pongclock/README.md index 47883c56f..cc152d7b9 100644 --- a/apps/pongclock/README.md +++ b/apps/pongclock/README.md @@ -1,2 +1,13 @@ -**Pong Clock** -A clock that plays pong while the counter displays the time. +# Pong Clock + +A clock which is playing Pong while showing the current time as score +* Settings + * Show or hide widgets (auto detecting the used widgets areas) + * Use inverted or standard theme colors for the play area + * Optionally pause while locked (saving battery) +* Loosely based on [https://codepen.io/Rabrennie/pen/WxNEoe](https://codepen.io/Rabrennie/pen/WxNEoe) + +![](screenshot.png) + +## Creator +[@pidajo](https://github.com/pidajo) From 44d7e883a40dbb406eebf4210b9f571d694f58dc Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:19:20 +0200 Subject: [PATCH 012/183] Add files via upload --- apps/pongclock/pongclock.png | Bin 933 -> 934 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/pongclock/pongclock.png b/apps/pongclock/pongclock.png index 9aa0177b2e90c16bc9310fb05658e801b0202b1a..78934d7c606d485816e991c4286263ff67ca19a8 100644 GIT binary patch delta 562 zcmV-20?qxU2c`#*Ne_U4fdBvh3=9k%9UUtxE3sHR0e^1SbA|u_010qNS#tmY4#NNd z4#NS*Z>VGd00H7jL_t(YOWl-LTN6PPKyMC`SOT`#3y3{puc#=f7%O7$9cu#r|IxX3 z?kowcVe{appXVXB%%0u3v-?HzDN*vQApeBW*JoixzlBmM3gt@0qR7fsoIJ%43A8!T?D!KTfY8e0fdW$QNB4m-RXfSnq4={oGTo-)L+3VUEg_OdVA(tbFg z@gRo|SLz(m+!#F??o|!_Vl@e*!n3>i=5%C6^;ru&WW6d3rQH`qAgz1J6)z` zg=0f2<6KF{dKD&OQ>jz;%*cdEeS8$I`Hqb1aDT&7BMBogm4ut&P#fH`zTD={-Izs^ zFvz{|Yr=g!)Fe!2rsKi`mVGd00H4iL_t(YOWl-bR}(=LK;K1@SSXg*3y3{puc#=X7%O7$9cu#r|D*HX zya}vHVD}t7$K(BwS9b60yxBdG&H$d}T!z%2B5!uK7)|L*y zL5+tve56w2sOHA#v9MNO=pPq30VmVYr+oI)oDn(8IV&6$s+rxSj`bQ$#HLcC=9$qFCiU@AnDQMN*MH%Lr$!P+U^)pm!=cu>WqrBLox3rM zBw>JiRt4d{9%>S1TBhT|1DLfc2orj!>AoQz&RCL&!lTDLiB%Au>W>T4@J!<(QFsph zTG@+xp@-^1jh7k%aXc4Z!KhVAFN{@R*O`1{FDE@9BfN!oRw+S3^vM%dFLo-dtGdOqVVFCN!G!o^@L)+g=Feg6DaJMyQ|>i#$Tpgk~)A2=gZR6nTWg zGZa6ir4$zOy||SrEOcj?&$}~!f3tr~5El6bBUvs7bl1r300000NkvXXu0mjf_yYvZ From 6e0cc5cd9f90b4a8a67a1f66f3f106fc7f46b96e Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:40:28 +0200 Subject: [PATCH 013/183] Update settings.js --- apps/pongclock/settings.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/pongclock/settings.js b/apps/pongclock/settings.js index 2c9b9d6a0..0d61d013d 100644 --- a/apps/pongclock/settings.js +++ b/apps/pongclock/settings.js @@ -28,17 +28,17 @@ value: !!settings.isInvers, // !! converts undefined to false format: v => v?"Yes":"No", onchange: v => { - settings.withWidgets = v; + settings.isInvers = v; writeSettings(); } }, 'On Lock?': { - value: !!settings.isInvers, // !! converts undefined to false + value: !!settings.playLocked, // !! converts undefined to false format: v => v?"Play":"Pause", onchange: v => { - settings.withWidgets = v; + settings.playLocked = v; writeSettings(); } } }); -})/*(load)/**/ \ No newline at end of file +})/*(load)/**/ From 787a6ae87e3a6d17fcd3e9dd29d46a62e523afcb Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:41:08 +0200 Subject: [PATCH 014/183] Add files via upload --- apps/pongclock/screenshot.png | Bin 0 -> 755 bytes apps/pongclock/screenshot_invers_full.png | Bin 0 -> 480 bytes apps/pongclock/screenshot_settings.png | Bin 0 -> 1154 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/pongclock/screenshot.png create mode 100644 apps/pongclock/screenshot_invers_full.png create mode 100644 apps/pongclock/screenshot_settings.png diff --git a/apps/pongclock/screenshot.png b/apps/pongclock/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..0750105f0bf3e25ac22eec3334235702c2cecd94 GIT binary patch literal 755 zcmVPx#1ZP1_K>z@;j|==^1poj54^T{0MF0Q*|Ns90|Nj9000030(Qvkb00009a7bBm z000id000id0mpBsWB>pHZAnByRA}Dq+igz9APfNDb|-)vyx{~UUcevT|4hCc8-r5D z$BJ>WjnRPkNLcxpoA9r~X5s6X*DToiuXt3OUbs-P>|Lh6@IDOgF8sO22Z2eKK?HUI zHoFWc0xz#H6kdK`L=hO=dGS^mn2XU3Z_MIcD83U7CC1nr?iGsf@=zYvVT;z-2}7}} zrn}1p*u^t%RR!SnQq4zN|^JZ;L z|2d4p3M;JeLt(N(kyEpQblc!tae*mJ&*MDYaB9c&43M4lSvYIOM0&W$@1{7o<(`W) z$i|X|^Hy2lEO`AUo-q2h@%7wc+8fBOdIp;mHb?a(Oj|Lqfe1bXJShfdS}`ziFf_qe zv5%EJY-Yj0!^{{*$wi7Sa5*dDw5?}x2E&=5z`^NCQIoM_<{8L~O>lJ)g1p!SSC>tB z7|z9k6r14UP{he%8`cU67cXA;wa~U!Ffiol2I;qLK0j-4VS?O;EkC8@U{KgzZ%yOr zR>%rcjr|j(u>F(j#_hkbzCZ*wFUZND{tnD9LbSSgC@jPLvYAyEI(!8K{RzWX^X?@~ zH+I8Uvo7@fRjljgMqz~&R#;($6;}Aq!#$y}!U`*_u)+${XncsFu)+!}tgyl&aKo+P z5L|ouGYoUjCKP@MJS{7x<#9_q68=u(3#4KitPw|eUMuY;&&1{8c=eHgR(lJ6f2^

8)3B4w}@M>Aza1>z}stz6JVSKZ~tR51K!ej0*w1xDAF(i_mmfd_A5L06)cZkHOI4NO=GN002ovPDHLkV1it>S||Vj literal 0 HcmV?d00001 diff --git a/apps/pongclock/screenshot_invers_full.png b/apps/pongclock/screenshot_invers_full.png new file mode 100644 index 0000000000000000000000000000000000000000..434e248722a5b200c2490be1a55e3e3bdab3d748 GIT binary patch literal 480 zcmeAS@N?(olHy`uVBq!ia0vp^8$g(a8A!&?{Fw`+7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x{{R0U$P7JnxeiEi7I;J!GcfQS24TkI`72U@MkIT>IEG~0dwVmm zs6~ON;bB4ZlYi6SmRM;_*uf<|x9s=xvpGN9L32pzn1IG6pg7XNAA4fj}2i`W$Q zK7Y^|Xvmt+TrPjyh*O+@`p%i=2Yl7z4~B~=vS0T*RWr;<$dJ=IQY*zucn-V4GjKq{CE@1_rbVe?a8+7`7$>@eB=M4-{9J? w{6TAAA#a?-aq)*z5RKW4JTUO*;)WCAD@sBxT=}?y7Z?W&p00i_>zopr03ff+=l}o! literal 0 HcmV?d00001 diff --git a/apps/pongclock/screenshot_settings.png b/apps/pongclock/screenshot_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..0b27286ea2122211673304570156c799cf9623a8 GIT binary patch literal 1154 zcmV-|1bzF7P)Px#1ZP1_K>z@;j|==^1poj56;Mo6MF0Q*{{R60|Nj90{{a60sQ>@~0RK~Nwu=A& z010qNS#tmY4#NNd4#NS*Z>VGd00Z_(L_t(&-tC%8lH4E+hG}zw_9A;1CvcT6kVOuX zRqlU;F-QpUvhjnSOcj5nCpI=;%aX8B8|CzRs~&pIo8Fzc^98cWgzb98|7X&3V2}o1 zFxgZZG@3lmS52;h72E~?A^lFk)@0`iq`w~lg8;v;Wn3AoS9Hb8`QTFYDy{$w-ir-> z0PGS@gO44y&hxKlzzWu`;BKyXGoxX9nXx!>6@_r^S+{ z#eD~EO0Z})?FQrZw}Hv#V;=js9eix?MR2o+pSQRTY|i`m3b-jNVjpvsQm!saWbnB> zPQZR#;UF{=sW2ihjJ%R=b^aEx=|d$K4-E|s{Y2TR@;0r-88gpslfA8gTeFT^QK#3N zU{G{IbZ{%bZi4Mb%CH@v0j#co8(d+F;LVYnC&BqnZoygyyDseR=$zmRP~J-T8B zl`Mwf?lKsUu?*0i@p2cA_Vp( zx&6R2%~b42u%5?O?F+dwnCiFUY!ejMcHWUR^9FAcS2>w=G&wHSd8K-Zz8a!JPE}^f z)w0@8pT+l5T4msZJ5PdD5nM_vE+^_>=U}Yx1eo{tz%Fi;;CV1dO|mL(kQVb!0j#MQ z{XBTj$9v$=KY-wRA zQsL2$;76k0;&;JuZ4}J|>x!qSMQ}3T+pQWu1!lJ)SVwQ^pa|CCt%9rwQ*d0!`Qpx3 zaVqmMU5TuHAS=G5O%Qte1KcFRWPm8L@`?8zSoyax(w2~Jx4@afekat|m%wOS0W89b zFKi(hH%%5t5|vaiGp|hBeEc-nXGOskhhU$s0-Wb@&BviEguD=pUV}q;ksd}~Ju4K) zZ5?l^KB|AQ{{H{qAt_qsIGtTaiBBeRo5XEyp#_waG3HUQ1zNILy5Gq4%K_pK-*G0p zme#IfU(~Z;wAOieI-FE|8`Ihq&K_?8XW1w7pVtJEC=JmK2v z=fN(G&j%0W^ir>B3mM!2jNB`(I1r7B=fTD=oj*D98o+q>IeioQcJTBtw~v(i0yqOa Uz*OMF<^TWy07*qoM6N<$g8VEe9RL6T literal 0 HcmV?d00001 From 0443a56a9d7dfb5fc539aa69735141b3a05e0c18 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:42:42 +0200 Subject: [PATCH 015/183] Update metadata.json --- apps/pongclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index 9ce9fe291..31df2e747 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -7,6 +7,7 @@ "tags": "", "supports": ["BANGLEJS", "BANGLEJS2"], "readme":"README.md", + "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_settings.png" }, { "url":"screenshot_invers_full.png" } ], "storage": [ {"name":"pongclock.app.js","url":"app.js"}, {"name":"pongclock.img","url":"pongclock-icon.js","evaluate":true}, From d2a6789a1f07f21a329980b32251e4edde1107f0 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:44:25 +0200 Subject: [PATCH 016/183] Update README.md --- apps/pongclock/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/pongclock/README.md b/apps/pongclock/README.md index cc152d7b9..894070b73 100644 --- a/apps/pongclock/README.md +++ b/apps/pongclock/README.md @@ -8,6 +8,8 @@ A clock which is playing Pong while showing the current time as score * Loosely based on [https://codepen.io/Rabrennie/pen/WxNEoe](https://codepen.io/Rabrennie/pen/WxNEoe) ![](screenshot.png) +![](screenshot_settings.png) +![](screenshot_invers_full.png) ## Creator [@pidajo](https://github.com/pidajo) From 44bb646946cbe344a259de95c0d425d19bd0c76d Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:56:55 +0200 Subject: [PATCH 017/183] Update app.js --- apps/pongclock/app.js | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/apps/pongclock/app.js b/apps/pongclock/app.js index 8efe0eca5..e6f8355ea 100644 --- a/apps/pongclock/app.js +++ b/apps/pongclock/app.js @@ -28,7 +28,7 @@ class Ball { } if (test) { this.velX = -this.velX; - this.valY = (3.5 + Math.random()) * this.valY / Math.abs(this.valY); + this.valY = (3.5 + 2 * Math.random()) * this.valY / Math.abs(this.valY); if (isLeft) { right.follow = this; @@ -161,9 +161,17 @@ function redraw() { g.clearRect(0, top + left.oldY, left.w, top + left.oldY + left.h); g.clearRect(width - right.w, top + right.oldY, width, top + right.oldY + right.h); - g.clearRect(width / 2 - fontHeight * 1.4, fontTop, width / 2 + fontHeight * 1.4, fontTop + fontHeight); + //g.clearRect(width / 2 - fontHeight * 1.4, fontTop, width / 2 + fontHeight * 1.4, fontTop + fontHeight); g.clearRect(ball.oldX - ball.w, top + ball.oldY - ball.h, ball.oldX + ball.w, top + ball.oldY + ball.h); + g.setFontVector(fontHeight); + /**/ + g.setFontAlign(1, -1); + g.drawString(("0" + left.score).substr(-2), 5 * width / 11, fontTop, true); + g.setFontAlign(-1, -1); + g.drawString(("0" + right.score).substr(-2), 6 * width / 11, fontTop, true); + /**/ + g.drawLine(width / 2, top, width / 2, topHeight); g.fillRect(0, top + left.y, left.w, top + left.y + left.h); left.oldY = left.y; @@ -172,18 +180,6 @@ function redraw() { g.fillCircle(ball.x, top + ball.y, ball.w); ball.oldX = ball.x; ball.oldY = ball.y; - - g.setFontVector(fontHeight); - /* - g.setFontAlign(0, -1); - g.drawString(("0" + left.score).substr(-2)+ " " + ("0" + right.score).substr(-2), width / 2, fontTop); - */ - /**/ - g.setFontAlign(1, -1); - g.drawString(("0" + left.score).substr(-2), 5 * width / 11, fontTop); - g.setFontAlign(-1, -1); - g.drawString(("0" + right.score).substr(-2), 6 * width / 11, fontTop); - /**/ } function restart() { @@ -224,6 +220,7 @@ function pause() { pauseTimeout = setTimeout(pause, Date.now() % 60000); } +//load settings const SETTINGS_FILE = "pongclock.json"; var settings = Object.assign({ // default values @@ -233,12 +230,14 @@ var settings = Object.assign({ }, require('Storage').readJSON(SETTINGS_FILE, true) || {}); require('Storage').writeJSON(SETTINGS_FILE, settings); +//make clock +Bangle.setUI("clock"); + +//setup play area var height = g.getHeight(), width = g.getWidth(); var top = 0; -Bangle.setUI("clock"); - g.reset(); g.clearRect(0, top, width, height); @@ -252,10 +251,10 @@ if (settings.withWidgets) { var w = WIDGETS[i]; if (w.area) { if (w.area.indexOf("t") >= 0) { - top = 25; + top = Bangle.appRect.y; } if (w.area.indexOf("b") >= 0) { - bottom = 25; + bottom = height - Bangle.appRect.y2; } } } @@ -269,6 +268,7 @@ if (settings.isInvers) { } g.clearRect(0, top, width, top + height); +//setup game var left = new Paddle("left"); var right = new Paddle("right"); var ball = new Ball(true); @@ -291,6 +291,7 @@ Bangle.on("lock", (on) => { } }); +//start clock restart(); if (!settings.playLocked && Bangle.isLocked()) { pause(); @@ -299,6 +300,7 @@ if (!settings.playLocked && Bangle.isLocked()) { } /* +//local testing require("Storage").write("pongclock.info",{ "id":"pongclock", "name":"Pong Clock", From eec644be42fc87b91504b3e11bd844e47863c18b Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 19:58:15 +0200 Subject: [PATCH 018/183] Update metadata.json --- apps/pongclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index 31df2e747..78565e794 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -5,6 +5,7 @@ "version":"0.1", "description": "A clock playing Pong", "tags": "", + "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], "readme":"README.md", "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_settings.png" }, { "url":"screenshot_invers_full.png" } ], From 1f59957735f7da4a9c3e557ca4315194e827c62e Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 20:03:56 +0200 Subject: [PATCH 019/183] Update pongclock-icon.js --- apps/pongclock/pongclock-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/pongclock-icon.js b/apps/pongclock/pongclock-icon.js index 00002a018..22e472af4 100644 --- a/apps/pongclock/pongclock-icon.js +++ b/apps/pongclock/pongclock-icon.js @@ -1 +1 @@ -atob("MDCEBP//////////////AA//////////////////////////////AA//////////////////////////////AA//////////////////////////////AA//////////////////////////P///Ii//////////P////////zEAP/MQAC///////xAf//8xAAL/////8gAAP/AAAAL//////wAv//MAAAAv////8gEAPzAD8QD/Ii//8wA///IAPxAf////8S8APyAf8wD/AA//8gD///EB/yAP//////8APxAP8wD/AA//8AH///AB/yAf//////8AP///8gD/AA//MAP//////xAf//////8AP///8QH/AA//IA///////wAv//////8AP///MAP/AA//EB8AL///8gD///////8AP///EB//AA//AC8AL///8AL///////8AP//yAD//AA/zAD8AL///IA////////8AP//wAf//AA/xAP8AL//zAC////////8AP/8gA///Ii/wAf8AL//xAP///wAP//8AP/MAH/////8wABEAEf8wAv///wAP//8AP/EA//////8wAAAAAf8QD////wAP//8APzAB////Ii/yIiIAEvIAL////wAP//8APyAAAAD/AA////8AL/EAAAAP/wAP//8APyAAAAD/AA////8AL/EAAAAP/wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////AA///////////////wAP////////////Ii///////////////wAP///////////////////////////wAAAP///////////////////////////wAP//////////////Ii/////////////wAP//////8yP/////AA/////////////wAP//////EAAf////AA/////////////wAP/////zAAAD////AA/////////////wAP/////yAAAC////AA/////////////wAP/////zAAAD////AA/////////////wAP//////EAAf////AA/////////////wAP//////8yP/////AA/////////////wAP//////////////AA/////////////wAP//////////////Ii/////////////wAP/////////////////////////////wAP//////////////////////////////////////////////Ii//////////////////////////////AA//////////////////////////////AA//////////////////////////////AA//////////////////////////////AA///////////////w==") +atob("MDCEBAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAIiAAAAAAAAAAEAAAAAAAABP/EAE//yAAAAAAAD8wAAAT//IAAAAAAv//EA////IAAAAAAP8gAAH///8gAAAAAvP/EB/xA/MAIiAAAf8QAAL/ED8wAAAAAxD/EC8wAf8ALyAAAv8AAAPyAC/wAAAAAAD/ED/wAf8ALyAAD/MAAA/zAC8wAAAAAAD/EAAAAv8ALyAAH/EAAAAAAD8wAAAAAAD/EAAAA/IALyAAL/AAAAAAAP8gAAAAAAD/EAAAH/EALyAAPzD/IAAAAv8AAAAAAAD/EAAAPzAALyAA/yD/IAAAD/IAAAAAAAD/EAAB/xAALyAB/xD/IAAAL/AAAAAAAAD/EAAP8wAALyAC/wD/IAAB/yAAAAAAAAD/EAAv8QAAIiAP8wD/IAAD/wAAAAAAAAD/EAD/MAAAAAAf/zP/MwAf8gAAAA//AAD/EAL/AAAAAAAf////8wA/8AAAAA//AAD/EB/zAAAAIiACIiL/MgL/IAAAAA//AAD/EC////8ALyAAAAD/IAP////wAA//AAD/EC////8ALyAAAAD/IAP////wAA//AAAAAAAAAAAALyAAAAAAAAAAAAAAAA//AAAAAAAAAAAALyAAAAAAAAAAAAAAAA//AAAAAAAAAAAALyAAAAAAAAAAAAAAAA//AAAAAAAAAAAALyAAAAAAAAAAAAAAAA//AAAAAAAAAAAALyAAAAAAAAAAAAAAAA//AAAAAAAAAAAALyAAAAAAAAAAAAAAAA//AAAAAAAAAAAAIiAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAAAAAAAAD/8A//AAAAAAAAAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAIiAAAAAAAAAAAAD/8AAAAAAAASEAAAAALyAAAAAAAAAAAAD/8AAAAAAAP/8wAAAALyAAAAAAAAAAAAD/8AAAAAAB///xAAAALyAAAAAAAAAAAAD/8AAAAAAC///yAAAALyAAAAAAAAAAAAD/8AAAAAAB///xAAAALyAAAAAAAAAAAAD/8AAAAAAAP/8wAAAALyAAAAAAAAAAAAD/8AAAAAAAASEAAAAALyAAAAAAAAAAAAD/8AAAAAAAAAAAAAAALyAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAIiAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyAAAAAAAAAAAAAAAA==") From 11c7fd7e341b8036822c4ebab7eff8e16979edce Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 20:15:01 +0200 Subject: [PATCH 020/183] Update metadata.json --- apps/pongclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index 78565e794..f4c23c7c1 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -3,7 +3,7 @@ "shortName":"Pong Clock", "icon": "pongclock.png", "version":"0.1", - "description": "A clock playing Pong", + "description": "A Pong playing clock", "tags": "", "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], From fd3838dff6731ac00f79db72764ac45654702d82 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 23:53:15 +0200 Subject: [PATCH 021/183] Update app.js --- apps/pongclock/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/app.js b/apps/pongclock/app.js index e6f8355ea..932c1f3d7 100644 --- a/apps/pongclock/app.js +++ b/apps/pongclock/app.js @@ -28,7 +28,7 @@ class Ball { } if (test) { this.velX = -this.velX; - this.valY = (3.5 + 2 * Math.random()) * this.valY / Math.abs(this.valY); + this.velY = (3.5 + 2 * Math.random()) * this.velY / Math.abs(this.velY); if (isLeft) { right.follow = this; From 5b85363de8d6383120ba98f71adf2c9162e426fc Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 23:53:54 +0200 Subject: [PATCH 022/183] Update metadata.json --- apps/pongclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index f4c23c7c1..dbd044517 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -2,7 +2,7 @@ "name": "Pong Clock", "shortName":"Pong Clock", "icon": "pongclock.png", - "version":"0.1", + "version":"0.01", "description": "A Pong playing clock", "tags": "", "allow_emulator":true, From 133abbee90c1d8d7336ea872f4c327e31494728d Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 20 May 2022 23:54:15 +0200 Subject: [PATCH 023/183] Update ChangeLog --- apps/pongclock/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/ChangeLog b/apps/pongclock/ChangeLog index e8c8518ae..7b83706bf 100644 --- a/apps/pongclock/ChangeLog +++ b/apps/pongclock/ChangeLog @@ -1 +1 @@ -0.1: First release +0.01: First release From 2f1342eebc410b28933fa5fb4ffc82ec3916b9ee Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:30:12 +0200 Subject: [PATCH 024/183] Create app.js --- apps/widday/app.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 apps/widday/app.js diff --git a/apps/widday/app.js b/apps/widday/app.js new file mode 100644 index 000000000..a244098f5 --- /dev/null +++ b/apps/widday/app.js @@ -0,0 +1,27 @@ +(() => { + var width = 32; // width of the widget + + function draw() { + var date = new Date(); + g.reset(); // reset the graphics context to defaults (color/font/etc) + g.setFontAlign(0,1); // center fonts + //g.drawRect(this.x, this.y, this.x+width-1, this.y+23); // check the bounds! + + var text = "date.getDate(); + g.setFont("Vector", 24); + g.drawString(text, this.x+width/2+1, this.y + 28); + //g.setColor(0, 0, 1); + //g.drawRect(this.x, this.y, this.x+width-2, this.y+1); + } + + setInterval(function() { + WIDGETS["widdateday"].draw(WIDGETS["widdateday"]); + }, 10*60000); // update every 10 minutes + + // add your widget + WIDGETS["widdateday"]={ + area:"bl", // tl (top left), tr (top right), bl (bottom left), br (bottom right) + width: width, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout + draw:draw // called to draw the widget + }; +})() From e672b523c558e7ff7b01c92f2b232df9810e50c2 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:33:19 +0200 Subject: [PATCH 025/183] Update app.js --- apps/widday/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/widday/app.js b/apps/widday/app.js index a244098f5..189fc1951 100644 --- a/apps/widday/app.js +++ b/apps/widday/app.js @@ -15,11 +15,11 @@ } setInterval(function() { - WIDGETS["widdateday"].draw(WIDGETS["widdateday"]); + WIDGETS["widday"].draw(WIDGETS["widdateday"]); }, 10*60000); // update every 10 minutes // add your widget - WIDGETS["widdateday"]={ + WIDGETS["widday"]={ area:"bl", // tl (top left), tr (top right), bl (bottom left), br (bottom right) width: width, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout draw:draw // called to draw the widget From c5fac3dd2a6da475f22af869727f4fd60bd97a11 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:37:26 +0200 Subject: [PATCH 026/183] Create widday.info --- apps/widday/widday.info | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 apps/widday/widday.info diff --git a/apps/widday/widday.info b/apps/widday/widday.info new file mode 100644 index 000000000..351a302ca --- /dev/null +++ b/apps/widday/widday.info @@ -0,0 +1,8 @@ +{ + "id":"widday", + "name":"Day Widget", + "type":"widget", + "version":"0.01", + "tags":"widget,date,day", + "files":"widday.info,widday.wid.js" +} From 858d4deeebefb62246322619c647fdef91c99097 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:45:07 +0200 Subject: [PATCH 027/183] Create app-icon.js --- apps/widday/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/widday/app-icon.js diff --git a/apps/widday/app-icon.js b/apps/widday/app-icon.js new file mode 100644 index 000000000..aa17aedc5 --- /dev/null +++ b/apps/widday/app-icon.js @@ -0,0 +1 @@ +atob("MDCEAiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIBEREREREREREREREREREREREREREQIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////zMz////8zMzMzMzP////xIiIf///////czM////PMzMzMzMzP///xIiIf/////zzMzM////PMzMzMzMzP///xIiIf////PczMzM////PMzMzMzMzP///xIiIf////3MzMzM////8zMzMz3MzP///xIiIf////3MM8zM//////////zMw////xIiIf////0/88zM/////////zzMz////xIiIf//////88zM/////////8zM3////xIiIf//////88zM////////88zM/////xIiIf//////88zM/////////MzN/////xIiIf//////88zM////////PMzD/////xIiIf//////88zM////////3Mzf/////xIiIf//////88zM////////zMw//////xIiIf//////88zM///////9zMz//////xIiIf//////88zM///////8zMP//////xIiIf//////88zM//////88zM///////xIiIf//////88zM///////MzN///////xIiIf////8zM8zM//////PMzD///////xIiIf////3MzMzMzM3///3Mzf///////xIiIf////3MzMzMzM3//zzMw////////xIiIf////PMzMzMzM3//9zMz////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIf///////////////////////////xIiIBEREREREREREREREREREREREREREQIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIg==") From 68af6449dc5e737cf3503a073af1752f166d2580 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:45:59 +0200 Subject: [PATCH 028/183] Create ChangeLog --- apps/widday/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/widday/ChangeLog diff --git a/apps/widday/ChangeLog b/apps/widday/ChangeLog new file mode 100644 index 000000000..7b83706bf --- /dev/null +++ b/apps/widday/ChangeLog @@ -0,0 +1 @@ +0.01: First release From 6ab7263272e310c891a84e1ffd02d78760cf4384 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:48:07 +0200 Subject: [PATCH 029/183] Create metadata.info --- apps/widday/metadata.info | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 apps/widday/metadata.info diff --git a/apps/widday/metadata.info b/apps/widday/metadata.info new file mode 100644 index 000000000..1569528b0 --- /dev/null +++ b/apps/widday/metadata.info @@ -0,0 +1,12 @@ +{ "id": "widday", + "name": "Day Widget", + "shortName":"My Timer", + "icon": "widday.png", + "version":"0.01", + "description": "Just the day of the current date as widget", + "tags": "widget,say,date", + "storage": [ + {"name":"widday.wid.js","url":"app.js"}, + {"name":"widday.img","url":"app-icon.js","evaluate":true} + ] +} From 515469d2b5de6639efe30a9a7d96951a13e188e4 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:51:02 +0200 Subject: [PATCH 030/183] Update metadata.info --- apps/widday/metadata.info | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widday/metadata.info b/apps/widday/metadata.info index 1569528b0..fe999110a 100644 --- a/apps/widday/metadata.info +++ b/apps/widday/metadata.info @@ -4,6 +4,7 @@ "icon": "widday.png", "version":"0.01", "description": "Just the day of the current date as widget", + readme: "README.md "tags": "widget,say,date", "storage": [ {"name":"widday.wid.js","url":"app.js"}, From 309db1bdf2f641eff395dfc8bac51109a9e639f6 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:54:55 +0200 Subject: [PATCH 031/183] Create README.md --- apps/widday/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 apps/widday/README.md diff --git a/apps/widday/README.md b/apps/widday/README.md new file mode 100644 index 000000000..9d1969471 --- /dev/null +++ b/apps/widday/README.md @@ -0,0 +1,3 @@ +==Day Widget + +Just shows the day of the current date, to save space in the widget area. The month and year should be known because they don't change that often. Just the number in maximum size for readability. From 61135af33f7a761f83fe8ef4626918d09d3c819c Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:56:44 +0200 Subject: [PATCH 032/183] Update README.md --- apps/widday/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/widday/README.md b/apps/widday/README.md index 9d1969471..61f48aa4c 100644 --- a/apps/widday/README.md +++ b/apps/widday/README.md @@ -1,3 +1,9 @@ -==Day Widget +# Day Widget Just shows the day of the current date, to save space in the widget area. The month and year should be known because they don't change that often. Just the number in maximum size for readability. + +![](screenshot.png) + +## Creator +[@pidajo](https://github.com/pidajo) + From 65524a28b67ca76207417d9afaa422ab0a6bce30 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Thu, 26 May 2022 18:58:40 +0200 Subject: [PATCH 033/183] Update metadata.info --- apps/widday/metadata.info | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/widday/metadata.info b/apps/widday/metadata.info index fe999110a..54e42f000 100644 --- a/apps/widday/metadata.info +++ b/apps/widday/metadata.info @@ -6,6 +6,9 @@ "description": "Just the day of the current date as widget", readme: "README.md "tags": "widget,say,date", + "allow_emulator":true, + "supports": ["BANGLEJS", "BANGLEJS2"], + "screenshots" : [ { "url":"screenshot.png" } ], "storage": [ {"name":"widday.wid.js","url":"app.js"}, {"name":"widday.img","url":"app-icon.js","evaluate":true} From dab3c045db660ae4f7837312e713fcc206dd113a Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:13:40 +0200 Subject: [PATCH 034/183] Use prompt with dimiss and pause --- apps/widbaroalarm/ChangeLog | 1 + apps/widbaroalarm/metadata.json | 2 +- apps/widbaroalarm/settings.js | 20 +++++++++++++++ apps/widbaroalarm/widget.js | 44 ++++++++++++++++++++------------- 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/apps/widbaroalarm/ChangeLog b/apps/widbaroalarm/ChangeLog index 5786741c7..b61e1691b 100644 --- a/apps/widbaroalarm/ChangeLog +++ b/apps/widbaroalarm/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial version 0.02: Do not warn multiple times for the same exceedance 0.03: Fix crash +0.04: Use Prompt with dismiss and pause diff --git a/apps/widbaroalarm/metadata.json b/apps/widbaroalarm/metadata.json index 134f03623..9f5cffcfe 100644 --- a/apps/widbaroalarm/metadata.json +++ b/apps/widbaroalarm/metadata.json @@ -2,7 +2,7 @@ "id": "widbaroalarm", "name": "Barometer Alarm Widget", "shortName": "Barometer Alarm", - "version": "0.03", + "version": "0.04", "description": "A widget that can alarm on when the pressure reaches defined thresholds.", "icon": "widget.png", "type": "widget", diff --git a/apps/widbaroalarm/settings.js b/apps/widbaroalarm/settings.js index bea6319d1..faece90a2 100644 --- a/apps/widbaroalarm/settings.js +++ b/apps/widbaroalarm/settings.js @@ -87,6 +87,26 @@ }, onchange: x => save('buzz', x) }, + 'Dismiss delay': { + value: settings.dismissDelayMin, + min: 5, max: 60, + onchange: v => { + save('dismissDelayMin', x) + }, + format: x => { + return x + " min"; + } + }, + 'Pause delay': { + value: settings.pauseDelayMin, + min: 30, max: 240, + onchange: v => { + save('pauseDelayMin', x) + }, + format: x => { + return x + " min"; + } + }, }; E.showMenu(menu); } diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 2745db8ad..c2a9e1c54 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -32,13 +32,21 @@ let history3 = storage.readJSON(LOG_FILE, true) || []; // history of recent 3 hours - function showAlarm(body, title) { + function showAlarm(body, title, key) { if (body == undefined) return; - require("notify").show({ + E.showPrompt(body, { title: title || "Pressure", - body: body, - icon: require("heatshrink").decompress(atob("jEY4cA///gH4/++mkK30kiWC4H8x3BGDmSGgYDCgmSoEAg3bsAIDpAIFkmSpMAm3btgIFDQwIGNQpTYkAIJwAHEgMoCA0JgMEyBnBCAW3KoQQDhu3oAIH5JnDBAW24IIBEYm2EYwACBCIACA")) + buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } + }).then(function (v) { + const tsNow = Math.round(Date.now() / 1000); // seconds + + if (v == 2) { + saveSetting(key, tsNow + 60 * settings('dismissDelayMin')); + } + if (v == 3) { + saveSetting(key, tsNow + 60 * settings('pauseDelayMin')); + } }); if (setting("buzz") && @@ -48,8 +56,10 @@ } - function didWeAlreadyWarn(key) { - return setting(key) == undefined || setting(key) > 0; + function doWeNeedToWarn(key) { + const tsNow = Math.round(Date.now() / 1000); // seconds + + return setting(key) == 0 || setting(key) < tsNow; } function checkForAlarms(pressure) { @@ -77,7 +87,7 @@ if (setting("lowalarm")) { // Is below the alarm threshold? if (pressure <= setting("min")) { - if (!didWeAlreadyWarn("lastLowWarningTs")) { + if (!doWeNeedToWarn("lastLowWarningTs")) { showAlarm("Pressure low: " + Math.round(pressure) + " hPa"); saveSetting("lastLowWarningTs", ts); alreadyWarned = true; @@ -92,7 +102,7 @@ if (setting("highalarm")) { // Is above the alarm threshold? if (pressure >= setting("max")) { - if (!didWeAlreadyWarn("lastHighWarningTs")) { + if (!doWeNeedToWarn("lastHighWarningTs")) { showAlarm("Pressure high: " + Math.round(pressure) + " hPa"); saveSetting("lastHighWarningTs", ts); alreadyWarned = true; @@ -122,7 +132,7 @@ // drop alarm if (drop3halarm > 0 && oldestPressure > pressure) { if (Math.abs(diff) > drop3halarm) { - if (!didWeAlreadyWarn("lastDropWarningTs")) { + if (!doWeNeedToWarn("lastDropWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop"); saveSetting("lastDropWarningTs", ts); @@ -137,7 +147,7 @@ // raise alarm if (raise3halarm > 0 && oldestPressure < pressure) { if (Math.abs(diff) > raise3halarm) { - if (!didWeAlreadyWarn("lastRaiseWarningTs")) { + if (!doWeNeedToWarn("lastRaiseWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise"); saveSetting("lastRaiseWarningTs", ts); @@ -176,7 +186,7 @@ /* turn on barometer power - take 5 measurements + take `numberOfMeasurements` measurements sort the results take the middle one (median) turn off barometer power @@ -186,11 +196,11 @@ setTimeout(function() { currentPressures = []; - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); + const numberOfMeasurements = 5; + + for (let i = 0; i < numberOfMeasurements; i++) { + Bangle.getPressure().then(baroHandler); + } setTimeout(function() { Bangle.setBarometerPower(false, "widbaroalarm"); @@ -198,7 +208,7 @@ currentPressures.sort(); // take median value - medianPressure = currentPressures[3]; + medianPressure = currentPressures[Math.round(numberOfMeasurements / 2) + 1]; checkForAlarms(medianPressure); }, 1000); }, 500); From 71d9907657c820da3ad94bd5219b18777215d6b3 Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:20:15 +0200 Subject: [PATCH 035/183] Fix settings --- apps/widbaroalarm/default.json | 4 +++- apps/widbaroalarm/settings.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/widbaroalarm/default.json b/apps/widbaroalarm/default.json index 3d81baa81..696c70819 100644 --- a/apps/widbaroalarm/default.json +++ b/apps/widbaroalarm/default.json @@ -7,5 +7,7 @@ "drop3halarm": 2, "raise3halarm": 0, "show": true, - "interval": 15 + "interval": 15, + "dismissDelayMin": 15, + "pauseDelayMin": 60 } diff --git a/apps/widbaroalarm/settings.js b/apps/widbaroalarm/settings.js index faece90a2..ee8ce82c2 100644 --- a/apps/widbaroalarm/settings.js +++ b/apps/widbaroalarm/settings.js @@ -91,7 +91,7 @@ value: settings.dismissDelayMin, min: 5, max: 60, onchange: v => { - save('dismissDelayMin', x) + save('dismissDelayMin', v) }, format: x => { return x + " min"; @@ -101,7 +101,7 @@ value: settings.pauseDelayMin, min: 30, max: 240, onchange: v => { - save('pauseDelayMin', x) + save('pauseDelayMin', v) }, format: x => { return x + " min"; From a29eeaca510a3386fd9794316a051d4fd0b6977e Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:25:29 +0200 Subject: [PATCH 036/183] Remove dependency --- apps/widbaroalarm/metadata.json | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/widbaroalarm/metadata.json b/apps/widbaroalarm/metadata.json index 9f5cffcfe..41b8d3e17 100644 --- a/apps/widbaroalarm/metadata.json +++ b/apps/widbaroalarm/metadata.json @@ -8,7 +8,6 @@ "type": "widget", "tags": "tool,barometer", "supports": ["BANGLEJS2"], - "dependencies": {"notify":"type"}, "readme": "README.md", "storage": [ {"name":"widbaroalarm.wid.js","url":"widget.js"}, From 55a346272aaeb317a32f9d33f010f4912bbf861b Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:31:48 +0200 Subject: [PATCH 037/183] Update README --- apps/widbaroalarm/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/widbaroalarm/README.md b/apps/widbaroalarm/README.md index fdc239170..a74d89546 100644 --- a/apps/widbaroalarm/README.md +++ b/apps/widbaroalarm/README.md @@ -15,7 +15,8 @@ Get a notification when the pressure reaches defined thresholds. 0 to disable this alarm. * Show widget: Enable/disable widget visibility * Buzz on alarm: Enable/disable buzzer on alarm - +* Dismiss delay: Delay added before the next alert if the alert is dismissed. From 5 to 60 min +* Pause delay: Same as Dismiss delay but longer (usefull for meetings and such). From 30 to 240 min ## Widget The widget shows two rows: pressure value of last measurement and pressure average of the the last three hours. From 02fc7af75085581c6de5cc67c515b445331398f2 Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 20:07:15 +0200 Subject: [PATCH 038/183] Fix warning --- apps/widbaroalarm/widget.js | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index c2a9e1c54..721d0bbb8 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -32,33 +32,38 @@ let history3 = storage.readJSON(LOG_FILE, true) || []; // history of recent 3 hours - function showAlarm(body, title, key) { + function showAlarm(body, key) { if (body == undefined) return; E.showPrompt(body, { - title: title || "Pressure", + title: "Pressure alarm", buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } }).then(function (v) { const tsNow = Math.round(Date.now() / 1000); // seconds + if (v == 1) { + saveSetting(key, tsNow); + } if (v == 2) { - saveSetting(key, tsNow + 60 * settings('dismissDelayMin')); + saveSetting(key, tsNow + 60 * setting('dismissDelayMin')); } if (v == 3) { - saveSetting(key, tsNow + 60 * settings('pauseDelayMin')); + saveSetting(key, tsNow + 60 * setting('pauseDelayMin')); } + load(); }); if (setting("buzz") && !(storage.readJSON('setting.json', 1) || {}).quiet) { Bangle.buzz(); } + + setTimeout(load, 20000); } function doWeNeedToWarn(key) { const tsNow = Math.round(Date.now() / 1000); // seconds - return setting(key) == 0 || setting(key) < tsNow; } @@ -88,8 +93,7 @@ // Is below the alarm threshold? if (pressure <= setting("min")) { if (!doWeNeedToWarn("lastLowWarningTs")) { - showAlarm("Pressure low: " + Math.round(pressure) + " hPa"); - saveSetting("lastLowWarningTs", ts); + showAlarm("Pressure low: " + Math.round(pressure) + " hPa", "lastLowWarningTs"); alreadyWarned = true; } } else { @@ -102,9 +106,8 @@ if (setting("highalarm")) { // Is above the alarm threshold? if (pressure >= setting("max")) { - if (!doWeNeedToWarn("lastHighWarningTs")) { - showAlarm("Pressure high: " + Math.round(pressure) + " hPa"); - saveSetting("lastHighWarningTs", ts); + if (doWeNeedToWarn("lastHighWarningTs")) { + showAlarm("Pressure high: " + Math.round(pressure) + " hPa", "lastHighWarningTs"); alreadyWarned = true; } } else { @@ -132,10 +135,9 @@ // drop alarm if (drop3halarm > 0 && oldestPressure > pressure) { if (Math.abs(diff) > drop3halarm) { - if (!doWeNeedToWarn("lastDropWarningTs")) { + if (doWeNeedToWarn("lastDropWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop"); - saveSetting("lastDropWarningTs", ts); + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop", "lastDropWarningTs"); } } else { saveSetting("lastDropWarningTs", 0); @@ -147,10 +149,9 @@ // raise alarm if (raise3halarm > 0 && oldestPressure < pressure) { if (Math.abs(diff) > raise3halarm) { - if (!doWeNeedToWarn("lastRaiseWarningTs")) { + if (doWeNeedToWarn("lastRaiseWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise"); - saveSetting("lastRaiseWarningTs", ts); + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise", "lastRaiseWarningTs"); } } else { saveSetting("lastRaiseWarningTs", 0); @@ -186,7 +187,7 @@ /* turn on barometer power - take `numberOfMeasurements` measurements + take `numberOfMeasurements` measurements with a delay of 1000ms each sort the results take the middle one (median) turn off barometer power @@ -196,10 +197,12 @@ setTimeout(function() { currentPressures = []; - const numberOfMeasurements = 5; + const numberOfMeasurements = 7; for (let i = 0; i < numberOfMeasurements; i++) { - Bangle.getPressure().then(baroHandler); + setTimeout(function() { + Bangle.getPressure().then(baroHandler); + }, i * 1000); } setTimeout(function() { @@ -210,7 +213,7 @@ // take median value medianPressure = currentPressures[Math.round(numberOfMeasurements / 2) + 1]; checkForAlarms(medianPressure); - }, 1000); + }, numberOfMeasurements * 1000 + 500); }, 500); } From 5968df327cf8001cf8e70445131a0689ad0f2035 Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 20:15:05 +0200 Subject: [PATCH 039/183] Improve changelog --- apps/widbaroalarm/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widbaroalarm/ChangeLog b/apps/widbaroalarm/ChangeLog index b61e1691b..0afe4bc8b 100644 --- a/apps/widbaroalarm/ChangeLog +++ b/apps/widbaroalarm/ChangeLog @@ -2,3 +2,4 @@ 0.02: Do not warn multiple times for the same exceedance 0.03: Fix crash 0.04: Use Prompt with dismiss and pause + Improve barometer value median calculation From 704195c8b7aeda0bc6b45fa90135c5365902367a Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 27 May 2022 00:10:45 +0200 Subject: [PATCH 040/183] Add files via upload --- apps/widday/screenshot.png | Bin 0 -> 938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/widday/screenshot.png diff --git a/apps/widday/screenshot.png b/apps/widday/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..9a7a9f8cf2734434d401dfb8ad00aae994e1f7af GIT binary patch literal 938 zcmV;b16BNqP)Px#1ZP1_K>z@;j|==^1poj56;Mo6MF0Q*Hvj-PH#Yz`Hvl&P03;;;|NnfXPbB~V z010qNS#tmY4#NNd4#NS*Z>VGd00SOLL_t(&-tC!Dj^iKx<)$Qbxf|Vtxc7SUw4|E(1o;o#y>Q?) zHkeJer#}YIg^raD23wP-=zBZBdOd;X%;(GCKVQ3Iu=BF>1k-N_u(5Ur-?ofHSWMm( z7v}>XJp@><9K1^~*z7rLn!y}+qAhm(In$U9>DUU^A=_fGO=S!?b_E9PT@eQl0*-4uNyYCivgTnxchcv`ul?PX)TcN{GLh-a&IY3HaKhsN1^m30Tv4^P=d;AaO z73HzZOSf72xrP%G9|~R~3<4a+a*Wu)3I%pkoa^x$H_T=g^;Lhvwq1^{usgr4su6+$ zY>Q$9o@RGXjn1*R2?WOz@iYs8&80jC7Qk)6Q;|(2uxd?05%2;A2Oo3HmO}7sXI&oe z!E?LG4?`YovpMp#_L2924N6E-;Lh2uM3wRG(9qD3n1~31NjuD1Qm+W`n)xP#$*234 z1#7Y|N65LG+MKRaUod#J4YD4$%_gU(<^-@_L$gU@;M5n^r4VqMaH++u!Fvx@jlt7W z;CI2pgFExMFhKf8Uj8CBv1`hZ1FuqGB?KNC8X6iJ8iI>*MOOnR?KrRVAk}ehIo1fy zEyt7?m}^&8b8_LS_v-UQWy@G~D7?dts+Kyb5$@6*%+T$aD*STxh3P?n^|_GU)(3sy zT!lWJB0t0@r&clLvuCTl$k1KI^2Pfx!wLjV8( M07*qoM6N<$f^(y#>Hq)$ literal 0 HcmV?d00001 From 069e0c13a918273f6c35e295cf3688734d75a615 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Thu, 26 May 2022 15:29:38 +0200 Subject: [PATCH 041/183] android: added calendar sync events --- apps/android/boot.js | 15 +++++++++++++++ apps/android/metadata.json | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/android/boot.js b/apps/android/boot.js index efd7e7e46..829c1b4b0 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -90,6 +90,21 @@ sched.setAlarms(alarms); sched.reload(); }, + //TODO perhaps move those in a library (like messages), used also for viewing events? + "calendar" : function() { + var cal; + try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} + if (!cal) cal = {}; // first event + cal[event.id] = event; + require("Storage").writeJSON("android.calendar.json", cal); + }, + "calendar-" : function() { + var cal; + try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} + if (!cal) return; //nothing to remove + if (event.id in cal) delete cal[event.id]; + require("Storage").writeJSON("android.calendar.json", cal); + } }; var h = HANDLERS[event.t]; if (h) h(); else console.log("GB Unknown",event); diff --git a/apps/android/metadata.json b/apps/android/metadata.json index bf37b8407..c8e404aba 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -15,6 +15,6 @@ {"name":"android.img","url":"app-icon.js","evaluate":true}, {"name":"android.boot.js","url":"boot.js"} ], - "data": [{"name":"android.settings.json"}], + "data": [{"name":"android.settings.json"}, {"name":"android.calendar.json"}], "sortorder": -8 } From 8c42e81aea127cb2cb47c30ebd30a2764d857889 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Thu, 26 May 2022 20:41:44 +0200 Subject: [PATCH 042/183] Added basic agenda --- apps/agenda/ChangeLog | 1 + apps/agenda/README.md | 3 + apps/agenda/agenda-icon.js | 1 + apps/agenda/agenda.js | 102 ++++++++++++++++++++++++++++++ apps/agenda/agenda.png | Bin 0 -> 7227 bytes apps/agenda/metadata.json | 16 +++++ apps/agenda/screenshot_agenda.png | Bin 0 -> 2584 bytes 7 files changed, 123 insertions(+) create mode 100644 apps/agenda/ChangeLog create mode 100644 apps/agenda/README.md create mode 100644 apps/agenda/agenda-icon.js create mode 100644 apps/agenda/agenda.js create mode 100644 apps/agenda/agenda.png create mode 100644 apps/agenda/metadata.json create mode 100644 apps/agenda/screenshot_agenda.png diff --git a/apps/agenda/ChangeLog b/apps/agenda/ChangeLog new file mode 100644 index 000000000..56dfffa0d --- /dev/null +++ b/apps/agenda/ChangeLog @@ -0,0 +1 @@ +0.01: Basic agenda with events from GB diff --git a/apps/agenda/README.md b/apps/agenda/README.md new file mode 100644 index 000000000..5141673c0 --- /dev/null +++ b/apps/agenda/README.md @@ -0,0 +1,3 @@ +# Calendar + +Basic agenda reading the events synchronised from GadgetBridge diff --git a/apps/agenda/agenda-icon.js b/apps/agenda/agenda-icon.js new file mode 100644 index 000000000..ed6690033 --- /dev/null +++ b/apps/agenda/agenda-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwcCpMkyQC3wAIFgIRJn8JAoeQ/gRYwB0Bn57F/gCBHAgfCn8EDgdI/kSAoIR8oBkFgAFCCIysKCPM//4AKZAgR3/0Aj+Ag/ggP4gF/CPpr/Nf5r/NfYRhw4RL8IRDyEAABUJCIYC/AVI=")) \ No newline at end of file diff --git a/apps/agenda/agenda.js b/apps/agenda/agenda.js new file mode 100644 index 000000000..c7260af07 --- /dev/null +++ b/apps/agenda/agenda.js @@ -0,0 +1,102 @@ +/* CALENDAR is a list of: + {id:int, + type, + timestamp, + durationInSeconds, + title, + description, + location, + allDay: bool, + } + the file on storage has the same content but is an object indexed by id +*/ + +var FILE = "android.calendar.json" + +var fontSmall = "6x8"; +var fontMedium = g.getFonts().includes("6x15")?"6x15":"6x8:2"; +var fontBig = g.getFonts().includes("12x20")?"12x20":"6x8:2"; +var fontLarge = g.getFonts().includes("6x15")?"6x15:2":"6x8:4"; + +//FIXME maybe write the end from GB already? Not durationInSeconds here (or do while receiving?) +var cal; +try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} +if (!cal) //cal = {}; // first event + cal = { //FIXME test + 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere"}, + 2: {id: 2, title:"last", timestamp: 1653579989371, durationInSeconds: 3000, location: "somewhere"}, + 3: {id: 3, title:"bar", timestamp: 1653578989371, durationInSeconds: 3000, location: "somewhere"} + }; + +function formatDateLong(timestamp) { + return new Date(timestamp*1000).toString(); +} +function formatDateShort(timestamp) { + return new Date(timestamp*1000).toISOString(); +} + +function showEvent(ev) { + var bodyFont = fontBig; + g.setFont(bodyFont); + var lines = []; + if (ev.title) lines = g.wrapString(ev.title, g.getWidth()-10) + var titleCnt = lines.length; + if (titleCnt) lines.push(""); // add blank line after title + lines = lines.concat( + g.wrapString(formatDateLong(ev.timestamp)+"\n", g.getWidth()-10), + g.wrapString(formatDateLong((+ev.timestamp) + (+ev.durationInSeconds))+"\n", g.getWidth()-10), + g.wrapString(ev.location, g.getWidth()-10), + ["",/*LANG*/"< Back"]); + E.showScroller({ + h : g.getFontHeight(), // height of each menu item in pixels + c : lines.length, // number of menu items + // a function to draw a menu item + draw : function(idx, r) { + // FIXME: in 2v13 onwards, clearRect(r) will work fine. There's a bug in 2v12 + g.setBgColor(idx=lines.length-2) + showEvent(ev); + }, + back : () => showList() + }); +} + +CALENDAR=Object.keys(cal) + .sort((a,b)=>cal[a].timestamp - cal[b].timestamp) + .map(k=>cal[k]); //make it an array + +function showList() { + E.showScroller({ + h : 48, + c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) + draw : function(idx, r) {"ram" + var ev = CALENDAR[idx]; + g.setColor(g.theme.fg); + g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); + if (!ev) return; + var x = r.x+2, title = ev.title, body = formatDateShort(ev.timestamp)+ + "\n"+ev.location; + var m = ev.title+"\n"+ev.location, longBody=false; + if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); + if (body) { + g.setFontAlign(-1,-1).setFont("6x8"); + var l = g.wrapString(body, r.w-(x+14)); + if (l.length>3) { + l = l.slice(0,3); + l[l.length-1]+="..."; + } + longBody = l.length>2; + g.drawString(l.join("\n"), x+10,r.y+20); + } + //if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); + g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items + }, + select : idx => showEvent(CALENDAR[idx]), + back : () => load() + }); +} +showList(); diff --git a/apps/agenda/agenda.png b/apps/agenda/agenda.png new file mode 100644 index 0000000000000000000000000000000000000000..ccbcce5fff4e578b44d2e1ba87d21339e5dd19e0 GIT binary patch literal 7227 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 GhyMqGu%7Dx literal 0 HcmV?d00001 diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json new file mode 100644 index 000000000..2c1bdfe9c --- /dev/null +++ b/apps/agenda/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "agenda", + "name": "Agenda", + "version": "1.01", + "description": "Simple agenda", + "icon": "agenda.png", + "screenshots": [{"url":"screenshot_agenda.png"}], + "tags": "agenda", + "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + {"name":"agenda.app.js","url":"agenda.js"}, + {"name":"agenda.img","url":"agenda-icon.js","evaluate":true} + ] +} diff --git a/apps/agenda/screenshot_agenda.png b/apps/agenda/screenshot_agenda.png new file mode 100644 index 0000000000000000000000000000000000000000..7ef5986d4e63537cdaed0a9daa474c3e633a485b GIT binary patch literal 2584 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 Date: Sat, 28 May 2022 19:43:32 +0200 Subject: [PATCH 043/183] Fixed layout in agenda --- apps/agenda/agenda.js | 62 ++++++++++++++++++++++++++++----------- apps/agenda/metadata.json | 2 +- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/apps/agenda/agenda.js b/apps/agenda/agenda.js index c7260af07..6bb757629 100644 --- a/apps/agenda/agenda.js +++ b/apps/agenda/agenda.js @@ -11,7 +11,12 @@ the file on storage has the same content but is an object indexed by id */ -var FILE = "android.calendar.json" +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +var FILE = "android.calendar.json"; + +var Locale = require("locale"); var fontSmall = "6x8"; var fontMedium = g.getFonts().includes("6x15")?"6x15":"6x8:2"; @@ -23,30 +28,53 @@ var cal; try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} if (!cal) //cal = {}; // first event cal = { //FIXME test - 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere"}, + 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere", description: "something very very long"}, 2: {id: 2, title:"last", timestamp: 1653579989371, durationInSeconds: 3000, location: "somewhere"}, 3: {id: 3, title:"bar", timestamp: 1653578989371, durationInSeconds: 3000, location: "somewhere"} }; -function formatDateLong(timestamp) { - return new Date(timestamp*1000).toString(); +function getDate(timestamp) { + return new Date(timestamp*1000); } -function formatDateShort(timestamp) { - return new Date(timestamp*1000).toISOString(); +function formatDateLong(date, includeDay) { + if(includeDay) + return Locale.date(date)+" "+Locale.time(date,1); + return Locale.time(date,1); +} +function formatDateShort(date) { + return Locale.date(date).replace(/\d\d\d\d/,"")+Locale.time(date,1); } +var lines = []; function showEvent(ev) { var bodyFont = fontBig; g.setFont(bodyFont); - var lines = []; + //var lines = []; if (ev.title) lines = g.wrapString(ev.title, g.getWidth()-10) var titleCnt = lines.length; + var start = getDate(ev.timestamp); + var end = getDate((+ev.timestamp) + (+ev.durationInSeconds)); + var includeDay = true; if (titleCnt) lines.push(""); // add blank line after title - lines = lines.concat( - g.wrapString(formatDateLong(ev.timestamp)+"\n", g.getWidth()-10), - g.wrapString(formatDateLong((+ev.timestamp) + (+ev.durationInSeconds))+"\n", g.getWidth()-10), - g.wrapString(ev.location, g.getWidth()-10), - ["",/*LANG*/"< Back"]); + if(start.getDay() == end.getDay() && start.getMonth() == end.getMonth()) + includeDay = false; + if(includeDay) { + lines = lines.concat( + /*LANG*/"Start:", + g.wrapString(formatDateLong(start, includeDay), g.getWidth()-10), + /*LANG*/"End:", + g.wrapString(formatDateLong(end, includeDay), g.getWidth()-10)); + } else { + lines = lines.concat( + g.wrapString(Locale.date(start), g.getWidth()-10), + g.wrapString(/*LANG*/"Start"+": "+formatDateLong(start, includeDay), g.getWidth()-10), + g.wrapString(/*LANG*/"End"+": "+formatDateLong(end, includeDay), g.getWidth()-10)); + } + if(ev.location) + lines = lines.concat(/*LANG*/"Location"+": ", g.wrapString(ev.location, g.getWidth()-10)); + if(ev.description) + lines = lines.concat("",g.wrapString(ev.description, g.getWidth()-10)); + lines = lines.concat(["",/*LANG*/"< Back"]); E.showScroller({ h : g.getFontHeight(), // height of each menu item in pixels c : lines.length, // number of menu items @@ -59,7 +87,7 @@ function showEvent(ev) { g.setFont(bodyFont).drawString(lines[idx], r.x, r.y); }, select : function(idx) { if (idx>=lines.length-2) - showEvent(ev); + showList(); }, back : () => showList() }); @@ -71,19 +99,19 @@ CALENDAR=Object.keys(cal) function showList() { E.showScroller({ - h : 48, + h : 52, c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) draw : function(idx, r) {"ram" var ev = CALENDAR[idx]; g.setColor(g.theme.fg); g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); if (!ev) return; - var x = r.x+2, title = ev.title, body = formatDateShort(ev.timestamp)+ - "\n"+ev.location; + var x = r.x+2, title = ev.title; + var body = formatDateShort(getDate(ev.timestamp))+"\n"+ev.location; var m = ev.title+"\n"+ev.location, longBody=false; if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); if (body) { - g.setFontAlign(-1,-1).setFont("6x8"); + g.setFontAlign(-1,-1).setFont(fontMedium); var l = g.wrapString(body, r.w-(x+14)); if (l.length>3) { l = l.slice(0,3); diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 2c1bdfe9c..6895bbc7c 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,7 +1,7 @@ { "id": "agenda", "name": "Agenda", - "version": "1.01", + "version": "3.01", "description": "Simple agenda", "icon": "agenda.png", "screenshots": [{"url":"screenshot_agenda.png"}], From 5fee259dd0dae2e8fe5e6bdf255debe68f229493 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Mon, 30 May 2022 20:44:28 +0200 Subject: [PATCH 044/183] Changed calendar format to array and graying out old events --- apps/agenda/README.md | 2 +- apps/agenda/agenda-icon.js | 2 +- apps/agenda/agenda.js | 89 ++++++++++++++++++------------------- apps/agenda/agenda.png | Bin 7227 -> 3119 bytes apps/agenda/metadata.json | 2 +- apps/android/boot.js | 12 ++--- 6 files changed, 50 insertions(+), 57 deletions(-) diff --git a/apps/agenda/README.md b/apps/agenda/README.md index 5141673c0..a546e0a89 100644 --- a/apps/agenda/README.md +++ b/apps/agenda/README.md @@ -1,3 +1,3 @@ -# Calendar +# Agenda Basic agenda reading the events synchronised from GadgetBridge diff --git a/apps/agenda/agenda-icon.js b/apps/agenda/agenda-icon.js index ed6690033..891543955 100644 --- a/apps/agenda/agenda-icon.js +++ b/apps/agenda/agenda-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwcCpMkyQC3wAIFgIRJn8JAoeQ/gRYwB0Bn57F/gCBHAgfCn8EDgdI/kSAoIR8oBkFgAFCCIysKCPM//4AKZAgR3/0Aj+Ag/ggP4gF/CPpr/Nf5r/NfYRhw4RL8IRDyEAABUJCIYC/AVI=")) \ No newline at end of file +require("heatshrink").decompress(atob("mEwwg1yhGIxAPMBwIPFhH//GAC5n/C4oHBC5/IGwoXBHQQAKC4OIFAWOxHv9GO9wAKI4XoC4foEIIWLC4IABC4gIBFxnuE4IqBC4gARC4ZzNAAwXaxe7ACO4C625C4m4xIJBzAeCxGbCAOIFgQOBC4pOBxe4AYIPBAYQKCAYYXE3GL/ADBx/oxb3BC4X+xG4xwOBC4uP/YDB54MBf4Po3eM/4XBx/+C4pTBGIIkBLgOYAYIvB9GJBwI6BL45zCL4aCCL4h3GU64ALdYS1CI55bBAAgXFO4mMO4QDBDIO/////YxBU53IxIVB/GfDAWYa5wtC/GPAYWIL4wXBL4oSBC4jcBC4m4QIWYSwWIIQIAG/CnMMAIAC/JLCMIIvMIwZHFJAJfLC5yPHAYIRDAoy/KCIi7BMon4d4+Od4IXBxAZBEQLtB/+YxIXDL4SLCL4WPzAXCNgRFBLIKnKLIrcEI4gXNAAp3CxGZAAzCBC5KnCKAIAICxBlBC4IAJxG/C4/4wAXLhBgD/IcD3AXMGAIqDDgRGNGAoXDFxxhEI4W4FxwwCaoYWBFx4YDAAQWRAEQ")) diff --git a/apps/agenda/agenda.js b/apps/agenda/agenda.js index 6bb757629..f39e31c75 100644 --- a/apps/agenda/agenda.js +++ b/apps/agenda/agenda.js @@ -8,7 +8,6 @@ location, allDay: bool, } - the file on storage has the same content but is an object indexed by id */ Bangle.loadWidgets(); @@ -24,30 +23,26 @@ var fontBig = g.getFonts().includes("12x20")?"12x20":"6x8:2"; var fontLarge = g.getFonts().includes("6x15")?"6x15:2":"6x8:4"; //FIXME maybe write the end from GB already? Not durationInSeconds here (or do while receiving?) -var cal; -try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} -if (!cal) //cal = {}; // first event - cal = { //FIXME test - 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere", description: "something very very long"}, - 2: {id: 2, title:"last", timestamp: 1653579989371, durationInSeconds: 3000, location: "somewhere"}, - 3: {id: 3, title:"bar", timestamp: 1653578989371, durationInSeconds: 3000, location: "somewhere"} - }; +var CALENDAR = require("Storage").readJSON("android.calendar.json",true)||[]; + +CALENDAR=CALENDAR.sort((a,b)=>a.timestamp - b.timestamp) function getDate(timestamp) { - return new Date(timestamp*1000); + return new Date(timestamp*1000); } function formatDateLong(date, includeDay) { - if(includeDay) - return Locale.date(date)+" "+Locale.time(date,1); - return Locale.time(date,1); + if(includeDay) + return Locale.date(date)+" "+Locale.time(date,1); + return Locale.time(date,1); } function formatDateShort(date) { - return Locale.date(date).replace(/\d\d\d\d/,"")+Locale.time(date,1); + return Locale.date(date).replace(/\d\d\d\d/,"")+Locale.time(date,1); } var lines = []; function showEvent(ev) { var bodyFont = fontBig; + if(!ev) return; g.setFont(bodyFont); //var lines = []; if (ev.title) lines = g.wrapString(ev.title, g.getWidth()-10) @@ -93,38 +88,40 @@ function showEvent(ev) { }); } -CALENDAR=Object.keys(cal) - .sort((a,b)=>cal[a].timestamp - cal[b].timestamp) - .map(k=>cal[k]); //make it an array - function showList() { - E.showScroller({ - h : 52, - c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) - draw : function(idx, r) {"ram" - var ev = CALENDAR[idx]; - g.setColor(g.theme.fg); - g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); - if (!ev) return; - var x = r.x+2, title = ev.title; - var body = formatDateShort(getDate(ev.timestamp))+"\n"+ev.location; - var m = ev.title+"\n"+ev.location, longBody=false; - if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); - if (body) { - g.setFontAlign(-1,-1).setFont(fontMedium); - var l = g.wrapString(body, r.w-(x+14)); - if (l.length>3) { - l = l.slice(0,3); - l[l.length-1]+="..."; - } - longBody = l.length>2; - g.drawString(l.join("\n"), x+10,r.y+20); - } - //if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); - g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items - }, - select : idx => showEvent(CALENDAR[idx]), - back : () => load() - }); + if(CALENDAR.length == 0) { + E.showMessage("No events"); + return; + } + E.showScroller({ + h : 52, + c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) + draw : function(idx, r) {"ram" + var ev = CALENDAR[idx]; + g.setColor(g.theme.fg); + g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); + if (!ev) return; + var isPast = ev.timestamp + ev.durationInSeconds < (new Date())/1000; + var x = r.x+2, title = ev.title; + var body = formatDateShort(getDate(ev.timestamp))+"\n"+ev.location; + var m = ev.title+"\n"+ev.location, longBody=false; + if (title) g.setFontAlign(-1,-1).setFont(fontBig) + .setColor(isPast ? "#888" : g.theme.fg).drawString(title, x,r.y+2); + if (body) { + g.setFontAlign(-1,-1).setFont(fontMedium).setColor(isPast ? "#888" : g.theme.fg); + var l = g.wrapString(body, r.w-(x+14)); + if (l.length>3) { + l = l.slice(0,3); + l[l.length-1]+="..."; + } + longBody = l.length>2; + g.drawString(l.join("\n"), x+10,r.y+20); + } + //if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); + g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items + }, + select : idx => showEvent(CALENDAR[idx]), + back : () => load() + }); } showList(); diff --git a/apps/agenda/agenda.png b/apps/agenda/agenda.png index ccbcce5fff4e578b44d2e1ba87d21339e5dd19e0..c850b0e5d1a3eb98b9c9cb68968ab554119fe23f 100644 GIT binary patch literal 3119 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 GhyMqGu%7Dx diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 6895bbc7c..0a9f6e44f 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,7 +1,7 @@ { "id": "agenda", "name": "Agenda", - "version": "3.01", + "version": "2.01", "description": "Simple agenda", "icon": "agenda.png", "screenshots": [{"url":"screenshot_agenda.png"}], diff --git a/apps/android/boot.js b/apps/android/boot.js index 829c1b4b0..df21a5521 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -92,17 +92,13 @@ }, //TODO perhaps move those in a library (like messages), used also for viewing events? "calendar" : function() { - var cal; - try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} - if (!cal) cal = {}; // first event - cal[event.id] = event; + var cal = require("Storage").readJSON("android.calendar.json",true)||[]; + cal.push(event); require("Storage").writeJSON("android.calendar.json", cal); }, "calendar-" : function() { - var cal; - try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} - if (!cal) return; //nothing to remove - if (event.id in cal) delete cal[event.id]; + var cal = require("Storage").readJSON("android.calendar.json",true)||return; + cal = cal.filter(e=>e.id!=event.id); require("Storage").writeJSON("android.calendar.json", cal); } }; From a50f53b15aa21d1de3dd0ffd3709b18d61056ea5 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Mon, 30 May 2022 21:36:07 +0200 Subject: [PATCH 045/183] Added screenshots and correct version number --- apps/agenda/metadata.json | 4 ++-- apps/agenda/screenshot_agenda.png | Bin 2584 -> 0 bytes apps/agenda/screenshot_agenda_event1.png | Bin 0 -> 3588 bytes apps/agenda/screenshot_agenda_event2.png | Bin 0 -> 3386 bytes apps/agenda/screenshot_agenda_overview.png | Bin 0 -> 3785 bytes apps/android/boot.js | 7 +++++-- apps/android/metadata.json | 2 +- 7 files changed, 8 insertions(+), 5 deletions(-) delete mode 100644 apps/agenda/screenshot_agenda.png create mode 100644 apps/agenda/screenshot_agenda_event1.png create mode 100644 apps/agenda/screenshot_agenda_event2.png create mode 100644 apps/agenda/screenshot_agenda_overview.png diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 0a9f6e44f..0b8ffaded 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,10 +1,10 @@ { "id": "agenda", "name": "Agenda", - "version": "2.01", + "version": "0.01", "description": "Simple agenda", "icon": "agenda.png", - "screenshots": [{"url":"screenshot_agenda.png"}], + "screenshots": [{"url":"screenshot_agenda_overview.png"}, {"url":"screenshot_agenda_event1.png"}, {"url":"screenshot_agenda_event2.png"}], "tags": "agenda", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", diff --git a/apps/agenda/screenshot_agenda.png b/apps/agenda/screenshot_agenda.png deleted file mode 100644 index 7ef5986d4e63537cdaed0a9daa474c3e633a485b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2584 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 literal 0 HcmV?d00001 diff --git a/apps/agenda/screenshot_agenda_event2.png b/apps/agenda/screenshot_agenda_event2.png new file mode 100644 index 0000000000000000000000000000000000000000..f5edcaae8e25eaa8c014ef7a77127dd91c8a7120 GIT binary patch literal 3386 zcmb_f`8U*!_sz;GZ>)v~AqP3+7KhJ5N6DLmao0+0*S+VN> z48qCsl?}7*tUQ|;`l|gM_un`m?Ylf*^ZqdXCc=I(A}utYY=O)o|wF6sz*8QuntNSI#1nFQQ3{9e=) z+9u(DQ)%rZ$y!W#Xm-`=T1#VQGqs>md&Hu#dCT&veRJrrj8U>%g$S*B6x|^_eCnYq zPY?Xi3g`TX1gmLPb*d}IWH?uHdh=mC#}wVr0>2V`bL(0s3(NtbUsdE zn#%P2q(<)O2AK1?ypG~;zok>Bo__lFA3Z_k7k>Lr$31`*$Id2ndt1|CmZ3r_KRV7R zN>;L<-Nn9UU;dPP`n#fnPVe||5^pzM>bZDa^t7t7fN6@~Lr0~k0E>nV-KS^W9m1*2;OAC%p3@ zEju{c#}dhL4h?=8Nf#_Sqv??t$zkk}U@ImOX7MB~St;22%;c?z>16V)smK?*Jv?qq zSwFvua-Xg6RBMSpUytkR-S)Pbc_tAJ<-b*$9_#wI%zPSo??&b)fj@LW*jJqs;r*@Vh&Ns6THwRiApo&u}+iv!&harcbd6v6AOR3&`#&6Aol*1XC zaV@Y_G`Vm{FG*;L<__pb(qSbjJ=enUf6gqII`G@wjkM^KdtYEb&c@t^u)GKPX?}A2X3`(aBjgg}26*U}%d2Q3L2TcW)@vK8g zSOH|%H$gy==ZpiFz)NuqkYC8~*-dGsFw6eBgfI0sg;JX$d=B2U%7d<)L~=~H0+R>E z9XUBgC8FT}7`AvtwOY>`%3uVn-*5Y|Pif_Ca4DGBity6f4E~C4Hhj=)<2G}>qdFmA zZ&{CV9SexnIFWVCr%dsCU%BA60E!aUVYbytBeM$Ag+3p{(V@e{S(KpQ)d-?#|~+|3Pzsx zLSscsr0v#e2Sru_6cxMnb@u96Q`dlBPwd2vA$;{9;3iJskYLS%=wF%EC zCEaqr==T?Q+zmLVSI<7J!^R*>6Yu-Ni$8P}r6E*vQg%m}=oJ#UyiI_8^XV@fsCSyR8lC6+~a87?zEbPuEcTDsS zV(pt))$UG{1KG>J=Tyk~>MDDg^7VpH!4j!|AJaDaOLNgrC2bD0J%X43xG^p?k%po-!|0|ABP;%7S*{Tqn_ONY;yPZ_ZB2LOr|pE4A@%4 z$vZ=DNoaSelDrRp6QvfH0&}se`3SYIKWbK7wgdB9-1-;u^KQ?F2RZj=3@yd9;{CB_ z2a|UcKpyNj%)ZzP8>f^Xjg8ho+%V3mtD!wnS!Jq}6~l4U=iUKH8`eqF>6Zt zZxxqcPqg;`K8{lQT*Nd@nM7Y(a{6JJOGtCFy|d}=C*UukQ!ARSUi7LYjH~oJsW~a> z10K8Y3Q5+F69NW46<}**zTwQmy~ioCYA*WJlXox85k+Vte=HHpUp0`_NLvV6nh3&{ z7!=eB5GusAVuwa5-X}fWudjvbPDQ}i*lNPqsJ;fOll6P#oUOClGv}zdvwwNWVHztj zcrlwSm-Kd*wFY}r^DpT_l$g4hty?(e$0waX#dv!F-MrEiXs3ZbxYxiXHt?!GxRt{( zEQb^i$tAry7*B|Y#PF6cUgQPdhT&(Sx*^m*bKB%a_R>D4=VFSX1ADm0!ngL6E2-U79?0HV7sTkwML9V8=awmPg*Y6sn?7g!? z@N%*}Wb~{!Xcf{6T)c_V_sESTS2O2gWQNLy%%7j$oJ8Bn8%v0)?a_Qf4OTu_g>W@# zL6!o^txbLhIY_sTll*?@D0N$z;Ez!#msR@aJn^uE22yamt?R8c`HLfC0O^r>^@;mE z5tz;uQq=^1H;F7l99!*doG@#vwoxr)EVDKgbuW08SEsJkl_$x6ETrqX39AYJq38#7 z#`q)^Jqh17gf!?B*!W}#!Qov_eyxy9v^WR@&H5}ZV+)yY`{d{M4CI_5Ee+zrUK{{j2N9xJT*-1WjBGpj4fu-SphgpDijJ(Q|wAARa)(llfn3SKmcYv{`}@-`p&r z7>Wo!`ceq#VTNbB#t{X2lGz`pIg@t>_hTqS+97l8cHESR2Hx#x_l7@lhnHPdI~<4G z_qFH?gM=2?qRv`WXb~9#M&m)q?1~5RkmiY81q6r@!vS!xVkWUfCr4PI6ilv`SP41?l7aRNnjzbr?A+Uv!n}=DBeS z&_Gnt9%)4_;ee;t_z-KH;Q9lda&JU5K@*%LCqJ(f_?anq&wISY14p?!Wg?LL^jEO< zUcrs^>u?J(-o;FKG`~A>Tz!!04h0QA(7X?6NkmmThY~U_BGhsw7CeF+;l@M7SXE;l zcY|JJv8ijgI()M4#g|;z{qzB2@`zs&xy@eF*ni-iVMuTG#6mRf@_BPY01e_(^XZ_T zGjun-i!9OV(o9#EsHdyq-1o1mMWXUHOiDHxyIG&Sq(O*a>8wR1DK?mpeuo9dY# z^;s}|wP6PoixoA$Axe&ioPiX->1Iu7??*RDb{34i%^thUV*URp-Y-`*7i!j``t3}J zORI*?6-i7k6*UxV0nP!}r+LoG#M`7gd8KT;h-F?aFvs7Ac8cIA@rZU4bnc>zBp?MQ zcEv9bY?I-H9WvSO?t7WF6ow?C;4XbJDeNEq^|y)EyW#s<5VXcVqA;q!fjW@3by)?m zj(FXI+ey2rpQzMC~R;*=q+Lb{~9Zb0W zcdx&%o5EhCLjGd{7a+;@vBGL~9=yO%UZW{Urp~yPnZs!`VufRgDkLUnKeU@M`k2m5AF zTe0tuPgUTTQ@uLGp$d$GuCIH?qbES!qq7XMJ-+2XnwQ->uzs9zA-h@jP@Y(wuN)Vy zz$jRh>^eEopphT!JP2CkpXJBsVji`N^g-8A+;?9OokF0XN0a6i1^MHJm|c8PyKH& zJ+#5H9`Edi3yt$u_FW-fq5>nB(Dl13CEGK4q4dU8`@!nQ`hUkbRp7s>&w|IBRCZ(L zg;5pw=r^iwC9*a|s1l4`_f{%2pBEk$;#rGmS9mY!fe}0`ENEQzb!3l)*b5~)o*kE^ zKf4I89v3{MpC+?X71g;;MOO$07Uw6bJ*%Zs?HMsF!2sL2yQ|qx(>Nx;|HdFu%>F9N9ql4m_n;KbX6i5M>nFx)E!h-HY6&`J{kl(s~uL3CmTa^>-o~_Ukl2T4a$`AO!GX9BtfK2hccFG12|(brycsp2l6HKp5a_+|w*l zps#=c79mS3Ab^)npPU!KVqj?nZULCxnC-SvT$+@JI)4kmj20~9j4h4XSAkmqej1!l z^Jib&@*|rDF#A#fwF#^p>m>!UpD(E_Ua3F`VDB3@?|38tf*L`K?nm?M`g0Tr0epq~ zdaPfe^7?ax0QOc?G~W9G4XU8%t2A`~`e}Vn1R;R0kVh5x3YFKNBLpz2sP%@59nZ>% zDk!Sx=zi7@jk{lg5WuC|-b%@iXUC07c-1_ke(L_V0z&{>z2>YVE!5khd20z!r4}^L zS6~R>=Z7Z`cUM3F@1Eh!;}gJ}CwTYp1n}+|-aI}5ym^9m5APFTw7b{!k6*uK`tgIT z(&c_#RDpLdQJcpnfHzO@?%{0#@bM@={v3~a{dt!HUjUyFSmC$eXn|APDes#FTDIMY zy~sV5);(KS&9llf_yI5r>Jgw<=uGiTfwS#K>_zSoz~jq=0@#980RKyX03L@iVqpm2 z-h{pOBD+`3gavMbJjP%)ckiA6^nWxo~F#7>d z&u{s4o-y|ldBz)wjlHKg&a;=fa$!&aTMl_EMb>z)9dExJv5%fOo}@USo z#e%MnRNVUB^iv3?0$bIy3>=9NSyZfWk-2*SpYyVO&c=LyPU{9jFPc~}-dy4=&uh*_8cJJ6N0q%)_ z#77m-^E6`S@-84`GrEtMW!DR&cf0^@DCSA#dHd=W*b}p7tQSb{cmXVc-F@wH09y{T zJyWkrMJkwgUhgI^V*iO17_~#S&z`su6X%A{TT#8^L+8NOPPO+&$@8|U1za82Q{Tj$ zelojtrdKb=FgDR~UTeBBi0n}n-&Mts6)s(GI1s)G@ z>(SvothaJ)^<}81iu9nKo=Ya=@CbZ@W!&0vAm>M;P9i@*agy05f#R`J$?v*s)p11qY=U8g`Q zz%>}Hii%o+UiCzk9)T%UVn^NC7+py&Rjb2Dr62 zP|J}cyR2j>5CRx&*6Qk)(aSQY0ouf6VX=;#X#ltS%id$1sfOrL&H`L7hTZ~0bFP!> zJv|Kpd;)MvV*SXq=RDWyb;|>DbU^NX{FjTYPH*qpo+zvtRT$tk!bFqfZC8gv0wH!+H_Xve|26 zMtoR1o$vEL9pKhylb&xO&{*&F8U6bEFnMmomjPT$z<$^31-93Uczk$n%H&z8z-0iV z?-=T|uz2iFqMlfcKN06(=BEJPNmx(68HN^Gf#ODtBE_L~ zPyKfc4ua@iiC-1}5E?G7K=Yf|28FWy=yZB9vz% zDS+DoO1$O$c?}0%Fh$;cyKx*I=1q84Fo&wfYMneF%9zSR^ z=dEPNcx1EnxbgVL^qHvty(&?fr>#H;;8s7yz{W!9f&H{u|1U~-=?m%ynb^>Lx;{sN zr2(!XJU1NZJ$`E;^%elT@aCjQR(lGh0$e8={kOG4?Sa@k1rWgRgZ)tew<;=|lCpv_ z$5Z8bV+p>es2a2Csy=ZYiv5 z@5AJ|5r+YOZbz~>1=YZKQy(#qD4+32-S zL&}XF+DvBqEPJ^MgaNKk9_|2v0l2rI*!y!Om$gg<1n}>FjYxmiRUjQ;<^@LmqM&X? zS|8h-W2`r7Wn0twVN&ZG;X9rj>*De}&(i^JJ+i&8p6f->dd=H=HH=<|&>VZ9|JacRq;MO+Vyt)iv26RuQ)g~?@ z{p;IE1vt`+wvNAgrwE>7G|M04=lW@VPXr-=-y@GAeYyey_~{vve_aIxumD+F0Rg;p z`sBO-76VHw@Ck5ze5L>X^Q&E@!}E1e1zx)T$aw)Q29{Pp056?BIsXN4>+Muap6K_p z^*6qEN{@W$T}StN)5UrMAX~HiV)8VSqhWxVN2ax6k*Mf8+TG5W7x{#)&jJO_i>}Y| z>(KzS@Xi3q5~fbn$m+I!;PjaLX_XEEimnS_utUfONdSL8TeUVj%mypko1;x(Ys1bK z1+?JK>q9MsD)7$~BH?FMI`6y)zR0GlXVYsB#Up@&Z2&7QySTlHwN7A=UkKRDg%z#n zY{f2HQdQuF+F4LB&}7XefGf2}gk@J?#vEwVmfd?JP|)?vN{3>%s`co?LZ?4o%`MHC zzn@-#t<6R2E#2sb!%7T#v(?*Jlr~GBvrZvO7&7MSZRXgv1_4@cpj)~#n)ld1b9~vi zzD8qK>F5}5wHlpI_wT2`tsk@t;QfHQI->sp&{5j39yJ+500000NkvXXu0mjfKTTWB literal 0 HcmV?d00001 diff --git a/apps/android/boot.js b/apps/android/boot.js index df21a5521..0c7dd04b5 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -92,12 +92,15 @@ }, //TODO perhaps move those in a library (like messages), used also for viewing events? "calendar" : function() { - var cal = require("Storage").readJSON("android.calendar.json",true)||[]; + var cal = require("Storage").readJSON("android.calendar.json",true); + if (!cal || !Array.isArray(cal)) cal = []; cal.push(event); require("Storage").writeJSON("android.calendar.json", cal); }, "calendar-" : function() { - var cal = require("Storage").readJSON("android.calendar.json",true)||return; + var cal = require("Storage").readJSON("android.calendar.json",true); + //if any of those happen we are out of sync! + if (!cal || !Array.isArray(cal)) return; cal = cal.filter(e=>e.id!=event.id); require("Storage").writeJSON("android.calendar.json", cal); } diff --git a/apps/android/metadata.json b/apps/android/metadata.json index c8e404aba..27b77cf2f 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "0.10", + "version": "0.11", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From e057270d01e419c5c92efa35b061afc710d5b254 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Wed, 1 Jun 2022 17:39:09 +0200 Subject: [PATCH 046/183] Added settings page to force calendar sync --- apps/agenda/metadata.json | 3 ++- apps/agenda/settings.js | 36 ++++++++++++++++++++++++++++++++++++ apps/android/boot.js | 6 +++++- apps/android/metadata.json | 2 +- 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 apps/agenda/settings.js diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 0b8ffaded..ce8438686 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,7 +1,7 @@ { "id": "agenda", "name": "Agenda", - "version": "0.01", + "version": "0.02", "description": "Simple agenda", "icon": "agenda.png", "screenshots": [{"url":"screenshot_agenda_overview.png"}, {"url":"screenshot_agenda_event1.png"}, {"url":"screenshot_agenda_event2.png"}], @@ -11,6 +11,7 @@ "allow_emulator": true, "storage": [ {"name":"agenda.app.js","url":"agenda.js"}, + {"name":"agenda.settings.js","url":"settings.js"}, {"name":"agenda.img","url":"agenda-icon.js","evaluate":true} ] } diff --git a/apps/agenda/settings.js b/apps/agenda/settings.js new file mode 100644 index 000000000..7edb013b9 --- /dev/null +++ b/apps/agenda/settings.js @@ -0,0 +1,36 @@ +(function(back) { + function gbSend(message) { + Bluetooth.println(""); + Bluetooth.println(JSON.stringify(message)); + } + var CALENDAR = require("Storage").readJSON("android.calendar.json",true)||[]; + var mainmenu = { + "" : { "title" : "Agenda" }, + "< Back" : back, + /*LANG*/"Connected" : { value : NRF.getSecurityStatus().connected?/*LANG*/"Yes":/*LANG*/"No" }, + /*LANG*/"Force calendar sync" : () => { + if(NRF.getSecurityStatus().connected) { + E.showPrompt(/*LANG*/"Do you want to also clear the internal database first?", { + buttons: {/*LANG*/"Yes": 1, /*LANG*/"No": 2, /*LANG*/"Cancel": 3} + }).then((v)=>{ + switch(v) { + case 1: + require("Storage").writeJSON("android.calendar.json",[]); + CALENDAR = []; + case 2: + gbSend({t:"force_calendar_sync", ids: CALENDAR.map(e=>e.id)}); + E.showAlert(/*LANG*/"Request sent to the phone").then(()=>E.showMenu(mainmenu)); + break; + case 3: + default: + E.showMenu(mainmenu); + return; + } + }); + } else { + E.showAlert(/*LANG*/"You are not connected").then(()=>E.showMenu(mainmenu)); + } + }, + }; + E.showMenu(mainmenu); +}) diff --git a/apps/android/boot.js b/apps/android/boot.js index 0c7dd04b5..72c5bc386 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -94,7 +94,11 @@ "calendar" : function() { var cal = require("Storage").readJSON("android.calendar.json",true); if (!cal || !Array.isArray(cal)) cal = []; - cal.push(event); + var i = cal.findIndex(e=>e.id==event.id); + if(i<0) + cal.push(event); + else + cal[i] = event; require("Storage").writeJSON("android.calendar.json", cal); }, "calendar-" : function() { diff --git a/apps/android/metadata.json b/apps/android/metadata.json index 27b77cf2f..6458087e8 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "0.11", + "version": "4.01", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From 9e4d58d2151795b83ee09effd10f2cad6eded415 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Fri, 3 Jun 2022 08:44:13 +0200 Subject: [PATCH 047/183] Added simpler calendar management (all in single packet) --- apps/android/boot.js | 5 +++++ apps/android/metadata.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/android/boot.js b/apps/android/boot.js index 72c5bc386..191db3838 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -91,6 +91,11 @@ sched.reload(); }, //TODO perhaps move those in a library (like messages), used also for viewing events? + //simple package with events all together + "calendarevents" : function() { + require("Storage").writeJSON("android.calendar.json", event.events); + }, + //add and remove events based on activity on phone (pebble-like) "calendar" : function() { var cal = require("Storage").readJSON("android.calendar.json",true); if (!cal || !Array.isArray(cal)) cal = []; diff --git a/apps/android/metadata.json b/apps/android/metadata.json index 6458087e8..7e4b275c5 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "4.01", + "version": "4.02", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From 064b9996e7e2bd01d7fdff608bb4ff30754ae9cc Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Sun, 5 Jun 2022 18:55:26 +0200 Subject: [PATCH 048/183] Added periodic call to forceCalendarSync --- apps/agenda/settings.js | 1 + apps/android/boot.js | 11 +++++++++++ apps/android/metadata.json | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/agenda/settings.js b/apps/agenda/settings.js index 7edb013b9..fe9dab2d8 100644 --- a/apps/agenda/settings.js +++ b/apps/agenda/settings.js @@ -17,6 +17,7 @@ case 1: require("Storage").writeJSON("android.calendar.json",[]); CALENDAR = []; + /* falls through */ case 2: gbSend({t:"force_calendar_sync", ids: CALENDAR.map(e=>e.id)}); E.showAlert(/*LANG*/"Request sent to the phone").then(()=>E.showMenu(mainmenu)); diff --git a/apps/android/boot.js b/apps/android/boot.js index 191db3838..a548089cb 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -125,6 +125,17 @@ if (!settings.keep) NRF.on("disconnect", () => require("messages").clearAll()); // remove all messages on disconnect setInterval(sendBattery, 10*60*1000); + // Fix calendar every 2 days (can be done manually too) + function forceCalendarSync() { + if(NRF.getSecurityStatus().connected) { + var cal = require("Storage").readJSON("android.calendar.json",true); + if (!cal || !Array.isArray(cal)) cal = []; + gbSend({t:"force_calendar_sync", ids: cal.map(e=>e.id)}); + setTimeout(forceCalendarSync, 2*24*60*60*1000); + } else + NRF.once("connect", () => setTimeout(forceCalendarSync, 4000)); + } + setTimeout(forceCalendarSync, 2*24*60*60*1000); //schedule the first // Health tracking Bangle.on('health', health=>{ gbSend({ t: "act", stp: health.steps, hrm: health.bpm }); diff --git a/apps/android/metadata.json b/apps/android/metadata.json index 7e4b275c5..27b77cf2f 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "4.02", + "version": "0.11", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From 3dabc77c553a59db5e1ec80973acf61452e2d701 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 12:42:05 +0200 Subject: [PATCH 049/183] Rename metadata.info to metadata.json --- apps/widday/{metadata.info => metadata.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/widday/{metadata.info => metadata.json} (100%) diff --git a/apps/widday/metadata.info b/apps/widday/metadata.json similarity index 100% rename from apps/widday/metadata.info rename to apps/widday/metadata.json From 9defc580c2ac62bfe950e280f705f3ebf5b84a88 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 12:42:41 +0200 Subject: [PATCH 050/183] Update metadata.json --- apps/widday/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index 54e42f000..1a12e6f56 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -4,7 +4,7 @@ "icon": "widday.png", "version":"0.01", "description": "Just the day of the current date as widget", - readme: "README.md + readme: "README.md" "tags": "widget,say,date", "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], From 9c8463d2dc7b0f4ba0b1cd8a69ca6ae434046ff7 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 12:43:07 +0200 Subject: [PATCH 051/183] Delete widday.info --- apps/widday/widday.info | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 apps/widday/widday.info diff --git a/apps/widday/widday.info b/apps/widday/widday.info deleted file mode 100644 index 351a302ca..000000000 --- a/apps/widday/widday.info +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id":"widday", - "name":"Day Widget", - "type":"widget", - "version":"0.01", - "tags":"widget,date,day", - "files":"widday.info,widday.wid.js" -} From d88c2d6ede22508ad65b349fa95eda8d27de58b0 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 12:44:08 +0200 Subject: [PATCH 052/183] Delete pongclock.img --- apps/pongclock/pongclock.img | Bin 1156 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/pongclock/pongclock.img diff --git a/apps/pongclock/pongclock.img b/apps/pongclock/pongclock.img deleted file mode 100644 index e0045eff79314697cb8fe35138277dd0de433bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1156 zcmcJNQEtN^5JVR{|3>NoAie;oIRKaIft~mO+nI&fSg!w4BrD5fn4JJQ|J-CBy6kmd zeS~|FIW||+9AD~P(P(waoWEEPs(#X13znU#iH22uc#bQ5oO1`BaYG;BSLy%hW>&UNWPw3kNy2f@>t7EWdFER5bVG z&5e2n(S^Y8Rl8P2eYsG z1ffabKcYrr^Z%Q}gM*T7bd#<;i2j>z?}wod&9; Date: Mon, 6 Jun 2022 13:33:55 +0200 Subject: [PATCH 053/183] Update metadata.json --- apps/widday/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index 1a12e6f56..e929c9498 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -4,7 +4,7 @@ "icon": "widday.png", "version":"0.01", "description": "Just the day of the current date as widget", - readme: "README.md" + "readme": "README.md" "tags": "widget,say,date", "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], From 2529f294e27abf160d2b7c2e55b14328e71c6aec Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 13:40:07 +0200 Subject: [PATCH 054/183] Update metadata.json --- apps/widday/metadata.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index e929c9498..530cd9276 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -10,7 +10,6 @@ "supports": ["BANGLEJS", "BANGLEJS2"], "screenshots" : [ { "url":"screenshot.png" } ], "storage": [ - {"name":"widday.wid.js","url":"app.js"}, - {"name":"widday.img","url":"app-icon.js","evaluate":true} + {"name":"widday.wid.js","url":"app.js"} ] } From 0499e6040c824375f156b592777842d8d76327ec Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 13:43:08 +0200 Subject: [PATCH 055/183] Update metadata.json --- apps/widday/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index 530cd9276..86647b729 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -4,7 +4,7 @@ "icon": "widday.png", "version":"0.01", "description": "Just the day of the current date as widget", - "readme": "README.md" + "readme": "README.md", "tags": "widget,say,date", "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], From fb0af46f49a5c99abfe987d764673936c1a9807c Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 13:46:30 +0200 Subject: [PATCH 056/183] Add files via upload --- apps/widday/widget.png | Bin 0 -> 778 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/widday/widget.png diff --git a/apps/widday/widget.png b/apps/widday/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..4620978719b3091d1e043eacc05df818219249d3 GIT binary patch literal 778 zcmV+l1NHogP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0-s4lK~!i%?U_GF z>rfQNzvmxZ6w%FsI`|J~!9hByI156%h=ZuJi?f30pe_n7f{P&9BDm@3QbiEK!BHtv zD7YxUK4drw(&d(_nX>JC(yP4RD$KyyQlNG!N(rGEihFOdY(bdJqB5Z8f z`>IAJ!wcA{>^-o)4)pfIoC2O8pPv*(xWA|H$lDu*JL(25FM+{9V0IRGedS3Dr3|<% zg|gJvQn;gTU}Xh3IbmW_S4Tlg8JL&=4iAgR!2z(l3k(mlGih%J+S-^XQ1%%Z9nG!F zh6cmf-ZqTQP5XLnZDmKFSg$1^*LT6+Gtk)yEGz&|Pr&3PPg*E-2g(Jx#8Eq{yy;h%!DY;zVLGfK0YWsvb01& z#>PBVExmW(^c1+hWe?V2Ll84e*OJyP{-e9 z?)H{Kk((O|3$h(QJ7YpBoPBiz@-55@Jv|f__Vy@9Qxh;X#iT;YE+OIlT|L}*c`1ZX z{4F7&rba#7sIM=?58%zfFC;Xeo6vx60&gJy6GPzt Date: Mon, 6 Jun 2022 13:49:31 +0200 Subject: [PATCH 057/183] Update metadata.json --- apps/widday/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index 86647b729..6065c6881 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -1,7 +1,7 @@ { "id": "widday", "name": "Day Widget", "shortName":"My Timer", - "icon": "widday.png", + "icon": "widget.png", "version":"0.01", "description": "Just the day of the current date as widget", "readme": "README.md", From b2d1a52800a4509c854b013de98e63c5085fcf98 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 13:52:26 +0200 Subject: [PATCH 058/183] Update app.js --- apps/widday/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widday/app.js b/apps/widday/app.js index 189fc1951..cdea76a29 100644 --- a/apps/widday/app.js +++ b/apps/widday/app.js @@ -7,7 +7,7 @@ g.setFontAlign(0,1); // center fonts //g.drawRect(this.x, this.y, this.x+width-1, this.y+23); // check the bounds! - var text = "date.getDate(); + var text = date.getDate(); g.setFont("Vector", 24); g.drawString(text, this.x+width/2+1, this.y + 28); //g.setColor(0, 0, 1); From de751b1b80bd4897e87e356996101d322d01aa35 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:00:17 +0200 Subject: [PATCH 059/183] Rename app.js to widget.js --- apps/widday/{app.js => widget.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/widday/{app.js => widget.js} (100%) diff --git a/apps/widday/app.js b/apps/widday/widget.js similarity index 100% rename from apps/widday/app.js rename to apps/widday/widget.js From e75a044257ce8ff30e674dea4c3446ccd971e8a9 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:00:40 +0200 Subject: [PATCH 060/183] Update metadata.json --- apps/widday/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index 6065c6881..f75652c09 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -10,6 +10,6 @@ "supports": ["BANGLEJS", "BANGLEJS2"], "screenshots" : [ { "url":"screenshot.png" } ], "storage": [ - {"name":"widday.wid.js","url":"app.js"} + {"name":"widday.wid.js","url":"widget.js"} ] } From de4b820b58e95851d2d00dda550a358adcb1cbf9 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:05:50 +0200 Subject: [PATCH 061/183] Update metadata.json --- apps/widday/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index f75652c09..3fd406b4b 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -2,6 +2,7 @@ "name": "Day Widget", "shortName":"My Timer", "icon": "widget.png", + "type": "widget" "version":"0.01", "description": "Just the day of the current date as widget", "readme": "README.md", From fe5c293c4603b15ba8b06e325955125b5dbeef23 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:07:11 +0200 Subject: [PATCH 062/183] Update metadata.json --- apps/widday/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index 3fd406b4b..352fe78c0 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -2,7 +2,7 @@ "name": "Day Widget", "shortName":"My Timer", "icon": "widget.png", - "type": "widget" + "type": "widget", "version":"0.01", "description": "Just the day of the current date as widget", "readme": "README.md", From bb1f8d6c2bdfa7993eeedb4f46aa7943de934fe9 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:11:00 +0200 Subject: [PATCH 063/183] Update app.js --- apps/pongclock/app.js | 167 +++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 84 deletions(-) diff --git a/apps/pongclock/app.js b/apps/pongclock/app.js index 932c1f3d7..2a10bf6ed 100644 --- a/apps/pongclock/app.js +++ b/apps/pongclock/app.js @@ -1,119 +1,116 @@ class Ball { - constructor(collision) { - this.collision = collision; - this.w = 4; - this.h = this.w; - this.y = height / 2 - this.h / 2; - this.x = width / 2 - this.w / 2; + constructor(collision) { + this.collision = collision; + this.w = 4; + this.h = this.w; + this.y = height / 2 - this.h / 2; + this.x = width / 2 - this.w / 2; this.oldX = this.x; this.oldY = this.y; - this.velX = 6; - this.velY = 3.5 + Math.random(); - } + this.velX = 6; + this.velY = 3.5 + Math.random(); + } - reset() { - this.y = height / 2 - this.h / 2; - this.x = width / 2 - this.w / 2; - this.velX = 6; - this.velY = 3.5 + Math.random(); - } + reset() { + this.y = height / 2 - this.h / 2; + this.x = width / 2 - this.w / 2; + this.velX = 6; + this.velY = 3.5 + Math.random(); + } - checkCollision(that, isLeft) { + checkCollision(that, isLeft) { let test = false; if (isLeft) { test = this.x <= that.w + this.w && this.y > that.y && this.y < that.y + that.h; - } - else { + } else { test = this.x >= that.x + this.w && this.y > that.y && this.y < that.y + that.h; } - if (test) { - this.velX = -this.velX; + if (test) { + this.velX = -this.velX; this.velY = (3.5 + 2 * Math.random()) * this.velY / Math.abs(this.velY); if (isLeft) { - right.follow = this; + right.follow = this; left.follow = null; - } else { - left.follow = this; + } else { + left.follow = this; right.follow = null; - } - } - } + } + } + } - move() { - if (this.velX > 0) { - this.checkCollision(right, false); - } else { - this.checkCollision(left, true); + move() { + if (this.velX > 0) { + this.checkCollision(right, false); + } else { + this.checkCollision(left, true); } - this.x += this.velX; - this.y += this.velY; + this.x += this.velX; + this.y += this.velY; - if (this.y <= this.h) { - this.y = this.h; + if (this.y <= this.h) { + this.y = this.h; this.velY = -this.velY; - } + } - if (this.y >= height - this.h) { - this.y = height - this.h; + if (this.y >= height - this.h) { + this.y = height - this.h; this.velY = -this.velY; - } + } - if(this.x >= width) { - left.scored(); + if (this.x >= width) { + left.scored(); restart(); - } else if(this.x < 0) { - right.scored(); + } else if (this.x < 0) { + right.scored(); restart(); - } + } - } + } } class Paddle { - constructor(side) { - this.side = side; - this.w = 4;//15; - this.h = 30;//80; - this.y = height / 2 - this.h/2; - this.follow = null; - this.target = height / 2 - this.h/2; - this.score = 99; + constructor(side) { + this.side = side; + this.w = 4; //15; + this.h = 30; //80; + this.y = height / 2 - this.h / 2; + this.follow = null; + this.target = height / 2 - this.h / 2; + this.score = 99; this.hasLost = false; - } + } - reset() { - this.follow = null; + reset() { + this.follow = null; this.hasLost = false; - this.target = height / 2 - this.h/2; - this.y = height / 2 - this.h/2; - this.move(); - } + this.target = height / 2 - this.h / 2; + this.y = height / 2 - this.h / 2; + this.move(); + } - scored() { + scored() { let d = new Date(); let value = 0; if (this.side == "left") { - value = d.getHours(); + value = d.getHours(); } else { - value = d.getMinutes(); + value = d.getMinutes(); } if (this.score < value) { this.score++; - } - else { + } else { this.score = value; } - } + } - move() { + move() { - if (this.follow && ! this.hasLost) { + if (this.follow && !this.hasLost) { var dy = this.follow.y - this.y - this.h / 2; this.y += dy / 2; - } - else { + } else { this.y += (this.target - this.y) / 10; } if (this.y < 0) { @@ -122,25 +119,26 @@ class Paddle { if (this.y > height - this.h) { this.y = height - this.h; } - } + } } var updateTimeout = null; + function update() { - var d = new Date(); + var d = new Date(); var lastStep = Date.now(); - left.move(); - right.move(); - if(d.getHours() != left.score) { + left.move(); + right.move(); + if (d.getHours() != left.score) { right.follow = null; - right.hasLost = true; - } - if(d.getMinutes() != right.score) { + right.hasLost = true; + } + if (d.getMinutes() != right.score) { left.follow = null; - left.hasLost = true; - } - - ball.move(); + left.hasLost = true; + } + + ball.move(); redraw(); var nextStep = 40 - (Date.now() - lastStep); //console.log(nextStep); @@ -153,7 +151,7 @@ function redraw() { let fontTop = top + height / 11; let topHeight = top + height; g.reset(); - + if (settings.isInvers) { g.setColor(g.theme.bg); g.setBgColor(g.theme.fg); @@ -212,6 +210,7 @@ function stop() { } var pauseTimeout = null; + function pause() { stop(); left.scored(); @@ -235,7 +234,7 @@ Bangle.setUI("clock"); //setup play area var height = g.getHeight(), - width = g.getWidth(); + width = g.getWidth(); var top = 0; g.reset(); From 336ee1052a741ee90b0f704926ad7a10d1fd8666 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:19:00 +0200 Subject: [PATCH 064/183] Update metadata.json --- apps/widday/metadata.json | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/widday/metadata.json b/apps/widday/metadata.json index 352fe78c0..82de23035 100644 --- a/apps/widday/metadata.json +++ b/apps/widday/metadata.json @@ -7,7 +7,6 @@ "description": "Just the day of the current date as widget", "readme": "README.md", "tags": "widget,say,date", - "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], "screenshots" : [ { "url":"screenshot.png" } ], "storage": [ From 09e2407b55e2f25c506139974e5209d80ec9cc3c Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 17:15:17 +0100 Subject: [PATCH 065/183] Darkmode, and fix a bug with location updates Now supports darkmode. Also the widget now reacts to changes in the data in mylocation.json --- apps/widmp/widget.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/apps/widmp/widget.js b/apps/widmp/widget.js index bf032a5ff..b232cf24c 100644 --- a/apps/widmp/widget.js +++ b/apps/widmp/widget.js @@ -1,11 +1,8 @@ -WIDGETS["widmoon"] = { area: "tr", width: 24, draw: function() { - const CenterX = this.x + 12, CenterY = this.y + 12, Radius = 11; - var southernHemisphere = false; // when in southern hemisphere, use the "My Location" App +(() => { + var lastCalculated = 0; // When we last calculated the phase var phase = 0; // The last phase we calculated - - const simulate = false; // simulate one month in one minute - const updateR = 1000; // update every x ms in simulation + var southernHemisphere = false; // when in southern hemisphere -- use the "My Location" App // https://deirdreobyrne.github.io/calculating_moon_phases/ function moonPhase(millis) { @@ -24,7 +21,7 @@ WIDGETS["widmoon"] = { area: "tr", width: 24, draw: function() { function loadLocation() { // "mylocation.json" is created by the "My Location" app location = require("Storage").readJSON("mylocation.json",1)||{"lat":50.1236,"lon":8.6553,"location":"Frankfurt"}; - if (location.lat < 0) southernHemisphere = true; + southernHemisphere = (location.lat < 0); } // code source: github.com/rozek/banglejs-2-activities/blob/main/README.md#drawmoonphase @@ -44,13 +41,20 @@ WIDGETS["widmoon"] = { area: "tr", width: 24, draw: function() { } } - function updateWidget() { + function draw() { + const CenterX = this.x + 12, CenterY = this.y + 12, Radius = 11; + + loadLocation(); g.reset().setColor(g.theme.bg); g.fillRect(CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius); - g.setColor(0x41f); + if (g.theme.dark) { + g.setColor(0xffff); // white + } else { + g.setColor(0x41f); // blue-ish + } millis = (new Date()).getTime(); - if ((millis - lastCalculated) >= 7200000) { + if ((millis - lastCalculated) >= 7000000) { // if it's more than 7,000 sec since last calculation, re-calculate! phase = moonPhase(millis); lastCalculated = millis; } @@ -67,10 +71,14 @@ WIDGETS["widmoon"] = { area: "tr", width: 24, draw: function() { } drawMoonPhase(CenterX,CenterY, Radius, leftFactor,rightFactor); - - if (simulate) setTimeout(updateWidget, updateR); } - loadLocation(); - updateWidget(); -} }; + WIDGETS["widmoon"] = { + area: "tr", + width: 24, + draw: draw + }; + + setInterval(function() {WIDGETS["widmoon"].draw(WIDGETS["widmoon"])}, 7010000); // Re-draw at an interval of 10 sec more than our re-calculate period + +})(); From a35b4f7e96251336083ddcfe30d3aec13f0d062a Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 17:20:23 +0100 Subject: [PATCH 066/183] formatting. --- apps/widmp/widget.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/widmp/widget.js b/apps/widmp/widget.js index b232cf24c..c11812ef7 100644 --- a/apps/widmp/widget.js +++ b/apps/widmp/widget.js @@ -21,7 +21,7 @@ function loadLocation() { // "mylocation.json" is created by the "My Location" app location = require("Storage").readJSON("mylocation.json",1)||{"lat":50.1236,"lon":8.6553,"location":"Frankfurt"}; - southernHemisphere = (location.lat < 0); + southernHemisphere = (location.lat < 0); } // code source: github.com/rozek/banglejs-2-activities/blob/main/README.md#drawmoonphase @@ -47,11 +47,11 @@ loadLocation(); g.reset().setColor(g.theme.bg); g.fillRect(CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius); - if (g.theme.dark) { - g.setColor(0xffff); // white - } else { + if (g.theme.dark) { + g.setColor(0xffff); // white + } else { g.setColor(0x41f); // blue-ish - } + } millis = (new Date()).getTime(); if ((millis - lastCalculated) >= 7000000) { // if it's more than 7,000 sec since last calculation, re-calculate! @@ -74,11 +74,11 @@ } WIDGETS["widmoon"] = { - area: "tr", - width: 24, - draw: draw + area: "tr", + width: 24, + draw: draw }; - + setInterval(function() {WIDGETS["widmoon"].draw(WIDGETS["widmoon"])}, 7010000); // Re-draw at an interval of 10 sec more than our re-calculate period })(); From a0d0b9fdea9f8a9106d2a11c4ba121855e35d562 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 17:21:37 +0100 Subject: [PATCH 067/183] Update ChangeLog --- apps/widmp/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widmp/ChangeLog b/apps/widmp/ChangeLog index 036bdb0f4..ccdc7b1e8 100644 --- a/apps/widmp/ChangeLog +++ b/apps/widmp/ChangeLog @@ -3,3 +3,4 @@ 0.03: Better memory usage, theme support 0.04: Replace the 8 phases by a more exact drawing, see forum.espruino.com/conversations/371985 0.05: Fixed the algorithm for calculating the moon's phase +0.06: Darkmode, and fix a bug with acting on my location changes From e841e9646d9363e1f0bc472a6a228cb5a76733d4 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 17:22:21 +0100 Subject: [PATCH 068/183] New version --- apps/widmp/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widmp/metadata.json b/apps/widmp/metadata.json index ff7ad79ad..cd4dca3ed 100644 --- a/apps/widmp/metadata.json +++ b/apps/widmp/metadata.json @@ -1,7 +1,7 @@ { "id": "widmp", "name": "Moon Phase Widget", - "version": "0.05", + "version": "0.06", "description": "Display the current moon phase in blueish for both hemispheres. In the southern hemisphere the 'My Location' app is needed.", "icon": "widget.png", "type": "widget", From 6f3fb779416caee6ab72dd502d134d0053504337 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 17:53:15 +0100 Subject: [PATCH 069/183] Update description --- apps/widmp/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widmp/metadata.json b/apps/widmp/metadata.json index cd4dca3ed..71503befc 100644 --- a/apps/widmp/metadata.json +++ b/apps/widmp/metadata.json @@ -2,7 +2,7 @@ "id": "widmp", "name": "Moon Phase Widget", "version": "0.06", - "description": "Display the current moon phase in blueish for both hemispheres. In the southern hemisphere the 'My Location' app is needed.", + "description": "Display the current moon phase in blueish (in light mode) or white (in dark mode) for both hemispheres. In the southern hemisphere the 'My Location' app is needed.", "icon": "widget.png", "type": "widget", "tags": "widget,tools", From 932895b53c0ca5d9a5f2bd12e62b9481246473ae Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 18:08:40 +0100 Subject: [PATCH 070/183] Widgets don't need periodic calls --- apps/widmp/widget.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/widmp/widget.js b/apps/widmp/widget.js index c11812ef7..6f6932eca 100644 --- a/apps/widmp/widget.js +++ b/apps/widmp/widget.js @@ -79,6 +79,4 @@ draw: draw }; - setInterval(function() {WIDGETS["widmoon"].draw(WIDGETS["widmoon"])}, 7010000); // Re-draw at an interval of 10 sec more than our re-calculate period - })(); From 417df8e2c1e0a7819e11936b5ea93a75c2e515e9 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 18:23:49 +0100 Subject: [PATCH 071/183] Timeout bug fix; no leading zero on the date. --- apps/bigdclock/bigdclock.app.js | 40 ++++++++------------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index 983ca0d1c..c4da40606 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -10,40 +10,17 @@ Graphics.prototype.setFontOpenSans = function(scale) { ); }; -// 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(); - }, 60300 - (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); + }, 60300 - (Date.now() % 60000)); // We aim for 300ms into the next minute to ensure we make it! } function draw() { - g.reset(); - drawBackground(); var date = new Date(); var h = date.getHours(), m = date.getMinutes(); @@ -52,13 +29,16 @@ function draw() { const level = E.getBattery(); const width = level + (level/2); + g.reset(); g.setBgColor(0, 0, 0); g.setColor(1, 1, 1); + g.clear(); g.setFontOpenSans(); g.setFontAlign(0, -1); - g.drawString(timeString(h, m), g.getWidth() / 2, 30); - g.drawString(dayString(d), g.getWidth() * 3 / 4, 98); + g.drawString(("0"+h).substr(-2) + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); + g.setFontAlign(1, -1); + g.drawString(d, g.getWidth() -6, 98); g.setFont('Vector', 52); g.setFontAlign(-1, -1); g.drawString("SUMOTUWETHFRSA".slice(2*w,2*w+2), 6, 103); @@ -86,9 +66,6 @@ function draw() { queueDraw(); } -Bangle.loadWidgets(); -draw(); - //the following section is also from waveclk Bangle.on('lcdPower', on => { if (on) { @@ -99,6 +76,7 @@ Bangle.on('lcdPower', on => { } }); -Bangle.setUI("clock"); +Bangle.loadWidgets(); +draw(); -Bangle.drawWidgets(); +Bangle.setUI("clock"); From e95842a9d78278b5ba7f79e1c819be901698cd20 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 18:29:50 +0100 Subject: [PATCH 072/183] Wee cleanup --- apps/bigdclock/bigdclock.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index c4da40606..bbdb966db 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -42,9 +42,9 @@ function draw() { g.setFont('Vector', 52); g.setFontAlign(-1, -1); g.drawString("SUMOTUWETHFRSA".slice(2*w,2*w+2), 6, 103); + g.setColor(0, 1, 0); g.fillRect(0, 90, g.getWidth(), 94); - g.reset(); g.setColor(1,1,1); g.fillRect(9,159,166,171); From 5226477f60509f9dee6fbc832cbb79d2a3c1d346 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 18:33:27 +0100 Subject: [PATCH 073/183] Update ChangeLog --- apps/bigdclock/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index ec66c5568..7d9974587 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -1 +1,2 @@ 0.01: Initial version +0.02: setTimeout bug fix; no leading zero on date; cleanup From 0555efc44b1c350e952765a2d07971c2ce9593e9 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 18:33:48 +0100 Subject: [PATCH 074/183] Update metadata.json --- apps/bigdclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index 275a33343..3802a8dfd 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -1,7 +1,7 @@ { "id": "bigdclock", "name": "Big digit clock containing just the essentials", "shortName":"Big digit clock", - "version":"0.01", + "version":"0.02", "description": "A clock containing just the essentials, made as easy to read as possible for those of us that need glasses. It contains the time, the day-of-week, the day-of-month, and the current battery state-of-charge.", "icon": "bigdclock.png", "type": "clock", From d5014356c06c766ba933a103c9c5c21ac947c82d Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 18:39:37 +0100 Subject: [PATCH 075/183] Update screenshot.png --- apps/bigdclock/screenshot.png | Bin 16711 -> 3180 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/bigdclock/screenshot.png b/apps/bigdclock/screenshot.png index 96f2dd4ef1653332bcfe0d8b31f28a78ee5c89a6..8a12b266e71005631235cacc50750f08c59e247d 100644 GIT binary patch literal 3180 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 Nqup8CDjTm`{{i=jI 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 From 335c29dc8039dd3f1db8cedc44ab8b6bf1986bbc Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 19:11:13 +0100 Subject: [PATCH 076/183] Now does light mode --- apps/bigdclock/bigdclock.app.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index bbdb966db..8b190980f 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -30,8 +30,6 @@ function draw() { const width = level + (level/2); g.reset(); - g.setBgColor(0, 0, 0); - g.setColor(1, 1, 1); g.clear(); g.setFontOpenSans(); @@ -43,10 +41,6 @@ function draw() { g.setFontAlign(-1, -1); g.drawString("SUMOTUWETHFRSA".slice(2*w,2*w+2), 6, 103); - g.setColor(0, 1, 0); - g.fillRect(0, 90, g.getWidth(), 94); - - g.setColor(1,1,1); g.fillRect(9,159,166,171); g.fillRect(167,163,170,167); if (Bangle.isCharging()) { @@ -58,9 +52,13 @@ function draw() { } g.fillRect(12,162,12+width,168); if (level < 100) { - g.setColor(0,0,0); + g.setColor(g.theme.bg); g.fillRect(12+width+1,162,162,168); } + + g.setColor(0, 1, 0); + g.fillRect(0, 90, g.getWidth(), 94); + // widget redraw Bangle.drawWidgets(); queueDraw(); From 72d9d2ad19c9bd8f2a6df7ed286076bd3a47f8bc Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 19:11:59 +0100 Subject: [PATCH 077/183] Update ChangeLog --- apps/bigdclock/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index 7d9974587..ef5ee2433 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -1,2 +1,2 @@ 0.01: Initial version -0.02: setTimeout bug fix; no leading zero on date; cleanup +0.02: setTimeout bug fix; no leading zero on date; lightmode; cleanup From 7256f11f94969512a94ed0a95536ca58ab675dee Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 20:57:26 +0100 Subject: [PATCH 078/183] Should now support 12 hour clocl --- apps/bigdclock/ChangeLog | 2 +- apps/bigdclock/bigdclock.app.js | 11 ++++++++++- apps/bigdclock/bigdclock.settings.js | 26 ++++++++++++++++++++++++++ apps/bigdclock/metadata.json | 4 +++- 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 apps/bigdclock/bigdclock.settings.js diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index ef5ee2433..ae5ae9224 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -1,2 +1,2 @@ 0.01: Initial version -0.02: setTimeout bug fix; no leading zero on date; lightmode; cleanup +0.02: setTimeout bug fix; no leading zero on date; lightmode; 12 hour format; cleanup diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index 8b190980f..a597c5840 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -28,13 +28,22 @@ function draw() { w = date.getDay(); // d=1..31; w=0..6 const level = E.getBattery(); const width = level + (level/2); + var settings = Object.assign({ + "12hour": false, + }, require('Storage').readJSON("bigdclock.json", true) || {}); g.reset(); g.clear(); g.setFontOpenSans(); g.setFontAlign(0, -1); - g.drawString(("0"+h).substr(-2) + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); + if (settings["12hour"]) { + if (h > 12) h -= 12; + if (h == 0) h = 12; + g.drawString(h + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); + } else { + g.drawString(("0"+h).substr(-2) + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); + } g.setFontAlign(1, -1); g.drawString(d, g.getWidth() -6, 98); g.setFont('Vector', 52); diff --git a/apps/bigdclock/bigdclock.settings.js b/apps/bigdclock/bigdclock.settings.js new file mode 100644 index 000000000..e5f7bd990 --- /dev/null +++ b/apps/bigdclock/bigdclock.settings.js @@ -0,0 +1,26 @@ +(function(back) { + + var settings = Object.assign({ + "12hour": false, + }, require('Storage').readJSON("bigdclock.json", true) || {}); + + function set12hour(val) { + settings["12hour"]=val; + require('Storage').writeJSON("bigdclock.json", settings); + } + + var mainmenu = { + "": { + "title": "BigDClock" + }, + "< Back": () => back(), + "Time format": { + value: (settings["12hour"] !== undefined ? settings["12hour"] : false), + format: v => v ? "12 hr" : "24 hr", + onchange: v=> { set12hour(v) } + } + }; + + E.showMenu(mainmenu); + +}); diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index 3802a8dfd..3dfd9ce01 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -12,6 +12,8 @@ "screenshots": [ { "url":"screenshot.png" } ], "storage": [ {"name":"bigdclock.app.js","url":"bigdclock.app.js"}, + {"name":"bigdclock.settings.js","url":"bigdclock.settings.js"}, {"name":"bigdclock.img","url":"bigdclock.icon.js","evaluate":true} - ] + ], + "data": [{"name":"bigdclock.json"}] } From 4d8884e1e385b75acb117818a31e1157c554caaa Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 21:00:46 +0100 Subject: [PATCH 079/183] formatting --- apps/bigdclock/bigdclock.app.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index a597c5840..ea95c4de0 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -38,12 +38,12 @@ function draw() { g.setFontOpenSans(); g.setFontAlign(0, -1); if (settings["12hour"]) { - if (h > 12) h -= 12; - if (h == 0) h = 12; + if (h > 12) h -= 12; + if (h == 0) h = 12; g.drawString(h + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); - } else { - g.drawString(("0"+h).substr(-2) + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); - } + } else { + g.drawString(("0"+h).substr(-2) + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); + } g.setFontAlign(1, -1); g.drawString(d, g.getWidth() -6, 98); g.setFont('Vector', 52); From f36edc4213aca638f35ff4fe33c2750a781b1c5c Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 21:02:33 +0100 Subject: [PATCH 080/183] formatting --- apps/bigdclock/bigdclock.settings.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/bigdclock/bigdclock.settings.js b/apps/bigdclock/bigdclock.settings.js index e5f7bd990..ffe553b25 100644 --- a/apps/bigdclock/bigdclock.settings.js +++ b/apps/bigdclock/bigdclock.settings.js @@ -6,19 +6,19 @@ function set12hour(val) { settings["12hour"]=val; - require('Storage').writeJSON("bigdclock.json", settings); + require('Storage').writeJSON("bigdclock.json", settings); } var mainmenu = { "": { - "title": "BigDClock" + "title": "BigDClock" }, - "< Back": () => back(), - "Time format": { - value: (settings["12hour"] !== undefined ? settings["12hour"] : false), - format: v => v ? "12 hr" : "24 hr", - onchange: v=> { set12hour(v) } - } + "< Back": () => back(), + "Time format": { + value: (settings["12hour"] !== undefined ? settings["12hour"] : false), + format: v => v ? "12 hr" : "24 hr", + onchange: v=> { set12hour(v) } + } }; E.showMenu(mainmenu); From 82579465de2e167532e84cf2ab44a19e996077e3 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 21:36:09 +0100 Subject: [PATCH 081/183] Update metadata.json --- apps/bigdclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index 3dfd9ce01..c35838c7d 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -1,6 +1,6 @@ { "id": "bigdclock", "name": "Big digit clock containing just the essentials", - "shortName":"Big digit clock", + "shortName":"Big digit clk", "version":"0.02", "description": "A clock containing just the essentials, made as easy to read as possible for those of us that need glasses. It contains the time, the day-of-week, the day-of-month, and the current battery state-of-charge.", "icon": "bigdclock.png", From 09fe12373821f0cee024940cb16c4c24ba144694 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 21:36:54 +0100 Subject: [PATCH 082/183] formatting. --- apps/bigdclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index c35838c7d..dfa55b44f 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -12,7 +12,7 @@ "screenshots": [ { "url":"screenshot.png" } ], "storage": [ {"name":"bigdclock.app.js","url":"bigdclock.app.js"}, - {"name":"bigdclock.settings.js","url":"bigdclock.settings.js"}, + {"name":"bigdclock.settings.js","url":"bigdclock.settings.js"}, {"name":"bigdclock.img","url":"bigdclock.icon.js","evaluate":true} ], "data": [{"name":"bigdclock.json"}] From d200f6afbf0ff3080a41fd331199216c612d1d09 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 21:41:40 +0100 Subject: [PATCH 083/183] Shortening the name of the config item --- apps/bigdclock/bigdclock.settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bigdclock/bigdclock.settings.js b/apps/bigdclock/bigdclock.settings.js index ffe553b25..396c2ab21 100644 --- a/apps/bigdclock/bigdclock.settings.js +++ b/apps/bigdclock/bigdclock.settings.js @@ -14,7 +14,7 @@ "title": "BigDClock" }, "< Back": () => back(), - "Time format": { + "Clock type": { value: (settings["12hour"] !== undefined ? settings["12hour"] : false), format: v => v ? "12 hr" : "24 hr", onchange: v=> { set12hour(v) } From f10ff7cb2f444a53aee7d59a9a332d5c231d3015 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 22:17:03 +0100 Subject: [PATCH 084/183] The 12/24 hour clock setting is in setting.json --- apps/bigdclock/bigdclock.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index ea95c4de0..4850a4e25 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -30,7 +30,7 @@ function draw() { const width = level + (level/2); var settings = Object.assign({ "12hour": false, - }, require('Storage').readJSON("bigdclock.json", true) || {}); + }, require('Storage').readJSON("setting.json", true) || {}); g.reset(); g.clear(); From 3fc2c33fc15a9cbe9928bd5eb3595e10c898e086 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 22:17:56 +0100 Subject: [PATCH 085/183] Not needed - the 12 hour config is in setting.json --- apps/bigdclock/bigdclock.settings.js | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 apps/bigdclock/bigdclock.settings.js diff --git a/apps/bigdclock/bigdclock.settings.js b/apps/bigdclock/bigdclock.settings.js deleted file mode 100644 index 396c2ab21..000000000 --- a/apps/bigdclock/bigdclock.settings.js +++ /dev/null @@ -1,26 +0,0 @@ -(function(back) { - - var settings = Object.assign({ - "12hour": false, - }, require('Storage').readJSON("bigdclock.json", true) || {}); - - function set12hour(val) { - settings["12hour"]=val; - require('Storage').writeJSON("bigdclock.json", settings); - } - - var mainmenu = { - "": { - "title": "BigDClock" - }, - "< Back": () => back(), - "Clock type": { - value: (settings["12hour"] !== undefined ? settings["12hour"] : false), - format: v => v ? "12 hr" : "24 hr", - onchange: v=> { set12hour(v) } - } - }; - - E.showMenu(mainmenu); - -}); From 3cc0d137722652643e4ba4ed11ba71c27bc7f7f1 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 22:19:24 +0100 Subject: [PATCH 086/183] The 12 hour config is in setting.json --- apps/bigdclock/metadata.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index dfa55b44f..a2174d540 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -14,6 +14,5 @@ {"name":"bigdclock.app.js","url":"bigdclock.app.js"}, {"name":"bigdclock.settings.js","url":"bigdclock.settings.js"}, {"name":"bigdclock.img","url":"bigdclock.icon.js","evaluate":true} - ], - "data": [{"name":"bigdclock.json"}] + ] } From dd45d0e513ec0c478757eaa00089103ffb284cae Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 22:24:26 +0100 Subject: [PATCH 087/183] Not needed - 12 hour config is in setting.json --- apps/bigdclock/metadata.json | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index a2174d540..c6be19138 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -12,7 +12,6 @@ "screenshots": [ { "url":"screenshot.png" } ], "storage": [ {"name":"bigdclock.app.js","url":"bigdclock.app.js"}, - {"name":"bigdclock.settings.js","url":"bigdclock.settings.js"}, {"name":"bigdclock.img","url":"bigdclock.icon.js","evaluate":true} ] } From 92f0aea4dbb228090d3224c208cf5543fa3f6a7d Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 22:35:30 +0100 Subject: [PATCH 088/183] Pausing this. --- apps/widmp/settings.js | 71 ++++++++++++++++++++++++++++++++++++++++++ apps/widmp/widget.js | 2 ++ 2 files changed, 73 insertions(+) create mode 100644 apps/widmp/settings.js diff --git a/apps/widmp/settings.js b/apps/widmp/settings.js new file mode 100644 index 000000000..e0eb24b2d --- /dev/null +++ b/apps/widmp/settings.js @@ -0,0 +1,71 @@ +(function(back) { + + var settings = Object.assign({ + default_colour: true, + red: 0, + green: 0, + blue: 0, + }, require('Storage').readJSON("widmp.json", true) || {}); + + function writeSettings() { + require('Storage').writeJSON("widmp.json", settings); + } + + function writeSettingsCustom() { + settings.default_colour = false; + writeSettings(); + } + + var mainmenu = { + "": { + "title": "Moon colour" + }, + "< Back": () => back(), + "Default": { + value: (settings.default_colour !== undefined ? settings.default_colour : true), + format: v => v ? "Yes" : "No", + onchange: v => { + settings.default_colour = v; + writeSettings(); + } + }, + "Custom...": () => E.showMenu(custommenu) + }; + + var custommenu = { + "": { + "title": "Custom colour..." + }, + "< Back": () => E.showMenu(mainmenu), + "red": { + value: 0|settings.red, + min: 0, + max: 7, + onchange: v => { + settings.red = v; + writeSettingsCustom(); + } + }, + "green": { + value: 0|settings.green, + min: 0, + max: 7, + onchange: v => { + settings.green = v; + writeSettingsCustom(); + } + }, + "blue": { + value: 0|settings.blue, + min: 0, + max: 7, + onchange: v => { + settings.blue = v; + writeSettingsCustom(); + } + } + }; + + E.showMenu(mainmenu); + +}); diff --git a/apps/widmp/widget.js b/apps/widmp/widget.js index 6f6932eca..537ddef68 100644 --- a/apps/widmp/widget.js +++ b/apps/widmp/widget.js @@ -50,6 +50,8 @@ if (g.theme.dark) { g.setColor(0xffff); // white } else { + // rrrrrggggggbbbbb + // 0000010000011111 g.setColor(0x41f); // blue-ish } From 45c830d21678920bb866f828ce5c7e739f7ac7dd Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 22:45:45 +0100 Subject: [PATCH 089/183] Should draw the moon in the right colour --- apps/widmp/widget.js | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/widmp/widget.js b/apps/widmp/widget.js index 537ddef68..bab980de0 100644 --- a/apps/widmp/widget.js +++ b/apps/widmp/widget.js @@ -40,6 +40,37 @@ g.drawLine(CenterX-leftFactor*y,CenterY+x, CenterX+rightFactor*y,CenterY+x); } } + + function setMoonColour() { + var settings = Object.assign({ + default_colour: true, + red: 0, + green: 0, + blue: 0, + }, require('Storage').readJSON("widmp.json", true) || {}); + if (settings.default_colour) { + if (g.theme.dark) { + g.setColor(0xffff); // white + } else { + // rrrrrggggggbbbbb + // 0000010000011111 + g.setColor(0x41f); // blue-ish + } + } else { + // 1111110000000000 + // 5432109876543210 + // rrrrrggggggbbbbb + // RxxRxGxxGxxBxxBx + let r = settings.red; + let g = settings.green; + let b = settings.blue; + r = (r << 13) | ((r & 3) << 11); + g = (g << 8) | (g << 5); + b = (b << 2) | (b & 3); + g.setColor(r | g | b); + } + } + function draw() { const CenterX = this.x + 12, CenterY = this.y + 12, Radius = 11; @@ -47,13 +78,6 @@ loadLocation(); g.reset().setColor(g.theme.bg); g.fillRect(CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius); - if (g.theme.dark) { - g.setColor(0xffff); // white - } else { - // rrrrrggggggbbbbb - // 0000010000011111 - g.setColor(0x41f); // blue-ish - } millis = (new Date()).getTime(); if ((millis - lastCalculated) >= 7000000) { // if it's more than 7,000 sec since last calculation, re-calculate! @@ -72,6 +96,7 @@ var tmp=leftFactor; leftFactor=rightFactor; rightFactor=tmp; } + setMoonColour(); drawMoonPhase(CenterX,CenterY, Radius, leftFactor,rightFactor); } From f79f76056b33e7f17bdd1eb6d0ef9811e511bf25 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 23:04:55 +0100 Subject: [PATCH 090/183] Reducing number of possible colours --- apps/widmp/settings.js | 7 ++++--- apps/widmp/widget.js | 28 +++++++++------------------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/apps/widmp/settings.js b/apps/widmp/settings.js index e0eb24b2d..c1ead5033 100644 --- a/apps/widmp/settings.js +++ b/apps/widmp/settings.js @@ -13,6 +13,7 @@ function writeSettingsCustom() { settings.default_colour = false; + mainmenu["Default"].value = false; writeSettings(); } @@ -40,7 +41,7 @@ "red": { value: 0|settings.red, min: 0, - max: 7, + max: 4, onchange: v => { settings.red = v; writeSettingsCustom(); @@ -49,7 +50,7 @@ "green": { value: 0|settings.green, min: 0, - max: 7, + max: 4, onchange: v => { settings.green = v; writeSettingsCustom(); @@ -58,7 +59,7 @@ "blue": { value: 0|settings.blue, min: 0, - max: 7, + max: 4, onchange: v => { settings.blue = v; writeSettingsCustom(); diff --git a/apps/widmp/widget.js b/apps/widmp/widget.js index bab980de0..8b617cc9f 100644 --- a/apps/widmp/widget.js +++ b/apps/widmp/widget.js @@ -41,14 +41,14 @@ } } - function setMoonColour() { + function setMoonColour(g) { var settings = Object.assign({ default_colour: true, - red: 0, - green: 0, - blue: 0, + red: 0, + green: 0, + blue: 0, }, require('Storage').readJSON("widmp.json", true) || {}); - if (settings.default_colour) { + if (settings.default_colour) { if (g.theme.dark) { g.setColor(0xffff); // white } else { @@ -56,19 +56,9 @@ // 0000010000011111 g.setColor(0x41f); // blue-ish } - } else { - // 1111110000000000 - // 5432109876543210 - // rrrrrggggggbbbbb - // RxxRxGxxGxxBxxBx - let r = settings.red; - let g = settings.green; - let b = settings.blue; - r = (r << 13) | ((r & 3) << 11); - g = (g << 8) | (g << 5); - b = (b << 2) | (b & 3); - g.setColor(r | g | b); - } + } else { + g.setColor(settings.red/4, settings.green/4, settings.blue/4); + } } @@ -96,7 +86,7 @@ var tmp=leftFactor; leftFactor=rightFactor; rightFactor=tmp; } - setMoonColour(); + setMoonColour(g); drawMoonPhase(CenterX,CenterY, Radius, leftFactor,rightFactor); } From 26f1c29ace9f3a4ec1e420c44ddc562a69b21397 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 23:08:06 +0100 Subject: [PATCH 091/183] Formatting... --- apps/widmp/settings.js | 100 ++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/apps/widmp/settings.js b/apps/widmp/settings.js index c1ead5033..731d78584 100644 --- a/apps/widmp/settings.js +++ b/apps/widmp/settings.js @@ -2,9 +2,9 @@ var settings = Object.assign({ default_colour: true, - red: 0, - green: 0, - blue: 0, + red: 0, + green: 0, + blue: 0, }, require('Storage').readJSON("widmp.json", true) || {}); function writeSettings() { @@ -12,59 +12,59 @@ } function writeSettingsCustom() { - settings.default_colour = false; - mainmenu["Default"].value = false; - writeSettings(); + settings.default_colour = false; + mainmenu["Default"].value = false; + writeSettings(); } var mainmenu = { - "": { - "title": "Moon colour" - }, - "< Back": () => back(), - "Default": { - value: (settings.default_colour !== undefined ? settings.default_colour : true), - format: v => v ? "Yes" : "No", - onchange: v => { - settings.default_colour = v; - writeSettings(); - } - }, - "Custom...": () => E.showMenu(custommenu) + "": { + "title": "Moon colour" + }, + "< Back": () => back(), + "Default": { + value: (settings.default_colour !== undefined ? settings.default_colour : true), + format: v => v ? "Yes" : "No", + onchange: v => { + settings.default_colour = v; + writeSettings(); + } + }, + "Custom...": () => E.showMenu(custommenu) }; var custommenu = { - "": { - "title": "Custom colour..." - }, - "< Back": () => E.showMenu(mainmenu), - "red": { - value: 0|settings.red, - min: 0, - max: 4, - onchange: v => { - settings.red = v; - writeSettingsCustom(); - } - }, - "green": { - value: 0|settings.green, - min: 0, - max: 4, - onchange: v => { - settings.green = v; - writeSettingsCustom(); - } - }, - "blue": { - value: 0|settings.blue, - min: 0, - max: 4, - onchange: v => { - settings.blue = v; - writeSettingsCustom(); - } - } + "": { + "title": "Custom colour..." + }, + "< Back": () => E.showMenu(mainmenu), + "red": { + value: 0|settings.red, + min: 0, + max: 4, + onchange: v => { + settings.red = v; + writeSettingsCustom(); + } + }, + "green": { + value: 0|settings.green, + min: 0, + max: 4, + onchange: v => { + settings.green = v; + writeSettingsCustom(); + } + }, + "blue": { + value: 0|settings.blue, + min: 0, + max: 4, + onchange: v => { + settings.blue = v; + writeSettingsCustom(); + } + } }; E.showMenu(mainmenu); From 3adb5b0b796cdb12b3370c708e70836cd36ba6a0 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 23:09:46 +0100 Subject: [PATCH 092/183] Update ChangeLog --- apps/widmp/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widmp/ChangeLog b/apps/widmp/ChangeLog index ccdc7b1e8..f0cd6bd8a 100644 --- a/apps/widmp/ChangeLog +++ b/apps/widmp/ChangeLog @@ -3,4 +3,4 @@ 0.03: Better memory usage, theme support 0.04: Replace the 8 phases by a more exact drawing, see forum.espruino.com/conversations/371985 0.05: Fixed the algorithm for calculating the moon's phase -0.06: Darkmode, and fix a bug with acting on my location changes +0.06: Darkmode, custom colours, and fix a bug with acting on mylocation changes From 107dabdb2821ffc5f19554c482b42b73d1783d2f Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 23:18:18 +0100 Subject: [PATCH 093/183] Including the settings.js --- apps/widmp/metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/widmp/metadata.json b/apps/widmp/metadata.json index 71503befc..c5bec93a4 100644 --- a/apps/widmp/metadata.json +++ b/apps/widmp/metadata.json @@ -8,6 +8,7 @@ "tags": "widget,tools", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ - {"name":"widmp.wid.js","url":"widget.js"} + {"name":"widmp.wid.js","url":"widget.js"}, + {"name":"widmp.settings.js","url":"settings.js"} ] } From 60a8d736f20520277e01ecb657aac8936d4416b9 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 23:28:25 +0100 Subject: [PATCH 094/183] Update metadata.json --- apps/widmp/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/widmp/metadata.json b/apps/widmp/metadata.json index c5bec93a4..b1e6a6c8c 100644 --- a/apps/widmp/metadata.json +++ b/apps/widmp/metadata.json @@ -1,6 +1,6 @@ { "id": "widmp", - "name": "Moon Phase Widget", + "name": "Moon Phase", "version": "0.06", "description": "Display the current moon phase in blueish (in light mode) or white (in dark mode) for both hemispheres. In the southern hemisphere the 'My Location' app is needed.", "icon": "widget.png", @@ -10,5 +10,6 @@ "storage": [ {"name":"widmp.wid.js","url":"widget.js"}, {"name":"widmp.settings.js","url":"settings.js"} - ] + ], + "data": [{"name":"widmp.json"}] } From 7517e21adab57529ae17a3eec18434907be662a4 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Mon, 6 Jun 2022 23:37:41 +0100 Subject: [PATCH 095/183] Dynamically updates the widget --- apps/widmp/settings.js | 1 + apps/widmp/widget.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/widmp/settings.js b/apps/widmp/settings.js index 731d78584..46c5d3609 100644 --- a/apps/widmp/settings.js +++ b/apps/widmp/settings.js @@ -9,6 +9,7 @@ function writeSettings() { require('Storage').writeJSON("widmp.json", settings); + if (WIDGETS["widmp"]) WIDGETS["widmp"].draw(); } function writeSettingsCustom() { diff --git a/apps/widmp/widget.js b/apps/widmp/widget.js index 8b617cc9f..22a7d6572 100644 --- a/apps/widmp/widget.js +++ b/apps/widmp/widget.js @@ -90,7 +90,7 @@ drawMoonPhase(CenterX,CenterY, Radius, leftFactor,rightFactor); } - WIDGETS["widmoon"] = { + WIDGETS["widmp"] = { area: "tr", width: 24, draw: draw From f0222b01954e618d00dc65aa6a3d797d7a1b99e7 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Tue, 7 Jun 2022 02:11:53 +0100 Subject: [PATCH 096/183] Better way of determining 12 hour clock setting --- apps/bigdclock/bigdclock.app.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index 4850a4e25..ce2368e87 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -28,16 +28,14 @@ function draw() { w = date.getDay(); // d=1..31; w=0..6 const level = E.getBattery(); const width = level + (level/2); - var settings = Object.assign({ - "12hour": false, - }, require('Storage').readJSON("setting.json", true) || {}); + var is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; g.reset(); g.clear(); g.setFontOpenSans(); g.setFontAlign(0, -1); - if (settings["12hour"]) { + if (is12Hour) { if (h > 12) h -= 12; if (h == 0) h = 12; g.drawString(h + ":" + ("0"+m).substr(-2), g.getWidth() / 2, 30); From cfb808f5e6423d9c42424f52c940e1a6410a2b7e Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 7 Jun 2022 13:07:13 +0100 Subject: [PATCH 097/183] info --- apps/weather/readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/weather/readme.md b/apps/weather/readme.md index 6d0ea04a5..b37d0b38e 100644 --- a/apps/weather/readme.md +++ b/apps/weather/readme.md @@ -11,6 +11,9 @@ You can view the full report through the app: 1. Install [Gadgetbridge for Android](https://f-droid.org/packages/nodomain.freeyourgadget.gadgetbridge/) on your phone. 2. Set up [Gadgetbridge weather reporting](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Weather). +If using the `Bangle.js Gadgetbridge` app on your phone (as opposed to the standard F-Droid `Gadgetbridge`) you need to set the package name +to `com.espruino.gadgetbridge.banglejs` in the settings of the weather app (`settings -> gadgetbridge support -> package name`). + ## Settings * Expiration timespan can be set after which the local weather data is considered as invalid From e5de06eba5694092e2446ca5d567301a1263aa2c Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Tue, 7 Jun 2022 14:04:55 +0100 Subject: [PATCH 098/183] Internationalisation; small bug fix --- apps/bigdclock/ChangeLog | 1 + apps/bigdclock/bigdclock.app.js | 8 ++++++-- apps/bigdclock/metadata.json | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index ae5ae9224..2b6fcc7cb 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial version 0.02: setTimeout bug fix; no leading zero on date; lightmode; 12 hour format; cleanup +0.03: Internationalisation; bug fix - battery icon responds promptly to charging state diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index ce2368e87..7b26d4f17 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -29,6 +29,7 @@ function draw() { const level = E.getBattery(); const width = level + (level/2); var is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; + var dows = require("date_utils").dows(0,1); g.reset(); g.clear(); @@ -46,7 +47,7 @@ function draw() { g.drawString(d, g.getWidth() -6, 98); g.setFont('Vector', 52); g.setFontAlign(-1, -1); - g.drawString("SUMOTUWETHFRSA".slice(2*w,2*w+2), 6, 103); + g.drawString(dows[w].slice(0,2).toUpperCase(), 6, 103); g.fillRect(9,159,166,171); g.fillRect(167,163,170,167); @@ -71,7 +72,6 @@ function draw() { queueDraw(); } -//the following section is also from waveclk Bangle.on('lcdPower', on => { if (on) { draw(); // draw immediately, queue redraw @@ -81,6 +81,10 @@ Bangle.on('lcdPower', on => { } }); +Bangle.on('charging', (charging) => { + draw(); +}); + Bangle.loadWidgets(); draw(); diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index c6be19138..e80dd9a04 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -1,7 +1,7 @@ { "id": "bigdclock", "name": "Big digit clock containing just the essentials", "shortName":"Big digit clk", - "version":"0.02", + "version":"0.03", "description": "A clock containing just the essentials, made as easy to read as possible for those of us that need glasses. It contains the time, the day-of-week, the day-of-month, and the current battery state-of-charge.", "icon": "bigdclock.png", "type": "clock", From 0c3a7dfe9e7e2f6aa4ad997cc226bb789d222f87 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 7 Jun 2022 16:47:45 +0100 Subject: [PATCH 099/183] exstats: Add altitude (GPS and barometer) Ensure speed(and alt) updates from GPS even when a run isn't started --- modules/exstats.js | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/modules/exstats.js b/modules/exstats.js index 63d94ec7b..461ae727f 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -128,10 +128,11 @@ function formatPace(speed, paceLength) { Bangle.on("GPS", function(fix) { if (!fix.fix) return; // only process actual fixes - - if (!state.active) return; state.lastGPS = state.thisGPS; state.thisGPS = fix; + if (stats["altg"]) stats["altg"].emit("changed",stats["altg"]); + if (stats["speed"]) stats["speed"].emit("changed",stats["speed"]); + if (!state.active) return; if (state.lastGPS.fix) state.distance += calcDistance(state.lastGPS, fix); if (stats["dist"]) stats["dist"].emit("changed",stats["dist"]); @@ -140,7 +141,6 @@ Bangle.on("GPS", function(fix) { 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"]); if (state.notify.dist.increment > 0 && state.notify.dist.next <= state.distance) { stats["dist"].emit("notify",stats["dist"]); state.notify.dist.next = state.notify.dist.next + state.notify.dist.increment; @@ -168,10 +168,21 @@ Bangle.on("HRM", function(h) { if (stats["bpm"]) stats["bpm"].emit("changed",stats["bpm"]); } }); +if (Bangle.setBarometerPower) Bangle.on("pressure", function(e) { + if (state.alt === undefined) + state.alt = e.altitude; + else + state.alt = state.alt*0.9 + e.altitude*0.1; + var i = Math.round(state.alt); + if (i!==state.alti) { + state.alti = i; + if (stats["altb"]) stats["altb"].emit("changed",stats["altb"]); + } +}); /** Get list of available statistic types */ exports.getList = function() { - return [ + var l = [ {name: "Time", id:"time"}, {name: "Distance", id:"dist"}, {name: "Steps", id:"step"}, @@ -181,7 +192,10 @@ exports.getList = function() { {name: "Pace (curr)", id:"pacec"}, {name: "Speed", id:"speed"}, {name: "Cadence", id:"caden"}, + {name: "Altitude (GPS)", id:"altg"} ]; + if (Bangle.setBarometerPower) l.push({name: "Altitude (baro)", id:"altb"}); + return l; }; /** Instantiate the given list of statistic IDs (see comments at top) options = { @@ -205,7 +219,7 @@ exports.getStats = function(statIDs, options) { options.notify.dist.increment = (options.notify && options.notify.dist && options.notify.dist.increment)||0; options.notify.step.increment = (options.notify && options.notify.step && options.notify.step.increment)||0; options.notify.time.increment = (options.notify && options.notify.time && options.notify.time.increment)||0; - var needGPS,needHRM; + var needGPS,needHRM,needBaro; // ====================== if (statIDs.includes("time")) { stats["time"]={ @@ -276,10 +290,27 @@ exports.getStats = function(statIDs, options) { getString : function() { return state.stepsPerMin; }, }; } + if (statIDs.includes("altg")) { + needGPS = true; + stats["altg"]={ + title : "Altitude", + getValue : function() { return state.thisGPS.alt; }, + getString : function() { return (state.thisGPS.alt===undefined)?"-":Math.round(state.thisGPS.alt)+"m"; }, + }; + } + if (statIDs.includes("altb")) { + needBaro = true; + stats["altb"]={ + title : "Altitude", + getValue : function() { return state.alt; }, + getString : function() { return (state.alt===undefined)?"-":state.alti+"m"; }, + }; + } // ====================== for (var i in stats) stats[i].id=i; // set up ID field if (needGPS) Bangle.setGPSPower(true,"exs"); if (needHRM) Bangle.setHRMPower(true,"exs"); + if (needBaro) Bangle.setBarometerPower(true,"exs"); setInterval(function() { // run once a second.... if (!state.active) return; // called once a second @@ -315,6 +346,8 @@ exports.getStats = function(statIDs, options) { state.BPM = 0; state.BPMage = 0; state.maxBPM = 0; + state.alt = undefined; // barometer altitude (meters) + state.alti = 0; // integer ver of state.alt (to avoid repeated 'changed' notifications) state.notify = options.notify; if (options.notify.dist.increment > 0) { state.notify.dist.next = state.distance + options.notify.dist.increment; From 66bf7f3b1269bf1b2a053d6b50bb9604e2d54ba4 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:23:12 +0200 Subject: [PATCH 100/183] ClockFace_menu: use addItems for settings --- modules/ClockFace.md | 25 +++++++++++++++++++++++++ modules/ClockFace_menu.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/modules/ClockFace.md b/modules/ClockFace.md index 6b59e68e7..e5ab71179 100644 --- a/modules/ClockFace.md +++ b/modules/ClockFace.md @@ -174,4 +174,29 @@ Bangle.on('step', function(steps) { if (clock.paused === false) // draw step count }); +``` + + +ClockFace_menu +============== +If your clock comes with a settings menu, you can use this library to easily add +some common options: + +```js + +let settings = require("Storage").readJSON(".settings.json", true)||{}; +function save(key, value) { + settings[key] = value; + require("Storage").writeJSON(".settings.json", settings); +} + +let menu = { + "": {"title": /*LANG*/" Settings"}, +}; +require("ClockFace_menu").addItems(menu, save, { + showDate: settings.showDate, + loadWidgets: settings.loadWidgets, +}); +E.showMenu(menu); + ``` \ No newline at end of file diff --git a/modules/ClockFace_menu.js b/modules/ClockFace_menu.js index cd99ea39f..9fe61cac6 100644 --- a/modules/ClockFace_menu.js +++ b/modules/ClockFace_menu.js @@ -1,4 +1,31 @@ -// boolean options, which default to true +/** + * Add setting items to a menu + * + * @param {object} menu Menu to add items to + * @param {function} callback Callback when value changes + * @param {object} items Menu items to add, with their current value + */ +exports.addItems = function(menu, callback, items) { + Object.keys(items).forEach(key => { + let value = items[key]; + const label = { + showDate:/*LANG*/"Show date", + loadWidgets:/*LANG*/"Load widgets", + }[key]; + switch(key) { + case "showDate": + case "loadWidgets": + // boolean options, which default to true + if (value===undefined) value = true; + menu[label] = { + value: !!value, + onchange: v => callback(key, v), + }; + } + }); +}; + +// legacy boolean options exports.showDate = exports.loadWidgets = function(value, callback) { From c6c146029ef0e1ac6b65d33e6fd8661e2b7caf85 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:26:31 +0200 Subject: [PATCH 101/183] barclock: Use ClockFace_menu.addItems --- apps/barclock/ChangeLog | 1 + apps/barclock/metadata.json | 2 +- apps/barclock/settings.js | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/apps/barclock/ChangeLog b/apps/barclock/ChangeLog index 197a24738..ba44ecef8 100644 --- a/apps/barclock/ChangeLog +++ b/apps/barclock/ChangeLog @@ -11,3 +11,4 @@ 0.11: Use ClockFace.is12Hour 0.12: Add settings to hide date,widgets 0.13: Add font setting +0.14: Use ClockFace_menu.addItems diff --git a/apps/barclock/metadata.json b/apps/barclock/metadata.json index 0a0b73778..0c227dc52 100644 --- a/apps/barclock/metadata.json +++ b/apps/barclock/metadata.json @@ -1,7 +1,7 @@ { "id": "barclock", "name": "Bar Clock", - "version": "0.13", + "version": "0.14", "description": "A simple digital clock showing seconds as a bar", "icon": "clock-bar.png", "screenshots": [{"url":"screenshot.png"},{"url":"screenshot_pm.png"}], diff --git a/apps/barclock/settings.js b/apps/barclock/settings.js index 3e97688a1..dfe25581c 100644 --- a/apps/barclock/settings.js +++ b/apps/barclock/settings.js @@ -1,26 +1,26 @@ (function(back) { - let s = require('Storage').readJSON("barclock.settings.json", true) || {}; + let s = require("Storage").readJSON("barclock.settings.json", true) || {}; - function saver(key) { - return value => { - s[key] = value; - require('Storage').writeJSON("barclock.settings.json", s); - } + function save(key, value) { + s[key] = value; + require("Storage").writeJSON("barclock.settings.json", s); } const fonts = [/*LANG*/"Bitmap",/*LANG*/"Vector"]; - const menu = { + let menu = { "": {"title": /*LANG*/"Bar Clock"}, /*LANG*/"< Back": back, - /*LANG*/"Show date": require("ClockFace_menu").showDate(s.showDate, saver('showDate')), - /*LANG*/"Load widgets": require("ClockFace_menu").loadWidgets(s.loadWidgets, saver('loadWidgets')), /*LANG*/"Font": { value: s.font|0, - min:0,max:1,wrap:true, - format:v=>fonts[v], - onchange:saver('font'), + min: 0, max: 1, wrap: true, + format: v => fonts[v], + onchange: v => save("font", v), }, }; + require("ClockFace_menu").addItems(menu, save, { + showDate: s.showDate, + loadWidgets: s.loadWidgets, + }); E.showMenu(menu); }); From 994d9f2a0871d1fd4efe5b3d6b62ba1bb55f37b9 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:28:11 +0200 Subject: [PATCH 102/183] cogclock: Use ClockFace_menu.addItems --- apps/cogclock/ChangeLog | 1 + apps/cogclock/metadata.json | 2 +- apps/cogclock/settings.js | 16 ++++++++-------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/cogclock/ChangeLog b/apps/cogclock/ChangeLog index 3158b6116..684b22642 100644 --- a/apps/cogclock/ChangeLog +++ b/apps/cogclock/ChangeLog @@ -1,2 +1,3 @@ 0.01: New clock 0.02: Use ClockFace library, add settings +0.03: Use ClockFace_menu.addItems \ No newline at end of file diff --git a/apps/cogclock/metadata.json b/apps/cogclock/metadata.json index 40733bcd1..29000b589 100644 --- a/apps/cogclock/metadata.json +++ b/apps/cogclock/metadata.json @@ -1,7 +1,7 @@ { "id": "cogclock", "name": "Cog Clock", - "version": "0.02", + "version": "0.03", "description": "A cross-shaped clock inside a cog", "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], diff --git a/apps/cogclock/settings.js b/apps/cogclock/settings.js index 4eadc32c2..a6627d6d2 100644 --- a/apps/cogclock/settings.js +++ b/apps/cogclock/settings.js @@ -1,19 +1,19 @@ (function(back) { let s = require('Storage').readJSON("cogclock.settings.json", true) || {}; - function saver(key) { - return value => { - s[key] = value; - require('Storage').writeJSON("cogclock.settings.json", s); - } + function save(key, value) { + s[key] = value; + require("Storage").writeJSON("cogclock.settings.json", s); } - const menu = { + let menu = { "": {"title": /*LANG*/"Cog Clock"}, /*LANG*/"< Back": back, - /*LANG*/"Show date": require("ClockFace_menu").showDate(s.showDate, saver('showDate')), - /*LANG*/"Load widgets": require("ClockFace_menu").loadWidgets(s.loadWidgets, saver('loadWidgets')), }; + require("ClockFace_menu").addItems(menu, save, { + showDate: s.showDate, + loadWidgets: s.loadWidgets, + }); E.showMenu(menu); }); From aded08293fca595dacfaac7705be0228a46e438b Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:29:18 +0200 Subject: [PATCH 103/183] ClockFace_menu: remove old options exports --- modules/ClockFace_menu.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/modules/ClockFace_menu.js b/modules/ClockFace_menu.js index 9fe61cac6..62a3a9576 100644 --- a/modules/ClockFace_menu.js +++ b/modules/ClockFace_menu.js @@ -23,15 +23,4 @@ exports.addItems = function(menu, callback, items) { }; } }); -}; - -// legacy boolean options -exports.showDate = -exports.loadWidgets = - function(value, callback) { - if (value === undefined) value = true; - return { - value: !!value, - onchange: v=>callback(v), - }; - }; +}; \ No newline at end of file From 5ffb6117e600f593a6764fa4ff21bad0368f8012 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:43:00 +0200 Subject: [PATCH 104/183] ClockFace_menu: addSettingsFile with included Storage code --- modules/ClockFace.md | 13 +++++++++++++ modules/ClockFace_menu.js | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/modules/ClockFace.md b/modules/ClockFace.md index e5ab71179..b2332c805 100644 --- a/modules/ClockFace.md +++ b/modules/ClockFace.md @@ -199,4 +199,17 @@ require("ClockFace_menu").addItems(menu, save, { }); E.showMenu(menu); +``` + +Or even simpler, if you just want to use a basic settings file: +```js +let menu = { + "": {"title": /*LANG*/" Settings"}, + /*LANG*/"< Back": back, +}; +require("ClockFace_menu").addSettingsFile(menu, ".settings.json", [ + "showDate", "loadWidgets" +]); +E.showMenu(menu); + ``` \ No newline at end of file diff --git a/modules/ClockFace_menu.js b/modules/ClockFace_menu.js index 62a3a9576..f2267d9ca 100644 --- a/modules/ClockFace_menu.js +++ b/modules/ClockFace_menu.js @@ -23,4 +23,26 @@ exports.addItems = function(menu, callback, items) { }; } }); +}; + +/** + * Create a basic settings menu for app, reading/writing to settings file + * + * @param {object} menu Menu to add settings to + * @param {string} settingsFile File to read/write settings to/from + * @param {string[]} items List of settings to add + */ +exports.addSettingsFile = function(menu, settingsFile, items) { + let s = require("Storage").readJSON(settingsFile, true) || {}; + + function save(key, value) { + s[key] = value; + require("Storage").writeJSON(settingsFile, s); + } + + let toAdd = {}; + items.forEach(function(key) { + toAdd[key] = s[key]; + }); + exports.addItems(menu, save, toAdd); }; \ No newline at end of file From d09f85413b0f0d13307ed0fdf15039fb1f10c76e Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:44:54 +0200 Subject: [PATCH 105/183] cogclock: Use ClockFace_menu.addSettingsFile --- apps/cogclock/ChangeLog | 2 +- apps/cogclock/settings.js | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/apps/cogclock/ChangeLog b/apps/cogclock/ChangeLog index 684b22642..f4bfe77a5 100644 --- a/apps/cogclock/ChangeLog +++ b/apps/cogclock/ChangeLog @@ -1,3 +1,3 @@ 0.01: New clock 0.02: Use ClockFace library, add settings -0.03: Use ClockFace_menu.addItems \ No newline at end of file +0.03: Use ClockFace_menu.addSettingsFile diff --git a/apps/cogclock/settings.js b/apps/cogclock/settings.js index a6627d6d2..a91b033d0 100644 --- a/apps/cogclock/settings.js +++ b/apps/cogclock/settings.js @@ -1,19 +1,10 @@ (function(back) { - let s = require('Storage').readJSON("cogclock.settings.json", true) || {}; - - function save(key, value) { - s[key] = value; - require("Storage").writeJSON("cogclock.settings.json", s); - } - let menu = { "": {"title": /*LANG*/"Cog Clock"}, /*LANG*/"< Back": back, }; - require("ClockFace_menu").addItems(menu, save, { - showDate: s.showDate, - loadWidgets: s.loadWidgets, - }); - + require("ClockFace_menu").addSettingsFile(menu, "cogclock.settings.json", [ + "showDate", "loadWidgets" + ]); E.showMenu(menu); }); From 48164384ebdec91e742f6d281004d6ac4b0909b8 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Thu, 2 Jun 2022 17:54:16 +0200 Subject: [PATCH 106/183] [Alarms & Timers] Add seconds to timers --- apps/alarm/ChangeLog | 1 + apps/alarm/app.js | 10 +++++++++- apps/alarm/metadata.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog index 00187fa7c..1be0dcdd5 100644 --- a/apps/alarm/ChangeLog +++ b/apps/alarm/ChangeLog @@ -30,3 +30,4 @@ 0.28: Fix bug with alarms not firing when configured to fire only once 0.29: Fix wrong 'dow' handling in new timer if first day of week is Monday 0.30: Fix "Enable All" +0.31: Add seconds to timers diff --git a/apps/alarm/app.js b/apps/alarm/app.js index 2aff43de2..f39efc5fc 100644 --- a/apps/alarm/app.js +++ b/apps/alarm/app.js @@ -268,11 +268,19 @@ function showEditTimerMenu(selectedTimer, timerIndex) { wrap: true, onchange: v => time.m = v }, + /*LANG*/"Seconds": { + value: time.s, + min: 0, + max: 59, + step: 1, + wrap: true, + onchange: v => time.s = v + }, /*LANG*/"Enabled": { value: timer.on, onchange: v => timer.on = v }, - /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v), + /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v) }; if (!isNew) { diff --git a/apps/alarm/metadata.json b/apps/alarm/metadata.json index 3c17ee177..54472a12c 100644 --- a/apps/alarm/metadata.json +++ b/apps/alarm/metadata.json @@ -2,7 +2,7 @@ "id": "alarm", "name": "Alarms & Timers", "shortName": "Alarms", - "version": "0.30", + "version": "0.31", "description": "Set alarms and timers on your Bangle", "icon": "app.png", "tags": "tool,alarm,widget", From 2247ee07bbfc5acfc4a1a7d1f174a94d28dc785e Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Tue, 7 Jun 2022 21:56:14 +0200 Subject: [PATCH 107/183] [Alarms & Timers] Restore "Cancel" in timer view Oooops --- apps/alarm/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/alarm/app.js b/apps/alarm/app.js index f39efc5fc..0a7bb8f24 100644 --- a/apps/alarm/app.js +++ b/apps/alarm/app.js @@ -280,7 +280,8 @@ function showEditTimerMenu(selectedTimer, timerIndex) { value: timer.on, onchange: v => timer.on = v }, - /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v) + /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v), + /*LANG*/"Cancel": () => showMainMenu() }; if (!isNew) { From 6e1aeed55b1bbe5bb3499db901384008bfd27ab4 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Tue, 7 Jun 2022 22:34:21 +0100 Subject: [PATCH 108/183] I was right the first time with drawTimeout --- apps/bigdclock/ChangeLog | 1 + apps/bigdclock/bigdclock.app.js | 1 + apps/bigdclock/metadata.json | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index 2b6fcc7cb..5407fee95 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial version 0.02: setTimeout bug fix; no leading zero on date; lightmode; 12 hour format; cleanup 0.03: Internationalisation; bug fix - battery icon responds promptly to charging state +0.04: bug fix diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index 7b26d4f17..014aa92af 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -16,6 +16,7 @@ var drawTimeout; function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function () { + drawTimeout = undefined; draw(); }, 60300 - (Date.now() % 60000)); // We aim for 300ms into the next minute to ensure we make it! } diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index e80dd9a04..769b05fcf 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -1,7 +1,7 @@ { "id": "bigdclock", "name": "Big digit clock containing just the essentials", "shortName":"Big digit clk", - "version":"0.03", + "version":"0.04", "description": "A clock containing just the essentials, made as easy to read as possible for those of us that need glasses. It contains the time, the day-of-week, the day-of-month, and the current battery state-of-charge.", "icon": "bigdclock.png", "type": "clock", From 7222465e508b0b26f0df6a1a74b1f285fc273729 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Tue, 7 Jun 2022 21:20:02 +0200 Subject: [PATCH 109/183] [Nifty-A Clock] Use ClockFace library --- apps/ffcniftya/app.js | 118 +++++++++++++----------------------------- 1 file changed, 36 insertions(+), 82 deletions(-) diff --git a/apps/ffcniftya/app.js b/apps/ffcniftya/app.js index 4000a1578..24d26622c 100644 --- a/apps/ffcniftya/app.js +++ b/apps/ffcniftya/app.js @@ -1,22 +1,3 @@ -const locale = require("locale"); -const is12Hour = Object.assign({ "12hour": false }, require("Storage").readJSON("setting.json", true))["12hour"]; -const showWeekNum = Object.assign({ showWeekNum: true }, require('Storage').readJSON("ffcniftya.json", true))["showWeekNum"]; - -/* Clock *********************************************/ -const scale = g.getWidth() / 176; - -const widget = 24; - -const viewport = { - width: g.getWidth(), - height: g.getHeight(), -} - -const center = { - x: viewport.width / 2, - y: Math.round(((viewport.height - widget) / 2) + widget), -} - // copied from: https://gist.github.com/IamSilviu/5899269#gistcomment-3035480 function ISO8601_week_no(date) { var tdt = new Date(date.valueOf()); @@ -30,77 +11,50 @@ function ISO8601_week_no(date) { return 1 + Math.ceil((firstThursday - tdt) / 604800000); } -function d02(value) { - return ('0' + value).substr(-2); +function format(value) { + return ("0" + value).substr(-2); } -function draw() { - g.reset(); - g.clearRect(0, widget, viewport.width, viewport.height); - const now = new Date(); +const ClockFace = require("ClockFace"); +const clock = new ClockFace({ + init: function () { + const appRect = Bangle.appRect; - const hour = d02(now.getHours() - (is12Hour && now.getHours() > 12 ? 12 : 0)); - const minutes = d02(now.getMinutes()); - const day = d02(now.getDate()); - const month = d02(now.getMonth() + 1); - const year = now.getFullYear(now); - const weekNum = d02(ISO8601_week_no(now)); - const monthName = locale.month(now, 3); - const dayName = locale.dow(now, 3); + this.viewport = { + width: appRect.w, + height: appRect.h + }; - const centerTimeScaleX = center.x + 32 * scale; - g.setFontAlign(1, 0).setFont("Vector", 90 * scale); - g.drawString(hour, centerTimeScaleX, center.y - 31 * scale); - g.drawString(minutes, centerTimeScaleX, center.y + 46 * scale); + this.center = { + x: this.viewport.width / 2, + y: Math.round((this.viewport.height / 2) + appRect.y) + }; - g.fillRect(center.x + 30 * scale, center.y - 72 * scale, center.x + 32 * scale, center.y + 74 * scale); + this.scale = g.getWidth() / this.viewport.width; + this.centerTimeScaleX = this.center.x + 32 * this.scale; + this.centerDatesScaleX = this.center.x + 40 * this.scale; - const centerDatesScaleX = center.x + 40 * scale; - g.setFontAlign(-1, 0).setFont("Vector", 16 * scale); - g.drawString(year, centerDatesScaleX, center.y - 62 * scale); - g.drawString(month, centerDatesScaleX, center.y - 44 * scale); - g.drawString(day, centerDatesScaleX, center.y - 26 * scale); - if (showWeekNum) g.drawString(weekNum, centerDatesScaleX, center.y + 15 * scale); - g.drawString(monthName, centerDatesScaleX, center.y + 48 * scale); - g.drawString(dayName, centerDatesScaleX, center.y + 66 * scale); -} + this.showWeekNum = Object.assign({ showWeekNum: true }, require("Storage").readJSON("ffcniftya.json", true))["showWeekNum"]; + }, + draw: function (date) { + const hour = date.getHours() - (this.is12Hour && date.getHours() > 12 ? 12 : 0); + const month = date.getMonth() + 1; + const monthName = require("date_utils").month(month, 1); + const dayName = require("date_utils").dow(date.getDay(), 1); + g.setFontAlign(1, 0).setFont("Vector", 90 * this.scale); + g.drawString(format(hour), this.centerTimeScaleX, this.center.y - 31 * this.scale); + g.drawString(format(date.getMinutes()), this.centerTimeScaleX, this.center.y + 46 * this.scale); -/* Minute Ticker *************************************/ + g.fillRect(this.center.x + 30 * this.scale, this.center.y - 72 * this.scale, this.center.x + 32 * this.scale, this.center.y + 74 * this.scale); -let tickTimer; - -function clearTickTimer() { - if (tickTimer) { - clearTimeout(tickTimer); - tickTimer = undefined; - } -} - -function queueNextTick() { - clearTickTimer(); - tickTimer = setTimeout(tick, 60000 - (Date.now() % 60000)); -} - -function tick() { - draw(); - queueNextTick(); -} - -/* Init **********************************************/ - -// Clear the screen once, at startup -g.clear(); -tick(); - -Bangle.on('lcdPower', (on) => { - if (on) { - tick(); - } else { - clearTickTimer(); + g.setFontAlign(-1, 0).setFont("Vector", 16 * this.scale); + g.drawString(date.getFullYear(date), this.centerDatesScaleX, this.center.y - 62 * this.scale); + g.drawString(format(month), this.centerDatesScaleX, this.center.y - 44 * this.scale); + g.drawString(format(date.getDate()), this.centerDatesScaleX, this.center.y - 26 * this.scale); + if (this.showWeekNum) g.drawString(format(ISO8601_week_no(date)), this.centerDatesScaleX, this.center.y + 15 * this.scale); + g.drawString(monthName, this.centerDatesScaleX, this.center.y + 48 * this.scale); + g.drawString(dayName, this.centerDatesScaleX, this.center.y + 66 * this.scale); } }); - -Bangle.setUI("clock"); -Bangle.loadWidgets(); -Bangle.drawWidgets(); +clock.start(); \ No newline at end of file From 955bff9e520f1bda917dd153c20cc1df8ef98012 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Tue, 7 Jun 2022 21:20:22 +0200 Subject: [PATCH 110/183] [Nifty-A Clock] Update metadata and changelog --- apps/ffcniftya/ChangeLog | 2 ++ apps/ffcniftya/metadata.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/ffcniftya/ChangeLog b/apps/ffcniftya/ChangeLog index cb520193b..6d2f50119 100644 --- a/apps/ffcniftya/ChangeLog +++ b/apps/ffcniftya/ChangeLog @@ -2,3 +2,5 @@ 0.02: Shows the current week number (ISO8601), can be disabled via settings 0.03: Call setUI before loading widgets Improve settings page +0.04: Use ClockFace library + diff --git a/apps/ffcniftya/metadata.json b/apps/ffcniftya/metadata.json index 91b426cd0..015c56119 100644 --- a/apps/ffcniftya/metadata.json +++ b/apps/ffcniftya/metadata.json @@ -1,7 +1,7 @@ { "id": "ffcniftya", "name": "Nifty-A Clock", - "version": "0.03", + "version": "0.04", "description": "A nifty clock with time and date", "icon": "app.png", "screenshots": [{"url":"screenshot_nifty.png"}], From 685f3710f312f097976cf241344dc179a1546b5d Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Wed, 8 Jun 2022 17:45:39 +0200 Subject: [PATCH 111/183] Starting forceCalendarSync from Gadgetbridge --- apps/android/boot.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/apps/android/boot.js b/apps/android/boot.js index a548089cb..9cdc019a6 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -112,6 +112,12 @@ if (!cal || !Array.isArray(cal)) return; cal = cal.filter(e=>e.id!=event.id); require("Storage").writeJSON("android.calendar.json", cal); + }, + //triggered by GB, send all ids + "force_calendar_sync_start" : function() { + var cal = require("Storage").readJSON("android.calendar.json",true); + if (!cal || !Array.isArray(cal)) cal = []; + gbSend({t:"force_calendar_sync", ids: cal.map(e=>e.id)}); } }; var h = HANDLERS[event.t]; @@ -125,17 +131,6 @@ if (!settings.keep) NRF.on("disconnect", () => require("messages").clearAll()); // remove all messages on disconnect setInterval(sendBattery, 10*60*1000); - // Fix calendar every 2 days (can be done manually too) - function forceCalendarSync() { - if(NRF.getSecurityStatus().connected) { - var cal = require("Storage").readJSON("android.calendar.json",true); - if (!cal || !Array.isArray(cal)) cal = []; - gbSend({t:"force_calendar_sync", ids: cal.map(e=>e.id)}); - setTimeout(forceCalendarSync, 2*24*60*60*1000); - } else - NRF.once("connect", () => setTimeout(forceCalendarSync, 4000)); - } - setTimeout(forceCalendarSync, 2*24*60*60*1000); //schedule the first // Health tracking Bangle.on('health', health=>{ gbSend({ t: "act", stp: health.steps, hrm: health.bpm }); From ac084fa386a8ae135d18ebacae806f917299f440 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 8 Jun 2022 18:13:23 +0200 Subject: [PATCH 112/183] Fix regression in rgb introduced by semistandard --fix --- apps/rgb/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/rgb/app.js b/apps/rgb/app.js index aa18d93ae..373ee6f54 100644 --- a/apps/rgb/app.js +++ b/apps/rgb/app.js @@ -1,4 +1,5 @@ const rgb = [0, 0, 0]; +const hex = '0123456789ABCDEF'; const w = g.getWidth(); const h = g.getHeight(); function drawToggle (value, x, y, options) { From b793e7d6e460fb8e1ff232208220a886779079c5 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Wed, 8 Jun 2022 21:03:39 +0200 Subject: [PATCH 113/183] [Nifty-A Clock] Read settings file via ClockFace --- apps/ffcniftya/app.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/ffcniftya/app.js b/apps/ffcniftya/app.js index 24d26622c..2c1a54f6e 100644 --- a/apps/ffcniftya/app.js +++ b/apps/ffcniftya/app.js @@ -33,8 +33,6 @@ const clock = new ClockFace({ this.scale = g.getWidth() / this.viewport.width; this.centerTimeScaleX = this.center.x + 32 * this.scale; this.centerDatesScaleX = this.center.x + 40 * this.scale; - - this.showWeekNum = Object.assign({ showWeekNum: true }, require("Storage").readJSON("ffcniftya.json", true))["showWeekNum"]; }, draw: function (date) { const hour = date.getHours() - (this.is12Hour && date.getHours() > 12 ? 12 : 0); @@ -55,6 +53,7 @@ const clock = new ClockFace({ if (this.showWeekNum) g.drawString(format(ISO8601_week_no(date)), this.centerDatesScaleX, this.center.y + 15 * this.scale); g.drawString(monthName, this.centerDatesScaleX, this.center.y + 48 * this.scale); g.drawString(dayName, this.centerDatesScaleX, this.center.y + 66 * this.scale); - } + }, + settingsFile: "ffcniftya.json" }); clock.start(); \ No newline at end of file From d9a0884c5a06ef5461d05f60377c9cef44b114cc Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Wed, 8 Jun 2022 22:50:19 +0200 Subject: [PATCH 114/183] [Nifty-B Clock] Use ClockFace library --- apps/ffcniftyb/app.js | 160 +++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 96 deletions(-) diff --git a/apps/ffcniftyb/app.js b/apps/ffcniftyb/app.js index 65c74dbd7..540924fa5 100644 --- a/apps/ffcniftyb/app.js +++ b/apps/ffcniftyb/app.js @@ -1,20 +1,10 @@ -const is12Hour = Object.assign({ "12hour": false }, require("Storage").readJSON("setting.json", true))["12hour"]; -const color = Object.assign({ color: 63488 }, require("Storage").readJSON("ffcniftyb.json", true)).color; // Default to RED +var scale; +var screen; +var center; +var buf; +var img; -/* Clock *********************************************/ -const scale = g.getWidth() / 176; - -const screen = { - width: g.getWidth(), - height: g.getHeight() - 24, -}; - -const center = { - x: screen.width / 2, - y: screen.height / 2, -}; - -function d02(value) { +function format(value) { return ("0" + value).substr(-2); } @@ -22,91 +12,69 @@ function renderEllipse(g) { g.fillEllipse(center.x - 5 * scale, center.y - 70 * scale, center.x + 160 * scale, center.y + 90 * scale); } -function renderText(g) { - const now = new Date(); +function renderText(g, date) { + const hour = date.getHours() - (this.is12Hour && date.getHours() > 12 ? 12 : 0); + const month = date.getMonth() + 1; - const hour = d02(now.getHours() - (is12Hour && now.getHours() > 12 ? 12 : 0)); - const minutes = d02(now.getMinutes()); - const day = d02(now.getDate()); - const month = d02(now.getMonth() + 1); - const year = now.getFullYear(); - - const month2 = require("locale").month(now, 3); - const day2 = require("locale").dow(now, 3); + const monthName = require("date_utils").month(month, 1); + const dayName = require("date_utils").dow(date.getDay(), 1); g.setFontAlign(1, 0).setFont("Vector", 90 * scale); - g.drawString(hour, center.x + 32 * scale, center.y - 31 * scale); - g.drawString(minutes, center.x + 32 * scale, center.y + 46 * scale); + g.drawString(format(hour), center.x + 32 * scale, center.y - 31 * scale); + g.drawString(format(date.getMinutes()), center.x + 32 * scale, center.y + 46 * scale); g.setFontAlign(1, 0).setFont("Vector", 16 * scale); - g.drawString(year, center.x + 80 * scale, center.y - 42 * scale); - g.drawString(month, center.x + 80 * scale, center.y - 26 * scale); - g.drawString(day, center.x + 80 * scale, center.y - 10 * scale); - g.drawString(month2, center.x + 80 * scale, center.y + 44 * scale); - g.drawString(day2, center.x + 80 * scale, center.y + 60 * scale); + g.drawString(date.getFullYear(), center.x + 80 * scale, center.y - 42 * scale); + g.drawString(format(month), center.x + 80 * scale, center.y - 26 * scale); + g.drawString(format(date.getDate()), center.x + 80 * scale, center.y - 10 * scale); + g.drawString(monthName, center.x + 80 * scale, center.y + 44 * scale); + g.drawString(dayName, center.x + 80 * scale, center.y + 60 * scale); } -const buf = Graphics.createArrayBuffer(screen.width, screen.height, 1, { - msb: true +const ClockFace = require("ClockFace"); +const clock = new ClockFace({ + init: function () { + const appRect = Bangle.appRect; + + screen = { + width: appRect.w, + height: appRect.h + }; + + center = { + x: screen.width / 2, + y: screen.height / 2 + }; + + buf = Graphics.createArrayBuffer(screen.width, screen.height, 1, { msb: true }); + + scale = g.getWidth() / screen.width; + + img = { + width: screen.width, + height: screen.height, + transparent: 0, + bpp: 1, + buffer: buf.buffer + }; + + // default to RED (see settings.js) + // don't use || to default because 0 is a valid color + this.color = this.color === undefined ? 63488 : this.color; + }, + draw: function (date) { + // render outside text with ellipse + buf.clear(); + renderText(buf.setColor(1), date); + renderEllipse(buf.setColor(0)); + g.setColor(this.color).drawImage(img, 0, 24); + + // render ellipse with inside text + buf.clear(); + renderEllipse(buf.setColor(1)); + renderText(buf.setColor(0), date); + g.setColor(this.color).drawImage(img, 0, 24); + }, + settingsFile: "ffcniftyb.json" }); - -function draw() { - - const img = { - width: screen.width, - height: screen.height, - transparent: 0, - bpp: 1, - buffer: buf.buffer - }; - - // cleat screen area - g.clearRect(0, 24, g.getWidth(), g.getHeight()); - - // render outside text with ellipse - buf.clear(); - renderText(buf.setColor(1)); - renderEllipse(buf.setColor(0)); - g.setColor(color).drawImage(img, 0, 24); - - // render ellipse with inside text - buf.clear(); - renderEllipse(buf.setColor(1)); - renderText(buf.setColor(0)); - g.setColor(color).drawImage(img, 0, 24); -} - - -/* Minute Ticker *************************************/ - -let ticker; - -function stopTick() { - if (ticker) { - clearTimeout(ticker); - ticker = undefined; - } -} - -function startTick(run) { - stopTick(); - run(); - ticker = setTimeout(() => startTick(run), 60000 - (Date.now() % 60000)); -} - -/* Init **********************************************/ - -g.clear(); -startTick(draw); - -Bangle.on("lcdPower", (on) => { - if (on) { - startTick(draw); - } else { - stopTick(); - } -}); - -Bangle.setUI("clock"); -Bangle.loadWidgets(); -Bangle.drawWidgets(); +clock.start(); \ No newline at end of file From db096ea2f829a3317d572c482d94f1196190eed4 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Wed, 8 Jun 2022 22:50:39 +0200 Subject: [PATCH 115/183] [Nifty-B Clock] Update metadata and changelog --- apps/ffcniftyb/ChangeLog | 1 + apps/ffcniftyb/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/ffcniftyb/ChangeLog b/apps/ffcniftyb/ChangeLog index 9fc7e3c5c..83b11eb78 100644 --- a/apps/ffcniftyb/ChangeLog +++ b/apps/ffcniftyb/ChangeLog @@ -3,3 +3,4 @@ 0.03: Call setUI before loading widgets Fix bug with black being unselectable Improve settings page +0.04: Use ClockFace library diff --git a/apps/ffcniftyb/metadata.json b/apps/ffcniftyb/metadata.json index 3d26c27ea..019ae6eb3 100644 --- a/apps/ffcniftyb/metadata.json +++ b/apps/ffcniftyb/metadata.json @@ -1,7 +1,7 @@ { "id": "ffcniftyb", "name": "Nifty-B Clock", - "version": "0.03", + "version": "0.04", "description": "A nifty clock (series B) with time, date and colour configuration", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], From d07580cc907d3bd7d3de221231ccf32936394d2d Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 9 Jun 2022 10:41:03 +0100 Subject: [PATCH 116/183] Add minified layout library, which should improve layout speed a lot. --- modules/Layout.js | 8 ++++++ modules/Layout.min.js | 14 ++++++++++ tests/Layout/bin/runtest.sh | 51 ++++++++++++++++++++++--------------- 3 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 modules/Layout.min.js diff --git a/modules/Layout.js b/modules/Layout.js index 19cfabe11..436b04592 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -2,6 +2,14 @@ // See Layout.md for documentation +/* Minify to 'Layout.min.js' by: + + * checking out: https://github.com/espruino/EspruinoDocs + * run: ../EspruinoDocs/bin/minify.js modules/Layout.js modules/Layout.min.js + +*/ + + function Layout(layout, options) { this._l = this.l = layout; // Do we have >1 physical buttons? diff --git a/modules/Layout.min.js b/modules/Layout.min.js new file mode 100644 index 000000000..7dd169eb9 --- /dev/null +++ b/modules/Layout.min.js @@ -0,0 +1,14 @@ +function p(b,k){function d(h){h.id&&(f[h.id]=h);h.type||(h.type="");h.c&&h.c.forEach(d)}this._l=this.l=b;this.physBtns=2==process.env.HWVERSION?1:3;this.options=k||{};this.lazy=this.options.lazy||!1;if(2!=process.env.HWVERSION){var a=[];function h(m){"btn"==m.type&&a.push(m);m.c&&m.c.forEach(h)}h(b);a.length&&(this.physBtns=0,this.buttons=a,this.selectedButton=-1)}if(this.options.btns)if(this.b=b=this.options.btns,this.physBtns>=b.length){let h=Math.floor(Bangle.appRect.h/ +this.physBtns);for(2b.length;)b.push({label:""});this._l.width=g.getWidth()-8;this._l={type:"h",filly:1,c:[this._l,{type:"v",pad:1,filly:1,c:b.map(m=>(m.type="txt",m.font="6x8",m.height=h,m.r=1,m))}]}}else this._l.width=g.getWidth()-32,this._l={type:"h",c:[this._l,{type:"v",c:b.map(h=>(h.type="btn",h.filly=1,h.width=32,h.r=1,h))}]},a&&a.push.apply(a,this._l.c[1].c);this.setUI();var f=this;d(this._l);this.updateNeeded=!0}function r(b, +k,d,a,f){var h=null==b.bgCol?f:g.toColor(b.bgCol);if(h!=f||"txt"==b.type||"btn"==b.type||"img"==b.type||"custom"==b.type){var m=b.c;delete b.c;var c="H"+E.CRC32(E.toJS(b));m&&(b.c=m);delete k[c]||((a[c]=[b.x,b.y,b.x+b.w-1,b.y+b.h-1]).bg=null==f?g.theme.bg:f,d&&(d.push(b),d=null))}if(b.c)for(var l of b.c)r(l,k,d,a,h)}p.prototype.setUI=function(){Bangle.setUI();if(this.buttons){Bangle.setUI({mode:"updown",back:this.options.back},k=>{var d=this.selectedButton,a=this.buttons.length;if(void 0===k&&this.buttons[d])return this.buttons[d].cb(); +this.buttons[d]&&(delete this.buttons[d].selected,this.render(this.buttons[d]));d=(d+a+k)%a;this.buttons[d]&&(this.buttons[d].selected=1,this.render(this.buttons[d]));this.selectedButton=d});var b=!0}this.options.back&&!b&&Bangle.setUI({mode:"custom",back:this.options.back});if(this.b){function k(d,a){.75=d.x&&a.y>=d.y&&a.x<=d.x+d.w&&a.y<=d.y+d.h&&(2==a.type&&d.cbl?d.cbl(a):d.cb&&d.cb(a));d.c&&d.c.forEach(f=>k(f,a))}Bangle.touchHandler=(d,a)=>k(this._l,a);Bangle.on("touch",Bangle.touchHandler)}};p.prototype.render=function(b){function k(c){"ram"; +g.reset();void 0!==c.col&&g.setColor(c.col);void 0!==c.bgCol&&g.setBgColor(c.bgCol).clearRect(c.x,c.y,c.x+c.w-1,c.y+c.h-1);d[c.type](c)}b||(b=this._l);this.updateNeeded&&this.update();var d={"":function(){},txt:function(c){if(c.wrap){g.setFont(c.font).setFontAlign(0,-1);var l=g.wrapString(c.label,c.w),e=c.y+(c.h-g.getFontHeight()*l.length>>1);l.forEach((n,q)=>g.drawString(n,c.x+(c.w>>1),e+g.getFontHeight()*q))}else g.setFont(c.font).setFontAlign(0,0,c.r).drawString(c.label,c.x+(c.w>>1),c.y+(c.h>> +1))},btn:function(c){var l=c.x+(0|c.pad),e=c.y+(0|c.pad),n=c.w-(c.pad<<1),q=c.h-(c.pad<<1);l=[l,e+4,l+4,e,l+n-5,e,l+n-1,e+4,l+n-1,e+q-5,l+n-5,e+q-1,l+4,e+q-1,l,e+q-5,l,e+4];e=c.selected?g.theme.bgH:g.theme.bg2;g.setColor(e).fillPoly(l).setColor(c.selected?g.theme.fgH:g.theme.fg2).drawPoly(l);void 0!==c.col&&g.setColor(c.col);c.src?g.setBgColor(e).drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)}):g.setFont(c.font||"6x8:2").setFontAlign(0, +0,c.r).drawString(c.label,c.x+c.w/2,c.y+c.h/2)},img:function(c){g.drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)})},custom:function(c){c.render(c)},h:function(c){c.c.forEach(k)},v:function(c){c.c.forEach(k)}};if(this.lazy){this.rects||(this.rects={});var a=this.rects.clone(),f=[];r(b,a,f,this.rects,null);for(var h in a)delete this.rects[h];b=Object.keys(a).map(c=>a[c]).reverse();for(var m of b)g.setBgColor(m.bg).clearRect.apply(g, +m);f.forEach(k)}else k(b)};p.prototype.forgetLazyState=function(){this.rects={}};p.prototype.layout=function(b){switch(b.type){case "h":var k=b.x+(0|b.pad),d=0,a=b.c&&b.c.reduce((e,n)=>e+(0|n.fillx),0);a||(k+=b.w-b._w>>1,a=1);var f=k;b.c.forEach(e=>{e.x=0|f;k+=e._w;d+=0|e.fillx;f=k+Math.floor(d*(b.w-b._w)/a);e.w=0|f-e.x;e.h=0|(e.filly?b.h-(b.pad<<1):e._h);e.y=0|b.y+(0|b.pad)+((1+(0|e.valign))*(b.h-(b.pad<<1)-e.h)>>1);e.c&&this.layout(e)});break;case "v":var h=b.y+(0|b.pad),m=0,c=b.c&&b.c.reduce((e, +n)=>e+(0|n.filly),0);c||(h+=b.h-b._h>>1,c=1);var l=h;b.c.forEach(e=>{e.y=0|l;h+=e._h;m+=0|e.filly;l=h+Math.floor(m*(b.h-b._h)/c);e.h=0|l-e.y;e.w=0|(e.fillx?b.w-(b.pad<<1):e._w);e.x=0|b.x+(0|b.pad)+((1+(0|e.halign))*(b.w-(b.pad<<1)-e.w)>>1);e.c&&this.layout(e)})}};p.prototype.debug=function(b,k){b||(b=this._l);k=k||1;g.setColor(k&1,k&2,k&4).drawRect(b.x+k-1,b.y+k-1,b.x+b.w-k,b.y+b.h-k);b.pad&&g.drawRect(b.x+b.pad-1,b.y+b.pad-1,b.x+b.w-b.pad,b.y+b.h-b.pad);k++;b.c&&b.c.forEach(d=>this.debug(d,k))}; +p.prototype.update=function(){function b(a){"ram";k[a.type](a);if(a.r&1){var f=a._w;a._w=a._h;a._h=f}a._w=0|Math.max(a._w+(a.pad<<1),0|a.width);a._h=0|Math.max(a._h+(a.pad<<1),0|a.height)}delete this.updateNeeded;var k={txt:function(a){a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));if(a.wrap)a._h=a._w=0;else{var f=g.setFont(a.font).stringMetrics(a.label);a._w=f.width;a._h=f.height}},btn:function(a){a.font&&a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()* +a.font.slice(0,-1)/100));var f=a.src?g.imageMetrics("function"==typeof a.src?a.src():a.src):g.setFont(a.font||"6x8:2").stringMetrics(a.label);a._h=16+f.height;a._w=20+f.width},img:function(a){var f=g.imageMetrics("function"==typeof a.src?a.src():a.src),h=a.scale||1;a._w=f.width*h;a._h=f.height*h},"":function(a){a._w=0;a._h=0},custom:function(a){a._w=0;a._h=0},h:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>Math.max(f,h._h),0);a._w=a.c.reduce((f,h)=>f+h._w,0);null==a.fillx&&a.c.some(f=>f.fillx)&& +(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)},v:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>f+h._h,0);a._w=a.c.reduce((f,h)=>Math.max(f,h._w),0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)}},d=this._l;b(d);d.fillx||d.filly?(d.w=Bangle.appRect.w,d.h=Bangle.appRect.h,d.x=Bangle.appRect.x,d.y=Bangle.appRect.y):(d.w=d._w,d.h=d._h,d.x=Bangle.appRect.w-d.w>>1,d.y=Bangle.appRect.y+(Bangle.appRect.h-d.h>>1));this.layout(d)};p.prototype.clear= +function(b){b||(b=this._l);g.reset();void 0!==b.bgCol&&g.setBgColor(b.bgCol);g.clearRect(b.x,b.y,b.x+b.w-1,b.y+b.h-1)};exports=p \ No newline at end of file diff --git a/tests/Layout/bin/runtest.sh b/tests/Layout/bin/runtest.sh index e06dec86b..9bac72283 100755 --- a/tests/Layout/bin/runtest.sh +++ b/tests/Layout/bin/runtest.sh @@ -18,24 +18,35 @@ SRCJS=$1 SRCBMP=$SRCDIR/`basename $SRCJS .js`.bmp echo "TEST $SRCJS ($SRCBMP)" -cat ../../modules/Layout.js > $TESTJS -echo 'Bangle = { setUI : function(){}, appRect:{x:0,y:0,w:176,h:176,x2:175,y2:175} };BTN1=0;process.env = process.env;process.env.HWVERSION=2;' >> $TESTJS -echo 'g = Graphics.createArrayBuffer(176,176,4);' >> $TESTJS -cat $SRCJS >> $TESTJS || exit 1 -echo 'layout.render()' >> $TESTJS -#echo 'layout.debug()' >> $TESTJS -echo 'require("fs").writeFileSync("'$TESTBMP'",g.asBMP())' >> $TESTJS +run_test () { + LAYOUTFILE=$1 + echo 'exports = {};' > $TESTJS + cat $LAYOUTFILE >> $TESTJS + echo ';' >> $TESTJS + echo 'Layout = exports;' >> $TESTJS + echo 'Bangle = { setUI : function(){}, appRect:{x:0,y:0,w:176,h:176,x2:175,y2:175} };BTN1=0;process.env = process.env;process.env.HWVERSION=2;' >> $TESTJS + echo 'g = Graphics.createArrayBuffer(176,176,4);' >> $TESTJS + cat $SRCJS >> $TESTJS || exit 1 + echo 'layout.render()' >> $TESTJS + #echo 'layout.debug()' >> $TESTJS + echo 'require("fs").writeFileSync("'$TESTBMP'",g.asBMP())' >> $TESTJS + echo ============================================= + echo TESTING $LAYOUTFILE $SRCJS + bin/espruino $TESTJS || exit 1 + if ! cmp $TESTBMP $SRCBMP >/dev/null 2>&1 + then + echo ============================================= + echo $LAYOUTFILE + echo $TESTBMP $SRCBMP differ + echo ============================================== + convert "+append" $TESTBMP $SRCBMP testresult.bmp + display testresult.bmp + exit 1 + else + echo Files are the same + exit 0 + fi +} -bin/espruino $TESTJS || exit 1 -if ! cmp $TESTBMP $SRCBMP >/dev/null 2>&1 -then - echo ============================================= - echo $TESTBMP $SRCBMP differ - echo ============================================== - convert "+append" $TESTBMP $SRCBMP testresult.bmp - display testresult.bmp - exit 1 -else - echo Files are the same - exit 0 -fi +run_test ../../modules/Layout.js +run_test ../../modules/Layout.min.js From e1cc59ec4f6a969554ccfa69c63c9cdad33b33a6 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 9 Jun 2022 17:06:52 +0100 Subject: [PATCH 117/183] bootloader CRC --- apps/fwupdate/custom.html | 1 + bin/firmwaremaker_c.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/fwupdate/custom.html b/apps/fwupdate/custom.html index 0321e46bc..3f8f50b3f 100644 --- a/apps/fwupdate/custom.html +++ b/apps/fwupdate/custom.html @@ -82,6 +82,7 @@ function onInit(device) { if (crc==46757280) version = "2v11.58"; if (crc==3508163280 || crc==1418074094) version = "2v12"; if (crc==4056371285) version = "2v13"; + if (crc==1038322422) version = "2v14"; if (!ok) { version += `(⚠ update required)`; } diff --git a/bin/firmwaremaker_c.js b/bin/firmwaremaker_c.js index 7940e551d..fd8072e06 100755 --- a/bin/firmwaremaker_c.js +++ b/bin/firmwaremaker_c.js @@ -1,4 +1,4 @@ -#!/usr/bin/nodejs +#!/usr/bin/node /* Mashes together a bunch of different apps into a big binary blob. We then store this *inside* the Bangle.js firmware and can use it From 53cbb2bb328ce766a94af11438a8393ddb2750b4 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Fri, 10 Jun 2022 05:14:22 +0100 Subject: [PATCH 118/183] Proper fix for the race condition --- apps/bigdclock/ChangeLog | 1 + apps/bigdclock/bigdclock.app.js | 7 +++---- apps/bigdclock/metadata.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index 5407fee95..09cc978fb 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -2,3 +2,4 @@ 0.02: setTimeout bug fix; no leading zero on date; lightmode; 12 hour format; cleanup 0.03: Internationalisation; bug fix - battery icon responds promptly to charging state 0.04: bug fix +0.05: proper fix for the race condition in queueDraw() diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index 014aa92af..c013c6188 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -12,13 +12,12 @@ Graphics.prototype.setFontOpenSans = function(scale) { var drawTimeout; -// schedule a draw for the next minute -function queueDraw() { +function queueDraw(millis_now) { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function () { drawTimeout = undefined; draw(); - }, 60300 - (Date.now() % 60000)); // We aim for 300ms into the next minute to ensure we make it! + }, 60000 - (millis_now % 60000)); } function draw() { @@ -70,7 +69,7 @@ function draw() { // widget redraw Bangle.drawWidgets(); - queueDraw(); + queueDraw(date.getTime()); } Bangle.on('lcdPower', on => { diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index 769b05fcf..7359bcf20 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -1,7 +1,7 @@ { "id": "bigdclock", "name": "Big digit clock containing just the essentials", "shortName":"Big digit clk", - "version":"0.04", + "version":"0.05", "description": "A clock containing just the essentials, made as easy to read as possible for those of us that need glasses. It contains the time, the day-of-week, the day-of-month, and the current battery state-of-charge.", "icon": "bigdclock.png", "type": "clock", From 0cc0a40356577ffa232526f23b147de9816bc3e0 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 10 Jun 2022 09:19:53 +0100 Subject: [PATCH 119/183] fix layout minification issue --- modules/Layout.js | 8 ++++---- modules/Layout.min.js | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/Layout.js b/modules/Layout.js index 436b04592..fd5809a93 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -6,9 +6,9 @@ * checking out: https://github.com/espruino/EspruinoDocs * run: ../EspruinoDocs/bin/minify.js modules/Layout.js modules/Layout.min.js - -*/ - + +*/ + function Layout(layout, options) { this._l = this.l = layout; @@ -79,7 +79,7 @@ function Layout(layout, options) { Layout.prototype.setUI = function() { Bangle.setUI(); // remove all existing input handlers - var uiSet; + let uiSet; if (this.buttons) { // multiple buttons so we'll jus use back/next/select Bangle.setUI({mode:"updown", back:this.options.back}, dir=>{ diff --git a/modules/Layout.min.js b/modules/Layout.min.js index 7dd169eb9..4523c547c 100644 --- a/modules/Layout.min.js +++ b/modules/Layout.min.js @@ -1,14 +1,14 @@ function p(b,k){function d(h){h.id&&(f[h.id]=h);h.type||(h.type="");h.c&&h.c.forEach(d)}this._l=this.l=b;this.physBtns=2==process.env.HWVERSION?1:3;this.options=k||{};this.lazy=this.options.lazy||!1;if(2!=process.env.HWVERSION){var a=[];function h(m){"btn"==m.type&&a.push(m);m.c&&m.c.forEach(h)}h(b);a.length&&(this.physBtns=0,this.buttons=a,this.selectedButton=-1)}if(this.options.btns)if(this.b=b=this.options.btns,this.physBtns>=b.length){let h=Math.floor(Bangle.appRect.h/ this.physBtns);for(2b.length;)b.push({label:""});this._l.width=g.getWidth()-8;this._l={type:"h",filly:1,c:[this._l,{type:"v",pad:1,filly:1,c:b.map(m=>(m.type="txt",m.font="6x8",m.height=h,m.r=1,m))}]}}else this._l.width=g.getWidth()-32,this._l={type:"h",c:[this._l,{type:"v",c:b.map(h=>(h.type="btn",h.filly=1,h.width=32,h.r=1,h))}]},a&&a.push.apply(a,this._l.c[1].c);this.setUI();var f=this;d(this._l);this.updateNeeded=!0}function r(b, -k,d,a,f){var h=null==b.bgCol?f:g.toColor(b.bgCol);if(h!=f||"txt"==b.type||"btn"==b.type||"img"==b.type||"custom"==b.type){var m=b.c;delete b.c;var c="H"+E.CRC32(E.toJS(b));m&&(b.c=m);delete k[c]||((a[c]=[b.x,b.y,b.x+b.w-1,b.y+b.h-1]).bg=null==f?g.theme.bg:f,d&&(d.push(b),d=null))}if(b.c)for(var l of b.c)r(l,k,d,a,h)}p.prototype.setUI=function(){Bangle.setUI();if(this.buttons){Bangle.setUI({mode:"updown",back:this.options.back},k=>{var d=this.selectedButton,a=this.buttons.length;if(void 0===k&&this.buttons[d])return this.buttons[d].cb(); -this.buttons[d]&&(delete this.buttons[d].selected,this.render(this.buttons[d]));d=(d+a+k)%a;this.buttons[d]&&(this.buttons[d].selected=1,this.render(this.buttons[d]));this.selectedButton=d});var b=!0}this.options.back&&!b&&Bangle.setUI({mode:"custom",back:this.options.back});if(this.b){function k(d,a){.75=d.x&&a.y>=d.y&&a.x<=d.x+d.w&&a.y<=d.y+d.h&&(2==a.type&&d.cbl?d.cbl(a):d.cb&&d.cb(a));d.c&&d.c.forEach(f=>k(f,a))}Bangle.touchHandler=(d,a)=>k(this._l,a);Bangle.on("touch",Bangle.touchHandler)}};p.prototype.render=function(b){function k(c){"ram"; -g.reset();void 0!==c.col&&g.setColor(c.col);void 0!==c.bgCol&&g.setBgColor(c.bgCol).clearRect(c.x,c.y,c.x+c.w-1,c.y+c.h-1);d[c.type](c)}b||(b=this._l);this.updateNeeded&&this.update();var d={"":function(){},txt:function(c){if(c.wrap){g.setFont(c.font).setFontAlign(0,-1);var l=g.wrapString(c.label,c.w),e=c.y+(c.h-g.getFontHeight()*l.length>>1);l.forEach((n,q)=>g.drawString(n,c.x+(c.w>>1),e+g.getFontHeight()*q))}else g.setFont(c.font).setFontAlign(0,0,c.r).drawString(c.label,c.x+(c.w>>1),c.y+(c.h>> -1))},btn:function(c){var l=c.x+(0|c.pad),e=c.y+(0|c.pad),n=c.w-(c.pad<<1),q=c.h-(c.pad<<1);l=[l,e+4,l+4,e,l+n-5,e,l+n-1,e+4,l+n-1,e+q-5,l+n-5,e+q-1,l+4,e+q-1,l,e+q-5,l,e+4];e=c.selected?g.theme.bgH:g.theme.bg2;g.setColor(e).fillPoly(l).setColor(c.selected?g.theme.fgH:g.theme.fg2).drawPoly(l);void 0!==c.col&&g.setColor(c.col);c.src?g.setBgColor(e).drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)}):g.setFont(c.font||"6x8:2").setFontAlign(0, -0,c.r).drawString(c.label,c.x+c.w/2,c.y+c.h/2)},img:function(c){g.drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)})},custom:function(c){c.render(c)},h:function(c){c.c.forEach(k)},v:function(c){c.c.forEach(k)}};if(this.lazy){this.rects||(this.rects={});var a=this.rects.clone(),f=[];r(b,a,f,this.rects,null);for(var h in a)delete this.rects[h];b=Object.keys(a).map(c=>a[c]).reverse();for(var m of b)g.setBgColor(m.bg).clearRect.apply(g, -m);f.forEach(k)}else k(b)};p.prototype.forgetLazyState=function(){this.rects={}};p.prototype.layout=function(b){switch(b.type){case "h":var k=b.x+(0|b.pad),d=0,a=b.c&&b.c.reduce((e,n)=>e+(0|n.fillx),0);a||(k+=b.w-b._w>>1,a=1);var f=k;b.c.forEach(e=>{e.x=0|f;k+=e._w;d+=0|e.fillx;f=k+Math.floor(d*(b.w-b._w)/a);e.w=0|f-e.x;e.h=0|(e.filly?b.h-(b.pad<<1):e._h);e.y=0|b.y+(0|b.pad)+((1+(0|e.valign))*(b.h-(b.pad<<1)-e.h)>>1);e.c&&this.layout(e)});break;case "v":var h=b.y+(0|b.pad),m=0,c=b.c&&b.c.reduce((e, -n)=>e+(0|n.filly),0);c||(h+=b.h-b._h>>1,c=1);var l=h;b.c.forEach(e=>{e.y=0|l;h+=e._h;m+=0|e.filly;l=h+Math.floor(m*(b.h-b._h)/c);e.h=0|l-e.y;e.w=0|(e.fillx?b.w-(b.pad<<1):e._w);e.x=0|b.x+(0|b.pad)+((1+(0|e.halign))*(b.w-(b.pad<<1)-e.w)>>1);e.c&&this.layout(e)})}};p.prototype.debug=function(b,k){b||(b=this._l);k=k||1;g.setColor(k&1,k&2,k&4).drawRect(b.x+k-1,b.y+k-1,b.x+b.w-k,b.y+b.h-k);b.pad&&g.drawRect(b.x+b.pad-1,b.y+b.pad-1,b.x+b.w-b.pad,b.y+b.h-b.pad);k++;b.c&&b.c.forEach(d=>this.debug(d,k))}; -p.prototype.update=function(){function b(a){"ram";k[a.type](a);if(a.r&1){var f=a._w;a._w=a._h;a._h=f}a._w=0|Math.max(a._w+(a.pad<<1),0|a.width);a._h=0|Math.max(a._h+(a.pad<<1),0|a.height)}delete this.updateNeeded;var k={txt:function(a){a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));if(a.wrap)a._h=a._w=0;else{var f=g.setFont(a.font).stringMetrics(a.label);a._w=f.width;a._h=f.height}},btn:function(a){a.font&&a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()* -a.font.slice(0,-1)/100));var f=a.src?g.imageMetrics("function"==typeof a.src?a.src():a.src):g.setFont(a.font||"6x8:2").stringMetrics(a.label);a._h=16+f.height;a._w=20+f.width},img:function(a){var f=g.imageMetrics("function"==typeof a.src?a.src():a.src),h=a.scale||1;a._w=f.width*h;a._h=f.height*h},"":function(a){a._w=0;a._h=0},custom:function(a){a._w=0;a._h=0},h:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>Math.max(f,h._h),0);a._w=a.c.reduce((f,h)=>f+h._w,0);null==a.fillx&&a.c.some(f=>f.fillx)&& -(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)},v:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>f+h._h,0);a._w=a.c.reduce((f,h)=>Math.max(f,h._w),0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)}},d=this._l;b(d);d.fillx||d.filly?(d.w=Bangle.appRect.w,d.h=Bangle.appRect.h,d.x=Bangle.appRect.x,d.y=Bangle.appRect.y):(d.w=d._w,d.h=d._h,d.x=Bangle.appRect.w-d.w>>1,d.y=Bangle.appRect.y+(Bangle.appRect.h-d.h>>1));this.layout(d)};p.prototype.clear= -function(b){b||(b=this._l);g.reset();void 0!==b.bgCol&&g.setBgColor(b.bgCol);g.clearRect(b.x,b.y,b.x+b.w-1,b.y+b.h-1)};exports=p \ No newline at end of file +k,d,a,f){var h=null==b.bgCol?f:g.toColor(b.bgCol);if(h!=f||"txt"==b.type||"btn"==b.type||"img"==b.type||"custom"==b.type){var m=b.c;delete b.c;var c="H"+E.CRC32(E.toJS(b));m&&(b.c=m);delete k[c]||((a[c]=[b.x,b.y,b.x+b.w-1,b.y+b.h-1]).bg=null==f?g.theme.bg:f,d&&(d.push(b),d=null))}if(b.c)for(var l of b.c)r(l,k,d,a,h)}p.prototype.setUI=function(){Bangle.setUI();let b;this.buttons&&(Bangle.setUI({mode:"updown",back:this.options.back},k=>{var d=this.selectedButton,a=this.buttons.length;if(void 0===k&& +this.buttons[d])return this.buttons[d].cb();this.buttons[d]&&(delete this.buttons[d].selected,this.render(this.buttons[d]));d=(d+a+k)%a;this.buttons[d]&&(this.buttons[d].selected=1,this.render(this.buttons[d]));this.selectedButton=d}),b=!0);this.options.back&&!b&&Bangle.setUI({mode:"custom",back:this.options.back});if(this.b){function k(d,a){.75=d.x&&a.y>=d.y&&a.x<=d.x+d.w&&a.y<=d.y+d.h&&(2==a.type&&d.cbl?d.cbl(a):d.cb&&d.cb(a));d.c&&d.c.forEach(f=>k(f,a))}Bangle.touchHandler=(d,a)=>k(this._l,a);Bangle.on("touch",Bangle.touchHandler)}}; +p.prototype.render=function(b){function k(c){"ram";g.reset();void 0!==c.col&&g.setColor(c.col);void 0!==c.bgCol&&g.setBgColor(c.bgCol).clearRect(c.x,c.y,c.x+c.w-1,c.y+c.h-1);d[c.type](c)}b||(b=this._l);this.updateNeeded&&this.update();var d={"":function(){},txt:function(c){if(c.wrap){g.setFont(c.font).setFontAlign(0,-1);var l=g.wrapString(c.label,c.w),e=c.y+(c.h-g.getFontHeight()*l.length>>1);l.forEach((n,q)=>g.drawString(n,c.x+(c.w>>1),e+g.getFontHeight()*q))}else g.setFont(c.font).setFontAlign(0, +0,c.r).drawString(c.label,c.x+(c.w>>1),c.y+(c.h>>1))},btn:function(c){var l=c.x+(0|c.pad),e=c.y+(0|c.pad),n=c.w-(c.pad<<1),q=c.h-(c.pad<<1);l=[l,e+4,l+4,e,l+n-5,e,l+n-1,e+4,l+n-1,e+q-5,l+n-5,e+q-1,l+4,e+q-1,l,e+q-5,l,e+4];e=c.selected?g.theme.bgH:g.theme.bg2;g.setColor(e).fillPoly(l).setColor(c.selected?g.theme.fgH:g.theme.fg2).drawPoly(l);void 0!==c.col&&g.setColor(c.col);c.src?g.setBgColor(e).drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI* +(c.r||0)}):g.setFont(c.font||"6x8:2").setFontAlign(0,0,c.r).drawString(c.label,c.x+c.w/2,c.y+c.h/2)},img:function(c){g.drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)})},custom:function(c){c.render(c)},h:function(c){c.c.forEach(k)},v:function(c){c.c.forEach(k)}};if(this.lazy){this.rects||(this.rects={});var a=this.rects.clone(),f=[];r(b,a,f,this.rects,null);for(var h in a)delete this.rects[h];b=Object.keys(a).map(c=>a[c]).reverse(); +for(var m of b)g.setBgColor(m.bg).clearRect.apply(g,m);f.forEach(k)}else k(b)};p.prototype.forgetLazyState=function(){this.rects={}};p.prototype.layout=function(b){switch(b.type){case "h":var k=b.x+(0|b.pad),d=0,a=b.c&&b.c.reduce((e,n)=>e+(0|n.fillx),0);a||(k+=b.w-b._w>>1,a=1);var f=k;b.c.forEach(e=>{e.x=0|f;k+=e._w;d+=0|e.fillx;f=k+Math.floor(d*(b.w-b._w)/a);e.w=0|f-e.x;e.h=0|(e.filly?b.h-(b.pad<<1):e._h);e.y=0|b.y+(0|b.pad)+((1+(0|e.valign))*(b.h-(b.pad<<1)-e.h)>>1);e.c&&this.layout(e)});break; +case "v":var h=b.y+(0|b.pad),m=0,c=b.c&&b.c.reduce((e,n)=>e+(0|n.filly),0);c||(h+=b.h-b._h>>1,c=1);var l=h;b.c.forEach(e=>{e.y=0|l;h+=e._h;m+=0|e.filly;l=h+Math.floor(m*(b.h-b._h)/c);e.h=0|l-e.y;e.w=0|(e.fillx?b.w-(b.pad<<1):e._w);e.x=0|b.x+(0|b.pad)+((1+(0|e.halign))*(b.w-(b.pad<<1)-e.w)>>1);e.c&&this.layout(e)})}};p.prototype.debug=function(b,k){b||(b=this._l);k=k||1;g.setColor(k&1,k&2,k&4).drawRect(b.x+k-1,b.y+k-1,b.x+b.w-k,b.y+b.h-k);b.pad&&g.drawRect(b.x+b.pad-1,b.y+b.pad-1,b.x+b.w-b.pad,b.y+ +b.h-b.pad);k++;b.c&&b.c.forEach(d=>this.debug(d,k))};p.prototype.update=function(){function b(a){"ram";k[a.type](a);if(a.r&1){var f=a._w;a._w=a._h;a._h=f}a._w=0|Math.max(a._w+(a.pad<<1),0|a.width);a._h=0|Math.max(a._h+(a.pad<<1),0|a.height)}delete this.updateNeeded;var k={txt:function(a){a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));if(a.wrap)a._h=a._w=0;else{var f=g.setFont(a.font).stringMetrics(a.label);a._w=f.width;a._h=f.height}},btn:function(a){a.font&& +a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));var f=a.src?g.imageMetrics("function"==typeof a.src?a.src():a.src):g.setFont(a.font||"6x8:2").stringMetrics(a.label);a._h=16+f.height;a._w=20+f.width},img:function(a){var f=g.imageMetrics("function"==typeof a.src?a.src():a.src),h=a.scale||1;a._w=f.width*h;a._h=f.height*h},"":function(a){a._w=0;a._h=0},custom:function(a){a._w=0;a._h=0},h:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>Math.max(f,h._h),0);a._w= +a.c.reduce((f,h)=>f+h._w,0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)},v:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>f+h._h,0);a._w=a.c.reduce((f,h)=>Math.max(f,h._w),0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)}},d=this._l;b(d);d.fillx||d.filly?(d.w=Bangle.appRect.w,d.h=Bangle.appRect.h,d.x=Bangle.appRect.x,d.y=Bangle.appRect.y):(d.w=d._w,d.h=d._h,d.x=Bangle.appRect.w-d.w>>1,d.y= +Bangle.appRect.y+(Bangle.appRect.h-d.h>>1));this.layout(d)};p.prototype.clear=function(b){b||(b=this._l);g.reset();void 0!==b.bgCol&&g.setBgColor(b.bgCol);g.clearRect(b.x,b.y,b.x+b.w-1,b.y+b.h-1)};exports=p From 713a2849cccd7c0ca666ac47e648e4e0da4386af Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:34:27 +0200 Subject: [PATCH 120/183] Create app.js --- apps/wristlight/app.js | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 apps/wristlight/app.js diff --git a/apps/wristlight/app.js b/apps/wristlight/app.js new file mode 100644 index 000000000..24bc1eab2 --- /dev/null +++ b/apps/wristlight/app.js @@ -0,0 +1,52 @@ +function draw(color) { + if (color == undefined) { + color = -1; + } + g.clear(); + g.setColor(color); + g.fillRect(0, 0, g.getWidth(), g.getHeight()); +} + +function draw2Pattern() { + colors = ["ff0000", "8080ff", "00ff00", + "ffffff"]; + drawPattern(2, colors); +} + +function draw3Pattern() { + colors = ["ff0000", "00ff00", "0000ff", + "ff00ff", "ffffff", "00ffff", + "ffff00", "ff8000", "ff0080"]; + drawPattern(3, colors); +} + +function drawPattern(size, colors) { + g.clear(); + var w = g.getWidth() / size; + var h = g.getHeight() / size; + for (var i = 0; i < size; i++) { + for (var j = 0; j < size; j++) { + var color = colors[i*size + j]; + g.setColor("#" + color); + g.fillRect(j * w, i * h, j * w + w, i * h + h); + } + } + Bangle.on("touch", function(btn, xy) { + var x = parseInt((xy.x) / w); + var y = parseInt((xy.y) / h); + draw("#" + colors[y * size + x]); + }); +} + +// Clear the screen once, at startup +// draw immediately at first +draw3Pattern(); + +/* +require("Storage").write("wristlight.info",{ + "id":"wristlight", + "name":"Wrist Light", + "src":"wristlight.app.js", + "icon":"wristlight.img" +}); +*/ From baf2f9a93d6eae3a6942599b57df0f2d2c38c723 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:35:54 +0200 Subject: [PATCH 121/183] Create metadata.json --- apps/wristlight/metadata.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/wristlight/metadata.json diff --git a/apps/wristlight/metadata.json b/apps/wristlight/metadata.json new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/apps/wristlight/metadata.json @@ -0,0 +1 @@ + From a51016d5bcf3000b03b93178cdfc348b89ca3d17 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:36:16 +0200 Subject: [PATCH 122/183] Add files via upload --- apps/wristlight/wristlight48.png | Bin 0 -> 1859 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/wristlight48.png diff --git a/apps/wristlight/wristlight48.png b/apps/wristlight/wristlight48.png new file mode 100644 index 0000000000000000000000000000000000000000..8f0ff59f7811dad27ad975ad452626d89aa8893f GIT binary patch literal 1859 zcmV-J2fX-+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TD&%c|dY11Tak~XcBf;5ET;(!Q_T!iu>ij0>Rb;c*2U>F&|8IS>WP(~R=g$JZ` z7<}=KIm)+mA}HHah*LJNuvWpR;?; z=D(cX!Xy(6kkQ`*rf(V>Sv zxQm+%{wagmGM~;)Dg*-1A*&TJBtTzNGk9b%sRSr2A;hL5V8*tR(tvs>^m-_5$974j z9;{f6=JULY==6p>Q)!t7&(VFw=kW8M=D zsLu!eE;rmkaY)w1;Rnd3tsD?5wiP810qLrl9z2X~skpe9U%!66rlzK*vZ|_TNoi?m zjase7Vh;IApjjm0c*dZ&H^uIf)I{{19q_Zq$XvBmro zfqo7vZQIDRw`5T%(i-~16zit7y=&I2(ON8)=d4!iPMuD-68nY8XlMx3-l?@{8?;^6ozYwj?hDQmwhOmeJMQR(kXCMH0_TTt!IC9Q@{LC0(%G|T z*JALim_F8>fDpp7KD0SxGMSb#9|%AJc4ZVigL-K^*0?hTs$|%Vg3r(64Fo6WXM zqtUS8mlm{{iMBhLkD6C2DyK&=tbETn`;in^l;-1jUx5KBu4K{ndFE45T#@#LNeNje zV5}-HDlaczg+oN~wU{mQsWes=$*OUabpjflR{LnR$pq%3LuXkWH(4hjN)jhYQpWR# z`A88d>-%SY0iVkw_%q*$_`40O5=;hUJSC21z`3?wqH&x%tGABS-e!zkk0q)o@}u*2ip^ z?fLWPJv2;3yolnV_Xrw5KbhgHhxrV7^MfK#S7TerszL`qxW1Zx{~5Li%w{t`Z{9r9 ztXZ=bEMB~L#exM37UPCh#_T*EkE6A<^%By2>(;H-YuBzh`}_M@5Jv4u?R%tz%*D2% zds08W8(0SFaMMC6l|ItevYw590u|+EFqw*nmj{o9pq0z*g|04k z&*WY=16li(RVsB9`wStyM>gJLEN0vGk+c@soL8w?H=C_X~r zX`t7a%hyTVGzh}DD#I{@R9Na~5`2`XPbjRyhLW+LfY}R)STnwHt}&UwMDzbiAOhix zcf<)JoQO4^z-g#=ORO@;btnzNvEyD@N+e*1yIvRcU6RGz#p!H=d-vGCcB2fR1HM!6 z-C+ueLMaD{z%Rdki|3RHguj5zC(gldUtximdr9Ed4NXn8uxso0o_6<=p6GsU?fqWhYy1g3`VQUln{c?66a-icPkwHdI!Am z);Fki#X4i8+QylVeeS5xgV8bv7MXeAM<$98+6nEQ9dP?P3dT~)3-dX`Yhr!rk*Fv* zdQY}t(+Rej)i9&F0w3|{SR$ebEiEn>7;vJ*Dp2-8H|Z;Cx;ljQvB1;SNNlLFgW0lw xyrsL|a99v*7_c+Deu@Vahb@`8JTJ2W;2--p$DOW1Az1(b002ovPDHLkV1j}@bNB!N literal 0 HcmV?d00001 From 894df7889eb604ade9b1e9f09dcf00383547702b Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:40:33 +0200 Subject: [PATCH 123/183] Update metadata.json --- apps/wristlight/metadata.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/wristlight/metadata.json b/apps/wristlight/metadata.json index 8b1378917..3a2bff048 100644 --- a/apps/wristlight/metadata.json +++ b/apps/wristlight/metadata.json @@ -1 +1,16 @@ - +{ "id": "wristlight", + "name": "Wrist Light", + "shortName":"Wrist Light", + "icon": "wristlight48.png", + "version":"0.01", + "description": "A flash light with different colors on your wrist", + "tags": "flash,light", + "allow_emulator":true, + "supports": ["BANGLEJS", "BANGLEJS2"], + "readme":"README.md", + "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_red.png" }} ], + "storage": [ + {"name":"wristlight.app.js","url":"app.js"}, + {"name":"wristlight.img","url":"wristlight-icon.js","evaluate":true} + ] +} From d623647ef3a88423302b64267e20ad62c28e54fe Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:40:56 +0200 Subject: [PATCH 124/183] Update metadata.json --- apps/wristlight/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wristlight/metadata.json b/apps/wristlight/metadata.json index 3a2bff048..af1d700df 100644 --- a/apps/wristlight/metadata.json +++ b/apps/wristlight/metadata.json @@ -8,7 +8,7 @@ "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], "readme":"README.md", - "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_red.png" }} ], + "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_red.png" } ], "storage": [ {"name":"wristlight.app.js","url":"app.js"}, {"name":"wristlight.img","url":"wristlight-icon.js","evaluate":true} From 21db0d3412c21a63500932aea06bb29ebe7eabb7 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:43:06 +0200 Subject: [PATCH 125/183] Create README.md --- apps/wristlight/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 apps/wristlight/README.md diff --git a/apps/wristlight/README.md b/apps/wristlight/README.md new file mode 100644 index 000000000..e69d61b76 --- /dev/null +++ b/apps/wristlight/README.md @@ -0,0 +1,9 @@ +# Wrist Light + +A flash light on your wrist with different colors + +![](screenshot.png) +![](screenshot_red.png) + +## Creator +[@pidajo](https://github.com/pidajo) From c12ece7cde5b79ce0c10efa31ce6331af6e10f96 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:44:43 +0200 Subject: [PATCH 126/183] Create wristlight-icon.js --- apps/wristlight/wristlight-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/wristlight/wristlight-icon.js diff --git a/apps/wristlight/wristlight-icon.js b/apps/wristlight/wristlight-icon.js new file mode 100644 index 000000000..689372499 --- /dev/null +++ b/apps/wristlight/wristlight-icon.js @@ -0,0 +1 @@ +atob("MDCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzMzMAN3d3d3d3QDu7u7u7gAAAAAADMzMzMzMDd3d3d3d3dDu7u7u7uAAAAAAzMzMzMzMDd3d3d3d3dDu7u7u7u4AAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7u7u7uwAAAA//8AAAAHd3d3d3cAAAALu7u7u7u7AAD/////AAB3d3d3d3dwAAALu7u7u7u7AA//////8AB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7D/////////B3d3d3d3dwAAALu7u7u7u7D/////////B3d3d3d3dwAAALu7u7u7u7D/////////B3d3d3d3dwAAALu7u7u7u7A////////zB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7AA//////8AB3d3d3d3dwAAALu7u7u7u7AAD/////AAB3d3d3d3dwAAAMu7u7u7u8AAACMzMgAAB3d3d3d3dwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u7u7u7AIiIiIiIiACIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAAAu7u7u7u7CYiIiIiIiJCIiIiIiIgAAAAAq7u7u7u7CYiIiIiIiJCIiIiIiIAAAAAAALu7u7u7CoiIiIiIiKCIiIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==") From d29b7596bc14b55769fad1542e6dc55624b34c86 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:46:42 +0200 Subject: [PATCH 127/183] Add files via upload --- apps/wristlight/Icon.png | Bin 0 -> 47586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/Icon.png diff --git a/apps/wristlight/Icon.png b/apps/wristlight/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a GIT binary patch literal 47586 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 KR__}6`+opC#zdX~ literal 0 HcmV?d00001 From 835f62d59ad7c8ec14654dbefa3ee032151bee87 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:48:50 +0200 Subject: [PATCH 128/183] Delete wristlight48.png --- apps/wristlight/wristlight48.png | Bin 1859 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/wristlight/wristlight48.png diff --git a/apps/wristlight/wristlight48.png b/apps/wristlight/wristlight48.png deleted file mode 100644 index 8f0ff59f7811dad27ad975ad452626d89aa8893f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1859 zcmV-J2fX-+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TD&%c|dY11Tak~XcBf;5ET;(!Q_T!iu>ij0>Rb;c*2U>F&|8IS>WP(~R=g$JZ` z7<}=KIm)+mA}HHah*LJNuvWpR;?; z=D(cX!Xy(6kkQ`*rf(V>Sv zxQm+%{wagmGM~;)Dg*-1A*&TJBtTzNGk9b%sRSr2A;hL5V8*tR(tvs>^m-_5$974j z9;{f6=JULY==6p>Q)!t7&(VFw=kW8M=D zsLu!eE;rmkaY)w1;Rnd3tsD?5wiP810qLrl9z2X~skpe9U%!66rlzK*vZ|_TNoi?m zjase7Vh;IApjjm0c*dZ&H^uIf)I{{19q_Zq$XvBmro zfqo7vZQIDRw`5T%(i-~16zit7y=&I2(ON8)=d4!iPMuD-68nY8XlMx3-l?@{8?;^6ozYwj?hDQmwhOmeJMQR(kXCMH0_TTt!IC9Q@{LC0(%G|T z*JALim_F8>fDpp7KD0SxGMSb#9|%AJc4ZVigL-K^*0?hTs$|%Vg3r(64Fo6WXM zqtUS8mlm{{iMBhLkD6C2DyK&=tbETn`;in^l;-1jUx5KBu4K{ndFE45T#@#LNeNje zV5}-HDlaczg+oN~wU{mQsWes=$*OUabpjflR{LnR$pq%3LuXkWH(4hjN)jhYQpWR# z`A88d>-%SY0iVkw_%q*$_`40O5=;hUJSC21z`3?wqH&x%tGABS-e!zkk0q)o@}u*2ip^ z?fLWPJv2;3yolnV_Xrw5KbhgHhxrV7^MfK#S7TerszL`qxW1Zx{~5Li%w{t`Z{9r9 ztXZ=bEMB~L#exM37UPCh#_T*EkE6A<^%By2>(;H-YuBzh`}_M@5Jv4u?R%tz%*D2% zds08W8(0SFaMMC6l|ItevYw590u|+EFqw*nmj{o9pq0z*g|04k z&*WY=16li(RVsB9`wStyM>gJLEN0vGk+c@soL8w?H=C_X~r zX`t7a%hyTVGzh}DD#I{@R9Na~5`2`XPbjRyhLW+LfY}R)STnwHt}&UwMDzbiAOhix zcf<)JoQO4^z-g#=ORO@;btnzNvEyD@N+e*1yIvRcU6RGz#p!H=d-vGCcB2fR1HM!6 z-C+ueLMaD{z%Rdki|3RHguj5zC(gldUtximdr9Ed4NXn8uxso0o_6<=p6GsU?fqWhYy1g3`VQUln{c?66a-icPkwHdI!Am z);Fki#X4i8+QylVeeS5xgV8bv7MXeAM<$98+6nEQ9dP?P3dT~)3-dX`Yhr!rk*Fv* zdQY}t(+Rej)i9&F0w3|{SR$ebEiEn>7;vJ*Dp2-8H|Z;Cx;ljQvB1;SNNlLFgW0lw xyrsL|a99v*7_c+Deu@Vahb@`8JTJ2W;2--p$DOW1Az1(b002ovPDHLkV1j}@bNB!N From c191b01d2b4e69433d2182faed82242f4555acc0 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:49:19 +0200 Subject: [PATCH 129/183] Add files via upload --- apps/wristlight/screenshot.png | Bin 0 -> 47586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/screenshot.png diff --git a/apps/wristlight/screenshot.png b/apps/wristlight/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a GIT binary patch literal 47586 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 KR__}6`+opC#zdX~ literal 0 HcmV?d00001 From a9922f3fa0d556c8fff49a9c633b18cd1439b547 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:50:26 +0200 Subject: [PATCH 130/183] Add files via upload --- apps/wristlight/screenshot_red.png | Bin 0 -> 47586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/screenshot_red.png diff --git a/apps/wristlight/screenshot_red.png b/apps/wristlight/screenshot_red.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a GIT binary patch literal 47586 zcmeEucRbba|Mx+t>|}=|RQ47!5-O`Q$|##-93wI^j*;zI=2XZIAN`*p$LH#N0VVpiNVjOoNns7Kp>P& z_&)?~j&Ci%KQg*1KXBD{v~qPfeQXJFGPQAV6>zY0JufC8Bp_}XBw`7HRB7M3p{V2W zXf>5IMR#DJ&avn&U$L3vdEFDr&$%B!uUvY2>FtA<3-|agT?oHKC~-&eEWw)*>Xlk| zgz!Lff?4>1y8Xcm#;n#k+*kOu*+<(j%A+oF(fugx2^U`~qL4(d?vdqjyIQYwpYA#A z(IoCP$202JX)&^wo>5;9{iv~(L4Exs$C5;QAozIpcJw0E&o4N{{(ts`x3WkdRh=ju zFFl447n&!@FG=1-tW<@D$Jnaf6@NjhJYo@KBNjS*-c0E(M@{XF8=pb${*c7XzIMkF z={JMb#?dcfqrIa@=;r(7i&Wv|VK?HJ8d!)WBqYM1j8GjC#4^*!^1cKiDpDewf40l` zTd%gWzOhH@##1(#==3%Lx%8E)oDZt~MkSjO=7zLodcEiFrnk3t%+42YqkCJ~>R&Kk zzan4;dqLV_z$&%YJYwd5^V+nSumpuY{jhA2GLv@&TTHDRs&zEnEsLUd*2}u^@#Fc0 z#%`~3rNTSIEzV!l?3SM1=;UIlPkLQ0b-!{jW##J7{TYePgcj$(;kg#!NDTt#x2}B4 zMD2mQbkEM5m`#-wKp#j825?Q=+t^#$vkr3?!J6G(pKzo?g&<##L*=!`$_m^cOS`{$ zAv(!WC$HIBlhziqf2&0>%5VvzygEHP$n4ovK7VlGefeP;&y1aW%|lrS=am_B)h#EN zDd!IBlNKZwUXU)+p1d%{IuzkM=1FtEuB&>S1;I>lcq>ao^SH=))($(7y*ZAv|28MS zu*{9Xp(i^fjtf6`!;{3YN3S%JY7U)ax$oDHdc;m=`YcYBU4?1o<|uht3si7!f zb1<@nv&D0}6;Jo`$2Ow7zdk(v{&MU+E-~ro2%b9<9U)C7%stqgGMwd~5p>;-UjW19 zIeULyOlo>o-ce{fqFd4fD{m~0{((ET3oN|hTZeu9$q{=nLLw*yKhFO2g-U+dWN=j8 zRtU2@Bq{X`)sF~B4jk^U;@Dsc$Y;9Lew61i$O8^ZqzG{}X!aAj7sV6Vv*YHYx37}v~E){ z?Im=ijyAE{SyC&VP=7^hZh^|DX38Be!V=*jvzYp}`1IKY&s3Patf0HbJI2sMvLpo- zMb5ZhgF)yEC8TL{(iNlEQkbK!B<%3LdJ49~-Remu8DDP)K{JzPs|IUNA;RWCYvRE$ zM<4tSt~)6`uPwa*5u}t8;k!(&qMfsI`7p2X;=Aa57V(e$GoO5}lk2A>sHs{fN?FsE zFu;9%tE0O*A0}UcT(6NAzJIA8ZZ1Z?w*HfD-i5gD^2V?Y!I*TNWZknJ4bkwPDT@eF zXGEuhEUzEUB}DOE$4G@OlZOE&!5L3g-)tP!nn>G)X-gsvE2o1~v8e3LYs`y7d~9PL zvvTz5IVvd$VOd(Uajp;Qg5fT*hL~hIDX}4*ICPLx&q;$*NqKJv(YQ*q<9@@E(YlUe zfKCi;9OppYz;oFL$s7+j zple;Ha!$kf7rYP>SNqJ6S&F$_z28j3c;~xht{5Lkwhi6>JjoIxBO136^f^GUN4-bW z(;&-4C{_KDsYTT+OQD1mr=jb;pxbBD?a!IX;f_cIRaE?v?!?o)jpYVfL|%VR?mj

Z4(l<#_SRC=NP#HT|%7SCzUV-bA+ofbKjyW%Csr7qKC!IoFR% z9~~KboyJVJc)vn`b1OSI}0R|(QK)9Ho`lJ>{gLsg3g7pr37FH zrvgkZRFCDxwW!rp{Oe);&?Nf(fk)W!>`iNWRk^{^>Q6iQ(H&!N`V?nrm~h?uo5xRp_5>pGPni@?Il>Q8 z^XOGcs5W5)W*V@}*8ap1zqwB+LINT0{`LJspMGPJad=ZOi<>Ep{=2uKsGye8^4^Y( z7$%Z#R_WBf*>z5ly6APs)Z07P=ZHE_tj_f%MPn~hgJTb7Sk}#?UwQD_BirnGbUw`# zvH>AEFKsA0J4(oglNMzGCdHC5tpqvwtlBxnVDT-kKqWb{=WYF(iSYO+)Kuu(j4v;D z_kEi_;lB@<`=W;WKmi=h(x%f54ir$`ypnNOdpE7)+|H~6#DB?8C5@JqBbl)lGX_X_YA%!X{_O1<%%lyLDWkJaxaoB)kK?&~pfV5h?!hPB9Re(_!j z&t6IY%EhrA2X{%qy&|BFBLtvfQLdLp@ME6%g0A|#7S(?8dz;~55%sjmezcmG4$g)a zo-#>2$xai=POmeoj$fXb;w*ExDqm|iO5ifKb)CZZnBzYd-k zO0Y4iAp&{gr!$sPiI#C7#2)AevKwL!ZeHT{8&&ETfIql{@V0jXiw42Q_V=xi`kcJS zf`hXa-H$Syv)<%2o?jx(Az*^s<pN^z()SP`&35o z-LDvT(*C!*koLey60ykX{o|p7Hv)pvi2c|M37iQmQLoO zuR3qKkDaK&cn8Mh5UDF*c5d1x37*auE(NO$P*9jztb^@vMUSM^eIltv`)uUBKEFhj zL;S~X)UO2NcSGJVWGsfZINTZY&mkTnf0`E)K^RN=o|d_BBM)A`t`*qpy6a+Jpy26?l6OaK`wIZ#E(MSX&E(AUDeW0H}h`Q+XcOfz?#fIduqgQH6vL5%s?{1ZXx81aKO=Xx}Mk zJBG&Ua8U2k_B|u_drJ>IFpAvo5*M9zC|P|IUjw`EkV%+LfU0sQd+RwYrmc&kNH07F>{*`FAny4a_J$%DWZdMZAi7xF9`9;U}X z&)&zW9$SX?isg39Iqmm$GC|@GSv|TZ90lCLilB!^bgaWQi`}X&kvN0imltm*EzQXO zACs|eq6nEN~L@^N0~)FiQm15LC@&I?to6g&n)wO_H9ZV!*O# z;D@I9G;nAHEX}MznMv-jZS#4)vjSHZu8rA2Ryb}a$Vr{&A8EY4o;?FLyHFg$5-FOR zk>^2w-dEZrRSbgdfWw#4-PzVc$_^@>XBV_@8J}!({bR>h)UV7tZ-zu;`=>7V-QsOZ zCu^W}$_sl_&v{-~DME3}B(s?R5oVzqvk-PuDudpqpfCGO9kp-{-5;_wy(b(UQQub& z|De{RfpJxEKxlKmhY6eDAMRwp9jM}Nryn?$`P#&42xxG5bC{{~{p3$}3`E>i^vt6(i?}EBIG_H?O|raaf;S>afie1^PAyvWeiB>Rba zD8@}yLLXt1@^KO%>x)RsT->5m9XdK%X(ej__xeJD-andcei|F@V-LY&QB( z868*!@DZ{w;GMVw#v99a5-2G2$_QCZ%g!IN8cfz%F(-n|wthcMe&j7|vLvC9Dh%0N zf@}3~rOtN-QxvLkd2y5^Jo@KdH{N`1l>?{4lujnvKE1pwq0l=-aFL4s^yo|o4!r~i z36UO-<>&{t{_Uk4hCgI_`QBzU1%QFkDc`<`<*$xJ&Cw(Rhf4lnm&81dPJ*1iXew=1 zbx)z)Ud4T!va)dPpO6(34!4IiO8fbcwjPd&&Wn06=RMlW5`CNNDaXA8 zt3OY9%jUcUq=Mg8=mM0KB2!pQ7q$!mTlI%+9>dpcn)h*uTf+-=!7N(;yJz>uN2iSX zBJKF9D9`H}lPPbRa1?b?C}0k7Xe|6FUBb5PQrwTAo2E%I1k?kBAlCw)aolhGhanjB z5zCla(q%hVg}V%dz-|aNQJ)1MJKZ=J9DGt<%wY$5rI#$GQ4IL!Uw-=Th8|Hd0eZZU zMHZT5r!bhm{4{cnD`Q~poH!Ba@$g#1i&tP|b*40BN9*ep~!H>EQK=yjW zEtX9l$Zhy>VQ<%ui$v!KN&6!Iz=kuISuMyRADvT$Z>m`Lcf5w50ZAUU(>E2&DF}$R z=Wfdpn7Cp;-kODHpQ)w3tS!;v(+(1I|MX5)*G|J?TpbK`B~i#{$YJ`!ODs#IZ!$t~sgTW5 zh;1#wMhIlHN=5qiq9B3D$2b3Zpx6P$R*0)`N&VSSBfXsv0oO^RV{}z+uI7aw!y2URpw$ zpZ*u=y$SjZaTQ(4CfJxfkst!O_ER@M^E${~onHyYTanBBFU=u6@#KEgl)s!vnfOq+{%;mjBsm}RyOaX%{m0G%$Q3U9F6@98hvT~s;0wCkZ-|-v zZoFW)zz$MRkcyn8`xS=Ysow@EVA$`{2A^16`Sk^z#Fz9IkTZCr{ZGMshFtus0RNwZ zxB-;`_5P1W{>QZb1dspm5qul)-w^o!#79cyNKE8GRh6%Fn~aIb54hj6pDm?-{x760Rha7I6?U~<3DYPZQe$sq>sL`nQ&7cPuJrW}ALzrh#7(3AX`m&=qz z+`bv8{RPbT40yjnT;m9+_3s&kk}C{lqz*&u?fP#KH7J)%WgZP_FvHV8^Yd5lnUq4e z8G=b46zKB#=O20Ah)Y5)+DJlRkv@nI#y%5Ma7)My0Km`_1$c}V)8U~|7`yx94wtrN zx|joI_MZ+e^s~%uiObvTPs-hV*V^(d1aHun;UmkI4aH|W874300*V(NucGCKr;g-4 ze&s&aai)Hfo=<7S4#mf;434sAIX#2(Dj?h%on_7Izg$01H2v+L<=0-;W_etXirqpP zu*4W9{nJ8!Q_kOXe<+E?kFu4(u@3pkj0r*$JK(=egx@d_Kv7!WAd6ox3B#ur3z^%m z;*#yf#N$@}>i7>{e)Z~Qb^f`OYzfFmHMgi6C3X6R-kbs)Ye6s2k z;zR+ufLm-XLZerYHfxUwQdHnyT>ME{NCb3G<0k|~Da9y#%1xVO?hz~W8>iV0J8_^+ zGH+hiFQc7|RW`h65y@@*bqJML_4^Cbm+$KqIIqW#63fjtx1FT&{T@US|6P>e`4#5Z zd$Hl-89_Yk$6bVFG-5NN8lbqT8cZ;qQGD9pLz2gAcoNh&1UxW%3nv;Q^8N0aBTHG6 z!0wS5q!*J9kA3Adx*jy|s&$0_9zv3U5f!vG*P{1K(sjcGb=TIRaGO=XF?7B9mtz54 z@*Bql6dA-~G-btd2Ilk)Lj*!kzS{f4x1PnYTD{(HcCIQ;_a2_QpBDf+Wl#uzMpy=g z*i5?EUkY#G0aB3H*xLG=Vk)}-paQprr494O% z80B|2Lq8IM;cmCMy@z12Dv=`D+Kb+k2Aeh_=`WOlj-IJoPcI+ZtZt00Scfd=;hfFZ z7>qUAePXVh5l>(DR?F^sW2F=sw(HX5vVX=)jJm9-&VUHJT9K0Q(GuBUO<>kE(kA7N zMNB3hbkI_)VVk^IFgp?5%ou*%i#Nvo8ENgzG*@~Rdam1x`RqjhvZfA^1HuLa8we&A zGS(F8NQ6EOGZve5NDPt;VRUUJXf>IYGEZ=R;auYU&N<2XX*1JnJ?ged#xrVWx9!6= zsRI*ez3}tiXVn$}OT3klTJ5j-rB6%G+NBN{1d>pw=sZJ6px$1}p5Rqp8hf88Wz{m6 z)Gf8?(?O5s^JCGZ_bmR9(R_kYm8p&KLj^5jnqBP>$k@InD9-ZLhVk z^JkorOp-g)>J-Z?eeFYtFL!|{6nXf2F;-fo3z!FSevo$i%J*%nIg-{|I*LT*n-nUe ziOrE*96C%(&aB@r7s@JpG2ZpLIfa>ee%MtY|Fq}5Bz?vDuU7gjpkxSPUA^2gtCpSY z&}m`4=R=vMO~E|5(6P$R%W)jL2G5_auN*MFSxEbcw0%8nu&obCcb++_ivC(aq<$iz zdhCSIlKE0az5iy$B`1NDSi7z#Jhtp?@@9+DoUP4CcqvV_u)}~K2Ur=|$@M)$_B`mN zhk(&eW)XiKMZ?SB=nhO8leRrySs1NopOe^Gvd2yft~xo3&<;fs3NoqpjLZ-FWlNkd zxJA~5atU)Gn-d<;x|l_i$Z}*+hz00j*b<{ZdnZLcQ&*j~D;PwPu-FS-Y-we2tfAKn zjV3!cnSCoZvui%tv5wNvq3V0lm*-Cl(6t_p^3f{?Z$1#*8!}QTalVo>C|h_C8Cxh5 zM!{p%r~%Qg8{2Pj5;~I&4t4ez6{KCJ93YF;U-W#IidH|oc z5_4W_;*@@#OPtKFY1*7}^JOBBRnFv0SEK7G);N{yJ~peKBBy7HN)ad`;cYa{Pg4>u zj*>ZLaNhqlMfwFLQQ-J3oFZbuBl&R#rHxWT5p;K@&M=GHy1p!3%t@vU;71O>ep!G- z*%mqPAV(d%B1@0=M%kBF%K9|pF8CtQ<(`5QqH?72g=nK=OjUfpcn<2dpU$hnnQ}-1 zv2Paz&#AN<-8zE%UgNG?n}Xp1%ZS92UC{xbs=`sE#hk&--=3&MhLtC)i}}&d%tY(; zkfRip1|$wcK=;5b8P41=MCb$$yeyt0gZ@mE%0HlwzC_9Ta`7s2jHX)Pb zjM{5o@5|AM9(HbHC2bI>UJ;>ooAlY|%+xQnQdNwg=O?*ZU|8`;a3+0sXnSaXe|vwy z2vdWRJ+3*Hp0QJV==Bcq?&cFHelA}U9NVlJU>*MIsK!D1V3?uBFVAF%MU>{l)uGh4 z*F466kGZDOn44*Igk57+AcI~Iz!vu!soCWv8QcUO76y|eQ!r~C5sIVdnXfD@+6W$~ zsC1U*?t3i8mKta6(&ucWb1qIvDI!VhoT%ANzOc*1yOh^|t>w%UM*G-J8rjUXEsm*f zwS_fNNXiQ30Jpk^cx1x)$2~bB6gU9?+W&SEP=q%Q7oU{QiH|SZlO1OWOv!v&-Vs2PZ zEncE$h*C0>rnJ_a?bWxrDJ_5qcggivUJV@nw~r8%H8e7UrDmS3Xj?2-T3}hDh8PR< zO_$I9AV)BZOE-+zmv-JBwtZjlarkr9GBD~{RL?n# z(h!kSo`a~eKIv}=pPKCM-eRtauNPSVXb7z#!b7wX>i#T2Be)nhtIRE;&W~sIF zYf(&LaRaw{`VClv0H3F&pELG6}{#& z=G?Z+ChZDM2WGe{vzQ%wnC`vR9+K*Yvf)bcJzP|cWE3`oM4r3)I78H`BcVJL*Il0u z+-zFh6E+dJKXc8~5!lysij-tmjLY|wtL`8C?WU6|B|gO1eNQ?*w27#Mm8{0wj>=lh z>ZBS(00gZX>$bf6s#`W@C(+boCuGrN(BI`#sFQyP&e3Qi)6%_=3!>_mS9Z9R;ZXYbnnn9ETr9D8sqSUDBYBv7-_$jPmhCTp_PpGPE6HTS|F zV3~}F*&Vjq^&#og)}9oPB8KM5J*g%l_UCG^l6D2T%#2B?cE!2Ok5!R;2(p_&RjPc5 zv)fzF<%iOuxEEkq5E(Kd?J{qAO^op{gY*0>oMg=MLGZ z=9j}yd!x&P>3dF~6gcSy4TSL{B%=qF3IZ>W&PDb-c)0xG>Y7kmhEJIaCn3dc(lg}@ z>t_L5r#`-St^Jn`=C9)Q?%T! z<%DC$uOkGcH)bLP<)DWJH{VIeq1?I7dOoARyaXJll3Sd5k+ga{RcMqgX>y*kZSZsv%u( z@!Fb5AzEm>>gKs%ZUcOa}7u!X% z8lc?>o(d)@s_^T2j<5I5EJqIivQd15c!ci#{M4qP2RJsZfRNE!!3^gi^|lBZ^3-oK z2p*etSxQ#@ezuumPuZ{ncSajUf zrxwq5b!BhVQQqwPmpG!xthLJ7C`ET5?p}8gTZP~26-e);d97V_0IzLpN)opVMh(%P zJK7JM!qu(U9R&xiUq0|X@|21nn!#g%`N7tAB2TS}WS1!;DV{Eb%bd|w>#kJ0DT7Mx z51r&1EWm<)i+ORP_UJ&oS=2)LfM`!*`WKpjxFK-eI_H4XMWta-iWmp(a{l;KaKthPAj@@UFT>-yU{M?^M4v|R;r^`*GPxr z{XbE*$_?d*%+Ls?Wc|nqyJ6UCRmKXtY1j&5sqnnQ?Qf4UGJdYn4CT;l4H{%#j}a&Q zkmp^c(JxnWm4EPIenkMZfchep9)pnw6v7;EV_n<&qGkF!UDZ6Vx#df8#1SOkw)rNh z&xTGGes51X^QRP1%TpJO;H zm_VFDGCXv>+s7nowPK>|w6I)Q?>huCaAzvssLq1V6%UHdlv!9{6{6B(aNIF#K_#1s zs~2XojjC+MtB7uTqWjvuk^F2Z!y}LBo3lS&J$kzM!2HMi!aC^=Ml8y%FxAXhtD=ze z5&U>pbafeeBt4IioM5y|p_n|H*l!&vK6M!_kCXFljY6C%{A7nXS=i}CzVLqxSieOH zWkH1^Uw1-fP(7ou$X&NCB>aksibNEfu^_s6;>jJp)Hhqq#GkeeBr3vChy}53I|r$U z(Zt<$x*VQG(o>B}L>@fOx#~(SnpZ~^XRg0swhT{FJ6CNV5|%0gAR{fC45jap3MpLN zV4EW5U}w=MKn*WW*5kOHzFf`~J11gslatp7(JixH!!6M`-XD&lcUkBm>mKd2!Hyt?X zz1=y{YTDXRG4a&yx$qpRJo?j}*^5URWM0w%t>T)wX4&AoE zyf88;C?rr;uO%UH*skR(!sX-~aM_z`@@w}->E8Y}!o{<5169+Ou#sl%M43Xi&|Kvl zm0~BgFkwVA)F|!@GvXZjBJQ$UMgUVx?veP*-#K8nlD{F#gkh_zY;6I<7G`mcv*+6C zZctq=$QPV0H`22FE*`E_SHo>9==^BgU!#1k{0kVwsaFm=^`_Ztvo?c1RdUvZI?UVZsVtuQenF`zOLiQ`q z*DN$UQJVjT&!(&FmN>aaY`WdmW~|Toq0i-yJB?&u3Wh!0WfcE7`nQ}i7<3k4W77ItEqpNKPL?oXytt7wXLDK1~O#pbPSB)ln?w3-lMg%(?F8Q zErA;6J6l*_{B-dRtaih2dbE?QzPBrUrcNS!&7!5Kn(oUZ6-V9|Axx^lgwh>#3l=iI zABDe2CBL>)FCmm2sneurIS9W~R(Lp2==)@rl-=8@n+If{&BnOHAxXKTl~Q(}-GTc! zT6Dt)o~q+|+&*rlzW(t1ovmY_xC5D*))01IGToUnSIBlf0 zFjf`p#BbDR>Q+*4mC?b8i zCFiCJT^8z6ubg>}^~0zACqc>u<#OvB_@?g>U0LK&d@3k6dt-ExNN|p2iI9n=OQMCatqyKd$Gu%E$F>$lujA2P z2vENw%cQ|07f|?8Fq{>LBx~O6x#gsw9x)Y;JQk9iPr`Q=89i@C63`pXvZIpXy^<$oJ9p|M~+3oFxQGm7BtMl3#hU>YLJT|$&Y9m2v$+OCqOGU zZ?A?vR`vn3k=WUE?RjnN)HCGKCCPb|4gvMd@z`6n-kUwQ$MkQry4-frZ9zT>m*>-JDLX-T-&c*wX3KES`A_3K}{wKu)~6!1BBZvhr<_k zDu3XXfh{+8z1Oo(;a%uh4K*RjVd0aVLvcG57>N!!;N;?wLPCV3y(*ans6Mwc(;7KH ziJSuMQi4r>e<`=-Z<@SJ3-A2)B5OPg+Eq0^AZY8|R_i1^>)R_{43&V4^USDIJKy6e zIaOq=n2(U;TdgabWYa%;*X7FJDV{UA+3XAk5}pme>>{z4eE>~m^xQ_ZQaOzA zXrfW&*6v~fdI479NkdyPvJYXO+b=%J?M8EG*<@{~k6(y3?2GNL$8# zn>aKxtkTBrm6xGK&y-)#d0Z&ZwhLePnzXZP32%XsGLjl7F2jOWPx3S0_5p@)yPds!(Q8 z=R=V`=6nx}UZVYL35Ua*URAMO>VRri^3Uw$x}mPySB$r3i@eNtM`df7oHuv?cnGsV ztqj~Z=GPzZ{ycE{f#i`)`mB6M9VOD-+YKki>y}l}P@s#(Ex@tXafp|brQ2^A421|I z%z)q-v&hqU8$^krrP#8+!>UGd-(K^1FSQIlT1Ze&c#LGB_~D~0(b*e?554MGe@>VJ z7Ji0=v&h~NClPf!q1sPhRO#h6BF?xSE3I{~+-rXn%Je{$6ALwUUx^D4fNIR6&K3ZEJ*R1@QhA+I#E)6o6eM#n=#gT z_#72IB@I?pi$>T`BFHh>WdqTRm_CP3{1<)A2)BZUbJ~R5r!A$VpC@R~@dT z^{>1N;UKr;`+M({%#SP1O^O;8Mm6pOg6U;?=gs}2!gm+nBkX3Lh3H~Ix$FF35XmDyiQ z{&+_jB)26J)uG5N3L7<4Kgt6FJBRv63)3PGB^Kt8Xuj0^&h;S#j2h@?%hmnbCMV?b zqR&oSf9bGGKK3f@{+BN1%6CD^OFc}l6}x%z#+u`llaq93h0fDqF*CidiJL4c63XZkh+y~RH+nxm?zxFf5rXs7+s>)V5+4}{W{>NU< zYQ4%Ve=HLYTRsavGC1^OKOIzTgG853tpqVV8sJ$p7Vx-`{} zc=-&kktqCVbn*jczaDq&?qv*%8&06e!0YxU@))~cFE3pt4wF0IoWYCNZs-F`4Tvxo z(t$A4GxYdrB4qSSr=9cTp%1k+tYE6GBVDK)KlkaK8B1zd3)xtci85zBO?z&85(^A* z{F`mJM*+J3V77Li^o$r>%Vb%m|ckYq#@_8A4T0|c% z7w#7Y^o`cB*{Do;%!=`wof3q4iLq0%BkFpc|{$nxDEy}!~Ps2db3J`*J3UH0jI zJ5nrR>qp8zsx=mmK-OesRMoW0Xzr*awxnO4t32F^BG?gZ{pOcIE zp(_7z>s3AGyBYru?*zTWseB}K8#*yO$|Y{` zGI?lb?!!YbPZ>Z>(_gRA(*>0K(>yGiNwEu}2tM15Ba3{G6_bB1^z=NR6jU;VMiPs* zM>Q5peKMReUgnVh`btpn;i^`q$5LMIAoD>;z_-31`=HXMK*r49(sM$4pswmg3P@P# zn|{m^kZY{Sfq_EqXT)hR6aF^y_yQ2nfx2Hy|1 z*WXYj$b63eEH8kSSd#5l$@Er-?cwn)cXtH4Gzwh?nen;+h};kOy12NTxdAwE2_rNV z>Uc<6NzO;d|4VN=QiXKkz|XFJrF7n`DCE+{ zacoMyrp9+FFnU!lLNFei*2-0MF~_y&(fVj)VN*dv(dpC~cphEG`+T&#`TCnx!(phG z*-yJ^PlA~JNT)oH#1@^$&z$kOH8hKlmKyu;Unp_iv*0=C#{6Wfx}Wv!Rjj#(%pzkjFbXo@yR|_tf#o^L%C3{eVO2FtH#x&5de~7P*UUVO@up-zbY}M&; z?3gLi`|r{4BNpNF^u?!&0Do7QtazEmY$X1VHYT(Ycox%8Ol_RqyRjO29`{w$*U?^Z zFRRKE-`o7TBiDCX8$CpN*S5>X(jZ9(q$vYx{Ir$%UL^RDH_nKx32I}+w+b^2EeHh= z>J4G7cRAvlU5(Aonbp#QX*e`9U)jGn2VWPajFsC7I;sK^ljXd4tY^uDUeIsD5qO`q zbMvoTa$m$DX*EP|_K$Dv@apAHWtkWj=$GbLwBTa3(k2?Rks#i4hJ1T`6A zFwJPnc}vbtZs7FS6?`M(3Rc|vC>?i@t{O%s%<0zr{J|M*GquPtap8Sse`sdSF66`e z3}Gh7Dly(7{$|_Cit`o{Y-DQ?g3A|L$45SJ`e!4ToCI0uw(b^d>M=eY8EPuHbIvgf z*9Y5?ng*@8DSy#Y`0=vwK@@y4KUGu@@%bZ$rap|(!J`V!Bn(MMRe_yJQ%pJ!o-IA!mq=5v2BdG zsL#$Ri1UJnAo#(*gYJt93sr_N%o5)jNxQ8H>42u@i+ z1cKtN&BEV=gZ#Q5yT$Csp%na5c7>;C@Eu%jZB%I7Ze<>kRycEu|Qdj?hfQu9ylh(rlR!8cnNR3F47 zKsi;|uDI;tTQT8_`iA@y*qvPYYifU+Z4JZEG5QnU^WZv?A(Xs;xD&jqaO=-^wc9~v zX7H09@vS_#+R~^T=+Mc?VbQbINB#A^oa&@5j_7{S{l$rV-G% zSE?2nw>woo4%+ntEmAv))@e)@#M2keBk4lP?6ak2Rpk$RJB>lJ**eD(_QZrU9>~;- zSQt<~#$27w;!jEVi_bDc><>K+%M>mPo)6fwfRx?0!6SzVXAVH5@FgD1Zvw_EN>`NwK`4bN-%o?m)Je@i$9l@xp9Pd1ETj@c) z5F|d4=l|uTz>=mwa9j=J?!nW$^1$245Sij)3}qqUCS=+Dr+>aZ-x7ixHjCglCz{HF ztBu+5WAF`kL%D;wSk}ljlD_)32j3QEO|3<**>g6Jtk>>O9OszAo;V$S7leCK;SZZK zY`7`U%zr||6|}dAI|0M;Y&T&gfr1NE5PFA1!Rw7XfNH>!|9P#q%YejWyHj#9JX_Y{ z^K+H>>;sJ3;tw2{ZP`D?9q+GiO$Aa(RGg^a2O*<(1o)4)Y7&7|uS!5x0i(LvQ?wUA z!rjBq#^d9m{K67MPQ=3Cv_DA*rX(5s28yCk9vQMJ5=dueZH6L1sJMwg5$X*|1|X7* z#zq<|+;n0)vH-kBsW^FUzG60P-grz zL3G4-hR;UZU~E%kc{rdKB8d-B2OxY15#T9uKaC8$zRj8dWGmOrp%k5&*TfjhE&&L+ z_g^4H=6PhYBv9Zjp49$}j}F+Qv0!x9>lQypRdfRW7O_KeZM#F12R}BpP9#Xc05|UP z2JPloOLyy^!2e=P0qh6AL&Uo5Mbd9KA}S(cCO3FV(DNt{pSb@O0ZQWuh5 z(&wi89$F0?X`{jK>=0^rUd-l|=9aQMNOJ!gHf1mWD(%~JSbU%G(gxb1sYmcNvmPOQKy zN9KoTs$R!KMdnpt!o6la+2F0ae`r>PC#xA^U((K9?O3}zC?nxG;XTTB?Wz6M$8(?g z8T0rJk&%-tNFUilIC?rnO$8S}7hTaikr=px!z>=Q@bRPnt`OJ*I;$3)W+{bn6c~9od9BZQqBm;1di2 z4Zxoa_{FAzp3=zV7YiN)c)?(+DhjC7)Rz8Mk!OgCHd|RLE*`7_Dwho2A2mqH8H+lv zE~JzW01&&af_s0zaH12s+dxEB^sYLDYp;n7j@g{G&u$|!>Duj;=Tz*=M?S4ArazxV zEXD8(p?WBpumAg$P?7(7%Dc8dk>Z*ekq``328-v@FImNxzgb+X*Vw%`J|W{j%Zv;u z+23$~$+bU?$0Pmt6{h2EESMF&_QLIYEB$jokVhJp;n~u2?XeY66cA>-*~YPUG6GP1 zNt`4s4Q{}ytnx1+9~1Qyo42u&P_fmdGC}C=#A}y7RJ#>t*A9UJG|G^0-C+m5Qrs5h zv(?ViU39VA+(gjpd))nbkoe}xi`Lq{ZyUwW#g#-ME`ag?;xmt?Dlc>%d$hhD{Et~x z4MQ?+m4&Iy{w$fiKHL4?h8a;&F09&Zc@Wl?sT3knyY+=P`2!eIlBx|>PlBm<0l&Yy z7-dP!SOfkgC)C!=)4=q$9n`wtIwU8(U3%f5#RyM)R6a0E@h3=tD~ViULHKf6$puP9 z@md*=RO3pIVt?5aUee=kqgFu7BfHO)C`T4wYHN=8wnj3^Ja{qTIq*)`+uP1D>nk9o z^o+hZ5RUKH@&W}Kw=6)6R|X~Zdw}T!pD25$F$(V`Oj5wJ>N1!>X#bZR;Uj@1m8S-Y zLTHIl=Q-$0Mn4V7@iOuDiYLp1)iIH(2CqoY_`o6^R>K6@cfl6w8NX6kAUkv-+ zMiUj450JZx-0@DIEY7DDG@!g^Ux5ZDL*F|I7)}`<`w|GG*#Das_nKKiC?kJ0Li(?R zD+WK`4}OymiyI|LMkfdbV>Q5?ssYu;{S|=gRc|m2Su62A*t(WbQl4Fl1KcGlpKm@#o%9|4@&Zzl~2#CWCx{O&BTWU-I2VYpWbAe z^a*m#q#YT^;)fSlHvtjJinK2V{cxcxwYr*XabCi}&f4{1sg(wM&f~;yKEQam@lz<- z!zXL$AgdYD$VHXKIY4Jx7>rZQNlcgxHb)`QpO+efT6>t2l)OGc$`oUBy1Sranro=? zR~6c16d;rP(kP~F1_7+Cn)P@?hY>fBw?Y-q$Su9ia!VI7ZCrDi?-+4u38&*pMN*|JYlSWCU_8t;Lre8E(m8 zr$gA~`d%Cy;E{=3ZB5b_@GRg$2-`kn*WOS)c6aE%b(27X;qINwL>WG{?zWj6AdAs| zu(>`^WZLw>(7sqXi~tJAhRcCea+TjVrkf1aQ>DwlgY;%B*sDA~-wRJ6BO1)tcX`dV zDI5)qRk>SsyCa{$*xUINcw=F=Mi#29pfvM8K>vTS_g4W`?c4h}JPARiL?oApii(Oz zhqMK{MUai6gn)pAbT=$T6omzX3P=kI1|ibYEh;759ZL72*7}c0sC)18{%+r!@5Q+| zx?OY5PmFlRGoDeqx9zN_5&h**>6{x{qpTa*_gk-*N4`K_=ih>$Jl>VGlthQgu0-^E zf`ENtVpo4zbUanJ?6G1{!qP~Sa!{_4JJh$!WgwPQ;d!e)3tZAp1pp2-Jjnz6;w z-#n~FyLjNVB#$ZbPzyt6tGBB@jqJ+8c>BU+cR>~KH#F4#HW&0DtkMR(%4xZfI6xpm zg75I@@U+c|7upMBsWsJWYfx4R{Gk$-k&A)A^Z)1V+xQGRQA7jWH380@%L;k{Edr7-^>HyECrcB91Zch}zgWe&Iv0hVA*fWXkI%%(=lp&vyGZR+Di%$!93 z?KHR65B;ETzdneZtQM!A1A(^PNK1-d&RsIf40fRFbp<_Z@3#KRv(kPPS7XXy1x}UL zrROfCoW|~`RUrRVxe}I!Etb(@*USIM$E}BYA0^WH8qTe!Ya}fwVU=1IC~AvRJy^1Z zQ*guEaO@HpoxZHVZ~+cR1kXhd{n+%oL1{`K2c((;@nu2ZlHGf~n9cdk?$oPJJoslQ zu=Q2Ciag1XGifJBsI%OOL7QD$bUbNjcTz+%T+9S!$oR!#y>j2yioh9nc=+fiFr8=D z*nZ(^!d35C3d({Yo%9XvB z`humvRoHYp4M)gd4gbF*QG3I{*+z8{j7n=w*C-b{6eD3GUY|2g$(K z4HHQ>=5{!{c_wX#BOLbS*#7vQzZq1L$oinUc8&_w*~`yRTw%i*=3uaqQZ7Ml?FIxUM6uN6jDLhKAObYCH%j#&GtnMbqvXYy?zj(7RT* z>E-1pqI1x=we#0K{*3Ic{doK9+Qs||c83o4BEOf=(RP(C3etkIM#27?-`Yi>~7sOo_mUZM(Q7*!IRnXk+RYr4HStG z5uUhM9OSzg10eTM6$pw0oN7Ra&+Q2riusRKGixN7OVy=Sg}IP+uL7*Xl_6VeZYu@42v53e}7TR zy2a%RoZP_`UOOFbQ~kpg;ywEcz6zqox5c8?gSb3NEI@Nf@i%NvHsHH!+?mW>3)LaSd5`S zAmKFPUHD~dUr`rA*4b=4){=5F{&HB;(}7&0x|rBh3fW8~EpakP09ik_<`O8-RQl_m zl~P0l9222OW?6YScrH}J!CWSA?)&RYN;YIupE> zib#eXs*OaKY2w%0o~JHM%M=J`ck?6wt&xX@y{MRJKaFR!D;_ZJhHD)x3HVYoin92izXeD1pXZ5o90kRG{#q9R zi2xt^^u*Q$ev@AWY1VQv;|QD!JbXz}3$8C7?CfPX@L5T2fZog>)iGo2`sLx@!c8~c z#pVMWdd|n_Z-8WO+i#tEGBVk~!>tqP&04Q1bOt^LP-@!Nou{mhl**yI=nU9q$@PRA z{MCVrWhjZYG3XmJnphPG|7jRD5>*3=Xv$CpmHrn%6Jfz0Ui)H{_*{_VK<~3%xGS99gtkTOvouIW&X#b9yEa? zdF2w%X3s>XAmkamo*8Ke24746qU!=0Ld^2I zPx~+{{B}a$5CyqQMt2}QC9B;u)@b1H<=5($Qs|&@aMXZ=P9b(p5dyAtD!+NEL6!Ib zw2(>a_7;0_b-1sL$4&xky3(X6;l&cF5>EL`FOLLztoCzo zgh{6xf6aM`wgj&GQxr@}LCr>bZ^^?+pAGkbG0(as`V}(vwq}!G#|?>`=(&UBW7Eh(CbnxG&>Rj<9)nDvec@1Vzn?_X8pM~204u8pn2i;PuW%y~UkxX37Ukh;&Y=WZC< zR3W_aRHNVM0Nk4Q&g(dJtrj$vwWBuZAGe_0EOT6TX1pzZw5wvTjY7L}tXz7Oq?2_# zcT!eNJg&hn3&5#|JepaS4G`EI>4XeHa02`ahQnnnrM+PJ=X;O;kw$(3T!rr3CS>Z( zgd!96zqV3AFz>=gXaH;L4m4juG11BD2#L&7GoLxzp$q9_#NlDTpjS=@b%-dL{4?AN zxemA$!(HHgf)lm!oF_`?WODIPa9fHnz8aQcCz5toPJ!EIy<>3;W7`U>A>E3p+qxS< zAb9|)Xw($ZCQZm*I1q`@`&738fzc!%gn}m}liemdvgK={WQYxLUzAWUd>FbUJ`Dkc ztd2+P5j6F0M9fA_p?c4&E&uD<7*vHeVm8VF3!M(#O%VHn?rZAn@%HA5v!Sq;mvLMJVwyb|G=3o;Hrm7qQpgMz z5z`y*r~4}=-M}r|4&36oe$%cI!DQ3qK)0zJuiD3fd(XMASKom81&$7U?6|h;beZ-h zK0^8{k?$kOfR~0o3R54{hC_-AiKff#t;{;az*!eTd)n4Qg^a(OLwBFi`P~zZ@2}6I zOsBH@I~dfJUI@Go+_rBu#hPu6anGd zCo7Zfzg_?W8u)s&5QCabQb68>jF(H1xqrh^33`Znrg`3VNH#)g;9@Poeb&$f*mfMB zu)ug-vu*`I`F*Zy^UYC^IA;3hKzA)~KD{cN*U0orLDGj9^Xci(Hr# zc1dtCcL69mWd$ufdQ7}pt}k(8Nx49G7)C2smxzlV#6_|#EUq|BSzygyHH09)DZ25W zlz;QE`(m(exQs*HXb+bJspQE@b@o*JCPiV}?6c3IXn0okC5USe!Kq zx!VA$B)$eWJ#rRJGMoVzm^Vhu4rA118RBrGK|C7vtm@eS@yS7X=zfstTmkP!o;m*U z>&dG1FyDv)SH2mMZ{RE;22BD8v_Gj)1x~?<&d~r5;&5v4nTkD!jQgqxulokcmxP@R%@y zcBNo0<+})*wb}YZ;d87FVD$(ksriPR)c^uY0Zf@IBAHUPd$CB+uv&5kNHJ1Y5JAK; zpVV|Lni>3R*m7Z#0yEu7fTWFBJ@+ngpM_Bm;LZg!mmyWLT^C+307#dtZe6oty+Zf! zzwp)zGF-LX!xluyq{$Q(`O}z??MN+qjreFn=MjaF+Q4J&C;@PI?ngacYCwk-90^t{ zD6mDLEnUXk*OPM1!MsqR6$eU%(e* zy4ry+B|<895MR|p+JRHh?EO(MUNIsAJ(-ytP~o9fX!OH~CRIWI{z4{w$7vLW#=a0V zq)iRz{EQ~KtAO~JeZt{~03C3ygXO|U8>?zab$G8gbpN(azl}o%ga|k5_N!BeLVlXx zm18Uic-RbI6_|w!#fSPKm(DScl6K3GfR4{l^_Z^bH72ti3qB`5y~)81EVp`3grIjL z4Lw7-xVe)V^xdX%?tpL+1*%9J3UDC|D}2jQxc`AsLli@m9tKK=_m9%mD>NZvt$;M% zM2i9AXvNShSt~E&6g1^#=)G&&Z7;Zw#3<5K;hf>C|$re`LEE#$x`?r?gpeE9d^gpHv$`NJJ7Xc?9&D(kraDh)#{Oi8A z#KL|{K=m}uDCII7#tb$gquM6lh7-3YQ7|<#RLrW+{ppd*; z3#kA{{>L@6oA5H&hHh(Ehp2H#B9F7K{ZVXNuO8q32MCqseWWf9g-zNngO1>tXAg~! zm>~9CJ4B7Y>*qiyWi^Tx`kbJN+qCk6S*bU@ghpT2S2@cSfCf(8Jo#xP<}7daz;5^V z?H7IL0EdwI0VzSAE5PeEs)_39c&O)UCJvJ}tl?PDV#51%-HZQOh^y7)LvkqBG13Ne zRQ54O5=wun)Ce6+h|45-E^zKY&Iw3Q5kqRb%P&9hKv3a zGkck?gV>+(JndtSIG1jiP9eQ@px>zc##e+z0?vM1yLn0(Q@2@H?$XfO%3`fE`%-osE@yRhpBM) zvUGnrZnSuN&F(d2)N1U2_Sk)Ps8i3>DZ00wBc!8S%LC3Dy`UXxD9?AFWE_m9&bU1KZ_N5XTu>+Z#eJ6RFy%>?*U0fW&wokN^Anve zR8iZ+z^X0i=!-hfjks0#b9DEkakj+mFVBjCZ`!v`wWb>SgH5kqqGCD`k`KPkbJ-3NI?w~8Hyp;T2X5xRLg7}EMFbgq}s6voM& z6-5-9(NeFVoF&@(TfJL6YS0{oJ0_(-=s*!YD#FI!UzKby=e8@R-m_eQOk4)?I*WX3 zxTVb~xb1_Mdn(X!FlBvOhI$sggzkkC79ie{jpm)yC}{*$*4bL7jWnbZpcyK48!{|K zC-Q6{eIo<;lMr>FHRdpsOV|#t!($jjLlVb(VYs0Tncn*h_Nj-ut-!<%Wg7Py##1Tdos6B3vo3^lcB!Nk66{D8N~_ zdo>b(VD&IKQWFkMYKHRwtDY$UqKxI#>tHQ$SBQCHle33HXA`a{pk=#8RWb8V5Z?vo zug-i`x+5h!-s;WBpW0_}K+~DwKl@3B)0ZbIPjkh;{4W6!u;DvEtzj`?1x{pP;a##Y zl=+ZDjS=xZuQe`*V{3E*IFd2~Ji|lKUvT;iMGQr>sK4Yk#as8#MV`K!;q;kaLEDXYT$4a_8-m_G$))a&dqcI9MAS?$CL&Mh%vNQ?siWFOeHg;uG<~eV~_@5IUht- zCiZjh;=1ut%mz;N@V5ww#Xcyud`mlHT>`Z^X0=<{{p&4YaaLx+mYgD`pXCTX-mEGA zH3|ChggQmO08BRURG~7Cf+&N3l9W`ENcaLXNtYMKa~h#en=e(L7c>_ZW&8c23ow>` zth5__h-Z92VAixOs)Oq3v?Vu7EE>K{z*3z|IV0c#*H5(VjdcoRh=j*NYSdbxZBinI zS?T?jU7Roj$r}~60;_G^9krne1>KmknA-|#=o)?bbB(OXuyIh{5Dv5<)8k>-RYO{u zN$MxPY^3U%nRcd@fO2jM<-90y95RHdi%*ZxynvflSs$;&VYY3+mHSYALbT@X*e^~H zcxxVHxRNTuODKK7;?*aE`(v-rx}`J(VXxu{bqX=~SROwot+OtX%>V>n2d2+&X5fGz zqR<%ls+0U#HR+SuMJSIQF(+MKoGcg*kl&Xb%Xn8Ri&D}RKjmh2wZ#r_;fFU~vRI-4 zp(xl*l|*c~UE{UumjOhdxGf4YCylB)LvWtMc~n-188{!y@N?RW%*c5CBKNK{=^Ur! zIi=^L_>m;;|I%OM4^rr`GZcRIBku-CtLnwXI7sN&i!8Ud%H5S*%)_O0LrI|3>{|$b zUIh*#S}TXE2;0%KSQ=#(TS=wM@BwPm?fRtoomD;}1!#{2hn{K|X^hjY#oOXfx;ZYLbJXGnxzT_cYw+C2a%C!YL)DLQWK3 zx8e3Mf7)>ajNR(%OToIN6OKP#2S+~Nag-pp(dVW_or`A(%fd6D-eQB`4U%XprqjH7 zbCaI}|NRyW7;IK7)GcO0kpjlrSa~}4c8yAB1j9H{UCf6$JYfS=l^IifWURdZg#3Y1 z#MRlQi0OE3FfRQ^g_>_VblwK=HD?(j;Rr)7qiK}IHS-ogW(9wmlU;J{XsfN#djH*4 z3)o19O%2a6!Y`_HO7|kyg7mz0Q6F6jiT7;if1JV>7HqmgAskJ;j!)O*h*6ZAKFf10&KM0rF@?iNcgd%dT z#~3UjQ5X}l>?xEw$^w-+&6TH$;yS2q$lvw$x|-iqn;)~b=(+`_O&sv zd71?fb9e!X|Asw!ie@2bC)O_CgDxe7rTUH5@vQ|ruetgMZ9eQc!RY0^GL9Km?Ds#~ zD1MRVZ`(g3PubDq(&YSC^kL%V@lmD|+a(5`oDKc7gGI>bipkE;kO7LTT#@r-Q5I*g z1a5#XY4s-v)A5}%!4NPT4gqUR$Pf@-QC^LVu>~}Ku0{niT2X=_)hI*T@f7|+rLF$< zt(PnVzM$Z<4eR)^EDDWh*>$y?yE!hCn?1X>`tlzwA9(_Q=(>W)>y@}2+o_8Fx-1Kl zJ`UBPSaespwhaLRKpf>jR%lxmZCh1b;s?7Z<1qB?1+z9Jeu980IgCRk&Y5BH&Gohg ztQm^&cc;3)G?Nl(^M&Tak~Kn@kw%*%+!hrhwB2?WmF^i+?*L{GU3uz9w>4K&eF(K@ zYR@^9ar~oir{NS??dO)_DZlR>KtOuF-id-LmTto(HY(#o4~QV6AxNC3%8^1jKNngS zzUW5&ioL1+VOYUxvDlgremx4n4<^v{8=m#_b5sriDW35&CJ7F0*9IH6+#wrz^m8h~oy zy`5obnalLK0Ex)QF(I)0`_M>h5+bb`jX`|lM=ms~88{rQDL|M3h|Ut^&gxBHiK7%} z8x)tCMGKi2&Q_O+Y{PjptxA$UnKdC7whA3)u3^wtnNSr}3vK5iGf{Hw-^J+o*%+h(9`vEUTm1HI3gv8bS|in$iI(0bb&4c9pPZ4Euc z*cV0TCk$;@4v8-Op{85Aj(2glD&t-5*(o4Ygk0Qv{| zQQjrdX!uQ)NLwG|ZLZ!KFQLJB{gkb@LH@QR_d<4sp*>2s0Sve2GPuo1oWC&_+^CZ6 zWLB>vvSt-N@cRQ_=Bk3`-+CLJ_{32OR!vQeo_6f0M)uR7-&5$I`)J4I=kRq7_pC2t zd8uDvQ2{ZDojbh-Ka|j#@H3vCVleSF!3vA@ zN7AYwOw7e*=u&uX^z;5{HsND25RrU?vzc&b`k`e)M{W~7vHVj1AMMmThttnMEB-aH zR?F`+xGJ0(^~pO*vFUY1BOe7EN*jL58E=)op(D=ku=iy|CbL?Q^y86e;G{`_@e;Gt z(cl(eK_Qx(ijvc%o~DP|Cci-g)(mPV%)w5qE@TI&rj_4>?%$`7VOc$56f_`9%ILEv zQ)$m^&46Ixxya9(^MI`8X+{~4XQ_UpYgWY6GNtV>JBw+x-xf;%mSMzyOq&BSj3tENUI^-IP!8{KZs)trd$bV(|D*J`lDex{xIYC~}!g5RkPFy@~bv$p>u> z)m-70XKEmxUPS4!{w%;TpA9x~N>S2IU>@revZ}%%NJ~e9 zG)Zn}Dm~7r`({95B3O*}v5_QI?j){g>cvg*zCz{R9>6tanFn!*e|Gp|q0`v4Ooo5v zVHUnbeffh*b^ObngXvX-j8+$`nC2v@oLE#MS>^3kE2v3rQEn_uiM1FrNaOn}DpdGX zvy=YuAOHH^uM#^$-@hTjW+7KUlS7E9*N!UTQSMX((;vnTMKRX~Q;xWoX6M>E<>DR+ zNJ#dry>JJmjI$40)lr<{@nLVHK~0fWsf`N(0dz%vri7Qz?`>)s67+BmgyjR zN^0Pjr)rg;4S=J`ONqwP$8$qCu#QUR_qNxmrm?Q8wMc_c+j3@Tm%7(cf=+y-(pknY zCK$yoOZ`7Y8Ll2rzV>{xJae%wbiI;P&lHC)+1(m##uZg^(cff&{ex+<^_j(aW~3@L(6{%}`EE2n+T*O2O<#dzbH+x3Iq@-T#wUY0&Sc zH)y-KhEk8?-2{ZZP;|%S$#-2}v(ZDYoF}(mWGIx<-+2j8f6>@l+n)`_qhz#V(E|*m zV1lR2MRs<6m5Vh?5KHHfbhPAxU`jz|02J1wO(A9my1DSrEC>u&4sn~uYXo5Q%FJUh zcY*IPGxI*_)14;B^pf)GGEgo{5kwK6jNtHGGSe{LHfO%`2h;}%uNa#$vma_bjpX~B zZK){ook%~-@|e&WF40_=Zh2V~1A0jUef~R%=i2W7zq|oPcffyA zyl;b9+VQRP=$&k_Ts81$9dodvuhk;j3t`vWmrl>B-v%)% z^6<3N!#;Gji-_vabJ)bXPhXn|=lvTr-`TzS zQ`}EFbmT!AP5uk0IxQi6nW>xWtO?`9(TqeD#5YTJK$v6?+fLg0Dkx>Qf6q79^D=UY zi=|PG39hENG5ymPs;dqt?oTH^UCOXR%OUMr2sxw`Sh`pz`?bpc3V&XHQZ$^tkJgP` zG4$H{oc)(f@4If}yv-fn3>Df%XN;sCg?UEtr_XW?9dg=353q*R{690!xN_7_pbT4X z7EiPb{kl2r-kn)DiQ-|*3oLT;xfEWJ&6-ezUR&3rbS@hHLnTqlcOkha6iPZGFV>em zDMBQA%l3mT&B=Z9^{8Un<*+))y`E}2NR-Icq&gk120Jj+<{hf-Ws+`xx3R;^ z$G4ruPUC>q>C;0_XCcimXwP~WkZm=ICbexh^vYJGAB&-WchQp=M(lUNYq>v&nmYDx@I|*ht6p1bbs)-=Z9}6;wIT4!-TW=xr8oZaFZn-?`T98D<^E$HZC#U# z*X5@lP6>W7DSo7<$~n`vjB3z`8GBY&NKwaq4f);^OOs$(`opro(_iYta)6g$mzt%# zLcm`0y~caZYP~BkXKC2x$@|YKb00uEtOK|E3&Wva?^$&OC2WNN;76CJe6+0GBB?ax z#7+r1K_2UkgVDD-hrW2H0p8j!aHeegeR^&VWs|Bs88`z8RMm!Zugy1pN~qA@=W2P* zau?EDvng+SPCtzBorXsu2c_*G`Z831DLHzN>LiOr?BHyiVuW)qptH`?P)O!YFLqu^ z00vRp=g@914>LY;QNEvXySi=bFK6CR&Yy>-6*bcnxAe_Vyf(soMfdwDEDa&cvrk$BaY`#m#g z)?F@bc$2HD42ol3X10>zoS@udWSjZT&F>~noYalgT@Flfa#=FP2Y2jcz*RIl+ZJ5s;B>2*$uu^|4G)%*PKGXW!UXJ3z{*1`O2D-{+&t!?LA6A z+7LZ|;C)Znff#5Ss>3L4PR=s^_o^RQihQm}$3FV_aO<5M4iZ5D(_knb`m;*}adqQf zVFjEs?m1UO5{X}1d~+<=Nb~?LQjI{JwK9`Zy|uLAj2hxm?&fQ8U#apEp&%A)mOE=iX*5CAZcy zecT8fmWmcbt5{=Jt}6Y;atVp+js;~G6!D7deDXX`=Q>v;L8WrAgZY*fIrpKZ5OQ2| zMf3qWL8Gf;Fmv>L!#?j975@K31AAZqz$Rbf<-Je(?$UHx=L)GVJ=(!1QVoDg+@53F zm|fjWum}~AYMeUHI@mtY^C@M3`c^>TPdTg%305vrb+seIzura!kp7c8dDRK zoyv7NRH#U`Wu?((_X`|zp))l0@Md8f;=xGIyu4Gl7e@2A%yS-A~g48gkjOV%P;`{T}J zaTLdFSCyNY-p+4wLq4%k%C2x?3IX<^&8(XV z*mFg$X3tg3MY_yB=f@aQ%x(XSVu_}mQ(_n=r8HevT9wK2L*MQ){-6R4Fo{)bUHLwWL?tSKu*pImFN_LaQ&(4tC|fJJ!|lW z9N$3N{KQ0mXtq5#`$x>~Q4{gwGq`2r**9zN6Y&xm)5~8>NblHcar>ZJ|Ck6rzl(;w zdNc|ar4ic}OZIGEJbi<@=<$WUyK!Y#cPL$qA#u_Yz*Sl(>K-q98F0Re>z5PJ3+Mmk zL_qdku}?)G$XSfv4$rDPc~ki?W5nNL?(Syjkwcrw4oB^I<4w<}zWAfw&?2@3!te|t zV1w>xl_#hDXg0Hf4pg??SfrvXi+4!wF{}lioWJyZg9>2c>;`c?=M;*7cdYn&SNn*| zeST1eG`;I4<-_WUEcRDukQkQc(-MfiE;Y30Bb!;O{;RW#ibSsq4gR5HI_)iU4R3t5 z?K_o69NuNc1ymzn>w>=BROAQbj1~joYq&;J@hLkQ*$XBDEJfF0P{{=dCIsu8}0Q z3YaeLKN8)r9d9aYN?SaDoBAmSH)6uqllEWV$YT-T26F$VvuCP``FjbpQ>nqMhNa$$K zn{(qO{qn!Da2O9V!D1F2pwGqscqq_mT+%V+ZVS2WqaE1CEO*f|@DG$DrU$K?4$x{j zYQB)JU$mcd02n{x;|7I0kH!v@CA_i6@aZ5_!_I7!Dz^TohC=d1`X-bPfZY8Ey*c$5 zH`PQI(Ve>GXheYXj-nIKb`!PnU9n4QS|wCcAQe2NS`at$PN_l)YphC8QvO_Jj#kqB~LEXlM|IS2RtUTuNTU<hekuB%X7!4SQU6g)_cnwna7r4Caa^vd%v(FB zD%kOLd3mKLww9`rec0TRp2v=RVjS2UYK0E+xt)o9+(yMe=Lr0Pu?WwWSdz*88{bRb z*nTm;&P-a2xx(iuhNL>PVLP03ln51Ac5lz=C`QPX%S3#ACG5wtJi|y49oEr#TD&~i;6{YS>nfg0q}g0)FEb0Ur< zz)_zx_f0sKA$?YsWCG?mXsmpBCgC%dHC*kT>xsF4B}*d6%Oi>y&TdkJT77p%e^n5L z9p4tUK1zV&hfCcs=&qEnQQ}v@I#aY%ex>%Wo$lB(l$ueauJ!0x8k-iBH~V2cr#wgkGTbJeZPpm> z&~~-yj;_Zew4g}ZtY|=OpFx^qGTM~rVAA?=a6;8~(G)25spwpRbifJH5bpBCgrk`m zdS;LTH#AX~bos4m=j@qYoDu{(b&J^iMLT%0C(jWy=x34N2`xJE1m;oHB?p_(ne~kK zj`xEiU$9y8)pm)uA!Ux?{VmMj_S|o_ma>u#Pp*)zHc4TbD5HVY%6+d`|gT_R`hXF zcBuy@))xp`h-Q0Aer5;shGul35%mt!c3>`!`^JgrcDbW!|3z{&66(_(m5+a(RMm0l zgr<_ju8E8s#x5yesl;8PsW_QX4f-wVMw!WEt zvZ)^<-XEgqoPe8GJU#fD-}s>=mN^l7D}Bj zFwC_9qMQT2JNQ@Tin_>x~V{)R-)d&g{!& zo@CAQa3$8))Yr66dX}racF$A0S!(votl%mp_`HaF67T0Dw?)aXiIA>p;+>k=mhBRq z%xx00t5?HQn@`+fPFc{jND{6w2HM7+23u87Hq-O>13#6Y*i(2yYj3Jo-m5H1*IV>- z)Fi5VR=!xZa27t+i`QqIK}SnnKj%ZvGy7z@>wEJ|Gu`AM-U;utBd1XR2H41mvd3w(RSG%4%;?jz81;}H?Oq@aKWRTqNH+s2Cy+mlr z#yED#CzEoBFjp~a9p#a6aIuluVj!O|GaN$;v)0i6c8P{7RL!D94X|_{5@x28PZZ0} z=Ws9R=g#wF8`8Q zR5ZVExz}T8x;mRzy1*l`Zz`F$i+&y}He`hGB$$!cKE_nv5ha0R(#av`-bjtxD{zd7ti1CY^f(9c{Pmax^YFV5c$92(Dji)vaODx&5R5 zT=4N_ZFhpt&gn9lE=J)eR}=m&<#%9@eq>?JkX7v}65T+qZ>M@)Fa_K~a55IcEu zUgy(n|D?-|$bo%Tc^=2ucBnsMu=z1!>Xz2D=)Lh5&K&t&>LsQIK19)2ci&QCu8eVF zF$eR5tIA8mh6Q`lL#`_Hhg8V*I25p|!~|HR-7|nvin;+h1%3zf?vvhBUylsLH4pC_ zdkXUj#UO_zuX5DYicg&qUX^&8Ufs#@$6q{)7yfpn;>BTaA7WE>qk{u)>Xe~R#jpqQ z`5Q9*e)S-FSx#cSpeP9-3x^HEcU}fCXa{p&#C?~2uXnVz{Alb5mQgzFc3`g%D$Sf* z68$85H*`wUD4Fy6KXxqsR}9(6_kQ?w6Diu|t`{(0a&z+Lm+x!_Pg_Yu z!@5Vt(}N#8Vr*42G}pDge7M&8;CDG|DNRmGPZiNCoa6ENlwa4L+#T^z zak_@dotMdj*u8j;{g4TTE@#gt&;%MJ+CF&D2ZCY=_H2k^M|5l{r$C&zV-_VHMeD3r zhoQyqYT)#bR!4m~-Rk%0CH|{pRewHi$UxBLz435Id{jrO;O>>0dekkPxL2TG8bme8I&egEPg#f&^q+@ zwn5&gRjr0If2a6X$x6e*<~vy*L8V=(dQ3@1X2Uv^m|;UpUzF&MDkz^lHq; zwCf6a1EVkT-$wXcFW=#LKH{}LEVl9vO+-L_hw1W2w_(`A(M-I{-Oo$`N-_k`H)Z<$ zteCqW6$(ZDzspG&9gW;}blD6GDWwjE0(*=)P=L8KH7mRMZoBcn^?A3xi|6^~Xzq)~ zRaFMLO#@+d9w(b!*~y;p5VZDx+&1vkzl%9N#8gs`^NBEt2?jfKT4LJtY4WKeWY2g# z0#*b2R3xN0y2O#Iw_mtJ!{m0F(w1-|WLq=U#h-m?OPXIbZOtu@NNB2MJw?;kdSs$s zAkakFe0q^I;P}CqiCr5XBF8X}SI0VLywzuyeOJzO4^_<#<3;p$deWA-(L@E7ji(7O zTtXjlE3{P<8iJM@PPFOX4SL$3zA?fb#;J0~lX&>Y6EB&ICf-K=F6*W$t>7RiH{8ZwQ#2Y|*C7|aVlnkf*`^GOrb^d81 zn>gpGr_CQT!)}PRWOUROFcbX=t1>aPkVxjLVJ&>oot_>)B8r^X*dDSz>7G*yxlqwd zpm={rgH0jXPVv|3JV~yNgNMZ8XPXjlkBn8*yn@B3EVHOhi85|=N1 zAx|(tT=RCYJ+=_F3VWnBr*4Lf9JSqB!1dKuo-+2*`p3g7dOqlLN&UvByt>5JP2_F- z_38{JRaHkQ5WECOXI~djx2IZ5d;?-M$NMF88(xO&gVK6e8^KD}T(I#DS>Ztn@yA@Z zCv4LAvkIDox6TMu<&TLVihrBDJ+z@jt@xLTZ#A|cRiuzcw(?$mx*SmenGgF&jjbVd z6|5hiQgl0@6CsFbvar9^R}QNCb=XjG(N2NPkPGGDJ6qM&*Z1=-=p=qrzr>0qY9OBz z?owkdj~gJaaXV<1?y01CkxcoMHr*kUt>`Uwy=E^T>+<`9UF|Y32-n-+EBIPi&JeU8 z^B=a}OCy=;<0ZRNU`f_%t#*HP&;jX6)u3h{{1F@ z1CzM0d&w3l5c8f~8VXW@0j#ketk~uAO-Qtt9Syeo&KZ=X(71!Fu!1Gz`0T51^6dW@ z%G@E~llnhC5JofeY3wK4Pw;H{L_`?*kdno?+)3Hn?6|DA{byBGiewggQzh>$3B8C^ilKNu$E(;Mb$<}>mc@h-;x>rWd% z9Rp~J7g(_q>rO}k`q^UCH;vg0=%sWMX4>zQ80j@Qkri$WV#A7BYp)Nxf5le?zjudZ zUDVV2i%KL39$%9jY!nyCiuIFQjJM_>9)gJL!Y#BZt&w!ozH*r$wP#HccVf;%1wnS- zXCy5Rz>XyS=Tj33NGv1DU?zL4Dh6wYi=ctr?I0LyOua8P_6<|*y1MflNpr;8V~HaA z1$4WGvDlR(mUnFf*L=O+lDPauH;0~V`#z4U!{YnV^THTCmyao7+2htOjw7<)@atcIweVa`sxBeovmuhj;*rUfce}a~mV2-%X zO;YHL)N=kc7wArHS?58AY)rX;Fvg$EFN(r@_J{f27&|29V2J9U>v#c2=!Ab9FRH-Z zL7^l?{-&A*i@zm%Xc(`C9Ol?2MB5~eDAOx&|M}^lTjIVN`#O%%+%t8*^a{Of+O@fd z$VPfpQn`|fjGQ1S7p6<^u)I8xZ=$k8+nc5S@$Z9u!^7K3jiM(~f>$UpnwLl}o9~Y_ zIg{=3*p1yrd&1URW{0KD`wn-{|M3rV@rE=A^pLEKJ9ry=wf7_?H*g`3m+57J&9W!l zHETQZ5W@ah;*zno2(8c& zfw?PJEN6NT_IY8a#SvB6pae3$<-Ew1W*L=7+S~bXfBt(<{E#3L<-VF>eE&3W+m|k) zzXzpk9rOCQ^`3!}^LWm?{dS1tE^j;JFdeyob8_X{%!{ji%%lpOzt>-P&D%$&G?r)) zM_iH;Yo$b9PY|2U$&ie)QDpV5tnCqxeTe^=QhN695)Na=K(Qkak^5uE%Z{1M`S0_S zc79@9DnqO>vy3D5uMnx9y&oi?Q;~O{JgDiLOxB}EOOQl}jfG+{f$fO@FkvqB>I`%7 z90ZlW42~Z&@fitzK6#&@8-A{UxKk&Nm>NY)4q73C6}XV)ZOK19i>!*0CD~wfOwEVR zza8Mc{{vbPf1Uks$2q#`5s&h@fH=A+g8cP{g0VS|bXP(*TCnQX{m4Q2>g;U`vc0Bz zPGNexUvr2lh;HOH#twO!}diqjx%**at2q3cjx zks79K(FW5Bn5NVv-nG*lgqH5HJfg+zIXHP`EEt5 zC77+`5p|q4WL>oU`v$_~hD2rMlHp!#!#oiLMb`FVn zG)&qPm@8O^C0On^-$rd3Wa9F%iL62C1mU+u>BIE(O;Qy45Q(`&)uhW|oIC{Sd4KyG zHA6M4@|=VQ8Da-9Q+)X$RG|tp@C+mb+d{kpc~5AcJb7@}PB9Tt=RgJ7wGv(4-y8Qu zdrtIDDJzqU>RNmpVNK72@Xf>HXZPl>6lXXx6?({HxhyqRT)DBdYBO&Uz1oy)W#-T1 z4ZQczm8;u`>gFR{%Q&Q$>m{-S41GUjap*?Ba8)6~MZ+hr&c_qnOk&|+C!92$jVCi; zCO5FyhEFBIo85Ku4V*`Yht0D@t{pwsS*m;T*PC65y2uC`>>i!M%Vwu{EP;tGT(3nJ|^IGYwKFx_+-Yd_eyN_7kp5?bkt$ z&R5o&=CEqJ;3JqB<5tIE(vXW6)T?syn7b$P`C><#Up&F2bc7?2vVg{PR)d7_7CYvQ z5O0zQrSa~3w&RWb{gAJ}uJ}&|Xxfk=5Gb7<%a}CO?(iXmq{z`tyAjz^f682%>B;mm zbLZZlvkx23RpvuF8;X^(PONbhU##T#d)v7N^E0`(H#eD47@@wRkKEzb!lyz@RFO-8 z^Wo-qjde`jK&;oAW0o21o?K~u^VWmQX{x6E$(<0#JpHaNO*U0!A@H2!&5}NqM+UxNHZ|UcM`NGK^s7kx@T%H)RKxj|i4pwyF?t z^ws|2nm5FtZGtEKB&~wPi=)5G3{P^*&-P8$6I%Nwxd|p6F$E_oJ%zWme>{RMe;v?? zzRY%NlH%9=*GhD0?m0dy`hG@j^uDAxi167pkma!cG7g8!R*W+^)YYmdW+If+6${{W|t1y zuO16rC5oziT(F_sH`Da}clF^|;%ypasF34Ell0=3OR2Y!JBU@C5~DjWLB?g}MTaq$ ze@e^Jo2XB{iz{k+F(*@I;-(n?Y|UEoC(W*$$Q@ znnkAW-A5y6_!Py3MV*3tWygCScYJxvB&hqCimTeTSnSx!vjhx6AcoPuSnJ4NNe&PF zU6p8J^HHc{t=xytsS%r&@}*v^4SRg|lU+8Kswj&Je|iG0P6TR-OxT3Xsoze9uY&5`%6?4Gbsz4cS41%s zSC+E(xul0m3Ot|lvIN1g9idPa@sX)H+B+FS>Y;v&^W02zel}ILgkmPiW7&*a39F(S zCN~|cZf@ShFY`Za-j!8Q6(}vPM%^aG4%S!n?OR6j0Z~sr@T#a9NLL=)Kg#HwnuzUziglK%hi}x{c(Ni8 zJ=fhg79SZ2RwT{y+M#55D>O#eQv%BJ$YFMUiw22pN=wTVt;8WL1G4NK=GI{K<-&7i^8&zb}#HWt-L3F9o(Qm1PA^ ziR_=nMG7*48OUEi$95hKq|ZOHP;gqt*QEE^$k_8{Z-v_K>vh;(zv`t3daQHsFgj>~ z>?GPm>A9zM(eJgW81+sUZmNC3ZI?XW_5XySNxx==nrd#C7wgs!E;9>ua_usFr5;#p z#qIter>a+WxxH5WQI$|Y@u6Li{q^N&wP7h(WQS3)g*Zf#+PelmbEKClb;cyI%9LaM z=tTW+bwS+A$({w0j0-N&QcyBQE-o{fWUEt$3T2UIgX($js1bQbvE_1J3vf)zKk2GX*y~?n!btddL<4Yg-T; zG$6tB==4%<+47{FTXj)S?&_H932Xs`+!O4w^q`>iJj3}8k!IQ-%jOfq2>I6~8XFj@ zD9>hvDl~`Gz32u2KMML25du1hxOxIXkzIZvW^FHy=C(|^<**>aIx&gYKgsK?2Bv?I zF){DF{QIqIrwT{WL+29T2|2&4#q>Jtj`VZ(g%GR-IU%;gv%9+`{x=lAOGg=NzS&uU zTg_71@K>;1(NU+oRkI5%)Q|LQqjmii42L+>2vY*T$Kep`VdFy6k!P>xS6b=2oeaAp zr4t*Sm;ix|sHj8Li1VL#+-Z7on01j}i~3kM%gNmV8apCU*5=#y42 zHDgNSQuz(2&;O*ZtWl4r);(2ECuUc+yWzgi`BDZLJENErl_OIf$>;g~hQ@EmY5Z?v zHN-y(4lIstKdu@E6}gjBi#ndZ^1W7hIs&z`GU!{!n5xi8`qR<{Tmr?#q!WH_|bP?1k!?l9X>Xdhr(E@w& zj%z%im^9~7MNug~poZ-U@g)B6hR*IJX}w;FGW2~5acj4mpeh&p_%jm9Wn#=6*aQp_ zbP-}AsjISgkAPw#jfIi!fu&#n9P(-F(mr-Jt!l#LmnMDk{h3^`wah_=e@%FvvYZAI zC9PNE-6xMxFvHCnejhR(;>`+^LSSDHk_4Z25<@1Z;2Fsxd+g(Rm_`XD{D|F?mT~p4qJ3yv~6WGPVw-iT)7Cfa8 zZbNQ1d*XJ4C!a=J-i~(yvxpCO&pP~50qDtSuAzksKv1e)<9!yY>)-Xle zBjh{VR|Y=|b7e5-+4umymrc9XfM6|7L@(;+NGv-#9-iK@DM~zc_b9M2r76d8Yvof> zGo?Zr@>}E#j)e&dzVVk6aap$-oTM>m;8o9lBat2B6u)?)bA zTyPSlG?Y(YW(mHT;+Xf7T_!41|8DUEu9u;gvq6${gwUTnrP7O$__FRTeFGGm2ay&t zy_{JKgX_4(J{~GK)JeV>#5usMcbrc)mD!N3|M)S3_JAB|#V#81X#*7KRu2!_8n1L# zo4zE-NmpBBL7a?*OjFG{^V)}tDfcT9g$}7$e_4%a6*#gXdhiA*?->_CUeNFb$^}F*0`V~Jj?WxvE zEnCNki_QelWx%~6&5v%*L>v`18A>{7&avF5P}?)fVPzUC7-$+4mF#%)gC%Rio5FRx^agnM@cB8 z&YOhB2lJd+fR#98wjQ$4yL>?X-byldIZ?|BPj{M?XAMu^ZI$y|J471`Q{;l7R$?;> z9`~^Jr;;)SMR9xFWvx55GDGk(i=Rdun{L6A*+T^mJ=ZMtfH0*shbeG0z3?Y0nuybC zs4K|=@_|nWU>sP4ZBrXQlZ2qJZ9OI7Lo+igJr!~X?HY$+5q5Fya@YK7mzZRV#TmV75IXIhjNy~?XzSXr-Lz^$t$FDSia`}n<3S?^hSx+j)# z0Rwl)Y338}${SoP4^X*s;+*bP;MciNiQC07jFHiV;Dt-W&0Iy6|Jx$eHuDaL3-p2c zuW9>W3$XYldTzR0xdnJ-(0L4opnp(8pkw2>8g}nmPLZqXr{8Phu}dTI7umP`O7+8S zW9f(APb5!fmggBwu>=I~lp1|Y{P;ah-~RFDNA;+`gZ}t6ih??9TNyiX!-=B=YN>Xd zUgRcjkDPX%e6+|5^KDD+(hpEXvB{g%FN)AGg`&;*t3SB0^NJEqBvqJuzYIc0Ap?K$ zSoVjoQ!sqAl{8Me$Sx^G|KkIOIRUkaKG2q+@C47fVrK+U6Nkh5hqu2BUULrY84544 zP4gqvqU$b5E7DI#O9aK?_?4uj-B{T%437q4vkK^}L8wD<5ra#RxfG{0H*2(2oR3KX z5VBq2*e4AeOECW{!wqR>`=U%-LRB5S#GUNZfXAiizq`jkj@C5Q;dzO=wBYOHCFoSh z4Q9DnLVn;P^=y+AF-B-JtT7`SY_929y_y~6E7F=Y)-C)Rvzr>8Ys{ zrM&MbBG8Siq5dh!#iekvkMWRz8O|wab1Y_T`lE&tc*pgoRa1>cbe8G$^9S0jvEy+* z=Zb1uBBlkGFV$7qAjd*d^svwz%PaH=dn|4NVJv)v%k+PmDdU_KE3XFWx5IO~rqTRn zXZa|{pplKNg$;swx5l^~?#?ZoO0Yhi!Wx=}>qqJn>L1SoH0@{+@5AYmvHrh)Z6|7v zVd2Z0tECsFKQ|cWRou!iI8!#`;%C{=D{kz#v~az^|F#cJ(e15mLkCU1qay6IlaSVQ z*Ea_JHE13=o{*RK@hCPxdHeWHdxOKir%S7N)$Hf3y_AC5kJUf@OpX{vReQZ48yx7% zaD`}R)_&C8w^ut8R)xJ~Z;%Od&29Brt%LzHUoHRt3(UU1*-2|?4WOz!ETn^g;pL7# KR__}6`+opC#zdX~ literal 0 HcmV?d00001 From 5d908f50f479be127551c208004759937305fd51 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:52:52 +0200 Subject: [PATCH 131/183] Add files via upload --- apps/wristlight/wristlight48.png | Bin 0 -> 1859 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/wristlight48.png diff --git a/apps/wristlight/wristlight48.png b/apps/wristlight/wristlight48.png new file mode 100644 index 0000000000000000000000000000000000000000..8f0ff59f7811dad27ad975ad452626d89aa8893f GIT binary patch literal 1859 zcmV-J2fX-+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TD&%c|dY11Tak~XcBf;5ET;(!Q_T!iu>ij0>Rb;c*2U>F&|8IS>WP(~R=g$JZ` z7<}=KIm)+mA}HHah*LJNuvWpR;?; z=D(cX!Xy(6kkQ`*rf(V>Sv zxQm+%{wagmGM~;)Dg*-1A*&TJBtTzNGk9b%sRSr2A;hL5V8*tR(tvs>^m-_5$974j z9;{f6=JULY==6p>Q)!t7&(VFw=kW8M=D zsLu!eE;rmkaY)w1;Rnd3tsD?5wiP810qLrl9z2X~skpe9U%!66rlzK*vZ|_TNoi?m zjase7Vh;IApjjm0c*dZ&H^uIf)I{{19q_Zq$XvBmro zfqo7vZQIDRw`5T%(i-~16zit7y=&I2(ON8)=d4!iPMuD-68nY8XlMx3-l?@{8?;^6ozYwj?hDQmwhOmeJMQR(kXCMH0_TTt!IC9Q@{LC0(%G|T z*JALim_F8>fDpp7KD0SxGMSb#9|%AJc4ZVigL-K^*0?hTs$|%Vg3r(64Fo6WXM zqtUS8mlm{{iMBhLkD6C2DyK&=tbETn`;in^l;-1jUx5KBu4K{ndFE45T#@#LNeNje zV5}-HDlaczg+oN~wU{mQsWes=$*OUabpjflR{LnR$pq%3LuXkWH(4hjN)jhYQpWR# z`A88d>-%SY0iVkw_%q*$_`40O5=;hUJSC21z`3?wqH&x%tGABS-e!zkk0q)o@}u*2ip^ z?fLWPJv2;3yolnV_Xrw5KbhgHhxrV7^MfK#S7TerszL`qxW1Zx{~5Li%w{t`Z{9r9 ztXZ=bEMB~L#exM37UPCh#_T*EkE6A<^%By2>(;H-YuBzh`}_M@5Jv4u?R%tz%*D2% zds08W8(0SFaMMC6l|ItevYw590u|+EFqw*nmj{o9pq0z*g|04k z&*WY=16li(RVsB9`wStyM>gJLEN0vGk+c@soL8w?H=C_X~r zX`t7a%hyTVGzh}DD#I{@R9Na~5`2`XPbjRyhLW+LfY}R)STnwHt}&UwMDzbiAOhix zcf<)JoQO4^z-g#=ORO@;btnzNvEyD@N+e*1yIvRcU6RGz#p!H=d-vGCcB2fR1HM!6 z-C+ueLMaD{z%Rdki|3RHguj5zC(gldUtximdr9Ed4NXn8uxso0o_6<=p6GsU?fqWhYy1g3`VQUln{c?66a-icPkwHdI!Am z);Fki#X4i8+QylVeeS5xgV8bv7MXeAM<$98+6nEQ9dP?P3dT~)3-dX`Yhr!rk*Fv* zdQY}t(+Rej)i9&F0w3|{SR$ebEiEn>7;vJ*Dp2-8H|Z;Cx;ljQvB1;SNNlLFgW0lw xyrsL|a99v*7_c+Deu@Vahb@`8JTJ2W;2--p$DOW1Az1(b002ovPDHLkV1j}@bNB!N literal 0 HcmV?d00001 From fb48fccd6cbb1360464c8794de93bc3b776fbf49 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:03:24 +0200 Subject: [PATCH 132/183] Add files via upload --- apps/wristlight/screenshot.png | Bin 47586 -> 261 bytes apps/wristlight/screenshot_red.png | Bin 47586 -> 160 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/wristlight/screenshot.png b/apps/wristlight/screenshot.png index 0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a..31850d1ca814da33ad24c5551b36f3a1539285c0 100644 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^8$g(a8A!&?{Fw`+7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0(2Ka=y{s%I^_&>vcAb=1>{Wc(DISV`@iy0XB4ude`@%$AjK*35+7srr{ zdvDJj=+*N6Gj|4v^Z`sRPawuZ#%Z=!RnS=pKoCKyQYz^U}6 z{#R@2!ZE}T>eqz-&k5mOe^tHs&5e!8$NOZh%a9l!O^zqq9GzX9JA0$eL!cuVJYD@< J);T3K0RTc%U-ke1 literal 47586 zcmeEucRbba|Mx+t>|}=|RQ47!5-O`Q$|##-93wI^j*;zI=2XZIAN`*p$LH#N0VVpiNVjOoNns7Kp>P& z_&)?~j&Ci%KQg*1KXBD{v~qPfeQXJFGPQAV6>zY0JufC8Bp_}XBw`7HRB7M3p{V2W zXf>5IMR#DJ&avn&U$L3vdEFDr&$%B!uUvY2>FtA<3-|agT?oHKC~-&eEWw)*>Xlk| zgz!Lff?4>1y8Xcm#;n#k+*kOu*+<(j%A+oF(fugx2^U`~qL4(d?vdqjyIQYwpYA#A z(IoCP$202JX)&^wo>5;9{iv~(L4Exs$C5;QAozIpcJw0E&o4N{{(ts`x3WkdRh=ju zFFl447n&!@FG=1-tW<@D$Jnaf6@NjhJYo@KBNjS*-c0E(M@{XF8=pb${*c7XzIMkF z={JMb#?dcfqrIa@=;r(7i&Wv|VK?HJ8d!)WBqYM1j8GjC#4^*!^1cKiDpDewf40l` zTd%gWzOhH@##1(#==3%Lx%8E)oDZt~MkSjO=7zLodcEiFrnk3t%+42YqkCJ~>R&Kk zzan4;dqLV_z$&%YJYwd5^V+nSumpuY{jhA2GLv@&TTHDRs&zEnEsLUd*2}u^@#Fc0 z#%`~3rNTSIEzV!l?3SM1=;UIlPkLQ0b-!{jW##J7{TYePgcj$(;kg#!NDTt#x2}B4 zMD2mQbkEM5m`#-wKp#j825?Q=+t^#$vkr3?!J6G(pKzo?g&<##L*=!`$_m^cOS`{$ zAv(!WC$HIBlhziqf2&0>%5VvzygEHP$n4ovK7VlGefeP;&y1aW%|lrS=am_B)h#EN zDd!IBlNKZwUXU)+p1d%{IuzkM=1FtEuB&>S1;I>lcq>ao^SH=))($(7y*ZAv|28MS zu*{9Xp(i^fjtf6`!;{3YN3S%JY7U)ax$oDHdc;m=`YcYBU4?1o<|uht3si7!f zb1<@nv&D0}6;Jo`$2Ow7zdk(v{&MU+E-~ro2%b9<9U)C7%stqgGMwd~5p>;-UjW19 zIeULyOlo>o-ce{fqFd4fD{m~0{((ET3oN|hTZeu9$q{=nLLw*yKhFO2g-U+dWN=j8 zRtU2@Bq{X`)sF~B4jk^U;@Dsc$Y;9Lew61i$O8^ZqzG{}X!aAj7sV6Vv*YHYx37}v~E){ z?Im=ijyAE{SyC&VP=7^hZh^|DX38Be!V=*jvzYp}`1IKY&s3Patf0HbJI2sMvLpo- zMb5ZhgF)yEC8TL{(iNlEQkbK!B<%3LdJ49~-Remu8DDP)K{JzPs|IUNA;RWCYvRE$ zM<4tSt~)6`uPwa*5u}t8;k!(&qMfsI`7p2X;=Aa57V(e$GoO5}lk2A>sHs{fN?FsE zFu;9%tE0O*A0}UcT(6NAzJIA8ZZ1Z?w*HfD-i5gD^2V?Y!I*TNWZknJ4bkwPDT@eF zXGEuhEUzEUB}DOE$4G@OlZOE&!5L3g-)tP!nn>G)X-gsvE2o1~v8e3LYs`y7d~9PL zvvTz5IVvd$VOd(Uajp;Qg5fT*hL~hIDX}4*ICPLx&q;$*NqKJv(YQ*q<9@@E(YlUe zfKCi;9OppYz;oFL$s7+j zple;Ha!$kf7rYP>SNqJ6S&F$_z28j3c;~xht{5Lkwhi6>JjoIxBO136^f^GUN4-bW z(;&-4C{_KDsYTT+OQD1mr=jb;pxbBD?a!IX;f_cIRaE?v?!?o)jpYVfL|%VR?mj

Z4(l<#_SRC=NP#HT|%7SCzUV-bA+ofbKjyW%Csr7qKC!IoFR% z9~~KboyJVJc)vn`b1OSI}0R|(QK)9Ho`lJ>{gLsg3g7pr37FH zrvgkZRFCDxwW!rp{Oe);&?Nf(fk)W!>`iNWRk^{^>Q6iQ(H&!N`V?nrm~h?uo5xRp_5>pGPni@?Il>Q8 z^XOGcs5W5)W*V@}*8ap1zqwB+LINT0{`LJspMGPJad=ZOi<>Ep{=2uKsGye8^4^Y( z7$%Z#R_WBf*>z5ly6APs)Z07P=ZHE_tj_f%MPn~hgJTb7Sk}#?UwQD_BirnGbUw`# zvH>AEFKsA0J4(oglNMzGCdHC5tpqvwtlBxnVDT-kKqWb{=WYF(iSYO+)Kuu(j4v;D z_kEi_;lB@<`=W;WKmi=h(x%f54ir$`ypnNOdpE7)+|H~6#DB?8C5@JqBbl)lGX_X_YA%!X{_O1<%%lyLDWkJaxaoB)kK?&~pfV5h?!hPB9Re(_!j z&t6IY%EhrA2X{%qy&|BFBLtvfQLdLp@ME6%g0A|#7S(?8dz;~55%sjmezcmG4$g)a zo-#>2$xai=POmeoj$fXb;w*ExDqm|iO5ifKb)CZZnBzYd-k zO0Y4iAp&{gr!$sPiI#C7#2)AevKwL!ZeHT{8&&ETfIql{@V0jXiw42Q_V=xi`kcJS zf`hXa-H$Syv)<%2o?jx(Az*^s<pN^z()SP`&35o z-LDvT(*C!*koLey60ykX{o|p7Hv)pvi2c|M37iQmQLoO zuR3qKkDaK&cn8Mh5UDF*c5d1x37*auE(NO$P*9jztb^@vMUSM^eIltv`)uUBKEFhj zL;S~X)UO2NcSGJVWGsfZINTZY&mkTnf0`E)K^RN=o|d_BBM)A`t`*qpy6a+Jpy26?l6OaK`wIZ#E(MSX&E(AUDeW0H}h`Q+XcOfz?#fIduqgQH6vL5%s?{1ZXx81aKO=Xx}Mk zJBG&Ua8U2k_B|u_drJ>IFpAvo5*M9zC|P|IUjw`EkV%+LfU0sQd+RwYrmc&kNH07F>{*`FAny4a_J$%DWZdMZAi7xF9`9;U}X z&)&zW9$SX?isg39Iqmm$GC|@GSv|TZ90lCLilB!^bgaWQi`}X&kvN0imltm*EzQXO zACs|eq6nEN~L@^N0~)FiQm15LC@&I?to6g&n)wO_H9ZV!*O# z;D@I9G;nAHEX}MznMv-jZS#4)vjSHZu8rA2Ryb}a$Vr{&A8EY4o;?FLyHFg$5-FOR zk>^2w-dEZrRSbgdfWw#4-PzVc$_^@>XBV_@8J}!({bR>h)UV7tZ-zu;`=>7V-QsOZ zCu^W}$_sl_&v{-~DME3}B(s?R5oVzqvk-PuDudpqpfCGO9kp-{-5;_wy(b(UQQub& z|De{RfpJxEKxlKmhY6eDAMRwp9jM}Nryn?$`P#&42xxG5bC{{~{p3$}3`E>i^vt6(i?}EBIG_H?O|raaf;S>afie1^PAyvWeiB>Rba zD8@}yLLXt1@^KO%>x)RsT->5m9XdK%X(ej__xeJD-andcei|F@V-LY&QB( z868*!@DZ{w;GMVw#v99a5-2G2$_QCZ%g!IN8cfz%F(-n|wthcMe&j7|vLvC9Dh%0N zf@}3~rOtN-QxvLkd2y5^Jo@KdH{N`1l>?{4lujnvKE1pwq0l=-aFL4s^yo|o4!r~i z36UO-<>&{t{_Uk4hCgI_`QBzU1%QFkDc`<`<*$xJ&Cw(Rhf4lnm&81dPJ*1iXew=1 zbx)z)Ud4T!va)dPpO6(34!4IiO8fbcwjPd&&Wn06=RMlW5`CNNDaXA8 zt3OY9%jUcUq=Mg8=mM0KB2!pQ7q$!mTlI%+9>dpcn)h*uTf+-=!7N(;yJz>uN2iSX zBJKF9D9`H}lPPbRa1?b?C}0k7Xe|6FUBb5PQrwTAo2E%I1k?kBAlCw)aolhGhanjB z5zCla(q%hVg}V%dz-|aNQJ)1MJKZ=J9DGt<%wY$5rI#$GQ4IL!Uw-=Th8|Hd0eZZU zMHZT5r!bhm{4{cnD`Q~poH!Ba@$g#1i&tP|b*40BN9*ep~!H>EQK=yjW zEtX9l$Zhy>VQ<%ui$v!KN&6!Iz=kuISuMyRADvT$Z>m`Lcf5w50ZAUU(>E2&DF}$R z=Wfdpn7Cp;-kODHpQ)w3tS!;v(+(1I|MX5)*G|J?TpbK`B~i#{$YJ`!ODs#IZ!$t~sgTW5 zh;1#wMhIlHN=5qiq9B3D$2b3Zpx6P$R*0)`N&VSSBfXsv0oO^RV{}z+uI7aw!y2URpw$ zpZ*u=y$SjZaTQ(4CfJxfkst!O_ER@M^E${~onHyYTanBBFU=u6@#KEgl)s!vnfOq+{%;mjBsm}RyOaX%{m0G%$Q3U9F6@98hvT~s;0wCkZ-|-v zZoFW)zz$MRkcyn8`xS=Ysow@EVA$`{2A^16`Sk^z#Fz9IkTZCr{ZGMshFtus0RNwZ zxB-;`_5P1W{>QZb1dspm5qul)-w^o!#79cyNKE8GRh6%Fn~aIb54hj6pDm?-{x760Rha7I6?U~<3DYPZQe$sq>sL`nQ&7cPuJrW}ALzrh#7(3AX`m&=qz z+`bv8{RPbT40yjnT;m9+_3s&kk}C{lqz*&u?fP#KH7J)%WgZP_FvHV8^Yd5lnUq4e z8G=b46zKB#=O20Ah)Y5)+DJlRkv@nI#y%5Ma7)My0Km`_1$c}V)8U~|7`yx94wtrN zx|joI_MZ+e^s~%uiObvTPs-hV*V^(d1aHun;UmkI4aH|W874300*V(NucGCKr;g-4 ze&s&aai)Hfo=<7S4#mf;434sAIX#2(Dj?h%on_7Izg$01H2v+L<=0-;W_etXirqpP zu*4W9{nJ8!Q_kOXe<+E?kFu4(u@3pkj0r*$JK(=egx@d_Kv7!WAd6ox3B#ur3z^%m z;*#yf#N$@}>i7>{e)Z~Qb^f`OYzfFmHMgi6C3X6R-kbs)Ye6s2k z;zR+ufLm-XLZerYHfxUwQdHnyT>ME{NCb3G<0k|~Da9y#%1xVO?hz~W8>iV0J8_^+ zGH+hiFQc7|RW`h65y@@*bqJML_4^Cbm+$KqIIqW#63fjtx1FT&{T@US|6P>e`4#5Z zd$Hl-89_Yk$6bVFG-5NN8lbqT8cZ;qQGD9pLz2gAcoNh&1UxW%3nv;Q^8N0aBTHG6 z!0wS5q!*J9kA3Adx*jy|s&$0_9zv3U5f!vG*P{1K(sjcGb=TIRaGO=XF?7B9mtz54 z@*Bql6dA-~G-btd2Ilk)Lj*!kzS{f4x1PnYTD{(HcCIQ;_a2_QpBDf+Wl#uzMpy=g z*i5?EUkY#G0aB3H*xLG=Vk)}-paQprr494O% z80B|2Lq8IM;cmCMy@z12Dv=`D+Kb+k2Aeh_=`WOlj-IJoPcI+ZtZt00Scfd=;hfFZ z7>qUAePXVh5l>(DR?F^sW2F=sw(HX5vVX=)jJm9-&VUHJT9K0Q(GuBUO<>kE(kA7N zMNB3hbkI_)VVk^IFgp?5%ou*%i#Nvo8ENgzG*@~Rdam1x`RqjhvZfA^1HuLa8we&A zGS(F8NQ6EOGZve5NDPt;VRUUJXf>IYGEZ=R;auYU&N<2XX*1JnJ?ged#xrVWx9!6= zsRI*ez3}tiXVn$}OT3klTJ5j-rB6%G+NBN{1d>pw=sZJ6px$1}p5Rqp8hf88Wz{m6 z)Gf8?(?O5s^JCGZ_bmR9(R_kYm8p&KLj^5jnqBP>$k@InD9-ZLhVk z^JkorOp-g)>J-Z?eeFYtFL!|{6nXf2F;-fo3z!FSevo$i%J*%nIg-{|I*LT*n-nUe ziOrE*96C%(&aB@r7s@JpG2ZpLIfa>ee%MtY|Fq}5Bz?vDuU7gjpkxSPUA^2gtCpSY z&}m`4=R=vMO~E|5(6P$R%W)jL2G5_auN*MFSxEbcw0%8nu&obCcb++_ivC(aq<$iz zdhCSIlKE0az5iy$B`1NDSi7z#Jhtp?@@9+DoUP4CcqvV_u)}~K2Ur=|$@M)$_B`mN zhk(&eW)XiKMZ?SB=nhO8leRrySs1NopOe^Gvd2yft~xo3&<;fs3NoqpjLZ-FWlNkd zxJA~5atU)Gn-d<;x|l_i$Z}*+hz00j*b<{ZdnZLcQ&*j~D;PwPu-FS-Y-we2tfAKn zjV3!cnSCoZvui%tv5wNvq3V0lm*-Cl(6t_p^3f{?Z$1#*8!}QTalVo>C|h_C8Cxh5 zM!{p%r~%Qg8{2Pj5;~I&4t4ez6{KCJ93YF;U-W#IidH|oc z5_4W_;*@@#OPtKFY1*7}^JOBBRnFv0SEK7G);N{yJ~peKBBy7HN)ad`;cYa{Pg4>u zj*>ZLaNhqlMfwFLQQ-J3oFZbuBl&R#rHxWT5p;K@&M=GHy1p!3%t@vU;71O>ep!G- z*%mqPAV(d%B1@0=M%kBF%K9|pF8CtQ<(`5QqH?72g=nK=OjUfpcn<2dpU$hnnQ}-1 zv2Paz&#AN<-8zE%UgNG?n}Xp1%ZS92UC{xbs=`sE#hk&--=3&MhLtC)i}}&d%tY(; zkfRip1|$wcK=;5b8P41=MCb$$yeyt0gZ@mE%0HlwzC_9Ta`7s2jHX)Pb zjM{5o@5|AM9(HbHC2bI>UJ;>ooAlY|%+xQnQdNwg=O?*ZU|8`;a3+0sXnSaXe|vwy z2vdWRJ+3*Hp0QJV==Bcq?&cFHelA}U9NVlJU>*MIsK!D1V3?uBFVAF%MU>{l)uGh4 z*F466kGZDOn44*Igk57+AcI~Iz!vu!soCWv8QcUO76y|eQ!r~C5sIVdnXfD@+6W$~ zsC1U*?t3i8mKta6(&ucWb1qIvDI!VhoT%ANzOc*1yOh^|t>w%UM*G-J8rjUXEsm*f zwS_fNNXiQ30Jpk^cx1x)$2~bB6gU9?+W&SEP=q%Q7oU{QiH|SZlO1OWOv!v&-Vs2PZ zEncE$h*C0>rnJ_a?bWxrDJ_5qcggivUJV@nw~r8%H8e7UrDmS3Xj?2-T3}hDh8PR< zO_$I9AV)BZOE-+zmv-JBwtZjlarkr9GBD~{RL?n# z(h!kSo`a~eKIv}=pPKCM-eRtauNPSVXb7z#!b7wX>i#T2Be)nhtIRE;&W~sIF zYf(&LaRaw{`VClv0H3F&pELG6}{#& z=G?Z+ChZDM2WGe{vzQ%wnC`vR9+K*Yvf)bcJzP|cWE3`oM4r3)I78H`BcVJL*Il0u z+-zFh6E+dJKXc8~5!lysij-tmjLY|wtL`8C?WU6|B|gO1eNQ?*w27#Mm8{0wj>=lh z>ZBS(00gZX>$bf6s#`W@C(+boCuGrN(BI`#sFQyP&e3Qi)6%_=3!>_mS9Z9R;ZXYbnnn9ETr9D8sqSUDBYBv7-_$jPmhCTp_PpGPE6HTS|F zV3~}F*&Vjq^&#og)}9oPB8KM5J*g%l_UCG^l6D2T%#2B?cE!2Ok5!R;2(p_&RjPc5 zv)fzF<%iOuxEEkq5E(Kd?J{qAO^op{gY*0>oMg=MLGZ z=9j}yd!x&P>3dF~6gcSy4TSL{B%=qF3IZ>W&PDb-c)0xG>Y7kmhEJIaCn3dc(lg}@ z>t_L5r#`-St^Jn`=C9)Q?%T! z<%DC$uOkGcH)bLP<)DWJH{VIeq1?I7dOoARyaXJll3Sd5k+ga{RcMqgX>y*kZSZsv%u( z@!Fb5AzEm>>gKs%ZUcOa}7u!X% z8lc?>o(d)@s_^T2j<5I5EJqIivQd15c!ci#{M4qP2RJsZfRNE!!3^gi^|lBZ^3-oK z2p*etSxQ#@ezuumPuZ{ncSajUf zrxwq5b!BhVQQqwPmpG!xthLJ7C`ET5?p}8gTZP~26-e);d97V_0IzLpN)opVMh(%P zJK7JM!qu(U9R&xiUq0|X@|21nn!#g%`N7tAB2TS}WS1!;DV{Eb%bd|w>#kJ0DT7Mx z51r&1EWm<)i+ORP_UJ&oS=2)LfM`!*`WKpjxFK-eI_H4XMWta-iWmp(a{l;KaKthPAj@@UFT>-yU{M?^M4v|R;r^`*GPxr z{XbE*$_?d*%+Ls?Wc|nqyJ6UCRmKXtY1j&5sqnnQ?Qf4UGJdYn4CT;l4H{%#j}a&Q zkmp^c(JxnWm4EPIenkMZfchep9)pnw6v7;EV_n<&qGkF!UDZ6Vx#df8#1SOkw)rNh z&xTGGes51X^QRP1%TpJO;H zm_VFDGCXv>+s7nowPK>|w6I)Q?>huCaAzvssLq1V6%UHdlv!9{6{6B(aNIF#K_#1s zs~2XojjC+MtB7uTqWjvuk^F2Z!y}LBo3lS&J$kzM!2HMi!aC^=Ml8y%FxAXhtD=ze z5&U>pbafeeBt4IioM5y|p_n|H*l!&vK6M!_kCXFljY6C%{A7nXS=i}CzVLqxSieOH zWkH1^Uw1-fP(7ou$X&NCB>aksibNEfu^_s6;>jJp)Hhqq#GkeeBr3vChy}53I|r$U z(Zt<$x*VQG(o>B}L>@fOx#~(SnpZ~^XRg0swhT{FJ6CNV5|%0gAR{fC45jap3MpLN zV4EW5U}w=MKn*WW*5kOHzFf`~J11gslatp7(JixH!!6M`-XD&lcUkBm>mKd2!Hyt?X zz1=y{YTDXRG4a&yx$qpRJo?j}*^5URWM0w%t>T)wX4&AoE zyf88;C?rr;uO%UH*skR(!sX-~aM_z`@@w}->E8Y}!o{<5169+Ou#sl%M43Xi&|Kvl zm0~BgFkwVA)F|!@GvXZjBJQ$UMgUVx?veP*-#K8nlD{F#gkh_zY;6I<7G`mcv*+6C zZctq=$QPV0H`22FE*`E_SHo>9==^BgU!#1k{0kVwsaFm=^`_Ztvo?c1RdUvZI?UVZsVtuQenF`zOLiQ`q z*DN$UQJVjT&!(&FmN>aaY`WdmW~|Toq0i-yJB?&u3Wh!0WfcE7`nQ}i7<3k4W77ItEqpNKPL?oXytt7wXLDK1~O#pbPSB)ln?w3-lMg%(?F8Q zErA;6J6l*_{B-dRtaih2dbE?QzPBrUrcNS!&7!5Kn(oUZ6-V9|Axx^lgwh>#3l=iI zABDe2CBL>)FCmm2sneurIS9W~R(Lp2==)@rl-=8@n+If{&BnOHAxXKTl~Q(}-GTc! zT6Dt)o~q+|+&*rlzW(t1ovmY_xC5D*))01IGToUnSIBlf0 zFjf`p#BbDR>Q+*4mC?b8i zCFiCJT^8z6ubg>}^~0zACqc>u<#OvB_@?g>U0LK&d@3k6dt-ExNN|p2iI9n=OQMCatqyKd$Gu%E$F>$lujA2P z2vENw%cQ|07f|?8Fq{>LBx~O6x#gsw9x)Y;JQk9iPr`Q=89i@C63`pXvZIpXy^<$oJ9p|M~+3oFxQGm7BtMl3#hU>YLJT|$&Y9m2v$+OCqOGU zZ?A?vR`vn3k=WUE?RjnN)HCGKCCPb|4gvMd@z`6n-kUwQ$MkQry4-frZ9zT>m*>-JDLX-T-&c*wX3KES`A_3K}{wKu)~6!1BBZvhr<_k zDu3XXfh{+8z1Oo(;a%uh4K*RjVd0aVLvcG57>N!!;N;?wLPCV3y(*ans6Mwc(;7KH ziJSuMQi4r>e<`=-Z<@SJ3-A2)B5OPg+Eq0^AZY8|R_i1^>)R_{43&V4^USDIJKy6e zIaOq=n2(U;TdgabWYa%;*X7FJDV{UA+3XAk5}pme>>{z4eE>~m^xQ_ZQaOzA zXrfW&*6v~fdI479NkdyPvJYXO+b=%J?M8EG*<@{~k6(y3?2GNL$8# zn>aKxtkTBrm6xGK&y-)#d0Z&ZwhLePnzXZP32%XsGLjl7F2jOWPx3S0_5p@)yPds!(Q8 z=R=V`=6nx}UZVYL35Ua*URAMO>VRri^3Uw$x}mPySB$r3i@eNtM`df7oHuv?cnGsV ztqj~Z=GPzZ{ycE{f#i`)`mB6M9VOD-+YKki>y}l}P@s#(Ex@tXafp|brQ2^A421|I z%z)q-v&hqU8$^krrP#8+!>UGd-(K^1FSQIlT1Ze&c#LGB_~D~0(b*e?554MGe@>VJ z7Ji0=v&h~NClPf!q1sPhRO#h6BF?xSE3I{~+-rXn%Je{$6ALwUUx^D4fNIR6&K3ZEJ*R1@QhA+I#E)6o6eM#n=#gT z_#72IB@I?pi$>T`BFHh>WdqTRm_CP3{1<)A2)BZUbJ~R5r!A$VpC@R~@dT z^{>1N;UKr;`+M({%#SP1O^O;8Mm6pOg6U;?=gs}2!gm+nBkX3Lh3H~Ix$FF35XmDyiQ z{&+_jB)26J)uG5N3L7<4Kgt6FJBRv63)3PGB^Kt8Xuj0^&h;S#j2h@?%hmnbCMV?b zqR&oSf9bGGKK3f@{+BN1%6CD^OFc}l6}x%z#+u`llaq93h0fDqF*CidiJL4c63XZkh+y~RH+nxm?zxFf5rXs7+s>)V5+4}{W{>NU< zYQ4%Ve=HLYTRsavGC1^OKOIzTgG853tpqVV8sJ$p7Vx-`{} zc=-&kktqCVbn*jczaDq&?qv*%8&06e!0YxU@))~cFE3pt4wF0IoWYCNZs-F`4Tvxo z(t$A4GxYdrB4qSSr=9cTp%1k+tYE6GBVDK)KlkaK8B1zd3)xtci85zBO?z&85(^A* z{F`mJM*+J3V77Li^o$r>%Vb%m|ckYq#@_8A4T0|c% z7w#7Y^o`cB*{Do;%!=`wof3q4iLq0%BkFpc|{$nxDEy}!~Ps2db3J`*J3UH0jI zJ5nrR>qp8zsx=mmK-OesRMoW0Xzr*awxnO4t32F^BG?gZ{pOcIE zp(_7z>s3AGyBYru?*zTWseB}K8#*yO$|Y{` zGI?lb?!!YbPZ>Z>(_gRA(*>0K(>yGiNwEu}2tM15Ba3{G6_bB1^z=NR6jU;VMiPs* zM>Q5peKMReUgnVh`btpn;i^`q$5LMIAoD>;z_-31`=HXMK*r49(sM$4pswmg3P@P# zn|{m^kZY{Sfq_EqXT)hR6aF^y_yQ2nfx2Hy|1 z*WXYj$b63eEH8kSSd#5l$@Er-?cwn)cXtH4Gzwh?nen;+h};kOy12NTxdAwE2_rNV z>Uc<6NzO;d|4VN=QiXKkz|XFJrF7n`DCE+{ zacoMyrp9+FFnU!lLNFei*2-0MF~_y&(fVj)VN*dv(dpC~cphEG`+T&#`TCnx!(phG z*-yJ^PlA~JNT)oH#1@^$&z$kOH8hKlmKyu;Unp_iv*0=C#{6Wfx}Wv!Rjj#(%pzkjFbXo@yR|_tf#o^L%C3{eVO2FtH#x&5de~7P*UUVO@up-zbY}M&; z?3gLi`|r{4BNpNF^u?!&0Do7QtazEmY$X1VHYT(Ycox%8Ol_RqyRjO29`{w$*U?^Z zFRRKE-`o7TBiDCX8$CpN*S5>X(jZ9(q$vYx{Ir$%UL^RDH_nKx32I}+w+b^2EeHh= z>J4G7cRAvlU5(Aonbp#QX*e`9U)jGn2VWPajFsC7I;sK^ljXd4tY^uDUeIsD5qO`q zbMvoTa$m$DX*EP|_K$Dv@apAHWtkWj=$GbLwBTa3(k2?Rks#i4hJ1T`6A zFwJPnc}vbtZs7FS6?`M(3Rc|vC>?i@t{O%s%<0zr{J|M*GquPtap8Sse`sdSF66`e z3}Gh7Dly(7{$|_Cit`o{Y-DQ?g3A|L$45SJ`e!4ToCI0uw(b^d>M=eY8EPuHbIvgf z*9Y5?ng*@8DSy#Y`0=vwK@@y4KUGu@@%bZ$rap|(!J`V!Bn(MMRe_yJQ%pJ!o-IA!mq=5v2BdG zsL#$Ri1UJnAo#(*gYJt93sr_N%o5)jNxQ8H>42u@i+ z1cKtN&BEV=gZ#Q5yT$Csp%na5c7>;C@Eu%jZB%I7Ze<>kRycEu|Qdj?hfQu9ylh(rlR!8cnNR3F47 zKsi;|uDI;tTQT8_`iA@y*qvPYYifU+Z4JZEG5QnU^WZv?A(Xs;xD&jqaO=-^wc9~v zX7H09@vS_#+R~^T=+Mc?VbQbINB#A^oa&@5j_7{S{l$rV-G% zSE?2nw>woo4%+ntEmAv))@e)@#M2keBk4lP?6ak2Rpk$RJB>lJ**eD(_QZrU9>~;- zSQt<~#$27w;!jEVi_bDc><>K+%M>mPo)6fwfRx?0!6SzVXAVH5@FgD1Zvw_EN>`NwK`4bN-%o?m)Je@i$9l@xp9Pd1ETj@c) z5F|d4=l|uTz>=mwa9j=J?!nW$^1$245Sij)3}qqUCS=+Dr+>aZ-x7ixHjCglCz{HF ztBu+5WAF`kL%D;wSk}ljlD_)32j3QEO|3<**>g6Jtk>>O9OszAo;V$S7leCK;SZZK zY`7`U%zr||6|}dAI|0M;Y&T&gfr1NE5PFA1!Rw7XfNH>!|9P#q%YejWyHj#9JX_Y{ z^K+H>>;sJ3;tw2{ZP`D?9q+GiO$Aa(RGg^a2O*<(1o)4)Y7&7|uS!5x0i(LvQ?wUA z!rjBq#^d9m{K67MPQ=3Cv_DA*rX(5s28yCk9vQMJ5=dueZH6L1sJMwg5$X*|1|X7* z#zq<|+;n0)vH-kBsW^FUzG60P-grz zL3G4-hR;UZU~E%kc{rdKB8d-B2OxY15#T9uKaC8$zRj8dWGmOrp%k5&*TfjhE&&L+ z_g^4H=6PhYBv9Zjp49$}j}F+Qv0!x9>lQypRdfRW7O_KeZM#F12R}BpP9#Xc05|UP z2JPloOLyy^!2e=P0qh6AL&Uo5Mbd9KA}S(cCO3FV(DNt{pSb@O0ZQWuh5 z(&wi89$F0?X`{jK>=0^rUd-l|=9aQMNOJ!gHf1mWD(%~JSbU%G(gxb1sYmcNvmPOQKy zN9KoTs$R!KMdnpt!o6la+2F0ae`r>PC#xA^U((K9?O3}zC?nxG;XTTB?Wz6M$8(?g z8T0rJk&%-tNFUilIC?rnO$8S}7hTaikr=px!z>=Q@bRPnt`OJ*I;$3)W+{bn6c~9od9BZQqBm;1di2 z4Zxoa_{FAzp3=zV7YiN)c)?(+DhjC7)Rz8Mk!OgCHd|RLE*`7_Dwho2A2mqH8H+lv zE~JzW01&&af_s0zaH12s+dxEB^sYLDYp;n7j@g{G&u$|!>Duj;=Tz*=M?S4ArazxV zEXD8(p?WBpumAg$P?7(7%Dc8dk>Z*ekq``328-v@FImNxzgb+X*Vw%`J|W{j%Zv;u z+23$~$+bU?$0Pmt6{h2EESMF&_QLIYEB$jokVhJp;n~u2?XeY66cA>-*~YPUG6GP1 zNt`4s4Q{}ytnx1+9~1Qyo42u&P_fmdGC}C=#A}y7RJ#>t*A9UJG|G^0-C+m5Qrs5h zv(?ViU39VA+(gjpd))nbkoe}xi`Lq{ZyUwW#g#-ME`ag?;xmt?Dlc>%d$hhD{Et~x z4MQ?+m4&Iy{w$fiKHL4?h8a;&F09&Zc@Wl?sT3knyY+=P`2!eIlBx|>PlBm<0l&Yy z7-dP!SOfkgC)C!=)4=q$9n`wtIwU8(U3%f5#RyM)R6a0E@h3=tD~ViULHKf6$puP9 z@md*=RO3pIVt?5aUee=kqgFu7BfHO)C`T4wYHN=8wnj3^Ja{qTIq*)`+uP1D>nk9o z^o+hZ5RUKH@&W}Kw=6)6R|X~Zdw}T!pD25$F$(V`Oj5wJ>N1!>X#bZR;Uj@1m8S-Y zLTHIl=Q-$0Mn4V7@iOuDiYLp1)iIH(2CqoY_`o6^R>K6@cfl6w8NX6kAUkv-+ zMiUj450JZx-0@DIEY7DDG@!g^Ux5ZDL*F|I7)}`<`w|GG*#Das_nKKiC?kJ0Li(?R zD+WK`4}OymiyI|LMkfdbV>Q5?ssYu;{S|=gRc|m2Su62A*t(WbQl4Fl1KcGlpKm@#o%9|4@&Zzl~2#CWCx{O&BTWU-I2VYpWbAe z^a*m#q#YT^;)fSlHvtjJinK2V{cxcxwYr*XabCi}&f4{1sg(wM&f~;yKEQam@lz<- z!zXL$AgdYD$VHXKIY4Jx7>rZQNlcgxHb)`QpO+efT6>t2l)OGc$`oUBy1Sranro=? zR~6c16d;rP(kP~F1_7+Cn)P@?hY>fBw?Y-q$Su9ia!VI7ZCrDi?-+4u38&*pMN*|JYlSWCU_8t;Lre8E(m8 zr$gA~`d%Cy;E{=3ZB5b_@GRg$2-`kn*WOS)c6aE%b(27X;qINwL>WG{?zWj6AdAs| zu(>`^WZLw>(7sqXi~tJAhRcCea+TjVrkf1aQ>DwlgY;%B*sDA~-wRJ6BO1)tcX`dV zDI5)qRk>SsyCa{$*xUINcw=F=Mi#29pfvM8K>vTS_g4W`?c4h}JPARiL?oApii(Oz zhqMK{MUai6gn)pAbT=$T6omzX3P=kI1|ibYEh;759ZL72*7}c0sC)18{%+r!@5Q+| zx?OY5PmFlRGoDeqx9zN_5&h**>6{x{qpTa*_gk-*N4`K_=ih>$Jl>VGlthQgu0-^E zf`ENtVpo4zbUanJ?6G1{!qP~Sa!{_4JJh$!WgwPQ;d!e)3tZAp1pp2-Jjnz6;w z-#n~FyLjNVB#$ZbPzyt6tGBB@jqJ+8c>BU+cR>~KH#F4#HW&0DtkMR(%4xZfI6xpm zg75I@@U+c|7upMBsWsJWYfx4R{Gk$-k&A)A^Z)1V+xQGRQA7jWH380@%L;k{Edr7-^>HyECrcB91Zch}zgWe&Iv0hVA*fWXkI%%(=lp&vyGZR+Di%$!93 z?KHR65B;ETzdneZtQM!A1A(^PNK1-d&RsIf40fRFbp<_Z@3#KRv(kPPS7XXy1x}UL zrROfCoW|~`RUrRVxe}I!Etb(@*USIM$E}BYA0^WH8qTe!Ya}fwVU=1IC~AvRJy^1Z zQ*guEaO@HpoxZHVZ~+cR1kXhd{n+%oL1{`K2c((;@nu2ZlHGf~n9cdk?$oPJJoslQ zu=Q2Ciag1XGifJBsI%OOL7QD$bUbNjcTz+%T+9S!$oR!#y>j2yioh9nc=+fiFr8=D z*nZ(^!d35C3d({Yo%9XvB z`humvRoHYp4M)gd4gbF*QG3I{*+z8{j7n=w*C-b{6eD3GUY|2g$(K z4HHQ>=5{!{c_wX#BOLbS*#7vQzZq1L$oinUc8&_w*~`yRTw%i*=3uaqQZ7Ml?FIxUM6uN6jDLhKAObYCH%j#&GtnMbqvXYy?zj(7RT* z>E-1pqI1x=we#0K{*3Ic{doK9+Qs||c83o4BEOf=(RP(C3etkIM#27?-`Yi>~7sOo_mUZM(Q7*!IRnXk+RYr4HStG z5uUhM9OSzg10eTM6$pw0oN7Ra&+Q2riusRKGixN7OVy=Sg}IP+uL7*Xl_6VeZYu@42v53e}7TR zy2a%RoZP_`UOOFbQ~kpg;ywEcz6zqox5c8?gSb3NEI@Nf@i%NvHsHH!+?mW>3)LaSd5`S zAmKFPUHD~dUr`rA*4b=4){=5F{&HB;(}7&0x|rBh3fW8~EpakP09ik_<`O8-RQl_m zl~P0l9222OW?6YScrH}J!CWSA?)&RYN;YIupE> zib#eXs*OaKY2w%0o~JHM%M=J`ck?6wt&xX@y{MRJKaFR!D;_ZJhHD)x3HVYoin92izXeD1pXZ5o90kRG{#q9R zi2xt^^u*Q$ev@AWY1VQv;|QD!JbXz}3$8C7?CfPX@L5T2fZog>)iGo2`sLx@!c8~c z#pVMWdd|n_Z-8WO+i#tEGBVk~!>tqP&04Q1bOt^LP-@!Nou{mhl**yI=nU9q$@PRA z{MCVrWhjZYG3XmJnphPG|7jRD5>*3=Xv$CpmHrn%6Jfz0Ui)H{_*{_VK<~3%xGS99gtkTOvouIW&X#b9yEa? zdF2w%X3s>XAmkamo*8Ke24746qU!=0Ld^2I zPx~+{{B}a$5CyqQMt2}QC9B;u)@b1H<=5($Qs|&@aMXZ=P9b(p5dyAtD!+NEL6!Ib zw2(>a_7;0_b-1sL$4&xky3(X6;l&cF5>EL`FOLLztoCzo zgh{6xf6aM`wgj&GQxr@}LCr>bZ^^?+pAGkbG0(as`V}(vwq}!G#|?>`=(&UBW7Eh(CbnxG&>Rj<9)nDvec@1Vzn?_X8pM~204u8pn2i;PuW%y~UkxX37Ukh;&Y=WZC< zR3W_aRHNVM0Nk4Q&g(dJtrj$vwWBuZAGe_0EOT6TX1pzZw5wvTjY7L}tXz7Oq?2_# zcT!eNJg&hn3&5#|JepaS4G`EI>4XeHa02`ahQnnnrM+PJ=X;O;kw$(3T!rr3CS>Z( zgd!96zqV3AFz>=gXaH;L4m4juG11BD2#L&7GoLxzp$q9_#NlDTpjS=@b%-dL{4?AN zxemA$!(HHgf)lm!oF_`?WODIPa9fHnz8aQcCz5toPJ!EIy<>3;W7`U>A>E3p+qxS< zAb9|)Xw($ZCQZm*I1q`@`&738fzc!%gn}m}liemdvgK={WQYxLUzAWUd>FbUJ`Dkc ztd2+P5j6F0M9fA_p?c4&E&uD<7*vHeVm8VF3!M(#O%VHn?rZAn@%HA5v!Sq;mvLMJVwyb|G=3o;Hrm7qQpgMz z5z`y*r~4}=-M}r|4&36oe$%cI!DQ3qK)0zJuiD3fd(XMASKom81&$7U?6|h;beZ-h zK0^8{k?$kOfR~0o3R54{hC_-AiKff#t;{;az*!eTd)n4Qg^a(OLwBFi`P~zZ@2}6I zOsBH@I~dfJUI@Go+_rBu#hPu6anGd zCo7Zfzg_?W8u)s&5QCabQb68>jF(H1xqrh^33`Znrg`3VNH#)g;9@Poeb&$f*mfMB zu)ug-vu*`I`F*Zy^UYC^IA;3hKzA)~KD{cN*U0orLDGj9^Xci(Hr# zc1dtCcL69mWd$ufdQ7}pt}k(8Nx49G7)C2smxzlV#6_|#EUq|BSzygyHH09)DZ25W zlz;QE`(m(exQs*HXb+bJspQE@b@o*JCPiV}?6c3IXn0okC5USe!Kq zx!VA$B)$eWJ#rRJGMoVzm^Vhu4rA118RBrGK|C7vtm@eS@yS7X=zfstTmkP!o;m*U z>&dG1FyDv)SH2mMZ{RE;22BD8v_Gj)1x~?<&d~r5;&5v4nTkD!jQgqxulokcmxP@R%@y zcBNo0<+})*wb}YZ;d87FVD$(ksriPR)c^uY0Zf@IBAHUPd$CB+uv&5kNHJ1Y5JAK; zpVV|Lni>3R*m7Z#0yEu7fTWFBJ@+ngpM_Bm;LZg!mmyWLT^C+307#dtZe6oty+Zf! zzwp)zGF-LX!xluyq{$Q(`O}z??MN+qjreFn=MjaF+Q4J&C;@PI?ngacYCwk-90^t{ zD6mDLEnUXk*OPM1!MsqR6$eU%(e* zy4ry+B|<895MR|p+JRHh?EO(MUNIsAJ(-ytP~o9fX!OH~CRIWI{z4{w$7vLW#=a0V zq)iRz{EQ~KtAO~JeZt{~03C3ygXO|U8>?zab$G8gbpN(azl}o%ga|k5_N!BeLVlXx zm18Uic-RbI6_|w!#fSPKm(DScl6K3GfR4{l^_Z^bH72ti3qB`5y~)81EVp`3grIjL z4Lw7-xVe)V^xdX%?tpL+1*%9J3UDC|D}2jQxc`AsLli@m9tKK=_m9%mD>NZvt$;M% zM2i9AXvNShSt~E&6g1^#=)G&&Z7;Zw#3<5K;hf>C|$re`LEE#$x`?r?gpeE9d^gpHv$`NJJ7Xc?9&D(kraDh)#{Oi8A z#KL|{K=m}uDCII7#tb$gquM6lh7-3YQ7|<#RLrW+{ppd*; z3#kA{{>L@6oA5H&hHh(Ehp2H#B9F7K{ZVXNuO8q32MCqseWWf9g-zNngO1>tXAg~! zm>~9CJ4B7Y>*qiyWi^Tx`kbJN+qCk6S*bU@ghpT2S2@cSfCf(8Jo#xP<}7daz;5^V z?H7IL0EdwI0VzSAE5PeEs)_39c&O)UCJvJ}tl?PDV#51%-HZQOh^y7)LvkqBG13Ne zRQ54O5=wun)Ce6+h|45-E^zKY&Iw3Q5kqRb%P&9hKv3a zGkck?gV>+(JndtSIG1jiP9eQ@px>zc##e+z0?vM1yLn0(Q@2@H?$XfO%3`fE`%-osE@yRhpBM) zvUGnrZnSuN&F(d2)N1U2_Sk)Ps8i3>DZ00wBc!8S%LC3Dy`UXxD9?AFWE_m9&bU1KZ_N5XTu>+Z#eJ6RFy%>?*U0fW&wokN^Anve zR8iZ+z^X0i=!-hfjks0#b9DEkakj+mFVBjCZ`!v`wWb>SgH5kqqGCD`k`KPkbJ-3NI?w~8Hyp;T2X5xRLg7}EMFbgq}s6voM& z6-5-9(NeFVoF&@(TfJL6YS0{oJ0_(-=s*!YD#FI!UzKby=e8@R-m_eQOk4)?I*WX3 zxTVb~xb1_Mdn(X!FlBvOhI$sggzkkC79ie{jpm)yC}{*$*4bL7jWnbZpcyK48!{|K zC-Q6{eIo<;lMr>FHRdpsOV|#t!($jjLlVb(VYs0Tncn*h_Nj-ut-!<%Wg7Py##1Tdos6B3vo3^lcB!Nk66{D8N~_ zdo>b(VD&IKQWFkMYKHRwtDY$UqKxI#>tHQ$SBQCHle33HXA`a{pk=#8RWb8V5Z?vo zug-i`x+5h!-s;WBpW0_}K+~DwKl@3B)0ZbIPjkh;{4W6!u;DvEtzj`?1x{pP;a##Y zl=+ZDjS=xZuQe`*V{3E*IFd2~Ji|lKUvT;iMGQr>sK4Yk#as8#MV`K!;q;kaLEDXYT$4a_8-m_G$))a&dqcI9MAS?$CL&Mh%vNQ?siWFOeHg;uG<~eV~_@5IUht- zCiZjh;=1ut%mz;N@V5ww#Xcyud`mlHT>`Z^X0=<{{p&4YaaLx+mYgD`pXCTX-mEGA zH3|ChggQmO08BRURG~7Cf+&N3l9W`ENcaLXNtYMKa~h#en=e(L7c>_ZW&8c23ow>` zth5__h-Z92VAixOs)Oq3v?Vu7EE>K{z*3z|IV0c#*H5(VjdcoRh=j*NYSdbxZBinI zS?T?jU7Roj$r}~60;_G^9krne1>KmknA-|#=o)?bbB(OXuyIh{5Dv5<)8k>-RYO{u zN$MxPY^3U%nRcd@fO2jM<-90y95RHdi%*ZxynvflSs$;&VYY3+mHSYALbT@X*e^~H zcxxVHxRNTuODKK7;?*aE`(v-rx}`J(VXxu{bqX=~SROwot+OtX%>V>n2d2+&X5fGz zqR<%ls+0U#HR+SuMJSIQF(+MKoGcg*kl&Xb%Xn8Ri&D}RKjmh2wZ#r_;fFU~vRI-4 zp(xl*l|*c~UE{UumjOhdxGf4YCylB)LvWtMc~n-188{!y@N?RW%*c5CBKNK{=^Ur! zIi=^L_>m;;|I%OM4^rr`GZcRIBku-CtLnwXI7sN&i!8Ud%H5S*%)_O0LrI|3>{|$b zUIh*#S}TXE2;0%KSQ=#(TS=wM@BwPm?fRtoomD;}1!#{2hn{K|X^hjY#oOXfx;ZYLbJXGnxzT_cYw+C2a%C!YL)DLQWK3 zx8e3Mf7)>ajNR(%OToIN6OKP#2S+~Nag-pp(dVW_or`A(%fd6D-eQB`4U%XprqjH7 zbCaI}|NRyW7;IK7)GcO0kpjlrSa~}4c8yAB1j9H{UCf6$JYfS=l^IifWURdZg#3Y1 z#MRlQi0OE3FfRQ^g_>_VblwK=HD?(j;Rr)7qiK}IHS-ogW(9wmlU;J{XsfN#djH*4 z3)o19O%2a6!Y`_HO7|kyg7mz0Q6F6jiT7;if1JV>7HqmgAskJ;j!)O*h*6ZAKFf10&KM0rF@?iNcgd%dT z#~3UjQ5X}l>?xEw$^w-+&6TH$;yS2q$lvw$x|-iqn;)~b=(+`_O&sv zd71?fb9e!X|Asw!ie@2bC)O_CgDxe7rTUH5@vQ|ruetgMZ9eQc!RY0^GL9Km?Ds#~ zD1MRVZ`(g3PubDq(&YSC^kL%V@lmD|+a(5`oDKc7gGI>bipkE;kO7LTT#@r-Q5I*g z1a5#XY4s-v)A5}%!4NPT4gqUR$Pf@-QC^LVu>~}Ku0{niT2X=_)hI*T@f7|+rLF$< zt(PnVzM$Z<4eR)^EDDWh*>$y?yE!hCn?1X>`tlzwA9(_Q=(>W)>y@}2+o_8Fx-1Kl zJ`UBPSaespwhaLRKpf>jR%lxmZCh1b;s?7Z<1qB?1+z9Jeu980IgCRk&Y5BH&Gohg ztQm^&cc;3)G?Nl(^M&Tak~Kn@kw%*%+!hrhwB2?WmF^i+?*L{GU3uz9w>4K&eF(K@ zYR@^9ar~oir{NS??dO)_DZlR>KtOuF-id-LmTto(HY(#o4~QV6AxNC3%8^1jKNngS zzUW5&ioL1+VOYUxvDlgremx4n4<^v{8=m#_b5sriDW35&CJ7F0*9IH6+#wrz^m8h~oy zy`5obnalLK0Ex)QF(I)0`_M>h5+bb`jX`|lM=ms~88{rQDL|M3h|Ut^&gxBHiK7%} z8x)tCMGKi2&Q_O+Y{PjptxA$UnKdC7whA3)u3^wtnNSr}3vK5iGf{Hw-^J+o*%+h(9`vEUTm1HI3gv8bS|in$iI(0bb&4c9pPZ4Euc z*cV0TCk$;@4v8-Op{85Aj(2glD&t-5*(o4Ygk0Qv{| zQQjrdX!uQ)NLwG|ZLZ!KFQLJB{gkb@LH@QR_d<4sp*>2s0Sve2GPuo1oWC&_+^CZ6 zWLB>vvSt-N@cRQ_=Bk3`-+CLJ_{32OR!vQeo_6f0M)uR7-&5$I`)J4I=kRq7_pC2t zd8uDvQ2{ZDojbh-Ka|j#@H3vCVleSF!3vA@ zN7AYwOw7e*=u&uX^z;5{HsND25RrU?vzc&b`k`e)M{W~7vHVj1AMMmThttnMEB-aH zR?F`+xGJ0(^~pO*vFUY1BOe7EN*jL58E=)op(D=ku=iy|CbL?Q^y86e;G{`_@e;Gt z(cl(eK_Qx(ijvc%o~DP|Cci-g)(mPV%)w5qE@TI&rj_4>?%$`7VOc$56f_`9%ILEv zQ)$m^&46Ixxya9(^MI`8X+{~4XQ_UpYgWY6GNtV>JBw+x-xf;%mSMzyOq&BSj3tENUI^-IP!8{KZs)trd$bV(|D*J`lDex{xIYC~}!g5RkPFy@~bv$p>u> z)m-70XKEmxUPS4!{w%;TpA9x~N>S2IU>@revZ}%%NJ~e9 zG)Zn}Dm~7r`({95B3O*}v5_QI?j){g>cvg*zCz{R9>6tanFn!*e|Gp|q0`v4Ooo5v zVHUnbeffh*b^ObngXvX-j8+$`nC2v@oLE#MS>^3kE2v3rQEn_uiM1FrNaOn}DpdGX zvy=YuAOHH^uM#^$-@hTjW+7KUlS7E9*N!UTQSMX((;vnTMKRX~Q;xWoX6M>E<>DR+ zNJ#dry>JJmjI$40)lr<{@nLVHK~0fWsf`N(0dz%vri7Qz?`>)s67+BmgyjR zN^0Pjr)rg;4S=J`ONqwP$8$qCu#QUR_qNxmrm?Q8wMc_c+j3@Tm%7(cf=+y-(pknY zCK$yoOZ`7Y8Ll2rzV>{xJae%wbiI;P&lHC)+1(m##uZg^(cff&{ex+<^_j(aW~3@L(6{%}`EE2n+T*O2O<#dzbH+x3Iq@-T#wUY0&Sc zH)y-KhEk8?-2{ZZP;|%S$#-2}v(ZDYoF}(mWGIx<-+2j8f6>@l+n)`_qhz#V(E|*m zV1lR2MRs<6m5Vh?5KHHfbhPAxU`jz|02J1wO(A9my1DSrEC>u&4sn~uYXo5Q%FJUh zcY*IPGxI*_)14;B^pf)GGEgo{5kwK6jNtHGGSe{LHfO%`2h;}%uNa#$vma_bjpX~B zZK){ook%~-@|e&WF40_=Zh2V~1A0jUef~R%=i2W7zq|oPcffyA zyl;b9+VQRP=$&k_Ts81$9dodvuhk;j3t`vWmrl>B-v%)% z^6<3N!#;Gji-_vabJ)bXPhXn|=lvTr-`TzS zQ`}EFbmT!AP5uk0IxQi6nW>xWtO?`9(TqeD#5YTJK$v6?+fLg0Dkx>Qf6q79^D=UY zi=|PG39hENG5ymPs;dqt?oTH^UCOXR%OUMr2sxw`Sh`pz`?bpc3V&XHQZ$^tkJgP` zG4$H{oc)(f@4If}yv-fn3>Df%XN;sCg?UEtr_XW?9dg=353q*R{690!xN_7_pbT4X z7EiPb{kl2r-kn)DiQ-|*3oLT;xfEWJ&6-ezUR&3rbS@hHLnTqlcOkha6iPZGFV>em zDMBQA%l3mT&B=Z9^{8Un<*+))y`E}2NR-Icq&gk120Jj+<{hf-Ws+`xx3R;^ z$G4ruPUC>q>C;0_XCcimXwP~WkZm=ICbexh^vYJGAB&-WchQp=M(lUNYq>v&nmYDx@I|*ht6p1bbs)-=Z9}6;wIT4!-TW=xr8oZaFZn-?`T98D<^E$HZC#U# z*X5@lP6>W7DSo7<$~n`vjB3z`8GBY&NKwaq4f);^OOs$(`opro(_iYta)6g$mzt%# zLcm`0y~caZYP~BkXKC2x$@|YKb00uEtOK|E3&Wva?^$&OC2WNN;76CJe6+0GBB?ax z#7+r1K_2UkgVDD-hrW2H0p8j!aHeegeR^&VWs|Bs88`z8RMm!Zugy1pN~qA@=W2P* zau?EDvng+SPCtzBorXsu2c_*G`Z831DLHzN>LiOr?BHyiVuW)qptH`?P)O!YFLqu^ z00vRp=g@914>LY;QNEvXySi=bFK6CR&Yy>-6*bcnxAe_Vyf(soMfdwDEDa&cvrk$BaY`#m#g z)?F@bc$2HD42ol3X10>zoS@udWSjZT&F>~noYalgT@Flfa#=FP2Y2jcz*RIl+ZJ5s;B>2*$uu^|4G)%*PKGXW!UXJ3z{*1`O2D-{+&t!?LA6A z+7LZ|;C)Znff#5Ss>3L4PR=s^_o^RQihQm}$3FV_aO<5M4iZ5D(_knb`m;*}adqQf zVFjEs?m1UO5{X}1d~+<=Nb~?LQjI{JwK9`Zy|uLAj2hxm?&fQ8U#apEp&%A)mOE=iX*5CAZcy zecT8fmWmcbt5{=Jt}6Y;atVp+js;~G6!D7deDXX`=Q>v;L8WrAgZY*fIrpKZ5OQ2| zMf3qWL8Gf;Fmv>L!#?j975@K31AAZqz$Rbf<-Je(?$UHx=L)GVJ=(!1QVoDg+@53F zm|fjWum}~AYMeUHI@mtY^C@M3`c^>TPdTg%305vrb+seIzura!kp7c8dDRK zoyv7NRH#U`Wu?((_X`|zp))l0@Md8f;=xGIyu4Gl7e@2A%yS-A~g48gkjOV%P;`{T}J zaTLdFSCyNY-p+4wLq4%k%C2x?3IX<^&8(XV z*mFg$X3tg3MY_yB=f@aQ%x(XSVu_}mQ(_n=r8HevT9wK2L*MQ){-6R4Fo{)bUHLwWL?tSKu*pImFN_LaQ&(4tC|fJJ!|lW z9N$3N{KQ0mXtq5#`$x>~Q4{gwGq`2r**9zN6Y&xm)5~8>NblHcar>ZJ|Ck6rzl(;w zdNc|ar4ic}OZIGEJbi<@=<$WUyK!Y#cPL$qA#u_Yz*Sl(>K-q98F0Re>z5PJ3+Mmk zL_qdku}?)G$XSfv4$rDPc~ki?W5nNL?(Syjkwcrw4oB^I<4w<}zWAfw&?2@3!te|t zV1w>xl_#hDXg0Hf4pg??SfrvXi+4!wF{}lioWJyZg9>2c>;`c?=M;*7cdYn&SNn*| zeST1eG`;I4<-_WUEcRDukQkQc(-MfiE;Y30Bb!;O{;RW#ibSsq4gR5HI_)iU4R3t5 z?K_o69NuNc1ymzn>w>=BROAQbj1~joYq&;J@hLkQ*$XBDEJfF0P{{=dCIsu8}0Q z3YaeLKN8)r9d9aYN?SaDoBAmSH)6uqllEWV$YT-T26F$VvuCP``FjbpQ>nqMhNa$$K zn{(qO{qn!Da2O9V!D1F2pwGqscqq_mT+%V+ZVS2WqaE1CEO*f|@DG$DrU$K?4$x{j zYQB)JU$mcd02n{x;|7I0kH!v@CA_i6@aZ5_!_I7!Dz^TohC=d1`X-bPfZY8Ey*c$5 zH`PQI(Ve>GXheYXj-nIKb`!PnU9n4QS|wCcAQe2NS`at$PN_l)YphC8QvO_Jj#kqB~LEXlM|IS2RtUTuNTU<hekuB%X7!4SQU6g)_cnwna7r4Caa^vd%v(FB zD%kOLd3mKLww9`rec0TRp2v=RVjS2UYK0E+xt)o9+(yMe=Lr0Pu?WwWSdz*88{bRb z*nTm;&P-a2xx(iuhNL>PVLP03ln51Ac5lz=C`QPX%S3#ACG5wtJi|y49oEr#TD&~i;6{YS>nfg0q}g0)FEb0Ur< zz)_zx_f0sKA$?YsWCG?mXsmpBCgC%dHC*kT>xsF4B}*d6%Oi>y&TdkJT77p%e^n5L z9p4tUK1zV&hfCcs=&qEnQQ}v@I#aY%ex>%Wo$lB(l$ueauJ!0x8k-iBH~V2cr#wgkGTbJeZPpm> z&~~-yj;_Zew4g}ZtY|=OpFx^qGTM~rVAA?=a6;8~(G)25spwpRbifJH5bpBCgrk`m zdS;LTH#AX~bos4m=j@qYoDu{(b&J^iMLT%0C(jWy=x34N2`xJE1m;oHB?p_(ne~kK zj`xEiU$9y8)pm)uA!Ux?{VmMj_S|o_ma>u#Pp*)zHc4TbD5HVY%6+d`|gT_R`hXF zcBuy@))xp`h-Q0Aer5;shGul35%mt!c3>`!`^JgrcDbW!|3z{&66(_(m5+a(RMm0l zgr<_ju8E8s#x5yesl;8PsW_QX4f-wVMw!WEt zvZ)^<-XEgqoPe8GJU#fD-}s>=mN^l7D}Bj zFwC_9qMQT2JNQ@Tin_>x~V{)R-)d&g{!& zo@CAQa3$8))Yr66dX}racF$A0S!(votl%mp_`HaF67T0Dw?)aXiIA>p;+>k=mhBRq z%xx00t5?HQn@`+fPFc{jND{6w2HM7+23u87Hq-O>13#6Y*i(2yYj3Jo-m5H1*IV>- z)Fi5VR=!xZa27t+i`QqIK}SnnKj%ZvGy7z@>wEJ|Gu`AM-U;utBd1XR2H41mvd3w(RSG%4%;?jz81;}H?Oq@aKWRTqNH+s2Cy+mlr z#yED#CzEoBFjp~a9p#a6aIuluVj!O|GaN$;v)0i6c8P{7RL!D94X|_{5@x28PZZ0} z=Ws9R=g#wF8`8Q zR5ZVExz}T8x;mRzy1*l`Zz`F$i+&y}He`hGB$$!cKE_nv5ha0R(#av`-bjtxD{zd7ti1CY^f(9c{Pmax^YFV5c$92(Dji)vaODx&5R5 zT=4N_ZFhpt&gn9lE=J)eR}=m&<#%9@eq>?JkX7v}65T+qZ>M@)Fa_K~a55IcEu zUgy(n|D?-|$bo%Tc^=2ucBnsMu=z1!>Xz2D=)Lh5&K&t&>LsQIK19)2ci&QCu8eVF zF$eR5tIA8mh6Q`lL#`_Hhg8V*I25p|!~|HR-7|nvin;+h1%3zf?vvhBUylsLH4pC_ zdkXUj#UO_zuX5DYicg&qUX^&8Ufs#@$6q{)7yfpn;>BTaA7WE>qk{u)>Xe~R#jpqQ z`5Q9*e)S-FSx#cSpeP9-3x^HEcU}fCXa{p&#C?~2uXnVz{Alb5mQgzFc3`g%D$Sf* z68$85H*`wUD4Fy6KXxqsR}9(6_kQ?w6Diu|t`{(0a&z+Lm+x!_Pg_Yu z!@5Vt(}N#8Vr*42G}pDge7M&8;CDG|DNRmGPZiNCoa6ENlwa4L+#T^z zak_@dotMdj*u8j;{g4TTE@#gt&;%MJ+CF&D2ZCY=_H2k^M|5l{r$C&zV-_VHMeD3r zhoQyqYT)#bR!4m~-Rk%0CH|{pRewHi$UxBLz435Id{jrO;O>>0dekkPxL2TG8bme8I&egEPg#f&^q+@ zwn5&gRjr0If2a6X$x6e*<~vy*L8V=(dQ3@1X2Uv^m|;UpUzF&MDkz^lHq; zwCf6a1EVkT-$wXcFW=#LKH{}LEVl9vO+-L_hw1W2w_(`A(M-I{-Oo$`N-_k`H)Z<$ zteCqW6$(ZDzspG&9gW;}blD6GDWwjE0(*=)P=L8KH7mRMZoBcn^?A3xi|6^~Xzq)~ zRaFMLO#@+d9w(b!*~y;p5VZDx+&1vkzl%9N#8gs`^NBEt2?jfKT4LJtY4WKeWY2g# z0#*b2R3xN0y2O#Iw_mtJ!{m0F(w1-|WLq=U#h-m?OPXIbZOtu@NNB2MJw?;kdSs$s zAkakFe0q^I;P}CqiCr5XBF8X}SI0VLywzuyeOJzO4^_<#<3;p$deWA-(L@E7ji(7O zTtXjlE3{P<8iJM@PPFOX4SL$3zA?fb#;J0~lX&>Y6EB&ICf-K=F6*W$t>7RiH{8ZwQ#2Y|*C7|aVlnkf*`^GOrb^d81 zn>gpGr_CQT!)}PRWOUROFcbX=t1>aPkVxjLVJ&>oot_>)B8r^X*dDSz>7G*yxlqwd zpm={rgH0jXPVv|3JV~yNgNMZ8XPXjlkBn8*yn@B3EVHOhi85|=N1 zAx|(tT=RCYJ+=_F3VWnBr*4Lf9JSqB!1dKuo-+2*`p3g7dOqlLN&UvByt>5JP2_F- z_38{JRaHkQ5WECOXI~djx2IZ5d;?-M$NMF88(xO&gVK6e8^KD}T(I#DS>Ztn@yA@Z zCv4LAvkIDox6TMu<&TLVihrBDJ+z@jt@xLTZ#A|cRiuzcw(?$mx*SmenGgF&jjbVd z6|5hiQgl0@6CsFbvar9^R}QNCb=XjG(N2NPkPGGDJ6qM&*Z1=-=p=qrzr>0qY9OBz z?owkdj~gJaaXV<1?y01CkxcoMHr*kUt>`Uwy=E^T>+<`9UF|Y32-n-+EBIPi&JeU8 z^B=a}OCy=;<0ZRNU`f_%t#*HP&;jX6)u3h{{1F@ z1CzM0d&w3l5c8f~8VXW@0j#ketk~uAO-Qtt9Syeo&KZ=X(71!Fu!1Gz`0T51^6dW@ z%G@E~llnhC5JofeY3wK4Pw;H{L_`?*kdno?+)3Hn?6|DA{byBGiewggQzh>$3B8C^ilKNu$E(;Mb$<}>mc@h-;x>rWd% z9Rp~J7g(_q>rO}k`q^UCH;vg0=%sWMX4>zQ80j@Qkri$WV#A7BYp)Nxf5le?zjudZ zUDVV2i%KL39$%9jY!nyCiuIFQjJM_>9)gJL!Y#BZt&w!ozH*r$wP#HccVf;%1wnS- zXCy5Rz>XyS=Tj33NGv1DU?zL4Dh6wYi=ctr?I0LyOua8P_6<|*y1MflNpr;8V~HaA z1$4WGvDlR(mUnFf*L=O+lDPauH;0~V`#z4U!{YnV^THTCmyao7+2htOjw7<)@atcIweVa`sxBeovmuhj;*rUfce}a~mV2-%X zO;YHL)N=kc7wArHS?58AY)rX;Fvg$EFN(r@_J{f27&|29V2J9U>v#c2=!Ab9FRH-Z zL7^l?{-&A*i@zm%Xc(`C9Ol?2MB5~eDAOx&|M}^lTjIVN`#O%%+%t8*^a{Of+O@fd z$VPfpQn`|fjGQ1S7p6<^u)I8xZ=$k8+nc5S@$Z9u!^7K3jiM(~f>$UpnwLl}o9~Y_ zIg{=3*p1yrd&1URW{0KD`wn-{|M3rV@rE=A^pLEKJ9ry=wf7_?H*g`3m+57J&9W!l zHETQZ5W@ah;*zno2(8c& zfw?PJEN6NT_IY8a#SvB6pae3$<-Ew1W*L=7+S~bXfBt(<{E#3L<-VF>eE&3W+m|k) zzXzpk9rOCQ^`3!}^LWm?{dS1tE^j;JFdeyob8_X{%!{ji%%lpOzt>-P&D%$&G?r)) zM_iH;Yo$b9PY|2U$&ie)QDpV5tnCqxeTe^=QhN695)Na=K(Qkak^5uE%Z{1M`S0_S zc79@9DnqO>vy3D5uMnx9y&oi?Q;~O{JgDiLOxB}EOOQl}jfG+{f$fO@FkvqB>I`%7 z90ZlW42~Z&@fitzK6#&@8-A{UxKk&Nm>NY)4q73C6}XV)ZOK19i>!*0CD~wfOwEVR zza8Mc{{vbPf1Uks$2q#`5s&h@fH=A+g8cP{g0VS|bXP(*TCnQX{m4Q2>g;U`vc0Bz zPGNexUvr2lh;HOH#twO!}diqjx%**at2q3cjx zks79K(FW5Bn5NVv-nG*lgqH5HJfg+zIXHP`EEt5 zC77+`5p|q4WL>oU`v$_~hD2rMlHp!#!#oiLMb`FVn zG)&qPm@8O^C0On^-$rd3Wa9F%iL62C1mU+u>BIE(O;Qy45Q(`&)uhW|oIC{Sd4KyG zHA6M4@|=VQ8Da-9Q+)X$RG|tp@C+mb+d{kpc~5AcJb7@}PB9Tt=RgJ7wGv(4-y8Qu zdrtIDDJzqU>RNmpVNK72@Xf>HXZPl>6lXXx6?({HxhyqRT)DBdYBO&Uz1oy)W#-T1 z4ZQczm8;u`>gFR{%Q&Q$>m{-S41GUjap*?Ba8)6~MZ+hr&c_qnOk&|+C!92$jVCi; zCO5FyhEFBIo85Ku4V*`Yht0D@t{pwsS*m;T*PC65y2uC`>>i!M%Vwu{EP;tGT(3nJ|^IGYwKFx_+-Yd_eyN_7kp5?bkt$ z&R5o&=CEqJ;3JqB<5tIE(vXW6)T?syn7b$P`C><#Up&F2bc7?2vVg{PR)d7_7CYvQ z5O0zQrSa~3w&RWb{gAJ}uJ}&|Xxfk=5Gb7<%a}CO?(iXmq{z`tyAjz^f682%>B;mm zbLZZlvkx23RpvuF8;X^(PONbhU##T#d)v7N^E0`(H#eD47@@wRkKEzb!lyz@RFO-8 z^Wo-qjde`jK&;oAW0o21o?K~u^VWmQX{x6E$(<0#JpHaNO*U0!A@H2!&5}NqM+UxNHZ|UcM`NGK^s7kx@T%H)RKxj|i4pwyF?t z^ws|2nm5FtZGtEKB&~wPi=)5G3{P^*&-P8$6I%Nwxd|p6F$E_oJ%zWme>{RMe;v?? zzRY%NlH%9=*GhD0?m0dy`hG@j^uDAxi167pkma!cG7g8!R*W+^)YYmdW+If+6${{W|t1y zuO16rC5oziT(F_sH`Da}clF^|;%ypasF34Ell0=3OR2Y!JBU@C5~DjWLB?g}MTaq$ ze@e^Jo2XB{iz{k+F(*@I;-(n?Y|UEoC(W*$$Q@ znnkAW-A5y6_!Py3MV*3tWygCScYJxvB&hqCimTeTSnSx!vjhx6AcoPuSnJ4NNe&PF zU6p8J^HHc{t=xytsS%r&@}*v^4SRg|lU+8Kswj&Je|iG0P6TR-OxT3Xsoze9uY&5`%6?4Gbsz4cS41%s zSC+E(xul0m3Ot|lvIN1g9idPa@sX)H+B+FS>Y;v&^W02zel}ILgkmPiW7&*a39F(S zCN~|cZf@ShFY`Za-j!8Q6(}vPM%^aG4%S!n?OR6j0Z~sr@T#a9NLL=)Kg#HwnuzUziglK%hi}x{c(Ni8 zJ=fhg79SZ2RwT{y+M#55D>O#eQv%BJ$YFMUiw22pN=wTVt;8WL1G4NK=GI{K<-&7i^8&zb}#HWt-L3F9o(Qm1PA^ ziR_=nMG7*48OUEi$95hKq|ZOHP;gqt*QEE^$k_8{Z-v_K>vh;(zv`t3daQHsFgj>~ z>?GPm>A9zM(eJgW81+sUZmNC3ZI?XW_5XySNxx==nrd#C7wgs!E;9>ua_usFr5;#p z#qIter>a+WxxH5WQI$|Y@u6Li{q^N&wP7h(WQS3)g*Zf#+PelmbEKClb;cyI%9LaM z=tTW+bwS+A$({w0j0-N&QcyBQE-o{fWUEt$3T2UIgX($js1bQbvE_1J3vf)zKk2GX*y~?n!btddL<4Yg-T; zG$6tB==4%<+47{FTXj)S?&_H932Xs`+!O4w^q`>iJj3}8k!IQ-%jOfq2>I6~8XFj@ zD9>hvDl~`Gz32u2KMML25du1hxOxIXkzIZvW^FHy=C(|^<**>aIx&gYKgsK?2Bv?I zF){DF{QIqIrwT{WL+29T2|2&4#q>Jtj`VZ(g%GR-IU%;gv%9+`{x=lAOGg=NzS&uU zTg_71@K>;1(NU+oRkI5%)Q|LQqjmii42L+>2vY*T$Kep`VdFy6k!P>xS6b=2oeaAp zr4t*Sm;ix|sHj8Li1VL#+-Z7on01j}i~3kM%gNmV8apCU*5=#y42 zHDgNSQuz(2&;O*ZtWl4r);(2ECuUc+yWzgi`BDZLJENErl_OIf$>;g~hQ@EmY5Z?v zHN-y(4lIstKdu@E6}gjBi#ndZ^1W7hIs&z`GU!{!n5xi8`qR<{Tmr?#q!WH_|bP?1k!?l9X>Xdhr(E@w& zj%z%im^9~7MNug~poZ-U@g)B6hR*IJX}w;FGW2~5acj4mpeh&p_%jm9Wn#=6*aQp_ zbP-}AsjISgkAPw#jfIi!fu&#n9P(-F(mr-Jt!l#LmnMDk{h3^`wah_=e@%FvvYZAI zC9PNE-6xMxFvHCnejhR(;>`+^LSSDHk_4Z25<@1Z;2Fsxd+g(Rm_`XD{D|F?mT~p4qJ3yv~6WGPVw-iT)7Cfa8 zZbNQ1d*XJ4C!a=J-i~(yvxpCO&pP~50qDtSuAzksKv1e)<9!yY>)-Xle zBjh{VR|Y=|b7e5-+4umymrc9XfM6|7L@(;+NGv-#9-iK@DM~zc_b9M2r76d8Yvof> zGo?Zr@>}E#j)e&dzVVk6aap$-oTM>m;8o9lBat2B6u)?)bA zTyPSlG?Y(YW(mHT;+Xf7T_!41|8DUEu9u;gvq6${gwUTnrP7O$__FRTeFGGm2ay&t zy_{JKgX_4(J{~GK)JeV>#5usMcbrc)mD!N3|M)S3_JAB|#V#81X#*7KRu2!_8n1L# zo4zE-NmpBBL7a?*OjFG{^V)}tDfcT9g$}7$e_4%a6*#gXdhiA*?->_CUeNFb$^}F*0`V~Jj?WxvE zEnCNki_QelWx%~6&5v%*L>v`18A>{7&avF5P}?)fVPzUC7-$+4mF#%)gC%Rio5FRx^agnM@cB8 z&YOhB2lJd+fR#98wjQ$4yL>?X-byldIZ?|BPj{M?XAMu^ZI$y|J471`Q{;l7R$?;> z9`~^Jr;;)SMR9xFWvx55GDGk(i=Rdun{L6A*+T^mJ=ZMtfH0*shbeG0z3?Y0nuybC zs4K|=@_|nWU>sP4ZBrXQlZ2qJZ9OI7Lo+igJr!~X?HY$+5q5Fya@YK7mzZRV#TmV75IXIhjNy~?XzSXr-Lz^$t$FDSia`}n<3S?^hSx+j)# z0Rwl)Y338}${SoP4^X*s;+*bP;MciNiQC07jFHiV;Dt-W&0Iy6|Jx$eHuDaL3-p2c zuW9>W3$XYldTzR0xdnJ-(0L4opnp(8pkw2>8g}nmPLZqXr{8Phu}dTI7umP`O7+8S zW9f(APb5!fmggBwu>=I~lp1|Y{P;ah-~RFDNA;+`gZ}t6ih??9TNyiX!-=B=YN>Xd zUgRcjkDPX%e6+|5^KDD+(hpEXvB{g%FN)AGg`&;*t3SB0^NJEqBvqJuzYIc0Ap?K$ zSoVjoQ!sqAl{8Me$Sx^G|KkIOIRUkaKG2q+@C47fVrK+U6Nkh5hqu2BUULrY84544 zP4gqvqU$b5E7DI#O9aK?_?4uj-B{T%437q4vkK^}L8wD<5ra#RxfG{0H*2(2oR3KX z5VBq2*e4AeOECW{!wqR>`=U%-LRB5S#GUNZfXAiizq`jkj@C5Q;dzO=wBYOHCFoSh z4Q9DnLVn;P^=y+AF-B-JtT7`SY_929y_y~6E7F=Y)-C)Rvzr>8Ys{ zrM&MbBG8Siq5dh!#iekvkMWRz8O|wab1Y_T`lE&tc*pgoRa1>cbe8G$^9S0jvEy+* z=Zb1uBBlkGFV$7qAjd*d^svwz%PaH=dn|4NVJv)v%k+PmDdU_KE3XFWx5IO~rqTRn zXZa|{pplKNg$;swx5l^~?#?ZoO0Yhi!Wx=}>qqJn>L1SoH0@{+@5AYmvHrh)Z6|7v zVd2Z0tECsFKQ|cWRou!iI8!#`;%C{=D{kz#v~az^|F#cJ(e15mLkCU1qay6IlaSVQ z*Ea_JHE13=o{*RK@hCPxdHeWHdxOKir%S7N)$Hf3y_AC5kJUf@OpX{vReQZ48yx7% zaD`}R)_&C8w^ut8R)xJ~Z;%Od&29Brt%LzHUoHRt3(UU1*-2|?4WOz!ETn^g;pL7# KR__}6`+opC#zdX~ diff --git a/apps/wristlight/screenshot_red.png b/apps/wristlight/screenshot_red.png index 0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a..06ac7a190a39202403bcd9b1bd35a24805e405b0 100644 GIT binary patch delta 118 zcmaF#nP~x|VrPJ#J1>_M7Xt$WucwDg5Rl#g!Ys@{GIr+A+=+?`Jj?+;A+G-!7$hHY znoqQouvYVQaSX}0_x2zoFHqH?1>gO1`OFo7OeE0YZE9=4!1$ACc^*jA)78&qol`;+ E0NM2%-~a#s literal 47586 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 KR__}6`+opC#zdX~ From 42b3e9597dc20d994c0d3fae3519b9759f4d7a96 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:24:57 +0200 Subject: [PATCH 133/183] Update metadata.json --- apps/pongclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index dbd044517..f68246b35 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -4,6 +4,7 @@ "icon": "pongclock.png", "version":"0.01", "description": "A Pong playing clock", + "type": "clock", "tags": "", "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], From 8d588d8220a292155e8b99cf05f9aae93e7cd3af Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:25:35 +0200 Subject: [PATCH 134/183] Update ChangeLog --- apps/pongclock/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pongclock/ChangeLog b/apps/pongclock/ChangeLog index 7b83706bf..9b83b345f 100644 --- a/apps/pongclock/ChangeLog +++ b/apps/pongclock/ChangeLog @@ -1 +1,2 @@ 0.01: First release +0.02: added missing type i metadata From f72148eea96a43bd05d761e33dcf4382cd31a1e5 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:25:55 +0200 Subject: [PATCH 135/183] Update metadata.json --- apps/pongclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index f68246b35..c714e9a10 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -2,7 +2,7 @@ "name": "Pong Clock", "shortName":"Pong Clock", "icon": "pongclock.png", - "version":"0.01", + "version":"0.02", "description": "A Pong playing clock", "type": "clock", "tags": "", From 87387d546dc06dd9659895e5b546eee3473ff584 Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 15:16:18 +0200 Subject: [PATCH 136/183] Initial Release --- apps/hworldclock/ChangeLog | 1 + apps/hworldclock/README.md | 30 +++ apps/hworldclock/app.js | 266 ++++++++++++++++++++++ apps/hworldclock/app.png | Bin 0 -> 2867 bytes apps/hworldclock/custom.html | 76 +++++++ apps/hworldclock/hsuncalc.js | 298 +++++++++++++++++++++++++ apps/hworldclock/hworldclock-icon.js | 1 + apps/hworldclock/hworldclock.png | Bin 0 -> 3457 bytes apps/hworldclock/metadata.json | 21 ++ apps/hworldclock/screenshot_hworld.png | Bin 0 -> 3457 bytes 10 files changed, 693 insertions(+) create mode 100644 apps/hworldclock/ChangeLog create mode 100644 apps/hworldclock/README.md create mode 100644 apps/hworldclock/app.js create mode 100644 apps/hworldclock/app.png create mode 100644 apps/hworldclock/custom.html create mode 100644 apps/hworldclock/hsuncalc.js create mode 100644 apps/hworldclock/hworldclock-icon.js create mode 100644 apps/hworldclock/hworldclock.png create mode 100644 apps/hworldclock/metadata.json create mode 100644 apps/hworldclock/screenshot_hworld.png diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog new file mode 100644 index 000000000..5b2a1edce --- /dev/null +++ b/apps/hworldclock/ChangeLog @@ -0,0 +1 @@ +0.15: Initial release - be patient as this is the first try :) diff --git a/apps/hworldclock/README.md b/apps/hworldclock/README.md new file mode 100644 index 000000000..40af71ee3 --- /dev/null +++ b/apps/hworldclock/README.md @@ -0,0 +1,30 @@ +# Hanks World Clock - See the time in four locations + +In addition to the main clock and date in your current location, you can add up to three other locations. Great for travel or remote working. +Additionally we show the sunset/sunrise and seconds for the current location and the day name is shown in your locale. + +![](hworldclock.png) + +## Usage + +Provide names and the UTC offsets for up to three other timezones in the app store. These are stored in a json file on your watch. UTC offsets can be decimal (e.g., 5.5 for India). + +The clock does not handle summer time / daylight saving time changes automatically. If one of your three locations changes its UTC offset, you can simply change the setting in the app store and update. Currently the clock only supports 24 hour time format for the additional time zones. + + +## Requests + +Please use [the Espruino Forum](http://forum.espruino.com/microcosms/1424/) if you have feature requests or notice bugs. + +## Creator + +Created by Hank. + +Based on the great work of +================= +World Clock - 4 time zones +Made by [Scott Hale](https://www.github.com/computermacgyver), based upon the [Simple Clock](https://github.com/espruino/BangleApps/tree/master/apps/sclock). +===== a n d ===== +Sun Clock +[Sun Clock](https://github.com/espruino/BangleApps/tree/master/apps/sunclock) +================= diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js new file mode 100644 index 000000000..8122371a6 --- /dev/null +++ b/apps/hworldclock/app.js @@ -0,0 +1,266 @@ +const big = g.getWidth()>200; +// Font for primary time and date +const primaryTimeFontSize = big?6:5; +const primaryDateFontSize = big?3:2; +require("Font5x9Numeric7Seg").add(Graphics); +require("FontTeletext10x18Ascii").add(Graphics); + +// Font for single secondary time +const secondaryTimeFontSize = 4; +const secondaryTimeZoneFontSize = 2; + +// Font / columns for multiple secondary times +const secondaryRowColFontSize = 2; +const xcol1 = 10; +const xcol2 = g.getWidth() - xcol1; + +const font = "6x8"; + +/* TODO: we could totally use 'Layout' here and +avoid a whole bunch of hard-coded offsets */ + + +const xyCenter = g.getWidth() / 2; +const xyCenterSeconds = xyCenter + (big ? 85 : 68); +const yAmPm = xyCenter - (big ? 70 : 48); +const yposTime = big ? 70 : 55; +const yposTime2 = yposTime + (big ? 100 : 60); +const yposDate = big ? 135 : 95; +const yposWorld = big ? 170 : 120; + +const OFFSET_TIME_ZONE = 0; +const OFFSET_HOURS = 1; + +var offsets = require("Storage").readJSON("hworldclock.settings.json") || []; + +//=======Sun +setting = require("Storage").readJSON("setting.json",1); +E.setTimeZone(setting.timezone); // timezone = 1 for MEZ, = 2 for MESZ +SunCalc = require("hsuncalc.js"); +const LOCATION_FILE = "mylocation.json"; +var rise = "07:00"; +var set = "20:00"; +var pos = {altitude: 20, azimuth: 135}; +var noonpos = {altitude: 37, azimuth: 180}; +//=======Sun + +var ampm = "AM"; + +// TESTING CODE +// Used to test offset array values during development. +// Uncomment to override secondary offsets value +/* +const mockOffsets = { + zeroOffsets: [], + oneOffset: [["UTC", 0]], + twoOffsets: [ + ["Tokyo", 9], + ["UTC", 0], + ], + fourOffsets: [ + ["Tokyo", 9], + ["UTC", 0], + ["Denver", -7], + ["Miami", -5], + ], +};*/ + +// Uncomment one at a time to test various offsets array scenarios +//offsets = mockOffsets.zeroOffsets; // should render nothing below primary time +//offsets = mockOffsets.oneOffset; // should render larger in two rows +//offsets = mockOffsets.twoOffsets; // should render two in columns +//offsets = mockOffsets.fourOffsets; // should render in columns + +// END TESTING CODE + +// Check settings for what type our clock should be +var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false; + +// timeout used to update every minute +var drawTimeout; +var drawTimeoutSeconds; + +g.setBgColor(0, 0, 0); + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function doublenum(x) { + return x < 10 ? "0" + x : "" + x; +} + +function getCurrentTimeFromOffset(dt, offset) { + return new Date(dt.getTime() + offset * 60 * 60 * 1000); +} + +function updatePos() { + coord = require("Storage").readJSON(LOCATION_FILE,1)|| {"lat":53.3,"lon":10.1,"location":"Pattensen"}; + pos = SunCalc.getPosition(Date.now(), coord.lat, coord.lon); + times = SunCalc.getTimes(Date.now(), coord.lat, coord.lon); + rise = times.sunrise.toString().split(" ")[4].substr(0,5); + set = times.sunset.toString().split(" ")[4].substr(0,5); + noonpos = SunCalc.getPosition(times.solarNoon, coord.lat, coord.lon); +} + + +function drawSeconds() { + // get date + var d = new Date(); + var da = d.toString().split(" "); + + // default draw styles + g.reset(); + g.setBgColor(0, 0, 0); + + // drawSting centered + g.setFontAlign(0, 0); + + // draw time + var time = da[4].split(":"); + var seconds = time[2]; + + g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); + g.setColor("#22ff05"); + //g.setFont(font, primaryTimeFontSize-3); + g.drawString(`${seconds}`, xyCenterSeconds, yposTime+14, true); +} + +function draw() { + // get date + var d = new Date(); + var da = d.toString().split(" "); + + // default draw styles + g.reset(); + g.setBgColor(0, 0, 0); + + // drawSting centered + g.setFontAlign(0, 0); + + // draw time + var time = da[4].split(":"); + var hours = time[0], + minutes = time[1]; + + + if (_12hour){ + //do 12 hour stuff + if (hours > 12) { + ampm = "PM"; + hours = hours - 12; + } else { + ampm = "AM"; + } + } + + //g.setFont(font, primaryTimeFontSize); + g.setFont("5x9Numeric7Seg",primaryTimeFontSize); + g.setColor("#22ff05"); + g.drawString(`${doublenum(hours)}:${minutes}`, xyCenter-10, yposTime, true); + + // am / PM ? + if (_12hour){ + //do 12 hour stuff + //var ampm = require("locale").medidian(new Date()); Not working + g.setFont("Vector", 17); + g.setColor("#22ff05"); + g.drawString(ampm, xyCenterSeconds, yAmPm, true); + } + + drawSeconds(); // To make sure... + + // draw Day, name of month, Date + //DATE + var localDate = require("locale").date(new Date(), 1); + localDate = localDate.substring(0, localDate.length - 5) + g.setFont("Vector", 17); + g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true); + + + + g.setFont(font, primaryDateFontSize); + // set gmt to UTC+0 + var gmt = new Date(d.getTime() + d.getTimezoneOffset() * 60 * 1000); + + // Loop through offset(s) and render + offsets.forEach((offset, index) => { + dx = getCurrentTimeFromOffset(gmt, offset[OFFSET_HOURS]); + hours = doublenum(dx.getHours()); + minutes = doublenum(dx.getMinutes()); + + + if (offsets.length === 1) { + var date = [require("locale").dow(new Date(), 1), require("locale").date(new Date(), 1)]; + // For a single secondary timezone, draw it bigger and drop time zone to second line + const xOffset = 30; + g.setFont(font, secondaryTimeFontSize); + g.drawString(`${hours}:${minutes}`, xyCenter, yposTime2, true); + g.setFont(font, secondaryTimeZoneFontSize); + g.drawString(offset[OFFSET_TIME_ZONE], xyCenter, yposTime2 + 30, true); + + // draw Day, name of month, Date + g.setFont(font, secondaryTimeZoneFontSize); + g.drawString(date, xyCenter, yposDate, true); + } else if (index < 3) { + // For > 1 extra timezones, render as columns / rows + g.setFont(font, secondaryRowColFontSize); + g.setFontAlign(-1, 0); + g.drawString( + offset[OFFSET_TIME_ZONE], + xcol1, + yposWorld + index * 15, + true + ); + g.setFontAlign(1, 0); + g.drawString(`${hours}:${minutes}`, xcol2, yposWorld + index * 15, true); + } + }); + + g.setFontAlign(-1, 0); + g.setFont("Vector",12); + g.drawString(`^${rise}`, 10, 3 + yposWorld + 3 * 15, true); // draw riseset + g.setFontAlign(1, 0); + g.drawString(`v${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw riseset + + queueDraw(); +} + +// clean app screen +g.clear(); +// Show launcher when button pressed +Bangle.setUI("clock"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +updatePos(); +setInterval(drawSeconds, 1E3); + + + +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower',on=>{ + if (on) { + draw(); // draw immediately, queue redraw + drawSeconds(); // draw immediately, queue redraw + setInterval(updatePos, 60*5E3); // refesh every 5 mins + setInterval(drawSeconds, 1E3); + updatePos(); + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + setInterval(updatePos, 60*50E3); // refesh every 50 mins + setInterval(drawSeconds, 10E3); + updatePos(); + } +}); + +// draw now +drawSeconds(); +draw(); diff --git a/apps/hworldclock/app.png b/apps/hworldclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..506fa45b917be1f40fc2e691581ff199e8144f58 GIT binary patch literal 2867 zcmV-33(WM1P)Dr$W1mWa^_`k0JNLm4i2H*_fM*v3! zLEwGx1OW&FpahUD2*R!2a`Y+yk^+F|01O21A3+eBd+V?pUIzfr1Ly#dAqaxHFL;fe zNJu7;^z3u;UwyccOe7iD*TgeO&h1lD^ZuSC8Piu}uaFGr6SCg<^(GllvfqP{EFt+= zAL{C@e^-*p_Z0-mMI?P6g09}`7(_C$w?@yB9QBYi^%}bFWO7X0^=e2C1>htI!s&-C ztfvqJp$>qYU33i;a!VYj1DYPzSkO-kFq?G#|PI850w;MkEr=)bY3i@OO50 zj??|Nj*5y(`|`^#v$C_Zvm6~Ap90`!Z*M=)&CM+WCLXSCP|v&LY3hFj1qF#JD=Xvb z>+2O#sZ`P4-hSQM+FIDRZ{LK#z(D`3tgJn*uC7BI9UXnb!opk&3JOX!8ckmR{{5d( ztJNqgE2}OnEPQ{%h7JGLb6&rGJ@?yhzkRu@t1GgosHo)YufLXrhljg(d3jA$DwU(& ze*0~SNF)+eDisC%cA~z%{z_F<)u6z@K$ToBFKKOUEtAP);vqwZ$d@l)UXqfM z;!M&`5Cr8fZ)e)HX{+n&>u<_rvM!}kNkgbqDt2{s@tbeH$%u%E_3=IMEG%5MY}pI|4xXN#uK=(GfOp@0cXDxY@s&-RHdQn=HEFhQ-+sHXv5_R1 zo14q4SFftrL)6vPbyZhaD{^vjWK*V02_-q-@GXR`U%x)>%$YMEIXgRh*3{G}jS0@4 zJ=+o*8ag61HFddMF6ZvuyN>~|l1L;Detv%ThGfHs5BHipdGd=(mo9y4<;sCCYNlTCvlYCxx(Qn6&9hXS5 zrl#iN-o1ObtXZ>WrMtU(P*0prpFVx$wQJXY$qSvGovf^^Y^$oOYEDm2zjpKHO^sTu z=2u^RReAmTb#+g=&zd!B=1C+H4`W{>|3Fd#l24L+N`GV2s8R2=wY6zdQ&SfJu_*_JI^Qi_X0VzKy< z{QUfDB$=3)m;*oS=G6@xfcLnz<>eq4h{~H z-30M6NJg3pKnDwvNHqKC(W5s=vZbY^Ln@Vi?&jtuHr4pM@4nloP$*blUf$Hw(qb~x z%H?v^>eZ{CH?*5SfBwku@bFi4f4w3iB9^`Z3t-888FOpM0(w1f_0I$9FT3};iqshK4l}dM;6OxgU@t$G(ii(P602To3 z?iGYFJUl#n0s;bJ!otG-EEbDLe(}W@ugc|eZO5&zzkREH`i7oF$XVx}u_@KHR-~_d7bxFME1= zKA{g_(Y;u5a&k5pim9%yRs!g6&L%G}FUufchJ}UsA31X5a8y)Ow_Vl{adB}^78Mnp zRjai*Ppww-`0?Xs0rb;pw$%p^OVZ@bqQ|G7ewv^cbMD-^HeX*~?|TV|iHUi-t*wnD zdHVF}Y5=y27cX9dUyHluU|CX9a@n}sc6D_zAt51xlpdKmGL6Y?6L3 z>;WW~m}5&xNtvP1Xn648!Kz7dCl-s{#A2~qFU13Zl}IGgul%gHZQJ&b{QUeM zUwY}K0Fti*Kzw}szYGI-hUD<>*a89qp1N}7irUW3?x7WT%^^BEdc42Ce;`S>*4EYq z78Vu@TwPu7EVGbYYKFtMxVX3_K0babfctr(eFBn8h7TX^1MTk5U4^Z38mvr>aC`gq z?NdocIXOAmK2(+6fZ7$q)ym4s8ff7=1#ph!#NR|&51{MTZMqt1kBy?tjECP0)K;cnykFzk-!lkm_vK!HP?FidM|UC_ zOmabAk}dhIW+#$!NSgc>eh|_@B$ttVx=)Gk^zk?!@>VWLhEuzH=--E&LrK0ta%yjF z@B6HTZd~{PXa%re5QLk(w6_H?6~H3^F6lUWeO#e04tqEQm;&wg5urWzZ~;IQfE&7N zj?f-Y@Yb~x0Ne(UF9^bw2l4;F0T_d%4YVgx1_H2$Hd(eq`=-tt?yU3${s(KJ-urwb RzLEd{002ovPDHLkV1oI8cc%aV literal 0 HcmV?d00001 diff --git a/apps/hworldclock/custom.html b/apps/hworldclock/custom.html new file mode 100644 index 000000000..896d999f5 --- /dev/null +++ b/apps/hworldclock/custom.html @@ -0,0 +1,76 @@ + + + + + + +

You can add up to 3 timezones. Please give a name and UTC offset in hours. + If you want less than 3, clear the checkbox to the left.

+ + + + + + + +
Enabled?NameUTC Offset
+ +

Click

+ + + + + + diff --git a/apps/hworldclock/hsuncalc.js b/apps/hworldclock/hsuncalc.js new file mode 100644 index 000000000..b1af0a0d9 --- /dev/null +++ b/apps/hworldclock/hsuncalc.js @@ -0,0 +1,298 @@ +/* Module suncalc.js + (c) 2011-2015, Vladimir Agafonkin + SunCalc is a JavaScript library for calculating sun/moon position and light phases. + https://github.com/mourner/suncalc + +PB: Usage: +E.setTimeZone(2); // 1 = MEZ, 2 = MESZ +SunCalc = require("suncalc.js"); +pos = SunCalc.getPosition(Date.now(), 53.3, 10.1); +times = SunCalc.getTimes(Date.now(), 53.3, 10.1); +rise = times.sunrise; // Date object +rise_str = rise.getHours() + ':' + rise.getMinutes(); //hh:mm +*/ +var exports={}; + +// shortcuts for easier to read formulas + +var PI = Math.PI, + sin = Math.sin, + cos = Math.cos, + tan = Math.tan, + asin = Math.asin, + atan = Math.atan2, + acos = Math.acos, + rad = PI / 180; + +// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas + +// date/time constants and conversions + +var dayMs = 1000 * 60 * 60 * 24, + J1970 = 2440588, + J2000 = 2451545; + +function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; } +function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); } // PB: onece removed + 0.5; included it again 4 Jan 2021 +function toDays(date) { return toJulian(date) - J2000; } + + +// general calculations for position + +var e = rad * 23.4397; // obliquity of the Earth + +function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); } +function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); } + +function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); } +function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); } + +function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; } + +function astroRefraction(h) { + if (h < 0) // the following formula works for positive altitudes only. + h = 0; // if h = -0.08901179 a div/0 would occur. + + // formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. + // 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad: + return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179)); +} + +// general sun calculations + +function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); } + +function eclipticLongitude(M) { + + var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center + P = rad * 102.9372; // perihelion of the Earth + + return M + C + P + PI; +} + +function sunCoords(d) { + + var M = solarMeanAnomaly(d), + L = eclipticLongitude(M); + + return { + dec: declination(L, 0), + ra: rightAscension(L, 0) + }; +} + +// calculates sun position for a given date and latitude/longitude + +exports.getPosition = function (date, lat, lng) { + + var lw = rad * -lng, + phi = rad * lat, + d = toDays(date), + + c = sunCoords(d), + H = siderealTime(d, lw) - c.ra; + + return { + azimuth: Math.round((azimuth(H, phi, c.dec) / rad + 180) % 360), // PB: converted to deg + altitude: Math.round( altitude(H, phi, c.dec) / rad) // PB: converted to deg + }; +}; + + +// sun times configuration (angle, morning name, evening name) + +var times = [ + [-0.833, 'sunrise', 'sunset' ] +]; + +// calculations for sun times +var J0 = 0.0009; + +function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); } + +function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; } +function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); } + +function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); } +function observerAngle(height) { return -2.076 * Math.sqrt(height) / 60; } + +// returns set time for the given sun altitude +function getSetJ(h, lw, phi, dec, n, M, L) { + + var w = hourAngle(h, phi, dec), + a = approxTransit(w, lw, n); + return solarTransitJ(a, M, L); +} + + +// calculates sun times for a given date, latitude/longitude, and, optionally, +// the observer height (in meters) relative to the horizon + +exports.getTimes = function (date, lat, lng, height) { + + height = height || 0; + + var lw = rad * -lng, + phi = rad * lat, + + dh = observerAngle(height), + + d = toDays(date), + n = julianCycle(d, lw), + ds = approxTransit(0, lw, n), + + M = solarMeanAnomaly(ds), + L = eclipticLongitude(M), + dec = declination(L, 0), + + Jnoon = solarTransitJ(ds, M, L), + + i, len, time, h0, Jset, Jrise; + + + var result = { + solarNoon: fromJulian(Jnoon), + nadir: fromJulian(Jnoon - 0.5) + }; + + for (i = 0, len = times.length; i < len; i += 1) { + time = times[i]; + h0 = (time[0] + dh) * rad; + + Jset = getSetJ(h0, lw, phi, dec, n, M, L); + Jrise = Jnoon - (Jset - Jnoon); + + result[time[1]] = fromJulian(Jrise); + result[time[2]] = fromJulian(Jset); + } + + return result; +}; + + +// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas + +function moonCoords(d) { // geocentric ecliptic coordinates of the moon + + var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude + M = rad * (134.963 + 13.064993 * d), // mean anomaly + F = rad * (93.272 + 13.229350 * d), // mean distance + + l = L + rad * 6.289 * sin(M), // longitude + b = rad * 5.128 * sin(F), // latitude + dt = 385001 - 20905 * cos(M); // distance to the moon in km + + return { + ra: rightAscension(l, b), + dec: declination(l, b), + dist: dt + }; +} + +getMoonPosition = function (date, lat, lng) { + + var lw = rad * -lng, + phi = rad * lat, + d = toDays(date), + + c = moonCoords(d), + H = siderealTime(d, lw) - c.ra, + h = altitude(H, phi, c.dec), + // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. + pa = atan(sin(H), tan(phi) * cos(c.dec) - sin(c.dec) * cos(H)); + + h = h + astroRefraction(h); // altitude correction for refraction + + return { + azimuth: azimuth(H, phi, c.dec), + altitude: h, + distance: c.dist, + parallacticAngle: pa + }; +}; + + +// calculations for illumination parameters of the moon, +// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and +// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. + +getMoonIllumination = function (date) { + + var d = toDays(date || new Date()), + s = sunCoords(d), + m = moonCoords(d), + + sdist = 149598000, // distance from Earth to Sun in km + + phi = acos(sin(s.dec) * sin(m.dec) + cos(s.dec) * cos(m.dec) * cos(s.ra - m.ra)), + inc = atan(sdist * sin(phi), m.dist - sdist * cos(phi)), + angle = atan(cos(s.dec) * sin(s.ra - m.ra), sin(s.dec) * cos(m.dec) - + cos(s.dec) * sin(m.dec) * cos(s.ra - m.ra)); + + return { + fraction: (1 + cos(inc)) / 2, + phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI, + angle: angle + }; +}; + + +function hoursLater(date, h) { + return new Date(date.valueOf() + h * dayMs / 24); +} + +// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article + +getMoonTimes = function (date, lat, lng, inUTC) { + var t = new Date(date); + if (inUTC) t.setUTCHours(0, 0, 0, 0); + else t.setHours(0, 0, 0, 0); + + var hc = 0.133 * rad, + h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc, + h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx; + + // go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set) + for (var i = 1; i <= 24; i += 2) { + h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc; + h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc; + + a = (h0 + h2) / 2 - h1; + b = (h2 - h0) / 2; + xe = -b / (2 * a); + ye = (a * xe + b) * xe + h1; + d = b * b - 4 * a * h1; + roots = 0; + + if (d >= 0) { + dx = Math.sqrt(d) / (Math.abs(a) * 2); + x1 = xe - dx; + x2 = xe + dx; + if (Math.abs(x1) <= 1) roots++; + if (Math.abs(x2) <= 1) roots++; + if (x1 < -1) x1 = x2; + } + + if (roots === 1) { + if (h0 < 0) rise = i + x1; + else set = i + x1; + + } else if (roots === 2) { + rise = i + (ye < 0 ? x2 : x1); + set = i + (ye < 0 ? x1 : x2); + } + + if (rise && set) break; + + h0 = h2; + } + + var result = {}; + + if (rise) result.rise = hoursLater(t, rise); + if (set) result.set = hoursLater(t, set); + + if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true; + + return result; +}; \ No newline at end of file diff --git a/apps/hworldclock/hworldclock-icon.js b/apps/hworldclock/hworldclock-icon.js new file mode 100644 index 000000000..6e05d254c --- /dev/null +++ b/apps/hworldclock/hworldclock-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgJC/ABEE+EA4EAj9E8HF//gn/gwP///wt/MgF//8gh/8gYLBwEP+EHAofghgFD4EOj//gEPA4ILBGgIxB/wFBgwFB/lsgCKBj/4oxHBvAFBJoV8gP4TQX+gJUBAAN/Aok+AoVgAoXogAfBjkA8AfBAoXAAoUYY4cAiCDEAooA/ABg")) diff --git a/apps/hworldclock/hworldclock.png b/apps/hworldclock/hworldclock.png new file mode 100644 index 0000000000000000000000000000000000000000..565e0dc6b8e08edffc313b889bc2e062ffc1edf7 GIT binary patch literal 3457 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 Date: Sat, 11 Jun 2022 15:23:47 +0200 Subject: [PATCH 137/183] Initial Release --- .../widget.png | Bin 0 -> 2385 bytes apps/hwid_a_battery_widget/ChangeLog | 5 ++ apps/hwid_a_battery_widget/README.md | 15 +++++ .../h_battery_widget-pic.jpg | Bin 0 -> 66429 bytes apps/hwid_a_battery_widget/metadata.json | 15 +++++ apps/hwid_a_battery_widget/widget.js | 56 ++++++++++++++++++ apps/hwid_a_battery_widget/widget.png | Bin 0 -> 877 bytes 7 files changed, 91 insertions(+) create mode 100644 apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png create mode 100644 apps/hwid_a_battery_widget/ChangeLog create mode 100644 apps/hwid_a_battery_widget/README.md create mode 100644 apps/hwid_a_battery_widget/h_battery_widget-pic.jpg create mode 100644 apps/hwid_a_battery_widget/metadata.json create mode 100644 apps/hwid_a_battery_widget/widget.js create mode 100644 apps/hwid_a_battery_widget/widget.png diff --git a/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png b/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..868628b6085cb0da28098648ae713dc1f08e44d0 GIT binary patch literal 2385 zcmaJ@3s_S}7QRV%6-6sAF<4ClyK7v@i-;0K3Ni8!q9Gtc4b~8DAdq)1aB(YAt>u%d z1QAzxOM?njO9Tu>6tPi@^y8Cq0o>m5~KlokLMAQ3HazyNs#E&zZ#FAa}`B6%T9u~JSJ#VTV!GAvi2N&pLHBBmUK zLS3?Dm5U%i%ca`iELW}fxyzlN|*w!{|p^@ z^C8AVkcvs6q@<*fQ#{E^O&o>h?d?sW(kXPh2ZHd>rYay2?4i)QO^f`Y!v(csjZ_6m zl?no?D~eGjK|Vwxy3y-49VaA}%- zo53R0G|7Az(=oEp2$)dxGIwnb9z78#m+Sq0cd}KFI#A;yHf?IRDcwX=oQiR>aFy?ugdQ6YyDM9=!Ox)6 z-QwI1%ye`nVGTAnt{o#ero6HML)Uy^Dj6ygJslhQ-l*K`UtG1cwe@N1cVDLrwdRMG z*64k76TUsT2uh&{4?j3|Ne+tME|dQYKSCDEpg8kolSq#+^^!R)ie+U z+s11v=x1NukMZ}niWUm_R2O|qOK`|UPMgE#(5}Jk;~k)HT0%l*MP+4DZAyM`Pfuxc za}bloswueJ3BW4`U0q#Co}QjDK$KIEn`0ez=clGG-0CZEQ^M%z@-?u@J`5Kt(5+iU z#uXJ8=iGmKrnyp3Bv0G-oedIQndCY+#&iwI4%dH@kxX^BbGx#&>l$)y9T~ zkjlzR27|%n@pupf>3gb(iHV6Hepx3Z=bb!xs=mG+w&RbTc;zlnU-sJ6JCs%aX z>{!HYi_>azcJKZQPoS#rbKUi=N-VU=E%-tkypQL*|~ zOUnW`T+CgsyMm664#o!`eARY=_wK;w_qw~!V2!1v9Jf`=Tt3OM-BDRvyKQ7|=fk0) z3UTLfFhy+I?6Dod#QiOvLL!Bx7oB7eSJ~g*e--e3wmRopRvE^nd$={{#|FZYOIi0` z{iDsmz26SNiEa)73wZvvR8kw&<<{1Q|u{R*kDbNFBDQ31}%3AJl^-n#&A7i zxIK5{orx`M+GVZ3ZuIbI-e`Wmh~?5m3NID^c4ADVE=l|sd~femU2l7U^9Td|Ul6ou L3->%{*S`M&n6+>< literal 0 HcmV?d00001 diff --git a/apps/hwid_a_battery_widget/ChangeLog b/apps/hwid_a_battery_widget/ChangeLog new file mode 100644 index 000000000..84cbad8ad --- /dev/null +++ b/apps/hwid_a_battery_widget/ChangeLog @@ -0,0 +1,5 @@ +0.01: Release for Bangle 2 (2021/11/18) +0.02: Internal id update to wid_* as per Gordon's request (2021/11/21) +0.03: Support dark themes +0.04: Increase screen update rate when charging +0.05: Deleting Background - making Font larger \ No newline at end of file diff --git a/apps/hwid_a_battery_widget/README.md b/apps/hwid_a_battery_widget/README.md new file mode 100644 index 000000000..638272b3f --- /dev/null +++ b/apps/hwid_a_battery_widget/README.md @@ -0,0 +1,15 @@ +# A Battery Widget (with percentage) + +Show the current battery level and charging status in the top right of the clock, with charge percentage + +* Works with Bangle 2 +* Simple design, no settings + * Red when the batterly level is below 30% + * Blue when charging +* 40 pixels wide + +![](a_battery_widget-pic.jpg) + +## Creator +[@alainsaas](https://github.com/alainsaas) +Mod by Hank diff --git a/apps/hwid_a_battery_widget/h_battery_widget-pic.jpg b/apps/hwid_a_battery_widget/h_battery_widget-pic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9d9a4deccf352be3086e7d8d66200a436839c8da GIT binary patch literal 66429 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�y4n1O6P<0tvFKDNAjl02*?a;Bxc?7T-^SzHp2 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 { + if (Bangle.isCharging()) return COLORS.charging; + if (l >= 30) return COLORS.high; + return COLORS.low; + }; + + function draw() { + var s = 29; + var x = this.x, y = this.y; + + const l = E.getBattery(); + + let xl = x+4+l*(s-12)/100; + + g.setColor(COLORS.white); + // g.fillRect(x+2,y+5,x+s-6,y+18); + + g.fillRect(x,y,xl+4,y+16+3); //Clear + + g.setColor(levelColor(l)); + // g.fillRect(x+1,y+3,x+s-5,y+4); + // g.fillRect(x+1,y+19,x+s-5,y+20); + // g.fillRect(x,y+4,x+1,y+19); + // g.fillRect(x+s-5,y+4,x+s-4,y+19); + //g.fillRect(x+s-3,y+8,x+s-2,y+16); // tip of the battery + g.fillRect(x+4,y+14+3,xl,y+16+3); // charging bar + + g.fillRect((x+4+100*(s-12)/100)-1,y+14+3,x+4+100*(s-12)/100,y+16+3); // charging bar full + + g.setColor(COLORS.black); + g.setFontAlign(0,0); + g.setFont('Vector',16); + g.drawString(l, x + 14, y + 10); + + if (Bangle.isCharging()) changeInterval(id, intervalHigh); + else changeInterval(id, intervalLow); + } + + + Bangle.on('charging',function(charging) { draw(); }); + var id = setInterval(()=>WIDGETS["wid_a_battery_widget"].draw(), intervalLow); + + WIDGETS["wid_a_battery_widget"]={area:"tr",width:30,draw:draw}; +})(); diff --git a/apps/hwid_a_battery_widget/widget.png b/apps/hwid_a_battery_widget/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..b9c9594b15c9832c0c5632044ae68989ff5f8cba GIT binary patch literal 877 zcmV-z1CsoSP)kEXCn{4Izi|(P5>F#v86JekZe56yURMlVS)agELvk4O>OqeiXb7r^O zZBD0i!{_sDc)i|vZ0m;R#r%97rVNWuCX>$#g~DIr5AlomNo0uc#4+)S_&~fT-Vlex zYXbj^5>JSS#6EGKxJTR}ZV@+#Ys47aH3bttea}Z(5u=6y?@9}udrqk&uCX)#V zziY8fpZW3e8$`eprVOD%1N^{XYKHc~V8Cj%8Y>oym}~~Lbvhl^@Ant>QJVv8)aMey z$*cey4UpCoP_NfnC=_BYm+J(#+s(msEEZ$sa+w8#!I^d?i9~{XKtsRjUhl5||ayh-Bmk@xLwsU-bmcPY4n42o|5oWLT@!;<1iUfk%`fgs`est4vN3 z8Uij_74X@J0QA9Ol*0+1_>SFex7*wkYT;ubgf^`T__9cVym;(5b{>m|C**X9EL5pf zShLyWAtr}fKA-2FfCzX&L%?OL0zNJhfXU^sNvG2@X;GP}(8q*;ZL0!~j0nIYuo%R< zG92_WmBA3YVpYI9qaMI69u)yQRs|ejBJ3I#Pt7YqD|N2J1JSeYf#{h%1E_>(fTwcS(5tGJMJrpWRAg68 zS7fL~sU|&7gFKdM+I^|UeTKs=)xI$zA%X8NB@Q5-ctkvqYT>)YZQ`a>4_}vR;ytM@ z-ocJ5*rWM Date: Sat, 11 Jun 2022 15:55:03 +0200 Subject: [PATCH 138/183] Improve median calculation Do no longer show 3h average pressure in widget --- apps/widbaroalarm/README.md | 2 +- apps/widbaroalarm/widget.js | 74 +++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/apps/widbaroalarm/README.md b/apps/widbaroalarm/README.md index a74d89546..80ba35abc 100644 --- a/apps/widbaroalarm/README.md +++ b/apps/widbaroalarm/README.md @@ -19,7 +19,7 @@ Get a notification when the pressure reaches defined thresholds. * Pause delay: Same as Dismiss delay but longer (usefull for meetings and such). From 30 to 240 min ## Widget -The widget shows two rows: pressure value of last measurement and pressure average of the the last three hours. +The widget shows the last median pressure value ## Creator Marco ([myxor](https://github.com/myxor)) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 721d0bbb8..00456f42f 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -37,8 +37,12 @@ E.showPrompt(body, { title: "Pressure alarm", - buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } - }).then(function (v) { + buttons: { + "Ok": 1, + "Dismiss": 2, + "Pause": 3 + } + }).then(function(v) { const tsNow = Math.round(Date.now() / 1000); // seconds if (v == 1) { @@ -176,45 +180,38 @@ } - - function baroHandler(data) { - if (data) { - const pressure = Math.round(data.pressure); - if (pressure == undefined || pressure <= 0) return; - currentPressures.push(pressure); - } - } - /* turn on barometer power - take `numberOfMeasurements` measurements with a delay of 1000ms each + take multiple measurements sort the results take the middle one (median) turn off barometer power */ function check() { + const MEDIANLENGTH = 20; Bangle.setBarometerPower(true, "widbaroalarm"); - setTimeout(function() { - currentPressures = []; + Bangle.on('pressure', function(e) { + while (currentPressures.length > MEDIANLENGTH) currentPressures.pop(); + currentPressures.unshift(e.pressure); + median = currentPressures.slice().sort(); - const numberOfMeasurements = 7; - - for (let i = 0; i < numberOfMeasurements; i++) { - setTimeout(function() { - Bangle.getPressure().then(baroHandler); - }, i * 1000); + if (median.length > 10) { + var mid = median.length >> 1; + medianPressure = Math.round(E.sum(median.slice(mid - 4, mid + 5)) / 9); + if (medianPressure > 0) { + turnOff(); + checkForAlarms(medianPressure); + } } + }); - setTimeout(function() { - Bangle.setBarometerPower(false, "widbaroalarm"); + setTimeout(function() { + turnOff(); + }, 10000); + } - currentPressures.sort(); - - // take median value - medianPressure = currentPressures[Math.round(numberOfMeasurements / 2) + 1]; - checkForAlarms(medianPressure); - }, numberOfMeasurements * 1000 + 500); - }, 500); + function turnOff() { + Bangle.setBarometerPower(false, "widbaroalarm"); } function reload() { @@ -222,8 +219,8 @@ } function draw() { - if (global.WIDGETS != undefined && typeof WIDGETS === "object") { - WIDGETS["baroalarm"] = { + if (global.WIDGETS != undefined && typeof global.WIDGETS === "object") { + global.WIDGETS["baroalarm"] = { width: setting("show") ? 24 : 0, reload: reload, area: "tr", @@ -235,18 +232,13 @@ if (setting("show") && medianPressure != undefined) { g.setFont("6x8", 1).setFontAlign(1, 0); g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); - if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) { - g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10); - } } } - // Let's delay the first check a bit - setTimeout(function() { - check(); - if (interval > 0) { - setInterval(check, interval * 60000); - } - }, 1000); + check(); + if (interval > 0) { + setInterval(check, interval * 60000); + } + draw(); })(); From e6515080e85e4ef2d1ba081ec453abdcbec51263 Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 17:46:36 +0200 Subject: [PATCH 139/183] Fixing refresh issues --- apps/hwid_a_battery_widget/ChangeLog | 3 +- apps/hwid_a_battery_widget/metadata.json | 2 +- apps/hwid_a_battery_widget/widget.js | 92 ++++++++++++------------ 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/apps/hwid_a_battery_widget/ChangeLog b/apps/hwid_a_battery_widget/ChangeLog index 84cbad8ad..3d7b39737 100644 --- a/apps/hwid_a_battery_widget/ChangeLog +++ b/apps/hwid_a_battery_widget/ChangeLog @@ -2,4 +2,5 @@ 0.02: Internal id update to wid_* as per Gordon's request (2021/11/21) 0.03: Support dark themes 0.04: Increase screen update rate when charging -0.05: Deleting Background - making Font larger \ No newline at end of file +0.05: Deleting Background - making Font larger +0.06: Fixing refresh issues \ No newline at end of file diff --git a/apps/hwid_a_battery_widget/metadata.json b/apps/hwid_a_battery_widget/metadata.json index 7fdd2907a..d0cb5233a 100644 --- a/apps/hwid_a_battery_widget/metadata.json +++ b/apps/hwid_a_battery_widget/metadata.json @@ -3,7 +3,7 @@ "name": "A Battery Widget (with percentage) - Hanks Mod", "shortName":"H Battery Widget", "icon": "widget.png", - "version":"0.04", + "version":"0.06", "type": "widget", "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", diff --git a/apps/hwid_a_battery_widget/widget.js b/apps/hwid_a_battery_widget/widget.js index 0929dea41..708e8cbbf 100644 --- a/apps/hwid_a_battery_widget/widget.js +++ b/apps/hwid_a_battery_widget/widget.js @@ -1,56 +1,54 @@ (function(){ - const intervalLow = 60000; // update time when not charging - const intervalHigh = 2000; // update time when charging + const intervalLow = 60000; // update time when not charging + const intervalHigh = 2000; // update time when charging + var old_l; - let COLORS = { - 'white': g.theme.dark ? "#000" : "#fff", - 'black': g.theme.dark ? "#fff" : "#000", - 'charging': "#08f", - 'high': g.theme.dark ? "#fff" : "#000", - 'low': "#f00", - }; + let COLORS = { + 'white': g.theme.dark ? "#000" : "#fff", + 'black': g.theme.dark ? "#fff" : "#000", + 'charging': "#08f", + 'high': g.theme.dark ? "#fff" : "#000", + 'low': "#f00", + }; - const levelColor = (l) => { - if (Bangle.isCharging()) return COLORS.charging; - if (l >= 30) return COLORS.high; - return COLORS.low; - }; + const levelColor = (l) => { + if (Bangle.isCharging()) return COLORS.charging; + if (l >= 30) return COLORS.high; + return COLORS.low; + }; - function draw() { - var s = 29; - var x = this.x, y = this.y; + function draw() { + var s = 29; + var x = this.x, y = this.y; + const l = E.getBattery(); + let xl = x+4+l*(s-12)/100; + if (l != old_l){ // Delete the old value from screen + old_l = l; + let xl_old = x+4+old_l*(s-12)/100; + g.setColor(COLORS.white); + // g.fillRect(x+2,y+5,x+s-6,y+18); + g.fillRect(x,y,xl+4,y+16+3); //Clear + g.setFontAlign(0,0); + g.setFont('Vector',16); + g.drawString(old_l, x + 14, y + 10); + g.fillRect(x+4,y+14+3,xl_old,y+16+3); // charging bar + } - const l = E.getBattery(); + g.setColor(levelColor(l)); + g.fillRect(x+4,y+14+3,xl,y+16+3); // charging bar + g.fillRect((x+4+100*(s-12)/100)-1,y+14+3,x+4+100*(s-12)/100,y+16+3); // charging bar "full mark" + // Show percentage + g.setColor(COLORS.black); + g.setFontAlign(0,0); + g.setFont('Vector',16); + g.drawString(l, x + 14, y + 10); - let xl = x+4+l*(s-12)/100; + if (Bangle.isCharging()) changeInterval(id, intervalHigh); + else changeInterval(id, intervalLow); + } - g.setColor(COLORS.white); - // g.fillRect(x+2,y+5,x+s-6,y+18); + Bangle.on('charging',function(charging) { draw(); }); + var id = setInterval(()=>WIDGETS["wid_a_battery_widget"].draw(), intervalLow); - g.fillRect(x,y,xl+4,y+16+3); //Clear - - g.setColor(levelColor(l)); - // g.fillRect(x+1,y+3,x+s-5,y+4); - // g.fillRect(x+1,y+19,x+s-5,y+20); - // g.fillRect(x,y+4,x+1,y+19); - // g.fillRect(x+s-5,y+4,x+s-4,y+19); - //g.fillRect(x+s-3,y+8,x+s-2,y+16); // tip of the battery - g.fillRect(x+4,y+14+3,xl,y+16+3); // charging bar - - g.fillRect((x+4+100*(s-12)/100)-1,y+14+3,x+4+100*(s-12)/100,y+16+3); // charging bar full - - g.setColor(COLORS.black); - g.setFontAlign(0,0); - g.setFont('Vector',16); - g.drawString(l, x + 14, y + 10); - - if (Bangle.isCharging()) changeInterval(id, intervalHigh); - else changeInterval(id, intervalLow); - } - - - Bangle.on('charging',function(charging) { draw(); }); - var id = setInterval(()=>WIDGETS["wid_a_battery_widget"].draw(), intervalLow); - - WIDGETS["wid_a_battery_widget"]={area:"tr",width:30,draw:draw}; + WIDGETS["wid_a_battery_widget"]={area:"tr",width:30,draw:draw}; })(); From 5c8ba46ea96159da3e8fc23daf5f7845f4698435 Mon Sep 17 00:00:00 2001 From: David Peer Date: Sat, 11 Jun 2022 17:49:47 +0200 Subject: [PATCH 140/183] Version 0.10 - Show daily step count, temperature as well as heartrate. --- apps/cassioWatch/ChangeLog | 3 +- apps/cassioWatch/README.md | 3 +- apps/cassioWatch/app.js | 61 ++++++++++++++++++++++++++++++++++---- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/apps/cassioWatch/ChangeLog b/apps/cassioWatch/ChangeLog index f00b3fa0a..419810021 100644 --- a/apps/cassioWatch/ChangeLog +++ b/apps/cassioWatch/ChangeLog @@ -7,4 +7,5 @@ 0.6: Add Settings Page 0.7: Update Rocket Sequences Scope to not use memory all time 0.8: Update Some Variable Scopes to not use memory until need -0.9: Remove ESLint spaces \ No newline at end of file +0.9: Remove ESLint spaces +0.10: Show daily steps, heartrate and the temperature if weather information is available. \ No newline at end of file diff --git a/apps/cassioWatch/README.md b/apps/cassioWatch/README.md index 1342af8e6..aaeb3f122 100644 --- a/apps/cassioWatch/README.md +++ b/apps/cassioWatch/README.md @@ -6,5 +6,6 @@ Clock with Space Cassio Watch Style. It displays current temperature,day,steps,battery.heartbeat and weather. + **To-do**: -Integrate heartbeat and Weather, Align and change size of some elements. +Align and change size of some elements. diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 93538ec50..49e23c2eb 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -1,7 +1,11 @@ +const storage = require('Storage'); +const locale = require('locale'); + require("Font6x12").add(Graphics); require("Font8x12").add(Graphics); require("Font7x11Numeric7Seg").add(Graphics); + let ClockInterval; let RocketInterval; let BatteryInterval; @@ -43,7 +47,7 @@ function getRocketSequences() { let rocket_sequence = 1; -let settings = require('Storage').readJSON("cassioWatch.settings.json", true) || {}; +let settings = storage.readJSON("cassioWatch.settings.json", true) || {}; let rocketSpeed = settings.rocketSpeed || 700; delete settings; @@ -82,6 +86,43 @@ function DrawRocket() { if (rocket_sequence > 8) rocket_sequence = 1; } +function getTemperature(){ + try { + var weatherJson = storage.readJSON('weather.json'); + var weather = weatherJson.weather; + return Math.round(weather.temp-273.15); + + } catch(ex) { + print(ex) + return "?" + } +} + +function getSteps() { + var steps = 0; + try{ + if (WIDGETS.wpedom !== undefined) { + steps = WIDGETS.wpedom.getSteps(); + } else if (WIDGETS.activepedom !== undefined) { + steps = WIDGETS.activepedom.getSteps(); + } else { + steps = Bangle.getHealthStatus("day").steps; + } + } catch(ex) { + // In case we failed, we can only show 0 steps. + return "? k"; + } + + // Show always 2 digits. E.g. 1.5k if < 10000 otherwise 12k + if(steps > 10000){ + steps = Math.round(steps/1000); + } else { + steps = Math.round(steps/100) / 10; + } + return steps + "k"; +} + + function DrawScene() { g.reset(); g.clear(); @@ -94,17 +135,22 @@ function DrawScene() { g.drawString("Launching Process", 30, 20); g.setFont("8x12"); g.drawString("ACTIVATE", 40, 35); + + g.setFontAlign(0,-1); g.setFont("8x12", 2); - g.drawString("30", 142, 132); - g.drawString("55", 95, 98); - g.setFont("8x12", 1); - g.drawString(Bangle.getStepCount(), 143, 104); + g.drawString(getTemperature(), 155, 132); + g.drawString(Math.round(Bangle.getHealthStatus("last").bpm), 109, 98); + g.drawString(getSteps(), 158, 98); + + g.setFontAlign(-1,-1); ClockInterval = setInterval(DrawClock, 30000); DrawClock(); RocketInterval = setInterval(DrawRocket, rocketSpeed); DrawRocket(); BatteryInterval = setInterval(DrawBattery, 5 * 60000); DrawBattery(); + + for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} } Bangle.on("lcdPower", (on) => { @@ -123,6 +169,11 @@ Bangle.on("lock", (locked) => { } }); + +// Load widgets, but don't show them +Bangle.loadWidgets(); + + g.reset(); g.clear(); Bangle.setUI("clock"); From 8295cc794e6e074735a6cbbd47c9ec316318516d Mon Sep 17 00:00:00 2001 From: David Peer Date: Sat, 11 Jun 2022 17:58:15 +0200 Subject: [PATCH 141/183] Update version to 0.10 --- apps/cassioWatch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cassioWatch/metadata.json b/apps/cassioWatch/metadata.json index 70cd9c242..dabdc2c93 100644 --- a/apps/cassioWatch/metadata.json +++ b/apps/cassioWatch/metadata.json @@ -4,7 +4,7 @@ "description": "Animated Clock with Space Cassio Watch Style", "screenshots": [{ "url": "screens/screen_night.png" },{ "url": "screens/screen_day.png" }], "icon": "app.png", - "version": "0.9", + "version": "0.10", "type": "clock", "tags": "clock, weather, cassio, retro", "supports": ["BANGLEJS2"], From 3ec548c922de3d9f60b6f7db55d2c15d372e2ee2 Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 17:58:18 +0200 Subject: [PATCH 142/183] Prepare new version --- apps/hwid_a_battery_widget/ChangeLog | 3 ++- apps/hwid_a_battery_widget/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/hwid_a_battery_widget/ChangeLog b/apps/hwid_a_battery_widget/ChangeLog index 3d7b39737..9d5ee1264 100644 --- a/apps/hwid_a_battery_widget/ChangeLog +++ b/apps/hwid_a_battery_widget/ChangeLog @@ -3,4 +3,5 @@ 0.03: Support dark themes 0.04: Increase screen update rate when charging 0.05: Deleting Background - making Font larger -0.06: Fixing refresh issues \ No newline at end of file +0.06: Fixing refresh issues +0.07 \ No newline at end of file diff --git a/apps/hwid_a_battery_widget/metadata.json b/apps/hwid_a_battery_widget/metadata.json index d0cb5233a..38fd503a2 100644 --- a/apps/hwid_a_battery_widget/metadata.json +++ b/apps/hwid_a_battery_widget/metadata.json @@ -3,7 +3,7 @@ "name": "A Battery Widget (with percentage) - Hanks Mod", "shortName":"H Battery Widget", "icon": "widget.png", - "version":"0.06", + "version":"0.07", "type": "widget", "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", From 99cdfdb8d48603baae38cf9c347b79a42653933d Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 18:15:27 +0200 Subject: [PATCH 143/183] Removing obsolete stuff --- apps/hworldclock/app.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 8122371a6..1358b81d2 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -246,7 +246,6 @@ setInterval(drawSeconds, 1E3); Bangle.on('lcdPower',on=>{ if (on) { draw(); // draw immediately, queue redraw - drawSeconds(); // draw immediately, queue redraw setInterval(updatePos, 60*5E3); // refesh every 5 mins setInterval(drawSeconds, 1E3); updatePos(); @@ -262,5 +261,4 @@ Bangle.on('lcdPower',on=>{ }); // draw now -drawSeconds(); draw(); From b5c3607ca192bf3d9a37dd8b9fdf69572148e8ae Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 18:22:37 +0200 Subject: [PATCH 144/183] Version Info --- apps/hworldclock/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 1358b81d2..f724c35d9 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -129,6 +129,7 @@ function drawSeconds() { g.setColor("#22ff05"); //g.setFont(font, primaryTimeFontSize-3); g.drawString(`${seconds}`, xyCenterSeconds, yposTime+14, true); + queueDraw(); } function draw() { @@ -238,7 +239,7 @@ Bangle.setUI("clock"); Bangle.loadWidgets(); Bangle.drawWidgets(); updatePos(); -setInterval(drawSeconds, 1E3); +setInterval(drawSeconds, 1E3/2); From 3e0a5af414e57e39b55808e2d4a394e44c320fef Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 18:22:56 +0200 Subject: [PATCH 145/183] Version Info --- apps/hworldclock/ChangeLog | 1 + apps/hworldclock/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index 5b2a1edce..e67af806a 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1 +1,2 @@ 0.15: Initial release - be patient as this is the first try :) +0.16: Fix timing \ No newline at end of file diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index e9e0175f5..4f3cd80cf 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.15", + "version": "0.16", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From e1180c88d23cc21c48f99e0a9c1f8b9b25d14e78 Mon Sep 17 00:00:00 2001 From: David Peer Date: Sat, 11 Jun 2022 19:08:37 +0200 Subject: [PATCH 146/183] Use interval for animation and timeout for time to ensure that the time changes precisely. --- apps/cassioWatch/app.js | 90 ++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 49e23c2eb..75ec85503 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -1,15 +1,9 @@ const storage = require('Storage'); -const locale = require('locale'); require("Font6x12").add(Graphics); require("Font8x12").add(Graphics); require("Font7x11Numeric7Seg").add(Graphics); - -let ClockInterval; -let RocketInterval; -let BatteryInterval; - function bigThenSmall(big, small, x, y) { g.setFont("7x11Numeric7Seg", 2); g.drawString(big, x, y); @@ -18,16 +12,6 @@ function bigThenSmall(big, small, x, y) { g.drawString(small, x, y); } -function ClearIntervals(inoreclock) { - if (RocketInterval) clearInterval(RocketInterval); - if (BatteryInterval) clearInterval(BatteryInterval); - RocketInterval = undefined; - BatteryInterval = undefined; - if (inoreclock) return; - if (ClockInterval) clearInterval(ClockInterval); - ClockInterval = undefined; -} - function getBackgroundImage() { return require("heatshrink").decompress(atob("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")); } @@ -45,15 +29,31 @@ function getRocketSequences() { }; } -let rocket_sequence = 1; - +let rocketSequence = 1; let settings = storage.readJSON("cassioWatch.settings.json", true) || {}; let rocketSpeed = settings.rocketSpeed || 700; delete settings; -g.clear(); +// schedule a draw for the next minute +let rocketInterval; +var drawTimeout; +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} -function DrawClock() { + +function clearIntervals() { + if (rocketInterval) clearInterval(rocketInterval); + rocketInterval = undefined; + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; +} + +function drawClock() { g.setFont("7x11Numeric7Seg", 3); g.clearRect(80, 57, 170, 96); g.setColor(0, 255, 255); @@ -70,20 +70,20 @@ function DrawClock() { g.drawString(time < 10 ? "0" + time : time, 78, 137); } -function DrawBattery() { +function drawBattery() { bigThenSmall(E.getBattery(), "%", 135, 21); } -function DrawRocket() { +function drawRocket() { let Rocket = getRocketSequences(); g.clearRect(5, 62, 63, 115); g.setColor(0, 255, 255); g.drawRect(5, 62, 63, 115); g.fillRect(5, 62, 63, 115); - g.drawImage(Rocket[rocket_sequence], 5, 65, { scale: 0.7 }); + g.drawImage(Rocket[rocketSequence], 5, 65, { scale: 0.7 }); g.setColor(0, 0, 0); - rocket_sequence = rocket_sequence + 1; - if (rocket_sequence > 8) rocket_sequence = 1; + rocketSequence = rocketSequence + 1; + if(rocketSequence > 8) rocketSequence = 1; } function getTemperature(){ @@ -123,7 +123,9 @@ function getSteps() { } -function DrawScene() { +function draw() { + queueDraw(); + g.reset(); g.clear(); g.setColor(0, 255, 255); @@ -143,42 +145,36 @@ function DrawScene() { g.drawString(getSteps(), 158, 98); g.setFontAlign(-1,-1); - ClockInterval = setInterval(DrawClock, 30000); - DrawClock(); - RocketInterval = setInterval(DrawRocket, rocketSpeed); - DrawRocket(); - BatteryInterval = setInterval(DrawBattery, 5 * 60000); - DrawBattery(); + drawClock(); + drawRocket(); + rocketSequence -= 1; // This avoids a "jump" in the animation + drawBattery(); for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} } Bangle.on("lcdPower", (on) => { - if (!on) { - g.clear(); - ClearIntervals(true); + if (on) { + draw(); + } else { + clearIntervals(); } }); + Bangle.on("lock", (locked) => { - if (locked) { - ClearIntervals(true); - } else { - ClearIntervals(); - DrawScene(); + clearIntervals(); + draw(); + if (!locked) { + rocketInterval = setInterval(drawRocket, rocketSpeed); } }); // Load widgets, but don't show them Bangle.loadWidgets(); - +Bangle.setUI("clock"); g.reset(); g.clear(); -Bangle.setUI("clock"); -DrawScene(); - -if (Bangle.isLocked()) { - ClearIntervals(true); -} \ No newline at end of file +draw(); \ No newline at end of file From 1a3b8e5446a26a7a73973d4148c7fb920dcb81ce Mon Sep 17 00:00:00 2001 From: pebl-hank Date: Sat, 11 Jun 2022 23:08:03 +0200 Subject: [PATCH 147/183] Fix hours --- apps/hworldclock/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index f724c35d9..c37ec5714 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -163,7 +163,7 @@ function draw() { //g.setFont(font, primaryTimeFontSize); g.setFont("5x9Numeric7Seg",primaryTimeFontSize); g.setColor("#22ff05"); - g.drawString(`${doublenum(hours)}:${minutes}`, xyCenter-10, yposTime, true); + g.drawString(`${hours}:${minutes}`, xyCenter-10, yposTime, true); // am / PM ? if (_12hour){ From 223ee5043535dd61f2684dbf91048865f64a6f53 Mon Sep 17 00:00:00 2001 From: pancake Date: Sun, 12 Jun 2022 02:36:39 +0200 Subject: [PATCH 148/183] football: Upgrade to 1.01. Works with BTN1 --- apps/football/ChangeLog | 1 + apps/football/app.js | 76 +++++++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/apps/football/ChangeLog b/apps/football/ChangeLog index 9b91672a5..66b9882cc 100644 --- a/apps/football/ChangeLog +++ b/apps/football/ChangeLog @@ -1 +1,2 @@ 1.00: Initial implementation +1.01: Bug fixes and performance and visual improvements diff --git a/apps/football/app.js b/apps/football/app.js index 8350bea88..d12f07e2b 100644 --- a/apps/football/app.js +++ b/apps/football/app.js @@ -1,4 +1,19 @@ +// globals. TODO: move into an object const digit = []; +let part = 0; +let endInc = 0; +var endGame = false; +let goalFrame = 0; +var stopped = true; +let score0 = 0; +let score1 = 0; +let inc = 0; +let msinc = 0; +let seq0 = 0; +let seq1 = 0; +let goaler = -1; +const w = g.getWidth(); +let owner = -1; const dash = { width: 75, @@ -6,6 +21,7 @@ const dash = { bpp: 1, buffer: require('heatshrink').decompress(atob('AH4A/AH4A/AH4A/AH4A/AB0D/4AB+AJEBAX/BAk/CQ8PCQ4kDCQoIDCQgkDCQgkECQgIE4ASHFxH8JRgSEEgYSEPJAkEAH4A/AH4A/AH4A/AH4A/ACg=')) }; + function loadDigits () { digit[0] = { width: 80, @@ -58,8 +74,8 @@ function loadDigits () { digit[7] = { width: 80, height: 128, - bpp: 1, - buffer: require('heatshrink').decompress(atob('AGUH/4AE/wJBgYJF/gJBgIJF+AeCBJN/BIngsAJBn4JE4HgBIMfBImBBIUPBIkDBIRQE/0HBIRQE/kPBIRQE/EfBIRQE+E/BIZQD8AJEKAfABYIJCKAYsBBIYADIAIJHKgIJHNAIJ/BP4J/BP4Jzg//4AJGgf/wAJGgP/BAwAB/wJIvgJInAJIiAJIAH5PPMZJ3JRZCfJWZLHJfM4J/BP4J/BP4JNg4JIgYJIgIJIgAJJv4JIn4JIj4JIh4JIeg4JIgYJIgIJIgAJJsAJIkAJIAH4AQA=')) + bpp: 4, + buffer : require("heatshrink").decompress(atob("AH4A/AEtVADdQE5Nf/4AayAnJgoma/J4LKDR2KKDZODUMadChKhiJwefE5RQXJwbxLKCxOEE5hQVJwgnNKCZOFE5pQTJwonOKCJOGE5xQRD4Q8EE5xQPJw4nPgFZzIAMqCdFE6IARJwgnhJwonhJwonhe5In/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4nlr4mE/NQE78FE4n1Ez5QGE0JQEJ0RQETsBQFJ0gABrJOkAH4A/AH4A/ADNZqAmkgv/yAnkr///JQjJwIABypOkAAP5J0oABUMJODKAShgEwhQiE/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/AA+fE80JE8xQGE8JQFE8JQFE8RQEE8RQEE8ZQDE8ZQDE8hQCE8hQCE8pQBE8pQBE80JE80AE84A/AH4A/AH4A/AAQA==")) }; digit[8] = { @@ -170,9 +186,6 @@ const gol11 = { loadDigits(); -let goalFrame = 0; -let score0 = 0; -let score1 = 0; function printNumber (n, x, y, options) { if (n > 9 || n < -1) { @@ -197,13 +210,7 @@ function printNumber (n, x, y, options) { g.drawImage(img, x, y, options); } } -let inc = 0; -let msinc = 0; -let seq0 = 0; -let seq1 = 0; -let goaler = -1; -const w = g.getWidth(); -let owner = -1; + g.setBgColor(0, 0, 0); g.clear(); g.setColor(1, 1, 1); @@ -247,43 +254,63 @@ function onStop () { refresh(); refresh_ms(); } -var stopped = true; -Bangle.on('tap', function (pos) { - console.log('touch', pos); + +function onButtonPress() { + console.log('on.tap'); + setWatch(() => { + onButtonPress(); +}, BTN1); + Bangle.beep(); if (endGame) { - Bangle.beep(); score0 = 0; score1 = 0; seq0 = 0; seq1 = 0; + part = 0; inc = 0; msinc = 0; stopped = true; endGame = false; } else { if (inc == 0) { - autogame(); + // autogame(); + stopped = false; } else { onStop(); } } +} + +setWatch(() => { + onButtonPress(); +}, BTN1); +/*Bangle.on('tap', function () { + onButtonPress(); }); +*/ g.setFont12x20(3); -let part = 0; -let endInc = 0; -var endGame = false; + function refresh () { g.clear(); if (inc > 59) { inc = 0; part++; } + if (part >= 2 && inc > 30) { + part = 2; + Bangle.buzz(); + endGame = true; + endInc = inc; + inc = 0; + } if (inc > 44) { + inc = 0; if (part < 2) { part++; } if (part >= 2) { if (score0 != score1) { + Bangle.buzz(); endGame = true; endInc = inc; inc = 0; @@ -342,6 +369,12 @@ function refresh_pixels () { let bx = (owner == 0) ? w / 3 : w / 2; bx += 2; g.drawImage(frame4 ? ball0 : ball1, bx, 10, { scale: 5 }); + const liney = 60; + if (owner) { + g.drawLine(w-8, liney, 2*(w/3), liney); + } else { + g.drawLine(8, liney, w/3, liney); + } } let dots = 0; function refresh_dots () { @@ -437,4 +470,5 @@ function autogame () { } Bangle.setOptions({ lockTimeout: 0, backlightTimeout: 0 }); -autogame(); +// autogame(); + From b5f3930c41cc7f20a14f1f5ee19ce8d3bf969abd Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 11:24:29 +0200 Subject: [PATCH 149/183] Improve widget drawing code & fix some typos --- apps/widbaroalarm/ChangeLog | 2 +- apps/widbaroalarm/README.md | 4 ++-- apps/widbaroalarm/widget.js | 19 ++++++++++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/apps/widbaroalarm/ChangeLog b/apps/widbaroalarm/ChangeLog index 0afe4bc8b..86a902605 100644 --- a/apps/widbaroalarm/ChangeLog +++ b/apps/widbaroalarm/ChangeLog @@ -1,5 +1,5 @@ 0.01: Initial version -0.02: Do not warn multiple times for the same exceedance +0.02: Do not warn multiple times for the same exceed 0.03: Fix crash 0.04: Use Prompt with dismiss and pause Improve barometer value median calculation diff --git a/apps/widbaroalarm/README.md b/apps/widbaroalarm/README.md index 80ba35abc..59d91ff66 100644 --- a/apps/widbaroalarm/README.md +++ b/apps/widbaroalarm/README.md @@ -16,10 +16,10 @@ Get a notification when the pressure reaches defined thresholds. * Show widget: Enable/disable widget visibility * Buzz on alarm: Enable/disable buzzer on alarm * Dismiss delay: Delay added before the next alert if the alert is dismissed. From 5 to 60 min -* Pause delay: Same as Dismiss delay but longer (usefull for meetings and such). From 30 to 240 min +* Pause delay: Same as Dismiss delay but longer (useful for meetings and such). From 30 to 240 min ## Widget -The widget shows the last median pressure value +The widget shows two rows: pressure value of last measurement and pressure average of the the last three hours. ## Creator Marco ([myxor](https://github.com/myxor)) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 00456f42f..444b63ce6 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -227,11 +227,24 @@ draw: draw }; } - g.reset(); - if (setting("show") && medianPressure != undefined) { + if (setting("show")) { g.setFont("6x8", 1).setFontAlign(1, 0); - g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); + if (medianPressure == undefined) { + check(); + const x = this.x, y = this.y; + g.drawString("...", x + 24, y + 6); + setTimeout(function() { + g.setFont("6x8", 1).setFontAlign(1, 0); + g.drawString(Math.round(medianPressure), x + 24, y + 6); + }, 10000); + } else { + g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); + } + + if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) { + g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10); + } } } From 4dba48f0ace282a1b5ec8d21a7864db251be53db Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 17:12:06 +0200 Subject: [PATCH 150/183] Improve rais/drop calculation and handling --- apps/widbaroalarm/widget.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 444b63ce6..590c2f316 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -103,8 +103,6 @@ } else { saveSetting("lastLowWarningTs", 0); } - } else { - saveSetting("lastLowWarningTs", 0); } if (setting("highalarm")) { @@ -117,8 +115,6 @@ } else { saveSetting("lastHighWarningTs", 0); } - } else { - saveSetting("lastHighWarningTs", 0); } if (history3.length > 0 && !alreadyWarned) { @@ -127,21 +123,22 @@ const raise3halarm = setting("raise3halarm"); if (drop3halarm > 0 || raise3halarm > 0) { // we need at least 30min of data for reliable detection - if (history3[0]["ts"] > ts - (30 * 60)) { + const diffDateAge = Math.abs(history3[0]["ts"] - ts); + if (diffDateAge < 10 * 60) { // todo change to 1800 return; } // Get oldest entry: const oldestPressure = history3[0]["p"]; if (oldestPressure != undefined && oldestPressure > 0) { - const diff = oldestPressure - pressure; + const diffPressure = Math.abs(oldestPressure - pressure); // drop alarm if (drop3halarm > 0 && oldestPressure > pressure) { - if (Math.abs(diff) > drop3halarm) { + if (diffPressure > drop3halarm) { if (doWeNeedToWarn("lastDropWarningTs")) { - showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop", "lastDropWarningTs"); + showAlarm((Math.round(diffPressure * 10) / 10) + " hPa/3h from " + + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "lastDropWarningTs"); } } else { saveSetting("lastDropWarningTs", 0); @@ -152,10 +149,10 @@ // raise alarm if (raise3halarm > 0 && oldestPressure < pressure) { - if (Math.abs(diff) > raise3halarm) { + if (diffPressure > raise3halarm) { if (doWeNeedToWarn("lastRaiseWarningTs")) { - showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise", "lastRaiseWarningTs"); + showAlarm((Math.round(diffPressure * 10) / 10) + " hPa/3h from " + + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "lastRaiseWarningTs"); } } else { saveSetting("lastRaiseWarningTs", 0); From da9261446fa3da51f25be7fd738a3e4cec4fcf60 Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 17:34:30 +0200 Subject: [PATCH 151/183] Further improvements --- apps/widbaroalarm/widget.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 590c2f316..46ac9d480 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -49,9 +49,11 @@ saveSetting(key, tsNow); } if (v == 2) { + // save timestamp of the future so that we do not warn again for the same event until then saveSetting(key, tsNow + 60 * setting('dismissDelayMin')); } if (v == 3) { + // save timestamp of the future so that we do not warn again for the same event until then saveSetting(key, tsNow + 60 * setting('pauseDelayMin')); } load(); @@ -196,8 +198,8 @@ var mid = median.length >> 1; medianPressure = Math.round(E.sum(median.slice(mid - 4, mid + 5)) / 9); if (medianPressure > 0) { - turnOff(); - checkForAlarms(medianPressure); + turnOff(); + checkForAlarms(medianPressure); } } }); @@ -208,7 +210,8 @@ } function turnOff() { - Bangle.setBarometerPower(false, "widbaroalarm"); + if (Bangle.isBarometerOn()) + Bangle.setBarometerPower(false, "widbaroalarm"); } function reload() { @@ -228,15 +231,16 @@ if (setting("show")) { g.setFont("6x8", 1).setFontAlign(1, 0); if (medianPressure == undefined) { - check(); - const x = this.x, y = this.y; - g.drawString("...", x + 24, y + 6); - setTimeout(function() { - g.setFont("6x8", 1).setFontAlign(1, 0); - g.drawString(Math.round(medianPressure), x + 24, y + 6); - }, 10000); + check(); + const x = this.x, + y = this.y; + g.drawString("...", x + 24, y + 6); + setTimeout(function() { + g.setFont("6x8", 1).setFontAlign(1, 0); + g.drawString(Math.round(medianPressure), x + 24, y + 6); + }, 10000); } else { - g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); + g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); } if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) { @@ -245,7 +249,6 @@ } } - check(); if (interval > 0) { setInterval(check, interval * 60000); } From 02bb0ab481cdcf26699c901ecdd140d088b7922a Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 17:46:25 +0200 Subject: [PATCH 152/183] Calculate 3h average only if data is available --- apps/widbaroalarm/widget.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 46ac9d480..d8eb43995 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -171,11 +171,15 @@ storage.writeJSON(LOG_FILE, history3); // calculate 3h average for widget - let sum = 0; - for (let i = 0; i < history3.length; i++) { - sum += history3[i]["p"]; + if (history3.length > 0) { + let sum = 0; + for (let i = 0; i < history3.length; i++) { + sum += history3[i]["p"]; + } + threeHourAvrPressure = sum / history3.length; + } else { + threeHourAvrPressure = undefined; } - threeHourAvrPressure = sum / history3.length; } From d7e1cf704decf53bf17f4517fff87bbc09604c32 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 17:48:07 +0200 Subject: [PATCH 153/183] Fix hours --- apps/hworldclock/ChangeLog | 3 ++- apps/hworldclock/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index e67af806a..64b2be430 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1,2 +1,3 @@ 0.15: Initial release - be patient as this is the first try :) -0.16: Fix timing \ No newline at end of file +0.16: Fix timing +0.17: Fix hours \ No newline at end of file diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 4f3cd80cf..794992d2f 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.16", + "version": "0.17", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From 85a52afbf55725bd999bb94e2e8c1b929a3cc4ed Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 17:50:43 +0200 Subject: [PATCH 154/183] Fix the const reassign bug (cutting edge firmware) and better indentation and scoping --- apps/activityreminder/ChangeLog | 1 + apps/activityreminder/app.js | 81 +++++++------- apps/activityreminder/boot.js | 122 +++++++++++---------- apps/activityreminder/lib.js | 10 +- apps/activityreminder/metadata.json | 2 +- apps/activityreminder/settings.js | 164 ++++++++++++++-------------- 6 files changed, 191 insertions(+), 189 deletions(-) diff --git a/apps/activityreminder/ChangeLog b/apps/activityreminder/ChangeLog index 4edb72aa5..da897b899 100644 --- a/apps/activityreminder/ChangeLog +++ b/apps/activityreminder/ChangeLog @@ -4,3 +4,4 @@ 0.04: Obey system quiet mode 0.05: Battery optimisation, add the pause option, bug fixes 0.06: Add a temperature threshold to detect (and not alert) if the BJS isn't worn. Better support for the peoples using the app at night +0.07: Fix bug on the cutting edge firmware \ No newline at end of file diff --git a/apps/activityreminder/app.js b/apps/activityreminder/app.js index f3d72976e..52dec2928 100644 --- a/apps/activityreminder/app.js +++ b/apps/activityreminder/app.js @@ -1,42 +1,43 @@ -function drawAlert() { - E.showPrompt("Inactivity detected", { - title: "Activity reminder", - buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } - }).then(function (v) { - if (v == 1) { - activityreminder_data.okDate = new Date(); +(function () { + function drawAlert() { + E.showPrompt("Inactivity detected", { + title: "Activity reminder", + buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } + }).then(function (v) { + if (v == 1) { + activityreminder_data.okDate = new Date(); + } + if (v == 2) { + activityreminder_data.dismissDate = new Date(); + } + if (v == 3) { + activityreminder_data.pauseDate = new Date(); + } + activityreminder.saveData(activityreminder_data); + load(); + }); + + // Obey system quiet mode: + if (!(storage.readJSON('setting.json', 1) || {}).quiet) { + Bangle.buzz(400); + } + setTimeout(load, 20000); } - if (v == 2) { - activityreminder_data.dismissDate = new Date(); + + function run() { + if (activityreminder.mustAlert(activityreminder_data, activityreminder_settings)) { + drawAlert(); + } else { + eval(storage.read("activityreminder.settings.js"))(() => load()); + } } - if (v == 3) { - activityreminder_data.pauseDate = new Date(); - } - activityreminder.saveData(activityreminder_data); - load(); - }); - - // Obey system quiet mode: - if (!(storage.readJSON('setting.json', 1) || {}).quiet) { - Bangle.buzz(400); - } - setTimeout(load, 20000); -} - -function run() { - if (activityreminder.mustAlert(activityreminder_data, activityreminder_settings)) { - drawAlert(); - } else { - eval(storage.read("activityreminder.settings.js"))(() => load()); - } -} - - -const activityreminder = require("activityreminder"); -const storage = require("Storage"); -g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -const activityreminder_settings = activityreminder.loadSettings(); -const activityreminder_data = activityreminder.loadData(); -run(); + + const activityreminder = require("activityreminder"); + const storage = require("Storage"); + g.clear(); + Bangle.loadWidgets(); + Bangle.drawWidgets(); + const activityreminder_settings = activityreminder.loadSettings(); + const activityreminder_data = activityreminder.loadData(); + run(); +})(); \ No newline at end of file diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 4ae9548c2..86de0e901 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -1,65 +1,67 @@ -function run() { - if (isNotWorn()) return; - let now = new Date(); - let h = now.getHours(); +(function () { + function run() { + if (isNotWorn()) return; + let now = new Date(); + let h = now.getHours(); - if (isDuringAlertHours(h)) { - let health = Bangle.getHealthStatus("day"); - if (health.steps - activityreminder_data.stepsOnDate >= activityreminder_settings.minSteps // more steps made than needed - || health.steps < activityreminder_data.stepsOnDate) { // new day or reboot of the watch - activityreminder_data.stepsOnDate = health.steps; - activityreminder_data.stepsDate = now; + if (isDuringAlertHours(h)) { + let health = Bangle.getHealthStatus("day"); + if (health.steps - activityreminder_data.stepsOnDate >= activityreminder_settings.minSteps // more steps made than needed + || health.steps < activityreminder_data.stepsOnDate) { // new day or reboot of the watch + activityreminder_data.stepsOnDate = health.steps; + activityreminder_data.stepsDate = now; + activityreminder.saveData(activityreminder_data); + /* todo in a futur release + Add settimer to trigger like 30 secs after going in this part cause the person have been walking + (pass some argument to run() to handle long walks and not triggering so often) + */ + } + + if (activityreminder.mustAlert(activityreminder_data, activityreminder_settings)) { + load('activityreminder.app.js'); + } + } + + } + + function isNotWorn() { + return (Bangle.isCharging() || activityreminder_settings.tempThreshold >= E.getTemperature()); + } + + function isDuringAlertHours(h) { + if (activityreminder_settings.startHour < activityreminder_settings.endHour) { // not passing through midnight + return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour) + } else { // passing through midnight + return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour) + } + } + + Bangle.on('midnight', function () { + /* + Usefull trick to have the app working smothly for people using it at night + */ + let now = new Date(); + let h = now.getHours(); + if (activityreminder_settings.enabled && isDuringAlertHours(h)) { + // updating only the steps and keeping the original stepsDate on purpose + activityreminder_data.stepsOnDate = 0; activityreminder.saveData(activityreminder_data); - /* todo in a futur release - Add settimer to trigger like 30 secs after going in this part cause the person have been walking - (pass some argument to run() to handle long walks and not triggering so often) - */ } - - if(activityreminder.mustAlert(activityreminder_data, activityreminder_settings)){ - load('activityreminder.app.js'); + }); + + + const activityreminder = require("activityreminder"); + const activityreminder_settings = activityreminder.loadSettings(); + if (activityreminder_settings.enabled) { + const activityreminder_data = activityreminder.loadData(); + if (activityreminder_data.firstLoad) { + activityreminder_data.firstLoad = false; + activityreminder.saveData(activityreminder_data); } + setInterval(run, 60000); + /* todo in a futur release + increase setInterval time to something that is still sensible (5 mins ?) + when we added a settimer + */ } - -} - -function isNotWorn() { - return (Bangle.isCharging() || activityreminder_settings.tempThreshold >= E.getTemperature()); -} - -function isDuringAlertHours(h) { - if(activityreminder_settings.startHour < activityreminder_settings.endHour){ // not passing through midnight - return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour) - } else{ // passing through midnight - return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour) - } -} - -Bangle.on('midnight', function() { - /* - Usefull trick to have the app working smothly for people using it at night - */ - let now = new Date(); - let h = now.getHours(); - if (activityreminder_settings.enabled && isDuringAlertHours(h)){ - // updating only the steps and keeping the original stepsDate on purpose - activityreminder_data.stepsOnDate = 0; - activityreminder.saveData(activityreminder_data); - } -}); - -const activityreminder = require("activityreminder"); -const activityreminder_settings = activityreminder.loadSettings(); -if (activityreminder_settings.enabled) { - const activityreminder_data = activityreminder.loadData(); - if(activityreminder_data.firstLoad){ - activityreminder_data.firstLoad = false; - activityreminder.saveData(activityreminder_data); - } - setInterval(run, 60000); - /* todo in a futur release - increase setInterval time to something that is still sensible (5 mins ?) - when we added a settimer - */ -} - +})(); diff --git a/apps/activityreminder/lib.js b/apps/activityreminder/lib.js index 08fffd5f4..e0f7caca3 100644 --- a/apps/activityreminder/lib.js +++ b/apps/activityreminder/lib.js @@ -1,5 +1,3 @@ -const storage = require("Storage"); - exports.loadSettings = function () { return Object.assign({ enabled: true, @@ -10,15 +8,15 @@ exports.loadSettings = function () { pauseDelayMin: 120, minSteps: 50, tempThreshold: 27 - }, storage.readJSON("activityreminder.s.json", true) || {}); + }, require("Storage").readJSON("activityreminder.s.json", true) || {}); }; exports.writeSettings = function (settings) { - storage.writeJSON("activityreminder.s.json", settings); + require("Storage").writeJSON("activityreminder.s.json", settings); }; exports.saveData = function (data) { - storage.writeJSON("activityreminder.data.json", data); + require("Storage").writeJSON("activityreminder.data.json", data); }; exports.loadData = function () { @@ -31,7 +29,7 @@ exports.loadData = function () { dismissDate: new Date(1970), pauseDate: new Date(1970), }, - storage.readJSON("activityreminder.data.json") || {}); + require("Storage").readJSON("activityreminder.data.json") || {}); if(typeof(data.stepsDate) == "string") data.stepsDate = new Date(data.stepsDate); diff --git a/apps/activityreminder/metadata.json b/apps/activityreminder/metadata.json index 752c6c101..fb9423e7c 100644 --- a/apps/activityreminder/metadata.json +++ b/apps/activityreminder/metadata.json @@ -3,7 +3,7 @@ "name": "Activity Reminder", "shortName":"Activity Reminder", "description": "A reminder to take short walks for the ones with a sedentary lifestyle", - "version":"0.06", + "version":"0.07", "icon": "app.png", "type": "app", "tags": "tool,activity", diff --git a/apps/activityreminder/settings.js b/apps/activityreminder/settings.js index f25697de0..b4d288500 100644 --- a/apps/activityreminder/settings.js +++ b/apps/activityreminder/settings.js @@ -1,85 +1,85 @@ (function (back) { - // Load settings - const activityreminder = require("activityreminder"); - const settings = activityreminder.loadSettings(); + // Load settings + const activityreminder = require("activityreminder"); + const settings = activityreminder.loadSettings(); - // Show the menu - E.showMenu({ - "": { "title": "Activity Reminder" }, - "< Back": () => back(), - 'Enable': { - value: settings.enabled, - format: v => v ? "Yes" : "No", - onchange: v => { - settings.enabled = v; - activityreminder.writeSettings(settings); - } - }, - 'Start hour': { - value: settings.startHour, - min: 0, max: 24, - onchange: v => { - settings.startHour = v; - activityreminder.writeSettings(settings); - } - }, - 'End hour': { - value: settings.endHour, - min: 0, max: 24, - onchange: v => { - settings.endHour = v; - activityreminder.writeSettings(settings); - } - }, - 'Max inactivity': { - value: settings.maxInnactivityMin, - min: 15, max: 120, - onchange: v => { - settings.maxInnactivityMin = v; - activityreminder.writeSettings(settings); - }, - format: x => { - return x + " min"; - } - }, - 'Dismiss delay': { - value: settings.dismissDelayMin, - min: 5, max: 60, - onchange: v => { - settings.dismissDelayMin = v; - activityreminder.writeSettings(settings); - }, - format: x => { - return x + " min"; - } - }, - 'Pause delay': { - value: settings.pauseDelayMin, - min: 30, max: 240, step: 5, - onchange: v => { - settings.pauseDelayMin = v; - activityreminder.writeSettings(settings); - }, - format: x => { - return x + " min"; - } - }, - 'Min steps': { - value: settings.minSteps, - min: 10, max: 500, step: 10, - onchange: v => { - settings.minSteps = v; - activityreminder.writeSettings(settings); - } - }, - 'Temp Threshold': { - value: settings.tempThreshold, - min: 20, max: 40, step: 0.5, - format: v => v + "°C", - onchange: v => { - settings.tempThreshold = v; - activityreminder.writeSettings(settings); - } - } - }); + // Show the menu + E.showMenu({ + "": { "title": "Activity Reminder" }, + "< Back": () => back(), + 'Enable': { + value: settings.enabled, + format: v => v ? "Yes" : "No", + onchange: v => { + settings.enabled = v; + activityreminder.writeSettings(settings); + } + }, + 'Start hour': { + value: settings.startHour, + min: 0, max: 24, + onchange: v => { + settings.startHour = v; + activityreminder.writeSettings(settings); + } + }, + 'End hour': { + value: settings.endHour, + min: 0, max: 24, + onchange: v => { + settings.endHour = v; + activityreminder.writeSettings(settings); + } + }, + 'Max inactivity': { + value: settings.maxInnactivityMin, + min: 15, max: 120, + onchange: v => { + settings.maxInnactivityMin = v; + activityreminder.writeSettings(settings); + }, + format: x => { + return x + " min"; + } + }, + 'Dismiss delay': { + value: settings.dismissDelayMin, + min: 5, max: 60, + onchange: v => { + settings.dismissDelayMin = v; + activityreminder.writeSettings(settings); + }, + format: x => { + return x + " min"; + } + }, + 'Pause delay': { + value: settings.pauseDelayMin, + min: 30, max: 240, step: 5, + onchange: v => { + settings.pauseDelayMin = v; + activityreminder.writeSettings(settings); + }, + format: x => { + return x + " min"; + } + }, + 'Min steps': { + value: settings.minSteps, + min: 10, max: 500, step: 10, + onchange: v => { + settings.minSteps = v; + activityreminder.writeSettings(settings); + } + }, + 'Temp Threshold': { + value: settings.tempThreshold, + min: 20, max: 40, step: 0.5, + format: v => v + "°C", + onchange: v => { + settings.tempThreshold = v; + activityreminder.writeSettings(settings); + } + } + }); }) From 6ef45a4258e1326d561ba8f2512157cd954d111a Mon Sep 17 00:00:00 2001 From: David Peer Date: Sun, 12 Jun 2022 18:00:41 +0200 Subject: [PATCH 155/183] Minor fix --- apps/cassioWatch/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 75ec85503..41515b48c 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -147,9 +147,9 @@ function draw() { g.setFontAlign(-1,-1); drawClock(); drawRocket(); - rocketSequence -= 1; // This avoids a "jump" in the animation drawBattery(); + // Hide widgets for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} } From d734f921180d2d1fd094dfb17e8b99d7238a339e Mon Sep 17 00:00:00 2001 From: David Peer Date: Sun, 12 Jun 2022 18:01:47 +0200 Subject: [PATCH 156/183] Show steps in k. --- apps/cassioWatch/app.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 41515b48c..6bbb9e823 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -113,12 +113,7 @@ function getSteps() { return "? k"; } - // Show always 2 digits. E.g. 1.5k if < 10000 otherwise 12k - if(steps > 10000){ - steps = Math.round(steps/1000); - } else { - steps = Math.round(steps/100) / 10; - } + steps = Math.round(steps/1000); return steps + "k"; } From 749cb2fc2a9698b7f7e0c11988f065af65f8bc0a Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 19:38:40 +0200 Subject: [PATCH 157/183] 0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. --- apps/hworldclock/ChangeLog | 3 +- apps/hworldclock/README.md | 1 + apps/hworldclock/app.js | 126 ++++++++++++++++++++++++++++----- apps/hworldclock/metadata.json | 2 +- 4 files changed, 113 insertions(+), 19 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index 64b2be430..30d729cbf 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1,3 +1,4 @@ 0.15: Initial release - be patient as this is the first try :) 0.16: Fix timing -0.17: Fix hours \ No newline at end of file +0.17: Fix hours +0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. \ No newline at end of file diff --git a/apps/hworldclock/README.md b/apps/hworldclock/README.md index 40af71ee3..0f4f9296c 100644 --- a/apps/hworldclock/README.md +++ b/apps/hworldclock/README.md @@ -2,6 +2,7 @@ In addition to the main clock and date in your current location, you can add up to three other locations. Great for travel or remote working. Additionally we show the sunset/sunrise and seconds for the current location and the day name is shown in your locale. +If watch is locked, seconds get refreshed every 10 seconds. ![](hworldclock.png) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index c37ec5714..6d16e2295 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -31,6 +31,8 @@ const yposWorld = big ? 170 : 120; const OFFSET_TIME_ZONE = 0; const OFFSET_HOURS = 1; +var PosInterval = 0; + var offsets = require("Storage").readJSON("hworldclock.settings.json") || []; //=======Sun @@ -79,6 +81,7 @@ var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||fal // timeout used to update every minute var drawTimeout; var drawTimeoutSeconds; +var secondsTimeout; g.setBgColor(0, 0, 0); @@ -91,6 +94,16 @@ function queueDraw() { }, 60000 - (Date.now() % 60000)); } +// schedule a draw for the next second +function queueDrawSeconds() { + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeoutSeconds = setTimeout(function() { + drawTimeoutSeconds = undefined; + drawSeconds(); + //console.log("TO: " + secondsTimeout); + }, secondsTimeout - (Date.now() % secondsTimeout)); +} + function doublenum(x) { return x < 10 ? "0" + x : "" + x; } @@ -127,9 +140,13 @@ function drawSeconds() { g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); g.setColor("#22ff05"); - //g.setFont(font, primaryTimeFontSize-3); + //console.log("---"); + //console.log(seconds); + if (Bangle.isLocked()) seconds = seconds.slice(0, -1) + ':::'; // we use :: as the font does not have an x + //console.log(seconds); g.drawString(`${seconds}`, xyCenterSeconds, yposTime+14, true); - queueDraw(); + queueDrawSeconds(); + } function draw() { @@ -179,7 +196,7 @@ function draw() { // draw Day, name of month, Date //DATE var localDate = require("locale").date(new Date(), 1); - localDate = localDate.substring(0, localDate.length - 5) + localDate = localDate.substring(0, localDate.length - 5); g.setFont("Vector", 17); g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true); @@ -230,36 +247,111 @@ function draw() { g.drawString(`v${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw riseset queueDraw(); + queueDrawSeconds(); } // clean app screen g.clear(); + // Show launcher when button pressed Bangle.setUI("clock"); Bangle.loadWidgets(); Bangle.drawWidgets(); -updatePos(); -setInterval(drawSeconds, 1E3/2); +// draw immediately at first, queue update +draw(); -// Stop updates when LCD is off, restart when on -Bangle.on('lcdPower',on=>{ - if (on) { - draw(); // draw immediately, queue redraw - setInterval(updatePos, 60*5E3); // refesh every 5 mins - setInterval(drawSeconds, 1E3); - updatePos(); - } else { // stop draw timer + +if (!Bangle.isLocked()) { // Initial state + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + + secondsTimeout = 1000; if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; drawTimeoutSeconds = undefined; - setInterval(updatePos, 60*50E3); // refesh every 50 mins - setInterval(drawSeconds, 10E3); + + draw(); // draw immediately, queue redraw + updatePos(); + }else{ + secondsTimeout = 10 * 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + draw(); // draw immediately, queue redraw + updatePos(); + } + + +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower',on=>{ + if (on) { + if (PosInterval != 0) clearInterval(PosInterval); + + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + secondsTimeout = 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + draw(); // draw immediately, queue redraw + updatePos(); + } else { // stop draw timer + + secondsTimeout = 1000 * 60; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + draw(); // draw immediately, queue redraw updatePos(); } }); -// draw now -draw(); + +Bangle.on('lock',on=>{ + if (!on) { // UNlocked + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + + secondsTimeout = 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + draw(); // draw immediately, queue redraw + updatePos(); + }else{ // locked + + secondsTimeout = 10 * 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + draw(); // draw immediately, queue redraw + updatePos(); + } + }); + + + + + + + + diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 794992d2f..9eb95a0ed 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.17", + "version": "0.18", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From 516814cdf80940d0c253d7ee4d4a7e6c11657157 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 19:42:48 +0200 Subject: [PATCH 158/183] Fix spaces --- apps/hworldclock/app.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 6d16e2295..6101d4427 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -277,11 +277,11 @@ if (!Bangle.isLocked()) { // Initial state updatePos(); }else{ secondsTimeout = 10 * 1000; - if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; drawTimeoutSeconds = undefined; - + if (PosInterval != 0) clearInterval(PosInterval); PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins draw(); // draw immediately, queue redraw @@ -333,13 +333,12 @@ Bangle.on('lock',on=>{ draw(); // draw immediately, queue redraw updatePos(); }else{ // locked - + secondsTimeout = 10 * 1000; - if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; drawTimeoutSeconds = undefined; - if (PosInterval != 0) clearInterval(PosInterval); PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins From 59ee5b1a782d84f4e11a4d1bc94618820e728e8b Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 19:51:46 +0200 Subject: [PATCH 159/183] Moving stuff around to be sure to instanciate the variable before even referencing them in functions --- apps/activityreminder/app.js | 13 ++++++++----- apps/activityreminder/boot.js | 20 ++++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/apps/activityreminder/app.js b/apps/activityreminder/app.js index 52dec2928..95bdfe6f0 100644 --- a/apps/activityreminder/app.js +++ b/apps/activityreminder/app.js @@ -1,4 +1,10 @@ (function () { + + const activityreminder = require("activityreminder"); + const storage = require("Storage"); + const activityreminder_settings = activityreminder.loadSettings(); + const activityreminder_data = activityreminder.loadData(); + function drawAlert() { E.showPrompt("Inactivity detected", { title: "Activity reminder", @@ -31,13 +37,10 @@ eval(storage.read("activityreminder.settings.js"))(() => load()); } } - - const activityreminder = require("activityreminder"); - const storage = require("Storage"); + g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); - const activityreminder_settings = activityreminder.loadSettings(); - const activityreminder_data = activityreminder.loadData(); run(); + })(); \ No newline at end of file diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 86de0e901..c87dde3b2 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -1,4 +1,15 @@ (function () { + + const activityreminder = require("activityreminder"); + const activityreminder_settings = activityreminder.loadSettings(); + if (activityreminder_settings.enabled) { + const activityreminder_data = activityreminder.loadData(); + if (activityreminder_data.firstLoad) { + activityreminder_data.firstLoad = false; + activityreminder.saveData(activityreminder_data); + } + } + function run() { if (isNotWorn()) return; let now = new Date(); @@ -49,15 +60,8 @@ } }); - - const activityreminder = require("activityreminder"); - const activityreminder_settings = activityreminder.loadSettings(); + if (activityreminder_settings.enabled) { - const activityreminder_data = activityreminder.loadData(); - if (activityreminder_data.firstLoad) { - activityreminder_data.firstLoad = false; - activityreminder.saveData(activityreminder_data); - } setInterval(run, 60000); /* todo in a futur release increase setInterval time to something that is still sensible (5 mins ?) From 9b71b107cfb9ab05aeedbbe98a396933d223d209 Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 20:05:32 +0200 Subject: [PATCH 160/183] Use let instead of const on object that get updated --- apps/activityreminder/app.js | 4 ++-- apps/activityreminder/boot.js | 4 ++-- apps/activityreminder/lib.js | 2 +- apps/activityreminder/settings.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/activityreminder/app.js b/apps/activityreminder/app.js index 95bdfe6f0..c2b626fb3 100644 --- a/apps/activityreminder/app.js +++ b/apps/activityreminder/app.js @@ -1,9 +1,9 @@ (function () { - + // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const storage = require("Storage"); const activityreminder_settings = activityreminder.loadSettings(); - const activityreminder_data = activityreminder.loadData(); + let activityreminder_data = activityreminder.loadData(); function drawAlert() { E.showPrompt("Inactivity detected", { diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index c87dde3b2..4d6847a20 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -1,9 +1,9 @@ (function () { - + // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const activityreminder_settings = activityreminder.loadSettings(); if (activityreminder_settings.enabled) { - const activityreminder_data = activityreminder.loadData(); + let activityreminder_data = activityreminder.loadData(); if (activityreminder_data.firstLoad) { activityreminder_data.firstLoad = false; activityreminder.saveData(activityreminder_data); diff --git a/apps/activityreminder/lib.js b/apps/activityreminder/lib.js index e0f7caca3..704d35641 100644 --- a/apps/activityreminder/lib.js +++ b/apps/activityreminder/lib.js @@ -21,7 +21,7 @@ exports.saveData = function (data) { exports.loadData = function () { let health = Bangle.getHealthStatus("day"); - const data = Object.assign({ + let data = Object.assign({ firstLoad: true, stepsDate: new Date(), stepsOnDate: health.steps, diff --git a/apps/activityreminder/settings.js b/apps/activityreminder/settings.js index b4d288500..ce7cdc913 100644 --- a/apps/activityreminder/settings.js +++ b/apps/activityreminder/settings.js @@ -1,7 +1,7 @@ (function (back) { // Load settings const activityreminder = require("activityreminder"); - const settings = activityreminder.loadSettings(); + let settings = activityreminder.loadSettings(); // Show the menu E.showMenu({ From ea82ae3f255319e23704e041627655c7570e34f9 Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 20:16:14 +0200 Subject: [PATCH 161/183] Fix activityreminder_data scoping issue in boot.js --- apps/activityreminder/boot.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 4d6847a20..16c209737 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -2,8 +2,9 @@ // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const activityreminder_settings = activityreminder.loadSettings(); + let activityreminder_data = null; if (activityreminder_settings.enabled) { - let activityreminder_data = activityreminder.loadData(); + activityreminder_data = activityreminder.loadData(); if (activityreminder_data.firstLoad) { activityreminder_data.firstLoad = false; activityreminder.saveData(activityreminder_data); From 7ba81f1ba5b26b69a761ca07a9615c90a0b365ed Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 20:29:43 +0200 Subject: [PATCH 162/183] add missing semicolons --- apps/activityreminder/boot.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 16c209737..f97cf274d 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -2,13 +2,11 @@ // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const activityreminder_settings = activityreminder.loadSettings(); - let activityreminder_data = null; - if (activityreminder_settings.enabled) { - activityreminder_data = activityreminder.loadData(); - if (activityreminder_data.firstLoad) { - activityreminder_data.firstLoad = false; - activityreminder.saveData(activityreminder_data); - } + let activityreminder_data = activityreminder.loadData(); + + if (activityreminder_data.firstLoad) { + activityreminder_data.firstLoad = false; + activityreminder.saveData(activityreminder_data); } function run() { @@ -42,9 +40,9 @@ function isDuringAlertHours(h) { if (activityreminder_settings.startHour < activityreminder_settings.endHour) { // not passing through midnight - return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour) + return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour); } else { // passing through midnight - return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour) + return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour); } } From 38f23be5b4b9da4726eb53bcffd716766a5aa4d4 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 21:13:28 +0200 Subject: [PATCH 163/183] Fix PM hours --- apps/hworldclock/ChangeLog | 3 ++- apps/hworldclock/app.js | 16 +++------------- apps/hworldclock/metadata.json | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index 30d729cbf..fdc717c92 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1,4 +1,5 @@ 0.15: Initial release - be patient as this is the first try :) 0.16: Fix timing 0.17: Fix hours -0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. \ No newline at end of file +0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. +0.19: Fix PM Hours \ No newline at end of file diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 6101d4427..e907dd703 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -19,7 +19,6 @@ const font = "6x8"; /* TODO: we could totally use 'Layout' here and avoid a whole bunch of hard-coded offsets */ - const xyCenter = g.getWidth() / 2; const xyCenterSeconds = xyCenter + (big ? 85 : 68); const yAmPm = xyCenter - (big ? 70 : 48); @@ -171,7 +170,8 @@ function draw() { //do 12 hour stuff if (hours > 12) { ampm = "PM"; - hours = hours - 12; + hours = hours - 12; + if (hours < 10) hours = doublenum(hours); } else { ampm = "AM"; } @@ -200,8 +200,6 @@ function draw() { g.setFont("Vector", 17); g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true); - - g.setFont(font, primaryDateFontSize); // set gmt to UTC+0 var gmt = new Date(d.getTime() + d.getTimezoneOffset() * 60 * 1000); @@ -345,12 +343,4 @@ Bangle.on('lock',on=>{ draw(); // draw immediately, queue redraw updatePos(); } - }); - - - - - - - - + }); \ No newline at end of file diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 9eb95a0ed..1ee04b333 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.18", + "version": "0.19", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From 1d6887a4dff0f11475cc1bf21d62c59e07b75a94 Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 21:17:52 +0200 Subject: [PATCH 164/183] Do not check new values if alarm is shown --- apps/widbaroalarm/widget.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index d8eb43995..e1516b6f1 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -2,6 +2,7 @@ let medianPressure; let threeHourAvrPressure; let currentPressures = []; + let stop = false; // semaphore const LOG_FILE = "widbaroalarm.log.json"; const SETTINGS_FILE = "widbaroalarm.json"; @@ -34,6 +35,7 @@ function showAlarm(body, key) { if (body == undefined) return; + stop = true; E.showPrompt(body, { title: "Pressure alarm", @@ -56,6 +58,7 @@ // save timestamp of the future so that we do not warn again for the same event until then saveSetting(key, tsNow + 60 * setting('pauseDelayMin')); } + stop = false; load(); }); @@ -64,7 +67,10 @@ Bangle.buzz(); } - setTimeout(load, 20000); + setTimeout(function() { + stop = false; + load(); + }, 20000); } @@ -191,6 +197,7 @@ turn off barometer power */ function check() { + if (stop) return; const MEDIANLENGTH = 20; Bangle.setBarometerPower(true, "widbaroalarm"); Bangle.on('pressure', function(e) { From c3b1a973c0bcef1ac7130e1b0df89dd3b1003703 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 22:44:32 +0200 Subject: [PATCH 165/183] Add theme support --- apps/hworldclock/ChangeLog | 3 ++- apps/hworldclock/app.js | 45 ++++++++++------------------------ apps/hworldclock/metadata.json | 2 +- 3 files changed, 16 insertions(+), 34 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index fdc717c92..c7b1731a2 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -2,4 +2,5 @@ 0.16: Fix timing 0.17: Fix hours 0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. -0.19: Fix PM Hours \ No newline at end of file +0.19: Fix PM Hours +0.20: Add theme support \ No newline at end of file diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index e907dd703..faf24e974 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -82,7 +82,7 @@ var drawTimeout; var drawTimeoutSeconds; var secondsTimeout; -g.setBgColor(0, 0, 0); +g.setBgColor(g.theme.bg); // schedule a draw for the next minute function queueDraw() { @@ -128,7 +128,7 @@ function drawSeconds() { // default draw styles g.reset(); - g.setBgColor(0, 0, 0); + g.setBgColor(g.theme.bg); // drawSting centered g.setFontAlign(0, 0); @@ -138,7 +138,11 @@ function drawSeconds() { var seconds = time[2]; g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); - g.setColor("#22ff05"); + if (g.theme.dark) { + g.setColor("#22ff05"); + } else { + g.setColor(g.theme.fg); + } //console.log("---"); //console.log(seconds); if (Bangle.isLocked()) seconds = seconds.slice(0, -1) + ':::'; // we use :: as the font does not have an x @@ -155,7 +159,7 @@ function draw() { // default draw styles g.reset(); - g.setBgColor(0, 0, 0); + g.setBgColor(g.theme.bg); // drawSting centered g.setFontAlign(0, 0); @@ -179,7 +183,11 @@ function draw() { //g.setFont(font, primaryTimeFontSize); g.setFont("5x9Numeric7Seg",primaryTimeFontSize); - g.setColor("#22ff05"); + if (g.theme.dark) { + g.setColor("#22ff05"); + } else { + g.setColor(g.theme.fg); + } g.drawString(`${hours}:${minutes}`, xyCenter-10, yposTime, true); // am / PM ? @@ -187,7 +195,6 @@ function draw() { //do 12 hour stuff //var ampm = require("locale").medidian(new Date()); Not working g.setFont("Vector", 17); - g.setColor("#22ff05"); g.drawString(ampm, xyCenterSeconds, yAmPm, true); } @@ -287,33 +294,7 @@ if (!Bangle.isLocked()) { // Initial state } -// Stop updates when LCD is off, restart when on -Bangle.on('lcdPower',on=>{ - if (on) { - if (PosInterval != 0) clearInterval(PosInterval); - - PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins - secondsTimeout = 1000; - if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); - drawTimeout = undefined; - drawTimeoutSeconds = undefined; - draw(); // draw immediately, queue redraw - updatePos(); - } else { // stop draw timer - secondsTimeout = 1000 * 60; - if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); - drawTimeout = undefined; - drawTimeoutSeconds = undefined; - - if (PosInterval != 0) clearInterval(PosInterval); - PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins - draw(); // draw immediately, queue redraw - updatePos(); - } -}); Bangle.on('lock',on=>{ diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 1ee04b333..5cc2a49a8 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.19", + "version": "0.20", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From d89ba34bb7e72f94a85780cc7a19d185137557b1 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 22:49:55 +0200 Subject: [PATCH 166/183] Remove --- .../Automatisch beibehalten von Corel/widget.png | Bin 2385 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png diff --git a/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png b/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png deleted file mode 100644 index 868628b6085cb0da28098648ae713dc1f08e44d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2385 zcmaJ@3s_S}7QRV%6-6sAF<4ClyK7v@i-;0K3Ni8!q9Gtc4b~8DAdq)1aB(YAt>u%d z1QAzxOM?njO9Tu>6tPi@^y8Cq0o>m5~KlokLMAQ3HazyNs#E&zZ#FAa}`B6%T9u~JSJ#VTV!GAvi2N&pLHBBmUK zLS3?Dm5U%i%ca`iELW}fxyzlN|*w!{|p^@ z^C8AVkcvs6q@<*fQ#{E^O&o>h?d?sW(kXPh2ZHd>rYay2?4i)QO^f`Y!v(csjZ_6m zl?no?D~eGjK|Vwxy3y-49VaA}%- zo53R0G|7Az(=oEp2$)dxGIwnb9z78#m+Sq0cd}KFI#A;yHf?IRDcwX=oQiR>aFy?ugdQ6YyDM9=!Ox)6 z-QwI1%ye`nVGTAnt{o#ero6HML)Uy^Dj6ygJslhQ-l*K`UtG1cwe@N1cVDLrwdRMG z*64k76TUsT2uh&{4?j3|Ne+tME|dQYKSCDEpg8kolSq#+^^!R)ie+U z+s11v=x1NukMZ}niWUm_R2O|qOK`|UPMgE#(5}Jk;~k)HT0%l*MP+4DZAyM`Pfuxc za}bloswueJ3BW4`U0q#Co}QjDK$KIEn`0ez=clGG-0CZEQ^M%z@-?u@J`5Kt(5+iU z#uXJ8=iGmKrnyp3Bv0G-oedIQndCY+#&iwI4%dH@kxX^BbGx#&>l$)y9T~ zkjlzR27|%n@pupf>3gb(iHV6Hepx3Z=bb!xs=mG+w&RbTc;zlnU-sJ6JCs%aX z>{!HYi_>azcJKZQPoS#rbKUi=N-VU=E%-tkypQL*|~ zOUnW`T+CgsyMm664#o!`eARY=_wK;w_qw~!V2!1v9Jf`=Tt3OM-BDRvyKQ7|=fk0) z3UTLfFhy+I?6Dod#QiOvLL!Bx7oB7eSJ~g*e--e3wmRopRvE^nd$={{#|FZYOIi0` z{iDsmz26SNiEa)73wZvvR8kw&<<{1Q|u{R*kDbNFBDQ31}%3AJl^-n#&A7i zxIK5{orx`M+GVZ3ZuIbI-e`Wmh~?5m3NID^c4ADVE=l|sd~femU2l7U^9Td|Ul6ou L3->%{*S`M&n6+>< From e68d04da5bb5ee2be61fa15df743d8f37fd0f2d1 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 13 Jun 2022 08:23:16 +0100 Subject: [PATCH 167/183] works on v2 --- apps/espruinoctrl/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/espruinoctrl/metadata.json b/apps/espruinoctrl/metadata.json index 5798c7842..253307fa0 100644 --- a/apps/espruinoctrl/metadata.json +++ b/apps/espruinoctrl/metadata.json @@ -6,7 +6,7 @@ "description": "Send commands to other Espruino devices via the Bluetooth UART interface. Customisable commands!", "icon": "app.png", "tags": "", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "custom": "custom.html", "storage": [ From dac6e6ec916d37908eb5cfb49bd9f90b5ef4d8bb Mon Sep 17 00:00:00 2001 From: Rarder44 Date: Mon, 13 Jun 2022 14:18:26 +0200 Subject: [PATCH 168/183] Rebble: fix battery size --- apps/rebble/rebble.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/rebble/rebble.app.js b/apps/rebble/rebble.app.js index 8ba61f818..fc91fe0ac 100644 --- a/apps/rebble/rebble.app.js +++ b/apps/rebble/rebble.app.js @@ -236,7 +236,7 @@ function drawBattery(x,y,wi,hi) { g.clearRect(x+2,y+2+2,x+wi-4-2,y+2+hi-2); // centre g.setColor(g.theme.fg); g.fillRect(x+wi-3,y+2+(((hi - 1)/2)-1),x+wi-2,y+2+(((hi - 1)/2)-1)+4); // contact - g.fillRect(x+3, y+5, x +4 + E.getBattery()*(wi-12)/100, y+hi-1); // the level + g.fillRect(x+3, y+5, x +3 + E.getBattery()*(wi-10)/100, y+hi-1); // the level if( Bangle.isCharging() ) { From 988b4d478f6b58ec40b72d09f3122b2466ebd3d8 Mon Sep 17 00:00:00 2001 From: Rarder44 Date: Mon, 13 Jun 2022 14:20:40 +0200 Subject: [PATCH 169/183] changelog and metatada update --- apps/rebble/ChangeLog | 1 + apps/rebble/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/rebble/ChangeLog b/apps/rebble/ChangeLog index 4b415c1c5..4e2e76484 100644 --- a/apps/rebble/ChangeLog +++ b/apps/rebble/ChangeLog @@ -6,3 +6,4 @@ 0.06: Add 12h support and autocycle control 0.07: added localization, removed deprecated code 0.08: removed unused font, fix autocycle, imported suncalc and trimmed, removed pedometer dependency, "tap to cycle" setting +0.09: fix battery icon size \ No newline at end of file diff --git a/apps/rebble/metadata.json b/apps/rebble/metadata.json index e28c67784..ec7650f53 100644 --- a/apps/rebble/metadata.json +++ b/apps/rebble/metadata.json @@ -2,7 +2,7 @@ "id": "rebble", "name": "Rebble Clock", "shortName": "Rebble", - "version": "0.08", + "version": "0.09", "description": "A Pebble style clock, with configurable background, three sidebars including steps, day, date, sunrise, sunset, long live the rebellion", "readme": "README.md", "icon": "rebble.png", From 486d30ab5ef1b492ef19a54cc75f402ea13708db Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:14:09 +0200 Subject: [PATCH 170/183] Create app.js --- apps/novaclock/app.js | 274 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 apps/novaclock/app.js diff --git a/apps/novaclock/app.js b/apps/novaclock/app.js new file mode 100644 index 000000000..e5bd37b06 --- /dev/null +++ b/apps/novaclock/app.js @@ -0,0 +1,274 @@ +function nova() { + var nova = require("heatshrink").decompress(atob("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")); + return nova; +} + +function novaEyesStage1() { + var novaEyesStage1 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5gAFH58rDIXN5movwZRKs+oAIg/OgEr5mi1Go0V+AYIFCLN7oGABIZiK0fXAAkOh0Ph0IBQo+HDI0PhEHhEPDJpWoKQJVCh5ZHHwoZFCgcPg50BLIpYpHohVF1hFChxXODAQACL4hXsHgwABgAACBQg+HDIhuChAZEOYJYtJYkIKwo+EBoJXKJYIABDIyxGK8yUFSYpXKHwTIFKw4NFWFKUGHg0AKwaWGDIrHGWGA9QLIUIK5LJBDJAaDK9o8BhA9JHwSvLK5QQBhEOK9qVLgAMBK5bJJAAMHK9yuBJIRXWh78BDJBWBDIpXnWAIvB1hWNK4xYCOJK7BDIxYoGAZYGBQMOdg6wFBgZWFg7IGK9JYCGQI8FdYpXILAMIDI7IILFZOBAIYCBIoI8KOQ4VDYwRWtHorwCAAQ/DBohXKLAZZCLYQZKLFRZFBQo8HDJLLBDJpYlAB4ZiLE3M5moAQIAFHhgZD5oaCDofNK14/E1Go0QADHaBZDKwQBBKuTyKDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4A==")); + return novaEyesStage1; +} + +function novaEyesStage0() { + var novaEyesStage0 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj64AFH58rDLBVrH6EAlYZXK0Y7KH4gZiK1MOh0Ph0IHxoZGh8Ig8Ih5YwHgpSBKoUPLI4+FDIoUDh8HOgJZFLFI9EKousIoUOK5wYCAARfEK9g8GAAMAAAQKEHw4ZENwUIDIhzBLFpLEhBWFHwgNBK5RLBAAIZGWIxXmSgqTFK5Q+CZApWHBoqwpSgw8GgBWDSwwZFY4ywwHqBZChBXJZIIZIDQZXtHgMIHpI+CV5ZXKCAMIhxXtSpcABgJXLZJIABg5XuVwJJCK60PfgIZIKwIZFK86wBF4OsKxpXGLARxJXYIZGLFAwDLAwKBhzsHWAoMDKwsHZAxXpLAQyBHgrrFK5BYBhAZHZBBYrJwIBDAQJFBHhRyHCobGCK1o9FeAQACH4YNEK5RYDLIRbCDJRYqLIoKFHg4ZJZYIZNLFYAIHhIZZLEo/LBgIZkLNw7QDLJZnAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA")); + return novaEyesStage0; +} + +function novaEyesStage2() { + var novaEyesStage2 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCDwZYqKwKoGLowFDHwpWCDIRRBAQPMAwd+vANBWNRXBJASoDeRKWGDIoEBOoQDDDAQeBK9CUBJQiTCAAq2CB4Q+DDITGFCAZ2DOohYngAAVDLhWj64ACh0PhA0G6+sBoMPCQY+BgAKCBYMOhwZHBoYZFK88PAAKMHKwYABK4oZEKw5YEDIxXpHpRZChBXJZIIZIDQZXtHgMIHpI+CV5ZXKCAMIhxXtSpcABgJXLZJIABg5XuVwJJCK60PfgIZIKwIZFK86wBF4OsgErKxZXGLARxJXYIZGLEoAVDLhXk1AAC5mo0QGDABJXEBIgaBDYfMAA4ZELEouEHgIALHgsABAN+5hUB0R1CDJywlRIvNAQYECMgZXGY4ZXBCAIDCKQTIILFAAISYo8IOQYUDAoQDCBQRWrHwQABcoxdFHhJyCC4i3DDoWiK1hYDRgSQCAAgMBDJ3NDQJWE5oZMLM6ZGHaBZDOgQBBKuQ/FAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA")); + return novaEyesStage2; +} + +function novaEyesStage3() { + var novaEyesStage3 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCBQV+LFRWBVAxdGAoY+FKwQZCJgICB5hZCvF+qgFBWNRXBJASoDeROiK4ytDCIOoC4R5DAYQIBK9A8BGIY2EABQ+DZARRBUoJVCDYzTELE49CVgo7KHosABoocFZYgBDK8yuGABJfGHwIZQLYQcDLEsAAC4ZaK8nXAAMPh8OGhHX1gPBhATCK4QZDh0PJ5IaCh4ZEK848BhCOKHwI9FOIpXKCAMIhxXpdrAZZK8mo1Gi0V+AIYABBAOiBoIAEBAJXCAwQYDDIwAFDYRXoJAozCAYRDCAAN4I4RXCJAoFELBIdBK8o+DGoyzDKQKcDHgpyBYwquECoYMCAQJWmWAgvCUYadHdgzKF5jMCAITTD5gIDK84+B5gABG4SZDd5A8FZQZLDLQIWGDJCwlLAQAC5oCDAgQABVwoZEKIQeCAYTGFDI5YmcogEEAAg8IOQYUDAoQDCBQRWrHwQABJoV+SQ48KOQRpEW4YdC0RWsLAaMCAIQAEBgIZO5oaCKwfNDJhZnTIw7QLIZ0EKuQ/FAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA==")); + return novaEyesStage3; +} + +function novaEyesStage4() { + var novaEyesStage4 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCBQV+LFRWBVAxdGAoY+FKwQZCJgICB5hZCvF+qgFBWNRXBJASoDeROiK4ytDCIOoC4R5DAYQIBK9EAJQg2EBAoFEHwauBUIN4p1UKoQbGaYhYnK4KvCKoQFBHYi6EHosrBQQaCYwRbBDQd4XYSwoKwIuB5oACIAJBBAYpMDAAI+BKwIKDDAJKBvC2BEgIUDEwawmdgIvDGIhVDLYYAEHoIZBVIQPBKwJeBZoLJEXgYHBK8wzBHISMF5xdFK45GCMwQDBNYonBBAN+XAV+K8wAPlYHGDKIAHV8ztCqiHBWo6gEdgOoK4SpEAgQODDwIjBAAIjBCIRXm5g1CHQQCDHgJWCAgIAD0RXDDIPM5oRC5oECDYR+CK9aVES4ZQFHQShEK4yvEAAbJGAARXlHwI9BJYIAEAwLsEql4vwBBHgZYCCQRrEEYgMDAQJWmWAgvCJQJaDUQQ8DVwYZFVAS9CAITED5gIDK84+BcIQ3CTIa5HKwjKFJYZaBCwwZIWEpYCAAXNAQYECAAJkBK4ysCYYR2DAQIICAAZXpd4zqFAAg8IOQYUDAoQDCBQRWrHwQABJoV+SQ48KOQRpEW4YdC0RWsLAaMCAIQAEBgIZO5oaCKwfNDJhZnTIw7QLIZ0EKuQ/FAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA==")); + return novaEyesStage4; + +} + +function novaEyesWhiteStage0() { + var novaEyesWhiteStage0 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj64AFH58rDLBVrH6EAlYZXK0Y7KH4gZiK2Q+JDLJW0Hw4ZZK/5X6HiY+FDLJX/K/Q8VHwYZZK/5X/K/5X/K/5X/K/5X/K+Y+WHgYZZK/5X7Hyg8FDLJX/K/Y+SHg4ZZLGg8JDLJYlH5YMBDMhZuHaAZZLM4AEDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4A=")); + return novaEyesWhiteStage0; +} + +function novaEyesTransStage1() { + var novaEyesTransStage1 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5gAFH58rDIXN5movwZRKs+oAIg/OgEr5mi1Go0V+AYIFCLN7oGABIZiK0YRYDLJW0CY4ZZK/5X6FCoVDDLJX/K/QmXC4IZZK/5X/K/5X/K/5X/K/5X/K+YmWCoYZZK/5X7FCgTFDLJX/K/YqSCI4ZZLEoAPDMRYm5nM1ACBAAo8MDIfNDQQdD5pWvH4mo1GiAAY7QLIZWCAIJVyeRQZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA")); + return novaEyesTransStage1; +} + +function novaEyesTransStage2() { + var novaEyesTransStage2 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCDwZYqKwKoGLowFDHwpWCDIRRBAQPMAwd+vANBWNRXBJASoDeRKWGDIoEBOoQDDDAQeBK9CUBJQiTCAAq2CB4Q+DDITGFCAZ2DOohYngAAVDLhWjC7AZZK/5X/K/5X/K/5X/K/5X/K+YmBACoZcK8moAAXM1GiAwYAJK4gJEDQIbD5gAHDIhYlFwg8BABY8FgAIBv3MKgOiOoQZOWEqJF5oCDAgRkDK4zHDK4IQBAYRSCZBBYoABCTFHhByDCgYFCAYQKCK1Y+CAALlGLoo8JOQQXEW4YdC0RWsLAaMCSAQAEBgIZO5oaBKwnNDJhZnTIw7QLIZ0CAIJVyH4oAEDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4A==")); + return novaEyesTransStage2; +} + +function novaEyesTransStage3() { + var novaEyesTransStage3 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCBQV+LFRWBVAxdGAoY+FKwQZCJgICB5hZCvF+qgFBWNRXBJASoDeROiK4ytDCIOoC4R5DAYQIBK9A8BGIY2EABQ+DZARRBUoJVCDYzTELE49CVgo7KHosABoocFZYgBDK8yuGABJfGHwIZQLYQcDLEsAAC4ZaK8gXYDLJX/K/jtYDLJXk1Go0WivwBDAAIIB0QNBAAgIBK4QGCDAYZGAAobCK9BIFGYQDCIYQABvBHCK4RIFAohYJDoJXlHwY1GWYZSBTgY8FOQLGFVwgVDBgQCBK0ywEF4SjDTo7sGZQvMZgQBCaYfMBAZXnHwPMAAI3CTIbvIHgrKDJYZaBCwwZIWEpYCAAXNAQYECAAKuFDIhRCDwQDCYwoZHLEzlEAggAEHhByDCgYFCAYQKCK1Y+CAAJNCvySHHhRyCNIi3DDoWiK1hYDRgQBCAAgMBDJ3NDQRWD5oZMLM6ZGHaBZDOghVyH4oAEDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4=")); + return novaEyesTransStage3; +} + +function novaTopRedraw() { + var novaTopRedraw = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AHsAABZM/K5fM5kAv2igGi1EAvFUK/6v/K8isDAQV+BAK4BJn5XL1BOB1GoLod4LQIRE0XM5vM1HN5pX/5hXBIwJdGKwgYGA45X3TgJRDLQZXFAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AB8AIH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AP")); + return novaTopRedraw; +} + +function star() { + var backgroundstar = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A9qxA/K/5W/AH5XGLH6w/K34A/AA2BwJB/K62sIP5XWIH4AW1iv/K/5X/AHFWqwCCq2BJ4ICB1mBAAJZBAQIQBlYUCAYMrAgJZ8KQICBU4QCBLIJVBK4QOCNAJSCOQQA/XpQA/K6q3CAH5XUwJB/ACqu/V7BA/AC2BwJB/LC5A/V/4AtqxX/AC2slZB/ACuBqxB/LC5A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4Ao")); + return backgroundstar; +} + +function novaOpenEyes(speed, white, animation) { + if (!white) { + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + setTimeout(function() { + g.drawImage(novaEyesStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + g.drawImage(novaEyesStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + g.drawImage(novaEyesStage1(), -10, -10, { + scale: 2.2 + }); + }, speed * 4); + if (animation) { + setTimeout(function() { + g.drawImage(novaEyesStage0(), -10, -10, { + scale: 2.2 + }); + }, speed * 5); + } else {} + } else { + + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + timedraw(true); + g.drawImage(novaEyesTransStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + timedraw(true); + g.drawImage(novaEyesTransStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + timedraw(true); + g.drawImage(novaEyesTransStage1(), -10, -10, { + scale: 2.2 + }); + open = true; + }, speed * 4); + if (animation) { + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + open = true; + }, speed * 5); + } else {} + } +} + +function novaCloseEyes(speed, white, animation) { + if (!white) { // for other + if (animation) { + g.drawImage(novaEyesStage0(), -10, -10, { + scale: 2.2 + }); + } else {} + setTimeout(function() { + g.drawImage(novaEyesStage1(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + g.drawImage(novaEyesStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + g.drawImage(novaEyesStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 4); + setTimeout(function() { + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + }, speed * 5); + } else { // for time + + if (animation) { + timedraw(true); + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + } else {} + setTimeout(function() { + timedraw(true); + g.drawImage(novaEyesTransStage1(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + timedraw(true); + g.drawImage(novaEyesTransStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + timedraw(true); + g.drawImage(novaEyesTransStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 4); + setTimeout(function() { + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + }, speed * 5); + open = false; + } +} + +function timedraw(animation) { + if (open && timemode || animation) { + g.setFont("6x8", 4); + g.setColor("#00F"); + var d = new Date(); + var h = d.getHours(), + m = d.getMinutes(); + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + g.drawImage(novaEyesTransStage1(), -10, -10, { + scale: 2.2 + }); + // Check if single digit + var hourDigits = h.toString(); + if (hourDigits.length === 1) { // if hour digits only one, render in middle + g.drawString(h, 50, 66); + } else { + g.drawString(h, 38, 66); + } + var minutes = m.toString(); + if (minutes.length === 1) { // same for mins + g.drawString(m, 107, 66); + } else { + g.drawString(m, 94, 66); + } + } +} + +function main() { + Bangle.on("lock", function(lock) { + g.drawImage(novaTopRedraw(), -10, novaYPos, { + scale: 2.2 + }); + if (lock) { + novaCloseEyes(200, true, false); + setTimeout(function() { + novaOpenEyes(100, false, false); + timemode = false; + }, 1200); + }else{ + novaCloseEyes(100, false, false); + setTimeout(function() { + timemode = true; + novaOpenEyes(200, true, false); + }, 600); + } + }); +} + + +g.setFont("6x8", 4); +g.setColor("#FFF"); +var open = false; +var timemode = true; +var clockmode; +var novaYPos = -7; +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +g.drawImage(nova(), -10, -10, { + scale: 2.2 +}); +Bangle.setUI("clock"); + +g.drawImage(star(), 5, -5, {scale:0.8}); +g.drawImage(star(), -10, 120, {scale:0.8}); +g.drawImage(star(), 120, -5, {scale:0.8}); + + + +var secondInterval = setInterval(function() { + timedraw(); + g.drawImage(novaTopRedraw(), -10, novaYPos, { + scale: 2.2 + }); +}, 1000); + +novaOpenEyes(300, true, false); +main(); From 04f60a596f541c3acee476751133e9c03573348b Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:17:23 +0200 Subject: [PATCH 171/183] Create app-icon.js --- apps/novaclock/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/novaclock/app-icon.js diff --git a/apps/novaclock/app-icon.js b/apps/novaclock/app-icon.js new file mode 100644 index 000000000..cf159ba1f --- /dev/null +++ b/apps/novaclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AE3N5ouuGFovuFwYwrF9wuFGFIqC5nMF9guBF9ReD43GGFJeDF9ReFGFImCFwYvBGAReqMEAdCAAwvKAA4pWFxYwNGhQoJAAouHYQYAEGBwsIFBIANGRBgLFzIwDYhoweFx4xGGC4uSGDYuFFpqTIF1BhXFzBhVXSZhNF6QuWGAgvSFzAvS4wved6KOsSDovJ5gACF9IsCBIQxFF8ItEAAYxEF7qHDFowxGBwZeaFxgPEAwYvYABAONF74PVF64RbF6IThDZYVnDIoXtAH4A/AH4AkA==")) From e0b996b75cdf894e051f9ae713c4e6243838d217 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:19:53 +0200 Subject: [PATCH 172/183] Create metadata.json --- apps/novaclock/metadata.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 apps/novaclock/metadata.json diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json new file mode 100644 index 000000000..6e41d8fed --- /dev/null +++ b/apps/novaclock/metadata.json @@ -0,0 +1,12 @@ +{ "id": "novaclock", + "name": "Nova Clock", + "shortName":"Nova Clock", + "icon": "app.png", + "version":"0.1", + "description": "A clock inspired by the Kirby series", + "tags": "clock", + "storage": [ + {"name":"timer.app.js","url":"app.js"}, + {"name":"timer.img","url":"app-icon.js","evaluate":true} + ] +} From 2410a81b1c18d93be47d5da5aaf2e5180df5d958 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:20:25 +0200 Subject: [PATCH 173/183] Add files via upload --- apps/novaclock/app.png | Bin 0 -> 1882 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/novaclock/app.png diff --git a/apps/novaclock/app.png b/apps/novaclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..6270be5d37d3ec007b8c61a33f96004e1443cb98 GIT binary patch literal 1882 zcmV-g2c`IlP)F0cE(d+YrF=lsv9a~|AY|Hmt5BxhuiHWs#de)WD&J-7-$ zJGw*ef3;hL9kYl{0jP#AG7g?Lc>M6iMVVO$ft)eqc#;?)2I%9-oEKwjF%j5U{TU$% zp@l9$8-(>^KVO8Y#SlpGak>t=4%!yF2&Bgrk2px=ru=&9E z=WTEP5$NNW2@%>(^&dKwQ4G+BFV5TCTnXgOzx@hPUgs4{=Ar$$9 zsL|+x$s5O>o|oM@N+|tE0VW0A1&D=67d00`gqWaDKb)7rU2d;z8L&Y!h z#)k|||B}4-%A@{}0sOPV3!`2pTZEFN} zud0H#Ex~XI%@Ar27O)1yfH4_EM(h^GY+(5vwLQg!=CAURm*Z3f^5)TRk>u;-G$3Um zXDxxbhd!%U6Ofa7HWrEGbOVWPy}x@|qu_@_@Lt6$7L0%^MadYjQtoH4R>_G4CmCZ$ zNcyfU|K-`e32Yqg39+1_CE;RHFXsu^tpAggRLc69vq~p)FbXKc8&>V1uE17mSqwN) z;9?6Yqu&{)q^;FYUn%j*W?5dlp1W_%0pS!`9;KJ!(Ok-4EEOdwi3y>YKyryh)_a+~ z!Gl(&5CBs=UvOBfBuoKojY_U^O2*pa>kNid`$`BP|84cBjN+5DEsQz{tzK;^6{I9< zNc#hwb%`j*%Bq)r1>S*glt^9cRoNG0<=i8?U;VE#DtDj#4BmW?s)B)srUq9wt(=Bd z=5~{5!wXZQ4e1obkx~;+2>Yd4k-l^x_>Jm{e zHx8PKx4r(|_;NMR%Aqr#-}CjG?VUG|e1*t!j9VC&;iT(S$D^^{OHuXzW|k3fPMzXQ zg8Qb($g2XpeMSzR`_8`nZ)GE2T77~pJWtzccR4P-O*>XHqtZ6dN_TcJA zHgTQ+;xR zryiF2YqP?coj})rcBg@x0N4Y!EA2pCX=`xfN@&hZdaS;OEQm;+gYtc&Li~_e#%b~I0OBd;)ejm$Z=2GckCxxI)aJlyj zC6L#bYXU+aH3F#&9aZtZbt)Ze)%&hQAUH4qssO?2SQ!#zvumbE5VPd<5G&Q@MRtj6-ZQ~HfR)#>`16j;NN)?_|;+vB%Y!#x)qAn zO9ZM(hw7m+dN5fNFp>$*V?rTnptCxOg#y}`GJb=bjMZ4O4y22$zrifXElgv}z?KQeb?bQ)tpii^4 zH`6|tH;=E-jV}^P@9&Hztg)9#c2zzw+mBQE--qwu%G-ZW*BvF5gci{}Ixx6b?mE3b z%|6q!HSuAL=uaYb4Sw(%OJ+sxT{}1{cmTQc!c{qR<`@Ue3V!e!b*&B&3tfD8+I^<4 zLel>cYkP!kT>gX{Jon11p!eMNuJaqfo%zy{6GZt9h9RbUc^-S;Uboln^*^xw1D?l8 Uc_DV*Gynhq07*qoM6N<$g8EIA)c^nh literal 0 HcmV?d00001 From 0103f6a554bd4dee765ae4928761fe8ff560842b Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:22:07 +0200 Subject: [PATCH 174/183] readme --- apps/novaclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 6e41d8fed..1b42f22ab 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -5,6 +5,7 @@ "version":"0.1", "description": "A clock inspired by the Kirby series", "tags": "clock", + "readme":"README.md", "storage": [ {"name":"timer.app.js","url":"app.js"}, {"name":"timer.img","url":"app-icon.js","evaluate":true} From 4baf6b096b26b388a767819c4025ef7a277db675 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:25:06 +0200 Subject: [PATCH 175/183] Create README.md --- apps/novaclock/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 apps/novaclock/README.md diff --git a/apps/novaclock/README.md b/apps/novaclock/README.md new file mode 100644 index 000000000..677721c66 --- /dev/null +++ b/apps/novaclock/README.md @@ -0,0 +1,6 @@ +## Nova Clock +A simple clock app that uses a clockwork star, from Kirby. + +Pixel art by me. + +*Note: This clock draws slightly into the widget area, but since it's in the middle, it shouln't matter that much (nobody has that many widgets... right?)* From 0a7a8206453c69e9ef8ccfac2dfcc00633d05a19 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:28:34 +0200 Subject: [PATCH 176/183] supports --- apps/novaclock/metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 1b42f22ab..3ec2bb1b4 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -5,7 +5,8 @@ "version":"0.1", "description": "A clock inspired by the Kirby series", "tags": "clock", - "readme":"README.md", + "supports": ["BANGLEJS2"], + "readme":"README.md", "storage": [ {"name":"timer.app.js","url":"app.js"}, {"name":"timer.img","url":"app-icon.js","evaluate":true} From 99600e0c6c6f250e83c1cb0a4609d2c499475801 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:31:47 +0200 Subject: [PATCH 177/183] Update metadata.json --- apps/novaclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 3ec2bb1b4..177772e86 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -2,6 +2,7 @@ "name": "Nova Clock", "shortName":"Nova Clock", "icon": "app.png", + "type": "clock", "version":"0.1", "description": "A clock inspired by the Kirby series", "tags": "clock", From b6d14c41046c04d07bc0ca3f559322e37e799a6b Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:36:51 +0200 Subject: [PATCH 178/183] oh. --- apps/novaclock/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 177772e86..c1dad60a1 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -9,7 +9,7 @@ "supports": ["BANGLEJS2"], "readme":"README.md", "storage": [ - {"name":"timer.app.js","url":"app.js"}, - {"name":"timer.img","url":"app-icon.js","evaluate":true} + {"name":"novaclock.app.js","url":"app.js"}, + {"name":"novaclock.img","url":"app-icon.js","evaluate":true} ] } From c2d8229c9ef5420d3d684421b87bea00001deab5 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:41:56 +0200 Subject: [PATCH 179/183] Update README.md --- apps/novaclock/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/novaclock/README.md b/apps/novaclock/README.md index 677721c66..be10bcd6c 100644 --- a/apps/novaclock/README.md +++ b/apps/novaclock/README.md @@ -1,6 +1,9 @@ ## Nova Clock A simple clock app that uses a clockwork star, from Kirby. -Pixel art by me. - *Note: This clock draws slightly into the widget area, but since it's in the middle, it shouln't matter that much (nobody has that many widgets... right?)* + +# Credits +Pixel art by me, [dronesflier](https://github.com/dronesflier) + +The Kirby series belongs to Nintendo/HAL Labs From b27705eacce0da8fce77dbeb6ca791bbd574cb7c Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:42:09 +0200 Subject: [PATCH 180/183] Update README.md --- apps/novaclock/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/novaclock/README.md b/apps/novaclock/README.md index be10bcd6c..b54f44241 100644 --- a/apps/novaclock/README.md +++ b/apps/novaclock/README.md @@ -1,9 +1,9 @@ -## Nova Clock +# Nova Clock A simple clock app that uses a clockwork star, from Kirby. *Note: This clock draws slightly into the widget area, but since it's in the middle, it shouln't matter that much (nobody has that many widgets... right?)* -# Credits +## Credits Pixel art by me, [dronesflier](https://github.com/dronesflier) The Kirby series belongs to Nintendo/HAL Labs From 94aff2d0154cec4cb2ee64a6141eda83429dce0c Mon Sep 17 00:00:00 2001 From: Kilrah Date: Mon, 13 Jun 2022 23:08:05 +0200 Subject: [PATCH 181/183] two of them clock * Try adding new watchface * Add real screenshot * Fix app icon? * Doc Co-authored-by: Kilrah --- apps/2ofthemclk/ChangeLog | 1 + apps/2ofthemclk/README.md | 11 ++++ apps/2ofthemclk/app-icon.js | 1 + apps/2ofthemclk/app.js | 90 +++++++++++++++++++++++++++++++++ apps/2ofthemclk/app.png | Bin 0 -> 4480 bytes apps/2ofthemclk/bg.png | Bin 0 -> 5902 bytes apps/2ofthemclk/metadata.json | 17 +++++++ apps/2ofthemclk/screenshot.png | Bin 0 -> 7273 bytes 8 files changed, 120 insertions(+) create mode 100644 apps/2ofthemclk/ChangeLog create mode 100644 apps/2ofthemclk/README.md create mode 100644 apps/2ofthemclk/app-icon.js create mode 100644 apps/2ofthemclk/app.js create mode 100644 apps/2ofthemclk/app.png create mode 100644 apps/2ofthemclk/bg.png create mode 100644 apps/2ofthemclk/metadata.json create mode 100644 apps/2ofthemclk/screenshot.png diff --git a/apps/2ofthemclk/ChangeLog b/apps/2ofthemclk/ChangeLog new file mode 100644 index 000000000..2286a7f70 --- /dev/null +++ b/apps/2ofthemclk/ChangeLog @@ -0,0 +1 @@ +0.01: New App! \ No newline at end of file diff --git a/apps/2ofthemclk/README.md b/apps/2ofthemclk/README.md new file mode 100644 index 000000000..7ac2cf779 --- /dev/null +++ b/apps/2ofthemclk/README.md @@ -0,0 +1,11 @@ +# two of them clock + +You can now wear teh memez on your wrist. + +![](screenshot.png) + +Also serves as an example of displaying seconds only when unlocked or charging and only refreshing on the minute otherwise. +Widgets not supported + +## Creator +- [Kilrah](https://github.com/kilrah) diff --git a/apps/2ofthemclk/app-icon.js b/apps/2ofthemclk/app-icon.js new file mode 100644 index 000000000..9bfb8a550 --- /dev/null +++ b/apps/2ofthemclk/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgZC/AH4ADkAPOgVJkgEBAQQAJiQRByEJgmQCJWSpMEAQMkyQJCpASHhAOBpAmBJJgjBCIUJCRg4CCIJxFMQ2SoARCkmACI0EBAJHCCIMLj4RFiUBskAgIXBEAU5A4P34CtCiEJsEJ/AHBCgOBAoQAEi0H////HciQsBwywICIXWzkG4A+BEY0gif46dt6/cgnIgkWnHfLIP/MoUWwHbpvC/kAjEEj0HNYQCCkEfGgP/64RB2EAifHLwMAjg1CCIMD/0H/0B8EAh+HgeAkARCE4IjC/4jBYIMPLIcIAYUPB4OBCIQABhu/AoShCHYIRBx6QBDgUw2//8OHPwcJ39//ILBCIU9LgMBSQgsBJAYRBkE/CIIABgRHD3wRFkk/2zBDAYU//3b/oRB8ARBj6ABgEE7YREEYf+oMkSwINCyClCn//z//+4RBgMkgU3EgUcwFJgEeboOXCIP2EYJCDAAVJkkGWoIuBgf2EYQPDkECCIOGd4ffyEJkgFBAAcSoEkwQCBhw+BwQaByVAkGAKwIFBBANLkEQgAyBCIVIkBpBgmSBYOQoApBgcgiQRCAQIyCCgsSjIFBCIcgRgJNCCgQyBpAgDAQT2BCgIOBBAQUCCIpfBCIwCKP4QRNpCSDCLyJBCIbjBTwYRLboJ0BCI4QD")) diff --git a/apps/2ofthemclk/app.js b/apps/2ofthemclk/app.js new file mode 100644 index 000000000..78415fba7 --- /dev/null +++ b/apps/2ofthemclk/app.js @@ -0,0 +1,90 @@ +const img = require("heatshrink").decompress(atob("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")); + +var battery = E.getBattery(); + +// Positions on screen +const timeX = 88, timeY = 52; +const dateX = 5, dateY = 180; +const battX = 172, battY = 175; + +// Draw on every second if unlocked or charging, minute otherwise, start at with seconds on load +var drawTimeout; +var drawInterval = 1000; + +// schedule a draw for the next interval +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, drawInterval - (Date.now() % drawInterval)); +} + +// Update display and timeout on lock/unlock and charge state change +Bangle.on('lock',on=>{ + draw(); +}); + +Bangle.on('charging',charging=>{ + draw(); +}); + +function draw() { + // work out how to display the current time + var d = new Date(); + var h = d.getHours(), m = d.getMinutes(); + var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2); + var seconds = ("0"+d.getSeconds()).substr(-2); + + // g.clear(); // Unneeded if background image takes the whole screen + + // Draw background + g.drawImage(img); + g.setColor(1, 1, 1); + + // draw the current time + g.setFontAlign(1,1); // align right bottom + g.setFont("6x15",3); + g.drawString(time, timeX, timeY, false); + + // Draw battery % + g.setFont("6x15",1); + var battStr = ""; + if(Bangle.isCharging()) { + battStr = "+"; + } + g.drawString(battStr + battery + "%", battX, battY, false); + + // Draw date + g.setFontAlign(-1,1); // align left bottom + g.setFont("6x15",2); + var dateStr = require("locale").date(d)+" "; + g.drawString(dateStr, dateX, dateY, false); + + // draw the seconds only if unlocked, set next timeout + if(!Bangle.isLocked() || Bangle.isCharging()) { + drawInterval = 1000; + g.setFont("6x15",2); + g.drawString(seconds, timeX+2, timeY-4, false); + } + else + drawInterval = 60000; + + // Schedule next draw + queueDraw(); + // console.log("Draw " + time + ":" + seconds); +} + +function refreshBattery() { + battery = E.getBattery(); +} + +// Only update displayed battery level every minute as it fluctuates a lot +var batteryInterval = setInterval(refreshBattery, 60000); + +Bangle.setUI("clock"); +Bangle.setLocked(false); +// Clear the screen once, at startup +g.clear(); +// draw immediately at first +draw(); diff --git a/apps/2ofthemclk/app.png b/apps/2ofthemclk/app.png new file mode 100644 index 0000000000000000000000000000000000000000..d304f27d9adcd7e680db96c18d27d8408c05c279 GIT binary patch literal 4480 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 Date: Tue, 14 Jun 2022 09:04:15 +0100 Subject: [PATCH 182/183] Fixing apps that use buzz after recent buzz strength PR (these apps would have previously used a low strength buzz) --- apps/messages/settings.js | 2 +- apps/messages/widget.js | 2 +- apps/multitimer/alarm.js | 2 +- apps/noteify/app.js | 14 +++++++------- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/messages/settings.js b/apps/messages/settings.js index adea36f12..1b166dcf6 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -1,7 +1,7 @@ (function(back) { function settings() { let settings = require('Storage').readJSON("messages.settings.json", true) || {}; - if (settings.vibrate===undefined) settings.vibrate="."; + if (settings.vibrate===undefined) settings.vibrate=":"; if (settings.repeat===undefined) settings.repeat=4; if (settings.unreadTimeout===undefined) settings.unreadTimeout=60; settings.unlockWatch=!!settings.unlockWatch; diff --git a/apps/messages/widget.js b/apps/messages/widget.js index ca02d4f1f..25573220f 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -34,7 +34,7 @@ draw:function(recall) { Bangle.drawWidgets(); },buzz:function() { if ((require('Storage').readJSON('setting.json',1)||{}).quiet) return; // never buzz during Quiet Mode - require("buzz").pattern((require('Storage').readJSON("messages.settings.json", true) || {}).vibrate || "."); + require("buzz").pattern((require('Storage').readJSON("messages.settings.json", true) || {}).vibrate || ":"); },touch:function(b,c) { var w=WIDGETS["messages"]; if (!w||!w.width||c.xw.x+w.width||c.yw.y+w.iconwidth) return; diff --git a/apps/multitimer/alarm.js b/apps/multitimer/alarm.js index 97cbaa5fa..eb1b3b259 100644 --- a/apps/multitimer/alarm.js +++ b/apps/multitimer/alarm.js @@ -120,7 +120,7 @@ function showAlarm(alarm) { Bangle.setLocked(false); } - require("buzz").pattern(alarm.vibrate === undefined ? ".." : alarm.vibrate).then(() => { + require("buzz").pattern(alarm.vibrate === undefined ? "::" : alarm.vibrate).then(() => { if (buzzCount--) { setTimeout(buzz, settings.buzzIntervalMillis); } else if (alarm.as) { // auto-snooze diff --git a/apps/noteify/app.js b/apps/noteify/app.js index c19694ea4..2b3ee64f0 100644 --- a/apps/noteify/app.js +++ b/apps/noteify/app.js @@ -5,7 +5,7 @@ var notes = require("Storage").readJSON("noteify.json", true) || []; var alarms = require("sched").getAlarms(); msg = ""; -function startNote(idx) { +function startNote(idx) { idx == undefined ? note = "" : note = notes[idx].note; require("textinput").input({text:note}).then(result => { if (result != "") { @@ -23,20 +23,20 @@ function viewNote(idx) { textY += e.dy; g.setClipRect(0, 30, g.getWidth(), g.getHeight()); if (textY > 30) textY = 30; - if (textY < textBound) textY = textBound; + if (textY < textBound) textY = textBound; g.clearRect(0, 30, g.getWidth(), g.getHeight()).setColor(g.theme.fg).setFont("6x8:2").setFontAlign(-1, -1).drawString(g.wrapString(notes[idx].note, g.getWidth()).join("\n"), 0, textY); },back:()=>{ Bangle.setUI(); showEditMenu(idx); }}); - + } function showMainMenu() { var mainMenu = { "" : { "title" : "Noteify" }, "< Back" : function() { load(); }, - "New note" : function() { + "New note" : function() { E.showMenu(); startNote(); }, @@ -187,7 +187,7 @@ function editAlarm(alarmIndex, alarm) { as : false, dow : 0b1111111, last : 0, - vibrate : ".." + vibrate : "::" }; if (msg != "") a["msg"] = msg; if (!newAlarm) Object.assign(a, alarms[alarmIndex]); @@ -195,7 +195,7 @@ function editAlarm(alarmIndex, alarm) { var t = decodeTime(a.t); var alarmTitle = (a.msg == undefined) ? 'Alarm' : (a.msg.length > 12) ? a.msg.replace(/\n/g, " ").substring(0, 12)+"..." : msg.replace(/\n/g, " ").substring(0, 12)+"..."; - + const menu = { '': { 'title': alarmTitle }, '< Back' : () => showAlarmMenu(), @@ -264,7 +264,7 @@ function editTimer(alarmIndex, alarm) { var t = decodeTime(a.timer); var timerTitle = (a.msg == undefined) ? 'Timer' : (a.msg.length > 12) ? a.msg.replace(/\n/g, " ").substring(0, 12)+"..." : msg.replace(/\n/g, " ").substring(0, 12)+"..."; - + const menu = { '': { 'title': timerTitle }, '< Back' : () => showMainMenu(), From 3c024be9c94fe021496be65c6a1b28598b269453 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 14 Jun 2022 09:54:52 +0100 Subject: [PATCH 183/183] recommend 2v14 --- loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader.js b/loader.js index e9887f3d4..0e0fdcba0 100644 --- a/loader.js +++ b/loader.js @@ -16,7 +16,7 @@ if (window.location.host=="banglejs.com") { 'This is not the official Bangle.js App Loader - you can try the
Official Version here.'; } -var RECOMMENDED_VERSION = "2v13"; +var RECOMMENDED_VERSION = "2v14"; // could check http://www.espruino.com/json/BANGLEJS.json for this // We're only interested in Bangles