<!DOCTYPE html>

<html lang=”en”>

<head>

<meta charset=”UTF-8″>

<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>

<title>Guitar neck diagram</title>

<style>

:root {

–tp: #1a1a18; –ts: #5f5e5a; –tt: #888780;

–bg: #ffffff; –bg2: #f5f4f0;

–border: rgba(0,0,0,0.10);

–font: system-ui,-apple-system,sans-serif;

–tf: #E1F5EE; –ts2: #0F6E56; –tt2: #085041;

–cf: #FAECE7; –cs: #993C1D; –ct: #712B13;

}

@media (prefers-color-scheme:dark) {

:root {

–tp: #e8e6dc; –ts: #b4b2a9; –tt: #888780;

–bg: #1c1c1a; –bg2: #252523; –border: rgba(255,255,255,0.08);

–tf: #085041; –ts2: #5DCAA5; –tt2: #9FE1CB;

–cf: #712B13; –cs: #F0997B; –ct: #F5C4B3;

}

}

*{ box-sizing:border-box; margin:0; padding:0; }

body{ font-family:var(–font); background:var(–bg); color:var(–tp); padding:24px; min-height:100vh; }

h1{ font-size:18px; font-weight:500; margin-bottom:4px; }

.subtitle{ font-size:13px; color:var(–ts); margin-bottom:20px; line-height:1.6; }

.controls{ display:flex; flex-wrap:wrap; gap:14px; margin-bottom:20px; align-items:flex-end; }

.ctrl-group{ display:flex; flex-direction:column; gap:5px; }

.ctrl-group label{ font-size:12px; color:var(–ts); font-weight:500; }

select, input[type=text]{

font-family:var(–font); font-size:13px; background:var(–bg2); color:var(–tp);

border:1px solid var(–border); border-radius:6px; padding:6px 10px;

outline:none; cursor:pointer; min-width:220px;

}

select:focus, input:focus{ border-color:var(–ts2); }

.tuning-row{ display:flex; gap:6px; }

.tuning-row input{ width:52px !important; min-width:unset !important; text-align:center; font-weight:500; }

.err{ color:#c0392b; font-size:12px; margin-top:4px; display:none; }

.scroll-wrap{

overflow-x:auto; border:1px solid var(–border);

border-radius:8px; padding:12px 0 4px; background:var(–bg2);

}

svg .c-teal circle, svg .c-teal rect{ fill:var(–tf); stroke:var(–ts2); stroke-width:1; }

svg .c-teal text{ fill:var(–tt2); }

svg .c-coral circle, svg .c-coral rect{ fill:var(–cf); stroke:var(–cs); stroke-width:1; }

svg .c-coral text{ fill:var(–ct); }

svg .th{ font-family:var(–font); font-size:14px; font-weight:500; fill:var(–tp); }

svg .ts{ font-family:var(–font); font-size:12px; font-weight:400; fill:var(–ts); }

.legend{ display:flex; gap:24px; margin-top:14px; align-items:center; flex-wrap:wrap; }

.legend-item{ display:flex; align-items:center; gap:7px; font-size:13px; color:var(–ts); }

.swatch{ width:20px; height:20px; border-radius:50%; border:1.5px solid; flex-shrink:0; }

.sw-root{ background:var(–cf); border-color:var(–cs); }

.sw-scale{ background:var(–tf); border-color:var(–ts2); }

.notes-label{ margin-left:auto; font-size:12px; color:var(–tt); }

optgroup{ font-weight:600; }

/* ── Piano keyboard ── */

.piano-wrap{

margin-top:28px;

}

.piano-heading{

font-size:13px; font-weight:500; color:var(–ts); margin-bottom:10px;

}

.piano-scroll{

overflow-x:auto; border:1px solid var(–border);

border-radius:8px; padding:16px 20px 12px; background:var(–bg2);

display:inline-block; max-width:100%;

}

/* ── Flute fingerings ── */

.flute-wrap{

margin-top:32px;

}

.flute-heading{

font-size:13px; font-weight:500; color:var(–ts); margin-bottom:10px;

}

.flute-scroll{

overflow-x:auto; border:1px solid var(–border);

border-radius:8px; padding:20px; background:var(–bg2);

}

.flute-row{

display:flex; gap:18px; align-items:flex-start; flex-wrap:nowrap;

}

.flute-card{

display:flex; flex-direction:column; align-items:center; gap:6px; flex-shrink:0;

}

.flute-card .note-name{

font-size:12px; font-weight:600; color:var(–tp); text-align:center; line-height:1.2;

}

.flute-card .note-name.is-root{ color:var(–cs); }

.flute-card .octave-tag{

font-size:10px; color:var(–ts); text-align:center;

}

/* key circles inside flute SVG */

svg .fk-open { fill:var(–bg); stroke:var(–ts); stroke-width:1.5; }

svg .fk-closed{ fill:var(–tp); stroke:var(–ts); stroke-width:1.5; }

svg .fk-half { fill:url(#halfFill); stroke:var(–ts); stroke-width:1.5; }

svg .fk-trill { fill:#e8d88a; stroke:#9a8a20; stroke-width:1.5; }

svg .fk-oct { fill:var(–tp); stroke:var(–ts); stroke-width:1.2; }

svg .fk-oct-o { fill:var(–bg); stroke:var(–ts); stroke-width:1.2; }

svg .fl-body { fill:none; stroke:var(–ts); stroke-width:2; opacity:0.35; }

svg .fl-label { font-family:var(–font); font-size:8px; fill:var(–ts); text-anchor:middle; }

svg .wk{ fill:#f8f7f3; stroke:#c8c6bc; stroke-width:1; }

svg .bk{ fill:#f0eeea; stroke:#b0aea4; stroke-width:1; }

svg .wk-root{ fill:var(–cf); stroke:var(–cs); stroke-width:1.5; }

svg .bk-root{ fill:var(–cs); stroke:var(–ct); stroke-width:1.5; }

svg .wk-scale{ fill:var(–tf); stroke:var(–ts2); stroke-width:1.5; }

svg .bk-scale{ fill:var(–ts2); stroke:var(–tt2); stroke-width:1.5; }

svg .key-label{ font-family:var(–font); font-size:10px; fill:var(–ts); text-anchor:middle; }

svg .key-label-dark{ font-family:var(–font); font-size:9px; fill:var(–ts); text-anchor:middle; }

svg .key-label-active{ fill:var(–ct); }

svg .key-label-scale{ fill:var(–tt2); }

</style>

</head>

<body>

<h1 id=”main-title”>Guitar neck diagram</h1>

<p class=”subtitle” id=”subtitle”></p>

<div class=”controls”>

<div class=”ctrl-group”>

<label for=”sel-key”>Key / root</label>

<select id=”sel-key”>

<option value=”C”>C</option>

<option value=”C#”>C#</option>

<option value=”D”>D</option>

<option value=”D#”>D#</option>

<option value=”E”>E</option>

<option value=”F”>F</option>

<option value=”F#”>F#</option>

<option value=”G”>G</option>

<option value=”G#”>G#</option>

<option value=”A”>A</option>

<option value=”A#”>A#</option>

<option value=”B”>B</option>

</select>

</div>

<div class=”ctrl-group”>

<label for=”sel-mode”>Mode</label>

<select id=”sel-mode”>

<option value=”scale”>Scale / mode</option>

<option value=”chord”>Chord</option>

</select>

</div>

<div class=”ctrl-group” id=”scale-ctrl”>

<label for=”sel-scale”>Scale</label>

<select id=”sel-scale”>

<optgroup label=”Messiaen — Modes of Limited Transposition”>

<option value=”messiaen_1″>Messiaen mode 1 (whole tone)</option>

<option value=”messiaen_2″>Messiaen mode 2 (octatonic)</option>

<option value=”messiaen_3″>Messiaen mode 3</option>

<option value=”messiaen_4″>Messiaen mode 4</option>

<option value=”messiaen_5″>Messiaen mode 5</option>

<option value=”messiaen_6″>Messiaen mode 6</option>

<option value=”messiaen_7″>Messiaen mode 7</option>

</optgroup>

<optgroup label=”Standard scales &amp; modes”>

<option value=”major”>Major (Ionian)</option>

<option value=”minor”>Natural minor (Aeolian)</option>

<option value=”dorian”>Dorian</option>

<option value=”phrygian”>Phrygian</option>

<option value=”lydian”>Lydian</option>

<option value=”mixolydian”>Mixolydian</option>

<option value=”locrian”>Locrian</option>

<option value=”harmonic_minor”>Harmonic minor</option>

<option value=”melodic_minor”>Melodic minor</option>

<option value=”phrygian_dom”>Phrygian dominant</option>

<option value=”lydian_dom”>Lydian dominant</option>

<option value=”pentatonic”>Major pentatonic</option>

<option value=”minor_pent”>Minor pentatonic</option>

<option value=”blues”>Blues</option>

<option value=”diminished”>Diminished (H-W)</option>

<option value=”dim_wh”>Diminished (W-H)</option>

<option value=”augmented”>Augmented</option>

<option value=”chromatic”>Chromatic</option>

</optgroup>

</select>

</div>

<div class=”ctrl-group” id=”chord-ctrl” style=”display:none”>

<label for=”sel-chord”>Chord type</label>

<select id=”sel-chord”>

<optgroup label=”Triads”>

<option value=”major”>Major</option>

<option value=”minor”>Minor</option>

<option value=”dim”>Diminished</option>

<option value=”aug”>Augmented</option>

<option value=”sus2″>Sus2</option>

<option value=”sus4″>Sus4</option>

<option value=”power”>Power (5th)</option>

</optgroup>

<optgroup label=”Sixth chords”>

<option value=”maj6″>Major 6</option>

<option value=”min6″>Minor 6</option>

<option value=”six_nine”>6/9</option>

</optgroup>

<optgroup label=”Seventh chords”>

<option value=”maj7″>Major 7</option>

<option value=”dom7″>Dominant 7</option>

<option value=”min7″>Minor 7</option>

<option value=”minmaj7″>Minor/Major 7</option>

<option value=”half_dim”>Half-dim (m7b5)</option>

<option value=”dim7″>Diminished 7</option>

<option value=”augmaj7″>Augmented Maj7</option>

<option value=”aug7″>Augmented 7 (7#5)</option>

<option value=”dom7sus4″>Dom 7sus4</option>

<option value=”dom7b5″>Dom 7b5</option>

</optgroup>

<optgroup label=”Add chords”>

<option value=”add9″>Add9</option>

<option value=”madd9″>m(add9)</option>

<option value=”add11″>Add11</option>

</optgroup>

<optgroup label=”Ninth chords”>

<option value=”maj9″>Major 9</option>

<option value=”dom9″>Dominant 9</option>

<option value=”min9″>Minor 9</option>

<option value=”minmaj9″>Minor/Major 9</option>

<option value=”dom7b9″>Dom 7b9</option>

<option value=”dom7s9″>Dom 7#9 (Hendrix)</option>

<option value=”dom7b9s9″>Dom 7b9#9</option>

</optgroup>

<optgroup label=”Eleventh chords”>

<option value=”maj11″>Major 11</option>

<option value=”dom11″>Dominant 11</option>

<option value=”min11″>Minor 11</option>

<option value=”dom7s11″>Dom 7#11 (Lydian dom)</option>

<option value=”maj7s11″>Maj 7#11</option>

</optgroup>

<optgroup label=”Thirteenth chords”>

<option value=”maj13″>Major 13</option>

<option value=”dom13″>Dominant 13</option>

<option value=”min13″>Minor 13</option>

<option value=”dom13s11″>Dom 13#11</option>

</optgroup>

<optgroup label=”Altered / jazz”>

<option value=”alt”>Altered (7alt)</option>

<option value=”dom7b9b13″>Dom 7b9b13</option>

<option value=”dom7s9s11″>Dom 7#9#11</option>

<option value=”dom9s11″>Dom 9#11</option>

<option value=”dom9b13″>Dom 9b13</option>

</optgroup>

</select>

</div>

<div class=”ctrl-group”>

<label for=”sel-preset”>Tuning preset</label>

<select id=”sel-preset”>

<option value=””>— custom —</option>

<option value=”E,A,D,G,B,E”>Standard (E A D G B E)</option>

<option value=”D,A,D,G,B,E”>Drop D (D A D G B E)</option>

<option value=”D,G,D,G,B,D”>Open G (D G D G B D)</option>

<option value=”D,A,D,F#,A,D”>Open D (D A D F# A D)</option>

<option value=”E,B,E,G#,B,E”>Open E (E B E G# B E)</option>

<option value=”D,A,D,G,A,D”>DADGAD (D A D G A D)</option>

<option value=”Eb,Ab,Db,Gb,Bb,Eb”>Half step down (Eb Ab Db Gb Bb Eb)</option>

<option value=”D,G,C,F,A,D”>Full step down (D G C F A D)</option>

</select>

</div>

<div class=”ctrl-group”>

<label>Open strings (low → high)</label>

<div class=”tuning-row” id=”tuning-row”></div>

<div class=”err” id=”tuning-err”>Invalid note — use C, C#, D, D#, E, F, F#, G, G#, A, A#, B</div>

</div>

</div>

<div class=”scroll-wrap”>

<svg id=”neck” width=”1100″ height=”460″ viewBox=”0 0 1100 460″ xmlns=”http://www.w3.org/2000/svg”></svg&gt;

</div>

<div class=”legend”>

<div class=”legend-item”><div class=”swatch sw-root”></div><span id=”leg-root”>Root</span></div>

<div class=”legend-item”><div class=”swatch sw-scale”></div><span id=”leg-tone-label”>Scale tone</span></div>

<div class=”notes-label” id=”leg-notes”></div>

</div>

<div class=”piano-wrap”>

<div class=”piano-heading”>Piano keyboard</div>

<div class=”piano-scroll”>

<svg id=”piano” xmlns=”http://www.w3.org/2000/svg”></svg&gt;

</div>

</div>

<div class=”flute-wrap”>

<div class=”flute-heading”>Concert flute fingerings (Boehm system)</div>

<div class=”flute-scroll”>

<div class=”flute-row” id=”flute-row”></div>

</div>

</div>

<script>

const CHROMATIC = [“C”, “C#”, “D”, “D#”, “E”, “F”, “F#”, “G”, “G#”, “A”, “A#”, “B”];

const SCALES = {“messiaen_1”: {“name”: “Messiaen mode 1 (whole tone)”, “desc”: “6 notes \u00b7 2 transpositions \u00b7 All whole steps”, “intervals”: [0, 2, 4, 6, 8, 10]}, “messiaen_2”: {“name”: “Messiaen mode 2 (octatonic)”, “desc”: “8 notes \u00b7 3 transpositions \u00b7 Semitone\u2013tone repeating \u2014 his most-used mode”, “intervals”: [0, 1, 3, 4, 6, 7, 9, 10]}, “messiaen_3”: {“name”: “Messiaen mode 3”, “desc”: “9 notes \u00b7 4 transpositions \u00b7 Tone\u2013semitone\u2013semitone repeating”, “intervals”: [0, 2, 3, 4, 6, 7, 8, 10, 11]}, “messiaen_4”: {“name”: “Messiaen mode 4”, “desc”: “8 notes \u00b7 6 transpositions \u00b7 Semitone\u2013semitone\u2013min3rd\u2013semitone repeating”, “intervals”: [0, 1, 2, 5, 6, 7, 8, 11]}, “messiaen_5”: {“name”: “Messiaen mode 5”, “desc”: “6 notes \u00b7 6 transpositions \u00b7 Semitone\u2013maj3rd\u2013semitone repeating”, “intervals”: [0, 1, 5, 6, 7, 11]}, “messiaen_6”: {“name”: “Messiaen mode 6”, “desc”: “8 notes \u00b7 6 transpositions \u00b7 Tone\u2013tone\u2013semitone\u2013semitone repeating”, “intervals”: [0, 2, 4, 5, 6, 8, 10, 11]}, “messiaen_7”: {“name”: “Messiaen mode 7”, “desc”: “10 notes \u00b7 6 transpositions \u00b7 Semitone\u2013semitone\u2013semitone\u2013tone\u2013semitone repeating”, “intervals”: [0, 1, 2, 3, 5, 6, 7, 8, 9, 11]}, “major”: {“name”: “Major (Ionian)”, “desc”: “7 notes \u00b7 W W H W W W H”, “intervals”: [0, 2, 4, 5, 7, 9, 11]}, “minor”: {“name”: “Natural minor (Aeolian)”, “desc”: “7 notes \u00b7 W H W W H W W”, “intervals”: [0, 2, 3, 5, 7, 8, 10]}, “dorian”: {“name”: “Dorian”, “desc”: “7 notes \u00b7 W H W W W H W”, “intervals”: [0, 2, 3, 5, 7, 9, 10]}, “phrygian”: {“name”: “Phrygian”, “desc”: “7 notes \u00b7 H W W W H W W”, “intervals”: [0, 1, 3, 5, 7, 8, 10]}, “lydian”: {“name”: “Lydian”, “desc”: “7 notes \u00b7 W W W H W W H”, “intervals”: [0, 2, 4, 6, 7, 9, 11]}, “mixolydian”: {“name”: “Mixolydian”, “desc”: “7 notes \u00b7 W W H W W H W”, “intervals”: [0, 2, 4, 5, 7, 9, 10]}, “locrian”: {“name”: “Locrian”, “desc”: “7 notes \u00b7 H W W H W W W”, “intervals”: [0, 1, 3, 5, 6, 8, 10]}, “harmonic_minor”: {“name”: “Harmonic minor”, “desc”: “7 notes \u00b7 Natural minor with raised 7th”, “intervals”: [0, 2, 3, 5, 7, 8, 11]}, “melodic_minor”: {“name”: “Melodic minor”, “desc”: “7 notes \u00b7 Natural minor with raised 6th & 7th”, “intervals”: [0, 2, 3, 5, 7, 9, 11]}, “phrygian_dom”: {“name”: “Phrygian dominant”, “desc”: “7 notes \u00b7 Phrygian with raised 3rd”, “intervals”: [0, 1, 4, 5, 7, 8, 10]}, “lydian_dom”: {“name”: “Lydian dominant”, “desc”: “7 notes \u00b7 Lydian with b7”, “intervals”: [0, 2, 4, 6, 7, 9, 10]}, “pentatonic”: {“name”: “Major pentatonic”, “desc”: “5 notes”, “intervals”: [0, 2, 4, 7, 9]}, “minor_pent”: {“name”: “Minor pentatonic”, “desc”: “5 notes”, “intervals”: [0, 3, 5, 7, 10]}, “blues”: {“name”: “Blues”, “desc”: “6 notes \u00b7 Minor pent + b5”, “intervals”: [0, 3, 5, 6, 7, 10]}, “diminished”: {“name”: “Diminished (H-W)”, “desc”: “8 notes \u00b7 Semitone\u2013tone alternating”, “intervals”: [0, 1, 3, 4, 6, 7, 9, 10]}, “dim_wh”: {“name”: “Diminished (W-H)”, “desc”: “8 notes \u00b7 Tone\u2013semitone alternating”, “intervals”: [0, 2, 3, 5, 6, 8, 9, 11]}, “augmented”: {“name”: “Augmented”, “desc”: “6 notes \u00b7 Min3rd\u2013semitone repeating”, “intervals”: [0, 3, 4, 7, 8, 11]}, “chromatic”: {“name”: “Chromatic”, “desc”: “12 notes”, “intervals”: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}};

const CHORDS = {“major”: {“name”: “Major”, “desc”: “1 3 5”, “intervals”: [0, 4, 7]}, “minor”: {“name”: “Minor”, “desc”: “1 b3 5”, “intervals”: [0, 3, 7]}, “dim”: {“name”: “Diminished”, “desc”: “1 b3 b5”, “intervals”: [0, 3, 6]}, “aug”: {“name”: “Augmented”, “desc”: “1 3 #5”, “intervals”: [0, 4, 8]}, “sus2”: {“name”: “Sus2”, “desc”: “1 2 5”, “intervals”: [0, 2, 7]}, “sus4”: {“name”: “Sus4”, “desc”: “1 4 5”, “intervals”: [0, 5, 7]}, “power”: {“name”: “Power (5th)”, “desc”: “1 5”, “intervals”: [0, 7]}, “maj6”: {“name”: “Major 6”, “desc”: “1 3 5 6”, “intervals”: [0, 4, 7, 9]}, “min6”: {“name”: “Minor 6”, “desc”: “1 b3 5 6”, “intervals”: [0, 3, 7, 9]}, “six_nine”: {“name”: “6/9”, “desc”: “1 3 5 6 9”, “intervals”: [0, 2, 4, 7, 9]}, “maj7”: {“name”: “Major 7”, “desc”: “1 3 5 7”, “intervals”: [0, 4, 7, 11]}, “dom7”: {“name”: “Dominant 7”, “desc”: “1 3 5 b7”, “intervals”: [0, 4, 7, 10]}, “min7”: {“name”: “Minor 7”, “desc”: “1 b3 5 b7”, “intervals”: [0, 3, 7, 10]}, “minmaj7”: {“name”: “Minor/Major 7”, “desc”: “1 b3 5 7”, “intervals”: [0, 3, 7, 11]}, “half_dim”: {“name”: “Half-dim (m7b5)”, “desc”: “1 b3 b5 b7”, “intervals”: [0, 3, 6, 10]}, “dim7”: {“name”: “Diminished 7”, “desc”: “1 b3 b5 bb7”, “intervals”: [0, 3, 6, 9]}, “augmaj7”: {“name”: “Augmented Maj7”, “desc”: “1 3 #5 7”, “intervals”: [0, 4, 8, 11]}, “aug7”: {“name”: “Augmented 7 (7#5)”, “desc”: “1 3 #5 b7”, “intervals”: [0, 4, 8, 10]}, “dom7sus4”: {“name”: “Dom 7sus4”, “desc”: “1 4 5 b7”, “intervals”: [0, 5, 7, 10]}, “dom7b5”: {“name”: “Dom 7b5”, “desc”: “1 3 b5 b7”, “intervals”: [0, 4, 6, 10]}, “add9”: {“name”: “Add9”, “desc”: “1 3 5 9”, “intervals”: [0, 2, 4, 7]}, “madd9”: {“name”: “m(add9)”, “desc”: “1 b3 5 9”, “intervals”: [0, 2, 3, 7]}, “add11”: {“name”: “Add11”, “desc”: “1 3 5 11”, “intervals”: [0, 4, 5, 7]}, “maj9”: {“name”: “Major 9”, “desc”: “1 3 5 7 9”, “intervals”: [0, 2, 4, 7, 11]}, “dom9”: {“name”: “Dominant 9”, “desc”: “1 3 5 b7 9”, “intervals”: [0, 2, 4, 7, 10]}, “min9”: {“name”: “Minor 9”, “desc”: “1 b3 5 b7 9”, “intervals”: [0, 2, 3, 7, 10]}, “minmaj9”: {“name”: “Minor/Major 9”, “desc”: “1 b3 5 7 9”, “intervals”: [0, 2, 3, 7, 11]}, “dom7b9”: {“name”: “Dom 7b9”, “desc”: “1 3 5 b7 b9”, “intervals”: [0, 1, 4, 7, 10]}, “dom7s9”: {“name”: “Dom 7#9 (Hendrix)”, “desc”: “1 3 5 b7 #9”, “intervals”: [0, 3, 4, 7, 10]}, “dom7b9s9”: {“name”: “Dom 7b9#9”, “desc”: “1 3 5 b7 b9 #9”, “intervals”: [0, 1, 3, 4, 7, 10]}, “maj11”: {“name”: “Major 11”, “desc”: “1 3 5 7 9 11”, “intervals”: [0, 2, 4, 5, 7, 11]}, “dom11”: {“name”: “Dominant 11”, “desc”: “1 3 5 b7 9 11”, “intervals”: [0, 2, 4, 5, 7, 10]}, “min11”: {“name”: “Minor 11”, “desc”: “1 b3 5 b7 9 11”, “intervals”: [0, 2, 3, 5, 7, 10]}, “dom7s11”: {“name”: “Dom 7#11 (Lydian dom)”, “desc”: “1 3 5 b7 #11”, “intervals”: [0, 4, 6, 7, 10]}, “maj7s11”: {“name”: “Maj 7#11”, “desc”: “1 3 5 7 #11”, “intervals”: [0, 4, 6, 7, 11]}, “maj13”: {“name”: “Major 13”, “desc”: “1 3 5 7 9 11 13”, “intervals”: [0, 2, 4, 5, 7, 9, 11]}, “dom13”: {“name”: “Dominant 13”, “desc”: “1 3 5 b7 9 11 13”, “intervals”: [0, 2, 4, 5, 7, 9, 10]}, “min13”: {“name”: “Minor 13”, “desc”: “1 b3 5 b7 9 11 13”, “intervals”: [0, 2, 3, 5, 7, 9, 10]}, “dom13s11”: {“name”: “Dom 13#11”, “desc”: “1 3 5 b7 9 #11 13”, “intervals”: [0, 2, 4, 6, 7, 9, 10]}, “alt”: {“name”: “Altered (7alt)”, “desc”: “1 3 b7 b9 #9 b13”, “intervals”: [0, 1, 3, 4, 8, 10]}, “dom7b9b13”: {“name”: “Dom 7b9b13”, “desc”: “1 3 5 b7 b9 b13”, “intervals”: [0, 1, 4, 7, 8, 10]}, “dom7s9s11”: {“name”: “Dom 7#9#11”, “desc”: “1 3 b7 #9 #11”, “intervals”: [0, 3, 4, 6, 10]}, “dom9s11”: {“name”: “Dom 9#11”, “desc”: “1 3 5 b7 9 #11”, “intervals”: [0, 2, 4, 6, 7, 10]}, “dom9b13”: {“name”: “Dom 9b13”, “desc”: “1 3 5 b7 9 b13”, “intervals”: [0, 2, 4, 7, 8, 10]}};

const PRESETS = {“Standard (E A D G B E)”: “E,A,D,G,B,E”, “Drop D (D A D G B E)”: “D,A,D,G,B,E”, “Open G (D G D G B D)”: “D,G,D,G,B,D”, “Open D (D A D F# A D)”: “D,A,D,F#,A,D”, “Open E (E B E G# B E)”: “E,B,E,G#,B,E”, “DADGAD (D A D G A D)”: “D,A,D,G,A,D”, “Half step down (Eb Ab Db Gb Bb Eb)”: “Eb,Ab,Db,Gb,Bb,Eb”, “Full step down (D G C F A D)”: “D,G,C,F,A,D”};

const FRET_X = [72,152,232,310,386,460,532,602,670,736,800,862,922,1082];

const STRING_Y = [68,118,168,218,268,318];

const STR_WIDTHS = [3,2.4,1.9,1.4,1.0,0.7];

const DOT_R = 13;

const NECK_X0=72, NECK_X1=1082, NECK_Y0=32, NECK_Y1=348;

const ENHARMONIC = {Db:’C#’,Eb:’D#’,Fb:’E’,Gb:’F#’,Ab:’G#’,Bb:’A#’,Cb:’B’};

function norm(n) {

const s = n.trim();

const cap = s.charAt(0).toUpperCase() + s.slice(1).toLowerCase()

.replace(‘b’,’b’).replace(‘#’,’#’);

const cap2 = s.charAt(0).toUpperCase() + s.slice(1);

return ENHARMONIC[cap2] || cap2;

}

function fretMid(f) { return Math.floor((FRET_X[f]+FRET_X[f+1])/2); }

function noteAt(open, fret) { return CHROMATIC[(CHROMATIC.indexOf(open)+fret)%12]; }

function svgEl(tag, attrs) {

const el = document.createElementNS(‘http://www.w3.org/2000/svg&#8217;, tag);

for (const [k,v] of Object.entries(attrs)) el.setAttribute(k,v);

return el;

}

function svgTxt(attrs, text) {

const el = svgEl(‘text’, attrs);

el.textContent = text;

return el;

}

function buildNeck(tuning, noteSet, root) {

const svg = document.getElementById(‘neck’);

svg.innerHTML=”;

const a = el => svg.appendChild(el);

a(svgEl(‘rect’,{x:NECK_X0,y:NECK_Y0,width:NECK_X1-NECK_X0,height:NECK_Y1-NECK_Y0,rx:6,fill:’#C8A96A’,opacity:’0.15′}));

a(svgEl(‘rect’,{x:NECK_X0,y:NECK_Y0,width:8,height:NECK_Y1-NECK_Y0,rx:2,fill:’var(–tp)’,opacity:’0.3′}));

for (let f=1;f<=12;f++)

a(svgEl(‘line’,{x1:FRET_X[f],y1:NECK_Y0,x2:FRET_X[f],y2:NECK_Y1,stroke:’var(–tp)’,’stroke-width’:’2′,opacity:’0.25′}));

[[3,192],[5,192],[7,192],[9,192],[12,150],[12,234]].forEach(([f,cy])=>

a(svgEl(‘circle’,{cx:fretMid(f),cy,r:7,fill:’var(–tp)’,opacity:’0.10′})));

STRING_Y.forEach((sy,i)=>

a(svgEl(‘line’,{x1:NECK_X0,y1:sy,x2:NECK_X1,y2:sy,stroke:’var(–ts)’,’stroke-width’:STR_WIDTHS[i],opacity:’0.5′})));

// Open string labels

STRING_Y.forEach((sy,i)=>

a(svgTxt({x:56,y:sy,’text-anchor’:’middle’,’dominant-baseline’:’central’,’font-weight’:’500′,class:’ts’}, tuning[i])));

// Fret numbers

a(svgTxt({x:fretMid(0),y:372,’text-anchor’:’middle’,class:’ts’},’open’));

for (let f=1;f<=12;f++)

a(svgTxt({x:fretMid(f),y:372,’text-anchor’:’middle’,class:’ts’}, String(f)));

// Note dots

STRING_Y.forEach((sy,si)=>{

for (let fret=0;fret<=12;fret++){

const note = noteAt(tuning[si], fret);

if (!noteSet.has(note)) continue;

const cx = fretMid(fret);

const isRoot = note===root;

const g = svgEl(‘g’,{class:isRoot?’c-coral’:’c-teal’});

g.appendChild(svgEl(‘circle’,{cx,cy:sy,r:DOT_R,’stroke-width’:’0′}));

g.appendChild(svgTxt({x:cx,y:sy,’text-anchor’:’middle’,’dominant-baseline’:’central’,class:’th’,style:’font-size:11px’}, note));

svg.appendChild(g);

}

});

}

function getTuning() {

return […document.querySelectorAll(‘#tuning-row input’)].map(i=>norm(i.value));

}

function update() {

const key = document.getElementById(‘sel-key’).value;

const mode = document.getElementById(‘sel-mode’).value;

const tuning = getTuning();

const errEl = document.getElementById(‘tuning-err’);

if (tuning.some(n=>!CHROMATIC.includes(n))) { errEl.style.display=’block’; return; }

errEl.style.display=’none’;

const rootIdx = CHROMATIC.indexOf(key);

let entry, notes, label;

if (mode === ‘chord’) {

const ckey = document.getElementById(‘sel-chord’).value;

entry = CHORDS[ckey];

notes = entry.intervals.map(i=>CHROMATIC[(rootIdx+i)%12]);

label = key + ‘ ‘ + entry.name;

document.getElementById(‘subtitle’).textContent = label + ‘ · ‘ + entry.desc;

document.getElementById(‘leg-tone-label’).textContent = ‘Chord tone’;

} else {

const skey = document.getElementById(‘sel-scale’).value;

entry = SCALES[skey];

notes = entry.intervals.map(i=>CHROMATIC[(rootIdx+i)%12]);

label = entry.name;

document.getElementById(‘subtitle’).textContent = label + ‘ · ‘ + entry.desc;

document.getElementById(‘leg-tone-label’).textContent = ‘Scale tone’;

}

const noteSet = new Set(notes);

buildNeck(tuning, noteSet, key);

if (window.buildPiano) buildPiano(noteSet, key);

if (window.buildFlute) buildFlute(notes, key);

document.getElementById(‘leg-root’).textContent = key + ‘ (root)’;

document.getElementById(‘leg-notes’).textContent = ‘Notes: ‘ + notes.join(‘ ‘);

}

function buildTuningInputs(tuning) {

const row = document.getElementById(‘tuning-row’);

row.innerHTML=”;

const labels=[‘6 (low)’,’5′,’4′,’3′,’2′,’1 (high)’];

tuning.forEach((note,i)=>{

const inp = document.createElement(‘input’);

inp.type=’text’; inp.value=note; inp.maxLength=3; inp.title=labels[i]+’ string’;

inp.addEventListener(‘input’,()=>{

document.getElementById(‘sel-preset’).value=”;

update();

});

row.appendChild(inp);

});

}

// Preset tuning handler

document.getElementById(‘sel-preset’).addEventListener(‘change’, function(){

if (!this.value) return;

buildTuningInputs(this.value.split(‘,’).map(n=>norm(n.trim())));

update();

});

document.getElementById(‘sel-key’).addEventListener(‘change’, update);

document.getElementById(‘sel-scale’).addEventListener(‘change’, update);

document.getElementById(‘sel-chord’).addEventListener(‘change’, update);

document.getElementById(‘sel-mode’).addEventListener(‘change’, function() {

const isChord = this.value === ‘chord’;

document.getElementById(‘scale-ctrl’).style.display = isChord ? ‘none’ : ”;

document.getElementById(‘chord-ctrl’).style.display = isChord ? ” : ‘none’;

update();

});

// Initialise

const initKey = “C”;

const initScale = “major”;

const initChord = “major”;

const initMode = “scale”;

const initTuning = [“E”, “A”, “D”, “G”, “B”, “E”];

document.getElementById(‘sel-key’).value = initKey;

document.getElementById(‘sel-scale’).value = initScale;

document.getElementById(‘sel-chord’).value = initChord;

document.getElementById(‘sel-mode’).value = initMode;

if (initMode === ‘chord’) {

document.getElementById(‘scale-ctrl’).style.display = ‘none’;

document.getElementById(‘chord-ctrl’).style.display = ”;

}

buildTuningInputs(initTuning);

// Mark matching preset

for (const [,val] of Object.entries(PRESETS)) {

if (val === initTuning.join(‘,’)) {

document.getElementById(‘sel-preset’).value = val; break;

}

}

// ── Concert flute fingerings (Boehm system) ──────────────────────────────

//

// Key layout (top to bottom in diagram):

// OCT — octave/register key (left thumb, upper)

// TH — B♭ thumb lever (Briccialdi) — shown as small side key

// LH1 — left index finger (covers B hole)

// LH2 — left middle finger (covers A hole)

// LH3 — left ring finger (covers G hole)

// LH4 — left pinky (G#/Ab key)

// ··· — gap between hands

// RH1 — right index finger (covers F# hole)

// RH2 — right middle finger(covers E hole)

// RH3 — right ring finger (covers D hole)

// RH4 — right pinky (Eb/D# roller key)

//

// Each note’s fingering is encoded as an object:

// oct: bool — octave key depressed

// th: bool — Briccialdi Bb thumb lever

// lh1..lh4: bool — left fingers (true = key DOWN / hole covered)

// rh1..rh4: bool — right fingers (true = key DOWN / hole covered)

//

// Fingerings cover first octave (4th octave register = add oct key).

// Register 1: C4–B4, Register 2: C5–B5 (oct key), Register 3: C6+ (oct key + overblowing)

// We show register 1 as the canonical reference diagram, noting octave above.

(function() {

// Standard Boehm fingerings for all 12 chromatic pitches (register-1 reference).

// oct=false for all here; add oct=true for register 2, specific combos for reg 3.

// Keys: oct, th(Bb lever), lh1, lh2, lh3, lh4(G#key), rh1, rh2, rh3, rh4(Eb key)

//

// Convention: lh4 being TRUE means the G#/Ab key IS pressed (LH pinky down).

// On a standard closed-G# flute this key is NORMALLY UP (open), pressing it closes G#.

//

// Fingering reference: standard Boehm closed-G# system, C foot.

const BASE = {

// oct th lh1 lh2 lh3 lh4 rh1 rh2 rh3 rh4

‘C’ : { oct:false, th:false, lh1:true, lh2:true, lh3:true, lh4:false, rh1:true, rh2:true, rh3:true, rh4:false },

‘C#’: { oct:false, th:false, lh1:true, lh2:true, lh3:true, lh4:false, rh1:true, rh2:true, rh3:false, rh4:false },

‘D’ : { oct:false, th:false, lh1:true, lh2:true, lh3:true, lh4:false, rh1:true, rh2:false, rh3:false, rh4:false },

‘D#’: { oct:false, th:false, lh1:true, lh2:true, lh3:true, lh4:false, rh1:false, rh2:false, rh3:false, rh4:true },

‘E’ : { oct:false, th:false, lh1:true, lh2:true, lh3:true, lh4:false, rh1:false, rh2:false, rh3:false, rh4:false },

‘F’ : { oct:false, th:false, lh1:true, lh2:true, lh3:false, lh4:false, rh1:false, rh2:false, rh3:false, rh4:false },

‘F#’: { oct:false, th:false, lh1:true, lh2:false, lh3:false, lh4:false, rh1:false, rh2:false, rh3:false, rh4:false },

‘G’ : { oct:false, th:false, lh1:false, lh2:false, lh3:false, lh4:false, rh1:false, rh2:false, rh3:false, rh4:false },

‘G#’: { oct:false, th:false, lh1:false, lh2:false, lh3:false, lh4:true, rh1:false, rh2:false, rh3:false, rh4:false },

‘A’ : { oct:false, th:false, lh1:false, lh2:true, lh3:true, lh4:false, rh1:true, rh2:true, rh3:true, rh4:false },

‘A#’: { oct:false, th:true, lh1:true, lh2:false, lh3:false, lh4:false, rh1:false, rh2:false, rh3:false, rh4:false },

‘B’ : { oct:false, th:false, lh1:true, lh2:false, lh3:false, lh4:false, rh1:false, rh2:false, rh3:false, rh4:false },

};

// Compute register-specific fingering.

// Reg 1 = C4–B4 (base, no oct key)

// Reg 2 = C5–B5 (add oct key to all base fingerings)

// Reg 3 = C6–B6 (oct key + specific overblown fingerings — simplified: same as reg2 for display)

function fingeringFor(note, octave) {

const base = Object.assign({}, BASE[note]);

if (octave >= 2) base.oct = true;

return base;

}

// Choose which octave to show for a given chromatic note given the scale’s root.

// We default to register 2 (middle octave) as most practical for flutists.

function chooseOctave(/* unused for now */) { return 2; }

// ── SVG drawing ──────────────────────────────────────────────────────────

// Flute diagram is drawn top-to-bottom as a stylised side view.

// The body is a narrow vertical tube; keys appear as circles on the left side.

const CARD_W = 52; // SVG width per card

const KEY_R = 7; // main key circle radius

const OCT_R = 4; // octave key radius (small)

const TH_R = 4.5; // thumb Bb lever radius

const COL_X = 26; // x centre of key column

const BODY_X1 = 22; // tube left edge

const BODY_X2 = 30; // tube right edge

const TOP_Y = 18; // y of first key centre

const KEY_GAP = 18; // vertical gap between main keys

const HAND_GAP= 10; // extra gap between LH and RH groups

const OCT_Y = TOP_Y – 14; // octave key position above LH1

// Key vertical positions (y centres), relative to SVG top

// Order: OCT, LH1, LH2, LH3, LH4, [gap], RH1, RH2, RH3, RH4

function keyPositions() {

const ys = {};

ys.oct = OCT_Y;

ys.lh1 = TOP_Y;

ys.lh2 = TOP_Y + KEY_GAP;

ys.lh3 = TOP_Y + KEY_GAP * 2;

ys.lh4 = TOP_Y + KEY_GAP * 3;

ys.rh1 = TOP_Y + KEY_GAP * 3 + HAND_GAP + KEY_GAP;

ys.rh2 = TOP_Y + KEY_GAP * 3 + HAND_GAP + KEY_GAP * 2;

ys.rh3 = TOP_Y + KEY_GAP * 3 + HAND_GAP + KEY_GAP * 3;

ys.rh4 = TOP_Y + KEY_GAP * 3 + HAND_GAP + KEY_GAP * 4;

return ys;

}

const POS = keyPositions();

const TUBE_TOP = OCT_Y – OCT_R – 4;

const TUBE_BOTTOM= POS.rh4 + KEY_R + 6;

const SVG_H = TUBE_BOTTOM + 18; // extra for label below

function fEl(tag, attrs) {

const el = document.createElementNS(‘http://www.w3.org/2000/svg&#8217;, tag);

for (const [k,v] of Object.entries(attrs)) el.setAttribute(k,v);

return el;

}

function fTxt(attrs, text) {

const el = fEl(‘text’, attrs); el.textContent = text; return el;

}

function drawFluteCard(note, isRoot, octave) {

const f = fingeringFor(note, octave);

const svg = document.createElementNS(‘http://www.w3.org/2000/svg&#8217;,’svg’);

svg.setAttribute(‘width’, CARD_W);

svg.setAttribute(‘height’, SVG_H);

svg.setAttribute(‘viewBox’, `0 0 ${CARD_W} ${SVG_H}`);

svg.setAttribute(‘xmlns’,’http://www.w3.org/2000/svg&#8217;);

// Gradient def for half-hole (not needed here but good to include)

const defs = fEl(‘defs’,{});

const grad = fEl(‘linearGradient’,{id:`hf_${note.replace(‘#’,’s’)}`,x1:’0′,y1:’0′,x2:’1′,y2:’0′});

grad.appendChild(fEl(‘stop’,{offset:’50%’,’stop-color’:’var(–tp)’,’stop-opacity’:’1′}));

grad.appendChild(fEl(‘stop’,{offset:’50%’,’stop-color’:’var(–bg)’,’stop-opacity’:’1′}));

defs.appendChild(grad);

svg.appendChild(defs);

// Tube body (vertical rectangle)

svg.appendChild(fEl(‘rect’,{

x: BODY_X1, y: TUBE_TOP,

width: BODY_X2 – BODY_X1, height: TUBE_BOTTOM – TUBE_TOP,

rx: 3, class: ‘fl-body’

}));

// Hand separator dashes

const sepY = (POS.lh4 + POS.rh1) / 2;

for (let dx = 0; dx < 3; dx++) {

svg.appendChild(fEl(‘rect’,{

x: COL_X – 5 + dx*5, y: sepY – 0.5,

width: 2, height: 1,

fill:’var(–ts)’, opacity:’0.4′

}));

}

// Helper: draw one key circle

function drawKey(cx, cy, closed, r) {

r = r || KEY_R;

const cls = closed ? ‘fk-closed’ : ‘fk-open’;

svg.appendChild(fEl(‘circle’,{cx, cy, r, class:cls}));

}

// Octave key — small circle, offset slightly left

drawKey(COL_X – 4, POS.oct, f.oct, OCT_R);

// Bb thumb lever — small circle right of tube, above LH1

const thY = (POS.oct + POS.lh1) / 2;

svg.appendChild(fEl(‘circle’,{

cx: BODY_X2 + 5, cy: thY, r: TH_R,

class: f.th ? ‘fk-closed’ : ‘fk-open’

}));

// Main finger keys

drawKey(COL_X, POS.lh1, f.lh1);

drawKey(COL_X, POS.lh2, f.lh2);

drawKey(COL_X, POS.lh3, f.lh3);

// LH4 (G# key) — smaller, offset right to show it’s a side key

svg.appendChild(fEl(‘circle’,{

cx: BODY_X2 + 5, cy: POS.lh4, r: KEY_R – 2,

class: f.lh4 ? ‘fk-closed’ : ‘fk-open’

}));

drawKey(COL_X, POS.rh1, f.rh1);

drawKey(COL_X, POS.rh2, f.rh2);

drawKey(COL_X, POS.rh3, f.rh3);

// RH4 (Eb roller) — smaller, offset right

svg.appendChild(fEl(‘circle’,{

cx: BODY_X2 + 5, cy: POS.rh4, r: KEY_R – 2,

class: f.rh4 ? ‘fk-closed’ : ‘fk-open’

}));

return svg;

}

window.buildFlute = function(notes, root) {

const row = document.getElementById(‘flute-row’);

row.innerHTML = ”;

// Sort notes chromatically

const ORDER = [‘C’,’C#’,’D’,’D#’,’E’,’F’,’F#’,’G’,’G#’,’A’,’A#’,’B’];

const sorted = […notes].sort((a,b) => ORDER.indexOf(a) – ORDER.indexOf(b));

sorted.forEach(note => {

const octave = 2; // display register 2 (middle octave)

const isRoot = note === root;

const card = document.createElement(‘div’);

card.className = ‘flute-card’;

// Note name label

const nameEl = document.createElement(‘div’);

nameEl.className = ‘note-name’ + (isRoot ? ‘ is-root’ : ”);

nameEl.textContent = note;

card.appendChild(nameEl);

// Octave label

const octEl = document.createElement(‘div’);

octEl.className = ‘octave-tag’;

octEl.textContent = `(${octave + 3}th oct)`;

card.appendChild(octEl);

// SVG diagram

card.appendChild(drawFluteCard(note, isRoot, octave));

// Key legend below diagram

const legEl = document.createElement(‘div’);

legEl.style.cssText = ‘font-size:9px;color:var(–ts);text-align:center;line-height:1.5;margin-top:2px;’;

const f = fingeringFor(note, octave);

const parts = [];

if (f.oct) parts.push(‘oct’);

if (f.th) parts.push(‘B♭lv’);

[‘lh1′,’lh2′,’lh3′,’lh4′,’rh1′,’rh2′,’rh3′,’rh4’].forEach(k => {

if (f[k]) parts.push(k.toUpperCase());

});

legEl.textContent = parts.length ? parts.join(‘ ‘) : ‘open G’;

card.appendChild(legEl);

row.appendChild(card);

});

};

})();

(function() {

// Two full octaves of white/black keys (C–B repeated twice)

const OCTAVES = 2;

const WK_W = 32; // white key width px

const WK_H = 120; // white key height px

const BK_W = 20; // black key width px

const BK_H = 76; // black key height px

const BORDER_R = 4; // bottom-corner radius on white keys

// Within one octave (root = C):

const WHITE_SEMI = [0,2,4,5,7,9,11]; // semitones of white keys C D E F G A B

const WHITE_NAMES = [‘C’,’D’,’E’,’F’,’G’,’A’,’B’];

const BLACK_SEMI = [1,3,6,8,10]; // C# D# F# G# A#

const BLACK_BEFORE= [0,1,3,4,5]; // white-key index to the left of each black

const TOTAL_WHITE = 7 * OCTAVES;

const SVG_W = TOTAL_WHITE * WK_W + 2;

const SVG_H = WK_H + 30;

const svg = document.getElementById(‘piano’);

svg.setAttribute(‘width’, SVG_W);

svg.setAttribute(‘height’, SVG_H);

svg.setAttribute(‘viewBox’, `0 0 ${SVG_W} ${SVG_H}`);

function pEl(tag, attrs) {

const el = document.createElementNS(‘http://www.w3.org/2000/svg&#8217;, tag);

for (const [k,v] of Object.entries(attrs)) el.setAttribute(k,v);

return el;

}

function pTxt(attrs, text) {

const el = pEl(‘text’, attrs); el.textContent = text; return el;

}

window.buildPiano = function(noteSet, root) {

svg.innerHTML = ”;

svg.appendChild(pEl(‘rect’,{x:0,y:0,width:SVG_W,height:SVG_H,fill:’transparent’}));

// White keys (draw first so black keys render on top)

for (let oct=0; oct<OCTAVES; oct++) {

const octX = oct * 7 * WK_W + 1;

WHITE_SEMI.forEach((semi, wi) => {

const note = CHROMATIC[semi];

const x = octX + wi * WK_W;

const isRoot = note === root;

const inScale = noteSet.has(note);

const cls = isRoot ? ‘wk-root’ : inScale ? ‘wk-scale’ : ‘wk’;

const d = `M${x},0 L${x+WK_W-1},0 L${x+WK_W-1},${WK_H-BORDER_R} ` +

`Q${x+WK_W-1},${WK_H} ${x+WK_W-1-BORDER_R},${WK_H} ` +

`L${x+BORDER_R},${WK_H} Q${x},${WK_H} ${x},${WK_H-BORDER_R} Z`;

svg.appendChild(pEl(‘path’,{d,class:cls}));

// Note name label beneath key (first octave only)

if (oct === 0) {

const lCls = isRoot ? ‘key-label key-label-active’

: inScale ? ‘key-label key-label-scale’

: ‘key-label’;

svg.appendChild(pTxt({x:x+WK_W/2, y:WK_H+18, class:lCls}, WHITE_NAMES[wi]));

}

});

}

// Black keys (drawn on top)

for (let oct=0; oct<OCTAVES; oct++) {

const octX = oct * 7 * WK_W + 1;

BLACK_SEMI.forEach((semi, bi) => {

const note = CHROMATIC[semi];

const x = octX + BLACK_BEFORE[bi] * WK_W + WK_W – BK_W/2;

const isRoot = note === root;

const inScale = noteSet.has(note);

const cls = isRoot ? ‘bk-root’ : inScale ? ‘bk-scale’ : ‘bk’;

svg.appendChild(pEl(‘rect’,{x,y:0,width:BK_W,height:BK_H,rx:3,class:cls}));

// Label inside black keys (first octave only)

if (oct === 0) {

const labelStyle = isRoot ? ‘fill:var(–ct)’

: inScale ? ‘fill:var(–tt2)’

: ‘fill:var(–ts)’;

svg.appendChild(pTxt({

x: x+BK_W/2, y: BK_H-9, class:’key-label-dark’,

style: labelStyle

}, note));

}

});

}

};

})();

update();

</script>

</body>

</html>