initial commit

This commit is contained in:
2023-07-05 15:22:14 +02:00
commit e339e924dc
38 changed files with 10057 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
.DS_Store
node_modules
/build
.idea
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

2
.npmrc Normal file
View File

@@ -0,0 +1,2 @@
engine-strict=true
resolution-mode=highest

13
.prettierignore Normal file
View File

@@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

9
.prettierrc Normal file
View File

@@ -0,0 +1,9 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]
}

17
.stylelintrc.json Normal file
View File

@@ -0,0 +1,17 @@
{
"extends": [
"stylelint-config-standard-scss",
"stylelint-config-recommended-scss",
"stylelint-config-html/svelte",
"stylelint-config-clean-order",
"stylelint-config-prettier-scss"
],
"rules": {
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["global"]
}
]
}
}

38
README.md Normal file
View File

@@ -0,0 +1,38 @@
# dot i/o V2
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

13
jsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
}

7224
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
package.json Normal file
View File

@@ -0,0 +1,39 @@
{
"name": "cccs",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@theaninova/prettier-config": "^1.0.0",
"@types/w3c-web-serial": "^1.0.3",
"@vite-pwa/sveltekit": "^0.2.5",
"stylelint": "^15.9.0",
"stylelint-config-standard-scss": "^10.0.0",
"stylelint-config-prettier-scss": "^1.0.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recommended-scss": "^12.0.0",
"stylelint-config-clean-order": "^5.0.1",
"@sveltejs/adapter-static": "^2.0.2",
"@sveltejs/kit": "^1.20.4",
"@material/material-color-utilities": "^0.2.7",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1",
"svelte": "^4.0.0",
"svelte-check": "^3.4.3",
"typescript": "^5.0.0",
"vite": "^4.3.6",
"vite-plugin-pwa": "^0.16.4",
"svelte-preprocess": "^5.0.4",
"sass": "^1.63.6"
},
"type": "module",
"prettier": "@theaninova/prettier-config"
}

12
src/app.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}
export {}

12
src/app.html Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -0,0 +1,497 @@
s + Dup,say
y + b,by
y + Dup,why
n + Dup,no
n + f,find
l + f,life
l + p,people
l + s + p,spell
l + n,line
l + n + p,plant
t + h,that
t + n + h,than
t + n + p,plant
t + l + f,left
a + f,after
a + d,add
a + d + f,had
a + h,has
a + s,as
a + s + h,has
a + y + d,day
a + y + s,say
a + n,an
a + n + d,and
a + n + d + f,hand
a + n + h,hand
a + n + y,any
a + l,all
a + l + d,land
a + l + p,plant
a + l + s,last
a + l + y + p,play
a + l + n + d,land
a + t,at
a + t + h,that
a + t + n + h,than
a + t + l + s,last
a + t + l + n + p,plant
- + ?,question
w + h,who
w + s,saw
w + y + h,why
w + t,without
w + t + h,watch
w + t + n,went
w + a,was
w + a + h,what
w + a + s,saw
w + a + y,way
w + a + y + Dup,away
w + a + n,want
w + a + l + f,walk
w + a + l + y,always
w + a + l + y + s,always
w + a + t,watch
w + a + t + h,watch
w + a + t + n,want
g + b,begin
g + Dup,question
g + h,here
g + p,page
g + l + n,long
g + t,get
k + q,quick
k + f,and
k + l + y + q,quickly
k + t + l,talk
k + a + b,back
k + a + s,ask
k + a + t + l,talk
k + w + a + l,walk
m + f,form
m + y,my
m + t + Dup,mountain
m + a + f,family
m + a + s,small
m + a + y,may
m + a + n,man
m + a + n + y,many
m + a + l,almost
m + a + l + s,small
m + a + l + s + Dup,small
c + b,because
c + Dup,sea
c + h,head
c + a + n,can
c + a + n + h,change
c + a + l,call
c + a + l + p,place
c + k + a + b,back
u + p,us
u + y,you
u + j,just
u + j + s,just
u + t + b,but
u + t + p,put
u + t + s + d,study
u + t + n,until
u + t + j + s,just
u + a + l,last
u + k + q,quick
u + k + l + y + q,quickly
u + m + h,much
u + m + n,number
u + m + t + s,must
u + m + c + h,much
u + c + s + h,such
u + c + t,cut
u + c + t + n,country
' + a + s,say
' + a + n,any
' + m + a + n,many
o + Dup,off
o + f,of
o + f + f,food
o + d,do
o + s,so
o + y + b,boy
o + n,on
o + n + s + Dup,soon
o + l,line
o + l + Dup,oil
o + l + d,old
o + l + y,only
o + l + n + y,only
o + t,to
o + t + b,both
o + t + Dup,too
o + t + s,stop
o + t + s + p,stop
o + t + n,not
o + t + n + f,often
o + t + n + d,don't
o + t + n + p,point
o + a + n + h,another
o + a + l,also
o + a + l + s,also
o + w,own
o + w + h,how
o + w + s + h,show
o + w + n,now
o + w + n + d,down
o + w + l + f,follow
o + w + t,two
o + g,go
o + g + Dup,good
o + g + n + s,song
o + g + l + n,long
o + g + t,got
o + g + a + l,along
o + g + a + l + n,along
o + k + b,book
o + k + n,know
o + k + l,look
o + k + t,took
o + k + t + Dup,took
o + k + w + n,know
o + v + a + b,above
o + v + k,move
o + m + s,some
o + m + t + s,most
o + m + a + l,almost
o + m + a + l + s,almost
o + m + a + t + l + s,almost
o + c + f,food
o + c + l + s + h,school
o + u,our
o + u + f,four
o + u + s + h,should
o + u + y,you
o + u + n + f,found
o + u + n + f + f,found
o + u + n + s,sound
o + u + n + s + d,sound
o + u + l + s + d + f,should
o + u + l + s + h,should
o + u + t,out
o + u + a + b,about
o + u + a + t + b,about
o + u + w + l + d,would
o + u + g + n + y,young
o + u + g + t + h,thought
o + u + m + t + n,mountain
o + u + m + t + n + Dup,mountain
o + u + c + l + d,could
o + ' + t + n + d,don't
o + o + l,oil
o + o + t + n,into
o + o + t + n + p,point
o + o + u + w + t + h,without
o + o + u + m + a + t + n,mountain
i + f,if
i + f + f,different
i + d,did
i + RH_Thumb_1_Center,different
i + s,is
i + s + d,side
i + s + h,his
i + n,in
i + n + f + f,find
i + l,list
i + l + n,line
i + t,it
i + t + s + Dup,still
i + t + s + h,this
i + t + n,into
i + t + l + s,list
i + t + l + s + Dup,still
i + a + s,said
i + a + s + d,said
i + a + n,animal
i + w + h,which
i + w + h + Dup,which
i + w + l,will
i + w + l + Dup,will
i + w + l + h,while
i + w + t + h,with
i + g,give
i + g + b,big
i + g + h,high
i + g + n + h,night
i + g + l + h,light
i + g + t + n + h,thing
i + g + t + l + h,light
i + g + a + n,again
i + g + a + n + Dup,again
i + k + n + d,kind
i + k + l,like
i + k + t + n + h,think
i + v + l,live
i + m + h,him
i + m + p,important
i + m + s,miss
i + m + s + Dup,miss
i + m + l,mile
i + m + t,time
i + m + t + h,might
i + m + a + n,animal
i + m + a + n + Dup,animal
i + m + a + l + n,another
i + m + g + t + h,might
i + c + p,picture
i + c + t + y,city
i + u + t + l + n,until
i + u + w + t + h,without
i + u + k + q,quick
i + u + k + l + y + q,quickly
i + u + c + k + q,quick
i + u + c + k + l + y + q,quickly
i + ' + t,it's
i + ' + t + s,it's
e + b,be
e + Dup,earth
e + x,example
e + f + b,before
e + h,he
e + h + Dup,here
e + s,state
e + s + Dup,see
e + s + h,she
e + y + Dup,eye
e + n,name
e + n + b,been
e + n + Dup,need
e + n + d,end
e + l + h,help
e + l + h + f,help
e + l + s + p,spell
e + t,the
e + t + Dup,eat
e + t + f,feet
e + t + h,there
e + t + s,set
e + t + s + h,these
e + t + y + h,they
e + t + n + x,next
e + t + n + h,then
e + t + l,let
e + t + l + Dup,tell
e + t + l + f,left
e + a,at
e + a + f,father
e + a + d + f,head
e + a + h,hear
e + a + p,paper
e + a + s,sea
e + a + y,year
e + a + n,name
e + a + t,eat
e + a + t + s + Dup,state
e + w,we
e + w + f,few
e + w + n,new
e + w + n + h,when
e + w + l,well
e + w + l + Dup,well
e + w + t + b,between
e + w + t + n,went
e + w + t + n + b,between
e + g + h,here
e + g + t,get
e + g + a + p,page
e + g + a + n + b,began
e + k,keep
e + k + p,keep
e + k + t,take
e + k + a + t,take
e + v + y,every
e + v + n,even
e + v + a + h,have
e + v + a + l,leave
e + v + a + l + Dup,leave
e + m,me
e + m + s,seem
e + m + s + Dup,seem
e + m + n,men
e + m + t + h,them
e + m + a,make
e + m + a + d,made
e + m + a + s,same
e + m + a + n,mean
e + m + a + l + p + x,example
e + m + c + a,came
e + c + s,second
e + c + t + n + s,sentence
e + c + a,came
e + c + a + f,face
e + c + a + h,each
e + c + a + l + p,place
e + LH_Thumb_1_Center + a,make
e + u + s,use
e + u + s + q,question
e + u + n + d,under
e + u + t + q,quite
e + u + c + a + s + b,because
e + o + p,open
e + o + s + d,does
e + o + n,one
e + o + n + p,open
e + o + l + b,below
e + o + l + h,hello
e + o + l + h + Dup,hello
e + o + l + p,people
e + o + t + f,often
e + o + t + h,other
e + o + t + s + h,those
e + o + t + n + f,often
e + o + w + l + b,below
e + o + g + t + h,together
e + o + v,over
e + o + v + a + b,above
e + o + v + k,move
e + o + m,move
e + o + m + h,home
e + o + m + s,some
e + o + m + t + s,sometime
e + o + m + t + s + h,something
e + o + m + g + t + n + s + h,something
e + o + m + c,come
e + o + c,come
e + o + c + n,once
e + o + c + n + s + d,second
e + o + c + l + s,close
e + o + u + s + h,house
e + o + u + n,enough
e + o + u + g + n + h,enough
e + i + s + d,side
e + i + l + f,life
e + i + l + n,line
e + i + t + q,quite
e + i + t + l,little
e + i + t + l + Dup,little
e + i + a + d,idea
e + i + w + l + h,while
e + i + w + t + h,white
e + i + g,give
e + i + g + p,give
e + i + g + n + b,begin
e + i + k + l,like
e + i + v + l,live
e + i + m + l,mile
e + i + m + t,time
e + i + u + t + q,quite
e + i + u + u + t + n + s + q,question
r + e + h,her
r + e + t + Dup,tree
r + e + t + h,there
r + e + t + h + Dup,three
r + e + t + l,letter
r + e + a,are
r + e + a + d,read
r + e + a + h,hear
r + e + a + p,paper
r + e + a + n,near
r + e + a + l + y,really
r + e + a + l + y + Dup,really
r + e + a + t + f,after
r + e + a + t + h,earth
r + e + a + t + RH_Thumb_1_Center,father
r + e + a + t + l,learn
r + e + w,were
r + e + w + Dup,were
r + e + w + h,where
r + e + w + a + n + s,answer
r + e + w + a + t,water
r + e + g + h,here
r + e + g + a + l,large
r + e + g + a + t,great
r + e + v + y,very
r + e + v + y + Dup,every
r + e + v + n,never
r + e + u + n + d,under
r + e + u + m + n + b,number
r + e + o + f + b,before
r + e + o + t + h,other
r + e + o + g + t + h,together
r + e + o + v,over
r + e + o + m,more
r + e + o + m + t + h,mother
r + e + i + t + h,their
r + e + i + t + n + f + f,different
r + e + i + v,river
r + e + i + c + l + d + f,children
r + e + i + u + c + t + p,picture
r + f,for
r + h,her
r + y,your
r + n,near
r + l,learn
r + t + Dup,tree
r + t + f,father
r + t + s + Dup,start
r + t + y,try
r + t + l,letter
r + t + l + Dup,letter
r + a,are
r + a + f,far
r + a + d,read
r + a + d + f,hard
r + a + h,hard
r + a + p,part
r + a + l + y,really
r + a + l + y + Dup,really
r + a + t + p,part
r + a + t + s + Dup,start
r + w,were
r + w + h,where
r + w + t,water
r + w + a + n + s,answer
r + g + t,great
r + g + a + l,large
r + v + y,very
r + v + n,never
r + v + l,later
r + m + f,form
r + c + a,car
r + c + a + y,carry
r + c + a + y + Dup,carry
r + u + n,run
r + u + t + h,through
r + u + t + n,turn
r + ' + t + s,story
r + o,or
r + o + f,for
r + o + t + y + s,story
r + o + a + n + h,another
r + o + w,work
r + o + w + d,word
r + o + w + l + d,world
r + o + g,grow
r + o + LeftDoubleClick,grow
r + o + k + w,work
r + o + m,more
r + o + m + f,from
r + o + m + t + h,mother
r + o + u,our
r + o + u + f,four
r + o + u + y,your
r + o + u + a,around
r + o + u + a + n,around
r + o + u + a + n + d,around
r + o + u + g,group
r + o + u + g + p,group
r + o + u + g + t + h,through
r + o + u + c + t + n,country
r + o + u + c + t + n + y,country
r + i + t + h,their
r + i + t + s + f,first
r + i + a,air
r + i + w + t,write
r + i + g + h,right
r + i + g + l,girl
r + i + g + t + h,right
r + i + v,river
r + i + v + Dup,river
r + i + m + t + n + p,important
r + i + c + l + h,children
1 s + Dup say
2 y + b by
3 y + Dup why
4 n + Dup no
5 n + f find
6 l + f life
7 l + p people
8 l + s + p spell
9 l + n line
10 l + n + p plant
11 t + h that
12 t + n + h than
13 t + n + p plant
14 t + l + f left
15 a + f after
16 a + d add
17 a + d + f had
18 a + h has
19 a + s as
20 a + s + h has
21 a + y + d day
22 a + y + s say
23 a + n an
24 a + n + d and
25 a + n + d + f hand
26 a + n + h hand
27 a + n + y any
28 a + l all
29 a + l + d land
30 a + l + p plant
31 a + l + s last
32 a + l + y + p play
33 a + l + n + d land
34 a + t at
35 a + t + h that
36 a + t + n + h than
37 a + t + l + s last
38 a + t + l + n + p plant
39 - + ? question
40 w + h who
41 w + s saw
42 w + y + h why
43 w + t without
44 w + t + h watch
45 w + t + n went
46 w + a was
47 w + a + h what
48 w + a + s saw
49 w + a + y way
50 w + a + y + Dup away
51 w + a + n want
52 w + a + l + f walk
53 w + a + l + y always
54 w + a + l + y + s always
55 w + a + t watch
56 w + a + t + h watch
57 w + a + t + n want
58 g + b begin
59 g + Dup question
60 g + h here
61 g + p page
62 g + l + n long
63 g + t get
64 k + q quick
65 k + f and
66 k + l + y + q quickly
67 k + t + l talk
68 k + a + b back
69 k + a + s ask
70 k + a + t + l talk
71 k + w + a + l walk
72 m + f form
73 m + y my
74 m + t + Dup mountain
75 m + a + f family
76 m + a + s small
77 m + a + y may
78 m + a + n man
79 m + a + n + y many
80 m + a + l almost
81 m + a + l + s small
82 m + a + l + s + Dup small
83 c + b because
84 c + Dup sea
85 c + h head
86 c + a + n can
87 c + a + n + h change
88 c + a + l call
89 c + a + l + p place
90 c + k + a + b back
91 u + p us
92 u + y you
93 u + j just
94 u + j + s just
95 u + t + b but
96 u + t + p put
97 u + t + s + d study
98 u + t + n until
99 u + t + j + s just
100 u + a + l last
101 u + k + q quick
102 u + k + l + y + q quickly
103 u + m + h much
104 u + m + n number
105 u + m + t + s must
106 u + m + c + h much
107 u + c + s + h such
108 u + c + t cut
109 u + c + t + n country
110 ' + a + s say
111 ' + a + n any
112 ' + m + a + n many
113 o + Dup off
114 o + f of
115 o + f + f food
116 o + d do
117 o + s so
118 o + y + b boy
119 o + n on
120 o + n + s + Dup soon
121 o + l line
122 o + l + Dup oil
123 o + l + d old
124 o + l + y only
125 o + l + n + y only
126 o + t to
127 o + t + b both
128 o + t + Dup too
129 o + t + s stop
130 o + t + s + p stop
131 o + t + n not
132 o + t + n + f often
133 o + t + n + d don't
134 o + t + n + p point
135 o + a + n + h another
136 o + a + l also
137 o + a + l + s also
138 o + w own
139 o + w + h how
140 o + w + s + h show
141 o + w + n now
142 o + w + n + d down
143 o + w + l + f follow
144 o + w + t two
145 o + g go
146 o + g + Dup good
147 o + g + n + s song
148 o + g + l + n long
149 o + g + t got
150 o + g + a + l along
151 o + g + a + l + n along
152 o + k + b book
153 o + k + n know
154 o + k + l look
155 o + k + t took
156 o + k + t + Dup took
157 o + k + w + n know
158 o + v + a + b above
159 o + v + k move
160 o + m + s some
161 o + m + t + s most
162 o + m + a + l almost
163 o + m + a + l + s almost
164 o + m + a + t + l + s almost
165 o + c + f food
166 o + c + l + s + h school
167 o + u our
168 o + u + f four
169 o + u + s + h should
170 o + u + y you
171 o + u + n + f found
172 o + u + n + f + f found
173 o + u + n + s sound
174 o + u + n + s + d sound
175 o + u + l + s + d + f should
176 o + u + l + s + h should
177 o + u + t out
178 o + u + a + b about
179 o + u + a + t + b about
180 o + u + w + l + d would
181 o + u + g + n + y young
182 o + u + g + t + h thought
183 o + u + m + t + n mountain
184 o + u + m + t + n + Dup mountain
185 o + u + c + l + d could
186 o + ' + t + n + d don't
187 o + o + l oil
188 o + o + t + n into
189 o + o + t + n + p point
190 o + o + u + w + t + h without
191 o + o + u + m + a + t + n mountain
192 i + f if
193 i + f + f different
194 i + d did
195 i + RH_Thumb_1_Center different
196 i + s is
197 i + s + d side
198 i + s + h his
199 i + n in
200 i + n + f + f find
201 i + l list
202 i + l + n line
203 i + t it
204 i + t + s + Dup still
205 i + t + s + h this
206 i + t + n into
207 i + t + l + s list
208 i + t + l + s + Dup still
209 i + a + s said
210 i + a + s + d said
211 i + a + n animal
212 i + w + h which
213 i + w + h + Dup which
214 i + w + l will
215 i + w + l + Dup will
216 i + w + l + h while
217 i + w + t + h with
218 i + g give
219 i + g + b big
220 i + g + h high
221 i + g + n + h night
222 i + g + l + h light
223 i + g + t + n + h thing
224 i + g + t + l + h light
225 i + g + a + n again
226 i + g + a + n + Dup again
227 i + k + n + d kind
228 i + k + l like
229 i + k + t + n + h think
230 i + v + l live
231 i + m + h him
232 i + m + p important
233 i + m + s miss
234 i + m + s + Dup miss
235 i + m + l mile
236 i + m + t time
237 i + m + t + h might
238 i + m + a + n animal
239 i + m + a + n + Dup animal
240 i + m + a + l + n another
241 i + m + g + t + h might
242 i + c + p picture
243 i + c + t + y city
244 i + u + t + l + n until
245 i + u + w + t + h without
246 i + u + k + q quick
247 i + u + k + l + y + q quickly
248 i + u + c + k + q quick
249 i + u + c + k + l + y + q quickly
250 i + ' + t it's
251 i + ' + t + s it's
252 e + b be
253 e + Dup earth
254 e + x example
255 e + f + b before
256 e + h he
257 e + h + Dup here
258 e + s state
259 e + s + Dup see
260 e + s + h she
261 e + y + Dup eye
262 e + n name
263 e + n + b been
264 e + n + Dup need
265 e + n + d end
266 e + l + h help
267 e + l + h + f help
268 e + l + s + p spell
269 e + t the
270 e + t + Dup eat
271 e + t + f feet
272 e + t + h there
273 e + t + s set
274 e + t + s + h these
275 e + t + y + h they
276 e + t + n + x next
277 e + t + n + h then
278 e + t + l let
279 e + t + l + Dup tell
280 e + t + l + f left
281 e + a at
282 e + a + f father
283 e + a + d + f head
284 e + a + h hear
285 e + a + p paper
286 e + a + s sea
287 e + a + y year
288 e + a + n name
289 e + a + t eat
290 e + a + t + s + Dup state
291 e + w we
292 e + w + f few
293 e + w + n new
294 e + w + n + h when
295 e + w + l well
296 e + w + l + Dup well
297 e + w + t + b between
298 e + w + t + n went
299 e + w + t + n + b between
300 e + g + h here
301 e + g + t get
302 e + g + a + p page
303 e + g + a + n + b began
304 e + k keep
305 e + k + p keep
306 e + k + t take
307 e + k + a + t take
308 e + v + y every
309 e + v + n even
310 e + v + a + h have
311 e + v + a + l leave
312 e + v + a + l + Dup leave
313 e + m me
314 e + m + s seem
315 e + m + s + Dup seem
316 e + m + n men
317 e + m + t + h them
318 e + m + a make
319 e + m + a + d made
320 e + m + a + s same
321 e + m + a + n mean
322 e + m + a + l + p + x example
323 e + m + c + a came
324 e + c + s second
325 e + c + t + n + s sentence
326 e + c + a came
327 e + c + a + f face
328 e + c + a + h each
329 e + c + a + l + p place
330 e + LH_Thumb_1_Center + a make
331 e + u + s use
332 e + u + s + q question
333 e + u + n + d under
334 e + u + t + q quite
335 e + u + c + a + s + b because
336 e + o + p open
337 e + o + s + d does
338 e + o + n one
339 e + o + n + p open
340 e + o + l + b below
341 e + o + l + h hello
342 e + o + l + h + Dup hello
343 e + o + l + p people
344 e + o + t + f often
345 e + o + t + h other
346 e + o + t + s + h those
347 e + o + t + n + f often
348 e + o + w + l + b below
349 e + o + g + t + h together
350 e + o + v over
351 e + o + v + a + b above
352 e + o + v + k move
353 e + o + m move
354 e + o + m + h home
355 e + o + m + s some
356 e + o + m + t + s sometime
357 e + o + m + t + s + h something
358 e + o + m + g + t + n + s + h something
359 e + o + m + c come
360 e + o + c come
361 e + o + c + n once
362 e + o + c + n + s + d second
363 e + o + c + l + s close
364 e + o + u + s + h house
365 e + o + u + n enough
366 e + o + u + g + n + h enough
367 e + i + s + d side
368 e + i + l + f life
369 e + i + l + n line
370 e + i + t + q quite
371 e + i + t + l little
372 e + i + t + l + Dup little
373 e + i + a + d idea
374 e + i + w + l + h while
375 e + i + w + t + h white
376 e + i + g give
377 e + i + g + p give
378 e + i + g + n + b begin
379 e + i + k + l like
380 e + i + v + l live
381 e + i + m + l mile
382 e + i + m + t time
383 e + i + u + t + q quite
384 e + i + u + u + t + n + s + q question
385 r + e + h her
386 r + e + t + Dup tree
387 r + e + t + h there
388 r + e + t + h + Dup three
389 r + e + t + l letter
390 r + e + a are
391 r + e + a + d read
392 r + e + a + h hear
393 r + e + a + p paper
394 r + e + a + n near
395 r + e + a + l + y really
396 r + e + a + l + y + Dup really
397 r + e + a + t + f after
398 r + e + a + t + h earth
399 r + e + a + t + RH_Thumb_1_Center father
400 r + e + a + t + l learn
401 r + e + w were
402 r + e + w + Dup were
403 r + e + w + h where
404 r + e + w + a + n + s answer
405 r + e + w + a + t water
406 r + e + g + h here
407 r + e + g + a + l large
408 r + e + g + a + t great
409 r + e + v + y very
410 r + e + v + y + Dup every
411 r + e + v + n never
412 r + e + u + n + d under
413 r + e + u + m + n + b number
414 r + e + o + f + b before
415 r + e + o + t + h other
416 r + e + o + g + t + h together
417 r + e + o + v over
418 r + e + o + m more
419 r + e + o + m + t + h mother
420 r + e + i + t + h their
421 r + e + i + t + n + f + f different
422 r + e + i + v river
423 r + e + i + c + l + d + f children
424 r + e + i + u + c + t + p picture
425 r + f for
426 r + h her
427 r + y your
428 r + n near
429 r + l learn
430 r + t + Dup tree
431 r + t + f father
432 r + t + s + Dup start
433 r + t + y try
434 r + t + l letter
435 r + t + l + Dup letter
436 r + a are
437 r + a + f far
438 r + a + d read
439 r + a + d + f hard
440 r + a + h hard
441 r + a + p part
442 r + a + l + y really
443 r + a + l + y + Dup really
444 r + a + t + p part
445 r + a + t + s + Dup start
446 r + w were
447 r + w + h where
448 r + w + t water
449 r + w + a + n + s answer
450 r + g + t great
451 r + g + a + l large
452 r + v + y very
453 r + v + n never
454 r + v + l later
455 r + m + f form
456 r + c + a car
457 r + c + a + y carry
458 r + c + a + y + Dup carry
459 r + u + n run
460 r + u + t + h through
461 r + u + t + n turn
462 r + ' + t + s story
463 r + o or
464 r + o + f for
465 r + o + t + y + s story
466 r + o + a + n + h another
467 r + o + w work
468 r + o + w + d word
469 r + o + w + l + d world
470 r + o + g grow
471 r + o + LeftDoubleClick grow
472 r + o + k + w work
473 r + o + m more
474 r + o + m + f from
475 r + o + m + t + h mother
476 r + o + u our
477 r + o + u + f four
478 r + o + u + y your
479 r + o + u + a around
480 r + o + u + a + n around
481 r + o + u + a + n + d around
482 r + o + u + g group
483 r + o + u + g + p group
484 r + o + u + g + t + h through
485 r + o + u + c + t + n country
486 r + o + u + c + t + n + y country
487 r + i + t + h their
488 r + i + t + s + f first
489 r + i + a air
490 r + i + w + t write
491 r + i + g + h right
492 r + i + g + l girl
493 r + i + g + t + h right
494 r + i + v river
495 r + i + v + Dup river
496 r + i + m + t + n + p important
497 r + i + c + l + h children

View File

@@ -0,0 +1,3 @@
{
" ": "␣"
}

View File

@@ -0,0 +1,114 @@
<script>
import {serialPort} from "$lib/serial/connection.js"
import {browser} from "$app/environment"
</script>
<nav>
<h1>dot i/o</h1>
<div class="steps">
<a href="/train/cpm" title="CPM - characters per minute" class="icon train cpm">music_note</a>
<a href="/train/chm" title="ChM - chords mastered" class="icon train chords">piano</a>
<a href="/train/avg-wpm" title="aWPM - average words per minute" class="icon test avg">avg_pace</a>
<a href="/train/stm" title="StM - sentences mastered" class="icon train sentences">lyrics</a>
<a href="/train/top-wpm" title="tWPM - top words per minute" class="icon test top">speed</a>
<a href="/train/cm" title="CM - concepts mastered" class="icon train concepts">cognition</a>
</div>
<div class="actions">
{#if browser && !("serial" in navigator)}
<abbr
title="Your browser does not support serial connections. Try using Chrome instead."
class="icon error"
>
warning
</abbr>
{/if}
<a
href="/device-manager"
title="Device Manager"
class="icon connect"
class:error={$serialPort === undefined}>cable</a
>
<a href="/" title="Statistics" class="icon account">person</a>
</div>
</nav>
<style lang="scss">
nav {
display: flex;
gap: 4px;
align-items: center;
justify-content: space-between;
width: 100%;
}
h1 {
margin-block: 0;
font-size: 1.5rem;
}
.icon {
cursor: pointer;
aspect-ratio: 1;
padding: 4px;
color: inherit;
text-decoration: none;
background: transparent;
border: none;
border-radius: 50%;
&.error {
color: var(--md-sys-color-on-error);
background: var(--md-sys-color-error);
}
&:hover {
color: var(--md-sys-color-on-primary);
background: var(--md-sys-color-primary);
}
}
.steps {
display: flex;
> a.icon {
aspect-ratio: unset;
margin-inline: -4px;
padding-inline: 16px;
font-size: 24px;
color: var(--md-sys-on-surface-variant);
background: var(--md-sys-color-surface-variant);
clip-path: polygon(25% 50%, 0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%);
border-radius: 0;
&:hover {
color: var(--md-sys-color-on-tertiary);
background: var(--md-sys-color-tertiary);
&,
~ * {
translate: 8px 0;
}
}
}
}
.actions {
display: flex;
gap: 8px;
align-items: center;
}
.icon.account {
font-size: 32px;
color: var(--md-sys-color-on-secondary-container);
background: var(--md-sys-color-secondary-container);
}
</style>

View File

@@ -0,0 +1,5 @@
<svg>
<defs />
<circle cx="16" cy="16" r="16" color="black" />
</svg>

After

Width:  |  Height:  |  Size: 75 B

View File

@@ -0,0 +1,158 @@
<script>
import {serialLog, serialPort} from "$lib/serial/connection.js"
import {slide} from "svelte/transition"
/**
* @param event {KeyboardEvent}
*/
function keypress(event) {
if (event.code === "Enter") {
event.preventDefault()
const command = prompt.textContent.trim()
prompt.textContent = ""
$serialPort.send(command)
io.scrollTo({top: io.scrollHeight})
}
}
/** @type {HTMLSpanElement} */
let prompt
/** @type {HTMLDivElement} */
let io
</script>
<div class="terminal" tabindex="0" on:focus={() => prompt.focus()}>
<div bind:this={io} class="io">
{#each $serialLog as { type, value }}
<p class={type} transition:slide>{value}</p>
{/each}
<div class="anchor" />
</div>
<div class="prompt">
<b>$</b><span on:keypress={keypress} bind:this={prompt} contenteditable class="prompt" />
<div class="resize-me" />
</div>
</div>
<style lang="scss">
.terminal {
resize: both;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
width: calc(min(100%, 16.5cm));
height: 8cm;
font-family: "Noto Sans Mono", monospace;
font-size: 0.75rem;
color: var(--md-sys-color-on-secondary);
background: var(--md-sys-color-secondary);
border-radius: 16px;
}
::-webkit-scrollbar {
width: 8px;
background: transparent;
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: var(--md-sys-color-on-secondary);
border-radius: 4px;
}
::-webkit-resizer {
display: none;
}
.io {
overflow-y: auto;
flex: 1;
padding: 12px;
color: var(--md-sys-color-on-secondary-container);
background: var(--md-sys-color-secondary-container);
border-radius: 0 0 16px 16px;
}
:focus-visible {
outline: none;
}
.prompt {
position: relative;
margin: 0.5rem;
}
.resize-me {
position: absolute;
right: -2px;
bottom: 0;
rotate: -45deg;
width: 10px;
height: 5px;
background: var(--md-sys-color-on-secondary);
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.anchor {
overflow-anchor: auto;
height: 1px;
}
p {
overflow-anchor: none;
margin-block: 0.15rem;
}
p.input {
margin-block-end: 0.25rem;
font-weight: bold;
}
p.system {
display: flex;
justify-content: center;
margin-block-end: 1rem;
padding: 0.25rem;
color: var(--md-sys-color-on-secondary);
background: var(--md-sys-color-secondary);
border-radius: 8px;
}
p.input::before {
content: "> ";
font-weight: 900;
color: var(--md-sys-color-primary);
}
::selection {
color: var(--md-sys-color-background);
background: var(--md-sys-color-on-background);
}
@keyframes blink {
100%,
60% {
opacity: 1;
}
40%,
0% {
opacity: 0;
}
}
</style>

View File

@@ -0,0 +1,7 @@
import {writable} from "svelte/store"
/** @type {import('svelte/store').Writable<import('./device.js').CharaDevice>} */
export const serialPort = writable()
/** @type {import('svelte/store').Writable<Array<{type: 'input' | 'output' | 'system'; value: string}>>} */
export const serialLog = writable([])

133
src/lib/serial/device.js Normal file
View File

@@ -0,0 +1,133 @@
import {LineBreakTransformer} from "$lib/serial/webserial/util/line-break-transformer.js"
import {serialLog} from "$lib/serial/connection.js"
export class CharaDevice {
/** @type {Promise<SerialPort>} */
#port
/** @type {Promise<ReadableStreamDefaultReader<string>>} */
#reader
#encoder = new TextEncoder()
#abortController1 = new AbortController()
#abortController2 = new AbortController()
/** @type {Promise<true> | undefined} */
#lock
/** @type {Promise<string>} */
version
/** @type {Promise<string>} */
deviceId
/**
* @param baudRate
*/
constructor(baudRate = 115200) {
this.#port = navigator.serial.getPorts().then(async ports => {
const port = ports.find(it => it.getInfo().usbVendorId === 0x239a)
await port.open({baudRate})
const info = port.getInfo()
serialLog.update(it => {
it.push({
type: "system",
value: `Connected; ID: 0x${info.usbProductId.toString(16)}; Vendor: 0x${info.usbVendorId.toString(
16,
)}`,
})
return it
})
return port
})
this.#reader = this.#port.then(async port => {
const decoderStream = new TextDecoderStream()
void port.readable.pipeTo(decoderStream.writable, {signal: this.#abortController1.signal})
return decoderStream.readable
.pipeThrough(new TransformStream(new LineBreakTransformer()), {signal: this.#abortController2.signal})
.getReader()
})
this.#lock = this.#reader.then(() => {
this.#lock = undefined
return true
})
this.version = this.send("VERSION")
this.deviceId = this.send("ID")
}
/**
* @returns {Promise<string>}
*/
async #read() {
return this.#reader.then(async it => {
const result = await it.read().then(({value}) => value)
serialLog.update(it => {
it.push({
type: "output",
value: result,
})
return it
})
return result
})
}
/**
* Send a command to the device
* @param command {string}
* @returns {Promise<void>}
*/
async #send(...command) {
const port = await this.#port
const writer = port.writable.getWriter()
try {
serialLog.update(it => {
it.push({
type: "input",
value: command.join(" "),
})
return it
})
await writer.write(new TextEncoder().encode(`${command.join(" ")}\r\n`))
} finally {
writer.releaseLock()
}
}
/**
* Read/write to serial port
* @template T
* @param callback {(send: (...commands: string) => Promise<void>, read: () => Promise<string>) => T | Promise<T>}
* @returns Promise<T>
*/
async runWith(callback) {
while (this.#lock) {
await this.#lock
}
const send = this.#send.bind(this)
const read = this.#read.bind(this)
const exec = new Promise(async resolve => {
let result
try {
result = await callback(send, read)
} finally {
this.#lock = undefined
resolve(result)
}
})
this.#lock = exec.then(() => true)
return exec
}
/**
* Send to serial port
* @param command {string}
* @returns Promise<string>
*/
async send(...command) {
return this.runWith(async (send, read) => {
await send(...command)
return read()
})
}
}

132
src/lib/serial/webserial.js Normal file
View File

@@ -0,0 +1,132 @@
import {LineBreakTransformer} from "$lib/serial/webserial/util/line-break-transformer.js"
import {CONFIG_ID} from "$lib/serial/webserial/constants/config-id.js"
let _chordMaps = []
let serialPort = null
let portReader = null
let lineReader = null
let lineReaderDone = null
let abortController1 = new AbortController()
let abortController2 = new AbortController()
async function disconnectSerialConnection() {
console.log("disconnectSerialConnection()")
if (serialPort) {
console.log("closing serial port")
lineReader.releaseLock()
console.log(serialPort.readable)
await abortController1.abort()
await lineReaderDone.catch(() => {
/* Ingore the error */
})
await serialPort.close()
console.log("serial port is closed")
document.getElementById("statusDiv").innerHTML = "status: closed serial port"
} else {
console.log("there is no serial connection open to close")
}
}
//TODO not sure this actually works
async function cancelReader() {
if (serialPort) {
if (lineReader) {
// if(lineReader.locked){
await lineReader.cancel().then(() => {
console.log("cleared line reader")
})
// await serialPort.readable.releaseLock();
console.log(abortController1)
await abortController1.abort()
console.log(serialPort.readable)
await lineReaderDone.catch(() => {
/* Ingore the error */
}) //this frees up the serialPort.readable after the abortControl1.abort() signal
// await serialPort.readable.cancel();
// }
}
}
}
async function resetReader() {
console.log("resetting lineReader")
if (serialPort) {
if (lineReader) {
if (lineReader.locked) {
await lineReader.releaseLock()
}
await lineReader.cancel().then(() => {
console.log("cleared line reader")
})
await lineReaderDone.catch(() => {
/* Ingore the error */
})
}
await setupLineReader()
}
console.log("reset lineReader")
}
async function getCount() {
await sendCommandString("SELECT BASE")
await readGetChordmapCount()
document.getElementById("countDiv").innerHTML = "count: " + _chordmapCountOnDevice
}
async function getGetAll1() {
await selectBase() //select BASE
await sendCommandString("GETALL")
await readGetAllChordmaps()
}
async function getGetAll2() {
await selectBase() //select BASE
await sendCommandString("GETSOME 0 " + _chordmapCountOnDevice)
await readGetSomeChordmaps(_chordmapCountOnDevice)
}
async function getGetAll() {
await selectBase() //select BASE
for (let i = 0; i < _chordmapCountOnDevice; i++) {
await sendCommandString("GETSOME " + (i + 0).toString() + " " + (i + 1).toString())
await readGetOneChordmap()
}
}
let _chordmapId = "DEFAULT"
let _chordmapCountOnDevice = 50 //TODO set this to zero by default
let _firmwareVersion = "0"
async function readGetChordmapCount() {
const {value, done} = await lineReader.read()
if (value) {
_chordmapCountOnDevice = parseInt(value)
console.log(_chordmapCountOnDevice)
}
}
async function readGetAll() {
readGetSomeChordmaps(_chordmapCountOnDevice)
}
function commitAll() {
console.log("commitAll()")
const dataTable = document.getElementById("dataTable")
//iterate through table from bottom to top to see if there's a commit enabled
//TODO check if we need to skip the header row
for (let i = dataTable.rows.length - 1; i >= 1; i--) {
//iterate through rows
let row = dataTable.rows[i]
// console.log(row);
// console.log(row.cells);
// console.log(row.cells[0]);
// console.log(row.cells[0].innerHTML);
let virtualId = parseInt(row.cells[0].innerHTML)
console.log("table row " + i + " has virtualId of " + virtualId)
// document.getElementById(virtualId.toString()+"-commit")
setTimeout(pressCommitButton, i * 100, virtualId)
//rows would be accessed using the "row" variable assigned in the for loop
}
}

View File

@@ -0,0 +1,11 @@
export async function bootLoader() {
//Sends the bootloader command to the charachorder via the serial API
await sendCommandString("BOOTLOADER")
await readGetNone()
}
export async function reboot() {
//Sends the restart command to the charachorder via the serial API
await sendCommandString("RESTART")
await readGetNone()
}

View File

@@ -0,0 +1,638 @@
/**
* 512 'actions'
* phrase is an 'action sequence'
*
* ```js
* let _keys_to_humanreadableoutput_dict = {
* '0x0061':'a',
* '0x0062':'b',
* '0x0063':'c',
* '0x0064':'d',
* '0x0030':'0',
* '0x0031':'1',
* '0x0032':'2',
* '0x013D':'Mouse Left Button Press and Release',
* '0x0149':'Mouse Move Down',
* '0x0151':'Double Click',
* '0x0180':'LeftControl', // E0 in HID Keyboard Table
* '0x0181':'LeftShift',
* '0x0182':'LeftAlt',
* '0x0183':'LeftGUI',
* '0x0189':'F1',
* '0x018A':'F2',
* '0x018B':'F3',
* ```
*
* 64-bit integer as hexadecimal, string of hexadecimal pairs that represent ascii+ value
*
* `"a + f + t"`,
* `27,30,43`
* `00000000000000000000000000100100000000000010000000000000000000`
* `38,655,229,952`
* `0x00000000900080000`
*/
export const _actionMap = [
"NUL", //0x00 0
"CCFunc", //0x01
"STX", //0x02 2
"ETX", //0x03 3
"EOT", //0x04 4
"ENQ", //0x05 5
"ACK", //0x06 6
"BEL", //0x07 7
"BAC", //0x08 8
"Tab", //0x09 9
"ENT", //0x0A 10
"VT", //0x0B 11
"FF", //0x0C 12
"CR", //0x0D 13
"SOH", //0x0E 14
"SI", //0x0F 15
"DLE", //0x10 16
"DC1", //0x11 17
"DC2", //0x12 18
"DC3", //0x13 19
"DC4", //0x14 20
"NAK", //0x15 21
"SYN", //0x16 22
"ETB", //0x17 23
"CAN", //0x18 24
"EM", //0x19 25
"SUB", //0x1A 26
"ESC", //0x1B 27
"FS", //0x1C 28
"GS", //0x1D 29
"RS", //0x1E 30
"US", //0x1F 31
"SPA", //0x20 32
"!", //0x21 33
'"', //0x22 34
"#", //0x23 35
"$", //0x24 36
"%", //0x25 37
"&", //0x26 38
"'", //0x27 39
"(", //0x28 40
")", //0x29 41
"*", //0x2A 42
"+", //0x2B 43
",", //0x2C 44
"-", //0x2D 45
".", //0x2E 46
"/", //0x2F 47
"0", //0x30 48
"1", //0x31 49
"2", //0x32 50
"3", //0x33 51
"4", //0x34 52
"5", //0x35 53
"6", //0x36 54
"7", //0x37 55
"8", //0x38 56
"9", //0x39 57
":", //0x3A 58
";", //0x3B 59
"<", //0x3C 60
"=", //0x3D 61
">", //0x3E 62
"?", //0x3F 63
"@", //0x40 64
"A", //0x41 65
"B", //0x42 66
"C", //0x43 67
"D", //0x44 68
"E", //0x45 69
"F", //0x46 70
"G", //0x47 71
"H", //0x48 72
"I", //0x49 73
"J", //0x4A 74
"K", //0x4B 75
"L", //0x4C 76
"M", //0x4D 77
"N", //0x4E 78
"O", //0x4F 79
"P", //0x50 80
"Q", //0x51 81
"R", //0x52 82
"S", //0x53 83
"T", //0x54 84
"U", //0x55 85
"V", //0x56 86
"W", //0x57 87
"X", //0x58 88
"Y", //0x59 89
"Z", //0x5A 90
"[", //0x5B 91
"\\", //0x5C 92
"]", //0x5D 93
"^", //0x5E 94
"_", //0x5F 95
"`", //0x60 96
"a", //0x61 97
"b", //0x62 98
"c", //0x63 99
"d", //0x64 100
"e", //0x65 101
"f", //0x66 102
"g", //0x67 103
"h", //0x68 104
"i", //0x69 105
"j", //0x6A 106
"k", //0x6B 107
"l", //0x6C 108
"m", //0x6D 109
"n", //0x6E 110
"o", //0x6F 111
"p", //0x70 112
"q", //0x71 113
"r", //0x72 114
"s", //0x73 115
"t", //0x74 116
"u", //0x75 117
"v", //0x76 118
"w", //0x77 119
"x", //0x78 120
"y", //0x79 121
"z", //0x7A 122
"{", //0x7B 123
"|", //0x7C 124
"}", //0x7D 125
"~", //0x7E 126
"DEL", //0x7F 127
"Ç", //0x80 128
"ü", //0x81 129
"é", //0x82 130
"â", //0x83 131
"ä", //0x84 132
"à", //0x85 133
"å", //0x86 134
"ç", //0x87 135
"ê", //0x88 136
"ë", //0x89 137
"è", //0x8A 138
"ï", //0x8B 139
"î", //0x8C 140
"ì", //0x8D 141
"Ä", //0x8E 142
"Å", //0x8F 143
"É", //0x90 144
"æ", //0x91 145
"Æ", //0x92 146
"ô", //0x93 147
"ö", //0x94 148
"ò", //0x95 149
"û", //0x96 150
"ù", //0x97 151
"ÿ", //0x98 152
"Ö", //0x99 153
"Ü", //0x9A 154
"ø", //0x9B 155
"£", //0x9C 156
"Ø", //0x9D 157
"×", //0x9E 158
"ƒ", //0x9F 159
"á", //0xA0 160
"í", //0xA1 161
"ó", //0xA2 162
"ú", //0xA3 163
"ñ", //0xA4 164
"Ñ", //0xA5 165
"ª", //0xA6 166
"º", //0xA7 167
"¿", //0xA8 168
"®", //0xA9 169
"¬", //0xAA 170
"½", //0xAB 171
"¼", //0xAC 172
"¡", //0xAD 173
"«", //0xAE 174
"»", //0xAF 175
"░", //0xB0 176
"▒", //0xB1 177
"▓", //0xB2 178
"│", //0xB3 179
"┤", //0xB4 180
"Á", //0xB5 181
"Â", //0xB6 182
"À", //0xB7 183
"©", //0xB8 184
"╣", //0xB9 185
"║", //0xBA 186
"╗", //0xBB 187
"╝", //0xBC 188
"¢", //0xBD 189
"¥", //0xBE 190
"┐", //0xBF 191
"└", //0xC0 192
"┴", //0xC1 193
"┬", //0xC2 194
"├", //0xC3 195
"─", //0xC4 196
"┼", //0xC5 197
"ã", //0xC6 198
"Ã", //0xC7 199
"╚", //0xC8 200
"╔", //0xC9 201
"╩", //0xCA 202
"╦", //0xCB 203
"╠", //0xCC 204
"═", //0xCD 205
"╬", //0xCE 206
"¤", //0xCF 207
"ð", //0xD0 208
"Ð", //0xD1 209
"Ê", //0xD2 210
"Ë", //0xD3 211
"È", //0xD4 212
"ı", //0xD5 213
"Í", //0xD6 214
"Î", //0xD7 215
"Ï", //0xD8 216
"┘", //0xD9 217
"┌", //0xDA 218
"█", //0xDB 219
"▄", //0xDC 220
"¦", //0xDD 221
"Ì", //0xDE 222
"▀", //0xDF 223
"Ó", //0xE0 224
"ß", //0xE1 225
"Ô", //0xE2 226
"Ò", //0xE3 227
"õ", //0xE4 228
"Õ", //0xE5 229
"µ", //0xE6 230
"þ", //0xE7 231
"Þ", //0xE8 232
"Ú", //0xE9 233
"Û", //0xEA 234
"Ù", //0xEB 235
"ý", //0xEC 236
"Ý", //0xED 237
"¯", //0xEE 238
"´", //0xEF 239
"≡", //0xF0 240
"±", //0xF1 241
"‗", //0xF2 242
"¾", //0xF3 243
"¶", //0xF4 244
"§", //0xF5 245
"÷", //0xF6 246
"¸", //0xF7 247
"°", //0xF8 248
"¨", //0xF9 249
"·", //0xFA 250
"¹", //0xFB 251
"³", //0xFC 252
"²", //0xFD 253
"■", //0xFE 254
"NBSP", //0xFF 255
"Reset", //0x0100 256
"Delay0001ms", //0x0101 257
"Delay0010ms", //0x0102 258
"Delay0100ms", //0x0103 259
"Delay1000ms", //0x0104 260
"0x0105", //0x0105 261
"0x0106", //0x0106 262
"0x0107", //0x0107 263
"0x0108", //0x0108 264
"0x0109", //0x0109 265
"0x010A", //0x010A 266
"0x010B", //0x010B 267
"0x010C", //0x010C 268
"0x010D", //0x010D 269
"0x010E", //0x010E 270
"Impulse", //0x010F 271
"LAT", //0x0110 272
"RAT", //0x0111 273
"LNS", //0x0112 274
"RNS", //0x0113 275
"SpurToggle", //0x0114 276
"Prev", //0x0115 277
"ImpulseToggle", //0x0116 278
"GTM", //0x0117 279
"0x0118", //0x0118 280
"0x0119", //0x0119 281
"0x011A", //0x011A 282
"0x011B", //0x011B 283
"0x011C", //0x011C 284
"0x011D", //0x011D 285
"0x011E", //0x011E 286
"0x011F", //0x011F 287
"0x0120", //0x0120 288
"0x0121", //0x0121 289
"0x0122", //0x0122 290
"0x0123", //0x0123 291
"0x0124", //0x0124 292
"0x0125", //0x0125 293
"0x0126", //0x0126 294
"0x0127", //0x0127 295
"0x0128", //0x0128 296
"0x0129", //0x0129 297
"0x012A", //0x012A 298
"0x012B", //0x012B 299
"0x012C", //0x012C 300
"0x012D", //0x012D 301
"0x012E", //0x012E 302
"0x012F", //0x012F 303
"0x0130", //0x0130 304
"0x0131", //0x0131 305
"0x0132", //0x0132 306
"0x0133", //0x0133 307
"0x0134", //0x0134 308
"0x0135", //0x0135 309
"0x0136", //0x0136 310
"0x0137", //0x0137 311
"0x0138", //0x0138 312
"0x0139", //0x0139 313
"0x013A", //0x013A 314
"0x013B", //0x013B 315
"0x013C", //0x013C 316
"MLB", //0x013D 317
"RMC", //0x013E 318
"MMB", //0x013F 319
"MouseLeftBtnToggle", //0x0140 320
"MouseRightBtnToggle", //0x0141 321
"MouseMiddleBtnToggle", //0x0142 322
"MouseLeftBtnPress", //0x0143 323
"MouseRightBtnPress", //0x0144 324
"MouseMiddleBtnPress", //0x0145 325
"MouseLeftBtnRelease", //0x0146 326
"MouseRightBtnRelease", //0x0147 327
"MouseMiddleBtnRelease", //0x0148 328
"M↓", //0x0149 329
"M→", //0x014A 330
"M↑", //0x014B 331
"M←", //0x014C 332
"MSD", //0x014D 333
"MouseScrollCoastRight", //0x014E 334
"MSU", //0x014F 335
"MouseScrollCoastLeft", //0x0150 336
"LeftDoubleClick", //0x0151 337
"RightDoubleClick", //0x0152 338
"TripleClick", //0x0153 339
"0x0154", //0x0154 340
"0x0155", //0x0155 341
"0x0156", //0x0156 342
"0x0157", //0x0157 343
"0x0158", //0x0158 344
"0x0159", //0x0159 345
"0x015A", //0x015A 346
"0x015B", //0x015B 347
"0x015C", //0x015C 348
"0x015D", //0x015D 349
"0x015E", //0x015E 350
"0x015F", //0x015F 351
"0x0160", //0x0160 352
"0x0161", //0x0161 353
"0x0162", //0x0162 354
"0x0163", //0x0163 355
"0x0164", //0x0164 356
"0x0165", //0x0165 357
"PwrStat", //0x0166 358
"0x0167", //0x0167 359
"0x0168", //0x0168 360
"0x0169", //0x0169 361
"0x016A", //0x016A 362
"0x016B", //0x016B 363
"0x016C", //0x016C 364
"0x016D", //0x016D 365
"0x016E", //0x016E 366
"0x016F", //0x016F 367
"0x0170", //0x0170 368
"0x0171", //0x0171 369
"0x0172", //0x0172 370
"0x0173", //0x0173 371
"0x0174", //0x0174 372
"0x0175", //0x0175 373
"0x0176", //0x0176 374
"0x0177", //0x0177 375
"0x0178", //0x0178 376
"0x0179", //0x0179 377
"0x017A", //0x017A 378
"0x017B", //0x017B 379
"0x017C", //0x017C 380
"0x017D", //0x017D 381
"0x017E", //0x017E 382
"ReleaseMods", //0x017F 383
"LCK", //0x0180 384
"LSK", //0x0181 385
"LAK", //0x0182 386
"LGK", //0x0183 387
"RCK", //0x0184 388
"RSK", //0x0185 389
"RAK", //0x0186 390
"RGK", //0x0187 391
"CAP", //0x0188 392
"F1", //0x0189 393
"F2", //0x018A 394
"F3", //0x018B 395
"F4", //0x018C 396
"F5", //0x018D 397
"F6", //0x018E 398
"F7", //0x018F 399
"F8", //0x0190 400
"F9", //0x0191 401
"F10", //0x0192 402
"F11", //0x0193 403
"F12", //0x0194 404
"PrintScreen", //0x0195 405
"ScrollLock", //0x0196 406
"Pause", //0x0197 407
"Insert", //0x0198 408
"Home", //0x0199 409
"PageUp", //0x019A 410
"DeleteForward", //0x019B 411
"End", //0x019C 412
"PageDown", //0x019D 413
"→", //0x019E 414
"←", //0x019F 415
"↓", //0x01A0 416
"↑", //0x01A1 417
"NumLock", //0x01A2 418
"F13", //0x01A3 419
"F14", //0x01A4 420
"F15", //0x01A5 421
"F16", //0x01A6 422
"F17", //0x01A7 423
"F18", //0x01A8 424
"F19", //0x01A9 425
"F20", //0x01AA 426
"F21", //0x01AB 427
"F22", //0x01AC 428
"F23", //0x01AD 429
"F24", //0x01AE 430
"Execute", //0x01AF 431
"Help", //0x01B0 432
"Menu", //0x01B1 433
"Select", //0x01B2 434
"Stop", //0x01B3 435
"Again", //0x01B4 436
"Undo", //0x01B5 437
"Cut", //0x01B6 438
"Copy", //0x01B7 439
"Paste", //0x01B8 440
"Find", //0x01B9 441
"Mute", //0x01BA 442
"VolUp", //0x01BB 443
"VolDn", //0x01BC 444
"Intl1", //0x01BD 445
"Intl2", //0x01BE 446
"Intl3", //0x01BF 447
"Intl4", //0x01C0 448
"Intl5", //0x01C1 449
"Intl6", //0x01C2 450
"Intl7", //0x01C3 451
"Intl8", //0x01C4 452
"Intl9", //0x01C5 453
"LANG1", //0x01C6 454
"LANG2", //0x01C7 455
"LANG3", //0x01C8 456
"LANG4", //0x01C9 457
"LANG5", //0x01CA 458
"LANG6", //0x01CB 459
"LANG7", //0x01CC 460
"LANG8", //0x01CD 461
"LANG9", //0x01CE 462
"AtlErase", //0x01CF 463
"SysReq", //0x01D0 464
"Cancel", //0x01D1 465
"Clear", //0x01D2 466
"Prior", //0x01D3 467
"Return", //0x01D4 468
"Separator", //0x01D5 469
"Out", //0x01D6 470
"Oper", //0x01D7 471
"Clear/Again", //0x01D8 472
"CrSel/Props", //0x01D9 473
"ExSel", //0x01DA 474
"ThouSep", //0x01DB 475
"DeciSep", //0x01DC 476
"CurrencyUnit", //0x01DD 477
"CurrencySubUnit", //0x01DE 478
"KPMStore", //0x01DF 479
"KPMRecall", //0x01E0 480
"KPMClear", //0x01E1 481
"KPMAdd", //0x01E2 482
"KPMSub", //0x01E3 483
"KPMMult", //0x01E4 484
"KPMDiv", //0x01E5 485
"KP+/-", //0x01E6 486
"KPClear", //0x01E7 487
"KPClearEntry", //0x01E8 488
"KPBin", //0x01E9 489
"KPOct", //0x01EA 490
"KPDec", //0x01EB 491
"KPHex", //0x01EC 492
"KMPlayPause", //0x01ED 493
"KMStopCD", //0x01EE 494
"KMPrevSong", //0x01EF 495
"KMNextSong", //0x01F0 496
"KMEjectCD", //0x01F1 497
"KMVolUp", //0x01F2 498
"KMVolDn", //0x01F3 499
"KMMute", //0x01F4 500
"KMwww", //0x01F5 501
"KMBack", //0x01F6 502
"KMForward", //0x01F7 503
"KMStop", //0x01F8 504
"KMFind", //0x01F9 505
"KMScrollUp", //0x01FA 506
"KMScrollDn", //0x01FB 507
"KMEdit", //0x01FC 508
"KMSleep", //0x01FD 509
"KMCoffee", //0x01FE 510
"KMRefresh", //0x01FF 511
"CC_Physical", //0x0200 512
"RH_Thumb_3_Left", //0x0201 513
"RH_Thumb_3_Down", //0x0202 514
"RH_Thumb_3_Right", //0x0203 515
"RH_Thumb_3_Up", //0x0204 516
"RH_Thumb_3_Center", //0x0205 517
"RH_Thumb_2_Left", //0x0206 518
"RH_Thumb_2_Down", //0x0207 519
"RH_Thumb_2_Right", //0x0208 520
"RH_Thumb_2_Up", //0x0209 521
"RH_Thumb_2_Center", //0x0210 522
"RH_Thumb_1_Left", //0x0211 523
"RH_Thumb_1_Down", //0x0212 524
"RH_Thumb_1_Right", //0x0213 525
"RH_Thumb_1_Up", //0x0214 526
"RH_Thumb_1_Center", //0x0215 527
"RH_Pinky_Left", //0x0216 528
"RH_Pinky_Down", //0x0217 529
"RH_Pinky_Right", //0x0218 530
"RH_Pinky_Up", //0x0219 531
"RH_Pinky_Center", //0x0220 532
"RH_Ring_Secondary_Left", //0x0221 533
"RH_Ring_Secondary_Down", //0x0222 534
"RH_Ring_Secondary_Right", //0x0223 535
"RH_Ring_Secondary_Up", //0x0224 536
"RH_Ring_Secondary_Center", //0x0225 537
"RH_Ring_Primary_Left", //0x0226 538
"RH_Ring_Primary_Down", //0x0227 539
"RH_Ring_Primary_Right", //0x0228 540
"RH_Ring_Primary_Up", //0x0229 541
"RH_Ring_Primary_Center", //0x0230 542
"RH_Middle_Secondary_Left", //0x0231 543
"RH_Middle_Secondary_Down", //0x0232 544
"RH_Middle_Secondary_Right", //0x0233 545
"RH_Middle_Secondary_Up", //0x0234 546
"RH_Middle_Secondary_Center", //0x0235 547
"RH_Middle_Primary_Left", //0x0236 548
"RH_Middle_Primary_Down", //0x0237 549
"RH_Middle_Primary_Right", //0x0238 550
"RH_Middle_Primary_Up", //0x0239 551
"RH_Middle_Primary_Center", //0x0240 552
"RH_Index_Left", //0x0241 553
"RH_Index_Down", //0x0242 554
"RH_Index_Right", //0x0243 555
"RH_Index_Up", //0x0244 556
"RH_Index_Center", //0x0245 557
"LH_Thumb_3_Left", //0x0246 558
"LH_Thumb_3_Down", //0x0247 559
"LH_Thumb_3_Right", //0x0248 560
"LH_Thumb_3_Up", //0x0249 561
"LH_Thumb_3_Center", //0x0250 562
"LH_Thumb_2_Left", //0x0251 563
"LH_Thumb_2_Down", //0x0252 564
"LH_Thumb_2_Right", //0x0253 565
"LH_Thumb_2_Up", //0x0254 566
"LH_Thumb_2_Center", //0x0255 567
"LH_Thumb_1_Left", //0x0256 568
"LH_Thumb_1_Down", //0x0257 569
"LH_Thumb_1_Right", //0x0258 570
"LH_Thumb_1_Up", //0x0259 571
"LH_Thumb_1_Center", //0x0260 572
"LH_Pinky_Left", //0x0261 573
"LH_Pinky_Down", //0x0262 574
"LH_Pinky_Right", //0x0263 575
"LH_Pinky_Up", //0x0264 576
"LH_Pinky_Center", //0x0265 577
"LH_Ring_Secondary_Left", //0x0266 578
"LH_Ring_Secondary_Down", //0x0267 579
"LH_Ring_Secondary_Right", //0x0268 580
"LH_Ring_Secondary_Up", //0x0269 581
"LH_Ring_Secondary_Center", //0x0270 582
"LH_Ring_Primary_Left", //0x0271 583
"LH_Ring_Primary_Down", //0x0272 584
"LH_Ring_Primary_Right", //0x0273 585
"LH_Ring_Primary_Up", //0x0274 586
"LH_Ring_Primary_Center", //0x0275 587
"LH_Middle_Secondary_Left", //0x0276 588
"LH_Middle_Secondary_Down", //0x0277 589
"LH_Middle_Secondary_Right", //0x0278 590
"LH_Middle_Secondary_Up", //0x0279 591
"LH_Middle_Secondary_Center", //0x0280 592
"LH_Middle_Primary_Left", //0x0281 593
"LH_Middle_Primary_Down", //0x0282 594
"LH_Middle_Primary_Right", //0x0283 595
"LH_Middle_Primary_Up", //0x0284 596
"LH_Middle_Primary_Center", //0x0285 597
"LH_Index_Left", //0x0286 598
"LH_Index_Down", //0x0287 599
"LH_Index_Right", //0x0288 600
"LH_Index_Up", //0x0289 601
"LH_Index_Center", //0x0290 602
]

View File

@@ -0,0 +1,20 @@
export const CONFIG_ID = {
ENABLE_SERIAL_LOG: "01",
ENABLE_SERIAL_RAW: "02",
ENABLE_SERIAL_CHORD: "03",
ENABLE_SERIAL_KEYBOARD: "04",
ENABLE_SERIAL_MOUSE: "05",
ENABLE_SERIAL_DEBUG: "06",
ENABLE_SERIAL_HEADER: "07",
ENABLE_HID_KEYBOARD: "0A",
PRESS_THRESHOLD: "0B",
RELEASE_THRESHOLD: "0C",
ENABLE_HID_MOUSE: "14",
SCROLL_DELAY: "15",
ENABLE_SPURRING: "1E",
SPUR_KILLER_TOGGLE: "1F",
SPUR_KILLER: "20",
ENABLE_CHORDING: "28",
CHAR_KILLER_TOGGLE: "29",
CHAR_COUNTER_KILLER: "2A",
}

View File

@@ -0,0 +1,160 @@
export let _keyMapDefaults = {
CHARACHORDER: [
0x0000, // 0,
0x013e, // 1, mouse right button press-and-release
"!".charCodeAt(0), // 2, !
0x0187, // 3, right gui
0x003f, // 4, ?
0x0000, // 5,
"b".charCodeAt(0), // 6, b
"q".charCodeAt(0), // 7, q
0x0115, // 8, previous phrase
"x".charCodeAt(0), // 9, x
0x0000, //10,
"f".charCodeAt(0), //11, f
"d".charCodeAt(0), //12, d
"h".charCodeAt(0), //13, h
"p".charCodeAt(0), //14, p
0x0000, //15, //'fed' is using this
0x0111, //16, ambi throw right
0x0113, //17, num-shift right
0x0186, //18, alt right
0x0185, //19, shift right
0x0000, //20,
0x0149, //21, mouse left hand down
0x014a, //22, mouse left hand right
0x014b, //23, mouse left hand up
0x014c, //24, mouse left hand left
0x0000, //25,
"s".charCodeAt(0), //26, s
";".charCodeAt(0), //27, ;
0x0184, //28, ctrl right
"y".charCodeAt(0), //29, y
0x0000, //30,
0x01a0, //31, arrow down
0x019e, //32, arrow right
0x01a1, //33, arrow up
0x019f, //34, arrow left
0x0000, //35,
"n".charCodeAt(0), //36, n
"j".charCodeAt(0), //37, j
0x0009, //38, tab horizontal
"l".charCodeAt(0), //39, l
0x0000, //40,
"t".charCodeAt(0), //41, t
" ".charCodeAt(0), //42, (space)
0x000a, //43, enter (line feed)
"a".charCodeAt(0), //44, a
0x0000, //45,
"/".charCodeAt(0), //46, /
"-".charCodeAt(0), //47, -
0x0183, //48, left gui
0x001b, //49, escape
0x0000, //50,
"w".charCodeAt(0), //51, w
0x013d, //52, mouse left button press-and-release
"g".charCodeAt(0), //53, g
"z".charCodeAt(0), //54, z
0x0151, //55, double click
"k".charCodeAt(0), //56, k
"v".charCodeAt(0), //57, v
"m".charCodeAt(0), //58, m
"c".charCodeAt(0), //59, c
0x0000, //60,
0x0110, //61, ambi throw left
0x0181, //62, shift left
0x0182, //63, alt left
0x0110, //64, num-shift left
0x0000, //65,
0x0149, //66, mouse right hand down
0x014a, //67, mouse right hand right
0x014b, //68, mouse right hand up
0x014c, //69, mouse right hand left
0x0000, //70,
"u".charCodeAt(0), //71, u
"\\".charCodeAt(0), //72, \
0x0180, //73, left ctrl
",".charCodeAt(0), //74, ,
0x0000, //75,
0x01a0, //76, arrow down
0x019e, //77, arrow right
0x01a1, //78, arrow up
0x019f, //79, arrow left
0x0000, //80,
"o".charCodeAt(0), //81, o
"i".charCodeAt(0), //82, i
0x007f, //83, del forward
".".charCodeAt(0), //84, .
0x0000, //85,
"e".charCodeAt(0), //86, e
"r".charCodeAt(0), //87, r
0x0008, //88, backspace
" ".charCodeAt(0), //89, (space)
],
CHARACHORDERLITE: [
"GTM", //0
"LCtrl", //1
"LAlt", //2
"LSpace", //3
"Present", //4
"Plural", //5
"RSpace", //6
"Dup", //7
"Win", //8
"Left", //9
"Down", //10
"Right", //11
"LShift", //12
"z", //13
"x", //14
"c", //15
"v", //16
"b", //17
"n", //18
"m", //19
",", //20
".", //21
"/", //22
"RShift", //23
"Up", //24
"Del", //25
"Spur", //26
"0x0061", //27
"s", //28
"d", //29
"f", //30
"g", //31
"h", //32
"j", //33
"k", //34
"l", //35
";", //36
"'", //37
"Tab", //38
"q", //39
"w", //40
"e", //41
"r", //42
"t", //43
"y", //44
"u", //45
"i", //46
"o", //47
"p", //48
"[", //49
"\\", //50
"1", //51
"2", //52
"3", //53
"4", //54
"5", //55
"6", //56
"7", //57
"8", //58
"9", //59
"0", //60
"-", //61
"=", //62
"Back", //63
],
}

View File

@@ -0,0 +1,71 @@
/**
* this shouldn't be used anymore
*
* @deprecated
*/
export const _keyMap = [
"GTM", //0
"LCtrl", //1
"LAlt", //2
"LSpace", //3
"Present", //4
"Plural", //5
"RSpace", //6
"Dup", //7
"Win", //8
"Left", //9
"Down", //10
"Right", //11
"LShift", //12
"z", //13
"x", //14
"c", //15
"v", //16
"b", //17
"n", //18
"m", //19
",", //20
".", //21
"/", //22
"RShift", //23
"Up", //24
"Del", //25
"Spur", //26
"0x0061", //27
"s", //28
"d", //29
"f", //30
"g", //31
"h", //32
"j", //33
"k", //34
"l", //35
";", //36
"'", //37
"Tab", //38
"q", //39
"w", //40
"e", //41
"r", //42
"t", //43
"y", //44
"u", //45
"i", //46
"o", //47
"p", //48
"[", //49
"\\", //50
"1", //51
"2", //52
"3", //53
"4", //54
"5", //55
"6", //56
"7", //57
"8", //58
"9", //59
"0", //60
"-", //61
"=", //62
"Back", //63
].reverse()

View File

@@ -0,0 +1,27 @@
import {readGetOneAndToss} from "$lib/serial/webserial/noop.js"
/**
* Unused?
* @param lineReader {ReadableStreamDefaultReader<string>}
* @returns {Promise<string>}
*/
export async function readGetHexChord(lineReader) {
let hexChordString = ""
await readGetOneAndToss(lineReader) //this is added for the latest firmware with customers, where decimal version
const {value, done} = await lineReader.read()
if (done) {
console.log("reader is done")
} else {
console.log(["value", value])
if (value) {
let arrValue = [...value]
const strValue = String(arrValue.join(""))
console.log(strValue)
hexChordString = strValue.substr(0, 16)
await readGetOneAndToss(lineReader) // the "processing chord:" decimal output
}
}
return hexChordString
}

View File

@@ -0,0 +1,5 @@
/**
* @param lineReader {ReadableStreamDefaultReader<string>}
* @returns {Promise<void>}
*/
export async function readGetOneAndToss(lineReader) {}

View File

@@ -0,0 +1,19 @@
/**
* JavaScript handles up to 53-bit bs it uses float64 to operate with integers
*/
function bitwiseAndLarge(val1, val2) {
let shift = 0,
result = 0
const mask = ~(~0 << 30) // Gives us a bit mask like 01111..1 (30 ones)
const divisor = 1 << 30 // To work with the bit mask, we need to clear bits at a time
while (val1 !== 0 && val2 !== 0) {
let rs = mask & val1 & (mask & val2)
val1 = Math.floor(val1 / divisor) // val1 >>> 30
val2 = Math.floor(val2 / divisor) // val2 >>> 30
for (let i = shift++; i--; ) {
rs *= divisor // rs << 30
}
result += rs
}
return result
}

View File

@@ -0,0 +1,208 @@
import {_actionMap} from "$lib/serial/webserial/constants/action-map.js"
import {_keyMap} from "$lib/serial/webserial/constants/key-map.js"
import {_keyMapDefaults} from "$lib/serial/webserial/constants/key-map-defaults.js"
/**
* @param hexString {string}
* @param chordMapId {keyof typeof import('$lib/serial/webserial/constants/key-map-defaults.js')._keyMapDefaults}
* @returns {string}
*/
export function convertHexadecimalChordToHumanString(hexString, chordMapId) {
let humanString = ""
console.log(hexString)
if (hexString.length <= 0) {
hexString = "00"
}
let bigNum = BigInt("0x" + hexString)
if (chordMapId === "CHARACHORDER") {
// CharaChorder original uses different key map structure
let decString = String(bigNum).split("") //no left zeros; that's ok
console.log(decString)
for (let i = 0; i < decString.length; i++) {
if (decString[i] !== "0") {
if (humanString.length > 0) {
humanString += " + "
}
console.log({
"i": i,
"decString[i]": decString[i],
"decString.length": decString.length,
"decString": decString,
"10exp": decString.length - i - 1,
"decChordComp": decString[i] * 10 ** (decString.length - i - 1),
// 'decChordCompBigInt':BigInt(decString[i])*BigInt((BigInt(10)**(decString.length-i-1))),
"noteId": chord_to_noteId(decString[i] * 10 ** (decString.length - i - 1)),
})
let noteId
let actionId
if (decString[i] % 2 === 1) {
//if it is odd, then it is simple
noteId = chord_to_noteId(decString[i] * 10 ** (decString.length - i - 1))
actionId = _keyMapDefaults["CHARACHORDER"][noteId]
if (actionId === 0) {
actionId = 0x0200 + noteId
}
humanString += _actionMap[actionId]
} else {
//value is even, odd plus a 1
noteId = chord_to_noteId((decString[i] - 1) * 10 ** (decString.length - i - 1))
actionId = _keyMapDefaults["CHARACHORDER"][noteId]
if (actionId === 0) {
actionId = 0x0200 + noteId
}
humanString += _actionMap[actionId]
humanString += " + "
noteId = chord_to_noteId(10 ** (decString.length - i - 1))
actionId = _keyMapDefaults["CHARACHORDER"][noteId]
if (actionId === 0) {
actionId = 0x0200 + noteId
}
humanString += _actionMap[actionId]
}
}
}
} else {
let binString = bigNum.toString(2) //no left zeros; that's ok
console.log(binString)
for (let i = 0; i < binString.length; i++) {
if (binString[i] === "1") {
if (humanString.length > 0) {
humanString += " + "
}
humanString += _keyMap[64 - binString.length + i]
//console.log(i);
//humanString+=_keyMap[(64-binString.length+i)];
}
}
}
console.log(humanString)
return humanString
}
/**
* @param humanString {string}
* @returns {string}
*/
export function convertHumanStringToHexadecimalPhrase(humanString) {
let hexString = ""
for (let i = 0; i < humanString.length; i++) {
let hex = Number(humanString.charCodeAt(i)).toString(16)
hexString += hex
}
hexString = hexString.toUpperCase()
console.log(hexString)
return hexString
}
/**
* @param hexString {string}
* @returns {string}
*/
function convertHexadecimalPhraseToAsciiString(hexString) {
let asciiString = ""
console.log("convertHexadecimalPhraseToAsciiString()")
//assume 2x size
//get every 2 characters
//TODO covert to byte array and account for non-ascii inputs like mouse moves
for (let i = 0; i < hexString.length; i += 2) {
asciiString += String.fromCharCode(parseInt(hexString.substr(i, 2), 16))
//console.log("0x"+hexString.substr(i, 2));
//asciiString += String.fromCharCode("0x"+hexString.substr(i, 2));
}
console.log(asciiString)
return asciiString
}
function noteId_to_chord(note) {
return BigInt(2 * ((note - 1) % 5) + 1) * BigInt(10) ** BigInt(Math.floor((note - 1) / 5))
}
function chord_to_noteId(chord) {
const part1 = 5 * Math.floor(Math.log10(chord))
const part2 = Math.floor(chord / 10 ** Math.floor(Math.log10(chord)) + 1) / 2
const part3 = Math.log10(chord)
const full = Math.floor(
5 * Math.floor(Math.log10(chord)) + Math.floor(chord / 10 ** Math.floor(Math.log10(chord)) + 1) / 2,
)
console.log([chord, part1, part2, part3, full])
return full
}
/**
* @param humanString {string}
* @param chordMapId {keyof typeof import('$lib/serial/webserial/constants/key-map-defaults.js')._keyMapDefaults}
* @returns {Promise<bigint>}
*/
export async function convertHumanStringToBigNum(humanString, chordMapId) {
console.log("convertHumanStringToBigNum")
let bigNum = BigInt(0)
//parse the pieces with _+_
let humanStringParts = humanString.split(" + ") //assumes plus isn't being used; bc default is = for the +/= key
console.log(humanStringParts)
for (const part of humanStringParts) {
let actionId = _actionMap.indexOf(part)
console.log(actionId)
if (chordMapId === "CHARACHORDER") {
//charachorder original uses different key map structure
let keyId
if (actionId < 0x0200) {
keyId = _keyMapDefaults["CHARACHORDER"].indexOf(actionId)
} else {
keyId = actionId - 0x0200 //using the physical key position
}
console.log(keyId)
bigNum = BigInt(noteId_to_chord(keyId))
// bigNum+= BigInt(noteId_to_chord(keyId));
console.log(bigNum)
} else {
//use other keymap
}
}
console.log(bigNum)
return bigNum
}
/**
* @param humanString {string}
* @param chordMapId {keyof typeof import('$lib/serial/webserial/constants/key-map-defaults.js')._keyMapDefaults}
* @returns {string}
*/
export function convertHumanStringToHexadecimalChord(humanString, chordMapId) {
let bigNum = BigInt(0)
//parse the pieces with _+_
let humanStringParts = humanString.split(" + ") //assumes plus isn't being used; bc default is = for the +/= key
console.log(humanStringParts)
humanStringParts.forEach(async part => {
let actionId = _actionMap.indexOf(part)
console.log(actionId)
if (chordMapId === "CHARACHORDER") {
//charachorder original uses different key map structure
let keyId
if (actionId < 0x0200) {
keyId = _keyMapDefaults["CHARACHORDER"].indexOf(actionId)
} else {
keyId = actionId - 0x0200 //using the physical key position
}
console.log(keyId)
bigNum += BigInt(noteId_to_chord(keyId))
console.log(bigNum)
} else {
//use other keymap
}
})
console.log(bigNum)
let hexString = bigNum.toString(16).toUpperCase()
hexString = "0".repeat(16 - hexString.length) + hexString //add leading zeros up to 16 characters
console.log(hexString)
return hexString
}

View File

@@ -0,0 +1,21 @@
// @ts-check
export class LineBreakTransformer {
constructor() {
this.chunks = ""
}
// noinspection JSUnusedGlobalSymbols
transform(chunk, controller) {
this.chunks += chunk
const lines = this.chunks.split("\r\n")
this.chunks = lines.pop()
for (const line of lines) {
controller.enqueue(line)
}
}
// noinspection JSUnusedGlobalSymbols
flush(controller) {
controller.enqueue(this.chunks)
}
}

View File

@@ -0,0 +1,17 @@
import {readGetOneAndToss} from "$lib/serial/webserial/noop.js"
export let FIRMWARE_VERSION = "0"
/**
* @param lineReader {ReadableStreamDefaultReader<string>}
* @returns {Promise<void>}
*/
export async function readVersion(lineReader) {
await readGetOneAndToss(lineReader) //electronics board version
const {value, done} = await lineReader.read()
if (value) {
FIRMWARE_VERSION = value
console.log("Firmware Version:", FIRMWARE_VERSION)
}
await readGetOneAndToss(lineReader) //serial api version
}

View File

@@ -0,0 +1,30 @@
/* fallback */
@font-face {
font-family: 'Material Symbols Rounded';
font-weight: 100 700;
font-style: normal;
src: url("https://fonts.gstatic.com/s/materialsymbolsrounded/v121/sykg-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190Fjzag.woff2") format('woff2');
}
.icon {
direction: ltr;
display: inline-block;
/* stylelint-disable-next-line */
font-family: 'Material Symbols Rounded';
font-size: 24px;
font-feature-settings: 'liga';
font-variation-settings: "FILL" var(--icon-fill, 0) "wght" var(--icon-weigth, 400) "GRAD"
var(--icon-grade, 0);
font-weight: normal;
font-style: normal;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
transition: all 250ms ease;
-moz-osx-font-smoothing: grayscale;
}

View File

@@ -0,0 +1,153 @@
/* cyrillic-ext */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 320;
font-style: normal;
font-display: swap;
font-stretch: 77.8%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCLwR26eg.woff2") format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 320;
font-style: normal;
font-display: swap;
font-stretch: 77.8%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCCwR26eg.woff2") format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 320;
font-style: normal;
font-display: swap;
font-stretch: 77.8%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCKwR26eg.woff2") format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 320;
font-style: normal;
font-display: swap;
font-stretch: 77.8%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCFwR26eg.woff2") format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 320;
font-style: normal;
font-display: swap;
font-stretch: 77.8%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCJwR26eg.woff2") format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 320;
font-style: normal;
font-display: swap;
font-stretch: 77.8%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCIwR26eg.woff2") format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 320;
font-style: normal;
font-display: swap;
font-stretch: 77.8%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCGwR0.woff2") format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 400;
font-style: normal;
font-display: swap;
font-stretch: 100%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCLwR26eg.woff2") format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 400;
font-style: normal;
font-display: swap;
font-stretch: 100%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCCwR26eg.woff2") format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 400;
font-style: normal;
font-display: swap;
font-stretch: 100%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCKwR26eg.woff2") format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 400;
font-style: normal;
font-display: swap;
font-stretch: 100%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCFwR26eg.woff2") format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 400;
font-style: normal;
font-display: swap;
font-stretch: 100%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCJwR26eg.woff2") format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 400;
font-style: normal;
font-display: swap;
font-stretch: 100%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCIwR26eg.woff2") format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noto Sans Mono';
font-weight: 400;
font-style: normal;
font-display: swap;
font-stretch: 100%;
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCGwR0.woff2") format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

49
src/routes/+layout.svelte Normal file
View File

@@ -0,0 +1,49 @@
<script>
import "$lib/style/fonts/noto-sans-mono.scss"
import "$lib/style/fonts/material-symbols-rounded.scss"
import {onMount} from "svelte"
import {applyTheme, argbFromHex, themeFromSourceColor} from "@material/material-color-utilities"
import Navigation from "$lib/components/Navigation.svelte"
import {serialPort} from "$lib/serial/connection.js"
import {CharaDevice} from "$lib/serial/device.js"
/** @type {import('$lib/serial/device.js').CharaDevice} */
let device // @hmr:keep
onMount(async () => {
const theme = themeFromSourceColor(argbFromHex("#6D81C7"), [
{name: "success", value: argbFromHex("#00ff00"), blend: true},
])
const dark = true // window.matchMedia("(prefers-color-scheme: dark)").matches
applyTheme(theme, {target: document.body, dark})
device ??= new CharaDevice()
serialPort.set(device)
})
</script>
<Navigation />
<slot />
<style lang="scss" global>
* {
box-sizing: border-box;
}
a {
color: var(--md-sys-color-tertiary);
}
body {
font-family: "Noto Sans Mono", monospace;
color: var(--md-sys-color-on-background);
background: var(--md-sys-color-background);
}
h1 {
font-size: 4rem;
font-weight: 900;
color: var(--md-sys-color-secondary);
}
</style>

6
src/routes/+page.svelte Normal file
View File

@@ -0,0 +1,6 @@
<svelte:head>
<title>dot i/o</title>
</svelte:head>
<h1>dot i/o V2</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>

View File

@@ -0,0 +1,165 @@
<script>
import {serialPort} from "$lib/serial/connection.js"
import Terminal from "$lib/components/Terminal.svelte"
</script>
<svelte:head>
<title>dot i/o device manager</title>
</svelte:head>
<h1>Device Manager</h1>
<div class="device-grid">
<section>
<h2>Control</h2>
<div class="icon bg">memory</div>
<div class="row">
<button disabled class="icon secondary" title="Save changes to device">rule_settings</button>
<button disabled title="Reboot" class="icon">restart_alt</button>
<button disabled>
{#if $serialPort}
<span class="icon">usb_off</span> Disconnect
{:else}
<span class="icon">usb</span> Connect
{/if}
</button>
</div>
{#if $serialPort}
<pre>{#await $serialPort.version then version}{version}{/await}<br
/>{#await $serialPort.deviceId then id}{id}{/await}</pre>
{/if}
</section>
<section>
<h2>Layout</h2>
<div class="icon bg">keyboard</div>
<div class="row">
<button class="icon" title="Import Layout">download</button>
<button class="icon" title="Export Layout">upload</button>
</div>
</section>
<section>
<h2>Chords</h2>
<div class="icon bg">piano</div>
<table>
<tr>
<th>three</th>
<td><i></i><i>3</i></td>
</tr>
</table>
</section>
<section>
<h2>Serial Terminal</h2>
<div class="icon bg">terminal</div>
<Terminal />
</section>
</div>
<style lang="scss">
section {
position: relative;
min-height: 128px;
padding: 8px;
border-radius: 32px;
> h2 {
font-size: 1.5rem;
}
> div.icon.bg {
user-select: none;
position: absolute;
z-index: -1;
top: -4px;
left: -8px;
font-size: 64px;
opacity: 0.05;
}
}
.row {
display: flex;
gap: 8px;
}
button {
cursor: pointer;
display: flex;
gap: 4px;
align-items: center;
justify-content: center;
padding: 8px;
padding-inline-end: 16px;
font-size: 1rem;
color: var(--md-sys-color-on-background);
background: transparent;
border: none;
border-radius: 1rem;
transition: all 250ms ease;
&:disabled {
cursor: default;
opacity: 0.5;
}
&.icon {
aspect-ratio: 1;
padding-inline-end: 8px;
font-size: 24px;
border-radius: 50%;
}
&.primary {
color: var(--md-sys-color-on-primary);
background: var(--md-sys-color-primary);
}
&.secondary {
color: var(--md-sys-color-on-secondary);
background: var(--md-sys-color-secondary);
}
&.tertiary {
color: var(--md-sys-color-on-tertiary);
background: var(--md-sys-color-tertiary);
}
&:hover:not(:disabled) {
color: var(--md-sys-color-on-surface-variant);
background: var(--md-sys-color-surface-variant);
}
}
table td {
display: flex;
gap: 4px;
}
table i {
display: block;
aspect-ratio: 1;
padding-block: 4px;
padding-inline: 8px;
font-style: normal;
border: 1px solid var(--md-sys-color-outline);
border-radius: 8px;
}
.device-grid {
display: grid;
grid-template-rows: 1fr 1fr;
}
</style>

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

12
svelte.config.js Normal file
View File

@@ -0,0 +1,12 @@
import adapter from "@sveltejs/adapter-static"
import preprocess from "svelte-preprocess"
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: [preprocess()],
kit: {
adapter: adapter(),
},
}
export default config

6
vite.config.js Normal file
View File

@@ -0,0 +1,6 @@
import {sveltekit} from "@sveltejs/kit/vite"
import {defineConfig} from "vite"
export default defineConfig({
plugins: [sveltekit()],
})