@sebbo2002/vestaboard 4.0.2-develop.9 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,20 +9,17 @@
9
9
 
10
10
  <br />
11
11
 
12
-
13
- Just another client for the [Vestaboard](https://www.vestaboard.com/) [APIs](https://docs.vestaboard.com/). It supports
14
- the [Subscription API](https://docs.vestaboard.com/methods), [Read/Write API](https://docs.vestaboard.com/read-write) and
12
+ Just another client for the [Vestaboard](https://www.vestaboard.com/) [APIs](https://docs.vestaboard.com/). It supports
13
+ the [Subscription API](https://docs.vestaboard.com/methods), [Read/Write API](https://docs.vestaboard.com/read-write) and
15
14
  the [Local API](https://docs.vestaboard.com/local). Written in Typescript.
16
15
 
17
- The library also provides a small collection of helpers to format messages on the Vestaboard. This includes a `write()`
18
- method that automatically wraps text, a `fill()` method to fill the board with nice characters, or `table()` to conjure
16
+ The library also provides a small collection of helpers to format messages on the Vestaboard. This includes a `write()`
17
+ method that automatically wraps text, a `fill()` method to fill the board with nice characters, or `table()` to conjure
19
18
  up a table on the board.
20
19
 
21
-
22
20
  ## 📦 Installation
23
21
 
24
- npm i --save @sebbo2002/vestaboard
25
-
22
+ npm i --save @sebbo2002/vestaboard
26
23
 
27
24
  ## ⚡️ Quick Start
28
25
 
@@ -30,26 +27,31 @@ up a table on the board.
30
27
 
31
28
  ```js
32
29
  import { SubscriptionAPI, Message } from '@sebbo2002/vestaboard';
33
- const api = new SubscriptionAPI('3eadf7a8-6602-4bf5-92f4-970d36066958', '******************************');
30
+ const api = new SubscriptionAPI(
31
+ '3eadf7a8-6602-4bf5-92f4-970d36066958',
32
+ '******************************',
33
+ );
34
34
  const msg = new Message().fill('🟥🟧🟨🟩🟦🟪');
35
35
 
36
36
  api.postMessage(msg);
37
37
  ```
38
38
 
39
39
  #### Write a calendar on a local Vestaboard
40
+
40
41
  ```js
41
42
  import { LocalAPI, Message } from '@sebbo2002/vestaboard';
42
43
  const api = new LocalAPI('***');
43
44
  const msg = new Message().table([
44
- ['now', 'Daily'],
45
- ['13:00', 'Super Secret Meeting'],
46
- ['16:30', 'Awesome Presentation']
45
+ ['now', 'Daily'],
46
+ ['13:00', 'Super Secret Meeting'],
47
+ ['16:30', 'Awesome Presentation'],
47
48
  ]);
48
49
 
49
50
  api.postMessage(msg);
50
51
  ```
51
52
 
52
53
  #### Write Hello World on multiple local boards
54
+
53
55
  ```js
54
56
  import { MultipleBoards, LocalAPI, Message } from '@sebbo2002/vestaboard';
55
57
  const board1 = new LocalAPI('***');
@@ -61,20 +63,18 @@ boards.postMessage('Hello World');
61
63
 
62
64
  See the [examples](./examples) folder for more examples.
63
65
 
64
-
65
66
  ## 📑 API-Reference
66
67
 
67
68
  - [Index](https://sebbo2002.github.io/vestaboard/develop/reference/)
68
- - [LocalAPI](https://sebbo2002.github.io/vestaboard/develop/reference/classes/LocalAPI.html)
69
- - [Message](https://sebbo2002.github.io/vestaboard/develop/reference/classes/Message.html)
70
- - [MultipleBoards](https://sebbo2002.github.io/vestaboard/develop/reference/classes/MultipleBoards.html)
71
- - [ReadWriteAPI](https://sebbo2002.github.io/vestaboard/develop/reference/classes/ReadWriteAPI.html)
72
- - [SubscriptionAPI](https://sebbo2002.github.io/vestaboard/develop/reference/classes/SubscriptionAPI.html)
73
-
69
+ - [LocalAPI](https://sebbo2002.github.io/vestaboard/develop/reference/classes/LocalAPI.html)
70
+ - [Message](https://sebbo2002.github.io/vestaboard/develop/reference/classes/Message.html)
71
+ - [MultipleBoards](https://sebbo2002.github.io/vestaboard/develop/reference/classes/MultipleBoards.html)
72
+ - [ReadWriteAPI](https://sebbo2002.github.io/vestaboard/develop/reference/classes/ReadWriteAPI.html)
73
+ - [SubscriptionAPI](https://sebbo2002.github.io/vestaboard/develop/reference/classes/SubscriptionAPI.html)
74
74
 
75
75
  ## 🚦 Tests
76
76
 
77
- Some unit tests use the Vestaboard API to run the tests. You can use the `.env.example` file as a template and enter your
77
+ Some unit tests use the Vestaboard API to run the tests. You can use the `.env.example` file as a template and enter your
78
78
  data there accordingly.
79
79
 
80
80
  ```
@@ -82,7 +82,6 @@ npm test
82
82
  npm run coverage
83
83
  ```
84
84
 
85
-
86
85
  ## 🙆🏼‍♂️ Copyright and license
87
86
 
88
87
  Copyright (c) Sebastian Pekarek under the [MIT license](LICENSE).
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- "use strict";var E=Object.create;var O=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var N=(a,r)=>{for(var e in r)O(a,e,{get:r[e],enumerable:!0})},M=(a,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of v(r))!T.call(a,s)&&s!==e&&O(a,s,{get:()=>r[s],enumerable:!(t=B(r,s))||t.enumerable});return a};var L=(a,r,e)=>(e=a!=null?E(P(a)):{},M(r||!a||!a.__esModule?O(e,"default",{value:a,enumerable:!0}):e,a)),k=a=>M(O({},"__esModule",{value:!0}),a);var j={};N(j,{BOARD_LINES:()=>w,BOARD_LINE_LENGTH:()=>l,LocalAPI:()=>b,Message:()=>c,MessageWritePosition:()=>A,MultipleBoards:()=>y,ReadWriteAPI:()=>m,SubscriptionAPI:()=>g});module.exports=k(j);var x=L(require("grapheme-splitter"),1);async function d(a,r,e,t={}){let s=e===void 0?"GET":"POST";e!==void 0&&Object.assign(r,{"Content-Type":"application/json"});let n={method:s,headers:r};e!==void 0&&typeof e=="string"?n.body=e:e!==void 0&&(n.body=JSON.stringify(e));let o=null;for(let i=0;i<10&&(o=await(t.fetch||fetch)(a,n),!o.ok);i++)await new Promise(p=>setTimeout(p,1e3));if(!o?.ok)throw new Error("HTTP Request failed");return t.parseResponse===!1?void 0:await o.json()}var g=class{key;secret;options;constructor(r,e,t){this.key=r,this.secret=e,this.options=t||{}}async request(r,e){return d(`https://platform.vestaboard.com${r}`,{"X-Vestaboard-Api-Key":this.key,"X-Vestaboard-Api-Secret":this.secret},e,this.options)}async getViewer(){return await this.request("/viewer")}async getSubscriptions(){return await this.request("/subscriptions")}async postMessage(r,e){let t=!1,s=[],n=typeof r=="string"?new c(r):r;if(typeof e=="string")t=!0,s.push(e);else if(Array.isArray(e))s.push(...e);else{let u=await this.getSubscriptions();s.push(...u.subscriptions.map(i=>i._id))}let o=[];for(let u of s)o.push(await this.request(`/subscriptions/${u}/message`,{characters:n.toCharArray()}));return t?o[0]:o}};var m=class{key;options;constructor(r,e){this.key=r,this.options=e||{}}async request(r,e){return d(`https://rw.vestaboard.com${r}`,{"X-Vestaboard-Read-Write-Key":this.key},e,this.options)}async getCurrentMessage(){let r=await this.request("/");return new c(JSON.parse(r.currentMessage.layout))}async postMessage(r){let e=typeof r=="string"?new c(r):r;await this.request("/",JSON.stringify(e.toCharArray()))}};var l=22,w=6,A=(t=>(t[t.CURRENT=0]="CURRENT",t[t.NO_SPACE_BETWEEN=1]="NO_SPACE_BETWEEN",t[t.NEXT_LINE=2]="NEXT_LINE",t))(A||{});var S=[[" ",[0]],["A",[1]],["a",[1]],["b",[2]],["B",[2]],["C",[3]],["c",[3]],["d",[4]],["e",[5]],["f",[6]],["g",[7]],["h",[8]],["i",[9]],["j",[10]],["k",[11]],["l",[12]],["m",[13]],["n",[14]],["o",[15]],["p",[16]],["q",[17]],["r",[18]],["s",[19]],["t",[20]],["u",[21]],["v",[22]],["w",[23]],["x",[24]],["y",[25]],["z",[26]],["D",[4]],["E",[5]],["F",[6]],["G",[7]],["H",[8]],["I",[9]],["J",[10]],["K",[11]],["L",[12]],["M",[13]],["N",[14]],["O",[15]],["P",[16]],["Q",[17]],["R",[18]],["S",[19]],["T",[20]],["U",[21]],["V",[22]],["W",[23]],["X",[24]],["Y",[25]],["Z",[26]],["1",[27]],["2",[28]],["3",[29]],["4",[30]],["5",[31]],["6",[32]],["7",[33]],["8",[34]],["9",[35]],["0",[36]],["!",[37]],["@",[38]],["#",[39]],["$",[40]],["(",[41]],[")",[42]],["-",[44]],["+",[46]],["&",[47]],["=",[48]],[";",[49]],[":",[50]],["'",[52]],['"',[53]],["%",[54]],[",",[55]],[".",[56]],["/",[59]],["?",[60]],["\xB0",[62]],["\u20AC",[5,21,18]],["\u0192",[6]],["\u017D",[26]],["\u0161",[19]],["\xBC",[27,59,30]],["\xBD",[27,59,28]],["\xBE",[29,59,30]],["\xC0",[1]],["\xC1",[1]],["\xC2",[1]],["\xC3",[1]],["\xC4",[1,5]],["\xC5",[1]],["\xC6",[1,5]],["\xC7",[3]],["\xC8",[5]],["\xC9",[5]],["\xCA",[5]],["\xCB",[5]],["\xCC",[9]],["\xCD",[9]],["\xCE",[9]],["\xCF",[9]],["\xD0",[5,20,8]],["\xD1",[14]],["\xD2",[15]],["\xD3",[15]],["\xD4",[15]],["\xD5",[15]],["\xD6",[15,5]],["\xD7",[24]],["\xD9",[21]],["\xDA",[21]],["\xDB",[21]],["\xDC",[21,5]],["\xDD",[25]],["\xDF",[19,19]],["\xE0",[1]],["\xE1",[1]],["\xE2",[1]],["\xE3",[1]],["\xE4",[1,5]],["\xE5",[1]],["\xE6",[1,5]],["\xE7",[3]],["\xE8",[5]],["\xE9",[5]],["\xEA",[5]],["\xEB",[5]],["\xEC",[9]],["\xED",[9]],["\xEE",[9]],["\xEF",[9]],["\xF0",[15]],["\xF1",[14]],["\xF2",[15]],["\xF3",[15]],["\xF4",[15]],["\xF5",[15]],["\xF6",[15,5]],["\xF9",[21]],["\xFA",[21]],["\xFB",[21]],["\xFC",[21,5]],["\xFD",[25]],["\xFF",[25]],["\u{1F7E5}",[63]],["\u{1F7E7}",[64]],["\u{1F7E8}",[65]],["\u{1F7E9}",[66]],["\u{1F7E6}",[67]],["\u{1F7EA}",[68]],["\u2B1C\uFE0F",[69]],["\u2B1C",[69]],["\u2B1B\uFE0F",[-2]],["\u2B1B",[-2]],["\uFE6B",[38]],["\uFF20",[38]],["0\uFE0F\u20E3",[36]],["1\uFE0F\u20E3",[27]],["2\uFE0F\u20E3",[28]],["3\uFE0F\u20E3",[29]],["4\uFE0F\u20E3",[30]],["5\uFE0F\u20E3",[31]],["6\uFE0F\u20E3",[32]],["7\uFE0F\u20E3",[33]],["8\uFE0F\u20E3",[34]],["9\uFE0F\u20E3",[35]],["\u2755",[37]],["\u203C\uFE0F",[37,37]],["\u2757\uFE0F",[37]],["\u2049\uFE0F",[37,60]],["#\uFE0F\u20E3",[39]],["\u{1F4B2}",[40]],["$",[40]],["\uFE69",[40]],["\uFF04",[40]],["\u2190",[44]],["\u2192",[44]],["\u27A1",[44]],["\u2B05",[44]],["\u2794",[44]],["\u2194",[44]],["\u2013",[44]],["\u2795",[46]],["+",[46]],["\uFE6A",[54]],["\uFF05",[54]],["\u2753",[60]],["\u2754",[60]],["\u2103",[62,3]],["\u2109",[62,6]]],C=new Array(w).fill(new Array(l).fill(0)),c=class a{static splitter=new x.default;board;cursor=[0,0];constructor(r){typeof r=="string"&&r?(this.board=JSON.parse(JSON.stringify(C)),this.write(r),this.center()):Array.isArray(r)?this.board=r:this.board=JSON.parse(JSON.stringify(C))}static string2chars(r,e={}){let t=[],s=a.splitter.splitGraphemes(r);for(let n of s)t.push(...this.char2char(n));return e.removeUnsupportedWords!==!1&&(t=a.removeEmojisFromChars(t)),t=t.map(n=>n>=0?n:n===-2?0:typeof e.fallbackChar=="number"?e.fallbackChar:e.fallbackChar===null?-1:60).filter(n=>n>=0),t}static char2char(r){let e=S.find(([t])=>r===t);return e&&Array.isArray(e[1])?e[1]:[-1]}static charToString(r){let e=Object.values(S).filter(([t])=>t.length<=2).find(([,t])=>t[0]===r);return e?e[0].toUpperCase()+(e[0].length===1?" ":""):"\u26A1\uFE0E "}static splitCharsIntoLines(r,e){let t=[];for(let n of r){t.length||t.push([null,[]]);let o=t[t.length-1];n===0?t.push([0,[]]):n===44?(o[1].push(n),t.push([null,[]])):o[1].push(n)}let s=[];for(let[n,o]of t){s.length||s.push([]);let u=s[s.length-1],i=e[s.length===1?0:1]-u.length;if(!u.length&&o.length<=i)u.push(...o);else if(n!==null&&o.length+1<=i)u.push(0,...o);else if(o.length<=i)u.push(...o);else if(o.length<=e[1])u=[...o],i=e[1],s.push(u);else{i>=3&&!u.length||(i>=4&&u.length?(u.push(0),i--):(u=[],i=e[1],s.push(u)));for(let p of o)u.push(p),i--,i<=1&&(u.push(44),u=[],i=e[1],s.push(u))}}return s}static removeEmojisFromChars(r){let e=[];for(let s of r)e.length||e.push([]),s===0?e.push([]):e[e.length-1].push(s);e.forEach(s=>{if(s.length>0&&s[0]===-1)for(;s[0]<0;)s.splice(0,1);if(s.length>0&&s[s.length-1]===-1)for(;s.length>0&&s[s.length-1]<0;)s.splice(s.length-1,1)});let t=[];return e.filter(s=>s.length>0).forEach(s=>{t.length!==0&&t.push(0),t.push(...s)}),t}static getColumnSizesFromData(r,e={}){if(!r.length)return[];let t=r[0].length,s=[];r.forEach((p,h)=>{if(p.length!==t)throw new Error(`Unable to render table: Row ${h} has ${p.length} entries, but first row has ${t}!`);p.forEach((f,R)=>{s[R]=Math.max(s[R]||0,this.string2chars(f,e).length)})});let n=s.reduce((p,h)=>p+h,0),o=r[0].length-1,u=Math.max((l-o)/n,1),i=s.map(p=>Math.round(p*u));for(;;){let p=i.reduce((R,q)=>R+q,0)+o;if(p===l)break;let h=l-p<0?-1:1,f=i.indexOf(h<0?Math.max(...i):Math.min(...i));if(f<0)throw new Error("Unable to find max value in array\u2026");i[f]+=h}return i}get isEmpty(){return!this.board.find(r=>r.find(e=>e!==0))}fill(r=" "){let e=0,t=a.string2chars(r,{removeUnsupportedWords:!1});return this.board.forEach(s=>{s.forEach((n,o)=>{s[o]=t[e],e++,e>t.length-1&&(e=0)})}),this}write(r,e={}){if(!this.board[this.cursor[0]])return this;e.position===2&&(this.cursor[0]!==0||this.cursor[1]!==0)?(this.cursor[0]++,this.cursor[1]=0):typeof e.position=="object"&&(this.cursor[0]=e.position.line,this.cursor[1]=e.position.row||0),(e.position===void 0||e.position===0)&&this.cursor[1]!==0&&this.cursor[1]<l-1&&(this.board[this.cursor[0]].splice(this.cursor[1],1,0),this.cursor[1]+=1);let t=0;e.indent===!0?t=this.cursor[1]:typeof e.indent=="number"&&e.indent>=0&&e.indent<=l-5&&(t=e.indent);let s=r.split(`
2
- `),n=!0;for(let o of s){let u=a.string2chars(o,e),i=[l-this.cursor[1],l-t];n||(this.cursor[0]++,this.cursor[1]=t),typeof e.position=="object"&&e.position.width&&(i[0]=Math.min(i[0],e.position.width),i[1]=Math.min(i[1],e.position.width-t));let p=a.splitCharsIntoLines(u,i);for(let h of p){if(!this.board[this.cursor[0]])break;this.board[this.cursor[0]].splice(this.cursor[1],h.length,...h),this.cursor[1]+=h.length,h!==p[p.length-1]&&(this.cursor[0]++,this.cursor[1]=t)}n=!1}return this}table(r){let e=a.getColumnSizesFromData(r);return(this.cursor[0]!==0||this.cursor[1]!==0)&&(this.cursor[0]++,this.cursor[1]=0),r.forEach(t=>{let s=this.cursor[0],n=1;t.forEach((o,u)=>{let i=e[u],p=e.filter((h,f)=>f<u).reduce((h,f)=>h+f+1,0);this.write(o,{position:{line:s,row:p,width:i},indent:p}),n=Math.max(n,this.cursor[0]-s+1)}),this.cursor[0]=s+n+1,this.cursor[1]=0}),this}center(){let r=[this.board.findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.slice().reverse().findIndex(s=>s!==0):t.length)),this.board.slice().reverse().findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.findIndex(s=>s!==0):t.length))],e=[Math.floor((r[0]+r[2])/2),Math.floor((r[1]+r[3])/2)];if(r[0]!==e[0]){let t=e[0]-r[0];this.board.splice(t>0?0:this.board.length,0,...this.board.splice(t>0?this.board.length-t:0,Math.abs(t)))}if(r[3]!==e[1]){let t=e[1]-r[3];this.board.forEach(s=>{s.splice(t>0?0:s.length,0,...s.splice(t>0?s.length-t:0,Math.abs(t)))})}}toString(){return"#="+"=".repeat(l*2)+`=#
1
+ "use strict";var E=Object.create;var O=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var N=(a,r)=>{for(var e in r)O(a,e,{get:r[e],enumerable:!0})},M=(a,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of v(r))!T.call(a,s)&&s!==e&&O(a,s,{get:()=>r[s],enumerable:!(t=B(r,s))||t.enumerable});return a};var L=(a,r,e)=>(e=a!=null?E(P(a)):{},M(r||!a||!a.__esModule?O(e,"default",{value:a,enumerable:!0}):e,a)),k=a=>M(O({},"__esModule",{value:!0}),a);var j={};N(j,{BOARD_LINES:()=>w,BOARD_LINE_LENGTH:()=>l,LocalAPI:()=>b,Message:()=>c,MessageWritePosition:()=>A,MultipleBoards:()=>y,ReadWriteAPI:()=>g,SubscriptionAPI:()=>m});module.exports=k(j);var x=L(require("grapheme-splitter"),1);async function d(a,r,e,t={}){let s=e===void 0?"GET":"POST";e!==void 0&&Object.assign(r,{"Content-Type":"application/json"});let n={headers:r,method:s};e!==void 0&&typeof e=="string"?n.body=e:e!==void 0&&(n.body=JSON.stringify(e));let o=null;for(let i=0;i<10&&(o=await(t.fetch||fetch)(a,n),!o.ok);i++)await new Promise(p=>setTimeout(p,1e3));if(!o?.ok)throw new Error("HTTP Request failed");return t.parseResponse===!1?void 0:await o.json()}var g=class{key;options;constructor(r,e){this.key=r,this.options=e||{}}async getCurrentMessage(){let r=await this.request("/");return new c(JSON.parse(r.currentMessage.layout))}async postMessage(r){let e=typeof r=="string"?new c(r):r;await this.request("/",JSON.stringify(e.toCharArray()))}async request(r,e){return d(`https://rw.vestaboard.com${r}`,{"X-Vestaboard-Read-Write-Key":this.key},e,this.options)}};var m=class{key;options;secret;constructor(r,e,t){this.key=r,this.secret=e,this.options=t||{}}async getSubscriptions(){return await this.request("/subscriptions")}async getViewer(){return await this.request("/viewer")}async postMessage(r,e){let t=!1,s=[],n=typeof r=="string"?new c(r):r;if(typeof e=="string")t=!0,s.push(e);else if(Array.isArray(e))s.push(...e);else{let u=await this.getSubscriptions();s.push(...u.subscriptions.map(i=>i._id))}let o=[];for(let u of s)o.push(await this.request(`/subscriptions/${u}/message`,{characters:n.toCharArray()}));return t?o[0]:o}async request(r,e){return d(`https://platform.vestaboard.com${r}`,{"X-Vestaboard-Api-Key":this.key,"X-Vestaboard-Api-Secret":this.secret},e,this.options)}};var l=22,w=6,A=(t=>(t[t.CURRENT=0]="CURRENT",t[t.NO_SPACE_BETWEEN=1]="NO_SPACE_BETWEEN",t[t.NEXT_LINE=2]="NEXT_LINE",t))(A||{});var S=[[" ",[0]],["A",[1]],["a",[1]],["b",[2]],["B",[2]],["C",[3]],["c",[3]],["d",[4]],["e",[5]],["f",[6]],["g",[7]],["h",[8]],["i",[9]],["j",[10]],["k",[11]],["l",[12]],["m",[13]],["n",[14]],["o",[15]],["p",[16]],["q",[17]],["r",[18]],["s",[19]],["t",[20]],["u",[21]],["v",[22]],["w",[23]],["x",[24]],["y",[25]],["z",[26]],["D",[4]],["E",[5]],["F",[6]],["G",[7]],["H",[8]],["I",[9]],["J",[10]],["K",[11]],["L",[12]],["M",[13]],["N",[14]],["O",[15]],["P",[16]],["Q",[17]],["R",[18]],["S",[19]],["T",[20]],["U",[21]],["V",[22]],["W",[23]],["X",[24]],["Y",[25]],["Z",[26]],["1",[27]],["2",[28]],["3",[29]],["4",[30]],["5",[31]],["6",[32]],["7",[33]],["8",[34]],["9",[35]],["0",[36]],["!",[37]],["@",[38]],["#",[39]],["$",[40]],["(",[41]],[")",[42]],["-",[44]],["+",[46]],["&",[47]],["=",[48]],[";",[49]],[":",[50]],["'",[52]],['"',[53]],["%",[54]],[",",[55]],[".",[56]],["/",[59]],["?",[60]],["\xB0",[62]],["\u20AC",[5,21,18]],["\u0192",[6]],["\u017D",[26]],["\u0161",[19]],["\xBC",[27,59,30]],["\xBD",[27,59,28]],["\xBE",[29,59,30]],["\xC0",[1]],["\xC1",[1]],["\xC2",[1]],["\xC3",[1]],["\xC4",[1,5]],["\xC5",[1]],["\xC6",[1,5]],["\xC7",[3]],["\xC8",[5]],["\xC9",[5]],["\xCA",[5]],["\xCB",[5]],["\xCC",[9]],["\xCD",[9]],["\xCE",[9]],["\xCF",[9]],["\xD0",[5,20,8]],["\xD1",[14]],["\xD2",[15]],["\xD3",[15]],["\xD4",[15]],["\xD5",[15]],["\xD6",[15,5]],["\xD7",[24]],["\xD9",[21]],["\xDA",[21]],["\xDB",[21]],["\xDC",[21,5]],["\xDD",[25]],["\xDF",[19,19]],["\xE0",[1]],["\xE1",[1]],["\xE2",[1]],["\xE3",[1]],["\xE4",[1,5]],["\xE5",[1]],["\xE6",[1,5]],["\xE7",[3]],["\xE8",[5]],["\xE9",[5]],["\xEA",[5]],["\xEB",[5]],["\xEC",[9]],["\xED",[9]],["\xEE",[9]],["\xEF",[9]],["\xF0",[15]],["\xF1",[14]],["\xF2",[15]],["\xF3",[15]],["\xF4",[15]],["\xF5",[15]],["\xF6",[15,5]],["\xF9",[21]],["\xFA",[21]],["\xFB",[21]],["\xFC",[21,5]],["\xFD",[25]],["\xFF",[25]],["\u{1F7E5}",[63]],["\u{1F7E7}",[64]],["\u{1F7E8}",[65]],["\u{1F7E9}",[66]],["\u{1F7E6}",[67]],["\u{1F7EA}",[68]],["\u2B1C\uFE0F",[69]],["\u2B1C",[69]],["\u2B1B\uFE0F",[-2]],["\u2B1B",[-2]],["\uFE6B",[38]],["\uFF20",[38]],["0\uFE0F\u20E3",[36]],["1\uFE0F\u20E3",[27]],["2\uFE0F\u20E3",[28]],["3\uFE0F\u20E3",[29]],["4\uFE0F\u20E3",[30]],["5\uFE0F\u20E3",[31]],["6\uFE0F\u20E3",[32]],["7\uFE0F\u20E3",[33]],["8\uFE0F\u20E3",[34]],["9\uFE0F\u20E3",[35]],["\u2755",[37]],["\u203C\uFE0F",[37,37]],["\u2757\uFE0F",[37]],["\u2049\uFE0F",[37,60]],["#\uFE0F\u20E3",[39]],["\u{1F4B2}",[40]],["$",[40]],["\uFE69",[40]],["\uFF04",[40]],["\u2190",[44]],["\u2192",[44]],["\u27A1",[44]],["\u2B05",[44]],["\u2794",[44]],["\u2194",[44]],["\u2013",[44]],["\u2795",[46]],["+",[46]],["\uFE6A",[54]],["\uFF05",[54]],["\u2753",[60]],["\u2754",[60]],["\u2103",[62,3]],["\u2109",[62,6]]],C=new Array(w).fill(new Array(l).fill(0)),c=class a{static splitter=new x.default;get isEmpty(){return!this.board.find(r=>r.find(e=>e!==0))}board;cursor=[0,0];constructor(r){typeof r=="string"&&r?(this.board=JSON.parse(JSON.stringify(C)),this.write(r),this.center()):Array.isArray(r)?this.board=r:this.board=JSON.parse(JSON.stringify(C))}static char2char(r){let e=S.find(([t])=>r===t);return e&&Array.isArray(e[1])?e[1]:[-1]}static charToString(r){let e=Object.values(S).filter(([t])=>t.length<=2).find(([,t])=>t[0]===r);return e?e[0].toUpperCase()+(e[0].length===1?" ":""):"\u26A1\uFE0E "}static getColumnSizesFromData(r,e={}){if(!r.length)return[];let t=r[0].length,s=[];r.forEach((p,h)=>{if(p.length!==t)throw new Error(`Unable to render table: Row ${h} has ${p.length} entries, but first row has ${t}!`);p.forEach((f,R)=>{s[R]=Math.max(s[R]||0,this.string2chars(f,e).length)})});let n=s.reduce((p,h)=>p+h,0),o=r[0].length-1,u=Math.max((l-o)/n,1),i=s.map(p=>Math.round(p*u));for(;;){let p=i.reduce((R,q)=>R+q,0)+o;if(p===l)break;let h=l-p<0?-1:1,f=i.indexOf(h<0?Math.max(...i):Math.min(...i));if(f<0)throw new Error("Unable to find max value in array\u2026");i[f]+=h}return i}static removeEmojisFromChars(r){let e=[];for(let s of r)e.length||e.push([]),s===0?e.push([]):e[e.length-1].push(s);e.forEach(s=>{if(s.length>0&&s[0]===-1)for(;s[0]<0;)s.splice(0,1);if(s.length>0&&s[s.length-1]===-1)for(;s.length>0&&s[s.length-1]<0;)s.splice(s.length-1,1)});let t=[];return e.filter(s=>s.length>0).forEach(s=>{t.length!==0&&t.push(0),t.push(...s)}),t}static splitCharsIntoLines(r,e){let t=[];for(let n of r){t.length||t.push([null,[]]);let o=t[t.length-1];n===0?t.push([0,[]]):n===44?(o[1].push(n),t.push([null,[]])):o[1].push(n)}let s=[];for(let[n,o]of t){s.length||s.push([]);let u=s[s.length-1],i=e[s.length===1?0:1]-u.length;if(!u.length&&o.length<=i)u.push(...o);else if(n!==null&&o.length+1<=i)u.push(0,...o);else if(o.length<=i)u.push(...o);else if(o.length<=e[1])u=[...o],i=e[1],s.push(u);else{i>=3&&!u.length||(i>=4&&u.length?(u.push(0),i--):(u=[],i=e[1],s.push(u)));for(let p of o)u.push(p),i--,i<=1&&(u.push(44),u=[],i=e[1],s.push(u))}}return s}static string2chars(r,e={}){let t=[],s=a.splitter.splitGraphemes(r);for(let n of s)t.push(...this.char2char(n));return e.removeUnsupportedWords!==!1&&(t=a.removeEmojisFromChars(t)),t=t.map(n=>n>=0?n:n===-2?0:typeof e.fallbackChar=="number"?e.fallbackChar:e.fallbackChar===null?-1:60).filter(n=>n>=0),t}center(){let r=[this.board.findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.slice().reverse().findIndex(s=>s!==0):t.length)),this.board.slice().reverse().findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.findIndex(s=>s!==0):t.length))],e=[Math.floor((r[0]+r[2])/2),Math.floor((r[1]+r[3])/2)];if(r[0]!==e[0]){let t=e[0]-r[0];this.board.splice(t>0?0:this.board.length,0,...this.board.splice(t>0?this.board.length-t:0,Math.abs(t)))}if(r[3]!==e[1]){let t=e[1]-r[3];this.board.forEach(s=>{s.splice(t>0?0:s.length,0,...s.splice(t>0?s.length-t:0,Math.abs(t)))})}}fill(r=" "){let e=0,t=a.string2chars(r,{removeUnsupportedWords:!1});return this.board.forEach(s=>{s.forEach((n,o)=>{s[o]=t[e],e++,e>t.length-1&&(e=0)})}),this}table(r){let e=a.getColumnSizesFromData(r);return(this.cursor[0]!==0||this.cursor[1]!==0)&&(this.cursor[0]++,this.cursor[1]=0),r.forEach(t=>{let s=this.cursor[0],n=1;t.forEach((o,u)=>{let i=e[u],p=e.filter((h,f)=>f<u).reduce((h,f)=>h+f+1,0);this.write(o,{indent:p,position:{line:s,row:p,width:i}}),n=Math.max(n,this.cursor[0]-s+1)}),this.cursor[0]=s+n+1,this.cursor[1]=0}),this}toCharArray(){return JSON.parse(JSON.stringify(this.board))}toString(){return"#="+"=".repeat(l*2)+`=#
3
2
  `+this.board.map(r=>"# "+r.map(e=>a.charToString(e)).join("")+` #
4
3
  `).join("")+"#="+"=".repeat(l*2)+`=#
5
- `}toCharArray(){return JSON.parse(JSON.stringify(this.board))}};var b=class{key;host;options;constructor(r,e,t){this.key=r,this.host=e||"vestaboard.local",this.options=t||{}}async request(r,e,t={}){return d(`http://${this.host}:7000/local-api/message`,{"X-Vestaboard-Local-Api-Key":this.key},e,Object.assign({},this.options,t))}async getCurrentMessage(){let r=await this.request("/");return new c(Array.isArray(r)?r:r.message)}async postMessage(r){let e=typeof r=="string"?new c(r):r;await this.request("/",JSON.stringify(e.toCharArray()),{parseResponse:!1})}};var y=class{boards;constructor(r=[]){this.boards=r}push(...r){r.forEach(e=>this.boards.push(e))}async postMessage(r){for(let e of this.boards)await e.postMessage(r)}};0&&(module.exports={BOARD_LINES,BOARD_LINE_LENGTH,LocalAPI,Message,MessageWritePosition,MultipleBoards,ReadWriteAPI,SubscriptionAPI});
4
+ `}write(r,e={}){if(!this.board[this.cursor[0]])return this;e.position===2&&(this.cursor[0]!==0||this.cursor[1]!==0)?(this.cursor[0]++,this.cursor[1]=0):typeof e.position=="object"&&(this.cursor[0]=e.position.line,this.cursor[1]=e.position.row||0),(e.position===void 0||e.position===0)&&this.cursor[1]!==0&&this.cursor[1]<l-1&&(this.board[this.cursor[0]].splice(this.cursor[1],1,0),this.cursor[1]+=1);let t=0;e.indent===!0?t=this.cursor[1]:typeof e.indent=="number"&&e.indent>=0&&e.indent<=l-5&&(t=e.indent);let s=r.split(`
5
+ `),n=!0;for(let o of s){let u=a.string2chars(o,e),i=[l-this.cursor[1],l-t];n||(this.cursor[0]++,this.cursor[1]=t),typeof e.position=="object"&&e.position.width&&(i[0]=Math.min(i[0],e.position.width),i[1]=Math.min(i[1],e.position.width-t));let p=a.splitCharsIntoLines(u,i);for(let h of p){if(!this.board[this.cursor[0]])break;this.board[this.cursor[0]].splice(this.cursor[1],h.length,...h),this.cursor[1]+=h.length,h!==p[p.length-1]&&(this.cursor[0]++,this.cursor[1]=t)}n=!1}return this}};var b=class{host;key;options;constructor(r,e,t){this.key=r,this.host=e||"vestaboard.local",this.options=t||{}}async getCurrentMessage(){let r=await this.request("/");return new c(Array.isArray(r)?r:r.message)}async postMessage(r){let e=typeof r=="string"?new c(r):r;await this.request("/",JSON.stringify(e.toCharArray()),{parseResponse:!1})}async request(r,e,t={}){return d(`http://${this.host}:7000/local-api/message`,{"X-Vestaboard-Local-Api-Key":this.key},e,Object.assign({},this.options,t))}};var y=class{boards;constructor(r=[]){this.boards=r}async postMessage(r){for(let e of this.boards)await e.postMessage(r)}push(...r){r.forEach(e=>this.boards.push(e))}};0&&(module.exports={BOARD_LINES,BOARD_LINE_LENGTH,LocalAPI,Message,MessageWritePosition,MultipleBoards,ReadWriteAPI,SubscriptionAPI});
6
6
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/message.ts","../src/tools.ts","../src/subscription-api.ts","../src/read-write-api.ts","../src/types.ts","../src/local-api.ts","../src/multiple-boards.ts"],"sourcesContent":["export { default as LocalAPI } from './local-api.js';\nexport { default as Message } from './message.js';\nexport { default as MultipleBoards } from './multiple-boards.js';\nexport { default as ReadWriteAPI } from './read-write-api.js';\nexport { default as SubscriptionAPI } from './subscription-api.js';\nexport {\n BOARD_LINES,\n BOARD_LINE_LENGTH,\n MessageWritePosition,\n type BoardCharArray,\n type BoardCharLine,\n type Boards,\n type Installation,\n type MessageWriteCoords,\n type MessageWriteOptions,\n type RequestOptions,\n type Subscription,\n type SubscriptionPostResponse,\n type Subscriptions,\n type Viewer,\n} from './types.js';\n","import GraphemeSplitter from 'grapheme-splitter';\nimport {\n BOARD_LINES,\n BOARD_LINE_LENGTH,\n MessageWritePosition,\n type BoardCharArray,\n type MessageWriteOptions,\n} from './types.js';\n\n\n/**\n * Map with all supported characters plus a few emojis\n * mapped to corresponding characters of the Vestaboard\n */\nexport const CHAR_MAP: Array<[string, number[]]> = [\n [' ', [0]],\n ['A', [1]],\n ['a', [1]],\n ['b', [2]],\n ['B', [2]],\n ['C', [3]],\n ['c', [3]],\n ['d', [4]],\n ['e', [5]],\n ['f', [6]],\n ['g', [7]],\n ['h', [8]],\n ['i', [9]],\n ['j', [10]],\n ['k', [11]],\n ['l', [12]],\n ['m', [13]],\n ['n', [14]],\n ['o', [15]],\n ['p', [16]],\n ['q', [17]],\n ['r', [18]],\n ['s', [19]],\n ['t', [20]],\n ['u', [21]],\n ['v', [22]],\n ['w', [23]],\n ['x', [24]],\n ['y', [25]],\n ['z', [26]],\n ['D', [4]],\n ['E', [5]],\n ['F', [6]],\n ['G', [7]],\n ['H', [8]],\n ['I', [9]],\n ['J', [10]],\n ['K', [11]],\n ['L', [12]],\n ['M', [13]],\n ['N', [14]],\n ['O', [15]],\n ['P', [16]],\n ['Q', [17]],\n ['R', [18]],\n ['S', [19]],\n ['T', [20]],\n ['U', [21]],\n ['V', [22]],\n ['W', [23]],\n ['X', [24]],\n ['Y', [25]],\n ['Z', [26]],\n ['1', [27]],\n ['2', [28]],\n ['3', [29]],\n ['4', [30]],\n ['5', [31]],\n ['6', [32]],\n ['7', [33]],\n ['8', [34]],\n ['9', [35]],\n ['0', [36]],\n ['!', [37]],\n ['@', [38]],\n ['#', [39]],\n ['$', [40]],\n ['(', [41]],\n [')', [42]],\n ['-', [44]],\n ['+', [46]],\n ['&', [47]],\n ['=', [48]],\n [';', [49]],\n [':', [50]],\n ['\\'', [52]],\n ['\"', [53]],\n ['%', [54]],\n [',', [55]],\n ['.', [56]],\n ['/', [59]],\n ['?', [60]],\n ['°', [62]],\n ['€', [5, 21, 18]],\n ['ƒ', [6]],\n ['Ž', [26]],\n ['š', [19]],\n ['¼', [27, 59, 30]],\n ['½', [27, 59, 28]],\n ['¾', [29, 59, 30]],\n ['À', [1]],\n ['Á', [1]],\n ['Â', [1]],\n ['Ã', [1]],\n ['Ä', [1, 5]],\n ['Å', [1]],\n ['Æ', [1, 5]],\n ['Ç', [3]],\n ['È', [5]],\n ['É', [5]],\n ['Ê', [5]],\n ['Ë', [5]],\n ['Ì', [9]],\n ['Í', [9]],\n ['Î', [9]],\n ['Ï', [9]],\n ['Ð', [5, 20, 8]],\n ['Ñ', [14]],\n ['Ò', [15]],\n ['Ó', [15]],\n ['Ô', [15]],\n ['Õ', [15]],\n ['Ö', [15, 5]],\n ['×', [24]],\n ['Ù', [21]],\n ['Ú', [21]],\n ['Û', [21]],\n ['Ü', [21, 5]],\n ['Ý', [25]],\n ['ß', [19, 19]],\n ['à', [1]],\n ['á', [1]],\n ['â', [1]],\n ['ã', [1]],\n ['ä', [1, 5]],\n ['å', [1]],\n ['æ', [1, 5]],\n ['ç', [3]],\n ['è', [5]],\n ['é', [5]],\n ['ê', [5]],\n ['ë', [5]],\n ['ì', [9]],\n ['í', [9]],\n ['î', [9]],\n ['ï', [9]],\n ['ð', [15]],\n ['ñ', [14]],\n ['ò', [15]],\n ['ó', [15]],\n ['ô', [15]],\n ['õ', [15]],\n ['ö', [15, 5]],\n ['ù', [21]],\n ['ú', [21]],\n ['û', [21]],\n ['ü', [21, 5]],\n ['ý', [25]],\n ['ÿ', [25]],\n ['🟥', [63]],\n ['🟧', [64]],\n ['🟨', [65]],\n ['🟩', [66]],\n ['🟦', [67]],\n ['🟪', [68]],\n ['⬜️', [69]],\n ['⬜', [69]],\n ['⬛️', [-2]],\n ['⬛', [-2]],\n ['﹫', [38]],\n ['@', [38]],\n ['0️⃣', [36]],\n ['1️⃣', [27]],\n ['2️⃣', [28]],\n ['3️⃣', [29]],\n ['4️⃣', [30]],\n ['5️⃣', [31]],\n ['6️⃣', [32]],\n ['7️⃣', [33]],\n ['8️⃣', [34]],\n ['9️⃣', [35]],\n ['❕', [37]],\n ['‼️', [37, 37]],\n ['❗️', [37]],\n ['⁉️', [37, 60]],\n ['#️⃣', [39]],\n ['💲', [40]],\n ['$', [40]],\n ['﹩', [40]],\n ['$', [40]],\n ['←', [44]],\n ['→', [44]],\n ['➡', [44]],\n ['⬅', [44]],\n ['➔', [44]],\n ['↔', [44]],\n ['–', [44]],\n ['➕', [46]],\n ['+', [46]],\n ['﹪', [54]],\n ['%', [54]],\n ['❓', [60]],\n ['❔', [60]],\n ['℃', [62, 3]],\n ['℉', [62, 6]]\n];\n\nconst EMPTY_BOARD: BoardCharArray = new Array(BOARD_LINES).fill(\n new Array(BOARD_LINE_LENGTH).fill(0)\n) as BoardCharArray;\n\n/**\n * You can build a message like this:\n *\n * ```javascript\n * import { Message } from '@sebbo2002/vestaboard';\n *\n * const myMessage = new Message('Hello World');\n *\n * // same as\n *\n * const myOtherMessage = new Message()\n * .write('Hello World')\n * .center();\n * ```\n */\nexport default class Message {\n private static readonly splitter = new GraphemeSplitter();\n private readonly board: BoardCharArray;\n private cursor = [0, 0];\n\n constructor (message?: BoardCharArray | string) {\n if(typeof message === 'string' && message) {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n this.write(message);\n this.center();\n }\n else if(Array.isArray(message)) {\n this.board = message;\n }\n else {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n }\n }\n\n static string2chars (word: string, options: MessageWriteOptions = {}): number[] {\n let chars: number[] = [];\n const singleCharStrings = Message.splitter.splitGraphemes(word);\n for (const char of singleCharStrings) {\n chars.push(...this.char2char(char));\n }\n\n // trim emoji words if not disabled\n if (options.removeUnsupportedWords !== false) {\n chars = Message.removeEmojisFromChars(chars);\n }\n\n // replace -1 with fallback char\n chars = chars.map(char => {\n if (char >= 0) {\n return char;\n } else if (char === -2) {\n return 0;\n } else if (typeof options.fallbackChar === 'number') {\n return options.fallbackChar;\n } else if (options.fallbackChar === null) {\n return -1;\n } else {\n return 60;\n }\n }).filter(char => char >= 0);\n\n return chars;\n }\n\n static char2char (char: string): number[] {\n const fromMap = CHAR_MAP\n .find(([mapChar]) => char === mapChar);\n\n if (fromMap && Array.isArray(fromMap[1])) {\n return fromMap[1];\n }\n\n return [-1];\n }\n\n static charToString (char: number): string {\n const entry = Object.values(CHAR_MAP)\n .filter(([name]) => name.length <= 2)\n .find(([, code]) => code[0] === char);\n\n if (entry) {\n return entry[0].toUpperCase() + (entry[0].length === 1 ? ' ' : '');\n }\n\n return '⚡︎ ';\n }\n\n static splitCharsIntoLines (chars: number[], lineLength: [number, number]): Array<number[]> {\n // Array with splitting char (if any) and chars of the word\n const words: Array<[number | null, number[]]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([null, []]);\n }\n\n const currentWord = words[words.length - 1];\n if (char === 0) {\n words.push([0, []]);\n } else if (char === 44) {\n currentWord[1].push(char);\n words.push([null, []]);\n } else {\n currentWord[1].push(char);\n }\n }\n\n const lines: Array<number[]> = [];\n for (const [separator, word] of words) {\n if (!lines.length) {\n lines.push([]);\n }\n\n let currentLine = lines[lines.length - 1];\n let charsLeft = lineLength[lines.length === 1 ? 0 : 1] - currentLine.length;\n\n // start of line, word fits\n if (!currentLine.length && word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // add separator and the whole word\n else if (separator !== null && word.length + 1 <= charsLeft) {\n currentLine.push(0, ...word);\n } else if (word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // no space for the word, write into next line\n else if (word.length <= lineLength[1]) {\n currentLine = [...word];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n // word too long for one line, start in\n // current line and continue in next line\n else {\n if (charsLeft >= 3 && !currentLine.length) {\n // No space required in front of long word\n } else if (charsLeft >= 4 && currentLine.length) {\n // Add space for next word\n currentLine.push(0);\n charsLeft--;\n } else {\n // No enough space for word, go to next line\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n for (const char of word) {\n currentLine.push(char);\n charsLeft--;\n\n if (charsLeft <= 1) {\n currentLine.push(44);\n\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n }\n }\n }\n\n return lines;\n }\n\n static removeEmojisFromChars (chars: number[]): number[] {\n const words: Array<number[]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([]);\n }\n\n if (char === 0) {\n words.push([]);\n } else {\n words[words.length - 1].push(char);\n }\n }\n\n words.forEach(chars => {\n if (chars.length > 0 && chars[0] === -1) {\n while (chars[0] < 0) {\n chars.splice(0, 1);\n }\n }\n if (chars.length > 0 && chars[chars.length - 1] === -1) {\n while (chars.length > 0 && chars[chars.length - 1] < 0) {\n chars.splice(chars.length - 1, 1);\n }\n }\n });\n\n const result: number[] = [];\n words\n .filter(chars => chars.length > 0)\n .forEach(chars => {\n if (result.length !== 0) {\n result.push(0);\n }\n\n result.push(...chars);\n });\n\n return result;\n }\n\n static getColumnSizesFromData (rows: Array<string[]>, options: MessageWriteOptions = {}): number[] {\n if (!rows.length) {\n return [];\n }\n\n const columns = rows[0].length;\n const columnDefaultSizes: number[] = [];\n rows.forEach((row, rowIndex) => {\n if (row.length !== columns) {\n throw new Error(`Unable to render table: Row ${rowIndex} has ${row.length} entries, but first row has ${columns}!`);\n }\n row.forEach((column, columnIndex) => {\n columnDefaultSizes[columnIndex] = Math.max(columnDefaultSizes[columnIndex] || 0, this.string2chars(column, options).length);\n });\n });\n\n const columnDefaultSum = columnDefaultSizes.reduce((a, b) => a + b, 0);\n const columnBorders = rows[0].length - 1;\n const factor = Math.max((BOARD_LINE_LENGTH - columnBorders) / columnDefaultSum, 1);\n const columnSizes = columnDefaultSizes.map(size => Math.round(size * factor));\n\n while (true) {\n const size = columnSizes.reduce((a, b) => a + b, 0) + columnBorders;\n if (size === BOARD_LINE_LENGTH) {\n break;\n }\n\n const diff = BOARD_LINE_LENGTH - size < 0 ? -1 : 1;\n const index = columnSizes.indexOf(diff < 0 ? Math.max(...columnSizes) : Math.min(...columnSizes));\n if(index < 0) {\n // This can actually never be achieved...\n throw new Error('Unable to find max value in array…');\n }\n\n columnSizes[index] += diff;\n }\n\n\n return columnSizes;\n }\n\n get isEmpty (): boolean {\n return !this.board.find(line =>\n line.find(char => char !== 0)\n );\n }\n\n /**\n * Fills the board with the passed character or text. The text\n * is repeated again and again until the board is completely filled.\n */\n fill (text = ' '): this {\n let pointer = 0;\n const chars = Message.string2chars(text, {removeUnsupportedWords: false});\n this.board.forEach((line) => {\n line.forEach((char, charIndex) => {\n line[charIndex] = chars[pointer];\n pointer++;\n\n if(pointer > chars.length - 1) {\n pointer = 0;\n }\n });\n });\n return this;\n }\n\n /**\n * Write a text on your new message. If your message is not empty it will continue\n * where you last left off (`position: MessageWritePosition.CURRENT`). Alternatively\n * you can continue on the next line or give an exact position.\n *\n * @param text\n * @param options\n */\n write (text: string, options: MessageWriteOptions = {}): this {\n\n // Cursor blow board length? Just return…\n if (!this.board[this.cursor[0]]) {\n return this;\n }\n\n // Add new line if NEXT_LINE is set (except it's already in the first line)\n if (options.position === MessageWritePosition.NEXT_LINE && (this.cursor[0] !== 0 || this.cursor[1] !== 0)) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n // Set cursor to given position\n else if (typeof options.position === 'object') {\n this.cursor[0] = options.position.line;\n this.cursor[1] = options.position.row || 0;\n }\n\n // Add space before text as it\n // will be rendered in the same line\n if (\n (options.position === undefined || options.position === MessageWritePosition.CURRENT) &&\n this.cursor[1] !== 0 && this.cursor[1] < BOARD_LINE_LENGTH - 1\n ) {\n this.board[this.cursor[0]].splice(this.cursor[1], 1, 0);\n this.cursor[1] += 1;\n }\n\n // Figure out left indent\n let indent = 0;\n if (options.indent === true) {\n indent = this.cursor[1];\n } else if (typeof options.indent === 'number' && options.indent >= 0 && options.indent <= BOARD_LINE_LENGTH - 5) {\n indent = options.indent;\n }\n\n const linesOfText = text.split('\\n');\n let isFirstLine = true;\n for (const lineOfText of linesOfText) {\n const chars = Message.string2chars(lineOfText, options);\n const charsLeftInLine: [number, number] = [\n BOARD_LINE_LENGTH - this.cursor[1],\n BOARD_LINE_LENGTH - indent\n ];\n\n if(!isFirstLine) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n\n if(typeof options.position === 'object' && options.position.width) {\n charsLeftInLine[0] = Math.min(charsLeftInLine[0], options.position.width);\n charsLeftInLine[1] = Math.min(charsLeftInLine[1], options.position.width - indent);\n }\n\n const linesOfChars = Message.splitCharsIntoLines(chars, charsLeftInLine);\n for (const chars of linesOfChars) {\n\n // Board is over, skip line…\n if (!this.board[this.cursor[0]]) {\n break;\n }\n\n // Add chars to current line and update cursor\n this.board[this.cursor[0]].splice(this.cursor[1], chars.length, ...chars);\n this.cursor[1] += chars.length;\n\n // Add new line (and update cursor),\n // if this wasn't the last line\n if (chars !== linesOfChars[linesOfChars.length - 1]) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n }\n\n isFirstLine = false;\n }\n\n return this;\n }\n\n /**\n * Generate a table with the given data\n *\n * @example new Message().table([\n * ['now', 'Daily'],\n * ['13:00', 'Super Secret Meeting'],\n * ['16:30', 'Awesome Presentation']\n * ])\n *\n * #==============================================#\n * # N O W D A I L Y #\n * # #\n * # 1 3 : 0 0 S U P E R S E C R E T #\n * # M E E T I N G #\n * # #\n * # 1 6 : 3 0 A W E S O M E P R E S E N T - #\n * #==============================================#\n */\n table (rows: Array<string[]>): this {\n const columnWidths = Message.getColumnSizesFromData(rows);\n if (this.cursor[0] !== 0 || this.cursor[1] !== 0) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n rows.forEach(line => {\n const lineStart = this.cursor[0];\n let lineHeight = 1;\n\n line.forEach((column, columnIndex) => {\n const columnWidth = columnWidths[columnIndex];\n const indent = columnWidths\n .filter((width, index) => index < columnIndex)\n .reduce((a, b) => a + b + 1, 0);\n\n this.write(column, {\n position: {\n line: lineStart,\n row: indent,\n width: columnWidth\n },\n indent\n });\n\n lineHeight = Math.max(lineHeight, this.cursor[0] - lineStart + 1);\n });\n\n this.cursor[0] = lineStart + lineHeight + 1;\n this.cursor[1] = 0;\n });\n\n return this;\n }\n\n /**\n * Center the current message content\n */\n center(): void {\n const space = [\n this.board.findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.slice().reverse().findIndex(c => c !== 0) : l.length)),\n this.board.slice().reverse().findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.findIndex(c => c !== 0) : l.length)),\n ];\n\n const padding = [\n Math.floor((space[0] + space[2]) / 2),\n Math.floor((space[1] + space[3]) / 2)\n ];\n\n // Move up/down\n if(space[0] !== padding[0]) {\n const add = padding[0] - space[0];\n this.board.splice(add > 0 ? 0 : this.board.length, 0,\n ...this.board.splice(add > 0 ? this.board.length - add : 0, Math.abs(add))\n );\n }\n\n // Move left/right\n if(space[3] !== padding[1]) {\n const add = padding[1] - space[3];\n this.board.forEach(line => {\n line.splice(add > 0 ? 0 : line.length, 0,\n ...line.splice(add > 0 ? line.length - add : 0, Math.abs(add))\n );\n });\n }\n }\n\n toString (): string {\n return '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n' +\n this.board.map(line => '# ' + line.map(char =>\n Message.charToString(char)\n ).join('') + ' #\\n').join('') +\n '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n';\n }\n\n toCharArray (): BoardCharArray {\n return JSON.parse(JSON.stringify(this.board));\n }\n}\n","import type { RequestFetchOptions, RequestFetchResponse, RequestOptions } from './types.js';\n\nexport async function request<T> (\n url: string,\n headers: Record<string, string>,\n data?: Record<string, unknown> | string,\n options: RequestOptions = {}\n): Promise<T> {\n const method = data === undefined ? 'GET' : 'POST';\n if (data !== undefined) {\n Object.assign(headers, {\n 'Content-Type': 'application/json'\n });\n }\n\n const init: RequestFetchOptions = {\n method,\n headers\n };\n if(data !== undefined && typeof data === 'string') {\n init.body = data;\n }\n else if(data !== undefined) {\n init.body = JSON.stringify(data);\n }\n\n let response: RequestFetchResponse | null = null;\n for (let i = 0; i < 10; i++) {\n response = await (options.fetch || fetch)(url, init);\n if(response.ok) {\n break;\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n\n if(!response?.ok) {\n throw new Error('HTTP Request failed');\n }\n\n if(options.parseResponse === false) {\n return undefined as unknown as T;\n }\n\n const json = await response.json();\n return json as T;\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { SubscriptionPostResponse, Subscriptions, Viewer } from './types.js';\nimport type { RequestOptions } from './types.js';\n\nexport default class SubscriptionAPI {\n private readonly key: string;\n private readonly secret: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, secret: string, options?: RequestOptions) {\n this.key = key;\n this.secret = secret;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: Record<string, unknown>): Promise<T> {\n return request(`https://platform.vestaboard.com${path}`, {\n 'X-Vestaboard-Api-Key': this.key,\n 'X-Vestaboard-Api-Secret': this.secret\n }, data, this.options);\n }\n\n async getViewer (): Promise<Viewer> {\n return await this.request<Viewer>('/viewer');\n }\n\n async getSubscriptions (): Promise<Subscriptions> {\n return await this.request<Subscriptions>('/subscriptions');\n }\n\n async postMessage (message: Message | string): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionId: string): Promise<SubscriptionPostResponse>;\n async postMessage (message: Message | string, subscriptionIds: string[]): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionIds?: string | string[]) {\n let singleMode = false;\n const ids: string[] = [];\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n\n if (typeof subscriptionIds === 'string') {\n singleMode = true;\n ids.push(subscriptionIds);\n } else if (Array.isArray(subscriptionIds)) {\n ids.push(...subscriptionIds);\n } else {\n const subscriptions = await this.getSubscriptions();\n ids.push(...subscriptions.subscriptions.map(subscription => subscription._id));\n }\n\n const results: SubscriptionPostResponse[] = [];\n for (const id of ids) {\n results.push(\n await this.request<SubscriptionPostResponse>(`/subscriptions/${id}/message`, {\n characters: msgObj.toCharArray()\n })\n );\n }\n if (singleMode) {\n return results[0];\n }\n\n return results;\n }\n}","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { ReadWriteGetMessageResponse, RequestOptions } from './types.js';\n\nexport default class ReadWriteAPI {\n private readonly key: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, options?: RequestOptions) {\n this.key = key;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string): Promise<T> {\n return request(`https://rw.vestaboard.com${path}`, {\n 'X-Vestaboard-Read-Write-Key': this.key\n }, data, this.options);\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<ReadWriteGetMessageResponse>('/');\n return new Message(JSON.parse(response.currentMessage.layout));\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray())\n );\n }\n}\n","import SubscriptionAPI from './subscription-api.js';\nimport ReadWriteAPI from './read-write-api.js';\nimport LocalAPI from './local-api.js';\n\nexport const BOARD_LINE_LENGTH = 22;\nexport const BOARD_LINES = 6;\n\nexport type BoardCharLine = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number\n];\n\nexport type BoardCharArray = [\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine\n];\n\nexport interface MessageWriteCoords {\n line: number;\n row?: number;\n width?: number;\n}\n\nexport enum MessageWritePosition {\n CURRENT,\n NO_SPACE_BETWEEN,\n NEXT_LINE\n}\n\nexport interface MessageWriteOptions {\n position?: MessageWriteCoords | MessageWritePosition;\n indent?: boolean | number;\n fallbackChar?: number | null;\n removeUnsupportedWords?: boolean;\n}\n\nexport interface RequestFetchOptions {\n body?: string;\n headers?: Record<string, string>;\n method?: string;\n}\n\nexport interface RequestFetchResponse {\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n json(): Promise<unknown>;\n}\n\nexport type RequestOptionsFetch = (url: string, init?: RequestFetchOptions) => Promise<RequestFetchResponse>;\n\nexport interface RequestOptions {\n fetch?: RequestOptionsFetch;\n parseResponse?: boolean;\n}\n\nexport interface Installation {\n _id: string;\n installable?: {\n _id: string;\n };\n}\n\nexport interface Viewer {\n type: string;\n _id: string;\n _created: string;\n installation: {\n _id: string;\n };\n}\n\nexport interface Subscription {\n _id: string;\n _created: string;\n installation: Installation;\n boards: Array<{_id: string}>;\n}\n\nexport interface Subscriptions {\n subscriptions: Subscription[];\n}\n\nexport interface SubscriptionPostResponse {\n message: {\n id: string;\n created: number;\n }\n}\n\nexport interface ReadWriteGetMessageResponse {\n currentMessage: {\n layout: string;\n }\n}\n\nexport type Boards = Array<LocalAPI | ReadWriteAPI | SubscriptionAPI>;\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { BoardCharArray, RequestOptions } from './types.js';\n\nexport default class LocalAPI {\n private readonly key: string;\n private readonly host: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, host?: string, options?: RequestOptions) {\n this.key = key;\n this.host = host || 'vestaboard.local';\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string, options: RequestOptions = {}): Promise<T> {\n return request(`http://${this.host}:7000/local-api/message`, {\n 'X-Vestaboard-Local-Api-Key': this.key\n }, data, Object.assign({}, this.options, options));\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<{message: BoardCharArray} | BoardCharArray>('/');\n return new Message(Array.isArray(response) ? response : response.message);\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray()),\n { parseResponse: false }\n );\n }\n}\n","import { type Boards } from './types.js';\nimport Message from './message.js';\n\nexport default class MultipleBoards {\n private readonly boards: Boards;\n\n constructor (boards: Boards = []) {\n this.boards = boards;\n }\n\n push(...boards: Boards): void {\n boards.forEach(board => this.boards.push(board));\n }\n\n async postMessage (message: Message | string): Promise<void> {\n for(const board of this.boards) {\n await board.postMessage(message);\n }\n }\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,EAAA,sBAAAC,EAAA,aAAAC,EAAA,YAAAC,EAAA,yBAAAC,EAAA,mBAAAC,EAAA,iBAAAC,EAAA,oBAAAC,IAAA,eAAAC,EAAAV,GCAA,IAAAW,EAA6B,kCCE7B,eAAsBC,EAClBC,EACAC,EACAC,EACAC,EAA0B,CAAC,EACjB,CACV,IAAMC,EAASF,IAAS,OAAY,MAAQ,OACxCA,IAAS,QACT,OAAO,OAAOD,EAAS,CACnB,eAAgB,kBACpB,CAAC,EAGL,IAAMI,EAA4B,CAC9B,OAAAD,EACA,QAAAH,CACJ,EACGC,IAAS,QAAa,OAAOA,GAAS,SACrCG,EAAK,KAAOH,EAERA,IAAS,SACbG,EAAK,KAAO,KAAK,UAAUH,CAAI,GAGnC,IAAII,EAAwC,KAC5C,QAAS,EAAI,EAAG,EAAI,KAChBA,EAAW,MAAOH,EAAQ,OAAS,OAAOH,EAAKK,CAAI,EAChD,CAAAC,EAAS,IAFQ,IAMpB,MAAM,IAAI,QAAQC,GAAW,WAAWA,EAAS,GAAI,CAAC,EAG1D,GAAG,CAACD,GAAU,GACV,MAAM,IAAI,MAAM,qBAAqB,EAGzC,OAAGH,EAAQ,gBAAkB,GACzB,OAGS,MAAMG,EAAS,KAAK,CAErC,CCzCA,IAAqBE,EAArB,KAAqC,CAChB,IACA,OACA,QAEjB,YAAaC,EAAaC,EAAgBC,EAA0B,CAChE,KAAK,IAAMF,EACX,KAAK,OAASC,EACd,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAA4C,CAChF,OAAOC,EAAQ,kCAAkCF,CAAI,GAAI,CACrD,uBAAwB,KAAK,IAC7B,0BAA2B,KAAK,MACpC,EAAGC,EAAM,KAAK,OAAO,CACzB,CAEA,MAAM,WAA8B,CAChC,OAAO,MAAM,KAAK,QAAgB,SAAS,CAC/C,CAEA,MAAM,kBAA4C,CAC9C,OAAO,MAAM,KAAK,QAAuB,gBAAgB,CAC7D,CAKA,MAAM,YAAaE,EAA2BC,EAAqC,CAC/E,IAAIC,EAAa,GACXC,EAAgB,CAAC,EACjBC,EAAS,OAAOJ,GAAY,SAAW,IAAIK,EAAQL,CAAO,EAAIA,EAEpE,GAAI,OAAOC,GAAoB,SAC3BC,EAAa,GACbC,EAAI,KAAKF,CAAe,UACjB,MAAM,QAAQA,CAAe,EACpCE,EAAI,KAAK,GAAGF,CAAe,MACxB,CACH,IAAMK,EAAgB,MAAM,KAAK,iBAAiB,EAClDH,EAAI,KAAK,GAAGG,EAAc,cAAc,IAAIC,GAAgBA,EAAa,GAAG,CAAC,CACjF,CAEA,IAAMC,EAAsC,CAAC,EAC7C,QAAWC,KAAMN,EACbK,EAAQ,KACJ,MAAM,KAAK,QAAkC,kBAAkBC,CAAE,WAAY,CACzE,WAAYL,EAAO,YAAY,CACnC,CAAC,CACL,EAEJ,OAAIF,EACOM,EAAQ,CAAC,EAGbA,CACX,CACJ,EC3DA,IAAqBE,EAArB,KAAkC,CACb,IACA,QAEjB,YAAaC,EAAaC,EAA0B,CAChD,KAAK,IAAMD,EACX,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAA2B,CAC/D,OAAOC,EAAQ,4BAA4BF,CAAI,GAAI,CAC/C,8BAA+B,KAAK,GACxC,EAAGC,EAAM,KAAK,OAAO,CACzB,CAEA,MAAM,mBAAuC,CACzC,IAAME,EAAW,MAAM,KAAK,QAAqC,GAAG,EACpE,OAAO,IAAIC,EAAQ,KAAK,MAAMD,EAAS,eAAe,MAAM,CAAC,CACjE,CAEA,MAAM,YAAaE,EAA2B,CAC1C,IAAMC,EAAS,OAAOD,GAAY,SAAW,IAAID,EAAQC,CAAO,EAAIA,EACpE,MAAM,KAAK,QAAc,IACrB,KAAK,UAAUC,EAAO,YAAY,CAAC,CACvC,CACJ,CACJ,EC1BO,IAAMC,EAAoB,GACpBC,EAAc,EA0CfC,OACRA,IAAA,qBACAA,IAAA,uCACAA,IAAA,yBAHQA,OAAA,IJjCL,IAAMC,EAAsC,CAC/C,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE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","names":["index_exports","__export","BOARD_LINES","BOARD_LINE_LENGTH","LocalAPI","Message","MessageWritePosition","MultipleBoards","ReadWriteAPI","SubscriptionAPI","__toCommonJS","import_grapheme_splitter","request","url","headers","data","options","method","init","response","resolve","SubscriptionAPI","key","secret","options","path","data","request","message","subscriptionIds","singleMode","ids","msgObj","Message","subscriptions","subscription","results","id","ReadWriteAPI","key","options","path","data","request","response","Message","message","msgObj","BOARD_LINE_LENGTH","BOARD_LINES","MessageWritePosition","CHAR_MAP","EMPTY_BOARD","BOARD_LINES","BOARD_LINE_LENGTH","Message","_Message","GraphemeSplitter","message","word","options","chars","singleCharStrings","char","fromMap","mapChar","entry","name","code","lineLength","words","currentWord","lines","separator","currentLine","charsLeft","result","rows","columns","columnDefaultSizes","row","rowIndex","column","columnIndex","columnDefaultSum","a","b","columnBorders","factor","columnSizes","size","diff","index","line","text","pointer","charIndex","indent","linesOfText","isFirstLine","lineOfText","charsLeftInLine","linesOfChars","columnWidths","lineStart","lineHeight","columnWidth","width","space","l","c","padding","add","LocalAPI","key","host","options","path","data","request","response","Message","message","msgObj","MultipleBoards","boards","board","message"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/message.ts","../src/tools.ts","../src/read-write-api.ts","../src/subscription-api.ts","../src/types.ts","../src/local-api.ts","../src/multiple-boards.ts"],"sourcesContent":["export { default as LocalAPI } from './local-api.js';\nexport { default as Message } from './message.js';\nexport { default as MultipleBoards } from './multiple-boards.js';\nexport { default as ReadWriteAPI } from './read-write-api.js';\nexport { default as SubscriptionAPI } from './subscription-api.js';\nexport {\n BOARD_LINE_LENGTH,\n BOARD_LINES,\n type BoardCharArray,\n type BoardCharLine,\n type Boards,\n type Installation,\n type MessageWriteCoords,\n type MessageWriteOptions,\n MessageWritePosition,\n type RequestOptions,\n type Subscription,\n type SubscriptionPostResponse,\n type Subscriptions,\n type Viewer,\n} from './types.js';\n","import GraphemeSplitter from 'grapheme-splitter';\n\nimport {\n BOARD_LINE_LENGTH,\n BOARD_LINES,\n type BoardCharArray,\n type MessageWriteOptions,\n MessageWritePosition,\n} from './types.js';\n\n/**\n * Map with all supported characters plus a few emojis\n * mapped to corresponding characters of the Vestaboard\n */\nexport const CHAR_MAP: Array<[string, number[]]> = [\n [' ', [0]],\n ['A', [1]],\n ['a', [1]],\n ['b', [2]],\n ['B', [2]],\n ['C', [3]],\n ['c', [3]],\n ['d', [4]],\n ['e', [5]],\n ['f', [6]],\n ['g', [7]],\n ['h', [8]],\n ['i', [9]],\n ['j', [10]],\n ['k', [11]],\n ['l', [12]],\n ['m', [13]],\n ['n', [14]],\n ['o', [15]],\n ['p', [16]],\n ['q', [17]],\n ['r', [18]],\n ['s', [19]],\n ['t', [20]],\n ['u', [21]],\n ['v', [22]],\n ['w', [23]],\n ['x', [24]],\n ['y', [25]],\n ['z', [26]],\n ['D', [4]],\n ['E', [5]],\n ['F', [6]],\n ['G', [7]],\n ['H', [8]],\n ['I', [9]],\n ['J', [10]],\n ['K', [11]],\n ['L', [12]],\n ['M', [13]],\n ['N', [14]],\n ['O', [15]],\n ['P', [16]],\n ['Q', [17]],\n ['R', [18]],\n ['S', [19]],\n ['T', [20]],\n ['U', [21]],\n ['V', [22]],\n ['W', [23]],\n ['X', [24]],\n ['Y', [25]],\n ['Z', [26]],\n ['1', [27]],\n ['2', [28]],\n ['3', [29]],\n ['4', [30]],\n ['5', [31]],\n ['6', [32]],\n ['7', [33]],\n ['8', [34]],\n ['9', [35]],\n ['0', [36]],\n ['!', [37]],\n ['@', [38]],\n ['#', [39]],\n ['$', [40]],\n ['(', [41]],\n [')', [42]],\n ['-', [44]],\n ['+', [46]],\n ['&', [47]],\n ['=', [48]],\n [';', [49]],\n [':', [50]],\n [\"'\", [52]],\n ['\"', [53]],\n ['%', [54]],\n [',', [55]],\n ['.', [56]],\n ['/', [59]],\n ['?', [60]],\n ['°', [62]],\n ['€', [5, 21, 18]],\n ['ƒ', [6]],\n ['Ž', [26]],\n ['š', [19]],\n ['¼', [27, 59, 30]],\n ['½', [27, 59, 28]],\n ['¾', [29, 59, 30]],\n ['À', [1]],\n ['Á', [1]],\n ['Â', [1]],\n ['Ã', [1]],\n ['Ä', [1, 5]],\n ['Å', [1]],\n ['Æ', [1, 5]],\n ['Ç', [3]],\n ['È', [5]],\n ['É', [5]],\n ['Ê', [5]],\n ['Ë', [5]],\n ['Ì', [9]],\n ['Í', [9]],\n ['Î', [9]],\n ['Ï', [9]],\n ['Ð', [5, 20, 8]],\n ['Ñ', [14]],\n ['Ò', [15]],\n ['Ó', [15]],\n ['Ô', [15]],\n ['Õ', [15]],\n ['Ö', [15, 5]],\n ['×', [24]],\n ['Ù', [21]],\n ['Ú', [21]],\n ['Û', [21]],\n ['Ü', [21, 5]],\n ['Ý', [25]],\n ['ß', [19, 19]],\n ['à', [1]],\n ['á', [1]],\n ['â', [1]],\n ['ã', [1]],\n ['ä', [1, 5]],\n ['å', [1]],\n ['æ', [1, 5]],\n ['ç', [3]],\n ['è', [5]],\n ['é', [5]],\n ['ê', [5]],\n ['ë', [5]],\n ['ì', [9]],\n ['í', [9]],\n ['î', [9]],\n ['ï', [9]],\n ['ð', [15]],\n ['ñ', [14]],\n ['ò', [15]],\n ['ó', [15]],\n ['ô', [15]],\n ['õ', [15]],\n ['ö', [15, 5]],\n ['ù', [21]],\n ['ú', [21]],\n ['û', [21]],\n ['ü', [21, 5]],\n ['ý', [25]],\n ['ÿ', [25]],\n ['🟥', [63]],\n ['🟧', [64]],\n ['🟨', [65]],\n ['🟩', [66]],\n ['🟦', [67]],\n ['🟪', [68]],\n ['⬜️', [69]],\n ['⬜', [69]],\n ['⬛️', [-2]],\n ['⬛', [-2]],\n ['﹫', [38]],\n ['@', [38]],\n ['0️⃣', [36]],\n ['1️⃣', [27]],\n ['2️⃣', [28]],\n ['3️⃣', [29]],\n ['4️⃣', [30]],\n ['5️⃣', [31]],\n ['6️⃣', [32]],\n ['7️⃣', [33]],\n ['8️⃣', [34]],\n ['9️⃣', [35]],\n ['❕', [37]],\n ['‼️', [37, 37]],\n ['❗️', [37]],\n ['⁉️', [37, 60]],\n ['#️⃣', [39]],\n ['💲', [40]],\n ['$', [40]],\n ['﹩', [40]],\n ['$', [40]],\n ['←', [44]],\n ['→', [44]],\n ['➡', [44]],\n ['⬅', [44]],\n ['➔', [44]],\n ['↔', [44]],\n ['–', [44]],\n ['➕', [46]],\n ['+', [46]],\n ['﹪', [54]],\n ['%', [54]],\n ['❓', [60]],\n ['❔', [60]],\n ['℃', [62, 3]],\n ['℉', [62, 6]],\n];\n\nconst EMPTY_BOARD: BoardCharArray = new Array(BOARD_LINES).fill(\n new Array(BOARD_LINE_LENGTH).fill(0),\n) as BoardCharArray;\n\n/**\n * You can build a message like this:\n *\n * ```javascript\n * import { Message } from '@sebbo2002/vestaboard';\n *\n * const myMessage = new Message('Hello World');\n *\n * // same as\n *\n * const myOtherMessage = new Message()\n * .write('Hello World')\n * .center();\n * ```\n */\nexport default class Message {\n private static readonly splitter = new GraphemeSplitter();\n get isEmpty(): boolean {\n return !this.board.find((line) => line.find((char) => char !== 0));\n }\n private readonly board: BoardCharArray;\n\n private cursor = [0, 0];\n\n constructor(message?: BoardCharArray | string) {\n if (typeof message === 'string' && message) {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n this.write(message);\n this.center();\n } else if (Array.isArray(message)) {\n this.board = message;\n } else {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n }\n }\n\n static char2char(char: string): number[] {\n const fromMap = CHAR_MAP.find(([mapChar]) => char === mapChar);\n\n if (fromMap && Array.isArray(fromMap[1])) {\n return fromMap[1];\n }\n\n return [-1];\n }\n\n static charToString(char: number): string {\n const entry = Object.values(CHAR_MAP)\n .filter(([name]) => name.length <= 2)\n .find(([, code]) => code[0] === char);\n\n if (entry) {\n return entry[0].toUpperCase() + (entry[0].length === 1 ? ' ' : '');\n }\n\n return '⚡︎ ';\n }\n\n static getColumnSizesFromData(\n rows: Array<string[]>,\n options: MessageWriteOptions = {},\n ): number[] {\n if (!rows.length) {\n return [];\n }\n\n const columns = rows[0].length;\n const columnDefaultSizes: number[] = [];\n rows.forEach((row, rowIndex) => {\n if (row.length !== columns) {\n throw new Error(\n `Unable to render table: Row ${rowIndex} has ${row.length} entries, but first row has ${columns}!`,\n );\n }\n row.forEach((column, columnIndex) => {\n columnDefaultSizes[columnIndex] = Math.max(\n columnDefaultSizes[columnIndex] || 0,\n this.string2chars(column, options).length,\n );\n });\n });\n\n const columnDefaultSum = columnDefaultSizes.reduce((a, b) => a + b, 0);\n const columnBorders = rows[0].length - 1;\n const factor = Math.max(\n (BOARD_LINE_LENGTH - columnBorders) / columnDefaultSum,\n 1,\n );\n const columnSizes = columnDefaultSizes.map((size) =>\n Math.round(size * factor),\n );\n\n while (true) {\n const size = columnSizes.reduce((a, b) => a + b, 0) + columnBorders;\n if (size === BOARD_LINE_LENGTH) {\n break;\n }\n\n const diff = BOARD_LINE_LENGTH - size < 0 ? -1 : 1;\n const index = columnSizes.indexOf(\n diff < 0 ? Math.max(...columnSizes) : Math.min(...columnSizes),\n );\n if (index < 0) {\n // This can actually never be achieved...\n throw new Error('Unable to find max value in array…');\n }\n\n columnSizes[index] += diff;\n }\n\n return columnSizes;\n }\n\n static removeEmojisFromChars(chars: number[]): number[] {\n const words: Array<number[]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([]);\n }\n\n if (char === 0) {\n words.push([]);\n } else {\n words[words.length - 1].push(char);\n }\n }\n\n words.forEach((chars) => {\n if (chars.length > 0 && chars[0] === -1) {\n while (chars[0] < 0) {\n chars.splice(0, 1);\n }\n }\n if (chars.length > 0 && chars[chars.length - 1] === -1) {\n while (chars.length > 0 && chars[chars.length - 1] < 0) {\n chars.splice(chars.length - 1, 1);\n }\n }\n });\n\n const result: number[] = [];\n words\n .filter((chars) => chars.length > 0)\n .forEach((chars) => {\n if (result.length !== 0) {\n result.push(0);\n }\n\n result.push(...chars);\n });\n\n return result;\n }\n\n static splitCharsIntoLines(\n chars: number[],\n lineLength: [number, number],\n ): Array<number[]> {\n // Array with splitting char (if any) and chars of the word\n const words: Array<[null | number, number[]]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([null, []]);\n }\n\n const currentWord = words[words.length - 1];\n if (char === 0) {\n words.push([0, []]);\n } else if (char === 44) {\n currentWord[1].push(char);\n words.push([null, []]);\n } else {\n currentWord[1].push(char);\n }\n }\n\n const lines: Array<number[]> = [];\n for (const [separator, word] of words) {\n if (!lines.length) {\n lines.push([]);\n }\n\n let currentLine = lines[lines.length - 1];\n let charsLeft =\n lineLength[lines.length === 1 ? 0 : 1] - currentLine.length;\n\n // start of line, word fits\n if (!currentLine.length && word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // add separator and the whole word\n else if (separator !== null && word.length + 1 <= charsLeft) {\n currentLine.push(0, ...word);\n } else if (word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // no space for the word, write into next line\n else if (word.length <= lineLength[1]) {\n currentLine = [...word];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n // word too long for one line, start in\n // current line and continue in next line\n else {\n if (charsLeft >= 3 && !currentLine.length) {\n // No space required in front of long word\n } else if (charsLeft >= 4 && currentLine.length) {\n // Add space for next word\n currentLine.push(0);\n charsLeft--;\n } else {\n // No enough space for word, go to next line\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n for (const char of word) {\n currentLine.push(char);\n charsLeft--;\n\n if (charsLeft <= 1) {\n currentLine.push(44);\n\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n }\n }\n }\n\n return lines;\n }\n\n static string2chars(\n word: string,\n options: MessageWriteOptions = {},\n ): number[] {\n let chars: number[] = [];\n const singleCharStrings = Message.splitter.splitGraphemes(word);\n for (const char of singleCharStrings) {\n chars.push(...this.char2char(char));\n }\n\n // trim emoji words if not disabled\n if (options.removeUnsupportedWords !== false) {\n chars = Message.removeEmojisFromChars(chars);\n }\n\n // replace -1 with fallback char\n chars = chars\n .map((char) => {\n if (char >= 0) {\n return char;\n } else if (char === -2) {\n return 0;\n } else if (typeof options.fallbackChar === 'number') {\n return options.fallbackChar;\n } else if (options.fallbackChar === null) {\n return -1;\n } else {\n return 60;\n }\n })\n .filter((char) => char >= 0);\n\n return chars;\n }\n\n /**\n * Center the current message content\n */\n center(): void {\n const space = [\n this.board.findIndex((l) => l.find((c) => c !== 0)),\n Math.min(\n ...this.board.map((l) =>\n l.find((c) => c !== 0)\n ? l\n .slice()\n .reverse()\n .findIndex((c) => c !== 0)\n : l.length,\n ),\n ),\n this.board\n .slice()\n .reverse()\n .findIndex((l) => l.find((c) => c !== 0)),\n Math.min(\n ...this.board.map((l) =>\n l.find((c) => c !== 0)\n ? l.findIndex((c) => c !== 0)\n : l.length,\n ),\n ),\n ];\n\n const padding = [\n Math.floor((space[0] + space[2]) / 2),\n Math.floor((space[1] + space[3]) / 2),\n ];\n\n // Move up/down\n if (space[0] !== padding[0]) {\n const add = padding[0] - space[0];\n this.board.splice(\n add > 0 ? 0 : this.board.length,\n 0,\n ...this.board.splice(\n add > 0 ? this.board.length - add : 0,\n Math.abs(add),\n ),\n );\n }\n\n // Move left/right\n if (space[3] !== padding[1]) {\n const add = padding[1] - space[3];\n this.board.forEach((line) => {\n line.splice(\n add > 0 ? 0 : line.length,\n 0,\n ...line.splice(\n add > 0 ? line.length - add : 0,\n Math.abs(add),\n ),\n );\n });\n }\n }\n\n /**\n * Fills the board with the passed character or text. The text\n * is repeated again and again until the board is completely filled.\n */\n fill(text = ' '): this {\n let pointer = 0;\n const chars = Message.string2chars(text, {\n removeUnsupportedWords: false,\n });\n this.board.forEach((line) => {\n line.forEach((char, charIndex) => {\n line[charIndex] = chars[pointer];\n pointer++;\n\n if (pointer > chars.length - 1) {\n pointer = 0;\n }\n });\n });\n return this;\n }\n\n /**\n * Generate a table with the given data\n *\n * @example new Message().table([\n * ['now', 'Daily'],\n * ['13:00', 'Super Secret Meeting'],\n * ['16:30', 'Awesome Presentation']\n * ])\n *\n * #==============================================#\n * # N O W D A I L Y #\n * # #\n * # 1 3 : 0 0 S U P E R S E C R E T #\n * # M E E T I N G #\n * # #\n * # 1 6 : 3 0 A W E S O M E P R E S E N T - #\n * #==============================================#\n */\n table(rows: Array<string[]>): this {\n const columnWidths = Message.getColumnSizesFromData(rows);\n if (this.cursor[0] !== 0 || this.cursor[1] !== 0) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n rows.forEach((line) => {\n const lineStart = this.cursor[0];\n let lineHeight = 1;\n\n line.forEach((column, columnIndex) => {\n const columnWidth = columnWidths[columnIndex];\n const indent = columnWidths\n .filter((width, index) => index < columnIndex)\n .reduce((a, b) => a + b + 1, 0);\n\n this.write(column, {\n indent,\n position: {\n line: lineStart,\n row: indent,\n width: columnWidth,\n },\n });\n\n lineHeight = Math.max(\n lineHeight,\n this.cursor[0] - lineStart + 1,\n );\n });\n\n this.cursor[0] = lineStart + lineHeight + 1;\n this.cursor[1] = 0;\n });\n\n return this;\n }\n\n toCharArray(): BoardCharArray {\n return JSON.parse(JSON.stringify(this.board));\n }\n\n toString(): string {\n return (\n '#=' +\n '='.repeat(BOARD_LINE_LENGTH * 2) +\n '=#\\n' +\n this.board\n .map(\n (line) =>\n '# ' +\n line\n .map((char) => Message.charToString(char))\n .join('') +\n ' #\\n',\n )\n .join('') +\n '#=' +\n '='.repeat(BOARD_LINE_LENGTH * 2) +\n '=#\\n'\n );\n }\n\n /**\n * Write a text on your new message. If your message is not empty it will continue\n * where you last left off (`position: MessageWritePosition.CURRENT`). Alternatively\n * you can continue on the next line or give an exact position.\n *\n * @param text\n * @param options\n */\n write(text: string, options: MessageWriteOptions = {}): this {\n // Cursor blow board length? Just return…\n if (!this.board[this.cursor[0]]) {\n return this;\n }\n\n // Add new line if NEXT_LINE is set (except it's already in the first line)\n if (\n options.position === MessageWritePosition.NEXT_LINE &&\n (this.cursor[0] !== 0 || this.cursor[1] !== 0)\n ) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n // Set cursor to given position\n else if (typeof options.position === 'object') {\n this.cursor[0] = options.position.line;\n this.cursor[1] = options.position.row || 0;\n }\n\n // Add space before text as it\n // will be rendered in the same line\n if (\n (options.position === undefined ||\n options.position === MessageWritePosition.CURRENT) &&\n this.cursor[1] !== 0 &&\n this.cursor[1] < BOARD_LINE_LENGTH - 1\n ) {\n this.board[this.cursor[0]].splice(this.cursor[1], 1, 0);\n this.cursor[1] += 1;\n }\n\n // Figure out left indent\n let indent = 0;\n if (options.indent === true) {\n indent = this.cursor[1];\n } else if (\n typeof options.indent === 'number' &&\n options.indent >= 0 &&\n options.indent <= BOARD_LINE_LENGTH - 5\n ) {\n indent = options.indent;\n }\n\n const linesOfText = text.split('\\n');\n let isFirstLine = true;\n for (const lineOfText of linesOfText) {\n const chars = Message.string2chars(lineOfText, options);\n const charsLeftInLine: [number, number] = [\n BOARD_LINE_LENGTH - this.cursor[1],\n BOARD_LINE_LENGTH - indent,\n ];\n\n if (!isFirstLine) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n\n if (\n typeof options.position === 'object' &&\n options.position.width\n ) {\n charsLeftInLine[0] = Math.min(\n charsLeftInLine[0],\n options.position.width,\n );\n charsLeftInLine[1] = Math.min(\n charsLeftInLine[1],\n options.position.width - indent,\n );\n }\n\n const linesOfChars = Message.splitCharsIntoLines(\n chars,\n charsLeftInLine,\n );\n for (const chars of linesOfChars) {\n // Board is over, skip line…\n if (!this.board[this.cursor[0]]) {\n break;\n }\n\n // Add chars to current line and update cursor\n this.board[this.cursor[0]].splice(\n this.cursor[1],\n chars.length,\n ...chars,\n );\n this.cursor[1] += chars.length;\n\n // Add new line (and update cursor),\n // if this wasn't the last line\n if (chars !== linesOfChars[linesOfChars.length - 1]) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n }\n\n isFirstLine = false;\n }\n\n return this;\n }\n}\n","import type {\n RequestFetchOptions,\n RequestFetchResponse,\n RequestOptions,\n} from './types.js';\n\nexport async function request<T>(\n url: string,\n headers: Record<string, string>,\n data?: Record<string, unknown> | string,\n options: RequestOptions = {},\n): Promise<T> {\n const method = data === undefined ? 'GET' : 'POST';\n if (data !== undefined) {\n Object.assign(headers, {\n 'Content-Type': 'application/json',\n });\n }\n\n const init: RequestFetchOptions = {\n headers,\n method,\n };\n if (data !== undefined && typeof data === 'string') {\n init.body = data;\n } else if (data !== undefined) {\n init.body = JSON.stringify(data);\n }\n\n let response: null | RequestFetchResponse = null;\n for (let i = 0; i < 10; i++) {\n response = await (options.fetch || fetch)(url, init);\n if (response.ok) {\n break;\n }\n\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n\n if (!response?.ok) {\n throw new Error('HTTP Request failed');\n }\n\n if (options.parseResponse === false) {\n return undefined as unknown as T;\n }\n\n const json = await response.json();\n return json as T;\n}\n","import type { ReadWriteGetMessageResponse, RequestOptions } from './types.js';\n\nimport Message from './message.js';\nimport { request } from './tools.js';\n\nexport default class ReadWriteAPI {\n private readonly key: string;\n private readonly options: RequestOptions;\n\n constructor(key: string, options?: RequestOptions) {\n this.key = key;\n this.options = options || {};\n }\n\n async getCurrentMessage(): Promise<Message> {\n const response = await this.request<ReadWriteGetMessageResponse>('/');\n return new Message(JSON.parse(response.currentMessage.layout));\n }\n\n async postMessage(message: Message | string) {\n const msgObj =\n typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/', JSON.stringify(msgObj.toCharArray()));\n }\n\n private async request<T>(path: string, data?: string): Promise<T> {\n return request(\n `https://rw.vestaboard.com${path}`,\n {\n 'X-Vestaboard-Read-Write-Key': this.key,\n },\n data,\n this.options,\n );\n }\n}\n","import type {\n SubscriptionPostResponse,\n Subscriptions,\n Viewer,\n} from './types.js';\nimport type { RequestOptions } from './types.js';\n\nimport Message from './message.js';\nimport { request } from './tools.js';\n\nexport default class SubscriptionAPI {\n private readonly key: string;\n private readonly options: RequestOptions;\n private readonly secret: string;\n\n constructor(key: string, secret: string, options?: RequestOptions) {\n this.key = key;\n this.secret = secret;\n this.options = options || {};\n }\n\n async getSubscriptions(): Promise<Subscriptions> {\n return await this.request<Subscriptions>('/subscriptions');\n }\n\n async getViewer(): Promise<Viewer> {\n return await this.request<Viewer>('/viewer');\n }\n\n async postMessage(\n message: Message | string,\n ): Promise<SubscriptionPostResponse[]>;\n async postMessage(\n message: Message | string,\n subscriptionId: string,\n ): Promise<SubscriptionPostResponse>;\n async postMessage(\n message: Message | string,\n subscriptionIds: string[],\n ): Promise<SubscriptionPostResponse[]>;\n async postMessage(\n message: Message | string,\n subscriptionIds?: string | string[],\n ) {\n let singleMode = false;\n const ids: string[] = [];\n const msgObj =\n typeof message === 'string' ? new Message(message) : message;\n\n if (typeof subscriptionIds === 'string') {\n singleMode = true;\n ids.push(subscriptionIds);\n } else if (Array.isArray(subscriptionIds)) {\n ids.push(...subscriptionIds);\n } else {\n const subscriptions = await this.getSubscriptions();\n ids.push(\n ...subscriptions.subscriptions.map(\n (subscription) => subscription._id,\n ),\n );\n }\n\n const results: SubscriptionPostResponse[] = [];\n for (const id of ids) {\n results.push(\n await this.request<SubscriptionPostResponse>(\n `/subscriptions/${id}/message`,\n {\n characters: msgObj.toCharArray(),\n },\n ),\n );\n }\n if (singleMode) {\n return results[0];\n }\n\n return results;\n }\n private async request<T>(\n path: string,\n data?: Record<string, unknown>,\n ): Promise<T> {\n return request(\n `https://platform.vestaboard.com${path}`,\n {\n 'X-Vestaboard-Api-Key': this.key,\n 'X-Vestaboard-Api-Secret': this.secret,\n },\n data,\n this.options,\n );\n }\n}\n","import LocalAPI from './local-api.js';\nimport ReadWriteAPI from './read-write-api.js';\nimport SubscriptionAPI from './subscription-api.js';\n\nexport const BOARD_LINE_LENGTH = 22;\nexport const BOARD_LINES = 6;\n\nexport enum MessageWritePosition {\n CURRENT,\n NO_SPACE_BETWEEN,\n NEXT_LINE,\n}\n\nexport type BoardCharArray = [\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n];\n\nexport type BoardCharLine = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n];\n\nexport type Boards = Array<LocalAPI | ReadWriteAPI | SubscriptionAPI>;\n\nexport interface Installation {\n _id: string;\n installable?: {\n _id: string;\n };\n}\n\nexport interface MessageWriteCoords {\n line: number;\n row?: number;\n width?: number;\n}\n\nexport interface MessageWriteOptions {\n fallbackChar?: null | number;\n indent?: boolean | number;\n position?: MessageWriteCoords | MessageWritePosition;\n removeUnsupportedWords?: boolean;\n}\n\nexport interface ReadWriteGetMessageResponse {\n currentMessage: {\n layout: string;\n };\n}\n\nexport interface RequestFetchOptions {\n body?: string;\n headers?: Record<string, string>;\n method?: string;\n}\n\nexport interface RequestFetchResponse {\n json(): Promise<unknown>;\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n}\n\nexport interface RequestOptions {\n fetch?: RequestOptionsFetch;\n parseResponse?: boolean;\n}\n\nexport type RequestOptionsFetch = (\n url: string,\n init?: RequestFetchOptions,\n) => Promise<RequestFetchResponse>;\n\nexport interface Subscription {\n _created: string;\n _id: string;\n boards: Array<{ _id: string }>;\n installation: Installation;\n}\n\nexport interface SubscriptionPostResponse {\n message: {\n created: number;\n id: string;\n };\n}\n\nexport interface Subscriptions {\n subscriptions: Subscription[];\n}\n\nexport interface Viewer {\n _created: string;\n _id: string;\n installation: {\n _id: string;\n };\n type: string;\n}\n","import type { BoardCharArray, RequestOptions } from './types.js';\n\nimport Message from './message.js';\nimport { request } from './tools.js';\n\nexport default class LocalAPI {\n private readonly host: string;\n private readonly key: string;\n private readonly options: RequestOptions;\n\n constructor(key: string, host?: string, options?: RequestOptions) {\n this.key = key;\n this.host = host || 'vestaboard.local';\n this.options = options || {};\n }\n\n async getCurrentMessage(): Promise<Message> {\n const response = await this.request<\n BoardCharArray | { message: BoardCharArray }\n >('/');\n return new Message(\n Array.isArray(response) ? response : response.message,\n );\n }\n\n async postMessage(message: Message | string) {\n const msgObj =\n typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/', JSON.stringify(msgObj.toCharArray()), {\n parseResponse: false,\n });\n }\n\n private async request<T>(\n path: string,\n data?: string,\n options: RequestOptions = {},\n ): Promise<T> {\n return request(\n `http://${this.host}:7000/local-api/message`,\n {\n 'X-Vestaboard-Local-Api-Key': this.key,\n },\n data,\n Object.assign({}, this.options, options),\n );\n }\n}\n","import Message from './message.js';\nimport { type Boards } from './types.js';\n\nexport default class MultipleBoards {\n private readonly boards: Boards;\n\n constructor(boards: Boards = []) {\n this.boards = boards;\n }\n\n async postMessage(message: Message | string): Promise<void> {\n for (const board of this.boards) {\n await board.postMessage(message);\n }\n }\n\n push(...boards: Boards): void {\n boards.forEach((board) => this.boards.push(board));\n }\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,EAAA,sBAAAC,EAAA,aAAAC,EAAA,YAAAC,EAAA,yBAAAC,EAAA,mBAAAC,EAAA,iBAAAC,EAAA,oBAAAC,IAAA,eAAAC,EAAAV,GCAA,IAAAW,EAA6B,kCCM7B,eAAsBC,EAClBC,EACAC,EACAC,EACAC,EAA0B,CAAC,EACjB,CACV,IAAMC,EAASF,IAAS,OAAY,MAAQ,OACxCA,IAAS,QACT,OAAO,OAAOD,EAAS,CACnB,eAAgB,kBACpB,CAAC,EAGL,IAAMI,EAA4B,CAC9B,QAAAJ,EACA,OAAAG,CACJ,EACIF,IAAS,QAAa,OAAOA,GAAS,SACtCG,EAAK,KAAOH,EACLA,IAAS,SAChBG,EAAK,KAAO,KAAK,UAAUH,CAAI,GAGnC,IAAII,EAAwC,KAC5C,QAAS,EAAI,EAAG,EAAI,KAChBA,EAAW,MAAOH,EAAQ,OAAS,OAAOH,EAAKK,CAAI,EAC/C,CAAAC,EAAS,IAFO,IAMpB,MAAM,IAAI,QAASC,GAAY,WAAWA,EAAS,GAAI,CAAC,EAG5D,GAAI,CAACD,GAAU,GACX,MAAM,IAAI,MAAM,qBAAqB,EAGzC,OAAIH,EAAQ,gBAAkB,GAC1B,OAGS,MAAMG,EAAS,KAAK,CAErC,CC5CA,IAAqBE,EAArB,KAAkC,CACb,IACA,QAEjB,YAAYC,EAAaC,EAA0B,CAC/C,KAAK,IAAMD,EACX,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAM,mBAAsC,CACxC,IAAMC,EAAW,MAAM,KAAK,QAAqC,GAAG,EACpE,OAAO,IAAIC,EAAQ,KAAK,MAAMD,EAAS,eAAe,MAAM,CAAC,CACjE,CAEA,MAAM,YAAYE,EAA2B,CACzC,IAAMC,EACF,OAAOD,GAAY,SAAW,IAAID,EAAQC,CAAO,EAAIA,EACzD,MAAM,KAAK,QAAc,IAAK,KAAK,UAAUC,EAAO,YAAY,CAAC,CAAC,CACtE,CAEA,MAAc,QAAWC,EAAcC,EAA2B,CAC9D,OAAOC,EACH,4BAA4BF,CAAI,GAChC,CACI,8BAA+B,KAAK,GACxC,EACAC,EACA,KAAK,OACT,CACJ,CACJ,ECzBA,IAAqBE,EAArB,KAAqC,CAChB,IACA,QACA,OAEjB,YAAYC,EAAaC,EAAgBC,EAA0B,CAC/D,KAAK,IAAMF,EACX,KAAK,OAASC,EACd,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAM,kBAA2C,CAC7C,OAAO,MAAM,KAAK,QAAuB,gBAAgB,CAC7D,CAEA,MAAM,WAA6B,CAC/B,OAAO,MAAM,KAAK,QAAgB,SAAS,CAC/C,CAaA,MAAM,YACFC,EACAC,EACF,CACE,IAAIC,EAAa,GACXC,EAAgB,CAAC,EACjBC,EACF,OAAOJ,GAAY,SAAW,IAAIK,EAAQL,CAAO,EAAIA,EAEzD,GAAI,OAAOC,GAAoB,SAC3BC,EAAa,GACbC,EAAI,KAAKF,CAAe,UACjB,MAAM,QAAQA,CAAe,EACpCE,EAAI,KAAK,GAAGF,CAAe,MACxB,CACH,IAAMK,EAAgB,MAAM,KAAK,iBAAiB,EAClDH,EAAI,KACA,GAAGG,EAAc,cAAc,IAC1BC,GAAiBA,EAAa,GACnC,CACJ,CACJ,CAEA,IAAMC,EAAsC,CAAC,EAC7C,QAAWC,KAAMN,EACbK,EAAQ,KACJ,MAAM,KAAK,QACP,kBAAkBC,CAAE,WACpB,CACI,WAAYL,EAAO,YAAY,CACnC,CACJ,CACJ,EAEJ,OAAIF,EACOM,EAAQ,CAAC,EAGbA,CACX,CACA,MAAc,QACVE,EACAC,EACU,CACV,OAAOC,EACH,kCAAkCF,CAAI,GACtC,CACI,uBAAwB,KAAK,IAC7B,0BAA2B,KAAK,MACpC,EACAC,EACA,KAAK,OACT,CACJ,CACJ,EC1FO,IAAME,EAAoB,GACpBC,EAAc,EAEfC,OACRA,IAAA,qBACAA,IAAA,uCACAA,IAAA,yBAHQA,OAAA,IJOL,IAAMC,EAAsC,CAC/C,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EAC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","names":["index_exports","__export","BOARD_LINES","BOARD_LINE_LENGTH","LocalAPI","Message","MessageWritePosition","MultipleBoards","ReadWriteAPI","SubscriptionAPI","__toCommonJS","import_grapheme_splitter","request","url","headers","data","options","method","init","response","resolve","ReadWriteAPI","key","options","response","Message","message","msgObj","path","data","request","SubscriptionAPI","key","secret","options","message","subscriptionIds","singleMode","ids","msgObj","Message","subscriptions","subscription","results","id","path","data","request","BOARD_LINE_LENGTH","BOARD_LINES","MessageWritePosition","CHAR_MAP","EMPTY_BOARD","BOARD_LINES","BOARD_LINE_LENGTH","Message","_Message","GraphemeSplitter","line","char","message","fromMap","mapChar","entry","name","code","rows","options","columns","columnDefaultSizes","row","rowIndex","column","columnIndex","columnDefaultSum","a","b","columnBorders","factor","columnSizes","size","diff","index","chars","words","result","lineLength","currentWord","lines","separator","word","currentLine","charsLeft","singleCharStrings","space","l","c","padding","add","text","pointer","charIndex","columnWidths","lineStart","lineHeight","columnWidth","indent","width","linesOfText","isFirstLine","lineOfText","charsLeftInLine","linesOfChars","LocalAPI","key","host","options","response","Message","message","msgObj","path","data","request","MultipleBoards","boards","message","board"]}