Device Name: Bangle.js 316f puck.js:371 Device ID: +zawUlUNoIowupCBtVbdAQ== puck.js:371 Connected comms.js:118 getInstalledApps Array(31) ui.js:86 [-] Updating Fullscreen Notifications... comms.js:30 uploadApp: notify, notifyfs.info comms.js:10 reset comms.js:12 reset: got "" comms.js:15 reset: no response. waiting 7... comms.js:12 reset: got "" comms.js:15 reset: no response. waiting 6... comms.js:12 reset: got "" comms.js:15 reset: no response. waiting 5... comms.js:12 reset: got "\u001b[?7l\r\n ____ _ \r\n| __|___ ___ ___ _ _|_|___ ___ \r\n| __|_ -| . | _| | | | | . |\r\n|____|___| _|_| |___|_|_|_|___|\r\n |_| espruino.com\r\n 2v06.81 (c) 2019 G.Williams\r\n\r\nExecution Interrupted\r\n>" comms.js:18 reset: complete. comms.js:51 Upload notify => "let oldg;\nlet id = null;\n\n/**\n * See notify/notify.js\n */\nfunction fitWords(text,rows,width) {\n // We never need more than rows*width characters anyway, split by any whitespace\n const words = text.trim().substr(0,rows*width).split(/\\s+/);\n let row=1,len=0,limit=width;\n let result = \"\";\n for (let word of words) {\n // len==0 means first word of row, after that we also add a space\n if ((len?len+1:0)+word.length > limit) {\n if (row>=rows) {\n result += \"...\";\n break;\n }\n result += \"\\n\";\n len=0;\n row++;\n if (row===rows) limit -= 3; // last row needs space for \"...\"\n }\n result += (len?\" \":\"\") + word;\n len += (len?1:0) + word.length;\n }\n return result;\n}\n\n\n/**\n options = {\n on : bool // turn screen on, default true\n size : int // height of notification, default 120 (max)\n title : string // optional title\n id // optional notification ID, used with hide()\n src : string // optional source name\n body : string // optional body text\n icon : string // optional icon (image string)\n render function(y) // function callback to render\n }\n*/\nexports.show = function(options) {\n if (oldg) g=oldg;\n options = options||{};\n if (options.on===undefined) options.on=true;\n id = (\"id\" in options)?options.id:null;\n let size = options.size||120;\n if (size>120) {size=120}\n Bangle.setLCDMode(\"direct\");\n let x = 0,\n y = 0,\n w = 240,\n h = 240;\n // clear screen\n g.clear(1);\n // top bar\n if (options.title||options.src) {\n y=40;h=size;\n const title = options.title || options.src\n g.setColor(0x39C7).fillRect(x, y, x+w-1, y+30);\n g.setColor(-1).setFontAlign(-1, -1, 0).setFont(\"6x8\", 3);\n g.drawString(title.trim().substring(0, 13), x+5, y+3);\n if (options.title && options.src) {\n g.setColor(-1).setFontAlign(1, 1, 0).setFont(\"6x8\", 2);\n // above drawing area, but we are fullscreen\n g.drawString(options.src.substring(0, 10), x+235, y-32);\n }\n y += 30;h -= 30;\n }\n if (options.icon) {\n let i = options.icon, iw,ih;\n if (\"string\"==typeof i) {iw=i.charCodeAt(0); ih=i.charCodeAt(1)}\n else {iw=i[0]; ih=i[1]}\n const iy=y ? (y+4) : (h-ih)/2; // show below title bar if present, otherwise center vertically\n g.drawImage(i, x+4,iy);\n x += iw+4;w -= iw+4;\n }\n // body text\n if (options.body) {\n const maxRows = Math.floor((h-4)/16), // font=2*(6x8)\n maxChars = Math.floor((w-4)/12),\n text=fitWords(options.body, maxRows, maxChars);\n g.setColor(-1).setFont(\"6x8\", 2).setFontAlign(-1, -1, 0).drawString(text, x+4, y+4);\n }\n\n if (options.render) {\n const area={x:x, y:y, w:w, h:h}\n options.render(area);\n }\n\n if (options.on) Bangle.setLCDPower(1); // light up\n Bangle.on(\"touch\", exports.hide);\n // Create a fake graphics to hide draw attempts\n oldg = g;\n g = Graphics.createArrayBuffer(8,8,1);\n g.flip = function() {};\n};\n\n/**\n options = {\n id // optional, only hide if current notification has this ID\n }\n */\nexports.hide = function(options) {\n options = options||{};\n if (\"id\" in options && options.id!==id) return;\n id = null;\n if (oldg) {\n g=oldg;\n oldg = undefined;\n }\n Bangle.removeListener(\"touch\", exports.hide);\n g.clear();\n Bangle.drawWidgets();\n // flipping the screen off then on often triggers a redraw - it may not!\n Bangle.setLCDPower(0);\n Bangle.setLCDPower(1);\n // hack for E.showMenu/showAlert/showPrompt - can force a redraw by faking next/back\n if (Bangle.btnWatches) {\n global[\"\\xff\"].watches[Bangle.btnWatches[0]].callback();\n global[\"\\xff\"].watches[Bangle.btnWatches[1]].callback();\n }\n};\n" ui.js:86 [error] Fullscreen Notifications update failed, Unexpected response comms.js:30 uploadApp: notify, notifyfs.info comms.js:10 reset comms.js:12 reset: got "" comms.js:15 reset: no response. waiting 7... comms.js:12 reset: got "\u001b[?7l\r\n ____ _ \r\n| __|___ ___ ___ _ _|_|___ ___ \r\n| __|_ -| . | _| | | | | . |\r\n|____|___| _|_| |___|_|_|_|___|\r\n |_| espruino.com\r\n 2v06.81 (c) 2019 G.Williams\r\n\r\n>" comms.js:18 reset: complete. comms.js:51 Upload notify => "let oldg;\nlet id = null;\n\n/**\n * See notify/notify.js\n */\nfunction fitWords(text,rows,width) {\n // We never need more than rows*width characters anyway, split by any whitespace\n const words = text.trim().substr(0,rows*width).split(/\\s+/);\n let row=1,len=0,limit=width;\n let result = \"\";\n for (let word of words) {\n // len==0 means first word of row, after that we also add a space\n if ((len?len+1:0)+word.length > limit) {\n if (row>=rows) {\n result += \"...\";\n break;\n }\n result += \"\\n\";\n len=0;\n row++;\n if (row===rows) limit -= 3; // last row needs space for \"...\"\n }\n result += (len?\" \":\"\") + word;\n len += (len?1:0) + word.length;\n }\n return result;\n}\n\n\n/**\n options = {\n on : bool // turn screen on, default true\n size : int // height of notification, default 120 (max)\n title : string // optional title\n id // optional notification ID, used with hide()\n src : string // optional source name\n body : string // optional body text\n icon : string // optional icon (image string)\n render function(y) // function callback to render\n }\n*/\nexports.show = function(options) {\n if (oldg) g=oldg;\n options = options||{};\n if (options.on===undefined) options.on=true;\n id = (\"id\" in options)?options.id:null;\n let size = options.size||120;\n if (size>120) {size=120}\n Bangle.setLCDMode(\"direct\");\n let x = 0,\n y = 0,\n w = 240,\n h = 240;\n // clear screen\n g.clear(1);\n // top bar\n if (options.title||options.src) {\n y=40;h=size;\n const title = options.title || options.src\n g.setColor(0x39C7).fillRect(x, y, x+w-1, y+30);\n g.setColor(-1).setFontAlign(-1, -1, 0).setFont(\"6x8\", 3);\n g.drawString(title.trim().substring(0, 13), x+5, y+3);\n if (options.title && options.src) {\n g.setColor(-1).setFontAlign(1, 1, 0).setFont(\"6x8\", 2);\n // above drawing area, but we are fullscreen\n g.drawString(options.src.substring(0, 10), x+235, y-32);\n }\n y += 30;h -= 30;\n }\n if (options.icon) {\n let i = options.icon, iw,ih;\n if (\"string\"==typeof i) {iw=i.charCodeAt(0); ih=i.charCodeAt(1)}\n else {iw=i[0]; ih=i[1]}\n const iy=y ? (y+4) : (h-ih)/2; // show below title bar if present, otherwise center vertically\n g.drawImage(i, x+4,iy);\n x += iw+4;w -= iw+4;\n }\n // body text\n if (options.body) {\n const maxRows = Math.floor((h-4)/16), // font=2*(6x8)\n maxChars = Math.floor((w-4)/12),\n text=fitWords(options.body, maxRows, maxChars);\n g.setColor(-1).setFont(\"6x8\", 2).setFontAlign(-1, -1, 0).drawString(text, x+4, y+4);\n }\n\n if (options.render) {\n const area={x:x, y:y, w:w, h:h}\n options.render(area);\n }\n\n if (options.on) Bangle.setLCDPower(1); // light up\n Bangle.on(\"touch\", exports.hide);\n // Create a fake graphics to hide draw attempts\n oldg = g;\n g = Graphics.createArrayBuffer(8,8,1);\n g.flip = function() {};\n};\n\n/**\n options = {\n id // optional, only hide if current notification has this ID\n }\n */\nexports.hide = function(options) {\n options = options||{};\n if (\"id\" in options && options.id!==id) return;\n id = null;\n if (oldg) {\n g=oldg;\n oldg = undefined;\n }\n Bangle.removeListener(\"touch\", exports.hide);\n g.clear();\n Bangle.drawWidgets();\n // flipping the screen off then on often triggers a redraw - it may not!\n Bangle.setLCDPower(0);\n Bangle.setLCDPower(1);\n // hack for E.showMenu/showAlert/showPrompt - can force a redraw by faking next/back\n if (Bangle.btnWatches) {\n global[\"\\xff\"].watches[Bangle.btnWatches[0]].callback();\n global[\"\\xff\"].watches[Bangle.btnWatches[1]].callback();\n }\n};\n" comms.js:51 Upload notifyfs.info => "{\"id\":\"notifyfs\",\"name\":\"Notifications\",\"type\":\"notify\",\"version\":\"0.05\",\"files\":\"notifyfs.info,notify\"}" ui.js:86 [error] Upload failed, Unexpected response Uncaught Error: File already written with different data