Merge branch 'espruino:master' into master
commit
368a8802e1
|
|
@ -12,3 +12,5 @@
|
|||
0.08: fixed calendar weeknumber not shortened to two digits
|
||||
0.09: Use default Bangle formatter for booleans
|
||||
0.10: Use Bangle.setUI({remove:...}) to allow loading the launcher without a full reset on 2v16
|
||||
0.11: Moved enhanced Anton clock to 'Anton Clock Plus' and stripped this clock back down to make it faster for new users (270ms -> 170ms)
|
||||
Modified to avoid leaving functions defined when using setUI({remove:...})
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 14 KiB |
|
|
@ -1,9 +1,8 @@
|
|||
{
|
||||
"id": "antonclk",
|
||||
"name": "Anton Clock",
|
||||
"version": "0.10",
|
||||
"description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.",
|
||||
"readme":"README.md",
|
||||
"version": "0.11",
|
||||
"description": "A simple clock using the bold Anton font. See `Anton Clock Plus` for an enhanced version",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"type": "clock",
|
||||
|
|
@ -12,8 +11,6 @@
|
|||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"antonclk.app.js","url":"app.js"},
|
||||
{"name":"antonclk.settings.js","url":"settings.js"},
|
||||
{"name":"antonclk.img","url":"app-icon.js","evaluate":true}
|
||||
],
|
||||
"data": [{"name":"antonclk.json"}]
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.8 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
0.01: New App!
|
||||
0.02: Load widgets after setUI so widclk knows when to hide
|
||||
0.03: Clock now shows day of week under date.
|
||||
0.04: Clock can optionally show seconds, date optionally in ISO-8601 format, weekdays and uppercase configurable, too.
|
||||
0.05: Clock can optionally show ISO-8601 calendar weeknumber (default: Off)
|
||||
when weekday name "Off": week #:<num>
|
||||
when weekday name "On": weekday name is cut at 6th position and .#<week num> is added
|
||||
0.06: fixes #1271 - wrong settings name
|
||||
when weekday name and calendar weeknumber are on then display is <weekday short> #<calweek>
|
||||
week is buffered until date or timezone changes
|
||||
0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users)
|
||||
0.08: fixed calendar weeknumber not shortened to two digits
|
||||
0.09: Use default Bangle formatter for booleans
|
||||
0.10: Use Bangle.setUI({remove:...}) to allow loading the launcher without a full reset on 2v16
|
||||
Modified to avoid leaving functions defined when using setUI({remove:...})
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Anton Clock - Large font digital watch with seconds and date
|
||||
# Anton Clock Plus - Large font digital watch with seconds and date
|
||||
|
||||
Anton clock uses the "Anton" bold font to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit.
|
||||
Anton Clock Plus uses the "Anton" bold font to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit.
|
||||
|
||||
## Features
|
||||
|
||||
|
|
@ -16,16 +16,16 @@ The basic time representation only shows hours and minutes of the current time.
|
|||
|
||||
## Usage
|
||||
|
||||
Install Anton clock through the Bangle.js app loader.
|
||||
Configure it through the default Bangle.js configuration mechanism
|
||||
* Install Anton Clock Plus through the Bangle.js app loader.
|
||||
* Configure it through the default Bangle.js configuration mechanism
|
||||
(Settings app, "Apps" menu, "Anton clock" submenu).
|
||||
If you like it, make it your default watch face
|
||||
* If you like it, make it your default watch face
|
||||
(Settings app, "System" menu, "Clock" submenu, select "Anton clock").
|
||||
|
||||
## Configuration
|
||||
|
||||
Anton clock is configured by the standard settings mechanism of Bangle.js's operating system:
|
||||
Open the "Settings" app, then the "Apps" submenu and below it the "Anton clock" menu.
|
||||
Anton Clock is configured by the standard settings mechanism of Bangle.js's operating system:
|
||||
Open the `Settings` app, then the `Apps` submenu and below it the `Anton Clock+` menu.
|
||||
You configure Anton clock through several "on/off" switches in two menus.
|
||||
|
||||
### The main menu
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwgf/AH4At/l/Aofgh4DB+EAj4REQoM/AgP4AoeACIoLCg4FB4AFDCIwLCgAROgYIB8EBAoUH/gVBCIxQBCKYHBCJp9DI4ICBLJYRCn4RQEYMOR5ARDIgIRMYQZZBgARGZwZBDCKQrCgEDR5AdBUIQRJDoLXFCJD7J/xrICIQFCn4RH/4LDAoTaCCI4Ar/LLDCBfypMkCgMkyV/CJOSCIOf5IRGFwOfCJNP//JnmT588z/+pM/BYIRCk4RC/88+f/n4RCngRCz1JCIf5/nzGoQRIHwXPCIPJI4f8CJHJGQJKCCI59LCI5ZCCJ/+v/kBoM/+V/HIJrHBYJWB/JKB5x9JEYP8AQKdBpwRL841Dp41KZoTxBHYTXBWY77PCKKhJ/4/CcgMkXoQAiA="))
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"id": "antonclkplus",
|
||||
"name": "Anton Clock Plus",
|
||||
"shortName": "Anton Clock+",
|
||||
"version": "0.10",
|
||||
"description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.",
|
||||
"readme":"README.md",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"antonclkplus.app.js","url":"app.js"},
|
||||
{"name":"antonclkplus.settings.js","url":"settings.js"},
|
||||
{"name":"antonclkplus.img","url":"app-icon.js","evaluate":true}
|
||||
],
|
||||
"data": [{"name":"antonclkplus.json"}]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -1,2 +1,3 @@
|
|||
0.01: Initial version
|
||||
0.02: Moved settings from launcher to settings->apps menu
|
||||
0.03: Better performance by not scanning on every boot
|
||||
|
|
|
|||
|
|
@ -1,67 +1,29 @@
|
|||
(function() {
|
||||
var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {});
|
||||
{
|
||||
let settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {});
|
||||
|
||||
//list all sources
|
||||
var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};});
|
||||
let hash = require("Storage").hash(/\.info/);
|
||||
if (settings.hash!=hash) {
|
||||
//apps changed, rescan and remove no longer existing apps
|
||||
let apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};});
|
||||
|
||||
//populate empty app list
|
||||
|
||||
if (!settings.leftapp) {
|
||||
settings["leftapp"] = {"name":"(none)"};
|
||||
require("Storage").write("quicklaunch.json",settings);
|
||||
for (let c of ["leftapp","rightapp","upapp","downapp","tapapp"]){
|
||||
if (!settings[c]) settings[c] = {"name":"(none)"};
|
||||
if (!require("Storage").read(settings[c].src)) settings[c] = {"name":"(none)"};
|
||||
}
|
||||
if (!settings.rightapp) {
|
||||
settings["rightapp"] = {"name":"(none)"};
|
||||
require("Storage").write("quicklaunch.json",settings);
|
||||
}
|
||||
if (!settings.upapp) {
|
||||
settings["upapp"] = {"name":"(none)"};
|
||||
require("Storage").write("quicklaunch.json",settings);
|
||||
}
|
||||
if (!settings.downapp) {
|
||||
settings["downapp"] = {"name":"(none)"};
|
||||
require("Storage").write("quicklaunch.json",settings);
|
||||
}
|
||||
if (!settings.tapapp) {
|
||||
settings["tapapp"] = {"name":"(none)"};
|
||||
settings.hash = hash;
|
||||
require("Storage").write("quicklaunch.json",settings);
|
||||
}
|
||||
|
||||
//activate on clock faces
|
||||
var sui = Bangle.setUI;
|
||||
Bangle.setUI = function(mode, cb) {
|
||||
sui(mode,cb);
|
||||
if(!mode) return;
|
||||
if ("object"==typeof mode) mode = mode.mode;
|
||||
if (!mode.startsWith("clock")) return;
|
||||
|
||||
function tap() {
|
||||
//tap, check if source exists, launch
|
||||
if ((settings.tapapp.src) && apps.some(e => e.src === settings.tapapp.src)) load (settings.tapapp.src);
|
||||
}
|
||||
|
||||
let drag;
|
||||
let e;
|
||||
|
||||
Bangle.on("touch",tap);
|
||||
Bangle.on("drag", e => {
|
||||
if (!drag) { // start dragging
|
||||
drag = {x: e.x, y: e.y};
|
||||
} else if (!e.b) { // released
|
||||
const dx = e.x-drag.x, dy = e.y-drag.y;
|
||||
drag = null;
|
||||
//horizontal swipes, check if source exists, launch
|
||||
if (Math.abs(dx)>Math.abs(dy)+10) {
|
||||
if ((settings.leftapp.src) && apps.some(e => e.src === settings.leftapp.src) && dx<0) load(settings.leftapp.src);
|
||||
if ((settings.rightapp.src) && apps.some(e => e.src === settings.rightapp.src) && dx>0) load(settings.rightapp.src);
|
||||
}
|
||||
//vertical swipes, check if source exists, launch
|
||||
else if (Math.abs(dy)>Math.abs(dx)+10) {
|
||||
if ((settings.upapp.src) && apps.some(e => e.src === settings.upapp.src) && dy<0) load(settings.upapp.src);
|
||||
if ((settings.downapp.src) && apps.some(e => e.src === settings.downapp.src) && dy>0) load(settings.downapp.src);
|
||||
}
|
||||
}
|
||||
Bangle.on("touch", () => {
|
||||
if (!Bangle.CLOCK) return;
|
||||
if (settings.tapapp.src) load(settings.tapapp.src);
|
||||
});
|
||||
Bangle.on("swipe", (lr,ud) => {
|
||||
if (!Bangle.CLOCK) return;
|
||||
|
||||
};
|
||||
})();
|
||||
if (lr == -1 && settings.leftapp.src) load(settings.leftapp.src);
|
||||
if (lr == 1 && settings.rightapp.src) load(settings.rightapp.src);
|
||||
if (ud == 1 && settings.upapp.src) load(settings.upapp.src);
|
||||
if (ud == -1 && settings.downapp.src) load(settings.downapp.src);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "quicklaunch",
|
||||
"name": "Quick Launch",
|
||||
"icon": "app.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Tap or swipe left/right/up/down on your clock face to launch up to five apps of your choice. Configurations can be accessed through Settings->Apps.",
|
||||
"type": "bootloader",
|
||||
"tags": "tools, system",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
(function(back) {
|
||||
var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {});
|
||||
|
||||
for (let c of ["leftapp","rightapp","upapp","downapp","tapapp"]){
|
||||
if (!settings[c]) settings[c] = {"name":"(none)"};
|
||||
}
|
||||
|
||||
var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="launch" || app.type=="clock" || !app.type));
|
||||
|
||||
apps.sort((a,b)=>{
|
||||
|
|
@ -119,4 +123,4 @@ apps.forEach((a)=>{
|
|||
});
|
||||
|
||||
showMainMenu();
|
||||
});
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@
|
|||
0.04: Fix regression stopping correct widget updates
|
||||
0.05: Don't show clock widget if already showing clock app
|
||||
0.06: Use 7 segment font, update *on* the minute, use less memory
|
||||
0.07: allow turning on/off when quick-switching apps
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "widclk",
|
||||
"name": "Digital clock widget",
|
||||
"version": "0.06",
|
||||
"version": "0.07",
|
||||
"description": "A simple digital clock widget",
|
||||
"icon": "widget.png",
|
||||
"type": "widget",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
/* Simple clock that appears in the widget bar if no other clock
|
||||
is running. We update once per minute, but don't bother stopping
|
||||
if the */
|
||||
|
||||
// don't show widget if we know we have a clock app running
|
||||
if (!Bangle.CLOCK) WIDGETS["wdclk"]={area:"tl",width:52/* g.stringWidth("00:00") */,draw:function() {
|
||||
g.reset().setFontCustom(atob("AAAAAAAAAAIAAAQCAQAAAd0BgMBdwAAAAAAAdwAB0RiMRcAAAERiMRdwAcAQCAQdwAcERiMRBwAd0RiMRBwAAEAgEAdwAd0RiMRdwAcERiMRdwAFAAd0QiEQdwAdwRCIRBwAd0BgMBAAABwRCIRdwAd0RiMRAAAd0QiEQAAAAAAAAAA="), 32, atob("BgAAAAAAAAAAAAAAAAYCAAYGBgYGBgYGBgYCAAAAAAAABgYGBgYG"), 512+9);
|
||||
WIDGETS["wdclk"]={area:"tl",width:Bangle.CLOCK?0:52/* g.stringWidth("00:00") */,draw:function() {
|
||||
if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not...
|
||||
this.width = Bangle.CLOCK?0:52;
|
||||
return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw
|
||||
}
|
||||
if (!this.width) return; // if size not right, return
|
||||
g.reset().setFontCustom(atob("AAAAAAAAAAIAAAQCAQAAAd0BgMBdwAAAAAAAdwAB0RiMRcAAAERiMRdwAcAQCAQdwAcERiMRBwAd0RiMRBwAAEAgEAdwAd0RiMRdwAcERiMRdwAFAAd0QiEQdwAdwRCIRBwAd0BgMBAAABwRCIRdwAd0RiMRAAAd0QiEQAAAAAAAAAA="), 32, atob("BgAAAAAAAAAAAAAAAAYCAAYGBgYGBgYGBgYCAAAAAAAABgYGBgYG"), 512+9);
|
||||
var time = require("locale").time(new Date(),1);
|
||||
g.drawString(time, this.x, this.y+3, true); // 5 * 6*2 = 60
|
||||
// queue draw in one minute
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
0.01: Fork of widclk v0.04 github.com/espruino/BangleApps/tree/master/apps/widclk
|
||||
0.02: Modification for bottom widget area and text color
|
||||
0.03: based in widclk v0.05 compatible at same time, bottom area and color
|
||||
|
||||
0.04: refactored to use less memory, and allow turning on/off when quick-switching apps
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
"id": "widclkbttm",
|
||||
"name": "Digital clock (Bottom) widget",
|
||||
"shortName": "Digital clock Bottom Widget",
|
||||
"version": "0.03",
|
||||
"description": "Displays time in the bottom area.",
|
||||
"version": "0.04",
|
||||
"description": "Displays time in the bottom of the screen (may not be compatible with some apps)",
|
||||
"icon": "widclkbttm.png",
|
||||
"type": "widget",
|
||||
"tags": "widget",
|
||||
|
|
|
|||
|
|
@ -1,31 +1,16 @@
|
|||
(function() {
|
||||
// don't show widget if we know we have a clock app running
|
||||
if (Bangle.CLOCK) return;
|
||||
|
||||
let intervalRef = null;
|
||||
var width = 5 * 6*2;
|
||||
var text_color=0x07FF;//cyan
|
||||
|
||||
function draw() {
|
||||
g.reset().setFont("6x8", 2).setFontAlign(-1, 0).setColor(text_color);
|
||||
WIDGETS["wdclkbttm"]={area:"br",width:Bangle.CLOCK?0:60,draw:function() {
|
||||
if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not...
|
||||
this.width = Bangle.CLOCK?0:60;
|
||||
return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw
|
||||
}
|
||||
if (!this.width) return; // if size not right, return
|
||||
g.reset().setFont("6x8", 2).setFontAlign(-1, 0).setColor("#0ff"); // cyan
|
||||
var time = require("locale").time(new Date(),1);
|
||||
g.drawString(time, this.x, this.y+11, true); // 5 * 6*2 = 60
|
||||
}
|
||||
function clearTimers(){
|
||||
if(intervalRef) {
|
||||
clearInterval(intervalRef);
|
||||
intervalRef = null;
|
||||
}
|
||||
}
|
||||
function startTimers(){
|
||||
intervalRef = setInterval(()=>WIDGETS["wdclkbttm"].draw(), 60*1000);
|
||||
WIDGETS["wdclkbttm"].draw();
|
||||
}
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
clearTimers();
|
||||
if (on) startTimers();
|
||||
});
|
||||
|
||||
WIDGETS["wdclkbttm"]={area:"br",width:width,draw:draw};
|
||||
if (Bangle.isLCDOn) intervalRef = setInterval(()=>WIDGETS["wdclkbttm"].draw(), 60*1000);
|
||||
})()
|
||||
// queue draw in one minute
|
||||
if (this.drawTimeout) clearTimeout(this.drawTimeout);
|
||||
this.drawTimeout = setTimeout(()=>{
|
||||
this.drawTimeout = undefined;
|
||||
this.draw();
|
||||
}, 60000 - (Date.now() % 60000));
|
||||
}};
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
0.01: New widget!
|
||||
0.02: allow turning on/off when quick-switching apps
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "widclose",
|
||||
"name": "Close Button",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "A button to close the current app",
|
||||
"readme": "README.md",
|
||||
"icon": "icon.png",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
if (!Bangle.CLOCK) WIDGETS.close = {
|
||||
area: "tr", width: 24, sortorder: 10, // we want the right-most spot please
|
||||
WIDGETS.close = {
|
||||
area: "tr", width: Bangle.CLOCK?0:24, sortorder: 10, // we want the right-most spot please
|
||||
draw: function() {
|
||||
Bangle.removeListener("touch", this.touch);
|
||||
Bangle.on("touch", this.touch);
|
||||
g.reset().setColor("#f00").drawImage(atob( // hardcoded red to match setUI back button
|
||||
if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not...
|
||||
this.width = Bangle.CLOCK?0:24;
|
||||
return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw
|
||||
}
|
||||
if (this.width) g.reset().setColor("#f00").drawImage(atob( // red to match setUI back button
|
||||
// b/w version of preview.png, 24x24
|
||||
"GBgBABgAAf+AB//gD//wH//4P//8P//8fn5+fjx+fxj+f4H+/8P//8P/f4H+fxj+fjx+fn5+P//8P//8H//4D//wB//gAf+AABgA"
|
||||
), this.x, this.y);
|
||||
}, touch: function(_, c) {
|
||||
const w = WIDGETS.close;
|
||||
if (w && c.x>=w.x && c.x<=w.x+24 && c.y>=w.y && c.y<=w.y+24) load();
|
||||
}, touch: function(_, c) { // if touched
|
||||
const w = WIDGETS.close; // if in range, go back to the clock
|
||||
if (w && c.x>=w.x && c.x<w.x+w.width && c.y>=w.y && c.y<=w.y+24) load();
|
||||
}
|
||||
};
|
||||
Bangle.on("touch", WIDGETS.close.touch);
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
0.01: New widget!
|
||||
0.02: allow turning on/off when quick-switching apps
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "widcloselaunch",
|
||||
"name": "Close Button to launcher",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "A button to close the current app and go to launcher",
|
||||
"readme": "README.md",
|
||||
"icon": "icon.png",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
if (!Bangle.CLOCK) WIDGETS.close = {
|
||||
area: "tr", width: 24, sortorder: 10, // we want the right-most spot please
|
||||
WIDGETS.close = {
|
||||
area: "tr", width: Bangle.CLOCK?0:24, sortorder: 10, // we want the right-most spot please
|
||||
draw: function() {
|
||||
Bangle.removeListener("touch", this.touch);
|
||||
Bangle.on("touch", this.touch);
|
||||
g.reset().setColor("#f00").drawImage(atob( // hardcoded red to match setUI back button
|
||||
if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not...
|
||||
this.width = Bangle.CLOCK?0:24;
|
||||
return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw
|
||||
}
|
||||
if (this.width) g.reset().setColor("#f00").drawImage(atob( // red to match setUI back button
|
||||
// b/w version of preview.png, 24x24
|
||||
"GBgBABgAAf+AB//gD//wH//4P//8P//8fn5+fjx+fxj+f4H+/8P//8P/f4H+fxj+fjx+fn5+P//8P//8H//4D//wB//gAf+AABgA"
|
||||
), this.x, this.y);
|
||||
}, touch: function(_, c) {
|
||||
const w = WIDGETS.close;
|
||||
if (w && c.x>=w.x && c.x<=w.x+24 && c.y>=w.y && c.y<=w.y+24) Bangle.showLauncher();
|
||||
if (w && c.x>=w.x && c.x<w.x+w.width && c.y>=w.y && c.y<=w.y+24) Bangle.showLauncher();
|
||||
}
|
||||
};
|
||||
Bangle.on("touch", WIDGETS.close.touch);
|
||||
|
|
|
|||
Loading…
Reference in New Issue