From 1336ad6d6372aecfb696715c6d98c831536f5311 Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Sun, 27 Nov 2022 23:56:37 -0500 Subject: [PATCH] state started --- .vscode/settings.json | 4 + app.js | 12 +- squarespace.html | 899 ------------------------------------------ store.js | 122 ++++-- ui.js | 48 +-- 5 files changed, 130 insertions(+), 955 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 squarespace.html diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8675ad5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "deno.enable": true, + "deno.unstable": true +} \ No newline at end of file diff --git a/app.js b/app.js index 6355aad..40fa2e2 100644 --- a/app.js +++ b/app.js @@ -3,6 +3,7 @@ import * as TW from "https://esm.sh/@twind/core@1.0.1"; import TWPreTail from "https://esm.sh/@twind/preset-tailwind@1.0.1"; import TWPreAuto from "https://esm.sh/@twind/preset-autoprefix@1.0.1"; +/** @type {TW.TwindConfig} */ const Configure = { theme: { @@ -41,8 +42,9 @@ const Configure = { [ "stroke-draw", { - "vector-effect":"non-scaling-stroke", - "stroke-linecap":"square" + "vector-effect": "non-scaling-stroke", + "stroke-linecap": "square", + "fill": "none" }, ], [ @@ -77,8 +79,10 @@ render(html` <${UI.Button} inactive>Right <${UI.Button} disabled>Right <${UI.Chart}> - - <${UI.Mark} /> + + <${UI.Mark} right=${true} x=${"20%"} y="20%" /> + <${UI.Mark} right=${false} x=${"10%"} y="20%" response=${true} /> + <${UI.Mark} right=${false}/> `, ShadowDiv); \ No newline at end of file diff --git a/squarespace.html b/squarespace.html deleted file mode 100644 index c096acb..0000000 --- a/squarespace.html +++ /dev/null @@ -1,899 +0,0 @@ - - -
- - - - - - - - - - -Earmark Hearing Conservation | Philadelphia - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - Earmark-Logo-Medium-Web-Ocean (2).png -
-
- -
- - -
- - - -
-
- - - - -

Serving musicians, music industry professionals, and music lovers in the Greater Philadelphia community.

- - - - -
-
- - -
- - - - - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - -
- - -
-
- -
- - -
- - - -
-
- - -

Online Courses Available

- - - - - - -
-
- - -
- - - - - - -
 
- -

Your Ears. your MUSIC.

 Hearing wellness for musicians is healthcare, hearing protection, and occupational safety, but it is much more than that. It is reducing barriers to great performance, increasing personal satisfaction, and ensuring career longevity. Contact us to see how we can help your ears.

- - -
- - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - -
-
- -
-
- -
- - - - -
- - -
- - - - - - -
- -

Talking Ears

A new podcast about hearing health in the music industry.

- - -
- - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - -
-
- Serving musicians and music lovers, Earmark aims to provide customized solutions for listening, monitoring and performance needs for years to come. -
-
- -
- - - - -
- - -
- - - - -
- -

About Earmark

About Earmark and Frank Wartinger, Au.D.

- - -
-
- -
- -
- -
- - -
- - - - - - - \ No newline at end of file diff --git a/store.js b/store.js index e898d79..a5d368e 100644 --- a/store.js +++ b/store.js @@ -1,31 +1,109 @@ //@ts-check -/** @typedef {[f1:ListEntry, f2:ListEntry, f3:ListEntry, f4:ListEntry, f5:ListEntry, f6:ListEntry, f7:ListEntry]} FreqList */ -/** @typedef {number|TestMark} ListEntry */ -/** @typedef {{Name:string, Sample:{Left:FreqList, Right:FreqList}, Answer?:{Left:FreqList, Right:FreqList}}} Test */ -/** @typedef {{Stim:number|null, Resp:boolean}|null} TestMark*/ -/** @type FreqList */ -export const Frequencies = [500, 1000, 2000, 3000, 4000, 6000, 8000]; -/** @type Array */ -export const Tests = [ - { - Name: "Patient A Asymmetric Notch", - Sample:{ - Left:[15, 10, 15, 30, 40, 35, 20], - Right:[10, 10, 20, 40, 55, 40, 15] - } - } +const size = 100/6; +/** @typedef {[frequency:number, position:number, normal:boolean]} ColumnMapping */ +/** @type {Array} */ +export const ColumnMapping = [ + [ 125, size*0.0, true ], + [ 250, size*1.0, true ], + [ 500, size*2.0, true ], + [1000, size*3.0, true ], + [2000, size*4.0, true ], + [3000, size*4.5, false], + [4000, size*5.0, true ], + [6000, size*5.5, false], + [8000, size*6.0, true ] ]; - -export const Controls = +/** @type {(inFrequency:number)=>ColumnMapping|false} */ +export const ColumnLookup =(inFrequency)=> { - Test:0, - Channel: "left", - Frequency: 1, - Stimulus: 30 + for(let i=0; i}} Test */ +/** @typedef {{Test?:Test, Freq?:TestFrequency, Mark?:TestFrequencySample}} Context */ +/** @typedef {{Chan:"left"|"right", Freq:number, Stim:number, Selection:Context, Tests:Array}} State */ +/** @type {State} */ +export const Initial = +{ + Chan: "left", + Freq: 3, + Stim: 30, + Selection: + { + Test: undefined, + Freq: undefined, + Mark: undefined + }, + Tests: [ + { + Name: "Patient A Asymmetric Notch", + Plot: + [ + { Hz: 500, TestL: { Stim: 30, Resp: true }, TestR: { Stim: 50, Resp: true } }, + { Hz: 1000, TestL: { Stim: 50, Resp: true }, TestR: { Stim: 55, Resp: true } } + ] + } + ] }; -function Reducer(inState, inAction) +/** @typedef {{Name:"Mark", Data:boolean|undefined}} ActionMark */ +/** @typedef {{Name:"Test", Data:number}} ActionTest*/ +/** @typedef {ActionMark|ActionTest} Action */ +/** @typedef {(inState:State, inAction:Action)=>State} Reducer */ +/** @type {Reducer} */ +export function Reducer(inState, inAction) { + const clone = {...inState}; + switch(inAction.Name) + { + case "Test" : + { + let selTest = clone.Tests[inAction.Data]; + let selFreq = undefined; + let selMark = undefined; + const column = ColumnLookup(clone.Freq); + if(column) + { + let hz = column[0]; + let plot; + for(let i=0; i -import {html} from "https://esm.sh/htm@3.1.1/preact"; +import { html } from "https://esm.sh/htm@3.1.1/preact"; +import { ColumnMapping, ColumnLookup } from "./store.js"; /** @typedef {({children}:{children:React.ReactNode})=>JSX.Element} BasicElement */ +/** @type {({children, icon, light, disabled, inactive}:{children:React.ReactNode, icon?:JSX.Element, light:boolean, disabled:boolean, inactive:boolean})=>JSX.Element} */ export function Button({children, icon, light, disabled, inactive}) { const [LightGet, LightSet] = React.useState(light); @@ -38,36 +39,23 @@ export function Button({children, icon, light, disabled, inactive}) /** @type {BasicElement} */ export function Chart({children}) { - const inset = 20 - - const size = 1/6; - /** @type {Record} */ - const rulesXMapping = { - "125": [size*0.0, true ], - "250": [size*1.0, true ], - "500": [size*2.0, true ], - "1000": [size*3.0, true ], - "2000": [size*4.0, true ], - "3000": [size*4.5, false], - "4000": [size*5.0, true ], - "6000": [size*5.5, false], - "8000": [size*6.0, true ] - }; - const rulesX = Object.entries(rulesXMapping).map(([label, [position, normal]])=> + const inset = 20; + /** @type {Array} */ + const rules = []; + ColumnMapping.forEach(([label, position, normal])=> { - return html` - + rules.push(html` + ${label} - `; + `); }); - const rulesY = []; - const rulesYMin = -10; - const rulesYMax = 120; - for(let db = rulesYMin; db <= rulesYMax; db+=10) + + const dbMin = -10; + const dbMax = 120; + for(let db = dbMin; db <= dbMax; db+=10) { - const percent = ((db-rulesYMin) / (rulesYMax-rulesYMin))*100; - rulesY.push(html` -
- ${ rulesX } - ${ rulesY } + ${ rules }
${ children }
@@ -94,6 +81,7 @@ export function Chart({children}) `; } + /** @type {Record} */ const Glyph = { Arrow:({children})=> html`